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:
bors 2024-08-23 18:04:21 +00:00
commit ab34fdd9f3

View file

@ -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)]