Skip to content

Commit 8215170

Browse files
authored
Rollup merge of rust-lang#111100 - BoxyUwU:array_repeat_expr_wf, r=compiler-errors
check array type of repeat exprs is wf Fixes rust-lang#111091 Also makes sure that we actually renumber regions in the length of repeat exprs which we previously weren't doing and would cause ICEs in `adt_const_params` + `generic_const_exprs` from attempting to prove the wf goals when the length was an unevaluated constant with `'erased` in the `ty` field of `Const` The duplicate errors are caused by the fact that `const_arg_to_const`/`array_len_to_const` in `FnCtxt` adds a `WellFormed` goal for the created `Const` which is also checked by the added `WellFormed(array_ty)`. I don't want to change this to just emit a `T: Sized` goal for the element type since that would ignore `ConstArgHasType` wf requirements and generally uncomfortable with the idea of trying to sync up `wf::obligations` for arrays and the code in hir typeck for repeat exprs. r? ``@compiler-errors``
2 parents ae78f17 + eb23f47 commit 8215170

File tree

10 files changed

+96
-6
lines changed

10 files changed

+96
-6
lines changed

compiler/rustc_borrowck/src/renumber.rs

+8
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,14 @@ impl<'a, 'tcx> MutVisitor<'tcx> for RegionRenumberer<'a, 'tcx> {
108108
debug!(?region);
109109
}
110110

111+
#[instrument(skip(self), level = "debug")]
112+
fn visit_ty_const(&mut self, ct: &mut ty::Const<'tcx>, location: Location) {
113+
let old_ct = *ct;
114+
*ct = self.renumber_regions(old_ct, || RegionCtxt::Location(location));
115+
116+
debug!(?ct);
117+
}
118+
111119
#[instrument(skip(self), level = "debug")]
112120
fn visit_constant(&mut self, constant: &mut Constant<'tcx>, location: Location) {
113121
let literal = constant.literal;

compiler/rustc_borrowck/src/type_check/mod.rs

+7
Original file line numberDiff line numberDiff line change
@@ -1798,6 +1798,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
17981798
Rvalue::Repeat(operand, len) => {
17991799
self.check_operand(operand, location);
18001800

1801+
let array_ty = rvalue.ty(body.local_decls(), tcx);
1802+
self.prove_predicate(
1803+
ty::PredicateKind::WellFormed(array_ty.into()),
1804+
Locations::Single(location),
1805+
ConstraintCategory::Boring,
1806+
);
1807+
18011808
// If the length cannot be evaluated we must assume that the length can be larger
18021809
// than 1.
18031810
// If the length is larger than 1, the repeat expression will need to copy the

compiler/rustc_hir_typeck/src/expr.rs

+6
Original file line numberDiff line numberDiff line change
@@ -1426,6 +1426,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14261426

14271427
self.check_repeat_element_needs_copy_bound(element, count, element_ty);
14281428

1429+
self.register_wf_obligation(
1430+
tcx.mk_array_with_const_len(t, count).into(),
1431+
expr.span,
1432+
traits::WellFormed(None),
1433+
);
1434+
14291435
tcx.mk_array_with_const_len(t, count)
14301436
}
14311437

compiler/rustc_middle/src/mir/visit.rs

+21-2
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,15 @@ macro_rules! make_mir_visitor {
192192
self.super_constant(constant, location);
193193
}
194194

195+
#[allow(rustc::pass_by_value)]
196+
fn visit_ty_const(
197+
&mut self,
198+
ct: & $($mutability)? ty::Const<'tcx>,
199+
location: Location,
200+
) {
201+
self.super_ty_const(ct, location);
202+
}
203+
195204
fn visit_span(
196205
&mut self,
197206
span: $(& $mutability)? Span,
@@ -625,8 +634,9 @@ macro_rules! make_mir_visitor {
625634
self.visit_operand(operand, location);
626635
}
627636

628-
Rvalue::Repeat(value, _) => {
637+
Rvalue::Repeat(value, ct) => {
629638
self.visit_operand(value, location);
639+
self.visit_ty_const(ct, location);
630640
}
631641

632642
Rvalue::ThreadLocalRef(_) => {}
@@ -878,12 +888,21 @@ macro_rules! make_mir_visitor {
878888
self.visit_span($(& $mutability)? *span);
879889
drop(user_ty); // no visit method for this
880890
match literal {
881-
ConstantKind::Ty(_) => {}
891+
ConstantKind::Ty(ct) => self.visit_ty_const(ct, location),
882892
ConstantKind::Val(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)),
883893
ConstantKind::Unevaluated(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)),
884894
}
885895
}
886896

897+
#[allow(rustc::pass_by_value)]
898+
fn super_ty_const(
899+
&mut self,
900+
_ct: & $($mutability)? ty::Const<'tcx>,
901+
_location: Location,
902+
) {
903+
904+
}
905+
887906
fn super_span(&mut self, _span: $(& $mutability)? Span) {
888907
}
889908

tests/ui/const-generics/sneaky-array-repeat-expr.rs

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ impl<const N: usize> Trait<N> for () {
1010
pub const fn foo<const N: usize>() where (): Trait<N> {
1111
let bar = [(); <()>::Assoc];
1212
//~^ error: constant expression depends on a generic parameter
13+
//~| error: constant expression depends on a generic parameter
1314
}
1415

1516
trait Trait2<const N: usize> {
@@ -24,6 +25,7 @@ impl<const N: usize> Trait2<N> for () {
2425
pub const fn foo2<const N: usize>() where (): Trait2<N> {
2526
let bar2 = [(); <()>::Assoc2];
2627
//~^ error: constant expression depends on a generic parameter
28+
//~| error: constant expression depends on a generic parameter
2729
}
2830

2931
fn main() {

tests/ui/const-generics/sneaky-array-repeat-expr.stderr

+18-2
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,28 @@ LL | let bar = [(); <()>::Assoc];
77
= note: this may fail depending on what value the parameter takes
88

99
error: constant expression depends on a generic parameter
10-
--> $DIR/sneaky-array-repeat-expr.rs:25:21
10+
--> $DIR/sneaky-array-repeat-expr.rs:11:15
11+
|
12+
LL | let bar = [(); <()>::Assoc];
13+
| ^^^^^^^^^^^^^^^^^
14+
|
15+
= note: this may fail depending on what value the parameter takes
16+
17+
error: constant expression depends on a generic parameter
18+
--> $DIR/sneaky-array-repeat-expr.rs:26:21
1119
|
1220
LL | let bar2 = [(); <()>::Assoc2];
1321
| ^^^^^^^^^^^^
1422
|
1523
= note: this may fail depending on what value the parameter takes
1624

17-
error: aborting due to 2 previous errors
25+
error: constant expression depends on a generic parameter
26+
--> $DIR/sneaky-array-repeat-expr.rs:26:16
27+
|
28+
LL | let bar2 = [(); <()>::Assoc2];
29+
| ^^^^^^^^^^^^^^^^^^
30+
|
31+
= note: this may fail depending on what value the parameter takes
32+
33+
error: aborting due to 4 previous errors
1834

tests/ui/consts/issue-50439.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ impl<T: Sized> PinDropInternal for Bears<T> {
2222
where
2323
Self: ReflectDrop,
2424
{
25-
let _ = [(); 0 - !!(<Bears<T> as ReflectDrop>::REFLECT_DROP) as usize]; //~ ERROR constant expression depends on a generic parameter
25+
let _ = [(); 0 - !!(<Bears<T> as ReflectDrop>::REFLECT_DROP) as usize];
26+
//~^ ERROR constant expression depends on a generic parameter
27+
//~| ERROR constant expression depends on a generic parameter
2628
}
2729
}
2830

tests/ui/consts/issue-50439.stderr

+9-1
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,13 @@ LL | let _ = [(); 0 - !!(<Bears<T> as ReflectDrop>::REFLECT_DROP) as usi
66
|
77
= note: this may fail depending on what value the parameter takes
88

9-
error: aborting due to previous error
9+
error: constant expression depends on a generic parameter
10+
--> $DIR/issue-50439.rs:25:17
11+
|
12+
LL | let _ = [(); 0 - !!(<Bears<T> as ReflectDrop>::REFLECT_DROP) as usize];
13+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
14+
|
15+
= note: this may fail depending on what value the parameter takes
16+
17+
error: aborting due to 2 previous errors
1018

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
trait Foo {
2+
const ASSOC: [u8];
3+
}
4+
5+
fn bar<T: Foo>() {
6+
let a = [T::ASSOC; 2];
7+
//~^ ERROR: the size for values of type `[u8]` cannot be known at compilation time
8+
}
9+
10+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
2+
--> $DIR/repeat-expr-checks-wf.rs:6:13
3+
|
4+
LL | let a = [T::ASSOC; 2];
5+
| ^^^^^^^^^^^^^ doesn't have a size known at compile-time
6+
|
7+
= help: the trait `Sized` is not implemented for `[u8]`
8+
= note: slice and array elements must have `Sized` type
9+
10+
error: aborting due to previous error
11+
12+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)