Repository: rust-lang/rust-analyzer (rust)

Issue:
panicked: mismatched kinds in substitution
**rust-analyzer version**: 0.4.2048

**rustc version**: 1.78.0

**editor or extension**: VS.-Code

im recieving the following error when i try to use the anchor_lang create:

thread 'Worker' panicked at C:\Users\runneradmin\.cargo\registry\src\index.crates.io-6f17d22bba15001f\chalk-ir-0.98.0\src\fold\subst.rs:59:22:
mismatched kinds in substitution
stack backtrace:
   0: std::panicking::begin_panic
   1: chalk_ir::fold::subst::_::<impl chalk_ir::fold::FallibleTypeFolder<I> for chalk_ir::fold::subst::Subst<I>>::try_fold_free_var_ty
   2: chalk_ir::fold::TypeSuperFoldable::super_fold_with
   3: chalk_ir::_::<impl chalk_ir::fold::TypeFoldable<I> for chalk_ir::WhereClause<I>>::try_fold_with
   4: chalk_ir::fold::binder_impls::<impl chalk_ir::fold::TypeFoldable<I> for chalk_ir::Binders<T>>::try_fold_with
   5: chalk_ir::Binders<T>::substitute
   6: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_assignee_expr
   7: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_assignee_expr
   8: hir_ty::infer::coerce::auto_deref_adjust_steps
   9: hir_ty::infer::coerce::auto_deref_adjust_steps
  10: hir_ty::infer::coerce::auto_deref_adjust_steps
  11: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_assignee_expr
  12: hir_ty::infer::coerce::auto_deref_adjust_steps
  13: hir_ty::infer::coerce::auto_deref_adjust_steps
  14: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_assignee_expr
  15: hir_ty::infer::coerce::auto_deref_adjust_steps
  16: hir_ty::infer::coerce::auto_deref_adjust_steps
  17: hir_ty::infer::infer_query
  18: salsa::Cycle::catch
  19: salsa::derived::slot::Slot<Q>::read
  20: salsa::derived::slot::Slot<Q>::read
  21: <salsa::derived::DerivedStorage<Q> as salsa::plumbing::QueryStorageOps<Q>>::fetch
  22: <DB as hir_ty::db::HirDatabase>::infer
  23: hir::semantics::SemanticsImpl::analyze_impl
  24: ide_db::active_parameter::generic_def_for_node
  25: ide::inlay_hints::generic_param::hints
  26: ide::inlay_hints::hints
  27: std::panicking::try
  28: rust_analyzer::handlers::request::handle_inlay_hints
  29: std::panicking::try
  30: core::ops::function::FnOnce::call_once{{vtable.shim}}
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
[Error - 8:41:25 PM] Request textDocument/inlayHint failed.
  Message: request handler panicked: mismatched kinds in substitution
  Code: -32603 


**code snippet to reproduce**: 
```rust
    let payer = Keypair::new();
    let client = Client::new(Cluster::Mainnet, Rc::new(payer));

    // Create program
    let program = client.program(alphazero_chain_swap::ID).unwrap();
    let instructions: Vec<Instruction> = program.request()
        .accounts(accounts)
        .args(args)
        .instructions()
        .unwrap();
```

The Error happens when i try after the args(args) parameter to use .instructions()

Pull request description:
fix: Wrong BoundVar index when lowering impl trait parameter of parent generics
Fixes #17711

From the following test code;

```rust
//- 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();
    }

}
```

when we call `register_obligations_for_call` for `let _ = self.foo();`,

https://github.com/rust-lang/rust-analyzer/blob/07659783fdfd4ec0a0bffa93017e33e31e567e42/crates/hir-ty/src/infer/expr.rs#L1939-L1952

we are querying `generic_predicates` and it has `T: Deref<Target = impl Trait>` predicate from the parent `impl Struct`;

https://github.com/rust-lang/rust-analyzer/blob/07659783fdfd4ec0a0bffa93017e33e31e567e42/crates/hir-ty/src/lower.rs#L375-L399

but as we can see above, lowering `TypeRef = impl Trait` doesn't take into account the parent generic parameters, so the `BoundVar` index here is `0`, as `fn foo` has no generic args other than parent's,

But this `BoundVar` is pointing at `'a` in `<'a, T: Deref<Target = impl Trait>>`.
So, in the first code reference `register_obligations_for_call`'s L:1948 - `.substitute(Interner, parameters)`, we are substituting `'a` with `Ty`, not `Lifetime` and this makes panic inside the chalk.

This PR fixes this wrong `BoundVar` index in such cases

Patch:
diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs
index 446f1853c8..79b096068d 100644
--- a/crates/hir-ty/src/lower.rs
+++ b/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/crates/syntax/Cargo.toml b/crates/syntax/Cargo.toml
index fcb9b0ea35..d945fa59c9 100644
--- a/crates/syntax/Cargo.toml
+++ b/crates/syntax/Cargo.toml
@@ -16,7 +16,7 @@ doctest = false
 cov-mark = "2.0.0-pre.1"
 either.workspace = true
 itertools.workspace = true
-rowan = "=0.15.15"
+rowan = "0.15.15"
 rustc-hash.workspace = true
 indexmap.workspace = true
 smol_str.workspace = true


Test patch:
diff --git a/crates/hir-ty/src/tests/regression.rs b/crates/hir-ty/src/tests/regression.rs
index 26e9243e73..01862aa2a3 100644
--- a/crates/hir-ty/src/tests/regression.rs
+++ b/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>
+        "#]],
+    );
+}