about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorShoyu Vanilla <modulo641@gmail.com>2024-08-24 01:28:48 +0900
committerShoyu Vanilla <modulo641@gmail.com>2024-08-24 01:28:48 +0900
commiteb896a580a09d2ebd695ae879a35ba7fc7e6ade3 (patch)
treec7377469e36c6448b10a1bb12657b7011f53f602 /src
parent3a097e16594f0f1aa89ff23a3f4f4659c09d9052 (diff)
downloadrust-eb896a580a09d2ebd695ae879a35ba7fc7e6ade3.tar.gz
rust-eb896a580a09d2ebd695ae879a35ba7fc7e6ade3.zip
fix: Wrong `Self: Sized` predicate for trait assoc items
Diffstat (limited to 'src')
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/lower.rs40
1 files changed, 32 insertions, 8 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
index 58c34cbd9e1..370d9ba99cb 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
@@ -1743,15 +1743,39 @@ fn implicitly_sized_clauses<'a, 'subst: 'a>(
     substitution: &'subst Substitution,
     resolver: &Resolver,
 ) -> 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
         .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| {
-        generic_args
-            .iter()
+    let get_trait_self_idx = |container: ItemContainerId| {
+        if matches!(container, ItemContainerId::TraitId(_)) {
+            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(move |&self_ty| !explicitly_unsized_tys.contains(self_ty))
             .map(move |self_ty| {
@@ -1759,8 +1783,8 @@ fn implicitly_sized_clauses<'a, 'subst: 'a>(
                     trait_id: sized_trait,
                     substitution: Substitution::from1(Interner, self_ty.clone()),
                 })
-            })
-    })
+            }),
+    )
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]