diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2024-08-24 22:14:12 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-08-24 22:14:12 +0200 |
| commit | 05b8bcc662afcfa9d3ccbe2dd0f48113fd1fb224 (patch) | |
| tree | 6349421f6b305fb03c47eea293c6e48201f06c61 | |
| parent | 0dfdea1c45b1b832391cb32db0fd58d0ec29d967 (diff) | |
| parent | 8b642a1883c489c74befca5b75514767a1f80314 (diff) | |
| download | rust-05b8bcc662afcfa9d3ccbe2dd0f48113fd1fb224.tar.gz rust-05b8bcc662afcfa9d3ccbe2dd0f48113fd1fb224.zip | |
Rollup merge of #129199 - RalfJung:writes_through_immutable_pointer, r=compiler-errors
make writes_through_immutable_pointer a hard error This turns the lint added in https://github.com/rust-lang/rust/pull/118324 into a hard error. This has been reported in cargo's future-compat reports since Rust 1.76 (released in February). Given that const_mut_refs is still unstable, it should be impossible to even hit this error on stable: we did accidentally stabilize some functions that can cause this error, but that got reverted in https://github.com/rust-lang/rust/pull/117905. Still, let's do a crater run just to be sure. Given that this should only affect unstable code, I don't think it needs an FCP, but let's Cc ``@rust-lang/lang`` anyway -- any objection to making this unambiguous UB into a hard error during const-eval? This can be viewed as part of https://github.com/rust-lang/rust/pull/129195 which is already nominated for discussion.
| -rw-r--r-- | compiler/rustc_const_eval/src/const_eval/error.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_const_eval/src/const_eval/machine.rs | 9 | ||||
| -rw-r--r-- | compiler/rustc_const_eval/src/errors.rs | 7 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/lib.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_lint_defs/src/builtin.rs | 35 | ||||
| -rw-r--r-- | tests/ui/consts/const-eval/ub-write-through-immutable.rs | 9 | ||||
| -rw-r--r-- | tests/ui/consts/const-eval/ub-write-through-immutable.stderr | 54 |
7 files changed, 23 insertions, 102 deletions
diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index 00bbd9337f7..25b32785b7d 100644 --- a/compiler/rustc_const_eval/src/const_eval/error.rs +++ b/compiler/rustc_const_eval/src/const_eval/error.rs @@ -22,6 +22,7 @@ pub enum ConstEvalErrKind { RecursiveStatic, AssertFailure(AssertKind<ConstInt>), Panic { msg: Symbol, line: u32, col: u32, file: Symbol }, + WriteThroughImmutablePointer, } impl MachineStopType for ConstEvalErrKind { @@ -35,12 +36,16 @@ impl MachineStopType for ConstEvalErrKind { Panic { .. } => const_eval_panic, RecursiveStatic => const_eval_recursive_static, AssertFailure(x) => x.diagnostic_message(), + WriteThroughImmutablePointer => const_eval_write_through_immutable_pointer, } } fn add_args(self: Box<Self>, adder: &mut dyn FnMut(DiagArgName, DiagArgValue)) { use ConstEvalErrKind::*; match *self { - RecursiveStatic | ConstAccessesMutGlobal | ModifiedGlobal => {} + RecursiveStatic + | ConstAccessesMutGlobal + | ModifiedGlobal + | WriteThroughImmutablePointer => {} AssertFailure(kind) => kind.add_args(adder), Panic { msg, line, col, file } => { adder("msg".into(), msg.into_diag_arg()); @@ -159,6 +164,7 @@ where /// Emit a lint from a const-eval situation, with a backtrace. // Even if this is unused, please don't remove it -- chances are we will need to emit a lint during const-eval again in the future! +#[allow(unused)] pub(super) fn lint<'tcx, L>( tcx: TyCtxtAt<'tcx>, machine: &CompileTimeMachine<'tcx>, diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index c3d94ca0e59..9c1fef095f5 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -12,7 +12,6 @@ use rustc_middle::query::TyCtxtAt; use rustc_middle::ty::layout::{FnAbiOf, TyAndLayout}; use rustc_middle::ty::{self, TyCtxt}; use rustc_middle::{bug, mir}; -use rustc_session::lint::builtin::WRITES_THROUGH_IMMUTABLE_POINTER; use rustc_span::symbol::{sym, Symbol}; use rustc_span::Span; use rustc_target::abi::{Align, Size}; @@ -732,8 +731,8 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> { } fn before_memory_write( - tcx: TyCtxtAt<'tcx>, - machine: &mut Self, + _tcx: TyCtxtAt<'tcx>, + _machine: &mut Self, _alloc_extra: &mut Self::AllocExtra, (_alloc_id, immutable): (AllocId, bool), range: AllocRange, @@ -744,9 +743,7 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> { } // Reject writes through immutable pointers. if immutable { - super::lint(tcx, machine, WRITES_THROUGH_IMMUTABLE_POINTER, |frames| { - crate::errors::WriteThroughImmutablePointer { frames } - }); + return Err(ConstEvalErrKind::WriteThroughImmutablePointer.into()); } // Everything else is fine. Ok(()) diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index 6075f3f84cd..0b366b43f95 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -407,13 +407,6 @@ pub struct ConstEvalError { pub frame_notes: Vec<FrameNote>, } -#[derive(LintDiagnostic)] -#[diag(const_eval_write_through_immutable_pointer)] -pub struct WriteThroughImmutablePointer { - #[subdiagnostic] - pub frames: Vec<FrameNote>, -} - #[derive(Diagnostic)] #[diag(const_eval_nullary_intrinsic_fail)] pub struct NullaryIntrinsicError { diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 1828b6ea93c..a6e7d288f08 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -572,7 +572,8 @@ fn register_builtins(store: &mut LintStore) { "byte_slice_in_packed_struct_with_derive", "converted into hard error, see issue #107457 \ <https://github.com/rust-lang/rust/issues/107457> for more information", - ) + ); + store.register_removed("writes_through_immutable_pointer", "converted into hard error"); } fn register_internals(store: &mut LintStore) { diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index a65d30eb817..44c72e0c4fe 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -142,7 +142,6 @@ declare_lint_pass! { USELESS_DEPRECATED, WARNINGS, WASM_C_ABI, - WRITES_THROUGH_IMMUTABLE_POINTER, // tidy-alphabetical-end ] } @@ -4697,40 +4696,6 @@ declare_lint! { } declare_lint! { - /// The `writes_through_immutable_pointer` lint detects writes through pointers derived from - /// shared references. - /// - /// ### Example - /// - /// ```rust,compile_fail - /// #![feature(const_mut_refs)] - /// const WRITE_AFTER_CAST: () = unsafe { - /// let mut x = 0; - /// let ptr = &x as *const i32 as *mut i32; - /// *ptr = 0; - /// }; - /// ``` - /// - /// {{produces}} - /// - /// ### Explanation - /// - /// Shared references are immutable (when there is no `UnsafeCell` involved), - /// and writing through them or through pointers derived from them is Undefined Behavior. - /// The compiler recently learned to detect such Undefined Behavior during compile-time - /// evaluation, and in the future this will raise a hard error. - /// - /// [future-incompatible]: ../index.md#future-incompatible-lints - pub WRITES_THROUGH_IMMUTABLE_POINTER, - Warn, - "shared references are immutable, and pointers derived from them must not be written to", - @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps, - reference: "issue #X <https://github.com/rust-lang/rust/issues/X>", - }; -} - -declare_lint! { /// The `private_macro_use` lint detects private macros that are imported /// with `#[macro_use]`. /// diff --git a/tests/ui/consts/const-eval/ub-write-through-immutable.rs b/tests/ui/consts/const-eval/ub-write-through-immutable.rs index 945367f1823..9860b8fde4a 100644 --- a/tests/ui/consts/const-eval/ub-write-through-immutable.rs +++ b/tests/ui/consts/const-eval/ub-write-through-immutable.rs @@ -1,6 +1,5 @@ //! Ensure we catch UB due to writing through a shared reference. #![feature(const_mut_refs, const_refs_to_cell)] -#![deny(writes_through_immutable_pointer)] #![allow(invalid_reference_casting)] use std::mem; @@ -9,15 +8,15 @@ use std::cell::UnsafeCell; const WRITE_AFTER_CAST: () = unsafe { let mut x = 0; let ptr = &x as *const i32 as *mut i32; - *ptr = 0; //~ERROR: writes_through_immutable_pointer - //~^ previously accepted + *ptr = 0; //~ERROR: evaluation of constant value failed + //~| immutable }; const WRITE_AFTER_TRANSMUTE: () = unsafe { let mut x = 0; let ptr: *mut i32 = mem::transmute(&x); - *ptr = 0; //~ERROR: writes_through_immutable_pointer - //~^ previously accepted + *ptr = 0; //~ERROR: evaluation of constant value failed + //~| immutable }; // it's okay when there is interior mutability; diff --git a/tests/ui/consts/const-eval/ub-write-through-immutable.stderr b/tests/ui/consts/const-eval/ub-write-through-immutable.stderr index 27eb2d2c0d1..dbcd35e0b88 100644 --- a/tests/ui/consts/const-eval/ub-write-through-immutable.stderr +++ b/tests/ui/consts/const-eval/ub-write-through-immutable.stderr @@ -1,55 +1,15 @@ -error: writing through a pointer that was derived from a shared (immutable) reference - --> $DIR/ub-write-through-immutable.rs:12:5 +error[E0080]: evaluation of constant value failed + --> $DIR/ub-write-through-immutable.rs:11:5 | LL | *ptr = 0; - | ^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #X <https://github.com/rust-lang/rust/issues/X> -note: the lint level is defined here - --> $DIR/ub-write-through-immutable.rs:3:9 - | -LL | #![deny(writes_through_immutable_pointer)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^ writing through a pointer that was derived from a shared (immutable) reference -error: writing through a pointer that was derived from a shared (immutable) reference - --> $DIR/ub-write-through-immutable.rs:19:5 +error[E0080]: evaluation of constant value failed + --> $DIR/ub-write-through-immutable.rs:18:5 | LL | *ptr = 0; - | ^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #X <https://github.com/rust-lang/rust/issues/X> + | ^^^^^^^^ writing through a pointer that was derived from a shared (immutable) reference error: aborting due to 2 previous errors -Future incompatibility report: Future breakage diagnostic: -error: writing through a pointer that was derived from a shared (immutable) reference - --> $DIR/ub-write-through-immutable.rs:12:5 - | -LL | *ptr = 0; - | ^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #X <https://github.com/rust-lang/rust/issues/X> -note: the lint level is defined here - --> $DIR/ub-write-through-immutable.rs:3:9 - | -LL | #![deny(writes_through_immutable_pointer)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Future breakage diagnostic: -error: writing through a pointer that was derived from a shared (immutable) reference - --> $DIR/ub-write-through-immutable.rs:19:5 - | -LL | *ptr = 0; - | ^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #X <https://github.com/rust-lang/rust/issues/X> -note: the lint level is defined here - --> $DIR/ub-write-through-immutable.rs:3:9 - | -LL | #![deny(writes_through_immutable_pointer)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - +For more information about this error, try `rustc --explain E0080`. |
