summaryrefslogtreecommitdiffstats
path: root/tests/ui/generic-const-items
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:59:35 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:59:35 +0000
commitd1b2d29528b7794b41e66fc2136e395a02f8529b (patch)
treea4a17504b260206dec3cf55b2dca82929a348ac2 /tests/ui/generic-const-items
parentReleasing progress-linux version 1.72.1+dfsg1-1~progress7.99u1. (diff)
downloadrustc-d1b2d29528b7794b41e66fc2136e395a02f8529b.tar.xz
rustc-d1b2d29528b7794b41e66fc2136e395a02f8529b.zip
Merging upstream version 1.73.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/ui/generic-const-items')
-rw-r--r--tests/ui/generic-const-items/associated-const-equality.rs22
-rw-r--r--tests/ui/generic-const-items/basic.rs61
-rw-r--r--tests/ui/generic-const-items/compare-impl-item.rs30
-rw-r--r--tests/ui/generic-const-items/compare-impl-item.stderr66
-rw-r--r--tests/ui/generic-const-items/const-trait-impl.rs25
-rw-r--r--tests/ui/generic-const-items/const-trait-impl.stderr11
-rw-r--r--tests/ui/generic-const-items/duplicate-where-clause.rs27
-rw-r--r--tests/ui/generic-const-items/duplicate-where-clause.stderr27
-rw-r--r--tests/ui/generic-const-items/elided-lifetimes.rs18
-rw-r--r--tests/ui/generic-const-items/elided-lifetimes.stderr35
-rw-r--r--tests/ui/generic-const-items/evaluatable-bounds.rs31
-rw-r--r--tests/ui/generic-const-items/evaluatable-bounds.unconstrained.stderr10
-rw-r--r--tests/ui/generic-const-items/feature-gate-generic_const_items.rs37
-rw-r--r--tests/ui/generic-const-items/feature-gate-generic_const_items.stderr77
-rw-r--r--tests/ui/generic-const-items/inference-failure.rs15
-rw-r--r--tests/ui/generic-const-items/inference-failure.stderr20
-rw-r--r--tests/ui/generic-const-items/misplaced-where-clause.fixed18
-rw-r--r--tests/ui/generic-const-items/misplaced-where-clause.rs20
-rw-r--r--tests/ui/generic-const-items/misplaced-where-clause.stderr36
-rw-r--r--tests/ui/generic-const-items/parameter-defaults.rs14
-rw-r--r--tests/ui/generic-const-items/parameter-defaults.stderr8
-rw-r--r--tests/ui/generic-const-items/recursive.rs12
-rw-r--r--tests/ui/generic-const-items/reference-outlives-referent.rs9
-rw-r--r--tests/ui/generic-const-items/reference-outlives-referent.stderr20
-rw-r--r--tests/ui/generic-const-items/trivially-unsatisfied-bounds-0.rs12
-rw-r--r--tests/ui/generic-const-items/trivially-unsatisfied-bounds-0.stderr18
-rw-r--r--tests/ui/generic-const-items/trivially-unsatisfied-bounds-1.rs12
-rw-r--r--tests/ui/generic-const-items/trivially-unsatisfied-bounds-1.stderr11
-rw-r--r--tests/ui/generic-const-items/unsatisfied-bounds.rs34
-rw-r--r--tests/ui/generic-const-items/unsatisfied-bounds.stderr62
-rw-r--r--tests/ui/generic-const-items/unsatisfied-evaluatable-bounds.rs12
-rw-r--r--tests/ui/generic-const-items/unsatisfied-evaluatable-bounds.stderr9
-rw-r--r--tests/ui/generic-const-items/unsatisfied-outlives-bounds.rs17
-rw-r--r--tests/ui/generic-const-items/unsatisfied-outlives-bounds.stderr18
34 files changed, 854 insertions, 0 deletions
diff --git a/tests/ui/generic-const-items/associated-const-equality.rs b/tests/ui/generic-const-items/associated-const-equality.rs
new file mode 100644
index 000000000..785d3aa50
--- /dev/null
+++ b/tests/ui/generic-const-items/associated-const-equality.rs
@@ -0,0 +1,22 @@
+// check-pass
+
+#![feature(generic_const_items, associated_const_equality)]
+#![allow(incomplete_features)]
+
+trait Owner {
+ const C<const N: u32>: u32;
+ const K<const N: u32>: u32;
+}
+
+impl Owner for () {
+ const C<const N: u32>: u32 = N;
+ const K<const N: u32>: u32 = N + 1;
+}
+
+fn take0<const N: u32>(_: impl Owner<C<N> = { N }>) {}
+fn take1(_: impl Owner<K<99> = 100>) {}
+
+fn main() {
+ take0::<128>(());
+ take1(());
+}
diff --git a/tests/ui/generic-const-items/basic.rs b/tests/ui/generic-const-items/basic.rs
new file mode 100644
index 000000000..73bfa803a
--- /dev/null
+++ b/tests/ui/generic-const-items/basic.rs
@@ -0,0 +1,61 @@
+// check-pass
+
+// Basic usage patterns of free & associated generic const items.
+
+#![feature(generic_const_items)]
+#![allow(incomplete_features)]
+
+fn main() {
+ const NULL<T>: Option<T> = None::<T>;
+ const NOTHING<T>: Option<T> = None; // arg inferred
+
+ let _ = NOTHING::<String>;
+ let _: Option<u8> = NULL; // arg inferred
+
+ const IDENTITY<const X: u64>: u64 = X;
+
+ const COUNT: u64 = IDENTITY::<48>;
+ const AMOUNT: u64 = IDENTITY::<COUNT>;
+ const NUMBER: u64 = IDENTITY::<{ AMOUNT * 2 }>;
+ let _ = NUMBER;
+ let _ = IDENTITY::<0>;
+
+ let _ = match 0 {
+ IDENTITY::<1> => 2,
+ IDENTITY::<{ 1 + 1 }> => 4,
+ _ => 0,
+ };
+
+ const CREATE<I: Inhabited>: I = I::PROOF;
+ let _ = CREATE::<u64>;
+ let _: u64 = CREATE; // arg inferred
+
+ let _ = <() as Main<u64>>::MAKE::<u64>;
+ let _: (u64, u64) = <()>::MAKE; // args inferred
+}
+
+pub fn usage<'any>() {
+ const REGION_POLY<'a>: &'a () = &();
+
+ let _: &'any () = REGION_POLY::<'any>;
+ let _: &'any () = REGION_POLY::<'_>;
+ let _: &'static () = REGION_POLY;
+}
+
+trait Main<O> {
+ type Output<I>;
+ const MAKE<I: Inhabited>: Self::Output<I>;
+}
+
+impl<O: Inhabited> Main<O> for () {
+ type Output<I> = (O, I);
+ const MAKE<I: Inhabited>: Self::Output<I> = (O::PROOF, I::PROOF);
+}
+
+trait Inhabited {
+ const PROOF: Self;
+}
+
+impl Inhabited for u64 {
+ const PROOF: Self = 512;
+}
diff --git a/tests/ui/generic-const-items/compare-impl-item.rs b/tests/ui/generic-const-items/compare-impl-item.rs
new file mode 100644
index 000000000..01e4477c6
--- /dev/null
+++ b/tests/ui/generic-const-items/compare-impl-item.rs
@@ -0,0 +1,30 @@
+#![feature(generic_const_items)]
+#![allow(incomplete_features)]
+
+trait Trait<P> {
+ const A: ();
+ const B<const K: u64, const Q: u64>: u64;
+ const C<T>: T;
+ const D<const N: usize>: usize;
+
+ const E: usize;
+ const F<T: PartialEq>: ();
+}
+
+impl<P> Trait<P> for () {
+ const A<T>: () = ();
+ //~^ ERROR const `A` has 1 type parameter but its trait declaration has 0 type parameters
+ const B<const K: u64>: u64 = 0;
+ //~^ ERROR const `B` has 1 const parameter but its trait declaration has 2 const parameters
+ const C<'a>: &'a str = "";
+ //~^ ERROR const `C` has 0 type parameters but its trait declaration has 1 type parameter
+ const D<const N: u16>: u16 = N;
+ //~^ ERROR const `D` has an incompatible generic parameter for trait `Trait`
+
+ const E: usize = 1024
+ where
+ P: Copy; //~ ERROR impl has stricter requirements than trait
+ const F<T: Eq>: () = (); //~ ERROR impl has stricter requirements than trait
+}
+
+fn main() {}
diff --git a/tests/ui/generic-const-items/compare-impl-item.stderr b/tests/ui/generic-const-items/compare-impl-item.stderr
new file mode 100644
index 000000000..8610d8cba
--- /dev/null
+++ b/tests/ui/generic-const-items/compare-impl-item.stderr
@@ -0,0 +1,66 @@
+error[E0049]: const `A` has 1 type parameter but its trait declaration has 0 type parameters
+ --> $DIR/compare-impl-item.rs:15:13
+ |
+LL | const A: ();
+ | - expected 0 type parameters
+...
+LL | const A<T>: () = ();
+ | ^ found 1 type parameter
+
+error[E0049]: const `B` has 1 const parameter but its trait declaration has 2 const parameters
+ --> $DIR/compare-impl-item.rs:17:13
+ |
+LL | const B<const K: u64, const Q: u64>: u64;
+ | ------------ ------------
+ | |
+ | expected 2 const parameters
+...
+LL | const B<const K: u64>: u64 = 0;
+ | ^^^^^^^^^^^^ found 1 const parameter
+
+error[E0049]: const `C` has 0 type parameters but its trait declaration has 1 type parameter
+ --> $DIR/compare-impl-item.rs:19:13
+ |
+LL | const C<T>: T;
+ | - expected 1 type parameter
+...
+LL | const C<'a>: &'a str = "";
+ | ^^ found 0 type parameters
+
+error[E0053]: const `D` has an incompatible generic parameter for trait `Trait`
+ --> $DIR/compare-impl-item.rs:21:13
+ |
+LL | trait Trait<P> {
+ | -----
+...
+LL | const D<const N: usize>: usize;
+ | -------------- expected const parameter of type `usize`
+...
+LL | impl<P> Trait<P> for () {
+ | -----------------------
+...
+LL | const D<const N: u16>: u16 = N;
+ | ^^^^^^^^^^^^ found const parameter of type `u16`
+
+error[E0276]: impl has stricter requirements than trait
+ --> $DIR/compare-impl-item.rs:26:12
+ |
+LL | const E: usize;
+ | -------------- definition of `E` from trait
+...
+LL | P: Copy;
+ | ^^^^ impl has extra requirement `P: Copy`
+
+error[E0276]: impl has stricter requirements than trait
+ --> $DIR/compare-impl-item.rs:27:16
+ |
+LL | const F<T: PartialEq>: ();
+ | ------------------------- definition of `F` from trait
+...
+LL | const F<T: Eq>: () = ();
+ | ^^ impl has extra requirement `T: Eq`
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0049, E0053, E0276.
+For more information about an error, try `rustc --explain E0049`.
diff --git a/tests/ui/generic-const-items/const-trait-impl.rs b/tests/ui/generic-const-items/const-trait-impl.rs
new file mode 100644
index 000000000..d30f7af17
--- /dev/null
+++ b/tests/ui/generic-const-items/const-trait-impl.rs
@@ -0,0 +1,25 @@
+// known-bug: #110395
+// FIXME check-pass
+
+// Test that we can call methods from const trait impls inside of generic const items.
+
+#![feature(generic_const_items, const_trait_impl)]
+#![allow(incomplete_features)]
+#![crate_type = "lib"]
+
+// FIXME(generic_const_items): Interpret `~const` as always-const.
+const CREATE<T: ~const Create>: T = T::create();
+
+pub const K0: i32 = CREATE::<i32>;
+pub const K1: i32 = CREATE; // arg inferred
+
+#[const_trait]
+trait Create {
+ fn create() -> Self;
+}
+
+impl const Create for i32 {
+ fn create() -> i32 {
+ 4096
+ }
+}
diff --git a/tests/ui/generic-const-items/const-trait-impl.stderr b/tests/ui/generic-const-items/const-trait-impl.stderr
new file mode 100644
index 000000000..34360c581
--- /dev/null
+++ b/tests/ui/generic-const-items/const-trait-impl.stderr
@@ -0,0 +1,11 @@
+error[E0015]: cannot call non-const fn `<T as Create>::create` in constants
+ --> $DIR/const-trait-impl.rs:11:37
+ |
+LL | const CREATE<T: ~const Create>: T = T::create();
+ | ^^^^^^^^^^^
+ |
+ = note: calls in constants 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/tests/ui/generic-const-items/duplicate-where-clause.rs b/tests/ui/generic-const-items/duplicate-where-clause.rs
new file mode 100644
index 000000000..68da4073f
--- /dev/null
+++ b/tests/ui/generic-const-items/duplicate-where-clause.rs
@@ -0,0 +1,27 @@
+#![feature(generic_const_items)]
+#![allow(incomplete_features)]
+
+trait Tr<P> {
+ const K: ()
+ where
+ P: Copy
+ where
+ P: Eq;
+ //~^ ERROR cannot define duplicate `where` clauses on an item
+}
+
+// Test that we error on the first where-clause but also that we don't suggest to swap it with the
+// body as it would conflict with the second where-clause.
+// FIXME(generic_const_items): We should provide a structured sugg to merge the 1st into the 2nd WC.
+
+impl<P> Tr<P> for () {
+ const K: ()
+ where
+ P: Eq
+ = ()
+ where
+ P: Copy;
+ //~^^^^^ ERROR where clauses are not allowed before const item bodies
+}
+
+fn main() {}
diff --git a/tests/ui/generic-const-items/duplicate-where-clause.stderr b/tests/ui/generic-const-items/duplicate-where-clause.stderr
new file mode 100644
index 000000000..5fa61b01e
--- /dev/null
+++ b/tests/ui/generic-const-items/duplicate-where-clause.stderr
@@ -0,0 +1,27 @@
+error: cannot define duplicate `where` clauses on an item
+ --> $DIR/duplicate-where-clause.rs:9:9
+ |
+LL | P: Copy
+ | - previous `where` clause starts here
+LL | where
+LL | P: Eq;
+ | ^
+ |
+help: consider joining the two `where` clauses into one
+ |
+LL | P: Copy,
+ | ~
+
+error: where clauses are not allowed before const item bodies
+ --> $DIR/duplicate-where-clause.rs:19:5
+ |
+LL | const K: ()
+ | - while parsing this const item
+LL | / where
+LL | | P: Eq
+ | |_____________^ unexpected where clause
+LL | = ()
+ | -- the item body
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/generic-const-items/elided-lifetimes.rs b/tests/ui/generic-const-items/elided-lifetimes.rs
new file mode 100644
index 000000000..cca73e2e8
--- /dev/null
+++ b/tests/ui/generic-const-items/elided-lifetimes.rs
@@ -0,0 +1,18 @@
+#![feature(generic_const_items)]
+#![allow(incomplete_features)]
+
+// Check that we forbid elided lifetimes inside the generics of const items.
+
+const K<T>: () = ()
+where
+ &T: Copy; //~ ERROR `&` without an explicit lifetime name cannot be used here
+
+const I<const S: &str>: &str = "";
+//~^ ERROR `&` without an explicit lifetime name cannot be used here
+//~| ERROR `&str` is forbidden as the type of a const generic parameter
+
+const B<T: Trait<'_>>: () = (); //~ ERROR `'_` cannot be used here
+
+trait Trait<'a> {}
+
+fn main() {}
diff --git a/tests/ui/generic-const-items/elided-lifetimes.stderr b/tests/ui/generic-const-items/elided-lifetimes.stderr
new file mode 100644
index 000000000..8cd3f9ee7
--- /dev/null
+++ b/tests/ui/generic-const-items/elided-lifetimes.stderr
@@ -0,0 +1,35 @@
+error[E0637]: `&` without an explicit lifetime name cannot be used here
+ --> $DIR/elided-lifetimes.rs:8:5
+ |
+LL | &T: Copy;
+ | ^ explicit lifetime name needed here
+ |
+help: consider introducing a higher-ranked lifetime here
+ |
+LL | for<'a> &'a T: Copy;
+ | +++++++ ++
+
+error[E0637]: `&` without an explicit lifetime name cannot be used here
+ --> $DIR/elided-lifetimes.rs:10:18
+ |
+LL | const I<const S: &str>: &str = "";
+ | ^ explicit lifetime name needed here
+
+error[E0637]: `'_` cannot be used here
+ --> $DIR/elided-lifetimes.rs:14:18
+ |
+LL | const B<T: Trait<'_>>: () = ();
+ | ^^ `'_` is a reserved lifetime name
+
+error: `&str` is forbidden as the type of a const generic parameter
+ --> $DIR/elided-lifetimes.rs:10:18
+ |
+LL | const I<const S: &str>: &str = "";
+ | ^^^^
+ |
+ = note: the only supported types are integers, `bool` and `char`
+ = help: more complex types are supported with `#![feature(adt_const_params)]`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0637`.
diff --git a/tests/ui/generic-const-items/evaluatable-bounds.rs b/tests/ui/generic-const-items/evaluatable-bounds.rs
new file mode 100644
index 000000000..cdcfcf918
--- /dev/null
+++ b/tests/ui/generic-const-items/evaluatable-bounds.rs
@@ -0,0 +1,31 @@
+// This is a regression test for issue #104400.
+
+// revisions: unconstrained constrained
+//[constrained] check-pass
+
+// Test that we can constrain generic const items that appear inside associated consts by
+// adding a (makeshift) "evaluatable"-bound to the item.
+
+#![feature(generic_const_items, generic_const_exprs)]
+#![allow(incomplete_features)]
+
+trait Trait {
+ const LEN: usize;
+
+ #[cfg(unconstrained)]
+ const ARRAY: [i32; Self::LEN]; //[unconstrained]~ ERROR unconstrained generic constant
+
+ #[cfg(constrained)]
+ const ARRAY: [i32; Self::LEN]
+ where
+ [(); Self::LEN]:;
+}
+
+impl Trait for () {
+ const LEN: usize = 2;
+ const ARRAY: [i32; Self::LEN] = [360, 720];
+}
+
+fn main() {
+ let [_, _] = <() as Trait>::ARRAY;
+}
diff --git a/tests/ui/generic-const-items/evaluatable-bounds.unconstrained.stderr b/tests/ui/generic-const-items/evaluatable-bounds.unconstrained.stderr
new file mode 100644
index 000000000..930080f7c
--- /dev/null
+++ b/tests/ui/generic-const-items/evaluatable-bounds.unconstrained.stderr
@@ -0,0 +1,10 @@
+error: unconstrained generic constant
+ --> $DIR/evaluatable-bounds.rs:16:5
+ |
+LL | const ARRAY: [i32; Self::LEN];
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: try adding a `where` bound using this expression: `where [(); Self::LEN]:`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/generic-const-items/feature-gate-generic_const_items.rs b/tests/ui/generic-const-items/feature-gate-generic_const_items.rs
new file mode 100644
index 000000000..5c241f256
--- /dev/null
+++ b/tests/ui/generic-const-items/feature-gate-generic_const_items.rs
@@ -0,0 +1,37 @@
+pub trait Trait<A> {
+ const ONE<T>: i32;
+ //~^ ERROR generic const items are experimental
+
+ const TWO: ()
+ where
+ A: Copy;
+ //~^^ ERROR generic const items are experimental
+}
+
+const CONST<T>: i32 = 0;
+//~^ ERROR generic const items are experimental
+
+const EMPTY<>: i32 = 0;
+//~^ ERROR generic const items are experimental
+
+const TRUE: () = ()
+where
+ String: Clone;
+//~^^ ERROR generic const items are experimental
+
+// Ensure that we flag generic const items inside macro calls as well:
+
+macro_rules! discard {
+ ($item:item) => {}
+}
+
+discard! { const FREE<T>: () = (); }
+//~^ ERROR generic const items are experimental
+
+discard! { impl () { const ASSOC<const N: ()>: () = (); } }
+//~^ ERROR generic const items are experimental
+
+discard! { impl () { const ASSOC: i32 = 0 where String: Copy; } }
+//~^ ERROR generic const items are experimental
+
+fn main() {}
diff --git a/tests/ui/generic-const-items/feature-gate-generic_const_items.stderr b/tests/ui/generic-const-items/feature-gate-generic_const_items.stderr
new file mode 100644
index 000000000..a1fdf5f6e
--- /dev/null
+++ b/tests/ui/generic-const-items/feature-gate-generic_const_items.stderr
@@ -0,0 +1,77 @@
+error[E0658]: generic const items are experimental
+ --> $DIR/feature-gate-generic_const_items.rs:2:14
+ |
+LL | const ONE<T>: i32;
+ | ^^^
+ |
+ = note: see issue #113521 <https://github.com/rust-lang/rust/issues/113521> for more information
+ = help: add `#![feature(generic_const_items)]` to the crate attributes to enable
+
+error[E0658]: generic const items are experimental
+ --> $DIR/feature-gate-generic_const_items.rs:6:5
+ |
+LL | / where
+LL | | A: Copy;
+ | |_______________^
+ |
+ = note: see issue #113521 <https://github.com/rust-lang/rust/issues/113521> for more information
+ = help: add `#![feature(generic_const_items)]` to the crate attributes to enable
+
+error[E0658]: generic const items are experimental
+ --> $DIR/feature-gate-generic_const_items.rs:11:12
+ |
+LL | const CONST<T>: i32 = 0;
+ | ^^^
+ |
+ = note: see issue #113521 <https://github.com/rust-lang/rust/issues/113521> for more information
+ = help: add `#![feature(generic_const_items)]` to the crate attributes to enable
+
+error[E0658]: generic const items are experimental
+ --> $DIR/feature-gate-generic_const_items.rs:14:12
+ |
+LL | const EMPTY<>: i32 = 0;
+ | ^^
+ |
+ = note: see issue #113521 <https://github.com/rust-lang/rust/issues/113521> for more information
+ = help: add `#![feature(generic_const_items)]` to the crate attributes to enable
+
+error[E0658]: generic const items are experimental
+ --> $DIR/feature-gate-generic_const_items.rs:18:1
+ |
+LL | / where
+LL | | String: Clone;
+ | |_________________^
+ |
+ = note: see issue #113521 <https://github.com/rust-lang/rust/issues/113521> for more information
+ = help: add `#![feature(generic_const_items)]` to the crate attributes to enable
+
+error[E0658]: generic const items are experimental
+ --> $DIR/feature-gate-generic_const_items.rs:28:22
+ |
+LL | discard! { const FREE<T>: () = (); }
+ | ^^^
+ |
+ = note: see issue #113521 <https://github.com/rust-lang/rust/issues/113521> for more information
+ = help: add `#![feature(generic_const_items)]` to the crate attributes to enable
+
+error[E0658]: generic const items are experimental
+ --> $DIR/feature-gate-generic_const_items.rs:31:33
+ |
+LL | discard! { impl () { const ASSOC<const N: ()>: () = (); } }
+ | ^^^^^^^^^^^^^
+ |
+ = note: see issue #113521 <https://github.com/rust-lang/rust/issues/113521> for more information
+ = help: add `#![feature(generic_const_items)]` to the crate attributes to enable
+
+error[E0658]: generic const items are experimental
+ --> $DIR/feature-gate-generic_const_items.rs:34:43
+ |
+LL | discard! { impl () { const ASSOC: i32 = 0 where String: Copy; } }
+ | ^^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #113521 <https://github.com/rust-lang/rust/issues/113521> for more information
+ = help: add `#![feature(generic_const_items)]` to the crate attributes to enable
+
+error: aborting due to 8 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/generic-const-items/inference-failure.rs b/tests/ui/generic-const-items/inference-failure.rs
new file mode 100644
index 000000000..fd4f424dd
--- /dev/null
+++ b/tests/ui/generic-const-items/inference-failure.rs
@@ -0,0 +1,15 @@
+#![feature(generic_const_items)]
+#![allow(incomplete_features)]
+
+const NONE<T>: Option<T> = None::<T>;
+const IGNORE<T>: () = ();
+
+fn none() {
+ let _ = NONE; //~ ERROR type annotations needed
+}
+
+fn ignore() {
+ let _ = IGNORE; //~ ERROR type annotations needed
+}
+
+fn main() {}
diff --git a/tests/ui/generic-const-items/inference-failure.stderr b/tests/ui/generic-const-items/inference-failure.stderr
new file mode 100644
index 000000000..22ff1b9ba
--- /dev/null
+++ b/tests/ui/generic-const-items/inference-failure.stderr
@@ -0,0 +1,20 @@
+error[E0282]: type annotations needed for `Option<T>`
+ --> $DIR/inference-failure.rs:8:9
+ |
+LL | let _ = NONE;
+ | ^
+ |
+help: consider giving this pattern a type, where the type for type parameter `T` is specified
+ |
+LL | let _: Option<T> = NONE;
+ | +++++++++++
+
+error[E0282]: type annotations needed
+ --> $DIR/inference-failure.rs:12:13
+ |
+LL | let _ = IGNORE;
+ | ^^^^^^ cannot infer type for type parameter `T` declared on the constant `IGNORE`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/generic-const-items/misplaced-where-clause.fixed b/tests/ui/generic-const-items/misplaced-where-clause.fixed
new file mode 100644
index 000000000..bff470c28
--- /dev/null
+++ b/tests/ui/generic-const-items/misplaced-where-clause.fixed
@@ -0,0 +1,18 @@
+// run-rustfix
+
+#![feature(generic_const_items)]
+#![allow(incomplete_features, dead_code)]
+
+const K<T>: u64
+= T::K where
+ T: Tr<()>;
+//~^^^ ERROR where clauses are not allowed before const item bodies
+
+trait Tr<P> {
+ const K: u64
+ = 0 where
+ P: Copy;
+ //~^^^ ERROR where clauses are not allowed before const item bodies
+}
+
+fn main() {}
diff --git a/tests/ui/generic-const-items/misplaced-where-clause.rs b/tests/ui/generic-const-items/misplaced-where-clause.rs
new file mode 100644
index 000000000..b14c6d594
--- /dev/null
+++ b/tests/ui/generic-const-items/misplaced-where-clause.rs
@@ -0,0 +1,20 @@
+// run-rustfix
+
+#![feature(generic_const_items)]
+#![allow(incomplete_features, dead_code)]
+
+const K<T>: u64
+where
+ T: Tr<()>
+= T::K;
+//~^^^ ERROR where clauses are not allowed before const item bodies
+
+trait Tr<P> {
+ const K: u64
+ where
+ P: Copy
+ = 0;
+ //~^^^ ERROR where clauses are not allowed before const item bodies
+}
+
+fn main() {}
diff --git a/tests/ui/generic-const-items/misplaced-where-clause.stderr b/tests/ui/generic-const-items/misplaced-where-clause.stderr
new file mode 100644
index 000000000..431741d87
--- /dev/null
+++ b/tests/ui/generic-const-items/misplaced-where-clause.stderr
@@ -0,0 +1,36 @@
+error: where clauses are not allowed before const item bodies
+ --> $DIR/misplaced-where-clause.rs:7:1
+ |
+LL | const K<T>: u64
+ | - while parsing this const item
+LL | / where
+LL | | T: Tr<()>
+ | |_____________^ unexpected where clause
+LL | = T::K;
+ | ---- the item body
+ |
+help: move the body before the where clause
+ |
+LL ~ = T::K where
+LL ~ T: Tr<()>;
+ |
+
+error: where clauses are not allowed before const item bodies
+ --> $DIR/misplaced-where-clause.rs:14:5
+ |
+LL | const K: u64
+ | - while parsing this const item
+LL | / where
+LL | | P: Copy
+ | |_______________^ unexpected where clause
+LL | = 0;
+ | - the item body
+ |
+help: move the body before the where clause
+ |
+LL ~ = 0 where
+LL ~ P: Copy;
+ |
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/generic-const-items/parameter-defaults.rs b/tests/ui/generic-const-items/parameter-defaults.rs
new file mode 100644
index 000000000..a6f82c249
--- /dev/null
+++ b/tests/ui/generic-const-items/parameter-defaults.rs
@@ -0,0 +1,14 @@
+#![feature(generic_const_items)]
+#![allow(incomplete_features)]
+
+// Check that we emit a *hard* error (not just a lint warning or error for example) for generic
+// parameter defaults on free const items since we are not limited by backward compatibility.
+#![allow(invalid_type_param_default)] // Should have no effect here.
+
+// FIXME(default_type_parameter_fallback): Consider reallowing them once they work properly.
+
+const NONE<T = ()>: Option<T> = None::<T>; //~ ERROR defaults for type parameters are only allowed
+
+fn main() {
+ let _ = NONE;
+}
diff --git a/tests/ui/generic-const-items/parameter-defaults.stderr b/tests/ui/generic-const-items/parameter-defaults.stderr
new file mode 100644
index 000000000..62da45e55
--- /dev/null
+++ b/tests/ui/generic-const-items/parameter-defaults.stderr
@@ -0,0 +1,8 @@
+error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
+ --> $DIR/parameter-defaults.rs:10:12
+ |
+LL | const NONE<T = ()>: Option<T> = None::<T>;
+ | ^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/generic-const-items/recursive.rs b/tests/ui/generic-const-items/recursive.rs
new file mode 100644
index 000000000..3266b37d3
--- /dev/null
+++ b/tests/ui/generic-const-items/recursive.rs
@@ -0,0 +1,12 @@
+// FIXME(generic_const_items): This leads to a stack overflow in the compiler!
+// known-bug: unknown
+// ignore-test
+
+#![feature(generic_const_items)]
+#![allow(incomplete_features)]
+
+const RECUR<T>: () = RECUR::<(T,)>;
+
+fn main() {
+ let _ = RECUR::<()>;
+}
diff --git a/tests/ui/generic-const-items/reference-outlives-referent.rs b/tests/ui/generic-const-items/reference-outlives-referent.rs
new file mode 100644
index 000000000..13e4eaac3
--- /dev/null
+++ b/tests/ui/generic-const-items/reference-outlives-referent.rs
@@ -0,0 +1,9 @@
+// Test that we catch that the reference outlives the referent and we
+// successfully emit a diagnostic. Regression test for issue #114714.
+
+#![feature(generic_const_items)]
+#![allow(incomplete_features)]
+
+const Q<'a, 'b>: &'a &'b () = &&(); //~ ERROR reference has a longer lifetime than the data it references
+
+fn main() {}
diff --git a/tests/ui/generic-const-items/reference-outlives-referent.stderr b/tests/ui/generic-const-items/reference-outlives-referent.stderr
new file mode 100644
index 000000000..2b57713b5
--- /dev/null
+++ b/tests/ui/generic-const-items/reference-outlives-referent.stderr
@@ -0,0 +1,20 @@
+error[E0491]: in type `&'a &'b ()`, reference has a longer lifetime than the data it references
+ --> $DIR/reference-outlives-referent.rs:7:18
+ |
+LL | const Q<'a, 'b>: &'a &'b () = &&();
+ | ^^^^^^^^^^
+ |
+note: the pointer is valid for the lifetime `'a` as defined here
+ --> $DIR/reference-outlives-referent.rs:7:9
+ |
+LL | const Q<'a, 'b>: &'a &'b () = &&();
+ | ^^
+note: but the referenced data is only valid for the lifetime `'b` as defined here
+ --> $DIR/reference-outlives-referent.rs:7:13
+ |
+LL | const Q<'a, 'b>: &'a &'b () = &&();
+ | ^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0491`.
diff --git a/tests/ui/generic-const-items/trivially-unsatisfied-bounds-0.rs b/tests/ui/generic-const-items/trivially-unsatisfied-bounds-0.rs
new file mode 100644
index 000000000..dd00b327d
--- /dev/null
+++ b/tests/ui/generic-const-items/trivially-unsatisfied-bounds-0.rs
@@ -0,0 +1,12 @@
+#![feature(generic_const_items, trivial_bounds)]
+#![allow(incomplete_features)]
+
+// Ensure that we check if trivial bounds on const items hold or not.
+
+const UNUSABLE: () = ()
+where
+ String: Copy;
+
+fn main() {
+ let _ = UNUSABLE; //~ ERROR the trait bound `String: Copy` is not satisfied
+}
diff --git a/tests/ui/generic-const-items/trivially-unsatisfied-bounds-0.stderr b/tests/ui/generic-const-items/trivially-unsatisfied-bounds-0.stderr
new file mode 100644
index 000000000..c3ef94529
--- /dev/null
+++ b/tests/ui/generic-const-items/trivially-unsatisfied-bounds-0.stderr
@@ -0,0 +1,18 @@
+error[E0277]: the trait bound `String: Copy` is not satisfied
+ --> $DIR/trivially-unsatisfied-bounds-0.rs:11:13
+ |
+LL | let _ = UNUSABLE;
+ | ^^^^^^^^ the trait `Copy` is not implemented for `String`
+ |
+note: required by a bound in `UNUSABLE`
+ --> $DIR/trivially-unsatisfied-bounds-0.rs:8:13
+ |
+LL | const UNUSABLE: () = ()
+ | -------- required by a bound in this constant
+LL | where
+LL | String: Copy;
+ | ^^^^ required by this bound in `UNUSABLE`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/generic-const-items/trivially-unsatisfied-bounds-1.rs b/tests/ui/generic-const-items/trivially-unsatisfied-bounds-1.rs
new file mode 100644
index 000000000..9243deac8
--- /dev/null
+++ b/tests/ui/generic-const-items/trivially-unsatisfied-bounds-1.rs
@@ -0,0 +1,12 @@
+#![feature(generic_const_items, trivial_bounds)]
+#![allow(incomplete_features, dead_code, trivial_bounds)]
+
+// FIXME(generic_const_items): This looks like a bug to me. I expected that we wouldn't emit any
+// errors. I thought we'd skip the evaluation of consts whose bounds don't hold.
+
+const UNUSED: () = ()
+where
+ String: Copy;
+//~^^^ ERROR evaluation of constant value failed
+
+fn main() {}
diff --git a/tests/ui/generic-const-items/trivially-unsatisfied-bounds-1.stderr b/tests/ui/generic-const-items/trivially-unsatisfied-bounds-1.stderr
new file mode 100644
index 000000000..a68400798
--- /dev/null
+++ b/tests/ui/generic-const-items/trivially-unsatisfied-bounds-1.stderr
@@ -0,0 +1,11 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/trivially-unsatisfied-bounds-1.rs:7:1
+ |
+LL | / const UNUSED: () = ()
+LL | | where
+LL | | String: Copy;
+ | |_________________^ entering unreachable code
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/generic-const-items/unsatisfied-bounds.rs b/tests/ui/generic-const-items/unsatisfied-bounds.rs
new file mode 100644
index 000000000..058799001
--- /dev/null
+++ b/tests/ui/generic-const-items/unsatisfied-bounds.rs
@@ -0,0 +1,34 @@
+#![feature(generic_const_items)]
+#![allow(incomplete_features)]
+
+// Ensure that we check if bounds on const items hold or not.
+
+use std::convert::Infallible;
+
+const C<T: Copy>: () = ();
+
+const K<T>: () = ()
+where
+ Infallible: From<T>;
+
+trait Trait<P> {
+ const A: u32
+ where
+ P: Copy;
+
+ const B<T>: u32
+ where
+ Infallible: From<T>;
+}
+
+impl<P> Trait<P> for () {
+ const A: u32 = 0;
+ const B<T>: u32 = 1;
+}
+
+fn main() {
+ let () = C::<String>; //~ ERROR the trait bound `String: Copy` is not satisfied
+ let () = K::<()>; //~ ERROR the trait bound `Infallible: From<()>` is not satisfied
+ let _ = <() as Trait<Vec<u8>>>::A; //~ ERROR the trait bound `Vec<u8>: Copy` is not satisfied
+ let _ = <() as Trait<&'static str>>::B::<()>; //~ ERROR the trait bound `Infallible: From<()>` is not satisfied
+}
diff --git a/tests/ui/generic-const-items/unsatisfied-bounds.stderr b/tests/ui/generic-const-items/unsatisfied-bounds.stderr
new file mode 100644
index 000000000..1fda46037
--- /dev/null
+++ b/tests/ui/generic-const-items/unsatisfied-bounds.stderr
@@ -0,0 +1,62 @@
+error[E0277]: the trait bound `String: Copy` is not satisfied
+ --> $DIR/unsatisfied-bounds.rs:30:18
+ |
+LL | let () = C::<String>;
+ | ^^^^^^ the trait `Copy` is not implemented for `String`
+ |
+note: required by a bound in `C`
+ --> $DIR/unsatisfied-bounds.rs:8:12
+ |
+LL | const C<T: Copy>: () = ();
+ | ^^^^ required by this bound in `C`
+
+error[E0277]: the trait bound `Infallible: From<()>` is not satisfied
+ --> $DIR/unsatisfied-bounds.rs:31:18
+ |
+LL | let () = K::<()>;
+ | ^^ the trait `From<()>` is not implemented for `Infallible`
+ |
+ = help: the trait `From<!>` is implemented for `Infallible`
+note: required by a bound in `K`
+ --> $DIR/unsatisfied-bounds.rs:12:17
+ |
+LL | const K<T>: () = ()
+ | - required by a bound in this constant
+LL | where
+LL | Infallible: From<T>;
+ | ^^^^^^^ required by this bound in `K`
+
+error[E0277]: the trait bound `Vec<u8>: Copy` is not satisfied
+ --> $DIR/unsatisfied-bounds.rs:32:13
+ |
+LL | let _ = <() as Trait<Vec<u8>>>::A;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Vec<u8>`
+ |
+note: required by a bound in `Trait::A`
+ --> $DIR/unsatisfied-bounds.rs:17:12
+ |
+LL | const A: u32
+ | - required by a bound in this associated constant
+LL | where
+LL | P: Copy;
+ | ^^^^ required by this bound in `Trait::A`
+
+error[E0277]: the trait bound `Infallible: From<()>` is not satisfied
+ --> $DIR/unsatisfied-bounds.rs:33:46
+ |
+LL | let _ = <() as Trait<&'static str>>::B::<()>;
+ | ^^ the trait `From<()>` is not implemented for `Infallible`
+ |
+ = help: the trait `From<!>` is implemented for `Infallible`
+note: required by a bound in `Trait::B`
+ --> $DIR/unsatisfied-bounds.rs:21:21
+ |
+LL | const B<T>: u32
+ | - required by a bound in this associated constant
+LL | where
+LL | Infallible: From<T>;
+ | ^^^^^^^ required by this bound in `Trait::B`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/generic-const-items/unsatisfied-evaluatable-bounds.rs b/tests/ui/generic-const-items/unsatisfied-evaluatable-bounds.rs
new file mode 100644
index 000000000..961e5b4ae
--- /dev/null
+++ b/tests/ui/generic-const-items/unsatisfied-evaluatable-bounds.rs
@@ -0,0 +1,12 @@
+#![feature(generic_const_items, generic_const_exprs)]
+#![allow(incomplete_features)]
+
+// Ensure that we check if (makeshift) "evaluatable"-bounds on const items hold or not.
+
+const POSITIVE<const N: usize>: usize = N
+where
+ [(); N - 1]:; //~ ERROR evaluation of `POSITIVE::<0>::{constant#0}` failed
+
+fn main() {
+ let _ = POSITIVE::<0>;
+}
diff --git a/tests/ui/generic-const-items/unsatisfied-evaluatable-bounds.stderr b/tests/ui/generic-const-items/unsatisfied-evaluatable-bounds.stderr
new file mode 100644
index 000000000..bed213b0c
--- /dev/null
+++ b/tests/ui/generic-const-items/unsatisfied-evaluatable-bounds.stderr
@@ -0,0 +1,9 @@
+error[E0080]: evaluation of `POSITIVE::<0>::{constant#0}` failed
+ --> $DIR/unsatisfied-evaluatable-bounds.rs:8:10
+ |
+LL | [(); N - 1]:;
+ | ^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/generic-const-items/unsatisfied-outlives-bounds.rs b/tests/ui/generic-const-items/unsatisfied-outlives-bounds.rs
new file mode 100644
index 000000000..204cf9def
--- /dev/null
+++ b/tests/ui/generic-const-items/unsatisfied-outlives-bounds.rs
@@ -0,0 +1,17 @@
+#![feature(generic_const_items)]
+#![allow(incomplete_features)]
+
+// Ensure that we check if outlives-bounds on const items hold or not.
+
+const C<'a, T: 'a>: () = ();
+const K<'a, 'b: 'a>: () = ();
+
+fn parametrized0<'any>() {
+ let () = C::<'static, &'any ()>; //~ ERROR lifetime may not live long enough
+}
+
+fn parametrized1<'any>() {
+ let () = K::<'static, 'any>; //~ ERROR lifetime may not live long enough
+}
+
+fn main() {}
diff --git a/tests/ui/generic-const-items/unsatisfied-outlives-bounds.stderr b/tests/ui/generic-const-items/unsatisfied-outlives-bounds.stderr
new file mode 100644
index 000000000..72e4265b3
--- /dev/null
+++ b/tests/ui/generic-const-items/unsatisfied-outlives-bounds.stderr
@@ -0,0 +1,18 @@
+error: lifetime may not live long enough
+ --> $DIR/unsatisfied-outlives-bounds.rs:10:14
+ |
+LL | fn parametrized0<'any>() {
+ | ---- lifetime `'any` defined here
+LL | let () = C::<'static, &'any ()>;
+ | ^^^^^^^^^^^^^^^^^^^^^^ requires that `'any` must outlive `'static`
+
+error: lifetime may not live long enough
+ --> $DIR/unsatisfied-outlives-bounds.rs:14:14
+ |
+LL | fn parametrized1<'any>() {
+ | ---- lifetime `'any` defined here
+LL | let () = K::<'static, 'any>;
+ | ^^^^^^^^^^^^^^^^^^ requires that `'any` must outlive `'static`
+
+error: aborting due to 2 previous errors
+