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:
bors 2024-11-18 21:07:05 +00:00
commit b71fb5edc0
240 changed files with 1745 additions and 1341 deletions

View File

@ -682,8 +682,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
// Normalize before comparing to see through type aliases and projections.
let old_ty = ty::EarlyBinder::bind(ty).instantiate(tcx, generic_args);
let new_ty = ty::EarlyBinder::bind(ty).instantiate(tcx, new_args);
if let Ok(old_ty) = tcx.try_normalize_erasing_regions(self.param_env, old_ty)
&& let Ok(new_ty) = tcx.try_normalize_erasing_regions(self.param_env, new_ty)
if let Ok(old_ty) =
tcx.try_normalize_erasing_regions(self.infcx.typing_env(self.param_env), old_ty)
&& let Ok(new_ty) = tcx.try_normalize_erasing_regions(
self.infcx.typing_env(self.param_env),
new_ty,
)
{
old_ty == new_ty
} else {
@ -703,7 +707,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
// Test the callee's predicates, substituting in `ref_ty` for the moved argument type.
clauses.instantiate(tcx, new_args).predicates.iter().all(|&(mut clause)| {
// Normalize before testing to see through type aliases and projections.
if let Ok(normalized) = tcx.try_normalize_erasing_regions(self.param_env, clause) {
if let Ok(normalized) =
tcx.try_normalize_erasing_regions(self.infcx.typing_env(self.param_env), clause)
{
clause = normalized;
}
self.infcx.predicate_must_hold_modulo_regions(&Obligation::new(
@ -3831,11 +3837,16 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
if tcx.is_diagnostic_item(sym::deref_method, method_did) {
let deref_target =
tcx.get_diagnostic_item(sym::deref_target).and_then(|deref_target| {
Instance::try_resolve(tcx, self.param_env, deref_target, method_args)
.transpose()
Instance::try_resolve(
tcx,
self.infcx.typing_env(self.param_env),
deref_target,
method_args,
)
.transpose()
});
if let Some(Ok(instance)) = deref_target {
let deref_target_ty = instance.ty(tcx, self.param_env);
let deref_target_ty = instance.ty(tcx, self.infcx.typing_env(self.param_env));
err.note(format!("borrow occurs due to deref coercion to `{deref_target_ty}`"));
err.span_note(tcx.def_span(instance.def_id()), "deref defined here");
}

View File

@ -864,7 +864,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
let kind = call_kind(
self.infcx.tcx,
self.param_env,
self.infcx.typing_env(self.param_env),
method_did,
method_args,
*fn_span,

View File

@ -952,7 +952,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
if let Ok(Some(instance)) = ty::Instance::try_resolve(
tcx,
self.param_env,
self.infcx.typing_env(self.param_env),
*fn_did,
self.infcx.resolve_vars_if_possible(args),
) {

View File

@ -1527,7 +1527,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
// The signature in this call can reference region variables,
// so erase them before calling a query.
let output_ty = self.tcx().erase_regions(sig.output());
if !output_ty.is_privately_uninhabited(self.tcx(), self.param_env) {
if !output_ty
.is_privately_uninhabited(self.tcx(), self.infcx.typing_env(self.param_env))
{
span_mirbug!(self, term, "call to converging function {:?} w/o dest", sig);
}
}

View File

@ -376,7 +376,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
let instance = if let ty::FnDef(def_id, fn_args) = *func.layout().ty.kind() {
let instance = ty::Instance::expect_resolve(
fx.tcx,
ty::ParamEnv::reveal_all(),
ty::TypingEnv::fully_monomorphized(),
def_id,
fn_args,
source_info.span,

View File

@ -666,7 +666,7 @@ fn codegen_stmt<'tcx>(
let func_ref = fx.get_function_ref(
Instance::resolve_for_fn_ptr(
fx.tcx,
ParamEnv::reveal_all(),
ty::TypingEnv::fully_monomorphized(),
def_id,
args,
)
@ -841,14 +841,18 @@ fn codegen_stmt<'tcx>(
lval.write_cvalue(fx, CValue::by_val(operand, box_layout));
}
Rvalue::NullaryOp(ref null_op, ty) => {
assert!(lval.layout().ty.is_sized(fx.tcx, ParamEnv::reveal_all()));
assert!(lval.layout().ty.is_sized(fx.tcx, ty::ParamEnv::reveal_all()));
let layout = fx.layout_of(fx.monomorphize(ty));
let val = match null_op {
NullOp::SizeOf => layout.size.bytes(),
NullOp::AlignOf => layout.align.abi.bytes(),
NullOp::OffsetOf(fields) => fx
.tcx
.offset_of_subfield(ParamEnv::reveal_all(), layout, fields.iter())
.offset_of_subfield(
ty::TypingEnv::fully_monomorphized(),
layout,
fields.iter(),
)
.bytes(),
NullOp::UbChecks => {
let val = fx.tcx.sess.ub_checks();

View File

@ -103,11 +103,11 @@ fn clif_pair_type_from_ty<'tcx>(
/// Is a pointer to this type a wide ptr?
pub(crate) fn has_ptr_meta<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
if ty.is_sized(tcx, ParamEnv::reveal_all()) {
if ty.is_sized(tcx, ty::ParamEnv::reveal_all()) {
return false;
}
let tail = tcx.struct_tail_for_codegen(ty, ParamEnv::reveal_all());
let tail = tcx.struct_tail_for_codegen(ty, ty::TypingEnv::fully_monomorphized());
match tail.kind() {
ty::Foreign(..) => false,
ty::Str | ty::Slice(..) | ty::Dynamic(..) => true,
@ -339,9 +339,9 @@ impl<'tcx> rustc_abi::HasDataLayout for FunctionCx<'_, '_, 'tcx> {
}
}
impl<'tcx> layout::HasParamEnv<'tcx> for FunctionCx<'_, '_, 'tcx> {
fn param_env(&self) -> ParamEnv<'tcx> {
ParamEnv::reveal_all()
impl<'tcx> layout::HasTypingEnv<'tcx> for FunctionCx<'_, '_, 'tcx> {
fn typing_env(&self) -> ty::TypingEnv<'tcx> {
ty::TypingEnv::fully_monomorphized()
}
}
@ -358,7 +358,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
{
self.instance.instantiate_mir_and_normalize_erasing_regions(
self.tcx,
ty::ParamEnv::reveal_all(),
ty::TypingEnv::fully_monomorphized(),
ty::EarlyBinder::bind(value),
)
}
@ -497,9 +497,9 @@ impl<'tcx> rustc_abi::HasDataLayout for RevealAllLayoutCx<'tcx> {
}
}
impl<'tcx> layout::HasParamEnv<'tcx> for RevealAllLayoutCx<'tcx> {
fn param_env(&self) -> ParamEnv<'tcx> {
ParamEnv::reveal_all()
impl<'tcx> layout::HasTypingEnv<'tcx> for RevealAllLayoutCx<'tcx> {
fn typing_env(&self) -> ty::TypingEnv<'tcx> {
ty::TypingEnv::fully_monomorphized()
}
}

View File

@ -78,7 +78,7 @@ pub(crate) fn eval_mir_constant<'tcx>(
let cv = fx.monomorphize(constant.const_);
// This cannot fail because we checked all required_consts in advance.
let val = cv
.eval(fx.tcx, ty::ParamEnv::reveal_all(), constant.span)
.eval(fx.tcx, ty::TypingEnv::fully_monomorphized(), constant.span)
.expect("erroneous constant missed by mono item collection");
(val, cv.ty())
}
@ -265,8 +265,13 @@ fn data_id_for_static(
assert!(!definition);
assert!(!tcx.is_mutable_static(def_id));
let ty = instance.ty(tcx, ParamEnv::reveal_all());
let align = tcx.layout_of(ParamEnv::reveal_all().and(ty)).unwrap().align.pref.bytes();
let ty = instance.ty(tcx, ty::TypingEnv::fully_monomorphized());
let align = tcx
.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty))
.unwrap()
.align
.pref
.bytes();
let linkage = if import_linkage == rustc_middle::mir::mono::Linkage::ExternalWeak
|| import_linkage == rustc_middle::mir::mono::Linkage::WeakAny

View File

@ -210,7 +210,7 @@ impl DebugContext {
type_names::push_generic_params(
tcx,
tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), args),
tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), args),
&mut name,
);
@ -275,8 +275,10 @@ impl DebugContext {
let span = tcx.def_span(def_id);
let (file_id, line, _column) = self.get_span_loc(tcx, span, span);
let static_type = Instance::mono(tcx, def_id).ty(tcx, ty::ParamEnv::reveal_all());
let static_layout = tcx.layout_of(ty::ParamEnv::reveal_all().and(static_type)).unwrap();
let static_type = Instance::mono(tcx, def_id).ty(tcx, ty::TypingEnv::fully_monomorphized());
let static_layout = tcx
.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(static_type))
.unwrap();
// FIXME use the actual type layout
let type_id = self.debug_type(tcx, type_dbg, static_type);

View File

@ -92,7 +92,7 @@ pub(crate) fn codegen_inline_asm_terminator<'tcx>(
if let ty::FnDef(def_id, args) = *const_.ty().kind() {
let instance = ty::Instance::resolve_for_fn_ptr(
fx.tcx,
ty::ParamEnv::reveal_all(),
ty::TypingEnv::fully_monomorphized(),
def_id,
args,
)
@ -227,11 +227,11 @@ pub(crate) fn codegen_naked_asm<'tcx>(
InlineAsmOperand::Const { ref value } => {
let cv = instance.instantiate_mir_and_normalize_erasing_regions(
tcx,
ty::ParamEnv::reveal_all(),
ty::TypingEnv::fully_monomorphized(),
ty::EarlyBinder::bind(value.const_),
);
let const_value = cv
.eval(tcx, ty::ParamEnv::reveal_all(), value.span)
.eval(tcx, ty::TypingEnv::fully_monomorphized(), value.span)
.expect("erroneous constant missed by mono item collection");
let value = rustc_codegen_ssa::common::asm_const_to_str(
@ -250,13 +250,13 @@ pub(crate) fn codegen_naked_asm<'tcx>(
let const_ = instance.instantiate_mir_and_normalize_erasing_regions(
tcx,
ty::ParamEnv::reveal_all(),
ty::TypingEnv::fully_monomorphized(),
ty::EarlyBinder::bind(value.const_),
);
if let ty::FnDef(def_id, args) = *const_.ty().kind() {
let instance = ty::Instance::resolve_for_fn_ptr(
tcx,
ty::ParamEnv::reveal_all(),
ty::TypingEnv::fully_monomorphized(),
def_id,
args,
)

View File

@ -20,7 +20,7 @@ mod simd;
use cranelift_codegen::ir::AtomicRmwOp;
use rustc_middle::ty;
use rustc_middle::ty::GenericArgsRef;
use rustc_middle::ty::layout::{HasParamEnv, ValidityRequirement};
use rustc_middle::ty::layout::ValidityRequirement;
use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
use rustc_span::source_map::Spanned;
use rustc_span::symbol::{Symbol, sym};
@ -682,7 +682,10 @@ fn codegen_regular_intrinsic_call<'tcx>(
if let Some(requirement) = requirement {
let do_panic = !fx
.tcx
.check_validity_requirement((requirement, fx.param_env().and(ty)))
.check_validity_requirement((
requirement,
ty::TypingEnv::fully_monomorphized().as_query_input(ty),
))
.expect("expect to have layout during codegen");
if do_panic {
@ -741,7 +744,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
let const_val = fx
.tcx
.const_eval_instance(ParamEnv::reveal_all(), instance, source_info.span)
.const_eval_instance(ty::ParamEnv::reveal_all(), instance, source_info.span)
.unwrap();
let val = crate::constant::codegen_const_value(fx, const_val, ret.layout().ty);
ret.write_cvalue(fx, val);

View File

@ -98,7 +98,7 @@ mod prelude {
pub(crate) use rustc_middle::mir::{self, *};
pub(crate) use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
pub(crate) use rustc_middle::ty::{
self, FloatTy, Instance, InstanceKind, IntTy, ParamEnv, Ty, TyCtxt, UintTy,
self, FloatTy, Instance, InstanceKind, IntTy, Ty, TyCtxt, UintTy,
};
pub(crate) use rustc_span::Span;

View File

@ -49,7 +49,7 @@ pub(crate) fn maybe_create_entry_wrapper(
// regions must appear in the argument
// listing.
let main_ret_ty = tcx.normalize_erasing_regions(
ty::ParamEnv::reveal_all(),
ty::TypingEnv::fully_monomorphized(),
main_ret_ty.no_bound_vars().unwrap(),
);
@ -113,7 +113,7 @@ pub(crate) fn maybe_create_entry_wrapper(
.unwrap();
let report = Instance::expect_resolve(
tcx,
ParamEnv::reveal_all(),
ty::TypingEnv::fully_monomorphized(),
report.def_id,
tcx.mk_args(&[GenericArg::from(main_ret_ty)]),
DUMMY_SP,
@ -139,7 +139,7 @@ pub(crate) fn maybe_create_entry_wrapper(
let start_def_id = tcx.require_lang_item(LangItem::Start, None);
let start_instance = Instance::expect_resolve(
tcx,
ParamEnv::reveal_all(),
ty::TypingEnv::fully_monomorphized(),
start_def_id,
tcx.mk_args(&[main_ret_ty.into()]),
DUMMY_SP,

View File

@ -3,6 +3,7 @@
//! [`PointerCoercion::Unsize`]: `rustc_middle::ty::adjustment::PointerCoercion::Unsize`
use rustc_codegen_ssa::base::validate_trivial_unsize;
use rustc_middle::ty::layout::HasTypingEnv;
use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
use crate::base::codegen_panic_nounwind;
@ -23,7 +24,7 @@ pub(crate) fn unsized_info<'tcx>(
old_info: Option<Value>,
) -> Value {
let (source, target) =
fx.tcx.struct_lockstep_tails_for_codegen(source, target, ParamEnv::reveal_all());
fx.tcx.struct_lockstep_tails_for_codegen(source, target, fx.typing_env());
match (&source.kind(), &target.kind()) {
(&ty::Array(_, len), &ty::Slice(_)) => fx.bcx.ins().iconst(
fx.pointer_type,

View File

@ -4,6 +4,7 @@ use cranelift_codegen::entity::EntityRef;
use cranelift_codegen::ir::immediates::Offset32;
use cranelift_frontend::Variable;
use rustc_middle::ty::FnSig;
use rustc_middle::ty::layout::HasTypingEnv;
use crate::prelude::*;
@ -884,19 +885,17 @@ pub(crate) fn assert_assignable<'tcx>(
assert_assignable(fx, *a, *b, limit - 1);
}
(ty::FnPtr(..), ty::FnPtr(..)) => {
let from_sig = fx.tcx.normalize_erasing_late_bound_regions(
ParamEnv::reveal_all(),
from_ty.fn_sig(fx.tcx),
);
let from_sig = fx
.tcx
.normalize_erasing_late_bound_regions(fx.typing_env(), from_ty.fn_sig(fx.tcx));
let FnSig {
inputs_and_output: types_from,
c_variadic: c_variadic_from,
safety: unsafety_from,
abi: abi_from,
} = from_sig;
let to_sig = fx
.tcx
.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), to_ty.fn_sig(fx.tcx));
let to_sig =
fx.tcx.normalize_erasing_late_bound_regions(fx.typing_env(), to_ty.fn_sig(fx.tcx));
let FnSig {
inputs_and_output: types_to,
c_variadic: c_variadic_to,
@ -932,9 +931,8 @@ pub(crate) fn assert_assignable<'tcx>(
(&ty::Dynamic(from_traits, _, _from_kind), &ty::Dynamic(to_traits, _, _to_kind)) => {
// FIXME(dyn-star): Do the right thing with DynKinds
for (from, to) in from_traits.iter().zip(to_traits) {
let from =
fx.tcx.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), from);
let to = fx.tcx.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), to);
let from = fx.tcx.normalize_erasing_late_bound_regions(fx.typing_env(), from);
let to = fx.tcx.normalize_erasing_late_bound_regions(fx.typing_env(), to);
assert_eq!(
from, to,
"Can't write trait object of incompatible traits {:?} to place with traits {:?}\n\n{:#?}",

View File

@ -24,9 +24,9 @@ use rustc_data_structures::fx::FxHashSet;
use rustc_middle::bug;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
use rustc_middle::ty::layout::{
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, HasTyCtxt, LayoutError, LayoutOfHelpers,
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasTyCtxt, HasTypingEnv, LayoutError, LayoutOfHelpers,
};
use rustc_middle::ty::{Instance, ParamEnv, Ty, TyCtxt};
use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
use rustc_span::Span;
use rustc_span::def_id::DefId;
use rustc_target::abi::call::FnAbi;
@ -2319,9 +2319,9 @@ impl<'a, 'gcc, 'tcx> StaticBuilderMethods for Builder<'a, 'gcc, 'tcx> {
}
}
impl<'tcx> HasParamEnv<'tcx> for Builder<'_, '_, 'tcx> {
fn param_env(&self) -> ParamEnv<'tcx> {
self.cx.param_env()
impl<'tcx> HasTypingEnv<'tcx> for Builder<'_, '_, 'tcx> {
fn typing_env(&self) -> ty::TypingEnv<'tcx> {
self.cx.typing_env()
}
}

View File

@ -215,7 +215,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
let gcc_type = if nested {
self.type_i8()
} else {
let ty = instance.ty(self.tcx, ty::ParamEnv::reveal_all());
let ty = instance.ty(self.tcx, ty::TypingEnv::fully_monomorphized());
self.layout_of(ty).gcc_type(self)
};

View File

@ -11,10 +11,10 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_middle::mir::mono::CodegenUnit;
use rustc_middle::span_bug;
use rustc_middle::ty::layout::{
FnAbiError, FnAbiOf, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, HasTyCtxt, LayoutError,
FnAbiError, FnAbiOf, FnAbiOfHelpers, FnAbiRequest, HasTyCtxt, HasTypingEnv, LayoutError,
LayoutOfHelpers,
};
use rustc_middle::ty::{self, Instance, ParamEnv, PolyExistentialTraitRef, Ty, TyCtxt};
use rustc_middle::ty::{self, Instance, PolyExistentialTraitRef, Ty, TyCtxt};
use rustc_session::Session;
use rustc_span::source_map::respan;
use rustc_span::{DUMMY_SP, Span};
@ -144,7 +144,9 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
supports_f128_type: bool,
) -> Self {
let create_type = |ctype, rust_type| {
let layout = tcx.layout_of(ParamEnv::reveal_all().and(rust_type)).unwrap();
let layout = tcx
.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(rust_type))
.unwrap();
let align = layout.align.abi.bytes();
#[cfg(feature = "master")]
{
@ -459,7 +461,7 @@ impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
Some(def_id) if !wants_msvc_seh(self.sess()) => {
let instance = ty::Instance::expect_resolve(
tcx,
ty::ParamEnv::reveal_all(),
self.typing_env(),
def_id,
ty::List::empty(),
DUMMY_SP,
@ -583,9 +585,9 @@ impl<'gcc, 'tcx> FnAbiOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> {
}
}
impl<'tcx, 'gcc> HasParamEnv<'tcx> for CodegenCx<'gcc, 'tcx> {
fn param_env(&self) -> ParamEnv<'tcx> {
ParamEnv::reveal_all()
impl<'tcx, 'gcc> HasTypingEnv<'tcx> for CodegenCx<'gcc, 'tcx> {
fn typing_env(&self) -> ty::TypingEnv<'tcx> {
ty::TypingEnv::fully_monomorphized()
}
}

View File

@ -5,7 +5,7 @@
use gccjit::{BinaryOp, ComparisonOp, FunctionType, Location, RValue, ToRValue, Type, UnaryOp};
use rustc_codegen_ssa::common::{IntPredicate, TypeKind};
use rustc_codegen_ssa::traits::{BackendTypes, BaseTypeCodegenMethods, BuilderMethods, OverflowOp};
use rustc_middle::ty::{ParamEnv, Ty};
use rustc_middle::ty::{self, Ty};
use rustc_target::abi::Endian;
use rustc_target::abi::call::{ArgAbi, ArgAttributes, Conv, FnAbi, PassMode};
use rustc_target::spec;
@ -380,7 +380,10 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
let overflow_field = self.context.new_field(self.location, self.bool_type, "overflow");
let ret_ty = Ty::new_tup(self.tcx, &[self.tcx.types.i128, self.tcx.types.bool]);
let layout = self.tcx.layout_of(ParamEnv::reveal_all().and(ret_ty)).unwrap();
let layout = self
.tcx
.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ret_ty))
.unwrap();
let arg_abi = ArgAbi { layout, mode: PassMode::Direct(ArgAttributes::new()) };
let mut fn_abi = FnAbi {

View File

@ -21,7 +21,7 @@ use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, MiscCodegenMethods};
use rustc_middle::bug;
use rustc_middle::ty::layout::LayoutOf;
#[cfg(feature = "master")]
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt};
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, HasTypingEnv};
use rustc_middle::ty::{self, Instance, Ty};
use rustc_span::{Span, Symbol, sym};
use rustc_target::abi::HasDataLayout;
@ -107,7 +107,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
span: Span,
) -> Result<(), Instance<'tcx>> {
let tcx = self.tcx;
let callee_ty = instance.ty(tcx, ty::ParamEnv::reveal_all());
let callee_ty = instance.ty(tcx, self.typing_env());
let (def_id, fn_args) = match *callee_ty.kind() {
ty::FnDef(def_id, fn_args) => (def_id, fn_args),
@ -115,7 +115,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
};
let sig = callee_ty.fn_sig(tcx);
let sig = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), sig);
let sig = tcx.normalize_erasing_late_bound_regions(self.typing_env(), sig);
let arg_tys = sig.inputs();
let ret_ty = sig.output();
let name = tcx.item_name(def_id);

View File

@ -55,8 +55,10 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
}
let tcx = bx.tcx();
let sig =
tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), callee_ty.fn_sig(tcx));
let sig = tcx.normalize_erasing_late_bound_regions(
ty::TypingEnv::fully_monomorphized(),
callee_ty.fn_sig(tcx),
);
let arg_tys = sig.inputs();
if name == sym::simd_select_bitmask {
@ -478,7 +480,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
match *in_elem.kind() {
ty::RawPtr(p_ty, _) => {
let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| {
bx.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), ty)
bx.tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), ty)
});
require!(metadata.is_unit(), InvalidMonomorphization::CastWidePointer {
span,
@ -493,7 +495,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
match *out_elem.kind() {
ty::RawPtr(p_ty, _) => {
let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| {
bx.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), ty)
bx.tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), ty)
});
require!(metadata.is_unit(), InvalidMonomorphization::CastWidePointer {
span,

View File

@ -6,7 +6,7 @@ use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_middle::bug;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::mir::mono::{Linkage, Visibility};
use rustc_middle::ty::layout::{FnAbiOf, LayoutOf};
use rustc_middle::ty::layout::{FnAbiOf, HasTypingEnv, LayoutOf};
use rustc_middle::ty::{self, Instance, TypeVisitableExt};
use crate::context::CodegenCx;
@ -27,11 +27,8 @@ impl<'gcc, 'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
let DefKind::Static { nested, .. } = self.tcx.def_kind(def_id) else { bug!() };
// Nested statics do not have a type, so pick a dummy type and let `codegen_static` figure out
// the gcc type from the actual evaluated initializer.
let ty = if nested {
self.tcx.types.unit
} else {
instance.ty(self.tcx, ty::ParamEnv::reveal_all())
};
let ty =
if nested { self.tcx.types.unit } else { instance.ty(self.tcx, self.typing_env()) };
let gcc_type = self.layout_of(ty).gcc_type(self);
let is_tls = attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL);

View File

@ -14,7 +14,7 @@ use rustc_data_structures::small_c_str::SmallCStr;
use rustc_hir::def_id::DefId;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
use rustc_middle::ty::layout::{
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, LayoutError, LayoutOfHelpers,
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasTypingEnv, LayoutError, LayoutOfHelpers,
TyAndLayout,
};
use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
@ -81,9 +81,9 @@ impl<'tcx> ty::layout::HasTyCtxt<'tcx> for Builder<'_, '_, 'tcx> {
}
}
impl<'tcx> ty::layout::HasParamEnv<'tcx> for Builder<'_, '_, 'tcx> {
fn param_env(&self) -> ty::ParamEnv<'tcx> {
self.cx.param_env()
impl<'tcx> ty::layout::HasTypingEnv<'tcx> for Builder<'_, '_, 'tcx> {
fn typing_env(&self) -> ty::TypingEnv<'tcx> {
self.cx.typing_env()
}
}
@ -472,7 +472,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
#[instrument(level = "trace", skip(self))]
fn load_operand(&mut self, place: PlaceRef<'tcx, &'ll Value>) -> OperandRef<'tcx, &'ll Value> {
if place.layout.is_unsized() {
let tail = self.tcx.struct_tail_for_codegen(place.layout.ty, self.param_env());
let tail = self.tcx.struct_tail_for_codegen(place.layout.ty, self.typing_env());
if matches!(tail.kind(), ty::Foreign(..)) {
// Unsized locals and, at least conceptually, even unsized arguments must be copied
// around, which requires dynamically determining their size. Therefore, we cannot

View File

@ -5,7 +5,7 @@
//! closure.
use rustc_codegen_ssa::common;
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt};
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, HasTypingEnv};
use rustc_middle::ty::{self, Instance, TypeVisitableExt};
use tracing::debug;
@ -28,12 +28,7 @@ pub(crate) fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'t
}
let sym = tcx.symbol_name(instance).name;
debug!(
"get_fn({:?}: {:?}) => {}",
instance,
instance.ty(cx.tcx(), ty::ParamEnv::reveal_all()),
sym
);
debug!("get_fn({:?}: {:?}) => {}", instance, instance.ty(cx.tcx(), cx.typing_env()), sym);
let fn_abi = cx.fn_abi_of_instance(instance, ty::List::empty());

View File

@ -13,8 +13,8 @@ use rustc_middle::mir::interpret::{
read_target_uint,
};
use rustc_middle::mir::mono::MonoItem;
use rustc_middle::ty::layout::LayoutOf;
use rustc_middle::ty::{self, Instance};
use rustc_middle::ty::Instance;
use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf};
use rustc_middle::{bug, span_bug};
use rustc_session::config::Lto;
use tracing::{debug, instrument, trace};
@ -244,7 +244,7 @@ impl<'ll> CodegenCx<'ll, '_> {
let llty = if nested {
self.type_i8()
} else {
let ty = instance.ty(self.tcx, ty::ParamEnv::reveal_all());
let ty = instance.ty(self.tcx, self.typing_env());
trace!(?ty);
self.layout_of(ty).llvm_type(self)
};

View File

@ -15,7 +15,7 @@ use rustc_hir::def_id::DefId;
use rustc_middle::middle::codegen_fn_attrs::PatchableFunctionEntry;
use rustc_middle::mir::mono::CodegenUnit;
use rustc_middle::ty::layout::{
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, LayoutError, LayoutOfHelpers,
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasTypingEnv, LayoutError, LayoutOfHelpers,
};
use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
use rustc_middle::{bug, span_bug};
@ -658,7 +658,7 @@ impl<'ll, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
let llfn = match tcx.lang_items().eh_personality() {
Some(def_id) if name.is_none() => self.get_fn_addr(ty::Instance::expect_resolve(
tcx,
ty::ParamEnv::reveal_all(),
self.typing_env(),
def_id,
ty::List::empty(),
DUMMY_SP,
@ -1162,9 +1162,9 @@ impl<'tcx> ty::layout::HasTyCtxt<'tcx> for CodegenCx<'_, 'tcx> {
}
}
impl<'tcx, 'll> HasParamEnv<'tcx> for CodegenCx<'ll, 'tcx> {
fn param_env(&self) -> ty::ParamEnv<'tcx> {
ty::ParamEnv::reveal_all()
impl<'tcx, 'll> HasTypingEnv<'tcx> for CodegenCx<'ll, 'tcx> {
fn typing_env(&self) -> ty::TypingEnv<'tcx> {
ty::TypingEnv::fully_monomorphized()
}
}

View File

@ -6,7 +6,7 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_index::Idx;
use rustc_index::bit_set::BitSet;
use rustc_middle::mir::{Body, SourceScope};
use rustc_middle::ty::layout::FnAbiOf;
use rustc_middle::ty::layout::{FnAbiOf, HasTypingEnv};
use rustc_middle::ty::{self, Instance};
use rustc_session::config::DebugInfo;
use rustc_span::BytePos;
@ -118,7 +118,7 @@ fn make_mir_scope<'ll, 'tcx>(
// if this is moved to `rustc_codegen_ssa::mir::debuginfo`.
let callee = cx.tcx.instantiate_and_normalize_erasing_regions(
instance.args,
ty::ParamEnv::reveal_all(),
cx.typing_env(),
ty::EarlyBinder::bind(callee),
);
debug_context.inlined_function_scopes.entry(callee).or_insert_with(|| {

View File

@ -11,10 +11,9 @@ use rustc_codegen_ssa::traits::*;
use rustc_hir::def::{CtorKind, DefKind};
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_middle::bug;
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf, TyAndLayout};
use rustc_middle::ty::{
self, AdtKind, CoroutineArgsExt, Instance, ParamEnv, PolyExistentialTraitRef, Ty, TyCtxt,
Visibility,
self, AdtKind, CoroutineArgsExt, Instance, PolyExistentialTraitRef, Ty, TyCtxt, Visibility,
};
use rustc_session::config::{self, DebugInfo, Lto};
use rustc_span::symbol::Symbol;
@ -301,9 +300,8 @@ fn build_subroutine_type_di_node<'ll, 'tcx>(
.insert(unique_type_id, recursion_marker_type_di_node(cx));
let fn_ty = unique_type_id.expect_ty();
let signature = cx
.tcx
.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), fn_ty.fn_sig(cx.tcx));
let signature =
cx.tcx.normalize_erasing_late_bound_regions(cx.typing_env(), fn_ty.fn_sig(cx.tcx));
let signature_di_nodes: SmallVec<_> = iter::once(
// return type
@ -1109,9 +1107,7 @@ fn build_upvar_field_di_nodes<'ll, 'tcx>(
}
};
assert!(
up_var_tys.iter().all(|t| t == cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), t))
);
assert!(up_var_tys.iter().all(|t| t == cx.tcx.normalize_erasing_regions(cx.typing_env(), t)));
let capture_names = cx.tcx.closure_saved_names_of_captured_variables(def_id);
let layout = cx.layout_of(closure_or_coroutine_ty);
@ -1272,8 +1268,7 @@ fn build_generic_type_param_di_nodes<'ll, 'tcx>(
let template_params: SmallVec<_> = iter::zip(args, names)
.filter_map(|(kind, name)| {
kind.as_type().map(|ty| {
let actual_type =
cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
let actual_type = cx.tcx.normalize_erasing_regions(cx.typing_env(), ty);
let actual_type_di_node = type_di_node(cx, actual_type);
let name = name.as_str();
unsafe {
@ -1341,7 +1336,7 @@ pub(crate) fn build_global_var_di_node<'ll>(
if nested {
return;
}
let variable_type = Instance::mono(cx.tcx, def_id).ty(cx.tcx, ty::ParamEnv::reveal_all());
let variable_type = Instance::mono(cx.tcx, def_id).ty(cx.tcx, cx.typing_env());
let type_di_node = type_di_node(cx, variable_type);
let var_name = tcx.item_name(def_id);
let var_name = var_name.as_str();

View File

@ -6,7 +6,7 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_macros::HashStable;
use rustc_middle::bug;
use rustc_middle::ty::{ParamEnv, PolyExistentialTraitRef, Ty, TyCtxt};
use rustc_middle::ty::{self, PolyExistentialTraitRef, Ty, TyCtxt};
use super::{SmallVec, UNKNOWN_LINE_NUMBER, unknown_file_metadata};
use crate::common::{AsCCharPtr, CodegenCx};
@ -49,12 +49,15 @@ pub(super) enum UniqueTypeId<'tcx> {
impl<'tcx> UniqueTypeId<'tcx> {
pub(crate) fn for_ty(tcx: TyCtxt<'tcx>, t: Ty<'tcx>) -> Self {
assert_eq!(t, tcx.normalize_erasing_regions(ParamEnv::reveal_all(), t));
assert_eq!(t, tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), t));
UniqueTypeId::Ty(t, private::HiddenZst)
}
pub(crate) fn for_enum_variant_part(tcx: TyCtxt<'tcx>, enum_ty: Ty<'tcx>) -> Self {
assert_eq!(enum_ty, tcx.normalize_erasing_regions(ParamEnv::reveal_all(), enum_ty));
assert_eq!(
enum_ty,
tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), enum_ty)
);
UniqueTypeId::VariantPart(enum_ty, private::HiddenZst)
}
@ -63,7 +66,10 @@ impl<'tcx> UniqueTypeId<'tcx> {
enum_ty: Ty<'tcx>,
variant_idx: VariantIdx,
) -> Self {
assert_eq!(enum_ty, tcx.normalize_erasing_regions(ParamEnv::reveal_all(), enum_ty));
assert_eq!(
enum_ty,
tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), enum_ty)
);
UniqueTypeId::VariantStructType(enum_ty, variant_idx, private::HiddenZst)
}
@ -72,7 +78,10 @@ impl<'tcx> UniqueTypeId<'tcx> {
enum_ty: Ty<'tcx>,
variant_idx: VariantIdx,
) -> Self {
assert_eq!(enum_ty, tcx.normalize_erasing_regions(ParamEnv::reveal_all(), enum_ty));
assert_eq!(
enum_ty,
tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), enum_ty)
);
UniqueTypeId::VariantStructTypeCppLikeWrapper(enum_ty, variant_idx, private::HiddenZst)
}
@ -81,10 +90,13 @@ impl<'tcx> UniqueTypeId<'tcx> {
self_type: Ty<'tcx>,
implemented_trait: Option<PolyExistentialTraitRef<'tcx>>,
) -> Self {
assert_eq!(self_type, tcx.normalize_erasing_regions(ParamEnv::reveal_all(), self_type));
assert_eq!(
self_type,
tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), self_type)
);
assert_eq!(
implemented_trait,
tcx.normalize_erasing_regions(ParamEnv::reveal_all(), implemented_trait)
tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), implemented_trait)
);
UniqueTypeId::VTableTy(self_type, implemented_trait, private::HiddenZst)
}

View File

@ -15,8 +15,8 @@ use rustc_data_structures::unord::UnordMap;
use rustc_hir::def_id::{DefId, DefIdMap};
use rustc_index::IndexVec;
use rustc_middle::mir;
use rustc_middle::ty::layout::LayoutOf;
use rustc_middle::ty::{self, GenericArgsRef, Instance, ParamEnv, Ty, TypeVisitableExt};
use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf};
use rustc_middle::ty::{self, GenericArgsRef, Instance, Ty, TypeVisitableExt};
use rustc_session::Session;
use rustc_session::config::{self, DebugInfo};
use rustc_span::symbol::Symbol;
@ -344,7 +344,7 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
type_names::push_generic_params(
tcx,
tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), args),
tcx.normalize_erasing_regions(self.typing_env(), args),
&mut name,
);
@ -481,8 +481,7 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
iter::zip(args, names)
.filter_map(|(kind, name)| {
kind.as_type().map(|ty| {
let actual_type =
cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
let actual_type = cx.tcx.normalize_erasing_regions(cx.typing_env(), ty);
let actual_type_metadata = type_di_node(cx, actual_type);
let name = name.as_str();
unsafe {
@ -526,7 +525,7 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
if cx.tcx.trait_id_of_impl(impl_def_id).is_none() {
let impl_self_ty = cx.tcx.instantiate_and_normalize_erasing_regions(
instance.args,
ty::ParamEnv::reveal_all(),
cx.typing_env(),
cx.tcx.type_of(impl_def_id),
);

View File

@ -1,7 +1,7 @@
// Utility Functions.
use rustc_hir::def_id::DefId;
use rustc_middle::ty::layout::{HasParamEnv, LayoutOf};
use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf};
use rustc_middle::ty::{self, Ty};
use tracing::trace;
@ -62,7 +62,7 @@ pub(crate) fn wide_pointer_kind<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>,
pointee_ty: Ty<'tcx>,
) -> Option<WidePtrKind> {
let pointee_tail_ty = cx.tcx.struct_tail_for_codegen(pointee_ty, cx.param_env());
let pointee_tail_ty = cx.tcx.struct_tail_for_codegen(pointee_ty, cx.typing_env());
let layout = cx.layout_of(pointee_tail_ty);
trace!(
"wide_pointer_kind: {:?} has layout {:?} (is_unsized? {})",

View File

@ -10,7 +10,7 @@ use rustc_codegen_ssa::mir::place::{PlaceRef, PlaceValue};
use rustc_codegen_ssa::traits::*;
use rustc_hir as hir;
use rustc_middle::mir::BinOp;
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, LayoutOf};
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, HasTypingEnv, LayoutOf};
use rustc_middle::ty::{self, GenericArgsRef, Ty};
use rustc_middle::{bug, span_bug};
use rustc_span::{Span, Symbol, sym};
@ -163,14 +163,14 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
span: Span,
) -> Result<(), ty::Instance<'tcx>> {
let tcx = self.tcx;
let callee_ty = instance.ty(tcx, ty::ParamEnv::reveal_all());
let callee_ty = instance.ty(tcx, self.typing_env());
let ty::FnDef(def_id, fn_args) = *callee_ty.kind() else {
bug!("expected fn item type, found {}", callee_ty);
};
let sig = callee_ty.fn_sig(tcx);
let sig = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), sig);
let sig = tcx.normalize_erasing_late_bound_regions(self.typing_env(), sig);
let arg_tys = sig.inputs();
let ret_ty = sig.output();
let name = tcx.item_name(def_id);
@ -1152,8 +1152,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
}
let tcx = bx.tcx();
let sig =
tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), callee_ty.fn_sig(tcx));
let sig = tcx.normalize_erasing_late_bound_regions(bx.typing_env(), callee_ty.fn_sig(tcx));
let arg_tys = sig.inputs();
// Sanity-check: all vector arguments must be immediates.
@ -2187,7 +2186,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
match in_elem.kind() {
ty::RawPtr(p_ty, _) => {
let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| {
bx.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), ty)
bx.tcx.normalize_erasing_regions(bx.typing_env(), ty)
});
require!(metadata.is_unit(), InvalidMonomorphization::CastWidePointer {
span,
@ -2202,7 +2201,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
match out_elem.kind() {
ty::RawPtr(p_ty, _) => {
let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| {
bx.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), ty)
bx.tcx.normalize_erasing_regions(bx.typing_env(), ty)
});
require!(metadata.is_unit(), InvalidMonomorphization::CastWidePointer {
span,

View File

@ -3,7 +3,7 @@ use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_middle::bug;
use rustc_middle::mir::mono::{Linkage, Visibility};
use rustc_middle::ty::layout::{FnAbiOf, LayoutOf};
use rustc_middle::ty::layout::{FnAbiOf, HasTypingEnv, LayoutOf};
use rustc_middle::ty::{self, Instance, TypeVisitableExt};
use rustc_session::config::CrateType;
use rustc_target::spec::RelocModel;
@ -26,11 +26,8 @@ impl<'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
let DefKind::Static { nested, .. } = self.tcx.def_kind(def_id) else { bug!() };
// Nested statics do not have a type, so pick a dummy type and let `codegen_static` figure
// out the llvm type from the actual evaluated initializer.
let ty = if nested {
self.tcx.types.unit
} else {
instance.ty(self.tcx, ty::ParamEnv::reveal_all())
};
let ty =
if nested { self.tcx.types.unit } else { instance.ty(self.tcx, self.typing_env()) };
let llty = self.layout_of(ty).llvm_type(self);
let g = self.define_global(symbol_name, llty).unwrap_or_else(|| {

View File

@ -595,8 +595,10 @@ pub(crate) fn linking_symbol_name_for_instance_in_crate<'tcx>(
let (conv, args) = instance
.map(|i| {
tcx.fn_abi_of_instance(ty::ParamEnv::reveal_all().and((i, ty::List::empty())))
.unwrap_or_else(|_| bug!("fn_abi_of_instance({i:?}) failed"))
tcx.fn_abi_of_instance(
ty::TypingEnv::fully_monomorphized().as_query_input((i, ty::List::empty())),
)
.unwrap_or_else(|_| bug!("fn_abi_of_instance({i:?}) failed"))
})
.map(|fnabi| (fnabi.conv, &fnabi.args[..]))
.unwrap_or((Conv::Rust, &[]));

View File

@ -21,7 +21,7 @@ use rustc_middle::middle::{exported_symbols, lang_items};
use rustc_middle::mir::BinOp;
use rustc_middle::mir::mono::{CodegenUnit, CodegenUnitNameBuilder, MonoItem};
use rustc_middle::query::Providers;
use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout};
use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutOf, TyAndLayout};
use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypingMode};
use rustc_session::Session;
use rustc_session::config::{self, CrateType, EntryFnType, OptLevel, OutputType};
@ -165,7 +165,7 @@ fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
) -> Bx::Value {
let cx = bx.cx();
let (source, target) =
cx.tcx().struct_lockstep_tails_for_codegen(source, target, bx.param_env());
cx.tcx().struct_lockstep_tails_for_codegen(source, target, bx.typing_env());
match (source.kind(), target.kind()) {
(&ty::Array(_, len), &ty::Slice(_)) => cx.const_usize(
len.try_to_target_usize(cx.tcx()).expect("expected monomorphic const in codegen"),
@ -466,10 +466,9 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
// late-bound regions, since late-bound
// regions must appear in the argument
// listing.
let main_ret_ty = cx.tcx().normalize_erasing_regions(
ty::ParamEnv::reveal_all(),
main_ret_ty.no_bound_vars().unwrap(),
);
let main_ret_ty = cx
.tcx()
.normalize_erasing_regions(cx.typing_env(), main_ret_ty.no_bound_vars().unwrap());
let Some(llfn) = cx.declare_c_main(llfty) else {
// FIXME: We should be smart and show a better diagnostic here.
@ -495,7 +494,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
let start_def_id = cx.tcx().require_lang_item(LangItem::Start, None);
let start_instance = ty::Instance::expect_resolve(
cx.tcx(),
ty::ParamEnv::reveal_all(),
cx.typing_env(),
start_def_id,
cx.tcx().mk_args(&[main_ret_ty.into()]),
DUMMY_SP,

View File

@ -21,9 +21,7 @@ use rustc_hir::definitions::{DefPathData, DefPathDataName, DisambiguatedDefPathD
use rustc_hir::{CoroutineDesugaring, CoroutineKind, CoroutineSource, Mutability};
use rustc_middle::bug;
use rustc_middle::ty::layout::{IntegerExt, TyAndLayout};
use rustc_middle::ty::{
self, ExistentialProjection, GenericArgKind, GenericArgsRef, ParamEnv, Ty, TyCtxt,
};
use rustc_middle::ty::{self, ExistentialProjection, GenericArgKind, GenericArgsRef, Ty, TyCtxt};
use smallvec::SmallVec;
use crate::debuginfo::wants_c_like_enum_debuginfo;
@ -82,7 +80,7 @@ fn push_debuginfo_type_name<'tcx>(
ty::Adt(def, args) => {
// `layout_for_cpp_like_fallback` will be `Some` if we want to use the fallback encoding.
let layout_for_cpp_like_fallback = if cpp_like_debuginfo && def.is_enum() {
match tcx.layout_of(ParamEnv::reveal_all().and(t)) {
match tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(t)) {
Ok(layout) => {
if !wants_c_like_enum_debuginfo(tcx, layout) {
Some(layout)
@ -248,8 +246,10 @@ fn push_debuginfo_type_name<'tcx>(
};
if let Some(principal) = trait_data.principal() {
let principal =
tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), principal);
let principal = tcx.normalize_erasing_late_bound_regions(
ty::TypingEnv::fully_monomorphized(),
principal,
);
push_item_name(tcx, principal.def_id, qualified, output);
let principal_has_generic_params =
push_generic_params_internal(tcx, principal.args, output, visited);
@ -350,8 +350,10 @@ fn push_debuginfo_type_name<'tcx>(
return;
}
let sig =
tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), t.fn_sig(tcx));
let sig = tcx.normalize_erasing_late_bound_regions(
ty::TypingEnv::fully_monomorphized(),
t.fn_sig(tcx),
);
if cpp_like_debuginfo {
// Format as a C++ function pointer: return_type (*)(params...)
@ -415,7 +417,8 @@ fn push_debuginfo_type_name<'tcx>(
// In the case of cpp-like debuginfo, the name additionally gets wrapped inside of
// an artificial `enum2$<>` type, as defined in msvc_enum_fallback().
if cpp_like_debuginfo && t.is_coroutine() {
let ty_and_layout = tcx.layout_of(ParamEnv::reveal_all().and(t)).unwrap();
let ty_and_layout =
tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(t)).unwrap();
msvc_enum_fallback(
tcx,
ty_and_layout,
@ -529,8 +532,8 @@ pub fn compute_debuginfo_vtable_name<'tcx>(
}
if let Some(trait_ref) = trait_ref {
let trait_ref =
tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), trait_ref);
let trait_ref = tcx
.normalize_erasing_late_bound_regions(ty::TypingEnv::fully_monomorphized(), trait_ref);
push_item_name(tcx, trait_ref.def_id, true, &mut vtable_name);
visited.clear();
push_generic_params_internal(tcx, trait_ref.args, &mut vtable_name, &mut visited);
@ -639,7 +642,7 @@ fn push_generic_params_internal<'tcx>(
output: &mut String,
visited: &mut FxHashSet<Ty<'tcx>>,
) -> bool {
assert_eq!(args, tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), args));
assert_eq!(args, tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), args));
let mut args = args.non_erasable_generics().peekable();
if args.peek().is_none() {
return false;
@ -678,14 +681,14 @@ fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: ty::Const<'tcx>, output: &mut S
// FIXME: directly extract the bits from a valtree instead of evaluating an
// already evaluated `Const` in order to get the bits.
let bits = ct
.try_to_bits(tcx, ty::ParamEnv::reveal_all())
.try_to_bits(tcx, ty::TypingEnv::fully_monomorphized())
.expect("expected monomorphic const in codegen");
let val = Integer::from_int_ty(&tcx, *ity).size().sign_extend(bits) as i128;
write!(output, "{val}")
}
ty::Uint(_) => {
let val = ct
.try_to_bits(tcx, ty::ParamEnv::reveal_all())
.try_to_bits(tcx, ty::TypingEnv::fully_monomorphized())
.expect("expected monomorphic const in codegen");
write!(output, "{val}")
}

View File

@ -777,7 +777,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let do_panic = !bx
.tcx()
.check_validity_requirement((requirement, bx.param_env().and(ty)))
.check_validity_requirement((requirement, bx.typing_env().as_query_input(ty)))
.expect("expect to have layout during codegen");
let layout = bx.layout_of(ty);
@ -848,14 +848,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let (instance, mut llfn) = match *callee.layout.ty.kind() {
ty::FnDef(def_id, args) => (
Some(
ty::Instance::expect_resolve(
bx.tcx(),
ty::ParamEnv::reveal_all(),
def_id,
args,
fn_span,
)
.polymorphize(bx.tcx()),
ty::Instance::expect_resolve(bx.tcx(), bx.typing_env(), def_id, args, fn_span)
.polymorphize(bx.tcx()),
),
None,
),
@ -1191,7 +1185,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
if let ty::FnDef(def_id, args) = *const_.ty().kind() {
let instance = ty::Instance::resolve_for_fn_ptr(
bx.tcx(),
ty::ParamEnv::reveal_all(),
bx.typing_env(),
def_id,
args,
)

View File

@ -1,6 +1,6 @@
use rustc_abi::BackendRepr;
use rustc_middle::mir::interpret::ErrorHandled;
use rustc_middle::ty::layout::HasTyCtxt;
use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv};
use rustc_middle::ty::{self, Ty};
use rustc_middle::{bug, mir, span_bug};
@ -24,7 +24,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
// `MirUsedCollector` visited all required_consts before codegen began, so if we got here
// there can be no more constants that fail to evaluate.
self.monomorphize(constant.const_)
.eval(self.cx.tcx(), ty::ParamEnv::reveal_all(), constant.span)
.eval(self.cx.tcx(), self.cx.typing_env(), constant.span)
.expect("erroneous constant missed by mono item collection")
}
@ -57,7 +57,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
other => span_bug!(constant.span, "{other:#?}"),
};
let uv = self.monomorphize(uv);
self.cx.tcx().const_eval_resolve_for_typeck(ty::ParamEnv::reveal_all(), uv, constant.span)
self.cx.tcx().const_eval_resolve_for_typeck(self.cx.typing_env(), uv, constant.span)
}
/// process constant containing SIMD shuffle indices & constant vectors

View File

@ -59,14 +59,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
llresult: Bx::Value,
span: Span,
) -> Result<(), ty::Instance<'tcx>> {
let callee_ty = instance.ty(bx.tcx(), ty::ParamEnv::reveal_all());
let callee_ty = instance.ty(bx.tcx(), bx.typing_env());
let ty::FnDef(def_id, fn_args) = *callee_ty.kind() else {
bug!("expected fn item type, found {}", callee_ty);
};
let sig = callee_ty.fn_sig(bx.tcx());
let sig = bx.tcx().normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), sig);
let sig = bx.tcx().normalize_erasing_late_bound_regions(bx.typing_env(), sig);
let arg_tys = sig.inputs();
let ret_ty = sig.output();
let name = bx.tcx().item_name(def_id);

View File

@ -4,7 +4,7 @@ use rustc_index::IndexVec;
use rustc_index::bit_set::BitSet;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::mir::{UnwindTerminateReason, traversal};
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, TyAndLayout};
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, HasTypingEnv, TyAndLayout};
use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
use rustc_middle::{bug, mir, span_bug};
use rustc_target::callconv::{FnAbi, PassMode};
@ -128,7 +128,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
debug!("monomorphize: self.instance={:?}", self.instance);
self.instance.instantiate_mir_and_normalize_erasing_regions(
self.cx.tcx(),
ty::ParamEnv::reveal_all(),
self.cx.typing_env(),
ty::EarlyBinder::bind(value),
)
}

View File

@ -474,7 +474,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
ty::FnDef(def_id, args) => {
let instance = ty::Instance::resolve_for_fn_ptr(
bx.tcx(),
ty::ParamEnv::reveal_all(),
bx.typing_env(),
def_id,
args,
)
@ -709,7 +709,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
mir::NullOp::OffsetOf(fields) => {
let val = bx
.tcx()
.offset_of_subfield(bx.param_env(), layout, fields.iter())
.offset_of_subfield(bx.typing_env(), layout, fields.iter())
.bytes();
bx.cx().const_usize(val)
}
@ -727,7 +727,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
mir::Rvalue::ThreadLocalRef(def_id) => {
assert!(bx.cx().tcx().is_static(def_id));
let layout = bx.layout_of(bx.cx().tcx().static_ptr_ty(def_id));
let layout = bx.layout_of(bx.cx().tcx().static_ptr_ty(def_id, bx.typing_env()));
let static_ = if !def_id.is_local() && bx.cx().tcx().needs_thread_local_shim(def_id)
{
let instance = ty::Instance {

View File

@ -1,6 +1,6 @@
use rustc_abi::{AddressSpace, Float, Integer};
use rustc_middle::bug;
use rustc_middle::ty::layout::{HasTyCtxt, TyAndLayout};
use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, TyAndLayout};
use rustc_middle::ty::{self, Ty};
use rustc_target::callconv::{ArgAbi, CastTarget, FnAbi, Reg};
@ -41,7 +41,7 @@ pub trait BaseTypeCodegenMethods<'tcx>: BackendTypes {
}
pub trait DerivedTypeCodegenMethods<'tcx>:
BaseTypeCodegenMethods<'tcx> + MiscCodegenMethods<'tcx> + HasTyCtxt<'tcx>
BaseTypeCodegenMethods<'tcx> + MiscCodegenMethods<'tcx> + HasTyCtxt<'tcx> + HasTypingEnv<'tcx>
{
fn type_int(&self) -> Self::Type {
match &self.sess().target.c_int_width[..] {
@ -74,7 +74,7 @@ pub trait DerivedTypeCodegenMethods<'tcx>:
}
fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool {
ty.needs_drop(self.tcx(), ty::ParamEnv::reveal_all())
ty.needs_drop(self.tcx(), self.typing_env())
}
fn type_is_sized(&self, ty: Ty<'tcx>) -> bool {
@ -86,12 +86,11 @@ pub trait DerivedTypeCodegenMethods<'tcx>:
}
fn type_has_metadata(&self, ty: Ty<'tcx>) -> bool {
let param_env = ty::ParamEnv::reveal_all();
if ty.is_sized(self.tcx(), param_env) {
if ty.is_sized(self.tcx(), self.param_env()) {
return false;
}
let tail = self.tcx().struct_tail_for_codegen(ty, param_env);
let tail = self.tcx().struct_tail_for_codegen(ty, self.typing_env());
match tail.kind() {
ty::Foreign(..) => false,
ty::Str | ty::Slice(..) | ty::Dynamic(..) => true,
@ -101,7 +100,10 @@ pub trait DerivedTypeCodegenMethods<'tcx>:
}
impl<'tcx, T> DerivedTypeCodegenMethods<'tcx> for T where
Self: BaseTypeCodegenMethods<'tcx> + MiscCodegenMethods<'tcx> + HasTyCtxt<'tcx>
Self: BaseTypeCodegenMethods<'tcx>
+ MiscCodegenMethods<'tcx>
+ HasTyCtxt<'tcx>
+ HasTypingEnv<'tcx>
{
}

View File

@ -388,7 +388,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
return false;
}
let infcx = tcx.infer_ctxt().build(self.body.typing_mode(tcx));
let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(self.body.typing_env(tcx));
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
let body_id = self.body.source.def_id().expect_local();
@ -398,11 +398,8 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
ty::BoundConstness::Const
}
};
let const_conditions = ocx.normalize(
&ObligationCause::misc(call_span, body_id),
self.param_env,
const_conditions,
);
let const_conditions =
ocx.normalize(&ObligationCause::misc(call_span, body_id), param_env, const_conditions);
ocx.register_obligations(const_conditions.into_iter().map(|(trait_ref, span)| {
Obligation::new(
tcx,
@ -411,7 +408,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
body_id,
ObligationCauseCode::WhereClause(callee, span),
),
self.param_env,
param_env,
trait_ref.to_host_effect_clause(tcx, host_polarity),
)
}));

View File

@ -24,17 +24,15 @@ mod resolver;
pub struct ConstCx<'mir, 'tcx> {
pub body: &'mir mir::Body<'tcx>,
pub tcx: TyCtxt<'tcx>,
pub param_env: ty::ParamEnv<'tcx>,
pub typing_env: ty::TypingEnv<'tcx>,
pub const_kind: Option<hir::ConstContext>,
}
impl<'mir, 'tcx> ConstCx<'mir, 'tcx> {
pub fn new(tcx: TyCtxt<'tcx>, body: &'mir mir::Body<'tcx>) -> Self {
let def_id = body.source.def_id().expect_local();
let param_env = tcx.param_env(def_id);
let typing_env = body.typing_env(tcx);
let const_kind = tcx.hir().body_const_context(body.source.def_id().expect_local());
ConstCx { body, tcx, param_env, const_kind }
ConstCx { body, tcx, typing_env, const_kind }
}
pub(crate) fn dcx(&self) -> DiagCtxtHandle<'tcx> {

View File

@ -120,7 +120,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
#[allow(rustc::untranslatable_diagnostic)]
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, _: Span) -> Diag<'tcx> {
let FnCallNonConst { callee, args, span, call_source } = *self;
let ConstCx { tcx, param_env, .. } = *ccx;
let ConstCx { tcx, typing_env, .. } = *ccx;
let caller = ccx.def_id();
let diag_trait = |err, self_ty: Ty<'_>, trait_id| {
@ -146,13 +146,11 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
}
}
ty::Adt(..) => {
let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env);
let obligation =
Obligation::new(tcx, ObligationCause::dummy(), param_env, trait_ref);
let infcx = tcx.infer_ctxt().build(ccx.body.typing_mode(tcx));
let mut selcx = SelectionContext::new(&infcx);
let implsrc = selcx.select(&obligation);
if let Ok(Some(ImplSource::UserDefined(data))) = implsrc {
// FIXME(const_trait_impl) revisit this
if !tcx.is_const_trait_impl(data.impl_def_id) {
@ -166,7 +164,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
};
let call_kind =
call_kind(tcx, ccx.param_env, callee, args, span, call_source.from_hir_call(), None);
call_kind(tcx, ccx.typing_env, callee, args, span, call_source.from_hir_call(), None);
debug!(?call_kind);

View File

@ -32,17 +32,15 @@ pub fn checking_enabled(ccx: &ConstCx<'_, '_>) -> bool {
/// This is separate from the rest of the const checking logic because it must run after drop
/// elaboration.
pub fn check_live_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mir::Body<'tcx>) {
let def_id = body.source.def_id().expect_local();
let const_kind = tcx.hir().body_const_context(def_id);
if const_kind.is_none() {
let ccx = ConstCx::new(tcx, body);
if ccx.const_kind.is_none() {
return;
}
if tcx.has_attr(def_id, sym::rustc_do_not_const_check) {
if tcx.has_attr(body.source.def_id(), sym::rustc_do_not_const_check) {
return;
}
let ccx = ConstCx { body, tcx, const_kind, param_env: tcx.param_env(def_id) };
if !checking_enabled(&ccx) {
return;
}

View File

@ -106,20 +106,24 @@ impl Qualif for HasMutInterior {
// Instead we invoke an obligation context manually, and provide the opaque type inference settings
// that allow the trait solver to just error out instead of cycling.
let freeze_def_id = cx.tcx.require_lang_item(LangItem::Freeze, Some(cx.body.span));
// FIXME(#132279): Once we've got a typing mode which reveals opaque types using the HIR
// typeck results without causing query cycles, we should use this here instead of defining
// opaque types.
let typing_env = ty::TypingEnv {
typing_mode: ty::TypingMode::analysis_in_body(
cx.tcx,
cx.body.source.def_id().expect_local(),
),
param_env: cx.typing_env.param_env,
};
let (infcx, param_env) = cx.tcx.infer_ctxt().build_with_typing_env(typing_env);
let ocx = ObligationCtxt::new(&infcx);
let obligation = Obligation::new(
cx.tcx,
ObligationCause::dummy_with_span(cx.body.span),
cx.param_env,
param_env,
ty::TraitRef::new(cx.tcx, freeze_def_id, [ty::GenericArg::from(ty)]),
);
// FIXME(#132279): This should eventually use the already defined hidden types.
let infcx = cx.tcx.infer_ctxt().build(ty::TypingMode::analysis_in_body(
cx.tcx,
cx.body.source.def_id().expect_local(),
));
let ocx = ObligationCtxt::new(&infcx);
ocx.register_obligation(obligation);
let errors = ocx.select_all_or_error();
!errors.is_empty()
@ -156,7 +160,7 @@ impl Qualif for NeedsDrop {
}
fn in_any_value_of_ty<'tcx>(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool {
ty.needs_drop(cx.tcx, cx.param_env)
ty.needs_drop(cx.tcx, cx.typing_env)
}
fn in_adt_inherently<'tcx>(

View File

@ -120,7 +120,10 @@ where
///
/// [rust-lang/unsafe-code-guidelines#134]: https://github.com/rust-lang/unsafe-code-guidelines/issues/134
fn shared_borrow_allows_mutation(&self, place: mir::Place<'tcx>) -> bool {
!place.ty(self.ccx.body, self.ccx.tcx).ty.is_freeze(self.ccx.tcx, self.ccx.param_env)
!place
.ty(self.ccx.body, self.ccx.tcx)
.ty
.is_freeze(self.ccx.tcx, self.ccx.typing_env.param_env)
}
}

View File

@ -221,7 +221,7 @@ pub(super) fn op_to_const<'tcx>(
let pointee_ty = imm.layout.ty.builtin_deref(false).unwrap(); // `false` = no raw ptrs
debug_assert!(
matches!(
ecx.tcx.struct_tail_for_codegen(pointee_ty, ecx.param_env).kind(),
ecx.tcx.struct_tail_for_codegen(pointee_ty, ecx.typing_env()).kind(),
ty::Str | ty::Slice(..),
),
"`ConstValue::Slice` is for slice-tailed types only, but got {}",
@ -280,11 +280,13 @@ pub fn eval_to_const_value_raw_provider<'tcx>(
// opaque types. This is needed for trivial things like `size_of`, but also for using associated
// types that are not specified in the opaque type.
assert_eq!(key.param_env.reveal(), Reveal::All);
let typing_env =
ty::TypingEnv { typing_mode: ty::TypingMode::PostAnalysis, param_env: key.param_env };
// We call `const_eval` for zero arg intrinsics, too, in order to cache their value.
// Catch such calls and evaluate them instead of trying to load a constant's MIR.
if let ty::InstanceKind::Intrinsic(def_id) = key.value.instance.def {
let ty = key.value.instance.ty(tcx, key.param_env);
let ty = key.value.instance.ty(tcx, typing_env);
let ty::FnDef(_, args) = ty.kind() else {
bug!("intrinsic with type {:?}", ty);
};

View File

@ -249,9 +249,10 @@ impl<'tcx> CompileTimeInterpCx<'tcx> {
} else if self.tcx.is_lang_item(def_id, LangItem::PanicFmt) {
// For panic_fmt, call const_panic_fmt instead.
let const_def_id = self.tcx.require_lang_item(LangItem::ConstPanicFmt, None);
// FIXME(@lcnr): why does this use an empty env if we've got a `param_env` right here.
let new_instance = ty::Instance::expect_resolve(
*self.tcx,
ty::ParamEnv::reveal_all(),
ty::TypingEnv::fully_monomorphized(),
const_def_id,
instance.args,
self.cur_span(),

View File

@ -2,6 +2,7 @@ use rustc_abi::{BackendRepr, VariantIdx};
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId};
use rustc_middle::ty::layout::{LayoutCx, LayoutOf, TyAndLayout};
use rustc_middle::ty::solve::Reveal;
use rustc_middle::ty::{self, ScalarInt, Ty, TyCtxt};
use rustc_middle::{bug, mir};
use rustc_span::DUMMY_SP;
@ -281,8 +282,9 @@ pub fn valtree_to_const_value<'tcx>(
// the `ValTree` and using `place_projection` and `place_field` to
// create inner `MPlace`s which are filled recursively.
// FIXME Does this need an example?
let (param_env, ty) = param_env_ty.into_parts();
debug_assert_eq!(param_env.reveal(), Reveal::All);
let typing_env = ty::TypingEnv { typing_mode: ty::TypingMode::PostAnalysis, param_env };
match *ty.kind() {
ty::FnDef(..) => {
@ -302,11 +304,12 @@ pub fn valtree_to_const_value<'tcx>(
let mut ecx =
mk_eval_cx_to_read_const_val(tcx, DUMMY_SP, param_env, CanAccessMutGlobal::No);
let imm = valtree_to_ref(&mut ecx, valtree, inner_ty);
let imm = ImmTy::from_immediate(imm, tcx.layout_of(param_env_ty).unwrap());
let imm =
ImmTy::from_immediate(imm, tcx.layout_of(typing_env.as_query_input(ty)).unwrap());
op_to_const(&ecx, &imm.into(), /* for diagnostics */ false)
}
ty::Tuple(_) | ty::Array(_, _) | ty::Adt(..) => {
let layout = tcx.layout_of(param_env_ty).unwrap();
let layout = tcx.layout_of(typing_env.as_query_input(ty)).unwrap();
if layout.is_zst() {
// Fast path to avoid some allocations.
return mir::ConstValue::ZeroSized;
@ -319,7 +322,7 @@ pub fn valtree_to_const_value<'tcx>(
let branches = valtree.unwrap_branch();
// Find the non-ZST field. (There can be aligned ZST!)
for (i, &inner_valtree) in branches.iter().enumerate() {
let field = layout.field(&LayoutCx::new(tcx, param_env), i);
let field = layout.field(&LayoutCx::new(tcx, typing_env), i);
if !field.is_zst() {
return valtree_to_const_value(tcx, param_env.and(field.ty), inner_valtree);
}

View File

@ -215,7 +215,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
// Even if `ty` is normalized, the search for the unsized tail will project
// to fields, which can yield non-normalized types. So we need to provide a
// normalization function.
let normalize = |ty| self.tcx.normalize_erasing_regions(self.param_env, ty);
let normalize = |ty| self.tcx.normalize_erasing_regions(self.typing_env(), ty);
ty.ptr_metadata_ty(*self.tcx, normalize)
};
return interp_ok(meta_ty(caller) == meta_ty(callee));
@ -652,35 +652,35 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
};
// Obtain the underlying trait we are working on, and the adjusted receiver argument.
let (trait_, dyn_ty, adjusted_recv) = if let ty::Dynamic(data, _, ty::DynStar) =
receiver_place.layout.ty.kind()
{
let recv = self.unpack_dyn_star(&receiver_place, data)?;
let (trait_, dyn_ty, adjusted_recv) =
if let ty::Dynamic(data, _, ty::DynStar) = receiver_place.layout.ty.kind() {
let recv = self.unpack_dyn_star(&receiver_place, data)?;
(data.principal(), recv.layout.ty, recv.ptr())
} else {
// Doesn't have to be a `dyn Trait`, but the unsized tail must be `dyn Trait`.
// (For that reason we also cannot use `unpack_dyn_trait`.)
let receiver_tail =
self.tcx.struct_tail_for_codegen(receiver_place.layout.ty, self.param_env);
let ty::Dynamic(receiver_trait, _, ty::Dyn) = receiver_tail.kind() else {
span_bug!(
self.cur_span(),
"dynamic call on non-`dyn` type {}",
receiver_tail
)
(data.principal(), recv.layout.ty, recv.ptr())
} else {
// Doesn't have to be a `dyn Trait`, but the unsized tail must be `dyn Trait`.
// (For that reason we also cannot use `unpack_dyn_trait`.)
let receiver_tail = self
.tcx
.struct_tail_for_codegen(receiver_place.layout.ty, self.typing_env());
let ty::Dynamic(receiver_trait, _, ty::Dyn) = receiver_tail.kind() else {
span_bug!(
self.cur_span(),
"dynamic call on non-`dyn` type {}",
receiver_tail
)
};
assert!(receiver_place.layout.is_unsized());
// Get the required information from the vtable.
let vptr = receiver_place.meta().unwrap_meta().to_pointer(self)?;
let dyn_ty = self.get_ptr_vtable_ty(vptr, Some(receiver_trait))?;
// It might be surprising that we use a pointer as the receiver even if this
// is a by-val case; this works because by-val passing of an unsized `dyn
// Trait` to a function is actually desugared to a pointer.
(receiver_trait.principal(), dyn_ty, receiver_place.ptr())
};
assert!(receiver_place.layout.is_unsized());
// Get the required information from the vtable.
let vptr = receiver_place.meta().unwrap_meta().to_pointer(self)?;
let dyn_ty = self.get_ptr_vtable_ty(vptr, Some(receiver_trait))?;
// It might be surprising that we use a pointer as the receiver even if this
// is a by-val case; this works because by-val passing of an unsized `dyn
// Trait` to a function is actually desugared to a pointer.
(receiver_trait.principal(), dyn_ty, receiver_place.ptr())
};
// Now determine the actual method to call. Usually we use the easy way of just
// looking up the method at index `idx`.
@ -704,7 +704,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
let concrete_method = Instance::expect_resolve_for_vtable(
tcx,
self.param_env,
self.typing_env(),
def_id,
instance.args.rebase_onto(tcx, trait_def_id, concrete_trait_ref.args),
self.cur_span(),

View File

@ -83,7 +83,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
ty::FnDef(def_id, args) => {
let instance = ty::Instance::resolve_for_fn_ptr(
*self.tcx,
self.param_env,
self.typing_env(),
def_id,
args,
)
@ -384,7 +384,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
) -> InterpResult<'tcx> {
// A<Struct> -> A<Trait> conversion
let (src_pointee_ty, dest_pointee_ty) =
self.tcx.struct_lockstep_tails_for_codegen(source_ty, cast_ty, self.param_env);
self.tcx.struct_lockstep_tails_for_codegen(source_ty, cast_ty, self.typing_env());
match (src_pointee_ty.kind(), dest_pointee_ty.kind()) {
(&ty::Array(_, length), &ty::Slice(_)) => {

View File

@ -10,9 +10,7 @@ use rustc_middle::query::TyCtxtAt;
use rustc_middle::ty::layout::{
self, FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOfHelpers, TyAndLayout,
};
use rustc_middle::ty::{
self, GenericArgsRef, ParamEnv, Ty, TyCtxt, TypeFoldable, TypingMode, Variance,
};
use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypeFoldable, TypingEnv, Variance};
use rustc_middle::{mir, span_bug};
use rustc_session::Limit;
use rustc_span::Span;
@ -65,12 +63,12 @@ where
}
}
impl<'tcx, M> layout::HasParamEnv<'tcx> for InterpCx<'tcx, M>
impl<'tcx, M> layout::HasTypingEnv<'tcx> for InterpCx<'tcx, M>
where
M: Machine<'tcx>,
{
fn param_env(&self) -> ty::ParamEnv<'tcx> {
self.param_env
fn typing_env(&self) -> ty::TypingEnv<'tcx> {
self.typing_env()
}
}
@ -116,8 +114,7 @@ impl<'tcx, M: Machine<'tcx>> FnAbiOfHelpers<'tcx> for InterpCx<'tcx, M> {
/// This test should be symmetric, as it is primarily about layout compatibility.
pub(super) fn mir_assign_valid_types<'tcx>(
tcx: TyCtxt<'tcx>,
typing_mode: TypingMode<'tcx>,
param_env: ParamEnv<'tcx>,
typing_env: TypingEnv<'tcx>,
src: TyAndLayout<'tcx>,
dest: TyAndLayout<'tcx>,
) -> bool {
@ -125,7 +122,7 @@ pub(super) fn mir_assign_valid_types<'tcx>(
// all normal lifetimes are erased, higher-ranked types with their
// late-bound lifetimes are still around and can lead to type
// differences.
if util::relate_types(tcx, typing_mode, param_env, Variance::Covariant, src.ty, dest.ty) {
if util::relate_types(tcx, typing_env, Variance::Covariant, src.ty, dest.ty) {
// Make sure the layout is equal, too -- just to be safe. Miri really
// needs layout equality. For performance reason we skip this check when
// the types are equal. Equal types *can* have different layouts when
@ -145,8 +142,7 @@ pub(super) fn mir_assign_valid_types<'tcx>(
#[cfg_attr(not(debug_assertions), inline(always))]
pub(super) fn from_known_layout<'tcx>(
tcx: TyCtxtAt<'tcx>,
typing_mode: TypingMode<'tcx>,
param_env: ParamEnv<'tcx>,
typing_env: TypingEnv<'tcx>,
known_layout: Option<TyAndLayout<'tcx>>,
compute: impl FnOnce() -> InterpResult<'tcx, TyAndLayout<'tcx>>,
) -> InterpResult<'tcx, TyAndLayout<'tcx>> {
@ -155,13 +151,7 @@ pub(super) fn from_known_layout<'tcx>(
Some(known_layout) => {
if cfg!(debug_assertions) {
let check_layout = compute()?;
if !mir_assign_valid_types(
tcx.tcx,
typing_mode,
param_env,
check_layout,
known_layout,
) {
if !mir_assign_valid_types(tcx.tcx, typing_env, check_layout, known_layout) {
span_bug!(
tcx.span,
"expected type differs from actual type.\nexpected: {}\nactual: {}",
@ -211,9 +201,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
}
}
pub fn typing_mode(&self) -> TypingMode<'tcx> {
/// During CTFE we're always in `PostAnalysis` mode.
#[inline(always)]
pub fn typing_env(&self) -> ty::TypingEnv<'tcx> {
debug_assert_eq!(self.param_env.reveal(), Reveal::All);
TypingMode::PostAnalysis
ty::TypingEnv { typing_mode: ty::TypingMode::PostAnalysis, param_env: self.param_env }
}
/// Returns the span of the currently executed statement/terminator.
@ -304,13 +296,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
.instance
.try_instantiate_mir_and_normalize_erasing_regions(
*self.tcx,
self.param_env,
self.typing_env(),
ty::EarlyBinder::bind(value),
)
.map_err(|_| ErrorHandled::TooGeneric(self.cur_span()))
}
/// The `args` are assumed to already be in our interpreter "universe" (param_env).
/// The `args` are assumed to already be in our interpreter "universe".
pub(super) fn resolve(
&self,
def: DefId,
@ -319,7 +311,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
trace!("resolve: {:?}, {:#?}", def, args);
trace!("param_env: {:#?}", self.param_env);
trace!("args: {:#?}", args);
match ty::Instance::try_resolve(*self.tcx, self.param_env, def, args) {
match ty::Instance::try_resolve(*self.tcx, self.typing_env(), def, args) {
Ok(Some(instance)) => interp_ok(instance),
Ok(None) => throw_inval!(TooGeneric),
@ -328,7 +320,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
}
}
/// Check if the two things are equal in the current param_env, using an infctx to get proper
/// Check if the two things are equal in the current param_env, using an infcx to get proper
/// equality checks.
#[instrument(level = "trace", skip(self), ret)]
pub(super) fn eq_in_param_env<T>(&self, a: T, b: T) -> bool
@ -340,14 +332,14 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
return true;
}
// Slow path: spin up an inference context to check if these traits are sufficiently equal.
let infcx = self.tcx.infer_ctxt().build(self.typing_mode());
let (infcx, param_env) = self.tcx.infer_ctxt().build_with_typing_env(self.typing_env());
let ocx = ObligationCtxt::new(&infcx);
let cause = ObligationCause::dummy_with_span(self.cur_span());
// equate the two trait refs after normalization
let a = ocx.normalize(&cause, self.param_env, a);
let b = ocx.normalize(&cause, self.param_env, b);
let a = ocx.normalize(&cause, param_env, a);
let b = ocx.normalize(&cause, param_env, b);
if let Err(terr) = ocx.eq(&cause, self.param_env, a, b) {
if let Err(terr) = ocx.eq(&cause, param_env, a, b) {
trace!(?terr);
return false;
}
@ -572,7 +564,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
let val = if self.tcx.is_static(gid.instance.def_id()) {
let alloc_id = self.tcx.reserve_and_set_static_alloc(gid.instance.def_id());
let ty = instance.ty(self.tcx.tcx, self.param_env);
let ty = instance.ty(self.tcx.tcx, self.typing_env());
mir::ConstAlloc { alloc_id, ty }
} else {
self.ctfe_query(|tcx| tcx.eval_to_allocation_raw(self.param_env.and(gid)))?
@ -587,7 +579,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
layout: Option<TyAndLayout<'tcx>>,
) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
M::eval_mir_constant(self, *val, span, layout, |ecx, val, span, layout| {
let const_val = val.eval(*ecx.tcx, ecx.param_env, span).map_err(|err| {
let const_val = val.eval(*ecx.tcx, ecx.typing_env(), span).map_err(|err| {
if M::ALL_CONSTS_ARE_PRECHECKED {
match err {
ErrorHandled::TooGeneric(..) => {},

View File

@ -40,6 +40,7 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>(
) -> InterpResult<'tcx, ConstValue<'tcx>> {
let tp_ty = args.type_at(0);
let name = tcx.item_name(def_id);
let typing_env = ty::TypingEnv { typing_mode: ty::TypingMode::PostAnalysis, param_env };
interp_ok(match name {
sym::type_name => {
ensure_monomorphic_enough(tcx, tp_ty)?;
@ -48,11 +49,13 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>(
}
sym::needs_drop => {
ensure_monomorphic_enough(tcx, tp_ty)?;
ConstValue::from_bool(tp_ty.needs_drop(tcx, param_env))
ConstValue::from_bool(tp_ty.needs_drop(tcx, typing_env))
}
sym::pref_align_of => {
// Correctly handles non-monomorphic calls, so there is no need for ensure_monomorphic_enough.
let layout = tcx.layout_of(param_env.and(tp_ty)).map_err(|e| err_inval!(Layout(*e)))?;
let layout = tcx
.layout_of(typing_env.as_query_input(tp_ty))
.map_err(|e| err_inval!(Layout(*e)))?;
ConstValue::from_target_usize(layout.align.pref.bytes(), &tcx)
}
sym::type_id => {
@ -355,7 +358,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
let should_panic = !self
.tcx
.check_validity_requirement((requirement, self.param_env.and(ty)))
.check_validity_requirement((requirement, self.typing_env().as_query_input(ty)))
.map_err(|_| err_inval!(TooGeneric))?;
if should_panic {

View File

@ -859,7 +859,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
// # Global allocations
if let Some(global_alloc) = self.tcx.try_get_global_alloc(id) {
let (size, align) = global_alloc.size_and_align(*self.tcx, self.param_env);
let (size, align) = global_alloc.size_and_align(*self.tcx, self.typing_env());
let mutbl = global_alloc.mutability(*self.tcx, self.param_env);
let kind = match global_alloc {
GlobalAlloc::Static { .. } | GlobalAlloc::Memory { .. } => AllocKind::LiveData,

View File

@ -8,7 +8,7 @@ use rustc_abi as abi;
use rustc_abi::{BackendRepr, HasDataLayout, Size};
use rustc_hir::def::Namespace;
use rustc_middle::mir::interpret::ScalarSizeMismatch;
use rustc_middle::ty::layout::{HasParamEnv, HasTyCtxt, LayoutOf, TyAndLayout};
use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutOf, TyAndLayout};
use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter};
use rustc_middle::ty::{ConstInt, ScalarInt, Ty, TyCtxt};
use rustc_middle::{bug, mir, span_bug, ty};
@ -297,21 +297,25 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
#[inline]
pub fn from_bool(b: bool, tcx: TyCtxt<'tcx>) -> Self {
let layout = tcx.layout_of(ty::ParamEnv::reveal_all().and(tcx.types.bool)).unwrap();
let layout = tcx
.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(tcx.types.bool))
.unwrap();
Self::from_scalar(Scalar::from_bool(b), layout)
}
#[inline]
pub fn from_ordering(c: std::cmp::Ordering, tcx: TyCtxt<'tcx>) -> Self {
let ty = tcx.ty_ordering_enum(None);
let layout = tcx.layout_of(ty::ParamEnv::reveal_all().and(ty)).unwrap();
let layout =
tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)).unwrap();
Self::from_scalar(Scalar::from_i8(c as i8), layout)
}
pub fn from_pair(a: Self, b: Self, tcx: TyCtxt<'tcx>) -> Self {
let layout = tcx
.layout_of(
ty::ParamEnv::reveal_all().and(Ty::new_tup(tcx, &[a.layout.ty, b.layout.ty])),
ty::TypingEnv::fully_monomorphized()
.as_query_input(Ty::new_tup(tcx, &[a.layout.ty, b.layout.ty])),
)
.unwrap();
Self::from_scalar_pair(a.to_scalar(), b.to_scalar(), layout)
@ -341,7 +345,7 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
#[inline]
#[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980)
pub fn to_pair(self, cx: &(impl HasTyCtxt<'tcx> + HasParamEnv<'tcx>)) -> (Self, Self) {
pub fn to_pair(self, cx: &(impl HasTyCtxt<'tcx> + HasTypingEnv<'tcx>)) -> (Self, Self) {
let layout = self.layout;
let (val0, val1) = self.to_scalar_pair();
(
@ -773,8 +777,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
)?;
if !mir_assign_valid_types(
*self.tcx,
self.typing_mode(),
self.param_env,
self.typing_env(),
self.layout_of(normalized_place_ty)?,
op.layout,
) {
@ -833,9 +836,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
})
};
let layout =
from_known_layout(self.tcx, self.typing_mode(), self.param_env, layout, || {
self.layout_of(ty).into()
})?;
from_known_layout(self.tcx, self.typing_env(), layout, || self.layout_of(ty).into())?;
let imm = match val_val {
mir::ConstValue::Indirect { alloc_id, offset } => {
// This is const data, no mutation allowed.

View File

@ -533,7 +533,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
}
OffsetOf(fields) => {
let val =
self.tcx.offset_of_subfield(self.param_env, layout, fields.iter()).bytes();
self.tcx.offset_of_subfield(self.typing_env(), layout, fields.iter()).bytes();
ImmTy::from_uint(val, usize_layout())
}
UbChecks => ImmTy::from_bool(M::ub_checks(self)?, *self.tcx),

View File

@ -540,8 +540,7 @@ where
)?;
if !mir_assign_valid_types(
*self.tcx,
self.typing_mode(),
self.param_env,
self.typing_env(),
self.layout_of(normalized_place_ty)?,
place.layout,
) {
@ -871,13 +870,8 @@ where
) -> InterpResult<'tcx> {
// We do NOT compare the types for equality, because well-typed code can
// actually "transmute" `&mut T` to `&T` in an assignment without a cast.
let layout_compat = mir_assign_valid_types(
*self.tcx,
self.typing_mode(),
self.param_env,
src.layout(),
dest.layout(),
);
let layout_compat =
mir_assign_valid_types(*self.tcx, self.typing_env(), src.layout(), dest.layout());
if !allow_transmute && !layout_compat {
span_bug!(
self.cur_span(),

View File

@ -379,7 +379,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
for &const_ in body.required_consts() {
let c =
self.instantiate_from_current_frame_and_normalize_erasing_regions(const_.const_)?;
c.eval(*self.tcx, self.param_env, const_.span).map_err(|err| {
c.eval(*self.tcx, self.typing_env(), const_.span).map_err(|err| {
err.emit_note(*self.tcx);
err
})?;
@ -596,13 +596,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
return interp_ok(layout);
}
let layout =
from_known_layout(self.tcx, self.typing_mode(), self.param_env, layout, || {
let local_ty = frame.body.local_decls[local].ty;
let local_ty =
self.instantiate_from_frame_and_normalize_erasing_regions(frame, local_ty)?;
self.layout_of(local_ty).into()
})?;
let layout = from_known_layout(self.tcx, self.typing_env(), layout, || {
let local_ty = frame.body.local_decls[local].ty;
let local_ty =
self.instantiate_from_frame_and_normalize_erasing_regions(frame, local_ty)?;
self.layout_of(local_ty).into()
})?;
// Layouts of locals are requested a lot, so we cache them.
state.layout.set(Some(layout));

View File

@ -418,7 +418,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
.collect::<InterpResult<'tcx, Vec<_>>>()?;
let fn_sig_binder = func.layout.ty.fn_sig(*self.tcx);
let fn_sig = self.tcx.normalize_erasing_late_bound_regions(self.param_env, fn_sig_binder);
let fn_sig =
self.tcx.normalize_erasing_late_bound_regions(self.typing_env(), fn_sig_binder);
let extra_args = &args[fn_sig.inputs().len()..];
let extra_args =
self.tcx.mk_type_list_from_iter(extra_args.iter().map(|arg| arg.layout().ty));

View File

@ -448,7 +448,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
meta: MemPlaceMeta<M::Provenance>,
pointee: TyAndLayout<'tcx>,
) -> InterpResult<'tcx> {
let tail = self.ecx.tcx.struct_tail_for_codegen(pointee.ty, self.ecx.param_env);
let tail = self.ecx.tcx.struct_tail_for_codegen(pointee.ty, self.ecx.typing_env());
match tail.kind() {
ty::Dynamic(data, _, ty::Dyn) => {
let vtable = meta.unwrap_meta().to_pointer(self.ecx)?;
@ -568,7 +568,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
throw_validation_failure!(self.path, DanglingPtrUseAfterFree { ptr_kind });
};
let (size, _align) =
global_alloc.size_and_align(*self.ecx.tcx, self.ecx.param_env);
global_alloc.size_and_align(*self.ecx.tcx, self.ecx.typing_env());
if let GlobalAlloc::Static(did) = global_alloc {
let DefKind::Static { nested, .. } = self.ecx.tcx.def_kind(did) else {
@ -955,7 +955,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
) -> Cow<'e, RangeSet> {
assert!(layout.ty.is_union());
assert!(layout.is_sized(), "there are no unsized unions");
let layout_cx = LayoutCx::new(*ecx.tcx, ecx.param_env);
let layout_cx = LayoutCx::new(*ecx.tcx, ecx.typing_env());
return M::cached_union_data_range(ecx, layout.ty, || {
let mut out = RangeSet(Vec::new());
union_data_range_uncached(&layout_cx, layout, Size::ZERO, &mut out);

View File

@ -47,7 +47,7 @@ pub fn provide(providers: &mut Providers) {
providers.hooks.try_destructure_mir_constant_for_user_output =
const_eval::try_destructure_mir_constant_for_user_output;
providers.valtree_to_const_val = |tcx, (ty, valtree)| {
const_eval::valtree_to_const_value(tcx, ty::ParamEnv::empty().and(ty), valtree)
const_eval::valtree_to_const_value(tcx, ty::ParamEnv::reveal_all().and(ty), valtree)
};
providers.check_validity_requirement = |tcx, (init_kind, param_env_and_ty)| {
util::check_validity_requirement(tcx, init_kind, param_env_and_ty)

View File

@ -9,7 +9,7 @@ use tracing::debug;
pub fn is_disaligned<'tcx, L>(
tcx: TyCtxt<'tcx>,
local_decls: &L,
param_env: ty::ParamEnv<'tcx>,
typing_env: ty::TypingEnv<'tcx>,
place: Place<'tcx>,
) -> bool
where
@ -22,8 +22,8 @@ where
};
let ty = place.ty(local_decls, tcx).ty;
let unsized_tail = || tcx.struct_tail_for_codegen(ty, param_env);
match tcx.layout_of(param_env.and(ty)) {
let unsized_tail = || tcx.struct_tail_for_codegen(ty, typing_env);
match tcx.layout_of(typing_env.as_query_input(ty)) {
Ok(layout)
if layout.align.abi <= pack
&& (layout.is_sized()

View File

@ -3,7 +3,7 @@ use rustc_middle::bug;
use rustc_middle::ty::layout::{
HasTyCtxt, LayoutCx, LayoutError, LayoutOf, TyAndLayout, ValidityRequirement,
};
use rustc_middle::ty::{ParamEnvAnd, Ty, TyCtxt};
use rustc_middle::ty::{PseudoCanonicalInput, Ty, TyCtxt};
use crate::const_eval::{CanAccessMutGlobal, CheckAlignment, CompileTimeMachine};
use crate::interpret::{InterpCx, MemoryKind};
@ -23,16 +23,16 @@ use crate::interpret::{InterpCx, MemoryKind};
pub fn check_validity_requirement<'tcx>(
tcx: TyCtxt<'tcx>,
kind: ValidityRequirement,
param_env_and_ty: ParamEnvAnd<'tcx, Ty<'tcx>>,
input: PseudoCanonicalInput<'tcx, Ty<'tcx>>,
) -> Result<bool, &'tcx LayoutError<'tcx>> {
let layout = tcx.layout_of(param_env_and_ty)?;
let layout = tcx.layout_of(input)?;
// There is nothing strict or lax about inhabitedness.
if kind == ValidityRequirement::Inhabited {
return Ok(!layout.is_uninhabited());
}
let layout_cx = LayoutCx::new(tcx, param_env_and_ty.param_env);
let layout_cx = LayoutCx::new(tcx, input.typing_env);
if kind == ValidityRequirement::Uninit || tcx.sess.opts.unstable_opts.strict_init_checks {
check_validity_requirement_strict(layout, &layout_cx, kind)
} else {
@ -49,7 +49,7 @@ fn check_validity_requirement_strict<'tcx>(
) -> Result<bool, &'tcx LayoutError<'tcx>> {
let machine = CompileTimeMachine::new(CanAccessMutGlobal::No, CheckAlignment::Error);
let mut cx = InterpCx::new(cx.tcx(), rustc_span::DUMMY_SP, cx.param_env, machine);
let mut cx = InterpCx::new(cx.tcx(), rustc_span::DUMMY_SP, cx.typing_env.param_env, machine);
let allocated = cx
.allocate(ty, MemoryKind::Machine(crate::const_eval::MemoryKind::Heap))

View File

@ -5,18 +5,17 @@
use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::{ParamEnv, Ty, TyCtxt, TypingMode, Variance};
use rustc_middle::ty::{Ty, TyCtxt, TypingEnv, Variance};
use rustc_trait_selection::traits::ObligationCtxt;
/// Returns whether `src` is a subtype of `dest`, i.e. `src <: dest`.
pub fn sub_types<'tcx>(
tcx: TyCtxt<'tcx>,
typing_mode: TypingMode<'tcx>,
param_env: ParamEnv<'tcx>,
typing_env: TypingEnv<'tcx>,
src: Ty<'tcx>,
dest: Ty<'tcx>,
) -> bool {
relate_types(tcx, typing_mode, param_env, Variance::Covariant, src, dest)
relate_types(tcx, typing_env, Variance::Covariant, src, dest)
}
/// Returns whether `src` is a subtype of `dest`, i.e. `src <: dest`.
@ -26,8 +25,7 @@ pub fn sub_types<'tcx>(
/// because we want to check for type equality.
pub fn relate_types<'tcx>(
tcx: TyCtxt<'tcx>,
typing_mode: TypingMode<'tcx>,
param_env: ParamEnv<'tcx>,
typing_env: TypingEnv<'tcx>,
variance: Variance,
src: Ty<'tcx>,
dest: Ty<'tcx>,
@ -36,8 +34,7 @@ pub fn relate_types<'tcx>(
return true;
}
let mut builder = tcx.infer_ctxt().ignoring_regions();
let infcx = builder.build(typing_mode);
let (infcx, param_env) = tcx.infer_ctxt().ignoring_regions().build_with_typing_env(typing_env);
let ocx = ObligationCtxt::new(&infcx);
let cause = ObligationCause::dummy();
let src = ocx.normalize(&cause, param_env, src);

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, wfcx.infcx.typing_env(wfcx.param_env))
}
};
// 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;

View File

@ -2357,8 +2357,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Only assoc fns that return `Self`
let fn_sig = self.tcx.fn_sig(item.def_id).skip_binder();
let ret_ty = fn_sig.output();
let ret_ty =
self.tcx.normalize_erasing_late_bound_regions(self.param_env, ret_ty);
let ret_ty = self.tcx.normalize_erasing_late_bound_regions(
self.typing_env(self.param_env),
ret_ty,
);
if !self.can_eq(self.param_env, ret_ty, adt_ty) {
return None;
}

View File

@ -46,7 +46,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let span = tcx.hir().span(hir_id);
let normalize = |ty| {
let ty = self.resolve_vars_if_possible(ty);
self.tcx.normalize_erasing_regions(self.param_env, ty)
self.tcx.normalize_erasing_regions(self.typing_env(self.param_env), ty)
};
let from = normalize(from);
let to = normalize(to);
@ -62,7 +62,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
return;
}
let skel = |ty| SizeSkeleton::compute(ty, tcx, self.param_env);
let skel = |ty| SizeSkeleton::compute(ty, tcx, self.typing_env(self.param_env));
let sk_from = skel(from);
let sk_to = skel(to);
trace!(?sk_from, ?sk_to);

View File

@ -1257,7 +1257,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
) -> Option<FxIndexSet<UpvarMigrationInfo>> {
let ty = self.resolve_vars_if_possible(self.node_ty(var_hir_id));
if !ty.has_significant_drop(self.tcx, self.tcx.param_env(closure_def_id)) {
// FIXME(#132279): Using `non_body_analysis` here feels wrong.
if !ty.has_significant_drop(
self.tcx,
ty::TypingEnv::non_body_analysis(self.tcx, closure_def_id),
) {
debug!("does not have significant drop");
return None;
}
@ -1535,8 +1539,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
base_path_ty: Ty<'tcx>,
captured_by_move_projs: Vec<&[Projection<'tcx>]>,
) -> bool {
let needs_drop =
|ty: Ty<'tcx>| ty.has_significant_drop(self.tcx, self.tcx.param_env(closure_def_id));
// FIXME(#132279): Using `non_body_analysis` here feels wrong.
let needs_drop = |ty: Ty<'tcx>| {
ty.has_significant_drop(
self.tcx,
ty::TypingEnv::non_body_analysis(self.tcx, closure_def_id),
)
};
let is_drop_defined_for_ty = |ty: Ty<'tcx>| {
let drop_trait = self.tcx.require_lang_item(hir::LangItem::Drop, Some(closure_span));

View File

@ -881,6 +881,8 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for EagerlyNormalizeConsts<'tcx> {
}
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
self.tcx.try_normalize_erasing_regions(self.param_env, ct).unwrap_or(ct)
self.tcx
.try_normalize_erasing_regions(ty::TypingEnv::from_param_env(self.param_env), ct)
.unwrap_or(ct)
}
}

View File

@ -38,7 +38,8 @@ use rustc_middle::ty::fold::{
use rustc_middle::ty::visit::TypeVisitableExt;
use rustc_middle::ty::{
self, ConstVid, FloatVid, GenericArg, GenericArgKind, GenericArgs, GenericArgsRef,
GenericParamDefKind, InferConst, IntVid, Ty, TyCtxt, TyVid, TypingMode,
GenericParamDefKind, InferConst, IntVid, PseudoCanonicalInput, Ty, TyCtxt, TyVid,
TypeVisitable, TypingEnv, TypingMode,
};
use rustc_span::Span;
use rustc_span::symbol::Symbol;
@ -565,6 +566,13 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
(infcx, value, args)
}
pub fn build_with_typing_env(
mut self,
TypingEnv { typing_mode, param_env }: TypingEnv<'tcx>,
) -> (InferCtxt<'tcx>, ty::ParamEnv<'tcx>) {
(self.build(typing_mode), param_env)
}
pub fn build(&mut self, typing_mode: TypingMode<'tcx>) -> InferCtxt<'tcx> {
let InferCtxtBuilder { tcx, considering_regions, skip_leak_check, next_trait_solver } =
*self;
@ -1278,6 +1286,42 @@ impl<'tcx> InferCtxt<'tcx> {
u
}
/// Extract [`ty::TypingMode`] of this inference context to get a `TypingEnv`
/// which contains the necessary information to use the trait system without
/// using canonicalization or carrying this inference context around.
pub fn typing_env(&self, param_env: ty::ParamEnv<'tcx>) -> ty::TypingEnv<'tcx> {
let typing_mode = match self.typing_mode(param_env) {
ty::TypingMode::Coherence => ty::TypingMode::Coherence,
// FIXME(#132279): This erases the `defining_opaque_types` as it isn't possible
// to handle them without proper canonicalization. This means we may cause cycle
// errors and fail to reveal opaques while inside of bodies. We should rename this
// function and require explicit comments on all use-sites in the future.
ty::TypingMode::Analysis { defining_opaque_types: _ } => {
TypingMode::non_body_analysis()
}
ty::TypingMode::PostAnalysis => ty::TypingMode::PostAnalysis,
};
ty::TypingEnv { typing_mode, param_env }
}
/// Similar to [`Self::canonicalize_query`], except that it returns
/// a [`PseudoCanonicalInput`] and requires both the `value` and the
/// `param_env` to not contain any inference variables or placeholders.
pub fn pseudo_canonicalize_query<V>(
&self,
param_env: ty::ParamEnv<'tcx>,
value: V,
) -> PseudoCanonicalInput<'tcx, V>
where
V: TypeVisitable<TyCtxt<'tcx>>,
{
debug_assert!(!value.has_infer());
debug_assert!(!value.has_placeholders());
debug_assert!(!param_env.has_infer());
debug_assert!(!param_env.has_placeholders());
self.typing_env(param_env).as_query_input(value)
}
/// The returned function is used in a fast path. If it returns `true` the variable is
/// unchanged, `false` indicates that the status is unknown.
#[inline]

View File

@ -2485,7 +2485,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
});
// Check if this ADT has a constrained layout (like `NonNull` and friends).
if let Ok(layout) = cx.tcx.layout_of(cx.param_env.and(ty)) {
if let Ok(layout) = cx.tcx.layout_of(cx.typing_env().as_query_input(ty)) {
if let BackendRepr::Scalar(scalar) | BackendRepr::ScalarPair(scalar, _) =
&layout.backend_repr
{
@ -2521,7 +2521,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
ty: Ty<'tcx>,
init: InitKind,
) -> Option<InitError> {
let ty = cx.tcx.try_normalize_erasing_regions(cx.param_env, ty).unwrap_or(ty);
let ty = cx.tcx.try_normalize_erasing_regions(cx.typing_env(), ty).unwrap_or(ty);
use rustc_type_ir::TyKind::*;
match ty.kind() {
@ -2568,7 +2568,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
let definitely_inhabited = match variant
.inhabited_predicate(cx.tcx, *adt_def)
.instantiate(cx.tcx, args)
.apply_any_module(cx.tcx, cx.param_env)
.apply_any_module(cx.tcx, cx.typing_env())
{
// Entirely skip uninhabited variants.
Some(false) => return None,

View File

@ -19,7 +19,7 @@ use rustc_middle::bug;
use rustc_middle::middle::privacy::EffectiveVisibilities;
use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout};
use rustc_middle::ty::print::{PrintError, PrintTraitRefExt as _, Printer, with_no_trimmed_paths};
use rustc_middle::ty::{self, GenericArg, RegisteredTools, Ty, TyCtxt, TypingMode};
use rustc_middle::ty::{self, GenericArg, RegisteredTools, Ty, TyCtxt, TypingEnv, TypingMode};
use rustc_session::lint::{
BuiltinLintDiag, FutureIncompatibleInfo, Level, Lint, LintBuffer, LintExpectationId, LintId,
};
@ -708,6 +708,10 @@ impl<'tcx> LateContext<'tcx> {
TypingMode::non_body_analysis()
}
pub fn typing_env(&self) -> TypingEnv<'tcx> {
TypingEnv { typing_mode: self.typing_mode(), param_env: self.param_env }
}
/// Gets the type-checking results for the current body,
/// or `None` if outside a body.
pub fn maybe_typeck_results(&self) -> Option<&'tcx ty::TypeckResults<'tcx>> {
@ -906,7 +910,7 @@ impl<'tcx> LateContext<'tcx> {
.find_by_name_and_kind(tcx, Ident::from_str(name), ty::AssocKind::Type, trait_id)
.and_then(|assoc| {
let proj = Ty::new_projection(tcx, assoc.def_id, [self_ty]);
tcx.try_normalize_erasing_regions(self.param_env, proj).ok()
tcx.try_normalize_erasing_regions(self.typing_env(), proj).ok()
})
}
@ -1010,10 +1014,10 @@ impl<'tcx> ty::layout::HasTyCtxt<'tcx> for LateContext<'tcx> {
}
}
impl<'tcx> ty::layout::HasParamEnv<'tcx> for LateContext<'tcx> {
impl<'tcx> ty::layout::HasTypingEnv<'tcx> for LateContext<'tcx> {
#[inline]
fn param_env(&self) -> ty::ParamEnv<'tcx> {
self.param_env
fn typing_env(&self) -> ty::TypingEnv<'tcx> {
self.typing_env()
}
}

View File

@ -166,7 +166,7 @@ fn suggest_question_mark<'tcx>(
}
let ty = args.type_at(0);
let infcx = cx.tcx.infer_ctxt().build(cx.typing_mode());
let (infcx, param_env) = cx.tcx.infer_ctxt().build_with_typing_env(cx.typing_env());
let ocx = ObligationCtxt::new(&infcx);
let body_def_id = cx.tcx.hir().body_owner_def_id(body_id);
@ -175,7 +175,7 @@ fn suggest_question_mark<'tcx>(
ocx.register_bound(
cause,
cx.param_env,
param_env,
// Erase any region vids from the type, which may not be resolved
infcx.tcx.erase_regions(ty),
into_iterator_did,

View File

@ -131,7 +131,7 @@ impl ClashingExternDeclarations {
// Check that the declarations match.
if !structurally_same_type(
tcx,
tcx.param_env(this_fi.owner_id),
ty::TypingEnv::non_body_analysis(tcx, this_fi.owner_id),
existing_decl_ty,
this_decl_ty,
types::CItemKind::Declaration,
@ -205,18 +205,18 @@ fn get_relevant_span(tcx: TyCtxt<'_>, fi: hir::OwnerId) -> Span {
/// with the same members (as the declarations shouldn't clash).
fn structurally_same_type<'tcx>(
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
typing_env: ty::TypingEnv<'tcx>,
a: Ty<'tcx>,
b: Ty<'tcx>,
ckind: types::CItemKind,
) -> bool {
let mut seen_types = UnordSet::default();
let result = structurally_same_type_impl(&mut seen_types, tcx, param_env, a, b, ckind);
let result = structurally_same_type_impl(&mut seen_types, tcx, typing_env, a, b, ckind);
if cfg!(debug_assertions) && result {
// Sanity-check: must have same ABI, size and alignment.
// `extern` blocks cannot be generic, so we'll always get a layout here.
let a_layout = tcx.layout_of(param_env.and(a)).unwrap();
let b_layout = tcx.layout_of(param_env.and(b)).unwrap();
let a_layout = tcx.layout_of(typing_env.as_query_input(a)).unwrap();
let b_layout = tcx.layout_of(typing_env.as_query_input(b)).unwrap();
assert_eq!(a_layout.backend_repr, b_layout.backend_repr);
assert_eq!(a_layout.size, b_layout.size);
assert_eq!(a_layout.align, b_layout.align);
@ -227,7 +227,7 @@ fn structurally_same_type<'tcx>(
fn structurally_same_type_impl<'tcx>(
seen_types: &mut UnordSet<(Ty<'tcx>, Ty<'tcx>)>,
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
typing_env: ty::TypingEnv<'tcx>,
a: Ty<'tcx>,
b: Ty<'tcx>,
ckind: types::CItemKind,
@ -303,7 +303,7 @@ fn structurally_same_type_impl<'tcx>(
structurally_same_type_impl(
seen_types,
tcx,
param_env,
typing_env,
tcx.type_of(a_did).instantiate(tcx, a_gen_args),
tcx.type_of(b_did).instantiate(tcx, b_gen_args),
ckind,
@ -315,23 +315,23 @@ fn structurally_same_type_impl<'tcx>(
// For arrays, we also check the length.
a_len == b_len
&& structurally_same_type_impl(
seen_types, tcx, param_env, *a_ty, *b_ty, ckind,
seen_types, tcx, typing_env, *a_ty, *b_ty, ckind,
)
}
(Slice(a_ty), Slice(b_ty)) => {
structurally_same_type_impl(seen_types, tcx, param_env, *a_ty, *b_ty, ckind)
structurally_same_type_impl(seen_types, tcx, typing_env, *a_ty, *b_ty, ckind)
}
(RawPtr(a_ty, a_mutbl), RawPtr(b_ty, b_mutbl)) => {
a_mutbl == b_mutbl
&& structurally_same_type_impl(
seen_types, tcx, param_env, *a_ty, *b_ty, ckind,
seen_types, tcx, typing_env, *a_ty, *b_ty, ckind,
)
}
(Ref(_a_region, a_ty, a_mut), Ref(_b_region, b_ty, b_mut)) => {
// For structural sameness, we don't need the region to be same.
a_mut == b_mut
&& structurally_same_type_impl(
seen_types, tcx, param_env, *a_ty, *b_ty, ckind,
seen_types, tcx, typing_env, *a_ty, *b_ty, ckind,
)
}
(FnDef(..), FnDef(..)) => {
@ -346,12 +346,12 @@ fn structurally_same_type_impl<'tcx>(
(a_sig.abi, a_sig.safety, a_sig.c_variadic)
== (b_sig.abi, b_sig.safety, b_sig.c_variadic)
&& a_sig.inputs().iter().eq_by(b_sig.inputs().iter(), |a, b| {
structurally_same_type_impl(seen_types, tcx, param_env, *a, *b, ckind)
structurally_same_type_impl(seen_types, tcx, typing_env, *a, *b, ckind)
})
&& structurally_same_type_impl(
seen_types,
tcx,
param_env,
typing_env,
a_sig.output(),
b_sig.output(),
ckind,
@ -379,14 +379,14 @@ fn structurally_same_type_impl<'tcx>(
// An Adt and a primitive or pointer type. This can be FFI-safe if non-null
// enum layout optimisation is being applied.
(Adt(..), _) if is_primitive_or_pointer(b) => {
if let Some(a_inner) = types::repr_nullable_ptr(tcx, param_env, a, ckind) {
if let Some(a_inner) = types::repr_nullable_ptr(tcx, typing_env, a, ckind) {
a_inner == b
} else {
false
}
}
(_, Adt(..)) if is_primitive_or_pointer(a) => {
if let Some(b_inner) = types::repr_nullable_ptr(tcx, param_env, b, ckind) {
if let Some(b_inner) = types::repr_nullable_ptr(tcx, typing_env, b, ckind) {
b_inner == a
} else {
false

View File

@ -368,7 +368,7 @@ impl<'tcx, 'a> Visitor<'tcx> for FindSignificantDropper<'tcx, 'a> {
.cx
.typeck_results()
.expr_ty(expr)
.has_significant_drop(self.cx.tcx, self.cx.param_env)
.has_significant_drop(self.cx.tcx, self.cx.typing_env())
{
return ControlFlow::Break(expr.span);
}

View File

@ -103,7 +103,8 @@ declare_lint_pass!(QueryStability => [POTENTIAL_QUERY_INSTABILITY, UNTRACKED_QUE
impl LateLintPass<'_> for QueryStability {
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
let Some((span, def_id, args)) = typeck_results_of_method_fn(cx, expr) else { return };
if let Ok(Some(instance)) = ty::Instance::try_resolve(cx.tcx, cx.param_env, def_id, args) {
if let Ok(Some(instance)) = ty::Instance::try_resolve(cx.tcx, cx.typing_env(), def_id, args)
{
let def_id = instance.def_id();
if cx.tcx.has_attr(def_id, sym::rustc_lint_query_instability) {
cx.emit_span_lint(POTENTIAL_QUERY_INSTABILITY, span, QueryInstability {
@ -544,7 +545,7 @@ impl Diagnostics {
) {
// Is the callee marked with `#[rustc_lint_diagnostics]`?
let Some(inst) =
ty::Instance::try_resolve(cx.tcx, cx.param_env, def_id, fn_gen_args).ok().flatten()
ty::Instance::try_resolve(cx.tcx, cx.typing_env(), def_id, fn_gen_args).ok().flatten()
else {
return;
};

View File

@ -128,7 +128,7 @@ impl<'tcx> LateLintPass<'tcx> for LetUnderscore {
// If the type has a trivial Drop implementation, then it doesn't
// matter that we drop the value immediately.
if !ty.needs_drop(cx.tcx, cx.param_env) {
if !ty.needs_drop(cx.tcx, cx.typing_env()) {
return;
}
// Lint for patterns like `mutex.lock()`, which returns `Result<MutexGuard, _>` as well.

View File

@ -157,15 +157,17 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
Some(ty_def) if cx.tcx.is_lang_item(ty_def.did(), LangItem::String),
);
let infcx = cx.tcx.infer_ctxt().build(cx.typing_mode());
let (infcx, param_env) = cx.tcx.infer_ctxt().build_with_typing_env(cx.typing_env());
let suggest_display = is_str
|| cx.tcx.get_diagnostic_item(sym::Display).is_some_and(|t| {
infcx.type_implements_trait(t, [ty], cx.param_env).may_apply()
});
|| cx
.tcx
.get_diagnostic_item(sym::Display)
.is_some_and(|t| infcx.type_implements_trait(t, [ty], param_env).may_apply());
let suggest_debug = !suggest_display
&& cx.tcx.get_diagnostic_item(sym::Debug).is_some_and(|t| {
infcx.type_implements_trait(t, [ty], cx.param_env).may_apply()
});
&& cx
.tcx
.get_diagnostic_item(sym::Debug)
.is_some_and(|t| infcx.type_implements_trait(t, [ty], param_env).may_apply());
let suggest_panic_any = !is_str && panic == sym::std_panic_macro;

View File

@ -94,9 +94,9 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
let args = cx
.tcx
.normalize_erasing_regions(cx.param_env, cx.typeck_results().node_args(expr.hir_id));
.normalize_erasing_regions(cx.typing_env(), cx.typeck_results().node_args(expr.hir_id));
// Resolve the trait method instance.
let Ok(Some(i)) = ty::Instance::try_resolve(cx.tcx, cx.param_env, did, args) else {
let Ok(Some(i)) = ty::Instance::try_resolve(cx.tcx, cx.typing_env(), did, args) else {
return;
};
// (Re)check that it implements the noop diagnostic.

View File

@ -103,7 +103,7 @@ impl TailExprDropOrder {
if matches!(fn_kind, hir::intravisit::FnKind::Closure) {
for &capture in cx.tcx.closure_captures(def_id) {
if matches!(capture.info.capture_kind, ty::UpvarCapture::ByValue)
&& capture.place.ty().has_significant_drop(cx.tcx, cx.param_env)
&& capture.place.ty().has_significant_drop(cx.tcx, cx.typing_env())
{
locals.push(capture.var_ident.span);
}
@ -113,7 +113,7 @@ impl TailExprDropOrder {
if cx
.typeck_results()
.node_type(param.hir_id)
.has_significant_drop(cx.tcx, cx.param_env)
.has_significant_drop(cx.tcx, cx.typing_env())
{
locals.push(param.span);
}
@ -158,7 +158,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LocalCollector<'a, 'tcx> {
fn visit_pat(&mut self, pat: &'tcx Pat<'tcx>) {
if let PatKind::Binding(_binding_mode, id, ident, pat) = pat.kind {
let ty = self.cx.typeck_results().node_type(id);
if ty.has_significant_drop(self.cx.tcx, self.cx.param_env) {
if ty.has_significant_drop(self.cx.tcx, self.cx.typing_env()) {
self.locals.push(ident.span);
}
if let Some(pat) = pat {
@ -234,7 +234,10 @@ impl<'a, 'tcx> LintTailExpr<'a, 'tcx> {
if Self::expr_eventually_point_into_local(expr) {
return false;
}
self.cx.typeck_results().expr_ty(expr).has_significant_drop(self.cx.tcx, self.cx.param_env)
self.cx
.typeck_results()
.expr_ty(expr)
.has_significant_drop(self.cx.tcx, self.cx.typing_env())
}
}

View File

@ -613,10 +613,11 @@ pub(crate) fn transparent_newtype_field<'a, 'tcx>(
tcx: TyCtxt<'tcx>,
variant: &'a ty::VariantDef,
) -> Option<&'a ty::FieldDef> {
let param_env = tcx.param_env(variant.def_id);
let typing_env = ty::TypingEnv::non_body_analysis(tcx, variant.def_id);
variant.fields.iter().find(|field| {
let field_ty = tcx.type_of(field.did).instantiate_identity();
let is_1zst = tcx.layout_of(param_env.and(field_ty)).is_ok_and(|layout| layout.is_1zst());
let is_1zst =
tcx.layout_of(typing_env.as_query_input(field_ty)).is_ok_and(|layout| layout.is_1zst());
!is_1zst
})
}
@ -624,11 +625,11 @@ pub(crate) fn transparent_newtype_field<'a, 'tcx>(
/// Is type known to be non-null?
fn ty_is_known_nonnull<'tcx>(
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
typing_env: ty::TypingEnv<'tcx>,
ty: Ty<'tcx>,
mode: CItemKind,
) -> bool {
let ty = tcx.try_normalize_erasing_regions(param_env, ty).unwrap_or(ty);
let ty = tcx.try_normalize_erasing_regions(typing_env, ty).unwrap_or(ty);
match ty.kind() {
ty::FnPtr(..) => true,
@ -649,7 +650,7 @@ fn ty_is_known_nonnull<'tcx>(
def.variants()
.iter()
.filter_map(|variant| transparent_newtype_field(tcx, variant))
.any(|field| ty_is_known_nonnull(tcx, param_env, field.ty(tcx, args), mode))
.any(|field| ty_is_known_nonnull(tcx, typing_env, field.ty(tcx, args), mode))
}
_ => false,
}
@ -659,10 +660,10 @@ fn ty_is_known_nonnull<'tcx>(
/// If the type passed in was not scalar, returns None.
fn get_nullable_type<'tcx>(
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
typing_env: ty::TypingEnv<'tcx>,
ty: Ty<'tcx>,
) -> Option<Ty<'tcx>> {
let ty = tcx.try_normalize_erasing_regions(param_env, ty).unwrap_or(ty);
let ty = tcx.try_normalize_erasing_regions(typing_env, ty).unwrap_or(ty);
Some(match *ty.kind() {
ty::Adt(field_def, field_args) => {
@ -679,7 +680,7 @@ fn get_nullable_type<'tcx>(
.expect("No non-zst fields in transparent type.")
.ty(tcx, field_args)
};
return get_nullable_type(tcx, param_env, inner_field_ty);
return get_nullable_type(tcx, typing_env, inner_field_ty);
}
ty::Int(ty) => Ty::new_int(tcx, ty),
ty::Uint(ty) => Ty::new_uint(tcx, ty),
@ -708,10 +709,10 @@ fn get_nullable_type<'tcx>(
/// - Does not have the `#[non_exhaustive]` attribute.
fn is_niche_optimization_candidate<'tcx>(
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
typing_env: ty::TypingEnv<'tcx>,
ty: Ty<'tcx>,
) -> bool {
if tcx.layout_of(param_env.and(ty)).is_ok_and(|layout| !layout.is_1zst()) {
if tcx.layout_of(typing_env.as_query_input(ty)).is_ok_and(|layout| !layout.is_1zst()) {
return false;
}
@ -734,7 +735,7 @@ fn is_niche_optimization_candidate<'tcx>(
/// `core::ptr::NonNull`, and `#[repr(transparent)]` newtypes.
pub(crate) fn repr_nullable_ptr<'tcx>(
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
typing_env: ty::TypingEnv<'tcx>,
ty: Ty<'tcx>,
ckind: CItemKind,
) -> Option<Ty<'tcx>> {
@ -747,9 +748,9 @@ pub(crate) fn repr_nullable_ptr<'tcx>(
let ty1 = field1.ty(tcx, args);
let ty2 = field2.ty(tcx, args);
if is_niche_optimization_candidate(tcx, param_env, ty1) {
if is_niche_optimization_candidate(tcx, typing_env, ty1) {
ty2
} else if is_niche_optimization_candidate(tcx, param_env, ty2) {
} else if is_niche_optimization_candidate(tcx, typing_env, ty2) {
ty1
} else {
return None;
@ -760,20 +761,20 @@ pub(crate) fn repr_nullable_ptr<'tcx>(
_ => return None,
};
if !ty_is_known_nonnull(tcx, param_env, field_ty, ckind) {
if !ty_is_known_nonnull(tcx, typing_env, field_ty, ckind) {
return None;
}
// At this point, the field's type is known to be nonnull and the parent enum is Option-like.
// If the computed size for the field and the enum are different, the nonnull optimization isn't
// being applied (and we've got a problem somewhere).
let compute_size_skeleton = |t| SizeSkeleton::compute(t, tcx, param_env).ok();
let compute_size_skeleton = |t| SizeSkeleton::compute(t, tcx, typing_env).ok();
if !compute_size_skeleton(ty)?.same_size(compute_size_skeleton(field_ty)?) {
bug!("improper_ctypes: Option nonnull optimization not applied?");
}
// Return the nullable type this Option-like enum can be safely represented with.
let field_ty_layout = tcx.layout_of(param_env.and(field_ty));
let field_ty_layout = tcx.layout_of(typing_env.as_query_input(field_ty));
if field_ty_layout.is_err() && !field_ty.has_non_region_param() {
bug!("should be able to compute the layout of non-polymorphic type");
}
@ -784,10 +785,10 @@ pub(crate) fn repr_nullable_ptr<'tcx>(
WrappingRange { start: 0, end }
if end == field_ty_scalar.size(&tcx).unsigned_int_max() - 1 =>
{
return Some(get_nullable_type(tcx, param_env, field_ty).unwrap());
return Some(get_nullable_type(tcx, typing_env, field_ty).unwrap());
}
WrappingRange { start: 1, .. } => {
return Some(get_nullable_type(tcx, param_env, field_ty).unwrap());
return Some(get_nullable_type(tcx, typing_env, field_ty).unwrap());
}
WrappingRange { start, end } => {
unreachable!("Unhandled start and end range: ({}, {})", start, end)
@ -825,7 +826,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
let field_ty = self
.cx
.tcx
.try_normalize_erasing_regions(self.cx.param_env, field_ty)
.try_normalize_erasing_regions(self.cx.typing_env(), field_ty)
.unwrap_or(field_ty);
self.check_type_for_ffi(acc, field_ty)
}
@ -988,7 +989,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
{
// Special-case types like `Option<extern fn()>` and `Result<extern fn(), ()>`
if let Some(ty) =
repr_nullable_ptr(self.cx.tcx, self.cx.param_env, ty, self.mode)
repr_nullable_ptr(self.cx.tcx, self.cx.typing_env(), ty, self.mode)
{
return self.check_type_for_ffi(acc, ty);
}
@ -1196,7 +1197,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
if let Some(ty) = self
.cx
.tcx
.try_normalize_erasing_regions(self.cx.param_env, ty)
.try_normalize_erasing_regions(self.cx.typing_env(), ty)
.unwrap_or(ty)
.visit_with(&mut ProhibitOpaqueTypes)
.break_value()
@ -1220,7 +1221,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
return;
}
let ty = self.cx.tcx.try_normalize_erasing_regions(self.cx.param_env, ty).unwrap_or(ty);
let ty = self.cx.tcx.try_normalize_erasing_regions(self.cx.typing_env(), ty).unwrap_or(ty);
// C doesn't really support passing arrays by value - the only way to pass an array by value
// is through a struct. So, first test that the top level isn't an array, and then

View File

@ -272,7 +272,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|| !ty.is_inhabited_from(
cx.tcx,
cx.tcx.parent_module(expr.hir_id).to_def_id(),
cx.param_env,
cx.typing_env(),
)
{
return Some(MustUsePath::Suppressed);
@ -556,7 +556,7 @@ impl<'tcx> LateLintPass<'tcx> for PathStatements {
if let hir::StmtKind::Semi(expr) = s.kind {
if let hir::ExprKind::Path(_) = expr.kind {
let ty = cx.typeck_results().expr_ty(expr);
if ty.needs_drop(cx.tcx, cx.param_env) {
if ty.needs_drop(cx.tcx, cx.typing_env()) {
let sub = if let Ok(snippet) = cx.sess().source_map().span_to_snippet(expr.span)
{
PathStatementDropSub::Suggestion { span: s.span, snippet }

View File

@ -6,7 +6,7 @@ use rustc_ast::CRATE_NODE_ID;
use rustc_attr as attr;
use rustc_data_structures::fx::FxHashSet;
use rustc_middle::query::LocalCrate;
use rustc_middle::ty::{List, ParamEnv, ParamEnvAnd, Ty, TyCtxt};
use rustc_middle::ty::{self, List, Ty, TyCtxt};
use rustc_session::Session;
use rustc_session::config::CrateType;
use rustc_session::cstore::{
@ -613,7 +613,7 @@ impl<'tcx> Collector<'tcx> {
.map(|ty| {
let layout = self
.tcx
.layout_of(ParamEnvAnd { param_env: ParamEnv::empty(), value: ty })
.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty))
.expect("layout")
.layout;
// In both stdcall and fastcall, we always round up the argument size to the

View File

@ -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]

View File

@ -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)
}

View File

@ -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.

View File

@ -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 {

View File

@ -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 {

View File

@ -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`].

View File

@ -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>`

View File

@ -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 }
}

View File

@ -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) => {

View File

@ -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 {

View File

@ -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))
}

View File

@ -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))
}

Some files were not shown because too many files have changed in this diff Show More