mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 11:31:15 +00:00
Do not error at impls for unsized types that do not include where Self: Sized
items
This commit is contained in:
parent
6acff6c1f8
commit
6f4a6d4349
@ -122,7 +122,7 @@ pub fn dyn_compatibility_of_trait_query(
|
|||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generics_require_sized_self(db: &dyn HirDatabase, def: GenericDefId) -> bool {
|
pub fn generics_require_sized_self(db: &dyn HirDatabase, def: GenericDefId) -> bool {
|
||||||
let krate = def.module(db).krate();
|
let krate = def.module(db).krate();
|
||||||
let Some(sized) = LangItem::Sized.resolve_trait(db, krate) else {
|
let Some(sized) = LangItem::Sized.resolve_trait(db, krate) else {
|
||||||
return false;
|
return false;
|
||||||
|
@ -229,7 +229,7 @@ impl Generics {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a Substitution that replaces each parameter by itself (i.e. `Ty::Param`).
|
/// Returns a Substitution that replaces each parameter by itself (i.e. `Ty::Param`).
|
||||||
pub(crate) fn placeholder_subst(&self, db: &dyn HirDatabase) -> Substitution {
|
pub fn placeholder_subst(&self, db: &dyn HirDatabase) -> Substitution {
|
||||||
Substitution::from_iter(
|
Substitution::from_iter(
|
||||||
Interner,
|
Interner,
|
||||||
self.iter_id().map(|id| match id {
|
self.iter_id().map(|id| match id {
|
||||||
|
@ -846,7 +846,7 @@ impl Module {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
let missing: Vec<_> = required_items
|
let mut missing: Vec<_> = required_items
|
||||||
.filter(|(name, id)| {
|
.filter(|(name, id)| {
|
||||||
!impl_assoc_items_scratch.iter().any(|(impl_name, impl_item)| {
|
!impl_assoc_items_scratch.iter().any(|(impl_name, impl_item)| {
|
||||||
discriminant(impl_item) == discriminant(id) && impl_name == name
|
discriminant(impl_item) == discriminant(id) && impl_name == name
|
||||||
@ -854,6 +854,38 @@ impl Module {
|
|||||||
})
|
})
|
||||||
.map(|(name, item)| (name.clone(), AssocItem::from(*item)))
|
.map(|(name, item)| (name.clone(), AssocItem::from(*item)))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
if !missing.is_empty() {
|
||||||
|
let self_ty = db.impl_self_ty(impl_def.id).substitute(
|
||||||
|
Interner,
|
||||||
|
&hir_ty::generics::generics(db, impl_def.id.into()).placeholder_subst(db),
|
||||||
|
);
|
||||||
|
let self_ty = if let TyKind::Alias(AliasTy::Projection(projection)) =
|
||||||
|
self_ty.kind(Interner)
|
||||||
|
{
|
||||||
|
db.normalize_projection(
|
||||||
|
projection.clone(),
|
||||||
|
db.trait_environment(impl_def.id.into()),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
self_ty
|
||||||
|
};
|
||||||
|
let self_ty_is_guaranteed_unsized = matches!(
|
||||||
|
self_ty.kind(Interner),
|
||||||
|
TyKind::Dyn(..) | TyKind::Slice(..) | TyKind::Str
|
||||||
|
);
|
||||||
|
if self_ty_is_guaranteed_unsized {
|
||||||
|
missing.retain(|(_, assoc_item)| {
|
||||||
|
let assoc_item = match *assoc_item {
|
||||||
|
AssocItem::Function(it) => it.id.into(),
|
||||||
|
AssocItem::Const(it) => it.id.into(),
|
||||||
|
AssocItem::TypeAlias(it) => it.id.into(),
|
||||||
|
};
|
||||||
|
!hir_ty::dyn_compatibility::generics_require_sized_self(db, assoc_item)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if !missing.is_empty() {
|
if !missing.is_empty() {
|
||||||
acc.push(
|
acc.push(
|
||||||
TraitImplMissingAssocItems {
|
TraitImplMissingAssocItems {
|
||||||
|
@ -124,6 +124,35 @@ trait Trait {
|
|||||||
|
|
||||||
// Negative impls don't require any items (in fact, the forbid providing any)
|
// Negative impls don't require any items (in fact, the forbid providing any)
|
||||||
impl !Trait for () {}
|
impl !Trait for () {}
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn impl_sized_for_unsized() {
|
||||||
|
check_diagnostics(
|
||||||
|
r#"
|
||||||
|
//- minicore: sized
|
||||||
|
trait Trait {
|
||||||
|
type Item
|
||||||
|
where
|
||||||
|
Self: Sized;
|
||||||
|
|
||||||
|
fn item()
|
||||||
|
where
|
||||||
|
Self: Sized;
|
||||||
|
}
|
||||||
|
|
||||||
|
trait OtherTrait {}
|
||||||
|
|
||||||
|
impl Trait for () {
|
||||||
|
type Item = ();
|
||||||
|
fn item() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Items with Self: Sized bound not required to be implemented for unsized types.
|
||||||
|
impl Trait for str {}
|
||||||
|
impl Trait for dyn OtherTrait {}
|
||||||
"#,
|
"#,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user