@@ -184,19 +184,22 @@ impl Dereferencing {
184
184
}
185
185
}
186
186
187
+ #[ derive( Debug ) ]
187
188
struct StateData {
188
189
/// Span of the top level expression
189
190
span : Span ,
190
191
hir_id : HirId ,
191
192
position : Position ,
192
193
}
193
194
195
+ #[ derive( Debug ) ]
194
196
struct DerefedBorrow {
195
197
count : usize ,
196
198
msg : & ' static str ,
197
199
snip_expr : Option < HirId > ,
198
200
}
199
201
202
+ #[ derive( Debug ) ]
200
203
enum State {
201
204
// Any number of deref method calls.
202
205
DerefMethod {
@@ -276,10 +279,12 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing {
276
279
( None , kind) => {
277
280
let expr_ty = typeck. expr_ty ( expr) ;
278
281
let ( position, adjustments) = walk_parents ( cx, expr, self . msrv ) ;
279
-
280
282
match kind {
281
283
RefOp :: Deref => {
282
- if let Position :: FieldAccess ( name) = position
284
+ if let Position :: FieldAccess {
285
+ name,
286
+ of_union : false ,
287
+ } = position
283
288
&& !ty_contains_field ( typeck. expr_ty ( sub_expr) , name)
284
289
{
285
290
self . state = Some ( (
@@ -451,7 +456,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing {
451
456
( Some ( ( State :: DerefedBorrow ( state) , data) ) , RefOp :: Deref ) => {
452
457
let position = data. position ;
453
458
report ( cx, expr, State :: DerefedBorrow ( state) , data) ;
454
- if let Position :: FieldAccess ( name) = position
459
+ if let Position :: FieldAccess { name, .. } = position
455
460
&& !ty_contains_field ( typeck. expr_ty ( sub_expr) , name)
456
461
{
457
462
self . state = Some ( (
@@ -616,14 +621,17 @@ fn deref_method_same_type<'tcx>(result_ty: Ty<'tcx>, arg_ty: Ty<'tcx>) -> bool {
616
621
}
617
622
618
623
/// The position of an expression relative to it's parent.
619
- #[ derive( Clone , Copy ) ]
624
+ #[ derive( Clone , Copy , Debug ) ]
620
625
enum Position {
621
626
MethodReceiver ,
622
627
/// The method is defined on a reference type. e.g. `impl Foo for &T`
623
628
MethodReceiverRefImpl ,
624
629
Callee ,
625
630
ImplArg ( HirId ) ,
626
- FieldAccess ( Symbol ) ,
631
+ FieldAccess {
632
+ name : Symbol ,
633
+ of_union : bool ,
634
+ } , // union fields cannot be auto borrowed
627
635
Postfix ,
628
636
Deref ,
629
637
/// Any other location which will trigger auto-deref to a specific time.
@@ -645,7 +653,10 @@ impl Position {
645
653
}
646
654
647
655
fn can_auto_borrow ( self ) -> bool {
648
- matches ! ( self , Self :: MethodReceiver | Self :: FieldAccess ( _) | Self :: Callee )
656
+ matches ! (
657
+ self ,
658
+ Self :: MethodReceiver | Self :: FieldAccess { of_union: false , .. } | Self :: Callee
659
+ )
649
660
}
650
661
651
662
fn lint_explicit_deref ( self ) -> bool {
@@ -657,7 +668,7 @@ impl Position {
657
668
Self :: MethodReceiver
658
669
| Self :: MethodReceiverRefImpl
659
670
| Self :: Callee
660
- | Self :: FieldAccess ( _ )
671
+ | Self :: FieldAccess { .. }
661
672
| Self :: Postfix => PREC_POSTFIX ,
662
673
Self :: ImplArg ( _) | Self :: Deref => PREC_PREFIX ,
663
674
Self :: DerefStable ( p, _) | Self :: ReborrowStable ( p) | Self :: Other ( p) => p,
@@ -844,7 +855,10 @@ fn walk_parents<'tcx>(
844
855
}
845
856
} )
846
857
} ,
847
- ExprKind :: Field ( child, name) if child. hir_id == e. hir_id => Some ( Position :: FieldAccess ( name. name ) ) ,
858
+ ExprKind :: Field ( child, name) if child. hir_id == e. hir_id => Some ( Position :: FieldAccess {
859
+ name : name. name ,
860
+ of_union : is_union ( cx. typeck_results ( ) , child) ,
861
+ } ) ,
848
862
ExprKind :: Unary ( UnOp :: Deref , child) if child. hir_id == e. hir_id => Some ( Position :: Deref ) ,
849
863
ExprKind :: Match ( child, _, MatchSource :: TryDesugar | MatchSource :: AwaitDesugar )
850
864
| ExprKind :: Index ( child, _)
@@ -865,6 +879,13 @@ fn walk_parents<'tcx>(
865
879
( position, adjustments)
866
880
}
867
881
882
+ fn is_union < ' tcx > ( typeck : & ' tcx TypeckResults < ' _ > , path_expr : & ' tcx Expr < ' _ > ) -> bool {
883
+ typeck
884
+ . expr_ty_adjusted ( path_expr)
885
+ . ty_adt_def ( )
886
+ . map_or ( false , rustc_middle:: ty:: AdtDef :: is_union)
887
+ }
888
+
868
889
fn closure_result_position < ' tcx > (
869
890
cx : & LateContext < ' tcx > ,
870
891
closure : & ' tcx Closure < ' _ > ,
0 commit comments