@@ -184,19 +184,22 @@ impl Dereferencing {
184184 }
185185}
186186
187+ #[ derive( Debug ) ]
187188struct StateData {
188189 /// Span of the top level expression
189190 span : Span ,
190191 hir_id : HirId ,
191192 position : Position ,
192193}
193194
195+ #[ derive( Debug ) ]
194196struct DerefedBorrow {
195197 count : usize ,
196198 msg : & ' static str ,
197199 snip_expr : Option < HirId > ,
198200}
199201
202+ #[ derive( Debug ) ]
200203enum State {
201204 // Any number of deref method calls.
202205 DerefMethod {
@@ -276,10 +279,12 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing {
276279 ( None , kind) => {
277280 let expr_ty = typeck. expr_ty ( expr) ;
278281 let ( position, adjustments) = walk_parents ( cx, expr, self . msrv ) ;
279-
280282 match kind {
281283 RefOp :: Deref => {
282- if let Position :: FieldAccess ( name) = position
284+ if let Position :: FieldAccess {
285+ name,
286+ of_union : false ,
287+ } = position
283288 && !ty_contains_field ( typeck. expr_ty ( sub_expr) , name)
284289 {
285290 self . state = Some ( (
@@ -451,7 +456,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing {
451456 ( Some ( ( State :: DerefedBorrow ( state) , data) ) , RefOp :: Deref ) => {
452457 let position = data. position ;
453458 report ( cx, expr, State :: DerefedBorrow ( state) , data) ;
454- if let Position :: FieldAccess ( name) = position
459+ if let Position :: FieldAccess { name, .. } = position
455460 && !ty_contains_field ( typeck. expr_ty ( sub_expr) , name)
456461 {
457462 self . state = Some ( (
@@ -616,14 +621,17 @@ fn deref_method_same_type<'tcx>(result_ty: Ty<'tcx>, arg_ty: Ty<'tcx>) -> bool {
616621}
617622
618623/// The position of an expression relative to it's parent.
619- #[ derive( Clone , Copy ) ]
624+ #[ derive( Clone , Copy , Debug ) ]
620625enum Position {
621626 MethodReceiver ,
622627 /// The method is defined on a reference type. e.g. `impl Foo for &T`
623628 MethodReceiverRefImpl ,
624629 Callee ,
625630 ImplArg ( HirId ) ,
626- FieldAccess ( Symbol ) ,
631+ FieldAccess {
632+ name : Symbol ,
633+ of_union : bool ,
634+ } , // union fields cannot be auto borrowed
627635 Postfix ,
628636 Deref ,
629637 /// Any other location which will trigger auto-deref to a specific time.
@@ -645,7 +653,10 @@ impl Position {
645653 }
646654
647655 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+ )
649660 }
650661
651662 fn lint_explicit_deref ( self ) -> bool {
@@ -657,7 +668,7 @@ impl Position {
657668 Self :: MethodReceiver
658669 | Self :: MethodReceiverRefImpl
659670 | Self :: Callee
660- | Self :: FieldAccess ( _ )
671+ | Self :: FieldAccess { .. }
661672 | Self :: Postfix => PREC_POSTFIX ,
662673 Self :: ImplArg ( _) | Self :: Deref => PREC_PREFIX ,
663674 Self :: DerefStable ( p, _) | Self :: ReborrowStable ( p) | Self :: Other ( p) => p,
@@ -844,7 +855,10 @@ fn walk_parents<'tcx>(
844855 }
845856 } )
846857 } ,
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+ } ) ,
848862 ExprKind :: Unary ( UnOp :: Deref , child) if child. hir_id == e. hir_id => Some ( Position :: Deref ) ,
849863 ExprKind :: Match ( child, _, MatchSource :: TryDesugar | MatchSource :: AwaitDesugar )
850864 | ExprKind :: Index ( child, _)
@@ -865,6 +879,13 @@ fn walk_parents<'tcx>(
865879 ( position, adjustments)
866880}
867881
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+
868889fn closure_result_position < ' tcx > (
869890 cx : & LateContext < ' tcx > ,
870891 closure : & ' tcx Closure < ' _ > ,
0 commit comments