Skip to content

Commit 476d043

Browse files
committed
Auto merge of #13344 - lowr:patch/change-generic-param-order, r=Veykril
fix: use `BoundVar`s from current generic scope Fixup for #13335, addresses #13339 (comment) Before the change in generic parameter order, `BoundVar`s for trait reference didn't change whether you are in an impl's scope or in an associated item's scope. Now that item's generic params come before its parent's, we need to shift their indices when we are in an associated item's scope.
2 parents b429df2 + ded3326 commit 476d043

File tree

2 files changed

+33
-3
lines changed

2 files changed

+33
-3
lines changed

crates/hir-ty/src/lower.rs

+20-3
Original file line numberDiff line numberDiff line change
@@ -1158,11 +1158,28 @@ fn named_associated_type_shorthand_candidates<R>(
11581158
};
11591159

11601160
match res {
1161-
TypeNs::SelfType(impl_id) => search(
1161+
TypeNs::SelfType(impl_id) => {
11621162
// we're _in_ the impl -- the binders get added back later. Correct,
11631163
// but it would be nice to make this more explicit
1164-
db.impl_trait(impl_id)?.into_value_and_skipped_binders().0,
1165-
),
1164+
let trait_ref = db.impl_trait(impl_id)?.into_value_and_skipped_binders().0;
1165+
1166+
let impl_id_as_generic_def: GenericDefId = impl_id.into();
1167+
if impl_id_as_generic_def != def {
1168+
// `trait_ref` contains `BoundVar`s bound by impl's `Binders`, but here we need
1169+
// `BoundVar`s from `def`'s point of view.
1170+
// FIXME: A `HirDatabase` query may be handy if this process is needed in more
1171+
// places. It'd be almost identical as `impl_trait_query` where `resolver` would be
1172+
// of `def` instead of `impl_id`.
1173+
let starting_idx = generics(db.upcast(), def).len_self();
1174+
let subst = TyBuilder::subst_for_def(db, impl_id, None)
1175+
.fill_with_bound_vars(DebruijnIndex::INNERMOST, starting_idx)
1176+
.build();
1177+
let trait_ref = subst.apply(trait_ref, Interner);
1178+
search(trait_ref)
1179+
} else {
1180+
search(trait_ref)
1181+
}
1182+
}
11661183
TypeNs::GenericParam(param_id) => {
11671184
let predicates = db.generic_predicates_for_param(def, param_id.into(), assoc_name);
11681185
let res = predicates.iter().find_map(|pred| match pred.skip_binders().skip_binders() {

crates/hir-ty/src/tests/regression.rs

+13
Original file line numberDiff line numberDiff line change
@@ -1694,3 +1694,16 @@ fn foo(a: &dyn DoesNotExist) {
16941694
"#,
16951695
);
16961696
}
1697+
1698+
#[test]
1699+
fn self_assoc_with_const_generics_crash() {
1700+
check_no_mismatches(
1701+
r#"
1702+
trait Trait { type Item; }
1703+
impl<T, const N: usize> Trait for [T; N] {
1704+
type Item = ();
1705+
fn f<U>(_: Self::Item) {}
1706+
}
1707+
"#,
1708+
);
1709+
}

0 commit comments

Comments
 (0)