Cover more cases in the test suite
This commit is contained in:
parent
14f39aa81a
commit
cd09871157
4 changed files with 99 additions and 38 deletions
|
|
@ -1,6 +1,9 @@
|
|||
#![feature(const_mut_refs)]
|
||||
#![feature(const_fn)]
|
||||
#![feature(const_transmute)]
|
||||
#![feature(raw_ref_op)]
|
||||
#![feature(const_raw_ptr_deref)]
|
||||
|
||||
const NULL: *mut i32 = std::ptr::null_mut();
|
||||
const A: *const i32 = &4;
|
||||
|
||||
|
|
@ -9,6 +12,25 @@ const A: *const i32 = &4;
|
|||
// as that would be an enormous footgun in oli-obk's opinion.
|
||||
const B: *mut i32 = &mut 4; //~ ERROR mutable references are not allowed
|
||||
|
||||
// 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 temporary value dropped while borrowed
|
||||
|
||||
const fn helper() -> Option<&'static mut i32> { unsafe {
|
||||
// Undefined behaviour, who doesn't love tests like this.
|
||||
// This code never gets executed, because the static checks fail before that.
|
||||
Some(&mut *(42 as *mut i32))
|
||||
} }
|
||||
// Check that we do not look into function bodies.
|
||||
// We treat all functions as not returning a mutable reference, because there is no way to
|
||||
// do that without causing the borrow checker to complain (see the B5/helper2 test below).
|
||||
const B4: Option<&mut i32> = helper();
|
||||
|
||||
const fn helper2(x: &mut i32) -> Option<&mut i32> { Some(x) }
|
||||
const B5: Option<&mut i32> = helper2(&mut 42); //~ ERROR temporary value dropped while borrowed
|
||||
|
||||
// Ok, because no references to mutable data exist here, since the `{}` moves
|
||||
// its value and then takes a reference to that.
|
||||
const C: *const i32 = &{
|
||||
|
|
@ -17,7 +39,30 @@ const C: *const i32 = &{
|
|||
x
|
||||
};
|
||||
|
||||
use std::cell::UnsafeCell;
|
||||
struct NotAMutex<T>(UnsafeCell<T>);
|
||||
|
||||
unsafe impl<T> Sync for NotAMutex<T> {}
|
||||
|
||||
const FOO: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42));
|
||||
//~^ ERROR temporary value dropped while borrowed
|
||||
|
||||
static FOO2: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42));
|
||||
//~^ ERROR temporary value dropped while borrowed
|
||||
|
||||
static mut FOO3: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42));
|
||||
//~^ ERROR temporary value dropped while borrowed
|
||||
|
||||
// `BAR` works, because `&42` promotes immediately instead of relying on
|
||||
// the enclosing scope rule.
|
||||
const BAR: NotAMutex<&i32> = NotAMutex(UnsafeCell::new(&42));
|
||||
|
||||
fn main() {
|
||||
println!("{}", unsafe { *A });
|
||||
unsafe { *B = 4 } // Bad news
|
||||
|
||||
unsafe {
|
||||
**FOO.0.get() = 99;
|
||||
assert_eq!(**FOO.0.get(), 99);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,60 @@
|
|||
error[E0764]: mutable references are not allowed in the final value of constants
|
||||
--> $DIR/mut_ref_in_final.rs:10:21
|
||||
--> $DIR/mut_ref_in_final.rs:13:21
|
||||
|
|
||||
LL | const B: *mut i32 = &mut 4;
|
||||
| ^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0716]: temporary value dropped while borrowed
|
||||
--> $DIR/mut_ref_in_final.rs:19:40
|
||||
|
|
||||
LL | const B3: Option<&mut i32> = Some(&mut 42);
|
||||
| ----------^^-
|
||||
| | | |
|
||||
| | | temporary value is freed at the end of this statement
|
||||
| | creates a temporary which is freed while still in use
|
||||
| using this value as a constant requires that borrow lasts for `'static`
|
||||
|
||||
For more information about this error, try `rustc --explain E0764`.
|
||||
error[E0716]: temporary value dropped while borrowed
|
||||
--> $DIR/mut_ref_in_final.rs:32:43
|
||||
|
|
||||
LL | const B5: Option<&mut i32> = helper2(&mut 42);
|
||||
| -------------^^-
|
||||
| | | |
|
||||
| | | temporary value is freed at the end of this statement
|
||||
| | creates a temporary which is freed while still in use
|
||||
| using this value as a constant requires that borrow lasts for `'static`
|
||||
|
||||
error[E0716]: temporary value dropped while borrowed
|
||||
--> $DIR/mut_ref_in_final.rs:47:65
|
||||
|
|
||||
LL | const FOO: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42));
|
||||
| -------------------------------^^--
|
||||
| | | |
|
||||
| | | temporary value is freed at the end of this statement
|
||||
| | creates a temporary which is freed while still in use
|
||||
| using this value as a constant requires that borrow lasts for `'static`
|
||||
|
||||
error[E0716]: temporary value dropped while borrowed
|
||||
--> $DIR/mut_ref_in_final.rs:50:67
|
||||
|
|
||||
LL | static FOO2: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42));
|
||||
| -------------------------------^^--
|
||||
| | | |
|
||||
| | | temporary value is freed at the end of this statement
|
||||
| | creates a temporary which is freed while still in use
|
||||
| using this value as a static requires that borrow lasts for `'static`
|
||||
|
||||
error[E0716]: temporary value dropped while borrowed
|
||||
--> $DIR/mut_ref_in_final.rs:53:71
|
||||
|
|
||||
LL | static mut FOO3: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42));
|
||||
| -------------------------------^^--
|
||||
| | | |
|
||||
| | | temporary value is freed at the end of this statement
|
||||
| | creates a temporary which is freed while still in use
|
||||
| using this value as a static requires that borrow lasts for `'static`
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0716, E0764.
|
||||
For more information about an error, try `rustc --explain E0716`.
|
||||
|
|
|
|||
|
|
@ -1,22 +0,0 @@
|
|||
#![feature(const_mut_refs)]
|
||||
#![feature(const_fn)]
|
||||
#![feature(raw_ref_op)]
|
||||
|
||||
use std::cell::UnsafeCell;
|
||||
struct NotAMutex<T>(UnsafeCell<T>);
|
||||
|
||||
unsafe impl<T> Sync for NotAMutex<T> {}
|
||||
|
||||
const FOO: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42));
|
||||
//~^ ERROR temporary value dropped while borrowed
|
||||
|
||||
// `BAR` works, because `&42` promotes immediately instead of relying on
|
||||
// "final value lifetime extension".
|
||||
const BAR: NotAMutex<&i32> = NotAMutex(UnsafeCell::new(&42));
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
**FOO.0.get() = 99;
|
||||
assert_eq!(**FOO.0.get(), 99);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
error[E0716]: temporary value dropped while borrowed
|
||||
--> $DIR/mut_ref_in_final_ok.rs:10:65
|
||||
|
|
||||
LL | const FOO: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42));
|
||||
| -------------------------------^^--
|
||||
| | | |
|
||||
| | | temporary value is freed at the end of this statement
|
||||
| | creates a temporary which is freed while still in use
|
||||
| using this value as a constant requires that borrow lasts for `'static`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0716`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue