Skip to content

Commit 97523f9

Browse files
authored
Unrolled build for #143092
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 #140942 to use the terminology of "top-level scope", but after further discussion in rust-lang/reference#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``
2 parents bdaba05 + d0fa026 commit 97523f9

30 files changed

+190
-110
lines changed

compiler/rustc_const_eval/messages.ftl

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -125,16 +125,11 @@ const_eval_incompatible_types =
125125
calling a function with argument of type {$callee_ty} passing data of type {$caller_ty}
126126
127127
const_eval_interior_mutable_borrow_escaping =
128-
interior mutable shared borrows of lifetime-extended temporaries in the top-level scope of a {const_eval_const_context} are not allowed
129-
.label = this borrow of an interior mutable value refers to a lifetime-extended temporary
130-
.help = to fix this, the value can be extracted to a separate `static` item and then referenced
131-
.teach_note =
132-
This creates a raw pointer to a temporary that has its lifetime extended to last for the entire program.
133-
Lifetime-extended temporaries in constants and statics must be immutable.
134-
This is to avoid accidentally creating shared mutable state.
135-
136-
137-
If you really want global mutable state, try using an interior mutable `static` or a `static mut`.
128+
interior mutable shared borrows of temporaries that have their lifetime extended until the end of the program are not allowed
129+
.label = this borrow of an interior mutable value refers to such a temporary
130+
.note = Temporaries in constants and statics can have their lifetime extended until the end of the program
131+
.note2 = To avoid accidentally creating global mutable state, such temporaries must be immutable
132+
.help = If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut`
138133
139134
const_eval_intern_kind = {$kind ->
140135
[static] static
@@ -215,14 +210,11 @@ const_eval_modified_global =
215210
modifying a static's initial value from another static's initializer
216211
217212
const_eval_mutable_borrow_escaping =
218-
mutable borrows of lifetime-extended temporaries in the top-level scope of a {const_eval_const_context} are not allowed
219-
.teach_note =
220-
This creates a reference to a temporary that has its lifetime extended to last for the entire program.
221-
Lifetime-extended temporaries in constants and statics must be immutable.
222-
This is to avoid accidentally creating shared mutable state.
223-
224-
225-
If you really want global mutable state, try using an interior mutable `static` or a `static mut`.
213+
mutable borrows of temporaries that have their lifetime extended until the end of the program are not allowed
214+
.label = this mutable borrow refers to such a temporary
215+
.note = Temporaries in constants and statics can have their lifetime extended until the end of the program
216+
.note2 = To avoid accidentally creating global mutable state, such temporaries must be immutable
217+
.help = If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut`
226218
227219
const_eval_mutable_ptr_in_final = encountered mutable pointer in final value of {const_eval_intern_kind}
228220

compiler/rustc_const_eval/src/check_consts/ops.rs

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -567,12 +567,7 @@ impl<'tcx> NonConstOp<'tcx> for EscapingCellBorrow {
567567
DiagImportance::Secondary
568568
}
569569
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
570-
ccx.dcx().create_err(errors::InteriorMutableBorrowEscaping {
571-
span,
572-
opt_help: matches!(ccx.const_kind(), hir::ConstContext::Static(_)),
573-
kind: ccx.const_kind(),
574-
teach: ccx.tcx.sess.teach(E0492),
575-
})
570+
ccx.dcx().create_err(errors::InteriorMutableBorrowEscaping { span, kind: ccx.const_kind() })
576571
}
577572
}
578573

@@ -594,11 +589,7 @@ impl<'tcx> NonConstOp<'tcx> for EscapingMutBorrow {
594589
}
595590

596591
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
597-
ccx.dcx().create_err(errors::MutableBorrowEscaping {
598-
span,
599-
kind: ccx.const_kind(),
600-
teach: ccx.tcx.sess.teach(E0764),
601-
})
592+
ccx.dcx().create_err(errors::MutableBorrowEscaping { span, kind: ccx.const_kind() })
602593
}
603594
}
604595

compiler/rustc_const_eval/src/errors.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -151,12 +151,14 @@ pub(crate) struct UnmarkedIntrinsicExposed {
151151

152152
#[derive(Diagnostic)]
153153
#[diag(const_eval_mutable_borrow_escaping, code = E0764)]
154+
#[note]
155+
#[note(const_eval_note2)]
156+
#[help]
154157
pub(crate) struct MutableBorrowEscaping {
155158
#[primary_span]
159+
#[label]
156160
pub span: Span,
157161
pub kind: ConstContext,
158-
#[note(const_eval_teach_note)]
159-
pub teach: bool,
160162
}
161163

162164
#[derive(Diagnostic)]
@@ -217,15 +219,14 @@ pub(crate) struct UnallowedInlineAsm {
217219

218220
#[derive(Diagnostic)]
219221
#[diag(const_eval_interior_mutable_borrow_escaping, code = E0492)]
222+
#[note]
223+
#[note(const_eval_note2)]
224+
#[help]
220225
pub(crate) struct InteriorMutableBorrowEscaping {
221226
#[primary_span]
222227
#[label]
223228
pub span: Span,
224-
#[help]
225-
pub opt_help: bool,
226229
pub kind: ConstContext,
227-
#[note(const_eval_teach_note)]
228-
pub teach: bool,
229230
}
230231

231232
#[derive(LintDiagnostic)]

tests/ui/consts/const-mut-refs/issue-76510.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::mem::{transmute, ManuallyDrop};
22

33
const S: &'static mut str = &mut " hello ";
4-
//~^ ERROR: mutable borrows of lifetime-extended temporaries
4+
//~^ ERROR: mutable borrows of temporaries
55

66
const fn trigger() -> [(); unsafe {
77
let s = transmute::<(*const u8, usize), &ManuallyDrop<str>>((S.as_ptr(), 3));

tests/ui/consts/const-mut-refs/issue-76510.stderr

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1-
error[E0764]: mutable borrows of lifetime-extended temporaries in the top-level scope of a constant are not allowed
1+
error[E0764]: mutable borrows of temporaries that have their lifetime extended until the end of the program are not allowed
22
--> $DIR/issue-76510.rs:3:29
33
|
44
LL | const S: &'static mut str = &mut " hello ";
5-
| ^^^^^^^^^^^^^^
5+
| ^^^^^^^^^^^^^^ this mutable borrow refers to such a temporary
6+
|
7+
= note: Temporaries in constants and statics can have their lifetime extended until the end of the program
8+
= note: To avoid accidentally creating global mutable state, such temporaries must be immutable
9+
= help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut`
610

711
error: aborting due to 1 previous error
812

tests/ui/consts/const-mut-refs/mut_ref_in_final.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@ const A: *const i32 = &4;
1212
// It could be made sound to allow it to compile,
1313
// but we do not want to allow this to compile,
1414
// as that would be an enormous footgun in oli-obk's opinion.
15-
const B: *mut i32 = &mut 4; //~ ERROR mutable borrows of lifetime-extended temporaries
15+
const B: *mut i32 = &mut 4; //~ ERROR mutable borrows of temporaries
1616

1717
// Ok, no actual mutable allocation exists
1818
const B2: Option<&mut i32> = None;
1919

2020
// Not ok, can't prove that no mutable allocation ends up in final value
21-
const B3: Option<&mut i32> = Some(&mut 42); //~ ERROR mutable borrows of lifetime-extended temporaries
21+
const B3: Option<&mut i32> = Some(&mut 42); //~ ERROR mutable borrows of temporaries
2222

2323
const fn helper(x: &mut i32) -> Option<&mut i32> { Some(x) }
2424
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> {}
6969
// (This relies on `SyncPtr` being a curly brace struct.)
7070
// However, we intern the inner memory as read-only, so this must be rejected.
7171
static RAW_MUT_CAST_S: SyncPtr<i32> = SyncPtr { x : &mut 42 as *mut _ as *const _ };
72-
//~^ ERROR mutable borrows of lifetime-extended temporaries
72+
//~^ ERROR mutable borrows of temporaries
7373
static RAW_MUT_COERCE_S: SyncPtr<i32> = SyncPtr { x: &mut 0 };
74-
//~^ ERROR mutable borrows of lifetime-extended temporaries
74+
//~^ ERROR mutable borrows of temporaries
7575
const RAW_MUT_CAST_C: SyncPtr<i32> = SyncPtr { x : &mut 42 as *mut _ as *const _ };
76-
//~^ ERROR mutable borrows of lifetime-extended temporaries
76+
//~^ ERROR mutable borrows of temporaries
7777
const RAW_MUT_COERCE_C: SyncPtr<i32> = SyncPtr { x: &mut 0 };
78-
//~^ ERROR mutable borrows of lifetime-extended temporaries
78+
//~^ ERROR mutable borrows of temporaries
7979

8080
fn main() {
8181
println!("{}", unsafe { *A });

tests/ui/consts/const-mut-refs/mut_ref_in_final.stderr

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,22 @@
1-
error[E0764]: mutable borrows of lifetime-extended temporaries in the top-level scope of a constant are not allowed
1+
error[E0764]: mutable borrows of temporaries that have their lifetime extended until the end of the program are not allowed
22
--> $DIR/mut_ref_in_final.rs:15:21
33
|
44
LL | const B: *mut i32 = &mut 4;
5-
| ^^^^^^
5+
| ^^^^^^ this mutable borrow refers to such a temporary
6+
|
7+
= note: Temporaries in constants and statics can have their lifetime extended until the end of the program
8+
= note: To avoid accidentally creating global mutable state, such temporaries must be immutable
9+
= help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut`
610

7-
error[E0764]: mutable borrows of lifetime-extended temporaries in the top-level scope of a constant are not allowed
11+
error[E0764]: mutable borrows of temporaries that have their lifetime extended until the end of the program are not allowed
812
--> $DIR/mut_ref_in_final.rs:21:35
913
|
1014
LL | const B3: Option<&mut i32> = Some(&mut 42);
11-
| ^^^^^^^
15+
| ^^^^^^^ this mutable borrow refers to such a temporary
16+
|
17+
= note: Temporaries in constants and statics can have their lifetime extended until the end of the program
18+
= note: To avoid accidentally creating global mutable state, such temporaries must be immutable
19+
= help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut`
1220

1321
error[E0716]: temporary value dropped while borrowed
1422
--> $DIR/mut_ref_in_final.rs:24:42
@@ -72,29 +80,45 @@ LL | static mut FOO3: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42));
7280
| | creates a temporary value which is freed while still in use
7381
| using this value as a static requires that borrow lasts for `'static`
7482

75-
error[E0764]: mutable borrows of lifetime-extended temporaries in the top-level scope of a static are not allowed
83+
error[E0764]: mutable borrows of temporaries that have their lifetime extended until the end of the program are not allowed
7684
--> $DIR/mut_ref_in_final.rs:71:53
7785
|
7886
LL | static RAW_MUT_CAST_S: SyncPtr<i32> = SyncPtr { x : &mut 42 as *mut _ as *const _ };
79-
| ^^^^^^^
87+
| ^^^^^^^ this mutable borrow refers to such a temporary
88+
|
89+
= note: Temporaries in constants and statics can have their lifetime extended until the end of the program
90+
= note: To avoid accidentally creating global mutable state, such temporaries must be immutable
91+
= help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut`
8092

81-
error[E0764]: mutable borrows of lifetime-extended temporaries in the top-level scope of a static are not allowed
93+
error[E0764]: mutable borrows of temporaries that have their lifetime extended until the end of the program are not allowed
8294
--> $DIR/mut_ref_in_final.rs:73:54
8395
|
8496
LL | static RAW_MUT_COERCE_S: SyncPtr<i32> = SyncPtr { x: &mut 0 };
85-
| ^^^^^^
97+
| ^^^^^^ this mutable borrow refers to such a temporary
98+
|
99+
= note: Temporaries in constants and statics can have their lifetime extended until the end of the program
100+
= note: To avoid accidentally creating global mutable state, such temporaries must be immutable
101+
= help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut`
86102

87-
error[E0764]: mutable borrows of lifetime-extended temporaries in the top-level scope of a constant are not allowed
103+
error[E0764]: mutable borrows of temporaries that have their lifetime extended until the end of the program are not allowed
88104
--> $DIR/mut_ref_in_final.rs:75:52
89105
|
90106
LL | const RAW_MUT_CAST_C: SyncPtr<i32> = SyncPtr { x : &mut 42 as *mut _ as *const _ };
91-
| ^^^^^^^
107+
| ^^^^^^^ this mutable borrow refers to such a temporary
108+
|
109+
= note: Temporaries in constants and statics can have their lifetime extended until the end of the program
110+
= note: To avoid accidentally creating global mutable state, such temporaries must be immutable
111+
= help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut`
92112

93-
error[E0764]: mutable borrows of lifetime-extended temporaries in the top-level scope of a constant are not allowed
113+
error[E0764]: mutable borrows of temporaries that have their lifetime extended until the end of the program are not allowed
94114
--> $DIR/mut_ref_in_final.rs:77:53
95115
|
96116
LL | const RAW_MUT_COERCE_C: SyncPtr<i32> = SyncPtr { x: &mut 0 };
97-
| ^^^^^^
117+
| ^^^^^^ this mutable borrow refers to such a temporary
118+
|
119+
= note: Temporaries in constants and statics can have their lifetime extended until the end of the program
120+
= note: To avoid accidentally creating global mutable state, such temporaries must be immutable
121+
= help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut`
98122

99123
error: aborting due to 12 previous errors
100124

tests/ui/consts/const-promoted-opaque.atomic.stderr

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,15 @@ LL |
77
LL | };
88
| - value is dropped here
99

10-
error[E0492]: interior mutable shared borrows of lifetime-extended temporaries in the top-level scope of a constant are not allowed
10+
error[E0492]: interior mutable shared borrows of temporaries that have their lifetime extended until the end of the program are not allowed
1111
--> $DIR/const-promoted-opaque.rs:36:19
1212
|
1313
LL | const BAZ: &Foo = &FOO;
14-
| ^^^^ this borrow of an interior mutable value refers to a lifetime-extended temporary
14+
| ^^^^ this borrow of an interior mutable value refers to such a temporary
15+
|
16+
= note: Temporaries in constants and statics can have their lifetime extended until the end of the program
17+
= note: To avoid accidentally creating global mutable state, such temporaries must be immutable
18+
= help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut`
1519

1620
error[E0716]: temporary value dropped while borrowed
1721
--> $DIR/const-promoted-opaque.rs:40:26

tests/ui/consts/const-promoted-opaque.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ const BAR: () = {
3434
};
3535

3636
const BAZ: &Foo = &FOO;
37-
//[atomic]~^ ERROR: interior mutable shared borrows of lifetime-extended temporaries
37+
//[atomic]~^ ERROR: interior mutable shared borrows of temporaries
3838

3939
fn main() {
4040
let _: &'static _ = &FOO;

tests/ui/consts/issue-17718-const-bad-values.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#![allow(static_mut_refs)]
66

77
const C1: &'static mut [usize] = &mut [];
8-
//~^ ERROR: mutable borrows of lifetime-extended temporaries
8+
//~^ ERROR: mutable borrows of temporaries
99

1010
static mut S: i32 = 3;
1111
const C2: &'static mut i32 = unsafe { &mut S };

tests/ui/consts/issue-17718-const-bad-values.stderr

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1-
error[E0764]: mutable borrows of lifetime-extended temporaries in the top-level scope of a constant are not allowed
1+
error[E0764]: mutable borrows of temporaries that have their lifetime extended until the end of the program are not allowed
22
--> $DIR/issue-17718-const-bad-values.rs:7:34
33
|
44
LL | const C1: &'static mut [usize] = &mut [];
5-
| ^^^^^^^
5+
| ^^^^^^^ this mutable borrow refers to such a temporary
6+
|
7+
= note: Temporaries in constants and statics can have their lifetime extended until the end of the program
8+
= note: To avoid accidentally creating global mutable state, such temporaries must be immutable
9+
= help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut`
610

711
error[E0080]: constructing invalid value: encountered mutable reference in `const` value
812
--> $DIR/issue-17718-const-bad-values.rs:11:1

tests/ui/consts/issue-17718-const-borrow.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ use std::cell::UnsafeCell;
22

33
const A: UnsafeCell<usize> = UnsafeCell::new(1);
44
const B: &'static UnsafeCell<usize> = &A;
5-
//~^ ERROR: interior mutable shared borrows of lifetime-extended temporaries
5+
//~^ ERROR: interior mutable shared borrows of temporaries
66

77
struct C { a: UnsafeCell<usize> }
88
const D: C = C { a: UnsafeCell::new(1) };
99
const E: &'static UnsafeCell<usize> = &D.a;
10-
//~^ ERROR: interior mutable shared borrows of lifetime-extended temporaries
10+
//~^ ERROR: interior mutable shared borrows of temporaries
1111
const F: &'static C = &D;
12-
//~^ ERROR: interior mutable shared borrows of lifetime-extended temporaries
12+
//~^ ERROR: interior mutable shared borrows of temporaries
1313

1414
fn main() {}

tests/ui/consts/issue-17718-const-borrow.stderr

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,32 @@
1-
error[E0492]: interior mutable shared borrows of lifetime-extended temporaries in the top-level scope of a constant are not allowed
1+
error[E0492]: interior mutable shared borrows of temporaries that have their lifetime extended until the end of the program are not allowed
22
--> $DIR/issue-17718-const-borrow.rs:4:39
33
|
44
LL | const B: &'static UnsafeCell<usize> = &A;
5-
| ^^ this borrow of an interior mutable value refers to a lifetime-extended temporary
5+
| ^^ this borrow of an interior mutable value refers to such a temporary
6+
|
7+
= note: Temporaries in constants and statics can have their lifetime extended until the end of the program
8+
= note: To avoid accidentally creating global mutable state, such temporaries must be immutable
9+
= help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut`
610

7-
error[E0492]: interior mutable shared borrows of lifetime-extended temporaries in the top-level scope of a constant are not allowed
11+
error[E0492]: interior mutable shared borrows of temporaries that have their lifetime extended until the end of the program are not allowed
812
--> $DIR/issue-17718-const-borrow.rs:9:39
913
|
1014
LL | const E: &'static UnsafeCell<usize> = &D.a;
11-
| ^^^^ this borrow of an interior mutable value refers to a lifetime-extended temporary
15+
| ^^^^ this borrow of an interior mutable value refers to such a temporary
16+
|
17+
= note: Temporaries in constants and statics can have their lifetime extended until the end of the program
18+
= note: To avoid accidentally creating global mutable state, such temporaries must be immutable
19+
= help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut`
1220

13-
error[E0492]: interior mutable shared borrows of lifetime-extended temporaries in the top-level scope of a constant are not allowed
21+
error[E0492]: interior mutable shared borrows of temporaries that have their lifetime extended until the end of the program are not allowed
1422
--> $DIR/issue-17718-const-borrow.rs:11:23
1523
|
1624
LL | const F: &'static C = &D;
17-
| ^^ this borrow of an interior mutable value refers to a lifetime-extended temporary
25+
| ^^ this borrow of an interior mutable value refers to such a temporary
26+
|
27+
= note: Temporaries in constants and statics can have their lifetime extended until the end of the program
28+
= note: To avoid accidentally creating global mutable state, such temporaries must be immutable
29+
= help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut`
1830

1931
error: aborting due to 3 previous errors
2032

tests/ui/consts/partial_qualif.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::cell::Cell;
33
const FOO: &(Cell<usize>, bool) = {
44
let mut a = (Cell::new(0), false);
55
a.1 = true; // sets `qualif(a)` to `qualif(a) | qualif(true)`
6-
&{a} //~ ERROR interior mutable shared borrows of lifetime-extended temporaries
6+
&{a} //~ ERROR interior mutable shared borrows of temporaries
77
};
88

99
fn main() {}

0 commit comments

Comments
 (0)