diff options
| author | Matthias Krüger <476013+matthiaskrgr@users.noreply.github.com> | 2025-06-27 22:13:06 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-06-27 22:13:06 +0200 |
| commit | 088f6ab1c5127b5272056c0b27ee1fe06a943a57 (patch) | |
| tree | 694929bc3e645c7cfdbd95240f20ae1d890a6191 | |
| parent | 2d59c4e0fe7c012e59a985f7313ce1c5ec6e0e47 (diff) | |
| parent | d0fa0260ca410b5691a03237e7336bb09c135230 (diff) | |
| download | rust-088f6ab1c5127b5272056c0b27ee1fe06a943a57.tar.gz rust-088f6ab1c5127b5272056c0b27ee1fe06a943a57.zip | |
Rollup merge of #143092 - RalfJung:const-check-lifetime-ext, r=oli-obk
const checks for lifetime-extended temporaries: avoid 'top-level scope' terminology This error recently got changed in https://github.com/rust-lang/rust/pull/140942 to use the terminology of "top-level scope", but after further discussion in https://github.com/rust-lang/reference/pull/1865 it seems the reference will not be using that terminology after all. So let's also remove it from the compiler again, and let's focus on what actually happens with these temporaries: their lifetime is extended until the end of the program. r? ``@oli-obk`` ``@traviscross``
30 files changed, 190 insertions, 110 deletions
diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl index 671ae5975a7..2a2c3e6aee2 100644 --- a/compiler/rustc_const_eval/messages.ftl +++ b/compiler/rustc_const_eval/messages.ftl @@ -125,16 +125,11 @@ const_eval_incompatible_types = calling a function with argument of type {$callee_ty} passing data of type {$caller_ty} const_eval_interior_mutable_borrow_escaping = - interior mutable shared borrows of lifetime-extended temporaries in the top-level scope of a {const_eval_const_context} are not allowed - .label = this borrow of an interior mutable value refers to a lifetime-extended temporary - .help = to fix this, the value can be extracted to a separate `static` item and then referenced - .teach_note = - This creates a raw pointer to a temporary that has its lifetime extended to last for the entire program. - Lifetime-extended temporaries in constants and statics must be immutable. - This is to avoid accidentally creating shared mutable state. - - - If you really want global mutable state, try using an interior mutable `static` or a `static mut`. + interior mutable shared borrows of temporaries that have their lifetime extended until the end of the program are not allowed + .label = this borrow of an interior mutable value refers to such a temporary + .note = Temporaries in constants and statics can have their lifetime extended until the end of the program + .note2 = To avoid accidentally creating global mutable state, such temporaries must be immutable + .help = If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` const_eval_intern_kind = {$kind -> [static] static @@ -215,14 +210,11 @@ const_eval_modified_global = modifying a static's initial value from another static's initializer const_eval_mutable_borrow_escaping = - mutable borrows of lifetime-extended temporaries in the top-level scope of a {const_eval_const_context} are not allowed - .teach_note = - This creates a reference to a temporary that has its lifetime extended to last for the entire program. - Lifetime-extended temporaries in constants and statics must be immutable. - This is to avoid accidentally creating shared mutable state. - - - If you really want global mutable state, try using an interior mutable `static` or a `static mut`. + mutable borrows of temporaries that have their lifetime extended until the end of the program are not allowed + .label = this mutable borrow refers to such a temporary + .note = Temporaries in constants and statics can have their lifetime extended until the end of the program + .note2 = To avoid accidentally creating global mutable state, such temporaries must be immutable + .help = If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` const_eval_mutable_ptr_in_final = encountered mutable pointer in final value of {const_eval_intern_kind} diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs index b1e0ffd46c5..b2e0577cc82 100644 --- a/compiler/rustc_const_eval/src/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/check_consts/ops.rs @@ -567,12 +567,7 @@ impl<'tcx> NonConstOp<'tcx> for EscapingCellBorrow { DiagImportance::Secondary } fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> { - ccx.dcx().create_err(errors::InteriorMutableBorrowEscaping { - span, - opt_help: matches!(ccx.const_kind(), hir::ConstContext::Static(_)), - kind: ccx.const_kind(), - teach: ccx.tcx.sess.teach(E0492), - }) + ccx.dcx().create_err(errors::InteriorMutableBorrowEscaping { span, kind: ccx.const_kind() }) } } @@ -594,11 +589,7 @@ impl<'tcx> NonConstOp<'tcx> for EscapingMutBorrow { } fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> { - ccx.dcx().create_err(errors::MutableBorrowEscaping { - span, - kind: ccx.const_kind(), - teach: ccx.tcx.sess.teach(E0764), - }) + ccx.dcx().create_err(errors::MutableBorrowEscaping { span, kind: ccx.const_kind() }) } } diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index b2c3103c34a..14abdd8c98c 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -151,12 +151,14 @@ pub(crate) struct UnmarkedIntrinsicExposed { #[derive(Diagnostic)] #[diag(const_eval_mutable_borrow_escaping, code = E0764)] +#[note] +#[note(const_eval_note2)] +#[help] pub(crate) struct MutableBorrowEscaping { #[primary_span] + #[label] pub span: Span, pub kind: ConstContext, - #[note(const_eval_teach_note)] - pub teach: bool, } #[derive(Diagnostic)] @@ -217,15 +219,14 @@ pub(crate) struct UnallowedInlineAsm { #[derive(Diagnostic)] #[diag(const_eval_interior_mutable_borrow_escaping, code = E0492)] +#[note] +#[note(const_eval_note2)] +#[help] pub(crate) struct InteriorMutableBorrowEscaping { #[primary_span] #[label] pub span: Span, - #[help] - pub opt_help: bool, pub kind: ConstContext, - #[note(const_eval_teach_note)] - pub teach: bool, } #[derive(LintDiagnostic)] diff --git a/tests/ui/consts/const-mut-refs/issue-76510.rs b/tests/ui/consts/const-mut-refs/issue-76510.rs index 3b248d77a6b..a6f7540dd59 100644 --- a/tests/ui/consts/const-mut-refs/issue-76510.rs +++ b/tests/ui/consts/const-mut-refs/issue-76510.rs @@ -1,7 +1,7 @@ use std::mem::{transmute, ManuallyDrop}; const S: &'static mut str = &mut " hello "; -//~^ ERROR: mutable borrows of lifetime-extended temporaries +//~^ ERROR: mutable borrows of temporaries const fn trigger() -> [(); unsafe { let s = transmute::<(*const u8, usize), &ManuallyDrop<str>>((S.as_ptr(), 3)); diff --git a/tests/ui/consts/const-mut-refs/issue-76510.stderr b/tests/ui/consts/const-mut-refs/issue-76510.stderr index 6d5dac268e5..3a6c95141e5 100644 --- a/tests/ui/consts/const-mut-refs/issue-76510.stderr +++ b/tests/ui/consts/const-mut-refs/issue-76510.stderr @@ -1,8 +1,12 @@ -error[E0764]: mutable borrows of lifetime-extended temporaries in the top-level scope of a constant are not allowed +error[E0764]: mutable borrows of temporaries that have their lifetime extended until the end of the program are not allowed --> $DIR/issue-76510.rs:3:29 | LL | const S: &'static mut str = &mut " hello "; - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ this mutable borrow refers to such a temporary + | + = note: Temporaries in constants and statics can have their lifetime extended until the end of the program + = note: To avoid accidentally creating global mutable state, such temporaries must be immutable + = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error: aborting due to 1 previous error diff --git a/tests/ui/consts/const-mut-refs/mut_ref_in_final.rs b/tests/ui/consts/const-mut-refs/mut_ref_in_final.rs index 2af92bd1b9d..9f9384adeb7 100644 --- a/tests/ui/consts/const-mut-refs/mut_ref_in_final.rs +++ b/tests/ui/consts/const-mut-refs/mut_ref_in_final.rs @@ -12,13 +12,13 @@ const A: *const i32 = &4; // It could be made sound to allow it to compile, // but we do not want to allow this to compile, // as that would be an enormous footgun in oli-obk's opinion. -const B: *mut i32 = &mut 4; //~ ERROR mutable borrows of lifetime-extended temporaries +const B: *mut i32 = &mut 4; //~ ERROR mutable borrows of temporaries // Ok, no actual mutable allocation exists const B2: Option<&mut i32> = None; // Not ok, can't prove that no mutable allocation ends up in final value -const B3: Option<&mut i32> = Some(&mut 42); //~ ERROR mutable borrows of lifetime-extended temporaries +const B3: Option<&mut i32> = Some(&mut 42); //~ ERROR mutable borrows of temporaries const fn helper(x: &mut i32) -> Option<&mut i32> { Some(x) } const B4: Option<&mut i32> = helper(&mut 42); //~ ERROR temporary value dropped while borrowed @@ -69,13 +69,13 @@ unsafe impl<T> Sync for SyncPtr<T> {} // (This relies on `SyncPtr` being a curly brace struct.) // However, we intern the inner memory as read-only, so this must be rejected. static RAW_MUT_CAST_S: SyncPtr<i32> = SyncPtr { x : &mut 42 as *mut _ as *const _ }; -//~^ ERROR mutable borrows of lifetime-extended temporaries +//~^ ERROR mutable borrows of temporaries static RAW_MUT_COERCE_S: SyncPtr<i32> = SyncPtr { x: &mut 0 }; -//~^ ERROR mutable borrows of lifetime-extended temporaries +//~^ ERROR mutable borrows of temporaries const RAW_MUT_CAST_C: SyncPtr<i32> = SyncPtr { x : &mut 42 as *mut _ as *const _ }; -//~^ ERROR mutable borrows of lifetime-extended temporaries +//~^ ERROR mutable borrows of temporaries const RAW_MUT_COERCE_C: SyncPtr<i32> = SyncPtr { x: &mut 0 }; -//~^ ERROR mutable borrows of lifetime-extended temporaries +//~^ ERROR mutable borrows of temporaries fn main() { println!("{}", unsafe { *A }); diff --git a/tests/ui/consts/const-mut-refs/mut_ref_in_final.stderr b/tests/ui/consts/const-mut-refs/mut_ref_in_final.stderr index a55ccf71bc4..16dee44d800 100644 --- a/tests/ui/consts/const-mut-refs/mut_ref_in_final.stderr +++ b/tests/ui/consts/const-mut-refs/mut_ref_in_final.stderr @@ -1,14 +1,22 @@ -error[E0764]: mutable borrows of lifetime-extended temporaries in the top-level scope of a constant are not allowed +error[E0764]: mutable borrows of temporaries that have their lifetime extended until the end of the program are not allowed --> $DIR/mut_ref_in_final.rs:15:21 | LL | const B: *mut i32 = &mut 4; - | ^^^^^^ + | ^^^^^^ this mutable borrow refers to such a temporary + | + = note: Temporaries in constants and statics can have their lifetime extended until the end of the program + = note: To avoid accidentally creating global mutable state, such temporaries must be immutable + = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` -error[E0764]: mutable borrows of lifetime-extended temporaries in the top-level scope of a constant are not allowed +error[E0764]: mutable borrows of temporaries that have their lifetime extended until the end of the program are not allowed --> $DIR/mut_ref_in_final.rs:21:35 | LL | const B3: Option<&mut i32> = Some(&mut 42); - | ^^^^^^^ + | ^^^^^^^ this mutable borrow refers to such a temporary + | + = note: Temporaries in constants and statics can have their lifetime extended until the end of the program + = note: To avoid accidentally creating global mutable state, such temporaries must be immutable + = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error[E0716]: temporary value dropped while borrowed --> $DIR/mut_ref_in_final.rs:24:42 @@ -72,29 +80,45 @@ LL | static mut FOO3: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); | | creates a temporary value which is freed while still in use | using this value as a static requires that borrow lasts for `'static` -error[E0764]: mutable borrows of lifetime-extended temporaries in the top-level scope of a static are not allowed +error[E0764]: mutable borrows of temporaries that have their lifetime extended until the end of the program are not allowed --> $DIR/mut_ref_in_final.rs:71:53 | LL | static RAW_MUT_CAST_S: SyncPtr<i32> = SyncPtr { x : &mut 42 as *mut _ as *const _ }; - | ^^^^^^^ + | ^^^^^^^ this mutable borrow refers to such a temporary + | + = note: Temporaries in constants and statics can have their lifetime extended until the end of the program + = note: To avoid accidentally creating global mutable state, such temporaries must be immutable + = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` -error[E0764]: mutable borrows of lifetime-extended temporaries in the top-level scope of a static are not allowed +error[E0764]: mutable borrows of temporaries that have their lifetime extended until the end of the program are not allowed --> $DIR/mut_ref_in_final.rs:73:54 | LL | static RAW_MUT_COERCE_S: SyncPtr<i32> = SyncPtr { x: &mut 0 }; - | ^^^^^^ + | ^^^^^^ this mutable borrow refers to such a temporary + | + = note: Temporaries in constants and statics can have their lifetime extended until the end of the program + = note: To avoid accidentally creating global mutable state, such temporaries must be immutable + = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` -error[E0764]: mutable borrows of lifetime-extended temporaries in the top-level scope of a constant are not allowed +error[E0764]: mutable borrows of temporaries that have their lifetime extended until the end of the program are not allowed --> $DIR/mut_ref_in_final.rs:75:52 | LL | const RAW_MUT_CAST_C: SyncPtr<i32> = SyncPtr { x : &mut 42 as *mut _ as *const _ }; - | ^^^^^^^ + | ^^^^^^^ this mutable borrow refers to such a temporary + | + = note: Temporaries in constants and statics can have their lifetime extended until the end of the program + = note: To avoid accidentally creating global mutable state, such temporaries must be immutable + = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` -error[E0764]: mutable borrows of lifetime-extended temporaries in the top-level scope of a constant are not allowed +error[E0764]: mutable borrows of temporaries that have their lifetime extended until the end of the program are not allowed --> $DIR/mut_ref_in_final.rs:77:53 | LL | const RAW_MUT_COERCE_C: SyncPtr<i32> = SyncPtr { x: &mut 0 }; - | ^^^^^^ + | ^^^^^^ this mutable borrow refers to such a temporary + | + = note: Temporaries in constants and statics can have their lifetime extended until the end of the program + = note: To avoid accidentally creating global mutable state, such temporaries must be immutable + = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error: aborting due to 12 previous errors diff --git a/tests/ui/consts/const-promoted-opaque.atomic.stderr b/tests/ui/consts/const-promoted-opaque.atomic.stderr index 337bfa4137a..64cc7b3a329 100644 --- a/tests/ui/consts/const-promoted-opaque.atomic.stderr +++ b/tests/ui/consts/const-promoted-opaque.atomic.stderr @@ -7,11 +7,15 @@ LL | LL | }; | - value is dropped here -error[E0492]: interior mutable shared borrows of lifetime-extended temporaries in the top-level scope of a constant are not allowed +error[E0492]: interior mutable shared borrows of temporaries that have their lifetime extended until the end of the program are not allowed --> $DIR/const-promoted-opaque.rs:36:19 | LL | const BAZ: &Foo = &FOO; - | ^^^^ this borrow of an interior mutable value refers to a lifetime-extended temporary + | ^^^^ this borrow of an interior mutable value refers to such a temporary + | + = note: Temporaries in constants and statics can have their lifetime extended until the end of the program + = note: To avoid accidentally creating global mutable state, such temporaries must be immutable + = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error[E0716]: temporary value dropped while borrowed --> $DIR/const-promoted-opaque.rs:40:26 diff --git a/tests/ui/consts/const-promoted-opaque.rs b/tests/ui/consts/const-promoted-opaque.rs index 9ad2b108ca7..270dddbb4a2 100644 --- a/tests/ui/consts/const-promoted-opaque.rs +++ b/tests/ui/consts/const-promoted-opaque.rs @@ -34,7 +34,7 @@ const BAR: () = { }; const BAZ: &Foo = &FOO; -//[atomic]~^ ERROR: interior mutable shared borrows of lifetime-extended temporaries +//[atomic]~^ ERROR: interior mutable shared borrows of temporaries fn main() { let _: &'static _ = &FOO; diff --git a/tests/ui/consts/issue-17718-const-bad-values.rs b/tests/ui/consts/issue-17718-const-bad-values.rs index ae101927fd4..a447350e35b 100644 --- a/tests/ui/consts/issue-17718-const-bad-values.rs +++ b/tests/ui/consts/issue-17718-const-bad-values.rs @@ -5,7 +5,7 @@ #![allow(static_mut_refs)] const C1: &'static mut [usize] = &mut []; -//~^ ERROR: mutable borrows of lifetime-extended temporaries +//~^ ERROR: mutable borrows of temporaries static mut S: i32 = 3; const C2: &'static mut i32 = unsafe { &mut S }; diff --git a/tests/ui/consts/issue-17718-const-bad-values.stderr b/tests/ui/consts/issue-17718-const-bad-values.stderr index f0b02bdbc45..68d1a72b71e 100644 --- a/tests/ui/consts/issue-17718-const-bad-values.stderr +++ b/tests/ui/consts/issue-17718-const-bad-values.stderr @@ -1,8 +1,12 @@ -error[E0764]: mutable borrows of lifetime-extended temporaries in the top-level scope of a constant are not allowed +error[E0764]: mutable borrows of temporaries that have their lifetime extended until the end of the program are not allowed --> $DIR/issue-17718-const-bad-values.rs:7:34 | LL | const C1: &'static mut [usize] = &mut []; - | ^^^^^^^ + | ^^^^^^^ this mutable borrow refers to such a temporary + | + = note: Temporaries in constants and statics can have their lifetime extended until the end of the program + = note: To avoid accidentally creating global mutable state, such temporaries must be immutable + = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error[E0080]: constructing invalid value: encountered mutable reference in `const` value --> $DIR/issue-17718-const-bad-values.rs:11:1 diff --git a/tests/ui/consts/issue-17718-const-borrow.rs b/tests/ui/consts/issue-17718-const-borrow.rs index 541d27965f2..63733332591 100644 --- a/tests/ui/consts/issue-17718-const-borrow.rs +++ b/tests/ui/consts/issue-17718-const-borrow.rs @@ -2,13 +2,13 @@ use std::cell::UnsafeCell; const A: UnsafeCell<usize> = UnsafeCell::new(1); const B: &'static UnsafeCell<usize> = &A; -//~^ ERROR: interior mutable shared borrows of lifetime-extended temporaries +//~^ ERROR: interior mutable shared borrows of temporaries struct C { a: UnsafeCell<usize> } const D: C = C { a: UnsafeCell::new(1) }; const E: &'static UnsafeCell<usize> = &D.a; -//~^ ERROR: interior mutable shared borrows of lifetime-extended temporaries +//~^ ERROR: interior mutable shared borrows of temporaries const F: &'static C = &D; -//~^ ERROR: interior mutable shared borrows of lifetime-extended temporaries +//~^ ERROR: interior mutable shared borrows of temporaries fn main() {} diff --git a/tests/ui/consts/issue-17718-const-borrow.stderr b/tests/ui/consts/issue-17718-const-borrow.stderr index 962a81e70b3..420a2c378a2 100644 --- a/tests/ui/consts/issue-17718-const-borrow.stderr +++ b/tests/ui/consts/issue-17718-const-borrow.stderr @@ -1,20 +1,32 @@ -error[E0492]: interior mutable shared borrows of lifetime-extended temporaries in the top-level scope of a constant are not allowed +error[E0492]: interior mutable shared borrows of temporaries that have their lifetime extended until the end of the program are not allowed --> $DIR/issue-17718-const-borrow.rs:4:39 | LL | const B: &'static UnsafeCell<usize> = &A; - | ^^ this borrow of an interior mutable value refers to a lifetime-extended temporary + | ^^ this borrow of an interior mutable value refers to such a temporary + | + = note: Temporaries in constants and statics can have their lifetime extended until the end of the program + = note: To avoid accidentally creating global mutable state, such temporaries must be immutable + = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` -error[E0492]: interior mutable shared borrows of lifetime-extended temporaries in the top-level scope of a constant are not allowed +error[E0492]: interior mutable shared borrows of temporaries that have their lifetime extended until the end of the program are not allowed --> $DIR/issue-17718-const-borrow.rs:9:39 | LL | const E: &'static UnsafeCell<usize> = &D.a; - | ^^^^ this borrow of an interior mutable value refers to a lifetime-extended temporary + | ^^^^ this borrow of an interior mutable value refers to such a temporary + | + = note: Temporaries in constants and statics can have their lifetime extended until the end of the program + = note: To avoid accidentally creating global mutable state, such temporaries must be immutable + = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` -error[E0492]: interior mutable shared borrows of lifetime-extended temporaries in the top-level scope of a constant are not allowed +error[E0492]: interior mutable shared borrows of temporaries that have their lifetime extended until the end of the program are not allowed --> $DIR/issue-17718-const-borrow.rs:11:23 | LL | const F: &'static C = &D; - | ^^ this borrow of an interior mutable value refers to a lifetime-extended temporary + | ^^ this borrow of an interior mutable value refers to such a temporary + | + = note: Temporaries in constants and statics can have their lifetime extended until the end of the program + = note: To avoid accidentally creating global mutable state, such temporaries must be immutable + = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error: aborting due to 3 previous errors diff --git a/tests/ui/consts/partial_qualif.rs b/tests/ui/consts/partial_qualif.rs index 6770e138eca..18438cc576b 100644 --- a/tests/ui/consts/partial_qualif.rs +++ b/tests/ui/consts/partial_qualif.rs @@ -3,7 +3,7 @@ use std::cell::Cell; const FOO: &(Cell<usize>, bool) = { let mut a = (Cell::new(0), false); a.1 = true; // sets `qualif(a)` to `qualif(a) | qualif(true)` - &{a} //~ ERROR interior mutable shared borrows of lifetime-extended temporaries + &{a} //~ ERROR interior mutable shared borrows of temporaries }; fn main() {} diff --git a/tests/ui/consts/partial_qualif.stderr b/tests/ui/consts/partial_qualif.stderr index eb1a388ddee..b7632eb868a 100644 --- a/tests/ui/consts/partial_qualif.stderr +++ b/tests/ui/consts/partial_qualif.stderr @@ -1,8 +1,12 @@ -error[E0492]: interior mutable shared borrows of lifetime-extended temporaries in the top-level scope of a constant are not allowed +error[E0492]: interior mutable shared borrows of temporaries that have their lifetime extended until the end of the program are not allowed --> $DIR/partial_qualif.rs:6:5 | LL | &{a} - | ^^^^ this borrow of an interior mutable value refers to a lifetime-extended temporary + | ^^^^ this borrow of an interior mutable value refers to such a temporary + | + = note: Temporaries in constants and statics can have their lifetime extended until the end of the program + = note: To avoid accidentally creating global mutable state, such temporaries must be immutable + = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error: aborting due to 1 previous error diff --git a/tests/ui/consts/qualif_overwrite.rs b/tests/ui/consts/qualif_overwrite.rs index 3b494caa2c1..93310b3f2a6 100644 --- a/tests/ui/consts/qualif_overwrite.rs +++ b/tests/ui/consts/qualif_overwrite.rs @@ -7,7 +7,7 @@ use std::cell::Cell; const FOO: &Option<Cell<usize>> = { let mut a = Some(Cell::new(0)); a = None; // sets `qualif(a)` to `qualif(a) | qualif(None)` - &{a} //~ ERROR interior mutable shared borrows of lifetime-extended temporaries + &{a} //~ ERROR interior mutable shared borrows of temporaries }; fn main() {} diff --git a/tests/ui/consts/qualif_overwrite.stderr b/tests/ui/consts/qualif_overwrite.stderr index 92430a89b9e..4aaaa4b2ca9 100644 --- a/tests/ui/consts/qualif_overwrite.stderr +++ b/tests/ui/consts/qualif_overwrite.stderr @@ -1,8 +1,12 @@ -error[E0492]: interior mutable shared borrows of lifetime-extended temporaries in the top-level scope of a constant are not allowed +error[E0492]: interior mutable shared borrows of temporaries that have their lifetime extended until the end of the program are not allowed --> $DIR/qualif_overwrite.rs:10:5 | LL | &{a} - | ^^^^ this borrow of an interior mutable value refers to a lifetime-extended temporary + | ^^^^ this borrow of an interior mutable value refers to such a temporary + | + = note: Temporaries in constants and statics can have their lifetime extended until the end of the program + = note: To avoid accidentally creating global mutable state, such temporaries must be immutable + = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error: aborting due to 1 previous error diff --git a/tests/ui/consts/qualif_overwrite_2.rs b/tests/ui/consts/qualif_overwrite_2.rs index e06fd322553..e739790b566 100644 --- a/tests/ui/consts/qualif_overwrite_2.rs +++ b/tests/ui/consts/qualif_overwrite_2.rs @@ -5,7 +5,7 @@ use std::cell::Cell; const FOO: &Option<Cell<usize>> = { let mut a = (Some(Cell::new(0)),); a.0 = None; // sets `qualif(a)` to `qualif(a) | qualif(None)` - &{a.0} //~ ERROR interior mutable shared borrows of lifetime-extended temporaries + &{a.0} //~ ERROR interior mutable shared borrows of temporaries }; fn main() {} diff --git a/tests/ui/consts/qualif_overwrite_2.stderr b/tests/ui/consts/qualif_overwrite_2.stderr index a994ab61ea7..bc168141876 100644 --- a/tests/ui/consts/qualif_overwrite_2.stderr +++ b/tests/ui/consts/qualif_overwrite_2.stderr @@ -1,8 +1,12 @@ -error[E0492]: interior mutable shared borrows of lifetime-extended temporaries in the top-level scope of a constant are not allowed +error[E0492]: interior mutable shared borrows of temporaries that have their lifetime extended until the end of the program are not allowed --> $DIR/qualif_overwrite_2.rs:8:5 | LL | &{a.0} - | ^^^^^^ this borrow of an interior mutable value refers to a lifetime-extended temporary + | ^^^^^^ this borrow of an interior mutable value refers to such a temporary + | + = note: Temporaries in constants and statics can have their lifetime extended until the end of the program + = note: To avoid accidentally creating global mutable state, such temporaries must be immutable + = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error: aborting due to 1 previous error diff --git a/tests/ui/consts/refs-to-cell-in-final.rs b/tests/ui/consts/refs-to-cell-in-final.rs index 28a26f86909..2bd0623d94b 100644 --- a/tests/ui/consts/refs-to-cell-in-final.rs +++ b/tests/ui/consts/refs-to-cell-in-final.rs @@ -11,9 +11,9 @@ unsafe impl<T> Sync for SyncPtr<T> {} // The resulting constant would pass all validation checks, so it is crucial that this gets rejected // by static const checks! static RAW_SYNC_S: SyncPtr<Cell<i32>> = SyncPtr { x: &Cell::new(42) }; -//~^ ERROR: interior mutable shared borrows of lifetime-extended temporaries +//~^ ERROR: interior mutable shared borrows of temporaries const RAW_SYNC_C: SyncPtr<Cell<i32>> = SyncPtr { x: &Cell::new(42) }; -//~^ ERROR: interior mutable shared borrows of lifetime-extended temporaries +//~^ ERROR: interior mutable shared borrows of temporaries // This one does not get promoted because of `Drop`, and then enters interesting codepaths because // as a value it has no interior mutability, but as a type it does. See @@ -39,7 +39,7 @@ const NONE_EXPLICIT_PROMOTED: &'static Option<Cell<i32>> = { // Not okay, since we are borrowing something with interior mutability. const INTERIOR_MUT_VARIANT: &Option<UnsafeCell<bool>> = &{ - //~^ERROR: interior mutable shared borrows of lifetime-extended temporaries + //~^ERROR: interior mutable shared borrows of temporaries let mut x = None; assert!(x.is_none()); x = Some(UnsafeCell::new(false)); diff --git a/tests/ui/consts/refs-to-cell-in-final.stderr b/tests/ui/consts/refs-to-cell-in-final.stderr index 41f7a23852c..ac866dbe721 100644 --- a/tests/ui/consts/refs-to-cell-in-final.stderr +++ b/tests/ui/consts/refs-to-cell-in-final.stderr @@ -1,18 +1,24 @@ -error[E0492]: interior mutable shared borrows of lifetime-extended temporaries in the top-level scope of a static are not allowed +error[E0492]: interior mutable shared borrows of temporaries that have their lifetime extended until the end of the program are not allowed --> $DIR/refs-to-cell-in-final.rs:13:54 | LL | static RAW_SYNC_S: SyncPtr<Cell<i32>> = SyncPtr { x: &Cell::new(42) }; - | ^^^^^^^^^^^^^^ this borrow of an interior mutable value refers to a lifetime-extended temporary + | ^^^^^^^^^^^^^^ this borrow of an interior mutable value refers to such a temporary | - = help: to fix this, the value can be extracted to a separate `static` item and then referenced + = note: Temporaries in constants and statics can have their lifetime extended until the end of the program + = note: To avoid accidentally creating global mutable state, such temporaries must be immutable + = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` -error[E0492]: interior mutable shared borrows of lifetime-extended temporaries in the top-level scope of a constant are not allowed +error[E0492]: interior mutable shared borrows of temporaries that have their lifetime extended until the end of the program are not allowed --> $DIR/refs-to-cell-in-final.rs:15:53 | LL | const RAW_SYNC_C: SyncPtr<Cell<i32>> = SyncPtr { x: &Cell::new(42) }; - | ^^^^^^^^^^^^^^ this borrow of an interior mutable value refers to a lifetime-extended temporary + | ^^^^^^^^^^^^^^ this borrow of an interior mutable value refers to such a temporary + | + = note: Temporaries in constants and statics can have their lifetime extended until the end of the program + = note: To avoid accidentally creating global mutable state, such temporaries must be immutable + = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` -error[E0492]: interior mutable shared borrows of lifetime-extended temporaries in the top-level scope of a constant are not allowed +error[E0492]: interior mutable shared borrows of temporaries that have their lifetime extended until the end of the program are not allowed --> $DIR/refs-to-cell-in-final.rs:41:57 | LL | const INTERIOR_MUT_VARIANT: &Option<UnsafeCell<bool>> = &{ @@ -23,7 +29,11 @@ LL | | assert!(x.is_none()); LL | | x = Some(UnsafeCell::new(false)); LL | | x LL | | }; - | |_^ this borrow of an interior mutable value refers to a lifetime-extended temporary + | |_^ this borrow of an interior mutable value refers to such a temporary + | + = note: Temporaries in constants and statics can have their lifetime extended until the end of the program + = note: To avoid accidentally creating global mutable state, such temporaries must be immutable + = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error: aborting due to 3 previous errors diff --git a/tests/ui/consts/write_to_static_via_mut_ref.rs b/tests/ui/consts/write_to_static_via_mut_ref.rs index 6d3ddf01a2d..dc8a7eed13d 100644 --- a/tests/ui/consts/write_to_static_via_mut_ref.rs +++ b/tests/ui/consts/write_to_static_via_mut_ref.rs @@ -1,4 +1,4 @@ -static OH_NO: &mut i32 = &mut 42; //~ ERROR mutable borrows of lifetime-extended temporaries +static OH_NO: &mut i32 = &mut 42; //~ ERROR mutable borrows of temporaries fn main() { assert_eq!(*OH_NO, 42); *OH_NO = 43; //~ ERROR cannot assign to `*OH_NO`, as `OH_NO` is an immutable static diff --git a/tests/ui/consts/write_to_static_via_mut_ref.stderr b/tests/ui/consts/write_to_static_via_mut_ref.stderr index 76926e69491..1bcd7b81fe0 100644 --- a/tests/ui/consts/write_to_static_via_mut_ref.stderr +++ b/tests/ui/consts/write_to_static_via_mut_ref.stderr @@ -1,8 +1,12 @@ -error[E0764]: mutable borrows of lifetime-extended temporaries in the top-level scope of a static are not allowed +error[E0764]: mutable borrows of temporaries that have their lifetime extended until the end of the program are not allowed --> $DIR/write_to_static_via_mut_ref.rs:1:26 | LL | static OH_NO: &mut i32 = &mut 42; - | ^^^^^^^ + | ^^^^^^^ this mutable borrow refers to such a temporary + | + = note: Temporaries in constants and statics can have their lifetime extended until the end of the program + = note: To avoid accidentally creating global mutable state, such temporaries must be immutable + = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error[E0594]: cannot assign to `*OH_NO`, as `OH_NO` is an immutable static item --> $DIR/write_to_static_via_mut_ref.rs:4:5 diff --git a/tests/ui/error-codes/E0017.rs b/tests/ui/error-codes/E0017.rs index 52b81c8a09d..0f00ddac579 100644 --- a/tests/ui/error-codes/E0017.rs +++ b/tests/ui/error-codes/E0017.rs @@ -5,12 +5,12 @@ static X: i32 = 1; const C: i32 = 2; static mut M: i32 = 3; -const CR: &'static mut i32 = &mut C; //~ ERROR mutable borrows of lifetime-extended temporaries +const CR: &'static mut i32 = &mut C; //~ ERROR mutable borrows of temporaries //~| WARN taking a mutable static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR cannot borrow immutable static item `X` as mutable -static CONST_REF: &'static mut i32 = &mut C; //~ ERROR mutable borrows of lifetime-extended temporaries +static CONST_REF: &'static mut i32 = &mut C; //~ ERROR mutable borrows of temporaries //~| WARN taking a mutable fn main() {} diff --git a/tests/ui/error-codes/E0017.stderr b/tests/ui/error-codes/E0017.stderr index b1a94ca3e9d..2039e556470 100644 --- a/tests/ui/error-codes/E0017.stderr +++ b/tests/ui/error-codes/E0017.stderr @@ -13,11 +13,15 @@ LL | const C: i32 = 2; | ^^^^^^^^^^^^ = note: `#[warn(const_item_mutation)]` on by default -error[E0764]: mutable borrows of lifetime-extended temporaries in the top-level scope of a constant are not allowed +error[E0764]: mutable borrows of temporaries that have their lifetime extended until the end of the program are not allowed --> $DIR/E0017.rs:8:30 | LL | const CR: &'static mut i32 = &mut C; - | ^^^^^^ + | ^^^^^^ this mutable borrow refers to such a temporary + | + = note: Temporaries in constants and statics can have their lifetime extended until the end of the program + = note: To avoid accidentally creating global mutable state, such temporaries must be immutable + = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error[E0596]: cannot borrow immutable static item `X` as mutable --> $DIR/E0017.rs:11:39 @@ -39,11 +43,15 @@ note: `const` item defined here LL | const C: i32 = 2; | ^^^^^^^^^^^^ -error[E0764]: mutable borrows of lifetime-extended temporaries in the top-level scope of a static are not allowed +error[E0764]: mutable borrows of temporaries that have their lifetime extended until the end of the program are not allowed --> $DIR/E0017.rs:13:38 | LL | static CONST_REF: &'static mut i32 = &mut C; - | ^^^^^^ + | ^^^^^^ this mutable borrow refers to such a temporary + | + = note: Temporaries in constants and statics can have their lifetime extended until the end of the program + = note: To avoid accidentally creating global mutable state, such temporaries must be immutable + = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error: aborting due to 3 previous errors; 2 warnings emitted diff --git a/tests/ui/error-codes/E0492.stderr b/tests/ui/error-codes/E0492.stderr index fbbcf8f7d92..43a3a872e4e 100644 --- a/tests/ui/error-codes/E0492.stderr +++ b/tests/ui/error-codes/E0492.stderr @@ -1,16 +1,22 @@ -error[E0492]: interior mutable shared borrows of lifetime-extended temporaries in the top-level scope of a constant are not allowed +error[E0492]: interior mutable shared borrows of temporaries that have their lifetime extended until the end of the program are not allowed --> $DIR/E0492.rs:4:33 | LL | const B: &'static AtomicUsize = &A; - | ^^ this borrow of an interior mutable value refers to a lifetime-extended temporary + | ^^ this borrow of an interior mutable value refers to such a temporary + | + = note: Temporaries in constants and statics can have their lifetime extended until the end of the program + = note: To avoid accidentally creating global mutable state, such temporaries must be immutable + = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` -error[E0492]: interior mutable shared borrows of lifetime-extended temporaries in the top-level scope of a static are not allowed +error[E0492]: interior mutable shared borrows of temporaries that have their lifetime extended until the end of the program are not allowed --> $DIR/E0492.rs:5:34 | LL | static C: &'static AtomicUsize = &A; - | ^^ this borrow of an interior mutable value refers to a lifetime-extended temporary + | ^^ this borrow of an interior mutable value refers to such a temporary | - = help: to fix this, the value can be extracted to a separate `static` item and then referenced + = note: Temporaries in constants and statics can have their lifetime extended until the end of the program + = note: To avoid accidentally creating global mutable state, such temporaries must be immutable + = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error: aborting due to 2 previous errors diff --git a/tests/ui/issues/issue-46604.rs b/tests/ui/issues/issue-46604.rs index 03960941b2e..e15f0b52da2 100644 --- a/tests/ui/issues/issue-46604.rs +++ b/tests/ui/issues/issue-46604.rs @@ -1,4 +1,4 @@ -static buf: &mut [u8] = &mut [1u8,2,3,4,5,7]; //~ ERROR mutable borrows of lifetime-extended temporaries +static buf: &mut [u8] = &mut [1u8,2,3,4,5,7]; //~ ERROR mutable borrows of temporaries fn write<T: AsRef<[u8]>>(buffer: T) { } fn main() { diff --git a/tests/ui/issues/issue-46604.stderr b/tests/ui/issues/issue-46604.stderr index f00f3f0d23f..d983674995e 100644 --- a/tests/ui/issues/issue-46604.stderr +++ b/tests/ui/issues/issue-46604.stderr @@ -1,8 +1,12 @@ -error[E0764]: mutable borrows of lifetime-extended temporaries in the top-level scope of a static are not allowed +error[E0764]: mutable borrows of temporaries that have their lifetime extended until the end of the program are not allowed --> $DIR/issue-46604.rs:1:25 | LL | static buf: &mut [u8] = &mut [1u8,2,3,4,5,7]; - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^ this mutable borrow refers to such a temporary + | + = note: Temporaries in constants and statics can have their lifetime extended until the end of the program + = note: To avoid accidentally creating global mutable state, such temporaries must be immutable + = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error[E0594]: cannot assign to `buf[_]`, as `buf` is an immutable static item --> $DIR/issue-46604.rs:6:5 diff --git a/tests/ui/statics/check-immutable-mut-slices.rs b/tests/ui/statics/check-immutable-mut-slices.rs index 9e5ca5059d6..19545a1c925 100644 --- a/tests/ui/statics/check-immutable-mut-slices.rs +++ b/tests/ui/statics/check-immutable-mut-slices.rs @@ -1,6 +1,6 @@ // Checks that immutable static items can't have mutable slices static TEST: &'static mut [isize] = &mut []; -//~^ ERROR mutable borrows of lifetime-extended temporaries +//~^ ERROR mutable borrows of temporaries pub fn main() { } diff --git a/tests/ui/statics/check-immutable-mut-slices.stderr b/tests/ui/statics/check-immutable-mut-slices.stderr index 35521755650..a9486fc9d78 100644 --- a/tests/ui/statics/check-immutable-mut-slices.stderr +++ b/tests/ui/statics/check-immutable-mut-slices.stderr @@ -1,8 +1,12 @@ -error[E0764]: mutable borrows of lifetime-extended temporaries in the top-level scope of a static are not allowed +error[E0764]: mutable borrows of temporaries that have their lifetime extended until the end of the program are not allowed --> $DIR/check-immutable-mut-slices.rs:3:37 | LL | static TEST: &'static mut [isize] = &mut []; - | ^^^^^^^ + | ^^^^^^^ this mutable borrow refers to such a temporary + | + = note: Temporaries in constants and statics can have their lifetime extended until the end of the program + = note: To avoid accidentally creating global mutable state, such temporaries must be immutable + = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error: aborting due to 1 previous error |
