about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorChayim Refael Friedman <chayimfr@gmail.com>2025-08-24 08:49:40 +0300
committerChayim Refael Friedman <chayimfr@gmail.com>2025-08-24 08:49:40 +0300
commit31245cabecfc21c837745ec6253d63d5fc9ac75f (patch)
treeab49be0356f796f19a490ff94c8ad810dd80aca6 /src
parentcf358c09cebfe3e1c0d7145242396f6066033fad (diff)
downloadrust-31245cabecfc21c837745ec6253d63d5fc9ac75f.tar.gz
rust-31245cabecfc21c837745ec6253d63d5fc9ac75f.zip
Fix opaque generics
The parent generics were incorrectly not considered for TAIT.

I'm not convinced we should follow rustc here, also there are items (opaques) with more than 1 parent (opaque -> fn/type alias -> impl/trait) and I'm not sure we properly account for that in all places, but for now I left it as-is.

Also fix a bug where lifetimes' indices were incorrect when there is a self param (they started from 0 instead of 1).
Diffstat (limited to 'src')
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/next_solver/generics.rs68
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/next_solver/util.rs1
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/regression/new_solver.rs26
4 files changed, 54 insertions, 43 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/generics.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/generics.rs
index 48f5e73f256..a3ba8eb8345 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/generics.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/generics.rs
@@ -12,7 +12,7 @@ use hir_def::{
     },
 };
 use hir_expand::name::Name;
-use intern::Symbol;
+use intern::{Symbol, sym};
 use la_arena::Arena;
 use rustc_type_ir::inherent::Ty as _;
 use triomphe::Arc;
@@ -24,18 +24,13 @@ use super::{Const, EarlyParamRegion, ErrorGuaranteed, ParamConst, Region, Solver
 use super::{DbInterner, GenericArg};
 
 pub(crate) fn generics(db: &dyn HirDatabase, def: SolverDefId) -> Generics {
-    let mk_lt = |(index, (_, lt)): (usize, (_, &LifetimeParamData))| {
+    let mk_lt = |index, lt: &LifetimeParamData| {
         let name = lt.name.symbol().clone();
-        let index = index as u32;
         let kind = GenericParamDefKind::Lifetime;
         GenericParamDef { name, index, kind }
     };
-    let mk_ty = |len_lt, (index, p): (usize, &TypeOrConstParamData)| {
-        let name = p
-            .name()
-            .map(|n| n.symbol().clone())
-            .unwrap_or_else(|| Name::missing().symbol().clone());
-        let index = (len_lt + index) as u32;
+    let mk_ty = |index, p: &TypeOrConstParamData| {
+        let name = p.name().map(|n| n.symbol().clone()).unwrap_or_else(|| sym::MISSING_NAME);
         let kind = match p {
             TypeOrConstParamData::TypeParamData(_) => GenericParamDefKind::Type,
             TypeOrConstParamData::ConstParamData(_) => GenericParamDefKind::Const,
@@ -43,33 +38,25 @@ pub(crate) fn generics(db: &dyn HirDatabase, def: SolverDefId) -> Generics {
         GenericParamDef { name, index, kind }
     };
     let own_params_for_generic_params = |params: &GenericParams| {
-        if params.trait_self_param().is_some() {
-            let len_lt = params.len_lifetimes() + 1;
-            params
-                .iter_type_or_consts()
-                .take(1)
-                .enumerate()
-                .map(|t| mk_ty(0, (t.0, t.1.1)))
-                .chain(params.iter_lt().enumerate().map(mk_lt))
-                .chain(
-                    params
-                        .iter_type_or_consts()
-                        .skip(1)
-                        .enumerate()
-                        .map(|t| mk_ty(len_lt, (t.0, t.1.1))),
-                )
-                .collect()
-        } else {
-            let len_lt = params.len_lifetimes();
-            params
-                .iter_lt()
-                .enumerate()
-                .map(mk_lt)
-                .chain(
-                    params.iter_type_or_consts().enumerate().map(|t| mk_ty(len_lt, (t.0, t.1.1))),
-                )
-                .collect()
+        let mut result = Vec::with_capacity(params.len());
+        let mut type_and_consts = params.iter_type_or_consts();
+        let mut index = 0;
+        if let Some(self_param) = params.trait_self_param() {
+            result.push(mk_ty(0, &params[self_param]));
+            type_and_consts.next();
+            index += 1;
         }
+        result.extend(params.iter_lt().map(|(_, data)| {
+            let lt = mk_lt(index, data);
+            index += 1;
+            lt
+        }));
+        result.extend(type_and_consts.map(|(_, data)| {
+            let ty = mk_ty(index, data);
+            index += 1;
+            ty
+        }));
+        result
     };
 
     let (parent, own_params) = match (def.try_into(), def) {
@@ -82,12 +69,9 @@ pub(crate) fn generics(db: &dyn HirDatabase, def: SolverDefId) -> Generics {
                     // The opaque type itself does not have generics - only the parent function
                     (Some(GenericDefId::FunctionId(function_id)), vec![])
                 }
-                crate::ImplTraitId::TypeAliasImplTrait(type_alias_id, _) => (
-                    None,
-                    own_params_for_generic_params(
-                        &db.generic_params(GenericDefId::TypeAliasId(type_alias_id)),
-                    ),
-                ),
+                crate::ImplTraitId::TypeAliasImplTrait(type_alias_id, _) => {
+                    (Some(type_alias_id.into()), Vec::new())
+                }
                 crate::ImplTraitId::AsyncBlockTypeImplTrait(def, _) => {
                     let param = TypeOrConstParamData::TypeParamData(TypeParamData {
                         name: None,
@@ -95,7 +79,7 @@ pub(crate) fn generics(db: &dyn HirDatabase, def: SolverDefId) -> Generics {
                         provenance: TypeParamProvenance::TypeParamList,
                     });
                     // Yes, there is a parent but we don't include it in the generics
-                    (None, vec![mk_ty(0, (0, &param))])
+                    (None, vec![mk_ty(0, &param)])
                 }
             }
         }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/util.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/util.rs
index cedc203f7f5..1db02e9eb61 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/util.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/util.rs
@@ -685,7 +685,6 @@ pub fn explicit_item_bounds<'db>(
                 LifetimeElisionKind::AnonymousReportError,
             );
 
-            let trait_args = GenericArgs::identity_for_item(interner, trait_.into());
             let item_args = GenericArgs::identity_for_item(interner, def_id);
             let interner_ty = Ty::new_projection_from_args(interner, def_id, item_args);
 
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs
index 966433369aa..6a3f2286215 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs
@@ -1,3 +1,5 @@
+mod new_solver;
+
 use expect_test::expect;
 
 use super::{check_infer, check_no_mismatches, check_types};
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression/new_solver.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression/new_solver.rs
new file mode 100644
index 00000000000..059f4ad32a5
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression/new_solver.rs
@@ -0,0 +1,26 @@
+use expect_test::expect;
+
+use super::check_infer;
+
+#[test]
+fn opaque_generics() {
+    check_infer(
+        r#"
+//- minicore: iterator
+pub struct Grid {}
+
+impl<'a> IntoIterator for &'a Grid {
+    type Item = &'a ();
+
+    type IntoIter = impl Iterator<Item = &'a ()>;
+
+    fn into_iter(self) -> Self::IntoIter {
+    }
+}
+    "#,
+        expect![[r#"
+            150..154 'self': &'a Grid
+            174..181 '{     }': impl Iterator<Item = &'a ()>
+        "#]],
+    );
+}