diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2022-12-22 19:36:13 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-12-22 19:36:13 +0100 |
| commit | 548d49c7897e91ff6f703c00b3a2ff269b894fdc (patch) | |
| tree | ede72316e486c7f220b87e692b4330b7a4a83f01 | |
| parent | 17b3b97e08e3266e8e2ce0e0c0b2e6f19267f610 (diff) | |
| parent | c1181e12243f078b1cc562249569e6766d90f8f6 (diff) | |
| download | rust-548d49c7897e91ff6f703c00b3a2ff269b894fdc.tar.gz rust-548d49c7897e91ff6f703c00b3a2ff269b894fdc.zip | |
Rollup merge of #105847 - compiler-errors:issue-104396, r=oli-obk
Ensure param-env is const before calling `eval_to_valtree`
Other queries call `ParamEnv::with_const` *inside* of the query itself (e.g. `const_eval_global_id_for_typeck`), so this could alternatively be moved into the provider of `eval_to_valtree` instead. I don't have a particularly strong opinion, though *theoretically* caching is better if we make the query keys more constrained.
I'm not exactly sure how this is an effect of the `-Zmir-opt-level=3` flag. Maybe something about the inliner causes us to inline an unevaluated const into a body where it can be evaluated, but where it has not yet been normalized.
This seems likely, since we're inlining `from_fn_1::<{ N / 2 }, _>` in `from_fn_2`, which means that we will need to evaluate that constant during the const prop pass after inlining.
Fixes #104396
| -rw-r--r-- | compiler/rustc_const_eval/src/interpret/operand.rs | 6 | ||||
| -rw-r--r-- | src/test/ui/consts/issue-104396.rs | 36 | ||||
| -rw-r--r-- | src/test/ui/consts/issue-104396.stderr | 11 |
3 files changed, 51 insertions, 2 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 4dc4066e031..fcc6f8ea852 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -577,8 +577,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ty::ConstKind::Unevaluated(uv) => { let instance = self.resolve(uv.def, uv.substs)?; let cid = GlobalId { instance, promoted: None }; - self.ctfe_query(span, |tcx| tcx.eval_to_valtree(self.param_env.and(cid)))? - .unwrap_or_else(|| bug!("unable to create ValTree for {uv:?}")) + self.ctfe_query(span, |tcx| { + tcx.eval_to_valtree(self.param_env.with_const().and(cid)) + })? + .unwrap_or_else(|| bug!("unable to create ValTree for {uv:?}")) } ty::ConstKind::Bound(..) | ty::ConstKind::Infer(..) => { span_bug!(self.cur_span(), "unexpected ConstKind in ctfe: {val:?}") diff --git a/src/test/ui/consts/issue-104396.rs b/src/test/ui/consts/issue-104396.rs new file mode 100644 index 00000000000..315b0cf0fd6 --- /dev/null +++ b/src/test/ui/consts/issue-104396.rs @@ -0,0 +1,36 @@ +// compile-flags: -Zmir-opt-level=3 +// check-pass + +#![feature(generic_const_exprs)] +//~^ WARN the feature `generic_const_exprs` is incomplete + +#[inline(always)] +fn from_fn_1<const N: usize, F: FnMut(usize) -> f32>(mut f: F) -> [f32; N] { + let mut result = [0.0; N]; + let mut i = 0; + while i < N { + result[i] = f(i); + i += 1; + } + result +} + +pub struct TestArray<const N: usize> +where + [(); N / 2]:, +{ + array: [f32; N / 2], +} + +impl<const N: usize> TestArray<N> +where + [(); N / 2]:, +{ + fn from_fn_2<F: FnMut(usize) -> f32>(f: F) -> Self { + Self { array: from_fn_1(f) } + } +} + +fn main() { + TestArray::<4>::from_fn_2(|i| 0.0); +} diff --git a/src/test/ui/consts/issue-104396.stderr b/src/test/ui/consts/issue-104396.stderr new file mode 100644 index 00000000000..5856bee09a3 --- /dev/null +++ b/src/test/ui/consts/issue-104396.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/issue-104396.rs:4: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 + |
