diff --git a/src/test/ui/consts/const-mut-refs/mut_ref_in_final.rs b/src/test/ui/consts/const-mut-refs/mut_ref_in_final.rs index b2230697037f3..166ba20f124e6 100644 --- a/src/test/ui/consts/const-mut-refs/mut_ref_in_final.rs +++ b/src/test/ui/consts/const-mut-refs/mut_ref_in_final.rs @@ -1,6 +1,5 @@ #![feature(const_mut_refs)] #![feature(const_fn)] -#![feature(const_transmute)] #![feature(raw_ref_op)] #![feature(const_raw_ptr_deref)] @@ -18,18 +17,8 @@ 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 +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 // Ok, because no references to mutable data exist here, since the `{}` moves // its value and then takes a reference to that. diff --git a/src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr b/src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr index 389b88955cec4..cbae74cce6f6b 100644 --- a/src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr +++ b/src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr @@ -1,11 +1,11 @@ error[E0764]: mutable references are not allowed in the final value of constants - --> $DIR/mut_ref_in_final.rs:13:21 + --> $DIR/mut_ref_in_final.rs:12:21 | LL | const B: *mut i32 = &mut 4; | ^^^^^^ error[E0716]: temporary value dropped while borrowed - --> $DIR/mut_ref_in_final.rs:19:40 + --> $DIR/mut_ref_in_final.rs:18:40 | LL | const B3: Option<&mut i32> = Some(&mut 42); | ----------^^- @@ -15,17 +15,17 @@ LL | const B3: Option<&mut i32> = Some(&mut 42); | 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:32:43 + --> $DIR/mut_ref_in_final.rs:21:42 | -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 +LL | const B4: Option<&mut i32> = helper(&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 + --> $DIR/mut_ref_in_final.rs:36:65 | LL | const FOO: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); | -------------------------------^^-- @@ -35,7 +35,7 @@ LL | const FOO: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); | 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 + --> $DIR/mut_ref_in_final.rs:39:67 | LL | static FOO2: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); | -------------------------------^^-- @@ -45,7 +45,7 @@ LL | static FOO2: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); | 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 + --> $DIR/mut_ref_in_final.rs:42:71 | LL | static mut FOO3: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); | -------------------------------^^-- diff --git a/src/test/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.rs b/src/test/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.rs new file mode 100644 index 0000000000000..1e856ec0a0acc --- /dev/null +++ b/src/test/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.rs @@ -0,0 +1,28 @@ +#![feature(const_mut_refs)] +#![feature(const_fn)] +#![feature(raw_ref_op)] +#![feature(const_raw_ptr_deref)] + +// This file checks that our dynamic checks catch things that the static checks miss. +// We do not have static checks for these, because 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 B4/helper test in +// mut_ref_in_final.rs). + +const fn helper() -> Option<&'static mut i32> { unsafe { + // Undefined behaviour (integer as pointer), 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)) //~ ERROR any use of this value will cause an error +} } +// The error is an evaluation error and not a validation error, so the error is reported +// directly at the site where it occurs. +const A: Option<&mut i32> = helper(); + +const fn helper2() -> Option<&'static mut i32> { unsafe { + // Undefined behaviour (dangling pointer), who doesn't love tests like this. + // This code never gets executed, because the static checks fail before that. + Some(&mut *(&mut 42 as *mut i32)) +} } +const B: Option<&mut i32> = helper2(); //~ ERROR encountered dangling pointer in final constant + +fn main() {} diff --git a/src/test/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr b/src/test/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr new file mode 100644 index 0000000000000..0bbf84b71bb68 --- /dev/null +++ b/src/test/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr @@ -0,0 +1,23 @@ +error: any use of this value will cause an error + --> $DIR/mut_ref_in_final_dynamic_check.rs:15:10 + | +LL | Some(&mut *(42 as *mut i32)) + | ^^^^^^^^^^^^^^^^^^^^^^ + | | + | unable to turn bytes into a pointer + | inside `helper` at $DIR/mut_ref_in_final_dynamic_check.rs:15:10 + | inside `A` at $DIR/mut_ref_in_final_dynamic_check.rs:19:29 +... +LL | const A: Option<&mut i32> = helper(); + | ------------------------------------- + | + = note: `#[deny(const_err)]` on by default + +error: encountered dangling pointer in final constant + --> $DIR/mut_ref_in_final_dynamic_check.rs:26:1 + | +LL | const B: Option<&mut i32> = helper2(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors +