From 3d39196040aa01e64c8a7fe989e2979a5de80023 Mon Sep 17 00:00:00 2001 From: jfecher Date: Tue, 10 Sep 2024 09:19:41 -0500 Subject: [PATCH] fix: Error when comptime types are used in runtime code (#5987) # Description ## Problem\* Resolves https://github.com/noir-lang/noir/issues/5983 ## Summary\* Errors when a comptime-only type is used in runtime code. Currently this is just the various quoted types but in the future would also include user-defined `comptime` structs. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- .../noirc_frontend/src/elaborator/types.rs | 10 +- .../src/hir/resolution/errors.rs | 9 ++ .../src/monomorphization/errors.rs | 7 ++ .../src/monomorphization/mod.rs | 5 +- compiler/noirc_frontend/src/tests.rs | 11 +++ noir_stdlib/src/meta/expr.nr | 98 +++++++++---------- noir_stdlib/src/meta/format_string.nr | 2 +- noir_stdlib/src/meta/function_def.nr | 26 ++--- noir_stdlib/src/meta/module.nr | 10 +- noir_stdlib/src/meta/quoted.nr | 14 +-- noir_stdlib/src/meta/struct_def.nr | 18 ++-- noir_stdlib/src/meta/trait_constraint.nr | 8 +- noir_stdlib/src/meta/trait_def.nr | 10 +- noir_stdlib/src/meta/trait_impl.nr | 4 +- noir_stdlib/src/meta/typ.nr | 28 +++--- noir_stdlib/src/meta/typed_expr.nr | 2 +- noir_stdlib/src/meta/unresolved_type.nr | 2 +- .../comptime_fmt_strings/src/main.nr | 2 +- .../comptime_function_definition/src/main.nr | 2 +- 19 files changed, 153 insertions(+), 115 deletions(-) diff --git a/compiler/noirc_frontend/src/elaborator/types.rs b/compiler/noirc_frontend/src/elaborator/types.rs index 39ef4e0bb8e..46c779dc4ff 100644 --- a/compiler/noirc_frontend/src/elaborator/types.rs +++ b/compiler/noirc_frontend/src/elaborator/types.rs @@ -118,7 +118,15 @@ impl<'context> Elaborator<'context> { let fields = self.resolve_type_inner(*fields, kind); Type::FmtString(Box::new(resolved_size), Box::new(fields)) } - Quoted(quoted) => Type::Quoted(quoted), + Quoted(quoted) => { + let in_function = matches!(self.current_item, Some(DependencyId::Function(_))); + if in_function && !self.in_comptime_context() { + let span = typ.span; + let typ = quoted.to_string(); + self.push_err(ResolverError::ComptimeTypeInRuntimeCode { span, typ }); + } + Type::Quoted(quoted) + } Unit => Type::Unit, Unspecified => { let span = typ.span; diff --git a/compiler/noirc_frontend/src/hir/resolution/errors.rs b/compiler/noirc_frontend/src/hir/resolution/errors.rs index 5abc94b89a2..ec22c8f1986 100644 --- a/compiler/noirc_frontend/src/hir/resolution/errors.rs +++ b/compiler/noirc_frontend/src/hir/resolution/errors.rs @@ -126,6 +126,8 @@ pub enum ResolverError { OverflowInType { lhs: u32, op: crate::BinaryTypeOperator, rhs: u32, span: Span }, #[error("`quote` cannot be used in runtime code")] QuoteInRuntimeCode { span: Span }, + #[error("Comptime-only type `{typ}` cannot be used in runtime code")] + ComptimeTypeInRuntimeCode { typ: String, span: Span }, } impl ResolverError { @@ -513,6 +515,13 @@ impl<'a> From<&'a ResolverError> for Diagnostic { *span, ) }, + ResolverError::ComptimeTypeInRuntimeCode { typ, span } => { + Diagnostic::simple_error( + format!("Comptime-only type `{typ}` cannot be used in runtime code"), + "Comptime-only type used here".to_string(), + *span, + ) + }, } } } diff --git a/compiler/noirc_frontend/src/monomorphization/errors.rs b/compiler/noirc_frontend/src/monomorphization/errors.rs index 66db72eef55..7f4172017e2 100644 --- a/compiler/noirc_frontend/src/monomorphization/errors.rs +++ b/compiler/noirc_frontend/src/monomorphization/errors.rs @@ -9,6 +9,7 @@ pub enum MonomorphizationError { InternalError { message: &'static str, location: Location }, InterpreterError(InterpreterError), ComptimeFnInRuntimeCode { name: String, location: Location }, + ComptimeTypeInRuntimeCode { typ: String, location: Location }, } impl MonomorphizationError { @@ -17,6 +18,7 @@ impl MonomorphizationError { MonomorphizationError::UnknownArrayLength { location, .. } | MonomorphizationError::InternalError { location, .. } | MonomorphizationError::ComptimeFnInRuntimeCode { location, .. } + | MonomorphizationError::ComptimeTypeInRuntimeCode { location, .. } | MonomorphizationError::NoDefaultType { location, .. } => *location, MonomorphizationError::InterpreterError(error) => error.get_location(), } @@ -51,6 +53,11 @@ impl MonomorphizationError { "Comptime functions must be in a comptime block to be called".into(); return CustomDiagnostic::simple_error(message, secondary, location.span); } + MonomorphizationError::ComptimeTypeInRuntimeCode { typ, location } => { + let message = format!("Comptime-only type `{typ}` used in runtime code"); + let secondary = "Comptime type used here".into(); + return CustomDiagnostic::simple_error(message, secondary, location.span); + } }; let location = self.location(); diff --git a/compiler/noirc_frontend/src/monomorphization/mod.rs b/compiler/noirc_frontend/src/monomorphization/mod.rs index 9357cc65c14..fd06a2b04a8 100644 --- a/compiler/noirc_frontend/src/monomorphization/mod.rs +++ b/compiler/noirc_frontend/src/monomorphization/mod.rs @@ -1056,7 +1056,10 @@ impl<'interner> Monomorphizer<'interner> { let message = "Unexpected Type::Error found during monomorphization"; return Err(MonomorphizationError::InternalError { message, location }); } - HirType::Quoted(_) => unreachable!("Tried to translate Code type into runtime code"), + HirType::Quoted(typ) => { + let typ = typ.to_string(); + return Err(MonomorphizationError::ComptimeTypeInRuntimeCode { typ, location }); + } }) } diff --git a/compiler/noirc_frontend/src/tests.rs b/compiler/noirc_frontend/src/tests.rs index 64c9b7471b4..414bfa5fa5b 100644 --- a/compiler/noirc_frontend/src/tests.rs +++ b/compiler/noirc_frontend/src/tests.rs @@ -3451,3 +3451,14 @@ fn constrained_reference_to_unconstrained() { panic!("Expected an error about passing a constrained reference to unconstrained"); }; } + +#[test] +fn comptime_type_in_runtime_code() { + let source = "pub fn foo(_f: FunctionDefinition) {}"; + let errors = get_program_errors(source); + assert_eq!(errors.len(), 1); + assert!(matches!( + errors[0].0, + CompilationError::ResolverError(ResolverError::ComptimeTypeInRuntimeCode { .. }) + )); +} diff --git a/noir_stdlib/src/meta/expr.nr b/noir_stdlib/src/meta/expr.nr index 642dbecc36b..72e1a88cea8 100644 --- a/noir_stdlib/src/meta/expr.nr +++ b/noir_stdlib/src/meta/expr.nr @@ -5,129 +5,129 @@ use crate::meta::op::BinaryOp; impl Expr { #[builtin(expr_as_array)] // docs:start:as_array - fn as_array(self) -> Option<[Expr]> {} + comptime fn as_array(self) -> Option<[Expr]> {} // docs:end:as_array #[builtin(expr_as_assert)] // docs:start:as_assert - fn as_assert(self) -> Option<(Expr, Option)> {} + comptime fn as_assert(self) -> Option<(Expr, Option)> {} // docs:end:as_assert #[builtin(expr_as_assert_eq)] // docs:start:as_assert_eq - fn as_assert_eq(self) -> Option<(Expr, Expr, Option)> {} + comptime fn as_assert_eq(self) -> Option<(Expr, Expr, Option)> {} // docs:end:as_assert_eq #[builtin(expr_as_assign)] // docs:start:as_assign - fn as_assign(self) -> Option<(Expr, Expr)> {} + comptime fn as_assign(self) -> Option<(Expr, Expr)> {} // docs:end:as_assign #[builtin(expr_as_integer)] // docs:start:as_integer - fn as_integer(self) -> Option<(Field, bool)> {} + comptime fn as_integer(self) -> Option<(Field, bool)> {} // docs:end:as_integer #[builtin(expr_as_binary_op)] // docs:start:as_binary_op - fn as_binary_op(self) -> Option<(Expr, BinaryOp, Expr)> {} + comptime fn as_binary_op(self) -> Option<(Expr, BinaryOp, Expr)> {} // docs:end:as_binary_op #[builtin(expr_as_block)] // docs:start:as_block - fn as_block(self) -> Option<[Expr]> {} + comptime fn as_block(self) -> Option<[Expr]> {} // docs:end:as_block #[builtin(expr_as_bool)] // docs:start:as_bool - fn as_bool(self) -> Option {} + comptime fn as_bool(self) -> Option {} // docs:end:as_bool #[builtin(expr_as_cast)] - fn as_cast(self) -> Option<(Expr, UnresolvedType)> {} + comptime fn as_cast(self) -> Option<(Expr, UnresolvedType)> {} #[builtin(expr_as_comptime)] // docs:start:as_comptime - fn as_comptime(self) -> Option<[Expr]> {} + comptime fn as_comptime(self) -> Option<[Expr]> {} // docs:end:as_comptime #[builtin(expr_as_function_call)] // docs:start:as_function_call - fn as_function_call(self) -> Option<(Expr, [Expr])> {} + comptime fn as_function_call(self) -> Option<(Expr, [Expr])> {} // docs:end:as_function_call #[builtin(expr_as_if)] // docs:start:as_if - fn as_if(self) -> Option<(Expr, Expr, Option)> {} + comptime fn as_if(self) -> Option<(Expr, Expr, Option)> {} // docs:end:as_if #[builtin(expr_as_index)] // docs:start:as_index - fn as_index(self) -> Option<(Expr, Expr)> {} + comptime fn as_index(self) -> Option<(Expr, Expr)> {} // docs:end:as_index #[builtin(expr_as_let)] // docs:start:as_let - fn as_let(self) -> Option<(Expr, Option, Expr)> {} + comptime fn as_let(self) -> Option<(Expr, Option, Expr)> {} // docs:end:as_let #[builtin(expr_as_member_access)] // docs:start:as_member_access - fn as_member_access(self) -> Option<(Expr, Quoted)> {} + comptime fn as_member_access(self) -> Option<(Expr, Quoted)> {} // docs:end:as_member_access #[builtin(expr_as_method_call)] // docs:start:as_method_call - fn as_method_call(self) -> Option<(Expr, Quoted, [UnresolvedType], [Expr])> {} + comptime fn as_method_call(self) -> Option<(Expr, Quoted, [UnresolvedType], [Expr])> {} // docs:end:as_method_call #[builtin(expr_as_repeated_element_array)] // docs:start:as_repeated_element_array - fn as_repeated_element_array(self) -> Option<(Expr, Expr)> {} + comptime fn as_repeated_element_array(self) -> Option<(Expr, Expr)> {} // docs:end:as_repeated_element_array #[builtin(expr_as_repeated_element_slice)] // docs:start:as_repeated_element_slice - fn as_repeated_element_slice(self) -> Option<(Expr, Expr)> {} + comptime fn as_repeated_element_slice(self) -> Option<(Expr, Expr)> {} // docs:end:as_repeated_element_slice #[builtin(expr_as_slice)] // docs:start:as_slice - fn as_slice(self) -> Option<[Expr]> {} + comptime fn as_slice(self) -> Option<[Expr]> {} // docs:end:as_slice #[builtin(expr_as_tuple)] // docs:start:as_tuple - fn as_tuple(self) -> Option<[Expr]> {} + comptime fn as_tuple(self) -> Option<[Expr]> {} // docs:end:as_tuple #[builtin(expr_as_unary_op)] // docs:start:as_unary_op - fn as_unary_op(self) -> Option<(UnaryOp, Expr)> {} + comptime fn as_unary_op(self) -> Option<(UnaryOp, Expr)> {} // docs:end:as_unary_op #[builtin(expr_as_unsafe)] // docs:start:as_unsafe - fn as_unsafe(self) -> Option<[Expr]> {} + comptime fn as_unsafe(self) -> Option<[Expr]> {} // docs:end:as_unsafe #[builtin(expr_has_semicolon)] // docs:start:has_semicolon - fn has_semicolon(self) -> bool {} + comptime fn has_semicolon(self) -> bool {} // docs:end:has_semicolon #[builtin(expr_is_break)] // docs:start:is_break - fn is_break(self) -> bool {} + comptime fn is_break(self) -> bool {} // docs:end:is_break #[builtin(expr_is_continue)] // docs:start:is_continue - fn is_continue(self) -> bool {} + comptime fn is_continue(self) -> bool {} // docs:end:is_continue // docs:start:modify - fn modify(self, f: fn[Env](Expr) -> Option) -> Expr { + comptime fn modify(self, f: fn[Env](Expr) -> Option) -> Expr { // docs:end:modify let result = modify_array(self, f); let result = result.or_else(|| modify_assert(self, f)); @@ -166,11 +166,11 @@ impl Expr { #[builtin(expr_resolve)] // docs:start:resolve - fn resolve(self, in_function: Option) -> TypedExpr {} + comptime fn resolve(self, in_function: Option) -> TypedExpr {} // docs:end:resolve } -fn modify_array(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { +comptime fn modify_array(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { expr.as_array().map( |exprs: [Expr]| { let exprs = modify_expressions(exprs, f); @@ -179,7 +179,7 @@ fn modify_array(expr: Expr, f: fn[Env](Expr) -> Option) -> Option(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { +comptime fn modify_assert(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { expr.as_assert().map( |expr: (Expr, Option)| { let (predicate, msg) = expr; @@ -190,7 +190,7 @@ fn modify_assert(expr: Expr, f: fn[Env](Expr) -> Option) -> Option(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { +comptime fn modify_assert_eq(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { expr.as_assert_eq().map( |expr: (Expr, Expr, Option)| { let (lhs, rhs, msg) = expr; @@ -202,7 +202,7 @@ fn modify_assert_eq(expr: Expr, f: fn[Env](Expr) -> Option) -> Option ) } -fn modify_assign(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { +comptime fn modify_assign(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { expr.as_assign().map( |expr: (Expr, Expr)| { let (lhs, rhs) = expr; @@ -213,7 +213,7 @@ fn modify_assign(expr: Expr, f: fn[Env](Expr) -> Option) -> Option(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { +comptime fn modify_binary_op(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { expr.as_binary_op().map( |expr: (Expr, BinaryOp, Expr)| { let (lhs, op, rhs) = expr; @@ -224,7 +224,7 @@ fn modify_binary_op(expr: Expr, f: fn[Env](Expr) -> Option) -> Option ) } -fn modify_block(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { +comptime fn modify_block(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { expr.as_block().map( |exprs: [Expr]| { let exprs = modify_expressions(exprs, f); @@ -233,7 +233,7 @@ fn modify_block(expr: Expr, f: fn[Env](Expr) -> Option) -> Option(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { +comptime fn modify_cast(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { expr.as_cast().map( |expr: (Expr, UnresolvedType)| { let (expr, typ) = expr; @@ -243,7 +243,7 @@ fn modify_cast(expr: Expr, f: fn[Env](Expr) -> Option) -> Option(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { +comptime fn modify_comptime(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { expr.as_comptime().map( |exprs: [Expr]| { let exprs = exprs.map(|expr: Expr| expr.modify(f)); @@ -252,7 +252,7 @@ fn modify_comptime(expr: Expr, f: fn[Env](Expr) -> Option) -> Option< ) } -fn modify_function_call(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { +comptime fn modify_function_call(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { expr.as_function_call().map( |expr: (Expr, [Expr])| { let (function, arguments) = expr; @@ -263,7 +263,7 @@ fn modify_function_call(expr: Expr, f: fn[Env](Expr) -> Option) -> Op ) } -fn modify_if(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { +comptime fn modify_if(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { expr.as_if().map( |expr: (Expr, Expr, Option)| { let (condition, consequence, alternative) = expr; @@ -275,7 +275,7 @@ fn modify_if(expr: Expr, f: fn[Env](Expr) -> Option) -> Option ) } -fn modify_index(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { +comptime fn modify_index(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { expr.as_index().map( |expr: (Expr, Expr)| { let (object, index) = expr; @@ -286,7 +286,7 @@ fn modify_index(expr: Expr, f: fn[Env](Expr) -> Option) -> Option(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { +comptime fn modify_let(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { expr.as_let().map( |expr: (Expr, Option, Expr)| { let (pattern, typ, expr) = expr; @@ -297,7 +297,7 @@ fn modify_let(expr: Expr, f: fn[Env](Expr) -> Option) -> Option ) } -fn modify_member_access(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { +comptime fn modify_member_access(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { expr.as_member_access().map( |expr: (Expr, Quoted)| { let (object, name) = expr; @@ -307,7 +307,7 @@ fn modify_member_access(expr: Expr, f: fn[Env](Expr) -> Option) -> Op ) } -fn modify_method_call(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { +comptime fn modify_method_call(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { expr.as_method_call().map( |expr: (Expr, Quoted, [UnresolvedType], [Expr])| { let (object, name, generics, arguments) = expr; @@ -318,7 +318,7 @@ fn modify_method_call(expr: Expr, f: fn[Env](Expr) -> Option) -> Opti ) } -fn modify_repeated_element_array(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { +comptime fn modify_repeated_element_array(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { expr.as_repeated_element_array().map( |expr: (Expr, Expr)| { let (expr, length) = expr; @@ -329,7 +329,7 @@ fn modify_repeated_element_array(expr: Expr, f: fn[Env](Expr) -> Option(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { +comptime fn modify_repeated_element_slice(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { expr.as_repeated_element_slice().map( |expr: (Expr, Expr)| { let (expr, length) = expr; @@ -340,7 +340,7 @@ fn modify_repeated_element_slice(expr: Expr, f: fn[Env](Expr) -> Option(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { +comptime fn modify_slice(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { expr.as_slice().map( |exprs: [Expr]| { let exprs = modify_expressions(exprs, f); @@ -349,7 +349,7 @@ fn modify_slice(expr: Expr, f: fn[Env](Expr) -> Option) -> Option(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { +comptime fn modify_tuple(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { expr.as_tuple().map( |exprs: [Expr]| { let exprs = modify_expressions(exprs, f); @@ -358,7 +358,7 @@ fn modify_tuple(expr: Expr, f: fn[Env](Expr) -> Option) -> Option(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { +comptime fn modify_unary_op(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { expr.as_unary_op().map( |expr: (UnaryOp, Expr)| { let (op, rhs) = expr; @@ -368,7 +368,7 @@ fn modify_unary_op(expr: Expr, f: fn[Env](Expr) -> Option) -> Option< ) } -fn modify_unsafe(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { +comptime fn modify_unsafe(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { expr.as_unsafe().map( |exprs: [Expr]| { let exprs = exprs.map(|expr: Expr| expr.modify(f)); @@ -377,7 +377,7 @@ fn modify_unsafe(expr: Expr, f: fn[Env](Expr) -> Option) -> Option(exprs: [Expr], f: fn[Env](Expr) -> Option) -> [Expr] { +comptime fn modify_expressions(exprs: [Expr], f: fn[Env](Expr) -> Option) -> [Expr] { exprs.map(|expr: Expr| expr.modify(f)) } @@ -498,7 +498,7 @@ comptime fn new_unsafe(exprs: [Expr]) -> Expr { quote { unsafe { $exprs }}.as_expr().unwrap() } -fn join_expressions(exprs: [Expr], separator: Quoted) -> Quoted { +comptime fn join_expressions(exprs: [Expr], separator: Quoted) -> Quoted { exprs.map(|expr: Expr| expr.quoted()).join(separator) } diff --git a/noir_stdlib/src/meta/format_string.nr b/noir_stdlib/src/meta/format_string.nr index 44b69719efe..075a69fdafb 100644 --- a/noir_stdlib/src/meta/format_string.nr +++ b/noir_stdlib/src/meta/format_string.nr @@ -1,6 +1,6 @@ impl fmtstr { #[builtin(fmtstr_quoted_contents)] // docs:start:quoted_contents - fn quoted_contents(self) -> Quoted {} + comptime fn quoted_contents(self) -> Quoted {} // docs:end:quoted_contents } diff --git a/noir_stdlib/src/meta/function_def.nr b/noir_stdlib/src/meta/function_def.nr index 5ce3dbeabff..5d536d60ae1 100644 --- a/noir_stdlib/src/meta/function_def.nr +++ b/noir_stdlib/src/meta/function_def.nr @@ -1,66 +1,66 @@ impl FunctionDefinition { #[builtin(function_def_add_attribute)] // docs:start:add_attribute - fn add_attribute(self, attribute: str) {} + comptime fn add_attribute(self, attribute: str) {} // docs:end:add_attribute #[builtin(function_def_body)] // docs:start:body - fn body(self) -> Expr {} + comptime fn body(self) -> Expr {} // docs:end:body #[builtin(function_def_has_named_attribute)] // docs:start:has_named_attribute - fn has_named_attribute(self, name: Quoted) -> bool {} + comptime fn has_named_attribute(self, name: Quoted) -> bool {} // docs:end:has_named_attribute #[builtin(function_def_is_unconstrained)] // docs:start:is_unconstrained - fn is_unconstrained(self) -> bool {} + comptime fn is_unconstrained(self) -> bool {} // docs:end:is_unconstrained #[builtin(function_def_module)] // docs:start:module - fn module(self) -> Module {} + comptime fn module(self) -> Module {} // docs:end:module #[builtin(function_def_name)] // docs:start:name - fn name(self) -> Quoted {} + comptime fn name(self) -> Quoted {} // docs:end:name #[builtin(function_def_parameters)] // docs:start:parameters - fn parameters(self) -> [(Quoted, Type)] {} + comptime fn parameters(self) -> [(Quoted, Type)] {} // docs:end:parameters #[builtin(function_def_return_type)] // docs:start:return_type - fn return_type(self) -> Type {} + comptime fn return_type(self) -> Type {} // docs:end:return_type #[builtin(function_def_set_body)] // docs:start:set_body - fn set_body(self, body: Expr) {} + comptime fn set_body(self, body: Expr) {} // docs:end:set_body #[builtin(function_def_set_parameters)] // docs:start:set_parameters - fn set_parameters(self, parameters: [(Quoted, Type)]) {} + comptime fn set_parameters(self, parameters: [(Quoted, Type)]) {} // docs:end:set_parameters #[builtin(function_def_set_return_type)] // docs:start:set_return_type - fn set_return_type(self, return_type: Type) {} + comptime fn set_return_type(self, return_type: Type) {} // docs:end:set_return_type #[builtin(function_def_set_return_public)] // docs:start:set_return_public - fn set_return_public(self, public: bool) {} + comptime fn set_return_public(self, public: bool) {} // docs:end:set_return_public #[builtin(function_def_set_unconstrained)] // docs:start:set_unconstrained - fn set_unconstrained(self, value: bool) {} + comptime fn set_unconstrained(self, value: bool) {} // docs:end:set_unconstrained } diff --git a/noir_stdlib/src/meta/module.nr b/noir_stdlib/src/meta/module.nr index bee6612e1bf..6f936bf4c57 100644 --- a/noir_stdlib/src/meta/module.nr +++ b/noir_stdlib/src/meta/module.nr @@ -1,26 +1,26 @@ impl Module { #[builtin(module_add_item)] // docs:start:add_item - fn add_item(self, item: Quoted) {} + comptime fn add_item(self, item: Quoted) {} // docs:end:add_item #[builtin(module_has_named_attribute)] // docs:start:has_named_attribute - fn has_named_attribute(self, name: Quoted) -> bool {} + comptime fn has_named_attribute(self, name: Quoted) -> bool {} // docs:end:has_named_attribute #[builtin(module_is_contract)] // docs:start:is_contract - fn is_contract(self) -> bool {} + comptime fn is_contract(self) -> bool {} // docs:end:is_contract #[builtin(module_functions)] // docs:start:functions - fn functions(self) -> [FunctionDefinition] {} + comptime fn functions(self) -> [FunctionDefinition] {} // docs:end:functions #[builtin(module_name)] // docs:start:name - fn name(self) -> Quoted {} + comptime fn name(self) -> Quoted {} // docs:end:name } diff --git a/noir_stdlib/src/meta/quoted.nr b/noir_stdlib/src/meta/quoted.nr index 3fab43359c1..ff74580ce20 100644 --- a/noir_stdlib/src/meta/quoted.nr +++ b/noir_stdlib/src/meta/quoted.nr @@ -4,36 +4,36 @@ use crate::option::Option; impl Quoted { #[builtin(quoted_as_expr)] // docs:start:as_expr - fn as_expr(self) -> Option {} + comptime fn as_expr(self) -> Option {} // docs:end:as_expr #[builtin(quoted_as_module)] // docs:start:as_module - fn as_module(self) -> Option {} + comptime fn as_module(self) -> Option {} // docs:end:as_module #[builtin(quoted_as_trait_constraint)] // docs:start:as_trait_constraint - fn as_trait_constraint(self) -> TraitConstraint {} + comptime fn as_trait_constraint(self) -> TraitConstraint {} // docs:end:as_trait_constraint #[builtin(quoted_as_type)] // docs:start:as_type - fn as_type(self) -> Type {} + comptime fn as_type(self) -> Type {} // docs:end:as_type #[builtin(quoted_tokens)] // docs:start:tokens - fn tokens(self) -> [Quoted] {} + comptime fn tokens(self) -> [Quoted] {} // docs:end:tokens } impl Eq for Quoted { - fn eq(self, other: Quoted) -> bool { + comptime fn eq(self, other: Quoted) -> bool { quoted_eq(self, other) } } #[builtin(quoted_eq)] -fn quoted_eq(_first: Quoted, _second: Quoted) -> bool {} +comptime fn quoted_eq(_first: Quoted, _second: Quoted) -> bool {} diff --git a/noir_stdlib/src/meta/struct_def.nr b/noir_stdlib/src/meta/struct_def.nr index 5db720b91d3..e3621b3482e 100644 --- a/noir_stdlib/src/meta/struct_def.nr +++ b/noir_stdlib/src/meta/struct_def.nr @@ -1,47 +1,47 @@ impl StructDefinition { #[builtin(struct_def_add_attribute)] // docs:start:add_attribute - fn add_attribute(self, attribute: str) {} + comptime fn add_attribute(self, attribute: str) {} // docs:end:add_attribute #[builtin(struct_def_add_generic)] // docs:start:add_generic - fn add_generic(self, generic_name: str) -> Type {} + comptime fn add_generic(self, generic_name: str) -> Type {} // docs:end:add_generic /// Return a syntactic version of this struct definition as a type. /// For example, `as_type(quote { type Foo { ... } })` would return `Foo` #[builtin(struct_def_as_type)] // docs:start:as_type - fn as_type(self) -> Type {} + comptime fn as_type(self) -> Type {} // docs:end:as_type #[builtin(struct_def_has_named_attribute)] // docs:start:has_named_attribute - fn has_named_attribute(self, name: Quoted) -> bool {} + comptime fn has_named_attribute(self, name: Quoted) -> bool {} // docs:end:has_named_attribute /// Return each generic on this struct. #[builtin(struct_def_generics)] // docs:start:generics - fn generics(self) -> [Type] {} + comptime fn generics(self) -> [Type] {} // docs:end:generics /// Returns (name, type) pairs of each field in this struct. Each type is as-is /// with any generic arguments unchanged. #[builtin(struct_def_fields)] // docs:start:fields - fn fields(self) -> [(Quoted, Type)] {} + comptime fn fields(self) -> [(Quoted, Type)] {} // docs:end:fields #[builtin(struct_def_module)] // docs:start:module - fn module(self) -> Module {} + comptime fn module(self) -> Module {} // docs:end:module #[builtin(struct_def_name)] // docs:start:name - fn name(self) -> Quoted {} + comptime fn name(self) -> Quoted {} // docs:end:name /// Sets the fields of this struct to the given fields list. @@ -50,6 +50,6 @@ impl StructDefinition { /// Each name is expected to be a single identifier. #[builtin(struct_def_set_fields)] // docs:start:set_fields - fn set_fields(self, new_fields: [(Quoted, Type)]) {} + comptime fn set_fields(self, new_fields: [(Quoted, Type)]) {} // docs:end:set_fields } diff --git a/noir_stdlib/src/meta/trait_constraint.nr b/noir_stdlib/src/meta/trait_constraint.nr index f0276608974..b90f0b590d5 100644 --- a/noir_stdlib/src/meta/trait_constraint.nr +++ b/noir_stdlib/src/meta/trait_constraint.nr @@ -2,19 +2,19 @@ use crate::hash::{Hash, Hasher}; use crate::cmp::Eq; impl Eq for TraitConstraint { - fn eq(self, other: Self) -> bool { + comptime fn eq(self, other: Self) -> bool { constraint_eq(self, other) } } impl Hash for TraitConstraint { - fn hash(self, state: &mut H) where H: Hasher { + comptime fn hash(self, state: &mut H) where H: Hasher { state.write(constraint_hash(self)); } } #[builtin(trait_constraint_eq)] -fn constraint_eq(_first: TraitConstraint, _second: TraitConstraint) -> bool {} +comptime fn constraint_eq(_first: TraitConstraint, _second: TraitConstraint) -> bool {} #[builtin(trait_constraint_hash)] -fn constraint_hash(_constraint: TraitConstraint) -> Field {} +comptime fn constraint_hash(_constraint: TraitConstraint) -> Field {} diff --git a/noir_stdlib/src/meta/trait_def.nr b/noir_stdlib/src/meta/trait_def.nr index c26b571240b..51676efbc34 100644 --- a/noir_stdlib/src/meta/trait_def.nr +++ b/noir_stdlib/src/meta/trait_def.nr @@ -4,24 +4,24 @@ use crate::cmp::Eq; impl TraitDefinition { #[builtin(trait_def_as_trait_constraint)] // docs:start:as_trait_constraint - fn as_trait_constraint(_self: Self) -> TraitConstraint {} + comptime fn as_trait_constraint(_self: Self) -> TraitConstraint {} // docs:end:as_trait_constraint } impl Eq for TraitDefinition { - fn eq(self, other: Self) -> bool { + comptime fn eq(self, other: Self) -> bool { trait_def_eq(self, other) } } impl Hash for TraitDefinition { - fn hash(self, state: &mut H) where H: Hasher { + comptime fn hash(self, state: &mut H) where H: Hasher { state.write(trait_def_hash(self)); } } #[builtin(trait_def_eq)] -fn trait_def_eq(_first: TraitDefinition, _second: TraitDefinition) -> bool {} +comptime fn trait_def_eq(_first: TraitDefinition, _second: TraitDefinition) -> bool {} #[builtin(trait_def_hash)] -fn trait_def_hash(_def: TraitDefinition) -> Field {} +comptime fn trait_def_hash(_def: TraitDefinition) -> Field {} diff --git a/noir_stdlib/src/meta/trait_impl.nr b/noir_stdlib/src/meta/trait_impl.nr index 15b02eac6bd..6755a5c2031 100644 --- a/noir_stdlib/src/meta/trait_impl.nr +++ b/noir_stdlib/src/meta/trait_impl.nr @@ -1,11 +1,11 @@ impl TraitImpl { #[builtin(trait_impl_trait_generic_args)] // docs:start:trait_generic_args - fn trait_generic_args(self) -> [Type] {} + comptime fn trait_generic_args(self) -> [Type] {} // docs:end:trait_generic_args #[builtin(trait_impl_methods)] // docs:start:methods - fn methods(self) -> [FunctionDefinition] {} + comptime fn methods(self) -> [FunctionDefinition] {} // docs:end:methods } diff --git a/noir_stdlib/src/meta/typ.nr b/noir_stdlib/src/meta/typ.nr index 71bd6fd7f1c..d692f6e5a7e 100644 --- a/noir_stdlib/src/meta/typ.nr +++ b/noir_stdlib/src/meta/typ.nr @@ -3,71 +3,71 @@ use crate::option::Option; #[builtin(fresh_type_variable)] // docs:start:fresh_type_variable -pub fn fresh_type_variable() -> Type {} +pub comptime fn fresh_type_variable() -> Type {} // docs:end:fresh_type_variable impl Type { #[builtin(type_as_array)] // docs:start:as_array - fn as_array(self) -> Option<(Type, Type)> {} + comptime fn as_array(self) -> Option<(Type, Type)> {} // docs:end:as_array #[builtin(type_as_constant)] // docs:start:as_constant - fn as_constant(self) -> Option {} + comptime fn as_constant(self) -> Option {} // docs:end:as_constant #[builtin(type_as_integer)] // docs:start:as_integer - fn as_integer(self) -> Option<(bool, u8)> {} + comptime fn as_integer(self) -> Option<(bool, u8)> {} // docs:end:as_integer #[builtin(type_as_slice)] // docs:start:as_slice - fn as_slice(self) -> Option {} + comptime fn as_slice(self) -> Option {} // docs:end:as_slice #[builtin(type_as_str)] // docs:start:as_str - fn as_str(self) -> Option {} + comptime fn as_str(self) -> Option {} // docs:end:as_str #[builtin(type_as_struct)] // docs:start:as_struct - fn as_struct(self) -> Option<(StructDefinition, [Type])> {} + comptime fn as_struct(self) -> Option<(StructDefinition, [Type])> {} // docs:end:as_struct #[builtin(type_as_tuple)] // docs:start:as_tuple - fn as_tuple(self) -> Option<[Type]> {} + comptime fn as_tuple(self) -> Option<[Type]> {} // docs:end:as_tuple #[builtin(type_get_trait_impl)] // docs:start:get_trait_impl - fn get_trait_impl(self, constraint: TraitConstraint) -> Option {} + comptime fn get_trait_impl(self, constraint: TraitConstraint) -> Option {} // docs:end:get_trait_impl #[builtin(type_implements)] // docs:start:implements - fn implements(self, constraint: TraitConstraint) -> bool {} + comptime fn implements(self, constraint: TraitConstraint) -> bool {} // docs:end:implements #[builtin(type_is_bool)] // docs:start:is_bool - fn is_bool(self) -> bool {} + comptime fn is_bool(self) -> bool {} // docs:end:is_bool #[builtin(type_is_field)] // docs:start:is_field - fn is_field(self) -> bool {} + comptime fn is_field(self) -> bool {} // docs:end:is_field } impl Eq for Type { - fn eq(self, other: Self) -> bool { + comptime fn eq(self, other: Self) -> bool { type_eq(self, other) } } #[builtin(type_eq)] -fn type_eq(_first: Type, _second: Type) -> bool {} +comptime fn type_eq(_first: Type, _second: Type) -> bool {} diff --git a/noir_stdlib/src/meta/typed_expr.nr b/noir_stdlib/src/meta/typed_expr.nr index 8daede97438..e01c0d3af67 100644 --- a/noir_stdlib/src/meta/typed_expr.nr +++ b/noir_stdlib/src/meta/typed_expr.nr @@ -3,6 +3,6 @@ use crate::option::Option; impl TypedExpr { #[builtin(typed_expr_as_function_definition)] // docs:start:as_function_definition - fn as_function_definition(self) -> Option {} + comptime fn as_function_definition(self) -> Option {} // docs:end:as_function_definition } diff --git a/noir_stdlib/src/meta/unresolved_type.nr b/noir_stdlib/src/meta/unresolved_type.nr index 2589174ed64..f53635414cc 100644 --- a/noir_stdlib/src/meta/unresolved_type.nr +++ b/noir_stdlib/src/meta/unresolved_type.nr @@ -1,6 +1,6 @@ impl UnresolvedType { #[builtin(unresolved_type_is_field)] // docs:start:is_field - fn is_field(self) -> bool {} + comptime fn is_field(self) -> bool {} // docs:end:is_field } diff --git a/test_programs/compile_success_empty/comptime_fmt_strings/src/main.nr b/test_programs/compile_success_empty/comptime_fmt_strings/src/main.nr index 0e2d459a00f..ca337c822d8 100644 --- a/test_programs/compile_success_empty/comptime_fmt_strings/src/main.nr +++ b/test_programs/compile_success_empty/comptime_fmt_strings/src/main.nr @@ -17,7 +17,7 @@ fn main() { call!(glue(quote { hello }, quote { world })); } -fn glue(x: Quoted, y: Quoted) -> Quoted { +comptime fn glue(x: Quoted, y: Quoted) -> Quoted { f"{x}_{y}".quoted_contents() } diff --git a/test_programs/compile_success_empty/comptime_function_definition/src/main.nr b/test_programs/compile_success_empty/comptime_function_definition/src/main.nr index 6bfd8ef9699..e01ff4a71f1 100644 --- a/test_programs/compile_success_empty/comptime_function_definition/src/main.nr +++ b/test_programs/compile_success_empty/comptime_function_definition/src/main.nr @@ -66,7 +66,7 @@ contract some_contract { } } -fn set_pub_return(f: FunctionDefinition) { +comptime fn set_pub_return(f: FunctionDefinition) { f.set_return_public(true); }