Skip to content

Commit 3e4d4ad

Browse files
authored
Unrolled build for #152492
Rollup merge of #152492 - biscuitrescue:fix-array-valtree-wf, r=BoxyUwU mGCA: Enforce WF element types for array valtrees Fixes #152125 Extends WellFormedness checking for const generics to validate that array element types in ValTrees match the declared element type. ### Problem Before commit, this would have incorrectly compiled ``` rust #![feature(adt_const_params, min_generic_const_args)] use std::marker::ConstParamTy; #[derive(Eq, PartialEq, ConstParamTy)] struct Foo; struct Bar; fn foo<const N: [Foo; 1]>() {} fn main() { foo::<{ [Bar] }>(); } ``` ### Solution Added a `ty::Array` arm to checking WellFormedness (similar to the existing `ty::Tuple` arm from #150713) which creates `ConstArgHasType` obligations for each array element, ensuring they match the array's declared element type. I attempted to combine the `Tuple` and `Array` arms into a single arm, but this proved difficult due to pattern matching limitations, and the separate arm is more readable anyway. ### Tests Added UI test which verifies that the type mismatch is now properly caught, and also returns an appropriate test message r? @BoxyUwU
2 parents 0028f34 + 7030be6 commit 3e4d4ad

11 files changed

Lines changed: 130 additions & 5 deletions

compiler/rustc_trait_selection/src/traits/wf.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1122,6 +1122,23 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
11221122
},
11231123
));
11241124
}
1125+
ty::Array(elem_ty, _len) => {
1126+
let elem_vals = val.to_branch();
1127+
let cause = self.cause(ObligationCauseCode::WellFormed(None));
1128+
1129+
self.out.extend(elem_vals.iter().map(|&elem_val| {
1130+
let predicate = ty::PredicateKind::Clause(
1131+
ty::ClauseKind::ConstArgHasType(elem_val, *elem_ty),
1132+
);
1133+
traits::Obligation::with_depth(
1134+
tcx,
1135+
cause.clone(),
1136+
self.recursion_depth,
1137+
self.param_env,
1138+
predicate,
1139+
)
1140+
}));
1141+
}
11251142
_ => {}
11261143
}
11271144
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#![expect(incomplete_features)]
2+
#![feature(adt_const_params, min_generic_const_args)]
3+
use std::marker::ConstParamTy;
4+
5+
#[derive(Eq, PartialEq, ConstParamTy)]
6+
struct Foo;
7+
8+
struct Bar;
9+
10+
fn test<const N: [Foo; 1]>() {}
11+
12+
fn main() {
13+
test::<{ [Bar] }>();
14+
//~^ ERROR constant `Bar` is not of type `Foo`
15+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: the constant `Bar` is not of type `Foo`
2+
--> $DIR/array-const-arg-type-mismatch.rs:13:14
3+
|
4+
LL | test::<{ [Bar] }>();
5+
| ^^^^^ expected `Foo`, found `Bar`
6+
7+
error: aborting due to 1 previous error
8+
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#![feature(adt_const_params, min_generic_const_args, unsized_const_params)]
2+
#![allow(incomplete_features)]
3+
4+
use std::marker::ConstParamTy;
5+
6+
#[derive(Eq, PartialEq, ConstParamTy)]
7+
struct A;
8+
9+
fn takes_tuple<const N: [(u32, u32); 1]>() {}
10+
fn takes_nested_tuple<const N: [(u32, (u32, u32)); 1]>() {}
11+
12+
13+
fn main() {
14+
takes_tuple::<{ [A] }>();
15+
//~^ ERROR the constant `A` is not of type `(u32, u32)`
16+
takes_nested_tuple::<{ [A] }>();
17+
//~^ ERROR the constant `A` is not of type `(u32, (u32, u32))`
18+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: the constant `A` is not of type `(u32, u32)`
2+
--> $DIR/array-with-wrong-tuple-type.rs:14:21
3+
|
4+
LL | takes_tuple::<{ [A] }>();
5+
| ^^^ expected `(u32, u32)`, found `A`
6+
7+
error: the constant `A` is not of type `(u32, (u32, u32))`
8+
--> $DIR/array-with-wrong-tuple-type.rs:16:28
9+
|
10+
LL | takes_nested_tuple::<{ [A] }>();
11+
| ^^^ expected `(u32, (u32, u32))`, found `A`
12+
13+
error: aborting due to 2 previous errors
14+
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#![feature(min_generic_const_args, adt_const_params, unsized_const_params)]
2+
#![expect(incomplete_features)]
3+
4+
trait Trait {
5+
type const ASSOC: usize;
6+
}
7+
8+
fn takes_array<const A: [u32; 2]>() {}
9+
fn takes_tuple_with_array<const A: ([u32; 2], u32)>() {}
10+
11+
fn generic_caller<T: Trait, const N: u32, const N2: u32>() {
12+
takes_array::<{ [N, N + 1] }>(); //~ ERROR complex const arguments must be placed inside of a `const` block
13+
takes_tuple_with_array::<{ ([N, N + 1], N) }>(); //~ ERROR complex const arguments must be placed inside of a `const` block
14+
}
15+
16+
fn main() {}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: complex const arguments must be placed inside of a `const` block
2+
--> $DIR/array_expr_arg_complex.rs:12:25
3+
|
4+
LL | takes_array::<{ [N, N + 1] }>();
5+
| ^^^^^
6+
7+
error: complex const arguments must be placed inside of a `const` block
8+
--> $DIR/array_expr_arg_complex.rs:13:37
9+
|
10+
LL | takes_tuple_with_array::<{ ([N, N + 1], N) }>();
11+
| ^^^^^
12+
13+
error: aborting due to 2 previous errors
14+
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#![feature(adt_const_params, min_generic_const_args, unsized_const_params)]
2+
#![allow(incomplete_features)]
3+
4+
use std::marker::ConstParamTy;
5+
6+
#[derive(Eq, PartialEq, ConstParamTy)]
7+
struct Foo;
8+
9+
struct Bar;
10+
11+
fn takes_tuple_with_array<const A: ([Foo; 1], u32)>() {}
12+
13+
fn main() {
14+
takes_tuple_with_array::<{ ([Bar], 1) }>();
15+
//~^ ERROR the constant `Bar` is not of type `Foo`
16+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: the constant `Bar` is not of type `Foo`
2+
--> $DIR/invalid-array-in-tuple.rs:14:32
3+
|
4+
LL | takes_tuple_with_array::<{ ([Bar], 1) }>();
5+
| ^^^^^^^^^^ expected `Foo`, found `Bar`
6+
7+
error: aborting due to 1 previous error
8+

tests/ui/const-generics/mgca/tuple_expr_arg_complex.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
#![expect(incomplete_features)]
33

44
trait Trait {
5-
65
type const ASSOC: usize;
76
}
87

0 commit comments

Comments
 (0)