diff --git a/compiler/noirc_frontend/src/monomorphization/errors.rs b/compiler/noirc_frontend/src/monomorphization/errors.rs index ce8ef3572e6..66db72eef55 100644 --- a/compiler/noirc_frontend/src/monomorphization/errors.rs +++ b/compiler/noirc_frontend/src/monomorphization/errors.rs @@ -8,6 +8,7 @@ pub enum MonomorphizationError { NoDefaultType { location: Location }, InternalError { message: &'static str, location: Location }, InterpreterError(InterpreterError), + ComptimeFnInRuntimeCode { name: String, location: Location }, } impl MonomorphizationError { @@ -15,6 +16,7 @@ impl MonomorphizationError { match self { MonomorphizationError::UnknownArrayLength { location, .. } | MonomorphizationError::InternalError { location, .. } + | MonomorphizationError::ComptimeFnInRuntimeCode { location, .. } | MonomorphizationError::NoDefaultType { location, .. } => *location, MonomorphizationError::InterpreterError(error) => error.get_location(), } @@ -43,6 +45,12 @@ impl MonomorphizationError { } MonomorphizationError::InterpreterError(error) => return error.into(), MonomorphizationError::InternalError { message, .. } => message.to_string(), + MonomorphizationError::ComptimeFnInRuntimeCode { name, location } => { + let message = format!("Comptime function {name} used in runtime code"); + let secondary = + "Comptime functions must be in a comptime block to be called".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 87b55540bbd..9357cc65c14 100644 --- a/compiler/noirc_frontend/src/monomorphization/mod.rs +++ b/compiler/noirc_frontend/src/monomorphization/mod.rs @@ -133,7 +133,7 @@ pub fn monomorphize_debug( let impl_bindings = perform_impl_bindings(interner, trait_method, next_fn_id, location) .map_err(MonomorphizationError::InterpreterError)?; - monomorphizer.function(next_fn_id, new_id)?; + monomorphizer.function(next_fn_id, new_id, location)?; undo_instantiation_bindings(impl_bindings); undo_instantiation_bindings(bindings); } @@ -278,7 +278,10 @@ impl<'interner> Monomorphizer<'interner> { ) -> Result { let new_main_id = self.next_function_id(); assert_eq!(new_main_id, Program::main_id()); - self.function(main_id, new_main_id)?; + + let location = self.interner.function_meta(&main_id).location; + self.function(main_id, new_main_id, location)?; + self.return_location = self.interner.function(&main_id).block(self.interner).statements().last().and_then( |x| match self.interner.statement(x) { @@ -294,6 +297,7 @@ impl<'interner> Monomorphizer<'interner> { &mut self, f: node_interner::FuncId, id: FuncId, + location: Location, ) -> Result<(), MonomorphizationError> { if let Some((self_type, trait_id)) = self.interner.get_function_trait(&f) { let the_trait = self.interner.get_trait(trait_id); @@ -313,6 +317,10 @@ impl<'interner> Monomorphizer<'interner> { let modifiers = self.interner.function_modifiers(&f); let name = self.interner.function_name(&f).to_owned(); + if modifiers.is_comptime { + return Err(MonomorphizationError::ComptimeFnInRuntimeCode { name, location }); + } + let body_expr_id = self.interner.function(&f).as_expr(); let body_return_type = self.interner.id_type(body_expr_id); let return_type = match meta.return_type() {