Skip to content

Commit c6f2d49

Browse files
committed
fix issue #78496
1 parent 8080f54 commit c6f2d49

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

compiler/rustc_mir/src/transform/early_otherwise_branch.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,34 @@ impl<'a, 'tcx> Helper<'a, 'tcx> {
283283
return None;
284284
}
285285

286+
// when one place is the projection of the other, it's not safe to calculate their discriminant values sequentially.
287+
// for example, this should not be optimized:
288+
//
289+
// ```rust
290+
// enum E<'a> { Empty, Some(&'a E<'a>), }
291+
// let Some(Some(_)) = e;
292+
// ```
293+
//
294+
// ```mir
295+
// bb0: {
296+
// _2 = discriminant(*_1)
297+
// switchInt(move _2) -> [...]
298+
// }
299+
// bb1: {
300+
// _3 = discriminant(*(((*_1) as Some).0: &E))
301+
// switchInt(move _3) -> [...]
302+
// }
303+
// ```
304+
let discr_place = discr_info.place_of_adt_discr_read;
305+
let this_discr_place = this_bb_discr_info.place_of_adt_discr_read;
306+
if discr_place.local == this_discr_place.local
307+
&& (discr_place.projection.starts_with(this_discr_place.projection)
308+
|| this_discr_place.projection.starts_with(discr_place.projection))
309+
{
310+
trace!("NO: one target is the projection of another");
311+
return None;
312+
}
313+
286314
// if we reach this point, the optimization applies, and we should be able to optimize this case
287315
// store the info that is needed to apply the optimization
288316

src/test/ui/mir/issue-78496.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// run-pass
2+
// compile-flags: -Z mir-opt-level=2 -C opt-level=0
3+
4+
// example from #68867
5+
pub enum E<'a> {
6+
Empty,
7+
Some(&'a E<'a>),
8+
}
9+
10+
fn f(e: &E) -> u32 {
11+
if let E::Some(E::Some(_)) = e { 1 } else { 2 }
12+
}
13+
14+
fn main() {
15+
assert_eq!(f(&E::Empty), 2);
16+
}

0 commit comments

Comments
 (0)