@@ -183,24 +183,24 @@ enum State {
183
183
} ,
184
184
DerefedBorrow ( DerefedBorrow ) ,
185
185
ExplicitDeref {
186
- // Span and id of the top-level deref expression if the parent expression is a borrow.
187
- deref_span_id : Option < ( Span , HirId ) > ,
186
+ mutability : Option < Mutability > ,
188
187
} ,
189
188
ExplicitDerefField {
190
189
name : Symbol ,
191
190
} ,
192
191
Reborrow {
193
- deref_span : Span ,
194
- deref_hir_id : HirId ,
192
+ mutability : Mutability ,
193
+ } ,
194
+ Borrow {
195
+ mutability : Mutability ,
195
196
} ,
196
- Borrow ,
197
197
}
198
198
199
199
// A reference operation considered by this lint pass
200
200
enum RefOp {
201
201
Method ( Mutability ) ,
202
202
Deref ,
203
- AddrOf ,
203
+ AddrOf ( Mutability ) ,
204
204
}
205
205
206
206
struct RefPat {
@@ -263,7 +263,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing {
263
263
) ) ;
264
264
} else if position. is_deref_stable ( ) {
265
265
self . state = Some ( (
266
- State :: ExplicitDeref { deref_span_id : None } ,
266
+ State :: ExplicitDeref { mutability : None } ,
267
267
StateData { span : expr. span , hir_id : expr. hir_id , position } ,
268
268
) ) ;
269
269
}
@@ -289,7 +289,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing {
289
289
} ,
290
290
) ) ;
291
291
} ,
292
- RefOp :: AddrOf => {
292
+ RefOp :: AddrOf ( mutability ) => {
293
293
// Find the number of times the borrow is auto-derefed.
294
294
let mut iter = adjustments. iter ( ) ;
295
295
let mut deref_count = 0usize ;
@@ -359,7 +359,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing {
359
359
) ) ;
360
360
} else if position. is_deref_stable ( ) {
361
361
self . state = Some ( (
362
- State :: Borrow ,
362
+ State :: Borrow { mutability } ,
363
363
StateData {
364
364
span : expr. span ,
365
365
hir_id : expr. hir_id ,
@@ -395,7 +395,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing {
395
395
data,
396
396
) ) ;
397
397
} ,
398
- ( Some ( ( State :: DerefedBorrow ( state) , data) ) , RefOp :: AddrOf ) if state. count != 0 => {
398
+ ( Some ( ( State :: DerefedBorrow ( state) , data) ) , RefOp :: AddrOf ( _ ) ) if state. count != 0 => {
399
399
self . state = Some ( (
400
400
State :: DerefedBorrow ( DerefedBorrow {
401
401
count : state. count - 1 ,
@@ -404,12 +404,12 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing {
404
404
data,
405
405
) ) ;
406
406
} ,
407
- ( Some ( ( State :: DerefedBorrow ( state) , data) ) , RefOp :: AddrOf ) => {
407
+ ( Some ( ( State :: DerefedBorrow ( state) , data) ) , RefOp :: AddrOf ( mutability ) ) => {
408
408
let position = data. position ;
409
409
report ( cx, expr, State :: DerefedBorrow ( state) , data) ;
410
410
if position. is_deref_stable ( ) {
411
411
self . state = Some ( (
412
- State :: Borrow ,
412
+ State :: Borrow { mutability } ,
413
413
StateData {
414
414
span : expr. span ,
415
415
hir_id : expr. hir_id ,
@@ -430,43 +430,28 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing {
430
430
) ) ;
431
431
} else if position. is_deref_stable ( ) {
432
432
self . state = Some ( (
433
- State :: ExplicitDeref { deref_span_id : None } ,
433
+ State :: ExplicitDeref { mutability : None } ,
434
434
StateData { span : expr. span , hir_id : expr. hir_id , position } ,
435
435
) ) ;
436
436
}
437
437
} ,
438
438
439
- ( Some ( ( State :: Borrow , data) ) , RefOp :: Deref ) => {
439
+ ( Some ( ( State :: Borrow { mutability } , data) ) , RefOp :: Deref ) => {
440
440
if typeck. expr_ty ( sub_expr) . is_ref ( ) {
441
- self . state = Some ( (
442
- State :: Reborrow {
443
- deref_span : expr. span ,
444
- deref_hir_id : expr. hir_id ,
445
- } ,
446
- data,
447
- ) ) ;
441
+ self . state = Some ( ( State :: Reborrow { mutability } , data) ) ;
448
442
} else {
449
443
self . state = Some ( (
450
444
State :: ExplicitDeref {
451
- deref_span_id : Some ( ( expr . span , expr . hir_id ) ) ,
445
+ mutability : Some ( mutability ) ,
452
446
} ,
453
447
data,
454
448
) ) ;
455
449
}
456
450
} ,
457
- (
458
- Some ( (
459
- State :: Reborrow {
460
- deref_span,
461
- deref_hir_id,
462
- } ,
463
- data,
464
- ) ) ,
465
- RefOp :: Deref ,
466
- ) => {
451
+ ( Some ( ( State :: Reborrow { mutability } , data) ) , RefOp :: Deref ) => {
467
452
self . state = Some ( (
468
453
State :: ExplicitDeref {
469
- deref_span_id : Some ( ( deref_span , deref_hir_id ) ) ,
454
+ mutability : Some ( mutability ) ,
470
455
} ,
471
456
data,
472
457
) ) ;
@@ -573,7 +558,7 @@ fn try_parse_ref_op<'tcx>(
573
558
ExprKind :: Unary ( UnOp :: Deref , sub_expr) if !typeck. expr_ty ( sub_expr) . is_unsafe_ptr ( ) => {
574
559
return Some ( ( RefOp :: Deref , sub_expr) ) ;
575
560
} ,
576
- ExprKind :: AddrOf ( BorrowKind :: Ref , _ , sub_expr) => return Some ( ( RefOp :: AddrOf , sub_expr) ) ,
561
+ ExprKind :: AddrOf ( BorrowKind :: Ref , mutability , sub_expr) => return Some ( ( RefOp :: AddrOf ( mutability ) , sub_expr) ) ,
577
562
_ => return None ,
578
563
} ;
579
564
if tcx. is_diagnostic_item ( sym:: deref_method, def_id) {
@@ -1074,7 +1059,7 @@ fn report<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, state: State, data
1074
1059
diag. span_suggestion ( data. span , "change this to" , sugg, app) ;
1075
1060
} ) ;
1076
1061
} ,
1077
- State :: ExplicitDeref { deref_span_id } => {
1062
+ State :: ExplicitDeref { mutability } => {
1078
1063
if matches ! (
1079
1064
expr. kind,
1080
1065
ExprKind :: Block ( ..)
@@ -1088,29 +1073,33 @@ fn report<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, state: State, data
1088
1073
return ;
1089
1074
}
1090
1075
1091
- let ( span , hir_id , precedence) = if let Some ( ( span , hir_id ) ) = deref_span_id
1076
+ let ( prefix , precedence) = if let Some ( mutability ) = mutability
1092
1077
&& !cx. typeck_results ( ) . expr_ty ( expr) . is_ref ( )
1093
1078
{
1094
- ( span, hir_id, PREC_PREFIX )
1079
+ let prefix = match mutability {
1080
+ Mutability :: Not => "&" ,
1081
+ Mutability :: Mut => "&mut " ,
1082
+ } ;
1083
+ ( prefix, 0 )
1095
1084
} else {
1096
- ( data . span , data . hir_id , data. position . precedence ( ) )
1085
+ ( "" , data. position . precedence ( ) )
1097
1086
} ;
1098
1087
span_lint_hir_and_then (
1099
1088
cx,
1100
1089
EXPLICIT_AUTO_DEREF ,
1101
- hir_id,
1102
- span,
1090
+ data . hir_id ,
1091
+ data . span ,
1103
1092
"deref which would be done by auto-deref" ,
1104
1093
|diag| {
1105
1094
let mut app = Applicability :: MachineApplicable ;
1106
- let ( snip, snip_is_macro) = snippet_with_context ( cx, expr. span , span. ctxt ( ) , ".." , & mut app) ;
1095
+ let ( snip, snip_is_macro) = snippet_with_context ( cx, expr. span , data . span . ctxt ( ) , ".." , & mut app) ;
1107
1096
let sugg =
1108
1097
if !snip_is_macro && expr. precedence ( ) . order ( ) < precedence && !has_enclosing_paren ( & snip) {
1109
- format ! ( "({})" , snip)
1098
+ format ! ( "{} ({})" , prefix , snip)
1110
1099
} else {
1111
- snip . into ( )
1100
+ format ! ( "{}{}" , prefix , snip )
1112
1101
} ;
1113
- diag. span_suggestion ( span, "try this" , sugg, app) ;
1102
+ diag. span_suggestion ( data . span , "try this" , sugg, app) ;
1114
1103
} ,
1115
1104
) ;
1116
1105
} ,
@@ -1141,7 +1130,7 @@ fn report<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, state: State, data
1141
1130
} ,
1142
1131
) ;
1143
1132
} ,
1144
- State :: Borrow | State :: Reborrow { .. } => ( ) ,
1133
+ State :: Borrow { .. } | State :: Reborrow { .. } => ( ) ,
1145
1134
}
1146
1135
}
1147
1136
0 commit comments