Change:
// Apply debuginfo to the newly allocated locals. fx.debug_introduce_locals(&mut start_bx); <del> let reachable_blocks = mir.reachable_blocks_in_mono(cx.tcx(), instance); </del> // The builders will be created separately for each basic block at `codegen_block`. // So drop the builder of `start_llbb` to avoid having two at the same time. drop(start_bx); <ins> let reachable_blocks = traversal::mono_reachable_as_bitset(mir, cx.tcx(), instance); </ins> // Codegen the body of each block using reverse postorder for (bb, _) in traversal::reverse_postorder(mir) { if reachable_blocks.contains(bb) { fx.codegen_block(bb); } else { <del> // This may have references to things we didn't monomorphize, so we // don't actually codegen the body. We still create the block so // terminators in other blocks can reference it without worry. </del> <ins> // We want to skip this block, because it's not reachable. But we still create // the block so terminators in other blocks can reference it. </ins> fx.codegen_block_as_unreachable(bb); } }

Discussion:
tracking issue: Inspired by comment in For things like it'd be nice to not have to even give LLVM the code for the else branch to have to emit. Ought to save time and binary size. Tentatively marked mir-opt, since we presumably still need to make the MIR for it, in order to borrow-check and such the unreachable code. But might need to be codegen-time instead to pick up on monomorphized inline constants. Hopefully should be doable relatively easily when the const is an inline const, since that forces const folding already, and thus there should just be a in the MIR.
Well, turns out this already works for simple constants in MIR! However, the place I actually needed it was more like , which doesn't work with today. So maybe come back to this once that's fixed.
This should be done by which AFAIK is run unconditionally. I wonder if its match needs to be expanded? Is there mcve?
The problem is that this can't be done on generic constants, as we don't mir-optimize post-monomorphization. We could start doing some benchmarks to see how bad running all mir opts (or at least a select few) would be if we duplicated, substituted and optimized MIR bodies for concrete generic parameters.
I would say qualifies as an MCVE as the monomorphized gives the following llvm ir
Maybe it should also be evaluated together with polymorphization or constevaluatablechecked since those can cut down on the duplication before applying further optimizations.
Bonus points if this can avoid monomorphizing functions called in the dead code too. Demo extracted from : (cc ) Would be great to not codegen all the downstream stuff that's only called in the else block of a .
FYI this should work with
Totally wild (and probably bad) idea: could we avoid borrow-checking unreachable code? After all, the purpose of borrow-checking is to prevent memory unsafety at runtime, but unreachable code cannot be memory unsafe, because it never executes!
We already do! As a , (But this isn't really the right issue to discuss possible extensions to that.)
This seems closely related to and
recent PR seems related here? If the condition becomes a constant during codegen, we should be entirely skipping it now and not even generate LLVM IR.

However, if that dead code calls functions, those still get codegen'd as usual -- the collector that determines which function to codegen doesn't know about dead branches. We'd have to embed a (simple) monomorphization-time reachability analysis in the collector to fix that.