use TypingEnv when no infcx is available

the behavior of the type system not only depends on the current
assumptions, but also the currentnphase of the compiler. This is
mostly necessary as we need to decide whether and how to reveal
opaque types. We track this via the `TypingMode`.
This commit is contained in:
lcnr 2024-11-15 13:53:31 +01:00
parent bf6adec108
commit 9cba14b95b
240 changed files with 1739 additions and 1340 deletions

View File

@ -682,8 +682,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
// Normalize before comparing to see through type aliases and projections. // Normalize before comparing to see through type aliases and projections.
let old_ty = ty::EarlyBinder::bind(ty).instantiate(tcx, generic_args); let old_ty = ty::EarlyBinder::bind(ty).instantiate(tcx, generic_args);
let new_ty = ty::EarlyBinder::bind(ty).instantiate(tcx, new_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) if let Ok(old_ty) =
&& let Ok(new_ty) = tcx.try_normalize_erasing_regions(self.param_env, new_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 old_ty == new_ty
} else { } else {
@ -3831,11 +3835,16 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
if tcx.is_diagnostic_item(sym::deref_method, method_did) { if tcx.is_diagnostic_item(sym::deref_method, method_did) {
let deref_target = let deref_target =
tcx.get_diagnostic_item(sym::deref_target).and_then(|deref_target| { tcx.get_diagnostic_item(sym::deref_target).and_then(|deref_target| {
Instance::try_resolve(tcx, self.param_env, deref_target, method_args) Instance::try_resolve(
.transpose() tcx,
self.infcx.typing_env(self.param_env),
deref_target,
method_args,
)
.transpose()
}); });
if let Some(Ok(instance)) = deref_target { 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.note(format!("borrow occurs due to deref coercion to `{deref_target_ty}`"));
err.span_note(tcx.def_span(instance.def_id()), "deref defined here"); 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( let kind = call_kind(
self.infcx.tcx, self.infcx.tcx,
self.param_env, self.infcx.typing_env(self.param_env),
method_did, method_did,
method_args, method_args,
*fn_span, *fn_span,

View File

@ -952,7 +952,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
if let Ok(Some(instance)) = ty::Instance::try_resolve( if let Ok(Some(instance)) = ty::Instance::try_resolve(
tcx, tcx,
self.param_env, self.infcx.typing_env(self.param_env),
*fn_did, *fn_did,
self.infcx.resolve_vars_if_possible(args), 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, // The signature in this call can reference region variables,
// so erase them before calling a query. // so erase them before calling a query.
let output_ty = self.tcx().erase_regions(sig.output()); 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); 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 = if let ty::FnDef(def_id, fn_args) = *func.layout().ty.kind() {
let instance = ty::Instance::expect_resolve( let instance = ty::Instance::expect_resolve(
fx.tcx, fx.tcx,
ty::ParamEnv::reveal_all(), ty::TypingEnv::fully_monomorphized(),
def_id, def_id,
fn_args, fn_args,
source_info.span, source_info.span,

View File

@ -666,7 +666,7 @@ fn codegen_stmt<'tcx>(
let func_ref = fx.get_function_ref( let func_ref = fx.get_function_ref(
Instance::resolve_for_fn_ptr( Instance::resolve_for_fn_ptr(
fx.tcx, fx.tcx,
ParamEnv::reveal_all(), ty::TypingEnv::fully_monomorphized(),
def_id, def_id,
args, args,
) )
@ -841,14 +841,18 @@ fn codegen_stmt<'tcx>(
lval.write_cvalue(fx, CValue::by_val(operand, box_layout)); lval.write_cvalue(fx, CValue::by_val(operand, box_layout));
} }
Rvalue::NullaryOp(ref null_op, ty) => { 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 layout = fx.layout_of(fx.monomorphize(ty));
let val = match null_op { let val = match null_op {
NullOp::SizeOf => layout.size.bytes(), NullOp::SizeOf => layout.size.bytes(),
NullOp::AlignOf => layout.align.abi.bytes(), NullOp::AlignOf => layout.align.abi.bytes(),
NullOp::OffsetOf(fields) => fx NullOp::OffsetOf(fields) => fx
.tcx .tcx
.offset_of_subfield(ParamEnv::reveal_all(), layout, fields.iter()) .offset_of_subfield(
ty::TypingEnv::fully_monomorphized(),
layout,
fields.iter(),
)
.bytes(), .bytes(),
NullOp::UbChecks => { NullOp::UbChecks => {
let val = fx.tcx.sess.ub_checks(); 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? /// Is a pointer to this type a wide ptr?
pub(crate) fn has_ptr_meta<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool { 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; 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() { match tail.kind() {
ty::Foreign(..) => false, ty::Foreign(..) => false,
ty::Str | ty::Slice(..) | ty::Dynamic(..) => true, 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> { impl<'tcx> layout::HasTypingEnv<'tcx> for FunctionCx<'_, '_, 'tcx> {
fn param_env(&self) -> ParamEnv<'tcx> { fn typing_env(&self) -> ty::TypingEnv<'tcx> {
ParamEnv::reveal_all() ty::TypingEnv::fully_monomorphized()
} }
} }
@ -358,7 +358,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
{ {
self.instance.instantiate_mir_and_normalize_erasing_regions( self.instance.instantiate_mir_and_normalize_erasing_regions(
self.tcx, self.tcx,
ty::ParamEnv::reveal_all(), ty::TypingEnv::fully_monomorphized(),
ty::EarlyBinder::bind(value), ty::EarlyBinder::bind(value),
) )
} }
@ -497,9 +497,9 @@ impl<'tcx> rustc_abi::HasDataLayout for RevealAllLayoutCx<'tcx> {
} }
} }
impl<'tcx> layout::HasParamEnv<'tcx> for RevealAllLayoutCx<'tcx> { impl<'tcx> layout::HasTypingEnv<'tcx> for RevealAllLayoutCx<'tcx> {
fn param_env(&self) -> ParamEnv<'tcx> { fn typing_env(&self) -> ty::TypingEnv<'tcx> {
ParamEnv::reveal_all() ty::TypingEnv::fully_monomorphized()
} }
} }

View File

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

View File

@ -210,7 +210,7 @@ impl DebugContext {
type_names::push_generic_params( type_names::push_generic_params(
tcx, tcx,
tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), args), tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), args),
&mut name, &mut name,
); );
@ -275,8 +275,10 @@ impl DebugContext {
let span = tcx.def_span(def_id); let span = tcx.def_span(def_id);
let (file_id, line, _column) = self.get_span_loc(tcx, span, span); 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_type = Instance::mono(tcx, def_id).ty(tcx, ty::TypingEnv::fully_monomorphized());
let static_layout = tcx.layout_of(ty::ParamEnv::reveal_all().and(static_type)).unwrap(); let static_layout = tcx
.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(static_type))
.unwrap();
// FIXME use the actual type layout // FIXME use the actual type layout
let type_id = self.debug_type(tcx, type_dbg, static_type); 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() { if let ty::FnDef(def_id, args) = *const_.ty().kind() {
let instance = ty::Instance::resolve_for_fn_ptr( let instance = ty::Instance::resolve_for_fn_ptr(
fx.tcx, fx.tcx,
ty::ParamEnv::reveal_all(), ty::TypingEnv::fully_monomorphized(),
def_id, def_id,
args, args,
) )
@ -227,11 +227,11 @@ pub(crate) fn codegen_naked_asm<'tcx>(
InlineAsmOperand::Const { ref value } => { InlineAsmOperand::Const { ref value } => {
let cv = instance.instantiate_mir_and_normalize_erasing_regions( let cv = instance.instantiate_mir_and_normalize_erasing_regions(
tcx, tcx,
ty::ParamEnv::reveal_all(), ty::TypingEnv::fully_monomorphized(),
ty::EarlyBinder::bind(value.const_), ty::EarlyBinder::bind(value.const_),
); );
let const_value = cv 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"); .expect("erroneous constant missed by mono item collection");
let value = rustc_codegen_ssa::common::asm_const_to_str( 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( let const_ = instance.instantiate_mir_and_normalize_erasing_regions(
tcx, tcx,
ty::ParamEnv::reveal_all(), ty::TypingEnv::fully_monomorphized(),
ty::EarlyBinder::bind(value.const_), ty::EarlyBinder::bind(value.const_),
); );
if let ty::FnDef(def_id, args) = *const_.ty().kind() { if let ty::FnDef(def_id, args) = *const_.ty().kind() {
let instance = ty::Instance::resolve_for_fn_ptr( let instance = ty::Instance::resolve_for_fn_ptr(
tcx, tcx,
ty::ParamEnv::reveal_all(), ty::TypingEnv::fully_monomorphized(),
def_id, def_id,
args, args,
) )

View File

@ -20,7 +20,7 @@ mod simd;
use cranelift_codegen::ir::AtomicRmwOp; use cranelift_codegen::ir::AtomicRmwOp;
use rustc_middle::ty; use rustc_middle::ty;
use rustc_middle::ty::GenericArgsRef; 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_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
use rustc_span::source_map::Spanned; use rustc_span::source_map::Spanned;
use rustc_span::symbol::{Symbol, sym}; use rustc_span::symbol::{Symbol, sym};
@ -682,7 +682,10 @@ fn codegen_regular_intrinsic_call<'tcx>(
if let Some(requirement) = requirement { if let Some(requirement) = requirement {
let do_panic = !fx let do_panic = !fx
.tcx .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"); .expect("expect to have layout during codegen");
if do_panic { if do_panic {
@ -741,7 +744,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
let const_val = fx let const_val = fx
.tcx .tcx
.const_eval_instance(ParamEnv::reveal_all(), instance, source_info.span) .const_eval_instance(ty::ParamEnv::reveal_all(), instance, source_info.span)
.unwrap(); .unwrap();
let val = crate::constant::codegen_const_value(fx, const_val, ret.layout().ty); let val = crate::constant::codegen_const_value(fx, const_val, ret.layout().ty);
ret.write_cvalue(fx, val); 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::mir::{self, *};
pub(crate) use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; pub(crate) use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
pub(crate) use rustc_middle::ty::{ 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; 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 // regions must appear in the argument
// listing. // listing.
let main_ret_ty = tcx.normalize_erasing_regions( let main_ret_ty = tcx.normalize_erasing_regions(
ty::ParamEnv::reveal_all(), ty::TypingEnv::fully_monomorphized(),
main_ret_ty.no_bound_vars().unwrap(), main_ret_ty.no_bound_vars().unwrap(),
); );
@ -113,7 +113,7 @@ pub(crate) fn maybe_create_entry_wrapper(
.unwrap(); .unwrap();
let report = Instance::expect_resolve( let report = Instance::expect_resolve(
tcx, tcx,
ParamEnv::reveal_all(), ty::TypingEnv::fully_monomorphized(),
report.def_id, report.def_id,
tcx.mk_args(&[GenericArg::from(main_ret_ty)]), tcx.mk_args(&[GenericArg::from(main_ret_ty)]),
DUMMY_SP, 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_def_id = tcx.require_lang_item(LangItem::Start, None);
let start_instance = Instance::expect_resolve( let start_instance = Instance::expect_resolve(
tcx, tcx,
ParamEnv::reveal_all(), ty::TypingEnv::fully_monomorphized(),
start_def_id, start_def_id,
tcx.mk_args(&[main_ret_ty.into()]), tcx.mk_args(&[main_ret_ty.into()]),
DUMMY_SP, DUMMY_SP,

View File

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

View File

@ -4,6 +4,7 @@ use cranelift_codegen::entity::EntityRef;
use cranelift_codegen::ir::immediates::Offset32; use cranelift_codegen::ir::immediates::Offset32;
use cranelift_frontend::Variable; use cranelift_frontend::Variable;
use rustc_middle::ty::FnSig; use rustc_middle::ty::FnSig;
use rustc_middle::ty::layout::HasTypingEnv;
use crate::prelude::*; use crate::prelude::*;
@ -884,19 +885,17 @@ pub(crate) fn assert_assignable<'tcx>(
assert_assignable(fx, *a, *b, limit - 1); assert_assignable(fx, *a, *b, limit - 1);
} }
(ty::FnPtr(..), ty::FnPtr(..)) => { (ty::FnPtr(..), ty::FnPtr(..)) => {
let from_sig = fx.tcx.normalize_erasing_late_bound_regions( let from_sig = fx
ParamEnv::reveal_all(), .tcx
from_ty.fn_sig(fx.tcx), .normalize_erasing_late_bound_regions(fx.typing_env(), from_ty.fn_sig(fx.tcx));
);
let FnSig { let FnSig {
inputs_and_output: types_from, inputs_and_output: types_from,
c_variadic: c_variadic_from, c_variadic: c_variadic_from,
safety: unsafety_from, safety: unsafety_from,
abi: abi_from, abi: abi_from,
} = from_sig; } = from_sig;
let to_sig = fx let to_sig =
.tcx fx.tcx.normalize_erasing_late_bound_regions(fx.typing_env(), to_ty.fn_sig(fx.tcx));
.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), to_ty.fn_sig(fx.tcx));
let FnSig { let FnSig {
inputs_and_output: types_to, inputs_and_output: types_to,
c_variadic: c_variadic_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)) => { (&ty::Dynamic(from_traits, _, _from_kind), &ty::Dynamic(to_traits, _, _to_kind)) => {
// FIXME(dyn-star): Do the right thing with DynKinds // FIXME(dyn-star): Do the right thing with DynKinds
for (from, to) in from_traits.iter().zip(to_traits) { for (from, to) in from_traits.iter().zip(to_traits) {
let from = let from = fx.tcx.normalize_erasing_late_bound_regions(fx.typing_env(), from);
fx.tcx.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), from); let to = fx.tcx.normalize_erasing_late_bound_regions(fx.typing_env(), to);
let to = fx.tcx.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), to);
assert_eq!( assert_eq!(
from, to, from, to,
"Can't write trait object of incompatible traits {:?} to place with traits {:?}\n\n{:#?}", "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::bug;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
use rustc_middle::ty::layout::{ 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::Span;
use rustc_span::def_id::DefId; use rustc_span::def_id::DefId;
use rustc_target::abi::call::FnAbi; 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> { impl<'tcx> HasTypingEnv<'tcx> for Builder<'_, '_, 'tcx> {
fn param_env(&self) -> ParamEnv<'tcx> { fn typing_env(&self) -> ty::TypingEnv<'tcx> {
self.cx.param_env() self.cx.typing_env()
} }
} }

View File

@ -215,7 +215,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
let gcc_type = if nested { let gcc_type = if nested {
self.type_i8() self.type_i8()
} else { } 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) 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::mir::mono::CodegenUnit;
use rustc_middle::span_bug; use rustc_middle::span_bug;
use rustc_middle::ty::layout::{ use rustc_middle::ty::layout::{
FnAbiError, FnAbiOf, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, HasTyCtxt, LayoutError, FnAbiError, FnAbiOf, FnAbiOfHelpers, FnAbiRequest, HasTyCtxt, HasTypingEnv, LayoutError,
LayoutOfHelpers, 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_session::Session;
use rustc_span::source_map::respan; use rustc_span::source_map::respan;
use rustc_span::{DUMMY_SP, Span}; use rustc_span::{DUMMY_SP, Span};
@ -144,7 +144,9 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
supports_f128_type: bool, supports_f128_type: bool,
) -> Self { ) -> Self {
let create_type = |ctype, rust_type| { 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(); let align = layout.align.abi.bytes();
#[cfg(feature = "master")] #[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()) => { Some(def_id) if !wants_msvc_seh(self.sess()) => {
let instance = ty::Instance::expect_resolve( let instance = ty::Instance::expect_resolve(
tcx, tcx,
ty::ParamEnv::reveal_all(), self.typing_env(),
def_id, def_id,
ty::List::empty(), ty::List::empty(),
DUMMY_SP, DUMMY_SP,
@ -583,9 +585,9 @@ impl<'gcc, 'tcx> FnAbiOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> {
} }
} }
impl<'tcx, 'gcc> HasParamEnv<'tcx> for CodegenCx<'gcc, 'tcx> { impl<'tcx, 'gcc> HasTypingEnv<'tcx> for CodegenCx<'gcc, 'tcx> {
fn param_env(&self) -> ParamEnv<'tcx> { fn typing_env(&self) -> ty::TypingEnv<'tcx> {
ParamEnv::reveal_all() ty::TypingEnv::fully_monomorphized()
} }
} }

View File

@ -5,7 +5,7 @@
use gccjit::{BinaryOp, ComparisonOp, FunctionType, Location, RValue, ToRValue, Type, UnaryOp}; use gccjit::{BinaryOp, ComparisonOp, FunctionType, Location, RValue, ToRValue, Type, UnaryOp};
use rustc_codegen_ssa::common::{IntPredicate, TypeKind}; use rustc_codegen_ssa::common::{IntPredicate, TypeKind};
use rustc_codegen_ssa::traits::{BackendTypes, BaseTypeCodegenMethods, BuilderMethods, OverflowOp}; 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::Endian;
use rustc_target::abi::call::{ArgAbi, ArgAttributes, Conv, FnAbi, PassMode}; use rustc_target::abi::call::{ArgAbi, ArgAttributes, Conv, FnAbi, PassMode};
use rustc_target::spec; 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 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 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 arg_abi = ArgAbi { layout, mode: PassMode::Direct(ArgAttributes::new()) };
let mut fn_abi = FnAbi { 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::bug;
use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::layout::LayoutOf;
#[cfg(feature = "master")] #[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_middle::ty::{self, Instance, Ty};
use rustc_span::{Span, Symbol, sym}; use rustc_span::{Span, Symbol, sym};
use rustc_target::abi::HasDataLayout; use rustc_target::abi::HasDataLayout;
@ -107,7 +107,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
span: Span, span: Span,
) -> Result<(), Instance<'tcx>> { ) -> Result<(), Instance<'tcx>> {
let tcx = self.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() { let (def_id, fn_args) = match *callee_ty.kind() {
ty::FnDef(def_id, fn_args) => (def_id, fn_args), 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 = 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 arg_tys = sig.inputs();
let ret_ty = sig.output(); let ret_ty = sig.output();
let name = tcx.item_name(def_id); 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 tcx = bx.tcx();
let sig = let sig = tcx.normalize_erasing_late_bound_regions(
tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), callee_ty.fn_sig(tcx)); ty::TypingEnv::fully_monomorphized(),
callee_ty.fn_sig(tcx),
);
let arg_tys = sig.inputs(); let arg_tys = sig.inputs();
if name == sym::simd_select_bitmask { if name == sym::simd_select_bitmask {
@ -478,7 +480,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
match *in_elem.kind() { match *in_elem.kind() {
ty::RawPtr(p_ty, _) => { ty::RawPtr(p_ty, _) => {
let metadata = p_ty.ptr_metadata_ty(bx.tcx, |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 { require!(metadata.is_unit(), InvalidMonomorphization::CastWidePointer {
span, span,
@ -493,7 +495,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
match *out_elem.kind() { match *out_elem.kind() {
ty::RawPtr(p_ty, _) => { ty::RawPtr(p_ty, _) => {
let metadata = p_ty.ptr_metadata_ty(bx.tcx, |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 { require!(metadata.is_unit(), InvalidMonomorphization::CastWidePointer {
span, span,

View File

@ -6,7 +6,7 @@ use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_middle::bug; use rustc_middle::bug;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::mir::mono::{Linkage, Visibility}; 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_middle::ty::{self, Instance, TypeVisitableExt};
use crate::context::CodegenCx; 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!() }; 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 // 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. // the gcc type from the actual evaluated initializer.
let ty = if nested { let ty =
self.tcx.types.unit if nested { self.tcx.types.unit } else { instance.ty(self.tcx, self.typing_env()) };
} else {
instance.ty(self.tcx, ty::ParamEnv::reveal_all())
};
let gcc_type = self.layout_of(ty).gcc_type(self); let gcc_type = self.layout_of(ty).gcc_type(self);
let is_tls = attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL); 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_hir::def_id::DefId;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
use rustc_middle::ty::layout::{ use rustc_middle::ty::layout::{
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, LayoutError, LayoutOfHelpers, FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasTypingEnv, LayoutError, LayoutOfHelpers,
TyAndLayout, TyAndLayout,
}; };
use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; 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> { impl<'tcx> ty::layout::HasTypingEnv<'tcx> for Builder<'_, '_, 'tcx> {
fn param_env(&self) -> ty::ParamEnv<'tcx> { fn typing_env(&self) -> ty::TypingEnv<'tcx> {
self.cx.param_env() 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))] #[instrument(level = "trace", skip(self))]
fn load_operand(&mut self, place: PlaceRef<'tcx, &'ll Value>) -> OperandRef<'tcx, &'ll Value> { fn load_operand(&mut self, place: PlaceRef<'tcx, &'ll Value>) -> OperandRef<'tcx, &'ll Value> {
if place.layout.is_unsized() { 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(..)) { if matches!(tail.kind(), ty::Foreign(..)) {
// Unsized locals and, at least conceptually, even unsized arguments must be copied // Unsized locals and, at least conceptually, even unsized arguments must be copied
// around, which requires dynamically determining their size. Therefore, we cannot // around, which requires dynamically determining their size. Therefore, we cannot

View File

@ -5,7 +5,7 @@
//! closure. //! closure.
use rustc_codegen_ssa::common; 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 rustc_middle::ty::{self, Instance, TypeVisitableExt};
use tracing::debug; 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; let sym = tcx.symbol_name(instance).name;
debug!( debug!("get_fn({:?}: {:?}) => {}", instance, instance.ty(cx.tcx(), cx.typing_env()), sym);
"get_fn({:?}: {:?}) => {}",
instance,
instance.ty(cx.tcx(), ty::ParamEnv::reveal_all()),
sym
);
let fn_abi = cx.fn_abi_of_instance(instance, ty::List::empty()); 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, read_target_uint,
}; };
use rustc_middle::mir::mono::MonoItem; use rustc_middle::mir::mono::MonoItem;
use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::Instance;
use rustc_middle::ty::{self, Instance}; use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf};
use rustc_middle::{bug, span_bug}; use rustc_middle::{bug, span_bug};
use rustc_session::config::Lto; use rustc_session::config::Lto;
use tracing::{debug, instrument, trace}; use tracing::{debug, instrument, trace};
@ -244,7 +244,7 @@ impl<'ll> CodegenCx<'ll, '_> {
let llty = if nested { let llty = if nested {
self.type_i8() self.type_i8()
} else { } else {
let ty = instance.ty(self.tcx, ty::ParamEnv::reveal_all()); let ty = instance.ty(self.tcx, self.typing_env());
trace!(?ty); trace!(?ty);
self.layout_of(ty).llvm_type(self) 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::middle::codegen_fn_attrs::PatchableFunctionEntry;
use rustc_middle::mir::mono::CodegenUnit; use rustc_middle::mir::mono::CodegenUnit;
use rustc_middle::ty::layout::{ 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::ty::{self, Instance, Ty, TyCtxt};
use rustc_middle::{bug, span_bug}; 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() { let llfn = match tcx.lang_items().eh_personality() {
Some(def_id) if name.is_none() => self.get_fn_addr(ty::Instance::expect_resolve( Some(def_id) if name.is_none() => self.get_fn_addr(ty::Instance::expect_resolve(
tcx, tcx,
ty::ParamEnv::reveal_all(), self.typing_env(),
def_id, def_id,
ty::List::empty(), ty::List::empty(),
DUMMY_SP, DUMMY_SP,
@ -1162,9 +1162,9 @@ impl<'tcx> ty::layout::HasTyCtxt<'tcx> for CodegenCx<'_, 'tcx> {
} }
} }
impl<'tcx, 'll> HasParamEnv<'tcx> for CodegenCx<'ll, 'tcx> { impl<'tcx, 'll> HasTypingEnv<'tcx> for CodegenCx<'ll, 'tcx> {
fn param_env(&self) -> ty::ParamEnv<'tcx> { fn typing_env(&self) -> ty::TypingEnv<'tcx> {
ty::ParamEnv::reveal_all() ty::TypingEnv::fully_monomorphized()
} }
} }

View File

@ -6,7 +6,7 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_index::Idx; use rustc_index::Idx;
use rustc_index::bit_set::BitSet; use rustc_index::bit_set::BitSet;
use rustc_middle::mir::{Body, SourceScope}; 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_middle::ty::{self, Instance};
use rustc_session::config::DebugInfo; use rustc_session::config::DebugInfo;
use rustc_span::BytePos; use rustc_span::BytePos;
@ -118,7 +118,7 @@ fn make_mir_scope<'ll, 'tcx>(
// if this is moved to `rustc_codegen_ssa::mir::debuginfo`. // if this is moved to `rustc_codegen_ssa::mir::debuginfo`.
let callee = cx.tcx.instantiate_and_normalize_erasing_regions( let callee = cx.tcx.instantiate_and_normalize_erasing_regions(
instance.args, instance.args,
ty::ParamEnv::reveal_all(), cx.typing_env(),
ty::EarlyBinder::bind(callee), ty::EarlyBinder::bind(callee),
); );
debug_context.inlined_function_scopes.entry(callee).or_insert_with(|| { 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::{CtorKind, DefKind};
use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_middle::bug; use rustc_middle::bug;
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf, TyAndLayout};
use rustc_middle::ty::{ use rustc_middle::ty::{
self, AdtKind, CoroutineArgsExt, Instance, ParamEnv, PolyExistentialTraitRef, Ty, TyCtxt, self, AdtKind, CoroutineArgsExt, Instance, PolyExistentialTraitRef, Ty, TyCtxt, Visibility,
Visibility,
}; };
use rustc_session::config::{self, DebugInfo, Lto}; use rustc_session::config::{self, DebugInfo, Lto};
use rustc_span::symbol::Symbol; 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)); .insert(unique_type_id, recursion_marker_type_di_node(cx));
let fn_ty = unique_type_id.expect_ty(); let fn_ty = unique_type_id.expect_ty();
let signature = cx let signature =
.tcx cx.tcx.normalize_erasing_late_bound_regions(cx.typing_env(), fn_ty.fn_sig(cx.tcx));
.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), fn_ty.fn_sig(cx.tcx));
let signature_di_nodes: SmallVec<_> = iter::once( let signature_di_nodes: SmallVec<_> = iter::once(
// return type // return type
@ -1109,9 +1107,7 @@ fn build_upvar_field_di_nodes<'ll, 'tcx>(
} }
}; };
assert!( assert!(up_var_tys.iter().all(|t| t == cx.tcx.normalize_erasing_regions(cx.typing_env(), t)));
up_var_tys.iter().all(|t| t == cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), t))
);
let capture_names = cx.tcx.closure_saved_names_of_captured_variables(def_id); let capture_names = cx.tcx.closure_saved_names_of_captured_variables(def_id);
let layout = cx.layout_of(closure_or_coroutine_ty); 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) let template_params: SmallVec<_> = iter::zip(args, names)
.filter_map(|(kind, name)| { .filter_map(|(kind, name)| {
kind.as_type().map(|ty| { kind.as_type().map(|ty| {
let actual_type = let actual_type = cx.tcx.normalize_erasing_regions(cx.typing_env(), ty);
cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
let actual_type_di_node = type_di_node(cx, actual_type); let actual_type_di_node = type_di_node(cx, actual_type);
let name = name.as_str(); let name = name.as_str();
unsafe { unsafe {
@ -1341,7 +1336,7 @@ pub(crate) fn build_global_var_di_node<'ll>(
if nested { if nested {
return; 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 type_di_node = type_di_node(cx, variable_type);
let var_name = tcx.item_name(def_id); let var_name = tcx.item_name(def_id);
let var_name = var_name.as_str(); 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_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_macros::HashStable; use rustc_macros::HashStable;
use rustc_middle::bug; 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 super::{SmallVec, UNKNOWN_LINE_NUMBER, unknown_file_metadata};
use crate::common::{AsCCharPtr, CodegenCx}; use crate::common::{AsCCharPtr, CodegenCx};
@ -49,12 +49,15 @@ pub(super) enum UniqueTypeId<'tcx> {
impl<'tcx> UniqueTypeId<'tcx> { impl<'tcx> UniqueTypeId<'tcx> {
pub(crate) fn for_ty(tcx: TyCtxt<'tcx>, t: Ty<'tcx>) -> Self { 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) UniqueTypeId::Ty(t, private::HiddenZst)
} }
pub(crate) fn for_enum_variant_part(tcx: TyCtxt<'tcx>, enum_ty: Ty<'tcx>) -> Self { 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) UniqueTypeId::VariantPart(enum_ty, private::HiddenZst)
} }
@ -63,7 +66,10 @@ impl<'tcx> UniqueTypeId<'tcx> {
enum_ty: Ty<'tcx>, enum_ty: Ty<'tcx>,
variant_idx: VariantIdx, variant_idx: VariantIdx,
) -> Self { ) -> 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) UniqueTypeId::VariantStructType(enum_ty, variant_idx, private::HiddenZst)
} }
@ -72,7 +78,10 @@ impl<'tcx> UniqueTypeId<'tcx> {
enum_ty: Ty<'tcx>, enum_ty: Ty<'tcx>,
variant_idx: VariantIdx, variant_idx: VariantIdx,
) -> Self { ) -> 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) UniqueTypeId::VariantStructTypeCppLikeWrapper(enum_ty, variant_idx, private::HiddenZst)
} }
@ -81,10 +90,13 @@ impl<'tcx> UniqueTypeId<'tcx> {
self_type: Ty<'tcx>, self_type: Ty<'tcx>,
implemented_trait: Option<PolyExistentialTraitRef<'tcx>>, implemented_trait: Option<PolyExistentialTraitRef<'tcx>>,
) -> Self { ) -> 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!( assert_eq!(
implemented_trait, 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) 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_hir::def_id::{DefId, DefIdMap};
use rustc_index::IndexVec; use rustc_index::IndexVec;
use rustc_middle::mir; use rustc_middle::mir;
use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf};
use rustc_middle::ty::{self, GenericArgsRef, Instance, ParamEnv, Ty, TypeVisitableExt}; use rustc_middle::ty::{self, GenericArgsRef, Instance, Ty, TypeVisitableExt};
use rustc_session::Session; use rustc_session::Session;
use rustc_session::config::{self, DebugInfo}; use rustc_session::config::{self, DebugInfo};
use rustc_span::symbol::Symbol; use rustc_span::symbol::Symbol;
@ -344,7 +344,7 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
type_names::push_generic_params( type_names::push_generic_params(
tcx, tcx,
tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), args), tcx.normalize_erasing_regions(self.typing_env(), args),
&mut name, &mut name,
); );
@ -481,8 +481,7 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
iter::zip(args, names) iter::zip(args, names)
.filter_map(|(kind, name)| { .filter_map(|(kind, name)| {
kind.as_type().map(|ty| { kind.as_type().map(|ty| {
let actual_type = let actual_type = cx.tcx.normalize_erasing_regions(cx.typing_env(), ty);
cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
let actual_type_metadata = type_di_node(cx, actual_type); let actual_type_metadata = type_di_node(cx, actual_type);
let name = name.as_str(); let name = name.as_str();
unsafe { 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() { if cx.tcx.trait_id_of_impl(impl_def_id).is_none() {
let impl_self_ty = cx.tcx.instantiate_and_normalize_erasing_regions( let impl_self_ty = cx.tcx.instantiate_and_normalize_erasing_regions(
instance.args, instance.args,
ty::ParamEnv::reveal_all(), cx.typing_env(),
cx.tcx.type_of(impl_def_id), cx.tcx.type_of(impl_def_id),
); );

View File

@ -1,7 +1,7 @@
// Utility Functions. // Utility Functions.
use rustc_hir::def_id::DefId; 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 rustc_middle::ty::{self, Ty};
use tracing::trace; use tracing::trace;
@ -62,7 +62,7 @@ pub(crate) fn wide_pointer_kind<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>, cx: &CodegenCx<'ll, 'tcx>,
pointee_ty: Ty<'tcx>, pointee_ty: Ty<'tcx>,
) -> Option<WidePtrKind> { ) -> 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); let layout = cx.layout_of(pointee_tail_ty);
trace!( trace!(
"wide_pointer_kind: {:?} has layout {:?} (is_unsized? {})", "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_codegen_ssa::traits::*;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_middle::mir::BinOp; 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::ty::{self, GenericArgsRef, Ty};
use rustc_middle::{bug, span_bug}; use rustc_middle::{bug, span_bug};
use rustc_span::{Span, Symbol, sym}; use rustc_span::{Span, Symbol, sym};
@ -163,14 +163,14 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
span: Span, span: Span,
) -> Result<(), ty::Instance<'tcx>> { ) -> Result<(), ty::Instance<'tcx>> {
let tcx = self.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 { let ty::FnDef(def_id, fn_args) = *callee_ty.kind() else {
bug!("expected fn item type, found {}", callee_ty); bug!("expected fn item type, found {}", callee_ty);
}; };
let sig = callee_ty.fn_sig(tcx); 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 arg_tys = sig.inputs();
let ret_ty = sig.output(); let ret_ty = sig.output();
let name = tcx.item_name(def_id); let name = tcx.item_name(def_id);
@ -1152,8 +1152,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
} }
let tcx = bx.tcx(); let tcx = bx.tcx();
let sig = let sig = tcx.normalize_erasing_late_bound_regions(bx.typing_env(), callee_ty.fn_sig(tcx));
tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), callee_ty.fn_sig(tcx));
let arg_tys = sig.inputs(); let arg_tys = sig.inputs();
// Sanity-check: all vector arguments must be immediates. // Sanity-check: all vector arguments must be immediates.
@ -2187,7 +2186,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
match in_elem.kind() { match in_elem.kind() {
ty::RawPtr(p_ty, _) => { ty::RawPtr(p_ty, _) => {
let metadata = p_ty.ptr_metadata_ty(bx.tcx, |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 { require!(metadata.is_unit(), InvalidMonomorphization::CastWidePointer {
span, span,
@ -2202,7 +2201,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
match out_elem.kind() { match out_elem.kind() {
ty::RawPtr(p_ty, _) => { ty::RawPtr(p_ty, _) => {
let metadata = p_ty.ptr_metadata_ty(bx.tcx, |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 { require!(metadata.is_unit(), InvalidMonomorphization::CastWidePointer {
span, span,

View File

@ -3,7 +3,7 @@ use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_middle::bug; use rustc_middle::bug;
use rustc_middle::mir::mono::{Linkage, Visibility}; 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_middle::ty::{self, Instance, TypeVisitableExt};
use rustc_session::config::CrateType; use rustc_session::config::CrateType;
use rustc_target::spec::RelocModel; 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!() }; 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 // 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. // out the llvm type from the actual evaluated initializer.
let ty = if nested { let ty =
self.tcx.types.unit if nested { self.tcx.types.unit } else { instance.ty(self.tcx, self.typing_env()) };
} else {
instance.ty(self.tcx, ty::ParamEnv::reveal_all())
};
let llty = self.layout_of(ty).llvm_type(self); let llty = self.layout_of(ty).llvm_type(self);
let g = self.define_global(symbol_name, llty).unwrap_or_else(|| { 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 let (conv, args) = instance
.map(|i| { .map(|i| {
tcx.fn_abi_of_instance(ty::ParamEnv::reveal_all().and((i, ty::List::empty()))) tcx.fn_abi_of_instance(
.unwrap_or_else(|_| bug!("fn_abi_of_instance({i:?}) failed")) 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[..])) .map(|fnabi| (fnabi.conv, &fnabi.args[..]))
.unwrap_or((Conv::Rust, &[])); .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::BinOp;
use rustc_middle::mir::mono::{CodegenUnit, CodegenUnitNameBuilder, MonoItem}; use rustc_middle::mir::mono::{CodegenUnit, CodegenUnitNameBuilder, MonoItem};
use rustc_middle::query::Providers; 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_middle::ty::{self, Instance, Ty, TyCtxt, TypingMode};
use rustc_session::Session; use rustc_session::Session;
use rustc_session::config::{self, CrateType, EntryFnType, OptLevel, OutputType}; use rustc_session::config::{self, CrateType, EntryFnType, OptLevel, OutputType};
@ -165,7 +165,7 @@ fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
) -> Bx::Value { ) -> Bx::Value {
let cx = bx.cx(); let cx = bx.cx();
let (source, target) = 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()) { match (source.kind(), target.kind()) {
(&ty::Array(_, len), &ty::Slice(_)) => cx.const_usize( (&ty::Array(_, len), &ty::Slice(_)) => cx.const_usize(
len.try_to_target_usize(cx.tcx()).expect("expected monomorphic const in codegen"), 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 // late-bound regions, since late-bound
// regions must appear in the argument // regions must appear in the argument
// listing. // listing.
let main_ret_ty = cx.tcx().normalize_erasing_regions( let main_ret_ty = cx
ty::ParamEnv::reveal_all(), .tcx()
main_ret_ty.no_bound_vars().unwrap(), .normalize_erasing_regions(cx.typing_env(), main_ret_ty.no_bound_vars().unwrap());
);
let Some(llfn) = cx.declare_c_main(llfty) else { let Some(llfn) = cx.declare_c_main(llfty) else {
// FIXME: We should be smart and show a better diagnostic here. // 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_def_id = cx.tcx().require_lang_item(LangItem::Start, None);
let start_instance = ty::Instance::expect_resolve( let start_instance = ty::Instance::expect_resolve(
cx.tcx(), cx.tcx(),
ty::ParamEnv::reveal_all(), cx.typing_env(),
start_def_id, start_def_id,
cx.tcx().mk_args(&[main_ret_ty.into()]), cx.tcx().mk_args(&[main_ret_ty.into()]),
DUMMY_SP, DUMMY_SP,

View File

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

View File

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

View File

@ -1,6 +1,6 @@
use rustc_abi::BackendRepr; use rustc_abi::BackendRepr;
use rustc_middle::mir::interpret::ErrorHandled; 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::ty::{self, Ty};
use rustc_middle::{bug, mir, span_bug}; 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 // `MirUsedCollector` visited all required_consts before codegen began, so if we got here
// there can be no more constants that fail to evaluate. // there can be no more constants that fail to evaluate.
self.monomorphize(constant.const_) 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") .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:#?}"), other => span_bug!(constant.span, "{other:#?}"),
}; };
let uv = self.monomorphize(uv); 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 /// 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, llresult: Bx::Value,
span: Span, span: Span,
) -> Result<(), ty::Instance<'tcx>> { ) -> 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 { let ty::FnDef(def_id, fn_args) = *callee_ty.kind() else {
bug!("expected fn item type, found {}", callee_ty); bug!("expected fn item type, found {}", callee_ty);
}; };
let sig = callee_ty.fn_sig(bx.tcx()); 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 arg_tys = sig.inputs();
let ret_ty = sig.output(); let ret_ty = sig.output();
let name = bx.tcx().item_name(def_id); 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_index::bit_set::BitSet;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::mir::{UnwindTerminateReason, traversal}; 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::ty::{self, Instance, Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
use rustc_middle::{bug, mir, span_bug}; use rustc_middle::{bug, mir, span_bug};
use rustc_target::callconv::{FnAbi, PassMode}; 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); debug!("monomorphize: self.instance={:?}", self.instance);
self.instance.instantiate_mir_and_normalize_erasing_regions( self.instance.instantiate_mir_and_normalize_erasing_regions(
self.cx.tcx(), self.cx.tcx(),
ty::ParamEnv::reveal_all(), self.cx.typing_env(),
ty::EarlyBinder::bind(value), 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) => { ty::FnDef(def_id, args) => {
let instance = ty::Instance::resolve_for_fn_ptr( let instance = ty::Instance::resolve_for_fn_ptr(
bx.tcx(), bx.tcx(),
ty::ParamEnv::reveal_all(), bx.typing_env(),
def_id, def_id,
args, args,
) )
@ -709,7 +709,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
mir::NullOp::OffsetOf(fields) => { mir::NullOp::OffsetOf(fields) => {
let val = bx let val = bx
.tcx() .tcx()
.offset_of_subfield(bx.param_env(), layout, fields.iter()) .offset_of_subfield(bx.typing_env(), layout, fields.iter())
.bytes(); .bytes();
bx.cx().const_usize(val) 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) => { mir::Rvalue::ThreadLocalRef(def_id) => {
assert!(bx.cx().tcx().is_static(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 static_ = if !def_id.is_local() && bx.cx().tcx().needs_thread_local_shim(def_id)
{ {
let instance = ty::Instance { let instance = ty::Instance {

View File

@ -1,6 +1,6 @@
use rustc_abi::{AddressSpace, Float, Integer}; use rustc_abi::{AddressSpace, Float, Integer};
use rustc_middle::bug; 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_middle::ty::{self, Ty};
use rustc_target::callconv::{ArgAbi, CastTarget, FnAbi, Reg}; use rustc_target::callconv::{ArgAbi, CastTarget, FnAbi, Reg};
@ -41,7 +41,7 @@ pub trait BaseTypeCodegenMethods<'tcx>: BackendTypes {
} }
pub trait DerivedTypeCodegenMethods<'tcx>: pub trait DerivedTypeCodegenMethods<'tcx>:
BaseTypeCodegenMethods<'tcx> + MiscCodegenMethods<'tcx> + HasTyCtxt<'tcx> BaseTypeCodegenMethods<'tcx> + MiscCodegenMethods<'tcx> + HasTyCtxt<'tcx> + HasTypingEnv<'tcx>
{ {
fn type_int(&self) -> Self::Type { fn type_int(&self) -> Self::Type {
match &self.sess().target.c_int_width[..] { match &self.sess().target.c_int_width[..] {
@ -74,7 +74,7 @@ pub trait DerivedTypeCodegenMethods<'tcx>:
} }
fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool { 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 { 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 { fn type_has_metadata(&self, ty: Ty<'tcx>) -> bool {
let param_env = ty::ParamEnv::reveal_all(); if ty.is_sized(self.tcx(), self.param_env()) {
if ty.is_sized(self.tcx(), param_env) {
return false; 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() { match tail.kind() {
ty::Foreign(..) => false, ty::Foreign(..) => false,
ty::Str | ty::Slice(..) | ty::Dynamic(..) => true, ty::Str | ty::Slice(..) | ty::Dynamic(..) => true,
@ -101,7 +100,10 @@ pub trait DerivedTypeCodegenMethods<'tcx>:
} }
impl<'tcx, T> DerivedTypeCodegenMethods<'tcx> for T where 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; 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 ocx = ObligationCtxt::new_with_diagnostics(&infcx);
let body_id = self.body.source.def_id().expect_local(); let body_id = self.body.source.def_id().expect_local();
@ -398,11 +398,8 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
ty::BoundConstness::Const ty::BoundConstness::Const
} }
}; };
let const_conditions = ocx.normalize( let const_conditions =
&ObligationCause::misc(call_span, body_id), ocx.normalize(&ObligationCause::misc(call_span, body_id), param_env, const_conditions);
self.param_env,
const_conditions,
);
ocx.register_obligations(const_conditions.into_iter().map(|(trait_ref, span)| { ocx.register_obligations(const_conditions.into_iter().map(|(trait_ref, span)| {
Obligation::new( Obligation::new(
tcx, tcx,
@ -411,7 +408,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
body_id, body_id,
ObligationCauseCode::WhereClause(callee, span), ObligationCauseCode::WhereClause(callee, span),
), ),
self.param_env, param_env,
trait_ref.to_host_effect_clause(tcx, host_polarity), trait_ref.to_host_effect_clause(tcx, host_polarity),
) )
})); }));

View File

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

View File

@ -120,7 +120,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
#[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::untranslatable_diagnostic)]
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, _: Span) -> Diag<'tcx> { fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, _: Span) -> Diag<'tcx> {
let FnCallNonConst { callee, args, span, call_source } = *self; 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 caller = ccx.def_id();
let diag_trait = |err, self_ty: Ty<'_>, trait_id| { let diag_trait = |err, self_ty: Ty<'_>, trait_id| {
@ -146,13 +146,11 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
} }
} }
ty::Adt(..) => { ty::Adt(..) => {
let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env);
let obligation = let obligation =
Obligation::new(tcx, ObligationCause::dummy(), param_env, trait_ref); 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 mut selcx = SelectionContext::new(&infcx);
let implsrc = selcx.select(&obligation); let implsrc = selcx.select(&obligation);
if let Ok(Some(ImplSource::UserDefined(data))) = implsrc { if let Ok(Some(ImplSource::UserDefined(data))) = implsrc {
// FIXME(const_trait_impl) revisit this // FIXME(const_trait_impl) revisit this
if !tcx.is_const_trait_impl(data.impl_def_id) { if !tcx.is_const_trait_impl(data.impl_def_id) {
@ -166,7 +164,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
}; };
let call_kind = 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); 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 /// This is separate from the rest of the const checking logic because it must run after drop
/// elaboration. /// elaboration.
pub fn check_live_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mir::Body<'tcx>) { pub fn check_live_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mir::Body<'tcx>) {
let def_id = body.source.def_id().expect_local(); let ccx = ConstCx::new(tcx, body);
let const_kind = tcx.hir().body_const_context(def_id); if ccx.const_kind.is_none() {
if const_kind.is_none() {
return; 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; return;
} }
let ccx = ConstCx { body, tcx, const_kind, param_env: tcx.param_env(def_id) };
if !checking_enabled(&ccx) { if !checking_enabled(&ccx) {
return; 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 // 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. // 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)); 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( let obligation = Obligation::new(
cx.tcx, cx.tcx,
ObligationCause::dummy_with_span(cx.body.span), ObligationCause::dummy_with_span(cx.body.span),
cx.param_env, param_env,
ty::TraitRef::new(cx.tcx, freeze_def_id, [ty::GenericArg::from(ty)]), 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); ocx.register_obligation(obligation);
let errors = ocx.select_all_or_error(); let errors = ocx.select_all_or_error();
!errors.is_empty() !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 { 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>( 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 /// [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 { 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 let pointee_ty = imm.layout.ty.builtin_deref(false).unwrap(); // `false` = no raw ptrs
debug_assert!( debug_assert!(
matches!( 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(..), ty::Str | ty::Slice(..),
), ),
"`ConstValue::Slice` is for slice-tailed types only, but got {}", "`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 // 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. // types that are not specified in the opaque type.
assert_eq!(key.param_env.reveal(), Reveal::All); 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. // 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. // 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 { 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 { let ty::FnDef(_, args) = ty.kind() else {
bug!("intrinsic with type {:?}", ty); 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) { } else if self.tcx.is_lang_item(def_id, LangItem::PanicFmt) {
// For panic_fmt, call const_panic_fmt instead. // For panic_fmt, call const_panic_fmt instead.
let const_def_id = self.tcx.require_lang_item(LangItem::ConstPanicFmt, None); 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( let new_instance = ty::Instance::expect_resolve(
*self.tcx, *self.tcx,
ty::ParamEnv::reveal_all(), ty::TypingEnv::fully_monomorphized(),
const_def_id, const_def_id,
instance.args, instance.args,
self.cur_span(), self.cur_span(),

View File

@ -2,6 +2,7 @@ use rustc_abi::{BackendRepr, VariantIdx};
use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId}; use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId};
use rustc_middle::ty::layout::{LayoutCx, LayoutOf, TyAndLayout}; 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::ty::{self, ScalarInt, Ty, TyCtxt};
use rustc_middle::{bug, mir}; use rustc_middle::{bug, mir};
use rustc_span::DUMMY_SP; 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 // the `ValTree` and using `place_projection` and `place_field` to
// create inner `MPlace`s which are filled recursively. // create inner `MPlace`s which are filled recursively.
// FIXME Does this need an example? // FIXME Does this need an example?
let (param_env, ty) = param_env_ty.into_parts(); 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() { match *ty.kind() {
ty::FnDef(..) => { ty::FnDef(..) => {
@ -302,11 +304,12 @@ pub fn valtree_to_const_value<'tcx>(
let mut ecx = let mut ecx =
mk_eval_cx_to_read_const_val(tcx, DUMMY_SP, param_env, CanAccessMutGlobal::No); 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 = 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) op_to_const(&ecx, &imm.into(), /* for diagnostics */ false)
} }
ty::Tuple(_) | ty::Array(_, _) | ty::Adt(..) => { 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() { if layout.is_zst() {
// Fast path to avoid some allocations. // Fast path to avoid some allocations.
return mir::ConstValue::ZeroSized; return mir::ConstValue::ZeroSized;
@ -319,7 +322,7 @@ pub fn valtree_to_const_value<'tcx>(
let branches = valtree.unwrap_branch(); let branches = valtree.unwrap_branch();
// Find the non-ZST field. (There can be aligned ZST!) // Find the non-ZST field. (There can be aligned ZST!)
for (i, &inner_valtree) in branches.iter().enumerate() { 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() { if !field.is_zst() {
return valtree_to_const_value(tcx, param_env.and(field.ty), inner_valtree); 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 // 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 // to fields, which can yield non-normalized types. So we need to provide a
// normalization function. // 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) ty.ptr_metadata_ty(*self.tcx, normalize)
}; };
return interp_ok(meta_ty(caller) == meta_ty(callee)); 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. // 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) = let (trait_, dyn_ty, adjusted_recv) =
receiver_place.layout.ty.kind() if let ty::Dynamic(data, _, ty::DynStar) = receiver_place.layout.ty.kind() {
{ let recv = self.unpack_dyn_star(&receiver_place, data)?;
let recv = self.unpack_dyn_star(&receiver_place, data)?;
(data.principal(), recv.layout.ty, recv.ptr()) (data.principal(), recv.layout.ty, recv.ptr())
} else { } else {
// Doesn't have to be a `dyn Trait`, but the unsized tail must be `dyn Trait`. // 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`.) // (For that reason we also cannot use `unpack_dyn_trait`.)
let receiver_tail = let receiver_tail = self
self.tcx.struct_tail_for_codegen(receiver_place.layout.ty, self.param_env); .tcx
let ty::Dynamic(receiver_trait, _, ty::Dyn) = receiver_tail.kind() else { .struct_tail_for_codegen(receiver_place.layout.ty, self.typing_env());
span_bug!( let ty::Dynamic(receiver_trait, _, ty::Dyn) = receiver_tail.kind() else {
self.cur_span(), span_bug!(
"dynamic call on non-`dyn` type {}", self.cur_span(),
receiver_tail "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 // Now determine the actual method to call. Usually we use the easy way of just
// looking up the method at index `idx`. // 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( let concrete_method = Instance::expect_resolve_for_vtable(
tcx, tcx,
self.param_env, self.typing_env(),
def_id, def_id,
instance.args.rebase_onto(tcx, trait_def_id, concrete_trait_ref.args), instance.args.rebase_onto(tcx, trait_def_id, concrete_trait_ref.args),
self.cur_span(), self.cur_span(),

View File

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

View File

@ -10,9 +10,7 @@ use rustc_middle::query::TyCtxtAt;
use rustc_middle::ty::layout::{ use rustc_middle::ty::layout::{
self, FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOfHelpers, TyAndLayout, self, FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOfHelpers, TyAndLayout,
}; };
use rustc_middle::ty::{ use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypeFoldable, TypingEnv, Variance};
self, GenericArgsRef, ParamEnv, Ty, TyCtxt, TypeFoldable, TypingMode, Variance,
};
use rustc_middle::{mir, span_bug}; use rustc_middle::{mir, span_bug};
use rustc_session::Limit; use rustc_session::Limit;
use rustc_span::Span; 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 where
M: Machine<'tcx>, M: Machine<'tcx>,
{ {
fn param_env(&self) -> ty::ParamEnv<'tcx> { fn typing_env(&self) -> ty::TypingEnv<'tcx> {
self.param_env 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. /// This test should be symmetric, as it is primarily about layout compatibility.
pub(super) fn mir_assign_valid_types<'tcx>( pub(super) fn mir_assign_valid_types<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
typing_mode: TypingMode<'tcx>, typing_env: TypingEnv<'tcx>,
param_env: ParamEnv<'tcx>,
src: TyAndLayout<'tcx>, src: TyAndLayout<'tcx>,
dest: TyAndLayout<'tcx>, dest: TyAndLayout<'tcx>,
) -> bool { ) -> bool {
@ -125,7 +122,7 @@ pub(super) fn mir_assign_valid_types<'tcx>(
// all normal lifetimes are erased, higher-ranked types with their // all normal lifetimes are erased, higher-ranked types with their
// late-bound lifetimes are still around and can lead to type // late-bound lifetimes are still around and can lead to type
// differences. // 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 // Make sure the layout is equal, too -- just to be safe. Miri really
// needs layout equality. For performance reason we skip this check when // needs layout equality. For performance reason we skip this check when
// the types are equal. Equal types *can* have different layouts 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))] #[cfg_attr(not(debug_assertions), inline(always))]
pub(super) fn from_known_layout<'tcx>( pub(super) fn from_known_layout<'tcx>(
tcx: TyCtxtAt<'tcx>, tcx: TyCtxtAt<'tcx>,
typing_mode: TypingMode<'tcx>, typing_env: TypingEnv<'tcx>,
param_env: ParamEnv<'tcx>,
known_layout: Option<TyAndLayout<'tcx>>, known_layout: Option<TyAndLayout<'tcx>>,
compute: impl FnOnce() -> InterpResult<'tcx, TyAndLayout<'tcx>>, compute: impl FnOnce() -> InterpResult<'tcx, TyAndLayout<'tcx>>,
) -> InterpResult<'tcx, TyAndLayout<'tcx>> { ) -> InterpResult<'tcx, TyAndLayout<'tcx>> {
@ -155,13 +151,7 @@ pub(super) fn from_known_layout<'tcx>(
Some(known_layout) => { Some(known_layout) => {
if cfg!(debug_assertions) { if cfg!(debug_assertions) {
let check_layout = compute()?; let check_layout = compute()?;
if !mir_assign_valid_types( if !mir_assign_valid_types(tcx.tcx, typing_env, check_layout, known_layout) {
tcx.tcx,
typing_mode,
param_env,
check_layout,
known_layout,
) {
span_bug!( span_bug!(
tcx.span, tcx.span,
"expected type differs from actual type.\nexpected: {}\nactual: {}", "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); 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. /// Returns the span of the currently executed statement/terminator.
@ -304,13 +296,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
.instance .instance
.try_instantiate_mir_and_normalize_erasing_regions( .try_instantiate_mir_and_normalize_erasing_regions(
*self.tcx, *self.tcx,
self.param_env, self.typing_env(),
ty::EarlyBinder::bind(value), ty::EarlyBinder::bind(value),
) )
.map_err(|_| ErrorHandled::TooGeneric(self.cur_span())) .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( pub(super) fn resolve(
&self, &self,
def: DefId, def: DefId,
@ -319,7 +311,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
trace!("resolve: {:?}, {:#?}", def, args); trace!("resolve: {:?}, {:#?}", def, args);
trace!("param_env: {:#?}", self.param_env); trace!("param_env: {:#?}", self.param_env);
trace!("args: {:#?}", args); 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(Some(instance)) => interp_ok(instance),
Ok(None) => throw_inval!(TooGeneric), 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. /// equality checks.
#[instrument(level = "trace", skip(self), ret)] #[instrument(level = "trace", skip(self), ret)]
pub(super) fn eq_in_param_env<T>(&self, a: T, b: T) -> bool 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; return true;
} }
// Slow path: spin up an inference context to check if these traits are sufficiently equal. // 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 ocx = ObligationCtxt::new(&infcx);
let cause = ObligationCause::dummy_with_span(self.cur_span()); let cause = ObligationCause::dummy_with_span(self.cur_span());
// equate the two trait refs after normalization // equate the two trait refs after normalization
let a = ocx.normalize(&cause, self.param_env, a); let a = ocx.normalize(&cause, param_env, a);
let b = ocx.normalize(&cause, self.param_env, b); 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); trace!(?terr);
return false; 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 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 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 } mir::ConstAlloc { alloc_id, ty }
} else { } else {
self.ctfe_query(|tcx| tcx.eval_to_allocation_raw(self.param_env.and(gid)))? 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>>, layout: Option<TyAndLayout<'tcx>>,
) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> { ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
M::eval_mir_constant(self, *val, span, layout, |ecx, val, span, layout| { 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 { if M::ALL_CONSTS_ARE_PRECHECKED {
match err { match err {
ErrorHandled::TooGeneric(..) => {}, ErrorHandled::TooGeneric(..) => {},

View File

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

View File

@ -859,7 +859,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
// # Global allocations // # Global allocations
if let Some(global_alloc) = self.tcx.try_get_global_alloc(id) { 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 mutbl = global_alloc.mutability(*self.tcx, self.param_env);
let kind = match global_alloc { let kind = match global_alloc {
GlobalAlloc::Static { .. } | GlobalAlloc::Memory { .. } => AllocKind::LiveData, 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_abi::{BackendRepr, HasDataLayout, Size};
use rustc_hir::def::Namespace; use rustc_hir::def::Namespace;
use rustc_middle::mir::interpret::ScalarSizeMismatch; 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::print::{FmtPrinter, PrettyPrinter};
use rustc_middle::ty::{ConstInt, ScalarInt, Ty, TyCtxt}; use rustc_middle::ty::{ConstInt, ScalarInt, Ty, TyCtxt};
use rustc_middle::{bug, mir, span_bug, ty}; use rustc_middle::{bug, mir, span_bug, ty};
@ -297,21 +297,25 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
#[inline] #[inline]
pub fn from_bool(b: bool, tcx: TyCtxt<'tcx>) -> Self { 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) Self::from_scalar(Scalar::from_bool(b), layout)
} }
#[inline] #[inline]
pub fn from_ordering(c: std::cmp::Ordering, tcx: TyCtxt<'tcx>) -> Self { pub fn from_ordering(c: std::cmp::Ordering, tcx: TyCtxt<'tcx>) -> Self {
let ty = tcx.ty_ordering_enum(None); 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) Self::from_scalar(Scalar::from_i8(c as i8), layout)
} }
pub fn from_pair(a: Self, b: Self, tcx: TyCtxt<'tcx>) -> Self { pub fn from_pair(a: Self, b: Self, tcx: TyCtxt<'tcx>) -> Self {
let layout = tcx let layout = tcx
.layout_of( .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(); .unwrap();
Self::from_scalar_pair(a.to_scalar(), b.to_scalar(), layout) Self::from_scalar_pair(a.to_scalar(), b.to_scalar(), layout)
@ -341,7 +345,7 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
#[inline] #[inline]
#[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980) #[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 layout = self.layout;
let (val0, val1) = self.to_scalar_pair(); let (val0, val1) = self.to_scalar_pair();
( (
@ -773,8 +777,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
)?; )?;
if !mir_assign_valid_types( if !mir_assign_valid_types(
*self.tcx, *self.tcx,
self.typing_mode(), self.typing_env(),
self.param_env,
self.layout_of(normalized_place_ty)?, self.layout_of(normalized_place_ty)?,
op.layout, op.layout,
) { ) {
@ -833,9 +836,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
}) })
}; };
let layout = let layout =
from_known_layout(self.tcx, self.typing_mode(), self.param_env, layout, || { from_known_layout(self.tcx, self.typing_env(), layout, || self.layout_of(ty).into())?;
self.layout_of(ty).into()
})?;
let imm = match val_val { let imm = match val_val {
mir::ConstValue::Indirect { alloc_id, offset } => { mir::ConstValue::Indirect { alloc_id, offset } => {
// This is const data, no mutation allowed. // This is const data, no mutation allowed.

View File

@ -533,7 +533,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
} }
OffsetOf(fields) => { OffsetOf(fields) => {
let val = 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()) ImmTy::from_uint(val, usize_layout())
} }
UbChecks => ImmTy::from_bool(M::ub_checks(self)?, *self.tcx), UbChecks => ImmTy::from_bool(M::ub_checks(self)?, *self.tcx),

View File

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

View File

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

View File

@ -418,7 +418,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
.collect::<InterpResult<'tcx, Vec<_>>>()?; .collect::<InterpResult<'tcx, Vec<_>>>()?;
let fn_sig_binder = func.layout.ty.fn_sig(*self.tcx); 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 = &args[fn_sig.inputs().len()..];
let extra_args = let extra_args =
self.tcx.mk_type_list_from_iter(extra_args.iter().map(|arg| arg.layout().ty)); 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>, meta: MemPlaceMeta<M::Provenance>,
pointee: TyAndLayout<'tcx>, pointee: TyAndLayout<'tcx>,
) -> InterpResult<'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() { match tail.kind() {
ty::Dynamic(data, _, ty::Dyn) => { ty::Dynamic(data, _, ty::Dyn) => {
let vtable = meta.unwrap_meta().to_pointer(self.ecx)?; 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 }); throw_validation_failure!(self.path, DanglingPtrUseAfterFree { ptr_kind });
}; };
let (size, _align) = 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 { if let GlobalAlloc::Static(did) = global_alloc {
let DefKind::Static { nested, .. } = self.ecx.tcx.def_kind(did) else { 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> { ) -> Cow<'e, RangeSet> {
assert!(layout.ty.is_union()); assert!(layout.ty.is_union());
assert!(layout.is_sized(), "there are no unsized unions"); 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, || { return M::cached_union_data_range(ecx, layout.ty, || {
let mut out = RangeSet(Vec::new()); let mut out = RangeSet(Vec::new());
union_data_range_uncached(&layout_cx, layout, Size::ZERO, &mut out); 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 = providers.hooks.try_destructure_mir_constant_for_user_output =
const_eval::try_destructure_mir_constant_for_user_output; const_eval::try_destructure_mir_constant_for_user_output;
providers.valtree_to_const_val = |tcx, (ty, valtree)| { 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)| { providers.check_validity_requirement = |tcx, (init_kind, param_env_and_ty)| {
util::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>( pub fn is_disaligned<'tcx, L>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
local_decls: &L, local_decls: &L,
param_env: ty::ParamEnv<'tcx>, typing_env: ty::TypingEnv<'tcx>,
place: Place<'tcx>, place: Place<'tcx>,
) -> bool ) -> bool
where where
@ -22,8 +22,8 @@ where
}; };
let ty = place.ty(local_decls, tcx).ty; let ty = place.ty(local_decls, tcx).ty;
let unsized_tail = || tcx.struct_tail_for_codegen(ty, param_env); let unsized_tail = || tcx.struct_tail_for_codegen(ty, typing_env);
match tcx.layout_of(param_env.and(ty)) { match tcx.layout_of(typing_env.as_query_input(ty)) {
Ok(layout) Ok(layout)
if layout.align.abi <= pack if layout.align.abi <= pack
&& (layout.is_sized() && (layout.is_sized()

View File

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

View File

@ -5,18 +5,17 @@
use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::traits::ObligationCause; 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; use rustc_trait_selection::traits::ObligationCtxt;
/// Returns whether `src` is a subtype of `dest`, i.e. `src <: dest`. /// Returns whether `src` is a subtype of `dest`, i.e. `src <: dest`.
pub fn sub_types<'tcx>( pub fn sub_types<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
typing_mode: TypingMode<'tcx>, typing_env: TypingEnv<'tcx>,
param_env: ParamEnv<'tcx>,
src: Ty<'tcx>, src: Ty<'tcx>,
dest: Ty<'tcx>, dest: Ty<'tcx>,
) -> bool { ) -> 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`. /// 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. /// because we want to check for type equality.
pub fn relate_types<'tcx>( pub fn relate_types<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
typing_mode: TypingMode<'tcx>, typing_env: TypingEnv<'tcx>,
param_env: ParamEnv<'tcx>,
variance: Variance, variance: Variance,
src: Ty<'tcx>, src: Ty<'tcx>,
dest: Ty<'tcx>, dest: Ty<'tcx>,
@ -36,8 +34,7 @@ pub fn relate_types<'tcx>(
return true; return true;
} }
let mut builder = tcx.infer_ctxt().ignoring_regions(); let (infcx, param_env) = tcx.infer_ctxt().ignoring_regions().build_with_typing_env(typing_env);
let infcx = builder.build(typing_mode);
let ocx = ObligationCtxt::new(&infcx); let ocx = ObligationCtxt::new(&infcx);
let cause = ObligationCause::dummy(); let cause = ObligationCause::dummy();
let src = ocx.normalize(&cause, param_env, src); 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::layout::{LayoutError, MAX_SIMD_LANES};
use rustc_middle::ty::util::{Discr, InspectCoroutineFields, IntTypeExt}; use rustc_middle::ty::util::{Discr, InspectCoroutineFields, IntTypeExt};
use rustc_middle::ty::{ use rustc_middle::ty::{
AdtDef, GenericArgKind, ParamEnv, RegionKind, TypeSuperVisitable, TypeVisitable, AdtDef, GenericArgKind, RegionKind, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
TypeVisitableExt,
}; };
use rustc_session::lint::builtin::UNINHABITED_STATIC; use rustc_session::lint::builtin::UNINHABITED_STATIC;
use rustc_trait_selection::error_reporting::InferCtxtErrorExt; 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 { 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 { else {
tcx.dcx().span_delayed_bug(span, "could not normalize field type"); tcx.dcx().span_delayed_bug(span, "could not normalize field type");
continue; 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) { 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. // We are currently checking the type this field came from, so it must be local.
Some(Node::Field(field)) => (field.span, field.ty.span), 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: (), note: (),
}); });
return false; 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. // This should never happen. But we can get here e.g. in case of name resolution errors.
tcx.dcx() tcx.dcx()
.span_delayed_bug(span, "we should never accept maybe-dropping union fields"); .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. // reason to allow any statics to be uninhabited.
let ty = tcx.type_of(def_id).instantiate_identity(); let ty = tcx.type_of(def_id).instantiate_identity();
let span = tcx.def_span(def_id); 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, Ok(l) => l,
// Foreign statics that overflow their allowed size should emit an error // Foreign statics that overflow their allowed size should emit an error
Err(LayoutError::SizeOverflow(_)) 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. // And also look for cycle errors in the layout of coroutines.
if let Err(&LayoutError::Cycle(guar)) = 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); 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. // "known" respecting #[non_exhaustive] attributes.
let field_infos = adt.all_fields().map(|field| { let field_infos = adt.all_fields().map(|field| {
let ty = field.ty(tcx, GenericArgs::identity_for_item(tcx, field.did)); let ty = field.ty(tcx, GenericArgs::identity_for_item(tcx, field.did));
let param_env = tcx.param_env(field.did); let typing_env = ty::TypingEnv::non_body_analysis(tcx, field.did);
let layout = tcx.layout_of(param_env.and(ty)); 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 // 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 span = tcx.hir().span_if_local(field.did).unwrap();
let trivial = layout.is_ok_and(|layout| layout.is_1zst()); 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.type_of(variant.tail().did).instantiate_identity();
let ty = tcx.erase_regions(ty); let ty = tcx.erase_regions(ty);
assert!(!ty.has_infer()); assert!(!ty.has_infer());
ty.needs_drop(tcx, tcx.param_env(item.owner_id)) ty.needs_drop(tcx, ty::TypingEnv::non_body_analysis(tcx, item.owner_id.def_id))
} }
}; };
// All fields (except for possibly the last) should be sized. // All fields (except for possibly the last) should be sized.
@ -1281,7 +1281,8 @@ fn check_item_type(
UnsizedHandling::Forbid => true, UnsizedHandling::Forbid => true,
UnsizedHandling::Allow => false, UnsizedHandling::Allow => false,
UnsizedHandling::AllowIfForeignTail => { 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(_)) !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_a = field.ty(tcx, args_a);
let ty_b = field.ty(tcx, args_b); 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() { if layout.is_1zst() {
// ignore 1-ZST fields // ignore 1-ZST fields
return false; 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_hir::{self as hir, HirId};
use rustc_middle::bug; use rustc_middle::bug;
use rustc_middle::ty::layout::LayoutError; use rustc_middle::ty::layout::LayoutError;
use rustc_middle::ty::{self, ParamEnv, TyCtxt}; use rustc_middle::ty::{self, TyCtxt};
use crate::errors; use crate::errors;
@ -130,7 +130,7 @@ fn is_valid_cmse_inputs<'tcx>(
let fn_sig = tcx.instantiate_bound_regions_with_erased(fn_sig); let fn_sig = tcx.instantiate_bound_regions_with_erased(fn_sig);
for (index, ty) in fn_sig.inputs().iter().enumerate() { 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 align = layout.layout.align().abi.bytes();
let size = layout.layout.size().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 // 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 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 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(); let size = layout.layout.size().bytes();
if size <= 4 { if size <= 4 {
@ -182,7 +184,7 @@ fn is_valid_cmse_output<'tcx>(
for variant_def in adt_def.variants() { for variant_def in adt_def.variants() {
for field_def in variant_def.fields.iter() { for field_def in variant_def.fields.iter() {
let ty = field_def.ty(tcx, args); 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() { if !layout.layout.is_1zst() {
ret_ty = ty; ret_ty = ty;

View File

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

View File

@ -46,7 +46,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let span = tcx.hir().span(hir_id); let span = tcx.hir().span(hir_id);
let normalize = |ty| { let normalize = |ty| {
let ty = self.resolve_vars_if_possible(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 from = normalize(from);
let to = normalize(to); let to = normalize(to);
@ -62,7 +62,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
return; 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_from = skel(from);
let sk_to = skel(to); let sk_to = skel(to);
trace!(?sk_from, ?sk_to); trace!(?sk_from, ?sk_to);

View File

@ -1257,7 +1257,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
) -> Option<FxIndexSet<UpvarMigrationInfo>> { ) -> Option<FxIndexSet<UpvarMigrationInfo>> {
let ty = self.resolve_vars_if_possible(self.node_ty(var_hir_id)); 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"); debug!("does not have significant drop");
return None; return None;
} }
@ -1535,8 +1539,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
base_path_ty: Ty<'tcx>, base_path_ty: Ty<'tcx>,
captured_by_move_projs: Vec<&[Projection<'tcx>]>, captured_by_move_projs: Vec<&[Projection<'tcx>]>,
) -> bool { ) -> bool {
let needs_drop = // FIXME(#132279): Using `non_body_analysis` here feels wrong.
|ty: Ty<'tcx>| ty.has_significant_drop(self.tcx, self.tcx.param_env(closure_def_id)); 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 is_drop_defined_for_ty = |ty: Ty<'tcx>| {
let drop_trait = self.tcx.require_lang_item(hir::LangItem::Drop, Some(closure_span)); 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> { 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::visit::TypeVisitableExt;
use rustc_middle::ty::{ use rustc_middle::ty::{
self, ConstVid, FloatVid, GenericArg, GenericArgKind, GenericArgs, GenericArgsRef, 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::Span;
use rustc_span::symbol::Symbol; use rustc_span::symbol::Symbol;
@ -565,6 +566,13 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
(infcx, value, args) (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> { pub fn build(&mut self, typing_mode: TypingMode<'tcx>) -> InferCtxt<'tcx> {
let InferCtxtBuilder { tcx, considering_regions, skip_leak_check, next_trait_solver } = let InferCtxtBuilder { tcx, considering_regions, skip_leak_check, next_trait_solver } =
*self; *self;
@ -1278,6 +1286,42 @@ impl<'tcx> InferCtxt<'tcx> {
u 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 /// The returned function is used in a fast path. If it returns `true` the variable is
/// unchanged, `false` indicates that the status is unknown. /// unchanged, `false` indicates that the status is unknown.
#[inline] #[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). // 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, _) = if let BackendRepr::Scalar(scalar) | BackendRepr::ScalarPair(scalar, _) =
&layout.backend_repr &layout.backend_repr
{ {
@ -2521,7 +2521,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
ty: Ty<'tcx>, ty: Ty<'tcx>,
init: InitKind, init: InitKind,
) -> Option<InitError> { ) -> 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::*; use rustc_type_ir::TyKind::*;
match ty.kind() { match ty.kind() {
@ -2568,7 +2568,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
let definitely_inhabited = match variant let definitely_inhabited = match variant
.inhabited_predicate(cx.tcx, *adt_def) .inhabited_predicate(cx.tcx, *adt_def)
.instantiate(cx.tcx, args) .instantiate(cx.tcx, args)
.apply_any_module(cx.tcx, cx.param_env) .apply_any_module(cx.tcx, cx.typing_env())
{ {
// Entirely skip uninhabited variants. // Entirely skip uninhabited variants.
Some(false) => return None, Some(false) => return None,

View File

@ -19,7 +19,7 @@ use rustc_middle::bug;
use rustc_middle::middle::privacy::EffectiveVisibilities; use rustc_middle::middle::privacy::EffectiveVisibilities;
use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout}; 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::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::{ use rustc_session::lint::{
BuiltinLintDiag, FutureIncompatibleInfo, Level, Lint, LintBuffer, LintExpectationId, LintId, BuiltinLintDiag, FutureIncompatibleInfo, Level, Lint, LintBuffer, LintExpectationId, LintId,
}; };
@ -708,6 +708,10 @@ impl<'tcx> LateContext<'tcx> {
TypingMode::non_body_analysis() 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, /// Gets the type-checking results for the current body,
/// or `None` if outside a body. /// or `None` if outside a body.
pub fn maybe_typeck_results(&self) -> Option<&'tcx ty::TypeckResults<'tcx>> { 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) .find_by_name_and_kind(tcx, Ident::from_str(name), ty::AssocKind::Type, trait_id)
.and_then(|assoc| { .and_then(|assoc| {
let proj = Ty::new_projection(tcx, assoc.def_id, [self_ty]); 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] #[inline]
fn param_env(&self) -> ty::ParamEnv<'tcx> { fn typing_env(&self) -> ty::TypingEnv<'tcx> {
self.param_env self.typing_env()
} }
} }

View File

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

View File

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

View File

@ -368,7 +368,7 @@ impl<'tcx, 'a> Visitor<'tcx> for FindSignificantDropper<'tcx, 'a> {
.cx .cx
.typeck_results() .typeck_results()
.expr_ty(expr) .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); return ControlFlow::Break(expr.span);
} }

View File

@ -103,7 +103,8 @@ declare_lint_pass!(QueryStability => [POTENTIAL_QUERY_INSTABILITY, UNTRACKED_QUE
impl LateLintPass<'_> for QueryStability { impl LateLintPass<'_> for QueryStability {
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
let Some((span, def_id, args)) = typeck_results_of_method_fn(cx, expr) else { return }; 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(); let def_id = instance.def_id();
if cx.tcx.has_attr(def_id, sym::rustc_lint_query_instability) { if cx.tcx.has_attr(def_id, sym::rustc_lint_query_instability) {
cx.emit_span_lint(POTENTIAL_QUERY_INSTABILITY, span, QueryInstability { cx.emit_span_lint(POTENTIAL_QUERY_INSTABILITY, span, QueryInstability {
@ -544,7 +545,7 @@ impl Diagnostics {
) { ) {
// Is the callee marked with `#[rustc_lint_diagnostics]`? // Is the callee marked with `#[rustc_lint_diagnostics]`?
let Some(inst) = 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 { else {
return; 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 // If the type has a trivial Drop implementation, then it doesn't
// matter that we drop the value immediately. // 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; return;
} }
// Lint for patterns like `mutex.lock()`, which returns `Result<MutexGuard, _>` as well. // 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), 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 let suggest_display = is_str
|| cx.tcx.get_diagnostic_item(sym::Display).is_some_and(|t| { || cx
infcx.type_implements_trait(t, [ty], cx.param_env).may_apply() .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 let suggest_debug = !suggest_display
&& cx.tcx.get_diagnostic_item(sym::Debug).is_some_and(|t| { && cx
infcx.type_implements_trait(t, [ty], cx.param_env).may_apply() .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; 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 let args = cx
.tcx .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. // 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; return;
}; };
// (Re)check that it implements the noop diagnostic. // (Re)check that it implements the noop diagnostic.

View File

@ -103,7 +103,7 @@ impl TailExprDropOrder {
if matches!(fn_kind, hir::intravisit::FnKind::Closure) { if matches!(fn_kind, hir::intravisit::FnKind::Closure) {
for &capture in cx.tcx.closure_captures(def_id) { for &capture in cx.tcx.closure_captures(def_id) {
if matches!(capture.info.capture_kind, ty::UpvarCapture::ByValue) 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); locals.push(capture.var_ident.span);
} }
@ -113,7 +113,7 @@ impl TailExprDropOrder {
if cx if cx
.typeck_results() .typeck_results()
.node_type(param.hir_id) .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); 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>) { fn visit_pat(&mut self, pat: &'tcx Pat<'tcx>) {
if let PatKind::Binding(_binding_mode, id, ident, pat) = pat.kind { if let PatKind::Binding(_binding_mode, id, ident, pat) = pat.kind {
let ty = self.cx.typeck_results().node_type(id); 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); self.locals.push(ident.span);
} }
if let Some(pat) = pat { if let Some(pat) = pat {
@ -234,7 +234,10 @@ impl<'a, 'tcx> LintTailExpr<'a, 'tcx> {
if Self::expr_eventually_point_into_local(expr) { if Self::expr_eventually_point_into_local(expr) {
return false; 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>, tcx: TyCtxt<'tcx>,
variant: &'a ty::VariantDef, variant: &'a ty::VariantDef,
) -> Option<&'a ty::FieldDef> { ) -> 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| { variant.fields.iter().find(|field| {
let field_ty = tcx.type_of(field.did).instantiate_identity(); 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 !is_1zst
}) })
} }
@ -624,11 +625,11 @@ pub(crate) fn transparent_newtype_field<'a, 'tcx>(
/// Is type known to be non-null? /// Is type known to be non-null?
fn ty_is_known_nonnull<'tcx>( fn ty_is_known_nonnull<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>, typing_env: ty::TypingEnv<'tcx>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
mode: CItemKind, mode: CItemKind,
) -> bool { ) -> 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() { match ty.kind() {
ty::FnPtr(..) => true, ty::FnPtr(..) => true,
@ -649,7 +650,7 @@ fn ty_is_known_nonnull<'tcx>(
def.variants() def.variants()
.iter() .iter()
.filter_map(|variant| transparent_newtype_field(tcx, variant)) .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, _ => false,
} }
@ -659,10 +660,10 @@ fn ty_is_known_nonnull<'tcx>(
/// If the type passed in was not scalar, returns None. /// If the type passed in was not scalar, returns None.
fn get_nullable_type<'tcx>( fn get_nullable_type<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>, typing_env: ty::TypingEnv<'tcx>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
) -> Option<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() { Some(match *ty.kind() {
ty::Adt(field_def, field_args) => { ty::Adt(field_def, field_args) => {
@ -679,7 +680,7 @@ fn get_nullable_type<'tcx>(
.expect("No non-zst fields in transparent type.") .expect("No non-zst fields in transparent type.")
.ty(tcx, field_args) .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::Int(ty) => Ty::new_int(tcx, ty),
ty::Uint(ty) => Ty::new_uint(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. /// - Does not have the `#[non_exhaustive]` attribute.
fn is_niche_optimization_candidate<'tcx>( fn is_niche_optimization_candidate<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>, typing_env: ty::TypingEnv<'tcx>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
) -> bool { ) -> 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; return false;
} }
@ -734,7 +735,7 @@ fn is_niche_optimization_candidate<'tcx>(
/// `core::ptr::NonNull`, and `#[repr(transparent)]` newtypes. /// `core::ptr::NonNull`, and `#[repr(transparent)]` newtypes.
pub(crate) fn repr_nullable_ptr<'tcx>( pub(crate) fn repr_nullable_ptr<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>, typing_env: ty::TypingEnv<'tcx>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
ckind: CItemKind, ckind: CItemKind,
) -> Option<Ty<'tcx>> { ) -> Option<Ty<'tcx>> {
@ -747,9 +748,9 @@ pub(crate) fn repr_nullable_ptr<'tcx>(
let ty1 = field1.ty(tcx, args); let ty1 = field1.ty(tcx, args);
let ty2 = field2.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 ty2
} else if is_niche_optimization_candidate(tcx, param_env, ty2) { } else if is_niche_optimization_candidate(tcx, typing_env, ty2) {
ty1 ty1
} else { } else {
return None; return None;
@ -760,20 +761,20 @@ pub(crate) fn repr_nullable_ptr<'tcx>(
_ => return None, _ => 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; return None;
} }
// At this point, the field's type is known to be nonnull and the parent enum is Option-like. // 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 // 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). // 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)?) { if !compute_size_skeleton(ty)?.same_size(compute_size_skeleton(field_ty)?) {
bug!("improper_ctypes: Option nonnull optimization not applied?"); bug!("improper_ctypes: Option nonnull optimization not applied?");
} }
// Return the nullable type this Option-like enum can be safely represented with. // 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() { if field_ty_layout.is_err() && !field_ty.has_non_region_param() {
bug!("should be able to compute the layout of non-polymorphic type"); 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 } WrappingRange { start: 0, end }
if end == field_ty_scalar.size(&tcx).unsigned_int_max() - 1 => 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, .. } => { 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 } => { WrappingRange { start, end } => {
unreachable!("Unhandled start and end range: ({}, {})", start, end) unreachable!("Unhandled start and end range: ({}, {})", start, end)
@ -825,7 +826,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
let field_ty = self let field_ty = self
.cx .cx
.tcx .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); .unwrap_or(field_ty);
self.check_type_for_ffi(acc, 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(), ()>` // Special-case types like `Option<extern fn()>` and `Result<extern fn(), ()>`
if let Some(ty) = 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); return self.check_type_for_ffi(acc, ty);
} }
@ -1196,7 +1197,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
if let Some(ty) = self if let Some(ty) = self
.cx .cx
.tcx .tcx
.try_normalize_erasing_regions(self.cx.param_env, ty) .try_normalize_erasing_regions(self.cx.typing_env(), ty)
.unwrap_or(ty) .unwrap_or(ty)
.visit_with(&mut ProhibitOpaqueTypes) .visit_with(&mut ProhibitOpaqueTypes)
.break_value() .break_value()
@ -1220,7 +1221,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
return; 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 // 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 // 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( || !ty.is_inhabited_from(
cx.tcx, cx.tcx,
cx.tcx.parent_module(expr.hir_id).to_def_id(), cx.tcx.parent_module(expr.hir_id).to_def_id(),
cx.param_env, cx.typing_env(),
) )
{ {
return Some(MustUsePath::Suppressed); 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::StmtKind::Semi(expr) = s.kind {
if let hir::ExprKind::Path(_) = expr.kind { if let hir::ExprKind::Path(_) = expr.kind {
let ty = cx.typeck_results().expr_ty(expr); 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) let sub = if let Ok(snippet) = cx.sess().source_map().span_to_snippet(expr.span)
{ {
PathStatementDropSub::Suggestion { span: s.span, snippet } 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_attr as attr;
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_middle::query::LocalCrate; 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::Session;
use rustc_session::config::CrateType; use rustc_session::config::CrateType;
use rustc_session::cstore::{ use rustc_session::cstore::{
@ -613,7 +613,7 @@ impl<'tcx> Collector<'tcx> {
.map(|ty| { .map(|ty| {
let layout = self let layout = self
.tcx .tcx
.layout_of(ParamEnvAnd { param_env: ParamEnv::empty(), value: ty }) .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty))
.expect("layout") .expect("layout")
.layout; .layout;
// In both stdcall and fastcall, we always round up the argument size to the // 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( pub fn try_to_bits_for_ty(
&self, &self,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>, typing_env: ty::TypingEnv<'tcx>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
) -> Option<u128> { ) -> 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) self.try_to_bits(size)
} }
@ -314,7 +315,7 @@ impl<'tcx> Const<'tcx> {
pub fn eval( pub fn eval(
self, self,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>, typing_env: ty::TypingEnv<'tcx>,
span: Span, span: Span,
) -> Result<ConstValue<'tcx>, ErrorHandled> { ) -> Result<ConstValue<'tcx>, ErrorHandled> {
match self { match self {
@ -333,7 +334,7 @@ impl<'tcx> Const<'tcx> {
} }
Const::Unevaluated(uneval, _) => { Const::Unevaluated(uneval, _) => {
// FIXME: We might want to have a `try_eval`-like function on `Unevaluated` // 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), Const::Val(val, _) => Ok(val),
} }
@ -343,7 +344,7 @@ impl<'tcx> Const<'tcx> {
pub fn try_eval_scalar( pub fn try_eval_scalar(
self, self,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>, typing_env: ty::TypingEnv<'tcx>,
) -> Option<Scalar> { ) -> Option<Scalar> {
if let Const::Ty(_, c) = self if let Const::Ty(_, c) = self
&& let ty::ConstKind::Value(ty, val) = c.kind() && let ty::ConstKind::Value(ty, val) = c.kind()
@ -354,7 +355,7 @@ impl<'tcx> Const<'tcx> {
// pointer here, which valtrees don't represent.) // pointer here, which valtrees don't represent.)
Some(val.unwrap_leaf().into()) Some(val.unwrap_leaf().into())
} else { } 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( pub fn try_eval_scalar_int(
self, self,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>, typing_env: ty::TypingEnv<'tcx>,
) -> Option<ScalarInt> { ) -> 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] #[inline]
pub fn try_eval_bits(&self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Option<u128> { pub fn try_eval_bits(
let int = self.try_eval_scalar_int(tcx, param_env)?; &self,
let size = tcx: TyCtxt<'tcx>,
tcx.layout_of(param_env.with_reveal_all_normalized(tcx).and(self.ty())).ok()?.size; 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)) Some(int.to_bits(size))
} }
/// Panics if the value cannot be evaluated or doesn't contain a valid integer of the given type. /// Panics if the value cannot be evaluated or doesn't contain a valid integer of the given type.
#[inline] #[inline]
pub fn eval_bits(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> u128 { pub fn eval_bits(self, tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> u128 {
self.try_eval_bits(tcx, param_env) self.try_eval_bits(tcx, typing_env)
.unwrap_or_else(|| bug!("expected bits of {:#?}, got {:#?}", self.ty(), self)) .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( pub fn try_eval_target_usize(
self, self,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>, typing_env: ty::TypingEnv<'tcx>,
) -> Option<u64> { ) -> 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] #[inline]
/// Panics if the value cannot be evaluated or doesn't contain a valid `usize`. /// 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 { pub fn eval_target_usize(self, tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> u64 {
self.try_eval_target_usize(tcx, param_env) self.try_eval_target_usize(tcx, typing_env)
.unwrap_or_else(|| bug!("expected usize, got {:#?}", self)) .unwrap_or_else(|| bug!("expected usize, got {:#?}", self))
} }
#[inline] #[inline]
pub fn try_eval_bool(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Option<bool> { pub fn try_eval_bool(self, tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> Option<bool> {
self.try_eval_scalar_int(tcx, param_env)?.try_into().ok() self.try_eval_scalar_int(tcx, typing_env)?.try_into().ok()
} }
#[inline] #[inline]
@ -411,17 +418,16 @@ impl<'tcx> Const<'tcx> {
pub fn from_bits( pub fn from_bits(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
bits: u128, bits: u128,
param_env_ty: ty::ParamEnvAnd<'tcx, Ty<'tcx>>, typing_env: ty::TypingEnv<'tcx>,
ty: Ty<'tcx>,
) -> Self { ) -> Self {
let size = tcx let size = tcx
.layout_of(param_env_ty) .layout_of(typing_env.as_query_input(ty))
.unwrap_or_else(|e| { .unwrap_or_else(|e| bug!("could not compute layout for {ty:?}: {e:?}"))
bug!("could not compute layout for {:?}: {:?}", param_env_ty.value, e)
})
.size; .size;
let cv = ConstValue::Scalar(Scalar::from_uint(bits, size)); let cv = ConstValue::Scalar(Scalar::from_uint(bits, size));
Self::Val(cv, param_env_ty.value) Self::Val(cv, ty)
} }
#[inline] #[inline]
@ -438,7 +444,8 @@ impl<'tcx> Const<'tcx> {
pub fn from_usize(tcx: TyCtxt<'tcx>, n: u64) -> Self { pub fn from_usize(tcx: TyCtxt<'tcx>, n: u64) -> Self {
let ty = tcx.types.usize; 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] #[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 { match self {
GlobalAlloc::Static(def_id) => { GlobalAlloc::Static(def_id) => {
let DefKind::Static { nested, .. } = tcx.def_kind(def_id) else { let DefKind::Static { nested, .. } = tcx.def_kind(def_id) else {
@ -374,7 +378,7 @@ impl<'tcx> GlobalAlloc<'tcx> {
.type_of(def_id) .type_of(def_id)
.no_bound_vars() .no_bound_vars()
.expect("statics should not have generic parameters"); .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()); assert!(layout.is_sized());
(layout.size, layout.align.abi) (layout.size, layout.align.abi)
} }

View File

@ -58,7 +58,7 @@ impl<'tcx> TyCtxt<'tcx> {
#[instrument(level = "debug", skip(self))] #[instrument(level = "debug", skip(self))]
pub fn const_eval_resolve( pub fn const_eval_resolve(
self, self,
param_env: ty::ParamEnv<'tcx>, typing_env: ty::TypingEnv<'tcx>,
ct: mir::UnevaluatedConst<'tcx>, ct: mir::UnevaluatedConst<'tcx>,
span: Span, span: Span,
) -> EvalToConstValueResult<'tcx> { ) -> EvalToConstValueResult<'tcx> {
@ -72,14 +72,11 @@ impl<'tcx> TyCtxt<'tcx> {
bug!("did not expect inference variables here"); bug!("did not expect inference variables here");
} }
match ty::Instance::try_resolve( // FIXME: maybe have a separate version for resolving mir::UnevaluatedConst?
self, param_env, match ty::Instance::try_resolve(self, typing_env, ct.def, ct.args) {
// FIXME: maybe have a separate version for resolving mir::UnevaluatedConst?
ct.def, ct.args,
) {
Ok(Some(instance)) => { Ok(Some(instance)) => {
let cid = GlobalId { instance, promoted: ct.promoted }; 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, // 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. // 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))] #[instrument(level = "debug", skip(self))]
pub fn const_eval_resolve_for_typeck( pub fn const_eval_resolve_for_typeck(
self, self,
param_env: ty::ParamEnv<'tcx>, typing_env: ty::TypingEnv<'tcx>,
ct: ty::UnevaluatedConst<'tcx>, ct: ty::UnevaluatedConst<'tcx>,
span: Span, span: Span,
) -> EvalToValTreeResult<'tcx> { ) -> EvalToValTreeResult<'tcx> {
@ -105,10 +102,10 @@ impl<'tcx> TyCtxt<'tcx> {
bug!("did not expect inference variables here"); 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)) => { Ok(Some(instance)) => {
let cid = GlobalId { instance, promoted: None }; 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` // We are emitting the lint here instead of in `is_const_evaluatable`
// as we normalize obligations before checking them, and normalization // as we normalize obligations before checking them, and normalization
// uses this function to evaluate this constant. // 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::print::{FmtPrinter, Printer, pretty_print_const, with_no_trimmed_paths};
use crate::ty::visit::TypeVisitableExt; use crate::ty::visit::TypeVisitableExt;
use crate::ty::{ use crate::ty::{
self, AdtDef, GenericArg, GenericArgsRef, Instance, InstanceKind, List, Ty, TyCtxt, TypingMode, self, AdtDef, GenericArg, GenericArgsRef, Instance, InstanceKind, List, Ty, TyCtxt, TypingEnv,
UserTypeAnnotationIndex, UserTypeAnnotationIndex,
}; };
@ -452,12 +452,17 @@ impl<'tcx> Body<'tcx> {
self.basic_blocks.as_mut() 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 { match self.phase {
// FIXME(#132279): the MIR is quite clearly inside of a body, so we // FIXME(#132279): we should reveal the opaques defined in the body during analysis.
// should instead reveal opaques defined by that body here. MirPhase::Built | MirPhase::Analysis(_) => TypingEnv {
MirPhase::Built | MirPhase::Analysis(_) => TypingMode::non_body_analysis(), typing_mode: ty::TypingMode::non_body_analysis(),
MirPhase::Runtime(_) => TypingMode::PostAnalysis, 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 /// 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. /// [`SwitchTargets`], just so the caller doesn't also have to match on the terminator.
fn try_const_mono_switchint<'a>( fn try_const_mono_switchint<'a>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
@ -627,13 +632,15 @@ impl<'tcx> Body<'tcx> {
) -> Option<(u128, &'a SwitchTargets)> { ) -> Option<(u128, &'a SwitchTargets)> {
// There are two places here we need to evaluate a constant. // There are two places here we need to evaluate a constant.
let eval_mono_const = |constant: &ConstOperand<'tcx>| { 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( let mono_literal = instance.instantiate_mir_and_normalize_erasing_regions(
tcx, tcx,
env, typing_env,
crate::ty::EarlyBinder::bind(constant.const_), 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 { let TerminatorKind::SwitchInt { discr, targets } = &block.terminator().kind else {

View File

@ -332,9 +332,9 @@ impl<'tcx> Operand<'tcx> {
span: Span, span: Span,
) -> Operand<'tcx> { ) -> Operand<'tcx> {
debug_assert!({ debug_assert!({
let param_env_and_ty = ty::ParamEnv::empty().and(ty); let typing_env = ty::TypingEnv::fully_monomorphized();
let type_size = tcx 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:?}")) .unwrap_or_else(|e| panic!("could not compute layout for {ty:?}: {e:?}"))
.size; .size;
let scalar_size = match val { let scalar_size = match val {

View File

@ -20,7 +20,7 @@ use smallvec::SmallVec;
use super::{BasicBlock, Const, Local, UserTypeProjection}; use super::{BasicBlock, Const, Local, UserTypeProjection};
use crate::mir::coverage::CoverageKind; use crate::mir::coverage::CoverageKind;
use crate::ty::adjustment::PointerCoercion; 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. /// Represents the "flavors" of MIR.
/// ///
@ -100,13 +100,6 @@ impl MirPhase {
MirPhase::Runtime(RuntimePhase::Optimized) => "runtime-optimized", 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`]. /// 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 { impl Key for Symbol {
type Cache<V> = DefaultCache<Self, V>; 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>; type Cache<V> = DefaultCache<Self, V>;
// Just forward to `Ty<'tcx>` // 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::print::{PrintTraitRefExt, describe_as_module};
use crate::ty::util::AlwaysRequiresDrop; use crate::ty::util::AlwaysRequiresDrop;
use crate::ty::{ use crate::ty::{
self, CrateInherentImpls, GenericArg, GenericArgsRef, ParamEnvAnd, Ty, TyCtxt, TyCtxtFeed, self, CrateInherentImpls, GenericArg, GenericArgsRef, PseudoCanonicalInput, Ty, TyCtxt,
UnusedGenericParams, TyCtxtFeed, UnusedGenericParams,
}; };
use crate::{dep_graph, mir, thir}; use crate::{dep_graph, mir, thir};
@ -1341,10 +1341,10 @@ rustc_queries! {
} }
query codegen_select_candidate( query codegen_select_candidate(
key: (ty::ParamEnv<'tcx>, ty::TraitRef<'tcx>) key: PseudoCanonicalInput<'tcx, ty::TraitRef<'tcx>>
) -> Result<&'tcx ImplSource<'tcx, ()>, CodegenObligationError> { ) -> Result<&'tcx ImplSource<'tcx, ()>, CodegenObligationError> {
cache_on_disk_if { true } 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. /// Return all `impl` blocks in the current crate.
@ -1406,15 +1406,15 @@ rustc_queries! {
desc { "computing whether `{}` is `Unpin`", env.value } desc { "computing whether `{}` is `Unpin`", env.value }
} }
/// Query backing `Ty::needs_drop`. /// 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 } desc { "computing whether `{}` needs drop", env.value }
} }
/// Query backing `Ty::needs_async_drop`. /// 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 } desc { "computing whether `{}` needs async drop", env.value }
} }
/// Query backing `Ty::has_significant_drop_raw`. /// 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 } 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 /// Computes the layout of a type. Note that this implicitly
/// executes in "reveal all" mode, and will normalize the input type. /// executes in "reveal all" mode, and will normalize the input type.
query layout_of( 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>> { ) -> Result<ty::layout::TyAndLayout<'tcx>, &'tcx ty::layout::LayoutError<'tcx>> {
depth_limit depth_limit
desc { "computing layout of `{}`", key.value } 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` /// NB: this doesn't handle virtual calls - those should use `fn_abi_of_instance`
/// instead, where the instance is an `InstanceKind::Virtual`. /// instead, where the instance is an `InstanceKind::Virtual`.
query fn_abi_of_fn_ptr( 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>> { ) -> Result<&'tcx rustc_target::callconv::FnAbi<'tcx, Ty<'tcx>>, &'tcx ty::layout::FnAbiError<'tcx>> {
desc { "computing call ABI of `{}` function pointers", key.value.0 } 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" /// NB: that includes virtual calls, which are represented by "direct calls"
/// to an `InstanceKind::Virtual` instance (of `<dyn Trait as Trait>::fn`). /// to an `InstanceKind::Virtual` instance (of `<dyn Trait as Trait>::fn`).
query fn_abi_of_instance( 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>> { ) -> Result<&'tcx rustc_target::callconv::FnAbi<'tcx, Ty<'tcx>>, &'tcx ty::layout::FnAbiError<'tcx>> {
desc { "computing call ABI of `{}`", key.value.0 } 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. /// Do not call this query directly: invoke `try_normalize_erasing_regions` instead.
query try_normalize_generic_arg_after_erasing_regions( query try_normalize_generic_arg_after_erasing_regions(
goal: ParamEnvAnd<'tcx, GenericArg<'tcx>> goal: PseudoCanonicalInput<'tcx, GenericArg<'tcx>>
) -> Result<GenericArg<'tcx>, NoSolution> { ) -> Result<GenericArg<'tcx>, NoSolution> {
desc { "normalizing `{}`", goal.value } desc { "normalizing `{}`", goal.value }
} }
@ -2245,7 +2245,7 @@ rustc_queries! {
/// from `Ok(None)` to avoid misleading diagnostics when an error /// from `Ok(None)` to avoid misleading diagnostics when an error
/// has already been/will be emitted, for the original cause. /// has already been/will be emitted, for the original cause.
query resolve_instance_raw( query resolve_instance_raw(
key: ty::ParamEnvAnd<'tcx, (DefId, GenericArgsRef<'tcx>)> key: ty::PseudoCanonicalInput<'tcx, (DefId, GenericArgsRef<'tcx>)>
) -> Result<Option<ty::Instance<'tcx>>, ErrorGuaranteed> { ) -> Result<Option<ty::Instance<'tcx>>, ErrorGuaranteed> {
desc { "resolving instance `{}`", ty::Instance::new(key.value.0, key.value.1) } 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" } 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 } desc { "checking validity requirement for `{}`: {}", key.1.value, key.0 }
} }

View File

@ -905,7 +905,7 @@ impl<'tcx> PatRange<'tcx> {
&self, &self,
value: mir::Const<'tcx>, value: mir::Const<'tcx>,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>, typing_env: ty::TypingEnv<'tcx>,
) -> Option<bool> { ) -> Option<bool> {
use Ordering::*; use Ordering::*;
debug_assert_eq!(self.ty, value.ty()); debug_assert_eq!(self.ty, value.ty());
@ -913,10 +913,10 @@ impl<'tcx> PatRange<'tcx> {
let value = PatRangeBoundary::Finite(value); let value = PatRangeBoundary::Finite(value);
// For performance, it's important to only do the second comparison if necessary. // For performance, it's important to only do the second comparison if necessary.
Some( Some(
match self.lo.compare_with(value, ty, tcx, param_env)? { match self.lo.compare_with(value, ty, tcx, typing_env)? {
Less | Equal => true, Less | Equal => true,
Greater => false, Greater => false,
} && match value.compare_with(self.hi, ty, tcx, param_env)? { } && match value.compare_with(self.hi, ty, tcx, typing_env)? {
Less => true, Less => true,
Equal => self.end == RangeEnd::Included, Equal => self.end == RangeEnd::Included,
Greater => false, Greater => false,
@ -929,17 +929,17 @@ impl<'tcx> PatRange<'tcx> {
&self, &self,
other: &Self, other: &Self,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>, typing_env: ty::TypingEnv<'tcx>,
) -> Option<bool> { ) -> Option<bool> {
use Ordering::*; use Ordering::*;
debug_assert_eq!(self.ty, other.ty); debug_assert_eq!(self.ty, other.ty);
// For performance, it's important to only do the second comparison if necessary. // For performance, it's important to only do the second comparison if necessary.
Some( 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, Less => true,
Equal => self.end == RangeEnd::Included, Equal => self.end == RangeEnd::Included,
Greater => false, 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, Less => true,
Equal => other.end == RangeEnd::Included, Equal => other.end == RangeEnd::Included,
Greater => false, Greater => false,
@ -985,9 +985,14 @@ impl<'tcx> PatRangeBoundary<'tcx> {
Self::NegInfinity | Self::PosInfinity => None, 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 { match self {
Self::Finite(value) => value.eval_bits(tcx, param_env), Self::Finite(value) => value.eval_bits(tcx, typing_env),
Self::NegInfinity => { Self::NegInfinity => {
// Unwrap is ok because the type is known to be numeric. // Unwrap is ok because the type is known to be numeric.
ty.numeric_min_and_max_as_bits(tcx).unwrap().0 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( pub fn compare_with(
self, self,
other: Self, other: Self,
ty: Ty<'tcx>, ty: Ty<'tcx>,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>, typing_env: ty::TypingEnv<'tcx>,
) -> Option<Ordering> { ) -> Option<Ordering> {
use PatRangeBoundary::*; use PatRangeBoundary::*;
match (self, other) { match (self, other) {
@ -1034,8 +1039,8 @@ impl<'tcx> PatRangeBoundary<'tcx> {
_ => {} _ => {}
} }
let a = self.eval_bits(ty, tcx, param_env); let a = self.eval_bits(ty, tcx, typing_env);
let b = other.eval_bits(ty, tcx, param_env); let b = other.eval_bits(ty, tcx, typing_env);
match ty.kind() { match ty.kind() {
ty::Float(ty::FloatTy::F16) => { ty::Float(ty::FloatTy::F16) => {

View File

@ -498,12 +498,13 @@ impl<'tcx> AdtDef<'tcx> {
expr_did: DefId, expr_did: DefId,
) -> Result<Discr<'tcx>, ErrorGuaranteed> { ) -> Result<Discr<'tcx>, ErrorGuaranteed> {
assert!(self.is_enum()); assert!(self.is_enum());
let param_env = tcx.param_env(expr_did);
let repr_type = self.repr().discr_type(); let repr_type = self.repr().discr_type();
match tcx.const_eval_poly(expr_did) { match tcx.const_eval_poly(expr_did) {
Ok(val) => { Ok(val) => {
let typing_env = ty::TypingEnv::post_analysis(tcx, expr_did);
let ty = repr_type.to_ty(tcx); 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); trace!("discriminants: {} ({:?})", b, repr_type);
Ok(Discr { val: b, ty }) Ok(Discr { val: b, ty })
} else { } else {

View File

@ -9,7 +9,7 @@ use tracing::{debug, instrument};
use crate::middle::resolve_bound_vars as rbv; use crate::middle::resolve_bound_vars as rbv;
use crate::mir::interpret::{LitToConstInput, Scalar}; 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 int;
mod kind; mod kind;
@ -330,17 +330,22 @@ impl<'tcx> Const<'tcx> {
None None
} }
#[inline]
/// Creates a constant with the given integer value and interns it. /// 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 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:?}")) .unwrap_or_else(|e| panic!("could not compute layout for {ty:?}: {e:?}"))
.size; .size;
ty::Const::new_value( ty::Const::new_value(
tcx, tcx,
ty::ValTree::from_scalar_int(ScalarInt::try_from_uint(bits, size).unwrap()), ty::ValTree::from_scalar_int(ScalarInt::try_from_uint(bits, size).unwrap()),
ty.value, ty,
) )
} }
@ -353,13 +358,13 @@ impl<'tcx> Const<'tcx> {
#[inline] #[inline]
/// Creates an interned bool constant. /// Creates an interned bool constant.
pub fn from_bool(tcx: TyCtxt<'tcx>, v: bool) -> Self { 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] #[inline]
/// Creates an interned usize constant. /// Creates an interned usize constant.
pub fn from_target_usize(tcx: TyCtxt<'tcx>, n: u64) -> Self { 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 /// 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) 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 /// 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 /// generics (or erroneous code) or if the value can't be represented as bits (e.g. because it
/// contains const generic parameters or pointers). /// 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, ty) = self.try_to_scalar()?;
let scalar = scalar.try_to_scalar_int().ok()?; let scalar = scalar.try_to_scalar_int().ok()?;
let size = tcx.layout_of(param_env.with_reveal_all_normalized(tcx).and(ty)).ok()?.size; let input = typing_env.with_reveal_all_normalized(tcx).as_query_input(ty);
// if `ty` does not depend on generic parameters, use an empty param_env let size = tcx.layout_of(input).ok()?.size;
Some(scalar.to_bits(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) self.coroutine_is_async_gen(coroutine_def_id)
} }
fn layout_is_pointer_like(self, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool { // We don't use `TypingEnv` here as it's only defined in `rustc_middle` and
self.layout_of(self.erase_regions(param_env.and(ty))) // `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)) .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