Skip to content

Commit 12c0668

Browse files
authored
feat: Allow secret functions to use public parameters (#1051)
* Allow secret functions to use public parameters * Add carve-out for the Unit type for pub return values * Fix contract test
1 parent bc52612 commit 12c0668

File tree

3 files changed

+17
-7
lines changed

3 files changed

+17
-7
lines changed

crates/nargo/tests/test_data/contracts/src/main.nr

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ fn main(x : Field, y : pub Field) {
33
}
44

55
contract Foo {
6-
fn double(x: Field) -> Field { x * 2 }
7-
fn triple(x: Field) -> Field { x * 3 }
6+
fn double(x: Field) -> pub Field { x * 2 }
7+
fn triple(x: Field) -> pub Field { x * 3 }
88
}

crates/noirc_frontend/src/hir/resolution/errors.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ impl From<ResolverError> for Diagnostic {
166166
ident.0.span(),
167167
);
168168

169-
diag.add_note("The `pub` keyword only has effects on arguments to the main function of a program. Thus, adding it to other function parameters can be deceiving and should be removed".to_owned());
169+
diag.add_note("The `pub` keyword only has effects on arguments to the entry-point function of a program. Thus, adding it to other function parameters can be deceiving and should be removed".to_owned());
170170
diag
171171
}
172172
ResolverError::NecessaryPub { ident } => {
@@ -178,7 +178,7 @@ impl From<ResolverError> for Diagnostic {
178178
ident.0.span(),
179179
);
180180

181-
diag.add_note("The `pub` keyword is mandatory for the main function return type because the verifier cannot retrieve private witness and thus the function will not be able to return a 'priv' value".to_owned());
181+
diag.add_note("The `pub` keyword is mandatory for the entry-point function return type because the verifier cannot retrieve private witness and thus the function will not be able to return a 'priv' value".to_owned());
182182
diag
183183
}
184184
ResolverError::ExpectedComptimeVariable { name, span } => Diagnostic::simple_error(

crates/noirc_frontend/src/hir/resolution/resolver.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -601,7 +601,7 @@ impl<'a> Resolver<'a> {
601601
let mut parameter_types = vec![];
602602

603603
for (pattern, typ, visibility) in func.parameters().iter().cloned() {
604-
if func.name() != "main" && visibility == noirc_abi::AbiVisibility::Public {
604+
if visibility == noirc_abi::AbiVisibility::Public && !self.pub_allowed(func) {
605605
self.push_err(ResolverError::UnnecessaryPub { ident: func.name_ident().clone() })
606606
}
607607

@@ -615,8 +615,9 @@ impl<'a> Resolver<'a> {
615615

616616
self.declare_numeric_generics(&parameter_types, &return_type);
617617

618-
if func.name() == "main"
619-
&& *return_type != Type::Unit
618+
// 'pub_allowed' also implies 'pub' is required on return types
619+
if self.pub_allowed(func)
620+
&& return_type.as_ref() != &Type::Unit
620621
&& func.def.return_visibility != noirc_abi::AbiVisibility::Public
621622
{
622623
self.push_err(ResolverError::NecessaryPub { ident: func.name_ident().clone() })
@@ -650,6 +651,15 @@ impl<'a> Resolver<'a> {
650651
}
651652
}
652653

654+
/// True if the 'pub' keyword is allowed on parameters in this function
655+
fn pub_allowed(&self, func: &NoirFunction) -> bool {
656+
if self.in_contract() {
657+
!func.def.is_unconstrained && !func.def.is_open
658+
} else {
659+
func.name() == "main"
660+
}
661+
}
662+
653663
fn handle_function_type(&mut self, func: &NoirFunction) -> Option<ContractFunctionType> {
654664
if func.def.is_open {
655665
if self.in_contract() {

0 commit comments

Comments
 (0)