1
Fork 0

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:
lcnr 2024-11-15 13:53:31 +01:00
parent bf6adec108
commit 9cba14b95b
240 changed files with 1739 additions and 1340 deletions

View file

@ -427,7 +427,7 @@ fn collect_items_rec<'tcx>(
let DefKind::Static { nested, .. } = tcx.def_kind(def_id) else { bug!() };
// Nested statics have no type.
if !nested {
let ty = instance.ty(tcx, ty::ParamEnv::reveal_all());
let ty = instance.ty(tcx, ty::TypingEnv::fully_monomorphized());
visit_drop_use(tcx, ty, true, starting_item.span, &mut used_items);
}
@ -636,7 +636,7 @@ impl<'a, 'tcx> MirUsedCollector<'a, 'tcx> {
trace!("monomorphize: self.instance={:?}", self.instance);
self.instance.instantiate_mir_and_normalize_erasing_regions(
self.tcx,
ty::ParamEnv::reveal_all(),
ty::TypingEnv::fully_monomorphized(),
ty::EarlyBinder::bind(value),
)
}
@ -647,12 +647,11 @@ impl<'a, 'tcx> MirUsedCollector<'a, 'tcx> {
constant: &mir::ConstOperand<'tcx>,
) -> Option<mir::ConstValue<'tcx>> {
let const_ = self.monomorphize(constant.const_);
let param_env = ty::ParamEnv::reveal_all();
// Evaluate the constant. This makes const eval failure a collection-time error (rather than
// a codegen-time error). rustc stops after collection if there was an error, so this
// ensures codegen never has to worry about failing consts.
// (codegen relies on this and ICEs will happen if this is violated.)
match const_.eval(self.tcx, param_env, constant.span) {
match const_.eval(self.tcx, ty::TypingEnv::fully_monomorphized(), constant.span) {
Ok(v) => Some(v),
Err(ErrorHandled::TooGeneric(..)) => span_bug!(
constant.span,
@ -863,9 +862,20 @@ fn visit_fn_use<'tcx>(
) {
if let ty::FnDef(def_id, args) = *ty.kind() {
let instance = if is_direct_call {
ty::Instance::expect_resolve(tcx, ty::ParamEnv::reveal_all(), def_id, args, source)
ty::Instance::expect_resolve(
tcx,
ty::TypingEnv::fully_monomorphized(),
def_id,
args,
source,
)
} else {
match ty::Instance::resolve_for_fn_ptr(tcx, ty::ParamEnv::reveal_all(), def_id, args) {
match ty::Instance::resolve_for_fn_ptr(
tcx,
ty::TypingEnv::fully_monomorphized(),
def_id,
args,
) {
Some(instance) => instance,
_ => bug!("failed to resolve instance for {ty}"),
}
@ -1024,12 +1034,12 @@ fn find_vtable_types_for_unsizing<'tcx>(
target_ty: Ty<'tcx>,
) -> (Ty<'tcx>, Ty<'tcx>) {
let ptr_vtable = |inner_source: Ty<'tcx>, inner_target: Ty<'tcx>| {
let param_env = ty::ParamEnv::reveal_all();
let typing_env = ty::TypingEnv::fully_monomorphized();
let type_has_metadata = |ty: Ty<'tcx>| -> bool {
if ty.is_sized(tcx.tcx, param_env) {
if ty.is_sized(tcx.tcx, typing_env.param_env) {
return false;
}
let tail = tcx.struct_tail_for_codegen(ty, param_env);
let tail = tcx.struct_tail_for_codegen(ty, typing_env);
match tail.kind() {
ty::Foreign(..) => false,
ty::Str | ty::Slice(..) | ty::Dynamic(..) => true,
@ -1039,7 +1049,7 @@ fn find_vtable_types_for_unsizing<'tcx>(
if type_has_metadata(inner_source) {
(inner_source, inner_target)
} else {
tcx.struct_lockstep_tails_for_codegen(inner_source, inner_target, param_env)
tcx.struct_lockstep_tails_for_codegen(inner_source, inner_target, typing_env)
}
};
@ -1270,8 +1280,13 @@ fn visit_mentioned_item<'tcx>(
match *item {
MentionedItem::Fn(ty) => {
if let ty::FnDef(def_id, args) = *ty.kind() {
let instance =
Instance::expect_resolve(tcx, ty::ParamEnv::reveal_all(), def_id, args, span);
let instance = Instance::expect_resolve(
tcx,
ty::TypingEnv::fully_monomorphized(),
def_id,
args,
span,
);
// `visit_instance_use` was written for "used" item collection but works just as well
// for "mentioned" item collection.
// We can set `is_direct_call`; that just means we'll skip a bunch of shims that anyway
@ -1487,13 +1502,13 @@ impl<'v> RootCollector<'_, 'v> {
// regions must appear in the argument
// listing.
let main_ret_ty = self.tcx.normalize_erasing_regions(
ty::ParamEnv::reveal_all(),
ty::TypingEnv::fully_monomorphized(),
main_ret_ty.no_bound_vars().unwrap(),
);
let start_instance = Instance::expect_resolve(
self.tcx,
ty::ParamEnv::reveal_all(),
ty::TypingEnv::fully_monomorphized(),
start_def_id,
self.tcx.mk_args(&[main_ret_ty.into()]),
DUMMY_SP,
@ -1551,8 +1566,8 @@ fn create_mono_items_for_default_impls<'tcx>(
return;
}
let param_env = ty::ParamEnv::reveal_all();
let trait_ref = tcx.normalize_erasing_regions(param_env, trait_ref);
let typing_env = ty::TypingEnv::fully_monomorphized();
let trait_ref = tcx.normalize_erasing_regions(typing_env, trait_ref);
let overridden_methods = tcx.impl_item_implementor_ids(item.owner_id);
for method in tcx.provided_trait_methods(trait_ref.def_id) {
if overridden_methods.contains_key(&method.def_id) {
@ -1567,7 +1582,7 @@ fn create_mono_items_for_default_impls<'tcx>(
// only has lifetime generic parameters. This is validated by calling
// `own_requires_monomorphization` on both the impl and method.
let args = trait_ref.args.extend_to(tcx, method.def_id, only_region_params);
let instance = ty::Instance::expect_resolve(tcx, param_env, method.def_id, args, DUMMY_SP);
let instance = ty::Instance::expect_resolve(tcx, typing_env, method.def_id, args, DUMMY_SP);
let mono_item = create_fn_mono_item(tcx, instance, DUMMY_SP);
if mono_item.node.is_instantiable(tcx) && tcx.should_codegen_locally(instance) {

View file

@ -35,7 +35,9 @@ fn custom_coerce_unsize_info<'tcx>(
[source_ty, target_ty],
);
match tcx.codegen_select_candidate((ty::ParamEnv::reveal_all(), trait_ref)) {
match tcx
.codegen_select_candidate(ty::TypingEnv::fully_monomorphized().as_query_input(trait_ref))
{
Ok(traits::ImplSource::UserDefined(traits::ImplSourceUserDefinedData {
impl_def_id,
..

View file

@ -3,7 +3,7 @@
use rustc_hir::CRATE_HIR_ID;
use rustc_middle::mir::{self, traversal};
use rustc_middle::ty::inherent::*;
use rustc_middle::ty::{self, Instance, InstanceKind, ParamEnv, Ty, TyCtxt};
use rustc_middle::ty::{self, Instance, InstanceKind, Ty, TyCtxt};
use rustc_session::lint::builtin::ABI_UNSUPPORTED_VECTOR_TYPES;
use rustc_span::def_id::DefId;
use rustc_span::{DUMMY_SP, Span, Symbol};
@ -62,8 +62,9 @@ fn do_check_abi<'tcx>(
/// Checks that the ABI of a given instance of a function does not contain vector-passed arguments
/// or return values for which the corresponding target feature is not enabled.
fn check_instance_abi<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) {
let param_env = ParamEnv::reveal_all();
let Ok(abi) = tcx.fn_abi_of_instance(param_env.and((instance, ty::List::empty()))) else {
let typing_env = ty::TypingEnv::fully_monomorphized();
let Ok(abi) = tcx.fn_abi_of_instance(typing_env.as_query_input((instance, ty::List::empty())))
else {
// An error will be reported during codegen if we cannot determine the ABI of this
// function.
return;
@ -100,18 +101,18 @@ fn check_call_site_abi<'tcx>(
// "Rust" ABI never passes arguments in vector registers.
return;
}
let param_env = ParamEnv::reveal_all();
let typing_env = ty::TypingEnv::fully_monomorphized();
let callee_abi = match *callee.kind() {
ty::FnPtr(..) => {
tcx.fn_abi_of_fn_ptr(param_env.and((callee.fn_sig(tcx), ty::List::empty())))
tcx.fn_abi_of_fn_ptr(typing_env.as_query_input((callee.fn_sig(tcx), ty::List::empty())))
}
ty::FnDef(def_id, args) => {
// Intrinsics are handled separately by the compiler.
if tcx.intrinsic(def_id).is_some() {
return;
}
let instance = ty::Instance::expect_resolve(tcx, param_env, def_id, args, DUMMY_SP);
tcx.fn_abi_of_instance(param_env.and((instance, ty::List::empty())))
let instance = ty::Instance::expect_resolve(tcx, typing_env, def_id, args, DUMMY_SP);
tcx.fn_abi_of_instance(typing_env.as_query_input((instance, ty::List::empty())))
}
_ => {
panic!("Invalid function call");
@ -151,7 +152,7 @@ fn check_callees_abi<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>, body: &m
let callee_ty = func.ty(body, tcx);
let callee_ty = instance.instantiate_mir_and_normalize_erasing_regions(
tcx,
ty::ParamEnv::reveal_all(),
ty::TypingEnv::fully_monomorphized(),
ty::EarlyBinder::bind(callee_ty),
);
check_call_site_abi(tcx, callee_ty, *fn_span, body.source.instance);

View file

@ -61,7 +61,7 @@ impl<'tcx> MoveCheckVisitor<'tcx> {
trace!("monomorphize: self.instance={:?}", self.instance);
self.instance.instantiate_mir_and_normalize_erasing_regions(
self.tcx,
ty::ParamEnv::reveal_all(),
ty::TypingEnv::fully_monomorphized(),
ty::EarlyBinder::bind(value),
)
}
@ -128,7 +128,9 @@ impl<'tcx> MoveCheckVisitor<'tcx> {
) -> Option<Size> {
let ty = operand.ty(self.body, self.tcx);
let ty = self.monomorphize(ty);
let Ok(layout) = self.tcx.layout_of(ty::ParamEnv::reveal_all().and(ty)) else {
let Ok(layout) =
self.tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty))
else {
return None;
};
if layout.size.bytes_usize() > limit.0 {

View file

@ -666,7 +666,7 @@ fn characteristic_def_id_of_mono_item<'tcx>(
// This is a method within an impl, find out what the self-type is:
let impl_self_ty = tcx.instantiate_and_normalize_erasing_regions(
instance.args,
ty::ParamEnv::reveal_all(),
ty::TypingEnv::fully_monomorphized(),
tcx.type_of(impl_def_id),
);
if let Some(def_id) = characteristic_def_id_of_type(impl_self_ty) {

View file

@ -22,29 +22,29 @@ pub(crate) fn dump_closure_profile<'tcx>(tcx: TyCtxt<'tcx>, closure_instance: In
let typeck_results = tcx.typeck(closure_def_id);
if typeck_results.closure_size_eval.contains_key(&closure_def_id) {
let param_env = ty::ParamEnv::reveal_all();
let typing_env = ty::TypingEnv::fully_monomorphized();
let ClosureSizeProfileData { before_feature_tys, after_feature_tys } =
typeck_results.closure_size_eval[&closure_def_id];
let before_feature_tys = tcx.instantiate_and_normalize_erasing_regions(
closure_instance.args,
param_env,
typing_env,
ty::EarlyBinder::bind(before_feature_tys),
);
let after_feature_tys = tcx.instantiate_and_normalize_erasing_regions(
closure_instance.args,
param_env,
typing_env,
ty::EarlyBinder::bind(after_feature_tys),
);
let new_size = tcx
.layout_of(param_env.and(after_feature_tys))
.layout_of(typing_env.as_query_input(after_feature_tys))
.map(|l| format!("{:?}", l.size.bytes()))
.unwrap_or_else(|e| format!("Failed {e:?}"));
let old_size = tcx
.layout_of(param_env.and(before_feature_tys))
.layout_of(typing_env.as_query_input(before_feature_tys))
.map(|l| format!("{:?}", l.size.bytes()))
.unwrap_or_else(|e| format!("Failed {e:?}"));