Improve find_self_call with reborrowed receiver
This commit is contained in:
parent
3560a2b399
commit
cd65cd27db
2 changed files with 28 additions and 20 deletions
|
@ -17,26 +17,29 @@ pub fn find_self_call<'tcx>(
|
||||||
debug!("find_self_call(local={:?}): terminator={:?}", local, body[block].terminator);
|
debug!("find_self_call(local={:?}): terminator={:?}", local, body[block].terminator);
|
||||||
if let Some(Terminator { kind: TerminatorKind::Call { func, args, .. }, .. }) =
|
if let Some(Terminator { kind: TerminatorKind::Call { func, args, .. }, .. }) =
|
||||||
&body[block].terminator
|
&body[block].terminator
|
||||||
{
|
&& let Operand::Constant(box ConstOperand { const_, .. }) = func
|
||||||
debug!("find_self_call: func={:?}", func);
|
&& let ty::FnDef(def_id, fn_args) = *const_.ty().kind()
|
||||||
if let Operand::Constant(box ConstOperand { const_, .. }) = func {
|
&& let Some(ty::AssocItem { fn_has_self_parameter: true, .. }) =
|
||||||
if let ty::FnDef(def_id, fn_args) = *const_.ty().kind() {
|
|
||||||
if let Some(ty::AssocItem { fn_has_self_parameter: true, .. }) =
|
|
||||||
tcx.opt_associated_item(def_id)
|
tcx.opt_associated_item(def_id)
|
||||||
{
|
&& let [Spanned { node: Operand::Move(self_place) | Operand::Copy(self_place), .. }, ..] =
|
||||||
debug!("find_self_call: args={:?}", fn_args);
|
**args
|
||||||
if let [
|
|
||||||
Spanned {
|
|
||||||
node: Operand::Move(self_place) | Operand::Copy(self_place), ..
|
|
||||||
},
|
|
||||||
..,
|
|
||||||
] = **args
|
|
||||||
{
|
{
|
||||||
if self_place.as_local() == Some(local) {
|
if self_place.as_local() == Some(local) {
|
||||||
return Some((def_id, fn_args));
|
return Some((def_id, fn_args));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
// Handle the case where `self_place` gets reborrowed.
|
||||||
|
// This happens when the receiver is `&T`.
|
||||||
|
for stmt in &body[block].statements {
|
||||||
|
if let StatementKind::Assign(box (place, rvalue)) = &stmt.kind
|
||||||
|
&& let Some(reborrow_local) = place.as_local()
|
||||||
|
&& self_place.as_local() == Some(reborrow_local)
|
||||||
|
&& let Rvalue::Ref(_, _, deref_place) = rvalue
|
||||||
|
&& let PlaceRef { local: deref_local, projection: [ProjectionElem::Deref] } =
|
||||||
|
deref_place.as_ref()
|
||||||
|
&& deref_local == local
|
||||||
|
{
|
||||||
|
return Some((def_id, fn_args));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,10 +75,15 @@ warning: taking a mutable reference to a `const` item
|
||||||
--> $DIR/lint-const-item-mutation.rs:42:5
|
--> $DIR/lint-const-item-mutation.rs:42:5
|
||||||
|
|
|
|
||||||
LL | (&mut MY_STRUCT).use_mut();
|
LL | (&mut MY_STRUCT).use_mut();
|
||||||
| ^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: each usage of a `const` item creates a new temporary
|
= note: each usage of a `const` item creates a new temporary
|
||||||
= note: the mutable reference will refer to this temporary, not the original `const` item
|
= note: the mutable reference will refer to this temporary, not the original `const` item
|
||||||
|
note: mutable reference created due to call to this method
|
||||||
|
--> $DIR/lint-const-item-mutation.rs:9:5
|
||||||
|
|
|
||||||
|
LL | fn use_mut(&mut self) {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
note: `const` item defined here
|
note: `const` item defined here
|
||||||
--> $DIR/lint-const-item-mutation.rs:27:1
|
--> $DIR/lint-const-item-mutation.rs:27:1
|
||||||
|
|
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue