Skip to content

Commit 1dad12f

Browse files
committed
Do not use NamedGeneric
1 parent 70d16d3 commit 1dad12f

File tree

4 files changed

+28
-45
lines changed

4 files changed

+28
-45
lines changed

compiler/noirc_frontend/src/elaborator/traits.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,7 @@ impl Elaborator<'_> {
616616
}
617617

618618
let parent_trait_bound =
619-
self.instantiate_parent_trait_bound(object, trait_bound, &parent_trait_bound);
619+
self.instantiate_parent_trait_bound(trait_bound, &parent_trait_bound);
620620
self.add_trait_bound_to_scope(
621621
location,
622622
object,

compiler/noirc_frontend/src/elaborator/types.rs

Lines changed: 10 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2295,7 +2295,6 @@ impl Elaborator<'_> {
22952295
let the_trait = self.interner.get_trait(trait_id);
22962296
let constraint = the_trait.as_constraint(the_trait.name.location());
22972297
let mut matches = self.lookup_methods_in_trait(
2298-
object_type,
22992298
the_trait,
23002299
method_name,
23012300
&constraint.trait_bound,
@@ -2332,7 +2331,6 @@ impl Elaborator<'_> {
23322331
self.interner.try_get_trait(constraint.trait_bound.trait_id)
23332332
{
23342333
let trait_matches = self.lookup_methods_in_trait(
2335-
object_type,
23362334
the_trait,
23372335
method_name,
23382336
&constraint.trait_bound,
@@ -2394,7 +2392,6 @@ impl Elaborator<'_> {
23942392
/// a child and its parent.
23952393
fn lookup_methods_in_trait(
23962394
&self,
2397-
object: &Type,
23982395
the_trait: &Trait,
23992396
method_name: &str,
24002397
trait_bound: &ResolvedTraitBound,
@@ -2423,9 +2420,8 @@ impl Elaborator<'_> {
24232420
}
24242421

24252422
let parent_trait_bound =
2426-
self.instantiate_parent_trait_bound(object, trait_bound, parent_trait_bound);
2423+
self.instantiate_parent_trait_bound(trait_bound, parent_trait_bound);
24272424
let parent_matches = self.lookup_methods_in_trait(
2428-
object,
24292425
the_trait,
24302426
method_name,
24312427
&parent_trait_bound,
@@ -2659,12 +2655,11 @@ impl Elaborator<'_> {
26592655
/// type to whatever type the constraint is defined on.
26602656
pub fn bind_generics_from_trait_constraint(
26612657
&self,
2662-
object: &Type,
26632658
constraint: &TraitConstraint,
26642659
assumed: bool,
26652660
bindings: &mut TypeBindings,
26662661
) {
2667-
self.bind_generics_from_trait_bound(object, &constraint.trait_bound, bindings);
2662+
self.bind_generics_from_trait_bound(&constraint.trait_bound, bindings);
26682663

26692664
// If the trait impl is already assumed to exist we should add any type bindings for `Self`.
26702665
// Otherwise `self` will be replaced with a fresh type variable, which will require the user
@@ -2680,35 +2675,24 @@ impl Elaborator<'_> {
26802675
/// Insert the ordered generics and associated types from the trait bound.
26812676
pub fn bind_generics_from_trait_bound(
26822677
&self,
2683-
object: &Type,
26842678
trait_bound: &ResolvedTraitBound,
26852679
bindings: &mut TypeBindings,
26862680
) {
26872681
let the_trait = self.interner.get_trait(trait_bound.trait_id);
26882682

26892683
bind_ordered_generics(&the_trait.generics, &trait_bound.trait_generics.ordered, bindings);
26902684

2691-
let associated_types = vecmap(&the_trait.associated_types, |typ| {
2692-
let is_const = the_trait.associated_constant_ids.contains_key(typ.name.as_str());
2693-
(typ.clone(), is_const)
2694-
});
2695-
bind_named_generics(
2696-
object,
2697-
&the_trait.name,
2698-
associated_types,
2699-
&trait_bound.trait_generics.named,
2700-
bindings,
2701-
);
2685+
let associated_types = the_trait.associated_types.clone();
2686+
bind_named_generics(associated_types, &trait_bound.trait_generics.named, bindings);
27022687
}
27032688

27042689
pub fn instantiate_parent_trait_bound(
27052690
&self,
2706-
object: &Type,
27072691
trait_bound: &ResolvedTraitBound,
27082692
parent_trait_bound: &ResolvedTraitBound,
27092693
) -> ResolvedTraitBound {
27102694
let mut bindings = TypeBindings::default();
2711-
self.bind_generics_from_trait_bound(object, trait_bound, &mut bindings);
2695+
self.bind_generics_from_trait_bound(trait_bound, &mut bindings);
27122696
ResolvedTraitBound {
27132697
trait_generics: parent_trait_bound.trait_generics.map(|typ| typ.substitute(&bindings)),
27142698
..*parent_trait_bound
@@ -2795,9 +2779,7 @@ pub(super) fn bind_ordered_generics(
27952779
/// Panics if the number of types exceeds the named generics in the trait.
27962780
/// Any named parameter that does not appear in the arguments is bound to [Type::Error].
27972781
fn bind_named_generics(
2798-
object: &Type,
2799-
trait_ident: &Ident,
2800-
mut params: Vec<(ResolvedGeneric, bool)>,
2782+
mut params: Vec<ResolvedGeneric>,
28012783
args: &[NamedType],
28022784
bindings: &mut TypeBindings,
28032785
) {
@@ -2806,34 +2788,19 @@ fn bind_named_generics(
28062788
if params.is_empty() {
28072789
return;
28082790
}
2809-
let object_name = object.to_string();
2810-
let trait_name = trait_ident.as_str();
28112791

28122792
for arg in args {
28132793
let i = params
28142794
.iter()
2815-
.position(|(typ, _)| *typ.name == arg.name.as_str())
2795+
.position(|typ| *typ.name == arg.name.as_str())
28162796
.unwrap_or_else(|| unreachable!("Expected to find associated type named {}", arg.name));
28172797

2818-
let (param, is_const) = params.swap_remove(i);
2798+
let param = params.swap_remove(i);
28192799

2820-
match &arg.typ {
2821-
Type::TypeVariable(v) if !is_const && v.borrow().is_unbound() => {
2822-
// If we allow associated types to bind to a Type::TypeVariable rather than a Type::NamedGeneric,
2823-
// then they be unified with anything else,
2824-
// whereas as a NamedGeneric they only unify with the same type variable.
2825-
let name = Rc::new(arg.name.to_string());
2826-
let typ = v.clone().into_named_generic(&name, Some((&object_name, trait_name)));
2827-
bind_generic(&param, &typ, bindings);
2828-
}
2829-
_ => {
2830-
// Other types or associated constants
2831-
bind_generic(&param, &arg.typ, bindings);
2832-
}
2833-
}
2800+
bind_generic(&param, &arg.typ, bindings);
28342801
}
28352802

2836-
for (unbound_param, _) in params {
2803+
for unbound_param in params {
28372804
bind_generic(&unbound_param, &Type::Error, bindings);
28382805
}
28392806
}

compiler/noirc_frontend/src/elaborator/variable.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,6 @@ impl Elaborator<'_> {
576576
// the type used in the trait constraint (if it exists). See #4088.
577577
if let ImplKind::TraitItem(method) = &ident.impl_kind {
578578
self.bind_generics_from_trait_constraint(
579-
&method.constraint.typ,
580579
&method.constraint,
581580
method.assumed,
582581
&mut bindings,

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,3 +213,20 @@ fn trait_impl_with_child_constraint() {
213213
"#;
214214
assert_no_errors(src);
215215
}
216+
217+
#[test]
218+
fn trait_inheritance_with_ambiguous_associated_type() {
219+
let src = r#"
220+
pub trait Foo {
221+
type Bar;
222+
fn foo(x: Self::Bar) -> Self::Bar;
223+
}
224+
225+
pub trait Qux: Foo {
226+
type Bar;
227+
fn qux(x: Self::Bar) -> Self::Bar;
228+
}
229+
"#;
230+
// TODO: Add errors for ambiguous type. But it should work as `<Self as Qux>::Bar`
231+
check_errors(src);
232+
}

0 commit comments

Comments
 (0)