From ac4f3e61f8c56dbe245e3ece0f2c38e17c3e199e Mon Sep 17 00:00:00 2001
From: Florian Diebold <flodiebold@gmail.com>
Date: Thu, 5 Aug 2021 22:44:38 +0200
Subject: [PATCH] Fix binders with bare dyn trait

Fixes #9639.
---
 crates/hir_ty/src/lower.rs            | 20 +++++++++-----------
 crates/hir_ty/src/tests/regression.rs | 16 ++++++++++++++++
 2 files changed, 25 insertions(+), 11 deletions(-)

diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs
index 92b376c4402..5ba66fda8f8 100644
--- a/crates/hir_ty/src/lower.rs
+++ b/crates/hir_ty/src/lower.rs
@@ -401,18 +401,9 @@ impl<'a> TyLoweringContext<'a> {
     ) -> (Ty, Option<TypeNs>) {
         let ty = match resolution {
             TypeNs::TraitId(trait_) => {
-                // if this is a bare dyn Trait, we'll directly put the required ^0 for the self type in there
-                let self_ty = if remaining_segments.len() == 0 {
-                    Some(
-                        TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0))
-                            .intern(&Interner),
-                    )
-                } else {
-                    None
-                };
-                let trait_ref =
-                    self.lower_trait_ref_from_resolved_path(trait_, resolved_segment, self_ty);
                 let ty = if remaining_segments.len() == 1 {
+                    let trait_ref =
+                        self.lower_trait_ref_from_resolved_path(trait_, resolved_segment, None);
                     let segment = remaining_segments.first().unwrap();
                     let found = self
                         .db
@@ -436,6 +427,13 @@ impl<'a> TyLoweringContext<'a> {
                     // FIXME report error (ambiguous associated type)
                     TyKind::Error.intern(&Interner)
                 } else {
+                    let self_ty = Some(
+                        TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0))
+                            .intern(&Interner),
+                    );
+                    let trait_ref = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
+                        ctx.lower_trait_ref_from_resolved_path(trait_, resolved_segment, self_ty)
+                    });
                     let dyn_ty = DynTy {
                         bounds: crate::make_only_type_binders(
                             1,
diff --git a/crates/hir_ty/src/tests/regression.rs b/crates/hir_ty/src/tests/regression.rs
index 1e40ff24e3a..58bbaa1c80e 100644
--- a/crates/hir_ty/src/tests/regression.rs
+++ b/crates/hir_ty/src/tests/regression.rs
@@ -1077,3 +1077,19 @@ fn test() {
         "#,
     )
 }
+
+#[test]
+fn bare_dyn_trait_binders_9639() {
+    check_no_mismatches(
+        r#"
+//- minicore: fn, coerce_unsized
+fn infix_parse<T, S>(_state: S, _level_code: &Fn(S)) -> T {
+    loop {}
+}
+
+fn parse_arule() {
+    infix_parse((), &(|_recurse| ()))
+}
+        "#,
+    )
+}