use TypingEnv when no infcx is available
the behavior of the type system not only depends on the current assumptions, but also the currentnphase of the compiler. This is mostly necessary as we need to decide whether and how to reveal opaque types. We track this via the `TypingMode`.
This commit is contained in:
@@ -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.param_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.param_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
|
||||
)
|
||||
(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())
|
||||
};
|
||||
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.param_env,
|
||||
self.typing_env(),
|
||||
def_id,
|
||||
instance.args.rebase_onto(tcx, trait_def_id, concrete_trait_ref.args),
|
||||
self.cur_span(),
|
||||
|
||||
@@ -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.param_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.param_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(_)) => {
|
||||
|
||||
@@ -10,9 +10,7 @@ use rustc_middle::query::TyCtxtAt;
|
||||
use rustc_middle::ty::layout::{
|
||||
self, FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOfHelpers, TyAndLayout,
|
||||
};
|
||||
use rustc_middle::ty::{
|
||||
self, GenericArgsRef, ParamEnv, Ty, TyCtxt, TypeFoldable, TypingMode, Variance,
|
||||
};
|
||||
use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypeFoldable, TypingEnv, Variance};
|
||||
use rustc_middle::{mir, span_bug};
|
||||
use rustc_session::Limit;
|
||||
use rustc_span::Span;
|
||||
@@ -65,12 +63,12 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, M> layout::HasParamEnv<'tcx> for InterpCx<'tcx, M>
|
||||
impl<'tcx, M> layout::HasTypingEnv<'tcx> for InterpCx<'tcx, M>
|
||||
where
|
||||
M: Machine<'tcx>,
|
||||
{
|
||||
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
||||
self.param_env
|
||||
fn typing_env(&self) -> ty::TypingEnv<'tcx> {
|
||||
self.typing_env()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,8 +114,7 @@ impl<'tcx, M: Machine<'tcx>> FnAbiOfHelpers<'tcx> for InterpCx<'tcx, M> {
|
||||
/// This test should be symmetric, as it is primarily about layout compatibility.
|
||||
pub(super) fn mir_assign_valid_types<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
typing_mode: TypingMode<'tcx>,
|
||||
param_env: ParamEnv<'tcx>,
|
||||
typing_env: TypingEnv<'tcx>,
|
||||
src: TyAndLayout<'tcx>,
|
||||
dest: TyAndLayout<'tcx>,
|
||||
) -> bool {
|
||||
@@ -125,7 +122,7 @@ pub(super) fn mir_assign_valid_types<'tcx>(
|
||||
// all normal lifetimes are erased, higher-ranked types with their
|
||||
// late-bound lifetimes are still around and can lead to type
|
||||
// differences.
|
||||
if util::relate_types(tcx, typing_mode, param_env, Variance::Covariant, src.ty, dest.ty) {
|
||||
if util::relate_types(tcx, typing_env, Variance::Covariant, src.ty, dest.ty) {
|
||||
// Make sure the layout is equal, too -- just to be safe. Miri really
|
||||
// needs layout equality. For performance reason we skip this check when
|
||||
// the types are equal. Equal types *can* have different layouts when
|
||||
@@ -145,8 +142,7 @@ pub(super) fn mir_assign_valid_types<'tcx>(
|
||||
#[cfg_attr(not(debug_assertions), inline(always))]
|
||||
pub(super) fn from_known_layout<'tcx>(
|
||||
tcx: TyCtxtAt<'tcx>,
|
||||
typing_mode: TypingMode<'tcx>,
|
||||
param_env: ParamEnv<'tcx>,
|
||||
typing_env: TypingEnv<'tcx>,
|
||||
known_layout: Option<TyAndLayout<'tcx>>,
|
||||
compute: impl FnOnce() -> InterpResult<'tcx, TyAndLayout<'tcx>>,
|
||||
) -> InterpResult<'tcx, TyAndLayout<'tcx>> {
|
||||
@@ -155,13 +151,7 @@ pub(super) fn from_known_layout<'tcx>(
|
||||
Some(known_layout) => {
|
||||
if cfg!(debug_assertions) {
|
||||
let check_layout = compute()?;
|
||||
if !mir_assign_valid_types(
|
||||
tcx.tcx,
|
||||
typing_mode,
|
||||
param_env,
|
||||
check_layout,
|
||||
known_layout,
|
||||
) {
|
||||
if !mir_assign_valid_types(tcx.tcx, typing_env, check_layout, known_layout) {
|
||||
span_bug!(
|
||||
tcx.span,
|
||||
"expected type differs from actual type.\nexpected: {}\nactual: {}",
|
||||
@@ -211,9 +201,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn typing_mode(&self) -> TypingMode<'tcx> {
|
||||
/// 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);
|
||||
TypingMode::PostAnalysis
|
||||
ty::TypingEnv { typing_mode: ty::TypingMode::PostAnalysis, param_env: self.param_env }
|
||||
}
|
||||
|
||||
/// Returns the span of the currently executed statement/terminator.
|
||||
@@ -304,13 +296,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
.instance
|
||||
.try_instantiate_mir_and_normalize_erasing_regions(
|
||||
*self.tcx,
|
||||
self.param_env,
|
||||
self.typing_env(),
|
||||
ty::EarlyBinder::bind(value),
|
||||
)
|
||||
.map_err(|_| ErrorHandled::TooGeneric(self.cur_span()))
|
||||
}
|
||||
|
||||
/// The `args` are assumed to already be in our interpreter "universe" (param_env).
|
||||
/// The `args` are assumed to already be in our interpreter "universe".
|
||||
pub(super) fn resolve(
|
||||
&self,
|
||||
def: DefId,
|
||||
@@ -319,7 +311,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
trace!("resolve: {:?}, {:#?}", def, args);
|
||||
trace!("param_env: {:#?}", self.param_env);
|
||||
trace!("args: {:#?}", args);
|
||||
match ty::Instance::try_resolve(*self.tcx, self.param_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),
|
||||
|
||||
@@ -328,7 +320,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if the two things are equal in the current param_env, using an infctx to get proper
|
||||
/// Check if the two things are equal in the current param_env, using an infcx to get proper
|
||||
/// equality checks.
|
||||
#[instrument(level = "trace", skip(self), ret)]
|
||||
pub(super) fn eq_in_param_env<T>(&self, a: T, b: T) -> bool
|
||||
@@ -340,14 +332,14 @@ 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 = self.tcx.infer_ctxt().build(self.typing_mode());
|
||||
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
|
||||
let a = ocx.normalize(&cause, self.param_env, a);
|
||||
let b = ocx.normalize(&cause, self.param_env, b);
|
||||
let a = ocx.normalize(&cause, param_env, a);
|
||||
let b = ocx.normalize(&cause, param_env, b);
|
||||
|
||||
if let Err(terr) = ocx.eq(&cause, self.param_env, a, b) {
|
||||
if let Err(terr) = ocx.eq(&cause, param_env, a, b) {
|
||||
trace!(?terr);
|
||||
return false;
|
||||
}
|
||||
@@ -572,7 +564,7 @@ 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.param_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)))?
|
||||
@@ -587,7 +579,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.param_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(..) => {},
|
||||
|
||||
@@ -40,6 +40,7 @@ pub(crate) fn eval_nullary_intrinsic<'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)?;
|
||||
@@ -48,11 +49,13 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>(
|
||||
}
|
||||
sym::needs_drop => {
|
||||
ensure_monomorphic_enough(tcx, tp_ty)?;
|
||||
ConstValue::from_bool(tp_ty.needs_drop(tcx, param_env))
|
||||
ConstValue::from_bool(tp_ty.needs_drop(tcx, typing_env))
|
||||
}
|
||||
sym::pref_align_of => {
|
||||
// Correctly handles non-monomorphic calls, so there is no need for ensure_monomorphic_enough.
|
||||
let layout = tcx.layout_of(param_env.and(tp_ty)).map_err(|e| err_inval!(Layout(*e)))?;
|
||||
let layout = tcx
|
||||
.layout_of(typing_env.as_query_input(tp_ty))
|
||||
.map_err(|e| err_inval!(Layout(*e)))?;
|
||||
ConstValue::from_target_usize(layout.align.pref.bytes(), &tcx)
|
||||
}
|
||||
sym::type_id => {
|
||||
@@ -355,7 +358,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
|
||||
let should_panic = !self
|
||||
.tcx
|
||||
.check_validity_requirement((requirement, self.param_env.and(ty)))
|
||||
.check_validity_requirement((requirement, self.typing_env().as_query_input(ty)))
|
||||
.map_err(|_| err_inval!(TooGeneric))?;
|
||||
|
||||
if should_panic {
|
||||
|
||||
@@ -859,7 +859,7 @@ 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.param_env);
|
||||
let (size, align) = global_alloc.size_and_align(*self.tcx, self.typing_env());
|
||||
let mutbl = global_alloc.mutability(*self.tcx, self.param_env);
|
||||
let kind = match global_alloc {
|
||||
GlobalAlloc::Static { .. } | GlobalAlloc::Memory { .. } => AllocKind::LiveData,
|
||||
|
||||
@@ -8,7 +8,7 @@ use rustc_abi as abi;
|
||||
use rustc_abi::{BackendRepr, HasDataLayout, Size};
|
||||
use rustc_hir::def::Namespace;
|
||||
use rustc_middle::mir::interpret::ScalarSizeMismatch;
|
||||
use rustc_middle::ty::layout::{HasParamEnv, HasTyCtxt, LayoutOf, TyAndLayout};
|
||||
use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutOf, TyAndLayout};
|
||||
use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter};
|
||||
use rustc_middle::ty::{ConstInt, ScalarInt, Ty, TyCtxt};
|
||||
use rustc_middle::{bug, mir, span_bug, ty};
|
||||
@@ -297,21 +297,25 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
|
||||
|
||||
#[inline]
|
||||
pub fn from_bool(b: bool, tcx: TyCtxt<'tcx>) -> Self {
|
||||
let layout = tcx.layout_of(ty::ParamEnv::reveal_all().and(tcx.types.bool)).unwrap();
|
||||
let layout = tcx
|
||||
.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(tcx.types.bool))
|
||||
.unwrap();
|
||||
Self::from_scalar(Scalar::from_bool(b), layout)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn from_ordering(c: std::cmp::Ordering, tcx: TyCtxt<'tcx>) -> Self {
|
||||
let ty = tcx.ty_ordering_enum(None);
|
||||
let layout = tcx.layout_of(ty::ParamEnv::reveal_all().and(ty)).unwrap();
|
||||
let layout =
|
||||
tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)).unwrap();
|
||||
Self::from_scalar(Scalar::from_i8(c as i8), layout)
|
||||
}
|
||||
|
||||
pub fn from_pair(a: Self, b: Self, tcx: TyCtxt<'tcx>) -> Self {
|
||||
let layout = tcx
|
||||
.layout_of(
|
||||
ty::ParamEnv::reveal_all().and(Ty::new_tup(tcx, &[a.layout.ty, b.layout.ty])),
|
||||
ty::TypingEnv::fully_monomorphized()
|
||||
.as_query_input(Ty::new_tup(tcx, &[a.layout.ty, b.layout.ty])),
|
||||
)
|
||||
.unwrap();
|
||||
Self::from_scalar_pair(a.to_scalar(), b.to_scalar(), layout)
|
||||
@@ -341,7 +345,7 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
|
||||
|
||||
#[inline]
|
||||
#[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980)
|
||||
pub fn to_pair(self, cx: &(impl HasTyCtxt<'tcx> + HasParamEnv<'tcx>)) -> (Self, Self) {
|
||||
pub fn to_pair(self, cx: &(impl HasTyCtxt<'tcx> + HasTypingEnv<'tcx>)) -> (Self, Self) {
|
||||
let layout = self.layout;
|
||||
let (val0, val1) = self.to_scalar_pair();
|
||||
(
|
||||
@@ -773,8 +777,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
)?;
|
||||
if !mir_assign_valid_types(
|
||||
*self.tcx,
|
||||
self.typing_mode(),
|
||||
self.param_env,
|
||||
self.typing_env(),
|
||||
self.layout_of(normalized_place_ty)?,
|
||||
op.layout,
|
||||
) {
|
||||
@@ -833,9 +836,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
})
|
||||
};
|
||||
let layout =
|
||||
from_known_layout(self.tcx, self.typing_mode(), self.param_env, layout, || {
|
||||
self.layout_of(ty).into()
|
||||
})?;
|
||||
from_known_layout(self.tcx, self.typing_env(), layout, || self.layout_of(ty).into())?;
|
||||
let imm = match val_val {
|
||||
mir::ConstValue::Indirect { alloc_id, offset } => {
|
||||
// This is const data, no mutation allowed.
|
||||
|
||||
@@ -533,7 +533,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
}
|
||||
OffsetOf(fields) => {
|
||||
let val =
|
||||
self.tcx.offset_of_subfield(self.param_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),
|
||||
|
||||
@@ -540,8 +540,7 @@ where
|
||||
)?;
|
||||
if !mir_assign_valid_types(
|
||||
*self.tcx,
|
||||
self.typing_mode(),
|
||||
self.param_env,
|
||||
self.typing_env(),
|
||||
self.layout_of(normalized_place_ty)?,
|
||||
place.layout,
|
||||
) {
|
||||
@@ -871,13 +870,8 @@ where
|
||||
) -> InterpResult<'tcx> {
|
||||
// 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_mode(),
|
||||
self.param_env,
|
||||
src.layout(),
|
||||
dest.layout(),
|
||||
);
|
||||
let layout_compat =
|
||||
mir_assign_valid_types(*self.tcx, self.typing_env(), src.layout(), dest.layout());
|
||||
if !allow_transmute && !layout_compat {
|
||||
span_bug!(
|
||||
self.cur_span(),
|
||||
|
||||
@@ -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.param_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,13 +596,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
return interp_ok(layout);
|
||||
}
|
||||
|
||||
let layout =
|
||||
from_known_layout(self.tcx, self.typing_mode(), self.param_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)?;
|
||||
self.layout_of(local_ty).into()
|
||||
})?;
|
||||
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)?;
|
||||
self.layout_of(local_ty).into()
|
||||
})?;
|
||||
|
||||
// Layouts of locals are requested a lot, so we cache them.
|
||||
state.layout.set(Some(layout));
|
||||
|
||||
@@ -418,7 +418,8 @@ 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.param_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));
|
||||
|
||||
@@ -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.param_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.param_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 {
|
||||
@@ -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.param_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);
|
||||
|
||||
Reference in New Issue
Block a user