Skip to content

Commit cd09871

Browse files
committed
Cover more cases in the test suite
1 parent 14f39aa commit cd09871

File tree

4 files changed

+99
-38
lines changed

4 files changed

+99
-38
lines changed

src/test/ui/consts/const-mut-refs/mut_ref_in_final.rs

+45
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
#![feature(const_mut_refs)]
22
#![feature(const_fn)]
3+
#![feature(const_transmute)]
34
#![feature(raw_ref_op)]
5+
#![feature(const_raw_ptr_deref)]
6+
47
const NULL: *mut i32 = std::ptr::null_mut();
58
const A: *const i32 = &4;
69

@@ -9,6 +12,25 @@ const A: *const i32 = &4;
912
// as that would be an enormous footgun in oli-obk's opinion.
1013
const B: *mut i32 = &mut 4; //~ ERROR mutable references are not allowed
1114

15+
// Ok, no actual mutable allocation exists
16+
const B2: Option<&mut i32> = None;
17+
18+
// Not ok, can't prove that no mutable allocation ends up in final value
19+
const B3: Option<&mut i32> = Some(&mut 42); //~ ERROR temporary value dropped while borrowed
20+
21+
const fn helper() -> Option<&'static mut i32> { unsafe {
22+
// Undefined behaviour, who doesn't love tests like this.
23+
// This code never gets executed, because the static checks fail before that.
24+
Some(&mut *(42 as *mut i32))
25+
} }
26+
// Check that we do not look into function bodies.
27+
// We treat all functions as not returning a mutable reference, because there is no way to
28+
// do that without causing the borrow checker to complain (see the B5/helper2 test below).
29+
const B4: Option<&mut i32> = helper();
30+
31+
const fn helper2(x: &mut i32) -> Option<&mut i32> { Some(x) }
32+
const B5: Option<&mut i32> = helper2(&mut 42); //~ ERROR temporary value dropped while borrowed
33+
1234
// Ok, because no references to mutable data exist here, since the `{}` moves
1335
// its value and then takes a reference to that.
1436
const C: *const i32 = &{
@@ -17,7 +39,30 @@ const C: *const i32 = &{
1739
x
1840
};
1941

42+
use std::cell::UnsafeCell;
43+
struct NotAMutex<T>(UnsafeCell<T>);
44+
45+
unsafe impl<T> Sync for NotAMutex<T> {}
46+
47+
const FOO: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42));
48+
//~^ ERROR temporary value dropped while borrowed
49+
50+
static FOO2: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42));
51+
//~^ ERROR temporary value dropped while borrowed
52+
53+
static mut FOO3: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42));
54+
//~^ ERROR temporary value dropped while borrowed
55+
56+
// `BAR` works, because `&42` promotes immediately instead of relying on
57+
// the enclosing scope rule.
58+
const BAR: NotAMutex<&i32> = NotAMutex(UnsafeCell::new(&42));
59+
2060
fn main() {
2161
println!("{}", unsafe { *A });
2262
unsafe { *B = 4 } // Bad news
63+
64+
unsafe {
65+
**FOO.0.get() = 99;
66+
assert_eq!(**FOO.0.get(), 99);
67+
}
2368
}
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,60 @@
11
error[E0764]: mutable references are not allowed in the final value of constants
2-
--> $DIR/mut_ref_in_final.rs:10:21
2+
--> $DIR/mut_ref_in_final.rs:13:21
33
|
44
LL | const B: *mut i32 = &mut 4;
55
| ^^^^^^
66

7-
error: aborting due to previous error
7+
error[E0716]: temporary value dropped while borrowed
8+
--> $DIR/mut_ref_in_final.rs:19:40
9+
|
10+
LL | const B3: Option<&mut i32> = Some(&mut 42);
11+
| ----------^^-
12+
| | | |
13+
| | | temporary value is freed at the end of this statement
14+
| | creates a temporary which is freed while still in use
15+
| using this value as a constant requires that borrow lasts for `'static`
16+
17+
error[E0716]: temporary value dropped while borrowed
18+
--> $DIR/mut_ref_in_final.rs:32:43
19+
|
20+
LL | const B5: Option<&mut i32> = helper2(&mut 42);
21+
| -------------^^-
22+
| | | |
23+
| | | temporary value is freed at the end of this statement
24+
| | creates a temporary which is freed while still in use
25+
| using this value as a constant requires that borrow lasts for `'static`
26+
27+
error[E0716]: temporary value dropped while borrowed
28+
--> $DIR/mut_ref_in_final.rs:47:65
29+
|
30+
LL | const FOO: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42));
31+
| -------------------------------^^--
32+
| | | |
33+
| | | temporary value is freed at the end of this statement
34+
| | creates a temporary which is freed while still in use
35+
| using this value as a constant requires that borrow lasts for `'static`
36+
37+
error[E0716]: temporary value dropped while borrowed
38+
--> $DIR/mut_ref_in_final.rs:50:67
39+
|
40+
LL | static FOO2: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42));
41+
| -------------------------------^^--
42+
| | | |
43+
| | | temporary value is freed at the end of this statement
44+
| | creates a temporary which is freed while still in use
45+
| using this value as a static requires that borrow lasts for `'static`
46+
47+
error[E0716]: temporary value dropped while borrowed
48+
--> $DIR/mut_ref_in_final.rs:53:71
49+
|
50+
LL | static mut FOO3: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42));
51+
| -------------------------------^^--
52+
| | | |
53+
| | | temporary value is freed at the end of this statement
54+
| | creates a temporary which is freed while still in use
55+
| using this value as a static requires that borrow lasts for `'static`
56+
57+
error: aborting due to 6 previous errors
858

9-
For more information about this error, try `rustc --explain E0764`.
59+
Some errors have detailed explanations: E0716, E0764.
60+
For more information about an error, try `rustc --explain E0716`.

src/test/ui/consts/const-mut-refs/mut_ref_in_final_ok.rs

-22
This file was deleted.

src/test/ui/consts/const-mut-refs/mut_ref_in_final_ok.stderr

-13
This file was deleted.

0 commit comments

Comments
 (0)