diff --git a/compiler/noirc_evaluator/src/ssa/function_builder/mod.rs b/compiler/noirc_evaluator/src/ssa/function_builder/mod.rs index f810b65d105..aebb47ccf8e 100644 --- a/compiler/noirc_evaluator/src/ssa/function_builder/mod.rs +++ b/compiler/noirc_evaluator/src/ssa/function_builder/mod.rs @@ -442,13 +442,7 @@ impl FunctionBuilder { match self.type_of_value(value) { Type::Numeric(_) => (), Type::Function => (), - Type::Reference(element) => { - if element.contains_an_array() { - let reference = value; - let value = self.insert_load(reference, element.as_ref().clone()); - self.update_array_reference_count(value, increment); - } - } + Type::Reference(_) => (), Type::Array(..) | Type::Slice(..) => { // If there are nested arrays or slices, we wait until ArrayGet // is issued to increment the count of that array. diff --git a/compiler/noirc_frontend/src/tests.rs b/compiler/noirc_frontend/src/tests.rs index 5ce3ec6686c..96a72961ca3 100644 --- a/compiler/noirc_frontend/src/tests.rs +++ b/compiler/noirc_frontend/src/tests.rs @@ -3548,17 +3548,27 @@ fn uses_self_in_import() { } #[test] -fn alias_in_let_pattern() { +fn does_not_error_on_return_values_after_block_expression() { + // Regression test for https://github.com/noir-lang/noir/issues/4372 let src = r#" - struct Foo { x: T } - - type Bar = Foo; + fn case1() -> [Field] { + if true { + } + &[1] + } - fn main() { - let Bar { x } = Foo { x: [0] }; - // This is just to show the compiler knows this is an array. - let _: [Field; 1] = x; + fn case2() -> [u8] { + let mut var: u8 = 1; + { + var += 1; } + &[var] + } + + fn main() { + let _ = case1(); + let _ = case2(); + } "#; assert_no_errors(src); } diff --git a/compiler/noirc_frontend/src/tests/aliases.rs b/compiler/noirc_frontend/src/tests/aliases.rs index 5239abcb366..8d3433299f6 100644 --- a/compiler/noirc_frontend/src/tests/aliases.rs +++ b/compiler/noirc_frontend/src/tests/aliases.rs @@ -31,3 +31,19 @@ fn allows_usage_of_type_alias_as_return_type() { "#; assert_no_errors(src); } + +#[test] +fn alias_in_let_pattern() { + let src = r#" + struct Foo { x: T } + + type Bar = Foo; + + fn main() { + let Bar { x } = Foo { x: [0] }; + // This is just to show the compiler knows this is an array. + let _: [Field; 1] = x; + } + "#; + assert_no_errors(src); +} diff --git a/compiler/noirc_frontend/src/tests/traits.rs b/compiler/noirc_frontend/src/tests/traits.rs index dd6430a94cc..2b5d6c1c8eb 100644 --- a/compiler/noirc_frontend/src/tests/traits.rs +++ b/compiler/noirc_frontend/src/tests/traits.rs @@ -262,6 +262,64 @@ fn errors_if_impl_trait_constraint_is_not_satisfied() { assert_eq!(impl_trait, "Foo"); } +#[test] +// Regression test for https://github.com/noir-lang/noir/issues/6314 +// Baz inherits from a single trait: Foo +fn regression_6314_single_inheritance() { + let src = r#" + trait Foo { + fn foo(self) -> Self; + } + + trait Baz: Foo {} + + impl Baz for T where T: Foo {} + + fn main() { } + "#; + assert_no_errors(src); +} + +#[test] +// Regression test for https://github.com/noir-lang/noir/issues/6314 +// Baz inherits from two traits: Foo and Bar +fn regression_6314_double_inheritance() { + let src = r#" + trait Foo { + fn foo(self) -> Self; + } + + trait Bar { + fn bar(self) -> Self; + } + + trait Baz: Foo + Bar {} + + impl Baz for T where T: Foo + Bar {} + + fn baz(x: T) -> T where T: Baz { + x.foo().bar() + } + + impl Foo for Field { + fn foo(self) -> Self { + self + 1 + } + } + + impl Bar for Field { + fn bar(self) -> Self { + self + 2 + } + } + + fn main() { + assert(0.foo().bar() == baz(0)); + }"#; + + assert_no_errors(src); +} + #[test] fn removes_assumed_parent_traits_after_function_ends() { let src = r#"