@@ -17,26 +17,29 @@ pub fn find_self_call<'tcx>(
1717 debug ! ( "find_self_call(local={:?}): terminator={:?}" , local, body[ block] . terminator) ;
1818 if let Some ( Terminator { kind : TerminatorKind :: Call { func, args, .. } , .. } ) =
1919 & body[ block] . terminator
20+ && let Operand :: Constant ( box ConstOperand { const_, .. } ) = func
21+ && let ty:: FnDef ( def_id, fn_args) = * const_. ty ( ) . kind ( )
22+ && let Some ( 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- if let Operand :: Constant ( box ConstOperand { const_, .. } ) = func {
23- if let ty:: FnDef ( def_id, fn_args) = * const_. ty ( ) . kind ( ) {
24- if let Some ( ty:: AssocItem { fn_has_self_parameter : true , .. } ) =
25- tcx. opt_associated_item ( def_id)
26- {
27- debug ! ( "find_self_call: args={:?}" , fn_args) ;
28- if let [
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- return Some ( ( def_id, fn_args) ) ;
37- }
38- }
39- }
27+ if self_place. as_local ( ) == Some ( local) {
28+ return Some ( ( 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+ if let StatementKind :: Assign ( box ( place, rvalue) ) = & stmt. kind
35+ && let Some ( reborrow_local) = place. as_local ( )
36+ && self_place. as_local ( ) == Some ( reborrow_local)
37+ && let Rvalue :: Ref ( _, _, deref_place) = rvalue
38+ && let PlaceRef { local : deref_local, projection : [ ProjectionElem :: Deref ] } =
39+ deref_place. as_ref ( )
40+ && deref_local == local
41+ {
42+ return Some ( ( def_id, fn_args) ) ;
4043 }
4144 }
4245 }
0 commit comments