diff --git a/compiler/noirc_evaluator/src/ssa/opt/loop_invariant.rs b/compiler/noirc_evaluator/src/ssa/opt/loop_invariant.rs index 92f5716a2bc..aec2ad7aef9 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/loop_invariant.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/loop_invariant.rs @@ -2695,7 +2695,7 @@ mod control_dependence { loop_body(): v6 = unchecked_mul v0, v1 v7 = unchecked_mul v6, v0 - call f1() + call f1(v7) v10 = unchecked_add v2, u32 1 jmp loop(v10) exit(): @@ -2722,7 +2722,7 @@ mod control_dependence { v6 = lt v2, v1 jmpif v6 then: b2, else: b3 b2(): - call f1() + call f1(v4) v9 = unchecked_add v2, u32 1 jmp b1(v9) b3(): @@ -2750,7 +2750,7 @@ mod control_dependence { loop_body(): v6 = mul v0, v1 v7 = mul v6, v0 - call f1() + call f1(v7) v10 = unchecked_add v2, u32 1 jmp loop(v10) exit(): @@ -2772,7 +2772,7 @@ mod control_dependence { b0(v0: u32, v1: u32): v3 = mul v0, v1 v4 = mul v3, v0 - call f1() + call f1(v4) jmp b1(u32 0) b1(v2: u32): v8 = lt v2, u32 4 diff --git a/compiler/noirc_evaluator/src/ssa/opt/mem2reg.rs b/compiler/noirc_evaluator/src/ssa/opt/mem2reg.rs index 507ed17c618..680a55180a1 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/mem2reg.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/mem2reg.rs @@ -1112,7 +1112,7 @@ mod tests { jmp b1(v8) } acir(inline) fn foo f1 { - b0(v0: &mut Field): + b0(v0: &mut &mut Field): return } "; diff --git a/compiler/noirc_evaluator/src/ssa/opt/preprocess_fns.rs b/compiler/noirc_evaluator/src/ssa/opt/preprocess_fns.rs index 36e2f238436..b22928706b1 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/preprocess_fns.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/preprocess_fns.rs @@ -92,7 +92,7 @@ mod tests { let src = r#" acir(inline) fn main f0 { b0(): - call f0() + call f0(u32 1, Field 2) return } acir(inline) fn foo f0 { @@ -116,7 +116,7 @@ mod tests { assert_ssa_snapshot!(ssa, @r" acir(inline) fn main f0 { b0(): - call f1() + call f1(u32 1) return } acir(inline) fn foo f1 { diff --git a/compiler/noirc_evaluator/src/ssa/validation/mod.rs b/compiler/noirc_evaluator/src/ssa/validation/mod.rs index 77ef78d3dc6..12b05fe9b0b 100644 --- a/compiler/noirc_evaluator/src/ssa/validation/mod.rs +++ b/compiler/noirc_evaluator/src/ssa/validation/mod.rs @@ -552,6 +552,28 @@ impl<'f> Validator<'f> { } Value::Function(func_id) => { let called_function = &self.ssa.functions[func_id]; + + let parameter_types = called_function.parameter_types(); + assert_eq!( + arguments.len(), + parameter_types.len(), + "Function call to {func_id} expected {} parameters, but got {}", + parameter_types.len(), + arguments.len() + ); + + for (index, (argument, parameter_type)) in + arguments.iter().zip(parameter_types).enumerate() + { + let argument_type = dfg.type_of_value(*argument); + if argument_type != parameter_type { + panic!( + "Argument #{} to {func_id} has type {parameter_type}, but {argument_type} was given", + index + 1, + ); + } + } + if let Some(returns) = called_function.returns() { let instruction_results = dfg.instruction_results(instruction); if instruction_results.len() != returns.len() { @@ -1116,6 +1138,42 @@ mod tests { let _ = Ssa::from_str(src).unwrap(); } + #[test] + #[should_panic(expected = "Function call to f1 expected 1 parameters, but got 0")] + fn call_has_wrong_parameter_count() { + let src = " + acir(inline) fn main f0 { + b0(): + call f1() + return + } + + acir(inline) fn foo f1 { + b0(v0: Field): + return + } + "; + let _ = Ssa::from_str(src).unwrap(); + } + + #[test] + #[should_panic(expected = "Argument #1 to f1 has type Field, but u32 was given")] + fn call_has_wrong_argument_type() { + let src = " + acir(inline) fn main f0 { + b0(v0: u32): + call f1(v0) + return + } + + acir(inline) fn foo f1 { + b0(v0: Field): + return + } + "; + let _ = Ssa::from_str(src).unwrap(); + } + #[test] #[should_panic(expected = "Function call to f1 expected 2 return values, but got 1")] fn call_has_wrong_return_count() { diff --git a/compiler/noirc_frontend/src/monomorphization/debug.rs b/compiler/noirc_frontend/src/monomorphization/debug.rs index a7f9e505e48..06e20424b27 100644 --- a/compiler/noirc_frontend/src/monomorphization/debug.rs +++ b/compiler/noirc_frontend/src/monomorphization/debug.rs @@ -4,9 +4,11 @@ use noirc_errors::Location; use noirc_errors::debug_info::DebugVarId; use noirc_printable_type::PrintableType; +use crate::ast::IntegerBitSize; use crate::debug::{SourceFieldId, SourceVarId}; use crate::hir_def::expr::*; use crate::node_interner::ExprId; +use crate::shared::Signedness; use crate::signed_field::SignedField; use super::ast::{Expression, Ident}; @@ -181,7 +183,8 @@ impl Monomorphizer<'_> { let value = SignedField::positive(var_id.0); let var_id_literal = HirLiteral::Integer(value); let expr_id = self.interner.push_expr(HirExpression::Literal(var_id_literal)); - self.interner.push_expr_type(expr_id, crate::Type::FieldElement); + let u32 = crate::Type::Integer(Signedness::Unsigned, IntegerBitSize::ThirtyTwo); + self.interner.push_expr_type(expr_id, u32); self.interner.push_expr_location(expr_id, *location); expr_id }