diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2023-05-04 19:18:21 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-05-04 19:18:21 +0200 |
| commit | c0ca84b006d86cfb76c9bc6c5e2c3805de073f5f (patch) | |
| tree | cd25aedff57518a7334034d32795c5f7137a9b81 | |
| parent | ea0b6504faa95dd4bfb0666cbcb5dfcfe0591313 (diff) | |
| parent | 7d9130f3b948400780fd8386e73d201df88d9ea9 (diff) | |
| download | rust-c0ca84b006d86cfb76c9bc6c5e2c3805de073f5f.tar.gz rust-c0ca84b006d86cfb76c9bc6c5e2c3805de073f5f.zip | |
Rollup merge of #111100 - BoxyUwU:array_repeat_expr_wf, r=compiler-errors
check array type of repeat exprs is wf Fixes #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`
| -rw-r--r-- | compiler/rustc_borrowck/src/renumber.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_borrowck/src/type_check/mod.rs | 7 | ||||
| -rw-r--r-- | compiler/rustc_hir_typeck/src/expr.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/visit.rs | 21 | ||||
| -rw-r--r-- | tests/ui/const-generics/sneaky-array-repeat-expr.rs | 2 | ||||
| -rw-r--r-- | tests/ui/const-generics/sneaky-array-repeat-expr.stderr | 20 | ||||
| -rw-r--r-- | tests/ui/consts/issue-50439.rs | 4 | ||||
| -rw-r--r-- | tests/ui/consts/issue-50439.stderr | 10 | ||||
| -rw-r--r-- | tests/ui/typeck/repeat-expr-checks-wf.rs | 10 | ||||
| -rw-r--r-- | tests/ui/typeck/repeat-expr-checks-wf.stderr | 12 |
10 files changed, 94 insertions, 6 deletions
diff --git a/compiler/rustc_borrowck/src/renumber.rs b/compiler/rustc_borrowck/src/renumber.rs index 22de7549e94..4389d2b60bc 100644 --- a/compiler/rustc_borrowck/src/renumber.rs +++ b/compiler/rustc_borrowck/src/renumber.rs @@ -109,6 +109,14 @@ impl<'a, 'tcx> MutVisitor<'tcx> for RegionRenumberer<'a, 'tcx> { } #[instrument(skip(self), level = "debug")] + fn visit_ty_const(&mut self, ct: &mut ty::Const<'tcx>, location: Location) { + let old_ct = *ct; + *ct = self.renumber_regions(old_ct, || RegionCtxt::Location(location)); + + debug!(?ct); + } + + #[instrument(skip(self), level = "debug")] fn visit_constant(&mut self, constant: &mut Constant<'tcx>, location: Location) { let literal = constant.literal; constant.literal = self.renumber_regions(literal, || RegionCtxt::Location(location)); diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 43107db2923..dcabeb792be 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1801,6 +1801,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { Rvalue::Repeat(operand, len) => { self.check_operand(operand, location); + let array_ty = rvalue.ty(body.local_decls(), tcx); + self.prove_predicate( + ty::PredicateKind::WellFormed(array_ty.into()), + Locations::Single(location), + ConstraintCategory::Boring, + ); + // If the length cannot be evaluated we must assume that the length can be larger // than 1. // If the length is larger than 1, the repeat expression will need to copy the diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 047d8a82bfc..bba049c3819 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1426,6 +1426,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.check_repeat_element_needs_copy_bound(element, count, element_ty); + self.register_wf_obligation( + tcx.mk_array_with_const_len(t, count).into(), + expr.span, + traits::WellFormed(None), + ); + tcx.mk_array_with_const_len(t, count) } diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 8e8ca7874f5..6718605ed0b 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -192,6 +192,14 @@ macro_rules! make_mir_visitor { self.super_constant(constant, location); } + fn visit_ty_const( + &mut self, + ct: $( & $mutability)? ty::Const<'tcx>, + location: Location, + ) { + self.super_ty_const(ct, location); + } + fn visit_span( &mut self, span: $(& $mutability)? Span, @@ -625,8 +633,9 @@ macro_rules! make_mir_visitor { self.visit_operand(operand, location); } - Rvalue::Repeat(value, _) => { + Rvalue::Repeat(value, ct) => { self.visit_operand(value, location); + self.visit_ty_const($(&$mutability)? *ct, location); } Rvalue::ThreadLocalRef(_) => {} @@ -878,12 +887,20 @@ macro_rules! make_mir_visitor { self.visit_span($(& $mutability)? *span); drop(user_ty); // no visit method for this match literal { - ConstantKind::Ty(_) => {} + ConstantKind::Ty(ct) => self.visit_ty_const($(&$mutability)? *ct, location), ConstantKind::Val(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)), ConstantKind::Unevaluated(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)), } } + fn super_ty_const( + &mut self, + _ct: $(& $mutability)? ty::Const<'tcx>, + _location: Location, + ) { + + } + fn super_span(&mut self, _span: $(& $mutability)? Span) { } diff --git a/tests/ui/const-generics/sneaky-array-repeat-expr.rs b/tests/ui/const-generics/sneaky-array-repeat-expr.rs index b147c246bda..cd1607608a6 100644 --- a/tests/ui/const-generics/sneaky-array-repeat-expr.rs +++ b/tests/ui/const-generics/sneaky-array-repeat-expr.rs @@ -10,6 +10,7 @@ impl<const N: usize> Trait<N> for () { pub const fn foo<const N: usize>() where (): Trait<N> { let bar = [(); <()>::Assoc]; //~^ error: constant expression depends on a generic parameter + //~| error: constant expression depends on a generic parameter } trait Trait2<const N: usize> { @@ -24,6 +25,7 @@ impl<const N: usize> Trait2<N> for () { pub const fn foo2<const N: usize>() where (): Trait2<N> { let bar2 = [(); <()>::Assoc2]; //~^ error: constant expression depends on a generic parameter + //~| error: constant expression depends on a generic parameter } fn main() { diff --git a/tests/ui/const-generics/sneaky-array-repeat-expr.stderr b/tests/ui/const-generics/sneaky-array-repeat-expr.stderr index 5c77375d399..e532f27a10d 100644 --- a/tests/ui/const-generics/sneaky-array-repeat-expr.stderr +++ b/tests/ui/const-generics/sneaky-array-repeat-expr.stderr @@ -7,12 +7,28 @@ LL | let bar = [(); <()>::Assoc]; = note: this may fail depending on what value the parameter takes error: constant expression depends on a generic parameter - --> $DIR/sneaky-array-repeat-expr.rs:25:21 + --> $DIR/sneaky-array-repeat-expr.rs:11:15 + | +LL | let bar = [(); <()>::Assoc]; + | ^^^^^^^^^^^^^^^^^ + | + = note: this may fail depending on what value the parameter takes + +error: constant expression depends on a generic parameter + --> $DIR/sneaky-array-repeat-expr.rs:26:21 | LL | let bar2 = [(); <()>::Assoc2]; | ^^^^^^^^^^^^ | = note: this may fail depending on what value the parameter takes -error: aborting due to 2 previous errors +error: constant expression depends on a generic parameter + --> $DIR/sneaky-array-repeat-expr.rs:26:16 + | +LL | let bar2 = [(); <()>::Assoc2]; + | ^^^^^^^^^^^^^^^^^^ + | + = note: this may fail depending on what value the parameter takes + +error: aborting due to 4 previous errors diff --git a/tests/ui/consts/issue-50439.rs b/tests/ui/consts/issue-50439.rs index 0be7c405473..d42347e136e 100644 --- a/tests/ui/consts/issue-50439.rs +++ b/tests/ui/consts/issue-50439.rs @@ -22,7 +22,9 @@ impl<T: Sized> PinDropInternal for Bears<T> { where Self: ReflectDrop, { - let _ = [(); 0 - !!(<Bears<T> as ReflectDrop>::REFLECT_DROP) as usize]; //~ ERROR constant expression depends on a generic parameter + let _ = [(); 0 - !!(<Bears<T> as ReflectDrop>::REFLECT_DROP) as usize]; + //~^ ERROR constant expression depends on a generic parameter + //~| ERROR constant expression depends on a generic parameter } } diff --git a/tests/ui/consts/issue-50439.stderr b/tests/ui/consts/issue-50439.stderr index 3fbdf33b2d8..7a8cd45ecc7 100644 --- a/tests/ui/consts/issue-50439.stderr +++ b/tests/ui/consts/issue-50439.stderr @@ -6,5 +6,13 @@ LL | let _ = [(); 0 - !!(<Bears<T> as ReflectDrop>::REFLECT_DROP) as usi | = note: this may fail depending on what value the parameter takes -error: aborting due to previous error +error: constant expression depends on a generic parameter + --> $DIR/issue-50439.rs:25:17 + | +LL | let _ = [(); 0 - !!(<Bears<T> as ReflectDrop>::REFLECT_DROP) as usize]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this may fail depending on what value the parameter takes + +error: aborting due to 2 previous errors diff --git a/tests/ui/typeck/repeat-expr-checks-wf.rs b/tests/ui/typeck/repeat-expr-checks-wf.rs new file mode 100644 index 00000000000..b8a2a0ceb58 --- /dev/null +++ b/tests/ui/typeck/repeat-expr-checks-wf.rs @@ -0,0 +1,10 @@ +trait Foo { + const ASSOC: [u8]; +} + +fn bar<T: Foo>() { + let a = [T::ASSOC; 2]; + //~^ ERROR: the size for values of type `[u8]` cannot be known at compilation time +} + +fn main() {} diff --git a/tests/ui/typeck/repeat-expr-checks-wf.stderr b/tests/ui/typeck/repeat-expr-checks-wf.stderr new file mode 100644 index 00000000000..a821088a4b3 --- /dev/null +++ b/tests/ui/typeck/repeat-expr-checks-wf.stderr @@ -0,0 +1,12 @@ +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/repeat-expr-checks-wf.rs:6:13 + | +LL | let a = [T::ASSOC; 2]; + | ^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` + = note: slice and array elements must have `Sized` type + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. |
