1
Fork 0

Improve find_self_call with reborrowed receiver

This commit is contained in:
Michael Goulet 2025-01-06 03:17:04 +00:00
parent 3560a2b399
commit cd65cd27db
2 changed files with 28 additions and 20 deletions

View file

@ -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));
} }
} }
} }

View file

@ -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
| |