From d5d32e498515ca2a1c0828f9879ecd862980a2f3 Mon Sep 17 00:00:00 2001 From: Sladyn Nunes Date: Thu, 4 Jun 2026 22:08:07 -0700 Subject: [PATCH 1/2] Fix variable deallocation order in panic unwinding paths --- compiler/rustc_borrowck/src/lib.rs | 51 +++-- .../rustc_borrowck/src/session_diagnostics.rs | 16 ++ compiler/rustc_lint_defs/src/builtin.rs | 42 ++++ compiler/rustc_middle/src/mir/pretty.rs | 4 +- compiler/rustc_middle/src/mir/syntax.rs | 2 + compiler/rustc_mir_build/src/builder/scope.rs | 213 +++++++++++------- ...ignment.main.SimplifyCfg-initial.after.mir | 5 + ...n_conditional.test_complex.built.after.mir | 33 ++- ..._or_in_conditional.test_or.built.after.mir | 17 +- ...nst_array_len.built.after.panic-unwind.mir | 62 +++-- tests/mir-opt/building/unwind_drop_hint.rs | 24 ++ .../unwind_drop_hint.test.built.after.mir | 48 ++++ .../drop_hint_removed_after_borrowck.rs | 26 +++ ...orrowck.test.CleanupPostBorrowck.after.mir | 48 ++++ ...emoved_after_borrowck.test.built.after.mir | 48 ++++ tests/mir-opt/issue_91633.bar.built.after.mir | 2 + tests/mir-opt/issue_91633.foo.built.after.mir | 13 +- ...fg-initial.after-ElaborateDrops.after.diff | 30 ++- ...l_call_drops.f.built.after.panic-abort.mir | 12 +- ..._call_drops.f.built.after.panic-unwind.mir | 12 +- ...ops.f_with_arg.built.after.panic-abort.mir | 60 +++-- ...ps.f_with_arg.built.after.panic-unwind.mir | 60 +++-- .../drop/unwind-drop-order-future-compat.rs | 26 +++ .../unwind-drop-order-future-compat.stderr | 19 ++ 24 files changed, 684 insertions(+), 189 deletions(-) create mode 100644 tests/mir-opt/building/unwind_drop_hint.rs create mode 100644 tests/mir-opt/building/unwind_drop_hint.test.built.after.mir create mode 100644 tests/mir-opt/drop_hint_removed_after_borrowck.rs create mode 100644 tests/mir-opt/drop_hint_removed_after_borrowck.test.CleanupPostBorrowck.after.mir create mode 100644 tests/mir-opt/drop_hint_removed_after_borrowck.test.built.after.mir create mode 100644 tests/ui/drop/unwind-drop-order-future-compat.rs create mode 100644 tests/ui/drop/unwind-drop-order-future-compat.stderr diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 94ad74b67b629..1d88833814cfe 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -46,7 +46,7 @@ use rustc_mir_dataflow::move_paths::{ }; use rustc_mir_dataflow::points::DenseLocationMap; use rustc_mir_dataflow::{Analysis, EntryStates, Results, ResultsVisitor, visit_results}; -use rustc_session::lint::builtin::{TAIL_EXPR_DROP_ORDER, UNUSED_MUT}; +use rustc_session::lint::builtin::{TAIL_EXPR_DROP_ORDER, UNUSED_MUT, UNWIND_DROP_ORDER}; use rustc_span::{ErrorGuaranteed, Span, Symbol}; use smallvec::SmallVec; use tracing::{debug, instrument}; @@ -844,11 +844,8 @@ impl<'a, 'tcx> ResultsVisitor<'tcx, Borrowck<'a, 'tcx>> for MirBorrowckCtxt<'a, // These do not actually affect borrowck StatementKind::ConstEvalCounter | StatementKind::StorageLive(..) => {} // This does not affect borrowck - StatementKind::BackwardIncompatibleDropHint { - place, - reason: BackwardIncompatibleDropReason::Edition2024, - } => { - self.check_backward_incompatible_drop(location, **place, state); + StatementKind::BackwardIncompatibleDropHint { place, reason } => { + self.check_backward_incompatible_drop(location, **place, *reason, state); } StatementKind::StorageDead(local) => { self.access_place( @@ -1391,6 +1388,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { &mut self, location: Location, place: Place<'tcx>, + reason: BackwardIncompatibleDropReason, state: &BorrowckDomain, ) { let tcx = self.infcx.tcx; @@ -1424,17 +1422,36 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { borrow, Some((WriteKind::StorageDeadOrDrop, place)), ); - this.infcx.tcx.emit_node_span_lint( - TAIL_EXPR_DROP_ORDER, - CRATE_HIR_ID, - borrowed, - session_diagnostics::TailExprDropOrder { - borrowed, - callback: |diag| { - explain.add_explanation_to_diagnostic(&this, diag, "", None, None); - }, - }, - ); + match reason { + BackwardIncompatibleDropReason::Edition2024 => { + this.infcx.tcx.emit_node_span_lint( + TAIL_EXPR_DROP_ORDER, + CRATE_HIR_ID, + borrowed, + session_diagnostics::TailExprDropOrder { + borrowed, + callback: |diag| { + explain + .add_explanation_to_diagnostic(&this, diag, "", None, None); + }, + }, + ); + } + BackwardIncompatibleDropReason::UnwindStorageDead => { + this.infcx.tcx.emit_node_span_lint( + UNWIND_DROP_ORDER, + CRATE_HIR_ID, + borrowed, + session_diagnostics::UnwindDropOrder { + borrowed, + callback: |diag| { + explain + .add_explanation_to_diagnostic(&this, diag, "", None, None); + }, + }, + ); + } + } // We may stop at the first case ControlFlow::Break(()) }, diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs index cd4d1f16b21af..2359bc898c0cb 100644 --- a/compiler/rustc_borrowck/src/session_diagnostics.rs +++ b/compiler/rustc_borrowck/src/session_diagnostics.rs @@ -633,3 +633,19 @@ impl<'a, F: FnOnce(&mut Diag<'_, ()>)> Diagnostic<'a, ()> for TailExprDropOrder< diag } } + +pub(crate) struct UnwindDropOrder)> { + pub borrowed: Span, + pub callback: F, +} + +impl<'a, F: FnOnce(&mut Diag<'_, ()>)> Diagnostic<'a, ()> for UnwindDropOrder { + fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> { + let Self { borrowed, callback } = self; + let mut diag = + Diag::new(dcx, level, "relative drop order on unwind changing in a future release") + .with_span_label(borrowed, "this value would be considered dead on an unwind path"); + callback(&mut diag); + diag + } +} diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index d38b1cf47bd6f..0e0bbbdeeb1fd 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -150,6 +150,7 @@ pub mod hardwired { UNUSED_UNSAFE, UNUSED_VARIABLES, UNUSED_VISIBILITIES, + UNWIND_DROP_ORDER, USELESS_DEPRECATED, VARARGS_WITHOUT_PATTERN, WARNINGS, @@ -5233,6 +5234,47 @@ declare_lint! { }; } +declare_lint! { + /// The `unwind_drop_order` lint detects values whose relative drop order on + /// panic unwind paths will change in a future release. + /// + /// ### Example + /// ```rust,no_run + /// #![warn(unwind_drop_order)] + /// + /// struct Wrap(T); + /// + /// impl Drop for Wrap { + /// fn drop(&mut self) {} + /// } + /// + /// fn main() { + /// let x; + /// { + /// let y = 1; + /// x = Wrap(&y); + /// panic!(); + /// } + /// } + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// During panic unwinding, Rust currently does not mark locals as dead at + /// the same program points as normal control flow. A future release may + /// make unwind paths use the same storage-dead points as normal paths. This + /// lint reports code where that change can affect relative drop order + /// checking. + pub UNWIND_DROP_ORDER, + Allow, + "detects future changes to drop order during panic unwinding", + @future_incompatible = FutureIncompatibleInfo { + reason: fcw!(FutureReleaseSemanticsChange #147875), + }; +} + declare_lint! { /// The `rust_2024_guarded_string_incompatible_syntax` lint detects `#` tokens /// that will be parsed as part of a guarded string literal in Rust 2024. diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 942c36f343343..a95b95d7a363a 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -880,8 +880,8 @@ impl Debug for StatementKind<'_> { ConstEvalCounter => write!(fmt, "ConstEvalCounter"), Nop => write!(fmt, "nop"), BackwardIncompatibleDropHint { ref place, reason: _ } => { - // For now, we don't record the reason because there is only one use case, - // which is to report breaking change in drop order by Edition 2024 + // The reason is intentionally omitted to keep MIR diffs stable + // across future-compatibility lint implementation details. write!(fmt, "BackwardIncompatibleDropHint({place:?})") } } diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 91ff3f52390e1..945ffec197f83 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -975,6 +975,7 @@ pub enum TerminatorKind<'tcx> { #[derive( Clone, + Copy, Debug, TyEncodable, TyDecodable, @@ -986,6 +987,7 @@ pub enum TerminatorKind<'tcx> { )] pub enum BackwardIncompatibleDropReason { Edition2024, + UnwindStorageDead, } #[derive(Debug, Clone, TyEncodable, TyDecodable, Hash, StableHash, PartialEq)] diff --git a/compiler/rustc_mir_build/src/builder/scope.rs b/compiler/rustc_mir_build/src/builder/scope.rs index 84abb6ca70e70..d8543598c3b2a 100644 --- a/compiler/rustc_mir_build/src/builder/scope.rs +++ b/compiler/rustc_mir_build/src/builder/scope.rs @@ -157,7 +157,7 @@ struct DropData { /// local to drop local: Local, - /// Whether this is a value Drop or a StorageDead. + /// What kind of drop or drop-order marker this is. kind: DropKind, } @@ -166,6 +166,7 @@ pub(crate) enum DropKind { Value, Storage, ForLint, + StorageForLint, } #[derive(Debug)] @@ -254,21 +255,16 @@ struct DropNodeKey { } impl Scope { - /// Whether there's anything to do for the cleanup path, that is, - /// when unwinding through this scope. This includes destructors, - /// but not StorageDead statements, which don't get emitted at all - /// for unwinding, for several reasons: - /// * clang doesn't emit llvm.lifetime.end for C++ unwinding - /// * LLVM's memory dependency analysis can't handle it atm - /// * polluting the cleanup MIR with StorageDead creates - /// landing pads even though there's no actual destructors - /// * freeing up stack space has no effect during unwinding - /// Note that for coroutines we do emit StorageDeads, for the - /// use of optimizations in the MIR coroutine transform. + /// Whether unwinding through this scope needs a cleanup block. This includes + /// actual destructors (`Value`) and lint-only drop hints (`ForLint`). Storage + /// markers alone do not need cleanup blocks; on non-coroutine unwind paths, + /// when a cleanup block is needed for another reason, storage markers are + /// represented as `BackwardIncompatibleDropHint`s for future-compatibility + /// linting instead of as `StorageDead`. fn needs_cleanup(&self) -> bool { self.drops.iter().any(|drop| match drop.kind { DropKind::Value | DropKind::ForLint => true, - DropKind::Storage => false, + DropKind::Storage | DropKind::StorageForLint => false, }) } @@ -430,12 +426,19 @@ impl DropTree { }; cfg.terminate(block, drop_node.data.source_info, terminator); } - DropKind::ForLint => { + DropKind::ForLint | DropKind::StorageForLint => { + let reason = match drop_node.data.kind { + DropKind::ForLint => BackwardIncompatibleDropReason::Edition2024, + DropKind::StorageForLint => { + BackwardIncompatibleDropReason::UnwindStorageDead + } + DropKind::Value | DropKind::Storage => bug!("unexpected drop kind"), + }; let stmt = Statement::new( drop_node.data.source_info, StatementKind::BackwardIncompatibleDropHint { place: Box::new(drop_node.data.local.into()), - reason: BackwardIncompatibleDropReason::Edition2024, + reason, }, ); cfg.push(block, stmt); @@ -476,6 +479,39 @@ impl DropTree { } } +fn drop_for_unwind_path( + is_coroutine: bool, + emit_storage_lint_hints: bool, + drop: DropData, +) -> Option { + match drop.kind { + DropKind::Value | DropKind::ForLint => Some(drop), + DropKind::Storage if is_coroutine => Some(drop), + DropKind::Storage if emit_storage_lint_hints => { + Some(DropData { kind: DropKind::StorageForLint, ..drop }) + } + DropKind::Storage => None, + DropKind::StorageForLint => bug!("StorageForLint should not be scheduled in scopes"), + } +} + +fn advance_unwind_to(unwind_drops: &DropTree, unwind_to: &mut DropIdx, drop: DropData) { + advance_unwind_to_kind(unwind_drops, unwind_to, drop, drop.kind); +} + +fn advance_unwind_to_kind( + unwind_drops: &DropTree, + unwind_to: &mut DropIdx, + drop: DropData, + expected_kind: DropKind, +) { + debug_assert_ne!(*unwind_to, DropIdx::MAX); + let unwind_drop = unwind_drops.drop_nodes[*unwind_to].data; + debug_assert_eq!(unwind_drop.local, drop.local); + debug_assert_eq!(unwind_drop.kind, expected_kind); + *unwind_to = unwind_drops.drop_nodes[*unwind_to].next; +} + impl<'tcx> Scopes<'tcx> { pub(crate) fn new() -> Self { Self { @@ -1121,6 +1157,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { DUMMY_SP, ); let typing_env = self.typing_env(); + let storage_marker_on_unwind = self.scopes.scopes[1..] + .iter() + .rev() + .skip(1) + .any(|scope| scope.needs_cleanup()) + .then_some(if self.coroutine.is_some() { + DropKind::Storage + } else { + DropKind::StorageForLint + }); let unwind_drops = &mut self.scopes.unwind_drops; // the innermost scope contains only the destructors for the tail call arguments @@ -1131,24 +1177,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let source_info = drop_data.source_info; let local = drop_data.local; - if !self.local_decls[local].ty.needs_drop(self.tcx, typing_env) { - continue; - } - match drop_data.kind { DropKind::Value => { + if !self.local_decls[local].ty.needs_drop(self.tcx, typing_env) { + continue; + } + // `unwind_to` should drop the value that we're about to // schedule. If dropping this value panics, then we continue // with the *next* value on the unwind path. - debug_assert_eq!( - unwind_drops.drop_nodes[unwind_to].data.local, - drop_data.local - ); - debug_assert_eq!( - unwind_drops.drop_nodes[unwind_to].data.kind, - drop_data.kind - ); - unwind_to = unwind_drops.drop_nodes[unwind_to].next; + advance_unwind_to(unwind_drops, &mut unwind_to, *drop_data); let mut unwind_entry_point = unwind_to; @@ -1174,6 +1212,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block = next; } DropKind::ForLint => { + advance_unwind_to(unwind_drops, &mut unwind_to, *drop_data); self.cfg.push( block, Statement::new( @@ -1186,6 +1225,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ); } DropKind::Storage => { + if let Some(kind) = storage_marker_on_unwind { + advance_unwind_to_kind(unwind_drops, &mut unwind_to, *drop_data, kind); + } // Only temps and vars need their storage dead. assert!(local.index() > self.arg_count); self.cfg.push( @@ -1193,6 +1235,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Statement::new(source_info, StatementKind::StorageDead(local)), ); } + DropKind::StorageForLint => { + bug!("StorageForLint should not be scheduled in scopes") + } } } } @@ -1222,6 +1267,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let needs_cleanup = self.scopes.scopes.last().is_some_and(|scope| scope.needs_cleanup()); let is_coroutine = self.coroutine.is_some(); let unwind_to = if needs_cleanup { self.diverge_cleanup() } else { DropIdx::MAX }; + let storage_marker_on_unwind = needs_cleanup.then_some(if is_coroutine { + DropKind::Storage + } else { + DropKind::StorageForLint + }); let scope = self.scopes.scopes.last().expect("leave_top_scope called with no scopes"); let has_async_drops = is_coroutine @@ -1237,7 +1287,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block, unwind_to, dropline_to, - is_coroutine && needs_cleanup, + storage_marker_on_unwind, self.arg_count, |v: Local| Self::is_async_drop_impl(self.tcx, &self.local_decls, typing_env, v), ) @@ -1418,6 +1468,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } true } + DropKind::StorageForLint => bug!("StorageForLint should not be scheduled in scopes"), DropKind::Storage => { if local.index() <= self.arg_count { span_bug!( @@ -1475,9 +1526,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // // Since we only cache drops for the unwind path and the coroutine drop // path, we only need to invalidate the cache for drops that happen on - // the unwind or coroutine drop paths. This means that for - // non-coroutines we don't need to invalidate caches for `DropKind::Storage`. - let invalidate_caches = needs_drop || self.coroutine.is_some(); + // those paths. Non-coroutine storage drops can now affect the unwind + // tree through lint-only `BackwardIncompatibleDropHint`s when a scope + // has value/lint drops, so they must invalidate cached unwind chains in + // that case. + let storage_affects_unwind_cache = drop_kind == DropKind::Storage + && self.scopes.scopes.iter().any(|scope| scope.needs_cleanup()); + let invalidate_caches = + needs_drop || storage_affects_unwind_cache || self.coroutine.is_some(); for scope in self.scopes.scopes.iter_mut().rev() { if invalidate_caches { scope.invalidate_cache(); @@ -1626,10 +1682,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } let is_coroutine = self.coroutine.is_some(); + let needs_cleanup = + self.scopes.scopes[uncached_scope..=target].iter().any(|scope| scope.needs_cleanup()); + for scope in &mut self.scopes.scopes[uncached_scope..=target] { for drop in &scope.drops { - if is_coroutine || drop.kind == DropKind::Value { - cached_drop = self.scopes.unwind_drops.add_drop(*drop, cached_drop); + if let Some(drop) = drop_for_unwind_path(is_coroutine, needs_cleanup, *drop) { + cached_drop = self.scopes.unwind_drops.add_drop(drop, cached_drop); } } scope.cached_unwind_block = Some(cached_drop); @@ -1809,11 +1868,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// * `scope`, describes the drops that will occur on exiting the scope in regular execution /// * `block`, the block to branch to once drops are complete (assuming no unwind occurs) /// * `unwind_to`, describes the drops that would occur at this point in the code if a -/// panic occurred (a subset of the drops in `scope`, since we sometimes elide StorageDead and other -/// instructions on unwinding) +/// panic occurred (a subset of the drops in `scope`) /// * `dropline_to`, describes the drops that would occur at this point in the code if a /// coroutine drop occurred. -/// * `storage_dead_on_unwind`, if true, then we should emit `StorageDead` even when unwinding +/// * `storage_marker_on_unwind`, if present, is the unwind-tree marker corresponding to +/// `StorageDead` statements on the normal path. Coroutines use real `StorageDead` so the +/// coroutine transform can use storage liveness; non-coroutines use +/// `StorageForLint`, which lowers to `BackwardIncompatibleDropHint`. /// * `arg_count`, number of MIR local variables corresponding to fn arguments (used to assert that we don't drop those) fn build_scope_drops<'tcx, F>( cfg: &mut CFG<'tcx>, @@ -1823,7 +1884,7 @@ fn build_scope_drops<'tcx, F>( block: BasicBlock, unwind_to: DropIdx, dropline_to: Option, - storage_dead_on_unwind: bool, + storage_marker_on_unwind: Option, arg_count: usize, is_async_drop: F, ) -> BlockAnd<()> @@ -1846,10 +1907,11 @@ where // drops panic (panicking while unwinding will abort, so there's no need for // another set of arrows). // - // For coroutines, we unwind from a drop on a local to its StorageDead - // statement. For other functions we don't worry about StorageDead. The - // drops for the unwind path should have already been generated by - // `diverge_cleanup_gen`. + // For coroutines, we unwind from a drop on a local to its `StorageDead` + // statement. For other functions, we unwind to a `BackwardIncompatibleDropHint` + // at the same position instead. This lets borrowck issue future-compatibility + // lints without changing the accepted program set yet. The drops for the + // unwind path should have already been generated by `diverge_cleanup_gen`. // `unwind_to` indicates what needs to be dropped should unwinding occur. // This is a subset of what needs to be dropped when exiting the scope. @@ -1878,9 +1940,8 @@ where // // We adjust this BEFORE we create the drop (e.g., `drops[n]`) // because `drops[n]` should unwind to `drops[n-1]`. - debug_assert_eq!(unwind_drops.drop_nodes[unwind_to].data.local, drop_data.local); - debug_assert_eq!(unwind_drops.drop_nodes[unwind_to].data.kind, drop_data.kind); - unwind_to = unwind_drops.drop_nodes[unwind_to].next; + // + advance_unwind_to(unwind_drops, &mut unwind_to, *drop_data); if let Some(idx) = dropline_to { debug_assert_eq!(coroutine_drops.drop_nodes[idx].data.local, drop_data.local); @@ -1918,19 +1979,7 @@ where block = next; } DropKind::ForLint => { - // As in the `DropKind::Storage` case below: - // normally lint-related drops are not emitted for unwind, - // so we can just leave `unwind_to` unmodified, but in some - // cases we emit things ALSO on the unwind path, so we need to adjust - // `unwind_to` in that case. - if storage_dead_on_unwind { - debug_assert_eq!( - unwind_drops.drop_nodes[unwind_to].data.local, - drop_data.local - ); - debug_assert_eq!(unwind_drops.drop_nodes[unwind_to].data.kind, drop_data.kind); - unwind_to = unwind_drops.drop_nodes[unwind_to].next; - } + advance_unwind_to(unwind_drops, &mut unwind_to, *drop_data); // If the operand has been moved, and we are not on an unwind // path, then don't generate the drop. (We only take this into @@ -1952,18 +2001,8 @@ where ); } DropKind::Storage => { - // Ordinarily, storage-dead nodes are not emitted on unwind, so we don't - // need to adjust `unwind_to` on this path. However, in some specific cases - // we *do* emit storage-dead nodes on the unwind path, and in that case now that - // the storage-dead has completed, we need to adjust the `unwind_to` pointer - // so that any future drops we emit will not register storage-dead. - if storage_dead_on_unwind { - debug_assert_eq!( - unwind_drops.drop_nodes[unwind_to].data.local, - drop_data.local - ); - debug_assert_eq!(unwind_drops.drop_nodes[unwind_to].data.kind, drop_data.kind); - unwind_to = unwind_drops.drop_nodes[unwind_to].next; + if let Some(kind) = storage_marker_on_unwind { + advance_unwind_to_kind(unwind_drops, &mut unwind_to, *drop_data, kind); } if let Some(idx) = dropline_to { debug_assert_eq!(coroutine_drops.drop_nodes[idx].data.local, drop_data.local); @@ -1974,6 +2013,7 @@ where assert!(local.index() > arg_count); cfg.push(block, Statement::new(source_info, StatementKind::StorageDead(local))); } + DropKind::StorageForLint => bug!("StorageForLint should not be scheduled in scopes"), } } block.unit() @@ -1997,31 +2037,34 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> { // Link the exit drop tree to unwind drop tree. if drops.drop_nodes.iter().any(|drop_node| drop_node.data.kind == DropKind::Value) { let unwind_target = self.diverge_cleanup_target(else_scope, span); + let needs_cleanup = drops.drop_nodes.iter().any(|drop_node| { + matches!(drop_node.data.kind, DropKind::Value | DropKind::ForLint) + }); + let mut unwind_indices = IndexVec::from_elem_n(unwind_target, 1); for (drop_idx, drop_node) in drops.drop_nodes.iter_enumerated().skip(1) { - match drop_node.data.kind { - DropKind::Storage | DropKind::ForLint => { - if is_coroutine { - let unwind_drop = self - .scopes - .unwind_drops - .add_drop(drop_node.data, unwind_indices[drop_node.next]); - unwind_indices.push(unwind_drop); - } else { - unwind_indices.push(unwind_indices[drop_node.next]); - } - } - DropKind::Value => { + match drop_for_unwind_path(is_coroutine, needs_cleanup, drop_node.data) { + Some(drop_data @ DropData { kind: DropKind::Value, .. }) => { let unwind_drop = self .scopes .unwind_drops - .add_drop(drop_node.data, unwind_indices[drop_node.next]); + .add_drop(drop_data, unwind_indices[drop_node.next]); self.scopes.unwind_drops.add_entry_point( blocks[drop_idx].unwrap(), unwind_indices[drop_node.next], ); unwind_indices.push(unwind_drop); } + Some(drop_data) => { + let unwind_drop = self + .scopes + .unwind_drops + .add_drop(drop_data, unwind_indices[drop_node.next]); + unwind_indices.push(unwind_drop); + } + None => { + unwind_indices.push(unwind_indices[drop_node.next]); + } } } } @@ -2039,7 +2082,7 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> { .coroutine_drops .add_drop(drop_data.data, dropline_indices[drop_data.next]); match drop_data.data.kind { - DropKind::Storage | DropKind::ForLint => {} + DropKind::Storage | DropKind::ForLint | DropKind::StorageForLint => {} DropKind::Value => { if self.is_async_drop(drop_data.data.local) { self.scopes.coroutine_drops.add_entry_point( diff --git a/tests/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir b/tests/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir index aa7d75242b408..4943fb2ccb099 100644 --- a/tests/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir +++ b/tests/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir @@ -73,14 +73,19 @@ fn main() -> () { } bb6 (cleanup): { + StorageDead(_6); drop(_5) -> [return: bb7, unwind terminate(cleanup)]; } bb7 (cleanup): { + StorageDead(_5); drop(_4) -> [return: bb8, unwind terminate(cleanup)]; } bb8 (cleanup): { + StorageDead(_4); + StorageDead(_2); + StorageDead(_1); resume; } } diff --git a/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir b/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir index 327b3b618a03a..357f97cf4ab51 100644 --- a/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir +++ b/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir @@ -19,7 +19,7 @@ fn test_complex() -> () { bb0: { StorageLive(_1); StorageLive(_2); - _2 = E::f() -> [return: bb1, unwind: bb35]; + _2 = E::f() -> [return: bb1, unwind: bb38]; } bb1: { @@ -42,7 +42,7 @@ fn test_complex() -> () { bb5: { StorageLive(_4); - _4 = always_true() -> [return: bb6, unwind: bb35]; + _4 = always_true() -> [return: bb6, unwind: bb38]; } bb6: { @@ -64,7 +64,7 @@ fn test_complex() -> () { } bb9: { - drop(_7) -> [return: bb11, unwind: bb35]; + drop(_7) -> [return: bb11, unwind: bb37]; } bb10: { @@ -78,7 +78,7 @@ fn test_complex() -> () { } bb12: { - drop(_7) -> [return: bb13, unwind: bb35]; + drop(_7) -> [return: bb13, unwind: bb37]; } bb13: { @@ -98,7 +98,7 @@ fn test_complex() -> () { } bb15: { - drop(_10) -> [return: bb17, unwind: bb35]; + drop(_10) -> [return: bb17, unwind: bb36]; } bb16: { @@ -139,7 +139,7 @@ fn test_complex() -> () { StorageDead(_4); StorageDead(_1); StorageLive(_11); - _11 = always_true() -> [return: bb23, unwind: bb35]; + _11 = always_true() -> [return: bb23, unwind: bb38]; } bb23: { @@ -156,7 +156,7 @@ fn test_complex() -> () { bb26: { StorageLive(_12); - _12 = E::f() -> [return: bb27, unwind: bb35]; + _12 = E::f() -> [return: bb27, unwind: bb38]; } bb27: { @@ -199,6 +199,25 @@ fn test_complex() -> () { } bb35 (cleanup): { + StorageDead(_10); + StorageDead(_9); + StorageDead(_2); + goto -> bb38; + } + + bb36 (cleanup): { + StorageDead(_10); + StorageDead(_9); + goto -> bb38; + } + + bb37 (cleanup): { + StorageDead(_7); + StorageDead(_6); + goto -> bb38; + } + + bb38 (cleanup): { resume; } } diff --git a/tests/mir-opt/building/logical_or_in_conditional.test_or.built.after.mir b/tests/mir-opt/building/logical_or_in_conditional.test_or.built.after.mir index 2fc19e7e0fdcd..7aa8dd0a147b7 100644 --- a/tests/mir-opt/building/logical_or_in_conditional.test_or.built.after.mir +++ b/tests/mir-opt/building/logical_or_in_conditional.test_or.built.after.mir @@ -20,7 +20,7 @@ fn test_or() -> () { } bb1: { - drop(_3) -> [return: bb3, unwind: bb13]; + drop(_3) -> [return: bb3, unwind: bb14]; } bb2: { @@ -34,7 +34,7 @@ fn test_or() -> () { } bb4: { - drop(_3) -> [return: bb5, unwind: bb13]; + drop(_3) -> [return: bb5, unwind: bb14]; } bb5: { @@ -86,6 +86,19 @@ fn test_or() -> () { } bb13 (cleanup): { + StorageDead(_6); + StorageDead(_5); + goto -> bb15; + } + + bb14 (cleanup): { + StorageDead(_3); + StorageDead(_2); + goto -> bb15; + } + + bb15 (cleanup): { + StorageDead(_1); resume; } } diff --git a/tests/mir-opt/building/match/array_len.const_array_len.built.after.panic-unwind.mir b/tests/mir-opt/building/match/array_len.const_array_len.built.after.panic-unwind.mir index 8d16f074b1e34..d0c78d8ccdd4f 100644 --- a/tests/mir-opt/building/match/array_len.const_array_len.built.after.panic-unwind.mir +++ b/tests/mir-opt/building/match/array_len.const_array_len.built.after.panic-unwind.mir @@ -43,7 +43,7 @@ fn const_array_len(_1: [T; 5]) -> () { StorageLive(_6); StorageLive(_7); _7 = move _2; - _6 = opaque::(move _7) -> [return: bb3, unwind: bb17]; + _6 = opaque::(move _7) -> [return: bb3, unwind: bb20]; } bb3: { @@ -52,7 +52,7 @@ fn const_array_len(_1: [T; 5]) -> () { StorageLive(_8); StorageLive(_9); _9 = move _3; - _8 = opaque::(move _9) -> [return: bb4, unwind: bb16]; + _8 = opaque::(move _9) -> [return: bb4, unwind: bb18]; } bb4: { @@ -61,7 +61,7 @@ fn const_array_len(_1: [T; 5]) -> () { StorageLive(_10); StorageLive(_11); _11 = move _4; - _10 = opaque::<[T; 2]>(move _11) -> [return: bb5, unwind: bb15]; + _10 = opaque::<[T; 2]>(move _11) -> [return: bb5, unwind: bb16]; } bb5: { @@ -77,7 +77,7 @@ fn const_array_len(_1: [T; 5]) -> () { StorageDead(_13); StorageDead(_12); _0 = const (); - drop(_5) -> [return: bb8, unwind: bb19]; + drop(_5) -> [return: bb8, unwind: bb23]; } bb7: { @@ -87,17 +87,17 @@ fn const_array_len(_1: [T; 5]) -> () { bb8: { StorageDead(_5); - drop(_4) -> [return: bb9, unwind: bb20]; + drop(_4) -> [return: bb9, unwind: bb24]; } bb9: { StorageDead(_4); - drop(_3) -> [return: bb10, unwind: bb21]; + drop(_3) -> [return: bb10, unwind: bb25]; } bb10: { StorageDead(_3); - drop(_2) -> [return: bb11, unwind: bb22]; + drop(_2) -> [return: bb11, unwind: bb26]; } bb11: { @@ -106,7 +106,7 @@ fn const_array_len(_1: [T; 5]) -> () { } bb12: { - drop(_1) -> [return: bb13, unwind: bb23]; + drop(_1) -> [return: bb13, unwind: bb27]; } bb13: { @@ -114,42 +114,70 @@ fn const_array_len(_1: [T; 5]) -> () { } bb14 (cleanup): { - drop(_13) -> [return: bb18, unwind terminate(cleanup)]; + drop(_13) -> [return: bb15, unwind terminate(cleanup)]; } bb15 (cleanup): { - drop(_11) -> [return: bb18, unwind terminate(cleanup)]; + StorageDead(_13); + StorageDead(_12); + goto -> bb22; } bb16 (cleanup): { - drop(_9) -> [return: bb18, unwind terminate(cleanup)]; + drop(_11) -> [return: bb17, unwind terminate(cleanup)]; } bb17 (cleanup): { - drop(_7) -> [return: bb18, unwind terminate(cleanup)]; + StorageDead(_11); + StorageDead(_10); + goto -> bb22; } bb18 (cleanup): { - drop(_5) -> [return: bb19, unwind terminate(cleanup)]; + drop(_9) -> [return: bb19, unwind terminate(cleanup)]; } bb19 (cleanup): { - drop(_4) -> [return: bb20, unwind terminate(cleanup)]; + StorageDead(_9); + StorageDead(_8); + goto -> bb22; } bb20 (cleanup): { - drop(_3) -> [return: bb21, unwind terminate(cleanup)]; + drop(_7) -> [return: bb21, unwind terminate(cleanup)]; } bb21 (cleanup): { - drop(_2) -> [return: bb22, unwind terminate(cleanup)]; + StorageDead(_7); + StorageDead(_6); + goto -> bb22; } bb22 (cleanup): { - drop(_1) -> [return: bb23, unwind terminate(cleanup)]; + drop(_5) -> [return: bb23, unwind terminate(cleanup)]; } bb23 (cleanup): { + StorageDead(_5); + drop(_4) -> [return: bb24, unwind terminate(cleanup)]; + } + + bb24 (cleanup): { + StorageDead(_4); + drop(_3) -> [return: bb25, unwind terminate(cleanup)]; + } + + bb25 (cleanup): { + StorageDead(_3); + drop(_2) -> [return: bb26, unwind terminate(cleanup)]; + } + + bb26 (cleanup): { + StorageDead(_2); + drop(_1) -> [return: bb27, unwind terminate(cleanup)]; + } + + bb27 (cleanup): { resume; } } diff --git a/tests/mir-opt/building/unwind_drop_hint.rs b/tests/mir-opt/building/unwind_drop_hint.rs new file mode 100644 index 0000000000000..b4ab00b6c04eb --- /dev/null +++ b/tests/mir-opt/building/unwind_drop_hint.rs @@ -0,0 +1,24 @@ +//@ compile-flags: -Zmir-opt-level=0 +//@ skip-filecheck +// Non-coroutine unwind paths use BackwardIncompatibleDropHint where a future +// edition would insert StorageDead. + +// EMIT_MIR unwind_drop_hint.test.built.after.mir + +struct Droppable; + +impl Drop for Droppable { + fn drop(&mut self) {} +} + +fn test() { + let x = 42i32; + let y = Droppable; + may_panic(); +} + +fn may_panic() {} + +fn main() { + test(); +} diff --git a/tests/mir-opt/building/unwind_drop_hint.test.built.after.mir b/tests/mir-opt/building/unwind_drop_hint.test.built.after.mir new file mode 100644 index 0000000000000..9e1624ec9a2bb --- /dev/null +++ b/tests/mir-opt/building/unwind_drop_hint.test.built.after.mir @@ -0,0 +1,48 @@ +// MIR for `test` after built + +fn test() -> () { + let mut _0: (); + let _1: i32; + let _3: (); + scope 1 { + debug x => _1; + let _2: Droppable; + scope 2 { + debug y => _2; + } + } + + bb0: { + StorageLive(_1); + _1 = const 42_i32; + FakeRead(ForLet(None), _1); + StorageLive(_2); + _2 = Droppable; + FakeRead(ForLet(None), _2); + StorageLive(_3); + _3 = may_panic() -> [return: bb1, unwind: bb3]; + } + + bb1: { + StorageDead(_3); + _0 = const (); + drop(_2) -> [return: bb2, unwind: bb4]; + } + + bb2: { + StorageDead(_2); + StorageDead(_1); + return; + } + + bb3 (cleanup): { + BackwardIncompatibleDropHint(_3); + drop(_2) -> [return: bb4, unwind terminate(cleanup)]; + } + + bb4 (cleanup): { + BackwardIncompatibleDropHint(_2); + BackwardIncompatibleDropHint(_1); + resume; + } +} diff --git a/tests/mir-opt/drop_hint_removed_after_borrowck.rs b/tests/mir-opt/drop_hint_removed_after_borrowck.rs new file mode 100644 index 0000000000000..93c2dca527e71 --- /dev/null +++ b/tests/mir-opt/drop_hint_removed_after_borrowck.rs @@ -0,0 +1,26 @@ +//@ compile-flags: -Zmir-opt-level=0 +//@ test-mir-pass: CleanupPostBorrowck +//@ skip-filecheck +// BackwardIncompatibleDropHint is only needed for borrowck/linting and should be +// removed after borrowck by CleanupPostBorrowck. + +// EMIT_MIR drop_hint_removed_after_borrowck.test.built.after.mir +// EMIT_MIR drop_hint_removed_after_borrowck.test.CleanupPostBorrowck.after.mir + +struct Droppable; + +impl Drop for Droppable { + fn drop(&mut self) {} +} + +fn test() { + let x = 42i32; + let y = Droppable; + may_panic(); +} + +fn may_panic() {} + +fn main() { + test(); +} diff --git a/tests/mir-opt/drop_hint_removed_after_borrowck.test.CleanupPostBorrowck.after.mir b/tests/mir-opt/drop_hint_removed_after_borrowck.test.CleanupPostBorrowck.after.mir new file mode 100644 index 0000000000000..c41654f8dfe3f --- /dev/null +++ b/tests/mir-opt/drop_hint_removed_after_borrowck.test.CleanupPostBorrowck.after.mir @@ -0,0 +1,48 @@ +// MIR for `test` after CleanupPostBorrowck + +fn test() -> () { + let mut _0: (); + let _1: i32; + let _3: (); + scope 1 { + debug x => _1; + let _2: Droppable; + scope 2 { + debug y => _2; + } + } + + bb0: { + StorageLive(_1); + _1 = const 42_i32; + nop; + StorageLive(_2); + _2 = Droppable; + nop; + StorageLive(_3); + _3 = may_panic() -> [return: bb1, unwind: bb3]; + } + + bb1: { + StorageDead(_3); + _0 = const (); + drop(_2) -> [return: bb2, unwind: bb4]; + } + + bb2: { + StorageDead(_2); + StorageDead(_1); + return; + } + + bb3 (cleanup): { + nop; + drop(_2) -> [return: bb4, unwind terminate(cleanup)]; + } + + bb4 (cleanup): { + nop; + nop; + resume; + } +} diff --git a/tests/mir-opt/drop_hint_removed_after_borrowck.test.built.after.mir b/tests/mir-opt/drop_hint_removed_after_borrowck.test.built.after.mir new file mode 100644 index 0000000000000..9e1624ec9a2bb --- /dev/null +++ b/tests/mir-opt/drop_hint_removed_after_borrowck.test.built.after.mir @@ -0,0 +1,48 @@ +// MIR for `test` after built + +fn test() -> () { + let mut _0: (); + let _1: i32; + let _3: (); + scope 1 { + debug x => _1; + let _2: Droppable; + scope 2 { + debug y => _2; + } + } + + bb0: { + StorageLive(_1); + _1 = const 42_i32; + FakeRead(ForLet(None), _1); + StorageLive(_2); + _2 = Droppable; + FakeRead(ForLet(None), _2); + StorageLive(_3); + _3 = may_panic() -> [return: bb1, unwind: bb3]; + } + + bb1: { + StorageDead(_3); + _0 = const (); + drop(_2) -> [return: bb2, unwind: bb4]; + } + + bb2: { + StorageDead(_2); + StorageDead(_1); + return; + } + + bb3 (cleanup): { + BackwardIncompatibleDropHint(_3); + drop(_2) -> [return: bb4, unwind terminate(cleanup)]; + } + + bb4 (cleanup): { + BackwardIncompatibleDropHint(_2); + BackwardIncompatibleDropHint(_1); + resume; + } +} diff --git a/tests/mir-opt/issue_91633.bar.built.after.mir b/tests/mir-opt/issue_91633.bar.built.after.mir index 53829588a1b36..0cb9da79b5a0f 100644 --- a/tests/mir-opt/issue_91633.bar.built.after.mir +++ b/tests/mir-opt/issue_91633.bar.built.after.mir @@ -33,6 +33,8 @@ fn bar(_1: Box<[T]>) -> () { } bb4 (cleanup): { + StorageDead(_3); + StorageDead(_2); drop(_1) -> [return: bb5, unwind terminate(cleanup)]; } diff --git a/tests/mir-opt/issue_91633.foo.built.after.mir b/tests/mir-opt/issue_91633.foo.built.after.mir index 53f48350596ee..d003419f2c8ec 100644 --- a/tests/mir-opt/issue_91633.foo.built.after.mir +++ b/tests/mir-opt/issue_91633.foo.built.after.mir @@ -34,12 +34,12 @@ fn foo(_1: Box<[T]>) -> T { FakeRead(ForLet(None), _2); StorageDead(_4); _0 = move _2; - drop(_2) -> [return: bb3, unwind: bb5]; + drop(_2) -> [return: bb3, unwind: bb6]; } bb3: { StorageDead(_2); - drop(_1) -> [return: bb4, unwind: bb6]; + drop(_1) -> [return: bb4, unwind: bb7]; } bb4: { @@ -47,10 +47,17 @@ fn foo(_1: Box<[T]>) -> T { } bb5 (cleanup): { - drop(_1) -> [return: bb6, unwind terminate(cleanup)]; + StorageDead(_3); + StorageDead(_4); + goto -> bb6; } bb6 (cleanup): { + StorageDead(_2); + drop(_1) -> [return: bb7, unwind terminate(cleanup)]; + } + + bb7 (cleanup): { resume; } } diff --git a/tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff b/tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff index 484bc7dad1289..f96045bb69448 100644 --- a/tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff +++ b/tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff @@ -110,7 +110,7 @@ - bb10: { + bb7: { _0 = const 1_i32; -- drop(_7) -> [return: bb19, unwind: bb25]; +- drop(_7) -> [return: bb19, unwind: bb26]; + drop(_7) -> [return: bb16, unwind: bb22]; } @@ -224,7 +224,7 @@ } - bb22: { -- drop(_2) -> [return: bb24, unwind: bb26]; +- drop(_2) -> [return: bb24, unwind: bb28]; + bb19: { + goto -> bb26; } @@ -233,7 +233,7 @@ + bb20: { StorageDead(_8); StorageDead(_6); -- drop(_2) -> [return: bb24, unwind: bb26]; +- drop(_2) -> [return: bb24, unwind: bb28]; + drop(_2) -> [return: bb21, unwind: bb23]; } @@ -243,20 +243,30 @@ } - bb25 (cleanup): { -- drop(_2) -> [return: bb26, unwind terminate(cleanup)]; +- StorageDead(_16); +- StorageDead(_15); + bb22 (cleanup): { -+ goto -> bb27; + goto -> bb27; } - bb26 (cleanup): { +- StorageDead(_7); +- StorageDead(_5); +- StorageDead(_8); +- StorageDead(_6); +- goto -> bb27; + bb23 (cleanup): { - resume; -+ } -+ ++ resume; + } + +- bb27 (cleanup): { +- drop(_2) -> [return: bb28, unwind terminate(cleanup)]; + bb24: { + goto -> bb21; -+ } -+ + } + +- bb28 (cleanup): { +- resume; + bb25 (cleanup): { + goto -> bb23; + } diff --git a/tests/mir-opt/tail_call_drops.f.built.after.panic-abort.mir b/tests/mir-opt/tail_call_drops.f.built.after.panic-abort.mir index e017424a4ccdd..29bd0c6312bae 100644 --- a/tests/mir-opt/tail_call_drops.f.built.after.panic-abort.mir +++ b/tests/mir-opt/tail_call_drops.f.built.after.panic-abort.mir @@ -24,7 +24,7 @@ fn f() -> () { bb0: { StorageLive(_2); - _2 = String::new() -> [return: bb1, unwind: bb17]; + _2 = String::new() -> [return: bb1, unwind: bb18]; } bb1: { @@ -100,18 +100,28 @@ fn f() -> () { } bb14 (cleanup): { + StorageDead(_7); + StorageDead(_6); drop(_5) -> [return: bb15, unwind terminate(cleanup)]; } bb15 (cleanup): { + StorageDead(_5); drop(_4) -> [return: bb16, unwind terminate(cleanup)]; } bb16 (cleanup): { + StorageDead(_4); + StorageDead(_3); drop(_2) -> [return: bb17, unwind terminate(cleanup)]; } bb17 (cleanup): { + StorageDead(_2); + goto -> bb18; + } + + bb18 (cleanup): { resume; } } diff --git a/tests/mir-opt/tail_call_drops.f.built.after.panic-unwind.mir b/tests/mir-opt/tail_call_drops.f.built.after.panic-unwind.mir index e017424a4ccdd..29bd0c6312bae 100644 --- a/tests/mir-opt/tail_call_drops.f.built.after.panic-unwind.mir +++ b/tests/mir-opt/tail_call_drops.f.built.after.panic-unwind.mir @@ -24,7 +24,7 @@ fn f() -> () { bb0: { StorageLive(_2); - _2 = String::new() -> [return: bb1, unwind: bb17]; + _2 = String::new() -> [return: bb1, unwind: bb18]; } bb1: { @@ -100,18 +100,28 @@ fn f() -> () { } bb14 (cleanup): { + StorageDead(_7); + StorageDead(_6); drop(_5) -> [return: bb15, unwind terminate(cleanup)]; } bb15 (cleanup): { + StorageDead(_5); drop(_4) -> [return: bb16, unwind terminate(cleanup)]; } bb16 (cleanup): { + StorageDead(_4); + StorageDead(_3); drop(_2) -> [return: bb17, unwind terminate(cleanup)]; } bb17 (cleanup): { + StorageDead(_2); + goto -> bb18; + } + + bb18 (cleanup): { resume; } } diff --git a/tests/mir-opt/tail_call_drops.f_with_arg.built.after.panic-abort.mir b/tests/mir-opt/tail_call_drops.f_with_arg.built.after.panic-abort.mir index 9ec358ec18930..ddd9fc091141a 100644 --- a/tests/mir-opt/tail_call_drops.f_with_arg.built.after.panic-abort.mir +++ b/tests/mir-opt/tail_call_drops.f_with_arg.built.after.panic-abort.mir @@ -28,7 +28,7 @@ fn f_with_arg(_1: String, _2: String) -> () { bb0: { StorageLive(_4); - _4 = String::new() -> [return: bb1, unwind: bb34]; + _4 = String::new() -> [return: bb1, unwind: bb36]; } bb1: { @@ -37,13 +37,13 @@ fn f_with_arg(_1: String, _2: String) -> () { _5 = const 12_i32; FakeRead(ForLet(None), _5); StorageLive(_6); - _6 = String::new() -> [return: bb2, unwind: bb33]; + _6 = String::new() -> [return: bb2, unwind: bb35]; } bb2: { FakeRead(ForLet(None), _6); StorageLive(_7); - _7 = String::new() -> [return: bb3, unwind: bb32]; + _7 = String::new() -> [return: bb3, unwind: bb34]; } bb3: { @@ -51,14 +51,14 @@ fn f_with_arg(_1: String, _2: String) -> () { StorageLive(_8); StorageLive(_9); _9 = move _6; - _8 = std::mem::drop::(move _9) -> [return: bb4, unwind: bb30]; + _8 = std::mem::drop::(move _9) -> [return: bb4, unwind: bb31]; } bb4: { StorageDead(_9); StorageDead(_8); StorageLive(_10); - _10 = String::new() -> [return: bb5, unwind: bb31]; + _10 = String::new() -> [return: bb5, unwind: bb33]; } bb5: { @@ -96,18 +96,18 @@ fn f_with_arg(_1: String, _2: String) -> () { bb12: { StorageDead(_11); StorageDead(_10); - drop(_7) -> [return: bb13, unwind: bb32]; + drop(_7) -> [return: bb13, unwind: bb34]; } bb13: { StorageDead(_7); - drop(_6) -> [return: bb14, unwind: bb33]; + drop(_6) -> [return: bb14, unwind: bb35]; } bb14: { StorageDead(_6); StorageDead(_5); - drop(_4) -> [return: bb15, unwind: bb34]; + drop(_4) -> [return: bb15, unwind: bb36]; } bb15: { @@ -116,11 +116,11 @@ fn f_with_arg(_1: String, _2: String) -> () { } bb16: { - drop(_2) -> [return: bb17, unwind: bb35]; + drop(_2) -> [return: bb17, unwind: bb37]; } bb17: { - drop(_1) -> [return: bb18, unwind: bb36]; + drop(_1) -> [return: bb18, unwind: bb38]; } bb18: { @@ -132,7 +132,7 @@ fn f_with_arg(_1: String, _2: String) -> () { } bb20 (cleanup): { - drop(_11) -> [return: bb36, unwind terminate(cleanup)]; + drop(_11) -> [return: bb38, unwind terminate(cleanup)]; } bb21 (cleanup): { @@ -140,7 +140,7 @@ fn f_with_arg(_1: String, _2: String) -> () { } bb22 (cleanup): { - drop(_11) -> [return: bb35, unwind terminate(cleanup)]; + drop(_11) -> [return: bb37, unwind terminate(cleanup)]; } bb23 (cleanup): { @@ -148,7 +148,7 @@ fn f_with_arg(_1: String, _2: String) -> () { } bb24 (cleanup): { - drop(_11) -> [return: bb34, unwind terminate(cleanup)]; + drop(_11) -> [return: bb36, unwind terminate(cleanup)]; } bb25 (cleanup): { @@ -156,7 +156,7 @@ fn f_with_arg(_1: String, _2: String) -> () { } bb26 (cleanup): { - drop(_11) -> [return: bb33, unwind terminate(cleanup)]; + drop(_11) -> [return: bb35, unwind terminate(cleanup)]; } bb27 (cleanup): { @@ -164,38 +164,54 @@ fn f_with_arg(_1: String, _2: String) -> () { } bb28 (cleanup): { - drop(_11) -> [return: bb32, unwind terminate(cleanup)]; + drop(_11) -> [return: bb34, unwind terminate(cleanup)]; } bb29 (cleanup): { - drop(_10) -> [return: bb31, unwind terminate(cleanup)]; + StorageDead(_11); + drop(_10) -> [return: bb30, unwind terminate(cleanup)]; } bb30 (cleanup): { - drop(_9) -> [return: bb31, unwind terminate(cleanup)]; + StorageDead(_10); + goto -> bb33; } bb31 (cleanup): { - drop(_7) -> [return: bb32, unwind terminate(cleanup)]; + drop(_9) -> [return: bb32, unwind terminate(cleanup)]; } bb32 (cleanup): { - drop(_6) -> [return: bb33, unwind terminate(cleanup)]; + StorageDead(_9); + StorageDead(_8); + goto -> bb33; } bb33 (cleanup): { - drop(_4) -> [return: bb34, unwind terminate(cleanup)]; + drop(_7) -> [return: bb34, unwind terminate(cleanup)]; } bb34 (cleanup): { - drop(_2) -> [return: bb35, unwind terminate(cleanup)]; + StorageDead(_7); + drop(_6) -> [return: bb35, unwind terminate(cleanup)]; } bb35 (cleanup): { - drop(_1) -> [return: bb36, unwind terminate(cleanup)]; + StorageDead(_6); + StorageDead(_5); + drop(_4) -> [return: bb36, unwind terminate(cleanup)]; } bb36 (cleanup): { + StorageDead(_4); + drop(_2) -> [return: bb37, unwind terminate(cleanup)]; + } + + bb37 (cleanup): { + drop(_1) -> [return: bb38, unwind terminate(cleanup)]; + } + + bb38 (cleanup): { resume; } } diff --git a/tests/mir-opt/tail_call_drops.f_with_arg.built.after.panic-unwind.mir b/tests/mir-opt/tail_call_drops.f_with_arg.built.after.panic-unwind.mir index 9ec358ec18930..ddd9fc091141a 100644 --- a/tests/mir-opt/tail_call_drops.f_with_arg.built.after.panic-unwind.mir +++ b/tests/mir-opt/tail_call_drops.f_with_arg.built.after.panic-unwind.mir @@ -28,7 +28,7 @@ fn f_with_arg(_1: String, _2: String) -> () { bb0: { StorageLive(_4); - _4 = String::new() -> [return: bb1, unwind: bb34]; + _4 = String::new() -> [return: bb1, unwind: bb36]; } bb1: { @@ -37,13 +37,13 @@ fn f_with_arg(_1: String, _2: String) -> () { _5 = const 12_i32; FakeRead(ForLet(None), _5); StorageLive(_6); - _6 = String::new() -> [return: bb2, unwind: bb33]; + _6 = String::new() -> [return: bb2, unwind: bb35]; } bb2: { FakeRead(ForLet(None), _6); StorageLive(_7); - _7 = String::new() -> [return: bb3, unwind: bb32]; + _7 = String::new() -> [return: bb3, unwind: bb34]; } bb3: { @@ -51,14 +51,14 @@ fn f_with_arg(_1: String, _2: String) -> () { StorageLive(_8); StorageLive(_9); _9 = move _6; - _8 = std::mem::drop::(move _9) -> [return: bb4, unwind: bb30]; + _8 = std::mem::drop::(move _9) -> [return: bb4, unwind: bb31]; } bb4: { StorageDead(_9); StorageDead(_8); StorageLive(_10); - _10 = String::new() -> [return: bb5, unwind: bb31]; + _10 = String::new() -> [return: bb5, unwind: bb33]; } bb5: { @@ -96,18 +96,18 @@ fn f_with_arg(_1: String, _2: String) -> () { bb12: { StorageDead(_11); StorageDead(_10); - drop(_7) -> [return: bb13, unwind: bb32]; + drop(_7) -> [return: bb13, unwind: bb34]; } bb13: { StorageDead(_7); - drop(_6) -> [return: bb14, unwind: bb33]; + drop(_6) -> [return: bb14, unwind: bb35]; } bb14: { StorageDead(_6); StorageDead(_5); - drop(_4) -> [return: bb15, unwind: bb34]; + drop(_4) -> [return: bb15, unwind: bb36]; } bb15: { @@ -116,11 +116,11 @@ fn f_with_arg(_1: String, _2: String) -> () { } bb16: { - drop(_2) -> [return: bb17, unwind: bb35]; + drop(_2) -> [return: bb17, unwind: bb37]; } bb17: { - drop(_1) -> [return: bb18, unwind: bb36]; + drop(_1) -> [return: bb18, unwind: bb38]; } bb18: { @@ -132,7 +132,7 @@ fn f_with_arg(_1: String, _2: String) -> () { } bb20 (cleanup): { - drop(_11) -> [return: bb36, unwind terminate(cleanup)]; + drop(_11) -> [return: bb38, unwind terminate(cleanup)]; } bb21 (cleanup): { @@ -140,7 +140,7 @@ fn f_with_arg(_1: String, _2: String) -> () { } bb22 (cleanup): { - drop(_11) -> [return: bb35, unwind terminate(cleanup)]; + drop(_11) -> [return: bb37, unwind terminate(cleanup)]; } bb23 (cleanup): { @@ -148,7 +148,7 @@ fn f_with_arg(_1: String, _2: String) -> () { } bb24 (cleanup): { - drop(_11) -> [return: bb34, unwind terminate(cleanup)]; + drop(_11) -> [return: bb36, unwind terminate(cleanup)]; } bb25 (cleanup): { @@ -156,7 +156,7 @@ fn f_with_arg(_1: String, _2: String) -> () { } bb26 (cleanup): { - drop(_11) -> [return: bb33, unwind terminate(cleanup)]; + drop(_11) -> [return: bb35, unwind terminate(cleanup)]; } bb27 (cleanup): { @@ -164,38 +164,54 @@ fn f_with_arg(_1: String, _2: String) -> () { } bb28 (cleanup): { - drop(_11) -> [return: bb32, unwind terminate(cleanup)]; + drop(_11) -> [return: bb34, unwind terminate(cleanup)]; } bb29 (cleanup): { - drop(_10) -> [return: bb31, unwind terminate(cleanup)]; + StorageDead(_11); + drop(_10) -> [return: bb30, unwind terminate(cleanup)]; } bb30 (cleanup): { - drop(_9) -> [return: bb31, unwind terminate(cleanup)]; + StorageDead(_10); + goto -> bb33; } bb31 (cleanup): { - drop(_7) -> [return: bb32, unwind terminate(cleanup)]; + drop(_9) -> [return: bb32, unwind terminate(cleanup)]; } bb32 (cleanup): { - drop(_6) -> [return: bb33, unwind terminate(cleanup)]; + StorageDead(_9); + StorageDead(_8); + goto -> bb33; } bb33 (cleanup): { - drop(_4) -> [return: bb34, unwind terminate(cleanup)]; + drop(_7) -> [return: bb34, unwind terminate(cleanup)]; } bb34 (cleanup): { - drop(_2) -> [return: bb35, unwind terminate(cleanup)]; + StorageDead(_7); + drop(_6) -> [return: bb35, unwind terminate(cleanup)]; } bb35 (cleanup): { - drop(_1) -> [return: bb36, unwind terminate(cleanup)]; + StorageDead(_6); + StorageDead(_5); + drop(_4) -> [return: bb36, unwind terminate(cleanup)]; } bb36 (cleanup): { + StorageDead(_4); + drop(_2) -> [return: bb37, unwind terminate(cleanup)]; + } + + bb37 (cleanup): { + drop(_1) -> [return: bb38, unwind terminate(cleanup)]; + } + + bb38 (cleanup): { resume; } } diff --git a/tests/ui/drop/unwind-drop-order-future-compat.rs b/tests/ui/drop/unwind-drop-order-future-compat.rs new file mode 100644 index 0000000000000..90e453cf3cf52 --- /dev/null +++ b/tests/ui/drop/unwind-drop-order-future-compat.rs @@ -0,0 +1,26 @@ +//@ edition: 2021 +//@ normalize-stderr: "\n\n\z" -> "\n" + +#![allow(unused)] +#![deny(unwind_drop_order)] + +use std::fmt::Display; + +struct Wrap(T); + +impl Drop for Wrap { + fn drop(&mut self) { + println!("{}", self.0); + } +} + +fn main() { + let x; + { + let y = 1; + x = Wrap(&y); + //~^ ERROR relative drop order on unwind changing in a future release + //~| WARNING this will change its meaning in a future release + panic!(); + } +} diff --git a/tests/ui/drop/unwind-drop-order-future-compat.stderr b/tests/ui/drop/unwind-drop-order-future-compat.stderr new file mode 100644 index 0000000000000..48dadf7cd6196 --- /dev/null +++ b/tests/ui/drop/unwind-drop-order-future-compat.stderr @@ -0,0 +1,19 @@ +error: relative drop order on unwind changing in a future release + --> $DIR/unwind-drop-order-future-compat.rs:21:18 + | +LL | x = Wrap(&y); + | ^^ this value would be considered dead on an unwind path +... +LL | } + | - borrow might be used here, when `x` is dropped and runs the `Drop` code for type `Wrap` + | + = note: values in a scope are dropped in the opposite order they are defined + = warning: this will change its meaning in a future release! + = note: for more information, see issue #147875 +note: the lint level is defined here + --> $DIR/unwind-drop-order-future-compat.rs:5:9 + | +LL | #![deny(unwind_drop_order)] + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error From d1c93d31d26943cde206ef3812bb074303b61142 Mon Sep 17 00:00:00 2001 From: Sladyn Nunes Date: Mon, 15 Jun 2026 18:46:52 -0700 Subject: [PATCH 2/2] Address unwind drop order review feedback --- .../src/polonius/legacy/loan_invalidations.rs | 5 +- compiler/rustc_middle/src/mir/pretty.rs | 6 +- compiler/rustc_middle/src/mir/syntax.rs | 3 +- compiler/rustc_mir_build/src/builder/scope.rs | 189 +++++------------- .../src/lint_tail_expr_drop_order.rs | 6 +- .../fail/tail_calls/dangling-local-var.stderr | 4 +- ...ignment.main.SimplifyCfg-initial.after.mir | 10 +- .../building/eq_never_type._f.built.after.mir | 4 + ...rray_and_slice.index_array.built.after.mir | 2 + ....index_const_generic_array.built.after.mir | 2 + ...ray_and_slice.index_custom.built.after.mir | 2 + ..._and_slice.index_mut_slice.built.after.mir | 2 + ...rray_and_slice.index_slice.built.after.mir | 2 + .../issue_101867.main.built.after.mir | 3 + .../building/issue_49232.main.built.after.mir | 9 +- ...n_conditional.test_complex.built.after.mir | 67 +++++-- ..._or_in_conditional.test_or.built.after.mir | 11 +- ...verges.break_to_block_unit.built.after.mir | 2 + ..._match_diverges.infinite_a.built.after.mir | 1 + ...loop_match_diverges.simple.built.after.mir | 1 + ...atch_no_self_assign.helper.built.after.mir | 2 + ...onst_array_len.built.after.panic-abort.mir | 62 ++++-- ...nst_array_len.built.after.panic-unwind.mir | 24 +-- ..._len.slice_len.built.after.panic-abort.mir | 34 +++- ...len.slice_len.built.after.panic-unwind.mir | 34 +++- ...se_edges.full_tested_match.built.after.mir | 4 + ...e_edges.full_tested_match2.built.after.mir | 4 + .../match_false_edges.main.built.after.mir | 17 +- ....constant_eq.SimplifyCfg-initial.after.mir | 1 + ...ceiver_ptr_mutability.main.built.after.mir | 21 +- .../shifts.shift_signed.built.after.mir | 70 ++++++- .../shifts.shift_unsigned.built.after.mir | 70 ++++++- ..._by_subslice.CleanupPostBorrowck.after.mir | 12 +- ...out_from_end.CleanupPostBorrowck.after.mir | 12 +- tests/mir-opt/building/unwind_drop_hint.rs | 6 +- .../unwind_drop_hint.test.built.after.mir | 6 +- ...move.box_new.CleanupPostBorrowck.after.mir | 17 +- ...ve.vec_macro.CleanupPostBorrowck.after.mir | 17 +- ...move.box_new.CleanupPostBorrowck.after.mir | 21 +- ...motion_extern_static.BAR.PromoteTemps.diff | 3 + ...motion_extern_static.FOO.PromoteTemps.diff | 3 + ...ch_match_arms.main.InstrumentCoverage.diff | 31 ++- ...ment_coverage.main.InstrumentCoverage.diff | 7 +- ...rage_cleanup.main.CleanupPostBorrowck.diff | 2 + ...erage_cleanup.main.InstrumentCoverage.diff | 1 + .../drop_hint_removed_after_borrowck.rs | 3 +- ...emoved_after_borrowck.test.built.after.mir | 6 +- ...e_38669.main.SimplifyCfg-initial.after.mir | 1 + tests/mir-opt/issue_72181.foo.built.after.mir | 1 + .../mir-opt/issue_72181.main.built.after.mir | 14 +- .../issue_72181_1.main.built.after.mir | 14 +- tests/mir-opt/issue_91633.bar.built.after.mir | 4 +- tests/mir-opt/issue_91633.foo.built.after.mir | 6 +- tests/mir-opt/issue_91633.fun.built.after.mir | 2 + tests/mir-opt/issue_91633.hey.built.after.mir | 3 + .../issue_99325.main.built.after.32bit.mir | 87 +++++++- .../issue_99325.main.built.after.64bit.mir | 87 +++++++- ....main.SimplifyCfg-promote-consts.after.mir | 1 + ...fg-initial.after-ElaborateDrops.after.diff | 30 ++- ...fg-initial.after-ElaborateDrops.after.diff | 12 +- ...egion_subtyping_basic.main.nll.0.32bit.mir | 36 +++- ...egion_subtyping_basic.main.nll.0.64bit.mir | 36 +++- ...simplify_cfg.main.SimplifyCfg-initial.diff | 11 +- ...fy_cfg.main.SimplifyCfg-post-analysis.diff | 5 + ...ll_drops.f.ElaborateDrops.panic-abort.diff | 1 + ...l_drops.f.ElaborateDrops.panic-unwind.diff | 1 + ...l_call_drops.f.built.after.panic-abort.mir | 19 +- ..._call_drops.f.built.after.panic-unwind.mir | 19 +- ...f_with_arg.ElaborateDrops.panic-abort.diff | 1 + ..._with_arg.ElaborateDrops.panic-unwind.diff | 1 + ...ops.f_with_arg.built.after.panic-abort.mir | 19 +- ...ps.f_with_arg.built.after.panic-unwind.mir | 19 +- .../rmake.rs | 23 ++- .../drop/unwind-drop-order-future-compat.rs | 3 - .../unwind-drop-order-future-compat.stderr | 5 +- 75 files changed, 932 insertions(+), 350 deletions(-) diff --git a/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs b/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs index 9edf7103f3990..83c56e00bdd4f 100644 --- a/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs +++ b/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs @@ -70,7 +70,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LoanInvalidationsGenerator<'a, 'tcx> { // Doesn't have any language semantics | StatementKind::Coverage(..) // Does not actually affect borrowck - | StatementKind::StorageLive(..) => {} + | StatementKind::StorageLive(..) + // Future-compatibility drop hints are lint markers, not loan invalidations. + | StatementKind::BackwardIncompatibleDropHint { .. } => {} StatementKind::StorageDead(local) => { self.access_place( location, @@ -81,7 +83,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LoanInvalidationsGenerator<'a, 'tcx> { } StatementKind::ConstEvalCounter | StatementKind::Nop - | StatementKind::BackwardIncompatibleDropHint { .. } | StatementKind::SetDiscriminant { .. } => { bug!("Statement not allowed in this MIR phase") } diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index a95b95d7a363a..7aa78ba10f4b1 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -879,10 +879,8 @@ impl Debug for StatementKind<'_> { Intrinsic(ref intrinsic) => write!(fmt, "{intrinsic}"), ConstEvalCounter => write!(fmt, "ConstEvalCounter"), Nop => write!(fmt, "nop"), - BackwardIncompatibleDropHint { ref place, reason: _ } => { - // The reason is intentionally omitted to keep MIR diffs stable - // across future-compatibility lint implementation details. - write!(fmt, "BackwardIncompatibleDropHint({place:?})") + BackwardIncompatibleDropHint { ref place, reason } => { + write!(fmt, "BackwardIncompatibleDropHint({place:?}, {reason:?})") } } } diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 945ffec197f83..e3e431d0aaf9f 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -445,8 +445,7 @@ pub enum StatementKind<'tcx> { /// Marker statement indicating where `place` would be dropped. /// This is semantically equivalent to `Nop`, so codegen and MIRI should interpret this /// statement as such. - /// The only use case of this statement is for linting in MIR to detect temporary lifetime - /// changes. + /// The only use case of this statement is for MIR future-compatibility linting. BackwardIncompatibleDropHint { /// Place to drop place: Box>, diff --git a/compiler/rustc_mir_build/src/builder/scope.rs b/compiler/rustc_mir_build/src/builder/scope.rs index d8543598c3b2a..f6f90e182ecd0 100644 --- a/compiler/rustc_mir_build/src/builder/scope.rs +++ b/compiler/rustc_mir_build/src/builder/scope.rs @@ -166,7 +166,6 @@ pub(crate) enum DropKind { Value, Storage, ForLint, - StorageForLint, } #[derive(Debug)] @@ -255,19 +254,6 @@ struct DropNodeKey { } impl Scope { - /// Whether unwinding through this scope needs a cleanup block. This includes - /// actual destructors (`Value`) and lint-only drop hints (`ForLint`). Storage - /// markers alone do not need cleanup blocks; on non-coroutine unwind paths, - /// when a cleanup block is needed for another reason, storage markers are - /// represented as `BackwardIncompatibleDropHint`s for future-compatibility - /// linting instead of as `StorageDead`. - fn needs_cleanup(&self) -> bool { - self.drops.iter().any(|drop| match drop.kind { - DropKind::Value | DropKind::ForLint => true, - DropKind::Storage | DropKind::StorageForLint => false, - }) - } - fn invalidate_cache(&mut self) { self.cached_unwind_block = None; self.cached_coroutine_drop_block = None; @@ -326,11 +312,12 @@ impl DropTree { &mut self, cfg: &mut CFG<'tcx>, root_node: Option, + storage_dead_on_cleanup: bool, ) -> IndexVec> { debug!("DropTree::build_mir(drops = {:#?})", self); let mut blocks = self.assign_blocks::(cfg, root_node); - self.link_blocks(cfg, &mut blocks); + self.link_blocks(cfg, &mut blocks, storage_dead_on_cleanup); blocks } @@ -411,6 +398,7 @@ impl DropTree { &self, cfg: &mut CFG<'tcx>, blocks: &IndexSlice>, + storage_dead_on_cleanup: bool, ) { for (drop_idx, drop_node) in self.drop_nodes.iter_enumerated().rev() { let Some(block) = blocks[drop_idx] else { continue }; @@ -426,19 +414,12 @@ impl DropTree { }; cfg.terminate(block, drop_node.data.source_info, terminator); } - DropKind::ForLint | DropKind::StorageForLint => { - let reason = match drop_node.data.kind { - DropKind::ForLint => BackwardIncompatibleDropReason::Edition2024, - DropKind::StorageForLint => { - BackwardIncompatibleDropReason::UnwindStorageDead - } - DropKind::Value | DropKind::Storage => bug!("unexpected drop kind"), - }; + DropKind::ForLint => { let stmt = Statement::new( drop_node.data.source_info, StatementKind::BackwardIncompatibleDropHint { place: Box::new(drop_node.data.local.into()), - reason, + reason: BackwardIncompatibleDropReason::Edition2024, }, ); cfg.push(block, stmt); @@ -457,10 +438,17 @@ impl DropTree { // Root nodes don't correspond to a drop. DropKind::Storage if drop_idx == ROOT_NODE => {} DropKind::Storage => { - let stmt = Statement::new( - drop_node.data.source_info, - StatementKind::StorageDead(drop_node.data.local), - ); + let kind = if cfg.block_data(block).is_cleanup && !storage_dead_on_cleanup { + // Future editions can switch this cleanup-path marker + // to a real `StorageDead` here. + StatementKind::BackwardIncompatibleDropHint { + place: Box::new(drop_node.data.local.into()), + reason: BackwardIncompatibleDropReason::UnwindStorageDead, + } + } else { + StatementKind::StorageDead(drop_node.data.local) + }; + let stmt = Statement::new(drop_node.data.source_info, kind); cfg.push(block, stmt); let target = blocks[drop_node.next].unwrap(); if target != block { @@ -479,36 +467,11 @@ impl DropTree { } } -fn drop_for_unwind_path( - is_coroutine: bool, - emit_storage_lint_hints: bool, - drop: DropData, -) -> Option { - match drop.kind { - DropKind::Value | DropKind::ForLint => Some(drop), - DropKind::Storage if is_coroutine => Some(drop), - DropKind::Storage if emit_storage_lint_hints => { - Some(DropData { kind: DropKind::StorageForLint, ..drop }) - } - DropKind::Storage => None, - DropKind::StorageForLint => bug!("StorageForLint should not be scheduled in scopes"), - } -} - fn advance_unwind_to(unwind_drops: &DropTree, unwind_to: &mut DropIdx, drop: DropData) { - advance_unwind_to_kind(unwind_drops, unwind_to, drop, drop.kind); -} - -fn advance_unwind_to_kind( - unwind_drops: &DropTree, - unwind_to: &mut DropIdx, - drop: DropData, - expected_kind: DropKind, -) { debug_assert_ne!(*unwind_to, DropIdx::MAX); let unwind_drop = unwind_drops.drop_nodes[*unwind_to].data; debug_assert_eq!(unwind_drop.local, drop.local); - debug_assert_eq!(unwind_drop.kind, expected_kind); + debug_assert_eq!(unwind_drop.kind, drop.kind); *unwind_to = unwind_drops.drop_nodes[*unwind_to].next; } @@ -1157,16 +1120,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { DUMMY_SP, ); let typing_env = self.typing_env(); - let storage_marker_on_unwind = self.scopes.scopes[1..] - .iter() - .rev() - .skip(1) - .any(|scope| scope.needs_cleanup()) - .then_some(if self.coroutine.is_some() { - DropKind::Storage - } else { - DropKind::StorageForLint - }); + let tail_call_source_info = SourceInfo { + span: args + .iter() + .map(|arg| arg.span) + .reduce(|span, arg_span| span.to(arg_span)) + .map(|span| span.shrink_to_hi()) + .unwrap_or(source_info.span), + ..source_info + }; let unwind_drops = &mut self.scopes.unwind_drops; // the innermost scope contains only the destructors for the tail call arguments @@ -1225,19 +1187,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ); } DropKind::Storage => { - if let Some(kind) = storage_marker_on_unwind { - advance_unwind_to_kind(unwind_drops, &mut unwind_to, *drop_data, kind); - } + advance_unwind_to(unwind_drops, &mut unwind_to, *drop_data); // Only temps and vars need their storage dead. assert!(local.index() > self.arg_count); self.cfg.push( block, - Statement::new(source_info, StatementKind::StorageDead(local)), + Statement::new( + tail_call_source_info, + StatementKind::StorageDead(local), + ), ); } - DropKind::StorageForLint => { - bug!("StorageForLint should not be scheduled in scopes") - } } } } @@ -1264,14 +1224,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fn leave_top_scope(&mut self, block: BasicBlock) -> BasicBlock { // If we are emitting a `drop` statement, we need to have the cached // diverge cleanup pads ready in case that drop panics. - let needs_cleanup = self.scopes.scopes.last().is_some_and(|scope| scope.needs_cleanup()); let is_coroutine = self.coroutine.is_some(); - let unwind_to = if needs_cleanup { self.diverge_cleanup() } else { DropIdx::MAX }; - let storage_marker_on_unwind = needs_cleanup.then_some(if is_coroutine { - DropKind::Storage - } else { - DropKind::StorageForLint - }); + let has_drops = self.scopes.scopes.last().is_some_and(|scope| !scope.drops.is_empty()); + let unwind_to = if has_drops { self.diverge_cleanup() } else { DropIdx::MAX }; let scope = self.scopes.scopes.last().expect("leave_top_scope called with no scopes"); let has_async_drops = is_coroutine @@ -1287,7 +1242,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block, unwind_to, dropline_to, - storage_marker_on_unwind, self.arg_count, |v: Local| Self::is_async_drop_impl(self.tcx, &self.local_decls, typing_env, v), ) @@ -1461,14 +1415,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { local: Local, drop_kind: DropKind, ) { - let needs_drop = match drop_kind { + match drop_kind { DropKind::Value | DropKind::ForLint => { if !self.local_decls[local].ty.needs_drop(self.tcx, self.typing_env()) { return; } - true } - DropKind::StorageForLint => bug!("StorageForLint should not be scheduled in scopes"), DropKind::Storage => { if local.index() <= self.arg_count { span_bug!( @@ -1478,7 +1430,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { local, ) } - false } }; @@ -1524,20 +1475,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // caches gets invalidated. i.e., if a new drop is added into the middle scope, the // cache of outer scope stays intact. // - // Since we only cache drops for the unwind path and the coroutine drop - // path, we only need to invalidate the cache for drops that happen on - // those paths. Non-coroutine storage drops can now affect the unwind - // tree through lint-only `BackwardIncompatibleDropHint`s when a scope - // has value/lint drops, so they must invalidate cached unwind chains in - // that case. - let storage_affects_unwind_cache = drop_kind == DropKind::Storage - && self.scopes.scopes.iter().any(|scope| scope.needs_cleanup()); - let invalidate_caches = - needs_drop || storage_affects_unwind_cache || self.coroutine.is_some(); for scope in self.scopes.scopes.iter_mut().rev() { - if invalidate_caches { - scope.invalidate_cache(); - } + scope.invalidate_cache(); if scope.region_scope == region_scope { let region_scope_span = region_scope.span(self.tcx, self.region_scope_tree); @@ -1681,15 +1620,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { return cached_drop; } - let is_coroutine = self.coroutine.is_some(); - let needs_cleanup = - self.scopes.scopes[uncached_scope..=target].iter().any(|scope| scope.needs_cleanup()); - for scope in &mut self.scopes.scopes[uncached_scope..=target] { for drop in &scope.drops { - if let Some(drop) = drop_for_unwind_path(is_coroutine, needs_cleanup, *drop) { - cached_drop = self.scopes.unwind_drops.add_drop(drop, cached_drop); - } + cached_drop = self.scopes.unwind_drops.add_drop(*drop, cached_drop); } scope.cached_unwind_block = Some(cached_drop); } @@ -1871,10 +1804,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// panic occurred (a subset of the drops in `scope`) /// * `dropline_to`, describes the drops that would occur at this point in the code if a /// coroutine drop occurred. -/// * `storage_marker_on_unwind`, if present, is the unwind-tree marker corresponding to -/// `StorageDead` statements on the normal path. Coroutines use real `StorageDead` so the -/// coroutine transform can use storage liveness; non-coroutines use -/// `StorageForLint`, which lowers to `BackwardIncompatibleDropHint`. /// * `arg_count`, number of MIR local variables corresponding to fn arguments (used to assert that we don't drop those) fn build_scope_drops<'tcx, F>( cfg: &mut CFG<'tcx>, @@ -1884,7 +1813,6 @@ fn build_scope_drops<'tcx, F>( block: BasicBlock, unwind_to: DropIdx, dropline_to: Option, - storage_marker_on_unwind: Option, arg_count: usize, is_async_drop: F, ) -> BlockAnd<()> @@ -1907,11 +1835,10 @@ where // drops panic (panicking while unwinding will abort, so there's no need for // another set of arrows). // - // For coroutines, we unwind from a drop on a local to its `StorageDead` - // statement. For other functions, we unwind to a `BackwardIncompatibleDropHint` - // at the same position instead. This lets borrowck issue future-compatibility - // lints without changing the accepted program set yet. The drops for the - // unwind path should have already been generated by `diverge_cleanup_gen`. + // Cleanup drop trees mirror the normal-path storage markers. When those trees + // are lowered, non-coroutine cleanup blocks turn `Storage` into + // `BackwardIncompatibleDropHint` so borrowck can issue future-compatibility + // lints without changing the accepted program set yet. // `unwind_to` indicates what needs to be dropped should unwinding occur. // This is a subset of what needs to be dropped when exiting the scope. @@ -2001,9 +1928,7 @@ where ); } DropKind::Storage => { - if let Some(kind) = storage_marker_on_unwind { - advance_unwind_to_kind(unwind_drops, &mut unwind_to, *drop_data, kind); - } + advance_unwind_to(unwind_drops, &mut unwind_to, *drop_data); if let Some(idx) = dropline_to { debug_assert_eq!(coroutine_drops.drop_nodes[idx].data.local, drop_data.local); debug_assert_eq!(coroutine_drops.drop_nodes[idx].data.kind, drop_data.kind); @@ -2013,7 +1938,6 @@ where assert!(local.index() > arg_count); cfg.push(block, Statement::new(source_info, StatementKind::StorageDead(local))); } - DropKind::StorageForLint => bug!("StorageForLint should not be scheduled in scopes"), } } block.unit() @@ -2031,40 +1955,33 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> { span: Span, continue_block: Option, ) -> Option> { - let blocks = drops.build_mir::(&mut self.cfg, continue_block); + let blocks = drops.build_mir::(&mut self.cfg, continue_block, true); let is_coroutine = self.coroutine.is_some(); // Link the exit drop tree to unwind drop tree. if drops.drop_nodes.iter().any(|drop_node| drop_node.data.kind == DropKind::Value) { let unwind_target = self.diverge_cleanup_target(else_scope, span); - let needs_cleanup = drops.drop_nodes.iter().any(|drop_node| { - matches!(drop_node.data.kind, DropKind::Value | DropKind::ForLint) - }); - let mut unwind_indices = IndexVec::from_elem_n(unwind_target, 1); for (drop_idx, drop_node) in drops.drop_nodes.iter_enumerated().skip(1) { - match drop_for_unwind_path(is_coroutine, needs_cleanup, drop_node.data) { - Some(drop_data @ DropData { kind: DropKind::Value, .. }) => { + match drop_node.data.kind { + DropKind::Value => { let unwind_drop = self .scopes .unwind_drops - .add_drop(drop_data, unwind_indices[drop_node.next]); + .add_drop(drop_node.data, unwind_indices[drop_node.next]); self.scopes.unwind_drops.add_entry_point( blocks[drop_idx].unwrap(), unwind_indices[drop_node.next], ); unwind_indices.push(unwind_drop); } - Some(drop_data) => { + DropKind::Storage | DropKind::ForLint => { let unwind_drop = self .scopes .unwind_drops - .add_drop(drop_data, unwind_indices[drop_node.next]); + .add_drop(drop_node.data, unwind_indices[drop_node.next]); unwind_indices.push(unwind_drop); } - None => { - unwind_indices.push(unwind_indices[drop_node.next]); - } } } } @@ -2082,7 +1999,7 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> { .coroutine_drops .add_drop(drop_data.data, dropline_indices[drop_data.next]); match drop_data.data.kind { - DropKind::Storage | DropKind::ForLint | DropKind::StorageForLint => {} + DropKind::Storage | DropKind::ForLint => {} DropKind::Value => { if self.is_async_drop(drop_data.data.local) { self.scopes.coroutine_drops.add_entry_point( @@ -2108,6 +2025,7 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> { &mut self.scopes.unwind_drops, self.fn_span, &mut None, + false, ); } } @@ -2117,7 +2035,7 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> { let drops = &mut self.scopes.coroutine_drops; let cfg = &mut self.cfg; let fn_span = self.fn_span; - let blocks = drops.build_mir::(cfg, None); + let blocks = drops.build_mir::(cfg, None, true); if let Some(root_block) = blocks[ROOT_NODE] { cfg.terminate( root_block, @@ -2129,7 +2047,7 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> { // Build the drop tree for unwinding in the normal control flow paths. let resume_block = &mut None; let unwind_drops = &mut self.scopes.unwind_drops; - Self::build_unwind_tree(cfg, unwind_drops, fn_span, resume_block); + Self::build_unwind_tree(cfg, unwind_drops, fn_span, resume_block, true); // Build the drop tree for unwinding when dropping a suspended // coroutine. @@ -2146,7 +2064,7 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> { drops.entry_points.push((drop_node.next, bb)); } } - Self::build_unwind_tree(cfg, drops, fn_span, resume_block); + Self::build_unwind_tree(cfg, drops, fn_span, resume_block, true); } fn build_unwind_tree( @@ -2154,8 +2072,9 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> { drops: &mut DropTree, fn_span: Span, resume_block: &mut Option, + storage_dead_on_cleanup: bool, ) { - let blocks = drops.build_mir::(cfg, *resume_block); + let blocks = drops.build_mir::(cfg, *resume_block, storage_dead_on_cleanup); if let (None, Some(resume)) = (*resume_block, blocks[ROOT_NODE]) { cfg.terminate(resume, SourceInfo::outermost(fn_span), TerminatorKind::UnwindResume); diff --git a/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs b/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs index 0bc5704a8625d..7aff162caaad1 100644 --- a/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs +++ b/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs @@ -207,7 +207,11 @@ pub(crate) fn run_lint<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &Body< let mut ty_dropped_components = UnordMap::default(); for (block, data) in body.basic_blocks.iter_enumerated() { for (statement_index, stmt) in data.statements.iter().enumerate() { - if let StatementKind::BackwardIncompatibleDropHint { place, reason: _ } = &stmt.kind { + if let StatementKind::BackwardIncompatibleDropHint { + place, + reason: mir::BackwardIncompatibleDropReason::Edition2024, + } = &stmt.kind + { let ty = place.ty(body, tcx).ty; if ty_dropped_components .entry(ty) diff --git a/src/tools/miri/tests/fail/tail_calls/dangling-local-var.stderr b/src/tools/miri/tests/fail/tail_calls/dangling-local-var.stderr index 7b0efec7be5a5..3f04b5e52a628 100644 --- a/src/tools/miri/tests/fail/tail_calls/dangling-local-var.stderr +++ b/src/tools/miri/tests/fail/tail_calls/dangling-local-var.stderr @@ -14,8 +14,8 @@ LL | let local = 0; help: ALLOC was deallocated here: --> tests/fail/tail_calls/dangling-local-var.rs:LL:CC | -LL | let _val = unsafe { *x }; - | ^^^^ +LL | become g(ptr) + | ^ = note: stack backtrace: 0: g at tests/fail/tail_calls/dangling-local-var.rs:LL:CC diff --git a/tests/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir b/tests/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir index 4943fb2ccb099..810137f49e524 100644 --- a/tests/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir +++ b/tests/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir @@ -73,19 +73,19 @@ fn main() -> () { } bb6 (cleanup): { - StorageDead(_6); + BackwardIncompatibleDropHint(_6, UnwindStorageDead); drop(_5) -> [return: bb7, unwind terminate(cleanup)]; } bb7 (cleanup): { - StorageDead(_5); + BackwardIncompatibleDropHint(_5, UnwindStorageDead); drop(_4) -> [return: bb8, unwind terminate(cleanup)]; } bb8 (cleanup): { - StorageDead(_4); - StorageDead(_2); - StorageDead(_1); + BackwardIncompatibleDropHint(_4, UnwindStorageDead); + BackwardIncompatibleDropHint(_2, UnwindStorageDead); + BackwardIncompatibleDropHint(_1, UnwindStorageDead); resume; } } diff --git a/tests/mir-opt/building/eq_never_type._f.built.after.mir b/tests/mir-opt/building/eq_never_type._f.built.after.mir index 4711af46f1c8c..c6a11dba08c57 100644 --- a/tests/mir-opt/building/eq_never_type._f.built.after.mir +++ b/tests/mir-opt/building/eq_never_type._f.built.after.mir @@ -48,6 +48,10 @@ fn _f(_1: !, _2: !) -> () { } bb5 (cleanup): { + BackwardIncompatibleDropHint(_7, UnwindStorageDead); + BackwardIncompatibleDropHint(_5, UnwindStorageDead); + BackwardIncompatibleDropHint(_8, UnwindStorageDead); + BackwardIncompatibleDropHint(_4, UnwindStorageDead); resume; } } diff --git a/tests/mir-opt/building/index_array_and_slice.index_array.built.after.mir b/tests/mir-opt/building/index_array_and_slice.index_array.built.after.mir index d28a2031013f3..9bd0bd94fc7e3 100644 --- a/tests/mir-opt/building/index_array_and_slice.index_array.built.after.mir +++ b/tests/mir-opt/building/index_array_and_slice.index_array.built.after.mir @@ -26,6 +26,8 @@ fn index_array(_1: &[i32; 7], _2: usize) -> &i32 { } bb2 (cleanup): { + BackwardIncompatibleDropHint(_4, UnwindStorageDead); + BackwardIncompatibleDropHint(_3, UnwindStorageDead); resume; } } diff --git a/tests/mir-opt/building/index_array_and_slice.index_const_generic_array.built.after.mir b/tests/mir-opt/building/index_array_and_slice.index_const_generic_array.built.after.mir index e9627532c3828..4db709a7521c2 100644 --- a/tests/mir-opt/building/index_array_and_slice.index_const_generic_array.built.after.mir +++ b/tests/mir-opt/building/index_array_and_slice.index_const_generic_array.built.after.mir @@ -26,6 +26,8 @@ fn index_const_generic_array(_1: &[i32; N], _2: usize) -> &i32 { } bb2 (cleanup): { + BackwardIncompatibleDropHint(_4, UnwindStorageDead); + BackwardIncompatibleDropHint(_3, UnwindStorageDead); resume; } } diff --git a/tests/mir-opt/building/index_array_and_slice.index_custom.built.after.mir b/tests/mir-opt/building/index_array_and_slice.index_custom.built.after.mir index e6745ddbf298a..57dbb7c71f3cf 100644 --- a/tests/mir-opt/building/index_array_and_slice.index_custom.built.after.mir +++ b/tests/mir-opt/building/index_array_and_slice.index_custom.built.after.mir @@ -29,6 +29,8 @@ fn index_custom(_1: &WithSliceTail, _2: usize) -> &i32 { } bb2 (cleanup): { + BackwardIncompatibleDropHint(_4, UnwindStorageDead); + BackwardIncompatibleDropHint(_3, UnwindStorageDead); resume; } } diff --git a/tests/mir-opt/building/index_array_and_slice.index_mut_slice.built.after.mir b/tests/mir-opt/building/index_array_and_slice.index_mut_slice.built.after.mir index c96bcdfc918ad..19182a0143921 100644 --- a/tests/mir-opt/building/index_array_and_slice.index_mut_slice.built.after.mir +++ b/tests/mir-opt/building/index_array_and_slice.index_mut_slice.built.after.mir @@ -29,6 +29,8 @@ fn index_mut_slice(_1: &mut [i32], _2: usize) -> &i32 { } bb2 (cleanup): { + BackwardIncompatibleDropHint(_4, UnwindStorageDead); + BackwardIncompatibleDropHint(_3, UnwindStorageDead); resume; } } diff --git a/tests/mir-opt/building/index_array_and_slice.index_slice.built.after.mir b/tests/mir-opt/building/index_array_and_slice.index_slice.built.after.mir index 0911df590497c..874340341682a 100644 --- a/tests/mir-opt/building/index_array_and_slice.index_slice.built.after.mir +++ b/tests/mir-opt/building/index_array_and_slice.index_slice.built.after.mir @@ -27,6 +27,8 @@ fn index_slice(_1: &[i32], _2: usize) -> &i32 { } bb2 (cleanup): { + BackwardIncompatibleDropHint(_4, UnwindStorageDead); + BackwardIncompatibleDropHint(_3, UnwindStorageDead); resume; } } diff --git a/tests/mir-opt/building/issue_101867.main.built.after.mir b/tests/mir-opt/building/issue_101867.main.built.after.mir index f68217a497b0b..dd6dc405094a4 100644 --- a/tests/mir-opt/building/issue_101867.main.built.after.mir +++ b/tests/mir-opt/building/issue_101867.main.built.after.mir @@ -67,6 +67,9 @@ fn main() -> () { } bb8 (cleanup): { + BackwardIncompatibleDropHint(_4, UnwindStorageDead); + BackwardIncompatibleDropHint(_3, UnwindStorageDead); + BackwardIncompatibleDropHint(_1, UnwindStorageDead); resume; } } diff --git a/tests/mir-opt/building/issue_49232.main.built.after.mir b/tests/mir-opt/building/issue_49232.main.built.after.mir index b78f6691d54c0..a2764ebef2343 100644 --- a/tests/mir-opt/building/issue_49232.main.built.after.mir +++ b/tests/mir-opt/building/issue_49232.main.built.after.mir @@ -17,7 +17,7 @@ fn main() -> () { } bb1: { - falseUnwind -> [real: bb2, unwind: bb14]; + falseUnwind -> [real: bb2, unwind: bb15]; } bb2: { @@ -87,6 +87,13 @@ fn main() -> () { } bb14 (cleanup): { + BackwardIncompatibleDropHint(_6, UnwindStorageDead); + BackwardIncompatibleDropHint(_5, UnwindStorageDead); + BackwardIncompatibleDropHint(_2, UnwindStorageDead); + goto -> bb15; + } + + bb15 (cleanup): { resume; } } diff --git a/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir b/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir index 357f97cf4ab51..a3bf643d24b2c 100644 --- a/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir +++ b/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir @@ -19,7 +19,7 @@ fn test_complex() -> () { bb0: { StorageLive(_1); StorageLive(_2); - _2 = E::f() -> [return: bb1, unwind: bb38]; + _2 = E::f() -> [return: bb1, unwind: bb42]; } bb1: { @@ -42,7 +42,7 @@ fn test_complex() -> () { bb5: { StorageLive(_4); - _4 = always_true() -> [return: bb6, unwind: bb38]; + _4 = always_true() -> [return: bb6, unwind: bb40]; } bb6: { @@ -64,7 +64,7 @@ fn test_complex() -> () { } bb9: { - drop(_7) -> [return: bb11, unwind: bb37]; + drop(_7) -> [return: bb11, unwind: bb38]; } bb10: { @@ -78,7 +78,7 @@ fn test_complex() -> () { } bb12: { - drop(_7) -> [return: bb13, unwind: bb37]; + drop(_7) -> [return: bb13, unwind: bb38]; } bb13: { @@ -98,7 +98,7 @@ fn test_complex() -> () { } bb15: { - drop(_10) -> [return: bb17, unwind: bb36]; + drop(_10) -> [return: bb17, unwind: bb37]; } bb16: { @@ -118,7 +118,7 @@ fn test_complex() -> () { } bb19: { - drop(_10) -> [return: bb20, unwind: bb35]; + drop(_10) -> [return: bb20, unwind: bb37]; } bb20: { @@ -139,7 +139,7 @@ fn test_complex() -> () { StorageDead(_4); StorageDead(_1); StorageLive(_11); - _11 = always_true() -> [return: bb23, unwind: bb38]; + _11 = always_true() -> [return: bb23, unwind: bb36]; } bb23: { @@ -156,7 +156,7 @@ fn test_complex() -> () { bb26: { StorageLive(_12); - _12 = E::f() -> [return: bb27, unwind: bb38]; + _12 = E::f() -> [return: bb27, unwind: bb35]; } bb27: { @@ -199,25 +199,56 @@ fn test_complex() -> () { } bb35 (cleanup): { - StorageDead(_10); - StorageDead(_9); - StorageDead(_2); - goto -> bb38; + BackwardIncompatibleDropHint(_12, UnwindStorageDead); + goto -> bb36; } bb36 (cleanup): { - StorageDead(_10); - StorageDead(_9); - goto -> bb38; + BackwardIncompatibleDropHint(_11, UnwindStorageDead); + goto -> bb44; } bb37 (cleanup): { - StorageDead(_7); - StorageDead(_6); - goto -> bb38; + BackwardIncompatibleDropHint(_10, UnwindStorageDead); + BackwardIncompatibleDropHint(_9, UnwindStorageDead); + BackwardIncompatibleDropHint(_2, UnwindStorageDead); + BackwardIncompatibleDropHint(_8, UnwindStorageDead); + goto -> bb39; } bb38 (cleanup): { + BackwardIncompatibleDropHint(_7, UnwindStorageDead); + BackwardIncompatibleDropHint(_6, UnwindStorageDead); + BackwardIncompatibleDropHint(_2, UnwindStorageDead); + goto -> bb39; + } + + bb39 (cleanup): { + BackwardIncompatibleDropHint(_5, UnwindStorageDead); + goto -> bb41; + } + + bb40 (cleanup): { + BackwardIncompatibleDropHint(_2, UnwindStorageDead); + goto -> bb41; + } + + bb41 (cleanup): { + BackwardIncompatibleDropHint(_4, UnwindStorageDead); + goto -> bb43; + } + + bb42 (cleanup): { + BackwardIncompatibleDropHint(_2, UnwindStorageDead); + goto -> bb43; + } + + bb43 (cleanup): { + BackwardIncompatibleDropHint(_1, UnwindStorageDead); + goto -> bb44; + } + + bb44 (cleanup): { resume; } } diff --git a/tests/mir-opt/building/logical_or_in_conditional.test_or.built.after.mir b/tests/mir-opt/building/logical_or_in_conditional.test_or.built.after.mir index 7aa8dd0a147b7..2334574e9afa6 100644 --- a/tests/mir-opt/building/logical_or_in_conditional.test_or.built.after.mir +++ b/tests/mir-opt/building/logical_or_in_conditional.test_or.built.after.mir @@ -86,19 +86,20 @@ fn test_or() -> () { } bb13 (cleanup): { - StorageDead(_6); - StorageDead(_5); + BackwardIncompatibleDropHint(_6, UnwindStorageDead); + BackwardIncompatibleDropHint(_5, UnwindStorageDead); + BackwardIncompatibleDropHint(_4, UnwindStorageDead); goto -> bb15; } bb14 (cleanup): { - StorageDead(_3); - StorageDead(_2); + BackwardIncompatibleDropHint(_3, UnwindStorageDead); + BackwardIncompatibleDropHint(_2, UnwindStorageDead); goto -> bb15; } bb15 (cleanup): { - StorageDead(_1); + BackwardIncompatibleDropHint(_1, UnwindStorageDead); resume; } } diff --git a/tests/mir-opt/building/loop_match_diverges.break_to_block_unit.built.after.mir b/tests/mir-opt/building/loop_match_diverges.break_to_block_unit.built.after.mir index 4416bd2b7d790..012bf98d57050 100644 --- a/tests/mir-opt/building/loop_match_diverges.break_to_block_unit.built.after.mir +++ b/tests/mir-opt/building/loop_match_diverges.break_to_block_unit.built.after.mir @@ -60,6 +60,8 @@ fn break_to_block_unit() -> u8 { } bb10 (cleanup): { + BackwardIncompatibleDropHint(_2, UnwindStorageDead); + BackwardIncompatibleDropHint(_1, UnwindStorageDead); resume; } } diff --git a/tests/mir-opt/building/loop_match_diverges.infinite_a.built.after.mir b/tests/mir-opt/building/loop_match_diverges.infinite_a.built.after.mir index e72151a6bd22b..48dc711eb1ec8 100644 --- a/tests/mir-opt/building/loop_match_diverges.infinite_a.built.after.mir +++ b/tests/mir-opt/building/loop_match_diverges.infinite_a.built.after.mir @@ -48,6 +48,7 @@ fn infinite_a(_1: u8) -> () { } bb7 (cleanup): { + BackwardIncompatibleDropHint(_2, UnwindStorageDead); resume; } } diff --git a/tests/mir-opt/building/loop_match_diverges.simple.built.after.mir b/tests/mir-opt/building/loop_match_diverges.simple.built.after.mir index de64bf23cc915..b1efc8b0b099c 100644 --- a/tests/mir-opt/building/loop_match_diverges.simple.built.after.mir +++ b/tests/mir-opt/building/loop_match_diverges.simple.built.after.mir @@ -184,6 +184,7 @@ fn simple(_1: State) -> State { } bb37 (cleanup): { + BackwardIncompatibleDropHint(_2, UnwindStorageDead); resume; } } diff --git a/tests/mir-opt/building/loop_match_no_self_assign.helper.built.after.mir b/tests/mir-opt/building/loop_match_no_self_assign.helper.built.after.mir index fb97e0778c90d..9769da01fd483 100644 --- a/tests/mir-opt/building/loop_match_no_self_assign.helper.built.after.mir +++ b/tests/mir-opt/building/loop_match_no_self_assign.helper.built.after.mir @@ -65,6 +65,8 @@ fn helper() -> u8 { } bb11 (cleanup): { + BackwardIncompatibleDropHint(_2, UnwindStorageDead); + BackwardIncompatibleDropHint(_1, UnwindStorageDead); resume; } } diff --git a/tests/mir-opt/building/match/array_len.const_array_len.built.after.panic-abort.mir b/tests/mir-opt/building/match/array_len.const_array_len.built.after.panic-abort.mir index 8d16f074b1e34..49c5eccc67ece 100644 --- a/tests/mir-opt/building/match/array_len.const_array_len.built.after.panic-abort.mir +++ b/tests/mir-opt/building/match/array_len.const_array_len.built.after.panic-abort.mir @@ -43,7 +43,7 @@ fn const_array_len(_1: [T; 5]) -> () { StorageLive(_6); StorageLive(_7); _7 = move _2; - _6 = opaque::(move _7) -> [return: bb3, unwind: bb17]; + _6 = opaque::(move _7) -> [return: bb3, unwind: bb20]; } bb3: { @@ -52,7 +52,7 @@ fn const_array_len(_1: [T; 5]) -> () { StorageLive(_8); StorageLive(_9); _9 = move _3; - _8 = opaque::(move _9) -> [return: bb4, unwind: bb16]; + _8 = opaque::(move _9) -> [return: bb4, unwind: bb18]; } bb4: { @@ -61,7 +61,7 @@ fn const_array_len(_1: [T; 5]) -> () { StorageLive(_10); StorageLive(_11); _11 = move _4; - _10 = opaque::<[T; 2]>(move _11) -> [return: bb5, unwind: bb15]; + _10 = opaque::<[T; 2]>(move _11) -> [return: bb5, unwind: bb16]; } bb5: { @@ -77,7 +77,7 @@ fn const_array_len(_1: [T; 5]) -> () { StorageDead(_13); StorageDead(_12); _0 = const (); - drop(_5) -> [return: bb8, unwind: bb19]; + drop(_5) -> [return: bb8, unwind: bb23]; } bb7: { @@ -87,17 +87,17 @@ fn const_array_len(_1: [T; 5]) -> () { bb8: { StorageDead(_5); - drop(_4) -> [return: bb9, unwind: bb20]; + drop(_4) -> [return: bb9, unwind: bb24]; } bb9: { StorageDead(_4); - drop(_3) -> [return: bb10, unwind: bb21]; + drop(_3) -> [return: bb10, unwind: bb25]; } bb10: { StorageDead(_3); - drop(_2) -> [return: bb11, unwind: bb22]; + drop(_2) -> [return: bb11, unwind: bb26]; } bb11: { @@ -106,7 +106,7 @@ fn const_array_len(_1: [T; 5]) -> () { } bb12: { - drop(_1) -> [return: bb13, unwind: bb23]; + drop(_1) -> [return: bb13, unwind: bb27]; } bb13: { @@ -114,42 +114,70 @@ fn const_array_len(_1: [T; 5]) -> () { } bb14 (cleanup): { - drop(_13) -> [return: bb18, unwind terminate(cleanup)]; + drop(_13) -> [return: bb15, unwind terminate(cleanup)]; } bb15 (cleanup): { - drop(_11) -> [return: bb18, unwind terminate(cleanup)]; + BackwardIncompatibleDropHint(_13, UnwindStorageDead); + BackwardIncompatibleDropHint(_12, UnwindStorageDead); + goto -> bb22; } bb16 (cleanup): { - drop(_9) -> [return: bb18, unwind terminate(cleanup)]; + drop(_11) -> [return: bb17, unwind terminate(cleanup)]; } bb17 (cleanup): { - drop(_7) -> [return: bb18, unwind terminate(cleanup)]; + BackwardIncompatibleDropHint(_11, UnwindStorageDead); + BackwardIncompatibleDropHint(_10, UnwindStorageDead); + goto -> bb22; } bb18 (cleanup): { - drop(_5) -> [return: bb19, unwind terminate(cleanup)]; + drop(_9) -> [return: bb19, unwind terminate(cleanup)]; } bb19 (cleanup): { - drop(_4) -> [return: bb20, unwind terminate(cleanup)]; + BackwardIncompatibleDropHint(_9, UnwindStorageDead); + BackwardIncompatibleDropHint(_8, UnwindStorageDead); + goto -> bb22; } bb20 (cleanup): { - drop(_3) -> [return: bb21, unwind terminate(cleanup)]; + drop(_7) -> [return: bb21, unwind terminate(cleanup)]; } bb21 (cleanup): { - drop(_2) -> [return: bb22, unwind terminate(cleanup)]; + BackwardIncompatibleDropHint(_7, UnwindStorageDead); + BackwardIncompatibleDropHint(_6, UnwindStorageDead); + goto -> bb22; } bb22 (cleanup): { - drop(_1) -> [return: bb23, unwind terminate(cleanup)]; + drop(_5) -> [return: bb23, unwind terminate(cleanup)]; } bb23 (cleanup): { + BackwardIncompatibleDropHint(_5, UnwindStorageDead); + drop(_4) -> [return: bb24, unwind terminate(cleanup)]; + } + + bb24 (cleanup): { + BackwardIncompatibleDropHint(_4, UnwindStorageDead); + drop(_3) -> [return: bb25, unwind terminate(cleanup)]; + } + + bb25 (cleanup): { + BackwardIncompatibleDropHint(_3, UnwindStorageDead); + drop(_2) -> [return: bb26, unwind terminate(cleanup)]; + } + + bb26 (cleanup): { + BackwardIncompatibleDropHint(_2, UnwindStorageDead); + drop(_1) -> [return: bb27, unwind terminate(cleanup)]; + } + + bb27 (cleanup): { resume; } } diff --git a/tests/mir-opt/building/match/array_len.const_array_len.built.after.panic-unwind.mir b/tests/mir-opt/building/match/array_len.const_array_len.built.after.panic-unwind.mir index d0c78d8ccdd4f..49c5eccc67ece 100644 --- a/tests/mir-opt/building/match/array_len.const_array_len.built.after.panic-unwind.mir +++ b/tests/mir-opt/building/match/array_len.const_array_len.built.after.panic-unwind.mir @@ -118,8 +118,8 @@ fn const_array_len(_1: [T; 5]) -> () { } bb15 (cleanup): { - StorageDead(_13); - StorageDead(_12); + BackwardIncompatibleDropHint(_13, UnwindStorageDead); + BackwardIncompatibleDropHint(_12, UnwindStorageDead); goto -> bb22; } @@ -128,8 +128,8 @@ fn const_array_len(_1: [T; 5]) -> () { } bb17 (cleanup): { - StorageDead(_11); - StorageDead(_10); + BackwardIncompatibleDropHint(_11, UnwindStorageDead); + BackwardIncompatibleDropHint(_10, UnwindStorageDead); goto -> bb22; } @@ -138,8 +138,8 @@ fn const_array_len(_1: [T; 5]) -> () { } bb19 (cleanup): { - StorageDead(_9); - StorageDead(_8); + BackwardIncompatibleDropHint(_9, UnwindStorageDead); + BackwardIncompatibleDropHint(_8, UnwindStorageDead); goto -> bb22; } @@ -148,8 +148,8 @@ fn const_array_len(_1: [T; 5]) -> () { } bb21 (cleanup): { - StorageDead(_7); - StorageDead(_6); + BackwardIncompatibleDropHint(_7, UnwindStorageDead); + BackwardIncompatibleDropHint(_6, UnwindStorageDead); goto -> bb22; } @@ -158,22 +158,22 @@ fn const_array_len(_1: [T; 5]) -> () { } bb23 (cleanup): { - StorageDead(_5); + BackwardIncompatibleDropHint(_5, UnwindStorageDead); drop(_4) -> [return: bb24, unwind terminate(cleanup)]; } bb24 (cleanup): { - StorageDead(_4); + BackwardIncompatibleDropHint(_4, UnwindStorageDead); drop(_3) -> [return: bb25, unwind terminate(cleanup)]; } bb25 (cleanup): { - StorageDead(_3); + BackwardIncompatibleDropHint(_3, UnwindStorageDead); drop(_2) -> [return: bb26, unwind terminate(cleanup)]; } bb26 (cleanup): { - StorageDead(_2); + BackwardIncompatibleDropHint(_2, UnwindStorageDead); drop(_1) -> [return: bb27, unwind terminate(cleanup)]; } diff --git a/tests/mir-opt/building/match/array_len.slice_len.built.after.panic-abort.mir b/tests/mir-opt/building/match/array_len.slice_len.built.after.panic-abort.mir index d73f5a1b6f716..eab4cdfd062c6 100644 --- a/tests/mir-opt/building/match/array_len.slice_len.built.after.panic-abort.mir +++ b/tests/mir-opt/building/match/array_len.slice_len.built.after.panic-abort.mir @@ -59,7 +59,7 @@ fn slice_len(_1: &[T]) -> () { StorageLive(_10); StorageLive(_11); _11 = copy _6; - _10 = opaque::<&T>(move _11) -> [return: bb5, unwind: bb11]; + _10 = opaque::<&T>(move _11) -> [return: bb5, unwind: bb14]; } bb5: { @@ -68,7 +68,7 @@ fn slice_len(_1: &[T]) -> () { StorageLive(_12); StorageLive(_13); _13 = copy _7; - _12 = opaque::<&T>(move _13) -> [return: bb6, unwind: bb11]; + _12 = opaque::<&T>(move _13) -> [return: bb6, unwind: bb13]; } bb6: { @@ -77,7 +77,7 @@ fn slice_len(_1: &[T]) -> () { StorageLive(_14); StorageLive(_15); _15 = copy _8; - _14 = opaque::<&[T]>(move _15) -> [return: bb7, unwind: bb11]; + _14 = opaque::<&[T]>(move _15) -> [return: bb7, unwind: bb12]; } bb7: { @@ -110,6 +110,34 @@ fn slice_len(_1: &[T]) -> () { } bb11 (cleanup): { + BackwardIncompatibleDropHint(_17, UnwindStorageDead); + BackwardIncompatibleDropHint(_16, UnwindStorageDead); + goto -> bb15; + } + + bb12 (cleanup): { + BackwardIncompatibleDropHint(_15, UnwindStorageDead); + BackwardIncompatibleDropHint(_14, UnwindStorageDead); + goto -> bb15; + } + + bb13 (cleanup): { + BackwardIncompatibleDropHint(_13, UnwindStorageDead); + BackwardIncompatibleDropHint(_12, UnwindStorageDead); + goto -> bb15; + } + + bb14 (cleanup): { + BackwardIncompatibleDropHint(_11, UnwindStorageDead); + BackwardIncompatibleDropHint(_10, UnwindStorageDead); + goto -> bb15; + } + + bb15 (cleanup): { + BackwardIncompatibleDropHint(_9, UnwindStorageDead); + BackwardIncompatibleDropHint(_8, UnwindStorageDead); + BackwardIncompatibleDropHint(_7, UnwindStorageDead); + BackwardIncompatibleDropHint(_6, UnwindStorageDead); resume; } } diff --git a/tests/mir-opt/building/match/array_len.slice_len.built.after.panic-unwind.mir b/tests/mir-opt/building/match/array_len.slice_len.built.after.panic-unwind.mir index d73f5a1b6f716..eab4cdfd062c6 100644 --- a/tests/mir-opt/building/match/array_len.slice_len.built.after.panic-unwind.mir +++ b/tests/mir-opt/building/match/array_len.slice_len.built.after.panic-unwind.mir @@ -59,7 +59,7 @@ fn slice_len(_1: &[T]) -> () { StorageLive(_10); StorageLive(_11); _11 = copy _6; - _10 = opaque::<&T>(move _11) -> [return: bb5, unwind: bb11]; + _10 = opaque::<&T>(move _11) -> [return: bb5, unwind: bb14]; } bb5: { @@ -68,7 +68,7 @@ fn slice_len(_1: &[T]) -> () { StorageLive(_12); StorageLive(_13); _13 = copy _7; - _12 = opaque::<&T>(move _13) -> [return: bb6, unwind: bb11]; + _12 = opaque::<&T>(move _13) -> [return: bb6, unwind: bb13]; } bb6: { @@ -77,7 +77,7 @@ fn slice_len(_1: &[T]) -> () { StorageLive(_14); StorageLive(_15); _15 = copy _8; - _14 = opaque::<&[T]>(move _15) -> [return: bb7, unwind: bb11]; + _14 = opaque::<&[T]>(move _15) -> [return: bb7, unwind: bb12]; } bb7: { @@ -110,6 +110,34 @@ fn slice_len(_1: &[T]) -> () { } bb11 (cleanup): { + BackwardIncompatibleDropHint(_17, UnwindStorageDead); + BackwardIncompatibleDropHint(_16, UnwindStorageDead); + goto -> bb15; + } + + bb12 (cleanup): { + BackwardIncompatibleDropHint(_15, UnwindStorageDead); + BackwardIncompatibleDropHint(_14, UnwindStorageDead); + goto -> bb15; + } + + bb13 (cleanup): { + BackwardIncompatibleDropHint(_13, UnwindStorageDead); + BackwardIncompatibleDropHint(_12, UnwindStorageDead); + goto -> bb15; + } + + bb14 (cleanup): { + BackwardIncompatibleDropHint(_11, UnwindStorageDead); + BackwardIncompatibleDropHint(_10, UnwindStorageDead); + goto -> bb15; + } + + bb15 (cleanup): { + BackwardIncompatibleDropHint(_9, UnwindStorageDead); + BackwardIncompatibleDropHint(_8, UnwindStorageDead); + BackwardIncompatibleDropHint(_7, UnwindStorageDead); + BackwardIncompatibleDropHint(_6, UnwindStorageDead); resume; } } diff --git a/tests/mir-opt/building/match/match_false_edges.full_tested_match.built.after.mir b/tests/mir-opt/building/match/match_false_edges.full_tested_match.built.after.mir index 4b0cdcfbb8662..b1a61281fed58 100644 --- a/tests/mir-opt/building/match/match_false_edges.full_tested_match.built.after.mir +++ b/tests/mir-opt/building/match/match_false_edges.full_tested_match.built.after.mir @@ -123,6 +123,10 @@ fn full_tested_match() -> () { } bb16 (cleanup): { + BackwardIncompatibleDropHint(_7, UnwindStorageDead); + BackwardIncompatibleDropHint(_6, UnwindStorageDead); + BackwardIncompatibleDropHint(_2, UnwindStorageDead); + BackwardIncompatibleDropHint(_1, UnwindStorageDead); resume; } } diff --git a/tests/mir-opt/building/match/match_false_edges.full_tested_match2.built.after.mir b/tests/mir-opt/building/match/match_false_edges.full_tested_match2.built.after.mir index 63ec71fdf5133..413e2289f0588 100644 --- a/tests/mir-opt/building/match/match_false_edges.full_tested_match2.built.after.mir +++ b/tests/mir-opt/building/match/match_false_edges.full_tested_match2.built.after.mir @@ -123,6 +123,10 @@ fn full_tested_match2() -> () { } bb16 (cleanup): { + BackwardIncompatibleDropHint(_7, UnwindStorageDead); + BackwardIncompatibleDropHint(_6, UnwindStorageDead); + BackwardIncompatibleDropHint(_2, UnwindStorageDead); + BackwardIncompatibleDropHint(_1, UnwindStorageDead); resume; } } diff --git a/tests/mir-opt/building/match/match_false_edges.main.built.after.mir b/tests/mir-opt/building/match/match_false_edges.main.built.after.mir index 3b10adb499cd5..d4f5204a48f85 100644 --- a/tests/mir-opt/building/match/match_false_edges.main.built.after.mir +++ b/tests/mir-opt/building/match/match_false_edges.main.built.after.mir @@ -107,7 +107,7 @@ fn main() -> () { _7 = &((_2 as Some).0: i32); _3 = &fake shallow _2; StorageLive(_8); - _8 = guard() -> [return: bb14, unwind: bb24]; + _8 = guard() -> [return: bb14, unwind: bb25]; } bb13: { @@ -182,6 +182,21 @@ fn main() -> () { } bb24 (cleanup): { + BackwardIncompatibleDropHint(_13, UnwindStorageDead); + BackwardIncompatibleDropHint(_12, UnwindStorageDead); + BackwardIncompatibleDropHint(_11, UnwindStorageDead); + goto -> bb26; + } + + bb25 (cleanup): { + BackwardIncompatibleDropHint(_8, UnwindStorageDead); + BackwardIncompatibleDropHint(_7, UnwindStorageDead); + goto -> bb26; + } + + bb26 (cleanup): { + BackwardIncompatibleDropHint(_2, UnwindStorageDead); + BackwardIncompatibleDropHint(_1, UnwindStorageDead); resume; } } diff --git a/tests/mir-opt/building/match/sort_candidates.constant_eq.SimplifyCfg-initial.after.mir b/tests/mir-opt/building/match/sort_candidates.constant_eq.SimplifyCfg-initial.after.mir index 4d13d087586e7..c88d31d61c252 100644 --- a/tests/mir-opt/building/match/sort_candidates.constant_eq.SimplifyCfg-initial.after.mir +++ b/tests/mir-opt/building/match/sort_candidates.constant_eq.SimplifyCfg-initial.after.mir @@ -120,6 +120,7 @@ fn constant_eq(_1: &str, _2: bool) -> u32 { } bb19 (cleanup): { + BackwardIncompatibleDropHint(_3, UnwindStorageDead); resume; } } diff --git a/tests/mir-opt/building/receiver_ptr_mutability.main.built.after.mir b/tests/mir-opt/building/receiver_ptr_mutability.main.built.after.mir index 0c73bd8ac6543..aa8b0c1960141 100644 --- a/tests/mir-opt/building/receiver_ptr_mutability.main.built.after.mir +++ b/tests/mir-opt/building/receiver_ptr_mutability.main.built.after.mir @@ -29,7 +29,7 @@ fn main() -> () { bb0: { StorageLive(_1); - _1 = null_mut::() -> [return: bb1, unwind: bb4]; + _1 = null_mut::() -> [return: bb1, unwind: bb6]; } bb1: { @@ -41,7 +41,7 @@ fn main() -> () { _4 = copy _1; _3 = move _4 as *const Test (PointerCoercion(MutToConstPointer, Implicit)); StorageDead(_4); - _2 = Test::x(move _3) -> [return: bb2, unwind: bb4]; + _2 = Test::x(move _3) -> [return: bb2, unwind: bb5]; } bb2: { @@ -82,6 +82,23 @@ fn main() -> () { } bb4 (cleanup): { + BackwardIncompatibleDropHint(_11, UnwindStorageDead); + BackwardIncompatibleDropHint(_10, UnwindStorageDead); + BackwardIncompatibleDropHint(_9, UnwindStorageDead); + BackwardIncompatibleDropHint(_8, UnwindStorageDead); + BackwardIncompatibleDropHint(_7, UnwindStorageDead); + BackwardIncompatibleDropHint(_5, UnwindStorageDead); + goto -> bb6; + } + + bb5 (cleanup): { + BackwardIncompatibleDropHint(_3, UnwindStorageDead); + BackwardIncompatibleDropHint(_2, UnwindStorageDead); + goto -> bb6; + } + + bb6 (cleanup): { + BackwardIncompatibleDropHint(_1, UnwindStorageDead); resume; } } diff --git a/tests/mir-opt/building/shifts.shift_signed.built.after.mir b/tests/mir-opt/building/shifts.shift_signed.built.after.mir index 65e2db300cdea..0b2fdf085349c 100644 --- a/tests/mir-opt/building/shifts.shift_signed.built.after.mir +++ b/tests/mir-opt/building/shifts.shift_signed.built.after.mir @@ -49,7 +49,7 @@ fn shift_signed(_1: i8, _2: u128, _3: i8, _4: i32, _5: i128) -> ([i8; 3], [u128; _9 = copy _3; _10 = copy _9 as u8 (IntToInt); _11 = Lt(move _10, const 8_u8); - assert(move _11, "attempt to shift right by `{}`, which would overflow", copy _9) -> [success: bb1, unwind: bb7]; + assert(move _11, "attempt to shift right by `{}`, which would overflow", copy _9) -> [success: bb1, unwind: bb15]; } bb1: { @@ -63,7 +63,7 @@ fn shift_signed(_1: i8, _2: u128, _3: i8, _4: i32, _5: i128) -> ([i8; 3], [u128; _14 = copy _4; _15 = copy _14 as u32 (IntToInt); _16 = Lt(move _15, const 8_u32); - assert(move _16, "attempt to shift right by `{}`, which would overflow", copy _14) -> [success: bb2, unwind: bb7]; + assert(move _16, "attempt to shift right by `{}`, which would overflow", copy _14) -> [success: bb2, unwind: bb13]; } bb2: { @@ -77,7 +77,7 @@ fn shift_signed(_1: i8, _2: u128, _3: i8, _4: i32, _5: i128) -> ([i8; 3], [u128; _19 = copy _5; _20 = copy _19 as u128 (IntToInt); _21 = Lt(move _20, const 8_u128); - assert(move _21, "attempt to shift right by `{}`, which would overflow", copy _19) -> [success: bb3, unwind: bb7]; + assert(move _21, "attempt to shift right by `{}`, which would overflow", copy _19) -> [success: bb3, unwind: bb12]; } bb3: { @@ -96,7 +96,7 @@ fn shift_signed(_1: i8, _2: u128, _3: i8, _4: i32, _5: i128) -> ([i8; 3], [u128; _25 = copy _3; _26 = copy _25 as u8 (IntToInt); _27 = Lt(move _26, const 128_u8); - assert(move _27, "attempt to shift left by `{}`, which would overflow", copy _25) -> [success: bb4, unwind: bb7]; + assert(move _27, "attempt to shift left by `{}`, which would overflow", copy _25) -> [success: bb4, unwind: bb10]; } bb4: { @@ -110,7 +110,7 @@ fn shift_signed(_1: i8, _2: u128, _3: i8, _4: i32, _5: i128) -> ([i8; 3], [u128; _30 = copy _4; _31 = copy _30 as u32 (IntToInt); _32 = Lt(move _31, const 128_u32); - assert(move _32, "attempt to shift left by `{}`, which would overflow", copy _30) -> [success: bb5, unwind: bb7]; + assert(move _32, "attempt to shift left by `{}`, which would overflow", copy _30) -> [success: bb5, unwind: bb8]; } bb5: { @@ -142,6 +142,66 @@ fn shift_signed(_1: i8, _2: u128, _3: i8, _4: i32, _5: i128) -> ([i8; 3], [u128; } bb7 (cleanup): { + BackwardIncompatibleDropHint(_35, UnwindStorageDead); + BackwardIncompatibleDropHint(_34, UnwindStorageDead); + BackwardIncompatibleDropHint(_33, UnwindStorageDead); + goto -> bb9; + } + + bb8 (cleanup): { + BackwardIncompatibleDropHint(_30, UnwindStorageDead); + BackwardIncompatibleDropHint(_29, UnwindStorageDead); + goto -> bb9; + } + + bb9 (cleanup): { + BackwardIncompatibleDropHint(_28, UnwindStorageDead); + goto -> bb11; + } + + bb10 (cleanup): { + BackwardIncompatibleDropHint(_25, UnwindStorageDead); + BackwardIncompatibleDropHint(_24, UnwindStorageDead); + goto -> bb11; + } + + bb11 (cleanup): { + BackwardIncompatibleDropHint(_23, UnwindStorageDead); + BackwardIncompatibleDropHint(_22, UnwindStorageDead); + goto -> bb17; + } + + bb12 (cleanup): { + BackwardIncompatibleDropHint(_19, UnwindStorageDead); + BackwardIncompatibleDropHint(_18, UnwindStorageDead); + BackwardIncompatibleDropHint(_17, UnwindStorageDead); + goto -> bb14; + } + + bb13 (cleanup): { + BackwardIncompatibleDropHint(_14, UnwindStorageDead); + BackwardIncompatibleDropHint(_13, UnwindStorageDead); + goto -> bb14; + } + + bb14 (cleanup): { + BackwardIncompatibleDropHint(_12, UnwindStorageDead); + goto -> bb16; + } + + bb15 (cleanup): { + BackwardIncompatibleDropHint(_9, UnwindStorageDead); + BackwardIncompatibleDropHint(_8, UnwindStorageDead); + goto -> bb16; + } + + bb16 (cleanup): { + BackwardIncompatibleDropHint(_7, UnwindStorageDead); + goto -> bb17; + } + + bb17 (cleanup): { + BackwardIncompatibleDropHint(_6, UnwindStorageDead); resume; } } diff --git a/tests/mir-opt/building/shifts.shift_unsigned.built.after.mir b/tests/mir-opt/building/shifts.shift_unsigned.built.after.mir index 62536833e4914..ee68114b3ffd5 100644 --- a/tests/mir-opt/building/shifts.shift_unsigned.built.after.mir +++ b/tests/mir-opt/building/shifts.shift_unsigned.built.after.mir @@ -42,7 +42,7 @@ fn shift_unsigned(_1: u8, _2: i128, _3: u8, _4: u32, _5: u128) -> ([u8; 3], [i12 StorageLive(_9); _9 = copy _3; _10 = Lt(copy _9, const 8_u8); - assert(move _10, "attempt to shift right by `{}`, which would overflow", copy _9) -> [success: bb1, unwind: bb7]; + assert(move _10, "attempt to shift right by `{}`, which would overflow", copy _9) -> [success: bb1, unwind: bb15]; } bb1: { @@ -55,7 +55,7 @@ fn shift_unsigned(_1: u8, _2: i128, _3: u8, _4: u32, _5: u128) -> ([u8; 3], [i12 StorageLive(_13); _13 = copy _4; _14 = Lt(copy _13, const 8_u32); - assert(move _14, "attempt to shift right by `{}`, which would overflow", copy _13) -> [success: bb2, unwind: bb7]; + assert(move _14, "attempt to shift right by `{}`, which would overflow", copy _13) -> [success: bb2, unwind: bb13]; } bb2: { @@ -68,7 +68,7 @@ fn shift_unsigned(_1: u8, _2: i128, _3: u8, _4: u32, _5: u128) -> ([u8; 3], [i12 StorageLive(_17); _17 = copy _5; _18 = Lt(copy _17, const 8_u128); - assert(move _18, "attempt to shift right by `{}`, which would overflow", copy _17) -> [success: bb3, unwind: bb7]; + assert(move _18, "attempt to shift right by `{}`, which would overflow", copy _17) -> [success: bb3, unwind: bb12]; } bb3: { @@ -86,7 +86,7 @@ fn shift_unsigned(_1: u8, _2: i128, _3: u8, _4: u32, _5: u128) -> ([u8; 3], [i12 StorageLive(_22); _22 = copy _3; _23 = Lt(copy _22, const 128_u8); - assert(move _23, "attempt to shift left by `{}`, which would overflow", copy _22) -> [success: bb4, unwind: bb7]; + assert(move _23, "attempt to shift left by `{}`, which would overflow", copy _22) -> [success: bb4, unwind: bb10]; } bb4: { @@ -99,7 +99,7 @@ fn shift_unsigned(_1: u8, _2: i128, _3: u8, _4: u32, _5: u128) -> ([u8; 3], [i12 StorageLive(_26); _26 = copy _4; _27 = Lt(copy _26, const 128_u32); - assert(move _27, "attempt to shift left by `{}`, which would overflow", copy _26) -> [success: bb5, unwind: bb7]; + assert(move _27, "attempt to shift left by `{}`, which would overflow", copy _26) -> [success: bb5, unwind: bb8]; } bb5: { @@ -130,6 +130,66 @@ fn shift_unsigned(_1: u8, _2: i128, _3: u8, _4: u32, _5: u128) -> ([u8; 3], [i12 } bb7 (cleanup): { + BackwardIncompatibleDropHint(_30, UnwindStorageDead); + BackwardIncompatibleDropHint(_29, UnwindStorageDead); + BackwardIncompatibleDropHint(_28, UnwindStorageDead); + goto -> bb9; + } + + bb8 (cleanup): { + BackwardIncompatibleDropHint(_26, UnwindStorageDead); + BackwardIncompatibleDropHint(_25, UnwindStorageDead); + goto -> bb9; + } + + bb9 (cleanup): { + BackwardIncompatibleDropHint(_24, UnwindStorageDead); + goto -> bb11; + } + + bb10 (cleanup): { + BackwardIncompatibleDropHint(_22, UnwindStorageDead); + BackwardIncompatibleDropHint(_21, UnwindStorageDead); + goto -> bb11; + } + + bb11 (cleanup): { + BackwardIncompatibleDropHint(_20, UnwindStorageDead); + BackwardIncompatibleDropHint(_19, UnwindStorageDead); + goto -> bb17; + } + + bb12 (cleanup): { + BackwardIncompatibleDropHint(_17, UnwindStorageDead); + BackwardIncompatibleDropHint(_16, UnwindStorageDead); + BackwardIncompatibleDropHint(_15, UnwindStorageDead); + goto -> bb14; + } + + bb13 (cleanup): { + BackwardIncompatibleDropHint(_13, UnwindStorageDead); + BackwardIncompatibleDropHint(_12, UnwindStorageDead); + goto -> bb14; + } + + bb14 (cleanup): { + BackwardIncompatibleDropHint(_11, UnwindStorageDead); + goto -> bb16; + } + + bb15 (cleanup): { + BackwardIncompatibleDropHint(_9, UnwindStorageDead); + BackwardIncompatibleDropHint(_8, UnwindStorageDead); + goto -> bb16; + } + + bb16 (cleanup): { + BackwardIncompatibleDropHint(_7, UnwindStorageDead); + goto -> bb17; + } + + bb17 (cleanup): { + BackwardIncompatibleDropHint(_6, UnwindStorageDead); resume; } } diff --git a/tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.CleanupPostBorrowck.after.mir b/tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.CleanupPostBorrowck.after.mir index 17756938b889d..394a38729a1d1 100644 --- a/tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.CleanupPostBorrowck.after.mir +++ b/tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.CleanupPostBorrowck.after.mir @@ -46,7 +46,7 @@ fn move_out_by_subslice() -> () { bb5: { StorageDead(_4); - drop(_1) -> [return: bb6, unwind: bb9]; + drop(_1) -> [return: bb6, unwind: bb10]; } bb6: { @@ -55,14 +55,22 @@ fn move_out_by_subslice() -> () { } bb7 (cleanup): { - drop(_1) -> [return: bb9, unwind terminate(cleanup)]; + nop; + drop(_1) -> [return: bb10, unwind terminate(cleanup)]; } bb8 (cleanup): { + nop; drop(_2) -> [return: bb9, unwind terminate(cleanup)]; } bb9 (cleanup): { + nop; + goto -> bb10; + } + + bb10 (cleanup): { + nop; resume; } } diff --git a/tests/mir-opt/building/uniform_array_move_out.move_out_from_end.CleanupPostBorrowck.after.mir b/tests/mir-opt/building/uniform_array_move_out.move_out_from_end.CleanupPostBorrowck.after.mir index 79e0f0af0dbc8..639a7043d1f48 100644 --- a/tests/mir-opt/building/uniform_array_move_out.move_out_from_end.CleanupPostBorrowck.after.mir +++ b/tests/mir-opt/building/uniform_array_move_out.move_out_from_end.CleanupPostBorrowck.after.mir @@ -46,7 +46,7 @@ fn move_out_from_end() -> () { bb5: { StorageDead(_4); - drop(_1) -> [return: bb6, unwind: bb9]; + drop(_1) -> [return: bb6, unwind: bb10]; } bb6: { @@ -55,14 +55,22 @@ fn move_out_from_end() -> () { } bb7 (cleanup): { - drop(_1) -> [return: bb9, unwind terminate(cleanup)]; + nop; + drop(_1) -> [return: bb10, unwind terminate(cleanup)]; } bb8 (cleanup): { + nop; drop(_2) -> [return: bb9, unwind terminate(cleanup)]; } bb9 (cleanup): { + nop; + goto -> bb10; + } + + bb10 (cleanup): { + nop; resume; } } diff --git a/tests/mir-opt/building/unwind_drop_hint.rs b/tests/mir-opt/building/unwind_drop_hint.rs index b4ab00b6c04eb..25ca2c0580e6f 100644 --- a/tests/mir-opt/building/unwind_drop_hint.rs +++ b/tests/mir-opt/building/unwind_drop_hint.rs @@ -1,5 +1,4 @@ //@ compile-flags: -Zmir-opt-level=0 -//@ skip-filecheck // Non-coroutine unwind paths use BackwardIncompatibleDropHint where a future // edition would insert StorageDead. @@ -12,6 +11,11 @@ impl Drop for Droppable { } fn test() { + // CHECK-LABEL: fn test( + // The built MIR dump asserts the exact BackwardIncompatibleDropHint placement. + // FileCheck runs on post-borrowck MIR, where CleanupPostBorrowck has removed + // those hints again. + // CHECK-NOT: BackwardIncompatibleDropHint let x = 42i32; let y = Droppable; may_panic(); diff --git a/tests/mir-opt/building/unwind_drop_hint.test.built.after.mir b/tests/mir-opt/building/unwind_drop_hint.test.built.after.mir index 9e1624ec9a2bb..f3c6ae1e57777 100644 --- a/tests/mir-opt/building/unwind_drop_hint.test.built.after.mir +++ b/tests/mir-opt/building/unwind_drop_hint.test.built.after.mir @@ -36,13 +36,13 @@ fn test() -> () { } bb3 (cleanup): { - BackwardIncompatibleDropHint(_3); + BackwardIncompatibleDropHint(_3, UnwindStorageDead); drop(_2) -> [return: bb4, unwind terminate(cleanup)]; } bb4 (cleanup): { - BackwardIncompatibleDropHint(_2); - BackwardIncompatibleDropHint(_1); + BackwardIncompatibleDropHint(_2, UnwindStorageDead); + BackwardIncompatibleDropHint(_1, UnwindStorageDead); resume; } } diff --git a/tests/mir-opt/building/write_box_via_move.box_new.CleanupPostBorrowck.after.mir b/tests/mir-opt/building/write_box_via_move.box_new.CleanupPostBorrowck.after.mir index 0050151e89b1b..52c8cc3380957 100644 --- a/tests/mir-opt/building/write_box_via_move.box_new.CleanupPostBorrowck.after.mir +++ b/tests/mir-opt/building/write_box_via_move.box_new.CleanupPostBorrowck.after.mir @@ -13,7 +13,7 @@ fn box_new(_1: T) -> Box<[T; 1024]> { bb0: { StorageLive(_2); - _2 = Box::<[T; 1024]>::new_uninit() -> [return: bb1, unwind: bb7]; + _2 = Box::<[T; 1024]>::new_uninit() -> [return: bb1, unwind: bb8]; } bb1: { @@ -31,12 +31,12 @@ fn box_new(_1: T) -> Box<[T; 1024]> { bb2: { StorageDead(_4); - _0 = Box::>::assume_init(move _3) -> [return: bb3, unwind: bb5]; + _0 = Box::>::assume_init(move _3) -> [return: bb3, unwind: bb6]; } bb3: { StorageDead(_3); - drop(_2) -> [return: bb4, unwind: bb7]; + drop(_2) -> [return: bb4, unwind: bb8]; } bb4: { @@ -45,14 +45,21 @@ fn box_new(_1: T) -> Box<[T; 1024]> { } bb5 (cleanup): { - drop(_3) -> [return: bb6, unwind terminate(cleanup)]; + nop; + goto -> bb6; } bb6 (cleanup): { - drop(_2) -> [return: bb7, unwind terminate(cleanup)]; + drop(_3) -> [return: bb7, unwind terminate(cleanup)]; } bb7 (cleanup): { + nop; + drop(_2) -> [return: bb8, unwind terminate(cleanup)]; + } + + bb8 (cleanup): { + nop; resume; } } diff --git a/tests/mir-opt/building/write_box_via_move.vec_macro.CleanupPostBorrowck.after.mir b/tests/mir-opt/building/write_box_via_move.vec_macro.CleanupPostBorrowck.after.mir index 2410e4d31b486..a95abc0a2a3c7 100644 --- a/tests/mir-opt/building/write_box_via_move.vec_macro.CleanupPostBorrowck.after.mir +++ b/tests/mir-opt/building/write_box_via_move.vec_macro.CleanupPostBorrowck.after.mir @@ -8,7 +8,7 @@ fn vec_macro() -> Vec { bb0: { StorageLive(_1); StorageLive(_2); - _2 = Box::<[i32; 8]>::new_uninit() -> [return: bb1, unwind: bb5]; + _2 = Box::<[i32; 8]>::new_uninit() -> [return: bb1, unwind: bb6]; } bb1: { @@ -19,7 +19,7 @@ fn vec_macro() -> Vec { bb2: { StorageDead(_2); - _0 = std::boxed::box_assume_init_into_vec_unsafe::(move _1) -> [return: bb3, unwind: bb4]; + _0 = std::boxed::box_assume_init_into_vec_unsafe::(move _1) -> [return: bb3, unwind: bb5]; } bb3: { @@ -28,10 +28,21 @@ fn vec_macro() -> Vec { } bb4 (cleanup): { - drop(_1) -> [return: bb5, unwind terminate(cleanup)]; + nop; + goto -> bb5; } bb5 (cleanup): { + drop(_1) -> [return: bb7, unwind terminate(cleanup)]; + } + + bb6 (cleanup): { + nop; + goto -> bb7; + } + + bb7 (cleanup): { + nop; resume; } } diff --git a/tests/mir-opt/building/write_via_move.box_new.CleanupPostBorrowck.after.mir b/tests/mir-opt/building/write_via_move.box_new.CleanupPostBorrowck.after.mir index 6a6e984023b75..cdc53da7ebb6b 100644 --- a/tests/mir-opt/building/write_via_move.box_new.CleanupPostBorrowck.after.mir +++ b/tests/mir-opt/building/write_via_move.box_new.CleanupPostBorrowck.after.mir @@ -20,7 +20,7 @@ fn box_new(_1: T) -> Box<[T; 1024]> { bb0: { StorageLive(_2); - _2 = Box::<[T; 1024]>::new_uninit() -> [return: bb1, unwind: bb7]; + _2 = Box::<[T; 1024]>::new_uninit() -> [return: bb1, unwind: bb9]; } bb1: { @@ -30,7 +30,7 @@ fn box_new(_1: T) -> Box<[T; 1024]> { StorageLive(_5); _5 = &mut (*_2); _4 = &mut (*_5); - _3 = MaybeUninit::<[T; 1024]>::as_mut_ptr(move _4) -> [return: bb2, unwind: bb6]; + _3 = MaybeUninit::<[T; 1024]>::as_mut_ptr(move _4) -> [return: bb2, unwind: bb7]; } bb2: { @@ -54,7 +54,7 @@ fn box_new(_1: T) -> Box<[T; 1024]> { bb3: { StorageDead(_9); StorageDead(_3); - drop(_2) -> [return: bb4, unwind: bb7]; + drop(_2) -> [return: bb4, unwind: bb9]; } bb4: { @@ -67,10 +67,23 @@ fn box_new(_1: T) -> Box<[T; 1024]> { } bb6 (cleanup): { - drop(_2) -> [return: bb7, unwind terminate(cleanup)]; + nop; + goto -> bb8; } bb7 (cleanup): { + nop; + nop; + goto -> bb8; + } + + bb8 (cleanup): { + nop; + drop(_2) -> [return: bb9, unwind terminate(cleanup)]; + } + + bb9 (cleanup): { + nop; resume; } } diff --git a/tests/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff b/tests/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff index 5f8f84244af6c..751a81aebaa97 100644 --- a/tests/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff +++ b/tests/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff @@ -36,6 +36,9 @@ } bb2 (cleanup): { + BackwardIncompatibleDropHint(_5, UnwindStorageDead); + BackwardIncompatibleDropHint(_3, UnwindStorageDead); + BackwardIncompatibleDropHint(_1, UnwindStorageDead); resume; } } diff --git a/tests/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff b/tests/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff index 0e4eed2c028d0..a69fbe43fb54c 100644 --- a/tests/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff +++ b/tests/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff @@ -36,6 +36,9 @@ } bb2 (cleanup): { + BackwardIncompatibleDropHint(_5, UnwindStorageDead); + BackwardIncompatibleDropHint(_3, UnwindStorageDead); + BackwardIncompatibleDropHint(_1, UnwindStorageDead); resume; } } diff --git a/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff b/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff index fa88211383a04..8b88ea329d2ee 100644 --- a/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff +++ b/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff @@ -85,7 +85,7 @@ _7 = copy ((_1 as B).0: u32); StorageLive(_8); _8 = copy _7; - _0 = consume(move _8) -> [return: bb11, unwind: bb14]; + _0 = consume(move _8) -> [return: bb11, unwind: bb15]; } bb7: { @@ -93,7 +93,7 @@ _5 = copy ((_1 as C).0: u32); StorageLive(_6); _6 = copy _5; - _0 = consume(move _6) -> [return: bb10, unwind: bb14]; + _0 = consume(move _6) -> [return: bb10, unwind: bb16]; } bb8: { @@ -101,7 +101,7 @@ _3 = copy ((_1 as D).0: u32); StorageLive(_4); _4 = copy _3; - _0 = consume(move _4) -> [return: bb9, unwind: bb14]; + _0 = consume(move _4) -> [return: bb9, unwind: bb17]; } bb9: { @@ -135,6 +135,31 @@ } bb14 (cleanup): { + BackwardIncompatibleDropHint(_10, UnwindStorageDead); + BackwardIncompatibleDropHint(_9, UnwindStorageDead); + goto -> bb18; + } + + bb15 (cleanup): { + BackwardIncompatibleDropHint(_8, UnwindStorageDead); + BackwardIncompatibleDropHint(_7, UnwindStorageDead); + goto -> bb18; + } + + bb16 (cleanup): { + BackwardIncompatibleDropHint(_6, UnwindStorageDead); + BackwardIncompatibleDropHint(_5, UnwindStorageDead); + goto -> bb18; + } + + bb17 (cleanup): { + BackwardIncompatibleDropHint(_4, UnwindStorageDead); + BackwardIncompatibleDropHint(_3, UnwindStorageDead); + goto -> bb18; + } + + bb18 (cleanup): { + BackwardIncompatibleDropHint(_1, UnwindStorageDead); resume; } } diff --git a/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff b/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff index b2bb2375aee60..95983e84eff37 100644 --- a/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff +++ b/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff @@ -20,7 +20,7 @@ bb1: { + Coverage::VirtualCounter(bcb1); - falseUnwind -> [real: bb2, unwind: bb6]; + falseUnwind -> [real: bb2, unwind: bb7]; } bb2: { @@ -47,6 +47,11 @@ } bb6 (cleanup): { + BackwardIncompatibleDropHint(_2, UnwindStorageDead); + goto -> bb7; + } + + bb7 (cleanup): { resume; } } diff --git a/tests/mir-opt/coverage/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff b/tests/mir-opt/coverage/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff index 2eb78c08ee800..c5c606e7e8df7 100644 --- a/tests/mir-opt/coverage/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff +++ b/tests/mir-opt/coverage/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff @@ -49,6 +49,8 @@ } bb5 (cleanup): { +- BackwardIncompatibleDropHint(_1, UnwindStorageDead); ++ nop; resume; } } diff --git a/tests/mir-opt/coverage/instrument_coverage_cleanup.main.InstrumentCoverage.diff b/tests/mir-opt/coverage/instrument_coverage_cleanup.main.InstrumentCoverage.diff index 0c1bc24b6dc19..24820c84f9f11 100644 --- a/tests/mir-opt/coverage/instrument_coverage_cleanup.main.InstrumentCoverage.diff +++ b/tests/mir-opt/coverage/instrument_coverage_cleanup.main.InstrumentCoverage.diff @@ -46,6 +46,7 @@ } bb5 (cleanup): { + BackwardIncompatibleDropHint(_1, UnwindStorageDead); resume; } } diff --git a/tests/mir-opt/drop_hint_removed_after_borrowck.rs b/tests/mir-opt/drop_hint_removed_after_borrowck.rs index 93c2dca527e71..f7270372c2bef 100644 --- a/tests/mir-opt/drop_hint_removed_after_borrowck.rs +++ b/tests/mir-opt/drop_hint_removed_after_borrowck.rs @@ -1,6 +1,5 @@ //@ compile-flags: -Zmir-opt-level=0 //@ test-mir-pass: CleanupPostBorrowck -//@ skip-filecheck // BackwardIncompatibleDropHint is only needed for borrowck/linting and should be // removed after borrowck by CleanupPostBorrowck. @@ -14,6 +13,8 @@ impl Drop for Droppable { } fn test() { + // CHECK-LABEL: fn test( + // CHECK-NOT: BackwardIncompatibleDropHint let x = 42i32; let y = Droppable; may_panic(); diff --git a/tests/mir-opt/drop_hint_removed_after_borrowck.test.built.after.mir b/tests/mir-opt/drop_hint_removed_after_borrowck.test.built.after.mir index 9e1624ec9a2bb..f3c6ae1e57777 100644 --- a/tests/mir-opt/drop_hint_removed_after_borrowck.test.built.after.mir +++ b/tests/mir-opt/drop_hint_removed_after_borrowck.test.built.after.mir @@ -36,13 +36,13 @@ fn test() -> () { } bb3 (cleanup): { - BackwardIncompatibleDropHint(_3); + BackwardIncompatibleDropHint(_3, UnwindStorageDead); drop(_2) -> [return: bb4, unwind terminate(cleanup)]; } bb4 (cleanup): { - BackwardIncompatibleDropHint(_2); - BackwardIncompatibleDropHint(_1); + BackwardIncompatibleDropHint(_2, UnwindStorageDead); + BackwardIncompatibleDropHint(_1, UnwindStorageDead); resume; } } diff --git a/tests/mir-opt/issue_38669.main.SimplifyCfg-initial.after.mir b/tests/mir-opt/issue_38669.main.SimplifyCfg-initial.after.mir index 66dbbc0c044b3..fc700f3209d01 100644 --- a/tests/mir-opt/issue_38669.main.SimplifyCfg-initial.after.mir +++ b/tests/mir-opt/issue_38669.main.SimplifyCfg-initial.after.mir @@ -47,6 +47,7 @@ fn main() -> () { } bb5 (cleanup): { + BackwardIncompatibleDropHint(_1, UnwindStorageDead); resume; } } diff --git a/tests/mir-opt/issue_72181.foo.built.after.mir b/tests/mir-opt/issue_72181.foo.built.after.mir index 7593b79543258..4af25075840df 100644 --- a/tests/mir-opt/issue_72181.foo.built.after.mir +++ b/tests/mir-opt/issue_72181.foo.built.after.mir @@ -21,6 +21,7 @@ fn foo(_1: [(Never, u32); 1]) -> u32 { } bb2 (cleanup): { + BackwardIncompatibleDropHint(_2, UnwindStorageDead); resume; } } diff --git a/tests/mir-opt/issue_72181.main.built.after.mir b/tests/mir-opt/issue_72181.main.built.after.mir index 9f3803f5407fe..4ca0d6ba9078f 100644 --- a/tests/mir-opt/issue_72181.main.built.after.mir +++ b/tests/mir-opt/issue_72181.main.built.after.mir @@ -19,7 +19,7 @@ fn main() -> () { bb0: { StorageLive(_1); - _1 = std::mem::size_of::() -> [return: bb1, unwind: bb5]; + _1 = std::mem::size_of::() -> [return: bb1, unwind: bb6]; } bb1: { @@ -63,6 +63,18 @@ fn main() -> () { } bb5 (cleanup): { + BackwardIncompatibleDropHint(_6, UnwindStorageDead); + BackwardIncompatibleDropHint(_5, UnwindStorageDead); + BackwardIncompatibleDropHint(_2, UnwindStorageDead); + goto -> bb7; + } + + bb6 (cleanup): { + BackwardIncompatibleDropHint(_1, UnwindStorageDead); + goto -> bb7; + } + + bb7 (cleanup): { resume; } } diff --git a/tests/mir-opt/issue_72181_1.main.built.after.mir b/tests/mir-opt/issue_72181_1.main.built.after.mir index 977d48d6d25f0..86cdb666b6466 100644 --- a/tests/mir-opt/issue_72181_1.main.built.after.mir +++ b/tests/mir-opt/issue_72181_1.main.built.after.mir @@ -19,7 +19,7 @@ fn main() -> () { StorageLive(_2); StorageLive(_3); _3 = (); - _2 = std::intrinsics::transmute::<(), Void>(move _3) -> [return: bb1, unwind: bb4]; + _2 = std::intrinsics::transmute::<(), Void>(move _3) -> [return: bb1, unwind: bb5]; } bb1: { @@ -44,6 +44,18 @@ fn main() -> () { } bb4 (cleanup): { + BackwardIncompatibleDropHint(_5, UnwindStorageDead); + BackwardIncompatibleDropHint(_4, UnwindStorageDead); + goto -> bb6; + } + + bb5 (cleanup): { + BackwardIncompatibleDropHint(_3, UnwindStorageDead); + goto -> bb6; + } + + bb6 (cleanup): { + BackwardIncompatibleDropHint(_2, UnwindStorageDead); resume; } } diff --git a/tests/mir-opt/issue_91633.bar.built.after.mir b/tests/mir-opt/issue_91633.bar.built.after.mir index 0cb9da79b5a0f..231f04c9d9517 100644 --- a/tests/mir-opt/issue_91633.bar.built.after.mir +++ b/tests/mir-opt/issue_91633.bar.built.after.mir @@ -33,8 +33,8 @@ fn bar(_1: Box<[T]>) -> () { } bb4 (cleanup): { - StorageDead(_3); - StorageDead(_2); + BackwardIncompatibleDropHint(_3, UnwindStorageDead); + BackwardIncompatibleDropHint(_2, UnwindStorageDead); drop(_1) -> [return: bb5, unwind terminate(cleanup)]; } diff --git a/tests/mir-opt/issue_91633.foo.built.after.mir b/tests/mir-opt/issue_91633.foo.built.after.mir index d003419f2c8ec..4399145988ca1 100644 --- a/tests/mir-opt/issue_91633.foo.built.after.mir +++ b/tests/mir-opt/issue_91633.foo.built.after.mir @@ -47,13 +47,13 @@ fn foo(_1: Box<[T]>) -> T { } bb5 (cleanup): { - StorageDead(_3); - StorageDead(_4); + BackwardIncompatibleDropHint(_3, UnwindStorageDead); + BackwardIncompatibleDropHint(_4, UnwindStorageDead); goto -> bb6; } bb6 (cleanup): { - StorageDead(_2); + BackwardIncompatibleDropHint(_2, UnwindStorageDead); drop(_1) -> [return: bb7, unwind terminate(cleanup)]; } diff --git a/tests/mir-opt/issue_91633.fun.built.after.mir b/tests/mir-opt/issue_91633.fun.built.after.mir index 7468e591b37b2..802e2bb927e3e 100644 --- a/tests/mir-opt/issue_91633.fun.built.after.mir +++ b/tests/mir-opt/issue_91633.fun.built.after.mir @@ -30,6 +30,8 @@ fn fun(_1: &[T]) -> &T { } bb2 (cleanup): { + BackwardIncompatibleDropHint(_3, UnwindStorageDead); + BackwardIncompatibleDropHint(_2, UnwindStorageDead); resume; } } diff --git a/tests/mir-opt/issue_91633.hey.built.after.mir b/tests/mir-opt/issue_91633.hey.built.after.mir index a537e509996d7..a97c2e1f7ef3f 100644 --- a/tests/mir-opt/issue_91633.hey.built.after.mir +++ b/tests/mir-opt/issue_91633.hey.built.after.mir @@ -33,6 +33,9 @@ fn hey(_1: &[T]) -> () { } bb3 (cleanup): { + BackwardIncompatibleDropHint(_4, UnwindStorageDead); + BackwardIncompatibleDropHint(_2, UnwindStorageDead); + BackwardIncompatibleDropHint(_3, UnwindStorageDead); resume; } } diff --git a/tests/mir-opt/issue_99325.main.built.after.32bit.mir b/tests/mir-opt/issue_99325.main.built.after.32bit.mir index 14a14ffe377f2..dd23beca9644e 100644 --- a/tests/mir-opt/issue_99325.main.built.after.32bit.mir +++ b/tests/mir-opt/issue_99325.main.built.after.32bit.mir @@ -67,7 +67,7 @@ fn main() -> () { StorageLive(_2); StorageLive(_3); StorageLive(_4); - _4 = function_with_bytes::<&*b"AAAA">() -> [return: bb1, unwind: bb23]; + _4 = function_with_bytes::<&*b"AAAA">() -> [return: bb1, unwind: bb31]; } bb1: { @@ -91,7 +91,7 @@ fn main() -> () { _11 = &(*_8); StorageLive(_12); _12 = &(*_9); - _10 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _11, move _12) -> [return: bb3, unwind: bb23]; + _10 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _11, move _12) -> [return: bb3, unwind: bb29]; } bb2: { @@ -132,7 +132,7 @@ fn main() -> () { _19 = &(*_20); StorageLive(_21); _21 = Option::>::None; - _15 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _16, move _17, move _19, move _21) -> [return: bb7, unwind: bb23]; + _15 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _16, move _17, move _19, move _21) -> [return: bb7, unwind: bb28]; } bb7: { @@ -173,7 +173,7 @@ fn main() -> () { StorageLive(_23); StorageLive(_24); StorageLive(_25); - _25 = function_with_bytes::<&*b"AAAA">() -> [return: bb12, unwind: bb23]; + _25 = function_with_bytes::<&*b"AAAA">() -> [return: bb12, unwind: bb26]; } bb12: { @@ -195,7 +195,7 @@ fn main() -> () { _31 = &(*_28); StorageLive(_32); _32 = &(*_29); - _30 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _31, move _32) -> [return: bb14, unwind: bb23]; + _30 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _31, move _32) -> [return: bb14, unwind: bb24]; } bb13: { @@ -277,6 +277,83 @@ fn main() -> () { } bb23 (cleanup): { + BackwardIncompatibleDropHint(_41, UnwindStorageDead); + BackwardIncompatibleDropHint(_39, UnwindStorageDead); + BackwardIncompatibleDropHint(_37, UnwindStorageDead); + BackwardIncompatibleDropHint(_36, UnwindStorageDead); + BackwardIncompatibleDropHint(_40, UnwindStorageDead); + BackwardIncompatibleDropHint(_38, UnwindStorageDead); + BackwardIncompatibleDropHint(_35, UnwindStorageDead); + BackwardIncompatibleDropHint(_34, UnwindStorageDead); + goto -> bb25; + } + + bb24 (cleanup): { + BackwardIncompatibleDropHint(_32, UnwindStorageDead); + BackwardIncompatibleDropHint(_31, UnwindStorageDead); + goto -> bb25; + } + + bb25 (cleanup): { + BackwardIncompatibleDropHint(_30, UnwindStorageDead); + BackwardIncompatibleDropHint(_29, UnwindStorageDead); + BackwardIncompatibleDropHint(_28, UnwindStorageDead); + BackwardIncompatibleDropHint(_27, UnwindStorageDead); + goto -> bb27; + } + + bb26 (cleanup): { + BackwardIncompatibleDropHint(_24, UnwindStorageDead); + goto -> bb27; + } + + bb27 (cleanup): { + BackwardIncompatibleDropHint(_25, UnwindStorageDead); + BackwardIncompatibleDropHint(_23, UnwindStorageDead); + BackwardIncompatibleDropHint(_22, UnwindStorageDead); + goto -> bb33; + } + + bb28 (cleanup): { + BackwardIncompatibleDropHint(_21, UnwindStorageDead); + BackwardIncompatibleDropHint(_19, UnwindStorageDead); + BackwardIncompatibleDropHint(_17, UnwindStorageDead); + BackwardIncompatibleDropHint(_16, UnwindStorageDead); + BackwardIncompatibleDropHint(_20, UnwindStorageDead); + BackwardIncompatibleDropHint(_18, UnwindStorageDead); + BackwardIncompatibleDropHint(_15, UnwindStorageDead); + BackwardIncompatibleDropHint(_14, UnwindStorageDead); + goto -> bb30; + } + + bb29 (cleanup): { + BackwardIncompatibleDropHint(_12, UnwindStorageDead); + BackwardIncompatibleDropHint(_11, UnwindStorageDead); + goto -> bb30; + } + + bb30 (cleanup): { + BackwardIncompatibleDropHint(_10, UnwindStorageDead); + BackwardIncompatibleDropHint(_9, UnwindStorageDead); + BackwardIncompatibleDropHint(_8, UnwindStorageDead); + BackwardIncompatibleDropHint(_7, UnwindStorageDead); + BackwardIncompatibleDropHint(_6, UnwindStorageDead); + goto -> bb32; + } + + bb31 (cleanup): { + BackwardIncompatibleDropHint(_3, UnwindStorageDead); + goto -> bb32; + } + + bb32 (cleanup): { + BackwardIncompatibleDropHint(_4, UnwindStorageDead); + BackwardIncompatibleDropHint(_2, UnwindStorageDead); + BackwardIncompatibleDropHint(_1, UnwindStorageDead); + goto -> bb33; + } + + bb33 (cleanup): { resume; } } diff --git a/tests/mir-opt/issue_99325.main.built.after.64bit.mir b/tests/mir-opt/issue_99325.main.built.after.64bit.mir index 14a14ffe377f2..dd23beca9644e 100644 --- a/tests/mir-opt/issue_99325.main.built.after.64bit.mir +++ b/tests/mir-opt/issue_99325.main.built.after.64bit.mir @@ -67,7 +67,7 @@ fn main() -> () { StorageLive(_2); StorageLive(_3); StorageLive(_4); - _4 = function_with_bytes::<&*b"AAAA">() -> [return: bb1, unwind: bb23]; + _4 = function_with_bytes::<&*b"AAAA">() -> [return: bb1, unwind: bb31]; } bb1: { @@ -91,7 +91,7 @@ fn main() -> () { _11 = &(*_8); StorageLive(_12); _12 = &(*_9); - _10 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _11, move _12) -> [return: bb3, unwind: bb23]; + _10 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _11, move _12) -> [return: bb3, unwind: bb29]; } bb2: { @@ -132,7 +132,7 @@ fn main() -> () { _19 = &(*_20); StorageLive(_21); _21 = Option::>::None; - _15 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _16, move _17, move _19, move _21) -> [return: bb7, unwind: bb23]; + _15 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _16, move _17, move _19, move _21) -> [return: bb7, unwind: bb28]; } bb7: { @@ -173,7 +173,7 @@ fn main() -> () { StorageLive(_23); StorageLive(_24); StorageLive(_25); - _25 = function_with_bytes::<&*b"AAAA">() -> [return: bb12, unwind: bb23]; + _25 = function_with_bytes::<&*b"AAAA">() -> [return: bb12, unwind: bb26]; } bb12: { @@ -195,7 +195,7 @@ fn main() -> () { _31 = &(*_28); StorageLive(_32); _32 = &(*_29); - _30 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _31, move _32) -> [return: bb14, unwind: bb23]; + _30 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _31, move _32) -> [return: bb14, unwind: bb24]; } bb13: { @@ -277,6 +277,83 @@ fn main() -> () { } bb23 (cleanup): { + BackwardIncompatibleDropHint(_41, UnwindStorageDead); + BackwardIncompatibleDropHint(_39, UnwindStorageDead); + BackwardIncompatibleDropHint(_37, UnwindStorageDead); + BackwardIncompatibleDropHint(_36, UnwindStorageDead); + BackwardIncompatibleDropHint(_40, UnwindStorageDead); + BackwardIncompatibleDropHint(_38, UnwindStorageDead); + BackwardIncompatibleDropHint(_35, UnwindStorageDead); + BackwardIncompatibleDropHint(_34, UnwindStorageDead); + goto -> bb25; + } + + bb24 (cleanup): { + BackwardIncompatibleDropHint(_32, UnwindStorageDead); + BackwardIncompatibleDropHint(_31, UnwindStorageDead); + goto -> bb25; + } + + bb25 (cleanup): { + BackwardIncompatibleDropHint(_30, UnwindStorageDead); + BackwardIncompatibleDropHint(_29, UnwindStorageDead); + BackwardIncompatibleDropHint(_28, UnwindStorageDead); + BackwardIncompatibleDropHint(_27, UnwindStorageDead); + goto -> bb27; + } + + bb26 (cleanup): { + BackwardIncompatibleDropHint(_24, UnwindStorageDead); + goto -> bb27; + } + + bb27 (cleanup): { + BackwardIncompatibleDropHint(_25, UnwindStorageDead); + BackwardIncompatibleDropHint(_23, UnwindStorageDead); + BackwardIncompatibleDropHint(_22, UnwindStorageDead); + goto -> bb33; + } + + bb28 (cleanup): { + BackwardIncompatibleDropHint(_21, UnwindStorageDead); + BackwardIncompatibleDropHint(_19, UnwindStorageDead); + BackwardIncompatibleDropHint(_17, UnwindStorageDead); + BackwardIncompatibleDropHint(_16, UnwindStorageDead); + BackwardIncompatibleDropHint(_20, UnwindStorageDead); + BackwardIncompatibleDropHint(_18, UnwindStorageDead); + BackwardIncompatibleDropHint(_15, UnwindStorageDead); + BackwardIncompatibleDropHint(_14, UnwindStorageDead); + goto -> bb30; + } + + bb29 (cleanup): { + BackwardIncompatibleDropHint(_12, UnwindStorageDead); + BackwardIncompatibleDropHint(_11, UnwindStorageDead); + goto -> bb30; + } + + bb30 (cleanup): { + BackwardIncompatibleDropHint(_10, UnwindStorageDead); + BackwardIncompatibleDropHint(_9, UnwindStorageDead); + BackwardIncompatibleDropHint(_8, UnwindStorageDead); + BackwardIncompatibleDropHint(_7, UnwindStorageDead); + BackwardIncompatibleDropHint(_6, UnwindStorageDead); + goto -> bb32; + } + + bb31 (cleanup): { + BackwardIncompatibleDropHint(_3, UnwindStorageDead); + goto -> bb32; + } + + bb32 (cleanup): { + BackwardIncompatibleDropHint(_4, UnwindStorageDead); + BackwardIncompatibleDropHint(_2, UnwindStorageDead); + BackwardIncompatibleDropHint(_1, UnwindStorageDead); + goto -> bb33; + } + + bb33 (cleanup): { resume; } } diff --git a/tests/mir-opt/loop_test.main.SimplifyCfg-promote-consts.after.mir b/tests/mir-opt/loop_test.main.SimplifyCfg-promote-consts.after.mir index 74754bc1652e7..3f4e2baf64c95 100644 --- a/tests/mir-opt/loop_test.main.SimplifyCfg-promote-consts.after.mir +++ b/tests/mir-opt/loop_test.main.SimplifyCfg-promote-consts.after.mir @@ -47,6 +47,7 @@ fn main() -> () { } bb5 (cleanup): { + BackwardIncompatibleDropHint(_4, UnwindStorageDead); resume; } } diff --git a/tests/mir-opt/match_arm_scopes.complicated_match.panic-abort.SimplifyCfg-initial.after-ElaborateDrops.after.diff b/tests/mir-opt/match_arm_scopes.complicated_match.panic-abort.SimplifyCfg-initial.after-ElaborateDrops.after.diff index 484bc7dad1289..7f1cb6440845c 100644 --- a/tests/mir-opt/match_arm_scopes.complicated_match.panic-abort.SimplifyCfg-initial.after-ElaborateDrops.after.diff +++ b/tests/mir-opt/match_arm_scopes.complicated_match.panic-abort.SimplifyCfg-initial.after-ElaborateDrops.after.diff @@ -110,7 +110,7 @@ - bb10: { + bb7: { _0 = const 1_i32; -- drop(_7) -> [return: bb19, unwind: bb25]; +- drop(_7) -> [return: bb19, unwind: bb26]; + drop(_7) -> [return: bb16, unwind: bb22]; } @@ -224,7 +224,7 @@ } - bb22: { -- drop(_2) -> [return: bb24, unwind: bb26]; +- drop(_2) -> [return: bb24, unwind: bb28]; + bb19: { + goto -> bb26; } @@ -233,7 +233,7 @@ + bb20: { StorageDead(_8); StorageDead(_6); -- drop(_2) -> [return: bb24, unwind: bb26]; +- drop(_2) -> [return: bb24, unwind: bb28]; + drop(_2) -> [return: bb21, unwind: bb23]; } @@ -243,20 +243,30 @@ } - bb25 (cleanup): { -- drop(_2) -> [return: bb26, unwind terminate(cleanup)]; +- BackwardIncompatibleDropHint(_16, UnwindStorageDead); +- BackwardIncompatibleDropHint(_15, UnwindStorageDead); + bb22 (cleanup): { -+ goto -> bb27; + goto -> bb27; } - bb26 (cleanup): { +- BackwardIncompatibleDropHint(_7, UnwindStorageDead); +- BackwardIncompatibleDropHint(_5, UnwindStorageDead); +- BackwardIncompatibleDropHint(_8, UnwindStorageDead); +- BackwardIncompatibleDropHint(_6, UnwindStorageDead); +- goto -> bb27; + bb23 (cleanup): { - resume; -+ } -+ ++ resume; + } + +- bb27 (cleanup): { +- drop(_2) -> [return: bb28, unwind terminate(cleanup)]; + bb24: { + goto -> bb21; -+ } -+ + } + +- bb28 (cleanup): { +- resume; + bb25 (cleanup): { + goto -> bb23; + } diff --git a/tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff b/tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff index f96045bb69448..7f1cb6440845c 100644 --- a/tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff +++ b/tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff @@ -243,17 +243,17 @@ } - bb25 (cleanup): { -- StorageDead(_16); -- StorageDead(_15); +- BackwardIncompatibleDropHint(_16, UnwindStorageDead); +- BackwardIncompatibleDropHint(_15, UnwindStorageDead); + bb22 (cleanup): { goto -> bb27; } - bb26 (cleanup): { -- StorageDead(_7); -- StorageDead(_5); -- StorageDead(_8); -- StorageDead(_6); +- BackwardIncompatibleDropHint(_7, UnwindStorageDead); +- BackwardIncompatibleDropHint(_5, UnwindStorageDead); +- BackwardIncompatibleDropHint(_8, UnwindStorageDead); +- BackwardIncompatibleDropHint(_6, UnwindStorageDead); - goto -> bb27; + bb23 (cleanup): { + resume; diff --git a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir index c069ce3fdf3cf..fbc8d91d5017a 100644 --- a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir +++ b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir @@ -5,15 +5,15 @@ | '?1 | Local | ['?1] | | Inferred Region Values -| '?0 | U0 | {bb0[0..=8], bb1[0..=8], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=4], bb7[0], '?0, '?1} -| '?1 | U0 | {bb0[0..=8], bb1[0..=8], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=4], bb7[0], '?1} +| '?0 | U0 | {bb0[0..=8], bb1[0..=8], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=4], bb7[0..=1], bb8[0..=2], bb9[0..=2], bb10[0..=1], bb11[0..=2], '?0, '?1} +| '?1 | U0 | {bb0[0..=8], bb1[0..=8], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=4], bb7[0..=1], bb8[0..=2], bb9[0..=2], bb10[0..=1], bb11[0..=2], '?1} | '?2 | U0 | {bb1[0..=8], bb2[0..=2]} | '?3 | U0 | {bb1[1..=8], bb2[0..=2]} | '?4 | U0 | {bb1[5..=8], bb2[0..=2]} | | Inference Constraints -| '?0 live at {bb0[0..=8], bb1[0..=8], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=4], bb7[0]} -| '?1 live at {bb0[0..=8], bb1[0..=8], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=4], bb7[0]} +| '?0 live at {bb0[0..=8], bb1[0..=8], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=4], bb7[0..=1], bb8[0..=2], bb9[0..=2], bb10[0..=1], bb11[0..=2]} +| '?1 live at {bb0[0..=8], bb1[0..=8], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=4], bb7[0..=1], bb8[0..=2], bb9[0..=2], bb10[0..=1], bb11[0..=2]} | '?2 live at {bb1[0]} | '?3 live at {bb1[1..=4]} | '?4 live at {bb1[5..=8], bb2[0..=2]} @@ -53,7 +53,7 @@ fn main() -> () { _3 = const ConstValue(Scalar(0x00000000): usize); FakeRead(ForIndex, _1); _4 = Lt(copy _3, const ValTree(Leaf(0x00000003): usize)); - assert(move _4, "index out of bounds: the length is {} but the index is {}", const ValTree(Leaf(0x00000003): usize), copy _3) -> [success: bb1, unwind: bb7]; + assert(move _4, "index out of bounds: the length is {} but the index is {}", const ValTree(Leaf(0x00000003): usize), copy _3) -> [success: bb1, unwind: bb10]; } bb1: { @@ -72,7 +72,7 @@ fn main() -> () { StorageLive(_7); StorageLive(_8); _8 = copy (*_5); - _7 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(move _8) -> [return: bb3, unwind: bb7]; + _7 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(move _8) -> [return: bb3, unwind: bb8]; } bb3: { @@ -102,6 +102,30 @@ fn main() -> () { } bb7 (cleanup): { + BackwardIncompatibleDropHint(_9, UnwindStorageDead); + goto -> bb9; + } + + bb8 (cleanup): { + BackwardIncompatibleDropHint(_8, UnwindStorageDead); + BackwardIncompatibleDropHint(_7, UnwindStorageDead); + goto -> bb9; + } + + bb9 (cleanup): { + BackwardIncompatibleDropHint(_6, UnwindStorageDead); + BackwardIncompatibleDropHint(_5, UnwindStorageDead); + goto -> bb11; + } + + bb10 (cleanup): { + BackwardIncompatibleDropHint(_3, UnwindStorageDead); + goto -> bb11; + } + + bb11 (cleanup): { + BackwardIncompatibleDropHint(_2, UnwindStorageDead); + BackwardIncompatibleDropHint(_1, UnwindStorageDead); resume; } } diff --git a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir index a866521e7c976..56f848bc87cb8 100644 --- a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir +++ b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir @@ -5,15 +5,15 @@ | '?1 | Local | ['?1] | | Inferred Region Values -| '?0 | U0 | {bb0[0..=8], bb1[0..=8], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=4], bb7[0], '?0, '?1} -| '?1 | U0 | {bb0[0..=8], bb1[0..=8], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=4], bb7[0], '?1} +| '?0 | U0 | {bb0[0..=8], bb1[0..=8], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=4], bb7[0..=1], bb8[0..=2], bb9[0..=2], bb10[0..=1], bb11[0..=2], '?0, '?1} +| '?1 | U0 | {bb0[0..=8], bb1[0..=8], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=4], bb7[0..=1], bb8[0..=2], bb9[0..=2], bb10[0..=1], bb11[0..=2], '?1} | '?2 | U0 | {bb1[0..=8], bb2[0..=2]} | '?3 | U0 | {bb1[1..=8], bb2[0..=2]} | '?4 | U0 | {bb1[5..=8], bb2[0..=2]} | | Inference Constraints -| '?0 live at {bb0[0..=8], bb1[0..=8], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=4], bb7[0]} -| '?1 live at {bb0[0..=8], bb1[0..=8], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=4], bb7[0]} +| '?0 live at {bb0[0..=8], bb1[0..=8], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=4], bb7[0..=1], bb8[0..=2], bb9[0..=2], bb10[0..=1], bb11[0..=2]} +| '?1 live at {bb0[0..=8], bb1[0..=8], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=4], bb7[0..=1], bb8[0..=2], bb9[0..=2], bb10[0..=1], bb11[0..=2]} | '?2 live at {bb1[0]} | '?3 live at {bb1[1..=4]} | '?4 live at {bb1[5..=8], bb2[0..=2]} @@ -53,7 +53,7 @@ fn main() -> () { _3 = const ConstValue(Scalar(0x0000000000000000): usize); FakeRead(ForIndex, _1); _4 = Lt(copy _3, const ValTree(Leaf(0x0000000000000003): usize)); - assert(move _4, "index out of bounds: the length is {} but the index is {}", const ValTree(Leaf(0x0000000000000003): usize), copy _3) -> [success: bb1, unwind: bb7]; + assert(move _4, "index out of bounds: the length is {} but the index is {}", const ValTree(Leaf(0x0000000000000003): usize), copy _3) -> [success: bb1, unwind: bb10]; } bb1: { @@ -72,7 +72,7 @@ fn main() -> () { StorageLive(_7); StorageLive(_8); _8 = copy (*_5); - _7 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(move _8) -> [return: bb3, unwind: bb7]; + _7 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(move _8) -> [return: bb3, unwind: bb8]; } bb3: { @@ -102,6 +102,30 @@ fn main() -> () { } bb7 (cleanup): { + BackwardIncompatibleDropHint(_9, UnwindStorageDead); + goto -> bb9; + } + + bb8 (cleanup): { + BackwardIncompatibleDropHint(_8, UnwindStorageDead); + BackwardIncompatibleDropHint(_7, UnwindStorageDead); + goto -> bb9; + } + + bb9 (cleanup): { + BackwardIncompatibleDropHint(_6, UnwindStorageDead); + BackwardIncompatibleDropHint(_5, UnwindStorageDead); + goto -> bb11; + } + + bb10 (cleanup): { + BackwardIncompatibleDropHint(_3, UnwindStorageDead); + goto -> bb11; + } + + bb11 (cleanup): { + BackwardIncompatibleDropHint(_2, UnwindStorageDead); + BackwardIncompatibleDropHint(_1, UnwindStorageDead); resume; } } diff --git a/tests/mir-opt/simplify_cfg.main.SimplifyCfg-initial.diff b/tests/mir-opt/simplify_cfg.main.SimplifyCfg-initial.diff index d106313f0ff38..624b3dffccfa2 100644 --- a/tests/mir-opt/simplify_cfg.main.SimplifyCfg-initial.diff +++ b/tests/mir-opt/simplify_cfg.main.SimplifyCfg-initial.diff @@ -12,8 +12,8 @@ } bb1: { -- falseUnwind -> [real: bb2, unwind: bb11]; -+ falseUnwind -> [real: bb2, unwind: bb6]; +- falseUnwind -> [real: bb2, unwind: bb12]; ++ falseUnwind -> [real: bb2, unwind: bb7]; } bb2: { @@ -62,6 +62,13 @@ - - bb11 (cleanup): { + bb6 (cleanup): { + BackwardIncompatibleDropHint(_2, UnwindStorageDead); +- goto -> bb12; ++ goto -> bb7; + } + +- bb12 (cleanup): { ++ bb7 (cleanup): { resume; } } diff --git a/tests/mir-opt/simplify_cfg.main.SimplifyCfg-post-analysis.diff b/tests/mir-opt/simplify_cfg.main.SimplifyCfg-post-analysis.diff index 0e41950d6267d..d49e63dd25014 100644 --- a/tests/mir-opt/simplify_cfg.main.SimplifyCfg-post-analysis.diff +++ b/tests/mir-opt/simplify_cfg.main.SimplifyCfg-post-analysis.diff @@ -41,6 +41,11 @@ } - bb6 (cleanup): { +- nop; +- goto -> bb7; +- } +- +- bb7 (cleanup): { + bb5 (cleanup): { resume; } diff --git a/tests/mir-opt/tail_call_drops.f.ElaborateDrops.panic-abort.diff b/tests/mir-opt/tail_call_drops.f.ElaborateDrops.panic-abort.diff index 9a4f27a497d18..17c64d4baf0ef 100644 --- a/tests/mir-opt/tail_call_drops.f.ElaborateDrops.panic-abort.diff +++ b/tests/mir-opt/tail_call_drops.f.ElaborateDrops.panic-abort.diff @@ -66,6 +66,7 @@ bb6: { + _8 = const false; StorageDead(_4); + StorageDead(_3); drop(_2) -> [return: bb7, unwind: bb12]; } diff --git a/tests/mir-opt/tail_call_drops.f.ElaborateDrops.panic-unwind.diff b/tests/mir-opt/tail_call_drops.f.ElaborateDrops.panic-unwind.diff index f13ee78aa368c..58d8a87986d6b 100644 --- a/tests/mir-opt/tail_call_drops.f.ElaborateDrops.panic-unwind.diff +++ b/tests/mir-opt/tail_call_drops.f.ElaborateDrops.panic-unwind.diff @@ -66,6 +66,7 @@ bb6: { + _8 = const false; StorageDead(_4); + StorageDead(_3); - drop(_2) -> [return: bb7, unwind continue]; + drop(_2) -> [return: bb7, unwind: bb12]; } diff --git a/tests/mir-opt/tail_call_drops.f.built.after.panic-abort.mir b/tests/mir-opt/tail_call_drops.f.built.after.panic-abort.mir index 29bd0c6312bae..faa6678b54937 100644 --- a/tests/mir-opt/tail_call_drops.f.built.after.panic-abort.mir +++ b/tests/mir-opt/tail_call_drops.f.built.after.panic-abort.mir @@ -24,7 +24,7 @@ fn f() -> () { bb0: { StorageLive(_2); - _2 = String::new() -> [return: bb1, unwind: bb18]; + _2 = String::new() -> [return: bb1, unwind: bb17]; } bb1: { @@ -63,6 +63,7 @@ fn f() -> () { bb6: { StorageDead(_4); + StorageDead(_3); drop(_2) -> [return: bb7, unwind: bb17]; } @@ -100,28 +101,24 @@ fn f() -> () { } bb14 (cleanup): { - StorageDead(_7); - StorageDead(_6); + BackwardIncompatibleDropHint(_7, UnwindStorageDead); + BackwardIncompatibleDropHint(_6, UnwindStorageDead); drop(_5) -> [return: bb15, unwind terminate(cleanup)]; } bb15 (cleanup): { - StorageDead(_5); + BackwardIncompatibleDropHint(_5, UnwindStorageDead); drop(_4) -> [return: bb16, unwind terminate(cleanup)]; } bb16 (cleanup): { - StorageDead(_4); - StorageDead(_3); + BackwardIncompatibleDropHint(_4, UnwindStorageDead); + BackwardIncompatibleDropHint(_3, UnwindStorageDead); drop(_2) -> [return: bb17, unwind terminate(cleanup)]; } bb17 (cleanup): { - StorageDead(_2); - goto -> bb18; - } - - bb18 (cleanup): { + BackwardIncompatibleDropHint(_2, UnwindStorageDead); resume; } } diff --git a/tests/mir-opt/tail_call_drops.f.built.after.panic-unwind.mir b/tests/mir-opt/tail_call_drops.f.built.after.panic-unwind.mir index 29bd0c6312bae..faa6678b54937 100644 --- a/tests/mir-opt/tail_call_drops.f.built.after.panic-unwind.mir +++ b/tests/mir-opt/tail_call_drops.f.built.after.panic-unwind.mir @@ -24,7 +24,7 @@ fn f() -> () { bb0: { StorageLive(_2); - _2 = String::new() -> [return: bb1, unwind: bb18]; + _2 = String::new() -> [return: bb1, unwind: bb17]; } bb1: { @@ -63,6 +63,7 @@ fn f() -> () { bb6: { StorageDead(_4); + StorageDead(_3); drop(_2) -> [return: bb7, unwind: bb17]; } @@ -100,28 +101,24 @@ fn f() -> () { } bb14 (cleanup): { - StorageDead(_7); - StorageDead(_6); + BackwardIncompatibleDropHint(_7, UnwindStorageDead); + BackwardIncompatibleDropHint(_6, UnwindStorageDead); drop(_5) -> [return: bb15, unwind terminate(cleanup)]; } bb15 (cleanup): { - StorageDead(_5); + BackwardIncompatibleDropHint(_5, UnwindStorageDead); drop(_4) -> [return: bb16, unwind terminate(cleanup)]; } bb16 (cleanup): { - StorageDead(_4); - StorageDead(_3); + BackwardIncompatibleDropHint(_4, UnwindStorageDead); + BackwardIncompatibleDropHint(_3, UnwindStorageDead); drop(_2) -> [return: bb17, unwind terminate(cleanup)]; } bb17 (cleanup): { - StorageDead(_2); - goto -> bb18; - } - - bb18 (cleanup): { + BackwardIncompatibleDropHint(_2, UnwindStorageDead); resume; } } diff --git a/tests/mir-opt/tail_call_drops.f_with_arg.ElaborateDrops.panic-abort.diff b/tests/mir-opt/tail_call_drops.f_with_arg.ElaborateDrops.panic-abort.diff index 4fba0032729e6..98c5556e0bce1 100644 --- a/tests/mir-opt/tail_call_drops.f_with_arg.ElaborateDrops.panic-abort.diff +++ b/tests/mir-opt/tail_call_drops.f_with_arg.ElaborateDrops.panic-abort.diff @@ -80,6 +80,7 @@ bb8: { + _12 = const false; StorageDead(_6); + StorageDead(_5); drop(_4) -> [return: bb9, unwind: bb16]; } diff --git a/tests/mir-opt/tail_call_drops.f_with_arg.ElaborateDrops.panic-unwind.diff b/tests/mir-opt/tail_call_drops.f_with_arg.ElaborateDrops.panic-unwind.diff index 4fba0032729e6..98c5556e0bce1 100644 --- a/tests/mir-opt/tail_call_drops.f_with_arg.ElaborateDrops.panic-unwind.diff +++ b/tests/mir-opt/tail_call_drops.f_with_arg.ElaborateDrops.panic-unwind.diff @@ -80,6 +80,7 @@ bb8: { + _12 = const false; StorageDead(_6); + StorageDead(_5); drop(_4) -> [return: bb9, unwind: bb16]; } diff --git a/tests/mir-opt/tail_call_drops.f_with_arg.built.after.panic-abort.mir b/tests/mir-opt/tail_call_drops.f_with_arg.built.after.panic-abort.mir index ddd9fc091141a..b4fdddced163c 100644 --- a/tests/mir-opt/tail_call_drops.f_with_arg.built.after.panic-abort.mir +++ b/tests/mir-opt/tail_call_drops.f_with_arg.built.after.panic-abort.mir @@ -58,7 +58,7 @@ fn f_with_arg(_1: String, _2: String) -> () { StorageDead(_9); StorageDead(_8); StorageLive(_10); - _10 = String::new() -> [return: bb5, unwind: bb33]; + _10 = String::new() -> [return: bb5, unwind: bb30]; } bb5: { @@ -77,6 +77,7 @@ fn f_with_arg(_1: String, _2: String) -> () { bb8: { StorageDead(_6); + StorageDead(_5); drop(_4) -> [return: bb9, unwind: bb23]; } @@ -168,12 +169,12 @@ fn f_with_arg(_1: String, _2: String) -> () { } bb29 (cleanup): { - StorageDead(_11); + BackwardIncompatibleDropHint(_11, UnwindStorageDead); drop(_10) -> [return: bb30, unwind terminate(cleanup)]; } bb30 (cleanup): { - StorageDead(_10); + BackwardIncompatibleDropHint(_10, UnwindStorageDead); goto -> bb33; } @@ -182,8 +183,8 @@ fn f_with_arg(_1: String, _2: String) -> () { } bb32 (cleanup): { - StorageDead(_9); - StorageDead(_8); + BackwardIncompatibleDropHint(_9, UnwindStorageDead); + BackwardIncompatibleDropHint(_8, UnwindStorageDead); goto -> bb33; } @@ -192,18 +193,18 @@ fn f_with_arg(_1: String, _2: String) -> () { } bb34 (cleanup): { - StorageDead(_7); + BackwardIncompatibleDropHint(_7, UnwindStorageDead); drop(_6) -> [return: bb35, unwind terminate(cleanup)]; } bb35 (cleanup): { - StorageDead(_6); - StorageDead(_5); + BackwardIncompatibleDropHint(_6, UnwindStorageDead); + BackwardIncompatibleDropHint(_5, UnwindStorageDead); drop(_4) -> [return: bb36, unwind terminate(cleanup)]; } bb36 (cleanup): { - StorageDead(_4); + BackwardIncompatibleDropHint(_4, UnwindStorageDead); drop(_2) -> [return: bb37, unwind terminate(cleanup)]; } diff --git a/tests/mir-opt/tail_call_drops.f_with_arg.built.after.panic-unwind.mir b/tests/mir-opt/tail_call_drops.f_with_arg.built.after.panic-unwind.mir index ddd9fc091141a..b4fdddced163c 100644 --- a/tests/mir-opt/tail_call_drops.f_with_arg.built.after.panic-unwind.mir +++ b/tests/mir-opt/tail_call_drops.f_with_arg.built.after.panic-unwind.mir @@ -58,7 +58,7 @@ fn f_with_arg(_1: String, _2: String) -> () { StorageDead(_9); StorageDead(_8); StorageLive(_10); - _10 = String::new() -> [return: bb5, unwind: bb33]; + _10 = String::new() -> [return: bb5, unwind: bb30]; } bb5: { @@ -77,6 +77,7 @@ fn f_with_arg(_1: String, _2: String) -> () { bb8: { StorageDead(_6); + StorageDead(_5); drop(_4) -> [return: bb9, unwind: bb23]; } @@ -168,12 +169,12 @@ fn f_with_arg(_1: String, _2: String) -> () { } bb29 (cleanup): { - StorageDead(_11); + BackwardIncompatibleDropHint(_11, UnwindStorageDead); drop(_10) -> [return: bb30, unwind terminate(cleanup)]; } bb30 (cleanup): { - StorageDead(_10); + BackwardIncompatibleDropHint(_10, UnwindStorageDead); goto -> bb33; } @@ -182,8 +183,8 @@ fn f_with_arg(_1: String, _2: String) -> () { } bb32 (cleanup): { - StorageDead(_9); - StorageDead(_8); + BackwardIncompatibleDropHint(_9, UnwindStorageDead); + BackwardIncompatibleDropHint(_8, UnwindStorageDead); goto -> bb33; } @@ -192,18 +193,18 @@ fn f_with_arg(_1: String, _2: String) -> () { } bb34 (cleanup): { - StorageDead(_7); + BackwardIncompatibleDropHint(_7, UnwindStorageDead); drop(_6) -> [return: bb35, unwind terminate(cleanup)]; } bb35 (cleanup): { - StorageDead(_6); - StorageDead(_5); + BackwardIncompatibleDropHint(_6, UnwindStorageDead); + BackwardIncompatibleDropHint(_5, UnwindStorageDead); drop(_4) -> [return: bb36, unwind terminate(cleanup)]; } bb36 (cleanup): { - StorageDead(_4); + BackwardIncompatibleDropHint(_4, UnwindStorageDead); drop(_2) -> [return: bb37, unwind terminate(cleanup)]; } diff --git a/tests/run-make/llvm-location-discriminator-limit-dummy-span/rmake.rs b/tests/run-make/llvm-location-discriminator-limit-dummy-span/rmake.rs index 00ae400f71d20..ec206e59b35d2 100644 --- a/tests/run-make/llvm-location-discriminator-limit-dummy-span/rmake.rs +++ b/tests/run-make/llvm-location-discriminator-limit-dummy-span/rmake.rs @@ -30,21 +30,30 @@ use run_make_support::{dynamic_lib_name, rfs, rust_lib_name, rustc}; // maximum value of 4096) so if this function gets big enough rustc's error // handling path will be exercised. fn generate_program(n: u32) -> String { - let mut program = String::from("pub type BigType = Vec>;\n\n"); + let mut program = String::from( + "pub type BigType = u64;\n\n\ + #[inline(always)]\n\ + fn step1(x: u64) -> u64 { std::hint::black_box(x.wrapping_add(1)) }\n\ + #[inline(always)]\n\ + fn step2(x: u64) -> u64 { std::hint::black_box(x.wrapping_add(1)) }\n\ + #[inline(always)]\n\ + fn step3(x: u64) -> u64 { std::hint::black_box(x.wrapping_add(1)) }\n\n", + ); program.push_str("pub fn big_function() -> BigType {\n"); - program.push_str(" vec![\n"); + program.push_str(" let mut value = 0u64;\n"); for i in 1..=n { - program.push_str(&format!("vec![\"string{}\".to_owned()],\n", i)); + program.push_str(&format!(" value = step3(step2(step1(value.wrapping_add({i}))));\n")); } - program.push_str(" ]\n"); + program.push_str(" value\n"); program.push_str("}\n"); program } fn main() { - // The reported threshold is around 1366 (4096/3), but let's bump it to - // around 1500 to be less sensitive. - rfs::write("generated.rs", generate_program(1500)); + // Use non-droppy values so this debuginfo test is not coupled to unwind cleanup markers. + // Each iteration generates three inlined callsites. The reported threshold is around + // 1366 (4096/3), but let's bump it above that to be less sensitive. + rfs::write("generated.rs", generate_program(1400)); rustc() .input("proc.rs") diff --git a/tests/ui/drop/unwind-drop-order-future-compat.rs b/tests/ui/drop/unwind-drop-order-future-compat.rs index 90e453cf3cf52..1dec9de0b5bbd 100644 --- a/tests/ui/drop/unwind-drop-order-future-compat.rs +++ b/tests/ui/drop/unwind-drop-order-future-compat.rs @@ -1,6 +1,3 @@ -//@ edition: 2021 -//@ normalize-stderr: "\n\n\z" -> "\n" - #![allow(unused)] #![deny(unwind_drop_order)] diff --git a/tests/ui/drop/unwind-drop-order-future-compat.stderr b/tests/ui/drop/unwind-drop-order-future-compat.stderr index 48dadf7cd6196..d6bb1c29a36a2 100644 --- a/tests/ui/drop/unwind-drop-order-future-compat.stderr +++ b/tests/ui/drop/unwind-drop-order-future-compat.stderr @@ -1,5 +1,5 @@ error: relative drop order on unwind changing in a future release - --> $DIR/unwind-drop-order-future-compat.rs:21:18 + --> $DIR/unwind-drop-order-future-compat.rs:18:18 | LL | x = Wrap(&y); | ^^ this value would be considered dead on an unwind path @@ -11,9 +11,10 @@ LL | } = warning: this will change its meaning in a future release! = note: for more information, see issue #147875 note: the lint level is defined here - --> $DIR/unwind-drop-order-future-compat.rs:5:9 + --> $DIR/unwind-drop-order-future-compat.rs:2:9 | LL | #![deny(unwind_drop_order)] | ^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error +