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:
parent
bf6adec108
commit
9cba14b95b
240 changed files with 1739 additions and 1340 deletions
|
@ -102,10 +102,11 @@ impl<'tcx> ConstValue<'tcx> {
|
|||
pub fn try_to_bits_for_ty(
|
||||
&self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> Option<u128> {
|
||||
let size = tcx.layout_of(param_env.with_reveal_all_normalized(tcx).and(ty)).ok()?.size;
|
||||
let size =
|
||||
tcx.layout_of(typing_env.with_reveal_all_normalized(tcx).as_query_input(ty)).ok()?.size;
|
||||
self.try_to_bits(size)
|
||||
}
|
||||
|
||||
|
@ -314,7 +315,7 @@ impl<'tcx> Const<'tcx> {
|
|||
pub fn eval(
|
||||
self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
span: Span,
|
||||
) -> Result<ConstValue<'tcx>, ErrorHandled> {
|
||||
match self {
|
||||
|
@ -333,7 +334,7 @@ impl<'tcx> Const<'tcx> {
|
|||
}
|
||||
Const::Unevaluated(uneval, _) => {
|
||||
// FIXME: We might want to have a `try_eval`-like function on `Unevaluated`
|
||||
tcx.const_eval_resolve(param_env, uneval, span)
|
||||
tcx.const_eval_resolve(typing_env, uneval, span)
|
||||
}
|
||||
Const::Val(val, _) => Ok(val),
|
||||
}
|
||||
|
@ -343,7 +344,7 @@ impl<'tcx> Const<'tcx> {
|
|||
pub fn try_eval_scalar(
|
||||
self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
) -> Option<Scalar> {
|
||||
if let Const::Ty(_, c) = self
|
||||
&& let ty::ConstKind::Value(ty, val) = c.kind()
|
||||
|
@ -354,7 +355,7 @@ impl<'tcx> Const<'tcx> {
|
|||
// pointer here, which valtrees don't represent.)
|
||||
Some(val.unwrap_leaf().into())
|
||||
} else {
|
||||
self.eval(tcx, param_env, DUMMY_SP).ok()?.try_to_scalar()
|
||||
self.eval(tcx, typing_env, DUMMY_SP).ok()?.try_to_scalar()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -362,23 +363,29 @@ impl<'tcx> Const<'tcx> {
|
|||
pub fn try_eval_scalar_int(
|
||||
self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
) -> Option<ScalarInt> {
|
||||
self.try_eval_scalar(tcx, param_env)?.try_to_scalar_int().ok()
|
||||
self.try_eval_scalar(tcx, typing_env)?.try_to_scalar_int().ok()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn try_eval_bits(&self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Option<u128> {
|
||||
let int = self.try_eval_scalar_int(tcx, param_env)?;
|
||||
let size =
|
||||
tcx.layout_of(param_env.with_reveal_all_normalized(tcx).and(self.ty())).ok()?.size;
|
||||
pub fn try_eval_bits(
|
||||
&self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
) -> Option<u128> {
|
||||
let int = self.try_eval_scalar_int(tcx, typing_env)?;
|
||||
let size = tcx
|
||||
.layout_of(typing_env.with_reveal_all_normalized(tcx).as_query_input(self.ty()))
|
||||
.ok()?
|
||||
.size;
|
||||
Some(int.to_bits(size))
|
||||
}
|
||||
|
||||
/// Panics if the value cannot be evaluated or doesn't contain a valid integer of the given type.
|
||||
#[inline]
|
||||
pub fn eval_bits(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> u128 {
|
||||
self.try_eval_bits(tcx, param_env)
|
||||
pub fn eval_bits(self, tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> u128 {
|
||||
self.try_eval_bits(tcx, typing_env)
|
||||
.unwrap_or_else(|| bug!("expected bits of {:#?}, got {:#?}", self.ty(), self))
|
||||
}
|
||||
|
||||
|
@ -386,21 +393,21 @@ impl<'tcx> Const<'tcx> {
|
|||
pub fn try_eval_target_usize(
|
||||
self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
) -> Option<u64> {
|
||||
Some(self.try_eval_scalar_int(tcx, param_env)?.to_target_usize(tcx))
|
||||
Some(self.try_eval_scalar_int(tcx, typing_env)?.to_target_usize(tcx))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Panics if the value cannot be evaluated or doesn't contain a valid `usize`.
|
||||
pub fn eval_target_usize(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> u64 {
|
||||
self.try_eval_target_usize(tcx, param_env)
|
||||
pub fn eval_target_usize(self, tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> u64 {
|
||||
self.try_eval_target_usize(tcx, typing_env)
|
||||
.unwrap_or_else(|| bug!("expected usize, got {:#?}", self))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn try_eval_bool(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Option<bool> {
|
||||
self.try_eval_scalar_int(tcx, param_env)?.try_into().ok()
|
||||
pub fn try_eval_bool(self, tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> Option<bool> {
|
||||
self.try_eval_scalar_int(tcx, typing_env)?.try_into().ok()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -411,17 +418,16 @@ impl<'tcx> Const<'tcx> {
|
|||
pub fn from_bits(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
bits: u128,
|
||||
param_env_ty: ty::ParamEnvAnd<'tcx, Ty<'tcx>>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> Self {
|
||||
let size = tcx
|
||||
.layout_of(param_env_ty)
|
||||
.unwrap_or_else(|e| {
|
||||
bug!("could not compute layout for {:?}: {:?}", param_env_ty.value, e)
|
||||
})
|
||||
.layout_of(typing_env.as_query_input(ty))
|
||||
.unwrap_or_else(|e| bug!("could not compute layout for {ty:?}: {e:?}"))
|
||||
.size;
|
||||
let cv = ConstValue::Scalar(Scalar::from_uint(bits, size));
|
||||
|
||||
Self::Val(cv, param_env_ty.value)
|
||||
Self::Val(cv, ty)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -438,7 +444,8 @@ impl<'tcx> Const<'tcx> {
|
|||
|
||||
pub fn from_usize(tcx: TyCtxt<'tcx>, n: u64) -> Self {
|
||||
let ty = tcx.types.usize;
|
||||
Self::from_bits(tcx, n as u128, ty::ParamEnv::empty().and(ty))
|
||||
let typing_env = ty::TypingEnv::fully_monomorphized();
|
||||
Self::from_bits(tcx, n as u128, typing_env, ty)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
@ -351,7 +351,11 @@ impl<'tcx> GlobalAlloc<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn size_and_align(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> (Size, Align) {
|
||||
pub fn size_and_align(
|
||||
&self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
) -> (Size, Align) {
|
||||
match self {
|
||||
GlobalAlloc::Static(def_id) => {
|
||||
let DefKind::Static { nested, .. } = tcx.def_kind(def_id) else {
|
||||
|
@ -374,7 +378,7 @@ impl<'tcx> GlobalAlloc<'tcx> {
|
|||
.type_of(def_id)
|
||||
.no_bound_vars()
|
||||
.expect("statics should not have generic parameters");
|
||||
let layout = tcx.layout_of(param_env.and(ty)).unwrap();
|
||||
let layout = tcx.layout_of(typing_env.as_query_input(ty)).unwrap();
|
||||
assert!(layout.is_sized());
|
||||
(layout.size, layout.align.abi)
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
#[instrument(level = "debug", skip(self))]
|
||||
pub fn const_eval_resolve(
|
||||
self,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
ct: mir::UnevaluatedConst<'tcx>,
|
||||
span: Span,
|
||||
) -> EvalToConstValueResult<'tcx> {
|
||||
|
@ -72,14 +72,11 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
bug!("did not expect inference variables here");
|
||||
}
|
||||
|
||||
match ty::Instance::try_resolve(
|
||||
self, param_env,
|
||||
// FIXME: maybe have a separate version for resolving mir::UnevaluatedConst?
|
||||
ct.def, ct.args,
|
||||
) {
|
||||
// FIXME: maybe have a separate version for resolving mir::UnevaluatedConst?
|
||||
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(param_env, cid, span)
|
||||
self.const_eval_global_id(typing_env.param_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.
|
||||
|
@ -91,7 +88,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
#[instrument(level = "debug", skip(self))]
|
||||
pub fn const_eval_resolve_for_typeck(
|
||||
self,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
ct: ty::UnevaluatedConst<'tcx>,
|
||||
span: Span,
|
||||
) -> EvalToValTreeResult<'tcx> {
|
||||
|
@ -105,10 +102,10 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
bug!("did not expect inference variables here");
|
||||
}
|
||||
|
||||
match ty::Instance::try_resolve(self, param_env, ct.def, ct.args) {
|
||||
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(param_env, cid, span).inspect(|_| {
|
||||
self.const_eval_global_id_for_typeck(typing_env.param_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.
|
||||
|
|
|
@ -39,7 +39,7 @@ use crate::ty::fold::{FallibleTypeFolder, TypeFoldable};
|
|||
use crate::ty::print::{FmtPrinter, Printer, pretty_print_const, with_no_trimmed_paths};
|
||||
use crate::ty::visit::TypeVisitableExt;
|
||||
use crate::ty::{
|
||||
self, AdtDef, GenericArg, GenericArgsRef, Instance, InstanceKind, List, Ty, TyCtxt, TypingMode,
|
||||
self, AdtDef, GenericArg, GenericArgsRef, Instance, InstanceKind, List, Ty, TyCtxt, TypingEnv,
|
||||
UserTypeAnnotationIndex,
|
||||
};
|
||||
|
||||
|
@ -452,12 +452,17 @@ impl<'tcx> Body<'tcx> {
|
|||
self.basic_blocks.as_mut()
|
||||
}
|
||||
|
||||
pub fn typing_mode(&self, _tcx: TyCtxt<'tcx>) -> TypingMode<'tcx> {
|
||||
pub fn typing_env(&self, tcx: TyCtxt<'tcx>) -> TypingEnv<'tcx> {
|
||||
match self.phase {
|
||||
// FIXME(#132279): the MIR is quite clearly inside of a body, so we
|
||||
// should instead reveal opaques defined by that body here.
|
||||
MirPhase::Built | MirPhase::Analysis(_) => TypingMode::non_body_analysis(),
|
||||
MirPhase::Runtime(_) => TypingMode::PostAnalysis,
|
||||
// FIXME(#132279): we should reveal the opaques defined in the body during analysis.
|
||||
MirPhase::Built | MirPhase::Analysis(_) => TypingEnv {
|
||||
typing_mode: ty::TypingMode::non_body_analysis(),
|
||||
param_env: tcx.param_env(self.source.def_id()),
|
||||
},
|
||||
MirPhase::Runtime(_) => TypingEnv {
|
||||
typing_mode: ty::TypingMode::PostAnalysis,
|
||||
param_env: tcx.param_env_reveal_all_normalized(self.source.def_id()),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -618,7 +623,7 @@ impl<'tcx> Body<'tcx> {
|
|||
}
|
||||
|
||||
/// If this basic block ends with a [`TerminatorKind::SwitchInt`] for which we can evaluate the
|
||||
/// dimscriminant in monomorphization, we return the discriminant bits and the
|
||||
/// discriminant in monomorphization, we return the discriminant bits and the
|
||||
/// [`SwitchTargets`], just so the caller doesn't also have to match on the terminator.
|
||||
fn try_const_mono_switchint<'a>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
|
@ -627,13 +632,15 @@ impl<'tcx> Body<'tcx> {
|
|||
) -> Option<(u128, &'a SwitchTargets)> {
|
||||
// There are two places here we need to evaluate a constant.
|
||||
let eval_mono_const = |constant: &ConstOperand<'tcx>| {
|
||||
let env = ty::ParamEnv::reveal_all();
|
||||
// FIXME(#132279): what is this, why are we using an empty environment with
|
||||
// `RevealAll` here.
|
||||
let typing_env = ty::TypingEnv::fully_monomorphized();
|
||||
let mono_literal = instance.instantiate_mir_and_normalize_erasing_regions(
|
||||
tcx,
|
||||
env,
|
||||
typing_env,
|
||||
crate::ty::EarlyBinder::bind(constant.const_),
|
||||
);
|
||||
mono_literal.try_eval_bits(tcx, env)
|
||||
mono_literal.try_eval_bits(tcx, typing_env)
|
||||
};
|
||||
|
||||
let TerminatorKind::SwitchInt { discr, targets } = &block.terminator().kind else {
|
||||
|
|
|
@ -332,9 +332,9 @@ impl<'tcx> Operand<'tcx> {
|
|||
span: Span,
|
||||
) -> Operand<'tcx> {
|
||||
debug_assert!({
|
||||
let param_env_and_ty = ty::ParamEnv::empty().and(ty);
|
||||
let typing_env = ty::TypingEnv::fully_monomorphized();
|
||||
let type_size = tcx
|
||||
.layout_of(param_env_and_ty)
|
||||
.layout_of(typing_env.as_query_input(ty))
|
||||
.unwrap_or_else(|e| panic!("could not compute layout for {ty:?}: {e:?}"))
|
||||
.size;
|
||||
let scalar_size = match val {
|
||||
|
|
|
@ -20,7 +20,7 @@ use smallvec::SmallVec;
|
|||
use super::{BasicBlock, Const, Local, UserTypeProjection};
|
||||
use crate::mir::coverage::CoverageKind;
|
||||
use crate::ty::adjustment::PointerCoercion;
|
||||
use crate::ty::{self, GenericArgsRef, List, Region, Ty, TyCtxt, UserTypeAnnotationIndex};
|
||||
use crate::ty::{self, GenericArgsRef, List, Region, Ty, UserTypeAnnotationIndex};
|
||||
|
||||
/// Represents the "flavors" of MIR.
|
||||
///
|
||||
|
@ -100,13 +100,6 @@ impl MirPhase {
|
|||
MirPhase::Runtime(RuntimePhase::Optimized) => "runtime-optimized",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn param_env<'tcx>(&self, tcx: TyCtxt<'tcx>, body_def_id: DefId) -> ty::ParamEnv<'tcx> {
|
||||
match self {
|
||||
MirPhase::Built | MirPhase::Analysis(_) => tcx.param_env(body_def_id),
|
||||
MirPhase::Runtime(_) => tcx.param_env_reveal_all_normalized(body_def_id),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// See [`MirPhase::Analysis`].
|
||||
|
|
|
@ -467,6 +467,18 @@ impl<'tcx, T: Key> Key for ty::ParamEnvAnd<'tcx, T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T: Key> Key for ty::PseudoCanonicalInput<'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 Key for Symbol {
|
||||
type Cache<V> = DefaultCache<Self, V>;
|
||||
|
||||
|
@ -575,7 +587,7 @@ impl Key for (LocalDefId, HirId) {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Key for (ValidityRequirement, ty::ParamEnvAnd<'tcx, Ty<'tcx>>) {
|
||||
impl<'tcx> Key for (ValidityRequirement, ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) {
|
||||
type Cache<V> = DefaultCache<Self, V>;
|
||||
|
||||
// Just forward to `Ty<'tcx>`
|
||||
|
|
|
@ -81,8 +81,8 @@ use crate::ty::layout::ValidityRequirement;
|
|||
use crate::ty::print::{PrintTraitRefExt, describe_as_module};
|
||||
use crate::ty::util::AlwaysRequiresDrop;
|
||||
use crate::ty::{
|
||||
self, CrateInherentImpls, GenericArg, GenericArgsRef, ParamEnvAnd, Ty, TyCtxt, TyCtxtFeed,
|
||||
UnusedGenericParams,
|
||||
self, CrateInherentImpls, GenericArg, GenericArgsRef, PseudoCanonicalInput, Ty, TyCtxt,
|
||||
TyCtxtFeed, UnusedGenericParams,
|
||||
};
|
||||
use crate::{dep_graph, mir, thir};
|
||||
|
||||
|
@ -1341,10 +1341,10 @@ rustc_queries! {
|
|||
}
|
||||
|
||||
query codegen_select_candidate(
|
||||
key: (ty::ParamEnv<'tcx>, ty::TraitRef<'tcx>)
|
||||
key: PseudoCanonicalInput<'tcx, ty::TraitRef<'tcx>>
|
||||
) -> Result<&'tcx ImplSource<'tcx, ()>, CodegenObligationError> {
|
||||
cache_on_disk_if { true }
|
||||
desc { |tcx| "computing candidate for `{}`", key.1 }
|
||||
desc { |tcx| "computing candidate for `{}`", key.value }
|
||||
}
|
||||
|
||||
/// Return all `impl` blocks in the current crate.
|
||||
|
@ -1406,15 +1406,15 @@ rustc_queries! {
|
|||
desc { "computing whether `{}` is `Unpin`", env.value }
|
||||
}
|
||||
/// Query backing `Ty::needs_drop`.
|
||||
query needs_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
|
||||
query needs_drop_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool {
|
||||
desc { "computing whether `{}` needs drop", env.value }
|
||||
}
|
||||
/// Query backing `Ty::needs_async_drop`.
|
||||
query needs_async_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
|
||||
query needs_async_drop_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool {
|
||||
desc { "computing whether `{}` needs async drop", env.value }
|
||||
}
|
||||
/// Query backing `Ty::has_significant_drop_raw`.
|
||||
query has_significant_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
|
||||
query has_significant_drop_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool {
|
||||
desc { "computing whether `{}` has a significant drop", env.value }
|
||||
}
|
||||
|
||||
|
@ -1451,7 +1451,7 @@ rustc_queries! {
|
|||
/// Computes the layout of a type. Note that this implicitly
|
||||
/// executes in "reveal all" mode, and will normalize the input type.
|
||||
query layout_of(
|
||||
key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>
|
||||
key: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>
|
||||
) -> Result<ty::layout::TyAndLayout<'tcx>, &'tcx ty::layout::LayoutError<'tcx>> {
|
||||
depth_limit
|
||||
desc { "computing layout of `{}`", key.value }
|
||||
|
@ -1464,7 +1464,7 @@ rustc_queries! {
|
|||
/// NB: this doesn't handle virtual calls - those should use `fn_abi_of_instance`
|
||||
/// instead, where the instance is an `InstanceKind::Virtual`.
|
||||
query fn_abi_of_fn_ptr(
|
||||
key: ty::ParamEnvAnd<'tcx, (ty::PolyFnSig<'tcx>, &'tcx ty::List<Ty<'tcx>>)>
|
||||
key: ty::PseudoCanonicalInput<'tcx, (ty::PolyFnSig<'tcx>, &'tcx ty::List<Ty<'tcx>>)>
|
||||
) -> Result<&'tcx rustc_target::callconv::FnAbi<'tcx, Ty<'tcx>>, &'tcx ty::layout::FnAbiError<'tcx>> {
|
||||
desc { "computing call ABI of `{}` function pointers", key.value.0 }
|
||||
}
|
||||
|
@ -1475,7 +1475,7 @@ rustc_queries! {
|
|||
/// NB: that includes virtual calls, which are represented by "direct calls"
|
||||
/// to an `InstanceKind::Virtual` instance (of `<dyn Trait as Trait>::fn`).
|
||||
query fn_abi_of_instance(
|
||||
key: ty::ParamEnvAnd<'tcx, (ty::Instance<'tcx>, &'tcx ty::List<Ty<'tcx>>)>
|
||||
key: ty::PseudoCanonicalInput<'tcx, (ty::Instance<'tcx>, &'tcx ty::List<Ty<'tcx>>)>
|
||||
) -> Result<&'tcx rustc_target::callconv::FnAbi<'tcx, Ty<'tcx>>, &'tcx ty::layout::FnAbiError<'tcx>> {
|
||||
desc { "computing call ABI of `{}`", key.value.0 }
|
||||
}
|
||||
|
@ -2088,7 +2088,7 @@ rustc_queries! {
|
|||
|
||||
/// Do not call this query directly: invoke `try_normalize_erasing_regions` instead.
|
||||
query try_normalize_generic_arg_after_erasing_regions(
|
||||
goal: ParamEnvAnd<'tcx, GenericArg<'tcx>>
|
||||
goal: PseudoCanonicalInput<'tcx, GenericArg<'tcx>>
|
||||
) -> Result<GenericArg<'tcx>, NoSolution> {
|
||||
desc { "normalizing `{}`", goal.value }
|
||||
}
|
||||
|
@ -2245,7 +2245,7 @@ rustc_queries! {
|
|||
/// from `Ok(None)` to avoid misleading diagnostics when an error
|
||||
/// has already been/will be emitted, for the original cause.
|
||||
query resolve_instance_raw(
|
||||
key: ty::ParamEnvAnd<'tcx, (DefId, GenericArgsRef<'tcx>)>
|
||||
key: ty::PseudoCanonicalInput<'tcx, (DefId, GenericArgsRef<'tcx>)>
|
||||
) -> Result<Option<ty::Instance<'tcx>>, ErrorGuaranteed> {
|
||||
desc { "resolving instance `{}`", ty::Instance::new(key.value.0, key.value.1) }
|
||||
}
|
||||
|
@ -2283,7 +2283,7 @@ rustc_queries! {
|
|||
desc { "computing the backend features for CLI flags" }
|
||||
}
|
||||
|
||||
query check_validity_requirement(key: (ValidityRequirement, ty::ParamEnvAnd<'tcx, Ty<'tcx>>)) -> Result<bool, &'tcx ty::layout::LayoutError<'tcx>> {
|
||||
query check_validity_requirement(key: (ValidityRequirement, ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>)) -> Result<bool, &'tcx ty::layout::LayoutError<'tcx>> {
|
||||
desc { "checking validity requirement for `{}`: {}", key.1.value, key.0 }
|
||||
}
|
||||
|
||||
|
|
|
@ -905,7 +905,7 @@ impl<'tcx> PatRange<'tcx> {
|
|||
&self,
|
||||
value: mir::Const<'tcx>,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
) -> Option<bool> {
|
||||
use Ordering::*;
|
||||
debug_assert_eq!(self.ty, value.ty());
|
||||
|
@ -913,10 +913,10 @@ impl<'tcx> PatRange<'tcx> {
|
|||
let value = PatRangeBoundary::Finite(value);
|
||||
// For performance, it's important to only do the second comparison if necessary.
|
||||
Some(
|
||||
match self.lo.compare_with(value, ty, tcx, param_env)? {
|
||||
match self.lo.compare_with(value, ty, tcx, typing_env)? {
|
||||
Less | Equal => true,
|
||||
Greater => false,
|
||||
} && match value.compare_with(self.hi, ty, tcx, param_env)? {
|
||||
} && match value.compare_with(self.hi, ty, tcx, typing_env)? {
|
||||
Less => true,
|
||||
Equal => self.end == RangeEnd::Included,
|
||||
Greater => false,
|
||||
|
@ -929,17 +929,17 @@ impl<'tcx> PatRange<'tcx> {
|
|||
&self,
|
||||
other: &Self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
) -> Option<bool> {
|
||||
use Ordering::*;
|
||||
debug_assert_eq!(self.ty, other.ty);
|
||||
// For performance, it's important to only do the second comparison if necessary.
|
||||
Some(
|
||||
match other.lo.compare_with(self.hi, self.ty, tcx, param_env)? {
|
||||
match other.lo.compare_with(self.hi, self.ty, tcx, typing_env)? {
|
||||
Less => true,
|
||||
Equal => self.end == RangeEnd::Included,
|
||||
Greater => false,
|
||||
} && match self.lo.compare_with(other.hi, self.ty, tcx, param_env)? {
|
||||
} && match self.lo.compare_with(other.hi, self.ty, tcx, typing_env)? {
|
||||
Less => true,
|
||||
Equal => other.end == RangeEnd::Included,
|
||||
Greater => false,
|
||||
|
@ -985,9 +985,14 @@ impl<'tcx> PatRangeBoundary<'tcx> {
|
|||
Self::NegInfinity | Self::PosInfinity => None,
|
||||
}
|
||||
}
|
||||
pub fn eval_bits(self, ty: Ty<'tcx>, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> u128 {
|
||||
pub fn eval_bits(
|
||||
self,
|
||||
ty: Ty<'tcx>,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
) -> u128 {
|
||||
match self {
|
||||
Self::Finite(value) => value.eval_bits(tcx, param_env),
|
||||
Self::Finite(value) => value.eval_bits(tcx, typing_env),
|
||||
Self::NegInfinity => {
|
||||
// Unwrap is ok because the type is known to be numeric.
|
||||
ty.numeric_min_and_max_as_bits(tcx).unwrap().0
|
||||
|
@ -999,13 +1004,13 @@ impl<'tcx> PatRangeBoundary<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(tcx, param_env), level = "debug", ret)]
|
||||
#[instrument(skip(tcx, typing_env), level = "debug", ret)]
|
||||
pub fn compare_with(
|
||||
self,
|
||||
other: Self,
|
||||
ty: Ty<'tcx>,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
) -> Option<Ordering> {
|
||||
use PatRangeBoundary::*;
|
||||
match (self, other) {
|
||||
|
@ -1034,8 +1039,8 @@ impl<'tcx> PatRangeBoundary<'tcx> {
|
|||
_ => {}
|
||||
}
|
||||
|
||||
let a = self.eval_bits(ty, tcx, param_env);
|
||||
let b = other.eval_bits(ty, tcx, param_env);
|
||||
let a = self.eval_bits(ty, tcx, typing_env);
|
||||
let b = other.eval_bits(ty, tcx, typing_env);
|
||||
|
||||
match ty.kind() {
|
||||
ty::Float(ty::FloatTy::F16) => {
|
||||
|
|
|
@ -498,12 +498,13 @@ impl<'tcx> AdtDef<'tcx> {
|
|||
expr_did: DefId,
|
||||
) -> Result<Discr<'tcx>, ErrorGuaranteed> {
|
||||
assert!(self.is_enum());
|
||||
let param_env = tcx.param_env(expr_did);
|
||||
|
||||
let repr_type = self.repr().discr_type();
|
||||
match tcx.const_eval_poly(expr_did) {
|
||||
Ok(val) => {
|
||||
let typing_env = ty::TypingEnv::post_analysis(tcx, expr_did);
|
||||
let ty = repr_type.to_ty(tcx);
|
||||
if let Some(b) = val.try_to_bits_for_ty(tcx, param_env, ty) {
|
||||
if let Some(b) = val.try_to_bits_for_ty(tcx, typing_env, ty) {
|
||||
trace!("discriminants: {} ({:?})", b, repr_type);
|
||||
Ok(Discr { val: b, ty })
|
||||
} else {
|
||||
|
|
|
@ -9,7 +9,7 @@ use tracing::{debug, instrument};
|
|||
|
||||
use crate::middle::resolve_bound_vars as rbv;
|
||||
use crate::mir::interpret::{LitToConstInput, Scalar};
|
||||
use crate::ty::{self, GenericArgs, ParamEnv, ParamEnvAnd, Ty, TyCtxt, TypeVisitableExt};
|
||||
use crate::ty::{self, GenericArgs, Ty, TyCtxt, TypeVisitableExt};
|
||||
|
||||
mod int;
|
||||
mod kind;
|
||||
|
@ -330,17 +330,22 @@ impl<'tcx> Const<'tcx> {
|
|||
None
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Creates a constant with the given integer value and interns it.
|
||||
pub fn from_bits(tcx: TyCtxt<'tcx>, bits: u128, ty: ParamEnvAnd<'tcx, Ty<'tcx>>) -> Self {
|
||||
#[inline]
|
||||
pub fn from_bits(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
bits: u128,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> Self {
|
||||
let size = tcx
|
||||
.layout_of(ty)
|
||||
.layout_of(typing_env.as_query_input(ty))
|
||||
.unwrap_or_else(|e| panic!("could not compute layout for {ty:?}: {e:?}"))
|
||||
.size;
|
||||
ty::Const::new_value(
|
||||
tcx,
|
||||
ty::ValTree::from_scalar_int(ScalarInt::try_from_uint(bits, size).unwrap()),
|
||||
ty.value,
|
||||
ty,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -353,13 +358,13 @@ impl<'tcx> Const<'tcx> {
|
|||
#[inline]
|
||||
/// Creates an interned bool constant.
|
||||
pub fn from_bool(tcx: TyCtxt<'tcx>, v: bool) -> Self {
|
||||
Self::from_bits(tcx, v as u128, ParamEnv::empty().and(tcx.types.bool))
|
||||
Self::from_bits(tcx, v as u128, ty::TypingEnv::fully_monomorphized(), tcx.types.bool)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Creates an interned usize constant.
|
||||
pub fn from_target_usize(tcx: TyCtxt<'tcx>, n: u64) -> Self {
|
||||
Self::from_bits(tcx, n as u128, ParamEnv::empty().and(tcx.types.usize))
|
||||
Self::from_bits(tcx, n as u128, ty::TypingEnv::fully_monomorphized(), tcx.types.usize)
|
||||
}
|
||||
|
||||
/// Panics if self.kind != ty::ConstKind::Value
|
||||
|
@ -393,15 +398,15 @@ impl<'tcx> Const<'tcx> {
|
|||
self.try_to_valtree()?.0.try_to_target_usize(tcx)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Attempts to evaluate the given constant to bits. Can fail to evaluate in the presence of
|
||||
/// generics (or erroneous code) or if the value can't be represented as bits (e.g. because it
|
||||
/// contains const generic parameters or pointers).
|
||||
pub fn try_to_bits(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Option<u128> {
|
||||
#[inline]
|
||||
pub fn try_to_bits(self, tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> Option<u128> {
|
||||
let (scalar, ty) = self.try_to_scalar()?;
|
||||
let scalar = scalar.try_to_scalar_int().ok()?;
|
||||
let size = tcx.layout_of(param_env.with_reveal_all_normalized(tcx).and(ty)).ok()?.size;
|
||||
// if `ty` does not depend on generic parameters, use an empty param_env
|
||||
let input = typing_env.with_reveal_all_normalized(tcx).as_query_input(ty);
|
||||
let size = tcx.layout_of(input).ok()?.size;
|
||||
Some(scalar.to_bits(size))
|
||||
}
|
||||
|
||||
|
|
|
@ -596,8 +596,16 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
|||
self.coroutine_is_async_gen(coroutine_def_id)
|
||||
}
|
||||
|
||||
fn layout_is_pointer_like(self, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
self.layout_of(self.erase_regions(param_env.and(ty)))
|
||||
// We don't use `TypingEnv` here as it's only defined in `rustc_middle` and
|
||||
// `rustc_next_trait_solver` shouldn't have to know about it.
|
||||
fn layout_is_pointer_like(
|
||||
self,
|
||||
typing_mode: ty::TypingMode<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> bool {
|
||||
let typing_env = ty::TypingEnv { typing_mode, param_env };
|
||||
self.layout_of(self.erase_regions(typing_env).as_query_input(self.erase_regions(ty)))
|
||||
.is_ok_and(|layout| layout.layout.is_pointer_like(&self.data_layout))
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ use smallvec::SmallVec;
|
|||
use tracing::instrument;
|
||||
|
||||
use crate::ty::context::TyCtxt;
|
||||
use crate::ty::{self, DefId, OpaqueTypeKey, ParamEnv, Ty};
|
||||
use crate::ty::{self, DefId, OpaqueTypeKey, Ty, TypingEnv};
|
||||
|
||||
/// Represents whether some type is inhabited in a given context.
|
||||
/// Examples of uninhabited types are `!`, `enum Void {}`, or a struct
|
||||
|
@ -35,8 +35,13 @@ pub enum InhabitedPredicate<'tcx> {
|
|||
|
||||
impl<'tcx> InhabitedPredicate<'tcx> {
|
||||
/// Returns true if the corresponding type is inhabited in the given `ParamEnv` and module.
|
||||
pub fn apply(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, module_def_id: DefId) -> bool {
|
||||
self.apply_revealing_opaque(tcx, param_env, module_def_id, &|_| None)
|
||||
pub fn apply(
|
||||
self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
typing_env: TypingEnv<'tcx>,
|
||||
module_def_id: DefId,
|
||||
) -> bool {
|
||||
self.apply_revealing_opaque(tcx, typing_env, module_def_id, &|_| None)
|
||||
}
|
||||
|
||||
/// Returns true if the corresponding type is inhabited in the given `ParamEnv` and module,
|
||||
|
@ -44,13 +49,13 @@ impl<'tcx> InhabitedPredicate<'tcx> {
|
|||
pub fn apply_revealing_opaque(
|
||||
self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ParamEnv<'tcx>,
|
||||
typing_env: TypingEnv<'tcx>,
|
||||
module_def_id: DefId,
|
||||
reveal_opaque: &impl Fn(OpaqueTypeKey<'tcx>) -> Option<Ty<'tcx>>,
|
||||
) -> bool {
|
||||
let Ok(result) = self.apply_inner::<!>(
|
||||
tcx,
|
||||
param_env,
|
||||
typing_env,
|
||||
&mut Default::default(),
|
||||
&|id| Ok(tcx.is_descendant_of(module_def_id, id)),
|
||||
reveal_opaque,
|
||||
|
@ -59,25 +64,25 @@ impl<'tcx> InhabitedPredicate<'tcx> {
|
|||
}
|
||||
|
||||
/// Same as `apply`, but returns `None` if self contains a module predicate
|
||||
pub fn apply_any_module(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Option<bool> {
|
||||
self.apply_inner(tcx, param_env, &mut Default::default(), &|_| Err(()), &|_| None).ok()
|
||||
pub fn apply_any_module(self, tcx: TyCtxt<'tcx>, typing_env: TypingEnv<'tcx>) -> Option<bool> {
|
||||
self.apply_inner(tcx, typing_env, &mut Default::default(), &|_| Err(()), &|_| None).ok()
|
||||
}
|
||||
|
||||
/// Same as `apply`, but `NotInModule(_)` predicates yield `false`. That is,
|
||||
/// privately uninhabited types are considered always uninhabited.
|
||||
pub fn apply_ignore_module(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> bool {
|
||||
pub fn apply_ignore_module(self, tcx: TyCtxt<'tcx>, typing_env: TypingEnv<'tcx>) -> bool {
|
||||
let Ok(result) =
|
||||
self.apply_inner::<!>(tcx, param_env, &mut Default::default(), &|_| Ok(true), &|_| {
|
||||
self.apply_inner::<!>(tcx, typing_env, &mut Default::default(), &|_| Ok(true), &|_| {
|
||||
None
|
||||
});
|
||||
result
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(tcx, param_env, in_module, reveal_opaque), ret)]
|
||||
#[instrument(level = "debug", skip(tcx, typing_env, in_module, reveal_opaque), ret)]
|
||||
fn apply_inner<E: std::fmt::Debug>(
|
||||
self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ParamEnv<'tcx>,
|
||||
typing_env: TypingEnv<'tcx>,
|
||||
eval_stack: &mut SmallVec<[Ty<'tcx>; 1]>, // for cycle detection
|
||||
in_module: &impl Fn(DefId) -> Result<bool, E>,
|
||||
reveal_opaque: &impl Fn(OpaqueTypeKey<'tcx>) -> Option<Ty<'tcx>>,
|
||||
|
@ -94,7 +99,7 @@ impl<'tcx> InhabitedPredicate<'tcx> {
|
|||
// we have a param_env available, we can do better.
|
||||
Self::GenericType(t) => {
|
||||
let normalized_pred = tcx
|
||||
.try_normalize_erasing_regions(param_env, t)
|
||||
.try_normalize_erasing_regions(typing_env, t)
|
||||
.map_or(self, |t| t.inhabited_predicate(tcx));
|
||||
match normalized_pred {
|
||||
// We don't have more information than we started with, so consider inhabited.
|
||||
|
@ -107,7 +112,7 @@ impl<'tcx> InhabitedPredicate<'tcx> {
|
|||
}
|
||||
eval_stack.push(t);
|
||||
let ret =
|
||||
pred.apply_inner(tcx, param_env, eval_stack, in_module, reveal_opaque);
|
||||
pred.apply_inner(tcx, typing_env, eval_stack, in_module, reveal_opaque);
|
||||
eval_stack.pop();
|
||||
ret
|
||||
}
|
||||
|
@ -126,7 +131,7 @@ impl<'tcx> InhabitedPredicate<'tcx> {
|
|||
eval_stack.push(t);
|
||||
let ret = t.inhabited_predicate(tcx).apply_inner(
|
||||
tcx,
|
||||
param_env,
|
||||
typing_env,
|
||||
eval_stack,
|
||||
in_module,
|
||||
reveal_opaque,
|
||||
|
@ -136,10 +141,10 @@ impl<'tcx> InhabitedPredicate<'tcx> {
|
|||
}
|
||||
},
|
||||
Self::And([a, b]) => try_and(a, b, |x| {
|
||||
x.apply_inner(tcx, param_env, eval_stack, in_module, reveal_opaque)
|
||||
x.apply_inner(tcx, typing_env, eval_stack, in_module, reveal_opaque)
|
||||
}),
|
||||
Self::Or([a, b]) => try_or(a, b, |x| {
|
||||
x.apply_inner(tcx, param_env, eval_stack, in_module, reveal_opaque)
|
||||
x.apply_inner(tcx, typing_env, eval_stack, in_module, reveal_opaque)
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -181,18 +181,18 @@ impl<'tcx> Ty<'tcx> {
|
|||
self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
module: DefId,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
) -> bool {
|
||||
self.inhabited_predicate(tcx).apply(tcx, param_env, module)
|
||||
self.inhabited_predicate(tcx).apply(tcx, typing_env, module)
|
||||
}
|
||||
|
||||
/// Returns true if the type is uninhabited without regard to visibility
|
||||
pub fn is_privately_uninhabited(
|
||||
self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
) -> bool {
|
||||
!self.inhabited_predicate(tcx).apply_ignore_module(tcx, param_env)
|
||||
!self.inhabited_predicate(tcx).apply_ignore_module(tcx, typing_env)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -178,9 +178,9 @@ pub enum InstanceKind<'tcx> {
|
|||
impl<'tcx> Instance<'tcx> {
|
||||
/// Returns the `Ty` corresponding to this `Instance`, with generic instantiations applied and
|
||||
/// lifetimes erased, allowing a `ParamEnv` to be specified for use during normalization.
|
||||
pub fn ty(&self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Ty<'tcx> {
|
||||
pub fn ty(&self, tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> Ty<'tcx> {
|
||||
let ty = tcx.type_of(self.def.def_id());
|
||||
tcx.instantiate_and_normalize_erasing_regions(self.args, param_env, ty)
|
||||
tcx.instantiate_and_normalize_erasing_regions(self.args, typing_env, ty)
|
||||
}
|
||||
|
||||
/// Finds a crate that contains a monomorphization of this instance that
|
||||
|
@ -519,7 +519,7 @@ impl<'tcx> Instance<'tcx> {
|
|||
#[instrument(level = "debug", skip(tcx), ret)]
|
||||
pub fn try_resolve(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
def_id: DefId,
|
||||
args: GenericArgsRef<'tcx>,
|
||||
) -> Result<Option<Instance<'tcx>>, ErrorGuaranteed> {
|
||||
|
@ -537,17 +537,14 @@ 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.
|
||||
|
||||
// HACK(eddyb) erase regions in `args` first, so that `param_env.and(...)`
|
||||
// below is more likely to ignore the bounds in scope (e.g. if the only
|
||||
// generic parameters mentioned by `args` were lifetime ones).
|
||||
let typing_env = tcx.erase_regions(typing_env);
|
||||
let args = tcx.erase_regions(args);
|
||||
tcx.resolve_instance_raw(tcx.erase_regions(param_env.and((def_id, args))))
|
||||
tcx.resolve_instance_raw(typing_env.as_query_input((def_id, args)))
|
||||
}
|
||||
|
||||
pub fn expect_resolve(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
def_id: DefId,
|
||||
args: GenericArgsRef<'tcx>,
|
||||
span: Span,
|
||||
|
@ -558,7 +555,7 @@ impl<'tcx> Instance<'tcx> {
|
|||
let span_or_local_def_span =
|
||||
|| if span.is_dummy() && def_id.is_local() { tcx.def_span(def_id) } else { span };
|
||||
|
||||
match ty::Instance::try_resolve(tcx, param_env, def_id, args) {
|
||||
match ty::Instance::try_resolve(tcx, typing_env, def_id, args) {
|
||||
Ok(Some(instance)) => instance,
|
||||
Ok(None) => {
|
||||
let type_length = type_length(args);
|
||||
|
@ -600,7 +597,7 @@ impl<'tcx> Instance<'tcx> {
|
|||
|
||||
pub fn resolve_for_fn_ptr(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
def_id: DefId,
|
||||
args: GenericArgsRef<'tcx>,
|
||||
) -> Option<Instance<'tcx>> {
|
||||
|
@ -608,7 +605,7 @@ impl<'tcx> Instance<'tcx> {
|
|||
// Use either `resolve_closure` or `resolve_for_vtable`
|
||||
assert!(!tcx.is_closure_like(def_id), "Called `resolve_for_fn_ptr` on closure: {def_id:?}");
|
||||
let reason = tcx.sess.is_sanitizer_kcfi_enabled().then_some(ReifyReason::FnPtr);
|
||||
Instance::try_resolve(tcx, param_env, def_id, args).ok().flatten().map(|mut resolved| {
|
||||
Instance::try_resolve(tcx, typing_env, def_id, args).ok().flatten().map(|mut resolved| {
|
||||
match resolved.def {
|
||||
InstanceKind::Item(def) if resolved.def.requires_caller_location(tcx) => {
|
||||
debug!(" => fn pointer created for function with #[track_caller]");
|
||||
|
@ -648,7 +645,7 @@ impl<'tcx> Instance<'tcx> {
|
|||
|
||||
pub fn expect_resolve_for_vtable(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
def_id: DefId,
|
||||
args: GenericArgsRef<'tcx>,
|
||||
span: Span,
|
||||
|
@ -664,7 +661,7 @@ impl<'tcx> Instance<'tcx> {
|
|||
return Instance { def: InstanceKind::VTableShim(def_id), args };
|
||||
}
|
||||
|
||||
let mut resolved = Instance::expect_resolve(tcx, param_env, def_id, args, span);
|
||||
let mut resolved = Instance::expect_resolve(tcx, typing_env, def_id, args, span);
|
||||
|
||||
let reason = tcx.sess.is_sanitizer_kcfi_enabled().then_some(ReifyReason::Vtable);
|
||||
match resolved.def {
|
||||
|
@ -743,7 +740,7 @@ impl<'tcx> Instance<'tcx> {
|
|||
let args = tcx.mk_args(&[ty.into()]);
|
||||
Instance::expect_resolve(
|
||||
tcx,
|
||||
ty::ParamEnv::reveal_all(),
|
||||
ty::TypingEnv::fully_monomorphized(),
|
||||
def_id,
|
||||
args,
|
||||
ty.ty_adt_def().and_then(|adt| tcx.hir().span_if_local(adt.did())).unwrap_or(DUMMY_SP),
|
||||
|
@ -755,7 +752,7 @@ impl<'tcx> Instance<'tcx> {
|
|||
let args = tcx.mk_args(&[ty.into()]);
|
||||
Instance::expect_resolve(
|
||||
tcx,
|
||||
ty::ParamEnv::reveal_all(),
|
||||
ty::TypingEnv::fully_monomorphized(),
|
||||
def_id,
|
||||
args,
|
||||
ty.ty_adt_def().and_then(|adt| tcx.hir().span_if_local(adt.did())).unwrap_or(DUMMY_SP),
|
||||
|
@ -883,16 +880,16 @@ impl<'tcx> Instance<'tcx> {
|
|||
pub fn instantiate_mir_and_normalize_erasing_regions<T>(
|
||||
&self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
v: EarlyBinder<'tcx, T>,
|
||||
) -> T
|
||||
where
|
||||
T: TypeFoldable<TyCtxt<'tcx>>,
|
||||
{
|
||||
if let Some(args) = self.args_for_mir_body() {
|
||||
tcx.instantiate_and_normalize_erasing_regions(args, param_env, v)
|
||||
tcx.instantiate_and_normalize_erasing_regions(args, typing_env, v)
|
||||
} else {
|
||||
tcx.normalize_erasing_regions(param_env, v.instantiate_identity())
|
||||
tcx.normalize_erasing_regions(typing_env, v.instantiate_identity())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -901,21 +898,21 @@ impl<'tcx> Instance<'tcx> {
|
|||
pub fn try_instantiate_mir_and_normalize_erasing_regions<T>(
|
||||
&self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
v: EarlyBinder<'tcx, T>,
|
||||
) -> Result<T, NormalizationError<'tcx>>
|
||||
where
|
||||
T: TypeFoldable<TyCtxt<'tcx>>,
|
||||
{
|
||||
if let Some(args) = self.args_for_mir_body() {
|
||||
tcx.try_instantiate_and_normalize_erasing_regions(args, param_env, v)
|
||||
tcx.try_instantiate_and_normalize_erasing_regions(args, typing_env, v)
|
||||
} else {
|
||||
// We're using `instantiate_identity` as e.g.
|
||||
// `FnPtrShim` is separately generated for every
|
||||
// instantiation of the `FnDef`, so the MIR body
|
||||
// is already instantiated. Any generic parameters it
|
||||
// contains are generic parameters from the caller.
|
||||
tcx.try_normalize_erasing_regions(param_env, v.instantiate_identity())
|
||||
tcx.try_normalize_erasing_regions(typing_env, v.instantiate_identity())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -297,12 +297,12 @@ impl<'tcx> IntoDiagArg for LayoutError<'tcx> {
|
|||
#[derive(Clone, Copy)]
|
||||
pub struct LayoutCx<'tcx> {
|
||||
pub calc: abi::LayoutCalculator<TyCtxt<'tcx>>,
|
||||
pub param_env: ty::ParamEnv<'tcx>,
|
||||
pub typing_env: ty::TypingEnv<'tcx>,
|
||||
}
|
||||
|
||||
impl<'tcx> LayoutCx<'tcx> {
|
||||
pub fn new(tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Self {
|
||||
Self { calc: abi::LayoutCalculator::new(tcx), param_env }
|
||||
pub fn new(tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> Self {
|
||||
Self { calc: abi::LayoutCalculator::new(tcx), typing_env }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -337,12 +337,12 @@ impl<'tcx> SizeSkeleton<'tcx> {
|
|||
pub fn compute(
|
||||
ty: Ty<'tcx>,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
) -> Result<SizeSkeleton<'tcx>, &'tcx LayoutError<'tcx>> {
|
||||
debug_assert!(!ty.has_non_region_infer());
|
||||
|
||||
// First try computing a static layout.
|
||||
let err = match tcx.layout_of(param_env.and(ty)) {
|
||||
let err = match tcx.layout_of(typing_env.as_query_input(ty)) {
|
||||
Ok(layout) => {
|
||||
if layout.is_sized() {
|
||||
return Ok(SizeSkeleton::Known(layout.size, Some(layout.align.abi)));
|
||||
|
@ -367,7 +367,7 @@ impl<'tcx> SizeSkeleton<'tcx> {
|
|||
|
||||
let tail = tcx.struct_tail_raw(
|
||||
pointee,
|
||||
|ty| match tcx.try_normalize_erasing_regions(param_env, ty) {
|
||||
|ty| match tcx.try_normalize_erasing_regions(typing_env, ty) {
|
||||
Ok(ty) => ty,
|
||||
Err(e) => Ty::new_error_with_message(
|
||||
tcx,
|
||||
|
@ -402,7 +402,7 @@ impl<'tcx> SizeSkeleton<'tcx> {
|
|||
return Ok(SizeSkeleton::Known(Size::from_bytes(0), None));
|
||||
}
|
||||
|
||||
match SizeSkeleton::compute(inner, tcx, param_env)? {
|
||||
match SizeSkeleton::compute(inner, tcx, typing_env)? {
|
||||
// This may succeed because the multiplication of two types may overflow
|
||||
// but a single size of a nested array will not.
|
||||
SizeSkeleton::Known(s, a) => {
|
||||
|
@ -432,7 +432,7 @@ impl<'tcx> SizeSkeleton<'tcx> {
|
|||
let i = VariantIdx::from_usize(i);
|
||||
let fields =
|
||||
def.variant(i).fields.iter().map(|field| {
|
||||
SizeSkeleton::compute(field.ty(tcx, args), tcx, param_env)
|
||||
SizeSkeleton::compute(field.ty(tcx, args), tcx, typing_env)
|
||||
});
|
||||
let mut ptr = None;
|
||||
for field in fields {
|
||||
|
@ -491,11 +491,11 @@ impl<'tcx> SizeSkeleton<'tcx> {
|
|||
}
|
||||
|
||||
ty::Alias(..) => {
|
||||
let normalized = tcx.normalize_erasing_regions(param_env, ty);
|
||||
let normalized = tcx.normalize_erasing_regions(typing_env, ty);
|
||||
if ty == normalized {
|
||||
Err(err)
|
||||
} else {
|
||||
SizeSkeleton::compute(normalized, tcx, param_env)
|
||||
SizeSkeleton::compute(normalized, tcx, typing_env)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -521,8 +521,14 @@ pub trait HasTyCtxt<'tcx>: HasDataLayout {
|
|||
fn tcx(&self) -> TyCtxt<'tcx>;
|
||||
}
|
||||
|
||||
pub trait HasParamEnv<'tcx> {
|
||||
fn param_env(&self) -> ty::ParamEnv<'tcx>;
|
||||
pub trait HasTypingEnv<'tcx> {
|
||||
fn typing_env(&self) -> ty::TypingEnv<'tcx>;
|
||||
|
||||
/// FIXME(#132279): This method should not be used as in the future
|
||||
/// everything should take a `TypingEnv` instead. Remove it as that point.
|
||||
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
||||
self.typing_env().param_env
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> HasDataLayout for TyCtxt<'tcx> {
|
||||
|
@ -577,9 +583,9 @@ impl<'tcx> HasTyCtxt<'tcx> for TyCtxtAt<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> HasParamEnv<'tcx> for LayoutCx<'tcx> {
|
||||
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
||||
self.param_env
|
||||
impl<'tcx> HasTypingEnv<'tcx> for LayoutCx<'tcx> {
|
||||
fn typing_env(&self) -> ty::TypingEnv<'tcx> {
|
||||
self.typing_env
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -646,7 +652,7 @@ pub type TyAndLayout<'tcx> = rustc_abi::TyAndLayout<'tcx, Ty<'tcx>>;
|
|||
|
||||
/// Trait for contexts that want to be able to compute layouts of types.
|
||||
/// This automatically gives access to `LayoutOf`, through a blanket `impl`.
|
||||
pub trait LayoutOfHelpers<'tcx>: HasDataLayout + HasTyCtxt<'tcx> + HasParamEnv<'tcx> {
|
||||
pub trait LayoutOfHelpers<'tcx>: HasDataLayout + HasTyCtxt<'tcx> + HasTypingEnv<'tcx> {
|
||||
/// The `TyAndLayout`-wrapping type (or `TyAndLayout` itself), which will be
|
||||
/// returned from `layout_of` (see also `handle_layout_err`).
|
||||
type LayoutOfResult: MaybeResult<TyAndLayout<'tcx>> = TyAndLayout<'tcx>;
|
||||
|
@ -692,7 +698,7 @@ pub trait LayoutOf<'tcx>: LayoutOfHelpers<'tcx> {
|
|||
let tcx = self.tcx().at(span);
|
||||
|
||||
MaybeResult::from(
|
||||
tcx.layout_of(self.param_env().and(ty))
|
||||
tcx.layout_of(self.typing_env().as_query_input(ty))
|
||||
.map_err(|err| self.handle_layout_err(*err, span, ty)),
|
||||
)
|
||||
}
|
||||
|
@ -716,7 +722,7 @@ impl<'tcx> LayoutOfHelpers<'tcx> for LayoutCx<'tcx> {
|
|||
|
||||
impl<'tcx, C> TyAbiInterface<'tcx, C> for Ty<'tcx>
|
||||
where
|
||||
C: HasTyCtxt<'tcx> + HasParamEnv<'tcx>,
|
||||
C: HasTyCtxt<'tcx> + HasTypingEnv<'tcx>,
|
||||
{
|
||||
fn ty_and_layout_for_variant(
|
||||
this: TyAndLayout<'tcx>,
|
||||
|
@ -736,10 +742,10 @@ where
|
|||
|
||||
Variants::Single { index } => {
|
||||
let tcx = cx.tcx();
|
||||
let param_env = cx.param_env();
|
||||
let typing_env = cx.typing_env();
|
||||
|
||||
// Deny calling for_variant more than once for non-Single enums.
|
||||
if let Ok(original_layout) = tcx.layout_of(param_env.and(this.ty)) {
|
||||
if let Ok(original_layout) = tcx.layout_of(typing_env.as_query_input(this.ty)) {
|
||||
assert_eq!(original_layout.variants, Variants::Single { index });
|
||||
}
|
||||
|
||||
|
@ -780,7 +786,7 @@ where
|
|||
|
||||
fn field_ty_or_layout<'tcx>(
|
||||
this: TyAndLayout<'tcx>,
|
||||
cx: &(impl HasTyCtxt<'tcx> + HasParamEnv<'tcx>),
|
||||
cx: &(impl HasTyCtxt<'tcx> + HasTypingEnv<'tcx>),
|
||||
i: usize,
|
||||
) -> TyMaybeWithLayout<'tcx> {
|
||||
let tcx = cx.tcx();
|
||||
|
@ -823,12 +829,13 @@ where
|
|||
Ty::new_mut_ref(tcx, tcx.lifetimes.re_static, nil)
|
||||
};
|
||||
|
||||
// NOTE(eddyb) using an empty `ParamEnv`, and `unwrap`-ing
|
||||
// the `Result` should always work because the type is
|
||||
// always either `*mut ()` or `&'static mut ()`.
|
||||
// NOTE: using an fully monomorphized typing env and `unwrap`-ing
|
||||
// the `Result` should always work because the type is always either
|
||||
// `*mut ()` or `&'static mut ()`.
|
||||
let typing_env = ty::TypingEnv::fully_monomorphized();
|
||||
return TyMaybeWithLayout::TyAndLayout(TyAndLayout {
|
||||
ty: this.ty,
|
||||
..tcx.layout_of(ty::ParamEnv::reveal_all().and(unit_ptr_ty)).unwrap()
|
||||
..tcx.layout_of(typing_env.as_query_input(unit_ptr_ty)).unwrap()
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -848,7 +855,7 @@ where
|
|||
&& !pointee.references_error()
|
||||
{
|
||||
let metadata = tcx.normalize_erasing_regions(
|
||||
cx.param_env(),
|
||||
cx.typing_env(),
|
||||
Ty::new_projection(tcx, metadata_def_id, [pointee]),
|
||||
);
|
||||
|
||||
|
@ -865,7 +872,7 @@ where
|
|||
metadata
|
||||
}
|
||||
} else {
|
||||
match tcx.struct_tail_for_codegen(pointee, cx.param_env()).kind() {
|
||||
match tcx.struct_tail_for_codegen(pointee, cx.typing_env()).kind() {
|
||||
ty::Slice(_) | ty::Str => tcx.types.usize,
|
||||
ty::Dynamic(data, _, ty::Dyn) => mk_dyn_vtable(data.principal()),
|
||||
_ => bug!("TyAndLayout::field({:?}): not applicable", this),
|
||||
|
@ -953,7 +960,7 @@ where
|
|||
|
||||
match field_ty_or_layout(this, cx, i) {
|
||||
TyMaybeWithLayout::Ty(field_ty) => {
|
||||
cx.tcx().layout_of(cx.param_env().and(field_ty)).unwrap_or_else(|e| {
|
||||
cx.tcx().layout_of(cx.typing_env().as_query_input(field_ty)).unwrap_or_else(|e| {
|
||||
bug!(
|
||||
"failed to get layout for `{field_ty}`: {e:?},\n\
|
||||
despite it being a field (#{i}) of an existing layout: {this:#?}",
|
||||
|
@ -972,18 +979,18 @@ where
|
|||
offset: Size,
|
||||
) -> Option<PointeeInfo> {
|
||||
let tcx = cx.tcx();
|
||||
let param_env = cx.param_env();
|
||||
let typing_env = cx.typing_env();
|
||||
|
||||
let pointee_info = match *this.ty.kind() {
|
||||
ty::RawPtr(p_ty, _) if offset.bytes() == 0 => {
|
||||
tcx.layout_of(param_env.and(p_ty)).ok().map(|layout| PointeeInfo {
|
||||
tcx.layout_of(typing_env.as_query_input(p_ty)).ok().map(|layout| PointeeInfo {
|
||||
size: layout.size,
|
||||
align: layout.align.abi,
|
||||
safe: None,
|
||||
})
|
||||
}
|
||||
ty::FnPtr(..) if offset.bytes() == 0 => {
|
||||
tcx.layout_of(param_env.and(this.ty)).ok().map(|layout| PointeeInfo {
|
||||
tcx.layout_of(typing_env.as_query_input(this.ty)).ok().map(|layout| PointeeInfo {
|
||||
size: layout.size,
|
||||
align: layout.align.abi,
|
||||
safe: None,
|
||||
|
@ -996,14 +1003,14 @@ where
|
|||
let optimize = tcx.sess.opts.optimize != OptLevel::No;
|
||||
let kind = match mt {
|
||||
hir::Mutability::Not => PointerKind::SharedRef {
|
||||
frozen: optimize && ty.is_freeze(tcx, cx.param_env()),
|
||||
frozen: optimize && ty.is_freeze(tcx, typing_env.param_env),
|
||||
},
|
||||
hir::Mutability::Mut => PointerKind::MutableRef {
|
||||
unpin: optimize && ty.is_unpin(tcx, cx.param_env()),
|
||||
unpin: optimize && ty.is_unpin(tcx, typing_env.param_env),
|
||||
},
|
||||
};
|
||||
|
||||
tcx.layout_of(param_env.and(ty)).ok().map(|layout| PointeeInfo {
|
||||
tcx.layout_of(typing_env.as_query_input(ty)).ok().map(|layout| PointeeInfo {
|
||||
size: layout.size,
|
||||
align: layout.align.abi,
|
||||
safe: Some(kind),
|
||||
|
@ -1093,7 +1100,7 @@ where
|
|||
debug_assert!(pointee.safe.is_none());
|
||||
let optimize = tcx.sess.opts.optimize != OptLevel::No;
|
||||
pointee.safe = Some(PointerKind::Box {
|
||||
unpin: optimize && boxed_ty.is_unpin(tcx, cx.param_env()),
|
||||
unpin: optimize && boxed_ty.is_unpin(tcx, typing_env.param_env),
|
||||
global: this.ty.is_box_global(tcx),
|
||||
});
|
||||
}
|
||||
|
@ -1304,9 +1311,11 @@ pub trait FnAbiOf<'tcx>: FnAbiOfHelpers<'tcx> {
|
|||
let span = self.layout_tcx_at_span();
|
||||
let tcx = self.tcx().at(span);
|
||||
|
||||
MaybeResult::from(tcx.fn_abi_of_fn_ptr(self.param_env().and((sig, extra_args))).map_err(
|
||||
|err| self.handle_fn_abi_err(*err, span, FnAbiRequest::OfFnPtr { sig, extra_args }),
|
||||
))
|
||||
MaybeResult::from(
|
||||
tcx.fn_abi_of_fn_ptr(self.typing_env().as_query_input((sig, extra_args))).map_err(
|
||||
|err| self.handle_fn_abi_err(*err, span, FnAbiRequest::OfFnPtr { sig, extra_args }),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
/// Compute a `FnAbi` suitable for declaring/defining an `fn` instance, and for
|
||||
|
@ -1326,17 +1335,19 @@ pub trait FnAbiOf<'tcx>: FnAbiOfHelpers<'tcx> {
|
|||
let tcx = self.tcx().at(span);
|
||||
|
||||
MaybeResult::from(
|
||||
tcx.fn_abi_of_instance(self.param_env().and((instance, extra_args))).map_err(|err| {
|
||||
// HACK(eddyb) at least for definitions of/calls to `Instance`s,
|
||||
// we can get some kind of span even if one wasn't provided.
|
||||
// However, we don't do this early in order to avoid calling
|
||||
// `def_span` unconditionally (which may have a perf penalty).
|
||||
let span = if !span.is_dummy() { span } else { tcx.def_span(instance.def_id()) };
|
||||
self.handle_fn_abi_err(*err, span, FnAbiRequest::OfInstance {
|
||||
instance,
|
||||
extra_args,
|
||||
})
|
||||
}),
|
||||
tcx.fn_abi_of_instance(self.typing_env().as_query_input((instance, extra_args)))
|
||||
.map_err(|err| {
|
||||
// HACK(eddyb) at least for definitions of/calls to `Instance`s,
|
||||
// we can get some kind of span even if one wasn't provided.
|
||||
// However, we don't do this early in order to avoid calling
|
||||
// `def_span` unconditionally (which may have a perf penalty).
|
||||
let span =
|
||||
if !span.is_dummy() { span } else { tcx.def_span(instance.def_id()) };
|
||||
self.handle_fn_abi_err(*err, span, FnAbiRequest::OfInstance {
|
||||
instance,
|
||||
extra_args,
|
||||
})
|
||||
}),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -1346,14 +1357,14 @@ impl<'tcx, C: FnAbiOfHelpers<'tcx>> FnAbiOf<'tcx> for C {}
|
|||
impl<'tcx> TyCtxt<'tcx> {
|
||||
pub fn offset_of_subfield<I>(
|
||||
self,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
mut layout: TyAndLayout<'tcx>,
|
||||
indices: I,
|
||||
) -> Size
|
||||
where
|
||||
I: Iterator<Item = (VariantIdx, FieldIdx)>,
|
||||
{
|
||||
let cx = LayoutCx::new(self, param_env);
|
||||
let cx = LayoutCx::new(self, typing_env);
|
||||
let mut offset = Size::ZERO;
|
||||
|
||||
for (variant, field) in indices {
|
||||
|
@ -1363,7 +1374,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
layout = layout.field(&cx, index);
|
||||
if !layout.is_sized() {
|
||||
// If it is not sized, then the tail must still have at least a known static alignment.
|
||||
let tail = self.struct_tail_for_codegen(layout.ty, param_env);
|
||||
let tail = self.struct_tail_for_codegen(layout.ty, typing_env);
|
||||
if !matches!(tail.kind(), ty::Slice(..)) {
|
||||
bug!(
|
||||
"offset of not-statically-aligned field (type {:?}) cannot be computed statically",
|
||||
|
|
|
@ -103,7 +103,7 @@ use crate::error::{OpaqueHiddenTypeMismatch, TypeMismatchReason};
|
|||
use crate::metadata::ModChild;
|
||||
use crate::middle::privacy::EffectiveVisibilities;
|
||||
use crate::mir::{Body, CoroutineLayout};
|
||||
use crate::query::Providers;
|
||||
use crate::query::{IntoQueryParam, Providers};
|
||||
use crate::traits::{self, Reveal};
|
||||
use crate::ty;
|
||||
pub use crate::ty::diagnostics::*;
|
||||
|
@ -1122,6 +1122,104 @@ impl<'tcx, T> ParamEnvAnd<'tcx, T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// The environment in which to do trait solving.
|
||||
///
|
||||
/// Most of the time you only need to care about the `ParamEnv`
|
||||
/// as the `TypingMode` is simply stored in the `InferCtxt`.
|
||||
///
|
||||
/// However, there are some places which rely on trait solving
|
||||
/// without using an `InferCtxt` themselves. For these to be
|
||||
/// able to use the trait system they have to be able to initialize
|
||||
/// such an `InferCtxt` with the right `typing_mode`, so they need
|
||||
/// to track both.
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)]
|
||||
#[derive(TypeVisitable, TypeFoldable)]
|
||||
pub struct TypingEnv<'tcx> {
|
||||
pub typing_mode: TypingMode<'tcx>,
|
||||
pub param_env: ParamEnv<'tcx>,
|
||||
}
|
||||
|
||||
impl<'tcx> TypingEnv<'tcx> {
|
||||
// FIXME(#132279): This method should be removed but simplifies the
|
||||
// transition.
|
||||
pub fn from_param_env(param_env: ParamEnv<'tcx>) -> TypingEnv<'tcx> {
|
||||
TypingEnv { typing_mode: TypingMode::from_param_env(param_env), param_env }
|
||||
}
|
||||
|
||||
/// Create a typing environment with no where-clauses in scope
|
||||
/// where all opaque types and default associated items are revealed.
|
||||
///
|
||||
/// This is only suitable for monomorphized, post-typeck environments.
|
||||
/// Do not use this for MIR optimizations, as even though they also
|
||||
/// use `TypingMode::PostAnalysis`, they may still have where-clauses
|
||||
/// in scope.
|
||||
pub fn fully_monomorphized() -> TypingEnv<'tcx> {
|
||||
TypingEnv { typing_mode: TypingMode::PostAnalysis, param_env: ParamEnv::reveal_all() }
|
||||
}
|
||||
|
||||
/// Create a typing environment for use during analysis outside of a body.
|
||||
///
|
||||
/// Using a typing environment inside of bodies is not supported as the body
|
||||
/// may define opaque types. In this case the used functions have to be
|
||||
/// converted to use proper canonical inputs instead.
|
||||
pub fn non_body_analysis(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def_id: impl IntoQueryParam<DefId>,
|
||||
) -> TypingEnv<'tcx> {
|
||||
TypingEnv { typing_mode: TypingMode::non_body_analysis(), param_env: tcx.param_env(def_id) }
|
||||
}
|
||||
|
||||
pub fn post_analysis(tcx: TyCtxt<'tcx>, def_id: impl IntoQueryParam<DefId>) -> TypingEnv<'tcx> {
|
||||
TypingEnv {
|
||||
typing_mode: TypingMode::PostAnalysis,
|
||||
param_env: tcx.param_env_reveal_all_normalized(def_id),
|
||||
}
|
||||
}
|
||||
|
||||
/// Modify the `typing_mode` to `PostAnalysis` and eagerly reveal all
|
||||
/// opaque types in the `param_env`.
|
||||
pub fn with_reveal_all_normalized(self, tcx: TyCtxt<'tcx>) -> TypingEnv<'tcx> {
|
||||
let TypingEnv { typing_mode: _, param_env } = self;
|
||||
let param_env = param_env.with_reveal_all_normalized(tcx);
|
||||
TypingEnv { typing_mode: TypingMode::PostAnalysis, param_env }
|
||||
}
|
||||
|
||||
/// Combine this typing environment with the given `value` to be used by
|
||||
/// not (yet) canonicalized queries. This only works if the value does not
|
||||
/// contain anything local to some `InferCtxt`, i.e. inference variables or
|
||||
/// placeholders.
|
||||
pub fn as_query_input<T>(self, value: T) -> PseudoCanonicalInput<'tcx, T>
|
||||
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
|
||||
// placeholders. We should also simply not use pseudo-canonical queries in the trait
|
||||
// solver, at which point we can readd this assert.
|
||||
//
|
||||
// debug_assert!(!value.has_placeholders());
|
||||
PseudoCanonicalInput { typing_env: self, value }
|
||||
}
|
||||
}
|
||||
|
||||
/// Similar to `CanonicalInput`, this carries the `typing_mode` and the environment
|
||||
/// necessary to do any kind of trait solving inside of nested queries.
|
||||
///
|
||||
/// Unlike proper canonicalization, this requires the `param_env` and the `value` to not
|
||||
/// contain anything local to the `infcx` of the caller, so we don't actually canonicalize
|
||||
/// anything.
|
||||
///
|
||||
/// 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)]
|
||||
pub struct PseudoCanonicalInput<'tcx, T> {
|
||||
pub typing_env: TypingEnv<'tcx>,
|
||||
pub value: T,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, HashStable, Encodable, Decodable)]
|
||||
pub struct Destructor {
|
||||
/// The `DefId` of the destructor method
|
||||
|
|
|
@ -35,16 +35,16 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
///
|
||||
/// This should only be used outside of type inference. For example,
|
||||
/// it assumes that normalization will succeed.
|
||||
#[tracing::instrument(level = "debug", skip(self, param_env), ret)]
|
||||
pub fn normalize_erasing_regions<T>(self, param_env: ty::ParamEnv<'tcx>, value: T) -> T
|
||||
#[tracing::instrument(level = "debug", skip(self, typing_env), ret)]
|
||||
pub fn normalize_erasing_regions<T>(self, typing_env: ty::TypingEnv<'tcx>, value: T) -> T
|
||||
where
|
||||
T: TypeFoldable<TyCtxt<'tcx>>,
|
||||
{
|
||||
debug!(
|
||||
"normalize_erasing_regions::<{}>(value={:?}, param_env={:?})",
|
||||
"normalize_erasing_regions::<{}>(value={:?}, typing_env={:?})",
|
||||
std::any::type_name::<T>(),
|
||||
value,
|
||||
param_env,
|
||||
typing_env,
|
||||
);
|
||||
|
||||
// Erase first before we do the real query -- this keeps the
|
||||
|
@ -55,7 +55,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
if !value.has_aliases() {
|
||||
value
|
||||
} else {
|
||||
value.fold_with(&mut NormalizeAfterErasingRegionsFolder { tcx: self, param_env })
|
||||
value.fold_with(&mut NormalizeAfterErasingRegionsFolder { tcx: self, typing_env })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,17 +66,17 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
/// succeeds.
|
||||
pub fn try_normalize_erasing_regions<T>(
|
||||
self,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
value: T,
|
||||
) -> Result<T, NormalizationError<'tcx>>
|
||||
where
|
||||
T: TypeFoldable<TyCtxt<'tcx>>,
|
||||
{
|
||||
debug!(
|
||||
"try_normalize_erasing_regions::<{}>(value={:?}, param_env={:?})",
|
||||
"try_normalize_erasing_regions::<{}>(value={:?}, typing_env={:?})",
|
||||
std::any::type_name::<T>(),
|
||||
value,
|
||||
param_env,
|
||||
typing_env,
|
||||
);
|
||||
|
||||
// Erase first before we do the real query -- this keeps the
|
||||
|
@ -87,7 +87,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
if !value.has_aliases() {
|
||||
Ok(value)
|
||||
} else {
|
||||
let mut folder = TryNormalizeAfterErasingRegionsFolder::new(self, param_env);
|
||||
let mut folder = TryNormalizeAfterErasingRegionsFolder::new(self, typing_env);
|
||||
value.try_fold_with(&mut folder)
|
||||
}
|
||||
}
|
||||
|
@ -103,17 +103,17 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
// FIXME(@lcnr): This method should not be necessary, we now normalize
|
||||
// inside of binders. We should be able to only use
|
||||
// `tcx.instantiate_bound_regions_with_erased`.
|
||||
#[tracing::instrument(level = "debug", skip(self, param_env))]
|
||||
#[tracing::instrument(level = "debug", skip(self, typing_env))]
|
||||
pub fn normalize_erasing_late_bound_regions<T>(
|
||||
self,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
value: ty::Binder<'tcx, T>,
|
||||
) -> T
|
||||
where
|
||||
T: TypeFoldable<TyCtxt<'tcx>>,
|
||||
{
|
||||
let value = self.instantiate_bound_regions_with_erased(value);
|
||||
self.normalize_erasing_regions(param_env, value)
|
||||
self.normalize_erasing_regions(typing_env, value)
|
||||
}
|
||||
|
||||
/// Monomorphizes a type from the AST by first applying the
|
||||
|
@ -125,14 +125,14 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
pub fn instantiate_and_normalize_erasing_regions<T>(
|
||||
self,
|
||||
param_args: GenericArgsRef<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
value: EarlyBinder<'tcx, T>,
|
||||
) -> T
|
||||
where
|
||||
T: TypeFoldable<TyCtxt<'tcx>>,
|
||||
{
|
||||
let instantiated = value.instantiate(self, param_args);
|
||||
self.normalize_erasing_regions(param_env, instantiated)
|
||||
self.normalize_erasing_regions(typing_env, instantiated)
|
||||
}
|
||||
|
||||
/// Monomorphizes a type from the AST by first applying the
|
||||
|
@ -143,20 +143,20 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
pub fn try_instantiate_and_normalize_erasing_regions<T>(
|
||||
self,
|
||||
param_args: GenericArgsRef<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
value: EarlyBinder<'tcx, T>,
|
||||
) -> Result<T, NormalizationError<'tcx>>
|
||||
where
|
||||
T: TypeFoldable<TyCtxt<'tcx>>,
|
||||
{
|
||||
let instantiated = value.instantiate(self, param_args);
|
||||
self.try_normalize_erasing_regions(param_env, instantiated)
|
||||
self.try_normalize_erasing_regions(typing_env, instantiated)
|
||||
}
|
||||
}
|
||||
|
||||
struct NormalizeAfterErasingRegionsFolder<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
}
|
||||
|
||||
impl<'tcx> NormalizeAfterErasingRegionsFolder<'tcx> {
|
||||
|
@ -164,8 +164,7 @@ impl<'tcx> NormalizeAfterErasingRegionsFolder<'tcx> {
|
|||
&self,
|
||||
arg: ty::GenericArg<'tcx>,
|
||||
) -> ty::GenericArg<'tcx> {
|
||||
let arg = self.param_env.and(arg);
|
||||
|
||||
let arg = self.typing_env.as_query_input(arg);
|
||||
self.tcx.try_normalize_generic_arg_after_erasing_regions(arg).unwrap_or_else(|_| bug!(
|
||||
"Failed to normalize {:?}, maybe try to call `try_normalize_erasing_regions` instead",
|
||||
arg.value
|
||||
|
@ -189,12 +188,12 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for NormalizeAfterErasingRegionsFolder<'tcx>
|
|||
|
||||
struct TryNormalizeAfterErasingRegionsFolder<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
}
|
||||
|
||||
impl<'tcx> TryNormalizeAfterErasingRegionsFolder<'tcx> {
|
||||
fn new(tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Self {
|
||||
TryNormalizeAfterErasingRegionsFolder { tcx, param_env }
|
||||
fn new(tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> Self {
|
||||
TryNormalizeAfterErasingRegionsFolder { tcx, typing_env }
|
||||
}
|
||||
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
|
@ -202,10 +201,8 @@ impl<'tcx> TryNormalizeAfterErasingRegionsFolder<'tcx> {
|
|||
&self,
|
||||
arg: ty::GenericArg<'tcx>,
|
||||
) -> Result<ty::GenericArg<'tcx>, NoSolution> {
|
||||
let arg = self.param_env.and(arg);
|
||||
debug!(?arg);
|
||||
|
||||
self.tcx.try_normalize_generic_arg_after_erasing_regions(arg)
|
||||
let input = self.typing_env.as_query_input(arg);
|
||||
self.tcx.try_normalize_generic_arg_after_erasing_regions(input)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ use rustc_span::sym;
|
|||
use smallvec::{SmallVec, smallvec};
|
||||
use tracing::{debug, instrument};
|
||||
|
||||
use super::TypingEnv;
|
||||
use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
||||
use crate::query::Providers;
|
||||
use crate::ty::layout::{FloatExt, IntegerExt};
|
||||
|
@ -177,9 +178,13 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
/// Should only be called if `ty` has no inference variables and does not
|
||||
/// need its lifetimes preserved (e.g. as part of codegen); otherwise
|
||||
/// normalization attempt may cause compiler bugs.
|
||||
pub fn struct_tail_for_codegen(self, ty: Ty<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Ty<'tcx> {
|
||||
pub fn struct_tail_for_codegen(
|
||||
self,
|
||||
ty: Ty<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
) -> Ty<'tcx> {
|
||||
let tcx = self;
|
||||
tcx.struct_tail_raw(ty, |ty| tcx.normalize_erasing_regions(param_env, ty), || {})
|
||||
tcx.struct_tail_raw(ty, |ty| tcx.normalize_erasing_regions(typing_env, ty), || {})
|
||||
}
|
||||
|
||||
/// Returns the deeply last field of nested structures, or the same type if
|
||||
|
@ -271,11 +276,11 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
self,
|
||||
source: Ty<'tcx>,
|
||||
target: Ty<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
) -> (Ty<'tcx>, Ty<'tcx>) {
|
||||
let tcx = self;
|
||||
tcx.struct_lockstep_tails_raw(source, target, |ty| {
|
||||
tcx.normalize_erasing_regions(param_env, ty)
|
||||
tcx.normalize_erasing_regions(typing_env, ty)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -420,10 +425,10 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
|
||||
// Async drop glue morphology is an internal detail, so reveal_all probably
|
||||
// should be fine
|
||||
let param_env = ty::ParamEnv::reveal_all();
|
||||
if ty.needs_async_drop(self, param_env) {
|
||||
let typing_env = ty::TypingEnv::fully_monomorphized();
|
||||
if ty.needs_async_drop(self, typing_env) {
|
||||
AsyncDropGlueMorphology::Custom
|
||||
} else if ty.needs_drop(self, param_env) {
|
||||
} else if ty.needs_drop(self, typing_env) {
|
||||
AsyncDropGlueMorphology::DeferredDropInPlace
|
||||
} else {
|
||||
AsyncDropGlueMorphology::Noop
|
||||
|
@ -683,12 +688,10 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
}
|
||||
|
||||
/// Get the type of the pointer to the static that we use in MIR.
|
||||
pub fn static_ptr_ty(self, def_id: DefId) -> Ty<'tcx> {
|
||||
pub fn static_ptr_ty(self, def_id: DefId, typing_env: ty::TypingEnv<'tcx>) -> Ty<'tcx> {
|
||||
// Make sure that any constants in the static's type are evaluated.
|
||||
let static_ty = self.normalize_erasing_regions(
|
||||
ty::ParamEnv::empty(),
|
||||
self.type_of(def_id).instantiate_identity(),
|
||||
);
|
||||
let static_ty =
|
||||
self.normalize_erasing_regions(typing_env, self.type_of(def_id).instantiate_identity());
|
||||
|
||||
// Make sure that accesses to unsafe statics end up using raw pointers.
|
||||
// For thread-locals, this needs to be kept in sync with `Rvalue::ty`.
|
||||
|
@ -1157,15 +1160,17 @@ impl<'tcx> Ty<'tcx> {
|
|||
/// Returns the maximum value for the given numeric type (including `char`s)
|
||||
/// or returns `None` if the type is not numeric.
|
||||
pub fn numeric_max_val(self, tcx: TyCtxt<'tcx>) -> Option<ty::Const<'tcx>> {
|
||||
let typing_env = TypingEnv::fully_monomorphized();
|
||||
self.numeric_min_and_max_as_bits(tcx)
|
||||
.map(|(_, max)| ty::Const::from_bits(tcx, max, ty::ParamEnv::empty().and(self)))
|
||||
.map(|(_, max)| ty::Const::from_bits(tcx, max, typing_env, self))
|
||||
}
|
||||
|
||||
/// Returns the minimum value for the given numeric type (including `char`s)
|
||||
/// or returns `None` if the type is not numeric.
|
||||
pub fn numeric_min_val(self, tcx: TyCtxt<'tcx>) -> Option<ty::Const<'tcx>> {
|
||||
let typing_env = TypingEnv::fully_monomorphized();
|
||||
self.numeric_min_and_max_as_bits(tcx)
|
||||
.map(|(min, _)| ty::Const::from_bits(tcx, min, ty::ParamEnv::empty().and(self)))
|
||||
.map(|(min, _)| ty::Const::from_bits(tcx, min, typing_env, self))
|
||||
}
|
||||
|
||||
/// Checks whether values of this type `T` are *moved* or *copied*
|
||||
|
@ -1345,7 +1350,7 @@ impl<'tcx> Ty<'tcx> {
|
|||
///
|
||||
/// Note that this method is used to check eligible types in unions.
|
||||
#[inline]
|
||||
pub fn needs_drop(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool {
|
||||
pub fn needs_drop(self, tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> bool {
|
||||
// Avoid querying in simple cases.
|
||||
match needs_drop_components(tcx, self) {
|
||||
Err(AlwaysRequiresDrop) => true,
|
||||
|
@ -1359,14 +1364,13 @@ impl<'tcx> Ty<'tcx> {
|
|||
};
|
||||
|
||||
// This doesn't depend on regions, so try to minimize distinct
|
||||
// query keys used.
|
||||
// If normalization fails, we just use `query_ty`.
|
||||
debug_assert!(!param_env.has_infer());
|
||||
// query keys used. If normalization fails, we just use `query_ty`.
|
||||
debug_assert!(!typing_env.param_env.has_infer());
|
||||
let query_ty = tcx
|
||||
.try_normalize_erasing_regions(param_env, query_ty)
|
||||
.try_normalize_erasing_regions(typing_env, query_ty)
|
||||
.unwrap_or_else(|_| tcx.erase_regions(query_ty));
|
||||
|
||||
tcx.needs_drop_raw(param_env.and(query_ty))
|
||||
tcx.needs_drop_raw(typing_env.as_query_input(query_ty))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1385,7 +1389,7 @@ impl<'tcx> Ty<'tcx> {
|
|||
// FIXME(zetanumbers): Note that this method is used to check eligible types
|
||||
// in unions.
|
||||
#[inline]
|
||||
pub fn needs_async_drop(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool {
|
||||
pub fn needs_async_drop(self, tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> bool {
|
||||
// Avoid querying in simple cases.
|
||||
match needs_drop_components(tcx, self) {
|
||||
Err(AlwaysRequiresDrop) => true,
|
||||
|
@ -1401,12 +1405,12 @@ impl<'tcx> Ty<'tcx> {
|
|||
// This doesn't depend on regions, so try to minimize distinct
|
||||
// query keys used.
|
||||
// If normalization fails, we just use `query_ty`.
|
||||
debug_assert!(!param_env.has_infer());
|
||||
debug_assert!(!typing_env.has_infer());
|
||||
let query_ty = tcx
|
||||
.try_normalize_erasing_regions(param_env, query_ty)
|
||||
.try_normalize_erasing_regions(typing_env, query_ty)
|
||||
.unwrap_or_else(|_| tcx.erase_regions(query_ty));
|
||||
|
||||
tcx.needs_async_drop_raw(param_env.and(query_ty))
|
||||
tcx.needs_async_drop_raw(typing_env.as_query_input(query_ty))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1420,7 +1424,7 @@ impl<'tcx> Ty<'tcx> {
|
|||
/// Note that this method is used to check for change in drop order for
|
||||
/// 2229 drop reorder migration analysis.
|
||||
#[inline]
|
||||
pub fn has_significant_drop(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool {
|
||||
pub fn has_significant_drop(self, tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> bool {
|
||||
// Avoid querying in simple cases.
|
||||
match needs_drop_components(tcx, self) {
|
||||
Err(AlwaysRequiresDrop) => true,
|
||||
|
@ -1443,8 +1447,8 @@ impl<'tcx> Ty<'tcx> {
|
|||
|
||||
// This doesn't depend on regions, so try to minimize distinct
|
||||
// query keys used.
|
||||
let erased = tcx.normalize_erasing_regions(param_env, query_ty);
|
||||
tcx.has_significant_drop_raw(param_env.and(erased))
|
||||
let erased = tcx.normalize_erasing_regions(typing_env, query_ty);
|
||||
tcx.has_significant_drop_raw(typing_env.as_query_input(erased))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -97,7 +97,7 @@ pub(super) fn vtable_allocation_provider<'tcx>(
|
|||
assert!(vtable_entries.len() >= vtable_min_entries(tcx, poly_trait_ref));
|
||||
|
||||
let layout = tcx
|
||||
.layout_of(ty::ParamEnv::reveal_all().and(ty))
|
||||
.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty))
|
||||
.expect("failed to build vtable representation");
|
||||
assert!(layout.is_sized(), "can't create a vtable for an unsized type");
|
||||
let size = layout.size.bytes();
|
||||
|
@ -117,7 +117,7 @@ pub(super) fn vtable_allocation_provider<'tcx>(
|
|||
let idx: u64 = u64::try_from(idx).unwrap();
|
||||
let scalar = match entry {
|
||||
VtblEntry::MetadataDropInPlace => {
|
||||
if ty.needs_drop(tcx, ty::ParamEnv::reveal_all()) {
|
||||
if ty.needs_drop(tcx, ty::TypingEnv::fully_monomorphized()) {
|
||||
let instance = ty::Instance::resolve_drop_in_place(tcx, ty);
|
||||
let fn_alloc_id = tcx.reserve_and_set_fn_alloc(instance, CTFE_ALLOC_SALT);
|
||||
let fn_ptr = Pointer::from(fn_alloc_id);
|
||||
|
|
|
@ -8,7 +8,7 @@ use rustc_span::symbol::Ident;
|
|||
use rustc_span::{DesugaringKind, Span, sym};
|
||||
use tracing::debug;
|
||||
|
||||
use crate::ty::{AssocItemContainer, GenericArgsRef, Instance, ParamEnv, Ty, TyCtxt};
|
||||
use crate::ty::{AssocItemContainer, GenericArgsRef, Instance, Ty, TyCtxt, TypingEnv};
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
pub enum CallDesugaringKind {
|
||||
|
@ -62,7 +62,7 @@ pub enum CallKind<'tcx> {
|
|||
|
||||
pub fn call_kind<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ParamEnv<'tcx>,
|
||||
typing_env: TypingEnv<'tcx>,
|
||||
method_did: DefId,
|
||||
method_args: GenericArgsRef<'tcx>,
|
||||
fn_call_span: Span,
|
||||
|
@ -98,10 +98,10 @@ pub fn call_kind<'tcx>(
|
|||
Some(CallKind::Operator { self_arg, trait_id, self_ty: method_args.type_at(0) })
|
||||
} else if is_deref {
|
||||
let deref_target = tcx.get_diagnostic_item(sym::deref_target).and_then(|deref_target| {
|
||||
Instance::try_resolve(tcx, param_env, deref_target, method_args).transpose()
|
||||
Instance::try_resolve(tcx, typing_env, deref_target, method_args).transpose()
|
||||
});
|
||||
if let Some(Ok(instance)) = deref_target {
|
||||
let deref_target_ty = instance.ty(tcx, param_env);
|
||||
let deref_target_ty = instance.ty(tcx, typing_env);
|
||||
Some(CallKind::DerefCoercion {
|
||||
deref_target: tcx.def_span(instance.def_id()),
|
||||
deref_target_ty,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue