Skip to content

Commit aebde8c

Browse files
committed
Auto merge of #149435 - sladyn98:fix-panic-drop-ordering-rebased, r=<try>
Fix variable deallocation order in panic unwinding paths
2 parents 5ff740e + 837937b commit aebde8c

40 files changed

Lines changed: 911 additions & 289 deletions

File tree

compiler/rustc_borrowck/src/lib.rs

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ use rustc_mir_dataflow::move_paths::{
4646
};
4747
use rustc_mir_dataflow::points::DenseLocationMap;
4848
use rustc_mir_dataflow::{Analysis, EntryStates, Results, ResultsVisitor, visit_results};
49-
use rustc_session::lint::builtin::{TAIL_EXPR_DROP_ORDER, UNUSED_MUT};
49+
use rustc_session::lint::builtin::{TAIL_EXPR_DROP_ORDER, UNUSED_MUT, UNWIND_DROP_ORDER};
5050
use rustc_span::{ErrorGuaranteed, Span, Symbol};
5151
use smallvec::SmallVec;
5252
use tracing::{debug, instrument};
@@ -844,11 +844,8 @@ impl<'a, 'tcx> ResultsVisitor<'tcx, Borrowck<'a, 'tcx>> for MirBorrowckCtxt<'a,
844844
// These do not actually affect borrowck
845845
StatementKind::ConstEvalCounter | StatementKind::StorageLive(..) => {}
846846
// This does not affect borrowck
847-
StatementKind::BackwardIncompatibleDropHint {
848-
place,
849-
reason: BackwardIncompatibleDropReason::Edition2024,
850-
} => {
851-
self.check_backward_incompatible_drop(location, **place, state);
847+
StatementKind::BackwardIncompatibleDropHint { place, reason } => {
848+
self.check_backward_incompatible_drop(location, **place, *reason, state);
852849
}
853850
StatementKind::StorageDead(local) => {
854851
self.access_place(
@@ -1391,6 +1388,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
13911388
&mut self,
13921389
location: Location,
13931390
place: Place<'tcx>,
1391+
reason: BackwardIncompatibleDropReason,
13941392
state: &BorrowckDomain,
13951393
) {
13961394
let tcx = self.infcx.tcx;
@@ -1424,17 +1422,36 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
14241422
borrow,
14251423
Some((WriteKind::StorageDeadOrDrop, place)),
14261424
);
1427-
this.infcx.tcx.emit_node_span_lint(
1428-
TAIL_EXPR_DROP_ORDER,
1429-
CRATE_HIR_ID,
1430-
borrowed,
1431-
session_diagnostics::TailExprDropOrder {
1432-
borrowed,
1433-
callback: |diag| {
1434-
explain.add_explanation_to_diagnostic(&this, diag, "", None, None);
1435-
},
1436-
},
1437-
);
1425+
match reason {
1426+
BackwardIncompatibleDropReason::Edition2024 => {
1427+
this.infcx.tcx.emit_node_span_lint(
1428+
TAIL_EXPR_DROP_ORDER,
1429+
CRATE_HIR_ID,
1430+
borrowed,
1431+
session_diagnostics::TailExprDropOrder {
1432+
borrowed,
1433+
callback: |diag| {
1434+
explain
1435+
.add_explanation_to_diagnostic(&this, diag, "", None, None);
1436+
},
1437+
},
1438+
);
1439+
}
1440+
BackwardIncompatibleDropReason::UnwindStorageDead => {
1441+
this.infcx.tcx.emit_node_span_lint(
1442+
UNWIND_DROP_ORDER,
1443+
CRATE_HIR_ID,
1444+
borrowed,
1445+
session_diagnostics::UnwindDropOrder {
1446+
borrowed,
1447+
callback: |diag| {
1448+
explain
1449+
.add_explanation_to_diagnostic(&this, diag, "", None, None);
1450+
},
1451+
},
1452+
);
1453+
}
1454+
}
14381455
// We may stop at the first case
14391456
ControlFlow::Break(())
14401457
},

compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LoanInvalidationsGenerator<'a, 'tcx> {
7070
// Doesn't have any language semantics
7171
| StatementKind::Coverage(..)
7272
// Does not actually affect borrowck
73-
| StatementKind::StorageLive(..) => {}
73+
| StatementKind::StorageLive(..)
74+
| StatementKind::BackwardIncompatibleDropHint { .. } => {}
7475
StatementKind::StorageDead(local) => {
7576
self.access_place(
7677
location,
@@ -81,7 +82,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LoanInvalidationsGenerator<'a, 'tcx> {
8182
}
8283
StatementKind::ConstEvalCounter
8384
| StatementKind::Nop
84-
| StatementKind::BackwardIncompatibleDropHint { .. }
8585
| StatementKind::SetDiscriminant { .. } => {
8686
bug!("Statement not allowed in this MIR phase")
8787
}

compiler/rustc_borrowck/src/session_diagnostics.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,3 +633,19 @@ impl<'a, F: FnOnce(&mut Diag<'_, ()>)> Diagnostic<'a, ()> for TailExprDropOrder<
633633
diag
634634
}
635635
}
636+
637+
pub(crate) struct UnwindDropOrder<F: FnOnce(&mut Diag<'_, ()>)> {
638+
pub borrowed: Span,
639+
pub callback: F,
640+
}
641+
642+
impl<'a, F: FnOnce(&mut Diag<'_, ()>)> Diagnostic<'a, ()> for UnwindDropOrder<F> {
643+
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> {
644+
let Self { borrowed, callback } = self;
645+
let mut diag =
646+
Diag::new(dcx, level, "relative drop order on unwind changing in a future release")
647+
.with_span_label(borrowed, "this value would be considered dead on an unwind path");
648+
callback(&mut diag);
649+
diag
650+
}
651+
}

compiler/rustc_lint_defs/src/builtin.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ declare_lint_pass! {
149149
UNUSED_UNSAFE,
150150
UNUSED_VARIABLES,
151151
UNUSED_VISIBILITIES,
152+
UNWIND_DROP_ORDER,
152153
USELESS_DEPRECATED,
153154
VARARGS_WITHOUT_PATTERN,
154155
WARNINGS,
@@ -5209,6 +5210,47 @@ declare_lint! {
52095210
};
52105211
}
52115212

5213+
declare_lint! {
5214+
/// The `unwind_drop_order` lint detects values whose relative drop order on
5215+
/// panic unwind paths will change in a future release.
5216+
///
5217+
/// ### Example
5218+
/// ```rust,no_run
5219+
/// #![warn(unwind_drop_order)]
5220+
///
5221+
/// struct Wrap<T>(T);
5222+
///
5223+
/// impl<T> Drop for Wrap<T> {
5224+
/// fn drop(&mut self) {}
5225+
/// }
5226+
///
5227+
/// fn main() {
5228+
/// let x;
5229+
/// {
5230+
/// let y = 1;
5231+
/// x = Wrap(&y);
5232+
/// panic!();
5233+
/// }
5234+
/// }
5235+
/// ```
5236+
///
5237+
/// {{produces}}
5238+
///
5239+
/// ### Explanation
5240+
///
5241+
/// During panic unwinding, Rust currently does not mark locals as dead at
5242+
/// the same program points as normal control flow. A future release may
5243+
/// make unwind paths use the same storage-dead points as normal paths. This
5244+
/// lint reports code where that change can affect relative drop order
5245+
/// checking.
5246+
pub UNWIND_DROP_ORDER,
5247+
Allow,
5248+
"detects future changes to drop order during panic unwinding",
5249+
@future_incompatible = FutureIncompatibleInfo {
5250+
reason: fcw!(FutureReleaseSemanticsChange #147875),
5251+
};
5252+
}
5253+
52125254
declare_lint! {
52135255
/// The `rust_2024_guarded_string_incompatible_syntax` lint detects `#` tokens
52145256
/// that will be parsed as part of a guarded string literal in Rust 2024.

compiler/rustc_middle/src/mir/pretty.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -880,8 +880,8 @@ impl Debug for StatementKind<'_> {
880880
ConstEvalCounter => write!(fmt, "ConstEvalCounter"),
881881
Nop => write!(fmt, "nop"),
882882
BackwardIncompatibleDropHint { ref place, reason: _ } => {
883-
// For now, we don't record the reason because there is only one use case,
884-
// which is to report breaking change in drop order by Edition 2024
883+
// The reason is intentionally omitted to keep MIR diffs stable
884+
// across future-compatibility lint implementation details.
885885
write!(fmt, "BackwardIncompatibleDropHint({place:?})")
886886
}
887887
}

compiler/rustc_middle/src/mir/syntax.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -975,6 +975,7 @@ pub enum TerminatorKind<'tcx> {
975975

976976
#[derive(
977977
Clone,
978+
Copy,
978979
Debug,
979980
TyEncodable,
980981
TyDecodable,
@@ -986,6 +987,7 @@ pub enum TerminatorKind<'tcx> {
986987
)]
987988
pub enum BackwardIncompatibleDropReason {
988989
Edition2024,
990+
UnwindStorageDead,
989991
}
990992

991993
#[derive(Debug, Clone, TyEncodable, TyDecodable, Hash, StableHash, PartialEq)]

0 commit comments

Comments
 (0)