disallow the use of the private keyword on non-entry point functions
This commit is contained in:
parent
90fe8494b0
commit
4d09fe1c19
2 changed files with 49 additions and 24 deletions
|
@ -0,0 +1,8 @@
|
||||||
|
def mul(private field a) -> field { // `private` should not be allowed here
|
||||||
|
return a * a;
|
||||||
|
}
|
||||||
|
|
||||||
|
def main(private field a, field b) {
|
||||||
|
assert(mul(a) == b);
|
||||||
|
return;
|
||||||
|
}
|
|
@ -89,6 +89,7 @@ type ConstantMap<'ast, T> =
|
||||||
/// The global state of the program during semantic checks
|
/// The global state of the program during semantic checks
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct State<'ast, T> {
|
struct State<'ast, T> {
|
||||||
|
main_id: OwnedModuleId,
|
||||||
/// The modules yet to be checked, which we consume as we explore the dependency tree
|
/// The modules yet to be checked, which we consume as we explore the dependency tree
|
||||||
modules: Modules<'ast>,
|
modules: Modules<'ast>,
|
||||||
/// The already checked modules, which we're returning at the end
|
/// The already checked modules, which we're returning at the end
|
||||||
|
@ -166,8 +167,9 @@ impl<'ast, T: std::cmp::Ord> SymbolUnifier<'ast, T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ast, T: Field> State<'ast, T> {
|
impl<'ast, T: Field> State<'ast, T> {
|
||||||
fn new(modules: Modules<'ast>) -> Self {
|
fn new(modules: Modules<'ast>, main_id: OwnedModuleId) -> Self {
|
||||||
State {
|
State {
|
||||||
|
main_id,
|
||||||
modules,
|
modules,
|
||||||
typed_modules: BTreeMap::new(),
|
typed_modules: BTreeMap::new(),
|
||||||
types: BTreeMap::new(),
|
types: BTreeMap::new(),
|
||||||
|
@ -340,12 +342,13 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
||||||
&mut self,
|
&mut self,
|
||||||
program: Program<'ast>,
|
program: Program<'ast>,
|
||||||
) -> Result<TypedProgram<'ast, T>, Vec<Error>> {
|
) -> Result<TypedProgram<'ast, T>, Vec<Error>> {
|
||||||
let mut state = State::new(program.modules);
|
let main_id = program.main.clone();
|
||||||
|
|
||||||
|
let mut state = State::new(program.modules, main_id.clone());
|
||||||
let mut errors = vec![];
|
let mut errors = vec![];
|
||||||
|
|
||||||
// recursively type-check modules starting with `main`
|
// recursively type-check modules starting with `main`
|
||||||
match self.check_module(&program.main, &mut state) {
|
match self.check_module(&main_id, &mut state) {
|
||||||
Ok(()) => {}
|
Ok(()) => {}
|
||||||
Err(e) => errors.extend(e),
|
Err(e) => errors.extend(e),
|
||||||
};
|
};
|
||||||
|
@ -354,9 +357,7 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
||||||
return Err(errors);
|
return Err(errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
let main_id = program.main.clone();
|
Checker::check_single_main(state.typed_modules.get(&main_id).unwrap()).map_err(
|
||||||
|
|
||||||
Checker::check_single_main(state.typed_modules.get(&program.main).unwrap()).map_err(
|
|
||||||
|inner| {
|
|inner| {
|
||||||
vec![Error {
|
vec![Error {
|
||||||
inner,
|
inner,
|
||||||
|
@ -762,24 +763,40 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
||||||
true => {}
|
true => {}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.functions.insert(
|
// parameters defined on a non-entrypoint function should not be set as private
|
||||||
DeclarationFunctionKey::with_location(
|
match (state.main_id != module_id || declaration.id != "main")
|
||||||
module_id.to_path_buf(),
|
&& funct.arguments.iter().any(|a| a.private)
|
||||||
declaration.id,
|
{
|
||||||
)
|
true => {
|
||||||
.signature(funct.signature.clone()),
|
errors.push(
|
||||||
);
|
ErrorInner {
|
||||||
symbols.push(
|
pos: Some(pos),
|
||||||
TypedFunctionSymbolDeclaration::new(
|
message: "Private argument(s) are only allowed on the entrypoint function".into(),
|
||||||
DeclarationFunctionKey::with_location(
|
}
|
||||||
module_id.to_path_buf(),
|
.in_file(module_id),
|
||||||
declaration.id,
|
);
|
||||||
)
|
}
|
||||||
.signature(funct.signature.clone()),
|
false => {
|
||||||
TypedFunctionSymbol::Here(funct),
|
self.functions.insert(
|
||||||
)
|
DeclarationFunctionKey::with_location(
|
||||||
.into(),
|
module_id.to_path_buf(),
|
||||||
);
|
declaration.id,
|
||||||
|
)
|
||||||
|
.signature(funct.signature.clone()),
|
||||||
|
);
|
||||||
|
symbols.push(
|
||||||
|
TypedFunctionSymbolDeclaration::new(
|
||||||
|
DeclarationFunctionKey::with_location(
|
||||||
|
module_id.to_path_buf(),
|
||||||
|
declaration.id,
|
||||||
|
)
|
||||||
|
.signature(funct.signature.clone()),
|
||||||
|
TypedFunctionSymbol::Here(funct),
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
errors.extend(e.into_iter().map(|inner| inner.in_file(module_id)));
|
errors.extend(e.into_iter().map(|inner| inner.in_file(module_id)));
|
||||||
|
|
Loading…
Reference in a new issue