summaryrefslogtreecommitdiffstats
path: root/src/test/ui/static
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/test/ui/static/auxiliary/extern-statics.rs4
-rw-r--r--src/test/ui/static/auxiliary/issue_24843.rs1
-rw-r--r--src/test/ui/static/auxiliary/nested_item.rs30
-rw-r--r--src/test/ui/static/auxiliary/static-priv-by-default.rs27
-rw-r--r--src/test/ui/static/auxiliary/static_priv_by_default.rs51
-rw-r--r--src/test/ui/static/bad-const-type.rs4
-rw-r--r--src/test/ui/static/bad-const-type.stderr11
-rw-r--r--src/test/ui/static/issue-24843.rs8
-rw-r--r--src/test/ui/static/issue-34194.rs11
-rw-r--r--src/test/ui/static/nested_item_main.rs10
-rw-r--r--src/test/ui/static/refer-to-other-statics-by-value.rs8
-rw-r--r--src/test/ui/static/safe-extern-statics-mut.mir.stderr35
-rw-r--r--src/test/ui/static/safe-extern-statics-mut.rs17
-rw-r--r--src/test/ui/static/safe-extern-statics-mut.thir.stderr35
-rw-r--r--src/test/ui/static/safe-extern-statics.mir.stderr35
-rw-r--r--src/test/ui/static/safe-extern-statics.rs17
-rw-r--r--src/test/ui/static/safe-extern-statics.thir.stderr35
-rw-r--r--src/test/ui/static/static-closures.rs4
-rw-r--r--src/test/ui/static/static-closures.stderr9
-rw-r--r--src/test/ui/static/static-drop-scope.rs37
-rw-r--r--src/test/ui/static/static-drop-scope.stderr89
-rw-r--r--src/test/ui/static/static-extern-type.rs27
-rw-r--r--src/test/ui/static/static-items-cant-move.rs19
-rw-r--r--src/test/ui/static/static-items-cant-move.stderr9
-rw-r--r--src/test/ui/static/static-lifetime-bound.rs6
-rw-r--r--src/test/ui/static/static-lifetime-bound.stderr22
-rw-r--r--src/test/ui/static/static-lifetime.rs6
-rw-r--r--src/test/ui/static/static-lifetime.stderr16
-rw-r--r--src/test/ui/static/static-method-privacy.rs10
-rw-r--r--src/test/ui/static/static-method-privacy.stderr12
-rw-r--r--src/test/ui/static/static-mut-bad-types.rs7
-rw-r--r--src/test/ui/static/static-mut-bad-types.stderr12
-rw-r--r--src/test/ui/static/static-mut-foreign-requires-unsafe.mir.stderr27
-rw-r--r--src/test/ui/static/static-mut-foreign-requires-unsafe.rs12
-rw-r--r--src/test/ui/static/static-mut-foreign-requires-unsafe.thir.stderr27
-rw-r--r--src/test/ui/static/static-mut-not-constant.rs6
-rw-r--r--src/test/ui/static/static-mut-not-constant.stderr9
-rw-r--r--src/test/ui/static/static-mut-not-pat.rs43
-rw-r--r--src/test/ui/static/static-mut-not-pat.stderr21
-rw-r--r--src/test/ui/static/static-mut-requires-unsafe.mir.stderr27
-rw-r--r--src/test/ui/static/static-mut-requires-unsafe.rs10
-rw-r--r--src/test/ui/static/static-mut-requires-unsafe.thir.stderr27
-rw-r--r--src/test/ui/static/static-priv-by-default2.rs30
-rw-r--r--src/test/ui/static/static-priv-by-default2.stderr27
-rw-r--r--src/test/ui/static/static-reference-to-fn-1.rs24
-rw-r--r--src/test/ui/static/static-reference-to-fn-1.stderr12
-rw-r--r--src/test/ui/static/static-reference-to-fn-2.rs54
-rw-r--r--src/test/ui/static/static-reference-to-fn-2.stderr49
-rw-r--r--src/test/ui/static/static-region-bound.rs12
-rw-r--r--src/test/ui/static/static-region-bound.stderr13
-rw-r--r--src/test/ui/static/static-vec-repeat-not-constant.rs6
-rw-r--r--src/test/ui/static/static-vec-repeat-not-constant.stderr11
-rw-r--r--src/test/ui/static/static_sized_requirement.rs12
-rw-r--r--src/test/ui/static/thread-local-in-ctfe.rs23
-rw-r--r--src/test/ui/static/thread-local-in-ctfe.stderr33
-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
84 files changed, 1768 insertions, 0 deletions
diff --git a/src/test/ui/static/auxiliary/extern-statics.rs b/src/test/ui/static/auxiliary/extern-statics.rs
new file mode 100644
index 000000000..c090bc79f
--- /dev/null
+++ b/src/test/ui/static/auxiliary/extern-statics.rs
@@ -0,0 +1,4 @@
+extern "C" {
+ pub static XA: u8;
+ pub static mut XB: u8;
+}
diff --git a/src/test/ui/static/auxiliary/issue_24843.rs b/src/test/ui/static/auxiliary/issue_24843.rs
new file mode 100644
index 000000000..6ca04f860
--- /dev/null
+++ b/src/test/ui/static/auxiliary/issue_24843.rs
@@ -0,0 +1 @@
+pub static TEST_STR: &'static str = "Hello world";
diff --git a/src/test/ui/static/auxiliary/nested_item.rs b/src/test/ui/static/auxiliary/nested_item.rs
new file mode 100644
index 000000000..9db9d19d6
--- /dev/null
+++ b/src/test/ui/static/auxiliary/nested_item.rs
@@ -0,0 +1,30 @@
+// original problem
+pub fn foo<T>() -> isize {
+ {
+ static foo: isize = 2;
+ foo
+ }
+}
+
+// issue 8134
+struct Foo;
+impl Foo {
+ pub fn foo<T>(&self) {
+ static X: usize = 1;
+ }
+}
+
+// issue 8134
+pub struct Parser<T>(T);
+impl<T: std::iter::Iterator<Item=char>> Parser<T> {
+ fn in_doctype(&mut self) {
+ static DOCTYPEPattern: [char; 6] = ['O', 'C', 'T', 'Y', 'P', 'E'];
+ }
+}
+
+struct Bar;
+impl Foo {
+ pub fn bar<T>(&self) {
+ static X: usize = 1;
+ }
+}
diff --git a/src/test/ui/static/auxiliary/static-priv-by-default.rs b/src/test/ui/static/auxiliary/static-priv-by-default.rs
new file mode 100644
index 000000000..41f368f46
--- /dev/null
+++ b/src/test/ui/static/auxiliary/static-priv-by-default.rs
@@ -0,0 +1,27 @@
+// aux-build:static_priv_by_default.rs
+
+extern crate static_priv_by_default;
+
+mod child {
+ pub mod childs_child {
+ static private: isize = 0;
+ pub static public: isize = 0;
+ }
+}
+
+fn foo(_: isize) {}
+
+fn full_ref() {
+ foo(static_priv_by_default::private); //~ ERROR: static `private` is private
+ foo(static_priv_by_default::public);
+ foo(child::childs_child::private); //~ ERROR: static `private` is private
+ foo(child::childs_child::public);
+}
+
+fn medium_ref() {
+ use child::childs_child;
+ foo(childs_child::private); //~ ERROR: static `private` is private
+ foo(childs_child::public);
+}
+
+fn main() {}
diff --git a/src/test/ui/static/auxiliary/static_priv_by_default.rs b/src/test/ui/static/auxiliary/static_priv_by_default.rs
new file mode 100644
index 000000000..39f912066
--- /dev/null
+++ b/src/test/ui/static/auxiliary/static_priv_by_default.rs
@@ -0,0 +1,51 @@
+#![crate_type = "lib"]
+
+static private: isize = 0;
+pub static public: isize = 0;
+
+pub struct A(());
+
+impl A {
+ fn foo() {}
+}
+
+mod foo {
+ pub static a: isize = 0;
+ pub fn b() {}
+ pub struct c;
+ pub enum d {}
+ pub type e = isize;
+
+ pub struct A(());
+
+ impl A {
+ fn foo() {}
+ }
+
+ // these are public so the parent can re-export them.
+ pub static reexported_a: isize = 0;
+ pub fn reexported_b() {}
+ pub struct reexported_c;
+ pub enum reexported_d {}
+ pub type reexported_e = isize;
+}
+
+pub mod bar {
+ pub use foo::reexported_a as e;
+ pub use foo::reexported_b as f;
+ pub use foo::reexported_c as g;
+ pub use foo::reexported_d as h;
+ pub use foo::reexported_e as i;
+}
+
+pub static a: isize = 0;
+pub fn b() {}
+pub struct c;
+pub enum d {}
+pub type e = isize;
+
+static j: isize = 0;
+fn k() {}
+struct l;
+enum m {}
+type n = isize;
diff --git a/src/test/ui/static/bad-const-type.rs b/src/test/ui/static/bad-const-type.rs
new file mode 100644
index 000000000..934ee353d
--- /dev/null
+++ b/src/test/ui/static/bad-const-type.rs
@@ -0,0 +1,4 @@
+static i: String = 10;
+//~^ ERROR mismatched types
+//~| expected struct `String`, found integer
+fn main() { println!("{}", i); }
diff --git a/src/test/ui/static/bad-const-type.stderr b/src/test/ui/static/bad-const-type.stderr
new file mode 100644
index 000000000..dcc1ee07c
--- /dev/null
+++ b/src/test/ui/static/bad-const-type.stderr
@@ -0,0 +1,11 @@
+error[E0308]: mismatched types
+ --> $DIR/bad-const-type.rs:1:20
+ |
+LL | static i: String = 10;
+ | ^^- help: try using a conversion method: `.to_string()`
+ | |
+ | expected struct `String`, found integer
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/static/issue-24843.rs b/src/test/ui/static/issue-24843.rs
new file mode 100644
index 000000000..0b3397e21
--- /dev/null
+++ b/src/test/ui/static/issue-24843.rs
@@ -0,0 +1,8 @@
+// aux-build: issue_24843.rs
+// check-pass
+
+extern crate issue_24843;
+
+static _TEST_STR_2: &'static str = &issue_24843::TEST_STR;
+
+fn main() {}
diff --git a/src/test/ui/static/issue-34194.rs b/src/test/ui/static/issue-34194.rs
new file mode 100644
index 000000000..6dce556e9
--- /dev/null
+++ b/src/test/ui/static/issue-34194.rs
@@ -0,0 +1,11 @@
+// build-pass
+#![allow(dead_code)]
+
+struct A {
+ a: &'static (),
+}
+
+static B: &'static A = &A { a: &() };
+static C: &'static A = &B;
+
+fn main() {}
diff --git a/src/test/ui/static/nested_item_main.rs b/src/test/ui/static/nested_item_main.rs
new file mode 100644
index 000000000..2fe00aede
--- /dev/null
+++ b/src/test/ui/static/nested_item_main.rs
@@ -0,0 +1,10 @@
+// run-pass
+// aux-build:nested_item.rs
+
+
+extern crate nested_item;
+
+pub fn main() {
+ assert_eq!(2, nested_item::foo::<()>());
+ assert_eq!(2, nested_item::foo::<isize>());
+}
diff --git a/src/test/ui/static/refer-to-other-statics-by-value.rs b/src/test/ui/static/refer-to-other-statics-by-value.rs
new file mode 100644
index 000000000..90f1980f8
--- /dev/null
+++ b/src/test/ui/static/refer-to-other-statics-by-value.rs
@@ -0,0 +1,8 @@
+// run-pass
+
+static A: usize = 42;
+static B: usize = A;
+
+fn main() {
+ assert_eq!(B, 42);
+}
diff --git a/src/test/ui/static/safe-extern-statics-mut.mir.stderr b/src/test/ui/static/safe-extern-statics-mut.mir.stderr
new file mode 100644
index 000000000..cec5f9d9c
--- /dev/null
+++ b/src/test/ui/static/safe-extern-statics-mut.mir.stderr
@@ -0,0 +1,35 @@
+error[E0133]: use of mutable static is unsafe and requires unsafe function or block
+ --> $DIR/safe-extern-statics-mut.rs:13:13
+ |
+LL | let b = B;
+ | ^ use of mutable static
+ |
+ = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
+
+error[E0133]: use of mutable static is unsafe and requires unsafe function or block
+ --> $DIR/safe-extern-statics-mut.rs:14:14
+ |
+LL | let rb = &B;
+ | ^^ use of mutable static
+ |
+ = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
+
+error[E0133]: use of mutable static is unsafe and requires unsafe function or block
+ --> $DIR/safe-extern-statics-mut.rs:15:14
+ |
+LL | let xb = XB;
+ | ^^ use of mutable static
+ |
+ = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
+
+error[E0133]: use of mutable static is unsafe and requires unsafe function or block
+ --> $DIR/safe-extern-statics-mut.rs:16:15
+ |
+LL | let xrb = &XB;
+ | ^^^ use of mutable static
+ |
+ = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/static/safe-extern-statics-mut.rs b/src/test/ui/static/safe-extern-statics-mut.rs
new file mode 100644
index 000000000..389a4589a
--- /dev/null
+++ b/src/test/ui/static/safe-extern-statics-mut.rs
@@ -0,0 +1,17 @@
+// aux-build:extern-statics.rs
+// revisions: mir thir
+// [thir]compile-flags: -Z thir-unsafeck
+
+extern crate extern_statics;
+use extern_statics::*;
+
+extern "C" {
+ static mut B: u8;
+}
+
+fn main() {
+ let b = B; //~ ERROR use of mutable static is unsafe
+ let rb = &B; //~ ERROR use of mutable static is unsafe
+ let xb = XB; //~ ERROR use of mutable static is unsafe
+ let xrb = &XB; //~ ERROR use of mutable static is unsafe
+}
diff --git a/src/test/ui/static/safe-extern-statics-mut.thir.stderr b/src/test/ui/static/safe-extern-statics-mut.thir.stderr
new file mode 100644
index 000000000..8e6d2805a
--- /dev/null
+++ b/src/test/ui/static/safe-extern-statics-mut.thir.stderr
@@ -0,0 +1,35 @@
+error[E0133]: use of mutable static is unsafe and requires unsafe function or block
+ --> $DIR/safe-extern-statics-mut.rs:13:13
+ |
+LL | let b = B;
+ | ^ use of mutable static
+ |
+ = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
+
+error[E0133]: use of mutable static is unsafe and requires unsafe function or block
+ --> $DIR/safe-extern-statics-mut.rs:14:15
+ |
+LL | let rb = &B;
+ | ^ use of mutable static
+ |
+ = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
+
+error[E0133]: use of mutable static is unsafe and requires unsafe function or block
+ --> $DIR/safe-extern-statics-mut.rs:15:14
+ |
+LL | let xb = XB;
+ | ^^ use of mutable static
+ |
+ = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
+
+error[E0133]: use of mutable static is unsafe and requires unsafe function or block
+ --> $DIR/safe-extern-statics-mut.rs:16:16
+ |
+LL | let xrb = &XB;
+ | ^^ use of mutable static
+ |
+ = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/static/safe-extern-statics.mir.stderr b/src/test/ui/static/safe-extern-statics.mir.stderr
new file mode 100644
index 000000000..102abd081
--- /dev/null
+++ b/src/test/ui/static/safe-extern-statics.mir.stderr
@@ -0,0 +1,35 @@
+error[E0133]: use of extern static is unsafe and requires unsafe function or block
+ --> $DIR/safe-extern-statics.rs:13:13
+ |
+LL | let a = A;
+ | ^ 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[E0133]: use of extern static is unsafe and requires unsafe function or block
+ --> $DIR/safe-extern-statics.rs:14:14
+ |
+LL | let ra = &A;
+ | ^^ 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[E0133]: use of extern static is unsafe and requires unsafe function or block
+ --> $DIR/safe-extern-statics.rs:15:14
+ |
+LL | let xa = XA;
+ | ^^ 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[E0133]: use of extern static is unsafe and requires unsafe function or block
+ --> $DIR/safe-extern-statics.rs:16:15
+ |
+LL | let xra = &XA;
+ | ^^^ 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 4 previous errors
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/static/safe-extern-statics.rs b/src/test/ui/static/safe-extern-statics.rs
new file mode 100644
index 000000000..0aa90c442
--- /dev/null
+++ b/src/test/ui/static/safe-extern-statics.rs
@@ -0,0 +1,17 @@
+// aux-build:extern-statics.rs
+// revisions: mir thir
+// [thir]compile-flags: -Z thir-unsafeck
+
+extern crate extern_statics;
+use extern_statics::*;
+
+extern "C" {
+ static A: u8;
+}
+
+fn main() {
+ let a = A; //~ ERROR use of extern static is unsafe
+ let ra = &A; //~ ERROR use of extern static is unsafe
+ let xa = XA; //~ ERROR use of extern static is unsafe
+ let xra = &XA; //~ ERROR use of extern static is unsafe
+}
diff --git a/src/test/ui/static/safe-extern-statics.thir.stderr b/src/test/ui/static/safe-extern-statics.thir.stderr
new file mode 100644
index 000000000..7fd2182c4
--- /dev/null
+++ b/src/test/ui/static/safe-extern-statics.thir.stderr
@@ -0,0 +1,35 @@
+error[E0133]: use of extern static is unsafe and requires unsafe function or block
+ --> $DIR/safe-extern-statics.rs:13:13
+ |
+LL | let a = A;
+ | ^ 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[E0133]: use of extern static is unsafe and requires unsafe function or block
+ --> $DIR/safe-extern-statics.rs:14:15
+ |
+LL | let ra = &A;
+ | ^ 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[E0133]: use of extern static is unsafe and requires unsafe function or block
+ --> $DIR/safe-extern-statics.rs:15:14
+ |
+LL | let xa = XA;
+ | ^^ 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[E0133]: use of extern static is unsafe and requires unsafe function or block
+ --> $DIR/safe-extern-statics.rs:16:16
+ |
+LL | let xra = &XA;
+ | ^^ 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 4 previous errors
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/static/static-closures.rs b/src/test/ui/static/static-closures.rs
new file mode 100644
index 000000000..1bd518d6f
--- /dev/null
+++ b/src/test/ui/static/static-closures.rs
@@ -0,0 +1,4 @@
+fn main() {
+ static || {};
+ //~^ ERROR closures cannot be static
+}
diff --git a/src/test/ui/static/static-closures.stderr b/src/test/ui/static/static-closures.stderr
new file mode 100644
index 000000000..99235e26e
--- /dev/null
+++ b/src/test/ui/static/static-closures.stderr
@@ -0,0 +1,9 @@
+error[E0697]: closures cannot be static
+ --> $DIR/static-closures.rs:2:5
+ |
+LL | static || {};
+ | ^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0697`.
diff --git a/src/test/ui/static/static-drop-scope.rs b/src/test/ui/static/static-drop-scope.rs
new file mode 100644
index 000000000..e7ea8663d
--- /dev/null
+++ b/src/test/ui/static/static-drop-scope.rs
@@ -0,0 +1,37 @@
+struct WithDtor;
+
+impl Drop for WithDtor {
+ fn drop(&mut self) {}
+}
+
+static PROMOTION_FAIL_S: Option<&'static WithDtor> = Some(&WithDtor);
+//~^ ERROR destructors cannot be evaluated at compile-time
+//~| ERROR temporary value dropped while borrowed
+
+const PROMOTION_FAIL_C: Option<&'static WithDtor> = Some(&WithDtor);
+//~^ ERROR destructors cannot be evaluated at compile-time
+//~| ERROR temporary value dropped while borrowed
+
+static EARLY_DROP_S: i32 = (WithDtor, 0).1;
+//~^ ERROR destructors cannot be evaluated at compile-time
+
+const EARLY_DROP_C: i32 = (WithDtor, 0).1;
+//~^ ERROR destructors cannot be evaluated at compile-time
+
+const fn const_drop<T>(_: T) {}
+//~^ ERROR destructors cannot be evaluated at compile-time
+
+const fn const_drop2<T>(x: T) {
+ (x, ()).1
+ //~^ ERROR destructors cannot be evaluated at compile-time
+}
+
+const EARLY_DROP_C_OPTION: i32 = (Some(WithDtor), 0).1;
+//~^ ERROR destructors cannot be evaluated at compile-time
+
+const HELPER: Option<WithDtor> = Some(WithDtor);
+
+const EARLY_DROP_C_OPTION_CONSTANT: i32 = (HELPER, 0).1;
+//~^ ERROR destructors cannot be evaluated at compile-time
+
+fn main () {}
diff --git a/src/test/ui/static/static-drop-scope.stderr b/src/test/ui/static/static-drop-scope.stderr
new file mode 100644
index 000000000..ac32f217f
--- /dev/null
+++ b/src/test/ui/static/static-drop-scope.stderr
@@ -0,0 +1,89 @@
+error[E0493]: destructors cannot be evaluated at compile-time
+ --> $DIR/static-drop-scope.rs:7:60
+ |
+LL | static PROMOTION_FAIL_S: Option<&'static WithDtor> = Some(&WithDtor);
+ | ^^^^^^^^- value is dropped here
+ | |
+ | statics cannot evaluate destructors
+
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/static-drop-scope.rs:7:60
+ |
+LL | static PROMOTION_FAIL_S: Option<&'static WithDtor> = Some(&WithDtor);
+ | ------^^^^^^^^-
+ | | | |
+ | | | 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[E0493]: destructors cannot be evaluated at compile-time
+ --> $DIR/static-drop-scope.rs:11:59
+ |
+LL | const PROMOTION_FAIL_C: Option<&'static WithDtor> = Some(&WithDtor);
+ | ^^^^^^^^- value is dropped here
+ | |
+ | constants cannot evaluate destructors
+
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/static-drop-scope.rs:11:59
+ |
+LL | const PROMOTION_FAIL_C: Option<&'static WithDtor> = Some(&WithDtor);
+ | ------^^^^^^^^-
+ | | | |
+ | | | 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[E0493]: destructors cannot be evaluated at compile-time
+ --> $DIR/static-drop-scope.rs:15:28
+ |
+LL | static EARLY_DROP_S: i32 = (WithDtor, 0).1;
+ | ^^^^^^^^^^^^^ - value is dropped here
+ | |
+ | statics cannot evaluate destructors
+
+error[E0493]: destructors cannot be evaluated at compile-time
+ --> $DIR/static-drop-scope.rs:18:27
+ |
+LL | const EARLY_DROP_C: i32 = (WithDtor, 0).1;
+ | ^^^^^^^^^^^^^ - value is dropped here
+ | |
+ | constants cannot evaluate destructors
+
+error[E0493]: destructors cannot be evaluated at compile-time
+ --> $DIR/static-drop-scope.rs:21:24
+ |
+LL | const fn const_drop<T>(_: T) {}
+ | ^ - value is dropped here
+ | |
+ | constant functions cannot evaluate destructors
+
+error[E0493]: destructors cannot be evaluated at compile-time
+ --> $DIR/static-drop-scope.rs:25:5
+ |
+LL | (x, ()).1
+ | ^^^^^^^ constant functions cannot evaluate destructors
+LL |
+LL | }
+ | - value is dropped here
+
+error[E0493]: destructors cannot be evaluated at compile-time
+ --> $DIR/static-drop-scope.rs:29:34
+ |
+LL | const EARLY_DROP_C_OPTION: i32 = (Some(WithDtor), 0).1;
+ | ^^^^^^^^^^^^^^^^^^^ - value is dropped here
+ | |
+ | constants cannot evaluate destructors
+
+error[E0493]: destructors cannot be evaluated at compile-time
+ --> $DIR/static-drop-scope.rs:34:43
+ |
+LL | const EARLY_DROP_C_OPTION_CONSTANT: i32 = (HELPER, 0).1;
+ | ^^^^^^^^^^^ - value is dropped here
+ | |
+ | constants cannot evaluate destructors
+
+error: aborting due to 10 previous errors
+
+Some errors have detailed explanations: E0493, E0716.
+For more information about an error, try `rustc --explain E0493`.
diff --git a/src/test/ui/static/static-extern-type.rs b/src/test/ui/static/static-extern-type.rs
new file mode 100644
index 000000000..4fa48fa13
--- /dev/null
+++ b/src/test/ui/static/static-extern-type.rs
@@ -0,0 +1,27 @@
+// build-pass (FIXME(62277): could be check-pass?)
+#![feature(extern_types)]
+
+pub mod a {
+ extern "C" {
+ pub type StartFn;
+ pub static start: StartFn;
+ }
+}
+
+pub mod b {
+ #[repr(transparent)]
+ pub struct TransparentType(::a::StartFn);
+ extern "C" {
+ pub static start: TransparentType;
+ }
+}
+
+pub mod c {
+ #[repr(C)]
+ pub struct CType(u32, ::b::TransparentType);
+ extern "C" {
+ pub static start: CType;
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/static/static-items-cant-move.rs b/src/test/ui/static/static-items-cant-move.rs
new file mode 100644
index 000000000..3e7aaa0b0
--- /dev/null
+++ b/src/test/ui/static/static-items-cant-move.rs
@@ -0,0 +1,19 @@
+// Verifies that static items can't be moved
+
+struct B;
+
+struct Foo {
+ foo: isize,
+ b: B,
+}
+
+static BAR: Foo = Foo { foo: 5, b: B };
+
+
+fn test(f: Foo) {
+ let _f = Foo{foo: 4, ..f};
+}
+
+fn main() {
+ test(BAR); //~ ERROR cannot move out of static item
+}
diff --git a/src/test/ui/static/static-items-cant-move.stderr b/src/test/ui/static/static-items-cant-move.stderr
new file mode 100644
index 000000000..235e9ee9b
--- /dev/null
+++ b/src/test/ui/static/static-items-cant-move.stderr
@@ -0,0 +1,9 @@
+error[E0507]: cannot move out of static item `BAR`
+ --> $DIR/static-items-cant-move.rs:18:10
+ |
+LL | test(BAR);
+ | ^^^ move occurs because `BAR` has type `Foo`, which does not implement the `Copy` trait
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0507`.
diff --git a/src/test/ui/static/static-lifetime-bound.rs b/src/test/ui/static/static-lifetime-bound.rs
new file mode 100644
index 000000000..b5da91ec3
--- /dev/null
+++ b/src/test/ui/static/static-lifetime-bound.rs
@@ -0,0 +1,6 @@
+fn f<'a: 'static>(_: &'a i32) {} //~WARN unnecessary lifetime parameter `'a`
+
+fn main() {
+ let x = 0;
+ f(&x); //~ERROR does not live long enough
+}
diff --git a/src/test/ui/static/static-lifetime-bound.stderr b/src/test/ui/static/static-lifetime-bound.stderr
new file mode 100644
index 000000000..ef07a8931
--- /dev/null
+++ b/src/test/ui/static/static-lifetime-bound.stderr
@@ -0,0 +1,22 @@
+warning: unnecessary lifetime parameter `'a`
+ --> $DIR/static-lifetime-bound.rs:1:6
+ |
+LL | fn f<'a: 'static>(_: &'a i32) {}
+ | ^^
+ |
+ = help: you can use the `'static` lifetime directly, in place of `'a`
+
+error[E0597]: `x` does not live long enough
+ --> $DIR/static-lifetime-bound.rs:5:7
+ |
+LL | f(&x);
+ | --^^-
+ | | |
+ | | borrowed value does not live long enough
+ | argument requires that `x` is borrowed for `'static`
+LL | }
+ | - `x` dropped here while still borrowed
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/static/static-lifetime.rs b/src/test/ui/static/static-lifetime.rs
new file mode 100644
index 000000000..ce1eeb610
--- /dev/null
+++ b/src/test/ui/static/static-lifetime.rs
@@ -0,0 +1,6 @@
+pub trait Arbitrary: Sized + 'static {}
+
+impl<'a, A: Clone> Arbitrary for ::std::borrow::Cow<'a, A> {} //~ ERROR lifetime bound
+
+fn main() {
+}
diff --git a/src/test/ui/static/static-lifetime.stderr b/src/test/ui/static/static-lifetime.stderr
new file mode 100644
index 000000000..4af3370c7
--- /dev/null
+++ b/src/test/ui/static/static-lifetime.stderr
@@ -0,0 +1,16 @@
+error[E0478]: lifetime bound not satisfied
+ --> $DIR/static-lifetime.rs:3:20
+ |
+LL | impl<'a, A: Clone> Arbitrary for ::std::borrow::Cow<'a, A> {}
+ | ^^^^^^^^^
+ |
+note: lifetime parameter instantiated with the lifetime `'a` as defined here
+ --> $DIR/static-lifetime.rs:3:6
+ |
+LL | impl<'a, A: Clone> Arbitrary for ::std::borrow::Cow<'a, A> {}
+ | ^^
+ = note: but lifetime parameter must outlive the static lifetime
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0478`.
diff --git a/src/test/ui/static/static-method-privacy.rs b/src/test/ui/static/static-method-privacy.rs
new file mode 100644
index 000000000..9ee59b320
--- /dev/null
+++ b/src/test/ui/static/static-method-privacy.rs
@@ -0,0 +1,10 @@
+mod a {
+ pub struct S;
+ impl S {
+ fn new() -> S { S }
+ }
+}
+
+fn main() {
+ let _ = a::S::new(); //~ ERROR associated function `new` is private
+}
diff --git a/src/test/ui/static/static-method-privacy.stderr b/src/test/ui/static/static-method-privacy.stderr
new file mode 100644
index 000000000..4be1b22fc
--- /dev/null
+++ b/src/test/ui/static/static-method-privacy.stderr
@@ -0,0 +1,12 @@
+error[E0624]: associated function `new` is private
+ --> $DIR/static-method-privacy.rs:9:19
+ |
+LL | fn new() -> S { S }
+ | ------------- private associated function defined here
+...
+LL | let _ = a::S::new();
+ | ^^^ private associated function
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0624`.
diff --git a/src/test/ui/static/static-mut-bad-types.rs b/src/test/ui/static/static-mut-bad-types.rs
new file mode 100644
index 000000000..8a98b1b7f
--- /dev/null
+++ b/src/test/ui/static/static-mut-bad-types.rs
@@ -0,0 +1,7 @@
+static mut a: isize = 3;
+
+fn main() {
+ unsafe {
+ a = true; //~ ERROR: mismatched types
+ }
+}
diff --git a/src/test/ui/static/static-mut-bad-types.stderr b/src/test/ui/static/static-mut-bad-types.stderr
new file mode 100644
index 000000000..983e1026f
--- /dev/null
+++ b/src/test/ui/static/static-mut-bad-types.stderr
@@ -0,0 +1,12 @@
+error[E0308]: mismatched types
+ --> $DIR/static-mut-bad-types.rs:5:13
+ |
+LL | static mut a: isize = 3;
+ | ----- expected due to this type
+...
+LL | a = true;
+ | ^^^^ expected `isize`, found `bool`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/static/static-mut-foreign-requires-unsafe.mir.stderr b/src/test/ui/static/static-mut-foreign-requires-unsafe.mir.stderr
new file mode 100644
index 000000000..a4659bc87
--- /dev/null
+++ b/src/test/ui/static/static-mut-foreign-requires-unsafe.mir.stderr
@@ -0,0 +1,27 @@
+error[E0133]: use of mutable static is unsafe and requires unsafe function or block
+ --> $DIR/static-mut-foreign-requires-unsafe.rs:9:5
+ |
+LL | a += 3;
+ | ^^^^^^ use of mutable static
+ |
+ = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
+
+error[E0133]: use of mutable static is unsafe and requires unsafe function or block
+ --> $DIR/static-mut-foreign-requires-unsafe.rs:10:5
+ |
+LL | a = 4;
+ | ^^^^^ use of mutable static
+ |
+ = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
+
+error[E0133]: use of mutable static is unsafe and requires unsafe function or block
+ --> $DIR/static-mut-foreign-requires-unsafe.rs:11:14
+ |
+LL | let _b = a;
+ | ^ use of mutable static
+ |
+ = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/static/static-mut-foreign-requires-unsafe.rs b/src/test/ui/static/static-mut-foreign-requires-unsafe.rs
new file mode 100644
index 000000000..4f96acb33
--- /dev/null
+++ b/src/test/ui/static/static-mut-foreign-requires-unsafe.rs
@@ -0,0 +1,12 @@
+// revisions: mir thir
+// [thir]compile-flags: -Z thir-unsafeck
+
+extern "C" {
+ static mut a: i32;
+}
+
+fn main() {
+ a += 3; //~ ERROR: requires unsafe
+ a = 4; //~ ERROR: requires unsafe
+ let _b = a; //~ ERROR: requires unsafe
+}
diff --git a/src/test/ui/static/static-mut-foreign-requires-unsafe.thir.stderr b/src/test/ui/static/static-mut-foreign-requires-unsafe.thir.stderr
new file mode 100644
index 000000000..2c62d4d8f
--- /dev/null
+++ b/src/test/ui/static/static-mut-foreign-requires-unsafe.thir.stderr
@@ -0,0 +1,27 @@
+error[E0133]: use of mutable static is unsafe and requires unsafe function or block
+ --> $DIR/static-mut-foreign-requires-unsafe.rs:9:5
+ |
+LL | a += 3;
+ | ^ use of mutable static
+ |
+ = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
+
+error[E0133]: use of mutable static is unsafe and requires unsafe function or block
+ --> $DIR/static-mut-foreign-requires-unsafe.rs:10:5
+ |
+LL | a = 4;
+ | ^ use of mutable static
+ |
+ = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
+
+error[E0133]: use of mutable static is unsafe and requires unsafe function or block
+ --> $DIR/static-mut-foreign-requires-unsafe.rs:11:14
+ |
+LL | let _b = a;
+ | ^ use of mutable static
+ |
+ = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/static/static-mut-not-constant.rs b/src/test/ui/static/static-mut-not-constant.rs
new file mode 100644
index 000000000..2091fffd4
--- /dev/null
+++ b/src/test/ui/static/static-mut-not-constant.rs
@@ -0,0 +1,6 @@
+#![feature(box_syntax)]
+
+static mut a: Box<isize> = box 3;
+//~^ ERROR allocations are not allowed in statics
+
+fn main() {}
diff --git a/src/test/ui/static/static-mut-not-constant.stderr b/src/test/ui/static/static-mut-not-constant.stderr
new file mode 100644
index 000000000..a0fa24515
--- /dev/null
+++ b/src/test/ui/static/static-mut-not-constant.stderr
@@ -0,0 +1,9 @@
+error[E0010]: allocations are not allowed in statics
+ --> $DIR/static-mut-not-constant.rs:3:28
+ |
+LL | static mut a: Box<isize> = box 3;
+ | ^^^^^ allocation not allowed in statics
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0010`.
diff --git a/src/test/ui/static/static-mut-not-pat.rs b/src/test/ui/static/static-mut-not-pat.rs
new file mode 100644
index 000000000..ce5ae164c
--- /dev/null
+++ b/src/test/ui/static/static-mut-not-pat.rs
@@ -0,0 +1,43 @@
+// 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.
+
+static mut a: isize = 3;
+
+fn main() {
+ // If they can't be matched against, then it's possible to capture the same
+ // name as a variable, hence this should be an unreachable pattern situation
+ // instead of spitting out a custom error about some identifier collisions
+ // (we should allow shadowing)
+ match 4 {
+ a => {} //~ ERROR match bindings cannot shadow statics
+ _ => {}
+ }
+}
+
+struct NewBool(bool);
+enum Direction {
+ North,
+ East,
+ South,
+ West
+}
+const NEW_FALSE: NewBool = NewBool(false);
+struct Foo {
+ bar: Option<Direction>,
+ baz: NewBool
+}
+
+static mut STATIC_MUT_FOO: Foo = Foo { bar: Some(Direction::West), baz: NEW_FALSE };
+
+fn mutable_statics() {
+ match (Foo { bar: Some(Direction::North), baz: NewBool(true) }) {
+ Foo { bar: None, baz: NewBool(true) } => (),
+ STATIC_MUT_FOO => (),
+ //~^ ERROR match bindings cannot shadow statics
+ Foo { bar: Some(Direction::South), .. } => (),
+ Foo { bar: Some(EAST), .. } => (),
+ Foo { bar: Some(Direction::North), baz: NewBool(true) } => (),
+ Foo { bar: Some(EAST), baz: NewBool(false) } => ()
+ }
+}
diff --git a/src/test/ui/static/static-mut-not-pat.stderr b/src/test/ui/static/static-mut-not-pat.stderr
new file mode 100644
index 000000000..33c1cd6a5
--- /dev/null
+++ b/src/test/ui/static/static-mut-not-pat.stderr
@@ -0,0 +1,21 @@
+error[E0530]: match bindings cannot shadow statics
+ --> $DIR/static-mut-not-pat.rs:13:9
+ |
+LL | static mut a: isize = 3;
+ | ------------------------ the static `a` is defined here
+...
+LL | a => {}
+ | ^ cannot be named the same as a static
+
+error[E0530]: match bindings cannot shadow statics
+ --> $DIR/static-mut-not-pat.rs:36:9
+ |
+LL | static mut STATIC_MUT_FOO: Foo = Foo { bar: Some(Direction::West), baz: NEW_FALSE };
+ | ------------------------------------------------------------------------------------ the static `STATIC_MUT_FOO` is defined here
+...
+LL | STATIC_MUT_FOO => (),
+ | ^^^^^^^^^^^^^^ cannot be named the same as a static
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0530`.
diff --git a/src/test/ui/static/static-mut-requires-unsafe.mir.stderr b/src/test/ui/static/static-mut-requires-unsafe.mir.stderr
new file mode 100644
index 000000000..0d4ce056f
--- /dev/null
+++ b/src/test/ui/static/static-mut-requires-unsafe.mir.stderr
@@ -0,0 +1,27 @@
+error[E0133]: use of mutable static is unsafe and requires unsafe function or block
+ --> $DIR/static-mut-requires-unsafe.rs:7:5
+ |
+LL | a += 3;
+ | ^^^^^^ use of mutable static
+ |
+ = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
+
+error[E0133]: use of mutable static is unsafe and requires unsafe function or block
+ --> $DIR/static-mut-requires-unsafe.rs:8:5
+ |
+LL | a = 4;
+ | ^^^^^ use of mutable static
+ |
+ = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
+
+error[E0133]: use of mutable static is unsafe and requires unsafe function or block
+ --> $DIR/static-mut-requires-unsafe.rs:9:14
+ |
+LL | let _b = a;
+ | ^ use of mutable static
+ |
+ = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/static/static-mut-requires-unsafe.rs b/src/test/ui/static/static-mut-requires-unsafe.rs
new file mode 100644
index 000000000..ea3ba0950
--- /dev/null
+++ b/src/test/ui/static/static-mut-requires-unsafe.rs
@@ -0,0 +1,10 @@
+// revisions: mir thir
+// [thir]compile-flags: -Z thir-unsafeck
+
+static mut a: isize = 3;
+
+fn main() {
+ a += 3; //~ ERROR: requires unsafe
+ a = 4; //~ ERROR: requires unsafe
+ let _b = a; //~ ERROR: requires unsafe
+}
diff --git a/src/test/ui/static/static-mut-requires-unsafe.thir.stderr b/src/test/ui/static/static-mut-requires-unsafe.thir.stderr
new file mode 100644
index 000000000..1a1cf1427
--- /dev/null
+++ b/src/test/ui/static/static-mut-requires-unsafe.thir.stderr
@@ -0,0 +1,27 @@
+error[E0133]: use of mutable static is unsafe and requires unsafe function or block
+ --> $DIR/static-mut-requires-unsafe.rs:7:5
+ |
+LL | a += 3;
+ | ^ use of mutable static
+ |
+ = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
+
+error[E0133]: use of mutable static is unsafe and requires unsafe function or block
+ --> $DIR/static-mut-requires-unsafe.rs:8:5
+ |
+LL | a = 4;
+ | ^ use of mutable static
+ |
+ = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
+
+error[E0133]: use of mutable static is unsafe and requires unsafe function or block
+ --> $DIR/static-mut-requires-unsafe.rs:9:14
+ |
+LL | let _b = a;
+ | ^ use of mutable static
+ |
+ = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/static/static-priv-by-default2.rs b/src/test/ui/static/static-priv-by-default2.rs
new file mode 100644
index 000000000..bbbdb253b
--- /dev/null
+++ b/src/test/ui/static/static-priv-by-default2.rs
@@ -0,0 +1,30 @@
+// aux-build:static_priv_by_default.rs
+
+extern crate static_priv_by_default;
+
+mod child {
+ pub mod childs_child {
+ static private: isize = 0;
+ pub static public: isize = 0;
+ }
+}
+
+fn foo<T>(_: T) {}
+
+fn test1() {
+ use child::childs_child::private;
+ //~^ ERROR: static `private` is private
+ use child::childs_child::public;
+
+ foo(private);
+}
+
+fn test2() {
+ use static_priv_by_default::private;
+ //~^ ERROR: static `private` is private
+ use static_priv_by_default::public;
+
+ foo(private);
+}
+
+fn main() {}
diff --git a/src/test/ui/static/static-priv-by-default2.stderr b/src/test/ui/static/static-priv-by-default2.stderr
new file mode 100644
index 000000000..b14e096d6
--- /dev/null
+++ b/src/test/ui/static/static-priv-by-default2.stderr
@@ -0,0 +1,27 @@
+error[E0603]: static `private` is private
+ --> $DIR/static-priv-by-default2.rs:15:30
+ |
+LL | use child::childs_child::private;
+ | ^^^^^^^ private static
+ |
+note: the static `private` is defined here
+ --> $DIR/static-priv-by-default2.rs:7:9
+ |
+LL | static private: isize = 0;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0603]: static `private` is private
+ --> $DIR/static-priv-by-default2.rs:23:33
+ |
+LL | use static_priv_by_default::private;
+ | ^^^^^^^ private static
+ |
+note: the static `private` is defined here
+ --> $DIR/auxiliary/static_priv_by_default.rs:3:1
+ |
+LL | static private: isize = 0;
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0603`.
diff --git a/src/test/ui/static/static-reference-to-fn-1.rs b/src/test/ui/static/static-reference-to-fn-1.rs
new file mode 100644
index 000000000..c15634dbf
--- /dev/null
+++ b/src/test/ui/static/static-reference-to-fn-1.rs
@@ -0,0 +1,24 @@
+struct A<'a> {
+ func: &'a fn() -> Option<isize>
+}
+
+impl<'a> A<'a> {
+ fn call(&self) -> Option<isize> {
+ (*self.func)()
+ }
+}
+
+fn foo() -> Option<isize> {
+ None
+}
+
+fn create() -> A<'static> {
+ A {
+ func: &foo, //~ ERROR mismatched types
+ }
+}
+
+fn main() {
+ let a = create();
+ a.call();
+}
diff --git a/src/test/ui/static/static-reference-to-fn-1.stderr b/src/test/ui/static/static-reference-to-fn-1.stderr
new file mode 100644
index 000000000..67b478bdb
--- /dev/null
+++ b/src/test/ui/static/static-reference-to-fn-1.stderr
@@ -0,0 +1,12 @@
+error[E0308]: mismatched types
+ --> $DIR/static-reference-to-fn-1.rs:17:15
+ |
+LL | func: &foo,
+ | ^^^^ expected fn pointer, found fn item
+ |
+ = note: expected reference `&fn() -> Option<isize>`
+ found reference `&fn() -> Option<isize> {foo}`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/static/static-reference-to-fn-2.rs b/src/test/ui/static/static-reference-to-fn-2.rs
new file mode 100644
index 000000000..6693667c0
--- /dev/null
+++ b/src/test/ui/static/static-reference-to-fn-2.rs
@@ -0,0 +1,54 @@
+fn id<T>(x: T) -> T { x }
+
+struct StateMachineIter<'a> {
+ statefn: &'a StateMachineFunc<'a>
+}
+
+type StateMachineFunc<'a> = fn(&mut StateMachineIter<'a>) -> Option<&'static str>;
+
+impl<'a> Iterator for StateMachineIter<'a> {
+ type Item = &'static str;
+
+ fn next(&mut self) -> Option<&'static str> {
+ return (*self.statefn)(self);
+ }
+}
+
+fn state1(self_: &mut StateMachineIter) -> Option<&'static str> {
+ self_.statefn = &id(state2 as StateMachineFunc);
+ //~^ ERROR temporary value dropped while borrowed
+ return Some("state1");
+}
+
+fn state2(self_: &mut StateMachineIter) -> Option<(&'static str)> {
+ self_.statefn = &id(state3 as StateMachineFunc);
+ //~^ ERROR temporary value dropped while borrowed
+ return Some("state2");
+}
+
+fn state3(self_: &mut StateMachineIter) -> Option<(&'static str)> {
+ self_.statefn = &id(finished as StateMachineFunc);
+ //~^ ERROR temporary value dropped while borrowed
+ return Some("state3");
+}
+
+fn finished(_: &mut StateMachineIter) -> Option<(&'static str)> {
+ return None;
+}
+
+fn state_iter() -> StateMachineIter<'static> {
+ StateMachineIter {
+ //~^ ERROR cannot return value referencing temporary value
+ statefn: &id(state1 as StateMachineFunc)
+ }
+}
+
+
+fn main() {
+ let mut it = state_iter();
+ println!("{:?}",it.next());
+ println!("{:?}",it.next());
+ println!("{:?}",it.next());
+ println!("{:?}",it.next());
+ println!("{:?}",it.next());
+}
diff --git a/src/test/ui/static/static-reference-to-fn-2.stderr b/src/test/ui/static/static-reference-to-fn-2.stderr
new file mode 100644
index 000000000..ff15884bd
--- /dev/null
+++ b/src/test/ui/static/static-reference-to-fn-2.stderr
@@ -0,0 +1,49 @@
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/static-reference-to-fn-2.rs:18:22
+ |
+LL | fn state1(self_: &mut StateMachineIter) -> Option<&'static str> {
+ | ----- has type `&mut StateMachineIter<'1>`
+LL | self_.statefn = &id(state2 as StateMachineFunc);
+ | -----------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- temporary value is freed at the end of this statement
+ | | |
+ | | creates a temporary which is freed while still in use
+ | assignment requires that borrow lasts for `'1`
+
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/static-reference-to-fn-2.rs:24:22
+ |
+LL | fn state2(self_: &mut StateMachineIter) -> Option<(&'static str)> {
+ | ----- has type `&mut StateMachineIter<'1>`
+LL | self_.statefn = &id(state3 as StateMachineFunc);
+ | -----------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- temporary value is freed at the end of this statement
+ | | |
+ | | creates a temporary which is freed while still in use
+ | assignment requires that borrow lasts for `'1`
+
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/static-reference-to-fn-2.rs:30:22
+ |
+LL | fn state3(self_: &mut StateMachineIter) -> Option<(&'static str)> {
+ | ----- has type `&mut StateMachineIter<'1>`
+LL | self_.statefn = &id(finished as StateMachineFunc);
+ | -----------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- temporary value is freed at the end of this statement
+ | | |
+ | | creates a temporary which is freed while still in use
+ | assignment requires that borrow lasts for `'1`
+
+error[E0515]: cannot return value referencing temporary value
+ --> $DIR/static-reference-to-fn-2.rs:40:5
+ |
+LL | / StateMachineIter {
+LL | |
+LL | | statefn: &id(state1 as StateMachineFunc)
+ | | ------------------------------ temporary value created here
+LL | | }
+ | |_____^ returns a value referencing data owned by the current function
+ |
+ = help: use `.collect()` to allocate the iterator
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0515, E0716.
+For more information about an error, try `rustc --explain E0515`.
diff --git a/src/test/ui/static/static-region-bound.rs b/src/test/ui/static/static-region-bound.rs
new file mode 100644
index 000000000..d70706e57
--- /dev/null
+++ b/src/test/ui/static/static-region-bound.rs
@@ -0,0 +1,12 @@
+fn id<T>(x: T) -> T { x }
+
+fn f<T:'static>(_: T) {}
+
+fn main() {
+
+ let x: Box<_> = Box::new(3);
+ f(x);
+
+ let x = &id(3); //~ ERROR temporary value dropped while borrowed
+ f(x);
+}
diff --git a/src/test/ui/static/static-region-bound.stderr b/src/test/ui/static/static-region-bound.stderr
new file mode 100644
index 000000000..15261259e
--- /dev/null
+++ b/src/test/ui/static/static-region-bound.stderr
@@ -0,0 +1,13 @@
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/static-region-bound.rs:10:14
+ |
+LL | let x = &id(3);
+ | ^^^^^ creates a temporary which is freed while still in use
+LL | f(x);
+ | ---- argument 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/static/static-vec-repeat-not-constant.rs b/src/test/ui/static/static-vec-repeat-not-constant.rs
new file mode 100644
index 000000000..61c87b144
--- /dev/null
+++ b/src/test/ui/static/static-vec-repeat-not-constant.rs
@@ -0,0 +1,6 @@
+fn foo() -> isize { 23 }
+
+static a: [isize; 2] = [foo(); 2];
+//~^ ERROR: E0015
+
+fn main() {}
diff --git a/src/test/ui/static/static-vec-repeat-not-constant.stderr b/src/test/ui/static/static-vec-repeat-not-constant.stderr
new file mode 100644
index 000000000..84fc638a9
--- /dev/null
+++ b/src/test/ui/static/static-vec-repeat-not-constant.stderr
@@ -0,0 +1,11 @@
+error[E0015]: cannot call non-const fn `foo` in statics
+ --> $DIR/static-vec-repeat-not-constant.rs:3:25
+ |
+LL | static a: [isize; 2] = [foo(); 2];
+ | ^^^^^
+ |
+ = note: calls in statics are limited to constant functions, tuple structs and tuple variants
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0015`.
diff --git a/src/test/ui/static/static_sized_requirement.rs b/src/test/ui/static/static_sized_requirement.rs
new file mode 100644
index 000000000..3943b2608
--- /dev/null
+++ b/src/test/ui/static/static_sized_requirement.rs
@@ -0,0 +1,12 @@
+// build-pass (FIXME(62277): could be check-pass?)
+
+#![feature(no_core, lang_items)]
+#![no_core]
+#![crate_type = "lib"]
+
+#[lang = "sized"]
+trait Sized {}
+
+extern "C" {
+ pub static A: u32;
+}
diff --git a/src/test/ui/static/thread-local-in-ctfe.rs b/src/test/ui/static/thread-local-in-ctfe.rs
new file mode 100644
index 000000000..547e5445a
--- /dev/null
+++ b/src/test/ui/static/thread-local-in-ctfe.rs
@@ -0,0 +1,23 @@
+#![feature(thread_local)]
+
+#[thread_local]
+static A: u32 = 1;
+
+static B: u32 = A;
+//~^ ERROR thread-local statics cannot be accessed at compile-time
+
+static C: &u32 = &A;
+//~^ ERROR thread-local statics cannot be accessed at compile-time
+
+const D: u32 = A;
+//~^ ERROR thread-local statics cannot be accessed at compile-time
+
+const E: &u32 = &A;
+//~^ ERROR thread-local statics cannot be accessed at compile-time
+
+const fn f() -> u32 {
+ A
+ //~^ ERROR thread-local statics cannot be accessed at compile-time
+}
+
+fn main() {}
diff --git a/src/test/ui/static/thread-local-in-ctfe.stderr b/src/test/ui/static/thread-local-in-ctfe.stderr
new file mode 100644
index 000000000..fd9676046
--- /dev/null
+++ b/src/test/ui/static/thread-local-in-ctfe.stderr
@@ -0,0 +1,33 @@
+error[E0625]: thread-local statics cannot be accessed at compile-time
+ --> $DIR/thread-local-in-ctfe.rs:6:17
+ |
+LL | static B: u32 = A;
+ | ^
+
+error[E0625]: thread-local statics cannot be accessed at compile-time
+ --> $DIR/thread-local-in-ctfe.rs:9:19
+ |
+LL | static C: &u32 = &A;
+ | ^
+
+error[E0625]: thread-local statics cannot be accessed at compile-time
+ --> $DIR/thread-local-in-ctfe.rs:12:16
+ |
+LL | const D: u32 = A;
+ | ^
+
+error[E0625]: thread-local statics cannot be accessed at compile-time
+ --> $DIR/thread-local-in-ctfe.rs:15:18
+ |
+LL | const E: &u32 = &A;
+ | ^
+
+error[E0625]: thread-local statics cannot be accessed at compile-time
+ --> $DIR/thread-local-in-ctfe.rs:19:5
+ |
+LL | A
+ | ^
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0625`.
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`.