Closed
Description
Right now, matches!()
generates MIR that sometimes has more branches than required. As an example:
fn foo(bar: Option<()>) {
if matches!(bar, None) {
stuff();
}
}
generates this MIR:
fn foo(_1: std::option::Option<()>) -> () {
debug bar => _1;
let mut _0: ();
let mut _2: bool;
let mut _3: isize;
let _4: ();
bb0: {
StorageLive(_2);
_3 = discriminant(_1);
switchInt(move _3) -> [0isize: bb2, otherwise: bb1];
}
bb1: {
_2 = const false;
goto -> bb3;
}
bb2: {
_2 = const true;
goto -> bb3;
}
bb3: {
switchInt(_2) -> [false: bb4, otherwise: bb5];
}
bb4: {
_0 = const ();
goto -> bb7;
}
bb5: {
StorageLive(_4);
_4 = const stuff() -> bb6;
}
bb6: {
StorageDead(_4);
_0 = const ();
goto -> bb7;
}
bb7: {
StorageDead(_2);
return;
}
}
Notice blocks bb0
, bb1
, bb2
and bb3
which we could transform into something like this:
bb0: {
StorageLive(_2);
_3 = discriminant(_1);
_2 = Eq(move _3, const 0isize);
switchInt(_2) -> [false: bb4, otherwise: bb5];
}
There may be a compile-time win since we can hand LLVM less code but the optimization would have to be implemented to be sure.
cc @rust-lang/wg-mir-opt