Auto merge of #132460 - lcnr:questionable-uwu, r=compiler-errors

Use `TypingMode` throughout the compiler instead of `ParamEnv`

Hopefully the biggest single PR as part of https://github.com/rust-lang/types-team/issues/128.

## `infcx.typing_env` while defining opaque types

I don't know how'll be able to correctly handle opaque types when using something taking a `TypingEnv` while defining opaque types. To correctly handle the opaques we need to be able to pass in the current `opaque_type_storage` and return constraints, i.e. we need to use a proper canonical query. We should migrate all the queries used during HIR typeck and borrowck where this matters to proper canonical queries. This is

## `layout_of` and `Reveal::All`

We convert the `ParamEnv` to `Reveal::All` right at the start of the `layout_of` query, so I've changed callers of `layout_of` to already use a post analysis `TypingEnv` when encountering it.

ca87b535a0/compiler/rustc_ty_utils/src/layout.rs (L51)

## `Ty::is_[unpin|sized|whatever]`

I haven't migrated `fn is_item_raw` to use `TypingEnv`, will do so in a followup PR, this should significantly reduce the amount of `typing_env.param_env`. At some point there will probably be zero such uses as using the type system while ignoring the `typing_mode` is incorrect.

## `MirPhase` and phase-transitions

When inside of a MIR-body, we can mostly use its `MirPhase` to figure out the right `typing_mode`. This does not work during phase transitions, most notably when transitioning from `Analysis` to `Runtime`:

dae7ac133b/compiler/rustc_mir_transform/src/lib.rs (L606-L625)

All these passes still run with `MirPhase::Analysis`, but we should only use `Reveal::All` once we're run the `RevealAll` pass. This required me to manually construct the right `TypingEnv` in all these passes. Given that it feels somewhat easy to accidentally miss this going forward, I would maybe like to change `Body::phase` to an `Option` and replace it at the start of phase transitions. This then makes it clear that the MIR is currently in a weird state.

r? `@ghost`
This commit is contained in:
bors 2024-11-18 21:07:05 +00:00
commit b71fb5edc0
240 changed files with 1745 additions and 1341 deletions

View File

@ -682,8 +682,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
// Normalize before comparing to see through type aliases and projections. // 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 {
@ -703,7 +707,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
// Test the callee's predicates, substituting in `ref_ty` for the moved argument type. // Test the callee's predicates, substituting in `ref_ty` for the moved argument type.
clauses.instantiate(tcx, new_args).predicates.iter().all(|&(mut clause)| { clauses.instantiate(tcx, new_args).predicates.iter().all(|&(mut clause)| {
// Normalize before testing to see through type aliases and projections. // Normalize before testing to see through type aliases and projections.
if let Ok(normalized) = tcx.try_normalize_erasing_regions(self.param_env, clause) { if let Ok(normalized) =
tcx.try_normalize_erasing_regions(self.infcx.typing_env(self.param_env), clause)
{
clause = normalized; clause = normalized;
} }
self.infcx.predicate_must_hold_modulo_regions(&Obligation::new( self.infcx.predicate_must_hold_modulo_regions(&Obligation::new(
@ -3831,11 +3837,16 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
if tcx.is_diagnostic_item(sym::deref_method, method_did) { 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, wfcx.infcx.typing_env(wfcx.param_env))
} }
}; };
// 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