@@ -595,12 +595,11 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
595595 ) -> ( String , String , String , String ) {
596596 // Define a small closure that we can use to check if the type of a place
597597 // 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)
603601 } ;
602+ let describe_place = |place| self . describe_place ( place) . unwrap_or_else ( || "_" . to_owned ( ) ) ;
604603
605604 // Start with an empty tuple, so we can use the functions on `Option` to reduce some
606605 // code duplication (particularly around returning an empty description in the failure
@@ -619,7 +618,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
619618 let mut current = first_borrowed_place;
620619 while let Place :: Projection ( box Projection { base, elem } ) = current {
621620 match elem {
622- ProjectionElem :: Field ( field, _) if is_union ( base) => {
621+ ProjectionElem :: Field ( field, _) if union_ty ( base) . is_some ( ) => {
623622 return Some ( ( base, field) ) ;
624623 } ,
625624 _ => current = base,
@@ -632,34 +631,32 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
632631 // borrowed place and look for a access to a different field of the same union.
633632 let mut current = second_borrowed_place;
634633 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+ }
653645 }
646+
647+ current = base;
654648 }
655649 None
656650 } )
657651 . unwrap_or_else ( || {
658652 // If we didn't find a field access into a union, or both places match, then
659653 // 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+ )
663660 } )
664661 }
665662
0 commit comments