@@ -2,7 +2,7 @@ use rustc_ast::{BorrowKind, UnOp};
22use rustc_hir:: { Expr , ExprKind , Mutability } ;
33use rustc_middle:: ty:: adjustment:: { Adjust , Adjustment , AutoBorrow , OverloadedDeref } ;
44use rustc_session:: { declare_lint, declare_lint_pass} ;
5- use rustc_span:: sym;
5+ use rustc_span:: { kw , sym} ;
66
77use crate :: lints:: { ImplicitUnsafeAutorefsDiag , ImplicitUnsafeAutorefsSuggestion } ;
88use crate :: { LateContext , LateLintPass , LintContext } ;
@@ -92,25 +92,30 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitAutorefs {
9292 && let adjustments = peel_derefs_adjustments ( & * * adjustments)
9393 // 3. An automatically inserted reference (might come from a deref).
9494 && let [ adjustment] = adjustments
95- && let Some ( borrow_mutbl) = has_implicit_borrow ( adjustment)
95+ && let Some ( ( borrow_mutbl, through_overloaded_deref ) ) = has_implicit_borrow ( adjustment)
9696 && let ExprKind :: Unary ( UnOp :: Deref , dereferenced) =
9797 // 2. Any number of place projections.
9898 peel_place_mappers ( inner) . kind
9999 // 1. Deref of a raw pointer.
100100 && typeck. expr_ty ( dereferenced) . is_raw_ptr ( )
101101 // 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 ,
102+ && let method_did = match expr. kind {
103+ ExprKind :: MethodCall ( ..) => cx. typeck_results ( ) . type_dependent_def_id ( expr. hir_id ) ,
104+ _ => None ,
108105 }
106+ && method_did. map ( |did| cx. tcx . has_attr ( did, sym:: rustc_no_implicit_autorefs) ) . unwrap_or ( true )
109107 {
110108 cx. emit_span_lint (
111109 DANGEROUS_IMPLICIT_AUTOREFS ,
112110 expr. span . source_callsite ( ) ,
113111 ImplicitUnsafeAutorefsDiag {
112+ raw_ptr_span : dereferenced. span ,
113+ raw_ptr_ty : typeck. expr_ty ( dereferenced) ,
114+ autoref_span : inner. span ,
115+ autoref_ty : typeck. expr_ty_adjusted ( inner) ,
116+ method_def_span : method_did. map ( |did| cx. tcx . def_span ( did) ) ,
117+ method_name : method_did. map ( |did| cx. tcx . item_name ( did) ) . unwrap_or ( kw:: Empty ) ,
118+ through_overloaded_deref,
114119 suggestion : ImplicitUnsafeAutorefsSuggestion {
115120 mutbl : borrow_mutbl. ref_prefix_str ( ) ,
116121 deref : if is_coming_from_deref { "*" } else { "" } ,
@@ -147,10 +152,10 @@ fn peel_derefs_adjustments<'a>(mut adjs: &'a [Adjustment<'a>]) -> &'a [Adjustmen
147152/// Test if some adjustment has some implicit borrow.
148153///
149154/// Returns `Some(mutability)` if the argument adjustment has implicit borrow in it.
150- fn has_implicit_borrow ( Adjustment { kind, .. } : & Adjustment < ' _ > ) -> Option < Mutability > {
155+ fn has_implicit_borrow ( Adjustment { kind, .. } : & Adjustment < ' _ > ) -> Option < ( Mutability , bool ) > {
151156 match kind {
152- & Adjust :: Deref ( Some ( OverloadedDeref { mutbl, .. } ) ) => Some ( mutbl) ,
153- & Adjust :: Borrow ( AutoBorrow :: Ref ( mutbl) ) => Some ( mutbl. into ( ) ) ,
157+ & Adjust :: Deref ( Some ( OverloadedDeref { mutbl, .. } ) ) => Some ( ( mutbl, true ) ) ,
158+ & Adjust :: Borrow ( AutoBorrow :: Ref ( mutbl) ) => Some ( ( mutbl. into ( ) , false ) ) ,
154159 Adjust :: NeverToAny
155160 | Adjust :: Pointer ( ..)
156161 | Adjust :: ReborrowPin ( ..)
0 commit comments