about summary refs log tree commit diff
path: root/src/tools
diff options
context:
space:
mode:
authorShoyu Vanilla <modulo641@gmail.com>2024-08-17 20:56:40 +0900
committerShoyu Vanilla <modulo641@gmail.com>2024-08-17 22:33:27 +0900
commitc4b8c657e40076505d4da332c467214fbabe99ad (patch)
tree9a037874dd12a62bfa8f92cead4a5937a850a1b9 /src/tools
parent01245bd4d22fdb150dd4e2aa17ad1e4236854647 (diff)
fix: Wrong BoundVar index when lowering impl trait parameter of parent generics
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/lower.rs35
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs33
2 files changed, 50 insertions, 18 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 446f1853c8a..79b096068da 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
@@ -377,26 +377,25 @@ impl<'a> TyLoweringContext<'a> {
                         // Count the number of `impl Trait` things that appear within our bounds.
                         // Since t hose have been emitted as implicit type args already.
                         counter.set(idx + count_impl_traits(type_ref) as u16);
-                        let (
-                            _parent_params,
-                            self_param,
-                            type_params,
-                            const_params,
-                            _impl_trait_params,
-                            lifetime_params,
-                        ) = self
+                        let kind = self
                             .generics()
                             .expect("variable impl trait lowering must be in a generic def")
-                            .provenance_split();
-                        TyKind::BoundVar(BoundVar::new(
-                            self.in_binders,
-                            idx as usize
-                                + self_param as usize
-                                + type_params
-                                + const_params
-                                + lifetime_params,
-                        ))
-                        .intern(Interner)
+                            .iter()
+                            .enumerate()
+                            .filter_map(|(i, (id, data))| match (id, data) {
+                                (
+                                    GenericParamId::TypeParamId(_),
+                                    GenericParamDataRef::TypeParamData(data),
+                                ) if data.provenance == TypeParamProvenance::ArgumentImplTrait => {
+                                    Some(i)
+                                }
+                                _ => None,
+                            })
+                            .nth(idx as usize)
+                            .map_or(TyKind::Error, |id| {
+                                TyKind::BoundVar(BoundVar { debruijn: self.in_binders, index: id })
+                            });
+                        kind.intern(Interner)
                     }
                     ImplTraitLoweringState::Disallowed => {
                         // FIXME: report error
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 26e9243e738..01862aa2a37 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
@@ -2162,3 +2162,36 @@ fn main() {
         "#]],
     );
 }
+
+#[test]
+fn issue_17711() {
+    check_infer(
+        r#"
+//- minicore: deref
+use core::ops::Deref;
+
+struct Struct<'a, T>(&'a T);
+
+trait Trait {}
+
+impl<'a, T: Deref<Target = impl Trait>> Struct<'a, T> {
+    fn foo(&self) -> &Self { self }
+
+    fn bar(&self) {
+        let _ = self.foo();
+    }
+
+}
+"#,
+        expect![[r#"
+            137..141 'self': &'? Struct<'a, T>
+            152..160 '{ self }': &'? Struct<'a, T>
+            154..158 'self': &'? Struct<'a, T>
+            174..178 'self': &'? Struct<'a, T>
+            180..215 '{     ...     }': ()
+            194..195 '_': &'? Struct<'?, T>
+            198..202 'self': &'? Struct<'a, T>
+            198..208 'self.foo()': &'? Struct<'?, T>
+        "#]],
+    );
+}