summaryrefslogtreecommitdiffstats
path: root/src/test/ui/const-generics/min_const_generics
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /src/test/ui/const-generics/min_const_generics
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/test/ui/const-generics/min_const_generics')
-rw-r--r--src/test/ui/const-generics/min_const_generics/assoc_const.rs16
-rw-r--r--src/test/ui/const-generics/min_const_generics/complex-expression.rs47
-rw-r--r--src/test/ui/const-generics/min_const_generics/complex-expression.stderr75
-rw-r--r--src/test/ui/const-generics/min_const_generics/complex-types.rs27
-rw-r--r--src/test/ui/const-generics/min_const_generics/complex-types.stderr65
-rw-r--r--src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.rs34
-rw-r--r--src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.stderr30
-rw-r--r--src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces-without-turbofish.rs47
-rw-r--r--src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces-without-turbofish.stderr140
-rw-r--r--src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.rs51
-rw-r--r--src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.stderr143
-rw-r--r--src/test/ui/const-generics/min_const_generics/const_default_first.rs7
-rw-r--r--src/test/ui/const-generics/min_const_generics/const_default_first.stderr8
-rw-r--r--src/test/ui/const-generics/min_const_generics/const_fn_in_generics.rs15
-rw-r--r--src/test/ui/const-generics/min_const_generics/default_function_param.rs4
-rw-r--r--src/test/ui/const-generics/min_const_generics/default_function_param.stderr8
-rw-r--r--src/test/ui/const-generics/min_const_generics/default_trait_param.rs4
-rw-r--r--src/test/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.rs25
-rw-r--r--src/test/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.stderr21
-rw-r--r--src/test/ui/const-generics/min_const_generics/forbid-self-no-normalize.rs15
-rw-r--r--src/test/ui/const-generics/min_const_generics/forbid-self-no-normalize.stderr14
-rw-r--r--src/test/ui/const-generics/min_const_generics/inferred_const.rs9
-rw-r--r--src/test/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr72
-rw-r--r--src/test/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr72
-rw-r--r--src/test/ui/const-generics/min_const_generics/invalid-patterns.rs45
-rw-r--r--src/test/ui/const-generics/min_const_generics/macro-fail.rs42
-rw-r--r--src/test/ui/const-generics/min_const_generics/macro-fail.stderr83
-rw-r--r--src/test/ui/const-generics/min_const_generics/macro.rs55
-rw-r--r--src/test/ui/const-generics/min_const_generics/self-ty-in-const-1.rs25
-rw-r--r--src/test/ui/const-generics/min_const_generics/self-ty-in-const-1.stderr23
-rw-r--r--src/test/ui/const-generics/min_const_generics/self-ty-in-const-2.rs19
-rw-r--r--src/test/ui/const-generics/min_const_generics/self-ty-in-const-2.stderr14
-rw-r--r--src/test/ui/const-generics/min_const_generics/type_and_const_defaults.rs25
33 files changed, 1280 insertions, 0 deletions
diff --git a/src/test/ui/const-generics/min_const_generics/assoc_const.rs b/src/test/ui/const-generics/min_const_generics/assoc_const.rs
new file mode 100644
index 000000000..27e971b5b
--- /dev/null
+++ b/src/test/ui/const-generics/min_const_generics/assoc_const.rs
@@ -0,0 +1,16 @@
+// check-pass
+struct Foo<const N: usize>;
+
+impl<const N: usize> Foo<N> {
+ const VALUE: usize = N * 2;
+}
+
+trait Bar {
+ const ASSOC: usize;
+}
+
+impl<const N: usize> Bar for Foo<N> {
+ const ASSOC: usize = N * 3;
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/min_const_generics/complex-expression.rs b/src/test/ui/const-generics/min_const_generics/complex-expression.rs
new file mode 100644
index 000000000..7840989cb
--- /dev/null
+++ b/src/test/ui/const-generics/min_const_generics/complex-expression.rs
@@ -0,0 +1,47 @@
+use std::mem::size_of;
+
+fn test<const N: usize>() {}
+
+fn ok<const M: usize>() -> [u8; M] {
+ [0; { M }]
+}
+
+struct Break0<const N: usize>([u8; { N + 1 }]);
+//~^ ERROR generic parameters may not be used in const operations
+
+struct Break1<const N: usize>([u8; { { N } }]);
+//~^ ERROR generic parameters may not be used in const operations
+
+fn break2<const N: usize>() {
+ let _: [u8; N + 1];
+ //~^ ERROR generic parameters may not be used in const operations
+}
+
+fn break3<const N: usize>() {
+ let _ = [0; N + 1];
+ //~^ ERROR generic parameters may not be used in const operations
+}
+
+struct BreakTy0<T>(T, [u8; { size_of::<*mut T>() }]);
+//~^ ERROR generic parameters may not be used in const operations
+
+struct BreakTy1<T>(T, [u8; { { size_of::<*mut T>() } }]);
+//~^ ERROR generic parameters may not be used in const operations
+
+fn break_ty2<T>() {
+ let _: [u8; size_of::<*mut T>() + 1];
+ //~^ ERROR generic parameters may not be used in const operations
+}
+
+fn break_ty3<T>() {
+ let _ = [0; size_of::<*mut T>() + 1];
+ //~^ WARN cannot use constants which depend on generic parameters in types
+ //~| WARN this was previously accepted by the compiler but is being phased out
+}
+
+
+trait Foo {
+ const ASSOC: usize;
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/min_const_generics/complex-expression.stderr b/src/test/ui/const-generics/min_const_generics/complex-expression.stderr
new file mode 100644
index 000000000..bf0d0f352
--- /dev/null
+++ b/src/test/ui/const-generics/min_const_generics/complex-expression.stderr
@@ -0,0 +1,75 @@
+error: generic parameters may not be used in const operations
+ --> $DIR/complex-expression.rs:9:38
+ |
+LL | struct Break0<const N: usize>([u8; { N + 1 }]);
+ | ^ cannot perform const operation using `N`
+ |
+ = help: const parameters may only be used as standalone arguments, i.e. `N`
+ = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+
+error: generic parameters may not be used in const operations
+ --> $DIR/complex-expression.rs:12:40
+ |
+LL | struct Break1<const N: usize>([u8; { { N } }]);
+ | ^ cannot perform const operation using `N`
+ |
+ = help: const parameters may only be used as standalone arguments, i.e. `N`
+ = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+
+error: generic parameters may not be used in const operations
+ --> $DIR/complex-expression.rs:16:17
+ |
+LL | let _: [u8; N + 1];
+ | ^ cannot perform const operation using `N`
+ |
+ = help: const parameters may only be used as standalone arguments, i.e. `N`
+ = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+
+error: generic parameters may not be used in const operations
+ --> $DIR/complex-expression.rs:21:17
+ |
+LL | let _ = [0; N + 1];
+ | ^ cannot perform const operation using `N`
+ |
+ = help: const parameters may only be used as standalone arguments, i.e. `N`
+ = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+
+error: generic parameters may not be used in const operations
+ --> $DIR/complex-expression.rs:25:45
+ |
+LL | struct BreakTy0<T>(T, [u8; { size_of::<*mut T>() }]);
+ | ^ cannot perform const operation using `T`
+ |
+ = note: type parameters may not be used in const expressions
+ = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+
+error: generic parameters may not be used in const operations
+ --> $DIR/complex-expression.rs:28:47
+ |
+LL | struct BreakTy1<T>(T, [u8; { { size_of::<*mut T>() } }]);
+ | ^ cannot perform const operation using `T`
+ |
+ = note: type parameters may not be used in const expressions
+ = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+
+error: generic parameters may not be used in const operations
+ --> $DIR/complex-expression.rs:32:32
+ |
+LL | let _: [u8; size_of::<*mut T>() + 1];
+ | ^ cannot perform const operation using `T`
+ |
+ = note: type parameters may not be used in const expressions
+ = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+
+warning: cannot use constants which depend on generic parameters in types
+ --> $DIR/complex-expression.rs:37:17
+ |
+LL | let _ = [0; size_of::<*mut T>() + 1];
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(const_evaluatable_unchecked)]` on by default
+ = 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 #76200 <https://github.com/rust-lang/rust/issues/76200>
+
+error: aborting due to 7 previous errors; 1 warning emitted
+
diff --git a/src/test/ui/const-generics/min_const_generics/complex-types.rs b/src/test/ui/const-generics/min_const_generics/complex-types.rs
new file mode 100644
index 000000000..057bd5af8
--- /dev/null
+++ b/src/test/ui/const-generics/min_const_generics/complex-types.rs
@@ -0,0 +1,27 @@
+#![feature(never_type)]
+
+struct Foo<const N: [u8; 0]>;
+//~^ ERROR `[u8; 0]` is forbidden
+
+struct Bar<const N: ()>;
+//~^ ERROR `()` is forbidden
+#[derive(PartialEq, Eq)]
+struct No;
+
+struct Fez<const N: No>;
+//~^ ERROR `No` is forbidden
+
+struct Faz<const N: &'static u8>;
+//~^ ERROR `&'static u8` is forbidden
+
+struct Fiz<const N: !>;
+//~^ ERROR `!` is forbidden
+
+enum Goo<const N: ()> { A, B }
+//~^ ERROR `()` is forbidden
+
+union Boo<const N: ()> { a: () }
+//~^ ERROR `()` is forbidden
+
+
+fn main() {}
diff --git a/src/test/ui/const-generics/min_const_generics/complex-types.stderr b/src/test/ui/const-generics/min_const_generics/complex-types.stderr
new file mode 100644
index 000000000..4ddbadb54
--- /dev/null
+++ b/src/test/ui/const-generics/min_const_generics/complex-types.stderr
@@ -0,0 +1,65 @@
+error: `[u8; 0]` is forbidden as the type of a const generic parameter
+ --> $DIR/complex-types.rs:3:21
+ |
+LL | struct Foo<const N: [u8; 0]>;
+ | ^^^^^^^
+ |
+ = note: the only supported types are integers, `bool` and `char`
+ = help: more complex types are supported with `#![feature(adt_const_params)]`
+
+error: `()` is forbidden as the type of a const generic parameter
+ --> $DIR/complex-types.rs:6:21
+ |
+LL | struct Bar<const N: ()>;
+ | ^^
+ |
+ = note: the only supported types are integers, `bool` and `char`
+ = help: more complex types are supported with `#![feature(adt_const_params)]`
+
+error: `No` is forbidden as the type of a const generic parameter
+ --> $DIR/complex-types.rs:11:21
+ |
+LL | struct Fez<const N: No>;
+ | ^^
+ |
+ = note: the only supported types are integers, `bool` and `char`
+ = help: more complex types are supported with `#![feature(adt_const_params)]`
+
+error: `&'static u8` is forbidden as the type of a const generic parameter
+ --> $DIR/complex-types.rs:14:21
+ |
+LL | struct Faz<const N: &'static u8>;
+ | ^^^^^^^^^^^
+ |
+ = note: the only supported types are integers, `bool` and `char`
+ = help: more complex types are supported with `#![feature(adt_const_params)]`
+
+error: `!` is forbidden as the type of a const generic parameter
+ --> $DIR/complex-types.rs:17:21
+ |
+LL | struct Fiz<const N: !>;
+ | ^
+ |
+ = note: the only supported types are integers, `bool` and `char`
+ = help: more complex types are supported with `#![feature(adt_const_params)]`
+
+error: `()` is forbidden as the type of a const generic parameter
+ --> $DIR/complex-types.rs:20:19
+ |
+LL | enum Goo<const N: ()> { A, B }
+ | ^^
+ |
+ = note: the only supported types are integers, `bool` and `char`
+ = help: more complex types are supported with `#![feature(adt_const_params)]`
+
+error: `()` is forbidden as the type of a const generic parameter
+ --> $DIR/complex-types.rs:23:20
+ |
+LL | union Boo<const N: ()> { a: () }
+ | ^^
+ |
+ = 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 7 previous errors
+
diff --git a/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.rs b/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.rs
new file mode 100644
index 000000000..71d13ca61
--- /dev/null
+++ b/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.rs
@@ -0,0 +1,34 @@
+// check-pass
+#![allow(dead_code)]
+
+fn foo<T>() {
+ [0; std::mem::size_of::<*mut T>()];
+ //~^ WARN cannot use constants which depend on generic parameters in types
+ //~| WARN this was previously accepted by the compiler but is being phased out
+}
+
+struct Foo<T>(T);
+
+impl<T> Foo<T> {
+ const ASSOC: usize = 4;
+
+ fn test() {
+ let _ = [0; Self::ASSOC];
+ //~^ WARN cannot use constants which depend on generic parameters in types
+ //~| WARN this was previously accepted by the compiler but is being phased out
+ }
+}
+
+struct Bar<const N: usize>;
+
+impl<const N: usize> Bar<N> {
+ const ASSOC: usize = 4;
+
+ fn test() {
+ let _ = [0; Self::ASSOC];
+ //~^ WARN cannot use constants which depend on generic parameters in types
+ //~| WARN this was previously accepted by the compiler but is being phased out
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.stderr b/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.stderr
new file mode 100644
index 000000000..f9f6660f6
--- /dev/null
+++ b/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.stderr
@@ -0,0 +1,30 @@
+warning: cannot use constants which depend on generic parameters in types
+ --> $DIR/const-evaluatable-unchecked.rs:5:9
+ |
+LL | [0; std::mem::size_of::<*mut T>()];
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(const_evaluatable_unchecked)]` on by default
+ = 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 #76200 <https://github.com/rust-lang/rust/issues/76200>
+
+warning: cannot use constants which depend on generic parameters in types
+ --> $DIR/const-evaluatable-unchecked.rs:16:21
+ |
+LL | let _ = [0; Self::ASSOC];
+ | ^^^^^^^^^^^
+ |
+ = 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 #76200 <https://github.com/rust-lang/rust/issues/76200>
+
+warning: cannot use constants which depend on generic parameters in types
+ --> $DIR/const-evaluatable-unchecked.rs:28:21
+ |
+LL | let _ = [0; Self::ASSOC];
+ | ^^^^^^^^^^^
+ |
+ = 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 #76200 <https://github.com/rust-lang/rust/issues/76200>
+
+warning: 3 warnings emitted
+
diff --git a/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces-without-turbofish.rs b/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces-without-turbofish.rs
new file mode 100644
index 000000000..fac3777cf
--- /dev/null
+++ b/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces-without-turbofish.rs
@@ -0,0 +1,47 @@
+fn foo<const C: usize>() {}
+
+const BAR: usize = 42;
+
+fn a() {
+ foo<BAR + 3>(); //~ ERROR comparison operators cannot be chained
+}
+fn b() {
+ foo<BAR + BAR>(); //~ ERROR comparison operators cannot be chained
+}
+fn c() {
+ foo<3 + 3>(); //~ ERROR comparison operators cannot be chained
+}
+fn d() {
+ foo<BAR - 3>(); //~ ERROR comparison operators cannot be chained
+}
+fn e() {
+ foo<BAR - BAR>(); //~ ERROR comparison operators cannot be chained
+}
+fn f() {
+ foo<100 - BAR>(); //~ ERROR comparison operators cannot be chained
+}
+fn g() {
+ foo<bar<i32>()>(); //~ ERROR comparison operators cannot be chained
+ //~^ ERROR expected one of `;` or `}`, found `>`
+}
+fn h() {
+ foo<bar::<i32>()>(); //~ ERROR comparison operators cannot be chained
+}
+fn i() {
+ foo<bar::<i32>() + BAR>(); //~ ERROR comparison operators cannot be chained
+}
+fn j() {
+ foo<bar::<i32>() - BAR>(); //~ ERROR comparison operators cannot be chained
+}
+fn k() {
+ foo<BAR - bar::<i32>()>(); //~ ERROR comparison operators cannot be chained
+}
+fn l() {
+ foo<BAR - bar::<i32>()>(); //~ ERROR comparison operators cannot be chained
+}
+
+const fn bar<const C: usize>() -> usize {
+ C
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces-without-turbofish.stderr b/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces-without-turbofish.stderr
new file mode 100644
index 000000000..a6825b845
--- /dev/null
+++ b/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces-without-turbofish.stderr
@@ -0,0 +1,140 @@
+error: comparison operators cannot be chained
+ --> $DIR/const-expression-suggest-missing-braces-without-turbofish.rs:6:8
+ |
+LL | foo<BAR + 3>();
+ | ^ ^
+ |
+help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
+ |
+LL | foo::<BAR + 3>();
+ | ++
+
+error: comparison operators cannot be chained
+ --> $DIR/const-expression-suggest-missing-braces-without-turbofish.rs:9:8
+ |
+LL | foo<BAR + BAR>();
+ | ^ ^
+ |
+help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
+ |
+LL | foo::<BAR + BAR>();
+ | ++
+
+error: comparison operators cannot be chained
+ --> $DIR/const-expression-suggest-missing-braces-without-turbofish.rs:12:8
+ |
+LL | foo<3 + 3>();
+ | ^ ^
+ |
+help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
+ |
+LL | foo::<3 + 3>();
+ | ++
+
+error: comparison operators cannot be chained
+ --> $DIR/const-expression-suggest-missing-braces-without-turbofish.rs:15:8
+ |
+LL | foo<BAR - 3>();
+ | ^ ^
+ |
+help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
+ |
+LL | foo::<BAR - 3>();
+ | ++
+
+error: comparison operators cannot be chained
+ --> $DIR/const-expression-suggest-missing-braces-without-turbofish.rs:18:8
+ |
+LL | foo<BAR - BAR>();
+ | ^ ^
+ |
+help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
+ |
+LL | foo::<BAR - BAR>();
+ | ++
+
+error: comparison operators cannot be chained
+ --> $DIR/const-expression-suggest-missing-braces-without-turbofish.rs:21:8
+ |
+LL | foo<100 - BAR>();
+ | ^ ^
+ |
+help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
+ |
+LL | foo::<100 - BAR>();
+ | ++
+
+error: comparison operators cannot be chained
+ --> $DIR/const-expression-suggest-missing-braces-without-turbofish.rs:24:8
+ |
+LL | foo<bar<i32>()>();
+ | ^ ^
+ |
+help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
+ |
+LL | foo::<bar<i32>()>();
+ | ++
+
+error: expected one of `;` or `}`, found `>`
+ --> $DIR/const-expression-suggest-missing-braces-without-turbofish.rs:24:19
+ |
+LL | foo<bar<i32>()>();
+ | ^ expected one of `;` or `}`
+
+error: comparison operators cannot be chained
+ --> $DIR/const-expression-suggest-missing-braces-without-turbofish.rs:28:8
+ |
+LL | foo<bar::<i32>()>();
+ | ^ ^
+ |
+help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
+ |
+LL | foo::<bar::<i32>()>();
+ | ++
+
+error: comparison operators cannot be chained
+ --> $DIR/const-expression-suggest-missing-braces-without-turbofish.rs:31:8
+ |
+LL | foo<bar::<i32>() + BAR>();
+ | ^ ^
+ |
+help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
+ |
+LL | foo::<bar::<i32>() + BAR>();
+ | ++
+
+error: comparison operators cannot be chained
+ --> $DIR/const-expression-suggest-missing-braces-without-turbofish.rs:34:8
+ |
+LL | foo<bar::<i32>() - BAR>();
+ | ^ ^
+ |
+help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
+ |
+LL | foo::<bar::<i32>() - BAR>();
+ | ++
+
+error: comparison operators cannot be chained
+ --> $DIR/const-expression-suggest-missing-braces-without-turbofish.rs:37:8
+ |
+LL | foo<BAR - bar::<i32>()>();
+ | ^ ^
+ |
+help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
+ |
+LL | foo::<BAR - bar::<i32>()>();
+ | ++
+
+error: comparison operators cannot be chained
+ --> $DIR/const-expression-suggest-missing-braces-without-turbofish.rs:40:8
+ |
+LL | foo<BAR - bar::<i32>()>();
+ | ^ ^
+ |
+help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
+ |
+LL | foo::<BAR - bar::<i32>()>();
+ | ++
+
+error: aborting due to 13 previous errors
+
diff --git a/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.rs b/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.rs
new file mode 100644
index 000000000..e12e07a28
--- /dev/null
+++ b/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.rs
@@ -0,0 +1,51 @@
+fn foo<const C: usize>() {}
+
+const BAR: usize = 42;
+
+fn a() {
+ foo::<BAR + 3>(); //~ ERROR expected one of
+}
+fn b() {
+ // FIXME(const_generics): these diagnostics are awful, because trait objects without `dyn` were
+ // a terrible mistake.
+ foo::<BAR + BAR>();
+ //~^ ERROR expected trait, found constant `BAR`
+ //~| ERROR expected trait, found constant `BAR`
+ //~| ERROR type provided when a constant was expected
+}
+fn c() {
+ foo::<3 + 3>(); //~ ERROR expressions must be enclosed in braces
+}
+fn d() {
+ foo::<BAR - 3>(); //~ ERROR expected one of
+}
+fn e() {
+ foo::<BAR - BAR>(); //~ ERROR expected one of
+}
+fn f() {
+ foo::<100 - BAR>(); //~ ERROR expressions must be enclosed in braces
+}
+fn g() {
+ foo::<bar<i32>()>(); //~ ERROR expected one of
+}
+fn h() {
+ foo::<bar::<i32>()>(); //~ ERROR expected one of
+}
+fn i() {
+ foo::<bar::<i32>() + BAR>(); //~ ERROR expected one of
+}
+fn j() {
+ foo::<bar::<i32>() - BAR>(); //~ ERROR expected one of
+}
+fn k() {
+ foo::<BAR - bar::<i32>()>(); //~ ERROR expected one of
+}
+fn l() {
+ foo::<BAR - bar::<i32>()>(); //~ ERROR expected one of
+}
+
+const fn bar<const C: usize>() -> usize {
+ C
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.stderr b/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.stderr
new file mode 100644
index 000000000..d9bcc523b
--- /dev/null
+++ b/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.stderr
@@ -0,0 +1,143 @@
+error: expected one of `,` or `>`, found `3`
+ --> $DIR/const-expression-suggest-missing-braces.rs:6:17
+ |
+LL | foo::<BAR + 3>();
+ | ^ expected one of `,` or `>`
+ |
+help: expressions must be enclosed in braces to be used as const generic arguments
+ |
+LL | foo::<{ BAR + 3 }>();
+ | + +
+
+error: expressions must be enclosed in braces to be used as const generic arguments
+ --> $DIR/const-expression-suggest-missing-braces.rs:17:11
+ |
+LL | foo::<3 + 3>();
+ | ^^^^^
+ |
+help: enclose the `const` expression in braces
+ |
+LL | foo::<{ 3 + 3 }>();
+ | + +
+
+error: expected one of `,` or `>`, found `-`
+ --> $DIR/const-expression-suggest-missing-braces.rs:20:15
+ |
+LL | foo::<BAR - 3>();
+ | ^ expected one of `,` or `>`
+ |
+help: expressions must be enclosed in braces to be used as const generic arguments
+ |
+LL | foo::<{ BAR - 3 }>();
+ | + +
+
+error: expected one of `,` or `>`, found `-`
+ --> $DIR/const-expression-suggest-missing-braces.rs:23:15
+ |
+LL | foo::<BAR - BAR>();
+ | ^ expected one of `,` or `>`
+ |
+help: expressions must be enclosed in braces to be used as const generic arguments
+ |
+LL | foo::<{ BAR - BAR }>();
+ | + +
+
+error: expressions must be enclosed in braces to be used as const generic arguments
+ --> $DIR/const-expression-suggest-missing-braces.rs:26:11
+ |
+LL | foo::<100 - BAR>();
+ | ^^^^^^^^^
+ |
+help: enclose the `const` expression in braces
+ |
+LL | foo::<{ 100 - BAR }>();
+ | + +
+
+error: expected one of `,` or `>`, found `(`
+ --> $DIR/const-expression-suggest-missing-braces.rs:29:19
+ |
+LL | foo::<bar<i32>()>();
+ | ^ expected one of `,` or `>`
+ |
+help: expressions must be enclosed in braces to be used as const generic arguments
+ |
+LL | foo::<{ bar<i32>() }>();
+ | + +
+
+error: expected one of `,` or `>`, found `(`
+ --> $DIR/const-expression-suggest-missing-braces.rs:32:21
+ |
+LL | foo::<bar::<i32>()>();
+ | ^ expected one of `,` or `>`
+ |
+help: expressions must be enclosed in braces to be used as const generic arguments
+ |
+LL | foo::<{ bar::<i32>() }>();
+ | + +
+
+error: expected one of `,` or `>`, found `(`
+ --> $DIR/const-expression-suggest-missing-braces.rs:35:21
+ |
+LL | foo::<bar::<i32>() + BAR>();
+ | ^ expected one of `,` or `>`
+ |
+help: expressions must be enclosed in braces to be used as const generic arguments
+ |
+LL | foo::<{ bar::<i32>() + BAR }>();
+ | + +
+
+error: expected one of `,` or `>`, found `(`
+ --> $DIR/const-expression-suggest-missing-braces.rs:38:21
+ |
+LL | foo::<bar::<i32>() - BAR>();
+ | ^ expected one of `,` or `>`
+ |
+help: expressions must be enclosed in braces to be used as const generic arguments
+ |
+LL | foo::<{ bar::<i32>() - BAR }>();
+ | + +
+
+error: expected one of `,` or `>`, found `-`
+ --> $DIR/const-expression-suggest-missing-braces.rs:41:15
+ |
+LL | foo::<BAR - bar::<i32>()>();
+ | ^ expected one of `,` or `>`
+ |
+help: expressions must be enclosed in braces to be used as const generic arguments
+ |
+LL | foo::<{ BAR - bar::<i32>() }>();
+ | + +
+
+error: expected one of `,` or `>`, found `-`
+ --> $DIR/const-expression-suggest-missing-braces.rs:44:15
+ |
+LL | foo::<BAR - bar::<i32>()>();
+ | ^ expected one of `,` or `>`
+ |
+help: expressions must be enclosed in braces to be used as const generic arguments
+ |
+LL | foo::<{ BAR - bar::<i32>() }>();
+ | + +
+
+error[E0404]: expected trait, found constant `BAR`
+ --> $DIR/const-expression-suggest-missing-braces.rs:11:11
+ |
+LL | foo::<BAR + BAR>();
+ | ^^^ not a trait
+
+error[E0404]: expected trait, found constant `BAR`
+ --> $DIR/const-expression-suggest-missing-braces.rs:11:17
+ |
+LL | foo::<BAR + BAR>();
+ | ^^^ not a trait
+
+error[E0747]: type provided when a constant was expected
+ --> $DIR/const-expression-suggest-missing-braces.rs:11:11
+ |
+LL | foo::<BAR + BAR>();
+ | ^^^^^^^^^
+
+error: aborting due to 14 previous errors
+
+Some errors have detailed explanations: E0404, E0747.
+For more information about an error, try `rustc --explain E0404`.
diff --git a/src/test/ui/const-generics/min_const_generics/const_default_first.rs b/src/test/ui/const-generics/min_const_generics/const_default_first.rs
new file mode 100644
index 000000000..eafafb8a2
--- /dev/null
+++ b/src/test/ui/const-generics/min_const_generics/const_default_first.rs
@@ -0,0 +1,7 @@
+#![crate_type = "lib"]
+#![allow(dead_code)]
+
+struct Both<const N: usize=3, T> {
+//~^ ERROR: generic parameters with a default must be
+ v: T
+}
diff --git a/src/test/ui/const-generics/min_const_generics/const_default_first.stderr b/src/test/ui/const-generics/min_const_generics/const_default_first.stderr
new file mode 100644
index 000000000..0d5a393cb
--- /dev/null
+++ b/src/test/ui/const-generics/min_const_generics/const_default_first.stderr
@@ -0,0 +1,8 @@
+error: generic parameters with a default must be trailing
+ --> $DIR/const_default_first.rs:4:19
+ |
+LL | struct Both<const N: usize=3, T> {
+ | ^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/min_const_generics/const_fn_in_generics.rs b/src/test/ui/const-generics/min_const_generics/const_fn_in_generics.rs
new file mode 100644
index 000000000..0c10af6c4
--- /dev/null
+++ b/src/test/ui/const-generics/min_const_generics/const_fn_in_generics.rs
@@ -0,0 +1,15 @@
+// run-pass
+
+const fn identity<const T: u32>() -> u32 { T }
+
+#[derive(Eq, PartialEq, Debug)]
+pub struct ConstU32<const U: u32>;
+
+pub fn new() -> ConstU32<{ identity::<3>() }> {
+ ConstU32::<{ identity::<3>() }>
+}
+
+fn main() {
+ let v = new();
+ assert_eq!(v, ConstU32::<3>);
+}
diff --git a/src/test/ui/const-generics/min_const_generics/default_function_param.rs b/src/test/ui/const-generics/min_const_generics/default_function_param.rs
new file mode 100644
index 000000000..92d495ef6
--- /dev/null
+++ b/src/test/ui/const-generics/min_const_generics/default_function_param.rs
@@ -0,0 +1,4 @@
+#![crate_type = "lib"]
+
+fn foo<const SIZE: usize = 5usize>() {}
+//~^ ERROR defaults for const parameters are
diff --git a/src/test/ui/const-generics/min_const_generics/default_function_param.stderr b/src/test/ui/const-generics/min_const_generics/default_function_param.stderr
new file mode 100644
index 000000000..dedad2880
--- /dev/null
+++ b/src/test/ui/const-generics/min_const_generics/default_function_param.stderr
@@ -0,0 +1,8 @@
+error: defaults for const parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
+ --> $DIR/default_function_param.rs:3:8
+ |
+LL | fn foo<const SIZE: usize = 5usize>() {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/min_const_generics/default_trait_param.rs b/src/test/ui/const-generics/min_const_generics/default_trait_param.rs
new file mode 100644
index 000000000..9cd5e3279
--- /dev/null
+++ b/src/test/ui/const-generics/min_const_generics/default_trait_param.rs
@@ -0,0 +1,4 @@
+// check-pass
+trait Foo<const KIND: bool = true> {}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.rs b/src/test/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.rs
new file mode 100644
index 000000000..6215b7d93
--- /dev/null
+++ b/src/test/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.rs
@@ -0,0 +1,25 @@
+// This test checks that non-static lifetimes are prohibited under `min_const_generics`. It
+// currently emits an error with `min_const_generics`.
+
+fn test<const N: usize>() {}
+
+fn issue_75323_and_74447_1<'a>() -> &'a () {
+ test::<{ let _: &'a (); 3 },>();
+ //~^ ERROR a non-static lifetime is not allowed in a `const`
+ &()
+}
+
+fn issue_75323_and_74447_2() {
+ test::<{ let _: &(); 3 },>();
+}
+
+fn issue_75323_and_74447_3() {
+ test::<{ let _: &'static (); 3 },>();
+}
+
+fn issue_73375<'a>() {
+ [(); (|_: &'a u8| (), 0).1];
+ //~^ ERROR a non-static lifetime is not allowed in a `const`
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.stderr b/src/test/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.stderr
new file mode 100644
index 000000000..5f641b070
--- /dev/null
+++ b/src/test/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.stderr
@@ -0,0 +1,21 @@
+error[E0658]: a non-static lifetime is not allowed in a `const`
+ --> $DIR/forbid-non-static-lifetimes.rs:7:22
+ |
+LL | test::<{ let _: &'a (); 3 },>();
+ | ^^
+ |
+ = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
+ = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
+
+error[E0658]: a non-static lifetime is not allowed in a `const`
+ --> $DIR/forbid-non-static-lifetimes.rs:21:16
+ |
+LL | [(); (|_: &'a u8| (), 0).1];
+ | ^^
+ |
+ = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
+ = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/const-generics/min_const_generics/forbid-self-no-normalize.rs b/src/test/ui/const-generics/min_const_generics/forbid-self-no-normalize.rs
new file mode 100644
index 000000000..e1cf7b579
--- /dev/null
+++ b/src/test/ui/const-generics/min_const_generics/forbid-self-no-normalize.rs
@@ -0,0 +1,15 @@
+trait AlwaysApplicable {
+ type Assoc;
+}
+impl<T: ?Sized> AlwaysApplicable for T {
+ type Assoc = usize;
+}
+
+trait BindsParam<T> {
+ type ArrayTy;
+}
+impl<T> BindsParam<T> for <T as AlwaysApplicable>::Assoc {
+ type ArrayTy = [u8; Self::MAX]; //~ ERROR generic `Self` types
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/min_const_generics/forbid-self-no-normalize.stderr b/src/test/ui/const-generics/min_const_generics/forbid-self-no-normalize.stderr
new file mode 100644
index 000000000..bda885970
--- /dev/null
+++ b/src/test/ui/const-generics/min_const_generics/forbid-self-no-normalize.stderr
@@ -0,0 +1,14 @@
+error: generic `Self` types are currently not permitted in anonymous constants
+ --> $DIR/forbid-self-no-normalize.rs:12:25
+ |
+LL | type ArrayTy = [u8; Self::MAX];
+ | ^^^^
+ |
+note: not a concrete type
+ --> $DIR/forbid-self-no-normalize.rs:11:27
+ |
+LL | impl<T> BindsParam<T> for <T as AlwaysApplicable>::Assoc {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/min_const_generics/inferred_const.rs b/src/test/ui/const-generics/min_const_generics/inferred_const.rs
new file mode 100644
index 000000000..57d694158
--- /dev/null
+++ b/src/test/ui/const-generics/min_const_generics/inferred_const.rs
@@ -0,0 +1,9 @@
+#![feature(generic_arg_infer)]
+// run-pass
+
+fn foo<const N: usize, const K: usize>(_data: [u32; N]) -> [u32; K] {
+ [0; K]
+}
+fn main() {
+ let _a = foo::<_, 2>([0, 1, 2]);
+}
diff --git a/src/test/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr b/src/test/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr
new file mode 100644
index 000000000..f5396b838
--- /dev/null
+++ b/src/test/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr
@@ -0,0 +1,72 @@
+error[E0308]: mismatched types
+ --> $DIR/invalid-patterns.rs:29:21
+ |
+LL | get_flag::<false, 0xFF>();
+ | ^^^^ expected `char`, found `u8`
+
+error[E0308]: mismatched types
+ --> $DIR/invalid-patterns.rs:31:14
+ |
+LL | get_flag::<7, 'c'>();
+ | ^ expected `bool`, found integer
+
+error[E0308]: mismatched types
+ --> $DIR/invalid-patterns.rs:33:14
+ |
+LL | get_flag::<42, 0x5ad>();
+ | ^^ expected `bool`, found integer
+
+error[E0308]: mismatched types
+ --> $DIR/invalid-patterns.rs:33:18
+ |
+LL | get_flag::<42, 0x5ad>();
+ | ^^^^^ expected `char`, found `u8`
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/invalid-patterns.rs:38:21
+ |
+LL | get_flag::<false, { unsafe { char_raw.character } }>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 4, align: 4) {
+ __ __ __ __ │ ░░░░
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/invalid-patterns.rs:40:14
+ |
+LL | get_flag::<{ unsafe { bool_raw.boolean } }, 'z'>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x42, but expected a boolean
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 1, align: 1) {
+ 42 │ B
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/invalid-patterns.rs:42:14
+ |
+LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x42, but expected a boolean
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 1, align: 1) {
+ 42 │ B
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/invalid-patterns.rs:42:47
+ |
+LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 4, align: 4) {
+ __ __ __ __ │ ░░░░
+ }
+
+error: aborting due to 8 previous errors
+
+Some errors have detailed explanations: E0080, E0308.
+For more information about an error, try `rustc --explain E0080`.
diff --git a/src/test/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr b/src/test/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr
new file mode 100644
index 000000000..f5396b838
--- /dev/null
+++ b/src/test/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr
@@ -0,0 +1,72 @@
+error[E0308]: mismatched types
+ --> $DIR/invalid-patterns.rs:29:21
+ |
+LL | get_flag::<false, 0xFF>();
+ | ^^^^ expected `char`, found `u8`
+
+error[E0308]: mismatched types
+ --> $DIR/invalid-patterns.rs:31:14
+ |
+LL | get_flag::<7, 'c'>();
+ | ^ expected `bool`, found integer
+
+error[E0308]: mismatched types
+ --> $DIR/invalid-patterns.rs:33:14
+ |
+LL | get_flag::<42, 0x5ad>();
+ | ^^ expected `bool`, found integer
+
+error[E0308]: mismatched types
+ --> $DIR/invalid-patterns.rs:33:18
+ |
+LL | get_flag::<42, 0x5ad>();
+ | ^^^^^ expected `char`, found `u8`
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/invalid-patterns.rs:38:21
+ |
+LL | get_flag::<false, { unsafe { char_raw.character } }>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 4, align: 4) {
+ __ __ __ __ │ ░░░░
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/invalid-patterns.rs:40:14
+ |
+LL | get_flag::<{ unsafe { bool_raw.boolean } }, 'z'>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x42, but expected a boolean
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 1, align: 1) {
+ 42 │ B
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/invalid-patterns.rs:42:14
+ |
+LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x42, but expected a boolean
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 1, align: 1) {
+ 42 │ B
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/invalid-patterns.rs:42:47
+ |
+LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered uninitialized bytes, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 4, align: 4) {
+ __ __ __ __ │ ░░░░
+ }
+
+error: aborting due to 8 previous errors
+
+Some errors have detailed explanations: E0080, E0308.
+For more information about an error, try `rustc --explain E0080`.
diff --git a/src/test/ui/const-generics/min_const_generics/invalid-patterns.rs b/src/test/ui/const-generics/min_const_generics/invalid-patterns.rs
new file mode 100644
index 000000000..682e0eced
--- /dev/null
+++ b/src/test/ui/const-generics/min_const_generics/invalid-patterns.rs
@@ -0,0 +1,45 @@
+// stderr-per-bitwidth
+use std::mem::transmute;
+
+fn get_flag<const FlagSet: bool, const ShortName: char>() -> Option<char> {
+ if FlagSet {
+ Some(ShortName)
+ } else {
+ None
+ }
+}
+
+union CharRaw {
+ byte: u8,
+ character: char,
+}
+
+union BoolRaw {
+ byte: u8,
+ boolean: bool,
+}
+
+const char_raw: CharRaw = CharRaw { byte: 0xFF };
+const bool_raw: BoolRaw = BoolRaw { byte: 0x42 };
+
+fn main() {
+ // Test that basic cases don't work
+ assert!(get_flag::<true, 'c'>().is_some());
+ assert!(get_flag::<false, 'x'>().is_none());
+ get_flag::<false, 0xFF>();
+ //~^ ERROR mismatched types
+ get_flag::<7, 'c'>();
+ //~^ ERROR mismatched types
+ get_flag::<42, 0x5ad>();
+ //~^ ERROR mismatched types
+ //~| ERROR mismatched types
+
+
+ get_flag::<false, { unsafe { char_raw.character } }>();
+ //~^ ERROR it is undefined behavior
+ get_flag::<{ unsafe { bool_raw.boolean } }, 'z'>();
+ //~^ ERROR it is undefined behavior
+ get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>();
+ //~^ ERROR it is undefined behavior
+ //~| ERROR it is undefined behavior
+}
diff --git a/src/test/ui/const-generics/min_const_generics/macro-fail.rs b/src/test/ui/const-generics/min_const_generics/macro-fail.rs
new file mode 100644
index 000000000..f83518fc9
--- /dev/null
+++ b/src/test/ui/const-generics/min_const_generics/macro-fail.rs
@@ -0,0 +1,42 @@
+struct Example<const N: usize>;
+
+macro_rules! external_macro {
+ () => {{
+ //~^ ERROR expected type
+ const X: usize = 1337;
+ X
+ }}
+}
+
+trait Marker<const N: usize> {}
+impl<const N: usize> Marker<N> for Example<N> {}
+
+fn make_marker() -> impl Marker<gimme_a_const!(marker)> {
+ //~^ ERROR: type provided when a constant was expected
+ Example::<gimme_a_const!(marker)>
+ //~^ ERROR: type provided when a constant was expected
+}
+
+fn from_marker(_: impl Marker<{
+ #[macro_export]
+ macro_rules! inline { () => {{ 3 }} }; inline!()
+}>) {}
+
+fn main() {
+ let _ok = Example::<{
+ #[macro_export]
+ macro_rules! gimme_a_const {
+ ($rusty: ident) => {{ let $rusty = 3; *&$rusty }}
+ //~^ ERROR expected type
+ //~| ERROR expected type
+ };
+ gimme_a_const!(run)
+ }>;
+
+ let _fail = Example::<external_macro!()>;
+ //~^ ERROR: type provided when a constant was expected
+
+ let _fail = Example::<gimme_a_const!()>;
+ //~^ ERROR: type provided when a constant was expected
+ //~| ERROR unexpected end of macro invocation
+}
diff --git a/src/test/ui/const-generics/min_const_generics/macro-fail.stderr b/src/test/ui/const-generics/min_const_generics/macro-fail.stderr
new file mode 100644
index 000000000..d5dd70d9b
--- /dev/null
+++ b/src/test/ui/const-generics/min_const_generics/macro-fail.stderr
@@ -0,0 +1,83 @@
+error: expected type, found `{`
+ --> $DIR/macro-fail.rs:29:27
+ |
+LL | fn make_marker() -> impl Marker<gimme_a_const!(marker)> {
+ | ----------------------
+ | |
+ | this macro call doesn't expand to a type
+ | in this macro invocation
+...
+LL | ($rusty: ident) => {{ let $rusty = 3; *&$rusty }}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type
+ |
+ = note: this error originates in the macro `gimme_a_const` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: expected type, found `{`
+ --> $DIR/macro-fail.rs:29:27
+ |
+LL | Example::<gimme_a_const!(marker)>
+ | ----------------------
+ | |
+ | this macro call doesn't expand to a type
+ | in this macro invocation
+...
+LL | ($rusty: ident) => {{ let $rusty = 3; *&$rusty }}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type
+ |
+ = note: this error originates in the macro `gimme_a_const` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: expected type, found `{`
+ --> $DIR/macro-fail.rs:4:10
+ |
+LL | () => {{
+ | __________^
+LL | |
+LL | | const X: usize = 1337;
+LL | | X
+LL | | }}
+ | |___^ expected type
+...
+LL | let _fail = Example::<external_macro!()>;
+ | -----------------
+ | |
+ | this macro call doesn't expand to a type
+ | in this macro invocation
+ |
+ = note: this error originates in the macro `external_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: unexpected end of macro invocation
+ --> $DIR/macro-fail.rs:39:25
+ |
+LL | macro_rules! gimme_a_const {
+ | -------------------------- when calling this macro
+...
+LL | let _fail = Example::<gimme_a_const!()>;
+ | ^^^^^^^^^^^^^^^^ missing tokens in macro arguments
+
+error[E0747]: type provided when a constant was expected
+ --> $DIR/macro-fail.rs:14:33
+ |
+LL | fn make_marker() -> impl Marker<gimme_a_const!(marker)> {
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0747]: type provided when a constant was expected
+ --> $DIR/macro-fail.rs:16:13
+ |
+LL | Example::<gimme_a_const!(marker)>
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0747]: type provided when a constant was expected
+ --> $DIR/macro-fail.rs:36:25
+ |
+LL | let _fail = Example::<external_macro!()>;
+ | ^^^^^^^^^^^^^^^^^
+
+error[E0747]: type provided when a constant was expected
+ --> $DIR/macro-fail.rs:39:25
+ |
+LL | let _fail = Example::<gimme_a_const!()>;
+ | ^^^^^^^^^^^^^^^^
+
+error: aborting due to 8 previous errors
+
+For more information about this error, try `rustc --explain E0747`.
diff --git a/src/test/ui/const-generics/min_const_generics/macro.rs b/src/test/ui/const-generics/min_const_generics/macro.rs
new file mode 100644
index 000000000..9b63f7698
--- /dev/null
+++ b/src/test/ui/const-generics/min_const_generics/macro.rs
@@ -0,0 +1,55 @@
+// run-pass
+struct Example<const N: usize>;
+
+macro_rules! external_macro {
+ () => {{
+ const X: usize = 1337;
+ X
+ }}
+}
+
+trait Marker<const N: usize> {}
+impl<const N: usize> Marker<N> for Example<N> {}
+
+fn make_marker() -> impl Marker<{
+ #[macro_export]
+ macro_rules! const_macro { () => {{ 3 }} } inline!()
+}> {
+ Example::<{ const_macro!() }>
+}
+
+fn from_marker(_: impl Marker<{
+ #[macro_export]
+ macro_rules! inline { () => {{ 3 }} } inline!()
+}>) {}
+
+fn main() {
+ let _ok = Example::<{
+ #[macro_export]
+ macro_rules! gimme_a_const {
+ ($rusty: ident) => {{ let $rusty = 3; *&$rusty }}
+ }
+ gimme_a_const!(run)
+ }>;
+
+ let _ok = Example::<{ external_macro!() }>;
+
+ let _ok: [_; gimme_a_const!(blah)] = [0,0,0];
+ let _ok: [[u8; gimme_a_const!(blah)]; gimme_a_const!(blah)];
+ let _ok: [u8; gimme_a_const!(blah)];
+
+ let _ok: [u8; {
+ #[macro_export]
+ macro_rules! const_two { () => {{ 2 }} }
+ const_two!()
+ }];
+
+ let _ok = [0; {
+ #[macro_export]
+ macro_rules! const_three { () => {{ 3 }} }
+ const_three!()
+ }];
+ let _ok = [0; const_three!()];
+
+ from_marker(make_marker());
+}
diff --git a/src/test/ui/const-generics/min_const_generics/self-ty-in-const-1.rs b/src/test/ui/const-generics/min_const_generics/self-ty-in-const-1.rs
new file mode 100644
index 000000000..9ef619365
--- /dev/null
+++ b/src/test/ui/const-generics/min_const_generics/self-ty-in-const-1.rs
@@ -0,0 +1,25 @@
+trait Foo {
+ fn t1() -> [u8; std::mem::size_of::<Self>()]; //~ERROR generic parameters
+}
+
+struct Bar<T>(T);
+
+impl Bar<u8> {
+ fn t2() -> [u8; std::mem::size_of::<Self>()] { todo!() } // ok
+}
+
+impl<T> Bar<T> {
+ fn t3() -> [u8; std::mem::size_of::<Self>()] {} //~ERROR generic `Self`
+}
+
+trait Baz {
+ fn hey();
+}
+
+impl Baz for u16 {
+ fn hey() {
+ let _: [u8; std::mem::size_of::<Self>()]; // ok
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/min_const_generics/self-ty-in-const-1.stderr b/src/test/ui/const-generics/min_const_generics/self-ty-in-const-1.stderr
new file mode 100644
index 000000000..16a7687c0
--- /dev/null
+++ b/src/test/ui/const-generics/min_const_generics/self-ty-in-const-1.stderr
@@ -0,0 +1,23 @@
+error: generic parameters may not be used in const operations
+ --> $DIR/self-ty-in-const-1.rs:2:41
+ |
+LL | fn t1() -> [u8; std::mem::size_of::<Self>()];
+ | ^^^^ cannot perform const operation using `Self`
+ |
+ = note: type parameters may not be used in const expressions
+ = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+
+error: generic `Self` types are currently not permitted in anonymous constants
+ --> $DIR/self-ty-in-const-1.rs:12:41
+ |
+LL | fn t3() -> [u8; std::mem::size_of::<Self>()] {}
+ | ^^^^
+ |
+note: not a concrete type
+ --> $DIR/self-ty-in-const-1.rs:11:9
+ |
+LL | impl<T> Bar<T> {
+ | ^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/const-generics/min_const_generics/self-ty-in-const-2.rs b/src/test/ui/const-generics/min_const_generics/self-ty-in-const-2.rs
new file mode 100644
index 000000000..286ec2d24
--- /dev/null
+++ b/src/test/ui/const-generics/min_const_generics/self-ty-in-const-2.rs
@@ -0,0 +1,19 @@
+struct Bar<T>(T);
+
+trait Baz {
+ fn hey();
+}
+
+impl Baz for u16 {
+ fn hey() {
+ let _: [u8; std::mem::size_of::<Self>()]; // ok
+ }
+}
+
+impl<T> Baz for Bar<T> {
+ fn hey() {
+ let _: [u8; std::mem::size_of::<Self>()]; //~ERROR generic `Self`
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/min_const_generics/self-ty-in-const-2.stderr b/src/test/ui/const-generics/min_const_generics/self-ty-in-const-2.stderr
new file mode 100644
index 000000000..41546292c
--- /dev/null
+++ b/src/test/ui/const-generics/min_const_generics/self-ty-in-const-2.stderr
@@ -0,0 +1,14 @@
+error: generic `Self` types are currently not permitted in anonymous constants
+ --> $DIR/self-ty-in-const-2.rs:15:41
+ |
+LL | let _: [u8; std::mem::size_of::<Self>()];
+ | ^^^^
+ |
+note: not a concrete type
+ --> $DIR/self-ty-in-const-2.rs:13:17
+ |
+LL | impl<T> Baz for Bar<T> {
+ | ^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/min_const_generics/type_and_const_defaults.rs b/src/test/ui/const-generics/min_const_generics/type_and_const_defaults.rs
new file mode 100644
index 000000000..fa119c59f
--- /dev/null
+++ b/src/test/ui/const-generics/min_const_generics/type_and_const_defaults.rs
@@ -0,0 +1,25 @@
+// run-pass
+#![allow(dead_code)]
+
+struct Both<T=u32, const N: usize=3> {
+ arr: [T; N]
+}
+
+trait BothTrait<T=u32, const N: usize=3> {}
+
+enum BothEnum<T=u32, const N: usize=3> {
+ Dummy([T; N])
+}
+
+struct OppOrder<const N: usize=3, T=u32> {
+ arr: [T; N]
+}
+
+fn main() {
+ let _ = OppOrder::<3, u32> {
+ arr: [0,0,0],
+ };
+ let _ = Both::<u8, 1> {
+ arr: [0],
+ };
+}