Skip to content

Commit 02f0421

Browse files
committed
Turn TypeVariable into NamedGeneric in lookup_trait_implementation_helper
1 parent d8394f3 commit 02f0421

File tree

2 files changed

+20
-8
lines changed

2 files changed

+20
-8
lines changed

compiler/noirc_frontend/src/node_interner/trait_impl.rs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use iter_extended::vecmap;
22
use noirc_errors::Location;
33
use rustc_hash::FxHashMap as HashMap;
4-
use std::collections::HashSet;
4+
use std::{collections::HashSet, rc::Rc};
55

66
use crate::{
77
GenericTypeVars, Shared, Type, TypeBindings,
@@ -316,17 +316,31 @@ impl NodeInterner {
316316
// Match associated types by name, not position
317317
let associated_types_unify = trait_associated_types.iter().all(|trait_generic| {
318318
// Find the matching impl generic by name
319-
let Some(impl_generic) = impl_trait_generics
319+
let Some(named_impl_generic) = impl_trait_generics
320320
.named
321321
.iter()
322322
.find(|impl_g| impl_g.name.as_str() == trait_generic.name.as_str())
323323
else {
324324
// If the impl doesn't have this associated type, it doesn't match
325325
return false;
326326
};
327-
let impl_generic2 = impl_generic.typ.force_substitute(&instantiation_bindings);
328-
trait_generic.typ.try_unify(&impl_generic2, &mut fresh_bindings).is_ok()
327+
328+
let mut impl_generic =
329+
named_impl_generic.typ.force_substitute(&instantiation_bindings);
330+
331+
// If the implementation is just a free type variable, it will bind to anything.
332+
// By turning it we can make sure it won't bind to other associated types.
333+
if let Type::TypeVariable(v) = &impl_generic {
334+
if v.borrow().is_unbound() {
335+
impl_generic = v
336+
.clone()
337+
.into_named_generic(&Rc::new(named_impl_generic.name.to_string()), None)
338+
}
339+
}
340+
341+
trait_generic.typ.try_unify(&impl_generic, &mut fresh_bindings).is_ok()
329342
});
343+
330344
if !associated_types_unify {
331345
continue;
332346
}

compiler/noirc_frontend/src/tests/traits/trait_associated_items.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -578,11 +578,9 @@ fn associated_type_mismatch_with_inheritance() {
578578
pub trait Qux: Foo {
579579
type Baz;
580580
fn qux(x: Self::Baz) -> Self::Baz {
581-
^^^^^^^^^ expected type Self::Baz, found type Self::Bar
582-
~~~~~~~~~ expected Self::Baz because of return type
583581
<Self as Foo>::foo(x)
584-
^ Expected type Self::Bar, found type Self::Baz
585-
~~~~~~~~~~~~~~~~~~~~~ Self::Bar returned here
582+
^^^^^^^^^^^ No matching impl found for `Self: Foo<Bar = Self::Baz>`
583+
~~~~~~~~~~~ No impl for `Self: Foo<Bar = Self::Baz>`
586584
}
587585
}
588586

0 commit comments

Comments
 (0)