@@ -434,11 +434,13 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
434434 fn visit_basic_block_data ( & mut self , bb : BasicBlock , block : & BasicBlockData < ' tcx > ) {
435435 trace ! ( "visit_basic_block_data: bb={:?} is_cleanup={:?}" , bb, block. is_cleanup) ;
436436
437- // Just as the old checker did, we skip const-checking basic blocks on the unwind path.
438- // These blocks often drop locals that would otherwise be returned from the function.
437+ // We don't const-check basic blocks on the cleanup path since we never unwind during
438+ // const-eval: a panic causes an immediate compile error. In other words, cleanup blocks
439+ // are unreachable during const-eval.
439440 //
440- // FIXME: This shouldn't be unsound since a panic at compile time will cause a compiler
441- // error anyway, but maybe we should do more here?
441+ // We can't be more conservative (e.g., by const-checking cleanup blocks anyways) because
442+ // locals that would never be dropped during normal execution are sometimes dropped during
443+ // unwinding, which means backwards-incompatible live-drop errors.
442444 if block. is_cleanup {
443445 return ;
444446 }
@@ -879,8 +881,11 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
879881 self . check_op ( ops:: Generator ( hir:: GeneratorKind :: Gen ) )
880882 }
881883
882- TerminatorKind :: Abort
883- | TerminatorKind :: Assert { .. }
884+ TerminatorKind :: Abort => {
885+ span_bug ! ( self . span, "`Abort` terminator outside of cleanup block" )
886+ }
887+
888+ TerminatorKind :: Assert { .. }
884889 | TerminatorKind :: FalseEdge { .. }
885890 | TerminatorKind :: FalseUnwind { .. }
886891 | TerminatorKind :: Goto { .. }
0 commit comments