From f394bb57bb800be024e95e624d96bc698e04dde3 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 25 Oct 2021 16:49:39 +0000 Subject: [PATCH] Always use const param envs for const eval. Nothing else makes sense, and there is no "danger" in doing so, as it only does something if there are const bounds, which are unstable. This used to happen implicitly via the inferctxt before, which was much more fragile. --- compiler/rustc_const_eval/src/const_eval/eval_queries.rs | 3 +++ compiler/rustc_const_eval/src/interpret/eval_context.rs | 1 + compiler/rustc_hir/src/hir.rs | 1 + compiler/rustc_middle/src/mir/interpret/queries.rs | 2 ++ compiler/rustc_middle/src/ty/mod.rs | 5 +++++ 5 files changed, 12 insertions(+) diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index 6d3a89c0a8a5..c5412affafe2 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -7,6 +7,7 @@ use crate::interpret::{ }; use rustc_errors::ErrorReported; +use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_middle::mir; use rustc_middle::mir::interpret::ErrorHandled; @@ -215,6 +216,7 @@ pub fn eval_to_const_value_raw_provider<'tcx>( tcx: TyCtxt<'tcx>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>, ) -> ::rustc_middle::mir::interpret::EvalToConstValueResult<'tcx> { + assert!(key.param_env.constness() == hir::Constness::Const); // see comment in eval_to_allocation_raw_provider for what we're doing here if key.param_env.reveal() == Reveal::All { let mut key = key; @@ -249,6 +251,7 @@ pub fn eval_to_allocation_raw_provider<'tcx>( tcx: TyCtxt<'tcx>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>, ) -> ::rustc_middle::mir::interpret::EvalToAllocationRawResult<'tcx> { + assert!(key.param_env.constness() == hir::Constness::Const); // Because the constant is computed twice (once per value of `Reveal`), we are at risk of // reporting the same error twice here. To resolve this, we check whether we can evaluate the // constant in the more restrictive `Reveal::UserFacing`, which most likely already was diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index cf084faade8c..6206deb21153 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -918,6 +918,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } else { self.param_env }; + let param_env = param_env.with_const(); let val = self.tcx.eval_to_allocation_raw(param_env.and(gid))?; self.raw_const_to_mplace(val) } diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 2b4403b37ffc..1446c84a3976 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3248,6 +3248,7 @@ impl<'hir> Node<'hir> { Node::Item(Item { kind: ItemKind::Const(..), .. }) | Node::Item(Item { kind: ItemKind::Static(..), .. }) | Node::TraitItem(TraitItem { kind: TraitItemKind::Const(..), .. }) + | Node::AnonConst(_) | Node::ImplItem(ImplItem { kind: ImplItemKind::Const(..), .. }) => Constness::Const, _ => Constness::NotConst, diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index c63613ae3af2..f98318556331 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -64,6 +64,7 @@ impl<'tcx> TyCtxt<'tcx> { cid: GlobalId<'tcx>, span: Option, ) -> EvalToConstValueResult<'tcx> { + let param_env = param_env.with_const(); // Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should // improve caching of queries. let inputs = self.erase_regions(param_env.and(cid)); @@ -92,6 +93,7 @@ impl<'tcx> TyCtxt<'tcx> { gid: GlobalId<'tcx>, param_env: ty::ParamEnv<'tcx>, ) -> Result<&'tcx mir::Allocation, ErrorHandled> { + let param_env = param_env.with_const(); trace!("eval_to_allocation: Need to compute {:?}", gid); let raw_const = self.eval_to_allocation_raw(param_env.and(gid))?; Ok(self.global_alloc(raw_const.alloc_id).unwrap_memory()) diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 8031eb8a1ec2..896e56026188 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1323,6 +1323,11 @@ impl<'tcx> ParamEnv<'tcx> { self } + pub fn with_const(mut self) -> Self { + self.packed.set_tag(ParamTag { constness: hir::Constness::Const, ..self.packed.tag() }); + self + } + /// Returns a new parameter environment with the same clauses, but /// which "reveals" the true results of projections in all cases /// (even for associated types that are specializable). This is