summaryrefslogtreecommitdiffstats
path: root/src/test/ui/const-generics/generic_const_exprs
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/ui/const-generics/generic_const_exprs')
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-1.rs18
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-2.rs20
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-2.stderr26
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.rs47
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr147
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-4.rs29
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/abstract-consts-as-cast-5.rs11
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/abstract-consts-as-cast-5.stderr10
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.full.stderr19
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.min.stderr29
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.rs29
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/associated-const.rs11
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/associated-consts.rs31
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/auxiliary/const_evaluatable_lib.rs9
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/auxiliary/issue-94287-aux.rs21
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/closures.rs6
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/closures.stderr26
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/const_eval_resolve_canonical.rs28
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/cross_crate.rs15
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/cross_crate_predicate.rs14
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/cross_crate_predicate.stderr54
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/dependence_lint.full.stderr39
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/dependence_lint.gce.stderr34
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/dependence_lint.rs25
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/different-fn.rs17
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/different-fn.stderr20
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/division.rs11
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/dont-eagerly-error-in-is-const-evaluatable.rs16
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/drop_impl.rs16
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/elaborate-trait-pred.rs24
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/eval-privacy.rs26
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/eval-privacy.stderr12
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/eval-try-unify.rs26
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/eval-try-unify.stderr11
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/evaluated-to-ambig.rs22
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/feature-gate-generic_const_exprs.rs11
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/feature-gate-generic_const_exprs.stderr11
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/fn_call.rs30
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/from-sig-fail.rs11
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/from-sig-fail.stderr9
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/from-sig.rs14
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/function-call.rs19
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/function-call.stderr12
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/impl-bounds.rs25
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/infer-too-generic.rs24
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-62504.full.stderr20
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-62504.min.stderr27
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-62504.rs27
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-69654.rs19
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-69654.stderr22
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-72787.min.stderr55
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-72787.rs35
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.full.stderr21
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.min.stderr11
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.rs23
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-73899.rs20
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-74634.rs28
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-74713.rs8
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-74713.stderr22
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-76595.rs17
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-76595.stderr21
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-79518-default_trait_method_normalization.rs21
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-79518-default_trait_method_normalization.stderr14
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-80561-incorrect-param-env.rs24
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-80742.rs32
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-80742.stderr66
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-83765.rs38
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-83765.stderr34
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-84408.rs38
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-85848.rs32
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-85848.stderr63
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-90847.rs9
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-94287.rs10
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-94287.stderr15
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-97047-ice-1.rs25
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-97047-ice-1.stderr19
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-97047-ice-2.rs23
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-97047-ice-2.stderr19
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/less_than.rs14
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/let-bindings.rs15
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/let-bindings.stderr20
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/needs_where_clause.rs14
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/needs_where_clause.stderr10
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/nested-abstract-consts-1.rs24
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/nested-abstract-consts-2.rs35
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/nested_uneval_unification-1.rs34
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/nested_uneval_unification-2.rs29
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/no_dependence.rs13
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/no_where_clause.rs29
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/no_where_clause.stderr10
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/object-safety-err-ret.rs21
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/object-safety-err-ret.stderr18
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/object-safety-err-where-bounds.rs22
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/object-safety-err-where-bounds.stderr24
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.rs21
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.stderr19
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/object-safety-ok.rs21
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/simple_fail.rs17
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/simple_fail.stderr15
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/subexprs_are_const_evalutable.rs17
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/ty-alias-substitution.rs14
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.rs35
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr10
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/unop.rs14
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/unused-complex-default-expr.rs6
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/unused_expr.rs25
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/unused_expr.stderr29
107 files changed, 2498 insertions, 0 deletions
diff --git a/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-1.rs b/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-1.rs
new file mode 100644
index 000000000..06f00de13
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-1.rs
@@ -0,0 +1,18 @@
+// check-pass
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+struct Foo<const N: u8>([u8; N as usize])
+where
+ [(); N as usize]:;
+
+struct Bar<const N: u8>([u8; (N + 2) as usize]) where [(); (N + 2) as usize]:;
+
+// unifying with subtrees
+struct Evaluatable<const N: u16>;
+fn foo<const N: u8>() where Evaluatable<{N as usize as u16 }>: {
+ let _ = Foo::<N>([1; N as usize]);
+}
+
+
+fn main() {}
diff --git a/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-2.rs b/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-2.rs
new file mode 100644
index 000000000..3b5b87b2b
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-2.rs
@@ -0,0 +1,20 @@
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+struct Evaluatable<const N: u128> {}
+
+struct Foo<const N: u8>([u8; N as usize])
+//~^ Error: unconstrained generic constant
+//~| help: try adding a `where` bound using this expression: `where [(); N as usize]:`
+where
+ Evaluatable<{N as u128}>:;
+
+struct Foo2<const N: u8>(Evaluatable::<{N as u128}>) where Evaluatable<{N as usize as u128 }>:;
+//~^ Error: unconstrained generic constant
+//~| help: try adding a `where` bound using this expression: `where [(); {N as u128}]:`
+
+struct Bar<const N: u8>([u8; (N + 2) as usize]) where [(); (N + 1) as usize]:;
+//~^ Error: unconstrained generic constant
+//~| help: try adding a `where` bound using this expression: `where [(); (N + 2) as usize]:`
+
+fn main() {}
diff --git a/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-2.stderr b/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-2.stderr
new file mode 100644
index 000000000..5ca04d25e
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-2.stderr
@@ -0,0 +1,26 @@
+error: unconstrained generic constant
+ --> $DIR/abstract-const-as-cast-2.rs:6:25
+ |
+LL | struct Foo<const N: u8>([u8; N as usize])
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: try adding a `where` bound using this expression: `where [(); N as usize]:`
+
+error: unconstrained generic constant
+ --> $DIR/abstract-const-as-cast-2.rs:12:26
+ |
+LL | struct Foo2<const N: u8>(Evaluatable::<{N as u128}>) where Evaluatable<{N as usize as u128 }>:;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: try adding a `where` bound using this expression: `where [(); {N as u128}]:`
+
+error: unconstrained generic constant
+ --> $DIR/abstract-const-as-cast-2.rs:16:25
+ |
+LL | struct Bar<const N: u8>([u8; (N + 2) as usize]) where [(); (N + 1) as usize]:;
+ | ^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: try adding a `where` bound using this expression: `where [(); (N + 2) as usize]:`
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.rs b/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.rs
new file mode 100644
index 000000000..7561ae2fe
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.rs
@@ -0,0 +1,47 @@
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+trait Trait {}
+pub struct EvaluatableU128<const N: u128>;
+
+struct HasCastInTraitImpl<const N: usize, const M: u128>;
+impl<const O: usize> Trait for HasCastInTraitImpl<O, { O as u128 }> {}
+
+pub fn use_trait_impl<const N: usize>()
+where
+ [(); { N + 1}]:,
+ EvaluatableU128<{N as u128}>:, {
+ fn assert_impl<T: Trait>() {}
+
+ // errors are bad but seems to be pre-existing issue #86198
+ assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
+ //~^ Error: mismatched types
+ //~^^ Error: unconstrained generic constant
+ assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
+ //~^ Error: mismatched types
+ //~^^ Error: unconstrained generic constant
+ assert_impl::<HasCastInTraitImpl<13, { 12 as u128 }>>();
+ //~^ Error: mismatched types
+ assert_impl::<HasCastInTraitImpl<14, 13>>();
+ //~^ Error: mismatched types
+}
+pub fn use_trait_impl_2<const N: usize>()
+where
+ [(); { N + 1}]:,
+ EvaluatableU128<{N as _}>:, {
+ fn assert_impl<T: Trait>() {}
+
+ // errors are bad but seems to be pre-existing issue #86198
+ assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
+ //~^ Error: mismatched types
+ //~^^ Error: unconstrained generic constant
+ assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
+ //~^ Error: mismatched types
+ //~^^ Error: unconstrained generic constant
+ assert_impl::<HasCastInTraitImpl<13, { 12 as u128 }>>();
+ //~^ Error: mismatched types
+ assert_impl::<HasCastInTraitImpl<14, 13>>();
+ //~^ Error: mismatched types
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr b/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr
new file mode 100644
index 000000000..ababb27a8
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr
@@ -0,0 +1,147 @@
+error: unconstrained generic constant
+ --> $DIR/abstract-const-as-cast-3.rs:17:5
+ |
+LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
+note: required because of the requirements on the impl of `Trait` for `HasCastInTraitImpl<{ N + 1 }, { N as u128 }>`
+ --> $DIR/abstract-const-as-cast-3.rs:8:22
+ |
+LL | impl<const O: usize> Trait for HasCastInTraitImpl<O, { O as u128 }> {}
+ | ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: required by a bound in `use_trait_impl::assert_impl`
+ --> $DIR/abstract-const-as-cast-3.rs:14:23
+ |
+LL | fn assert_impl<T: Trait>() {}
+ | ^^^^^ required by this bound in `use_trait_impl::assert_impl`
+
+error[E0308]: mismatched types
+ --> $DIR/abstract-const-as-cast-3.rs:17:5
+ |
+LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{ N as u128 }`, found `{ O as u128 }`
+ |
+ = note: expected type `{ N as u128 }`
+ found type `{ O as u128 }`
+
+error: unconstrained generic constant
+ --> $DIR/abstract-const-as-cast-3.rs:20:5
+ |
+LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
+note: required because of the requirements on the impl of `Trait` for `HasCastInTraitImpl<{ N + 1 }, { N as _ }>`
+ --> $DIR/abstract-const-as-cast-3.rs:8:22
+ |
+LL | impl<const O: usize> Trait for HasCastInTraitImpl<O, { O as u128 }> {}
+ | ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: required by a bound in `use_trait_impl::assert_impl`
+ --> $DIR/abstract-const-as-cast-3.rs:14:23
+ |
+LL | fn assert_impl<T: Trait>() {}
+ | ^^^^^ required by this bound in `use_trait_impl::assert_impl`
+
+error[E0308]: mismatched types
+ --> $DIR/abstract-const-as-cast-3.rs:20:5
+ |
+LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{ N as _ }`, found `{ O as u128 }`
+ |
+ = note: expected type `{ N as _ }`
+ found type `{ O as u128 }`
+
+error[E0308]: mismatched types
+ --> $DIR/abstract-const-as-cast-3.rs:23:5
+ |
+LL | assert_impl::<HasCastInTraitImpl<13, { 12 as u128 }>>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `12`, found `13`
+ |
+ = note: expected type `12`
+ found type `13`
+
+error[E0308]: mismatched types
+ --> $DIR/abstract-const-as-cast-3.rs:25:5
+ |
+LL | assert_impl::<HasCastInTraitImpl<14, 13>>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `13`, found `14`
+ |
+ = note: expected type `13`
+ found type `14`
+
+error: unconstrained generic constant
+ --> $DIR/abstract-const-as-cast-3.rs:35:5
+ |
+LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
+note: required because of the requirements on the impl of `Trait` for `HasCastInTraitImpl<{ N + 1 }, { N as u128 }>`
+ --> $DIR/abstract-const-as-cast-3.rs:8:22
+ |
+LL | impl<const O: usize> Trait for HasCastInTraitImpl<O, { O as u128 }> {}
+ | ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: required by a bound in `use_trait_impl_2::assert_impl`
+ --> $DIR/abstract-const-as-cast-3.rs:32:23
+ |
+LL | fn assert_impl<T: Trait>() {}
+ | ^^^^^ required by this bound in `use_trait_impl_2::assert_impl`
+
+error[E0308]: mismatched types
+ --> $DIR/abstract-const-as-cast-3.rs:35:5
+ |
+LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{ N as u128 }`, found `{ O as u128 }`
+ |
+ = note: expected type `{ N as u128 }`
+ found type `{ O as u128 }`
+
+error: unconstrained generic constant
+ --> $DIR/abstract-const-as-cast-3.rs:38:5
+ |
+LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
+note: required because of the requirements on the impl of `Trait` for `HasCastInTraitImpl<{ N + 1 }, { N as _ }>`
+ --> $DIR/abstract-const-as-cast-3.rs:8:22
+ |
+LL | impl<const O: usize> Trait for HasCastInTraitImpl<O, { O as u128 }> {}
+ | ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: required by a bound in `use_trait_impl_2::assert_impl`
+ --> $DIR/abstract-const-as-cast-3.rs:32:23
+ |
+LL | fn assert_impl<T: Trait>() {}
+ | ^^^^^ required by this bound in `use_trait_impl_2::assert_impl`
+
+error[E0308]: mismatched types
+ --> $DIR/abstract-const-as-cast-3.rs:38:5
+ |
+LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{ N as _ }`, found `{ O as u128 }`
+ |
+ = note: expected type `{ N as _ }`
+ found type `{ O as u128 }`
+
+error[E0308]: mismatched types
+ --> $DIR/abstract-const-as-cast-3.rs:41:5
+ |
+LL | assert_impl::<HasCastInTraitImpl<13, { 12 as u128 }>>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `12`, found `13`
+ |
+ = note: expected type `12`
+ found type `13`
+
+error[E0308]: mismatched types
+ --> $DIR/abstract-const-as-cast-3.rs:43:5
+ |
+LL | assert_impl::<HasCastInTraitImpl<14, 13>>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `13`, found `14`
+ |
+ = note: expected type `13`
+ found type `14`
+
+error: aborting due to 12 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-4.rs b/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-4.rs
new file mode 100644
index 000000000..184263f89
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-4.rs
@@ -0,0 +1,29 @@
+// check-pass
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+trait Trait {}
+pub struct EvaluatableU128<const N: u128>;
+
+struct HasCastInTraitImpl<const N: usize, const M: u128>;
+impl<const O: usize> Trait for HasCastInTraitImpl<O, { O as u128 }> {}
+
+pub fn use_trait_impl<const N: usize>() where EvaluatableU128<{N as u128}>:, {
+ fn assert_impl<T: Trait>() {}
+
+ assert_impl::<HasCastInTraitImpl<N, { N as u128 }>>();
+ assert_impl::<HasCastInTraitImpl<N, { N as _ }>>();
+ assert_impl::<HasCastInTraitImpl<12, { 12 as u128 }>>();
+ assert_impl::<HasCastInTraitImpl<13, 13>>();
+}
+pub fn use_trait_impl_2<const N: usize>() where EvaluatableU128<{N as _}>:, {
+ fn assert_impl<T: Trait>() {}
+
+ assert_impl::<HasCastInTraitImpl<N, { N as u128 }>>();
+ assert_impl::<HasCastInTraitImpl<N, { N as _ }>>();
+ assert_impl::<HasCastInTraitImpl<12, { 12 as u128 }>>();
+ assert_impl::<HasCastInTraitImpl<13, 13>>();
+}
+
+
+fn main() {}
diff --git a/src/test/ui/const-generics/generic_const_exprs/abstract-consts-as-cast-5.rs b/src/test/ui/const-generics/generic_const_exprs/abstract-consts-as-cast-5.rs
new file mode 100644
index 000000000..916d60c0e
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/abstract-consts-as-cast-5.rs
@@ -0,0 +1,11 @@
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+fn foo<const N: u8>(a: [(); N as usize]) {
+ bar::<{ N as usize as usize }>();
+ //~^ error: unconstrained generic constant
+}
+
+fn bar<const N: usize>() {}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/generic_const_exprs/abstract-consts-as-cast-5.stderr b/src/test/ui/const-generics/generic_const_exprs/abstract-consts-as-cast-5.stderr
new file mode 100644
index 000000000..d48b639db
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/abstract-consts-as-cast-5.stderr
@@ -0,0 +1,10 @@
+error: unconstrained generic constant
+ --> $DIR/abstract-consts-as-cast-5.rs:5:11
+ |
+LL | bar::<{ N as usize as usize }>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: try adding a `where` bound using this expression: `where [(); { N as usize as usize }]:`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.full.stderr b/src/test/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.full.stderr
new file mode 100644
index 000000000..041232e86
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.full.stderr
@@ -0,0 +1,19 @@
+error: unconstrained generic constant
+ --> $DIR/array-size-in-generic-struct-param.rs:8:38
+ |
+LL | struct ArithArrayLen<const N: usize>([u32; 0 + N]);
+ | ^^^^^^^^^^^^
+ |
+ = help: try adding a `where` bound using this expression: `where [(); 0 + N]:`
+
+error: overly complex generic constant
+ --> $DIR/array-size-in-generic-struct-param.rs:19:15
+ |
+LL | arr: [u8; CFG.arr_size],
+ | ^^^^^^^^^^^^ field access is not supported in generic constant
+ |
+ = help: consider moving this anonymous constant into a `const` function
+ = note: this operation may be supported in the future
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.min.stderr b/src/test/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.min.stderr
new file mode 100644
index 000000000..18e9135d0
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.min.stderr
@@ -0,0 +1,29 @@
+error: generic parameters may not be used in const operations
+ --> $DIR/array-size-in-generic-struct-param.rs:8:48
+ |
+LL | struct ArithArrayLen<const N: usize>([u32; 0 + 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/array-size-in-generic-struct-param.rs:19:15
+ |
+LL | arr: [u8; CFG.arr_size],
+ | ^^^ cannot perform const operation using `CFG`
+ |
+ = help: const parameters may only be used as standalone arguments, i.e. `CFG`
+ = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+
+error: `Config` is forbidden as the type of a const generic parameter
+ --> $DIR/array-size-in-generic-struct-param.rs:17:21
+ |
+LL | struct B<const CFG: Config> {
+ | ^^^^^^
+ |
+ = 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 3 previous errors
+
diff --git a/src/test/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.rs b/src/test/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.rs
new file mode 100644
index 000000000..7d3fe413c
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.rs
@@ -0,0 +1,29 @@
+// Tests that array sizes that depend on const-params are checked using `ConstEvaluatable`.
+// revisions: full min
+
+#![cfg_attr(full, feature(generic_const_exprs, adt_const_params))]
+#![cfg_attr(full, allow(incomplete_features))]
+
+#[allow(dead_code)]
+struct ArithArrayLen<const N: usize>([u32; 0 + N]);
+//[full]~^ ERROR unconstrained generic constant
+//[min]~^^ ERROR generic parameters may not be used in const operations
+
+#[derive(PartialEq, Eq)]
+struct Config {
+ arr_size: usize,
+}
+
+struct B<const CFG: Config> {
+ //[min]~^ ERROR `Config` is forbidden
+ arr: [u8; CFG.arr_size],
+ //[full]~^ ERROR overly complex generic constant
+ //[min]~^^ ERROR generic parameters may not be used in const operations
+}
+
+const C: Config = Config { arr_size: 5 };
+
+fn main() {
+ let b = B::<C> { arr: [1, 2, 3, 4, 5] };
+ assert_eq!(b.arr.len(), 5);
+}
diff --git a/src/test/ui/const-generics/generic_const_exprs/associated-const.rs b/src/test/ui/const-generics/generic_const_exprs/associated-const.rs
new file mode 100644
index 000000000..a67776322
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/associated-const.rs
@@ -0,0 +1,11 @@
+// check-pass
+struct Foo<T>(T);
+impl<T> Foo<T> {
+ const VALUE: usize = std::mem::size_of::<T>();
+}
+
+fn test<T>() {
+ let _ = [0; Foo::<u8>::VALUE];
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/generic_const_exprs/associated-consts.rs b/src/test/ui/const-generics/generic_const_exprs/associated-consts.rs
new file mode 100644
index 000000000..b839008d4
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/associated-consts.rs
@@ -0,0 +1,31 @@
+// run-pass
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+pub trait BlockCipher {
+ const BLOCK_SIZE: usize;
+}
+
+struct FooCipher;
+impl BlockCipher for FooCipher {
+ const BLOCK_SIZE: usize = 64;
+}
+
+struct BarCipher;
+impl BlockCipher for BarCipher {
+ const BLOCK_SIZE: usize = 32;
+}
+
+pub struct Block<C>(#[allow(unused_tuple_struct_fields)] C);
+
+pub fn test<C: BlockCipher, const M: usize>()
+where
+ [u8; M - C::BLOCK_SIZE]: Sized,
+{
+ let _ = [0; M - C::BLOCK_SIZE];
+}
+
+fn main() {
+ test::<FooCipher, 128>();
+ test::<BarCipher, 64>();
+}
diff --git a/src/test/ui/const-generics/generic_const_exprs/auxiliary/const_evaluatable_lib.rs b/src/test/ui/const-generics/generic_const_exprs/auxiliary/const_evaluatable_lib.rs
new file mode 100644
index 000000000..15d618cae
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/auxiliary/const_evaluatable_lib.rs
@@ -0,0 +1,9 @@
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+pub fn test1<T>() -> [u8; std::mem::size_of::<T>() - 1]
+where
+ [u8; std::mem::size_of::<T>() - 1]: Sized,
+{
+ [0; std::mem::size_of::<T>() - 1]
+}
diff --git a/src/test/ui/const-generics/generic_const_exprs/auxiliary/issue-94287-aux.rs b/src/test/ui/const-generics/generic_const_exprs/auxiliary/issue-94287-aux.rs
new file mode 100644
index 000000000..df454dae7
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/auxiliary/issue-94287-aux.rs
@@ -0,0 +1,21 @@
+#![feature(generic_const_exprs)]
+
+use std::str::FromStr;
+
+pub struct If<const CONDITION: bool>;
+
+pub trait True {}
+
+impl True for If<true> {}
+
+pub struct FixedI32<const FRAC: u32>;
+
+impl<const FRAC: u32> FromStr for FixedI32<FRAC>
+where
+ If<{ FRAC <= 32 }>: True,
+{
+ type Err = ();
+ fn from_str(_s: &str) -> Result<Self, Self::Err> {
+ unimplemented!()
+ }
+}
diff --git a/src/test/ui/const-generics/generic_const_exprs/closures.rs b/src/test/ui/const-generics/generic_const_exprs/closures.rs
new file mode 100644
index 000000000..1ea310d06
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/closures.rs
@@ -0,0 +1,6 @@
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+fn test<const N: usize>() -> [u8; N + (|| 42)()] {}
+//~^ ERROR cycle detected when building an abstract representation
+
+fn main() {}
diff --git a/src/test/ui/const-generics/generic_const_exprs/closures.stderr b/src/test/ui/const-generics/generic_const_exprs/closures.stderr
new file mode 100644
index 000000000..a15dd2016
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/closures.stderr
@@ -0,0 +1,26 @@
+error[E0391]: cycle detected when building an abstract representation for test::{constant#0}
+ --> $DIR/closures.rs:3:35
+ |
+LL | fn test<const N: usize>() -> [u8; N + (|| 42)()] {}
+ | ^^^^^^^^^^^^^
+ |
+note: ...which requires building THIR for `test::{constant#0}`...
+ --> $DIR/closures.rs:3:35
+ |
+LL | fn test<const N: usize>() -> [u8; N + (|| 42)()] {}
+ | ^^^^^^^^^^^^^
+note: ...which requires type-checking `test::{constant#0}`...
+ --> $DIR/closures.rs:3:35
+ |
+LL | fn test<const N: usize>() -> [u8; N + (|| 42)()] {}
+ | ^^^^^^^^^^^^^
+ = note: ...which again requires building an abstract representation for test::{constant#0}, completing the cycle
+note: cycle used when checking that `test` is well-formed
+ --> $DIR/closures.rs:3:1
+ |
+LL | fn test<const N: usize>() -> [u8; N + (|| 42)()] {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0391`.
diff --git a/src/test/ui/const-generics/generic_const_exprs/const_eval_resolve_canonical.rs b/src/test/ui/const-generics/generic_const_exprs/const_eval_resolve_canonical.rs
new file mode 100644
index 000000000..5874625ad
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/const_eval_resolve_canonical.rs
@@ -0,0 +1,28 @@
+// check-pass
+
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+trait Foo<const N: usize> {
+ type Assoc: Default;
+}
+
+impl Foo<0> for () {
+ type Assoc = u32;
+}
+
+impl Foo<3> for () {
+ type Assoc = i64;
+}
+
+fn foo<T, const N: usize>(_: T) -> <() as Foo<{ N + 1 }>>::Assoc
+where
+ (): Foo<{ N + 1 }>,
+{
+ Default::default()
+}
+
+fn main() {
+ let mut _q = Default::default();
+ _q = foo::<_, 2>(_q);
+}
diff --git a/src/test/ui/const-generics/generic_const_exprs/cross_crate.rs b/src/test/ui/const-generics/generic_const_exprs/cross_crate.rs
new file mode 100644
index 000000000..dfc69e0b0
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/cross_crate.rs
@@ -0,0 +1,15 @@
+// aux-build:const_evaluatable_lib.rs
+// run-pass
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+extern crate const_evaluatable_lib;
+
+fn user<T>() where [u8; std::mem::size_of::<T>() - 1]: Sized {
+ assert_eq!(const_evaluatable_lib::test1::<T>(), [0; std::mem::size_of::<T>() - 1]);
+}
+
+fn main() {
+ assert_eq!(const_evaluatable_lib::test1::<u32>(), [0; 3]);
+ user::<u32>();
+ user::<u64>();
+}
diff --git a/src/test/ui/const-generics/generic_const_exprs/cross_crate_predicate.rs b/src/test/ui/const-generics/generic_const_exprs/cross_crate_predicate.rs
new file mode 100644
index 000000000..b08fffd69
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/cross_crate_predicate.rs
@@ -0,0 +1,14 @@
+// aux-build:const_evaluatable_lib.rs
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+extern crate const_evaluatable_lib;
+
+fn user<T>() {
+ let _ = const_evaluatable_lib::test1::<T>();
+ //~^ ERROR unconstrained generic constant
+ //~| ERROR unconstrained generic constant
+ //~| ERROR unconstrained generic constant
+ //~| ERROR unconstrained generic constant
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/generic_const_exprs/cross_crate_predicate.stderr b/src/test/ui/const-generics/generic_const_exprs/cross_crate_predicate.stderr
new file mode 100644
index 000000000..7b4d46b82
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/cross_crate_predicate.stderr
@@ -0,0 +1,54 @@
+error: unconstrained generic constant
+ --> $DIR/cross_crate_predicate.rs:7:13
+ |
+LL | let _ = const_evaluatable_lib::test1::<T>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: try adding a `where` bound using this expression: `where [(); std::mem::size_of::<T>() - 1]:`
+note: required by a bound in `test1`
+ --> $DIR/auxiliary/const_evaluatable_lib.rs:6:10
+ |
+LL | [u8; std::mem::size_of::<T>() - 1]: Sized,
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `test1`
+
+error: unconstrained generic constant
+ --> $DIR/cross_crate_predicate.rs:7:13
+ |
+LL | let _ = const_evaluatable_lib::test1::<T>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: try adding a `where` bound using this expression: `where [(); std::mem::size_of::<T>() - 1]:`
+note: required by a bound in `test1`
+ --> $DIR/auxiliary/const_evaluatable_lib.rs:4:27
+ |
+LL | pub fn test1<T>() -> [u8; std::mem::size_of::<T>() - 1]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `test1`
+
+error: unconstrained generic constant
+ --> $DIR/cross_crate_predicate.rs:7:13
+ |
+LL | let _ = const_evaluatable_lib::test1::<T>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: try adding a `where` bound using this expression: `where [(); std::mem::size_of::<T>() - 1]:`
+note: required by a bound in `test1`
+ --> $DIR/auxiliary/const_evaluatable_lib.rs:6:10
+ |
+LL | [u8; std::mem::size_of::<T>() - 1]: Sized,
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `test1`
+
+error: unconstrained generic constant
+ --> $DIR/cross_crate_predicate.rs:7:13
+ |
+LL | let _ = const_evaluatable_lib::test1::<T>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: try adding a `where` bound using this expression: `where [(); std::mem::size_of::<T>() - 1]:`
+note: required by a bound in `test1`
+ --> $DIR/auxiliary/const_evaluatable_lib.rs:4:27
+ |
+LL | pub fn test1<T>() -> [u8; std::mem::size_of::<T>() - 1]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `test1`
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/const-generics/generic_const_exprs/dependence_lint.full.stderr b/src/test/ui/const-generics/generic_const_exprs/dependence_lint.full.stderr
new file mode 100644
index 000000000..4cd86fecd
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/dependence_lint.full.stderr
@@ -0,0 +1,39 @@
+error: generic parameters may not be used in const operations
+ --> $DIR/dependence_lint.rs:13:32
+ |
+LL | let _: [u8; size_of::<*mut T>()]; // error on stable, error with gce
+ | ^ 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/dependence_lint.rs:20:37
+ |
+LL | let _: [u8; if true { size_of::<T>() } else { 3 }]; // error on stable, error with gce
+ | ^ 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/dependence_lint.rs:9:9
+ |
+LL | [0; size_of::<*mut T>()]; // lint on stable, error with `generic_const_exprs`
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+ = 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/dependence_lint.rs:16:9
+ |
+LL | [0; if false { size_of::<T>() } else { 3 }]; // lint on stable, error with gce
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = 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 2 previous errors; 2 warnings emitted
+
diff --git a/src/test/ui/const-generics/generic_const_exprs/dependence_lint.gce.stderr b/src/test/ui/const-generics/generic_const_exprs/dependence_lint.gce.stderr
new file mode 100644
index 000000000..b13bcdb2c
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/dependence_lint.gce.stderr
@@ -0,0 +1,34 @@
+error: overly complex generic constant
+ --> $DIR/dependence_lint.rs:16:9
+ |
+LL | [0; if false { size_of::<T>() } else { 3 }]; // lint on stable, error with gce
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ control flow is not supported in generic constants
+ |
+ = help: consider moving this anonymous constant into a `const` function
+
+error: overly complex generic constant
+ --> $DIR/dependence_lint.rs:20:17
+ |
+LL | let _: [u8; if true { size_of::<T>() } else { 3 }]; // error on stable, error with gce
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ control flow is not supported in generic constants
+ |
+ = help: consider moving this anonymous constant into a `const` function
+
+error: unconstrained generic constant
+ --> $DIR/dependence_lint.rs:13:12
+ |
+LL | let _: [u8; size_of::<*mut T>()]; // error on stable, error with gce
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: try adding a `where` bound using this expression: `where [(); size_of::<*mut T>()]:`
+
+error: unconstrained generic constant
+ --> $DIR/dependence_lint.rs:9:9
+ |
+LL | [0; size_of::<*mut T>()]; // lint on stable, error with `generic_const_exprs`
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+ = help: try adding a `where` bound using this expression: `where [(); size_of::<*mut T>()]:`
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/const-generics/generic_const_exprs/dependence_lint.rs b/src/test/ui/const-generics/generic_const_exprs/dependence_lint.rs
new file mode 100644
index 000000000..dcdfd75de
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/dependence_lint.rs
@@ -0,0 +1,25 @@
+// revisions: full gce
+
+#![cfg_attr(gce, feature(generic_const_exprs))]
+#![allow(incomplete_features)]
+
+use std::mem::size_of;
+
+fn foo<T>() {
+ [0; size_of::<*mut T>()]; // lint on stable, error with `generic_const_exprs`
+ //[gce]~^ ERROR unconstrained
+ //[full]~^^ WARNING cannot use constants
+ //[full]~| WARNING this was previously accepted
+ let _: [u8; size_of::<*mut T>()]; // error on stable, error with gce
+ //[full]~^ ERROR generic parameters may not be used
+ //[gce]~^^ ERROR unconstrained generic
+ [0; if false { size_of::<T>() } else { 3 }]; // lint on stable, error with gce
+ //[gce]~^ ERROR overly complex
+ //[full]~^^ WARNING cannot use constants
+ //[full]~| WARNING this was previously accepted
+ let _: [u8; if true { size_of::<T>() } else { 3 }]; // error on stable, error with gce
+ //[full]~^ ERROR generic parameters may not be used
+ //[gce]~^^ ERROR overly complex
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/generic_const_exprs/different-fn.rs b/src/test/ui/const-generics/generic_const_exprs/different-fn.rs
new file mode 100644
index 000000000..e8bc703bd
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/different-fn.rs
@@ -0,0 +1,17 @@
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+use std::mem::size_of;
+use std::marker::PhantomData;
+
+struct Foo<T>(PhantomData<T>);
+
+fn test<T>() -> [u8; size_of::<T>()] {
+ [0; size_of::<Foo<T>>()]
+ //~^ ERROR unconstrained generic constant
+ //~| ERROR mismatched types
+}
+
+fn main() {
+ test::<u32>();
+}
diff --git a/src/test/ui/const-generics/generic_const_exprs/different-fn.stderr b/src/test/ui/const-generics/generic_const_exprs/different-fn.stderr
new file mode 100644
index 000000000..2aeb9b961
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/different-fn.stderr
@@ -0,0 +1,20 @@
+error[E0308]: mismatched types
+ --> $DIR/different-fn.rs:10:5
+ |
+LL | [0; size_of::<Foo<T>>()]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ expected `size_of::<T>()`, found `size_of::<Foo<T>>()`
+ |
+ = note: expected type `size_of::<T>()`
+ found type `size_of::<Foo<T>>()`
+
+error: unconstrained generic constant
+ --> $DIR/different-fn.rs:10:9
+ |
+LL | [0; size_of::<Foo<T>>()]
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+ = help: try adding a `where` bound using this expression: `where [(); size_of::<Foo<T>>()]:`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/const-generics/generic_const_exprs/division.rs b/src/test/ui/const-generics/generic_const_exprs/division.rs
new file mode 100644
index 000000000..098fa9e04
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/division.rs
@@ -0,0 +1,11 @@
+// run-pass
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+fn with_bound<const N: usize>() where [u8; N / 2]: Sized {
+ let _: [u8; N / 2] = [0; N / 2];
+}
+
+fn main() {
+ with_bound::<4>();
+}
diff --git a/src/test/ui/const-generics/generic_const_exprs/dont-eagerly-error-in-is-const-evaluatable.rs b/src/test/ui/const-generics/generic_const_exprs/dont-eagerly-error-in-is-const-evaluatable.rs
new file mode 100644
index 000000000..3543960c3
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/dont-eagerly-error-in-is-const-evaluatable.rs
@@ -0,0 +1,16 @@
+// run-pass
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+// This test is a repro for #82279. It checks that we don't error
+// when calling is_const_evaluatable on `std::mem::size_of::<T>()`
+// when looking for candidates that may prove `T: Foo` in `foo`
+
+trait Foo {}
+
+#[allow(dead_code)]
+fn foo<T: Foo>() {}
+
+impl<T> Foo for T where [(); std::mem::size_of::<T>()]: {}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/generic_const_exprs/drop_impl.rs b/src/test/ui/const-generics/generic_const_exprs/drop_impl.rs
new file mode 100644
index 000000000..077f77aa0
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/drop_impl.rs
@@ -0,0 +1,16 @@
+//check-pass
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+struct Foo<const N: usize>
+where
+ [(); N + 1]: ;
+
+impl<const N: usize> Drop for Foo<N>
+where
+ [(); N + 1]: ,
+{
+ fn drop(&mut self) {}
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/generic_const_exprs/elaborate-trait-pred.rs b/src/test/ui/const-generics/generic_const_exprs/elaborate-trait-pred.rs
new file mode 100644
index 000000000..e4111157e
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/elaborate-trait-pred.rs
@@ -0,0 +1,24 @@
+// run-pass
+// Test that we use the elaborated predicates from traits
+// to satisfy const evaluatable predicates.
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+use std::mem::size_of;
+
+trait Foo: Sized
+where
+ [(); size_of::<Self>()]: Sized,
+{
+}
+
+impl Foo for u64 {}
+impl Foo for u32 {}
+
+fn foo<T: Foo>() -> [u8; size_of::<T>()] {
+ [0; size_of::<T>()]
+}
+
+fn main() {
+ assert_eq!(foo::<u32>(), [0; 4]);
+ assert_eq!(foo::<u64>(), [0; 8]);
+}
diff --git a/src/test/ui/const-generics/generic_const_exprs/eval-privacy.rs b/src/test/ui/const-generics/generic_const_exprs/eval-privacy.rs
new file mode 100644
index 000000000..8023b998a
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/eval-privacy.rs
@@ -0,0 +1,26 @@
+#![crate_type = "lib"]
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+pub struct Const<const U: u8>;
+
+pub trait Trait {
+ type AssocTy;
+ fn assoc_fn() -> Self::AssocTy;
+}
+
+impl<const U: u8> Trait for Const<U> // OK, trait impl predicates
+where
+ Const<{ my_const_fn(U) }>: ,
+{
+ type AssocTy = Const<{ my_const_fn(U) }>;
+ //~^ ERROR private type
+ fn assoc_fn() -> Self::AssocTy {
+ Const
+ }
+}
+
+const fn my_const_fn(val: u8) -> u8 {
+ // body of this function doesn't matter
+ val
+}
diff --git a/src/test/ui/const-generics/generic_const_exprs/eval-privacy.stderr b/src/test/ui/const-generics/generic_const_exprs/eval-privacy.stderr
new file mode 100644
index 000000000..2d9de8805
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/eval-privacy.stderr
@@ -0,0 +1,12 @@
+error[E0446]: private type `fn(u8) -> u8 {my_const_fn}` in public interface
+ --> $DIR/eval-privacy.rs:16:5
+ |
+LL | type AssocTy = Const<{ my_const_fn(U) }>;
+ | ^^^^^^^^^^^^ can't leak private type
+...
+LL | const fn my_const_fn(val: u8) -> u8 {
+ | ----------------------------------- `fn(u8) -> u8 {my_const_fn}` declared as private
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0446`.
diff --git a/src/test/ui/const-generics/generic_const_exprs/eval-try-unify.rs b/src/test/ui/const-generics/generic_const_exprs/eval-try-unify.rs
new file mode 100644
index 000000000..c59d62e57
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/eval-try-unify.rs
@@ -0,0 +1,26 @@
+// build-pass
+
+#![feature(generic_const_exprs)]
+//~^ WARNING the feature `generic_const_exprs` is incomplete
+
+trait Generic {
+ const ASSOC: usize;
+}
+
+impl Generic for u8 {
+ const ASSOC: usize = 17;
+}
+impl Generic for u16 {
+ const ASSOC: usize = 13;
+}
+
+
+fn uses_assoc_type<T: Generic, const N: usize>() -> [u8; N + T::ASSOC] {
+ [0; N + T::ASSOC]
+}
+
+fn only_generic_n<const N: usize>() -> [u8; N + 13] {
+ uses_assoc_type::<u16, N>()
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/generic_const_exprs/eval-try-unify.stderr b/src/test/ui/const-generics/generic_const_exprs/eval-try-unify.stderr
new file mode 100644
index 000000000..b5719b3fe
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/eval-try-unify.stderr
@@ -0,0 +1,11 @@
+warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/eval-try-unify.rs:3:12
+ |
+LL | #![feature(generic_const_exprs)]
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(incomplete_features)]` on by default
+ = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/const-generics/generic_const_exprs/evaluated-to-ambig.rs b/src/test/ui/const-generics/generic_const_exprs/evaluated-to-ambig.rs
new file mode 100644
index 000000000..340e35e1c
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/evaluated-to-ambig.rs
@@ -0,0 +1,22 @@
+// check-pass
+
+// We previously always returned ambiguity when equating generic consts, even if they
+// only contain generic parameters. This is incorrect as trying to unify `N > 1` with `M > 1`
+// should fail.
+#![allow(incomplete_features)]
+#![feature(generic_const_exprs)]
+
+enum Assert<const COND: bool> {}
+trait IsTrue {}
+impl IsTrue for Assert<true> {}
+
+struct Foo<const N: usize, const M: usize>;
+trait Bar<const N: usize, const M: usize> {}
+impl<const N: usize, const M: usize> Bar<N, M> for Foo<N, M>
+where
+ Assert<{ N > 1 }>: IsTrue,
+ Assert<{ M > 1 }>: IsTrue,
+{
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/generic_const_exprs/feature-gate-generic_const_exprs.rs b/src/test/ui/const-generics/generic_const_exprs/feature-gate-generic_const_exprs.rs
new file mode 100644
index 000000000..10ab2fd86
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/feature-gate-generic_const_exprs.rs
@@ -0,0 +1,11 @@
+type Arr<const N: usize> = [u8; N - 1];
+//~^ ERROR generic parameters may not be used in const operations
+
+fn test<const N: usize>() -> Arr<N> where Arr<N>: Default {
+ Default::default()
+}
+
+fn main() {
+ let x = test::<33>();
+ assert_eq!(x, [0; 32]);
+}
diff --git a/src/test/ui/const-generics/generic_const_exprs/feature-gate-generic_const_exprs.stderr b/src/test/ui/const-generics/generic_const_exprs/feature-gate-generic_const_exprs.stderr
new file mode 100644
index 000000000..2d60ebaa8
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/feature-gate-generic_const_exprs.stderr
@@ -0,0 +1,11 @@
+error: generic parameters may not be used in const operations
+ --> $DIR/feature-gate-generic_const_exprs.rs:1:33
+ |
+LL | type Arr<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: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/generic_const_exprs/fn_call.rs b/src/test/ui/const-generics/generic_const_exprs/fn_call.rs
new file mode 100644
index 000000000..cbe4277df
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/fn_call.rs
@@ -0,0 +1,30 @@
+// run-pass
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+const fn test_me<T>(a: usize, b: usize) -> usize {
+ if a < b {
+ std::mem::size_of::<T>()
+ } else {
+ usize::MAX
+ }
+}
+
+fn test_simple<T>() -> [u8; std::mem::size_of::<T>()]
+where
+ [u8; std::mem::size_of::<T>()]: Sized,
+{
+ [0; std::mem::size_of::<T>()]
+}
+
+fn test_with_args<T, const N: usize>() -> [u8; test_me::<T>(N, N + 1) + N]
+where
+ [u8; test_me::<T>(N, N + 1) + N]: Sized,
+{
+ [0; test_me::<T>(N, N + 1) + N]
+}
+
+fn main() {
+ assert_eq!([0; 8], test_simple::<u64>());
+ assert_eq!([0; 12], test_with_args::<u64, 4>());
+}
diff --git a/src/test/ui/const-generics/generic_const_exprs/from-sig-fail.rs b/src/test/ui/const-generics/generic_const_exprs/from-sig-fail.rs
new file mode 100644
index 000000000..b8f9827ec
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/from-sig-fail.rs
@@ -0,0 +1,11 @@
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+fn test<const N: usize>() -> [u8; N - 1] {
+ //~^ ERROR evaluation of `test::<0>::{constant#0}` failed
+ todo!()
+}
+
+fn main() {
+ test::<0>();
+}
diff --git a/src/test/ui/const-generics/generic_const_exprs/from-sig-fail.stderr b/src/test/ui/const-generics/generic_const_exprs/from-sig-fail.stderr
new file mode 100644
index 000000000..bd71b49ee
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/from-sig-fail.stderr
@@ -0,0 +1,9 @@
+error[E0080]: evaluation of `test::<0>::{constant#0}` failed
+ --> $DIR/from-sig-fail.rs:4:35
+ |
+LL | fn test<const N: usize>() -> [u8; 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/src/test/ui/const-generics/generic_const_exprs/from-sig.rs b/src/test/ui/const-generics/generic_const_exprs/from-sig.rs
new file mode 100644
index 000000000..28de4f864
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/from-sig.rs
@@ -0,0 +1,14 @@
+// run-pass
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+struct Foo<const B: bool>;
+
+fn test<const N: usize>() -> Foo<{ N > 10 }> {
+ Foo
+}
+
+fn main() {
+ let _: Foo<true> = test::<12>();
+ let _: Foo<false> = test::<9>();
+}
diff --git a/src/test/ui/const-generics/generic_const_exprs/function-call.rs b/src/test/ui/const-generics/generic_const_exprs/function-call.rs
new file mode 100644
index 000000000..b5de66621
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/function-call.rs
@@ -0,0 +1,19 @@
+// check-pass
+
+const fn foo<T>() -> usize {
+ // We might instead branch on `std::mem::size_of::<*mut T>() < 8` here,
+ // which would cause this function to fail on 32 bit systems.
+ if false {
+ std::mem::size_of::<T>()
+ } else {
+ 8
+ }
+}
+
+fn test<T>() {
+ let _ = [0; foo::<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
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/generic_const_exprs/function-call.stderr b/src/test/ui/const-generics/generic_const_exprs/function-call.stderr
new file mode 100644
index 000000000..0d8463714
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/function-call.stderr
@@ -0,0 +1,12 @@
+warning: cannot use constants which depend on generic parameters in types
+ --> $DIR/function-call.rs:14:17
+ |
+LL | let _ = [0; foo::<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: 1 warning emitted
+
diff --git a/src/test/ui/const-generics/generic_const_exprs/impl-bounds.rs b/src/test/ui/const-generics/generic_const_exprs/impl-bounds.rs
new file mode 100644
index 000000000..7120d6ee2
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/impl-bounds.rs
@@ -0,0 +1,25 @@
+// check-pass
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+use std::mem::size_of;
+
+struct Foo<T, const N: usize>(T);
+
+impl<T> Foo<T, { size_of::<T>() }> {
+ fn test() {
+ let _: [u8; std::mem::size_of::<T>()];
+ }
+}
+
+trait Bar<const N: usize> {
+ fn test_me();
+}
+
+impl<T> Bar<{ size_of::<T>() }> for Foo<T, 3> {
+ fn test_me() {
+ let _: [u8; std::mem::size_of::<T>()];
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/generic_const_exprs/infer-too-generic.rs b/src/test/ui/const-generics/generic_const_exprs/infer-too-generic.rs
new file mode 100644
index 000000000..b8058c252
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/infer-too-generic.rs
@@ -0,0 +1,24 @@
+// run-pass
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+use std::{mem, ptr};
+
+fn split_first<T, const N: usize>(arr: [T; N]) -> (T, [T; N - 1])
+where
+ [T; N - 1]: Sized,
+{
+ let arr = mem::ManuallyDrop::new(arr);
+ unsafe {
+ let head = ptr::read(&arr[0]);
+ let tail = ptr::read(&arr[1..] as *const [T] as *const [T; N - 1]);
+ (head, tail)
+ }
+}
+
+fn main() {
+ let arr = [0, 1, 2, 3, 4];
+ let (head, tail) = split_first(arr);
+ assert_eq!(head, 0);
+ assert_eq!(tail, [1, 2, 3, 4]);
+}
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-62504.full.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-62504.full.stderr
new file mode 100644
index 000000000..f2ae361dc
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-62504.full.stderr
@@ -0,0 +1,20 @@
+error[E0308]: mismatched types
+ --> $DIR/issue-62504.rs:18:21
+ |
+LL | ArrayHolder([0; Self::SIZE])
+ | ^^^^^^^^^^^^^^^ expected `X`, found `Self::SIZE`
+ |
+ = note: expected type `X`
+ found type `Self::SIZE`
+
+error: unconstrained generic constant
+ --> $DIR/issue-62504.rs:18:25
+ |
+LL | ArrayHolder([0; Self::SIZE])
+ | ^^^^^^^^^^
+ |
+ = help: try adding a `where` bound using this expression: `where [(); Self::SIZE]:`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-62504.min.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-62504.min.stderr
new file mode 100644
index 000000000..9bea4105d
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-62504.min.stderr
@@ -0,0 +1,27 @@
+error: constant expression depends on a generic parameter
+ --> $DIR/issue-62504.rs:18:25
+ |
+LL | ArrayHolder([0; Self::SIZE])
+ | ^^^^^^^^^^
+ |
+ = note: this may fail depending on what value the parameter takes
+
+error[E0308]: mismatched types
+ --> $DIR/issue-62504.rs:18:21
+ |
+LL | ArrayHolder([0; Self::SIZE])
+ | ----------- ^^^^^^^^^^^^^^^ expected `X`, found `Self::SIZE`
+ | |
+ | arguments to this struct are incorrect
+ |
+ = note: expected array `[u32; X]`
+ found array `[u32; _]`
+note: tuple struct defined here
+ --> $DIR/issue-62504.rs:14:8
+ |
+LL | struct ArrayHolder<const X: usize>([u32; X]);
+ | ^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-62504.rs b/src/test/ui/const-generics/generic_const_exprs/issue-62504.rs
new file mode 100644
index 000000000..a97f4b8ff
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-62504.rs
@@ -0,0 +1,27 @@
+// revisions: full min
+#![allow(incomplete_features)]
+#![cfg_attr(full, feature(generic_const_exprs))]
+#![cfg_attr(full, allow(incomplete_features))]
+
+trait HasSize {
+ const SIZE: usize;
+}
+
+impl<const X: usize> HasSize for ArrayHolder<X> {
+ const SIZE: usize = X;
+}
+
+struct ArrayHolder<const X: usize>([u32; X]);
+
+impl<const X: usize> ArrayHolder<X> {
+ pub const fn new() -> Self {
+ ArrayHolder([0; Self::SIZE])
+ //~^ ERROR mismatched types
+ //[full]~^^ ERROR unconstrained generic constant
+ //[min]~^^^ ERROR constant expression depends on a generic parameter
+ }
+}
+
+fn main() {
+ let mut array = ArrayHolder::new();
+}
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-69654.rs b/src/test/ui/const-generics/generic_const_exprs/issue-69654.rs
new file mode 100644
index 000000000..9b36699bb
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-69654.rs
@@ -0,0 +1,19 @@
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+trait Bar<T> {}
+impl<T> Bar<T> for [u8; T] {}
+//~^ ERROR expected value, found type parameter `T`
+
+struct Foo<const N: usize> {}
+impl<const N: usize> Foo<N>
+where
+ [u8; N]: Bar<[(); N]>,
+{
+ fn foo() {}
+}
+
+fn main() {
+ Foo::foo();
+ //~^ ERROR the function or associated item
+}
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-69654.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-69654.stderr
new file mode 100644
index 000000000..7a083733a
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-69654.stderr
@@ -0,0 +1,22 @@
+error[E0423]: expected value, found type parameter `T`
+ --> $DIR/issue-69654.rs:5:25
+ |
+LL | impl<T> Bar<T> for [u8; T] {}
+ | ^ not a value
+
+error[E0599]: the function or associated item `foo` exists for struct `Foo<_>`, but its trait bounds were not satisfied
+ --> $DIR/issue-69654.rs:17:10
+ |
+LL | struct Foo<const N: usize> {}
+ | -------------------------- function or associated item `foo` not found for this struct
+...
+LL | Foo::foo();
+ | ^^^ function or associated item cannot be called on `Foo<_>` due to unsatisfied trait bounds
+ |
+ = note: the following trait bounds were not satisfied:
+ `[u8; _]: Bar<[(); _]>`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0423, E0599.
+For more information about an error, try `rustc --explain E0423`.
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-72787.min.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-72787.min.stderr
new file mode 100644
index 000000000..4d0d0253f
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-72787.min.stderr
@@ -0,0 +1,55 @@
+error: generic parameters may not be used in const operations
+ --> $DIR/issue-72787.rs:11:17
+ |
+LL | Condition<{ LHS <= RHS }>: True
+ | ^^^ cannot perform const operation using `LHS`
+ |
+ = help: const parameters may only be used as standalone arguments, i.e. `LHS`
+ = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+
+error: generic parameters may not be used in const operations
+ --> $DIR/issue-72787.rs:11:24
+ |
+LL | Condition<{ LHS <= RHS }>: True
+ | ^^^ cannot perform const operation using `RHS`
+ |
+ = help: const parameters may only be used as standalone arguments, i.e. `RHS`
+ = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+
+error: generic parameters may not be used in const operations
+ --> $DIR/issue-72787.rs:25:25
+ |
+LL | IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
+ | ^ cannot perform const operation using `I`
+ |
+ = help: const parameters may only be used as standalone arguments, i.e. `I`
+ = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+
+error: generic parameters may not be used in const operations
+ --> $DIR/issue-72787.rs:25:36
+ |
+LL | IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
+ | ^ cannot perform const operation using `J`
+ |
+ = help: const parameters may only be used as standalone arguments, i.e. `J`
+ = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+
+error[E0283]: type annotations needed: cannot satisfy `IsLessOrEqual<I, 8>: True`
+ --> $DIR/issue-72787.rs:21:26
+ |
+LL | IsLessOrEqual<I, 8>: True,
+ | ^^^^
+ |
+ = note: cannot satisfy `IsLessOrEqual<I, 8>: True`
+
+error[E0283]: type annotations needed: cannot satisfy `IsLessOrEqual<I, 8>: True`
+ --> $DIR/issue-72787.rs:21:26
+ |
+LL | IsLessOrEqual<I, 8>: True,
+ | ^^^^
+ |
+ = note: cannot satisfy `IsLessOrEqual<I, 8>: True`
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0283`.
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-72787.rs b/src/test/ui/const-generics/generic_const_exprs/issue-72787.rs
new file mode 100644
index 000000000..c651bf1c8
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-72787.rs
@@ -0,0 +1,35 @@
+// [full] check-pass
+// revisions: full min
+#![cfg_attr(full, feature(generic_const_exprs))]
+#![cfg_attr(full, allow(incomplete_features))]
+
+pub struct IsLessOrEqual<const LHS: u32, const RHS: u32>;
+pub struct Condition<const CONDITION: bool>;
+pub trait True {}
+
+impl<const LHS: u32, const RHS: u32> True for IsLessOrEqual<LHS, RHS> where
+ Condition<{ LHS <= RHS }>: True
+//[min]~^ Error generic parameters may not be used in const operations
+//[min]~| Error generic parameters may not be used in const operations
+{
+}
+impl True for Condition<true> {}
+
+struct S<const I: u32, const J: u32>;
+impl<const I: u32, const J: u32> S<I, J>
+where
+ IsLessOrEqual<I, 8>: True,
+//[min]~^ Error type annotations needed
+//[min]~| Error type annotations needed
+ IsLessOrEqual<J, 8>: True,
+ IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
+//[min]~^ Error generic parameters may not be used in const operations
+//[min]~| Error generic parameters may not be used in const operations
+ // Condition<{ 8 - I <= 8 - J }>: True,
+{
+ fn print() {
+ println!("I {} J {}", I, J);
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.full.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.full.stderr
new file mode 100644
index 000000000..d536f6fd1
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.full.stderr
@@ -0,0 +1,21 @@
+error[E0308]: mismatched types
+ --> $DIR/issue-72819-generic-in-const-eval.rs:20:12
+ |
+LL | let x: Arr<{usize::MAX}> = Arr {};
+ | ^^^^^^^^^^^^^^^^^ expected `false`, found `true`
+ |
+ = note: expected type `false`
+ found type `true`
+
+error[E0308]: mismatched types
+ --> $DIR/issue-72819-generic-in-const-eval.rs:20:32
+ |
+LL | let x: Arr<{usize::MAX}> = Arr {};
+ | ^^^ expected `false`, found `true`
+ |
+ = note: expected type `false`
+ found type `true`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.min.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.min.stderr
new file mode 100644
index 000000000..42671412f
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.min.stderr
@@ -0,0 +1,11 @@
+error: generic parameters may not be used in const operations
+ --> $DIR/issue-72819-generic-in-const-eval.rs:8:17
+ |
+LL | where Assert::<{N < usize::MAX / 2}>: IsTrue,
+ | ^ 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: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.rs b/src/test/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.rs
new file mode 100644
index 000000000..7a5aa9e47
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.rs
@@ -0,0 +1,23 @@
+// Regression test for #72819: ICE due to failure in resolving the const generic in `Arr`'s type
+// bounds.
+// revisions: full min
+#![cfg_attr(full, feature(generic_const_exprs))]
+#![cfg_attr(full, allow(incomplete_features))]
+
+struct Arr<const N: usize>
+where Assert::<{N < usize::MAX / 2}>: IsTrue,
+//[min]~^ ERROR generic parameters may not be used in const operations
+{
+}
+
+enum Assert<const CHECK: bool> {}
+
+trait IsTrue {}
+
+impl IsTrue for Assert<true> {}
+
+fn main() {
+ let x: Arr<{usize::MAX}> = Arr {};
+ //[full]~^ ERROR mismatched types
+ //[full]~| ERROR mismatched types
+}
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-73899.rs b/src/test/ui/const-generics/generic_const_exprs/issue-73899.rs
new file mode 100644
index 000000000..d1ab1be04
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-73899.rs
@@ -0,0 +1,20 @@
+// run-pass
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+trait Foo {}
+
+impl<const N: usize> Foo for [(); N] where Self: FooImpl<{ N == 0 }> {}
+
+trait FooImpl<const IS_ZERO: bool> {}
+
+impl FooImpl<{ 0u8 == 0u8 }> for [(); 0] {}
+
+impl<const N: usize> FooImpl<{ 0u8 != 0u8 }> for [(); N] {}
+
+fn foo<T: Foo>(_v: T) {}
+
+fn main() {
+ foo([]);
+ foo([()]);
+}
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-74634.rs b/src/test/ui/const-generics/generic_const_exprs/issue-74634.rs
new file mode 100644
index 000000000..cd1f7a9da
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-74634.rs
@@ -0,0 +1,28 @@
+// check-pass
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+trait If<const COND: bool> {}
+impl If<true> for () {}
+
+trait IsZero<const N: u8> {
+ type Answer;
+}
+
+struct True;
+struct False;
+
+impl<const N: u8> IsZero<N> for ()
+where (): If<{N == 0}> {
+ type Answer = True;
+}
+
+trait Foobar<const N: u8> {}
+
+impl<const N: u8> Foobar<N> for ()
+where (): IsZero<N, Answer = True> {}
+
+impl<const N: u8> Foobar<N> for ()
+where (): IsZero<N, Answer = False> {}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-74713.rs b/src/test/ui/const-generics/generic_const_exprs/issue-74713.rs
new file mode 100644
index 000000000..0bcb997d9
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-74713.rs
@@ -0,0 +1,8 @@
+fn bug<'a>()
+where
+ [(); { //~ ERROR mismatched types
+ let _: &'a (); //~ ERROR a non-static lifetime is not allowed in a `const`
+ }]:
+{}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-74713.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-74713.stderr
new file mode 100644
index 000000000..e7673df0a
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-74713.stderr
@@ -0,0 +1,22 @@
+error[E0658]: a non-static lifetime is not allowed in a `const`
+ --> $DIR/issue-74713.rs:4:17
+ |
+LL | let _: &'a ();
+ | ^^
+ |
+ = 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[E0308]: mismatched types
+ --> $DIR/issue-74713.rs:3:10
+ |
+LL | [(); {
+ | __________^
+LL | | let _: &'a ();
+LL | | }]:
+ | |_____^ expected `usize`, found `()`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0308, E0658.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-76595.rs b/src/test/ui/const-generics/generic_const_exprs/issue-76595.rs
new file mode 100644
index 000000000..faa8b3d10
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-76595.rs
@@ -0,0 +1,17 @@
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+struct Bool<const B: bool>;
+
+trait True {}
+
+impl True for Bool<true> {}
+
+fn test<T, const P: usize>() where Bool<{core::mem::size_of::<T>() > 4}>: True {
+ todo!()
+}
+
+fn main() {
+ test::<2>();
+ //~^ ERROR this function takes 2 generic arguments
+}
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-76595.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-76595.stderr
new file mode 100644
index 000000000..c587a7e15
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-76595.stderr
@@ -0,0 +1,21 @@
+error[E0107]: this function takes 2 generic arguments but 1 generic argument was supplied
+ --> $DIR/issue-76595.rs:15:5
+ |
+LL | test::<2>();
+ | ^^^^ - supplied 1 generic argument
+ | |
+ | expected 2 generic arguments
+ |
+note: function defined here, with 2 generic parameters: `T`, `P`
+ --> $DIR/issue-76595.rs:10:4
+ |
+LL | fn test<T, const P: usize>() where Bool<{core::mem::size_of::<T>() > 4}>: True {
+ | ^^^^ - --------------
+help: add missing generic argument
+ |
+LL | test::<2, P>();
+ | +++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0107`.
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-79518-default_trait_method_normalization.rs b/src/test/ui/const-generics/generic_const_exprs/issue-79518-default_trait_method_normalization.rs
new file mode 100644
index 000000000..2fa9a71fb
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-79518-default_trait_method_normalization.rs
@@ -0,0 +1,21 @@
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+// This test is a minimized reproduction for #79518 where
+// during error handling for the type mismatch we would try
+// to evaluate std::mem::size_of::<Self::Assoc> causing an ICE
+
+trait Foo {
+ type Assoc: PartialEq;
+ const AssocInstance: Self::Assoc;
+
+ fn foo()
+ where
+ [(); std::mem::size_of::<Self::Assoc>()]: ,
+ {
+ Self::AssocInstance == [(); std::mem::size_of::<Self::Assoc>()];
+ //~^ Error: mismatched types
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-79518-default_trait_method_normalization.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-79518-default_trait_method_normalization.stderr
new file mode 100644
index 000000000..c90774e94
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-79518-default_trait_method_normalization.stderr
@@ -0,0 +1,14 @@
+error[E0308]: mismatched types
+ --> $DIR/issue-79518-default_trait_method_normalization.rs:16:32
+ |
+LL | Self::AssocInstance == [(); std::mem::size_of::<Self::Assoc>()];
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected associated type, found array `[(); _]`
+ |
+ = note: expected associated type `<Self as Foo>::Assoc`
+ found array `[(); _]`
+ = help: consider constraining the associated type `<Self as Foo>::Assoc` to `[(); _]` or calling a method that returns `<Self as Foo>::Assoc`
+ = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-80561-incorrect-param-env.rs b/src/test/ui/const-generics/generic_const_exprs/issue-80561-incorrect-param-env.rs
new file mode 100644
index 000000000..77d3c98da
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-80561-incorrect-param-env.rs
@@ -0,0 +1,24 @@
+// check-pass
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+// This tests that the correct `param_env` is used so that
+// attempting to normalize `Self::N` does not cause an ICE.
+
+pub struct Foo<const N: usize>;
+
+impl<const N: usize> Foo<N> {
+ pub fn foo() {}
+}
+
+pub trait Bar {
+ const N: usize;
+ fn bar()
+ where
+ [(); Self::N]: ,
+ {
+ Foo::<{ Self::N }>::foo();
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-80742.rs b/src/test/ui/const-generics/generic_const_exprs/issue-80742.rs
new file mode 100644
index 000000000..275f69953
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-80742.rs
@@ -0,0 +1,32 @@
+// check-fail
+
+// This test used to cause an ICE in rustc_mir::interpret::step::eval_rvalue_into_place
+
+#![allow(incomplete_features)]
+#![feature(generic_const_exprs)]
+
+use std::fmt::Debug;
+use std::marker::PhantomData;
+use std::mem::size_of;
+
+struct Inline<T>
+where
+ [u8; size_of::<T>() + 1]: ,
+{
+ _phantom: PhantomData<T>,
+ buf: [u8; size_of::<T>() + 1],
+}
+
+impl<T> Inline<T>
+where
+ [u8; size_of::<T>() + 1]: ,
+{
+ pub fn new(val: T) -> Inline<T> {
+ todo!()
+ }
+}
+
+fn main() {
+ let dst = Inline::<dyn Debug>::new(0); //~ ERROR
+ //~^ ERROR
+}
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-80742.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-80742.stderr
new file mode 100644
index 000000000..1b502642e
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-80742.stderr
@@ -0,0 +1,66 @@
+error[E0080]: evaluation of `Inline::<dyn std::fmt::Debug>::{constant#0}` failed
+ --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
+ |
+LL | intrinsics::size_of::<T>()
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | size_of called on unsized type `dyn Debug`
+ | inside `std::mem::size_of::<dyn Debug>` at $SRC_DIR/core/src/mem/mod.rs:LL:COL
+ |
+ ::: $DIR/issue-80742.rs:22:10
+ |
+LL | [u8; size_of::<T>() + 1]: ,
+ | -------------- inside `Inline::<dyn Debug>::{constant#0}` at $DIR/issue-80742.rs:22:10
+
+error[E0599]: the function or associated item `new` exists for struct `Inline<dyn Debug>`, but its trait bounds were not satisfied
+ --> $DIR/issue-80742.rs:30:36
+ |
+LL | struct Inline<T>
+ | ---------------- function or associated item `new` not found for this struct
+...
+LL | let dst = Inline::<dyn Debug>::new(0);
+ | ^^^ function or associated item cannot be called on `Inline<dyn Debug>` due to unsatisfied trait bounds
+ |
+ ::: $SRC_DIR/core/src/fmt/mod.rs:LL:COL
+ |
+LL | pub trait Debug {
+ | --------------- doesn't satisfy `dyn Debug: Sized`
+ |
+ = note: the following trait bounds were not satisfied:
+ `dyn Debug: Sized`
+
+error[E0080]: evaluation of `Inline::<dyn std::fmt::Debug>::{constant#0}` failed
+ --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
+ |
+LL | intrinsics::size_of::<T>()
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | size_of called on unsized type `dyn Debug`
+ | inside `std::mem::size_of::<dyn Debug>` at $SRC_DIR/core/src/mem/mod.rs:LL:COL
+ |
+ ::: $DIR/issue-80742.rs:14:10
+ |
+LL | [u8; size_of::<T>() + 1]: ,
+ | -------------- inside `Inline::<dyn Debug>::{constant#0}` at $DIR/issue-80742.rs:14:10
+
+error[E0277]: the size for values of type `dyn Debug` cannot be known at compilation time
+ --> $DIR/issue-80742.rs:30:15
+ |
+LL | let dst = Inline::<dyn Debug>::new(0);
+ | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+ |
+ = help: the trait `Sized` is not implemented for `dyn Debug`
+note: required by a bound in `Inline`
+ --> $DIR/issue-80742.rs:12:15
+ |
+LL | struct Inline<T>
+ | ^ required by this bound in `Inline`
+help: consider relaxing the implicit `Sized` restriction
+ |
+LL | struct Inline<T: ?Sized>
+ | ++++++++
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0080, E0277, E0599.
+For more information about an error, try `rustc --explain E0080`.
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-83765.rs b/src/test/ui/const-generics/generic_const_exprs/issue-83765.rs
new file mode 100644
index 000000000..fac811d13
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-83765.rs
@@ -0,0 +1,38 @@
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+trait TensorDimension {
+ const DIM: usize;
+}
+
+trait TensorSize: TensorDimension {
+ fn size(&self) -> [usize; Self::DIM];
+}
+
+trait Broadcastable: TensorSize + Sized {
+ type Element;
+ fn lazy_updim<const NEWDIM: usize>(&self, size: [usize; NEWDIM]) {}
+}
+
+struct BMap<'a, R, T: Broadcastable, F: Fn(T::Element) -> R, const DIM: usize> {
+ reference: &'a T,
+ closure: F,
+}
+
+impl<'a, R, T: Broadcastable, F: Fn(T::Element) -> R, const DIM: usize> TensorDimension
+ for BMap<'a, R, T, F, DIM>
+{
+ const DIM: usize = DIM;
+}
+impl<'a, R, T: Broadcastable, F: Fn(T::Element) -> R, const DIM: usize> TensorSize
+ for BMap<'a, R, T, F, DIM>
+{
+ fn size(&self) -> [usize; DIM] {
+ //~^ ERROR: method not compatible with trait [E0308]
+ self.reference.size()
+ //~^ ERROR: unconstrained generic constant
+ //~| ERROR: mismatched types
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-83765.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-83765.stderr
new file mode 100644
index 000000000..0332e82fe
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-83765.stderr
@@ -0,0 +1,34 @@
+error[E0308]: method not compatible with trait
+ --> $DIR/issue-83765.rs:30:5
+ |
+LL | fn size(&self) -> [usize; DIM] {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Self::DIM`, found `DIM`
+ |
+ = note: expected type `Self::DIM`
+ found type `DIM`
+
+error: unconstrained generic constant
+ --> $DIR/issue-83765.rs:32:24
+ |
+LL | self.reference.size()
+ | ^^^^
+ |
+ = help: try adding a `where` bound using this expression: `where [(); Self::DIM]:`
+note: required by a bound in `TensorSize::size`
+ --> $DIR/issue-83765.rs:9:31
+ |
+LL | fn size(&self) -> [usize; Self::DIM];
+ | ^^^^^^^^^ required by this bound in `TensorSize::size`
+
+error[E0308]: mismatched types
+ --> $DIR/issue-83765.rs:32:9
+ |
+LL | self.reference.size()
+ | ^^^^^^^^^^^^^^^^^^^^^ expected `DIM`, found `Self::DIM`
+ |
+ = note: expected type `DIM`
+ found type `Self::DIM`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-84408.rs b/src/test/ui/const-generics/generic_const_exprs/issue-84408.rs
new file mode 100644
index 000000000..fb2e5590d
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-84408.rs
@@ -0,0 +1,38 @@
+// Regression test for #84408.
+// check-pass
+
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+trait Melon<const X: usize> {
+ fn new(arr: [i32; X]) -> Self;
+ fn change<T: Melon<X>>(self) -> T;
+}
+
+struct Foo([i32; 5]);
+struct Bar<const A: usize, const B: usize>([i32; A + B])
+where
+ [(); A + B]: ;
+
+impl Melon<5> for Foo {
+ fn new(arr: [i32; 5]) -> Self {
+ Foo(arr)
+ }
+ fn change<T: Melon<5>>(self) -> T {
+ T::new(self.0)
+ }
+}
+
+impl<const A: usize, const B: usize> Melon<{ A + B }> for Bar<A, B>
+where
+ [(); A + B]: ,
+{
+ fn new(arr: [i32; A + B]) -> Self {
+ Bar(arr)
+ }
+ fn change<T: Melon<{ A + B }>>(self) -> T {
+ T::new(self.0)
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-85848.rs b/src/test/ui/const-generics/generic_const_exprs/issue-85848.rs
new file mode 100644
index 000000000..3a7f4c618
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-85848.rs
@@ -0,0 +1,32 @@
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+trait _Contains<T> {
+ const does_contain: bool;
+}
+
+trait Contains<T, const Satisfied: bool> {}
+
+trait Delegates<T> {}
+
+impl<T, U> Delegates<U> for T where T: Contains<U, true> {}
+
+const fn contains<A, B>() -> bool
+where
+ A: _Contains<B>,
+{
+ A::does_contain
+}
+
+impl<T, U> Contains<T, { contains::<T, U>() }> for U where T: _Contains<U> {}
+
+fn writes_to_path<C>(cap: &C) {
+ writes_to_specific_path(&cap);
+ //~^ ERROR: the trait bound `(): _Contains<&C>` is not satisfied [E0277]
+ //~| ERROR: unconstrained generic constant
+ //~| ERROR: mismatched types [E0308]
+}
+
+fn writes_to_specific_path<C: Delegates<()>>(cap: &C) {}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-85848.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-85848.stderr
new file mode 100644
index 000000000..d45dfde9a
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-85848.stderr
@@ -0,0 +1,63 @@
+error[E0277]: the trait bound `(): _Contains<&C>` is not satisfied
+ --> $DIR/issue-85848.rs:24:29
+ |
+LL | writes_to_specific_path(&cap);
+ | ----------------------- ^^^^ the trait `_Contains<&C>` is not implemented for `()`
+ | |
+ | required by a bound introduced by this call
+ |
+ = help: the trait `Delegates<U>` is implemented for `T`
+note: required because of the requirements on the impl of `Contains<(), true>` for `&C`
+ --> $DIR/issue-85848.rs:21:12
+ |
+LL | impl<T, U> Contains<T, { contains::<T, U>() }> for U where T: _Contains<U> {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^
+note: required because of the requirements on the impl of `Delegates<()>` for `&C`
+ --> $DIR/issue-85848.rs:12:12
+ |
+LL | impl<T, U> Delegates<U> for T where T: Contains<U, true> {}
+ | ^^^^^^^^^^^^ ^
+note: required by a bound in `writes_to_specific_path`
+ --> $DIR/issue-85848.rs:30:31
+ |
+LL | fn writes_to_specific_path<C: Delegates<()>>(cap: &C) {}
+ | ^^^^^^^^^^^^^ required by this bound in `writes_to_specific_path`
+
+error: unconstrained generic constant
+ --> $DIR/issue-85848.rs:24:29
+ |
+LL | writes_to_specific_path(&cap);
+ | ----------------------- ^^^^
+ | |
+ | required by a bound introduced by this call
+ |
+ = help: try adding a `where` bound using this expression: `where [(); { contains::<T, U>() }]:`
+note: required because of the requirements on the impl of `Contains<(), true>` for `&C`
+ --> $DIR/issue-85848.rs:21:12
+ |
+LL | impl<T, U> Contains<T, { contains::<T, U>() }> for U where T: _Contains<U> {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^
+note: required because of the requirements on the impl of `Delegates<()>` for `&C`
+ --> $DIR/issue-85848.rs:12:12
+ |
+LL | impl<T, U> Delegates<U> for T where T: Contains<U, true> {}
+ | ^^^^^^^^^^^^ ^
+note: required by a bound in `writes_to_specific_path`
+ --> $DIR/issue-85848.rs:30:31
+ |
+LL | fn writes_to_specific_path<C: Delegates<()>>(cap: &C) {}
+ | ^^^^^^^^^^^^^ required by this bound in `writes_to_specific_path`
+
+error[E0308]: mismatched types
+ --> $DIR/issue-85848.rs:24:5
+ |
+LL | writes_to_specific_path(&cap);
+ | ^^^^^^^^^^^^^^^^^^^^^^^ expected `true`, found `{ contains::<T, U>() }`
+ |
+ = note: expected type `true`
+ found type `{ contains::<T, U>() }`
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0277, E0308.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-90847.rs b/src/test/ui/const-generics/generic_const_exprs/issue-90847.rs
new file mode 100644
index 000000000..ebc6fe141
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-90847.rs
@@ -0,0 +1,9 @@
+// check-pass
+
+#![allow(incomplete_features)]
+#![feature(generic_const_exprs)]
+#![feature(adt_const_params)]
+
+struct Foo<const A: [(); 0 + 0]> where [(); 0 + 0]: Sized;
+
+fn main() {}
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-94287.rs b/src/test/ui/const-generics/generic_const_exprs/issue-94287.rs
new file mode 100644
index 000000000..643126a46
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-94287.rs
@@ -0,0 +1,10 @@
+// aux-build:issue-94287-aux.rs
+// build-fail
+
+extern crate issue_94287_aux;
+
+use std::str::FromStr;
+
+fn main() {
+ let _ = <issue_94287_aux::FixedI32<16>>::from_str("");
+}
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-94287.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-94287.stderr
new file mode 100644
index 000000000..7390a0077
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-94287.stderr
@@ -0,0 +1,15 @@
+error: failed to evaluate generic const expression
+ --> $DIR/auxiliary/issue-94287-aux.rs:15:8
+ |
+LL | If<{ FRAC <= 32 }>: True,
+ | ^^^^^^^^^^^^^^
+ |
+ = note: the crate this constant originates from uses `#![feature(generic_const_exprs)]`
+help: consider enabling this feature
+ --> $DIR/issue-94287.rs:1:1
+ |
+LL | #![feature(generic_const_exprs)]
+ |
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-97047-ice-1.rs b/src/test/ui/const-generics/generic_const_exprs/issue-97047-ice-1.rs
new file mode 100644
index 000000000..67e30232e
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-97047-ice-1.rs
@@ -0,0 +1,25 @@
+// check-pass
+
+#![feature(adt_const_params, generic_const_exprs)]
+//~^ WARN the feature `adt_const_params` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features]
+//~^^ WARN the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features]
+
+pub struct Changes<const CHANGES: &'static [&'static str]>
+where
+ [(); CHANGES.len()]:,
+{
+ changes: [usize; CHANGES.len()],
+}
+
+impl<const CHANGES: &'static [&'static str]> Changes<CHANGES>
+where
+ [(); CHANGES.len()]:,
+{
+ pub const fn new() -> Self {
+ Self {
+ changes: [0; CHANGES.len()],
+ }
+ }
+}
+
+pub fn main() {}
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-97047-ice-1.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-97047-ice-1.stderr
new file mode 100644
index 000000000..b5b2b0e40
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-97047-ice-1.stderr
@@ -0,0 +1,19 @@
+warning: the feature `adt_const_params` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/issue-97047-ice-1.rs:3:12
+ |
+LL | #![feature(adt_const_params, generic_const_exprs)]
+ | ^^^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(incomplete_features)]` on by default
+ = note: see issue #95174 <https://github.com/rust-lang/rust/issues/95174> for more information
+
+warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/issue-97047-ice-1.rs:3:30
+ |
+LL | #![feature(adt_const_params, generic_const_exprs)]
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
+
+warning: 2 warnings emitted
+
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-97047-ice-2.rs b/src/test/ui/const-generics/generic_const_exprs/issue-97047-ice-2.rs
new file mode 100644
index 000000000..00568a089
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-97047-ice-2.rs
@@ -0,0 +1,23 @@
+// check-pass
+
+#![feature(adt_const_params, generic_const_exprs)]
+//~^ WARN the feature `adt_const_params` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features]
+//~^^ WARN the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features]
+
+pub struct Changes<const CHANGES: &'static [&'static str]>
+where
+ [(); CHANGES.len()]:,
+{
+ changes: [usize; CHANGES.len()],
+}
+
+impl<const CHANGES: &'static [&'static str]> Changes<CHANGES>
+where
+ [(); CHANGES.len()]:,
+{
+ pub fn combine(&mut self, other: &Self) {
+ for _change in &self.changes {}
+ }
+}
+
+pub fn main() {}
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-97047-ice-2.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-97047-ice-2.stderr
new file mode 100644
index 000000000..5dfbd87cc
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-97047-ice-2.stderr
@@ -0,0 +1,19 @@
+warning: the feature `adt_const_params` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/issue-97047-ice-2.rs:3:12
+ |
+LL | #![feature(adt_const_params, generic_const_exprs)]
+ | ^^^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(incomplete_features)]` on by default
+ = note: see issue #95174 <https://github.com/rust-lang/rust/issues/95174> for more information
+
+warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/issue-97047-ice-2.rs:3:30
+ |
+LL | #![feature(adt_const_params, generic_const_exprs)]
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
+
+warning: 2 warnings emitted
+
diff --git a/src/test/ui/const-generics/generic_const_exprs/less_than.rs b/src/test/ui/const-generics/generic_const_exprs/less_than.rs
new file mode 100644
index 000000000..2e9af1bf4
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/less_than.rs
@@ -0,0 +1,14 @@
+// run-pass
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+struct Foo<const B: bool>;
+
+fn test<const N: usize>() -> Foo<{ N > 10 }> where Foo<{ N > 10 }>: Sized {
+ Foo
+}
+
+fn main() {
+ let _: Foo<true> = test::<12>();
+ let _: Foo<false> = test::<9>();
+}
diff --git a/src/test/ui/const-generics/generic_const_exprs/let-bindings.rs b/src/test/ui/const-generics/generic_const_exprs/let-bindings.rs
new file mode 100644
index 000000000..cd5d76dd9
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/let-bindings.rs
@@ -0,0 +1,15 @@
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+// We do not yet want to support let-bindings in abstract consts,
+// so this test should keep failing for now.
+fn test<const N: usize>() -> [u8; { let x = N; N + 1 }] where [u8; { let x = N; N + 1 }]: Default {
+ //~^ ERROR overly complex generic constant
+ //~| ERROR overly complex generic constant
+ Default::default()
+}
+
+fn main() {
+ let x = test::<31>();
+ assert_eq!(x, [0; 32]);
+}
diff --git a/src/test/ui/const-generics/generic_const_exprs/let-bindings.stderr b/src/test/ui/const-generics/generic_const_exprs/let-bindings.stderr
new file mode 100644
index 000000000..5ebb4c399
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/let-bindings.stderr
@@ -0,0 +1,20 @@
+error: overly complex generic constant
+ --> $DIR/let-bindings.rs:6:68
+ |
+LL | fn test<const N: usize>() -> [u8; { let x = N; N + 1 }] where [u8; { let x = N; N + 1 }]: Default {
+ | ^^^^^^^^^^^^^^^^^^^^ blocks are not supported in generic constant
+ |
+ = help: consider moving this anonymous constant into a `const` function
+ = note: this operation may be supported in the future
+
+error: overly complex generic constant
+ --> $DIR/let-bindings.rs:6:35
+ |
+LL | fn test<const N: usize>() -> [u8; { let x = N; N + 1 }] where [u8; { let x = N; N + 1 }]: Default {
+ | ^^^^^^^^^^^^^^^^^^^^ blocks are not supported in generic constant
+ |
+ = help: consider moving this anonymous constant into a `const` function
+ = note: this operation may be supported in the future
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/const-generics/generic_const_exprs/needs_where_clause.rs b/src/test/ui/const-generics/generic_const_exprs/needs_where_clause.rs
new file mode 100644
index 000000000..2bd3c801f
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/needs_where_clause.rs
@@ -0,0 +1,14 @@
+#![crate_type = "lib"]
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+const fn complex_maths<T>(n : usize) -> usize {
+ 2 * n + 1
+}
+
+struct Example<T, const N: usize> {
+ a: [f32; N],
+ b: [f32; complex_maths::<T>(N)],
+ //~^ ERROR unconstrained
+ c: T,
+}
diff --git a/src/test/ui/const-generics/generic_const_exprs/needs_where_clause.stderr b/src/test/ui/const-generics/generic_const_exprs/needs_where_clause.stderr
new file mode 100644
index 000000000..7b41e39b7
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/needs_where_clause.stderr
@@ -0,0 +1,10 @@
+error: unconstrained generic constant
+ --> $DIR/needs_where_clause.rs:11:6
+ |
+LL | b: [f32; complex_maths::<T>(N)],
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: try adding a `where` bound using this expression: `where [(); complex_maths::<T>(N)]:`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/generic_const_exprs/nested-abstract-consts-1.rs b/src/test/ui/const-generics/generic_const_exprs/nested-abstract-consts-1.rs
new file mode 100644
index 000000000..7e5022817
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/nested-abstract-consts-1.rs
@@ -0,0 +1,24 @@
+// run-pass
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+fn callee<const M2: usize>() -> usize
+where
+ [u8; M2 + 1]: Sized,
+{
+ M2
+}
+
+fn caller<const N1: usize>() -> usize
+where
+ [u8; N1 + 1]: Sized,
+ [u8; (N1 + 1) + 1]: Sized,
+{
+ callee::<{ N1 + 1 }>()
+}
+
+fn main() {
+ assert_eq!(caller::<4>(), 5);
+}
+
+// Test that the ``(N1 + 1) + 1`` bound on ``caller`` satisfies the ``M2 + 1`` bound on ``callee``
diff --git a/src/test/ui/const-generics/generic_const_exprs/nested-abstract-consts-2.rs b/src/test/ui/const-generics/generic_const_exprs/nested-abstract-consts-2.rs
new file mode 100644
index 000000000..769e3ae68
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/nested-abstract-consts-2.rs
@@ -0,0 +1,35 @@
+// run-pass
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+struct Generic<const K: u64>;
+
+struct ConstU64<const K: u64>;
+
+impl<const K: u64> Generic<K>
+where
+ ConstU64<{ K - 1 }>: ,
+{
+ fn foo(self) -> u64 {
+ K
+ }
+}
+
+impl<const K: u64> Generic<K>
+where
+ ConstU64<{ K - 1 }>: ,
+ ConstU64<{ K + 1 }>: ,
+ ConstU64<{ K + 1 - 1 }>: ,
+{
+ fn bar(self) -> u64 {
+ let x: Generic<{ K + 1 }> = Generic;
+ x.foo()
+ }
+}
+
+fn main() {
+ assert_eq!((Generic::<10>).bar(), 11);
+}
+
+// Test that the ``ConstU64<{ K + 1 - 1}>`` bound on ``bar``'s impl block satisfies the
+// ``ConstU64<{K - 1}>`` bound on ``foo``'s impl block
diff --git a/src/test/ui/const-generics/generic_const_exprs/nested_uneval_unification-1.rs b/src/test/ui/const-generics/generic_const_exprs/nested_uneval_unification-1.rs
new file mode 100644
index 000000000..316887e5e
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/nested_uneval_unification-1.rs
@@ -0,0 +1,34 @@
+// run-pass
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+fn zero_init<const N: usize>() -> Substs1<N>
+where
+ [u8; N + 1]: ,
+{
+ Substs1([0; N + 1])
+}
+struct Substs1<const N: usize>([u8; N + 1])
+where
+ [(); N + 1]: ;
+
+fn substs2<const M: usize>() -> Substs1<{ M * 2 }>
+where
+ [(); { M * 2 } + 1]: ,
+{
+ zero_init::<{ M * 2 }>()
+}
+
+fn substs3<const L: usize>() -> Substs1<{ (L - 1) * 2 }>
+where
+ [(); (L - 1) * 2 + 1]: ,
+{
+ substs2::<{ L - 1 }>()
+}
+
+fn main() {
+ assert_eq!(substs3::<2>().0, [0; 3]);
+}
+
+// Test that the ``{ (L - 1) * 2 + 1 }`` bound on ``substs3`` satisfies the
+// ``{ N + 1 }`` bound on ``Substs1``
diff --git a/src/test/ui/const-generics/generic_const_exprs/nested_uneval_unification-2.rs b/src/test/ui/const-generics/generic_const_exprs/nested_uneval_unification-2.rs
new file mode 100644
index 000000000..d45a6465b
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/nested_uneval_unification-2.rs
@@ -0,0 +1,29 @@
+// run-pass
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features, unused_parens, unused_braces)]
+
+fn zero_init<const N: usize>() -> Substs1<{ (N) }>
+where
+ [u8; { (N) }]: ,
+{
+ Substs1([0; { (N) }])
+}
+
+struct Substs1<const N: usize>([u8; { (N) }])
+where
+ [(); { (N) }]: ;
+
+fn substs2<const M: usize>() -> Substs1<{ (M) }> {
+ zero_init::<{ (M) }>()
+}
+
+fn substs3<const L: usize>() -> Substs1<{ (L) }> {
+ substs2::<{ (L) }>()
+}
+
+fn main() {
+ assert_eq!(substs3::<2>().0, [0; 2]);
+}
+
+// Test that the implicit ``{ (L) }`` bound on ``substs3`` satisfies the
+// ``{ (N) }`` bound on ``Substs1``
diff --git a/src/test/ui/const-generics/generic_const_exprs/no_dependence.rs b/src/test/ui/const-generics/generic_const_exprs/no_dependence.rs
new file mode 100644
index 000000000..db8dc6ed4
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/no_dependence.rs
@@ -0,0 +1,13 @@
+// check-pass
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+fn two_args<const N: usize, const M: usize>() -> [u8; M + 2] {
+ [0; M + 2]
+}
+
+fn yay<const N: usize>() -> [u8; 4] {
+ two_args::<N, 2>() // no lint
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/generic_const_exprs/no_where_clause.rs b/src/test/ui/const-generics/generic_const_exprs/no_where_clause.rs
new file mode 100644
index 000000000..9c5de0317
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/no_where_clause.rs
@@ -0,0 +1,29 @@
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features, unused)]
+
+const fn complex_maths(n : usize) -> usize {
+ 2 * n + 1
+}
+
+pub struct Example<const N: usize> {
+ a: [f32; N],
+ b: [f32; complex_maths(N)],
+ //~^ ERROR unconstrained generic
+}
+
+impl<const N: usize> Example<N> {
+ pub fn new() -> Self {
+ Self {
+ a: [0.; N],
+ b: [0.; complex_maths(N)],
+ }
+ }
+}
+
+impl Example<2> {
+ pub fn sum(&self) -> f32 {
+ self.a.iter().sum::<f32>() + self.b.iter().sum::<f32>()
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/generic_const_exprs/no_where_clause.stderr b/src/test/ui/const-generics/generic_const_exprs/no_where_clause.stderr
new file mode 100644
index 000000000..3e5c2f5ca
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/no_where_clause.stderr
@@ -0,0 +1,10 @@
+error: unconstrained generic constant
+ --> $DIR/no_where_clause.rs:10:6
+ |
+LL | b: [f32; complex_maths(N)],
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: try adding a `where` bound using this expression: `where [(); complex_maths(N)]:`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/generic_const_exprs/object-safety-err-ret.rs b/src/test/ui/const-generics/generic_const_exprs/object-safety-err-ret.rs
new file mode 100644
index 000000000..24d333aba
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/object-safety-err-ret.rs
@@ -0,0 +1,21 @@
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+
+const fn bar<T: ?Sized>() -> usize { 7 }
+
+trait Foo {
+ fn test(&self) -> [u8; bar::<Self>()];
+}
+
+impl Foo for () {
+ fn test(&self) -> [u8; bar::<Self>()] {
+ [0; bar::<Self>()]
+ }
+}
+
+fn use_dyn(v: &dyn Foo) { //~ERROR the trait `Foo` cannot be made into an object
+ v.test();
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/generic_const_exprs/object-safety-err-ret.stderr b/src/test/ui/const-generics/generic_const_exprs/object-safety-err-ret.stderr
new file mode 100644
index 000000000..4e1d71f15
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/object-safety-err-ret.stderr
@@ -0,0 +1,18 @@
+error[E0038]: the trait `Foo` cannot be made into an object
+ --> $DIR/object-safety-err-ret.rs:17:16
+ |
+LL | fn use_dyn(v: &dyn Foo) {
+ | ^^^^^^^ `Foo` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/object-safety-err-ret.rs:8:23
+ |
+LL | trait Foo {
+ | --- this trait cannot be made into an object...
+LL | fn test(&self) -> [u8; bar::<Self>()];
+ | ^^^^^^^^^^^^^^^^^^^ ...because method `test` references the `Self` type in its return type
+ = help: consider moving `test` to another trait
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/src/test/ui/const-generics/generic_const_exprs/object-safety-err-where-bounds.rs b/src/test/ui/const-generics/generic_const_exprs/object-safety-err-where-bounds.rs
new file mode 100644
index 000000000..42c1cc507
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/object-safety-err-where-bounds.rs
@@ -0,0 +1,22 @@
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+#![deny(where_clauses_object_safety)]
+
+
+const fn bar<T: ?Sized>() -> usize { 7 }
+
+trait Foo {
+ fn test(&self) where [u8; bar::<Self>()]: Sized;
+ //~^ ERROR the trait `Foo` cannot be made into an object
+ //~| WARN this was previously accepted by the compiler but is being phased out
+}
+
+impl Foo for () {
+ fn test(&self) where [u8; bar::<Self>()]: Sized {}
+}
+
+fn use_dyn(v: &dyn Foo) {
+ v.test();
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/generic_const_exprs/object-safety-err-where-bounds.stderr b/src/test/ui/const-generics/generic_const_exprs/object-safety-err-where-bounds.stderr
new file mode 100644
index 000000000..45c7d835f
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/object-safety-err-where-bounds.stderr
@@ -0,0 +1,24 @@
+error: the trait `Foo` cannot be made into an object
+ --> $DIR/object-safety-err-where-bounds.rs:9:8
+ |
+LL | fn test(&self) where [u8; bar::<Self>()]: Sized;
+ | ^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/object-safety-err-where-bounds.rs:3:9
+ |
+LL | #![deny(where_clauses_object_safety)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = 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 #51443 <https://github.com/rust-lang/rust/issues/51443>
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/object-safety-err-where-bounds.rs:9:8
+ |
+LL | trait Foo {
+ | --- this trait cannot be made into an object...
+LL | fn test(&self) where [u8; bar::<Self>()]: Sized;
+ | ^^^^ ...because method `test` references the `Self` type in its `where` clause
+ = help: consider moving `test` to another trait
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.rs b/src/test/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.rs
new file mode 100644
index 000000000..79e9834b5
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.rs
@@ -0,0 +1,21 @@
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+trait Foo<const N: usize> {
+ fn test(&self) -> [u8; N + 1];
+}
+
+impl<const N: usize> Foo<N> for () {
+ fn test(&self) -> [u8; N + 1] {
+ [0; N + 1]
+ }
+}
+
+fn use_dyn<const N: usize>(v: &dyn Foo<N>) where [u8; N + 1]: Sized {
+ assert_eq!(v.test(), [0; N + 1]);
+}
+
+fn main() {
+ use_dyn(&());
+ //~^ ERROR type annotations needed
+}
diff --git a/src/test/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.stderr b/src/test/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.stderr
new file mode 100644
index 000000000..59e9fee1e
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.stderr
@@ -0,0 +1,19 @@
+error[E0284]: type annotations needed
+ --> $DIR/object-safety-ok-infer-err.rs:19:5
+ |
+LL | use_dyn(&());
+ | ^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `use_dyn`
+ |
+note: required by a bound in `use_dyn`
+ --> $DIR/object-safety-ok-infer-err.rs:14:55
+ |
+LL | fn use_dyn<const N: usize>(v: &dyn Foo<N>) where [u8; N + 1]: Sized {
+ | ^^^^^ required by this bound in `use_dyn`
+help: consider specifying the generic argument
+ |
+LL | use_dyn::<N>(&());
+ | +++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0284`.
diff --git a/src/test/ui/const-generics/generic_const_exprs/object-safety-ok.rs b/src/test/ui/const-generics/generic_const_exprs/object-safety-ok.rs
new file mode 100644
index 000000000..f4c89f623
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/object-safety-ok.rs
@@ -0,0 +1,21 @@
+// run-pass
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+trait Foo<const N: usize> {
+ fn test(&self) -> [u8; N + 1];
+}
+
+impl<const N: usize> Foo<N> for () {
+ fn test(&self) -> [u8; N + 1] {
+ [0; N + 1]
+ }
+}
+
+fn use_dyn<const N: usize>(v: &dyn Foo<N>) where [u8; N + 1]: Sized {
+ assert_eq!(v.test(), [0; N + 1]);
+}
+
+fn main() {
+ use_dyn::<3>(&());
+}
diff --git a/src/test/ui/const-generics/generic_const_exprs/simple_fail.rs b/src/test/ui/const-generics/generic_const_exprs/simple_fail.rs
new file mode 100644
index 000000000..cae54df4c
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/simple_fail.rs
@@ -0,0 +1,17 @@
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+type Arr<const N: usize> = [u8; N - 1];
+//~^ ERROR evaluation of `Arr::<0>::{constant#0}` failed
+
+fn test<const N: usize>() -> Arr<N>
+where
+ [u8; N - 1]: Sized,
+ //~^ ERROR evaluation of `test::<0>::{constant#0}` failed
+{
+ todo!()
+}
+
+fn main() {
+ test::<0>();
+}
diff --git a/src/test/ui/const-generics/generic_const_exprs/simple_fail.stderr b/src/test/ui/const-generics/generic_const_exprs/simple_fail.stderr
new file mode 100644
index 000000000..a25fa56b7
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/simple_fail.stderr
@@ -0,0 +1,15 @@
+error[E0080]: evaluation of `test::<0>::{constant#0}` failed
+ --> $DIR/simple_fail.rs:9:10
+ |
+LL | [u8; N - 1]: Sized,
+ | ^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow
+
+error[E0080]: evaluation of `Arr::<0>::{constant#0}` failed
+ --> $DIR/simple_fail.rs:4:33
+ |
+LL | type Arr<const N: usize> = [u8; N - 1];
+ | ^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/const-generics/generic_const_exprs/subexprs_are_const_evalutable.rs b/src/test/ui/const-generics/generic_const_exprs/subexprs_are_const_evalutable.rs
new file mode 100644
index 000000000..d6574a3aa
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/subexprs_are_const_evalutable.rs
@@ -0,0 +1,17 @@
+// run-pass
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+fn make_array<const M: usize>() -> [(); M + 1] {
+ [(); M + 1]
+}
+
+fn foo<const N: usize>() -> [(); (N * 2) + 1] {
+ make_array::<{ N * 2 }>()
+}
+
+fn main() {
+ assert_eq!(foo::<10>(), [(); 10 * 2 + 1])
+}
+
+// Tests that N * 2 is considered const_evalutable by appearing as part of the (N * 2) + 1 const
diff --git a/src/test/ui/const-generics/generic_const_exprs/ty-alias-substitution.rs b/src/test/ui/const-generics/generic_const_exprs/ty-alias-substitution.rs
new file mode 100644
index 000000000..d058b3638
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/ty-alias-substitution.rs
@@ -0,0 +1,14 @@
+// check-pass
+// Test that we correctly substitute generic arguments for type aliases.
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+type Alias<T, const N: usize> = [T; N + 1];
+
+fn foo<const M: usize>() -> Alias<u32, M> where [u8; M + 1]: Sized {
+ [0; M + 1]
+}
+
+fn main() {
+ foo::<0>();
+}
diff --git a/src/test/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.rs b/src/test/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.rs
new file mode 100644
index 000000000..c0404d35b
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.rs
@@ -0,0 +1,35 @@
+#![feature(generic_const_exprs, adt_const_params, const_trait_impl)]
+#![allow(incomplete_features)]
+
+// test `N + N` unifies with explicit function calls for non-builtin-types
+#[derive(PartialEq, Eq)]
+struct Foo(u8);
+
+impl const std::ops::Add for Foo {
+ type Output = Self;
+
+ fn add(self, rhs: Self) -> Self::Output {
+ self
+ }
+}
+
+struct Evaluatable<const N: Foo>;
+
+fn foo<const N: Foo>(a: Evaluatable<{ N + N }>) {
+ bar::<{ std::ops::Add::add(N, N) }>();
+}
+
+fn bar<const N: Foo>() {}
+
+// test that `N + N` unifies with explicit function calls for builin-types
+struct Evaluatable2<const N: usize>;
+
+fn foo2<const N: usize>(a: Evaluatable2<{ N + N }>) {
+ bar2::<{ std::ops::Add::add(N, N) }>();
+ //~^ error: unconstrained generic constant
+ // FIXME(generic_const_exprs) make this not an error
+}
+
+fn bar2<const N: usize>() {}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr b/src/test/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr
new file mode 100644
index 000000000..d18c7916f
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr
@@ -0,0 +1,10 @@
+error: unconstrained generic constant
+ --> $DIR/unify-op-with-fn-call.rs:28:12
+ |
+LL | bar2::<{ std::ops::Add::add(N, N) }>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: try adding a `where` bound using this expression: `where [(); { std::ops::Add::add(N, N) }]:`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/generic_const_exprs/unop.rs b/src/test/ui/const-generics/generic_const_exprs/unop.rs
new file mode 100644
index 000000000..c12fef083
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/unop.rs
@@ -0,0 +1,14 @@
+// run-pass
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+struct Foo<const B: bool>;
+
+fn test<const N: usize>() -> Foo<{ !(N > 10) }> where Foo<{ !(N > 10) }>: Sized {
+ Foo
+}
+
+fn main() {
+ let _: Foo<false> = test::<12>();
+ let _: Foo<true> = test::<9>();
+}
diff --git a/src/test/ui/const-generics/generic_const_exprs/unused-complex-default-expr.rs b/src/test/ui/const-generics/generic_const_exprs/unused-complex-default-expr.rs
new file mode 100644
index 000000000..9580f8a7f
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/unused-complex-default-expr.rs
@@ -0,0 +1,6 @@
+// check-pass
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+struct Foo<const N: usize, const M: usize = { N + 1 }>;
+struct Bar<const N: usize>(Foo<N, 3>);
+fn main() {}
diff --git a/src/test/ui/const-generics/generic_const_exprs/unused_expr.rs b/src/test/ui/const-generics/generic_const_exprs/unused_expr.rs
new file mode 100644
index 000000000..c1bf19e0f
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/unused_expr.rs
@@ -0,0 +1,25 @@
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+fn add<const N: usize>() -> [u8; { N + 1; 5 }] {
+ //~^ ERROR overly complex generic constant
+ todo!()
+}
+
+fn div<const N: usize>() -> [u8; { N / 1; 5 }] {
+ //~^ ERROR overly complex generic constant
+ todo!()
+}
+
+const fn foo(n: usize) {}
+
+fn fn_call<const N: usize>() -> [u8; { foo(N); 5 }] {
+ //~^ ERROR overly complex generic constant
+ todo!()
+}
+
+fn main() {
+ add::<12>();
+ div::<9>();
+ fn_call::<14>();
+}
diff --git a/src/test/ui/const-generics/generic_const_exprs/unused_expr.stderr b/src/test/ui/const-generics/generic_const_exprs/unused_expr.stderr
new file mode 100644
index 000000000..df73acf53
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/unused_expr.stderr
@@ -0,0 +1,29 @@
+error: overly complex generic constant
+ --> $DIR/unused_expr.rs:4:34
+ |
+LL | fn add<const N: usize>() -> [u8; { N + 1; 5 }] {
+ | ^^^^^^^^^^^^ blocks are not supported in generic constant
+ |
+ = help: consider moving this anonymous constant into a `const` function
+ = note: this operation may be supported in the future
+
+error: overly complex generic constant
+ --> $DIR/unused_expr.rs:9:34
+ |
+LL | fn div<const N: usize>() -> [u8; { N / 1; 5 }] {
+ | ^^^^^^^^^^^^ blocks are not supported in generic constant
+ |
+ = help: consider moving this anonymous constant into a `const` function
+ = note: this operation may be supported in the future
+
+error: overly complex generic constant
+ --> $DIR/unused_expr.rs:16:38
+ |
+LL | fn fn_call<const N: usize>() -> [u8; { foo(N); 5 }] {
+ | ^^^^^^^^^^^^^ blocks are not supported in generic constant
+ |
+ = help: consider moving this anonymous constant into a `const` function
+ = note: this operation may be supported in the future
+
+error: aborting due to 3 previous errors
+