about summary refs log tree commit diff
path: root/src/tools/rust-analyzer/crates/hir
diff options
context:
space:
mode:
authorChayim Refael Friedman <chayimfr@gmail.com>2025-06-10 14:04:21 +0300
committerChayim Refael Friedman <chayimfr@gmail.com>2025-06-10 14:04:21 +0300
commit95fdb2d81188cc04d3b26689da6e2d8cf3b0bb33 (patch)
treeb478d6c6a4390960f57177ae9bbd1ed00d309f5a /src/tools/rust-analyzer/crates/hir
parent3bae562b51452906e7f8046f984d8e861c0e8bc5 (diff)
downloadrust-95fdb2d81188cc04d3b26689da6e2d8cf3b0bb33.tar.gz
rust-95fdb2d81188cc04d3b26689da6e2d8cf3b0bb33.zip
Do not error at impls for unsized types that do not include `where Self: Sized` items
Diffstat (limited to 'src/tools/rust-analyzer/crates/hir')
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/lib.rs34
1 files changed, 33 insertions, 1 deletions
diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs
index e8218cf8611..969fd3eb480 100644
--- a/src/tools/rust-analyzer/crates/hir/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs
@@ -846,7 +846,7 @@ impl Module {
                     )
                 }
 
-                let missing: Vec<_> = required_items
+                let mut missing: Vec<_> = required_items
                     .filter(|(name, id)| {
                         !impl_assoc_items_scratch.iter().any(|(impl_name, impl_item)| {
                             discriminant(impl_item) == discriminant(id) && impl_name == name
@@ -854,6 +854,38 @@ impl Module {
                     })
                     .map(|(name, item)| (name.clone(), AssocItem::from(*item)))
                     .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() {
                     acc.push(
                         TraitImplMissingAssocItems {