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
&& let ty::FnDef(def_id, fn_args) = *const_.ty().kind()
&& let Some(ty::AssocItem { fn_has_self_parameter: true, .. }) =
tcx.opt_associated_item(def_id)
&& let [Spanned { node: Operand::Move(self_place) | Operand::Copy(self_place), .. }, ..] =
**args
{ {
debug!("find_self_call: func={:?}", func); if self_place.as_local() == Some(local) {
if let Operand::Constant(box ConstOperand { const_, .. }) = func { return Some((def_id, fn_args));
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) // Handle the case where `self_place` gets reborrowed.
{ // This happens when the receiver is `&T`.
debug!("find_self_call: args={:?}", fn_args); for stmt in &body[block].statements {
if let [ if let StatementKind::Assign(box (place, rvalue)) = &stmt.kind
Spanned { && let Some(reborrow_local) = place.as_local()
node: Operand::Move(self_place) | Operand::Copy(self_place), .. && self_place.as_local() == Some(reborrow_local)
}, && let Rvalue::Ref(_, _, deref_place) = rvalue
.., && let PlaceRef { local: deref_local, projection: [ProjectionElem::Deref] } =
] = **args deref_place.as_ref()
{ && deref_local == local
if self_place.as_local() == Some(local) { {
return Some((def_id, fn_args)); 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
| |