From 636d829c124afd1e014474a69e0d2ac425f17bd2 Mon Sep 17 00:00:00 2001 From: Jake Fecher Date: Mon, 15 Jul 2024 13:12:57 -0500 Subject: [PATCH 1/2] Error on empty function bodies --- .../src/hir/comptime/interpreter.rs | 6 +++++- compiler/noirc_frontend/src/hir_def/expr.rs | 7 ------- .../noirc_frontend/src/hir_def/function.rs | 18 +++++++++++------- compiler/noirc_frontend/src/node_interner.rs | 14 ++------------ 4 files changed, 18 insertions(+), 27 deletions(-) diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter.rs index 02714f77605..c1f69cb1e0a 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter.rs @@ -129,7 +129,11 @@ impl<'a> Interpreter<'a> { self.define_pattern(parameter, typ, argument, arg_location)?; } - let function_body = self.interner.function(&function).as_expr(); + let function_body = self.interner.function(&function).try_as_expr().ok_or_else(|| { + let function = self.interner.function_name(&function).to_owned(); + InterpreterError::NonComptimeFnCallInSameCrate { function, location } + })?; + let result = self.evaluate(function_body)?; self.exit_function(previous_state); diff --git a/compiler/noirc_frontend/src/hir_def/expr.rs b/compiler/noirc_frontend/src/hir_def/expr.rs index ab2344746d1..d498f2e1cfc 100644 --- a/compiler/noirc_frontend/src/hir_def/expr.rs +++ b/compiler/noirc_frontend/src/hir_def/expr.rs @@ -40,13 +40,6 @@ pub enum HirExpression { Error, } -impl HirExpression { - /// Returns an empty block expression - pub const fn empty_block() -> HirExpression { - HirExpression::Block(HirBlockExpression { statements: vec![] }) - } -} - /// Corresponds to a variable in the source code #[derive(Debug, Clone)] pub struct HirIdent { diff --git a/compiler/noirc_frontend/src/hir_def/function.rs b/compiler/noirc_frontend/src/hir_def/function.rs index e666f996231..dc563a5f65f 100644 --- a/compiler/noirc_frontend/src/hir_def/function.rs +++ b/compiler/noirc_frontend/src/hir_def/function.rs @@ -10,26 +10,30 @@ use crate::macros_api::{BlockExpression, StructId}; use crate::node_interner::{ExprId, NodeInterner, TraitImplId}; use crate::{ResolvedGeneric, Type}; -/// A Hir function is a block expression -/// with a list of statements +/// A Hir function is a block expression with a list of statements. +/// If the function has yet to be resolved, the body starts off empty (None). #[derive(Debug, Clone)] -pub struct HirFunction(ExprId); +pub struct HirFunction(Option); impl HirFunction { pub fn empty() -> HirFunction { - HirFunction(ExprId::empty_block_id()) + HirFunction(None) } pub const fn unchecked_from_expr(expr_id: ExprId) -> HirFunction { - HirFunction(expr_id) + HirFunction(Some(expr_id)) } - pub const fn as_expr(&self) -> ExprId { + pub fn as_expr(&self) -> ExprId { + self.0.expect("Function has yet to be elaborated, cannot get an ExprId of its body!") + } + + pub fn try_as_expr(&self) -> Option { self.0 } pub fn block(&self, interner: &NodeInterner) -> HirBlockExpression { - match interner.expression(&self.0) { + match interner.expression(&self.as_expr()) { HirExpression::Block(block_expr) => block_expr, _ => unreachable!("ice: functions can only be block expressions"), } diff --git a/compiler/noirc_frontend/src/node_interner.rs b/compiler/noirc_frontend/src/node_interner.rs index e534f1bab29..1cbb33d09e9 100644 --- a/compiler/noirc_frontend/src/node_interner.rs +++ b/compiler/noirc_frontend/src/node_interner.rs @@ -386,11 +386,6 @@ impl StmtId { #[derive(Debug, Eq, PartialEq, Hash, Copy, Clone, PartialOrd, Ord)] pub struct ExprId(Index); -impl ExprId { - pub fn empty_block_id() -> ExprId { - ExprId(Index::unsafe_zeroed()) - } -} #[derive(Debug, Eq, PartialEq, Hash, Copy, Clone)] pub struct FuncId(Index); @@ -558,7 +553,7 @@ pub struct QuotedTypeId(noirc_arena::Index); impl Default for NodeInterner { fn default() -> Self { - let mut interner = NodeInterner { + NodeInterner { nodes: Arena::default(), func_meta: HashMap::new(), function_definition_ids: HashMap::new(), @@ -598,12 +593,7 @@ impl Default for NodeInterner { reference_graph: petgraph::graph::DiGraph::new(), reference_graph_indices: HashMap::new(), reference_modules: HashMap::new(), - }; - - // An empty block expression is used often, we add this into the `node` on startup - let expr_id = interner.push_expr(HirExpression::empty_block()); - assert_eq!(expr_id, ExprId::empty_block_id()); - interner + } } } From 9815426b994414e7f64c1a43d4ee77166fa75d27 Mon Sep 17 00:00:00 2001 From: Jake Fecher Date: Mon, 15 Jul 2024 14:58:21 -0500 Subject: [PATCH 2/2] Fix legacy code --- .../noirc_frontend/src/hir/comptime/scan.rs | 9 ++- .../noirc_frontend/src/hir/type_check/mod.rs | 76 ++++++++++--------- 2 files changed, 45 insertions(+), 40 deletions(-) diff --git a/compiler/noirc_frontend/src/hir/comptime/scan.rs b/compiler/noirc_frontend/src/hir/comptime/scan.rs index f9cc54ef9e4..2ce22ab51e3 100644 --- a/compiler/noirc_frontend/src/hir/comptime/scan.rs +++ b/compiler/noirc_frontend/src/hir/comptime/scan.rs @@ -43,11 +43,12 @@ impl<'interner> Interpreter<'interner> { return Ok(()); } - let function = self.interner.function(&function); + if let Some(function) = self.interner.function(&function).try_as_expr() { + let state = self.enter_function(); + self.scan_expression(function)?; + self.exit_function(state); + } - let state = self.enter_function(); - self.scan_expression(function.as_expr())?; - self.exit_function(state); Ok(()) } diff --git a/compiler/noirc_frontend/src/hir/type_check/mod.rs b/compiler/noirc_frontend/src/hir/type_check/mod.rs index 57125e1e2dd..bbbd5b334c4 100644 --- a/compiler/noirc_frontend/src/hir/type_check/mod.rs +++ b/compiler/noirc_frontend/src/hir/type_check/mod.rs @@ -51,7 +51,7 @@ pub fn type_check_func(interner: &mut NodeInterner, func_id: FuncId) -> Vec Vec