diff --git a/compiler/noirc_frontend/src/hir_def/types/unification.rs b/compiler/noirc_frontend/src/hir_def/types/unification.rs index 854b63d13b7..a451fdfdbba 100644 --- a/compiler/noirc_frontend/src/hir_def/types/unification.rs +++ b/compiler/noirc_frontend/src/hir_def/types/unification.rs @@ -99,13 +99,6 @@ impl Type { ) -> Result<(), UnificationError> { use Type::*; - // If the two types are exactly the same then they trivially unify. - // This check avoids potentially unifying very complex types (usually infix - // expressions) when they are the same. - if self == other { - return Ok(()); - } - let lhs = self.follow_bindings_shallow(); let rhs = other.follow_bindings_shallow(); @@ -213,14 +206,14 @@ impl Type { } ( - NamedGeneric(types::NamedGeneric { type_var: binding_a, name: name_a, .. }), - NamedGeneric(types::NamedGeneric { type_var: binding_b, name: name_b, .. }), + NamedGeneric(types::NamedGeneric { type_var: binding_a, .. }), + NamedGeneric(types::NamedGeneric { type_var: binding_b, .. }), ) => { // Bound NamedGenerics are caught by the check above assert!(binding_a.borrow().is_unbound()); assert!(binding_b.borrow().is_unbound()); - if name_a == name_b { + if binding_a.0 == binding_b.0 { binding_a.kind().unify(&binding_b.kind()) } else { Err(UnificationError) 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 aa1e655dbf9..d081a575135 100644 --- a/compiler/noirc_frontend/src/tests/traits/trait_associated_items.rs +++ b/compiler/noirc_frontend/src/tests/traits/trait_associated_items.rs @@ -538,3 +538,31 @@ fn associated_and_type_mismatch_across_traits() { "#; check_errors(src); } + +#[test] +fn associated_mismatch_with_identical_names() { + // Error message is confusing here but it is an improvement over no error + let src = r#" + pub mod one { + pub trait Eggs { + type Item; + fn give() -> Self::Item; + } + } + + pub mod two { + pub trait Eggs { + type Item; + fn take(eggs: Self::Item); + } + } + + pub fn mix() { + T::take(T::give()); + ^^^^^^^^^ Expected type ::Item, found type ::Item + } + + fn main() {} + "#; + check_errors(src); +}