about summary refs log tree commit diff
path: root/src/test/ui
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/ui')
-rw-r--r--src/test/ui/consts/const-mut-refs/mut_ref_in_final.rs45
-rw-r--r--src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr57
-rw-r--r--src/test/ui/consts/const-mut-refs/mut_ref_in_final_ok.rs22
-rw-r--r--src/test/ui/consts/const-mut-refs/mut_ref_in_final_ok.stderr13
4 files changed, 99 insertions, 38 deletions
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 98960ec6c6e..b2230697037 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,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);
+    }
 }
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 57bf5f7395d..389b88955ce 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,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`
+
+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
 
-For more information about this error, try `rustc --explain E0764`.
+Some errors have detailed explanations: E0716, E0764.
+For more information about an error, try `rustc --explain E0716`.
diff --git a/src/test/ui/consts/const-mut-refs/mut_ref_in_final_ok.rs b/src/test/ui/consts/const-mut-refs/mut_ref_in_final_ok.rs
deleted file mode 100644
index 3f2995df2d7..00000000000
--- a/src/test/ui/consts/const-mut-refs/mut_ref_in_final_ok.rs
+++ /dev/null
@@ -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);
-    }
-}
diff --git a/src/test/ui/consts/const-mut-refs/mut_ref_in_final_ok.stderr b/src/test/ui/consts/const-mut-refs/mut_ref_in_final_ok.stderr
deleted file mode 100644
index 8b51e44e169..00000000000
--- a/src/test/ui/consts/const-mut-refs/mut_ref_in_final_ok.stderr
+++ /dev/null
@@ -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`.