Skip to content

Commit 7a85493

Browse files
LHerskindjfecherkevaundray
authored
feat: Adding internal keyword (#1873)
* feat: add internal keyword * chore: remove 👺 * fix: comment cleanup * feat: add `is_internal` to abi * Update crates/noirc_frontend/src/hir/resolution/resolver.rs Co-authored-by: jfecher <jfecher11@gmail.com> * fix: cleanup * fix: is_internal name * Update crates/noirc_driver/src/lib.rs Co-authored-by: jfecher <jfecher11@gmail.com> --------- Co-authored-by: jfecher <jfecher11@gmail.com> Co-authored-by: kevaundray <kevtheappdev@gmail.com>
1 parent fc755b9 commit 7a85493

File tree

12 files changed

+53
-7
lines changed

12 files changed

+53
-7
lines changed

crates/nargo/src/artifacts/contract.rs

+2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ pub struct PreprocessedContractFunction {
2828

2929
pub function_type: ContractFunctionType,
3030

31+
pub is_internal: bool,
32+
3133
pub abi: Abi,
3234

3335
#[serde(

crates/nargo/src/ops/preprocess.rs

+1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ pub fn preprocess_contract_function<B: ProofSystemCompiler>(
5353
Ok(PreprocessedContractFunction {
5454
name: func.name,
5555
function_type: func.function_type,
56+
is_internal: func.is_internal,
5657
abi: func.abi,
5758

5859
bytecode: optimized_bytecode,

crates/nargo_cli/tests/test_data_ssa_refactor/contracts/src/main.nr

+2
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,6 @@ fn main(x : Field, y : pub Field) {
55
contract Foo {
66
fn double(x: Field) -> pub Field { x * 2 }
77
fn triple(x: Field) -> pub Field { x * 3 }
8+
internal fn quadruple(x: Field) -> pub Field { x * 4 }
9+
open internal fn skibbidy(x: Field) -> pub Field { x * 5 }
810
}

crates/noirc_driver/src/contract.rs

+2
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ pub struct ContractFunction {
4141

4242
pub function_type: ContractFunctionType,
4343

44+
pub is_internal: bool,
45+
4446
pub abi: Abi,
4547

4648
#[serde(serialize_with = "serialize_circuit", deserialize_with = "deserialize_circuit")]

crates/noirc_driver/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,7 @@ fn compile_contract(
305305
functions.push(ContractFunction {
306306
name,
307307
function_type,
308+
is_internal: func_meta.is_internal.unwrap_or(false),
308309
abi: function.abi,
309310
bytecode: function.circuit,
310311
});

crates/noirc_frontend/src/ast/expression.rs

+2
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,8 @@ pub struct FunctionDefinition {
328328
/// True if this function was defined with the 'open' keyword
329329
pub is_open: bool,
330330

331+
pub is_internal: bool,
332+
331333
/// True if this function was defined with the 'unconstrained' keyword
332334
pub is_unconstrained: bool,
333335

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

+7
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ pub enum ResolverError {
6464
MutableReferenceToImmutableVariable { variable: String, span: Span },
6565
#[error("Mutable references to array indices are unsupported")]
6666
MutableReferenceToArrayElement { span: Span },
67+
#[error("Function is not defined in a contract yet sets is_internal")]
68+
ContractFunctionInternalInNormalFunction { span: Span },
6769
}
6870

6971
impl ResolverError {
@@ -268,6 +270,11 @@ impl From<ResolverError> for Diagnostic {
268270
ResolverError::MutableReferenceToArrayElement { span } => {
269271
Diagnostic::simple_error("Mutable references to array elements are currently unsupported".into(), "Try storing the element in a fresh variable first".into(), span)
270272
},
273+
ResolverError::ContractFunctionInternalInNormalFunction { span } => Diagnostic::simple_error(
274+
"Only functions defined within contracts can set their functions to be internal".into(),
275+
"Non-contract functions cannot be 'internal'".into(),
276+
span,
277+
),
271278
}
272279
}
273280
}

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

+14
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,7 @@ impl<'a> Resolver<'a> {
652652
kind: func.kind,
653653
attributes,
654654
contract_function_type: self.handle_function_type(func),
655+
is_internal: self.handle_is_function_internal(func),
655656
is_unconstrained: func.def.is_unconstrained,
656657
location,
657658
typ,
@@ -697,6 +698,19 @@ impl<'a> Resolver<'a> {
697698
}
698699
}
699700

701+
fn handle_is_function_internal(&mut self, func: &NoirFunction) -> Option<bool> {
702+
if self.in_contract() {
703+
Some(func.def.is_internal)
704+
} else {
705+
if func.def.is_internal {
706+
self.push_err(ResolverError::ContractFunctionInternalInNormalFunction {
707+
span: func.name_ident().span(),
708+
});
709+
}
710+
None
711+
}
712+
}
713+
700714
fn declare_numeric_generics(&mut self, params: &[Type], return_type: &Type) {
701715
if self.generics.is_empty() {
702716
return;

crates/noirc_frontend/src/hir/type_check/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ mod test {
232232
attributes: None,
233233
location,
234234
contract_function_type: None,
235+
is_internal: None,
235236
is_unconstrained: false,
236237
typ: Type::Function(vec![Type::field(None), Type::field(None)], Box::new(Type::Unit)),
237238
parameters: vec![

crates/noirc_frontend/src/hir_def/function.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -121,10 +121,15 @@ pub struct FuncMeta {
121121
/// Attribute per function.
122122
pub attributes: Option<Attribute>,
123123

124-
/// This function's visibility in its contract.
124+
/// This function's type in its contract.
125125
/// If this function is not in a contract, this is always 'Secret'.
126126
pub contract_function_type: Option<ContractFunctionType>,
127127

128+
/// This function's visibility.
129+
/// If this function is internal can only be called by itself.
130+
/// Will be None if not in contract.
131+
pub is_internal: Option<bool>,
132+
128133
pub is_unconstrained: bool,
129134

130135
pub parameters: Parameters,

crates/noirc_frontend/src/lexer/token.rs

+3
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,7 @@ pub enum Keyword {
431431
Impl,
432432
If,
433433
In,
434+
Internal,
434435
Let,
435436
Mod,
436437
Mut,
@@ -466,6 +467,7 @@ impl fmt::Display for Keyword {
466467
Keyword::Impl => write!(f, "impl"),
467468
Keyword::If => write!(f, "if"),
468469
Keyword::In => write!(f, "in"),
470+
Keyword::Internal => write!(f, "internal"),
469471
Keyword::Let => write!(f, "let"),
470472
Keyword::Mod => write!(f, "mod"),
471473
Keyword::Mut => write!(f, "mut"),
@@ -504,6 +506,7 @@ impl Keyword {
504506
"impl" => Keyword::Impl,
505507
"if" => Keyword::If,
506508
"in" => Keyword::In,
509+
"internal" => Keyword::Internal,
507510
"let" => Keyword::Let,
508511
"mod" => Keyword::Mod,
509512
"mut" => Keyword::Mut,

crates/noirc_frontend/src/parser/parser.rs

+12-6
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,10 @@ fn function_definition(allow_self: bool) -> impl NoirParser<NoirFunction> {
162162
.map(
163163
|(
164164
(
165-
((((attribute, (is_unconstrained, is_open)), name), generics), parameters),
165+
(
166+
(((attribute, (is_unconstrained, is_open, is_internal)), name), generics),
167+
parameters,
168+
),
166169
((return_distinctness, return_visibility), return_type),
167170
),
168171
body,
@@ -172,6 +175,7 @@ fn function_definition(allow_self: bool) -> impl NoirParser<NoirFunction> {
172175
name,
173176
attribute, // XXX: Currently we only have one attribute defined. If more attributes are needed per function, we can make this a vector and make attribute definition more expressive
174177
is_open,
178+
is_internal,
175179
is_unconstrained,
176180
generics,
177181
parameters,
@@ -185,14 +189,16 @@ fn function_definition(allow_self: bool) -> impl NoirParser<NoirFunction> {
185189
)
186190
}
187191

188-
/// function_modifiers: 'unconstrained' 'open' | 'unconstrained' | 'open' | %empty
189-
///
190-
/// returns (is_unconstrained, is_open) for whether each keyword was present
191-
fn function_modifiers() -> impl NoirParser<(bool, bool)> {
192+
/// function_modifiers: 'open internal' | 'internal' | 'unconstrained' | 'open' | %empty
193+
/// returns (is_unconstrained, is_open, is_internal) for whether each keyword was present
194+
fn function_modifiers() -> impl NoirParser<(bool, bool, bool)> {
192195
keyword(Keyword::Unconstrained)
193196
.or_not()
194197
.then(keyword(Keyword::Open).or_not())
195-
.map(|(unconstrained, open)| (unconstrained.is_some(), open.is_some()))
198+
.then(keyword(Keyword::Internal).or_not())
199+
.map(|((unconstrained, open), internal)| {
200+
(unconstrained.is_some(), open.is_some(), internal.is_some())
201+
})
196202
}
197203

198204
/// non_empty_ident_list: ident ',' non_empty_ident_list

0 commit comments

Comments
 (0)