Skip to content

Commit cd65cd2

Browse files
Improve find_self_call with reborrowed receiver
1 parent 3560a2b commit cd65cd2

2 files changed

Lines changed: 28 additions & 20 deletions

File tree

‎compiler/rustc_middle/src/util/find_self_call.rs‎

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,26 +17,29 @@ pub fn find_self_call<'tcx>(
1717
debug!("find_self_call(local={:?}): terminator={:?}", local, body[block].terminator);
1818
ifletSome(Terminator{kind:TerminatorKind::Call{ func, args, .. }, .. }) =
1919
&body[block].terminator
20+
&& letOperand::Constant(box ConstOperand{ const_, .. }) = func
21+
&& let ty::FnDef(def_id, fn_args) = *const_.ty().kind()
22+
&& letSome(ty::AssocItem{fn_has_self_parameter:true, .. }) =
23+
tcx.opt_associated_item(def_id)
24+
&& let[Spanned{node:Operand::Move(self_place) | Operand::Copy(self_place), .. }, ..] =
25+
**args
2026
{
21-
debug!("find_self_call: func={:?}", func);
22-
ifletOperand::Constant(box ConstOperand{ const_, .. }) = func {
23-
iflet ty::FnDef(def_id, fn_args) = *const_.ty().kind(){
24-
ifletSome(ty::AssocItem{fn_has_self_parameter:true, .. }) =
25-
tcx.opt_associated_item(def_id)
26-
{
27-
debug!("find_self_call: args={:?}", fn_args);
28-
iflet[
29-
Spanned{
30-
node:Operand::Move(self_place) | Operand::Copy(self_place), ..
31-
},
32-
..,
33-
] = **args
34-
{
35-
if self_place.as_local() == Some(local){
36-
returnSome((def_id, fn_args));
37-
}
38-
}
39-
}
27+
if self_place.as_local() == Some(local){
28+
returnSome((def_id, fn_args));
29+
}
30+
31+
// Handle the case where `self_place` gets reborrowed.
32+
// This happens when the receiver is `&T`.
33+
for stmt in&body[block].statements{
34+
ifletStatementKind::Assign(box (place, rvalue)) = &stmt.kind
35+
&& letSome(reborrow_local) = place.as_local()
36+
&& self_place.as_local() == Some(reborrow_local)
37+
&& letRvalue::Ref(_, _, deref_place) = rvalue
38+
&& letPlaceRef{local: deref_local,projection:[ProjectionElem::Deref]} =
39+
deref_place.as_ref()
40+
&& deref_local == local
41+
{
42+
returnSome((def_id, fn_args));
4043
}
4144
}
4245
}

‎tests/ui/lint/lint-const-item-mutation.stderr‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,15 @@ warning: taking a mutable reference to a `const` item
7575
--> $DIR/lint-const-item-mutation.rs:42:5
7676
|
7777
LL | (&mut MY_STRUCT).use_mut();
78-
| ^^^^^^^^^^^^^^^^
78+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
7979
|
8080
= note: each usage of a `const` item creates a new temporary
8181
= note: the mutable reference will refer to this temporary, not the original `const` item
82+
note: mutable reference created due to call to this method
83+
--> $DIR/lint-const-item-mutation.rs:9:5
84+
|
85+
LL | fn use_mut(&mut self) {}
86+
| ^^^^^^^^^^^^^^^^^^^^^
8287
note: `const` item defined here
8388
--> $DIR/lint-const-item-mutation.rs:27:1
8489
|

0 commit comments

Comments
 (0)