@@ -2,7 +2,7 @@ use rustc_ast::{BorrowKind, UnOp};
2
2
use rustc_hir:: { Expr , ExprKind , Mutability } ;
3
3
use rustc_middle:: ty:: adjustment:: { Adjust , Adjustment , AutoBorrow , OverloadedDeref } ;
4
4
use rustc_session:: { declare_lint, declare_lint_pass} ;
5
- use rustc_span:: sym;
5
+ use rustc_span:: { kw , sym} ;
6
6
7
7
use crate :: lints:: { ImplicitUnsafeAutorefsDiag , ImplicitUnsafeAutorefsSuggestion } ;
8
8
use crate :: { LateContext , LateLintPass , LintContext } ;
@@ -92,25 +92,30 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitAutorefs {
92
92
&& let adjustments = peel_derefs_adjustments ( & * * adjustments)
93
93
// 3. An automatically inserted reference (might come from a deref).
94
94
&& let [ adjustment] = adjustments
95
- && let Some ( borrow_mutbl) = has_implicit_borrow ( adjustment)
95
+ && let Some ( ( borrow_mutbl, through_overloaded_deref ) ) = has_implicit_borrow ( adjustment)
96
96
&& let ExprKind :: Unary ( UnOp :: Deref , dereferenced) =
97
97
// 2. Any number of place projections.
98
98
peel_place_mappers ( inner) . kind
99
99
// 1. Deref of a raw pointer.
100
100
&& typeck. expr_ty ( dereferenced) . is_raw_ptr ( )
101
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 ,
102
+ && let method_did = match expr. kind {
103
+ ExprKind :: MethodCall ( ..) => cx. typeck_results ( ) . type_dependent_def_id ( expr. hir_id ) ,
104
+ _ => None ,
108
105
}
106
+ && method_did. map ( |did| cx. tcx . has_attr ( did, sym:: rustc_no_implicit_autorefs) ) . unwrap_or ( true )
109
107
{
110
108
cx. emit_span_lint (
111
109
DANGEROUS_IMPLICIT_AUTOREFS ,
112
110
expr. span . source_callsite ( ) ,
113
111
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,
114
119
suggestion : ImplicitUnsafeAutorefsSuggestion {
115
120
mutbl : borrow_mutbl. ref_prefix_str ( ) ,
116
121
deref : if is_coming_from_deref { "*" } else { "" } ,
@@ -147,10 +152,10 @@ fn peel_derefs_adjustments<'a>(mut adjs: &'a [Adjustment<'a>]) -> &'a [Adjustmen
147
152
/// Test if some adjustment has some implicit borrow.
148
153
///
149
154
/// 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 ) > {
151
156
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 ) ) ,
154
159
Adjust :: NeverToAny
155
160
| Adjust :: Pointer ( ..)
156
161
| Adjust :: ReborrowPin ( ..)
0 commit comments