The previous design was described in terms of the "pure" MIR control-flow graph. However, using the raw graph has some undesirable properties around infinite loops. In such cases, the graph has no exit, which undermines the traditional definition of reverse analyses like liveness. To address this, when we build the control-flow graph for our functions, we will augment it with additional edges -- in particular, for every infinite loop ( loop { } ), we will add false "unwind" edges. This ensures that the control-flow graph has a final exit node (the success of the RETURN and RESUME nodes) that postdominates all other nodes in the graph.
Like the title, what's false unwind edges? what's unwind?
And what's the success of the RETURN and RESUME nodes?
I think this quote means that for purpose of analysis, every loop {} is converted internally to something like loop { if false { panic!() } }, i.e. with unreachable but formally existing exit.
Most liveliness algorithms work by starting at a return statement and working backwards in the control-flow graph to see which variables are alive/used at each node. This breaks down when you've got infinite loops though, because execution will never leave the loop (i.e. there is no "return" statement after it) and therefore nothing inside it will ever be considered alive.
It sounds like they are using "false unwinds" as a dummy node to ensure the loop gets checked for liveliness.
I mean ... how does code (which will be transformed into a RESUME node in MIR) look like?
I need an example because I can't understand the compiler source code...
Integer overflow panics on debug build. Obviously 1 + 1 never overflow, but recognizing it requires some level of compiler optimization but the debug build doesn't do most of them.
Edit: I found the 1 + 1 is optimized out by the MIR optimizer which still is enabled on debug build. So you need to pass rustc flag -Zmir-opt-level=0 to see the panic code.