InterpCx store TypingEnv instead of a ParamEnv

This commit is contained in:
lcnr 2024-11-19 20:10:42 +01:00
parent b9dea31ea9
commit 7a90e84f4d
36 changed files with 167 additions and 192 deletions

View File

@ -744,7 +744,11 @@ fn codegen_regular_intrinsic_call<'tcx>(
let const_val = fx
.tcx
.const_eval_instance(ty::ParamEnv::reveal_all(), instance, source_info.span)
.const_eval_instance(
ty::TypingEnv::fully_monomorphized(),
instance,
source_info.span,
)
.unwrap();
let val = crate::constant::codegen_const_value(fx, const_val, ret.layout().ty);
ret.write_cvalue(fx, val);

View File

@ -146,10 +146,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
| sym::type_id
| sym::type_name
| sym::variant_count => {
let value = bx
.tcx()
.const_eval_instance(ty::ParamEnv::reveal_all(), instance, span)
.unwrap();
let value = bx.tcx().const_eval_instance(bx.typing_env(), instance, span).unwrap();
OperandRef::from_const(bx, value, ret_ty).immediate_or_packed_pair(bx)
}
sym::arith_offset => {

View File

@ -7,7 +7,6 @@ use rustc_middle::bug;
use rustc_middle::mir::interpret::{AllocId, ErrorHandled, InterpErrorInfo};
use rustc_middle::mir::{self, ConstAlloc, ConstValue};
use rustc_middle::query::TyCtxtAt;
use rustc_middle::traits::Reveal;
use rustc_middle::ty::layout::LayoutOf;
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::{self, Ty, TyCtxt};
@ -31,7 +30,7 @@ fn eval_body_using_ecx<'tcx, R: InterpretationResult<'tcx>>(
cid: GlobalId<'tcx>,
body: &'tcx mir::Body<'tcx>,
) -> InterpResult<'tcx, R> {
trace!(?ecx.param_env);
trace!(?ecx.typing_env);
let tcx = *ecx.tcx;
assert!(
cid.promoted.is_some()
@ -126,14 +125,14 @@ fn eval_body_using_ecx<'tcx, R: InterpretationResult<'tcx>>(
pub(crate) fn mk_eval_cx_to_read_const_val<'tcx>(
tcx: TyCtxt<'tcx>,
root_span: Span,
param_env: ty::ParamEnv<'tcx>,
typing_env: ty::TypingEnv<'tcx>,
can_access_mut_global: CanAccessMutGlobal,
) -> CompileTimeInterpCx<'tcx> {
debug!("mk_eval_cx: {:?}", param_env);
debug!("mk_eval_cx: {:?}", typing_env);
InterpCx::new(
tcx,
root_span,
param_env,
typing_env,
CompileTimeMachine::new(can_access_mut_global, CheckAlignment::No),
)
}
@ -142,11 +141,11 @@ pub(crate) fn mk_eval_cx_to_read_const_val<'tcx>(
/// Returns both the context and an `OpTy` that represents the constant.
pub fn mk_eval_cx_for_const_val<'tcx>(
tcx: TyCtxtAt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
typing_env: ty::TypingEnv<'tcx>,
val: mir::ConstValue<'tcx>,
ty: Ty<'tcx>,
) -> Option<(CompileTimeInterpCx<'tcx>, OpTy<'tcx>)> {
let ecx = mk_eval_cx_to_read_const_val(tcx.tcx, tcx.span, param_env, CanAccessMutGlobal::No);
let ecx = mk_eval_cx_to_read_const_val(tcx.tcx, tcx.span, typing_env, CanAccessMutGlobal::No);
// FIXME: is it a problem to discard the error here?
let op = ecx.const_val_to_op(val, ty, None).discard_err()?;
Some((ecx, op))
@ -221,7 +220,7 @@ pub(super) fn op_to_const<'tcx>(
let pointee_ty = imm.layout.ty.builtin_deref(false).unwrap(); // `false` = no raw ptrs
debug_assert!(
matches!(
ecx.tcx.struct_tail_for_codegen(pointee_ty, ecx.typing_env()).kind(),
ecx.tcx.struct_tail_for_codegen(pointee_ty, ecx.typing_env).kind(),
ty::Str | ty::Slice(..),
),
"`ConstValue::Slice` is for slice-tailed types only, but got {}",
@ -245,7 +244,7 @@ pub(super) fn op_to_const<'tcx>(
pub(crate) fn turn_into_const_value<'tcx>(
tcx: TyCtxt<'tcx>,
constant: ConstAlloc<'tcx>,
key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>,
key: ty::PseudoCanonicalInput<'tcx, GlobalId<'tcx>>,
) -> ConstValue<'tcx> {
let cid = key.value;
let def_id = cid.instance.def.def_id();
@ -254,7 +253,7 @@ pub(crate) fn turn_into_const_value<'tcx>(
let ecx = mk_eval_cx_to_read_const_val(
tcx,
tcx.def_span(key.value.instance.def_id()),
key.param_env,
key.typing_env,
CanAccessMutGlobal::from(is_static),
);
@ -274,23 +273,16 @@ pub(crate) fn turn_into_const_value<'tcx>(
#[instrument(skip(tcx), level = "debug")]
pub fn eval_to_const_value_raw_provider<'tcx>(
tcx: TyCtxt<'tcx>,
key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>,
key: ty::PseudoCanonicalInput<'tcx, GlobalId<'tcx>>,
) -> ::rustc_middle::mir::interpret::EvalToConstValueResult<'tcx> {
// Const eval always happens in Reveal::All mode in order to be able to use the hidden types of
// opaque types. This is needed for trivial things like `size_of`, but also for using associated
// types that are not specified in the opaque type.
assert_eq!(key.param_env.reveal(), Reveal::All);
let typing_env =
ty::TypingEnv { typing_mode: ty::TypingMode::PostAnalysis, param_env: key.param_env };
// We call `const_eval` for zero arg intrinsics, too, in order to cache their value.
// Catch such calls and evaluate them instead of trying to load a constant's MIR.
if let ty::InstanceKind::Intrinsic(def_id) = key.value.instance.def {
let ty = key.value.instance.ty(tcx, typing_env);
let ty = key.value.instance.ty(tcx, key.typing_env);
let ty::FnDef(_, args) = ty.kind() else {
bug!("intrinsic with type {:?}", ty);
};
return eval_nullary_intrinsic(tcx, key.param_env, def_id, args).report_err().map_err(
return eval_nullary_intrinsic(tcx, key.typing_env, def_id, args).report_err().map_err(
|error| {
let span = tcx.def_span(def_id);
@ -317,7 +309,7 @@ pub fn eval_static_initializer_provider<'tcx>(
let instance = ty::Instance::mono(tcx, def_id.to_def_id());
let cid = rustc_middle::mir::interpret::GlobalId { instance, promoted: None };
eval_in_interpreter(tcx, cid, ty::ParamEnv::reveal_all())
eval_in_interpreter(tcx, cid, ty::TypingEnv::fully_monomorphized())
}
pub trait InterpretationResult<'tcx> {
@ -342,16 +334,14 @@ impl<'tcx> InterpretationResult<'tcx> for ConstAlloc<'tcx> {
#[instrument(skip(tcx), level = "debug")]
pub fn eval_to_allocation_raw_provider<'tcx>(
tcx: TyCtxt<'tcx>,
key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>,
key: ty::PseudoCanonicalInput<'tcx, GlobalId<'tcx>>,
) -> ::rustc_middle::mir::interpret::EvalToAllocationRawResult<'tcx> {
// This shouldn't be used for statics, since statics are conceptually places,
// not values -- so what we do here could break pointer identity.
assert!(key.value.promoted.is_some() || !tcx.is_static(key.value.instance.def_id()));
// Const eval always happens in Reveal::All mode in order to be able to use the hidden types of
// opaque types. This is needed for trivial things like `size_of`, but also for using associated
// types that are not specified in the opaque type.
assert_eq!(key.param_env.reveal(), Reveal::All);
// Const eval always happens in PostAnalysis mode . See the comment in
// `InterpCx::new` for more details.
debug_assert_eq!(key.typing_env.typing_mode, ty::TypingMode::PostAnalysis);
if cfg!(debug_assertions) {
// Make sure we format the instance even if we do not print it.
// This serves as a regression test against an ICE on printing.
@ -362,13 +352,13 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
trace!("const eval: {:?} ({})", key, instance);
}
eval_in_interpreter(tcx, key.value, key.param_env)
eval_in_interpreter(tcx, key.value, key.typing_env)
}
fn eval_in_interpreter<'tcx, R: InterpretationResult<'tcx>>(
tcx: TyCtxt<'tcx>,
cid: GlobalId<'tcx>,
param_env: ty::ParamEnv<'tcx>,
typing_env: ty::TypingEnv<'tcx>,
) -> Result<R, ErrorHandled> {
let def = cid.instance.def.def_id();
let is_static = tcx.is_static(def);
@ -376,7 +366,7 @@ fn eval_in_interpreter<'tcx, R: InterpretationResult<'tcx>>(
let mut ecx = InterpCx::new(
tcx,
tcx.def_span(def),
param_env,
typing_env,
// Statics (and promoteds inside statics) may access mutable global memory, because unlike consts
// they do not have to behave "as if" they were evaluated at runtime.
// For consts however we want to ensure they behave "as if" they were evaluated at runtime,

View File

@ -667,7 +667,7 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
.is_some_and(|p| !p.immutable())
{
// That next check is expensive, that's why we have all the guards above.
let is_immutable = ty.is_freeze(*ecx.tcx, ecx.typing_env());
let is_immutable = ty.is_freeze(*ecx.tcx, ecx.typing_env);
let place = ecx.ref_to_mplace(val)?;
let new_place = if is_immutable {
place.map_provenance(CtfeProvenance::as_immutable)

View File

@ -38,8 +38,8 @@ pub(crate) fn try_destructure_mir_constant_for_user_output<'tcx>(
val: mir::ConstValue<'tcx>,
ty: Ty<'tcx>,
) -> Option<mir::DestructuredConstant<'tcx>> {
let param_env = ty::ParamEnv::reveal_all();
let (ecx, op) = mk_eval_cx_for_const_val(tcx, param_env, val, ty)?;
let typing_env = ty::TypingEnv::fully_monomorphized();
let (ecx, op) = mk_eval_cx_for_const_val(tcx, typing_env, val, ty)?;
// We go to `usize` as we cannot allocate anything bigger anyway.
let (field_count, variant, down) = match ty.kind() {
@ -76,10 +76,12 @@ pub fn tag_for_variant_provider<'tcx>(
) -> Option<ty::ScalarInt> {
assert!(ty.is_enum());
// FIXME: This uses an empty `TypingEnv` even though
// it may be used by a generic CTFE.
let ecx = InterpCx::new(
tcx,
ty.default_span(tcx),
ty::ParamEnv::reveal_all(),
ty::TypingEnv::fully_monomorphized(),
crate::const_eval::DummyMachine,
);

View File

@ -2,7 +2,6 @@ use rustc_abi::{BackendRepr, VariantIdx};
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId};
use rustc_middle::ty::layout::{LayoutCx, LayoutOf, TyAndLayout};
use rustc_middle::ty::solve::Reveal;
use rustc_middle::ty::{self, ScalarInt, Ty, TyCtxt};
use rustc_middle::{bug, mir};
use rustc_span::DUMMY_SP;
@ -229,16 +228,19 @@ fn create_valtree_place<'tcx>(
/// Evaluates a constant and turns it into a type-level constant value.
pub(crate) fn eval_to_valtree<'tcx>(
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
typing_env: ty::TypingEnv<'tcx>,
cid: GlobalId<'tcx>,
) -> EvalToValTreeResult<'tcx> {
let const_alloc = tcx.eval_to_allocation_raw(param_env.and(cid))?;
// Const eval always happens in PostAnalysis mode . See the comment in
// `InterpCx::new` for more details.
debug_assert_eq!(typing_env.typing_mode, ty::TypingMode::PostAnalysis);
let const_alloc = tcx.eval_to_allocation_raw(typing_env.as_query_input(cid))?;
// FIXME Need to provide a span to `eval_to_valtree`
let ecx = mk_eval_cx_to_read_const_val(
tcx,
DUMMY_SP,
param_env,
typing_env,
// It is absolutely crucial for soundness that
// we do not read from mutable memory.
CanAccessMutGlobal::No,
@ -273,7 +275,8 @@ pub(crate) fn eval_to_valtree<'tcx>(
#[instrument(skip(tcx), level = "debug", ret)]
pub fn valtree_to_const_value<'tcx>(
tcx: TyCtxt<'tcx>,
param_env_ty: ty::ParamEnvAnd<'tcx, Ty<'tcx>>,
typing_env: ty::TypingEnv<'tcx>,
ty: Ty<'tcx>,
valtree: ty::ValTree<'tcx>,
) -> mir::ConstValue<'tcx> {
// Basic idea: We directly construct `Scalar` values from trivial `ValTree`s
@ -282,10 +285,6 @@ pub fn valtree_to_const_value<'tcx>(
// the `ValTree` and using `place_projection` and `place_field` to
// create inner `MPlace`s which are filled recursively.
// FIXME Does this need an example?
let (param_env, ty) = param_env_ty.into_parts();
debug_assert_eq!(param_env.reveal(), Reveal::All);
let typing_env = ty::TypingEnv { typing_mode: ty::TypingMode::PostAnalysis, param_env };
match *ty.kind() {
ty::FnDef(..) => {
assert!(valtree.unwrap_branch().is_empty());
@ -299,10 +298,10 @@ pub fn valtree_to_const_value<'tcx>(
),
}
}
ty::Pat(ty, _) => valtree_to_const_value(tcx, param_env.and(ty), valtree),
ty::Pat(ty, _) => valtree_to_const_value(tcx, typing_env, ty, valtree),
ty::Ref(_, inner_ty, _) => {
let mut ecx =
mk_eval_cx_to_read_const_val(tcx, DUMMY_SP, param_env, CanAccessMutGlobal::No);
mk_eval_cx_to_read_const_val(tcx, DUMMY_SP, typing_env, CanAccessMutGlobal::No);
let imm = valtree_to_ref(&mut ecx, valtree, inner_ty);
let imm =
ImmTy::from_immediate(imm, tcx.layout_of(typing_env.as_query_input(ty)).unwrap());
@ -324,14 +323,14 @@ pub fn valtree_to_const_value<'tcx>(
for (i, &inner_valtree) in branches.iter().enumerate() {
let field = layout.field(&LayoutCx::new(tcx, typing_env), i);
if !field.is_zst() {
return valtree_to_const_value(tcx, param_env.and(field.ty), inner_valtree);
return valtree_to_const_value(tcx, typing_env, field.ty, inner_valtree);
}
}
bug!("could not find non-ZST field during in {layout:#?}");
}
let mut ecx =
mk_eval_cx_to_read_const_val(tcx, DUMMY_SP, param_env, CanAccessMutGlobal::No);
mk_eval_cx_to_read_const_val(tcx, DUMMY_SP, typing_env, CanAccessMutGlobal::No);
// Need to create a place for this valtree.
let place = create_valtree_place(&mut ecx, layout, valtree);

View File

@ -215,7 +215,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
// Even if `ty` is normalized, the search for the unsized tail will project
// to fields, which can yield non-normalized types. So we need to provide a
// normalization function.
let normalize = |ty| self.tcx.normalize_erasing_regions(self.typing_env(), ty);
let normalize = |ty| self.tcx.normalize_erasing_regions(self.typing_env, ty);
ty.ptr_metadata_ty(*self.tcx, normalize)
};
return interp_ok(meta_ty(caller) == meta_ty(callee));
@ -652,35 +652,35 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
};
// Obtain the underlying trait we are working on, and the adjusted receiver argument.
let (trait_, dyn_ty, adjusted_recv) =
if let ty::Dynamic(data, _, ty::DynStar) = receiver_place.layout.ty.kind() {
let recv = self.unpack_dyn_star(&receiver_place, data)?;
let (trait_, dyn_ty, adjusted_recv) = if let ty::Dynamic(data, _, ty::DynStar) =
receiver_place.layout.ty.kind()
{
let recv = self.unpack_dyn_star(&receiver_place, data)?;
(data.principal(), recv.layout.ty, recv.ptr())
} else {
// Doesn't have to be a `dyn Trait`, but the unsized tail must be `dyn Trait`.
// (For that reason we also cannot use `unpack_dyn_trait`.)
let receiver_tail = self
.tcx
.struct_tail_for_codegen(receiver_place.layout.ty, self.typing_env());
let ty::Dynamic(receiver_trait, _, ty::Dyn) = receiver_tail.kind() else {
span_bug!(
self.cur_span(),
"dynamic call on non-`dyn` type {}",
receiver_tail
)
};
assert!(receiver_place.layout.is_unsized());
// Get the required information from the vtable.
let vptr = receiver_place.meta().unwrap_meta().to_pointer(self)?;
let dyn_ty = self.get_ptr_vtable_ty(vptr, Some(receiver_trait))?;
// It might be surprising that we use a pointer as the receiver even if this
// is a by-val case; this works because by-val passing of an unsized `dyn
// Trait` to a function is actually desugared to a pointer.
(receiver_trait.principal(), dyn_ty, receiver_place.ptr())
(data.principal(), recv.layout.ty, recv.ptr())
} else {
// Doesn't have to be a `dyn Trait`, but the unsized tail must be `dyn Trait`.
// (For that reason we also cannot use `unpack_dyn_trait`.)
let receiver_tail =
self.tcx.struct_tail_for_codegen(receiver_place.layout.ty, self.typing_env);
let ty::Dynamic(receiver_trait, _, ty::Dyn) = receiver_tail.kind() else {
span_bug!(
self.cur_span(),
"dynamic call on non-`dyn` type {}",
receiver_tail
)
};
assert!(receiver_place.layout.is_unsized());
// Get the required information from the vtable.
let vptr = receiver_place.meta().unwrap_meta().to_pointer(self)?;
let dyn_ty = self.get_ptr_vtable_ty(vptr, Some(receiver_trait))?;
// It might be surprising that we use a pointer as the receiver even if this
// is a by-val case; this works because by-val passing of an unsized `dyn
// Trait` to a function is actually desugared to a pointer.
(receiver_trait.principal(), dyn_ty, receiver_place.ptr())
};
// Now determine the actual method to call. Usually we use the easy way of just
// looking up the method at index `idx`.
@ -704,7 +704,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
let concrete_method = Instance::expect_resolve_for_vtable(
tcx,
self.typing_env(),
self.typing_env,
def_id,
instance.args.rebase_onto(tcx, trait_def_id, concrete_trait_ref.args),
self.cur_span(),

View File

@ -83,7 +83,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
ty::FnDef(def_id, args) => {
let instance = ty::Instance::resolve_for_fn_ptr(
*self.tcx,
self.typing_env(),
self.typing_env,
def_id,
args,
)
@ -384,7 +384,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
) -> InterpResult<'tcx> {
// A<Struct> -> A<Trait> conversion
let (src_pointee_ty, dest_pointee_ty) =
self.tcx.struct_lockstep_tails_for_codegen(source_ty, cast_ty, self.typing_env());
self.tcx.struct_lockstep_tails_for_codegen(source_ty, cast_ty, self.typing_env);
match (src_pointee_ty.kind(), dest_pointee_ty.kind()) {
(&ty::Array(_, length), &ty::Slice(_)) => {

View File

@ -1,10 +1,12 @@
use std::assert_matches::debug_assert_matches;
use either::{Left, Right};
use rustc_abi::{Align, HasDataLayout, Size, TargetDataLayout};
use rustc_errors::DiagCtxtHandle;
use rustc_hir::def_id::DefId;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::infer::at::ToTrace;
use rustc_infer::traits::{ObligationCause, Reveal};
use rustc_infer::traits::ObligationCause;
use rustc_middle::mir::interpret::{ErrorHandled, InvalidMetaKind, ReportedErrorInfo};
use rustc_middle::query::TyCtxtAt;
use rustc_middle::ty::layout::{
@ -36,8 +38,9 @@ pub struct InterpCx<'tcx, M: Machine<'tcx>> {
/// we are evaluating (if this is CTFE).
pub tcx: TyCtxtAt<'tcx>,
/// Bounds in scope for polymorphic evaluations.
pub(crate) param_env: ty::ParamEnv<'tcx>,
/// The current context in case we're evaluating in a
/// polymorphic context. This always uses `ty::TypingMode::PostAnalysis`
pub typing_env: ty::TypingEnv<'tcx>,
/// The virtual memory system.
pub memory: Memory<'tcx, M>,
@ -68,7 +71,7 @@ where
M: Machine<'tcx>,
{
fn typing_env(&self) -> ty::TypingEnv<'tcx> {
self.typing_env()
self.typing_env
}
}
@ -189,25 +192,23 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
pub fn new(
tcx: TyCtxt<'tcx>,
root_span: Span,
param_env: ty::ParamEnv<'tcx>,
typing_env: ty::TypingEnv<'tcx>,
machine: M,
) -> Self {
// Const eval always happens in post analysis mode in order to be able to use the hidden types of
// opaque types. This is needed for trivial things like `size_of`, but also for using associated
// types that are not specified in the opaque type. We also use MIR bodies whose opaque types have
// already been revealed, so we'd be able to at least partially observe the hidden types anyways.
debug_assert_matches!(typing_env.typing_mode, ty::TypingMode::PostAnalysis);
InterpCx {
machine,
tcx: tcx.at(root_span),
param_env,
typing_env,
memory: Memory::new(),
recursion_limit: tcx.recursion_limit(),
}
}
/// During CTFE we're always in `PostAnalysis` mode.
#[inline(always)]
pub fn typing_env(&self) -> ty::TypingEnv<'tcx> {
debug_assert_eq!(self.param_env.reveal(), Reveal::All);
ty::TypingEnv { typing_mode: ty::TypingMode::PostAnalysis, param_env: self.param_env }
}
/// Returns the span of the currently executed statement/terminator.
/// This is the span typically used for error reporting.
#[inline(always)]
@ -250,7 +251,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
#[inline]
pub fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool {
ty.is_freeze(*self.tcx, self.typing_env())
ty.is_freeze(*self.tcx, self.typing_env)
}
pub fn load_mir(
@ -296,7 +297,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
.instance
.try_instantiate_mir_and_normalize_erasing_regions(
*self.tcx,
self.typing_env(),
self.typing_env,
ty::EarlyBinder::bind(value),
)
.map_err(|_| ErrorHandled::TooGeneric(self.cur_span()))
@ -309,9 +310,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
args: GenericArgsRef<'tcx>,
) -> InterpResult<'tcx, ty::Instance<'tcx>> {
trace!("resolve: {:?}, {:#?}", def, args);
trace!("param_env: {:#?}", self.param_env);
trace!("typing_env: {:#?}", self.typing_env);
trace!("args: {:#?}", args);
match ty::Instance::try_resolve(*self.tcx, self.typing_env(), def, args) {
match ty::Instance::try_resolve(*self.tcx, self.typing_env, def, args) {
Ok(Some(instance)) => interp_ok(instance),
Ok(None) => throw_inval!(TooGeneric),
@ -332,7 +333,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
return true;
}
// Slow path: spin up an inference context to check if these traits are sufficiently equal.
let (infcx, param_env) = self.tcx.infer_ctxt().build_with_typing_env(self.typing_env());
let (infcx, param_env) = self.tcx.infer_ctxt().build_with_typing_env(self.typing_env);
let ocx = ObligationCtxt::new(&infcx);
let cause = ObligationCause::dummy_with_span(self.cur_span());
// equate the two trait refs after normalization
@ -564,10 +565,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
let val = if self.tcx.is_static(gid.instance.def_id()) {
let alloc_id = self.tcx.reserve_and_set_static_alloc(gid.instance.def_id());
let ty = instance.ty(self.tcx.tcx, self.typing_env());
let ty = instance.ty(self.tcx.tcx, self.typing_env);
mir::ConstAlloc { alloc_id, ty }
} else {
self.ctfe_query(|tcx| tcx.eval_to_allocation_raw(self.param_env.and(gid)))?
self.ctfe_query(|tcx| tcx.eval_to_allocation_raw(self.typing_env.as_query_input(gid)))?
};
self.raw_const_to_mplace(val)
}
@ -579,7 +580,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
layout: Option<TyAndLayout<'tcx>>,
) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
M::eval_mir_constant(self, *val, span, layout, |ecx, val, span, layout| {
let const_val = val.eval(*ecx.tcx, ecx.typing_env(), span).map_err(|err| {
let const_val = val.eval(*ecx.tcx, ecx.typing_env, span).map_err(|err| {
if M::ALL_CONSTS_ARE_PRECHECKED {
match err {
ErrorHandled::TooGeneric(..) => {},

View File

@ -165,7 +165,7 @@ pub fn intern_const_alloc_recursive<'tcx, M: CompileTimeMachine<'tcx, const_eval
InternKind::Static(Mutability::Not) => {
(
// Outermost allocation is mutable if `!Freeze`.
if ret.layout.ty.is_freeze(*ecx.tcx, ecx.typing_env()) {
if ret.layout.ty.is_freeze(*ecx.tcx, ecx.typing_env) {
Mutability::Not
} else {
Mutability::Mut

View File

@ -34,13 +34,12 @@ pub(crate) fn alloc_type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ConstAll
/// inside an `InterpCx` and instead have their value computed directly from rustc internal info.
pub(crate) fn eval_nullary_intrinsic<'tcx>(
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
typing_env: ty::TypingEnv<'tcx>,
def_id: DefId,
args: GenericArgsRef<'tcx>,
) -> InterpResult<'tcx, ConstValue<'tcx>> {
let tp_ty = args.type_at(0);
let name = tcx.item_name(def_id);
let typing_env = ty::TypingEnv { typing_mode: ty::TypingMode::PostAnalysis, param_env };
interp_ok(match name {
sym::type_name => {
ensure_monomorphic_enough(tcx, tp_ty)?;
@ -152,8 +151,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
sym::type_name => Ty::new_static_str(self.tcx.tcx),
_ => bug!(),
};
let val =
self.ctfe_query(|tcx| tcx.const_eval_global_id(self.param_env, gid, tcx.span))?;
let val = self
.ctfe_query(|tcx| tcx.const_eval_global_id(self.typing_env, gid, tcx.span))?;
let val = self.const_val_to_op(val, ty, Some(dest.layout))?;
self.copy_op(&val, dest)?;
}
@ -358,7 +357,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
let should_panic = !self
.tcx
.check_validity_requirement((requirement, self.typing_env().as_query_input(ty)))
.check_validity_requirement((requirement, self.typing_env.as_query_input(ty)))
.map_err(|_| err_inval!(TooGeneric))?;
if should_panic {

View File

@ -859,8 +859,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
// # Global allocations
if let Some(global_alloc) = self.tcx.try_get_global_alloc(id) {
let (size, align) = global_alloc.size_and_align(*self.tcx, self.typing_env());
let mutbl = global_alloc.mutability(*self.tcx, self.typing_env());
let (size, align) = global_alloc.size_and_align(*self.tcx, self.typing_env);
let mutbl = global_alloc.mutability(*self.tcx, self.typing_env);
let kind = match global_alloc {
GlobalAlloc::Static { .. } | GlobalAlloc::Memory { .. } => AllocKind::LiveData,
GlobalAlloc::Function { .. } => bug!("We already checked function pointers above"),

View File

@ -533,7 +533,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
}
OffsetOf(fields) => {
let val =
self.tcx.offset_of_subfield(self.typing_env(), layout, fields.iter()).bytes();
self.tcx.offset_of_subfield(self.typing_env, layout, fields.iter()).bytes();
ImmTy::from_uint(val, usize_layout())
}
UbChecks => ImmTy::from_bool(M::ub_checks(self)?, *self.tcx),

View File

@ -540,7 +540,7 @@ where
)?;
if !mir_assign_valid_types(
*self.tcx,
self.typing_env(),
self.typing_env,
self.layout_of(normalized_place_ty)?,
place.layout,
) {
@ -871,7 +871,7 @@ where
// We do NOT compare the types for equality, because well-typed code can
// actually "transmute" `&mut T` to `&T` in an assignment without a cast.
let layout_compat =
mir_assign_valid_types(*self.tcx, self.typing_env(), src.layout(), dest.layout());
mir_assign_valid_types(*self.tcx, self.typing_env, src.layout(), dest.layout());
if !allow_transmute && !layout_compat {
span_bug!(
self.cur_span(),

View File

@ -379,7 +379,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
for &const_ in body.required_consts() {
let c =
self.instantiate_from_current_frame_and_normalize_erasing_regions(const_.const_)?;
c.eval(*self.tcx, self.typing_env(), const_.span).map_err(|err| {
c.eval(*self.tcx, self.typing_env, const_.span).map_err(|err| {
err.emit_note(*self.tcx);
err
})?;
@ -596,7 +596,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
return interp_ok(layout);
}
let layout = from_known_layout(self.tcx, self.typing_env(), layout, || {
let layout = from_known_layout(self.tcx, self.typing_env, layout, || {
let local_ty = frame.body.local_decls[local].ty;
let local_ty =
self.instantiate_from_frame_and_normalize_erasing_regions(frame, local_ty)?;

View File

@ -418,8 +418,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
.collect::<InterpResult<'tcx, Vec<_>>>()?;
let fn_sig_binder = func.layout.ty.fn_sig(*self.tcx);
let fn_sig =
self.tcx.normalize_erasing_late_bound_regions(self.typing_env(), fn_sig_binder);
let fn_sig = self.tcx.normalize_erasing_late_bound_regions(self.typing_env, fn_sig_binder);
let extra_args = &args[fn_sig.inputs().len()..];
let extra_args =
self.tcx.mk_type_list_from_iter(extra_args.iter().map(|arg| arg.layout().ty));

View File

@ -448,7 +448,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
meta: MemPlaceMeta<M::Provenance>,
pointee: TyAndLayout<'tcx>,
) -> InterpResult<'tcx> {
let tail = self.ecx.tcx.struct_tail_for_codegen(pointee.ty, self.ecx.typing_env());
let tail = self.ecx.tcx.struct_tail_for_codegen(pointee.ty, self.ecx.typing_env);
match tail.kind() {
ty::Dynamic(data, _, ty::Dyn) => {
let vtable = meta.unwrap_meta().to_pointer(self.ecx)?;
@ -568,7 +568,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
throw_validation_failure!(self.path, DanglingPtrUseAfterFree { ptr_kind });
};
let (size, _align) =
global_alloc.size_and_align(*self.ecx.tcx, self.ecx.typing_env());
global_alloc.size_and_align(*self.ecx.tcx, self.ecx.typing_env);
if let GlobalAlloc::Static(did) = global_alloc {
let DefKind::Static { nested, .. } = self.ecx.tcx.def_kind(did) else {
@ -619,7 +619,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
};
// Determine what it actually points to.
let alloc_actual_mutbl =
global_alloc.mutability(*self.ecx.tcx, self.ecx.typing_env());
global_alloc.mutability(*self.ecx.tcx, self.ecx.typing_env);
// Mutable pointer to immutable memory is no good.
if ptr_expected_mutbl == Mutability::Mut
&& alloc_actual_mutbl == Mutability::Not
@ -848,7 +848,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
if let Some(alloc_id) = mplace.ptr().provenance.and_then(|p| p.get_alloc_id()) {
let tcx = *self.ecx.tcx;
// Everything must be already interned.
let mutbl = tcx.global_alloc(alloc_id).mutability(tcx, self.ecx.typing_env());
let mutbl = tcx.global_alloc(alloc_id).mutability(tcx, self.ecx.typing_env);
if let Some((_, alloc)) = self.ecx.memory.alloc_map.get(alloc_id) {
assert_eq!(alloc.mutability, mutbl);
}
@ -955,7 +955,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
) -> Cow<'e, RangeSet> {
assert!(layout.ty.is_union());
assert!(layout.is_sized(), "there are no unsized unions");
let layout_cx = LayoutCx::new(*ecx.tcx, ecx.typing_env());
let layout_cx = LayoutCx::new(*ecx.tcx, ecx.typing_env);
return M::cached_union_data_range(ecx, layout.ty, || {
let mut out = RangeSet(Vec::new());
union_data_range_uncached(&layout_cx, layout, Size::ZERO, &mut out);
@ -1085,8 +1085,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValueVisitor<'tcx, M> for ValidityVisitor<'rt,
) -> InterpResult<'tcx> {
// Special check for CTFE validation, preventing `UnsafeCell` inside unions in immutable memory.
if self.ctfe_mode.is_some_and(|c| !c.allow_immutable_unsafe_cell()) {
if !val.layout.is_zst()
&& !val.layout.ty.is_freeze(*self.ecx.tcx, self.ecx.typing_env())
if !val.layout.is_zst() && !val.layout.ty.is_freeze(*self.ecx.tcx, self.ecx.typing_env)
{
if !self.in_mutable_memory(val) {
throw_validation_failure!(self.path, UnsafeCellInImmutable);

View File

@ -40,14 +40,13 @@ pub fn provide(providers: &mut Providers) {
providers.eval_to_allocation_raw = const_eval::eval_to_allocation_raw_provider;
providers.eval_static_initializer = const_eval::eval_static_initializer_provider;
providers.hooks.const_caller_location = util::caller_location::const_caller_location_provider;
providers.eval_to_valtree = |tcx, param_env_and_value| {
let (param_env, raw) = param_env_and_value.into_parts();
const_eval::eval_to_valtree(tcx, param_env, raw)
providers.eval_to_valtree = |tcx, ty::PseudoCanonicalInput { typing_env, value }| {
const_eval::eval_to_valtree(tcx, typing_env, value)
};
providers.hooks.try_destructure_mir_constant_for_user_output =
const_eval::try_destructure_mir_constant_for_user_output;
providers.valtree_to_const_val = |tcx, (ty, valtree)| {
const_eval::valtree_to_const_value(tcx, ty::ParamEnv::reveal_all().and(ty), valtree)
const_eval::valtree_to_const_value(tcx, ty::TypingEnv::fully_monomorphized(), ty, valtree)
};
providers.check_validity_requirement = |tcx, (init_kind, param_env_and_ty)| {
util::check_validity_requirement(tcx, init_kind, param_env_and_ty)

View File

@ -60,7 +60,7 @@ pub(crate) fn const_caller_location_provider(
let mut ecx = mk_eval_cx_to_read_const_val(
tcx.tcx,
tcx.span,
ty::ParamEnv::reveal_all(),
ty::TypingEnv::fully_monomorphized(),
CanAccessMutGlobal::No,
);

View File

@ -49,7 +49,7 @@ fn check_validity_requirement_strict<'tcx>(
) -> Result<bool, &'tcx LayoutError<'tcx>> {
let machine = CompileTimeMachine::new(CanAccessMutGlobal::No, CheckAlignment::Error);
let mut cx = InterpCx::new(cx.tcx(), rustc_span::DUMMY_SP, cx.typing_env.param_env, machine);
let mut cx = InterpCx::new(cx.tcx(), rustc_span::DUMMY_SP, cx.typing_env, machine);
let allocated = cx
.allocate(ty, MemoryKind::Machine(crate::const_eval::MemoryKind::Heap))

View File

@ -188,8 +188,8 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
DefKind::Const if tcx.generics_of(item_def_id).is_empty() => {
let instance = ty::Instance::new(item_def_id.into(), ty::GenericArgs::empty());
let cid = GlobalId { instance, promoted: None };
let param_env = ty::ParamEnv::reveal_all();
tcx.ensure().eval_to_const_value_raw(param_env.and(cid));
let typing_env = ty::TypingEnv::fully_monomorphized();
tcx.ensure().eval_to_const_value_raw(typing_env.as_query_input(cid));
}
_ => (),
}

View File

@ -25,8 +25,8 @@ impl<'tcx> TyCtxt<'tcx> {
let args = GenericArgs::identity_for_item(self, def_id);
let instance = ty::Instance::new(def_id, args);
let cid = GlobalId { instance, promoted: None };
let param_env = self.param_env(def_id).with_reveal_all_normalized(self);
self.const_eval_global_id(param_env, cid, DUMMY_SP)
let typing_env = ty::TypingEnv::post_analysis(self, def_id);
self.const_eval_global_id(typing_env, cid, DUMMY_SP)
}
/// Evaluates a constant without providing any generic parameters. This is useful to evaluate consts
@ -41,8 +41,8 @@ impl<'tcx> TyCtxt<'tcx> {
let args = GenericArgs::identity_for_item(self, def_id);
let instance = ty::Instance::new(def_id, args);
let cid = GlobalId { instance, promoted: None };
let param_env = self.param_env(def_id).with_reveal_all_normalized(self);
let inputs = self.erase_regions(param_env.and(cid));
let typing_env = ty::TypingEnv::post_analysis(self, def_id);
let inputs = self.erase_regions(typing_env.as_query_input(cid));
self.eval_to_allocation_raw(inputs)
}
@ -76,7 +76,7 @@ impl<'tcx> TyCtxt<'tcx> {
match ty::Instance::try_resolve(self, typing_env, ct.def, ct.args) {
Ok(Some(instance)) => {
let cid = GlobalId { instance, promoted: ct.promoted };
self.const_eval_global_id(typing_env.param_env, cid, span)
self.const_eval_global_id(typing_env, cid, span)
}
// For errors during resolution, we deliberately do not point at the usage site of the constant,
// since for these errors the place the constant is used shouldn't matter.
@ -105,7 +105,7 @@ impl<'tcx> TyCtxt<'tcx> {
match ty::Instance::try_resolve(self, typing_env, ct.def, ct.args) {
Ok(Some(instance)) => {
let cid = GlobalId { instance, promoted: None };
self.const_eval_global_id_for_typeck(typing_env.param_env, cid, span).inspect(|_| {
self.const_eval_global_id_for_typeck(typing_env, cid, span).inspect(|_| {
// We are emitting the lint here instead of in `is_const_evaluatable`
// as we normalize obligations before checking them, and normalization
// uses this function to evaluate this constant.
@ -144,24 +144,25 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn const_eval_instance(
self,
param_env: ty::ParamEnv<'tcx>,
typing_env: ty::TypingEnv<'tcx>,
instance: ty::Instance<'tcx>,
span: Span,
) -> EvalToConstValueResult<'tcx> {
self.const_eval_global_id(param_env, GlobalId { instance, promoted: None }, span)
self.const_eval_global_id(typing_env, GlobalId { instance, promoted: None }, span)
}
/// Evaluate a constant to a `ConstValue`.
#[instrument(skip(self), level = "debug")]
pub fn const_eval_global_id(
self,
param_env: ty::ParamEnv<'tcx>,
typing_env: ty::TypingEnv<'tcx>,
cid: GlobalId<'tcx>,
span: Span,
) -> EvalToConstValueResult<'tcx> {
// 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.with_reveal_all_normalized(self).and(cid));
let inputs =
self.erase_regions(typing_env.with_reveal_all_normalized(self).as_query_input(cid));
if !span.is_dummy() {
// The query doesn't know where it is being invoked, so we need to fix the span.
self.at(span).eval_to_const_value_raw(inputs).map_err(|e| e.with_span(span))
@ -174,13 +175,14 @@ impl<'tcx> TyCtxt<'tcx> {
#[instrument(skip(self), level = "debug")]
pub fn const_eval_global_id_for_typeck(
self,
param_env: ty::ParamEnv<'tcx>,
typing_env: ty::TypingEnv<'tcx>,
cid: GlobalId<'tcx>,
span: Span,
) -> EvalToValTreeResult<'tcx> {
// 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.with_reveal_all_normalized(self).and(cid));
let inputs =
self.erase_regions(typing_env.with_reveal_all_normalized(self).as_query_input(cid));
debug!(?inputs);
if !span.is_dummy() {
// The query doesn't know where it is being invoked, so we need to fix the span.
@ -202,12 +204,12 @@ impl<'tcx> TyCtxtEnsure<'tcx> {
// into `const_eval` which will return `ErrorHandled::ToGeneric` if any of them are
// encountered.
let args = GenericArgs::identity_for_item(self.tcx, def_id);
let instance = ty::Instance::new(def_id, args);
let instance = ty::Instance::new(def_id, self.tcx.erase_regions(args));
let cid = GlobalId { instance, promoted: None };
let param_env = self.tcx.param_env(def_id).with_reveal_all_normalized(self.tcx);
let typing_env = ty::TypingEnv::post_analysis(self.tcx, def_id);
// Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should
// improve caching of queries.
let inputs = self.tcx.erase_regions(param_env.and(cid));
let inputs = self.tcx.erase_regions(typing_env.as_query_input(cid));
self.eval_to_const_value_raw(inputs)
}
}

View File

@ -456,18 +456,6 @@ impl<'tcx> Key for ty::ParamEnv<'tcx> {
}
}
impl<'tcx, T: Key> Key for ty::ParamEnvAnd<'tcx, T> {
type Cache<V> = DefaultCache<Self, V>;
fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
self.value.default_span(tcx)
}
fn ty_def_id(&self) -> Option<DefId> {
self.value.ty_def_id()
}
}
impl<'tcx, T: Key> Key for ty::PseudoCanonicalInput<'tcx, T> {
type Cache<V> = DefaultCache<Self, V>;

View File

@ -1095,7 +1095,7 @@ rustc_queries! {
/// Evaluates a constant and returns the computed allocation.
///
/// **Do not use this** directly, use the `eval_to_const_value` or `eval_to_valtree` instead.
query eval_to_allocation_raw(key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>)
query eval_to_allocation_raw(key: ty::PseudoCanonicalInput<'tcx, GlobalId<'tcx>>)
-> EvalToAllocationRawResult<'tcx> {
desc { |tcx|
"const-evaluating + checking `{}`",
@ -1121,7 +1121,7 @@ rustc_queries! {
///
/// **Do not use this** directly, use one of the following wrappers: `tcx.const_eval_poly`,
/// `tcx.const_eval_resolve`, `tcx.const_eval_instance`, or `tcx.const_eval_global_id`.
query eval_to_const_value_raw(key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>)
query eval_to_const_value_raw(key: ty::PseudoCanonicalInput<'tcx, GlobalId<'tcx>>)
-> EvalToConstValueResult<'tcx> {
desc { |tcx|
"simplifying constant for the type system `{}`",
@ -1133,7 +1133,7 @@ rustc_queries! {
/// Evaluate a constant and convert it to a type level constant or
/// return `None` if that is not possible.
query eval_to_valtree(
key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>
key: ty::PseudoCanonicalInput<'tcx, GlobalId<'tcx>>
) -> EvalToValTreeResult<'tcx> {
desc { "evaluating type-level constant" }
}

View File

@ -537,9 +537,7 @@ impl<'tcx> Instance<'tcx> {
// All regions in the result of this query are erased, so it's
// fine to erase all of the input regions.
let typing_env = tcx.erase_regions(typing_env);
let args = tcx.erase_regions(args);
tcx.resolve_instance_raw(typing_env.as_query_input((def_id, args)))
tcx.resolve_instance_raw(tcx.erase_regions(typing_env.as_query_input((def_id, args))))
}
pub fn expect_resolve(

View File

@ -1186,7 +1186,6 @@ impl<'tcx> TypingEnv<'tcx> {
where
T: TypeVisitable<TyCtxt<'tcx>>,
{
debug_assert!(!value.has_infer());
// FIXME(#132279): We should assert that the value does not contain any placeholders
// as these placeholders are also local to the current inference context. However, we
// currently use pseudo-canonical queries in the trait solver which replaces params with
@ -1209,7 +1208,7 @@ impl<'tcx> TypingEnv<'tcx> {
/// This should be created by using `infcx.pseudo_canonicalize_query(param_env, value)`
/// or by using `typing_env.as_query_input(value)`.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[derive(HashStable)]
#[derive(HashStable, TypeVisitable, TypeFoldable)]
pub struct PseudoCanonicalInput<'tcx, T> {
pub typing_env: TypingEnv<'tcx>,
pub value: T,

View File

@ -149,7 +149,7 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
map,
tcx,
local_decls: &body.local_decls,
ecx: InterpCx::new(tcx, DUMMY_SP, typing_env.param_env, DummyMachine),
ecx: InterpCx::new(tcx, DUMMY_SP, typing_env, DummyMachine),
typing_env,
}
}

View File

@ -125,8 +125,7 @@ impl<'tcx> crate::MirPass<'tcx> for GVN {
// Clone dominators because we need them while mutating the body.
let dominators = body.basic_blocks.dominators().clone();
let mut state =
VnState::new(tcx, body, typing_env.param_env, &ssa, dominators, &body.local_decls);
let mut state = VnState::new(tcx, body, typing_env, &ssa, dominators, &body.local_decls);
ssa.for_each_assignment_mut(
body.basic_blocks.as_mut_preserves_cfg(),
|local, value, location| {
@ -266,7 +265,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
fn new(
tcx: TyCtxt<'tcx>,
body: &Body<'tcx>,
param_env: ty::ParamEnv<'tcx>,
typing_env: ty::TypingEnv<'tcx>,
ssa: &'body SsaLocals,
dominators: Dominators<BasicBlock>,
local_decls: &'body LocalDecls<'tcx>,
@ -280,7 +279,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
+ 4 * body.basic_blocks.len();
VnState {
tcx,
ecx: InterpCx::new(tcx, DUMMY_SP, param_env, DummyMachine),
ecx: InterpCx::new(tcx, DUMMY_SP, typing_env, DummyMachine),
local_decls,
locals: IndexVec::from_elem(None, local_decls),
rev_locals: IndexVec::with_capacity(num_values),
@ -295,7 +294,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
}
fn typing_env(&self) -> ty::TypingEnv<'tcx> {
self.ecx.typing_env()
self.ecx.typing_env
}
#[instrument(level = "trace", skip(self), ret)]

View File

@ -82,7 +82,7 @@ impl<'tcx> crate::MirPass<'tcx> for JumpThreading {
let mut finder = TOFinder {
tcx,
typing_env,
ecx: InterpCx::new(tcx, DUMMY_SP, typing_env.param_env, DummyMachine),
ecx: InterpCx::new(tcx, DUMMY_SP, typing_env, DummyMachine),
body,
arena,
map: Map::new(tcx, body, Some(MAX_PLACES)),

View File

@ -183,7 +183,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
// to runtime, so we have to manually specify the correct typing mode.
let typing_env = ty::TypingEnv::post_analysis(tcx, body.source.def_id());
let can_const_prop = CanConstProp::check(tcx, typing_env, body);
let ecx = InterpCx::new(tcx, tcx.def_span(def_id), typing_env.param_env, DummyMachine);
let ecx = InterpCx::new(tcx, tcx.def_span(def_id), typing_env, DummyMachine);
ConstPropagator {
ecx,

View File

@ -15,7 +15,7 @@ use rustc_middle::ty::layout::{
};
use rustc_middle::ty::print::{with_forced_trimmed_paths, with_no_trimmed_paths};
use rustc_middle::ty::{
GenericPredicates, Instance, List, ParamEnv, ScalarInt, TyCtxt, TypeVisitableExt, ValTree,
GenericPredicates, Instance, List, ScalarInt, TyCtxt, TypeVisitableExt, ValTree,
};
use rustc_middle::{mir, ty};
use rustc_span::def_id::LOCAL_CRATE;
@ -713,7 +713,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
let instance = tables.instances[def];
let tcx = tables.tcx;
let result = tcx.const_eval_instance(
ParamEnv::reveal_all(),
ty::TypingEnv::fully_monomorphized(),
instance,
tcx.def_span(instance.def_id()),
);

View File

@ -270,8 +270,8 @@ impl<'tcx> NonCopyConst<'tcx> {
instance,
promoted: None,
};
let param_env = cx.tcx.param_env(def_id).with_reveal_all_normalized(cx.tcx);
let result = cx.tcx.const_eval_global_id_for_typeck(param_env, cid, DUMMY_SP);
let typing_env = ty::TypingEnv::post_analysis(cx.tcx, def_id);
let result = cx.tcx.const_eval_global_id_for_typeck(typing_env, cid, DUMMY_SP);
Self::is_value_unfrozen_raw(cx, result, ty)
}
@ -294,7 +294,7 @@ impl<'tcx> NonCopyConst<'tcx> {
instance,
promoted: None,
};
tcx.const_eval_global_id_for_typeck(typing_env.param_env, cid, span)
tcx.const_eval_global_id_for_typeck(typing_env, cid, span)
},
Ok(None) => Err(ErrorHandled::TooGeneric(span)),
Err(err) => Err(ErrorHandled::Reported(err.into(), span)),

View File

@ -70,7 +70,7 @@ impl NewPermission {
access: None,
protector: None,
}
} else if pointee.is_unpin(*cx.tcx, cx.typing_env()) {
} else if pointee.is_unpin(*cx.tcx, cx.typing_env) {
// A regular full mutable reference. On `FnEntry` this is `noalias` and `dereferenceable`.
NewPermission::Uniform {
perm: Permission::Unique,
@ -128,7 +128,7 @@ impl NewPermission {
fn from_box_ty<'tcx>(ty: Ty<'tcx>, kind: RetagKind, cx: &crate::MiriInterpCx<'tcx>) -> Self {
// `ty` is not the `Box` but the field of the Box with this pointer (due to allocator handling).
let pointee = ty.builtin_deref(true).unwrap();
if pointee.is_unpin(*cx.tcx, cx.typing_env()) {
if pointee.is_unpin(*cx.tcx, cx.typing_env) {
// A regular box. On `FnEntry` this is `noalias`, but not `dereferenceable` (hence only
// a weak protector).
NewPermission::Uniform {
@ -607,7 +607,7 @@ trait EvalContextPrivExt<'tcx, 'ecx>: crate::MiriInterpCxExt<'tcx> {
match new_perm {
NewPermission::Uniform { perm, .. } =>
write!(kind_str, "{perm:?} permission").unwrap(),
NewPermission::FreezeSensitive { freeze_perm, .. } if ty.is_freeze(*this.tcx, this.typing_env()) =>
NewPermission::FreezeSensitive { freeze_perm, .. } if ty.is_freeze(*this.tcx, this.typing_env) =>
write!(kind_str, "{freeze_perm:?} permission").unwrap(),
NewPermission::FreezeSensitive { freeze_perm, nonfreeze_perm, .. } =>
write!(kind_str, "{freeze_perm:?}/{nonfreeze_perm:?} permission for frozen/non-frozen parts").unwrap(),

View File

@ -131,8 +131,8 @@ impl<'tcx> NewPermission {
kind: RetagKind,
cx: &crate::MiriInterpCx<'tcx>,
) -> Option<Self> {
let ty_is_freeze = pointee.is_freeze(*cx.tcx, cx.typing_env());
let ty_is_unpin = pointee.is_unpin(*cx.tcx, cx.typing_env());
let ty_is_freeze = pointee.is_freeze(*cx.tcx, cx.typing_env);
let ty_is_unpin = pointee.is_unpin(*cx.tcx, cx.typing_env);
let is_protected = kind == RetagKind::FnEntry;
// As demonstrated by `tests/fail/tree_borrows/reservedim_spurious_write.rs`,
// interior mutability and protectors interact poorly.
@ -163,10 +163,10 @@ impl<'tcx> NewPermission {
zero_size: bool,
) -> Option<Self> {
let pointee = ty.builtin_deref(true).unwrap();
pointee.is_unpin(*cx.tcx, cx.typing_env()).then_some(()).map(|()| {
pointee.is_unpin(*cx.tcx, cx.typing_env).then_some(()).map(|()| {
// Regular `Unpin` box, give it `noalias` but only a weak protector
// because it is valid to deallocate it within the function.
let ty_is_freeze = ty.is_freeze(*cx.tcx, cx.typing_env());
let ty_is_freeze = ty.is_freeze(*cx.tcx, cx.typing_env);
let protected = kind == RetagKind::FnEntry;
let initial_state = Permission::new_reserved(ty_is_freeze, protected);
Self {
@ -520,7 +520,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Note: if we were to inline `new_reserved` below we would find out that
// `ty_is_freeze` is eventually unused because it appears in a `ty_is_freeze || true`.
// We are nevertheless including it here for clarity.
let ty_is_freeze = place.layout.ty.is_freeze(*this.tcx, this.typing_env());
let ty_is_freeze = place.layout.ty.is_freeze(*this.tcx, this.typing_env);
// Retag it. With protection! That is the entire point.
let new_perm = NewPermission {
initial_state: Permission::new_reserved(ty_is_freeze, /* protected */ true),

View File

@ -273,7 +273,7 @@ pub fn create_ecx<'tcx>(
let mut ecx = InterpCx::new(
tcx,
rustc_span::DUMMY_SP,
typing_env.param_env,
typing_env,
MiriMachine::new(config, layout_cx)
);

View File

@ -1128,7 +1128,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
let info = ecx.get_alloc_info(alloc_id);
let def_ty = ecx.tcx.type_of(def_id).instantiate_identity();
let extern_decl_layout = ecx.tcx.layout_of(
ecx.typing_env().as_query_input(def_ty)
ecx.typing_env.as_query_input(def_ty)
).unwrap();
if extern_decl_layout.size != info.size || extern_decl_layout.align.abi != info.align {
throw_unsup_format!(