Auto merge of #132460 - lcnr:questionable-uwu, r=compiler-errors
Use `TypingMode` throughout the compiler instead of `ParamEnv` Hopefully the biggest single PR as part of https://github.com/rust-lang/types-team/issues/128. ## `infcx.typing_env` while defining opaque types I don't know how'll be able to correctly handle opaque types when using something taking a `TypingEnv` while defining opaque types. To correctly handle the opaques we need to be able to pass in the current `opaque_type_storage` and return constraints, i.e. we need to use a proper canonical query. We should migrate all the queries used during HIR typeck and borrowck where this matters to proper canonical queries. This is ## `layout_of` and `Reveal::All` We convert the `ParamEnv` to `Reveal::All` right at the start of the `layout_of` query, so I've changed callers of `layout_of` to already use a post analysis `TypingEnv` when encountering it.ca87b535a0/compiler/rustc_ty_utils/src/layout.rs (L51)
## `Ty::is_[unpin|sized|whatever]` I haven't migrated `fn is_item_raw` to use `TypingEnv`, will do so in a followup PR, this should significantly reduce the amount of `typing_env.param_env`. At some point there will probably be zero such uses as using the type system while ignoring the `typing_mode` is incorrect. ## `MirPhase` and phase-transitions When inside of a MIR-body, we can mostly use its `MirPhase` to figure out the right `typing_mode`. This does not work during phase transitions, most notably when transitioning from `Analysis` to `Runtime`:dae7ac133b/compiler/rustc_mir_transform/src/lib.rs (L606-L625)
All these passes still run with `MirPhase::Analysis`, but we should only use `Reveal::All` once we're run the `RevealAll` pass. This required me to manually construct the right `TypingEnv` in all these passes. Given that it feels somewhat easy to accidentally miss this going forward, I would maybe like to change `Body::phase` to an `Option` and replace it at the start of phase transitions. This then makes it clear that the MIR is currently in a weird state. r? `@ghost`
This commit is contained in:
commit
b71fb5edc0
240 changed files with 1745 additions and 1341 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,105 @@ 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. As of writing this comment, this is
|
||||
// only used by `fn layout_is_pointer_like` when calling `layout_of`.
|
||||
//
|
||||
// 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