mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 13:33:31 +00:00
Auto merge of #17948 - ShoyuVanilla:parent-self-sized, r=Veykril
fix: Wrong `Self: Sized` predicate for trait assoc items Again while implementing object safety like #17939 😅 If we call `generic_predicates_query` on `fn foo` in the following code; ``` trait Foo { fn foo(); } ``` It returns implicit bound `Self: Sized`, even though `Self` is not appearing as a generic parameter inside angle brackets, but as a parent generic parameter, "trait self". This PR prevent pushing "implicit" `Self: Sized` predicates in such cases
This commit is contained in:
commit
ab34fdd9f3
1 changed files with 32 additions and 8 deletions
|
@ -1743,15 +1743,39 @@ fn implicitly_sized_clauses<'a, 'subst: 'a>(
|
||||||
substitution: &'subst Substitution,
|
substitution: &'subst Substitution,
|
||||||
resolver: &Resolver,
|
resolver: &Resolver,
|
||||||
) -> Option<impl Iterator<Item = WhereClause> + Captures<'a> + Captures<'subst>> {
|
) -> Option<impl Iterator<Item = WhereClause> + Captures<'a> + Captures<'subst>> {
|
||||||
let is_trait_def = matches!(def, GenericDefId::TraitId(..));
|
|
||||||
let generic_args = &substitution.as_slice(Interner)[is_trait_def as usize..];
|
|
||||||
let sized_trait = db
|
let sized_trait = db
|
||||||
.lang_item(resolver.krate(), LangItem::Sized)
|
.lang_item(resolver.krate(), LangItem::Sized)
|
||||||
.and_then(|lang_item| lang_item.as_trait().map(to_chalk_trait_id));
|
.and_then(|lang_item| lang_item.as_trait().map(to_chalk_trait_id))?;
|
||||||
|
|
||||||
sized_trait.map(move |sized_trait| {
|
let get_trait_self_idx = |container: ItemContainerId| {
|
||||||
generic_args
|
if matches!(container, ItemContainerId::TraitId(_)) {
|
||||||
.iter()
|
let generics = generics(db.upcast(), def);
|
||||||
|
Some(generics.len_self())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let trait_self_idx = match def {
|
||||||
|
GenericDefId::TraitId(_) => Some(0),
|
||||||
|
GenericDefId::FunctionId(it) => get_trait_self_idx(it.lookup(db.upcast()).container),
|
||||||
|
GenericDefId::ConstId(it) => get_trait_self_idx(it.lookup(db.upcast()).container),
|
||||||
|
GenericDefId::TypeAliasId(it) => get_trait_self_idx(it.lookup(db.upcast()).container),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
|
||||||
|
Some(
|
||||||
|
substitution
|
||||||
|
.iter(Interner)
|
||||||
|
.enumerate()
|
||||||
|
.filter_map(
|
||||||
|
move |(idx, generic_arg)| {
|
||||||
|
if Some(idx) == trait_self_idx {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(generic_arg)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
.filter_map(|generic_arg| generic_arg.ty(Interner))
|
.filter_map(|generic_arg| generic_arg.ty(Interner))
|
||||||
.filter(move |&self_ty| !explicitly_unsized_tys.contains(self_ty))
|
.filter(move |&self_ty| !explicitly_unsized_tys.contains(self_ty))
|
||||||
.map(move |self_ty| {
|
.map(move |self_ty| {
|
||||||
|
@ -1759,8 +1783,8 @@ fn implicitly_sized_clauses<'a, 'subst: 'a>(
|
||||||
trait_id: sized_trait,
|
trait_id: sized_trait,
|
||||||
substitution: Substitution::from1(Interner, self_ty.clone()),
|
substitution: Substitution::from1(Interner, self_ty.clone()),
|
||||||
})
|
})
|
||||||
})
|
}),
|
||||||
})
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
|
Loading…
Reference in a new issue