Auto merge of #13344 - lowr:patch/change-generic-param-order, r=Veykril
fix: use `BoundVar`s from current generic scope Fixup for #13335, addresses https://github.com/rust-lang/rust-analyzer/pull/13339#issuecomment-1266654607 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.
This commit is contained in:
commit
476d043874
@ -1158,11 +1158,28 @@ fn named_associated_type_shorthand_candidates<R>(
|
||||
};
|
||||
|
||||
match res {
|
||||
TypeNs::SelfType(impl_id) => search(
|
||||
TypeNs::SelfType(impl_id) => {
|
||||
// we're _in_ the impl -- the binders get added back later. Correct,
|
||||
// but it would be nice to make this more explicit
|
||||
db.impl_trait(impl_id)?.into_value_and_skipped_binders().0,
|
||||
),
|
||||
let trait_ref = db.impl_trait(impl_id)?.into_value_and_skipped_binders().0;
|
||||
|
||||
let impl_id_as_generic_def: GenericDefId = impl_id.into();
|
||||
if impl_id_as_generic_def != def {
|
||||
// `trait_ref` contains `BoundVar`s bound by impl's `Binders`, but here we need
|
||||
// `BoundVar`s from `def`'s point of view.
|
||||
// FIXME: A `HirDatabase` query may be handy if this process is needed in more
|
||||
// places. It'd be almost identical as `impl_trait_query` where `resolver` would be
|
||||
// of `def` instead of `impl_id`.
|
||||
let starting_idx = generics(db.upcast(), def).len_self();
|
||||
let subst = TyBuilder::subst_for_def(db, impl_id, None)
|
||||
.fill_with_bound_vars(DebruijnIndex::INNERMOST, starting_idx)
|
||||
.build();
|
||||
let trait_ref = subst.apply(trait_ref, Interner);
|
||||
search(trait_ref)
|
||||
} else {
|
||||
search(trait_ref)
|
||||
}
|
||||
}
|
||||
TypeNs::GenericParam(param_id) => {
|
||||
let predicates = db.generic_predicates_for_param(def, param_id.into(), assoc_name);
|
||||
let res = predicates.iter().find_map(|pred| match pred.skip_binders().skip_binders() {
|
||||
|
@ -1694,3 +1694,16 @@ fn foo(a: &dyn DoesNotExist) {
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn self_assoc_with_const_generics_crash() {
|
||||
check_no_mismatches(
|
||||
r#"
|
||||
trait Trait { type Item; }
|
||||
impl<T, const N: usize> Trait for [T; N] {
|
||||
type Item = ();
|
||||
fn f<U>(_: Self::Item) {}
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user