about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-04-06 21:18:15 +0000
committerbors <bors@rust-lang.org>2023-04-06 21:18:15 +0000
commite739c999cd23e3114187d889755eb897e02989ea (patch)
tree674efb8ed771973d9f18b94a5fb7e49d70fca3d2
parentca0f6bbf2f963273362257de390eaee8d75deb1d (diff)
parent7ba93cb8cf964ca9f5dbf5d51f69f2221b9bd2e9 (diff)
downloadrust-e739c999cd23e3114187d889755eb897e02989ea.tar.gz
rust-e739c999cd23e3114187d889755eb897e02989ea.zip
Auto merge of #14511 - HKalbasi:dev, r=Veykril
Always reborrow mutable reference receiver in methods

Dependency of #14470
-rw-r--r--crates/hir-ty/src/method_resolution.rs9
-rw-r--r--crates/hir-ty/src/tests/method_resolution.rs20
-rw-r--r--crates/ide/src/inlay_hints/adjustment.rs12
3 files changed, 39 insertions, 2 deletions
diff --git a/crates/hir-ty/src/method_resolution.rs b/crates/hir-ty/src/method_resolution.rs
index b04029d54bc..740b6ddc27a 100644
--- a/crates/hir-ty/src/method_resolution.rs
+++ b/crates/hir-ty/src/method_resolution.rs
@@ -954,7 +954,14 @@ fn iterate_method_candidates_with_autoref(
         )
     };
 
-    iterate_method_candidates_by_receiver(receiver_ty, first_adjustment.clone())?;
+    let mut maybe_reborrowed = first_adjustment.clone();
+    if let Some((_, _, m)) = receiver_ty.value.as_reference() {
+        // Prefer reborrow of references to move
+        maybe_reborrowed.autoref = Some(m);
+        maybe_reborrowed.autoderefs += 1;
+    }
+
+    iterate_method_candidates_by_receiver(receiver_ty, maybe_reborrowed)?;
 
     let refed = Canonical {
         value: TyKind::Ref(Mutability::Not, static_lifetime(), receiver_ty.value.clone())
diff --git a/crates/hir-ty/src/tests/method_resolution.rs b/crates/hir-ty/src/tests/method_resolution.rs
index f3ca93672d9..f62a3cfabe8 100644
--- a/crates/hir-ty/src/tests/method_resolution.rs
+++ b/crates/hir-ty/src/tests/method_resolution.rs
@@ -389,6 +389,24 @@ mod bar_test {
 }
 
 #[test]
+fn infer_trait_method_multiple_mutable_reference() {
+    check_types(
+        r#"
+trait Trait {
+    fn method(&mut self) -> i32 { 5 }
+}
+struct S;
+impl Trait for &mut &mut S {}
+fn test() {
+    let s = &mut &mut &mut S;
+    s.method();
+  //^^^^^^^^^^ i32
+}
+        "#,
+    );
+}
+
+#[test]
 fn infer_trait_method_generic_1() {
     // the trait implementation is intentionally incomplete -- it shouldn't matter
     check_types(
@@ -1722,7 +1740,7 @@ fn test() {
     Foo.foo();
   //^^^ adjustments: Borrow(Ref(Not))
     (&Foo).foo();
-  // ^^^^ adjustments: ,
+  // ^^^^ adjustments: Deref(None), Borrow(Ref(Not))
 }
 "#,
     );
diff --git a/crates/ide/src/inlay_hints/adjustment.rs b/crates/ide/src/inlay_hints/adjustment.rs
index f279c91a9e9..0b146091956 100644
--- a/crates/ide/src/inlay_hints/adjustment.rs
+++ b/crates/ide/src/inlay_hints/adjustment.rs
@@ -315,6 +315,8 @@ fn main() {
     (&Struct).consume();
    //^^^^^^^*
     (&Struct).by_ref();
+   //^^^^^^^&
+   //^^^^^^^*
 
     (&mut Struct).consume();
    //^^^^^^^^^^^*
@@ -322,6 +324,8 @@ fn main() {
    //^^^^^^^^^^^&
    //^^^^^^^^^^^*
     (&mut Struct).by_ref_mut();
+   //^^^^^^^^^^^&mut $
+   //^^^^^^^^^^^*
 
     // Check that block-like expressions don't duplicate hints
     let _: &mut [u32] = (&mut []);
@@ -414,6 +418,10 @@ fn main() {
    //^^^^^^^)
    //^^^^^^^.*
     (&Struct).by_ref();
+   //^^^^^^^(
+   //^^^^^^^)
+   //^^^^^^^.*
+   //^^^^^^^.&
 
     (&mut Struct).consume();
    //^^^^^^^^^^^(
@@ -425,6 +433,10 @@ fn main() {
    //^^^^^^^^^^^.*
    //^^^^^^^^^^^.&
     (&mut Struct).by_ref_mut();
+   //^^^^^^^^^^^(
+   //^^^^^^^^^^^)
+   //^^^^^^^^^^^.*
+   //^^^^^^^^^^^.&mut
 
     // Check that block-like expressions don't duplicate hints
     let _: &mut [u32] = (&mut []);