@@ -4,7 +4,10 @@ use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, OverloadedDer
44use  rustc_session:: { declare_lint,  declare_lint_pass} ; 
55use  rustc_span:: sym; 
66
7- use  crate :: lints:: { ImplicitUnsafeAutorefsDiag ,  ImplicitUnsafeAutorefsSuggestion } ; 
7+ use  crate :: lints:: { 
8+     ImplicitUnsafeAutorefsDiag ,  ImplicitUnsafeAutorefsMethodNote ,  ImplicitUnsafeAutorefsOrigin , 
9+     ImplicitUnsafeAutorefsSuggestion , 
10+ } ; 
811use  crate :: { LateContext ,  LateLintPass ,  LintContext } ; 
912
1013declare_lint !  { 
@@ -92,25 +95,37 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitAutorefs {
9295            && let  adjustments = peel_derefs_adjustments ( & * * adjustments) 
9396            // 3. An automatically inserted reference (might come from a deref). 
9497            && let  [ adjustment]  = adjustments
95-             && let  Some ( borrow_mutbl)  = has_implicit_borrow ( adjustment) 
98+             && let  Some ( ( borrow_mutbl,  through_overloaded_deref ) )  = has_implicit_borrow ( adjustment) 
9699            && let  ExprKind :: Unary ( UnOp :: Deref ,  dereferenced)  =
97100                // 2. Any number of place projections. 
98101                peel_place_mappers ( inner) . kind 
99102            // 1. Deref of a raw pointer. 
100103            && typeck. expr_ty ( dereferenced) . is_raw_ptr ( ) 
101-             // PERF: 5. b. A method call annotated with `#[rustc_no_implicit_refs]` 
102-             && match  expr. kind  { 
103-                 ExprKind :: MethodCall ( ..)  => matches ! ( 
104-                     cx. typeck_results( ) . type_dependent_def_id( expr. hir_id) , 
105-                     Some ( def_id)  if  cx. tcx. has_attr( def_id,  sym:: rustc_no_implicit_autorefs) 
106-                 ) , 
107-                 _ => true , 
104+             && let  method_did = match  expr. kind  { 
105+                 // PERF: 5. b. A method call annotated with `#[rustc_no_implicit_refs]` 
106+                 ExprKind :: MethodCall ( ..)  => cx. typeck_results ( ) . type_dependent_def_id ( expr. hir_id ) , 
107+                 _ => None , 
108108            } 
109+             && method_did. map ( |did| cx. tcx . has_attr ( did,  sym:: rustc_no_implicit_autorefs) ) . unwrap_or ( true ) 
109110        { 
110111            cx. emit_span_lint ( 
111112                DANGEROUS_IMPLICIT_AUTOREFS , 
112113                expr. span . source_callsite ( ) , 
113114                ImplicitUnsafeAutorefsDiag  { 
115+                     raw_ptr_span :  dereferenced. span , 
116+                     raw_ptr_ty :  typeck. expr_ty ( dereferenced) , 
117+                     origin :  if  through_overloaded_deref { 
118+                         ImplicitUnsafeAutorefsOrigin :: OverloadedDeref 
119+                     }  else  { 
120+                         ImplicitUnsafeAutorefsOrigin :: Autoref  { 
121+                             autoref_span :  inner. span , 
122+                             autoref_ty :  typeck. expr_ty_adjusted ( inner) , 
123+                         } 
124+                     } , 
125+                     method :  method_did. map ( |did| ImplicitUnsafeAutorefsMethodNote  { 
126+                         def_span :  cx. tcx . def_span ( did) , 
127+                         method_name :  cx. tcx . item_name ( did) , 
128+                     } ) , 
114129                    suggestion :  ImplicitUnsafeAutorefsSuggestion  { 
115130                        mutbl :  borrow_mutbl. ref_prefix_str ( ) , 
116131                        deref :  if  is_coming_from_deref {  "*"  }  else  {  ""  } , 
@@ -146,11 +161,12 @@ fn peel_derefs_adjustments<'a>(mut adjs: &'a [Adjustment<'a>]) -> &'a [Adjustmen
146161
147162/// Test if some adjustment has some implicit borrow. 
148163/// 
149- /// Returns `Some(mutability)` if the argument adjustment has implicit borrow in it. 
150- fn  has_implicit_borrow ( Adjustment  {  kind,  .. } :  & Adjustment < ' _ > )  -> Option < Mutability >  { 
164+ /// Returns `Some((mutability, was_an_overloaded_deref))` if the argument adjustment is 
165+ /// an implicit borrow (or has an implicit borrow via an overloaded deref). 
166+ fn  has_implicit_borrow ( Adjustment  {  kind,  .. } :  & Adjustment < ' _ > )  -> Option < ( Mutability ,  bool ) >  { 
151167    match  kind { 
152-         & Adjust :: Deref ( Some ( OverloadedDeref  {  mutbl,  .. } ) )  => Some ( mutbl) , 
153-         & Adjust :: Borrow ( AutoBorrow :: Ref ( mutbl) )  => Some ( mutbl. into ( ) ) , 
168+         & Adjust :: Deref ( Some ( OverloadedDeref  {  mutbl,  .. } ) )  => Some ( ( mutbl,   true ) ) , 
169+         & Adjust :: Borrow ( AutoBorrow :: Ref ( mutbl) )  => Some ( ( mutbl. into ( ) ,   false ) ) , 
154170        Adjust :: NeverToAny 
155171        | Adjust :: Pointer ( ..) 
156172        | Adjust :: ReborrowPin ( ..) 
0 commit comments