diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index d383cb9d91dd4..22f6f07a0ac02 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -1094,6 +1094,23 @@ impl<'a, 'tcx> TypeVisitor> for WfPredicates<'a, 'tcx> { }, )); } + ty::Array(elem_ty, _len) => { + let elem_vals = val.to_branch(); + let cause = self.cause(ObligationCauseCode::WellFormed(None)); + + self.out.extend(elem_vals.iter().map(|&elem_val| { + let predicate = ty::PredicateKind::Clause( + ty::ClauseKind::ConstArgHasType(elem_val, *elem_ty), + ); + traits::Obligation::with_depth( + tcx, + cause.clone(), + self.recursion_depth, + self.param_env, + predicate, + ) + })); + } _ => {} } } diff --git a/tests/ui/const-generics/mgca/array-const-arg-type-mismatch.rs b/tests/ui/const-generics/mgca/array-const-arg-type-mismatch.rs new file mode 100644 index 0000000000000..614532d3ec68e --- /dev/null +++ b/tests/ui/const-generics/mgca/array-const-arg-type-mismatch.rs @@ -0,0 +1,15 @@ +#![expect(incomplete_features)] +#![feature(adt_const_params, min_generic_const_args)] +use std::marker::ConstParamTy; + +#[derive(Eq, PartialEq, ConstParamTy)] +struct Foo; + +struct Bar; + +fn test() {} + +fn main() { + test::<{ [Bar] }>(); + //~^ ERROR constant `Bar` is not of type `Foo` +} diff --git a/tests/ui/const-generics/mgca/array-const-arg-type-mismatch.stderr b/tests/ui/const-generics/mgca/array-const-arg-type-mismatch.stderr new file mode 100644 index 0000000000000..573620366cbce --- /dev/null +++ b/tests/ui/const-generics/mgca/array-const-arg-type-mismatch.stderr @@ -0,0 +1,8 @@ +error: the constant `Bar` is not of type `Foo` + --> $DIR/array-const-arg-type-mismatch.rs:13:14 + | +LL | test::<{ [Bar] }>(); + | ^^^^^ expected `Foo`, found `Bar` + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/mgca/array-with-wrong-tuple-type.rs b/tests/ui/const-generics/mgca/array-with-wrong-tuple-type.rs new file mode 100644 index 0000000000000..d96a626b74226 --- /dev/null +++ b/tests/ui/const-generics/mgca/array-with-wrong-tuple-type.rs @@ -0,0 +1,18 @@ +#![feature(adt_const_params, min_generic_const_args, unsized_const_params)] +#![allow(incomplete_features)] + +use std::marker::ConstParamTy; + +#[derive(Eq, PartialEq, ConstParamTy)] +struct A; + +fn takes_tuple() {} +fn takes_nested_tuple() {} + + +fn main() { + takes_tuple::<{ [A] }>(); + //~^ ERROR the constant `A` is not of type `(u32, u32)` + takes_nested_tuple::<{ [A] }>(); + //~^ ERROR the constant `A` is not of type `(u32, (u32, u32))` +} diff --git a/tests/ui/const-generics/mgca/array-with-wrong-tuple-type.stderr b/tests/ui/const-generics/mgca/array-with-wrong-tuple-type.stderr new file mode 100644 index 0000000000000..d7b1fe096cb42 --- /dev/null +++ b/tests/ui/const-generics/mgca/array-with-wrong-tuple-type.stderr @@ -0,0 +1,14 @@ +error: the constant `A` is not of type `(u32, u32)` + --> $DIR/array-with-wrong-tuple-type.rs:14:21 + | +LL | takes_tuple::<{ [A] }>(); + | ^^^ expected `(u32, u32)`, found `A` + +error: the constant `A` is not of type `(u32, (u32, u32))` + --> $DIR/array-with-wrong-tuple-type.rs:16:28 + | +LL | takes_nested_tuple::<{ [A] }>(); + | ^^^ expected `(u32, (u32, u32))`, found `A` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/const-generics/mgca/array_expr_arg_complex.rs b/tests/ui/const-generics/mgca/array_expr_arg_complex.rs new file mode 100644 index 0000000000000..6d57e4f4b9686 --- /dev/null +++ b/tests/ui/const-generics/mgca/array_expr_arg_complex.rs @@ -0,0 +1,16 @@ +#![feature(min_generic_const_args, adt_const_params, unsized_const_params)] +#![expect(incomplete_features)] + +trait Trait { + type const ASSOC: usize; +} + +fn takes_array() {} +fn takes_tuple_with_array() {} + +fn generic_caller() { + takes_array::<{ [N, N + 1] }>(); //~ ERROR complex const arguments must be placed inside of a `const` block + takes_tuple_with_array::<{ ([N, N + 1], N) }>(); //~ ERROR complex const arguments must be placed inside of a `const` block +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/array_expr_arg_complex.stderr b/tests/ui/const-generics/mgca/array_expr_arg_complex.stderr new file mode 100644 index 0000000000000..f40d4b5035d86 --- /dev/null +++ b/tests/ui/const-generics/mgca/array_expr_arg_complex.stderr @@ -0,0 +1,14 @@ +error: complex const arguments must be placed inside of a `const` block + --> $DIR/array_expr_arg_complex.rs:12:25 + | +LL | takes_array::<{ [N, N + 1] }>(); + | ^^^^^ + +error: complex const arguments must be placed inside of a `const` block + --> $DIR/array_expr_arg_complex.rs:13:37 + | +LL | takes_tuple_with_array::<{ ([N, N + 1], N) }>(); + | ^^^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/const-generics/mgca/invalid-array-in-tuple.rs b/tests/ui/const-generics/mgca/invalid-array-in-tuple.rs new file mode 100644 index 0000000000000..8c84e12e654bc --- /dev/null +++ b/tests/ui/const-generics/mgca/invalid-array-in-tuple.rs @@ -0,0 +1,16 @@ +#![feature(adt_const_params, min_generic_const_args, unsized_const_params)] +#![allow(incomplete_features)] + +use std::marker::ConstParamTy; + +#[derive(Eq, PartialEq, ConstParamTy)] +struct Foo; + +struct Bar; + +fn takes_tuple_with_array() {} + +fn main() { + takes_tuple_with_array::<{ ([Bar], 1) }>(); + //~^ ERROR the constant `Bar` is not of type `Foo` +} diff --git a/tests/ui/const-generics/mgca/invalid-array-in-tuple.stderr b/tests/ui/const-generics/mgca/invalid-array-in-tuple.stderr new file mode 100644 index 0000000000000..1cd46883dcf79 --- /dev/null +++ b/tests/ui/const-generics/mgca/invalid-array-in-tuple.stderr @@ -0,0 +1,8 @@ +error: the constant `Bar` is not of type `Foo` + --> $DIR/invalid-array-in-tuple.rs:14:32 + | +LL | takes_tuple_with_array::<{ ([Bar], 1) }>(); + | ^^^^^^^^^^ expected `Foo`, found `Bar` + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/mgca/tuple_expr_arg_complex.rs b/tests/ui/const-generics/mgca/tuple_expr_arg_complex.rs index 5a40c1b14c2d6..d7cab17bad124 100644 --- a/tests/ui/const-generics/mgca/tuple_expr_arg_complex.rs +++ b/tests/ui/const-generics/mgca/tuple_expr_arg_complex.rs @@ -2,7 +2,6 @@ #![expect(incomplete_features)] trait Trait { - type const ASSOC: usize; } diff --git a/tests/ui/const-generics/mgca/tuple_expr_arg_complex.stderr b/tests/ui/const-generics/mgca/tuple_expr_arg_complex.stderr index b4853d3c2e38c..95a98d857b1d4 100644 --- a/tests/ui/const-generics/mgca/tuple_expr_arg_complex.stderr +++ b/tests/ui/const-generics/mgca/tuple_expr_arg_complex.stderr @@ -1,23 +1,23 @@ error: complex const arguments must be placed inside of a `const` block - --> $DIR/tuple_expr_arg_complex.rs:13:25 + --> $DIR/tuple_expr_arg_complex.rs:12:25 | LL | takes_tuple::<{ (N, N + 1) }>(); | ^^^^^ error: complex const arguments must be placed inside of a `const` block - --> $DIR/tuple_expr_arg_complex.rs:14:25 + --> $DIR/tuple_expr_arg_complex.rs:13:25 | LL | takes_tuple::<{ (N, T::ASSOC + 1) }>(); | ^^^^^^^^^^^^ error: complex const arguments must be placed inside of a `const` block - --> $DIR/tuple_expr_arg_complex.rs:16:36 + --> $DIR/tuple_expr_arg_complex.rs:15:36 | LL | takes_nested_tuple::<{ (N, (N, N + 1)) }>(); | ^^^^^ error: generic parameters may not be used in const operations - --> $DIR/tuple_expr_arg_complex.rs:17:44 + --> $DIR/tuple_expr_arg_complex.rs:16:44 | LL | takes_nested_tuple::<{ (N, (N, const { N + 1 })) }>(); | ^