Skip to content

Commit

Permalink
Auto merge of rust-lang#13344 - lowr:patch/change-generic-param-order…
Browse files Browse the repository at this point in the history
…, r=Veykril

fix: use `BoundVar`s from current generic scope

Fixup for rust-lang#13335, addresses rust-lang/rust-analyzer#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.
  • Loading branch information
bors committed Oct 4, 2022
2 parents b429df2 + ded3326 commit 476d043
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 3 deletions.
23 changes: 20 additions & 3 deletions crates/hir-ty/src/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
13 changes: 13 additions & 0 deletions crates/hir-ty/src/tests/regression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {}
}
"#,
);
}

0 comments on commit 476d043

Please sign in to comment.