about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-05-20 20:55:22 +0000
committerbors <bors@rust-lang.org>2023-05-20 20:55:22 +0000
commita04d8456be1d289c814846178cc1ff63b4fc297b (patch)
tree5b9d8f17a9bef38250cb0371d5c46bee0a59dc88
parent4de8c0980e4cd218e6b681d6957845d37f6dea10 (diff)
parent92d6670f72c3771322485bb29c96900932faf3d6 (diff)
downloadrust-a04d8456be1d289c814846178cc1ff63b4fc297b.tar.gz
rust-a04d8456be1d289c814846178cc1ff63b4fc297b.zip
Auto merge of #14855 - HKalbasi:mir, r=HKalbasi
Consider block impls in `lookup_impl_assoc_item_for_trait_ref`

fix #14782
-rw-r--r--crates/hir-ty/src/consteval/tests.rs29
-rw-r--r--crates/hir-ty/src/method_resolution.rs12
-rw-r--r--crates/ide/src/goto_definition.rs23
3 files changed, 62 insertions, 2 deletions
diff --git a/crates/hir-ty/src/consteval/tests.rs b/crates/hir-ty/src/consteval/tests.rs
index b4b5fdd8916..b336fa5f0f0 100644
--- a/crates/hir-ty/src/consteval/tests.rs
+++ b/crates/hir-ty/src/consteval/tests.rs
@@ -504,6 +504,35 @@ fn trait_method() {
 }
 
 #[test]
+fn trait_method_inside_block() {
+    check_number(
+        r#"
+trait Twait {
+    fn a(&self) -> i32;
+}
+
+fn outer() -> impl Twait {
+    struct Stwuct;
+
+    impl Twait for Stwuct {
+        fn a(&self) -> i32 {
+            5
+        }
+    }
+    fn f() -> impl Twait {
+        let s = Stwuct;
+        s
+    }
+    f()
+}
+
+const GOAL: i32 = outer().a();
+        "#,
+        5,
+    );
+}
+
+#[test]
 fn generic_fn() {
     check_number(
         r#"
diff --git a/crates/hir-ty/src/method_resolution.rs b/crates/hir-ty/src/method_resolution.rs
index bf1e875858a..7208bebb3bd 100644
--- a/crates/hir-ty/src/method_resolution.rs
+++ b/crates/hir-ty/src/method_resolution.rs
@@ -729,8 +729,16 @@ fn lookup_impl_assoc_item_for_trait_ref(
     let self_ty = trait_ref.self_type_parameter(Interner);
     let self_ty_fp = TyFingerprint::for_trait_impl(&self_ty)?;
     let impls = db.trait_impls_in_deps(env.krate);
-    let impls =
-        impls.iter().flat_map(|impls| impls.for_trait_and_self_ty(hir_trait_id, self_ty_fp));
+    let self_impls = match self_ty.kind(Interner) {
+        TyKind::Adt(id, _) => {
+            id.0.module(db.upcast()).containing_block().map(|x| db.trait_impls_in_block(x))
+        }
+        _ => None,
+    };
+    let impls = impls
+        .iter()
+        .chain(self_impls.as_ref())
+        .flat_map(|impls| impls.for_trait_and_self_ty(hir_trait_id, self_ty_fp));
 
     let table = InferenceTable::new(db, env);
 
diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs
index 1518b495153..ef3f14d79d1 100644
--- a/crates/ide/src/goto_definition.rs
+++ b/crates/ide/src/goto_definition.rs
@@ -1497,6 +1497,29 @@ fn f() {
             );
         }
         #[test]
+        fn method_call_inside_block() {
+            check(
+                r#"
+trait Twait {
+    fn a(&self);
+}
+
+fn outer() {
+    struct Stwuct;
+
+    impl Twait for Stwuct {
+        fn a(&self){}
+         //^
+    }
+    fn f() {
+        let s = Stwuct;
+        s.a$0();
+    }
+}
+        "#,
+            );
+        }
+        #[test]
         fn path_call() {
             check(
                 r#"