Always reborrow reference receiver in methods

This commit is contained in:
hkalbasi 2023-04-07 00:32:28 +03:30
parent ea22d245b6
commit 7ba93cb8cf
3 changed files with 39 additions and 2 deletions

View file

@ -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 { let refed = Canonical {
value: TyKind::Ref(Mutability::Not, static_lifetime(), receiver_ty.value.clone()) value: TyKind::Ref(Mutability::Not, static_lifetime(), receiver_ty.value.clone())

View file

@ -388,6 +388,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] #[test]
fn infer_trait_method_generic_1() { fn infer_trait_method_generic_1() {
// the trait implementation is intentionally incomplete -- it shouldn't matter // the trait implementation is intentionally incomplete -- it shouldn't matter
@ -1722,7 +1740,7 @@ fn test() {
Foo.foo(); Foo.foo();
//^^^ adjustments: Borrow(Ref(Not)) //^^^ adjustments: Borrow(Ref(Not))
(&Foo).foo(); (&Foo).foo();
// ^^^^ adjustments: , // ^^^^ adjustments: Deref(None), Borrow(Ref(Not))
} }
"#, "#,
); );

View file

@ -315,6 +315,8 @@ fn main() {
(&Struct).consume(); (&Struct).consume();
//^^^^^^^* //^^^^^^^*
(&Struct).by_ref(); (&Struct).by_ref();
//^^^^^^^&
//^^^^^^^*
(&mut Struct).consume(); (&mut Struct).consume();
//^^^^^^^^^^^* //^^^^^^^^^^^*
@ -322,6 +324,8 @@ fn main() {
//^^^^^^^^^^^& //^^^^^^^^^^^&
//^^^^^^^^^^^* //^^^^^^^^^^^*
(&mut Struct).by_ref_mut(); (&mut Struct).by_ref_mut();
//^^^^^^^^^^^&mut $
//^^^^^^^^^^^*
// Check that block-like expressions don't duplicate hints // Check that block-like expressions don't duplicate hints
let _: &mut [u32] = (&mut []); let _: &mut [u32] = (&mut []);
@ -414,6 +418,10 @@ fn main() {
//^^^^^^^) //^^^^^^^)
//^^^^^^^.* //^^^^^^^.*
(&Struct).by_ref(); (&Struct).by_ref();
//^^^^^^^(
//^^^^^^^)
//^^^^^^^.*
//^^^^^^^.&
(&mut Struct).consume(); (&mut Struct).consume();
//^^^^^^^^^^^( //^^^^^^^^^^^(
@ -425,6 +433,10 @@ fn main() {
//^^^^^^^^^^^.* //^^^^^^^^^^^.*
//^^^^^^^^^^^.& //^^^^^^^^^^^.&
(&mut Struct).by_ref_mut(); (&mut Struct).by_ref_mut();
//^^^^^^^^^^^(
//^^^^^^^^^^^)
//^^^^^^^^^^^.*
//^^^^^^^^^^^.&mut
// Check that block-like expressions don't duplicate hints // Check that block-like expressions don't duplicate hints
let _: &mut [u32] = (&mut []); let _: &mut [u32] = (&mut []);