Skip to content

Commit b621757

Browse files
authoredMay 29, 2019
Rollup merge of rust-lang#61261 - spastorino:is-union-return-ty, r=oli-obk
is_union returns ty to avoid computing it twice r? @oli-obk
2 parents 5579f01 + bb94fc0 commit b621757

File tree

1 file changed

+24
-27
lines changed

1 file changed

+24
-27
lines changed
 

‎src/librustc_mir/borrow_check/conflict_errors.rs

+24-27
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)