Skip to content

Commit ded3326

Browse files
committed
fix: use BoundVars from current generic scope
1 parent e0a161b commit ded3326

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)