diff --git a/src/librustc_mir/borrow_check/conflict_errors.rs b/src/librustc_mir/borrow_check/conflict_errors.rs index f464e58e36b15..e3a79b24cabe8 100644 --- a/src/librustc_mir/borrow_check/conflict_errors.rs +++ b/src/librustc_mir/borrow_check/conflict_errors.rs @@ -595,12 +595,11 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { ) -> (String, String, String, String) { // Define a small closure that we can use to check if the type of a place // is a union. - let is_union = |place: &Place<'tcx>| -> bool { - place.ty(self.mir, self.infcx.tcx).ty - .ty_adt_def() - .map(|adt| adt.is_union()) - .unwrap_or(false) + let union_ty = |place: &Place<'tcx>| -> Option> { + let ty = place.ty(self.mir, self.infcx.tcx).ty; + ty.ty_adt_def().filter(|adt| adt.is_union()).map(|_| ty) }; + let describe_place = |place| self.describe_place(place).unwrap_or_else(|| "_".to_owned()); // Start with an empty tuple, so we can use the functions on `Option` to reduce some // code duplication (particularly around returning an empty description in the failure @@ -619,7 +618,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { let mut current = first_borrowed_place; while let Place::Projection(box Projection { base, elem }) = current { match elem { - ProjectionElem::Field(field, _) if is_union(base) => { + ProjectionElem::Field(field, _) if union_ty(base).is_some() => { return Some((base, field)); }, _ => current = base, @@ -632,34 +631,32 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { // borrowed place and look for a access to a different field of the same union. let mut current = second_borrowed_place; while let Place::Projection(box Projection { base, elem }) = current { - match elem { - ProjectionElem::Field(field, _) if { - is_union(base) && field != target_field && base == target_base - } => { - let desc_base = self.describe_place(base) - .unwrap_or_else(|| "_".to_owned()); - let desc_first = self.describe_place(first_borrowed_place) - .unwrap_or_else(|| "_".to_owned()); - let desc_second = self.describe_place(second_borrowed_place) - .unwrap_or_else(|| "_".to_owned()); - - // Also compute the name of the union type, eg. `Foo` so we - // can add a helpful note with it. - let ty = base.ty(self.mir, self.infcx.tcx).ty; - - return Some((desc_base, desc_first, desc_second, ty.to_string())); - }, - _ => current = base, + if let ProjectionElem::Field(field, _) = elem { + if let Some(union_ty) = union_ty(base) { + if field != target_field && base == target_base { + return Some(( + describe_place(base), + describe_place(first_borrowed_place), + describe_place(second_borrowed_place), + union_ty.to_string(), + )); + } + } } + + current = base; } None }) .unwrap_or_else(|| { // If we didn't find a field access into a union, or both places match, then // only return the description of the first place. - let desc_place = self.describe_place(first_borrowed_place) - .unwrap_or_else(|| "_".to_owned()); - (desc_place, "".to_string(), "".to_string(), "".to_string()) + ( + describe_place(first_borrowed_place), + "".to_string(), + "".to_string(), + "".to_string(), + ) }) }