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

@ -21,8 +21,7 @@ use rustc_middle::ty::fold::BottomUpFolder;
use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES};
use rustc_middle::ty::util::{Discr, InspectCoroutineFields, IntTypeExt};
use rustc_middle::ty::{
AdtDef, GenericArgKind, ParamEnv, RegionKind, TypeSuperVisitable, TypeVisitable,
TypeVisitableExt,
AdtDef, GenericArgKind, RegionKind, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
};
use rustc_session::lint::builtin::UNINHABITED_STATIC;
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
@ -114,15 +113,15 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b
}
}
let param_env = tcx.param_env(item_def_id);
let typing_env = ty::TypingEnv::non_body_analysis(tcx, item_def_id);
for field in &def.non_enum_variant().fields {
let Ok(field_ty) = tcx.try_normalize_erasing_regions(param_env, field.ty(tcx, args))
let Ok(field_ty) = tcx.try_normalize_erasing_regions(typing_env, field.ty(tcx, args))
else {
tcx.dcx().span_delayed_bug(span, "could not normalize field type");
continue;
};
if !allowed_union_field(field_ty, tcx, param_env) {
if !allowed_union_field(field_ty, tcx, typing_env.param_env) {
let (field_span, ty_span) = match tcx.hir().get_if_local(field.did) {
// We are currently checking the type this field came from, so it must be local.
Some(Node::Field(field)) => (field.span, field.ty.span),
@ -137,7 +136,7 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b
note: (),
});
return false;
} else if field_ty.needs_drop(tcx, param_env) {
} else if field_ty.needs_drop(tcx, typing_env) {
// This should never happen. But we can get here e.g. in case of name resolution errors.
tcx.dcx()
.span_delayed_bug(span, "we should never accept maybe-dropping union fields");
@ -158,7 +157,7 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) {
// reason to allow any statics to be uninhabited.
let ty = tcx.type_of(def_id).instantiate_identity();
let span = tcx.def_span(def_id);
let layout = match tcx.layout_of(ParamEnv::reveal_all().and(ty)) {
let layout = match tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)) {
Ok(l) => l,
// Foreign statics that overflow their allowed size should emit an error
Err(LayoutError::SizeOverflow(_))
@ -237,7 +236,10 @@ pub(super) fn check_opaque_for_cycles<'tcx>(
// And also look for cycle errors in the layout of coroutines.
if let Err(&LayoutError::Cycle(guar)) =
tcx.layout_of(tcx.param_env(def_id).and(Ty::new_opaque(tcx, def_id.to_def_id(), args)))
tcx.layout_of(
ty::TypingEnv::post_analysis(tcx, def_id.to_def_id())
.as_query_input(Ty::new_opaque(tcx, def_id.to_def_id(), args)),
)
{
return Err(guar);
}
@ -1307,8 +1309,8 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
// "known" respecting #[non_exhaustive] attributes.
let field_infos = adt.all_fields().map(|field| {
let ty = field.ty(tcx, GenericArgs::identity_for_item(tcx, field.did));
let param_env = tcx.param_env(field.did);
let layout = tcx.layout_of(param_env.and(ty));
let typing_env = ty::TypingEnv::non_body_analysis(tcx, field.did);
let layout = tcx.layout_of(typing_env.as_query_input(ty));
// We are currently checking the type this field came from, so it must be local
let span = tcx.hir().span_if_local(field.did).unwrap();
let trivial = layout.is_ok_and(|layout| layout.is_1zst());

View file

@ -1126,7 +1126,7 @@ fn check_type_defn<'tcx>(
let ty = tcx.type_of(variant.tail().did).instantiate_identity();
let ty = tcx.erase_regions(ty);
assert!(!ty.has_infer());
ty.needs_drop(tcx, tcx.param_env(item.owner_id))
ty.needs_drop(tcx, ty::TypingEnv::non_body_analysis(tcx, item.owner_id.def_id))
}
};
// All fields (except for possibly the last) should be sized.
@ -1281,7 +1281,8 @@ fn check_item_type(
UnsizedHandling::Forbid => true,
UnsizedHandling::Allow => false,
UnsizedHandling::AllowIfForeignTail => {
let tail = tcx.struct_tail_for_codegen(item_ty, wfcx.param_env);
let tail =
tcx.struct_tail_for_codegen(item_ty, wfcx.infcx.typing_env(wfcx.param_env));
!matches!(tail.kind(), ty::Foreign(_))
}
};

View file

@ -259,7 +259,9 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
let ty_a = field.ty(tcx, args_a);
let ty_b = field.ty(tcx, args_b);
if let Ok(layout) = tcx.layout_of(param_env.and(ty_a)) {
if let Ok(layout) =
tcx.layout_of(infcx.typing_env(param_env).as_query_input(ty_a))
{
if layout.is_1zst() {
// ignore 1-ZST fields
return false;

View file

@ -3,7 +3,7 @@ use rustc_errors::{DiagCtxtHandle, E0781, struct_span_code_err};
use rustc_hir::{self as hir, HirId};
use rustc_middle::bug;
use rustc_middle::ty::layout::LayoutError;
use rustc_middle::ty::{self, ParamEnv, TyCtxt};
use rustc_middle::ty::{self, TyCtxt};
use crate::errors;
@ -130,7 +130,7 @@ fn is_valid_cmse_inputs<'tcx>(
let fn_sig = tcx.instantiate_bound_regions_with_erased(fn_sig);
for (index, ty) in fn_sig.inputs().iter().enumerate() {
let layout = tcx.layout_of(ParamEnv::reveal_all().and(*ty))?;
let layout = tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(*ty))?;
let align = layout.layout.align().abi.bytes();
let size = layout.layout.size().bytes();
@ -158,8 +158,10 @@ fn is_valid_cmse_output<'tcx>(
// this type is only used for layout computation, which does not rely on regions
let fn_sig = tcx.instantiate_bound_regions_with_erased(fn_sig);
let typing_env = ty::TypingEnv::fully_monomorphized();
let mut ret_ty = fn_sig.output();
let layout = tcx.layout_of(ParamEnv::reveal_all().and(ret_ty))?;
let layout = tcx.layout_of(typing_env.as_query_input(ret_ty))?;
let size = layout.layout.size().bytes();
if size <= 4 {
@ -182,7 +184,7 @@ fn is_valid_cmse_output<'tcx>(
for variant_def in adt_def.variants() {
for field_def in variant_def.fields.iter() {
let ty = field_def.ty(tcx, args);
let layout = tcx.layout_of(ParamEnv::reveal_all().and(ty))?;
let layout = tcx.layout_of(typing_env.as_query_input(ty))?;
if !layout.layout.is_1zst() {
ret_ty = ty;