diff --git a/compiler/noirc_frontend/src/hir_def/types.rs b/compiler/noirc_frontend/src/hir_def/types.rs index f6732789ece..e6b60fbd50d 100644 --- a/compiler/noirc_frontend/src/hir_def/types.rs +++ b/compiler/noirc_frontend/src/hir_def/types.rs @@ -3446,10 +3446,22 @@ impl PartialEq for Type { } // Two implicitly added unbound named generics are equal ( - NamedGeneric(types::NamedGeneric { type_var: lhs_var, implicit: true, .. }), - NamedGeneric(types::NamedGeneric { type_var: rhs_var, implicit: true, .. }), + NamedGeneric(types::NamedGeneric { + type_var: lhs_var, + implicit: true, + name: lhs_name, + .. + }), + NamedGeneric(types::NamedGeneric { + type_var: rhs_var, + implicit: true, + name: rhs_name, + .. + }), ) => { - lhs_var.borrow().is_unbound() && rhs_var.borrow().is_unbound() + lhs_var.borrow().is_unbound() + && rhs_var.borrow().is_unbound() + && lhs_name == rhs_name || lhs_var.id() == rhs_var.id() } // Special case: we consider unbound named generics and type variables to be equal to each diff --git a/compiler/noirc_frontend/src/tests/traits/trait_associated_items.rs b/compiler/noirc_frontend/src/tests/traits/trait_associated_items.rs index 26ee77132ec..aa1e655dbf9 100644 --- a/compiler/noirc_frontend/src/tests/traits/trait_associated_items.rs +++ b/compiler/noirc_frontend/src/tests/traits/trait_associated_items.rs @@ -517,3 +517,24 @@ fn associated_and_generic_type_share_name() { "#; check_errors(src); } + +#[test] +fn associated_and_type_mismatch_across_traits() { + let src = r#" + pub trait Spam { + type Item; + fn give_spam() -> Self::Item; + } + + pub trait Eggs { + type Item; + fn take_eggs(eggs: Self::Item); + } + + pub fn mix() { + B::take_eggs(A::give_spam()); + ^^^^^^^^^^^^^^ Expected type ::Item, found type ::Item + } + "#; + check_errors(src); +}