summaryrefslogtreecommitdiffstats
path: root/tests/ui/const-generics/generic_const_exprs
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/const-generics/generic_const_exprs')
-rw-r--r--tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-1.rs18
-rw-r--r--tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-2.rs20
-rw-r--r--tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-2.stderr26
-rw-r--r--tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.rs47
-rw-r--r--tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr187
-rw-r--r--tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-4.rs29
-rw-r--r--tests/ui/const-generics/generic_const_exprs/abstract-consts-as-cast-5.rs11
-rw-r--r--tests/ui/const-generics/generic_const_exprs/abstract-consts-as-cast-5.stderr10
-rw-r--r--tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.full.stderr19
-rw-r--r--tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.min.stderr29
-rw-r--r--tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.rs29
-rw-r--r--tests/ui/const-generics/generic_const_exprs/assoc_const_unification/const_equate_assoc_consts.rs27
-rw-r--r--tests/ui/const-generics/generic_const_exprs/assoc_const_unification/doesnt_unify_evaluatable.rs15
-rw-r--r--tests/ui/const-generics/generic_const_exprs/assoc_const_unification/doesnt_unify_evaluatable.stderr10
-rw-r--r--tests/ui/const-generics/generic_const_exprs/assoc_const_unification/dropck_unifies_assoc_consts.rs20
-rw-r--r--tests/ui/const-generics/generic_const_exprs/assoc_const_unification/unifies_evaluatable.rs18
-rw-r--r--tests/ui/const-generics/generic_const_exprs/associated-const.rs11
-rw-r--r--tests/ui/const-generics/generic_const_exprs/associated-consts.rs31
-rw-r--r--tests/ui/const-generics/generic_const_exprs/auxiliary/anon_const_non_local.rs8
-rw-r--r--tests/ui/const-generics/generic_const_exprs/auxiliary/const_evaluatable_lib.rs9
-rw-r--r--tests/ui/const-generics/generic_const_exprs/auxiliary/issue-94287-aux.rs21
-rw-r--r--tests/ui/const-generics/generic_const_exprs/closures.rs6
-rw-r--r--tests/ui/const-generics/generic_const_exprs/closures.stderr26
-rw-r--r--tests/ui/const-generics/generic_const_exprs/const-block-is-poly.rs11
-rw-r--r--tests/ui/const-generics/generic_const_exprs/const-block-is-poly.stderr20
-rw-r--r--tests/ui/const-generics/generic_const_exprs/const_eval_resolve_canonical.rs28
-rw-r--r--tests/ui/const-generics/generic_const_exprs/const_kind_expr/wf_obligation.rs22
-rw-r--r--tests/ui/const-generics/generic_const_exprs/const_kind_expr/wf_obligation.stderr20
-rw-r--r--tests/ui/const-generics/generic_const_exprs/cross_crate.rs15
-rw-r--r--tests/ui/const-generics/generic_const_exprs/cross_crate_predicate.rs14
-rw-r--r--tests/ui/const-generics/generic_const_exprs/cross_crate_predicate.stderr54
-rw-r--r--tests/ui/const-generics/generic_const_exprs/dependence_lint.full.stderr39
-rw-r--r--tests/ui/const-generics/generic_const_exprs/dependence_lint.gce.stderr34
-rw-r--r--tests/ui/const-generics/generic_const_exprs/dependence_lint.rs26
-rw-r--r--tests/ui/const-generics/generic_const_exprs/different-fn.rs17
-rw-r--r--tests/ui/const-generics/generic_const_exprs/different-fn.stderr20
-rw-r--r--tests/ui/const-generics/generic_const_exprs/division.rs11
-rw-r--r--tests/ui/const-generics/generic_const_exprs/dont-eagerly-error-in-is-const-evaluatable.rs16
-rw-r--r--tests/ui/const-generics/generic_const_exprs/drop_impl.rs16
-rw-r--r--tests/ui/const-generics/generic_const_exprs/elaborate-trait-pred.rs24
-rw-r--r--tests/ui/const-generics/generic_const_exprs/eval-privacy.rs26
-rw-r--r--tests/ui/const-generics/generic_const_exprs/eval-privacy.stderr12
-rw-r--r--tests/ui/const-generics/generic_const_exprs/eval-try-unify.rs26
-rw-r--r--tests/ui/const-generics/generic_const_exprs/eval-try-unify.stderr11
-rw-r--r--tests/ui/const-generics/generic_const_exprs/evaluated-to-ambig.rs22
-rw-r--r--tests/ui/const-generics/generic_const_exprs/feature-gate-generic_const_exprs.rs11
-rw-r--r--tests/ui/const-generics/generic_const_exprs/feature-gate-generic_const_exprs.stderr11
-rw-r--r--tests/ui/const-generics/generic_const_exprs/fn_call.rs30
-rw-r--r--tests/ui/const-generics/generic_const_exprs/from-sig-fail.rs11
-rw-r--r--tests/ui/const-generics/generic_const_exprs/from-sig-fail.stderr9
-rw-r--r--tests/ui/const-generics/generic_const_exprs/from-sig.rs14
-rw-r--r--tests/ui/const-generics/generic_const_exprs/function-call.rs20
-rw-r--r--tests/ui/const-generics/generic_const_exprs/function-call.stderr12
-rw-r--r--tests/ui/const-generics/generic_const_exprs/impl-bounds.rs25
-rw-r--r--tests/ui/const-generics/generic_const_exprs/infer-too-generic.rs24
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-100217.rs42
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-100360.rs13
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-102074.rs23
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-102768.rs14
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-102768.stderr33
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-105257.rs9
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-105257.stderr14
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-105608.rs15
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-105608.stderr14
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-62504.full.stderr20
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr27
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-62504.rs27
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-69654.rs19
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-69654.stderr30
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-72787.min.stderr38
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-72787.rs33
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.full.stderr35
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.min.stderr11
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.rs23
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-73298.rs23
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-73899.rs20
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-74634.rs28
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-74713.rs8
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-74713.stderr22
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-76595.rs17
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-76595.stderr21
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-79518-default_trait_method_normalization.rs21
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-79518-default_trait_method_normalization.stderr16
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-80561-incorrect-param-env.rs24
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-80742.rs32
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-80742.stderr71
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-82268.rs73
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-83765.rs38
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-83765.stderr34
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-83972.rs38
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-84408.rs38
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-84669.rs30
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-85848.rs32
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-85848.stderr65
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-86710.rs73
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-89851.rs12
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-90847.rs9
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-94287.rs10
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-94287.stderr15
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-94293.rs31
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-97047-ice-1.rs25
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-97047-ice-1.stderr19
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-97047-ice-2.rs23
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-97047-ice-2.stderr19
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-99647.rs15
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-99705.rs33
-rw-r--r--tests/ui/const-generics/generic_const_exprs/less_than.rs14
-rw-r--r--tests/ui/const-generics/generic_const_exprs/let-bindings.rs15
-rw-r--r--tests/ui/const-generics/generic_const_exprs/let-bindings.stderr20
-rw-r--r--tests/ui/const-generics/generic_const_exprs/needs_where_clause.rs14
-rw-r--r--tests/ui/const-generics/generic_const_exprs/needs_where_clause.stderr10
-rw-r--r--tests/ui/const-generics/generic_const_exprs/nested-abstract-consts-1.rs24
-rw-r--r--tests/ui/const-generics/generic_const_exprs/nested-abstract-consts-2.rs35
-rw-r--r--tests/ui/const-generics/generic_const_exprs/nested_uneval_unification-1.rs34
-rw-r--r--tests/ui/const-generics/generic_const_exprs/nested_uneval_unification-2.rs29
-rw-r--r--tests/ui/const-generics/generic_const_exprs/no_dependence.rs13
-rw-r--r--tests/ui/const-generics/generic_const_exprs/no_where_clause.rs29
-rw-r--r--tests/ui/const-generics/generic_const_exprs/no_where_clause.stderr10
-rw-r--r--tests/ui/const-generics/generic_const_exprs/non_local_anon_const_diagnostics.rs16
-rw-r--r--tests/ui/const-generics/generic_const_exprs/non_local_anon_const_diagnostics.stderr12
-rw-r--r--tests/ui/const-generics/generic_const_exprs/normed_to_param_is_evaluatable.rs12
-rw-r--r--tests/ui/const-generics/generic_const_exprs/object-safety-err-ret.rs21
-rw-r--r--tests/ui/const-generics/generic_const_exprs/object-safety-err-ret.stderr18
-rw-r--r--tests/ui/const-generics/generic_const_exprs/object-safety-err-where-bounds.rs22
-rw-r--r--tests/ui/const-generics/generic_const_exprs/object-safety-err-where-bounds.stderr24
-rw-r--r--tests/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.rs21
-rw-r--r--tests/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.stderr19
-rw-r--r--tests/ui/const-generics/generic_const_exprs/object-safety-ok.rs21
-rw-r--r--tests/ui/const-generics/generic_const_exprs/obligation-cause.rs24
-rw-r--r--tests/ui/const-generics/generic_const_exprs/obligation-cause.stderr20
-rw-r--r--tests/ui/const-generics/generic_const_exprs/simple_fail.rs17
-rw-r--r--tests/ui/const-generics/generic_const_exprs/simple_fail.stderr15
-rw-r--r--tests/ui/const-generics/generic_const_exprs/subexprs_are_const_evalutable.rs17
-rw-r--r--tests/ui/const-generics/generic_const_exprs/ty-alias-substitution.rs14
-rw-r--r--tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.rs35
-rw-r--r--tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr10
-rw-r--r--tests/ui/const-generics/generic_const_exprs/unop.rs14
-rw-r--r--tests/ui/const-generics/generic_const_exprs/unused-complex-default-expr.rs6
-rw-r--r--tests/ui/const-generics/generic_const_exprs/unused_expr.rs25
-rw-r--r--tests/ui/const-generics/generic_const_exprs/unused_expr.stderr29
140 files changed, 3312 insertions, 0 deletions
diff --git a/tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-1.rs b/tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-1.rs
new file mode 100644
index 000000000..06f00de13
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-2.rs b/tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-2.rs
new file mode 100644
index 000000000..3b5b87b2b
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-2.stderr b/tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-2.stderr
new file mode 100644
index 000000000..5ca04d25e
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.rs b/tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.rs
new file mode 100644
index 000000000..7561ae2fe
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr b/tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr
new file mode 100644
index 000000000..cdf97bd88
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr
@@ -0,0 +1,187 @@
+error: unconstrained generic constant
+ --> $DIR/abstract-const-as-cast-3.rs:17:19
+ |
+LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
+note: required for `HasCastInTraitImpl<{ N + 1 }, { N as u128 }>` to implement `Trait`
+ --> $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 `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 constant `{ N as u128 }`
+ found constant `{ 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 `assert_impl`
+
+error: unconstrained generic constant
+ --> $DIR/abstract-const-as-cast-3.rs:20:19
+ |
+LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
+note: required for `HasCastInTraitImpl<{ N + 1 }, { N as _ }>` to implement `Trait`
+ --> $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 `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 constant `{ N as _ }`
+ found constant `{ 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 `assert_impl`
+
+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 constant `12`
+ found constant `13`
+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 `assert_impl`
+
+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 constant `13`
+ found constant `14`
+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 `assert_impl`
+
+error: unconstrained generic constant
+ --> $DIR/abstract-const-as-cast-3.rs:35:19
+ |
+LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
+note: required for `HasCastInTraitImpl<{ N + 1 }, { N as u128 }>` to implement `Trait`
+ --> $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 `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 constant `{ N as u128 }`
+ found constant `{ 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 `assert_impl`
+
+error: unconstrained generic constant
+ --> $DIR/abstract-const-as-cast-3.rs:38:19
+ |
+LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
+note: required for `HasCastInTraitImpl<{ N + 1 }, { N as _ }>` to implement `Trait`
+ --> $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 `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 constant `{ N as _ }`
+ found constant `{ 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 `assert_impl`
+
+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 constant `12`
+ found constant `13`
+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 `assert_impl`
+
+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 constant `13`
+ found constant `14`
+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 `assert_impl`
+
+error: aborting due to 12 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-4.rs b/tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-4.rs
new file mode 100644
index 000000000..184263f89
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/abstract-consts-as-cast-5.rs b/tests/ui/const-generics/generic_const_exprs/abstract-consts-as-cast-5.rs
new file mode 100644
index 000000000..916d60c0e
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/abstract-consts-as-cast-5.stderr b/tests/ui/const-generics/generic_const_exprs/abstract-consts-as-cast-5.stderr
new file mode 100644
index 000000000..d48b639db
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.full.stderr b/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.full.stderr
new file mode 100644
index 000000000..1d10dfdf1
--- /dev/null
+++ b/tests/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 constants
+ |
+ = 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/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.min.stderr b/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.min.stderr
new file mode 100644
index 000000000..18e9135d0
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.rs b/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.rs
new file mode 100644
index 000000000..7d3fe413c
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/assoc_const_unification/const_equate_assoc_consts.rs b/tests/ui/const-generics/generic_const_exprs/assoc_const_unification/const_equate_assoc_consts.rs
new file mode 100644
index 000000000..e8f89cb1a
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/assoc_const_unification/const_equate_assoc_consts.rs
@@ -0,0 +1,27 @@
+// check-pass
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+trait Trait {
+ const ASSOC: usize;
+}
+impl<T> Trait for T {
+ const ASSOC: usize = std::mem::size_of::<T>();
+}
+
+struct Foo<T: Trait>([u8; T::ASSOC])
+where
+ [(); T::ASSOC]:;
+
+fn bar<T: Trait>()
+where
+ [(); T::ASSOC]:,
+{
+ let _: Foo<T> = Foo::<_>(make());
+}
+
+fn make() -> ! {
+ todo!()
+}
+
+fn main() {}
diff --git a/tests/ui/const-generics/generic_const_exprs/assoc_const_unification/doesnt_unify_evaluatable.rs b/tests/ui/const-generics/generic_const_exprs/assoc_const_unification/doesnt_unify_evaluatable.rs
new file mode 100644
index 000000000..c8f7553da
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/assoc_const_unification/doesnt_unify_evaluatable.rs
@@ -0,0 +1,15 @@
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+trait Trait {
+ const ASSOC: usize;
+}
+
+fn foo<T: Trait, U: Trait>() where [(); U::ASSOC]:, {
+ bar::<{ T::ASSOC }>();
+ //~^ ERROR: unconstrained generic constant
+}
+
+fn bar<const N: usize>() {}
+
+fn main() {}
diff --git a/tests/ui/const-generics/generic_const_exprs/assoc_const_unification/doesnt_unify_evaluatable.stderr b/tests/ui/const-generics/generic_const_exprs/assoc_const_unification/doesnt_unify_evaluatable.stderr
new file mode 100644
index 000000000..e4a0cabe5
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/assoc_const_unification/doesnt_unify_evaluatable.stderr
@@ -0,0 +1,10 @@
+error: unconstrained generic constant
+ --> $DIR/doesnt_unify_evaluatable.rs:9:11
+ |
+LL | bar::<{ T::ASSOC }>();
+ | ^^^^^^^^^^^^
+ |
+ = help: try adding a `where` bound using this expression: `where [(); { T::ASSOC }]:`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/const-generics/generic_const_exprs/assoc_const_unification/dropck_unifies_assoc_consts.rs b/tests/ui/const-generics/generic_const_exprs/assoc_const_unification/dropck_unifies_assoc_consts.rs
new file mode 100644
index 000000000..274caa1e9
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/assoc_const_unification/dropck_unifies_assoc_consts.rs
@@ -0,0 +1,20 @@
+// check-pass
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+trait Trait {
+ const ASSOC: usize;
+}
+
+struct Foo<T: Trait>(T)
+where
+ [(); T::ASSOC]:;
+
+impl<T: Trait> Drop for Foo<T>
+where
+ [(); T::ASSOC]:,
+{
+ fn drop(&mut self) {}
+}
+
+fn main() {}
diff --git a/tests/ui/const-generics/generic_const_exprs/assoc_const_unification/unifies_evaluatable.rs b/tests/ui/const-generics/generic_const_exprs/assoc_const_unification/unifies_evaluatable.rs
new file mode 100644
index 000000000..6597b9f2b
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/assoc_const_unification/unifies_evaluatable.rs
@@ -0,0 +1,18 @@
+// check-pass
+
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+trait Trait {
+ const ASSOC: usize;
+}
+
+fn foo<T: Trait, U: Trait>() where [(); T::ASSOC]:, {
+ bar::<{ T::ASSOC }>();
+}
+
+fn bar<const N: usize>() -> [(); N] {
+ [(); N]
+}
+
+fn main() {}
diff --git a/tests/ui/const-generics/generic_const_exprs/associated-const.rs b/tests/ui/const-generics/generic_const_exprs/associated-const.rs
new file mode 100644
index 000000000..a67776322
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/associated-consts.rs b/tests/ui/const-generics/generic_const_exprs/associated-consts.rs
new file mode 100644
index 000000000..b839008d4
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/auxiliary/anon_const_non_local.rs b/tests/ui/const-generics/generic_const_exprs/auxiliary/anon_const_non_local.rs
new file mode 100644
index 000000000..97be07493
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/auxiliary/anon_const_non_local.rs
@@ -0,0 +1,8 @@
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+pub struct Foo<const N: usize>;
+
+pub fn foo<const N: usize>() -> Foo<{ N + 1 }> {
+ Foo
+}
diff --git a/tests/ui/const-generics/generic_const_exprs/auxiliary/const_evaluatable_lib.rs b/tests/ui/const-generics/generic_const_exprs/auxiliary/const_evaluatable_lib.rs
new file mode 100644
index 000000000..15d618cae
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/auxiliary/issue-94287-aux.rs b/tests/ui/const-generics/generic_const_exprs/auxiliary/issue-94287-aux.rs
new file mode 100644
index 000000000..df454dae7
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/closures.rs b/tests/ui/const-generics/generic_const_exprs/closures.rs
new file mode 100644
index 000000000..1ea310d06
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/closures.stderr b/tests/ui/const-generics/generic_const_exprs/closures.stderr
new file mode 100644
index 000000000..a7d891d77
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/const-block-is-poly.rs b/tests/ui/const-generics/generic_const_exprs/const-block-is-poly.rs
new file mode 100644
index 000000000..7332a8f03
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/const-block-is-poly.rs
@@ -0,0 +1,11 @@
+#![feature(inline_const, generic_const_exprs)]
+//~^ WARN the feature `generic_const_exprs` is incomplete
+
+fn foo<T>() {
+ let _ = [0u8; const { std::mem::size_of::<T>() }];
+ //~^ ERROR: overly complex generic constant
+}
+
+fn main() {
+ foo::<i32>();
+}
diff --git a/tests/ui/const-generics/generic_const_exprs/const-block-is-poly.stderr b/tests/ui/const-generics/generic_const_exprs/const-block-is-poly.stderr
new file mode 100644
index 000000000..f26259908
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/const-block-is-poly.stderr
@@ -0,0 +1,20 @@
+warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/const-block-is-poly.rs:1:26
+ |
+LL | #![feature(inline_const, generic_const_exprs)]
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
+ = note: `#[warn(incomplete_features)]` on by default
+
+error: overly complex generic constant
+ --> $DIR/const-block-is-poly.rs:5:19
+ |
+LL | let _ = [0u8; const { std::mem::size_of::<T>() }];
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ const blocks are not supported in generic constants
+ |
+ = help: consider moving this anonymous constant into a `const` function
+ = note: this operation may be supported in the future
+
+error: aborting due to previous error; 1 warning emitted
+
diff --git a/tests/ui/const-generics/generic_const_exprs/const_eval_resolve_canonical.rs b/tests/ui/const-generics/generic_const_exprs/const_eval_resolve_canonical.rs
new file mode 100644
index 000000000..5874625ad
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/const_kind_expr/wf_obligation.rs b/tests/ui/const-generics/generic_const_exprs/const_kind_expr/wf_obligation.rs
new file mode 100644
index 000000000..6093fc70b
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/const_kind_expr/wf_obligation.rs
@@ -0,0 +1,22 @@
+#![feature(generic_const_exprs, generic_arg_infer)]
+#![allow(incomplete_features)]
+
+// minimized repro for #105205
+//
+// the `foo::<_, L>` call results in a `WellFormed(_)` obligation and a
+// `ConstEvaluatable(Unevaluated(_ + 1 + L))` obligation. Attempting to fulfill the latter
+// unifies the `_` with `Expr(L - 1)` from the paramenv which turns the `WellFormed`
+// obligation into `WellFormed(Expr(L - 1))`
+
+fn foo<const N: usize, const M: usize>(_: [(); N + 1 + M]) {}
+
+fn ice<const L: usize>()
+where
+ [(); (L - 1) + 1 + L]:,
+{
+ foo::<_, L>([(); L + 1 + L]);
+ //~^ ERROR: mismatched types
+ //~^^ ERROR: unconstrained generic constant
+}
+
+fn main() {}
diff --git a/tests/ui/const-generics/generic_const_exprs/const_kind_expr/wf_obligation.stderr b/tests/ui/const-generics/generic_const_exprs/const_kind_expr/wf_obligation.stderr
new file mode 100644
index 000000000..da5194696
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/const_kind_expr/wf_obligation.stderr
@@ -0,0 +1,20 @@
+error[E0308]: mismatched types
+ --> $DIR/wf_obligation.rs:17:17
+ |
+LL | foo::<_, L>([(); L + 1 + L]);
+ | ^^^^^^^^^^^^^^^ expected `N + 1 + M`, found `L + 1 + L`
+ |
+ = note: expected constant `N + 1 + M`
+ found constant `L + 1 + L`
+
+error: unconstrained generic constant
+ --> $DIR/wf_obligation.rs:17:22
+ |
+LL | foo::<_, L>([(); L + 1 + L]);
+ | ^^^^^^^^^
+ |
+ = help: try adding a `where` bound using this expression: `where [(); L + 1 + L]:`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/const-generics/generic_const_exprs/cross_crate.rs b/tests/ui/const-generics/generic_const_exprs/cross_crate.rs
new file mode 100644
index 000000000..dfc69e0b0
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/cross_crate_predicate.rs b/tests/ui/const-generics/generic_const_exprs/cross_crate_predicate.rs
new file mode 100644
index 000000000..b08fffd69
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/cross_crate_predicate.stderr b/tests/ui/const-generics/generic_const_exprs/cross_crate_predicate.stderr
new file mode 100644
index 000000000..7b4d46b82
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/dependence_lint.full.stderr b/tests/ui/const-generics/generic_const_exprs/dependence_lint.full.stderr
new file mode 100644
index 000000000..d674e3acd
--- /dev/null
+++ b/tests/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:14: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:21: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:10:9
+ |
+LL | [0; size_of::<*mut T>()]; // lint on stable, error with `generic_const_exprs`
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+ = 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>
+ = note: `#[warn(const_evaluatable_unchecked)]` on by default
+
+warning: cannot use constants which depend on generic parameters in types
+ --> $DIR/dependence_lint.rs:17: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/tests/ui/const-generics/generic_const_exprs/dependence_lint.gce.stderr b/tests/ui/const-generics/generic_const_exprs/dependence_lint.gce.stderr
new file mode 100644
index 000000000..74111ef1d
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/dependence_lint.gce.stderr
@@ -0,0 +1,34 @@
+error: overly complex generic constant
+ --> $DIR/dependence_lint.rs:17: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:21: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:14: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:10: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/tests/ui/const-generics/generic_const_exprs/dependence_lint.rs b/tests/ui/const-generics/generic_const_exprs/dependence_lint.rs
new file mode 100644
index 000000000..b715e07f8
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/dependence_lint.rs
@@ -0,0 +1,26 @@
+// revisions: full gce
+// compile-flags: -Zdeduplicate-diagnostics=yes
+
+#![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/tests/ui/const-generics/generic_const_exprs/different-fn.rs b/tests/ui/const-generics/generic_const_exprs/different-fn.rs
new file mode 100644
index 000000000..e8bc703bd
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/different-fn.stderr b/tests/ui/const-generics/generic_const_exprs/different-fn.stderr
new file mode 100644
index 000000000..83a2f3740
--- /dev/null
+++ b/tests/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 constant `size_of::<T>()`
+ found constant `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/tests/ui/const-generics/generic_const_exprs/division.rs b/tests/ui/const-generics/generic_const_exprs/division.rs
new file mode 100644
index 000000000..098fa9e04
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/dont-eagerly-error-in-is-const-evaluatable.rs b/tests/ui/const-generics/generic_const_exprs/dont-eagerly-error-in-is-const-evaluatable.rs
new file mode 100644
index 000000000..3543960c3
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/drop_impl.rs b/tests/ui/const-generics/generic_const_exprs/drop_impl.rs
new file mode 100644
index 000000000..077f77aa0
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/elaborate-trait-pred.rs b/tests/ui/const-generics/generic_const_exprs/elaborate-trait-pred.rs
new file mode 100644
index 000000000..e4111157e
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/eval-privacy.rs b/tests/ui/const-generics/generic_const_exprs/eval-privacy.rs
new file mode 100644
index 000000000..8023b998a
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/eval-privacy.stderr b/tests/ui/const-generics/generic_const_exprs/eval-privacy.stderr
new file mode 100644
index 000000000..2d9de8805
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/eval-try-unify.rs b/tests/ui/const-generics/generic_const_exprs/eval-try-unify.rs
new file mode 100644
index 000000000..c59d62e57
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/eval-try-unify.stderr b/tests/ui/const-generics/generic_const_exprs/eval-try-unify.stderr
new file mode 100644
index 000000000..8eb1fccc5
--- /dev/null
+++ b/tests/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: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
+ = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/const-generics/generic_const_exprs/evaluated-to-ambig.rs b/tests/ui/const-generics/generic_const_exprs/evaluated-to-ambig.rs
new file mode 100644
index 000000000..340e35e1c
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/feature-gate-generic_const_exprs.rs b/tests/ui/const-generics/generic_const_exprs/feature-gate-generic_const_exprs.rs
new file mode 100644
index 000000000..10ab2fd86
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/feature-gate-generic_const_exprs.stderr b/tests/ui/const-generics/generic_const_exprs/feature-gate-generic_const_exprs.stderr
new file mode 100644
index 000000000..2d60ebaa8
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/fn_call.rs b/tests/ui/const-generics/generic_const_exprs/fn_call.rs
new file mode 100644
index 000000000..cbe4277df
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/from-sig-fail.rs b/tests/ui/const-generics/generic_const_exprs/from-sig-fail.rs
new file mode 100644
index 000000000..b8f9827ec
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/from-sig-fail.stderr b/tests/ui/const-generics/generic_const_exprs/from-sig-fail.stderr
new file mode 100644
index 000000000..bd71b49ee
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/from-sig.rs b/tests/ui/const-generics/generic_const_exprs/from-sig.rs
new file mode 100644
index 000000000..28de4f864
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/function-call.rs b/tests/ui/const-generics/generic_const_exprs/function-call.rs
new file mode 100644
index 000000000..3c866333d
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/function-call.rs
@@ -0,0 +1,20 @@
+// check-pass
+// compile-flags: -Zdeduplicate-diagnostics=yes
+
+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/tests/ui/const-generics/generic_const_exprs/function-call.stderr b/tests/ui/const-generics/generic_const_exprs/function-call.stderr
new file mode 100644
index 000000000..84abfe578
--- /dev/null
+++ b/tests/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:15:17
+ |
+LL | let _ = [0; foo::<T>()];
+ | ^^^^^^^^^^
+ |
+ = 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>
+ = note: `#[warn(const_evaluatable_unchecked)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/const-generics/generic_const_exprs/impl-bounds.rs b/tests/ui/const-generics/generic_const_exprs/impl-bounds.rs
new file mode 100644
index 000000000..7120d6ee2
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/infer-too-generic.rs b/tests/ui/const-generics/generic_const_exprs/infer-too-generic.rs
new file mode 100644
index 000000000..b8058c252
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/issue-100217.rs b/tests/ui/const-generics/generic_const_exprs/issue-100217.rs
new file mode 100644
index 000000000..acdc348a3
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/issue-100217.rs
@@ -0,0 +1,42 @@
+// build-pass
+
+#![allow(incomplete_features)]
+#![feature(generic_const_exprs)]
+
+trait TraitOne {
+ const MY_NUM: usize;
+ type MyErr: std::fmt::Debug;
+
+ fn do_one_stuff(arr: [u8; Self::MY_NUM]) -> Result<(), Self::MyErr>;
+}
+
+trait TraitTwo {
+ fn do_two_stuff();
+}
+
+impl<O: TraitOne> TraitTwo for O
+where
+ [(); Self::MY_NUM]:,
+{
+ fn do_two_stuff() {
+ O::do_one_stuff([5; Self::MY_NUM]).unwrap()
+ }
+}
+
+struct Blargotron;
+
+#[derive(Debug)]
+struct ErrTy<const N: usize>([(); N]);
+
+impl TraitOne for Blargotron {
+ const MY_NUM: usize = 3;
+ type MyErr = ErrTy<{ Self::MY_NUM }>;
+
+ fn do_one_stuff(_arr: [u8; Self::MY_NUM]) -> Result<(), Self::MyErr> {
+ Ok(())
+ }
+}
+
+fn main() {
+ Blargotron::do_two_stuff();
+}
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-100360.rs b/tests/ui/const-generics/generic_const_exprs/issue-100360.rs
new file mode 100644
index 000000000..5572f1f88
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/issue-100360.rs
@@ -0,0 +1,13 @@
+// check-pass
+// (this requires debug assertions)
+
+#![feature(adt_const_params)]
+#![allow(incomplete_features)]
+
+fn foo<const B: &'static bool>(arg: &'static bool) -> bool {
+ B == arg
+}
+
+fn main() {
+ foo::<{ &true }>(&false);
+}
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-102074.rs b/tests/ui/const-generics/generic_const_exprs/issue-102074.rs
new file mode 100644
index 000000000..66d15cf12
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/issue-102074.rs
@@ -0,0 +1,23 @@
+// check-pass
+// Checks that the NoopMethodCall lint doesn't call Instance::resolve on unresolved consts
+
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+#[derive(Debug, Clone)]
+pub struct Aes128CipherKey([u8; Aes128Cipher::KEY_LEN]);
+
+impl Aes128CipherKey {
+ pub fn new(key: &[u8; Aes128Cipher::KEY_LEN]) -> Self {
+ Self(key.clone())
+ }
+}
+
+#[derive(Debug, Clone)]
+pub struct Aes128Cipher;
+
+impl Aes128Cipher {
+ const KEY_LEN: usize = 16;
+}
+
+fn main() {}
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-102768.rs b/tests/ui/const-generics/generic_const_exprs/issue-102768.rs
new file mode 100644
index 000000000..7aea0d30d
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/issue-102768.rs
@@ -0,0 +1,14 @@
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+trait X {
+ type Y<'a>;
+}
+
+const _: () = {
+ fn f2<'a>(arg: Box<dyn X<Y<1> = &'a ()>>) {}
+ //~^ ERROR this associated type takes 1 lifetime argument but 0 lifetime arguments
+ //~| ERROR this associated type takes 0 generic arguments but 1 generic argument
+};
+
+fn main() {}
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-102768.stderr b/tests/ui/const-generics/generic_const_exprs/issue-102768.stderr
new file mode 100644
index 000000000..8278edabe
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/issue-102768.stderr
@@ -0,0 +1,33 @@
+error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
+ --> $DIR/issue-102768.rs:9:30
+ |
+LL | fn f2<'a>(arg: Box<dyn X<Y<1> = &'a ()>>) {}
+ | ^ expected 1 lifetime argument
+ |
+note: associated type defined here, with 1 lifetime parameter: `'a`
+ --> $DIR/issue-102768.rs:5:10
+ |
+LL | type Y<'a>;
+ | ^ --
+help: add missing lifetime argument
+ |
+LL | fn f2<'a>(arg: Box<dyn X<Y<'_, 1> = &'a ()>>) {}
+ | +++
+
+error[E0107]: this associated type takes 0 generic arguments but 1 generic argument was supplied
+ --> $DIR/issue-102768.rs:9:30
+ |
+LL | fn f2<'a>(arg: Box<dyn X<Y<1> = &'a ()>>) {}
+ | ^--- help: remove these generics
+ | |
+ | expected 0 generic arguments
+ |
+note: associated type defined here, with 0 generic parameters
+ --> $DIR/issue-102768.rs:5:10
+ |
+LL | type Y<'a>;
+ | ^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0107`.
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-105257.rs b/tests/ui/const-generics/generic_const_exprs/issue-105257.rs
new file mode 100644
index 000000000..d8b23bc01
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/issue-105257.rs
@@ -0,0 +1,9 @@
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+trait Trait<T> {
+ fn fnc<const N: usize = "">(&self) {} //~ERROR defaults for const parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
+ fn foo<const N: usize = { std::mem::size_of::<T>() }>(&self) {} //~ERROR defaults for const parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
+}
+
+fn main() {}
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-105257.stderr b/tests/ui/const-generics/generic_const_exprs/issue-105257.stderr
new file mode 100644
index 000000000..ed7a8cb19
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/issue-105257.stderr
@@ -0,0 +1,14 @@
+error: defaults for const parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
+ --> $DIR/issue-105257.rs:5:12
+ |
+LL | fn fnc<const N: usize = "">(&self) {}
+ | ^^^^^^^^^^^^^^^^^^^
+
+error: defaults for const parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
+ --> $DIR/issue-105257.rs:6:12
+ |
+LL | fn foo<const N: usize = { std::mem::size_of::<T>() }>(&self) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-105608.rs b/tests/ui/const-generics/generic_const_exprs/issue-105608.rs
new file mode 100644
index 000000000..e28ba3b1a
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/issue-105608.rs
@@ -0,0 +1,15 @@
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+struct Combination<const STRATEGIES: usize>;
+
+impl<const STRATEGIES: usize> Combination<STRATEGIES> {
+ fn and<M>(self) -> Combination<{ STRATEGIES + 1 }> {
+ Combination
+ }
+}
+
+pub fn main() {
+ Combination::<0>.and::<_>().and::<_>();
+ //~^ ERROR: type annotations needed
+}
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-105608.stderr b/tests/ui/const-generics/generic_const_exprs/issue-105608.stderr
new file mode 100644
index 000000000..0be4c43da
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/issue-105608.stderr
@@ -0,0 +1,14 @@
+error[E0282]: type annotations needed
+ --> $DIR/issue-105608.rs:13:22
+ |
+LL | Combination::<0>.and::<_>().and::<_>();
+ | ^^^ cannot infer type of the type parameter `M` declared on the associated function `and`
+ |
+help: consider specifying the generic argument
+ |
+LL | Combination::<0>.and::<_>().and::<_>();
+ | ~~~~~
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-62504.full.stderr b/tests/ui/const-generics/generic_const_exprs/issue-62504.full.stderr
new file mode 100644
index 000000000..0742db398
--- /dev/null
+++ b/tests/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 constant `X`
+ found constant `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/tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr b/tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr
new file mode 100644
index 000000000..65822856e
--- /dev/null
+++ b/tests/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; Self::SIZE]`
+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/tests/ui/const-generics/generic_const_exprs/issue-62504.rs b/tests/ui/const-generics/generic_const_exprs/issue-62504.rs
new file mode 100644
index 000000000..a97f4b8ff
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/issue-69654.rs b/tests/ui/const-generics/generic_const_exprs/issue-69654.rs
new file mode 100644
index 000000000..9b36699bb
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/issue-69654.stderr b/tests/ui/const-generics/generic_const_exprs/issue-69654.stderr
new file mode 100644
index 000000000..eb4ff8305
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/issue-69654.stderr
@@ -0,0 +1,30 @@
+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
+ | |
+ | found this type parameter
+
+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: trait bound `[u8; _]: Bar<[(); _]>` was not satisfied
+ --> $DIR/issue-69654.rs:11:14
+ |
+LL | impl<const N: usize> Foo<N>
+ | ------
+LL | where
+LL | [u8; N]: Bar<[(); N]>,
+ | ^^^^^^^^^^^^ unsatisfied trait bound introduced here
+
+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/tests/ui/const-generics/generic_const_exprs/issue-72787.min.stderr b/tests/ui/const-generics/generic_const_exprs/issue-72787.min.stderr
new file mode 100644
index 000000000..ea6f5f692
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/issue-72787.min.stderr
@@ -0,0 +1,38 @@
+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:23: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:23: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: aborting due to 4 previous errors
+
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-72787.rs b/tests/ui/const-generics/generic_const_exprs/issue-72787.rs
new file mode 100644
index 000000000..657fec2e9
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/issue-72787.rs
@@ -0,0 +1,33 @@
+// [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,
+ 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/tests/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.full.stderr b/tests/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.full.stderr
new file mode 100644
index 000000000..f2fddfbfb
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.full.stderr
@@ -0,0 +1,35 @@
+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 constant `false`
+ found constant `true`
+note: required by a bound in `Arr`
+ --> $DIR/issue-72819-generic-in-const-eval.rs:8:39
+ |
+LL | struct Arr<const N: usize>
+ | --- required by a bound in this
+LL | where Assert::<{N < usize::MAX / 2}>: IsTrue,
+ | ^^^^^^ required by this bound in `Arr`
+
+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 constant `false`
+ found constant `true`
+note: required by a bound in `Arr`
+ --> $DIR/issue-72819-generic-in-const-eval.rs:8:39
+ |
+LL | struct Arr<const N: usize>
+ | --- required by a bound in this
+LL | where Assert::<{N < usize::MAX / 2}>: IsTrue,
+ | ^^^^^^ required by this bound in `Arr`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.min.stderr b/tests/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.min.stderr
new file mode 100644
index 000000000..42671412f
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.rs b/tests/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.rs
new file mode 100644
index 000000000..7a5aa9e47
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/issue-73298.rs b/tests/ui/const-generics/generic_const_exprs/issue-73298.rs
new file mode 100644
index 000000000..3c59e1b79
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/issue-73298.rs
@@ -0,0 +1,23 @@
+// build-pass
+
+#![allow(incomplete_features)]
+#![feature(generic_const_exprs)]
+
+use std::convert::AsMut;
+use std::default::Default;
+
+trait Foo: Sized {
+ type Baz: Default + AsMut<[u8]>;
+ fn bar() {
+ Self::Baz::default().as_mut();
+ }
+}
+
+impl Foo for () {
+ type Baz = [u8; 1 * 1];
+ //type Baz = [u8; 1];
+}
+
+fn main() {
+ <() as Foo>::bar();
+}
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-73899.rs b/tests/ui/const-generics/generic_const_exprs/issue-73899.rs
new file mode 100644
index 000000000..d1ab1be04
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/issue-74634.rs b/tests/ui/const-generics/generic_const_exprs/issue-74634.rs
new file mode 100644
index 000000000..cd1f7a9da
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/issue-74713.rs b/tests/ui/const-generics/generic_const_exprs/issue-74713.rs
new file mode 100644
index 000000000..0bcb997d9
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/issue-74713.stderr b/tests/ui/const-generics/generic_const_exprs/issue-74713.stderr
new file mode 100644
index 000000000..e7673df0a
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/issue-76595.rs b/tests/ui/const-generics/generic_const_exprs/issue-76595.rs
new file mode 100644
index 000000000..10247ce6b
--- /dev/null
+++ b/tests/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 function takes 2 generic arguments
+}
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-76595.stderr b/tests/ui/const-generics/generic_const_exprs/issue-76595.stderr
new file mode 100644
index 000000000..c587a7e15
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/issue-79518-default_trait_method_normalization.rs b/tests/ui/const-generics/generic_const_exprs/issue-79518-default_trait_method_normalization.rs
new file mode 100644
index 000000000..2fa9a71fb
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/issue-79518-default_trait_method_normalization.stderr b/tests/ui/const-generics/generic_const_exprs/issue-79518-default_trait_method_normalization.stderr
new file mode 100644
index 000000000..9baf9790e
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/issue-79518-default_trait_method_normalization.stderr
@@ -0,0 +1,16 @@
+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 `[(); std::mem::size_of::<Self::Assoc>()]`
+ | |
+ | expected because this is `<Self as Foo>::Assoc`
+ |
+ = note: expected associated type `<Self as Foo>::Assoc`
+ found array `[(); std::mem::size_of::<Self::Assoc>()]`
+ = help: consider constraining the associated type `<Self as Foo>::Assoc` to `[(); std::mem::size_of::<Self::Assoc>()]` 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/tests/ui/const-generics/generic_const_exprs/issue-80561-incorrect-param-env.rs b/tests/ui/const-generics/generic_const_exprs/issue-80561-incorrect-param-env.rs
new file mode 100644
index 000000000..77d3c98da
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/issue-80742.rs b/tests/ui/const-generics/generic_const_exprs/issue-80742.rs
new file mode 100644
index 000000000..275f69953
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr b/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr
new file mode 100644
index 000000000..6aa8ee13b
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr
@@ -0,0 +1,71 @@
+error[E0080]: evaluation of `Inline::<dyn std::fmt::Debug>::{constant#0}` failed
+ --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
+ |
+ = note: size_of called on unsized type `dyn Debug`
+ |
+note: inside `std::mem::size_of::<dyn Debug>`
+ --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
+note: inside `Inline::<dyn Debug>::{constant#0}`
+ --> $DIR/issue-80742.rs:22:10
+ |
+LL | [u8; size_of::<T>() + 1]: ,
+ | ^^^^^^^^^^^^^^
+
+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
+ |
+ = note: doesn't satisfy `dyn Debug: Sized`
+ |
+note: trait bound `dyn Debug: Sized` was not satisfied
+ --> $DIR/issue-80742.rs:20:6
+ |
+LL | impl<T> Inline<T>
+ | ^ ---------
+ | |
+ | unsatisfied trait bound introduced here
+help: consider relaxing the type parameter's implicit `Sized` bound
+ |
+LL | impl<T: ?Sized> Inline<T>
+ | ++++++++
+
+error[E0080]: evaluation of `Inline::<dyn std::fmt::Debug>::{constant#0}` failed
+ --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
+ |
+ = note: size_of called on unsized type `dyn Debug`
+ |
+note: inside `std::mem::size_of::<dyn Debug>`
+ --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
+note: inside `Inline::<dyn Debug>::{constant#0}`
+ --> $DIR/issue-80742.rs:14:10
+ |
+LL | [u8; size_of::<T>() + 1]: ,
+ | ^^^^^^^^^^^^^^
+
+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/tests/ui/const-generics/generic_const_exprs/issue-82268.rs b/tests/ui/const-generics/generic_const_exprs/issue-82268.rs
new file mode 100644
index 000000000..d08fc5beb
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/issue-82268.rs
@@ -0,0 +1,73 @@
+// build-pass
+
+#![allow(incomplete_features)]
+#![feature(generic_const_exprs)]
+
+trait Collate<Op> {
+ type Pass;
+ type Fail;
+
+ fn collate(self) -> (Self::Pass, Self::Fail);
+}
+
+impl<Op> Collate<Op> for () {
+ type Pass = ();
+ type Fail = ();
+
+ fn collate(self) -> ((), ()) {
+ ((), ())
+ }
+}
+
+trait CollateStep<X, Prev> {
+ type Pass;
+ type Fail;
+ fn collate_step(x: X, prev: Prev) -> (Self::Pass, Self::Fail);
+}
+
+impl<X, P, F> CollateStep<X, (P, F)> for () {
+ type Pass = (X, P);
+ type Fail = F;
+
+ fn collate_step(x: X, (p, f): (P, F)) -> ((X, P), F) {
+ ((x, p), f)
+ }
+}
+
+struct CollateOpImpl<const MASK: u32>;
+trait CollateOpStep {
+ type NextOp;
+ type Apply;
+}
+
+impl<const MASK: u32> CollateOpStep for CollateOpImpl<MASK>
+where
+ CollateOpImpl<{ MASK >> 1 }>: Sized,
+{
+ type NextOp = CollateOpImpl<{ MASK >> 1 }>;
+ type Apply = ();
+}
+
+impl<H, T, Op: CollateOpStep> Collate<Op> for (H, T)
+where
+ T: Collate<Op::NextOp>,
+ Op::Apply: CollateStep<H, (T::Pass, T::Fail)>,
+{
+ type Pass = <Op::Apply as CollateStep<H, (T::Pass, T::Fail)>>::Pass;
+ type Fail = <Op::Apply as CollateStep<H, (T::Pass, T::Fail)>>::Fail;
+
+ fn collate(self) -> (Self::Pass, Self::Fail) {
+ <Op::Apply as CollateStep<H, (T::Pass, T::Fail)>>::collate_step(self.0, self.1.collate())
+ }
+}
+
+fn collate<X, const MASK: u32>(x: X) -> (X::Pass, X::Fail)
+where
+ X: Collate<CollateOpImpl<MASK>>,
+{
+ x.collate()
+}
+
+fn main() {
+ dbg!(collate::<_, 5>(("Hello", (42, ('!', ())))));
+}
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-83765.rs b/tests/ui/const-generics/generic_const_exprs/issue-83765.rs
new file mode 100644
index 000000000..fac811d13
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/issue-83765.stderr b/tests/ui/const-generics/generic_const_exprs/issue-83765.stderr
new file mode 100644
index 000000000..b693023f1
--- /dev/null
+++ b/tests/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 constant `Self::DIM`
+ found constant `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 constant `DIM`
+ found constant `Self::DIM`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-83972.rs b/tests/ui/const-generics/generic_const_exprs/issue-83972.rs
new file mode 100644
index 000000000..0063719b8
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/issue-83972.rs
@@ -0,0 +1,38 @@
+// build-pass
+
+#![allow(incomplete_features)]
+#![feature(generic_const_exprs)]
+
+pub trait Foo {
+ fn foo(&self);
+}
+
+pub struct FooImpl<const N: usize>;
+impl<const N: usize> Foo for FooImpl<N> {
+ fn foo(&self) {}
+}
+
+pub trait Bar: 'static {
+ type Foo: Foo;
+ fn get() -> &'static Self::Foo;
+}
+
+struct BarImpl;
+impl Bar for BarImpl {
+ type Foo = FooImpl<
+ {
+ { 4 }
+ },
+ >;
+ fn get() -> &'static Self::Foo {
+ &FooImpl
+ }
+}
+
+pub fn boom<B: Bar>() {
+ B::get().foo();
+}
+
+fn main() {
+ boom::<BarImpl>();
+}
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-84408.rs b/tests/ui/const-generics/generic_const_exprs/issue-84408.rs
new file mode 100644
index 000000000..fb2e5590d
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/issue-84669.rs b/tests/ui/const-generics/generic_const_exprs/issue-84669.rs
new file mode 100644
index 000000000..3933ff20a
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/issue-84669.rs
@@ -0,0 +1,30 @@
+// build-pass
+
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+trait Foo {
+ type Output;
+
+ fn foo() -> Self::Output;
+}
+
+impl Foo for [u8; 3] {
+ type Output = [u8; 1 + 2];
+
+ fn foo() -> [u8; 3] {
+ [1u8; 3]
+ }
+}
+
+fn bug<const N: usize>()
+where
+ [u8; N]: Foo,
+ <[u8; N] as Foo>::Output: AsRef<[u8]>,
+{
+ <[u8; N]>::foo().as_ref();
+}
+
+fn main() {
+ bug::<3>();
+}
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-85848.rs b/tests/ui/const-generics/generic_const_exprs/issue-85848.rs
new file mode 100644
index 000000000..3a7f4c618
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/issue-85848.stderr b/tests/ui/const-generics/generic_const_exprs/issue-85848.stderr
new file mode 100644
index 000000000..e50ac671e
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/issue-85848.stderr
@@ -0,0 +1,65 @@
+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 for `&C` to implement `Contains<(), true>`
+ --> $DIR/issue-85848.rs:21:12
+ |
+LL | impl<T, U> Contains<T, { contains::<T, U>() }> for U where T: _Contains<U> {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^ ------------ unsatisfied trait bound introduced here
+note: required for `&C` to implement `Delegates<()>`
+ --> $DIR/issue-85848.rs:12:12
+ |
+LL | impl<T, U> Delegates<U> for T where T: Contains<U, true> {}
+ | ^^^^^^^^^^^^ ^ ----------------- unsatisfied trait bound introduced here
+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 for `&C` to implement `Contains<(), true>`
+ --> $DIR/issue-85848.rs:21:12
+ |
+LL | impl<T, U> Contains<T, { contains::<T, U>() }> for U where T: _Contains<U> {}
+ | ^^^^^^^^^^^^----------------------^ ^
+ | |
+ | unsatisfied trait bound introduced here
+note: required for `&C` to implement `Delegates<()>`
+ --> $DIR/issue-85848.rs:12:12
+ |
+LL | impl<T, U> Delegates<U> for T where T: Contains<U, true> {}
+ | ^^^^^^^^^^^^ ^ ----------------- unsatisfied trait bound introduced here
+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 constant `true`
+ found constant `{ 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/tests/ui/const-generics/generic_const_exprs/issue-86710.rs b/tests/ui/const-generics/generic_const_exprs/issue-86710.rs
new file mode 100644
index 000000000..bdd8a21b3
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/issue-86710.rs
@@ -0,0 +1,73 @@
+// build-pass
+
+#![allow(incomplete_features)]
+#![feature(generic_const_exprs)]
+
+use std::marker::PhantomData;
+
+fn main() {
+ let x = FooImpl::<BarImpl<1>> { phantom: PhantomData };
+ let _ = x.foo::<BarImpl<1>>();
+}
+
+trait Foo<T>
+where
+ T: Bar,
+{
+ fn foo<U>(&self)
+ where
+ T: Operation<U>,
+ <T as Operation<U>>::Output: Bar;
+}
+
+struct FooImpl<T>
+where
+ T: Bar,
+{
+ phantom: PhantomData<T>,
+}
+
+impl<T> Foo<T> for FooImpl<T>
+where
+ T: Bar,
+{
+ fn foo<U>(&self)
+ where
+ T: Operation<U>,
+ <T as Operation<U>>::Output: Bar,
+ {
+ <<T as Operation<U>>::Output as Bar>::error_occurs_here();
+ }
+}
+
+trait Bar {
+ fn error_occurs_here();
+}
+
+struct BarImpl<const N: usize>;
+
+impl<const N: usize> Bar for BarImpl<N> {
+ fn error_occurs_here() {}
+}
+
+trait Operation<Rhs> {
+ type Output;
+}
+
+//// Part-A: This causes error.
+impl<const M: usize, const N: usize> Operation<BarImpl<M>> for BarImpl<N>
+where
+ BarImpl<{ N + M }>: Sized,
+{
+ type Output = BarImpl<{ N + M }>;
+}
+
+//// Part-B: This doesn't cause error.
+// impl<const M: usize, const N: usize> Operation<BarImpl<M>> for BarImpl<N> {
+// type Output = BarImpl<M>;
+// }
+
+//// Part-C: This also doesn't cause error.
+// impl<const M: usize, const N: usize> Operation<BarImpl<M>> for BarImpl<N> {
+// type Output = BarImpl<{ M }>;
+// }
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-89851.rs b/tests/ui/const-generics/generic_const_exprs/issue-89851.rs
new file mode 100644
index 000000000..cde849d90
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/issue-89851.rs
@@ -0,0 +1,12 @@
+// check-pass
+// (this requires debug assertions)
+
+#![feature(adt_const_params)]
+#![allow(incomplete_features)]
+
+pub const BAR: () = ice::<"">();
+pub const fn ice<const N: &'static str>() {
+ &10;
+}
+
+fn main() {}
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-90847.rs b/tests/ui/const-generics/generic_const_exprs/issue-90847.rs
new file mode 100644
index 000000000..ebc6fe141
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/issue-94287.rs b/tests/ui/const-generics/generic_const_exprs/issue-94287.rs
new file mode 100644
index 000000000..643126a46
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/issue-94287.stderr b/tests/ui/const-generics/generic_const_exprs/issue-94287.stderr
new file mode 100644
index 000000000..7390a0077
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/issue-94293.rs b/tests/ui/const-generics/generic_const_exprs/issue-94293.rs
new file mode 100644
index 000000000..713c5d89a
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/issue-94293.rs
@@ -0,0 +1,31 @@
+// check-pass
+
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+#![deny(const_evaluatable_unchecked)]
+
+pub struct If<const CONDITION: bool>;
+pub trait True {}
+impl True for If<true> {}
+
+pub struct FixedI8<const FRAC: u32> {
+ pub bits: i8,
+}
+
+impl<const FRAC_LHS: u32, const FRAC_RHS: u32> PartialEq<FixedI8<FRAC_RHS>> for FixedI8<FRAC_LHS>
+where
+ If<{ FRAC_RHS <= 8 }>: True,
+{
+ fn eq(&self, _rhs: &FixedI8<FRAC_RHS>) -> bool {
+ unimplemented!()
+ }
+}
+
+impl<const FRAC: u32> PartialEq<i8> for FixedI8<FRAC> {
+ fn eq(&self, rhs: &i8) -> bool {
+ let rhs_as_fixed = FixedI8::<0> { bits: *rhs };
+ PartialEq::eq(self, &rhs_as_fixed)
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-97047-ice-1.rs b/tests/ui/const-generics/generic_const_exprs/issue-97047-ice-1.rs
new file mode 100644
index 000000000..67e30232e
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/issue-97047-ice-1.stderr b/tests/ui/const-generics/generic_const_exprs/issue-97047-ice-1.stderr
new file mode 100644
index 000000000..1cceaece7
--- /dev/null
+++ b/tests/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: see issue #95174 <https://github.com/rust-lang/rust/issues/95174> for more information
+ = note: `#[warn(incomplete_features)]` on by default
+
+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/tests/ui/const-generics/generic_const_exprs/issue-97047-ice-2.rs b/tests/ui/const-generics/generic_const_exprs/issue-97047-ice-2.rs
new file mode 100644
index 000000000..00568a089
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/issue-97047-ice-2.stderr b/tests/ui/const-generics/generic_const_exprs/issue-97047-ice-2.stderr
new file mode 100644
index 000000000..774e842bc
--- /dev/null
+++ b/tests/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: see issue #95174 <https://github.com/rust-lang/rust/issues/95174> for more information
+ = note: `#[warn(incomplete_features)]` on by default
+
+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/tests/ui/const-generics/generic_const_exprs/issue-99647.rs b/tests/ui/const-generics/generic_const_exprs/issue-99647.rs
new file mode 100644
index 000000000..f797beda8
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/issue-99647.rs
@@ -0,0 +1,15 @@
+// edition:2018
+// run-pass
+
+#![allow(incomplete_features)]
+#![feature(generic_const_exprs)]
+
+#[allow(unused)]
+async fn foo<'a>() {
+ let _data = &mut [0u8; { 1 + 4 }];
+ bar().await
+}
+
+async fn bar() {}
+
+fn main() {}
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-99705.rs b/tests/ui/const-generics/generic_const_exprs/issue-99705.rs
new file mode 100644
index 000000000..75b57b621
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/issue-99705.rs
@@ -0,0 +1,33 @@
+// check-pass
+#![crate_type = "lib"]
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+pub trait MyIterator {
+ type Output;
+}
+
+pub trait Foo {
+ const ABC: usize;
+}
+
+pub struct IteratorStruct<const N: usize>{
+
+}
+
+pub struct Bar<const N: usize> {
+ pub data: [usize; N]
+}
+
+impl<const N: usize> MyIterator for IteratorStruct<N> {
+ type Output = Bar<N>;
+}
+
+pub fn test1<T: Foo>() -> impl MyIterator<Output = Bar<{T::ABC}>> where [(); T::ABC]: Sized {
+ IteratorStruct::<{T::ABC}>{}
+}
+
+pub trait Baz<const N: usize>{}
+impl<const N: usize> Baz<N> for Bar<N> {}
+pub fn test2<T: Foo>() -> impl MyIterator<Output = impl Baz<{ T::ABC }>> where [(); T::ABC]: Sized {
+ IteratorStruct::<{T::ABC}>{}
+}
diff --git a/tests/ui/const-generics/generic_const_exprs/less_than.rs b/tests/ui/const-generics/generic_const_exprs/less_than.rs
new file mode 100644
index 000000000..2e9af1bf4
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/let-bindings.rs b/tests/ui/const-generics/generic_const_exprs/let-bindings.rs
new file mode 100644
index 000000000..cd5d76dd9
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/let-bindings.stderr b/tests/ui/const-generics/generic_const_exprs/let-bindings.stderr
new file mode 100644
index 000000000..823a4f8a1
--- /dev/null
+++ b/tests/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 constants
+ |
+ = 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 constants
+ |
+ = 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/tests/ui/const-generics/generic_const_exprs/needs_where_clause.rs b/tests/ui/const-generics/generic_const_exprs/needs_where_clause.rs
new file mode 100644
index 000000000..2bd3c801f
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/needs_where_clause.stderr b/tests/ui/const-generics/generic_const_exprs/needs_where_clause.stderr
new file mode 100644
index 000000000..7b41e39b7
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/nested-abstract-consts-1.rs b/tests/ui/const-generics/generic_const_exprs/nested-abstract-consts-1.rs
new file mode 100644
index 000000000..7e5022817
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/nested-abstract-consts-2.rs b/tests/ui/const-generics/generic_const_exprs/nested-abstract-consts-2.rs
new file mode 100644
index 000000000..769e3ae68
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/nested_uneval_unification-1.rs b/tests/ui/const-generics/generic_const_exprs/nested_uneval_unification-1.rs
new file mode 100644
index 000000000..316887e5e
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/nested_uneval_unification-2.rs b/tests/ui/const-generics/generic_const_exprs/nested_uneval_unification-2.rs
new file mode 100644
index 000000000..d45a6465b
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/no_dependence.rs b/tests/ui/const-generics/generic_const_exprs/no_dependence.rs
new file mode 100644
index 000000000..db8dc6ed4
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/no_where_clause.rs b/tests/ui/const-generics/generic_const_exprs/no_where_clause.rs
new file mode 100644
index 000000000..9c5de0317
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/no_where_clause.stderr b/tests/ui/const-generics/generic_const_exprs/no_where_clause.stderr
new file mode 100644
index 000000000..3e5c2f5ca
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/non_local_anon_const_diagnostics.rs b/tests/ui/const-generics/generic_const_exprs/non_local_anon_const_diagnostics.rs
new file mode 100644
index 000000000..1254b4435
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/non_local_anon_const_diagnostics.rs
@@ -0,0 +1,16 @@
+// aux-build:anon_const_non_local.rs
+
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+extern crate anon_const_non_local;
+
+fn bar<const M: usize>()
+where
+ [(); M + 1]:,
+{
+ let _: anon_const_non_local::Foo<2> = anon_const_non_local::foo::<M>();
+ //~^ ERROR: mismatched types
+}
+
+fn main() {}
diff --git a/tests/ui/const-generics/generic_const_exprs/non_local_anon_const_diagnostics.stderr b/tests/ui/const-generics/generic_const_exprs/non_local_anon_const_diagnostics.stderr
new file mode 100644
index 000000000..3926c830a
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/non_local_anon_const_diagnostics.stderr
@@ -0,0 +1,12 @@
+error[E0308]: mismatched types
+ --> $DIR/non_local_anon_const_diagnostics.rs:12:43
+ |
+LL | let _: anon_const_non_local::Foo<2> = anon_const_non_local::foo::<M>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `2`, found `anon_const_non_local::::foo::{constant#0}`
+ |
+ = note: expected constant `2`
+ found constant `anon_const_non_local::::foo::{constant#0}`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/const-generics/generic_const_exprs/normed_to_param_is_evaluatable.rs b/tests/ui/const-generics/generic_const_exprs/normed_to_param_is_evaluatable.rs
new file mode 100644
index 000000000..b37b354ae
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/normed_to_param_is_evaluatable.rs
@@ -0,0 +1,12 @@
+// check-pass
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features, unused_braces)]
+
+#[rustfmt::skip]
+fn foo<const N: usize>() {
+ bar::<{{{{{{ N }}}}}}>();
+}
+
+fn bar<const N: usize>() {}
+
+fn main() {}
diff --git a/tests/ui/const-generics/generic_const_exprs/object-safety-err-ret.rs b/tests/ui/const-generics/generic_const_exprs/object-safety-err-ret.rs
new file mode 100644
index 000000000..24d333aba
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/object-safety-err-ret.stderr b/tests/ui/const-generics/generic_const_exprs/object-safety-err-ret.stderr
new file mode 100644
index 000000000..4e1d71f15
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/object-safety-err-where-bounds.rs b/tests/ui/const-generics/generic_const_exprs/object-safety-err-where-bounds.rs
new file mode 100644
index 000000000..42c1cc507
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/object-safety-err-where-bounds.stderr b/tests/ui/const-generics/generic_const_exprs/object-safety-err-where-bounds.stderr
new file mode 100644
index 000000000..440cf457e
--- /dev/null
+++ b/tests/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;
+ | ^^^^
+ |
+ = 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
+note: the lint level is defined here
+ --> $DIR/object-safety-err-where-bounds.rs:3:9
+ |
+LL | #![deny(where_clauses_object_safety)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.rs b/tests/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.rs
new file mode 100644
index 000000000..79e9834b5
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.stderr b/tests/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.stderr
new file mode 100644
index 000000000..59e9fee1e
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/object-safety-ok.rs b/tests/ui/const-generics/generic_const_exprs/object-safety-ok.rs
new file mode 100644
index 000000000..f4c89f623
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/obligation-cause.rs b/tests/ui/const-generics/generic_const_exprs/obligation-cause.rs
new file mode 100644
index 000000000..e7c8e4f66
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/obligation-cause.rs
@@ -0,0 +1,24 @@
+#![allow(incomplete_features)]
+#![feature(generic_const_exprs)]
+
+trait True {}
+
+struct Is<const V: bool>;
+
+impl True for Is<true> {}
+
+fn g<T>()
+//~^ NOTE required by a bound in this
+where
+ Is<{ std::mem::size_of::<T>() == 0 }>: True,
+ //~^ NOTE required by a bound in `g`
+ //~| NOTE required by this bound in `g`
+{
+}
+
+fn main() {
+ g::<usize>();
+ //~^ ERROR mismatched types
+ //~| NOTE expected `false`, found `true`
+ //~| NOTE expected constant `false`
+}
diff --git a/tests/ui/const-generics/generic_const_exprs/obligation-cause.stderr b/tests/ui/const-generics/generic_const_exprs/obligation-cause.stderr
new file mode 100644
index 000000000..a253ec676
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/obligation-cause.stderr
@@ -0,0 +1,20 @@
+error[E0308]: mismatched types
+ --> $DIR/obligation-cause.rs:20:5
+ |
+LL | g::<usize>();
+ | ^^^^^^^^^^ expected `false`, found `true`
+ |
+ = note: expected constant `false`
+ found constant `true`
+note: required by a bound in `g`
+ --> $DIR/obligation-cause.rs:13:44
+ |
+LL | fn g<T>()
+ | - required by a bound in this
+...
+LL | Is<{ std::mem::size_of::<T>() == 0 }>: True,
+ | ^^^^ required by this bound in `g`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/const-generics/generic_const_exprs/simple_fail.rs b/tests/ui/const-generics/generic_const_exprs/simple_fail.rs
new file mode 100644
index 000000000..cae54df4c
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/simple_fail.stderr b/tests/ui/const-generics/generic_const_exprs/simple_fail.stderr
new file mode 100644
index 000000000..a25fa56b7
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/subexprs_are_const_evalutable.rs b/tests/ui/const-generics/generic_const_exprs/subexprs_are_const_evalutable.rs
new file mode 100644
index 000000000..d6574a3aa
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/ty-alias-substitution.rs b/tests/ui/const-generics/generic_const_exprs/ty-alias-substitution.rs
new file mode 100644
index 000000000..d058b3638
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.rs b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.rs
new file mode 100644
index 000000000..c0404d35b
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr
new file mode 100644
index 000000000..d18c7916f
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/unop.rs b/tests/ui/const-generics/generic_const_exprs/unop.rs
new file mode 100644
index 000000000..c12fef083
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/unused-complex-default-expr.rs b/tests/ui/const-generics/generic_const_exprs/unused-complex-default-expr.rs
new file mode 100644
index 000000000..9580f8a7f
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/unused_expr.rs b/tests/ui/const-generics/generic_const_exprs/unused_expr.rs
new file mode 100644
index 000000000..c1bf19e0f
--- /dev/null
+++ b/tests/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/tests/ui/const-generics/generic_const_exprs/unused_expr.stderr b/tests/ui/const-generics/generic_const_exprs/unused_expr.stderr
new file mode 100644
index 000000000..265a3b9d2
--- /dev/null
+++ b/tests/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 constants
+ |
+ = 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 constants
+ |
+ = 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 constants
+ |
+ = 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
+