@@ -595,12 +595,11 @@ 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
} ;
602
+ let describe_place = |place| self . describe_place ( place) . unwrap_or_else ( || "_" . to_owned ( ) ) ;
604
603
605
604
// Start with an empty tuple, so we can use the functions on `Option` to reduce some
606
605
// code duplication (particularly around returning an empty description in the failure
@@ -619,7 +618,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
619
618
let mut current = first_borrowed_place;
620
619
while let Place :: Projection ( box Projection { base, elem } ) = current {
621
620
match elem {
622
- ProjectionElem :: Field ( field, _) if is_union ( base) => {
621
+ ProjectionElem :: Field ( field, _) if union_ty ( base) . is_some ( ) => {
623
622
return Some ( ( base, field) ) ;
624
623
} ,
625
624
_ => current = base,
@@ -632,34 +631,32 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
632
631
// borrowed place and look for a access to a different field of the same union.
633
632
let mut current = second_borrowed_place;
634
633
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,
634
+ if let ProjectionElem :: Field ( field, _) = elem {
635
+ if let Some ( union_ty) = union_ty ( base) {
636
+ if field != target_field && base == target_base {
637
+ return Some ( (
638
+ describe_place ( base) ,
639
+ describe_place ( first_borrowed_place) ,
640
+ describe_place ( second_borrowed_place) ,
641
+ union_ty. to_string ( ) ,
642
+ ) ) ;
643
+ }
644
+ }
653
645
}
646
+
647
+ current = base;
654
648
}
655
649
None
656
650
} )
657
651
. unwrap_or_else ( || {
658
652
// If we didn't find a field access into a union, or both places match, then
659
653
// only return the description of the first place.
660
- let desc_place = self . describe_place ( first_borrowed_place)
661
- . unwrap_or_else ( || "_" . to_owned ( ) ) ;
662
- ( desc_place, "" . to_string ( ) , "" . to_string ( ) , "" . to_string ( ) )
654
+ (
655
+ describe_place ( first_borrowed_place) ,
656
+ "" . to_string ( ) ,
657
+ "" . to_string ( ) ,
658
+ "" . to_string ( ) ,
659
+ )
663
660
} )
664
661
}
665
662
0 commit comments