diff --git a/crates/hir-ty/src/method_resolution.rs b/crates/hir-ty/src/method_resolution.rs index 5d06906aa3a..938427d8075 100644 --- a/crates/hir-ty/src/method_resolution.rs +++ b/crates/hir-ty/src/method_resolution.rs @@ -952,7 +952,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 @@ -388,6 +388,24 @@ fn 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 @@ -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 []);