summaryrefslogtreecommitdiffstats
path: root/src/test/ui/statics
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /src/test/ui/statics
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/test/ui/statics')
-rw-r--r--src/test/ui/statics/auxiliary/static-function-pointer-aux.rs4
-rw-r--r--src/test/ui/statics/auxiliary/static-methods-crate.rs29
-rw-r--r--src/test/ui/statics/auxiliary/static_fn_inline_xc_aux.rs12
-rw-r--r--src/test/ui/statics/auxiliary/static_fn_trait_xc_aux.rs11
-rw-r--r--src/test/ui/statics/auxiliary/static_mut_xc.rs1
-rw-r--r--src/test/ui/statics/issue-14227.mir.stderr11
-rw-r--r--src/test/ui/statics/issue-14227.rs10
-rw-r--r--src/test/ui/statics/issue-14227.thir.stderr11
-rw-r--r--src/test/ui/statics/issue-15261.rs11
-rw-r--r--src/test/ui/statics/issue-17233.rs17
-rw-r--r--src/test/ui/statics/issue-44373-2.rs11
-rw-r--r--src/test/ui/statics/issue-44373.rs5
-rw-r--r--src/test/ui/statics/issue-44373.stderr13
-rw-r--r--src/test/ui/statics/issue-91050-1.rs34
-rw-r--r--src/test/ui/statics/issue-91050-2.rs24
-rw-r--r--src/test/ui/statics/static-fn-inline-xc.rs12
-rw-r--r--src/test/ui/statics/static-fn-trait-xc.rs12
-rw-r--r--src/test/ui/statics/static-function-pointer-xc.rs17
-rw-r--r--src/test/ui/statics/static-function-pointer.rs16
-rw-r--r--src/test/ui/statics/static-impl.rs66
-rw-r--r--src/test/ui/statics/static-method-in-trait-with-tps-intracrate.rs28
-rw-r--r--src/test/ui/statics/static-method-xcrate.rs13
-rw-r--r--src/test/ui/statics/static-methods-in-traits.rs26
-rw-r--r--src/test/ui/statics/static-methods-in-traits2.rs22
-rw-r--r--src/test/ui/statics/static-mut-xc.rs39
-rw-r--r--src/test/ui/statics/static-promotion.rs34
-rw-r--r--src/test/ui/statics/static-recursive.rs36
-rw-r--r--src/test/ui/statics/uninhabited-static.rs21
-rw-r--r--src/test/ui/statics/uninhabited-static.stderr83
29 files changed, 629 insertions, 0 deletions
diff --git a/src/test/ui/statics/auxiliary/static-function-pointer-aux.rs b/src/test/ui/statics/auxiliary/static-function-pointer-aux.rs
new file mode 100644
index 000000000..4dfc25764
--- /dev/null
+++ b/src/test/ui/statics/auxiliary/static-function-pointer-aux.rs
@@ -0,0 +1,4 @@
+pub fn f(x: isize) -> isize { -x }
+
+pub static F: fn(isize) -> isize = f;
+pub static mut MutF: fn(isize) -> isize = f;
diff --git a/src/test/ui/statics/auxiliary/static-methods-crate.rs b/src/test/ui/statics/auxiliary/static-methods-crate.rs
new file mode 100644
index 000000000..7ff3bc0dd
--- /dev/null
+++ b/src/test/ui/statics/auxiliary/static-methods-crate.rs
@@ -0,0 +1,29 @@
+#![crate_name="static_methods_crate"]
+#![crate_type = "lib"]
+
+pub trait read: Sized {
+ fn readMaybe(s: String) -> Option<Self>;
+}
+
+impl read for isize {
+ fn readMaybe(s: String) -> Option<isize> {
+ s.parse().ok()
+ }
+}
+
+impl read for bool {
+ fn readMaybe(s: String) -> Option<bool> {
+ match &*s {
+ "true" => Some(true),
+ "false" => Some(false),
+ _ => None
+ }
+ }
+}
+
+pub fn read<T:read>(s: String) -> T {
+ match read::readMaybe(s) {
+ Some(x) => x,
+ _ => panic!("read panicked!")
+ }
+}
diff --git a/src/test/ui/statics/auxiliary/static_fn_inline_xc_aux.rs b/src/test/ui/statics/auxiliary/static_fn_inline_xc_aux.rs
new file mode 100644
index 000000000..8d0f7f61c
--- /dev/null
+++ b/src/test/ui/statics/auxiliary/static_fn_inline_xc_aux.rs
@@ -0,0 +1,12 @@
+pub mod num {
+ pub trait Num2 {
+ fn from_int2(n: isize) -> Self;
+ }
+}
+
+pub mod f64 {
+ impl ::num::Num2 for f64 {
+ #[inline]
+ fn from_int2(n: isize) -> f64 { return n as f64; }
+ }
+}
diff --git a/src/test/ui/statics/auxiliary/static_fn_trait_xc_aux.rs b/src/test/ui/statics/auxiliary/static_fn_trait_xc_aux.rs
new file mode 100644
index 000000000..b8aed2c5f
--- /dev/null
+++ b/src/test/ui/statics/auxiliary/static_fn_trait_xc_aux.rs
@@ -0,0 +1,11 @@
+pub mod num {
+ pub trait Num2 {
+ fn from_int2(n: isize) -> Self;
+ }
+}
+
+pub mod f64 {
+ impl ::num::Num2 for f64 {
+ fn from_int2(n: isize) -> f64 { return n as f64; }
+ }
+}
diff --git a/src/test/ui/statics/auxiliary/static_mut_xc.rs b/src/test/ui/statics/auxiliary/static_mut_xc.rs
new file mode 100644
index 000000000..264a2243a
--- /dev/null
+++ b/src/test/ui/statics/auxiliary/static_mut_xc.rs
@@ -0,0 +1 @@
+pub static mut a: isize = 3;
diff --git a/src/test/ui/statics/issue-14227.mir.stderr b/src/test/ui/statics/issue-14227.mir.stderr
new file mode 100644
index 000000000..8e7a2514d
--- /dev/null
+++ b/src/test/ui/statics/issue-14227.mir.stderr
@@ -0,0 +1,11 @@
+error[E0133]: use of extern static is unsafe and requires unsafe function or block
+ --> $DIR/issue-14227.rs:7:21
+ |
+LL | static CRASH: u32 = symbol;
+ | ^^^^^^ use of extern static
+ |
+ = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/statics/issue-14227.rs b/src/test/ui/statics/issue-14227.rs
new file mode 100644
index 000000000..5f866ec90
--- /dev/null
+++ b/src/test/ui/statics/issue-14227.rs
@@ -0,0 +1,10 @@
+// revisions: mir thir
+// [thir]compile-flags: -Z thir-unsafeck
+
+extern "C" {
+ pub static symbol: u32;
+}
+static CRASH: u32 = symbol;
+//~^ ERROR use of extern static is unsafe and requires
+
+fn main() {}
diff --git a/src/test/ui/statics/issue-14227.thir.stderr b/src/test/ui/statics/issue-14227.thir.stderr
new file mode 100644
index 000000000..8e7a2514d
--- /dev/null
+++ b/src/test/ui/statics/issue-14227.thir.stderr
@@ -0,0 +1,11 @@
+error[E0133]: use of extern static is unsafe and requires unsafe function or block
+ --> $DIR/issue-14227.rs:7:21
+ |
+LL | static CRASH: u32 = symbol;
+ | ^^^^^^ use of extern static
+ |
+ = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/statics/issue-15261.rs b/src/test/ui/statics/issue-15261.rs
new file mode 100644
index 000000000..ec413f6d1
--- /dev/null
+++ b/src/test/ui/statics/issue-15261.rs
@@ -0,0 +1,11 @@
+// build-pass
+#![allow(dead_code)]
+#![allow(non_upper_case_globals)]
+
+// pretty-expanded FIXME #23616
+
+static mut n_mut: usize = 0;
+
+static n: &'static usize = unsafe{ &n_mut };
+
+fn main() {}
diff --git a/src/test/ui/statics/issue-17233.rs b/src/test/ui/statics/issue-17233.rs
new file mode 100644
index 000000000..54a12fdf8
--- /dev/null
+++ b/src/test/ui/statics/issue-17233.rs
@@ -0,0 +1,17 @@
+// run-pass
+
+const X1: &'static [u8] = &[b'1'];
+const X2: &'static [u8] = b"1";
+const X3: &'static [u8; 1] = &[b'1'];
+const X4: &'static [u8; 1] = b"1";
+
+static Y1: u8 = X1[0];
+static Y2: u8 = X2[0];
+static Y3: u8 = X3[0];
+static Y4: u8 = X4[0];
+
+fn main() {
+ assert_eq!(Y1, Y2);
+ assert_eq!(Y1, Y3);
+ assert_eq!(Y1, Y4);
+}
diff --git a/src/test/ui/statics/issue-44373-2.rs b/src/test/ui/statics/issue-44373-2.rs
new file mode 100644
index 000000000..194ce1dca
--- /dev/null
+++ b/src/test/ui/statics/issue-44373-2.rs
@@ -0,0 +1,11 @@
+// check-pass
+#![allow(dead_code)]
+
+struct Foo(bool);
+
+struct Container(&'static [&'static Foo]);
+
+static FOO: Foo = Foo(true);
+static CONTAINER: Container = Container(&[&FOO]);
+
+fn main() {}
diff --git a/src/test/ui/statics/issue-44373.rs b/src/test/ui/statics/issue-44373.rs
new file mode 100644
index 000000000..0d011d096
--- /dev/null
+++ b/src/test/ui/statics/issue-44373.rs
@@ -0,0 +1,5 @@
+static FOO: u32 = 50;
+
+fn main() {
+ let _val: &'static [&'static u32] = &[&FOO]; //~ ERROR temporary value dropped while borrowed
+}
diff --git a/src/test/ui/statics/issue-44373.stderr b/src/test/ui/statics/issue-44373.stderr
new file mode 100644
index 000000000..6f92fbb1e
--- /dev/null
+++ b/src/test/ui/statics/issue-44373.stderr
@@ -0,0 +1,13 @@
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/issue-44373.rs:4:42
+ |
+LL | let _val: &'static [&'static u32] = &[&FOO];
+ | ----------------------- ^^^^^^ creates a temporary which is freed while still in use
+ | |
+ | type annotation requires that borrow lasts for `'static`
+LL | }
+ | - temporary value is freed at the end of this statement
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0716`.
diff --git a/src/test/ui/statics/issue-91050-1.rs b/src/test/ui/statics/issue-91050-1.rs
new file mode 100644
index 000000000..403a41462
--- /dev/null
+++ b/src/test/ui/statics/issue-91050-1.rs
@@ -0,0 +1,34 @@
+// build-pass
+// compile-flags: --crate-type=rlib --emit=llvm-ir -Cno-prepopulate-passes
+
+// This test declares globals by the same name with different types, which
+// caused problems because Module::getOrInsertGlobal would return a Constant*
+// bitcast instead of a GlobalVariable* that could access linkage/visibility.
+// In alt builds with LLVM assertions this would fail:
+//
+// rustc: /checkout/src/llvm-project/llvm/include/llvm/Support/Casting.h:269:
+// typename cast_retty<X, Y *>::ret_type llvm::cast(Y *) [X = llvm::GlobalValue, Y = llvm::Value]:
+// Assertion `isa<X>(Val) && "cast<Ty>() argument of incompatible type!"' failed.
+//
+// In regular builds, the bad cast was UB, like "Invalid LLVMRustVisibility value!"
+
+pub mod before {
+ #[no_mangle]
+ pub static GLOBAL1: [u8; 1] = [1];
+}
+
+pub mod inner {
+ extern "C" {
+ pub static GLOBAL1: u8;
+ pub static GLOBAL2: u8;
+ }
+
+ pub fn call() {
+ drop(unsafe { (GLOBAL1, GLOBAL2) });
+ }
+}
+
+pub mod after {
+ #[no_mangle]
+ pub static GLOBAL2: [u8; 1] = [2];
+}
diff --git a/src/test/ui/statics/issue-91050-2.rs b/src/test/ui/statics/issue-91050-2.rs
new file mode 100644
index 000000000..2ff954d15
--- /dev/null
+++ b/src/test/ui/statics/issue-91050-2.rs
@@ -0,0 +1,24 @@
+// build-pass
+// compile-flags: --crate-type=rlib --emit=llvm-ir -Cno-prepopulate-passes
+
+// This is a variant of issue-91050-1.rs -- see there for an explanation.
+
+pub mod before {
+ extern "C" {
+ pub static GLOBAL1: [u8; 1];
+ }
+
+ pub unsafe fn do_something_with_array() -> u8 {
+ GLOBAL1[0]
+ }
+}
+
+pub mod inner {
+ extern "C" {
+ pub static GLOBAL1: u8;
+ }
+
+ pub unsafe fn call() -> u8 {
+ GLOBAL1 + 42
+ }
+}
diff --git a/src/test/ui/statics/static-fn-inline-xc.rs b/src/test/ui/statics/static-fn-inline-xc.rs
new file mode 100644
index 000000000..a400b9c8d
--- /dev/null
+++ b/src/test/ui/statics/static-fn-inline-xc.rs
@@ -0,0 +1,12 @@
+// run-pass
+// aux-build:static_fn_inline_xc_aux.rs
+
+// pretty-expanded FIXME #23616
+
+extern crate static_fn_inline_xc_aux as mycore;
+
+use mycore::num;
+
+pub fn main() {
+ let _1: f64 = num::Num2::from_int2(1);
+}
diff --git a/src/test/ui/statics/static-fn-trait-xc.rs b/src/test/ui/statics/static-fn-trait-xc.rs
new file mode 100644
index 000000000..1d3126128
--- /dev/null
+++ b/src/test/ui/statics/static-fn-trait-xc.rs
@@ -0,0 +1,12 @@
+// run-pass
+// aux-build:static_fn_trait_xc_aux.rs
+
+// pretty-expanded FIXME #23616
+
+extern crate static_fn_trait_xc_aux as mycore;
+
+use mycore::num;
+
+pub fn main() {
+ let _1: f64 = num::Num2::from_int2(1);
+}
diff --git a/src/test/ui/statics/static-function-pointer-xc.rs b/src/test/ui/statics/static-function-pointer-xc.rs
new file mode 100644
index 000000000..2d063a751
--- /dev/null
+++ b/src/test/ui/statics/static-function-pointer-xc.rs
@@ -0,0 +1,17 @@
+// run-pass
+// aux-build:static-function-pointer-aux.rs
+
+extern crate static_function_pointer_aux as aux;
+
+fn f(x: isize) -> isize { x }
+
+pub fn main() {
+ assert_eq!(aux::F(42), -42);
+ unsafe {
+ assert_eq!(aux::MutF(42), -42);
+ aux::MutF = f;
+ assert_eq!(aux::MutF(42), 42);
+ aux::MutF = aux::f;
+ assert_eq!(aux::MutF(42), -42);
+ }
+}
diff --git a/src/test/ui/statics/static-function-pointer.rs b/src/test/ui/statics/static-function-pointer.rs
new file mode 100644
index 000000000..6c52dfecd
--- /dev/null
+++ b/src/test/ui/statics/static-function-pointer.rs
@@ -0,0 +1,16 @@
+// run-pass
+
+fn f(x: isize) -> isize { x }
+fn g(x: isize) -> isize { 2 * x }
+
+static F: fn(isize) -> isize = f;
+static mut G: fn(isize) -> isize = f;
+
+pub fn main() {
+ assert_eq!(F(42), 42);
+ unsafe {
+ assert_eq!(G(42), 42);
+ G = g;
+ assert_eq!(G(42), 84);
+ }
+}
diff --git a/src/test/ui/statics/static-impl.rs b/src/test/ui/statics/static-impl.rs
new file mode 100644
index 000000000..e7bdb38ee
--- /dev/null
+++ b/src/test/ui/statics/static-impl.rs
@@ -0,0 +1,66 @@
+// run-pass
+#![allow(non_camel_case_types)]
+
+
+
+
+pub trait plus {
+ fn plus(&self) -> isize;
+}
+
+mod a {
+ use plus;
+ impl plus for usize { fn plus(&self) -> isize { *self as isize + 20 } }
+}
+
+mod b {
+ use plus;
+ impl plus for String { fn plus(&self) -> isize { 200 } }
+}
+
+trait uint_utils {
+ fn str(&self) -> String;
+ fn multi<F>(&self, f: F) where F: FnMut(usize);
+}
+
+impl uint_utils for usize {
+ fn str(&self) -> String {
+ self.to_string()
+ }
+ fn multi<F>(&self, mut f: F) where F: FnMut(usize) {
+ let mut c = 0_usize;
+ while c < *self { f(c); c += 1_usize; }
+ }
+}
+
+trait vec_utils<T> {
+ fn length_(&self, ) -> usize;
+ fn iter_<F>(&self, f: F) where F: FnMut(&T);
+ fn map_<U, F>(&self, f: F) -> Vec<U> where F: FnMut(&T) -> U;
+}
+
+impl<T> vec_utils<T> for Vec<T> {
+ fn length_(&self) -> usize { self.len() }
+ fn iter_<F>(&self, mut f: F) where F: FnMut(&T) { for x in self { f(x); } }
+ fn map_<U, F>(&self, mut f: F) -> Vec<U> where F: FnMut(&T) -> U {
+ let mut r = Vec::new();
+ for elt in self {
+ r.push(f(elt));
+ }
+ r
+ }
+}
+
+pub fn main() {
+ assert_eq!(10_usize.plus(), 30);
+ assert_eq!(("hi".to_string()).plus(), 200);
+
+ assert_eq!((vec![1]).length_().str(), "1".to_string());
+ let vect = vec![3, 4].map_(|a| *a + 4);
+ assert_eq!(vect[0], 7);
+ let vect = (vec![3, 4]).map_::<usize, _>(|a| *a as usize + 4_usize);
+ assert_eq!(vect[0], 7_usize);
+ let mut x = 0_usize;
+ 10_usize.multi(|_n| x += 2_usize );
+ assert_eq!(x, 20_usize);
+}
diff --git a/src/test/ui/statics/static-method-in-trait-with-tps-intracrate.rs b/src/test/ui/statics/static-method-in-trait-with-tps-intracrate.rs
new file mode 100644
index 000000000..cd3ccfee0
--- /dev/null
+++ b/src/test/ui/statics/static-method-in-trait-with-tps-intracrate.rs
@@ -0,0 +1,28 @@
+// run-pass
+#![allow(dead_code)]
+
+trait Deserializer {
+ fn read_int(&self) -> isize;
+}
+
+trait Deserializable<D:Deserializer> {
+ fn deserialize(d: &D) -> Self;
+}
+
+impl<D:Deserializer> Deserializable<D> for isize {
+ fn deserialize(d: &D) -> isize {
+ return d.read_int();
+ }
+}
+
+struct FromThinAir { dummy: () }
+
+impl Deserializer for FromThinAir {
+ fn read_int(&self) -> isize { 22 }
+}
+
+pub fn main() {
+ let d = FromThinAir { dummy: () };
+ let i: isize = Deserializable::deserialize(&d);
+ assert_eq!(i, 22);
+}
diff --git a/src/test/ui/statics/static-method-xcrate.rs b/src/test/ui/statics/static-method-xcrate.rs
new file mode 100644
index 000000000..1d1cb3810
--- /dev/null
+++ b/src/test/ui/statics/static-method-xcrate.rs
@@ -0,0 +1,13 @@
+// run-pass
+// aux-build:static-methods-crate.rs
+
+extern crate static_methods_crate;
+
+use static_methods_crate::read;
+
+pub fn main() {
+ let result: isize = read("5".to_string());
+ assert_eq!(result, 5);
+ assert_eq!(read::readMaybe("false".to_string()), Some(false));
+ assert_eq!(read::readMaybe("foo".to_string()), None::<bool>);
+}
diff --git a/src/test/ui/statics/static-methods-in-traits.rs b/src/test/ui/statics/static-methods-in-traits.rs
new file mode 100644
index 000000000..ff76d4e4a
--- /dev/null
+++ b/src/test/ui/statics/static-methods-in-traits.rs
@@ -0,0 +1,26 @@
+// run-pass
+
+mod a {
+ pub trait Foo {
+ fn foo() -> Self;
+ }
+
+ impl Foo for isize {
+ fn foo() -> isize {
+ 3
+ }
+ }
+
+ impl Foo for usize {
+ fn foo() -> usize {
+ 5
+ }
+ }
+}
+
+pub fn main() {
+ let x: isize = a::Foo::foo();
+ let y: usize = a::Foo::foo();
+ assert_eq!(x, 3);
+ assert_eq!(y, 5);
+}
diff --git a/src/test/ui/statics/static-methods-in-traits2.rs b/src/test/ui/statics/static-methods-in-traits2.rs
new file mode 100644
index 000000000..2c43ff6a7
--- /dev/null
+++ b/src/test/ui/statics/static-methods-in-traits2.rs
@@ -0,0 +1,22 @@
+// run-pass
+// pretty-expanded FIXME #23616
+
+pub trait Number: NumConv {
+ fn from<T:Number>(n: T) -> Self;
+}
+
+impl Number for f64 {
+ fn from<T:Number>(n: T) -> f64 { n.to_float() }
+}
+
+pub trait NumConv {
+ fn to_float(&self) -> f64;
+}
+
+impl NumConv for f64 {
+ fn to_float(&self) -> f64 { *self }
+}
+
+pub fn main() {
+ let _: f64 = Number::from(0.0f64);
+}
diff --git a/src/test/ui/statics/static-mut-xc.rs b/src/test/ui/statics/static-mut-xc.rs
new file mode 100644
index 000000000..1d172d26a
--- /dev/null
+++ b/src/test/ui/statics/static-mut-xc.rs
@@ -0,0 +1,39 @@
+// run-pass
+#![allow(non_upper_case_globals)]
+
+// Constants (static variables) can be used to match in patterns, but mutable
+// statics cannot. This ensures that there's some form of error if this is
+// attempted.
+
+// aux-build:static_mut_xc.rs
+
+
+extern crate static_mut_xc;
+
+unsafe fn static_bound(_: &'static isize) {}
+
+fn static_bound_set(a: &'static mut isize) {
+ *a = 3;
+}
+
+unsafe fn run() {
+ assert_eq!(static_mut_xc::a, 3);
+ static_mut_xc::a = 4;
+ assert_eq!(static_mut_xc::a, 4);
+ static_mut_xc::a += 1;
+ assert_eq!(static_mut_xc::a, 5);
+ static_mut_xc::a *= 3;
+ assert_eq!(static_mut_xc::a, 15);
+ static_mut_xc::a = -3;
+ assert_eq!(static_mut_xc::a, -3);
+ static_bound(&static_mut_xc::a);
+ static_bound_set(&mut static_mut_xc::a);
+}
+
+pub fn main() {
+ unsafe { run() }
+}
+
+pub mod inner {
+ pub static mut a: isize = 4;
+}
diff --git a/src/test/ui/statics/static-promotion.rs b/src/test/ui/statics/static-promotion.rs
new file mode 100644
index 000000000..b9eff4691
--- /dev/null
+++ b/src/test/ui/statics/static-promotion.rs
@@ -0,0 +1,34 @@
+// run-pass
+
+// Use of global static variables in literal values should be allowed for
+// promotion.
+// This test is to demonstrate the issue raised in
+// https://github.com/rust-lang/rust/issues/70584
+
+// Literal values were previously promoted into local static values when
+// other global static variables are used.
+
+struct A<T: 'static>(&'static T);
+struct B<T: 'static + ?Sized> {
+ x: &'static T,
+}
+static STR: &'static [u8] = b"hi";
+static C: A<B<B<[u8]>>> = {
+ A(&B {
+ x: &B { x: STR },
+ })
+};
+
+pub struct Slice(&'static [i32]);
+
+static CONTENT: i32 = 42;
+pub static CONTENT_MAP: Slice = Slice(&[CONTENT]);
+
+pub static FOO: (i32, i32) = (42, 43);
+pub static CONTENT_MAP2: Slice = Slice(&[FOO.0]);
+
+fn main() {
+ assert_eq!(b"hi", C.0.x.x);
+ assert_eq!(&[42], CONTENT_MAP.0);
+ assert_eq!(&[42], CONTENT_MAP2.0);
+}
diff --git a/src/test/ui/statics/static-recursive.rs b/src/test/ui/statics/static-recursive.rs
new file mode 100644
index 000000000..95dadc81f
--- /dev/null
+++ b/src/test/ui/statics/static-recursive.rs
@@ -0,0 +1,36 @@
+// run-pass
+static mut S: *const u8 = unsafe { &S as *const *const u8 as *const u8 };
+
+struct StaticDoubleLinked {
+ prev: &'static StaticDoubleLinked,
+ next: &'static StaticDoubleLinked,
+ data: i32,
+ head: bool
+}
+
+static L1: StaticDoubleLinked = StaticDoubleLinked{prev: &L3, next: &L2, data: 1, head: true};
+static L2: StaticDoubleLinked = StaticDoubleLinked{prev: &L1, next: &L3, data: 2, head: false};
+static L3: StaticDoubleLinked = StaticDoubleLinked{prev: &L2, next: &L1, data: 3, head: false};
+
+
+pub fn main() {
+ unsafe { assert_eq!(S, *(S as *const *const u8)); }
+
+ let mut test_vec = Vec::new();
+ let mut cur = &L1;
+ loop {
+ test_vec.push(cur.data);
+ cur = cur.next;
+ if cur.head { break }
+ }
+ assert_eq!(&test_vec, &[1,2,3]);
+
+ let mut test_vec = Vec::new();
+ let mut cur = &L1;
+ loop {
+ cur = cur.prev;
+ test_vec.push(cur.data);
+ if cur.head { break }
+ }
+ assert_eq!(&test_vec, &[3,2,1]);
+}
diff --git a/src/test/ui/statics/uninhabited-static.rs b/src/test/ui/statics/uninhabited-static.rs
new file mode 100644
index 000000000..f5c6f4443
--- /dev/null
+++ b/src/test/ui/statics/uninhabited-static.rs
@@ -0,0 +1,21 @@
+#![feature(never_type)]
+#![deny(uninhabited_static)]
+
+enum Void {}
+extern {
+ static VOID: Void; //~ ERROR static of uninhabited type
+ //~| WARN: previously accepted
+ static NEVER: !; //~ ERROR static of uninhabited type
+ //~| WARN: previously accepted
+}
+
+static VOID2: Void = unsafe { std::mem::transmute(()) }; //~ ERROR static of uninhabited type
+//~| WARN: previously accepted
+//~| ERROR could not evaluate static initializer
+//~| WARN: type `Void` does not permit zero-initialization
+static NEVER2: Void = unsafe { std::mem::transmute(()) }; //~ ERROR static of uninhabited type
+//~| WARN: previously accepted
+//~| ERROR could not evaluate static initializer
+//~| WARN: type `Void` does not permit zero-initialization
+
+fn main() {}
diff --git a/src/test/ui/statics/uninhabited-static.stderr b/src/test/ui/statics/uninhabited-static.stderr
new file mode 100644
index 000000000..88ee4cbdc
--- /dev/null
+++ b/src/test/ui/statics/uninhabited-static.stderr
@@ -0,0 +1,83 @@
+error: static of uninhabited type
+ --> $DIR/uninhabited-static.rs:6:5
+ |
+LL | static VOID: Void;
+ | ^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/uninhabited-static.rs:2:9
+ |
+LL | #![deny(uninhabited_static)]
+ | ^^^^^^^^^^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #74840 <https://github.com/rust-lang/rust/issues/74840>
+ = note: uninhabited statics cannot be initialized, and any access would be an immediate error
+
+error: static of uninhabited type
+ --> $DIR/uninhabited-static.rs:8:5
+ |
+LL | static NEVER: !;
+ | ^^^^^^^^^^^^^^^
+ |
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #74840 <https://github.com/rust-lang/rust/issues/74840>
+ = note: uninhabited statics cannot be initialized, and any access would be an immediate error
+
+error: static of uninhabited type
+ --> $DIR/uninhabited-static.rs:12:1
+ |
+LL | static VOID2: Void = unsafe { std::mem::transmute(()) };
+ | ^^^^^^^^^^^^^^^^^^
+ |
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #74840 <https://github.com/rust-lang/rust/issues/74840>
+ = note: uninhabited statics cannot be initialized, and any access would be an immediate error
+
+error: static of uninhabited type
+ --> $DIR/uninhabited-static.rs:16:1
+ |
+LL | static NEVER2: Void = unsafe { std::mem::transmute(()) };
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #74840 <https://github.com/rust-lang/rust/issues/74840>
+ = note: uninhabited statics cannot be initialized, and any access would be an immediate error
+
+error[E0080]: could not evaluate static initializer
+ --> $DIR/uninhabited-static.rs:12:31
+ |
+LL | static VOID2: Void = unsafe { std::mem::transmute(()) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type
+
+warning: the type `Void` does not permit zero-initialization
+ --> $DIR/uninhabited-static.rs:12:31
+ |
+LL | static VOID2: Void = unsafe { std::mem::transmute(()) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: `#[warn(invalid_value)]` on by default
+ = note: enums with no variants have no valid value
+
+error[E0080]: could not evaluate static initializer
+ --> $DIR/uninhabited-static.rs:16:32
+ |
+LL | static NEVER2: Void = unsafe { std::mem::transmute(()) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type
+
+warning: the type `Void` does not permit zero-initialization
+ --> $DIR/uninhabited-static.rs:16:32
+ |
+LL | static NEVER2: Void = unsafe { std::mem::transmute(()) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: enums with no variants have no valid value
+
+error: aborting due to 6 previous errors; 2 warnings emitted
+
+For more information about this error, try `rustc --explain E0080`.