From 218caa410aa38c29984be31a5229b9fa717560ee Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:19:13 +0200 Subject: Merging upstream version 1.68.2+dfsg1. Signed-off-by: Daniel Baumann --- .../consts/const-mut-refs/const_mut_address_of.rs | 28 ++++++++++ tests/ui/consts/const-mut-refs/const_mut_refs.rs | 35 +++++++++++++ .../const-mut-refs/feature-gate-const_mut_refs.rs | 8 +++ .../feature-gate-const_mut_refs.stderr | 12 +++++ .../consts/const-mut-refs/issue-76510.32bit.stderr | 31 +++++++++++ .../consts/const-mut-refs/issue-76510.64bit.stderr | 31 +++++++++++ tests/ui/consts/const-mut-refs/issue-76510.rs | 18 +++++++ tests/ui/consts/const-mut-refs/mut_ref_in_final.rs | 55 ++++++++++++++++++++ .../consts/const-mut-refs/mut_ref_in_final.stderr | 60 ++++++++++++++++++++++ .../mut_ref_in_final_dynamic_check.rs | 27 ++++++++++ .../mut_ref_in_final_dynamic_check.stderr | 26 ++++++++++ 11 files changed, 331 insertions(+) create mode 100644 tests/ui/consts/const-mut-refs/const_mut_address_of.rs create mode 100644 tests/ui/consts/const-mut-refs/const_mut_refs.rs create mode 100644 tests/ui/consts/const-mut-refs/feature-gate-const_mut_refs.rs create mode 100644 tests/ui/consts/const-mut-refs/feature-gate-const_mut_refs.stderr create mode 100644 tests/ui/consts/const-mut-refs/issue-76510.32bit.stderr create mode 100644 tests/ui/consts/const-mut-refs/issue-76510.64bit.stderr create mode 100644 tests/ui/consts/const-mut-refs/issue-76510.rs create mode 100644 tests/ui/consts/const-mut-refs/mut_ref_in_final.rs create mode 100644 tests/ui/consts/const-mut-refs/mut_ref_in_final.stderr create mode 100644 tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.rs create mode 100644 tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr (limited to 'tests/ui/consts/const-mut-refs') diff --git a/tests/ui/consts/const-mut-refs/const_mut_address_of.rs b/tests/ui/consts/const-mut-refs/const_mut_address_of.rs new file mode 100644 index 000000000..03b2f9e3c --- /dev/null +++ b/tests/ui/consts/const-mut-refs/const_mut_address_of.rs @@ -0,0 +1,28 @@ +// check-pass +#![feature(const_mut_refs)] +#![feature(raw_ref_op)] + +struct Foo { + x: usize +} + +const fn foo() -> Foo { + Foo { x: 0 } +} + +impl Foo { + const fn bar(&mut self) -> *mut usize { + &raw mut self.x + } +} + +const fn baz(foo: &mut Foo)-> *mut usize { + &raw mut foo.x +} + +const _: () = { + foo().bar(); + baz(&mut foo()); +}; + +fn main() {} diff --git a/tests/ui/consts/const-mut-refs/const_mut_refs.rs b/tests/ui/consts/const-mut-refs/const_mut_refs.rs new file mode 100644 index 000000000..544458dfc --- /dev/null +++ b/tests/ui/consts/const-mut-refs/const_mut_refs.rs @@ -0,0 +1,35 @@ +// check-pass +#![feature(const_mut_refs)] + +struct Foo { + x: usize +} + +const fn foo() -> Foo { + Foo { x: 0 } +} + +impl Foo { + const fn bar(&mut self) -> usize { + self.x = 1; + self.x + } + +} + +const fn baz(foo: &mut Foo) -> usize { + let x = &mut foo.x; + *x = 2; + *x +} + +const fn bazz(foo: &mut Foo) -> usize { + foo.x = 3; + foo.x +} + +fn main() { + let _: [(); foo().bar()] = [(); 1]; + let _: [(); baz(&mut foo())] = [(); 2]; + let _: [(); bazz(&mut foo())] = [(); 3]; +} diff --git a/tests/ui/consts/const-mut-refs/feature-gate-const_mut_refs.rs b/tests/ui/consts/const-mut-refs/feature-gate-const_mut_refs.rs new file mode 100644 index 000000000..ce9be4ac5 --- /dev/null +++ b/tests/ui/consts/const-mut-refs/feature-gate-const_mut_refs.rs @@ -0,0 +1,8 @@ +fn main() { + foo(&mut 5); +} + +const fn foo(x: &mut i32) -> i32 { //~ ERROR mutable references + *x + 1 + +} diff --git a/tests/ui/consts/const-mut-refs/feature-gate-const_mut_refs.stderr b/tests/ui/consts/const-mut-refs/feature-gate-const_mut_refs.stderr new file mode 100644 index 000000000..3f9bd3705 --- /dev/null +++ b/tests/ui/consts/const-mut-refs/feature-gate-const_mut_refs.stderr @@ -0,0 +1,12 @@ +error[E0658]: mutable references are not allowed in constant functions + --> $DIR/feature-gate-const_mut_refs.rs:5:14 + | +LL | const fn foo(x: &mut i32) -> i32 { + | ^ + | + = note: see issue #57349 for more information + = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/consts/const-mut-refs/issue-76510.32bit.stderr b/tests/ui/consts/const-mut-refs/issue-76510.32bit.stderr new file mode 100644 index 000000000..109d15a8e --- /dev/null +++ b/tests/ui/consts/const-mut-refs/issue-76510.32bit.stderr @@ -0,0 +1,31 @@ +error[E0764]: mutable references are not allowed in the final value of constants + --> $DIR/issue-76510.rs:5:29 + | +LL | const S: &'static mut str = &mut " hello "; + | ^^^^^^^^^^^^^^ + +error[E0658]: mutation through a reference is not allowed in constants + --> $DIR/issue-76510.rs:5:29 + | +LL | const S: &'static mut str = &mut " hello "; + | ^^^^^^^^^^^^^^ + | + = note: see issue #57349 for more information + = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable + +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/issue-76510.rs:5:29 + | +LL | const S: &'static mut str = &mut " hello "; + | ^^^^^^^^^^^^^^ cannot borrow as mutable + +note: erroneous constant used + --> $DIR/issue-76510.rs:11:70 + | +LL | let s = transmute::<(*const u8, usize), &ManuallyDrop>((S.as_ptr(), 3)); + | ^ + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0596, E0658, E0764. +For more information about an error, try `rustc --explain E0596`. diff --git a/tests/ui/consts/const-mut-refs/issue-76510.64bit.stderr b/tests/ui/consts/const-mut-refs/issue-76510.64bit.stderr new file mode 100644 index 000000000..109d15a8e --- /dev/null +++ b/tests/ui/consts/const-mut-refs/issue-76510.64bit.stderr @@ -0,0 +1,31 @@ +error[E0764]: mutable references are not allowed in the final value of constants + --> $DIR/issue-76510.rs:5:29 + | +LL | const S: &'static mut str = &mut " hello "; + | ^^^^^^^^^^^^^^ + +error[E0658]: mutation through a reference is not allowed in constants + --> $DIR/issue-76510.rs:5:29 + | +LL | const S: &'static mut str = &mut " hello "; + | ^^^^^^^^^^^^^^ + | + = note: see issue #57349 for more information + = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable + +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/issue-76510.rs:5:29 + | +LL | const S: &'static mut str = &mut " hello "; + | ^^^^^^^^^^^^^^ cannot borrow as mutable + +note: erroneous constant used + --> $DIR/issue-76510.rs:11:70 + | +LL | let s = transmute::<(*const u8, usize), &ManuallyDrop>((S.as_ptr(), 3)); + | ^ + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0596, E0658, E0764. +For more information about an error, try `rustc --explain E0596`. diff --git a/tests/ui/consts/const-mut-refs/issue-76510.rs b/tests/ui/consts/const-mut-refs/issue-76510.rs new file mode 100644 index 000000000..b853e2737 --- /dev/null +++ b/tests/ui/consts/const-mut-refs/issue-76510.rs @@ -0,0 +1,18 @@ +// stderr-per-bitwidth + +use std::mem::{transmute, ManuallyDrop}; + +const S: &'static mut str = &mut " hello "; +//~^ ERROR: mutable references are not allowed in the final value of constants +//~| ERROR: mutation through a reference is not allowed in constants +//~| ERROR: cannot borrow data in a `&` reference as mutable + +const fn trigger() -> [(); unsafe { + let s = transmute::<(*const u8, usize), &ManuallyDrop>((S.as_ptr(), 3)); + //~^ constant + 0 + }] { + [(); 0] +} + +fn main() {} 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 new file mode 100644 index 000000000..a7d329f12 --- /dev/null +++ b/tests/ui/consts/const-mut-refs/mut_ref_in_final.rs @@ -0,0 +1,55 @@ +#![feature(const_mut_refs)] +#![feature(raw_ref_op)] + +const NULL: *mut i32 = std::ptr::null_mut(); +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 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(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. +const C: *const i32 = &{ + let mut x = 42; + x += 3; + x +}; + +use std::cell::UnsafeCell; +struct NotAMutex(UnsafeCell); + +unsafe impl Sync for NotAMutex {} + +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); + } +} 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 new file mode 100644 index 000000000..78c58b5ab --- /dev/null +++ b/tests/ui/consts/const-mut-refs/mut_ref_in_final.stderr @@ -0,0 +1,60 @@ +error[E0764]: mutable references are not allowed in the final value of constants + --> $DIR/mut_ref_in_final.rs:10:21 + | +LL | const B: *mut i32 = &mut 4; + | ^^^^^^ + +error[E0716]: temporary value dropped while borrowed + --> $DIR/mut_ref_in_final.rs:16:40 + | +LL | const B3: Option<&mut i32> = Some(&mut 42); + | ----------^^- + | | | | + | | | temporary value is freed at the end of this statement + | | creates a temporary value 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:19:42 + | +LL | const B4: Option<&mut i32> = helper(&mut 42); + | ------------^^- + | | | | + | | | temporary value is freed at the end of this statement + | | creates a temporary value 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:34: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 value 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:37: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 value 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:40: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 value 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`. diff --git a/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.rs b/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.rs new file mode 100644 index 000000000..074beaab2 --- /dev/null +++ b/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.rs @@ -0,0 +1,27 @@ +#![feature(const_mut_refs)] +#![feature(raw_ref_op)] + +// 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 evaluation of constant value failed + //~| 0x2a[noalloc] is a dangling pointer +} } +// 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/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr b/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr new file mode 100644 index 000000000..6e110dbdd --- /dev/null +++ b/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr @@ -0,0 +1,26 @@ +error[E0080]: evaluation of constant value failed + --> $DIR/mut_ref_in_final_dynamic_check.rs:13:10 + | +LL | Some(&mut *(42 as *mut i32)) + | ^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: 0x2a[noalloc] is a dangling pointer (it has no provenance) + | +note: inside `helper` + --> $DIR/mut_ref_in_final_dynamic_check.rs:13:10 + | +LL | Some(&mut *(42 as *mut i32)) + | ^^^^^^^^^^^^^^^^^^^^^^ +note: inside `A` + --> $DIR/mut_ref_in_final_dynamic_check.rs:18:29 + | +LL | const A: Option<&mut i32> = helper(); + | ^^^^^^^^ + +error: encountered dangling pointer in final constant + --> $DIR/mut_ref_in_final_dynamic_check.rs:25:1 + | +LL | const B: Option<&mut i32> = helper2(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0080`. -- cgit v1.2.3