mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-24 18:52:58 +03:00
Implement fix
This commit is contained in:
parent
de6ac4eb9b
commit
9370c11a2b
@ -26,6 +26,57 @@ use std::collections::HashSet;
|
||||
// TODO: Generally, cleanup tyc logic.
|
||||
|
||||
impl<'a> ProgramVisitor<'a> for TypeChecker<'a> {
|
||||
fn visit_program(&mut self, input: &'a Program) {
|
||||
match self.is_imported {
|
||||
// If the program is imported, then it is not allowed to import any other programs.
|
||||
true => {
|
||||
input.imports.values().for_each(|(_, span)| {
|
||||
self.emit_err(TypeCheckerError::imported_program_cannot_import_program(*span))
|
||||
});
|
||||
}
|
||||
// Otherwise, typecheck the imported programs.
|
||||
false => {
|
||||
// Set `self.is_imported`.
|
||||
let previous_is_imported = core::mem::replace(&mut self.is_imported, true);
|
||||
|
||||
// Typecheck the imported programs.
|
||||
input.imports.values().for_each(|import| self.visit_import(&import.0));
|
||||
|
||||
// Set `self.is_imported` to its previous state.
|
||||
self.is_imported = previous_is_imported;
|
||||
}
|
||||
}
|
||||
|
||||
// Typecheck the program scopes.
|
||||
input
|
||||
.program_scopes
|
||||
.values()
|
||||
.for_each(|scope| self.visit_program_scope(scope));
|
||||
}
|
||||
|
||||
fn visit_program_scope(&mut self, input: &'a ProgramScope) {
|
||||
// Typecheck the struct definitions.
|
||||
input.structs.values().for_each(|function| self.visit_struct(function));
|
||||
|
||||
// Typecheck the mapping definitions.
|
||||
input.mappings.values().for_each(|mapping| self.visit_mapping(mapping));
|
||||
|
||||
// Typecheck the function definitions.
|
||||
let mut transition_count = 0;
|
||||
for function in input.functions.values() {
|
||||
self.visit_function(function);
|
||||
if matches!(function.call_type, CallType::Transition) {
|
||||
transition_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Use the snarkVM configurations to parameterize the check, need similar checks for structs (all in separate PR)
|
||||
// Check that the number of transitions does not exceed the maximum.
|
||||
if transition_count > 15 {
|
||||
self.emit_err(TypeCheckerError::too_many_transitions(15, input.program_id.name.span + input.program_id.network.span));
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_struct(&mut self, input: &'a Struct) {
|
||||
// Check for conflicting struct/record member names.
|
||||
let mut used = HashSet::new();
|
||||
@ -287,32 +338,4 @@ impl<'a> ProgramVisitor<'a> for TypeChecker<'a> {
|
||||
// Unset `is_transition_function` flag.
|
||||
self.is_transition_function = false;
|
||||
}
|
||||
|
||||
fn visit_program(&mut self, input: &'a Program) {
|
||||
match self.is_imported {
|
||||
// If the program is imported, then it is not allowed to import any other programs.
|
||||
true => {
|
||||
input.imports.values().for_each(|(_, span)| {
|
||||
self.emit_err(TypeCheckerError::imported_program_cannot_import_program(*span))
|
||||
});
|
||||
}
|
||||
// Otherwise, typecheck the imported programs.
|
||||
false => {
|
||||
// Set `self.is_imported`.
|
||||
let previous_is_imported = core::mem::replace(&mut self.is_imported, true);
|
||||
|
||||
// Typecheck the imported programs.
|
||||
input.imports.values().for_each(|import| self.visit_import(&import.0));
|
||||
|
||||
// Set `self.is_imported` to its previous state.
|
||||
self.is_imported = previous_is_imported;
|
||||
}
|
||||
}
|
||||
|
||||
// Typecheck the program scopes.
|
||||
input
|
||||
.program_scopes
|
||||
.values()
|
||||
.for_each(|scope| self.visit_program_scope(scope));
|
||||
}
|
||||
}
|
||||
|
@ -444,4 +444,11 @@ create_messages!(
|
||||
msg: format!("An imported program cannot import another program."),
|
||||
help: None,
|
||||
}
|
||||
|
||||
@formatted
|
||||
too_many_transitions {
|
||||
args: (max: impl Display),
|
||||
msg: format!("The number of transitions exceeds the maximum. snarkVM allows up to {max} transitions within a single program."),
|
||||
help: None,
|
||||
}
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user