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.
This commit is contained in:
Oli Scherer 2021-10-25 16:49:39 +00:00 committed by Deadbeef
parent a9a79f657c
commit f394bb57bb
No known key found for this signature in database
GPG key ID: 6D017A96D8E6C2F9
5 changed files with 12 additions and 0 deletions

View file

@ -7,6 +7,7 @@ use crate::interpret::{
}; };
use rustc_errors::ErrorReported; use rustc_errors::ErrorReported;
use rustc_hir as hir;
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
use rustc_middle::mir; use rustc_middle::mir;
use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::mir::interpret::ErrorHandled;
@ -215,6 +216,7 @@ pub fn eval_to_const_value_raw_provider<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>,
) -> ::rustc_middle::mir::interpret::EvalToConstValueResult<'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 // see comment in eval_to_allocation_raw_provider for what we're doing here
if key.param_env.reveal() == Reveal::All { if key.param_env.reveal() == Reveal::All {
let mut key = key; let mut key = key;
@ -249,6 +251,7 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>,
) -> ::rustc_middle::mir::interpret::EvalToAllocationRawResult<'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 // 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 // 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 // constant in the more restrictive `Reveal::UserFacing`, which most likely already was

View file

@ -918,6 +918,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
} else { } else {
self.param_env self.param_env
}; };
let param_env = param_env.with_const();
let val = self.tcx.eval_to_allocation_raw(param_env.and(gid))?; let val = self.tcx.eval_to_allocation_raw(param_env.and(gid))?;
self.raw_const_to_mplace(val) self.raw_const_to_mplace(val)
} }

View file

@ -3248,6 +3248,7 @@ impl<'hir> Node<'hir> {
Node::Item(Item { kind: ItemKind::Const(..), .. }) Node::Item(Item { kind: ItemKind::Const(..), .. })
| Node::Item(Item { kind: ItemKind::Static(..), .. }) | Node::Item(Item { kind: ItemKind::Static(..), .. })
| Node::TraitItem(TraitItem { kind: TraitItemKind::Const(..), .. }) | Node::TraitItem(TraitItem { kind: TraitItemKind::Const(..), .. })
| Node::AnonConst(_)
| Node::ImplItem(ImplItem { kind: ImplItemKind::Const(..), .. }) => Constness::Const, | Node::ImplItem(ImplItem { kind: ImplItemKind::Const(..), .. }) => Constness::Const,
_ => Constness::NotConst, _ => Constness::NotConst,

View file

@ -64,6 +64,7 @@ impl<'tcx> TyCtxt<'tcx> {
cid: GlobalId<'tcx>, cid: GlobalId<'tcx>,
span: Option<Span>, span: Option<Span>,
) -> EvalToConstValueResult<'tcx> { ) -> 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 // Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should
// improve caching of queries. // improve caching of queries.
let inputs = self.erase_regions(param_env.and(cid)); let inputs = self.erase_regions(param_env.and(cid));
@ -92,6 +93,7 @@ impl<'tcx> TyCtxt<'tcx> {
gid: GlobalId<'tcx>, gid: GlobalId<'tcx>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
) -> Result<&'tcx mir::Allocation, ErrorHandled> { ) -> Result<&'tcx mir::Allocation, ErrorHandled> {
let param_env = param_env.with_const();
trace!("eval_to_allocation: Need to compute {:?}", gid); trace!("eval_to_allocation: Need to compute {:?}", gid);
let raw_const = self.eval_to_allocation_raw(param_env.and(gid))?; let raw_const = self.eval_to_allocation_raw(param_env.and(gid))?;
Ok(self.global_alloc(raw_const.alloc_id).unwrap_memory()) Ok(self.global_alloc(raw_const.alloc_id).unwrap_memory())

View file

@ -1323,6 +1323,11 @@ impl<'tcx> ParamEnv<'tcx> {
self 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 /// Returns a new parameter environment with the same clauses, but
/// which "reveals" the true results of projections in all cases /// which "reveals" the true results of projections in all cases
/// (even for associated types that are specializable). This is /// (even for associated types that are specializable). This is