diff --git a/compiler/noirc_frontend/src/hir/type_check/expr.rs b/compiler/noirc_frontend/src/hir/type_check/expr.rs index b78f07c88f2..7b854e58fca 100644 --- a/compiler/noirc_frontend/src/hir/type_check/expr.rs +++ b/compiler/noirc_frontend/src/hir/type_check/expr.rs @@ -326,7 +326,10 @@ impl<'interner> TypeChecker<'interner> { assert_eq!(the_trait.generics.len(), constraint.trait_generics.len()); for (param, arg) in the_trait.generics.iter().zip(&constraint.trait_generics) { - bindings.insert(param.id(), (param.clone(), arg.clone())); + // Avoid binding t = t + if !arg.occurs(param.id()) { + bindings.insert(param.id(), (param.clone(), arg.clone())); + } } } diff --git a/compiler/noirc_frontend/src/hir_def/types.rs b/compiler/noirc_frontend/src/hir_def/types.rs index e105da1ccf0..b70aa43701c 100644 --- a/compiler/noirc_frontend/src/hir_def/types.rs +++ b/compiler/noirc_frontend/src/hir_def/types.rs @@ -1558,7 +1558,7 @@ impl Type { } /// True if the given TypeVariableId is free anywhere within self - fn occurs(&self, target_id: TypeVariableId) -> bool { + pub fn occurs(&self, target_id: TypeVariableId) -> bool { match self { Type::Array(len, elem) => len.occurs(target_id) || elem.occurs(target_id), Type::String(len) => len.occurs(target_id), diff --git a/test_programs/execution_success/regression_4436/Nargo.toml b/test_programs/execution_success/regression_4436/Nargo.toml new file mode 100644 index 00000000000..0904d858596 --- /dev/null +++ b/test_programs/execution_success/regression_4436/Nargo.toml @@ -0,0 +1,5 @@ +[package] +name = "regression_4436" +type = "bin" +authors = [""] +compiler_version = ">=0.22.0" diff --git a/test_programs/execution_success/regression_4436/src/main.nr b/test_programs/execution_success/regression_4436/src/main.nr new file mode 100644 index 00000000000..834ea3250cc --- /dev/null +++ b/test_programs/execution_success/regression_4436/src/main.nr @@ -0,0 +1,31 @@ +trait LibTrait { + fn broadcast(); + fn get_constant() -> Field; +} + +global STRUCT_A_LEN: Field = 3; +global STRUCT_B_LEN: Field = 5; + +struct StructA; +struct StructB; + +impl LibTrait for StructA { + fn broadcast() { + Self::get_constant(); + } + + fn get_constant() -> Field { + 1 + } +} +impl LibTrait for StructB { + fn broadcast() { + Self::get_constant(); + } + + fn get_constant() -> Field { + 1 + } +} + +fn main() {}