@@ -595,11 +595,9 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
595
595
) -> ( String , String , String , String ) {
596
596
// Define a small closure that we can use to check if the type of a place
597
597
// is a union.
598
- let is_union = |place : & Place < ' tcx > | -> bool {
599
- place. ty ( self . mir , self . infcx . tcx ) . ty
600
- . ty_adt_def ( )
601
- . map ( |adt| adt. is_union ( ) )
602
- . unwrap_or ( false )
598
+ let union_ty = |place : & Place < ' tcx > | -> Option < Ty < ' tcx > > {
599
+ let ty = place. ty ( self . mir , self . infcx . tcx ) . ty ;
600
+ ty. ty_adt_def ( ) . filter ( |adt| adt. is_union ( ) ) . map ( |_| ty)
603
601
} ;
604
602
605
603
// Start with an empty tuple, so we can use the functions on `Option` to reduce some
@@ -619,7 +617,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
619
617
let mut current = first_borrowed_place;
620
618
while let Place :: Projection ( box Projection { base, elem } ) = current {
621
619
match elem {
622
- ProjectionElem :: Field ( field, _) if is_union ( base) => {
620
+ ProjectionElem :: Field ( field, _) if union_ty ( base) . is_some ( ) => {
623
621
return Some ( ( base, field) ) ;
624
622
} ,
625
623
_ => current = base,
@@ -632,25 +630,29 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
632
630
// borrowed place and look for a access to a different field of the same union.
633
631
let mut current = second_borrowed_place;
634
632
while let Place :: Projection ( box Projection { base, elem } ) = current {
635
- match elem {
636
- ProjectionElem :: Field ( field, _) if {
637
- is_union ( base) && field != target_field && base == target_base
638
- } => {
639
- let desc_base = self . describe_place ( base)
640
- . unwrap_or_else ( || "_" . to_owned ( ) ) ;
641
- let desc_first = self . describe_place ( first_borrowed_place)
642
- . unwrap_or_else ( || "_" . to_owned ( ) ) ;
643
- let desc_second = self . describe_place ( second_borrowed_place)
644
- . unwrap_or_else ( || "_" . to_owned ( ) ) ;
645
-
646
- // Also compute the name of the union type, eg. `Foo` so we
647
- // can add a helpful note with it.
648
- let ty = base. ty ( self . mir , self . infcx . tcx ) . ty ;
649
-
650
- return Some ( ( desc_base, desc_first, desc_second, ty. to_string ( ) ) ) ;
651
- } ,
652
- _ => current = base,
633
+ if let ProjectionElem :: Field ( field, _) = elem {
634
+ if let Some ( union_ty) = union_ty ( base) {
635
+ if field != target_field && base == target_base {
636
+ let desc_base =
637
+ self . describe_place ( base) . unwrap_or_else ( || "_" . to_owned ( ) ) ;
638
+ let desc_first = self
639
+ . describe_place ( first_borrowed_place)
640
+ . unwrap_or_else ( || "_" . to_owned ( ) ) ;
641
+ let desc_second = self
642
+ . describe_place ( second_borrowed_place)
643
+ . unwrap_or_else ( || "_" . to_owned ( ) ) ;
644
+
645
+ return Some ( (
646
+ desc_base,
647
+ desc_first,
648
+ desc_second,
649
+ union_ty. to_string ( ) ,
650
+ ) ) ;
651
+ }
652
+ }
653
653
}
654
+
655
+ current = base;
654
656
}
655
657
None
656
658
} )
0 commit comments