mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-21 14:23:45 +00:00
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:
commit
b71fb5edc0
@ -682,8 +682,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||
// Normalize before comparing to see through type aliases and projections.
|
||||
let old_ty = ty::EarlyBinder::bind(ty).instantiate(tcx, generic_args);
|
||||
let new_ty = ty::EarlyBinder::bind(ty).instantiate(tcx, new_args);
|
||||
if let Ok(old_ty) = tcx.try_normalize_erasing_regions(self.param_env, old_ty)
|
||||
&& let Ok(new_ty) = tcx.try_normalize_erasing_regions(self.param_env, new_ty)
|
||||
if let Ok(old_ty) =
|
||||
tcx.try_normalize_erasing_regions(self.infcx.typing_env(self.param_env), old_ty)
|
||||
&& let Ok(new_ty) = tcx.try_normalize_erasing_regions(
|
||||
self.infcx.typing_env(self.param_env),
|
||||
new_ty,
|
||||
)
|
||||
{
|
||||
old_ty == new_ty
|
||||
} else {
|
||||
@ -703,7 +707,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||
// Test the callee's predicates, substituting in `ref_ty` for the moved argument type.
|
||||
clauses.instantiate(tcx, new_args).predicates.iter().all(|&(mut clause)| {
|
||||
// Normalize before testing to see through type aliases and projections.
|
||||
if let Ok(normalized) = tcx.try_normalize_erasing_regions(self.param_env, clause) {
|
||||
if let Ok(normalized) =
|
||||
tcx.try_normalize_erasing_regions(self.infcx.typing_env(self.param_env), clause)
|
||||
{
|
||||
clause = normalized;
|
||||
}
|
||||
self.infcx.predicate_must_hold_modulo_regions(&Obligation::new(
|
||||
@ -3831,11 +3837,16 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||
if tcx.is_diagnostic_item(sym::deref_method, method_did) {
|
||||
let deref_target =
|
||||
tcx.get_diagnostic_item(sym::deref_target).and_then(|deref_target| {
|
||||
Instance::try_resolve(tcx, self.param_env, deref_target, method_args)
|
||||
.transpose()
|
||||
Instance::try_resolve(
|
||||
tcx,
|
||||
self.infcx.typing_env(self.param_env),
|
||||
deref_target,
|
||||
method_args,
|
||||
)
|
||||
.transpose()
|
||||
});
|
||||
if let Some(Ok(instance)) = deref_target {
|
||||
let deref_target_ty = instance.ty(tcx, self.param_env);
|
||||
let deref_target_ty = instance.ty(tcx, self.infcx.typing_env(self.param_env));
|
||||
err.note(format!("borrow occurs due to deref coercion to `{deref_target_ty}`"));
|
||||
err.span_note(tcx.def_span(instance.def_id()), "deref defined here");
|
||||
}
|
||||
|
@ -864,7 +864,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||
|
||||
let kind = call_kind(
|
||||
self.infcx.tcx,
|
||||
self.param_env,
|
||||
self.infcx.typing_env(self.param_env),
|
||||
method_did,
|
||||
method_args,
|
||||
*fn_span,
|
||||
|
@ -952,7 +952,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||
|
||||
if let Ok(Some(instance)) = ty::Instance::try_resolve(
|
||||
tcx,
|
||||
self.param_env,
|
||||
self.infcx.typing_env(self.param_env),
|
||||
*fn_did,
|
||||
self.infcx.resolve_vars_if_possible(args),
|
||||
) {
|
||||
|
@ -1527,7 +1527,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
// The signature in this call can reference region variables,
|
||||
// so erase them before calling a query.
|
||||
let output_ty = self.tcx().erase_regions(sig.output());
|
||||
if !output_ty.is_privately_uninhabited(self.tcx(), self.param_env) {
|
||||
if !output_ty
|
||||
.is_privately_uninhabited(self.tcx(), self.infcx.typing_env(self.param_env))
|
||||
{
|
||||
span_mirbug!(self, term, "call to converging function {:?} w/o dest", sig);
|
||||
}
|
||||
}
|
||||
|
@ -376,7 +376,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
|
||||
let instance = if let ty::FnDef(def_id, fn_args) = *func.layout().ty.kind() {
|
||||
let instance = ty::Instance::expect_resolve(
|
||||
fx.tcx,
|
||||
ty::ParamEnv::reveal_all(),
|
||||
ty::TypingEnv::fully_monomorphized(),
|
||||
def_id,
|
||||
fn_args,
|
||||
source_info.span,
|
||||
|
@ -666,7 +666,7 @@ fn codegen_stmt<'tcx>(
|
||||
let func_ref = fx.get_function_ref(
|
||||
Instance::resolve_for_fn_ptr(
|
||||
fx.tcx,
|
||||
ParamEnv::reveal_all(),
|
||||
ty::TypingEnv::fully_monomorphized(),
|
||||
def_id,
|
||||
args,
|
||||
)
|
||||
@ -841,14 +841,18 @@ fn codegen_stmt<'tcx>(
|
||||
lval.write_cvalue(fx, CValue::by_val(operand, box_layout));
|
||||
}
|
||||
Rvalue::NullaryOp(ref null_op, ty) => {
|
||||
assert!(lval.layout().ty.is_sized(fx.tcx, ParamEnv::reveal_all()));
|
||||
assert!(lval.layout().ty.is_sized(fx.tcx, ty::ParamEnv::reveal_all()));
|
||||
let layout = fx.layout_of(fx.monomorphize(ty));
|
||||
let val = match null_op {
|
||||
NullOp::SizeOf => layout.size.bytes(),
|
||||
NullOp::AlignOf => layout.align.abi.bytes(),
|
||||
NullOp::OffsetOf(fields) => fx
|
||||
.tcx
|
||||
.offset_of_subfield(ParamEnv::reveal_all(), layout, fields.iter())
|
||||
.offset_of_subfield(
|
||||
ty::TypingEnv::fully_monomorphized(),
|
||||
layout,
|
||||
fields.iter(),
|
||||
)
|
||||
.bytes(),
|
||||
NullOp::UbChecks => {
|
||||
let val = fx.tcx.sess.ub_checks();
|
||||
|
@ -103,11 +103,11 @@ fn clif_pair_type_from_ty<'tcx>(
|
||||
|
||||
/// Is a pointer to this type a wide ptr?
|
||||
pub(crate) fn has_ptr_meta<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
if ty.is_sized(tcx, ParamEnv::reveal_all()) {
|
||||
if ty.is_sized(tcx, ty::ParamEnv::reveal_all()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let tail = tcx.struct_tail_for_codegen(ty, ParamEnv::reveal_all());
|
||||
let tail = tcx.struct_tail_for_codegen(ty, ty::TypingEnv::fully_monomorphized());
|
||||
match tail.kind() {
|
||||
ty::Foreign(..) => false,
|
||||
ty::Str | ty::Slice(..) | ty::Dynamic(..) => true,
|
||||
@ -339,9 +339,9 @@ impl<'tcx> rustc_abi::HasDataLayout for FunctionCx<'_, '_, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> layout::HasParamEnv<'tcx> for FunctionCx<'_, '_, 'tcx> {
|
||||
fn param_env(&self) -> ParamEnv<'tcx> {
|
||||
ParamEnv::reveal_all()
|
||||
impl<'tcx> layout::HasTypingEnv<'tcx> for FunctionCx<'_, '_, 'tcx> {
|
||||
fn typing_env(&self) -> ty::TypingEnv<'tcx> {
|
||||
ty::TypingEnv::fully_monomorphized()
|
||||
}
|
||||
}
|
||||
|
||||
@ -358,7 +358,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
|
||||
{
|
||||
self.instance.instantiate_mir_and_normalize_erasing_regions(
|
||||
self.tcx,
|
||||
ty::ParamEnv::reveal_all(),
|
||||
ty::TypingEnv::fully_monomorphized(),
|
||||
ty::EarlyBinder::bind(value),
|
||||
)
|
||||
}
|
||||
@ -497,9 +497,9 @@ impl<'tcx> rustc_abi::HasDataLayout for RevealAllLayoutCx<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> layout::HasParamEnv<'tcx> for RevealAllLayoutCx<'tcx> {
|
||||
fn param_env(&self) -> ParamEnv<'tcx> {
|
||||
ParamEnv::reveal_all()
|
||||
impl<'tcx> layout::HasTypingEnv<'tcx> for RevealAllLayoutCx<'tcx> {
|
||||
fn typing_env(&self) -> ty::TypingEnv<'tcx> {
|
||||
ty::TypingEnv::fully_monomorphized()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -78,7 +78,7 @@ pub(crate) fn eval_mir_constant<'tcx>(
|
||||
let cv = fx.monomorphize(constant.const_);
|
||||
// This cannot fail because we checked all required_consts in advance.
|
||||
let val = cv
|
||||
.eval(fx.tcx, ty::ParamEnv::reveal_all(), constant.span)
|
||||
.eval(fx.tcx, ty::TypingEnv::fully_monomorphized(), constant.span)
|
||||
.expect("erroneous constant missed by mono item collection");
|
||||
(val, cv.ty())
|
||||
}
|
||||
@ -265,8 +265,13 @@ fn data_id_for_static(
|
||||
assert!(!definition);
|
||||
assert!(!tcx.is_mutable_static(def_id));
|
||||
|
||||
let ty = instance.ty(tcx, ParamEnv::reveal_all());
|
||||
let align = tcx.layout_of(ParamEnv::reveal_all().and(ty)).unwrap().align.pref.bytes();
|
||||
let ty = instance.ty(tcx, ty::TypingEnv::fully_monomorphized());
|
||||
let align = tcx
|
||||
.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty))
|
||||
.unwrap()
|
||||
.align
|
||||
.pref
|
||||
.bytes();
|
||||
|
||||
let linkage = if import_linkage == rustc_middle::mir::mono::Linkage::ExternalWeak
|
||||
|| import_linkage == rustc_middle::mir::mono::Linkage::WeakAny
|
||||
|
@ -210,7 +210,7 @@ impl DebugContext {
|
||||
|
||||
type_names::push_generic_params(
|
||||
tcx,
|
||||
tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), args),
|
||||
tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), args),
|
||||
&mut name,
|
||||
);
|
||||
|
||||
@ -275,8 +275,10 @@ impl DebugContext {
|
||||
let span = tcx.def_span(def_id);
|
||||
let (file_id, line, _column) = self.get_span_loc(tcx, span, span);
|
||||
|
||||
let static_type = Instance::mono(tcx, def_id).ty(tcx, ty::ParamEnv::reveal_all());
|
||||
let static_layout = tcx.layout_of(ty::ParamEnv::reveal_all().and(static_type)).unwrap();
|
||||
let static_type = Instance::mono(tcx, def_id).ty(tcx, ty::TypingEnv::fully_monomorphized());
|
||||
let static_layout = tcx
|
||||
.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(static_type))
|
||||
.unwrap();
|
||||
// FIXME use the actual type layout
|
||||
let type_id = self.debug_type(tcx, type_dbg, static_type);
|
||||
|
||||
|
@ -92,7 +92,7 @@ pub(crate) fn codegen_inline_asm_terminator<'tcx>(
|
||||
if let ty::FnDef(def_id, args) = *const_.ty().kind() {
|
||||
let instance = ty::Instance::resolve_for_fn_ptr(
|
||||
fx.tcx,
|
||||
ty::ParamEnv::reveal_all(),
|
||||
ty::TypingEnv::fully_monomorphized(),
|
||||
def_id,
|
||||
args,
|
||||
)
|
||||
@ -227,11 +227,11 @@ pub(crate) fn codegen_naked_asm<'tcx>(
|
||||
InlineAsmOperand::Const { ref value } => {
|
||||
let cv = instance.instantiate_mir_and_normalize_erasing_regions(
|
||||
tcx,
|
||||
ty::ParamEnv::reveal_all(),
|
||||
ty::TypingEnv::fully_monomorphized(),
|
||||
ty::EarlyBinder::bind(value.const_),
|
||||
);
|
||||
let const_value = cv
|
||||
.eval(tcx, ty::ParamEnv::reveal_all(), value.span)
|
||||
.eval(tcx, ty::TypingEnv::fully_monomorphized(), value.span)
|
||||
.expect("erroneous constant missed by mono item collection");
|
||||
|
||||
let value = rustc_codegen_ssa::common::asm_const_to_str(
|
||||
@ -250,13 +250,13 @@ pub(crate) fn codegen_naked_asm<'tcx>(
|
||||
|
||||
let const_ = instance.instantiate_mir_and_normalize_erasing_regions(
|
||||
tcx,
|
||||
ty::ParamEnv::reveal_all(),
|
||||
ty::TypingEnv::fully_monomorphized(),
|
||||
ty::EarlyBinder::bind(value.const_),
|
||||
);
|
||||
if let ty::FnDef(def_id, args) = *const_.ty().kind() {
|
||||
let instance = ty::Instance::resolve_for_fn_ptr(
|
||||
tcx,
|
||||
ty::ParamEnv::reveal_all(),
|
||||
ty::TypingEnv::fully_monomorphized(),
|
||||
def_id,
|
||||
args,
|
||||
)
|
||||
|
@ -20,7 +20,7 @@ mod simd;
|
||||
use cranelift_codegen::ir::AtomicRmwOp;
|
||||
use rustc_middle::ty;
|
||||
use rustc_middle::ty::GenericArgsRef;
|
||||
use rustc_middle::ty::layout::{HasParamEnv, ValidityRequirement};
|
||||
use rustc_middle::ty::layout::ValidityRequirement;
|
||||
use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
|
||||
use rustc_span::source_map::Spanned;
|
||||
use rustc_span::symbol::{Symbol, sym};
|
||||
@ -682,7 +682,10 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||
if let Some(requirement) = requirement {
|
||||
let do_panic = !fx
|
||||
.tcx
|
||||
.check_validity_requirement((requirement, fx.param_env().and(ty)))
|
||||
.check_validity_requirement((
|
||||
requirement,
|
||||
ty::TypingEnv::fully_monomorphized().as_query_input(ty),
|
||||
))
|
||||
.expect("expect to have layout during codegen");
|
||||
|
||||
if do_panic {
|
||||
@ -741,7 +744,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||
|
||||
let const_val = fx
|
||||
.tcx
|
||||
.const_eval_instance(ParamEnv::reveal_all(), instance, source_info.span)
|
||||
.const_eval_instance(ty::ParamEnv::reveal_all(), instance, source_info.span)
|
||||
.unwrap();
|
||||
let val = crate::constant::codegen_const_value(fx, const_val, ret.layout().ty);
|
||||
ret.write_cvalue(fx, val);
|
||||
|
@ -98,7 +98,7 @@ mod prelude {
|
||||
pub(crate) use rustc_middle::mir::{self, *};
|
||||
pub(crate) use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
|
||||
pub(crate) use rustc_middle::ty::{
|
||||
self, FloatTy, Instance, InstanceKind, IntTy, ParamEnv, Ty, TyCtxt, UintTy,
|
||||
self, FloatTy, Instance, InstanceKind, IntTy, Ty, TyCtxt, UintTy,
|
||||
};
|
||||
pub(crate) use rustc_span::Span;
|
||||
|
||||
|
@ -49,7 +49,7 @@ pub(crate) fn maybe_create_entry_wrapper(
|
||||
// regions must appear in the argument
|
||||
// listing.
|
||||
let main_ret_ty = tcx.normalize_erasing_regions(
|
||||
ty::ParamEnv::reveal_all(),
|
||||
ty::TypingEnv::fully_monomorphized(),
|
||||
main_ret_ty.no_bound_vars().unwrap(),
|
||||
);
|
||||
|
||||
@ -113,7 +113,7 @@ pub(crate) fn maybe_create_entry_wrapper(
|
||||
.unwrap();
|
||||
let report = Instance::expect_resolve(
|
||||
tcx,
|
||||
ParamEnv::reveal_all(),
|
||||
ty::TypingEnv::fully_monomorphized(),
|
||||
report.def_id,
|
||||
tcx.mk_args(&[GenericArg::from(main_ret_ty)]),
|
||||
DUMMY_SP,
|
||||
@ -139,7 +139,7 @@ pub(crate) fn maybe_create_entry_wrapper(
|
||||
let start_def_id = tcx.require_lang_item(LangItem::Start, None);
|
||||
let start_instance = Instance::expect_resolve(
|
||||
tcx,
|
||||
ParamEnv::reveal_all(),
|
||||
ty::TypingEnv::fully_monomorphized(),
|
||||
start_def_id,
|
||||
tcx.mk_args(&[main_ret_ty.into()]),
|
||||
DUMMY_SP,
|
||||
|
@ -3,6 +3,7 @@
|
||||
//! [`PointerCoercion::Unsize`]: `rustc_middle::ty::adjustment::PointerCoercion::Unsize`
|
||||
|
||||
use rustc_codegen_ssa::base::validate_trivial_unsize;
|
||||
use rustc_middle::ty::layout::HasTypingEnv;
|
||||
use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
|
||||
|
||||
use crate::base::codegen_panic_nounwind;
|
||||
@ -23,7 +24,7 @@ pub(crate) fn unsized_info<'tcx>(
|
||||
old_info: Option<Value>,
|
||||
) -> Value {
|
||||
let (source, target) =
|
||||
fx.tcx.struct_lockstep_tails_for_codegen(source, target, ParamEnv::reveal_all());
|
||||
fx.tcx.struct_lockstep_tails_for_codegen(source, target, fx.typing_env());
|
||||
match (&source.kind(), &target.kind()) {
|
||||
(&ty::Array(_, len), &ty::Slice(_)) => fx.bcx.ins().iconst(
|
||||
fx.pointer_type,
|
||||
|
@ -4,6 +4,7 @@ use cranelift_codegen::entity::EntityRef;
|
||||
use cranelift_codegen::ir::immediates::Offset32;
|
||||
use cranelift_frontend::Variable;
|
||||
use rustc_middle::ty::FnSig;
|
||||
use rustc_middle::ty::layout::HasTypingEnv;
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
@ -884,19 +885,17 @@ pub(crate) fn assert_assignable<'tcx>(
|
||||
assert_assignable(fx, *a, *b, limit - 1);
|
||||
}
|
||||
(ty::FnPtr(..), ty::FnPtr(..)) => {
|
||||
let from_sig = fx.tcx.normalize_erasing_late_bound_regions(
|
||||
ParamEnv::reveal_all(),
|
||||
from_ty.fn_sig(fx.tcx),
|
||||
);
|
||||
let from_sig = fx
|
||||
.tcx
|
||||
.normalize_erasing_late_bound_regions(fx.typing_env(), from_ty.fn_sig(fx.tcx));
|
||||
let FnSig {
|
||||
inputs_and_output: types_from,
|
||||
c_variadic: c_variadic_from,
|
||||
safety: unsafety_from,
|
||||
abi: abi_from,
|
||||
} = from_sig;
|
||||
let to_sig = fx
|
||||
.tcx
|
||||
.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), to_ty.fn_sig(fx.tcx));
|
||||
let to_sig =
|
||||
fx.tcx.normalize_erasing_late_bound_regions(fx.typing_env(), to_ty.fn_sig(fx.tcx));
|
||||
let FnSig {
|
||||
inputs_and_output: types_to,
|
||||
c_variadic: c_variadic_to,
|
||||
@ -932,9 +931,8 @@ pub(crate) fn assert_assignable<'tcx>(
|
||||
(&ty::Dynamic(from_traits, _, _from_kind), &ty::Dynamic(to_traits, _, _to_kind)) => {
|
||||
// FIXME(dyn-star): Do the right thing with DynKinds
|
||||
for (from, to) in from_traits.iter().zip(to_traits) {
|
||||
let from =
|
||||
fx.tcx.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), from);
|
||||
let to = fx.tcx.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), to);
|
||||
let from = fx.tcx.normalize_erasing_late_bound_regions(fx.typing_env(), from);
|
||||
let to = fx.tcx.normalize_erasing_late_bound_regions(fx.typing_env(), to);
|
||||
assert_eq!(
|
||||
from, to,
|
||||
"Can't write trait object of incompatible traits {:?} to place with traits {:?}\n\n{:#?}",
|
||||
|
@ -24,9 +24,9 @@ use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
|
||||
use rustc_middle::ty::layout::{
|
||||
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, HasTyCtxt, LayoutError, LayoutOfHelpers,
|
||||
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasTyCtxt, HasTypingEnv, LayoutError, LayoutOfHelpers,
|
||||
};
|
||||
use rustc_middle::ty::{Instance, ParamEnv, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
|
||||
use rustc_span::Span;
|
||||
use rustc_span::def_id::DefId;
|
||||
use rustc_target::abi::call::FnAbi;
|
||||
@ -2319,9 +2319,9 @@ impl<'a, 'gcc, 'tcx> StaticBuilderMethods for Builder<'a, 'gcc, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> HasParamEnv<'tcx> for Builder<'_, '_, 'tcx> {
|
||||
fn param_env(&self) -> ParamEnv<'tcx> {
|
||||
self.cx.param_env()
|
||||
impl<'tcx> HasTypingEnv<'tcx> for Builder<'_, '_, 'tcx> {
|
||||
fn typing_env(&self) -> ty::TypingEnv<'tcx> {
|
||||
self.cx.typing_env()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -215,7 +215,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
|
||||
let gcc_type = if nested {
|
||||
self.type_i8()
|
||||
} else {
|
||||
let ty = instance.ty(self.tcx, ty::ParamEnv::reveal_all());
|
||||
let ty = instance.ty(self.tcx, ty::TypingEnv::fully_monomorphized());
|
||||
self.layout_of(ty).gcc_type(self)
|
||||
};
|
||||
|
||||
|
@ -11,10 +11,10 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_middle::mir::mono::CodegenUnit;
|
||||
use rustc_middle::span_bug;
|
||||
use rustc_middle::ty::layout::{
|
||||
FnAbiError, FnAbiOf, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, HasTyCtxt, LayoutError,
|
||||
FnAbiError, FnAbiOf, FnAbiOfHelpers, FnAbiRequest, HasTyCtxt, HasTypingEnv, LayoutError,
|
||||
LayoutOfHelpers,
|
||||
};
|
||||
use rustc_middle::ty::{self, Instance, ParamEnv, PolyExistentialTraitRef, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{self, Instance, PolyExistentialTraitRef, Ty, TyCtxt};
|
||||
use rustc_session::Session;
|
||||
use rustc_span::source_map::respan;
|
||||
use rustc_span::{DUMMY_SP, Span};
|
||||
@ -144,7 +144,9 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
|
||||
supports_f128_type: bool,
|
||||
) -> Self {
|
||||
let create_type = |ctype, rust_type| {
|
||||
let layout = tcx.layout_of(ParamEnv::reveal_all().and(rust_type)).unwrap();
|
||||
let layout = tcx
|
||||
.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(rust_type))
|
||||
.unwrap();
|
||||
let align = layout.align.abi.bytes();
|
||||
#[cfg(feature = "master")]
|
||||
{
|
||||
@ -459,7 +461,7 @@ impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
|
||||
Some(def_id) if !wants_msvc_seh(self.sess()) => {
|
||||
let instance = ty::Instance::expect_resolve(
|
||||
tcx,
|
||||
ty::ParamEnv::reveal_all(),
|
||||
self.typing_env(),
|
||||
def_id,
|
||||
ty::List::empty(),
|
||||
DUMMY_SP,
|
||||
@ -583,9 +585,9 @@ impl<'gcc, 'tcx> FnAbiOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, 'gcc> HasParamEnv<'tcx> for CodegenCx<'gcc, 'tcx> {
|
||||
fn param_env(&self) -> ParamEnv<'tcx> {
|
||||
ParamEnv::reveal_all()
|
||||
impl<'tcx, 'gcc> HasTypingEnv<'tcx> for CodegenCx<'gcc, 'tcx> {
|
||||
fn typing_env(&self) -> ty::TypingEnv<'tcx> {
|
||||
ty::TypingEnv::fully_monomorphized()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
use gccjit::{BinaryOp, ComparisonOp, FunctionType, Location, RValue, ToRValue, Type, UnaryOp};
|
||||
use rustc_codegen_ssa::common::{IntPredicate, TypeKind};
|
||||
use rustc_codegen_ssa::traits::{BackendTypes, BaseTypeCodegenMethods, BuilderMethods, OverflowOp};
|
||||
use rustc_middle::ty::{ParamEnv, Ty};
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use rustc_target::abi::Endian;
|
||||
use rustc_target::abi::call::{ArgAbi, ArgAttributes, Conv, FnAbi, PassMode};
|
||||
use rustc_target::spec;
|
||||
@ -380,7 +380,10 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
|
||||
let overflow_field = self.context.new_field(self.location, self.bool_type, "overflow");
|
||||
|
||||
let ret_ty = Ty::new_tup(self.tcx, &[self.tcx.types.i128, self.tcx.types.bool]);
|
||||
let layout = self.tcx.layout_of(ParamEnv::reveal_all().and(ret_ty)).unwrap();
|
||||
let layout = self
|
||||
.tcx
|
||||
.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ret_ty))
|
||||
.unwrap();
|
||||
|
||||
let arg_abi = ArgAbi { layout, mode: PassMode::Direct(ArgAttributes::new()) };
|
||||
let mut fn_abi = FnAbi {
|
||||
|
@ -21,7 +21,7 @@ use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, MiscCodegenMethods};
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::ty::layout::LayoutOf;
|
||||
#[cfg(feature = "master")]
|
||||
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt};
|
||||
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, HasTypingEnv};
|
||||
use rustc_middle::ty::{self, Instance, Ty};
|
||||
use rustc_span::{Span, Symbol, sym};
|
||||
use rustc_target::abi::HasDataLayout;
|
||||
@ -107,7 +107,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
|
||||
span: Span,
|
||||
) -> Result<(), Instance<'tcx>> {
|
||||
let tcx = self.tcx;
|
||||
let callee_ty = instance.ty(tcx, ty::ParamEnv::reveal_all());
|
||||
let callee_ty = instance.ty(tcx, self.typing_env());
|
||||
|
||||
let (def_id, fn_args) = match *callee_ty.kind() {
|
||||
ty::FnDef(def_id, fn_args) => (def_id, fn_args),
|
||||
@ -115,7 +115,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
|
||||
};
|
||||
|
||||
let sig = callee_ty.fn_sig(tcx);
|
||||
let sig = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), sig);
|
||||
let sig = tcx.normalize_erasing_late_bound_regions(self.typing_env(), sig);
|
||||
let arg_tys = sig.inputs();
|
||||
let ret_ty = sig.output();
|
||||
let name = tcx.item_name(def_id);
|
||||
|
@ -55,8 +55,10 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
||||
}
|
||||
|
||||
let tcx = bx.tcx();
|
||||
let sig =
|
||||
tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), callee_ty.fn_sig(tcx));
|
||||
let sig = tcx.normalize_erasing_late_bound_regions(
|
||||
ty::TypingEnv::fully_monomorphized(),
|
||||
callee_ty.fn_sig(tcx),
|
||||
);
|
||||
let arg_tys = sig.inputs();
|
||||
|
||||
if name == sym::simd_select_bitmask {
|
||||
@ -478,7 +480,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
||||
match *in_elem.kind() {
|
||||
ty::RawPtr(p_ty, _) => {
|
||||
let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| {
|
||||
bx.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), ty)
|
||||
bx.tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), ty)
|
||||
});
|
||||
require!(metadata.is_unit(), InvalidMonomorphization::CastWidePointer {
|
||||
span,
|
||||
@ -493,7 +495,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
||||
match *out_elem.kind() {
|
||||
ty::RawPtr(p_ty, _) => {
|
||||
let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| {
|
||||
bx.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), ty)
|
||||
bx.tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), ty)
|
||||
});
|
||||
require!(metadata.is_unit(), InvalidMonomorphization::CastWidePointer {
|
||||
span,
|
||||
|
@ -6,7 +6,7 @@ use rustc_hir::def_id::{DefId, LOCAL_CRATE};
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
||||
use rustc_middle::mir::mono::{Linkage, Visibility};
|
||||
use rustc_middle::ty::layout::{FnAbiOf, LayoutOf};
|
||||
use rustc_middle::ty::layout::{FnAbiOf, HasTypingEnv, LayoutOf};
|
||||
use rustc_middle::ty::{self, Instance, TypeVisitableExt};
|
||||
|
||||
use crate::context::CodegenCx;
|
||||
@ -27,11 +27,8 @@ impl<'gcc, 'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
|
||||
let DefKind::Static { nested, .. } = self.tcx.def_kind(def_id) else { bug!() };
|
||||
// Nested statics do not have a type, so pick a dummy type and let `codegen_static` figure out
|
||||
// the gcc type from the actual evaluated initializer.
|
||||
let ty = if nested {
|
||||
self.tcx.types.unit
|
||||
} else {
|
||||
instance.ty(self.tcx, ty::ParamEnv::reveal_all())
|
||||
};
|
||||
let ty =
|
||||
if nested { self.tcx.types.unit } else { instance.ty(self.tcx, self.typing_env()) };
|
||||
let gcc_type = self.layout_of(ty).gcc_type(self);
|
||||
|
||||
let is_tls = attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL);
|
||||
|
@ -14,7 +14,7 @@ use rustc_data_structures::small_c_str::SmallCStr;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
|
||||
use rustc_middle::ty::layout::{
|
||||
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, LayoutError, LayoutOfHelpers,
|
||||
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasTypingEnv, LayoutError, LayoutOfHelpers,
|
||||
TyAndLayout,
|
||||
};
|
||||
use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
|
||||
@ -81,9 +81,9 @@ impl<'tcx> ty::layout::HasTyCtxt<'tcx> for Builder<'_, '_, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> ty::layout::HasParamEnv<'tcx> for Builder<'_, '_, 'tcx> {
|
||||
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
||||
self.cx.param_env()
|
||||
impl<'tcx> ty::layout::HasTypingEnv<'tcx> for Builder<'_, '_, 'tcx> {
|
||||
fn typing_env(&self) -> ty::TypingEnv<'tcx> {
|
||||
self.cx.typing_env()
|
||||
}
|
||||
}
|
||||
|
||||
@ -472,7 +472,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
||||
#[instrument(level = "trace", skip(self))]
|
||||
fn load_operand(&mut self, place: PlaceRef<'tcx, &'ll Value>) -> OperandRef<'tcx, &'ll Value> {
|
||||
if place.layout.is_unsized() {
|
||||
let tail = self.tcx.struct_tail_for_codegen(place.layout.ty, self.param_env());
|
||||
let tail = self.tcx.struct_tail_for_codegen(place.layout.ty, self.typing_env());
|
||||
if matches!(tail.kind(), ty::Foreign(..)) {
|
||||
// Unsized locals and, at least conceptually, even unsized arguments must be copied
|
||||
// around, which requires dynamically determining their size. Therefore, we cannot
|
||||
|
@ -5,7 +5,7 @@
|
||||
//! closure.
|
||||
|
||||
use rustc_codegen_ssa::common;
|
||||
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt};
|
||||
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, HasTypingEnv};
|
||||
use rustc_middle::ty::{self, Instance, TypeVisitableExt};
|
||||
use tracing::debug;
|
||||
|
||||
@ -28,12 +28,7 @@ pub(crate) fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'t
|
||||
}
|
||||
|
||||
let sym = tcx.symbol_name(instance).name;
|
||||
debug!(
|
||||
"get_fn({:?}: {:?}) => {}",
|
||||
instance,
|
||||
instance.ty(cx.tcx(), ty::ParamEnv::reveal_all()),
|
||||
sym
|
||||
);
|
||||
debug!("get_fn({:?}: {:?}) => {}", instance, instance.ty(cx.tcx(), cx.typing_env()), sym);
|
||||
|
||||
let fn_abi = cx.fn_abi_of_instance(instance, ty::List::empty());
|
||||
|
||||
|
@ -13,8 +13,8 @@ use rustc_middle::mir::interpret::{
|
||||
read_target_uint,
|
||||
};
|
||||
use rustc_middle::mir::mono::MonoItem;
|
||||
use rustc_middle::ty::layout::LayoutOf;
|
||||
use rustc_middle::ty::{self, Instance};
|
||||
use rustc_middle::ty::Instance;
|
||||
use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_session::config::Lto;
|
||||
use tracing::{debug, instrument, trace};
|
||||
@ -244,7 +244,7 @@ impl<'ll> CodegenCx<'ll, '_> {
|
||||
let llty = if nested {
|
||||
self.type_i8()
|
||||
} else {
|
||||
let ty = instance.ty(self.tcx, ty::ParamEnv::reveal_all());
|
||||
let ty = instance.ty(self.tcx, self.typing_env());
|
||||
trace!(?ty);
|
||||
self.layout_of(ty).llvm_type(self)
|
||||
};
|
||||
|
@ -15,7 +15,7 @@ use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::middle::codegen_fn_attrs::PatchableFunctionEntry;
|
||||
use rustc_middle::mir::mono::CodegenUnit;
|
||||
use rustc_middle::ty::layout::{
|
||||
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, LayoutError, LayoutOfHelpers,
|
||||
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasTypingEnv, LayoutError, LayoutOfHelpers,
|
||||
};
|
||||
use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
@ -658,7 +658,7 @@ impl<'ll, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||
let llfn = match tcx.lang_items().eh_personality() {
|
||||
Some(def_id) if name.is_none() => self.get_fn_addr(ty::Instance::expect_resolve(
|
||||
tcx,
|
||||
ty::ParamEnv::reveal_all(),
|
||||
self.typing_env(),
|
||||
def_id,
|
||||
ty::List::empty(),
|
||||
DUMMY_SP,
|
||||
@ -1162,9 +1162,9 @@ impl<'tcx> ty::layout::HasTyCtxt<'tcx> for CodegenCx<'_, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, 'll> HasParamEnv<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
||||
ty::ParamEnv::reveal_all()
|
||||
impl<'tcx, 'll> HasTypingEnv<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||
fn typing_env(&self) -> ty::TypingEnv<'tcx> {
|
||||
ty::TypingEnv::fully_monomorphized()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@ use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_index::Idx;
|
||||
use rustc_index::bit_set::BitSet;
|
||||
use rustc_middle::mir::{Body, SourceScope};
|
||||
use rustc_middle::ty::layout::FnAbiOf;
|
||||
use rustc_middle::ty::layout::{FnAbiOf, HasTypingEnv};
|
||||
use rustc_middle::ty::{self, Instance};
|
||||
use rustc_session::config::DebugInfo;
|
||||
use rustc_span::BytePos;
|
||||
@ -118,7 +118,7 @@ fn make_mir_scope<'ll, 'tcx>(
|
||||
// if this is moved to `rustc_codegen_ssa::mir::debuginfo`.
|
||||
let callee = cx.tcx.instantiate_and_normalize_erasing_regions(
|
||||
instance.args,
|
||||
ty::ParamEnv::reveal_all(),
|
||||
cx.typing_env(),
|
||||
ty::EarlyBinder::bind(callee),
|
||||
);
|
||||
debug_context.inlined_function_scopes.entry(callee).or_insert_with(|| {
|
||||
|
@ -11,10 +11,9 @@ use rustc_codegen_ssa::traits::*;
|
||||
use rustc_hir::def::{CtorKind, DefKind};
|
||||
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
|
||||
use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf, TyAndLayout};
|
||||
use rustc_middle::ty::{
|
||||
self, AdtKind, CoroutineArgsExt, Instance, ParamEnv, PolyExistentialTraitRef, Ty, TyCtxt,
|
||||
Visibility,
|
||||
self, AdtKind, CoroutineArgsExt, Instance, PolyExistentialTraitRef, Ty, TyCtxt, Visibility,
|
||||
};
|
||||
use rustc_session::config::{self, DebugInfo, Lto};
|
||||
use rustc_span::symbol::Symbol;
|
||||
@ -301,9 +300,8 @@ fn build_subroutine_type_di_node<'ll, 'tcx>(
|
||||
.insert(unique_type_id, recursion_marker_type_di_node(cx));
|
||||
|
||||
let fn_ty = unique_type_id.expect_ty();
|
||||
let signature = cx
|
||||
.tcx
|
||||
.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), fn_ty.fn_sig(cx.tcx));
|
||||
let signature =
|
||||
cx.tcx.normalize_erasing_late_bound_regions(cx.typing_env(), fn_ty.fn_sig(cx.tcx));
|
||||
|
||||
let signature_di_nodes: SmallVec<_> = iter::once(
|
||||
// return type
|
||||
@ -1109,9 +1107,7 @@ fn build_upvar_field_di_nodes<'ll, 'tcx>(
|
||||
}
|
||||
};
|
||||
|
||||
assert!(
|
||||
up_var_tys.iter().all(|t| t == cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), t))
|
||||
);
|
||||
assert!(up_var_tys.iter().all(|t| t == cx.tcx.normalize_erasing_regions(cx.typing_env(), t)));
|
||||
|
||||
let capture_names = cx.tcx.closure_saved_names_of_captured_variables(def_id);
|
||||
let layout = cx.layout_of(closure_or_coroutine_ty);
|
||||
@ -1272,8 +1268,7 @@ fn build_generic_type_param_di_nodes<'ll, 'tcx>(
|
||||
let template_params: SmallVec<_> = iter::zip(args, names)
|
||||
.filter_map(|(kind, name)| {
|
||||
kind.as_type().map(|ty| {
|
||||
let actual_type =
|
||||
cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
|
||||
let actual_type = cx.tcx.normalize_erasing_regions(cx.typing_env(), ty);
|
||||
let actual_type_di_node = type_di_node(cx, actual_type);
|
||||
let name = name.as_str();
|
||||
unsafe {
|
||||
@ -1341,7 +1336,7 @@ pub(crate) fn build_global_var_di_node<'ll>(
|
||||
if nested {
|
||||
return;
|
||||
}
|
||||
let variable_type = Instance::mono(cx.tcx, def_id).ty(cx.tcx, ty::ParamEnv::reveal_all());
|
||||
let variable_type = Instance::mono(cx.tcx, def_id).ty(cx.tcx, cx.typing_env());
|
||||
let type_di_node = type_di_node(cx, variable_type);
|
||||
let var_name = tcx.item_name(def_id);
|
||||
let var_name = var_name.as_str();
|
||||
|
@ -6,7 +6,7 @@ use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_macros::HashStable;
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::ty::{ParamEnv, PolyExistentialTraitRef, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{self, PolyExistentialTraitRef, Ty, TyCtxt};
|
||||
|
||||
use super::{SmallVec, UNKNOWN_LINE_NUMBER, unknown_file_metadata};
|
||||
use crate::common::{AsCCharPtr, CodegenCx};
|
||||
@ -49,12 +49,15 @@ pub(super) enum UniqueTypeId<'tcx> {
|
||||
|
||||
impl<'tcx> UniqueTypeId<'tcx> {
|
||||
pub(crate) fn for_ty(tcx: TyCtxt<'tcx>, t: Ty<'tcx>) -> Self {
|
||||
assert_eq!(t, tcx.normalize_erasing_regions(ParamEnv::reveal_all(), t));
|
||||
assert_eq!(t, tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), t));
|
||||
UniqueTypeId::Ty(t, private::HiddenZst)
|
||||
}
|
||||
|
||||
pub(crate) fn for_enum_variant_part(tcx: TyCtxt<'tcx>, enum_ty: Ty<'tcx>) -> Self {
|
||||
assert_eq!(enum_ty, tcx.normalize_erasing_regions(ParamEnv::reveal_all(), enum_ty));
|
||||
assert_eq!(
|
||||
enum_ty,
|
||||
tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), enum_ty)
|
||||
);
|
||||
UniqueTypeId::VariantPart(enum_ty, private::HiddenZst)
|
||||
}
|
||||
|
||||
@ -63,7 +66,10 @@ impl<'tcx> UniqueTypeId<'tcx> {
|
||||
enum_ty: Ty<'tcx>,
|
||||
variant_idx: VariantIdx,
|
||||
) -> Self {
|
||||
assert_eq!(enum_ty, tcx.normalize_erasing_regions(ParamEnv::reveal_all(), enum_ty));
|
||||
assert_eq!(
|
||||
enum_ty,
|
||||
tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), enum_ty)
|
||||
);
|
||||
UniqueTypeId::VariantStructType(enum_ty, variant_idx, private::HiddenZst)
|
||||
}
|
||||
|
||||
@ -72,7 +78,10 @@ impl<'tcx> UniqueTypeId<'tcx> {
|
||||
enum_ty: Ty<'tcx>,
|
||||
variant_idx: VariantIdx,
|
||||
) -> Self {
|
||||
assert_eq!(enum_ty, tcx.normalize_erasing_regions(ParamEnv::reveal_all(), enum_ty));
|
||||
assert_eq!(
|
||||
enum_ty,
|
||||
tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), enum_ty)
|
||||
);
|
||||
UniqueTypeId::VariantStructTypeCppLikeWrapper(enum_ty, variant_idx, private::HiddenZst)
|
||||
}
|
||||
|
||||
@ -81,10 +90,13 @@ impl<'tcx> UniqueTypeId<'tcx> {
|
||||
self_type: Ty<'tcx>,
|
||||
implemented_trait: Option<PolyExistentialTraitRef<'tcx>>,
|
||||
) -> Self {
|
||||
assert_eq!(self_type, tcx.normalize_erasing_regions(ParamEnv::reveal_all(), self_type));
|
||||
assert_eq!(
|
||||
self_type,
|
||||
tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), self_type)
|
||||
);
|
||||
assert_eq!(
|
||||
implemented_trait,
|
||||
tcx.normalize_erasing_regions(ParamEnv::reveal_all(), implemented_trait)
|
||||
tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), implemented_trait)
|
||||
);
|
||||
UniqueTypeId::VTableTy(self_type, implemented_trait, private::HiddenZst)
|
||||
}
|
||||
|
@ -15,8 +15,8 @@ use rustc_data_structures::unord::UnordMap;
|
||||
use rustc_hir::def_id::{DefId, DefIdMap};
|
||||
use rustc_index::IndexVec;
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::ty::layout::LayoutOf;
|
||||
use rustc_middle::ty::{self, GenericArgsRef, Instance, ParamEnv, Ty, TypeVisitableExt};
|
||||
use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf};
|
||||
use rustc_middle::ty::{self, GenericArgsRef, Instance, Ty, TypeVisitableExt};
|
||||
use rustc_session::Session;
|
||||
use rustc_session::config::{self, DebugInfo};
|
||||
use rustc_span::symbol::Symbol;
|
||||
@ -344,7 +344,7 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||
|
||||
type_names::push_generic_params(
|
||||
tcx,
|
||||
tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), args),
|
||||
tcx.normalize_erasing_regions(self.typing_env(), args),
|
||||
&mut name,
|
||||
);
|
||||
|
||||
@ -481,8 +481,7 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||
iter::zip(args, names)
|
||||
.filter_map(|(kind, name)| {
|
||||
kind.as_type().map(|ty| {
|
||||
let actual_type =
|
||||
cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
|
||||
let actual_type = cx.tcx.normalize_erasing_regions(cx.typing_env(), ty);
|
||||
let actual_type_metadata = type_di_node(cx, actual_type);
|
||||
let name = name.as_str();
|
||||
unsafe {
|
||||
@ -526,7 +525,7 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||
if cx.tcx.trait_id_of_impl(impl_def_id).is_none() {
|
||||
let impl_self_ty = cx.tcx.instantiate_and_normalize_erasing_regions(
|
||||
instance.args,
|
||||
ty::ParamEnv::reveal_all(),
|
||||
cx.typing_env(),
|
||||
cx.tcx.type_of(impl_def_id),
|
||||
);
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Utility Functions.
|
||||
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::ty::layout::{HasParamEnv, LayoutOf};
|
||||
use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf};
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use tracing::trace;
|
||||
|
||||
@ -62,7 +62,7 @@ pub(crate) fn wide_pointer_kind<'ll, 'tcx>(
|
||||
cx: &CodegenCx<'ll, 'tcx>,
|
||||
pointee_ty: Ty<'tcx>,
|
||||
) -> Option<WidePtrKind> {
|
||||
let pointee_tail_ty = cx.tcx.struct_tail_for_codegen(pointee_ty, cx.param_env());
|
||||
let pointee_tail_ty = cx.tcx.struct_tail_for_codegen(pointee_ty, cx.typing_env());
|
||||
let layout = cx.layout_of(pointee_tail_ty);
|
||||
trace!(
|
||||
"wide_pointer_kind: {:?} has layout {:?} (is_unsized? {})",
|
||||
|
@ -10,7 +10,7 @@ use rustc_codegen_ssa::mir::place::{PlaceRef, PlaceValue};
|
||||
use rustc_codegen_ssa::traits::*;
|
||||
use rustc_hir as hir;
|
||||
use rustc_middle::mir::BinOp;
|
||||
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, LayoutOf};
|
||||
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, HasTypingEnv, LayoutOf};
|
||||
use rustc_middle::ty::{self, GenericArgsRef, Ty};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_span::{Span, Symbol, sym};
|
||||
@ -163,14 +163,14 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
|
||||
span: Span,
|
||||
) -> Result<(), ty::Instance<'tcx>> {
|
||||
let tcx = self.tcx;
|
||||
let callee_ty = instance.ty(tcx, ty::ParamEnv::reveal_all());
|
||||
let callee_ty = instance.ty(tcx, self.typing_env());
|
||||
|
||||
let ty::FnDef(def_id, fn_args) = *callee_ty.kind() else {
|
||||
bug!("expected fn item type, found {}", callee_ty);
|
||||
};
|
||||
|
||||
let sig = callee_ty.fn_sig(tcx);
|
||||
let sig = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), sig);
|
||||
let sig = tcx.normalize_erasing_late_bound_regions(self.typing_env(), sig);
|
||||
let arg_tys = sig.inputs();
|
||||
let ret_ty = sig.output();
|
||||
let name = tcx.item_name(def_id);
|
||||
@ -1152,8 +1152,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
|
||||
}
|
||||
|
||||
let tcx = bx.tcx();
|
||||
let sig =
|
||||
tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), callee_ty.fn_sig(tcx));
|
||||
let sig = tcx.normalize_erasing_late_bound_regions(bx.typing_env(), callee_ty.fn_sig(tcx));
|
||||
let arg_tys = sig.inputs();
|
||||
|
||||
// Sanity-check: all vector arguments must be immediates.
|
||||
@ -2187,7 +2186,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
|
||||
match in_elem.kind() {
|
||||
ty::RawPtr(p_ty, _) => {
|
||||
let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| {
|
||||
bx.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), ty)
|
||||
bx.tcx.normalize_erasing_regions(bx.typing_env(), ty)
|
||||
});
|
||||
require!(metadata.is_unit(), InvalidMonomorphization::CastWidePointer {
|
||||
span,
|
||||
@ -2202,7 +2201,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
|
||||
match out_elem.kind() {
|
||||
ty::RawPtr(p_ty, _) => {
|
||||
let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| {
|
||||
bx.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), ty)
|
||||
bx.tcx.normalize_erasing_regions(bx.typing_env(), ty)
|
||||
});
|
||||
require!(metadata.is_unit(), InvalidMonomorphization::CastWidePointer {
|
||||
span,
|
||||
|
@ -3,7 +3,7 @@ use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::mir::mono::{Linkage, Visibility};
|
||||
use rustc_middle::ty::layout::{FnAbiOf, LayoutOf};
|
||||
use rustc_middle::ty::layout::{FnAbiOf, HasTypingEnv, LayoutOf};
|
||||
use rustc_middle::ty::{self, Instance, TypeVisitableExt};
|
||||
use rustc_session::config::CrateType;
|
||||
use rustc_target::spec::RelocModel;
|
||||
@ -26,11 +26,8 @@ impl<'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
|
||||
let DefKind::Static { nested, .. } = self.tcx.def_kind(def_id) else { bug!() };
|
||||
// Nested statics do not have a type, so pick a dummy type and let `codegen_static` figure
|
||||
// out the llvm type from the actual evaluated initializer.
|
||||
let ty = if nested {
|
||||
self.tcx.types.unit
|
||||
} else {
|
||||
instance.ty(self.tcx, ty::ParamEnv::reveal_all())
|
||||
};
|
||||
let ty =
|
||||
if nested { self.tcx.types.unit } else { instance.ty(self.tcx, self.typing_env()) };
|
||||
let llty = self.layout_of(ty).llvm_type(self);
|
||||
|
||||
let g = self.define_global(symbol_name, llty).unwrap_or_else(|| {
|
||||
|
@ -595,8 +595,10 @@ pub(crate) fn linking_symbol_name_for_instance_in_crate<'tcx>(
|
||||
|
||||
let (conv, args) = instance
|
||||
.map(|i| {
|
||||
tcx.fn_abi_of_instance(ty::ParamEnv::reveal_all().and((i, ty::List::empty())))
|
||||
.unwrap_or_else(|_| bug!("fn_abi_of_instance({i:?}) failed"))
|
||||
tcx.fn_abi_of_instance(
|
||||
ty::TypingEnv::fully_monomorphized().as_query_input((i, ty::List::empty())),
|
||||
)
|
||||
.unwrap_or_else(|_| bug!("fn_abi_of_instance({i:?}) failed"))
|
||||
})
|
||||
.map(|fnabi| (fnabi.conv, &fnabi.args[..]))
|
||||
.unwrap_or((Conv::Rust, &[]));
|
||||
|
@ -21,7 +21,7 @@ use rustc_middle::middle::{exported_symbols, lang_items};
|
||||
use rustc_middle::mir::BinOp;
|
||||
use rustc_middle::mir::mono::{CodegenUnit, CodegenUnitNameBuilder, MonoItem};
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout};
|
||||
use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutOf, TyAndLayout};
|
||||
use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypingMode};
|
||||
use rustc_session::Session;
|
||||
use rustc_session::config::{self, CrateType, EntryFnType, OptLevel, OutputType};
|
||||
@ -165,7 +165,7 @@ fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
||||
) -> Bx::Value {
|
||||
let cx = bx.cx();
|
||||
let (source, target) =
|
||||
cx.tcx().struct_lockstep_tails_for_codegen(source, target, bx.param_env());
|
||||
cx.tcx().struct_lockstep_tails_for_codegen(source, target, bx.typing_env());
|
||||
match (source.kind(), target.kind()) {
|
||||
(&ty::Array(_, len), &ty::Slice(_)) => cx.const_usize(
|
||||
len.try_to_target_usize(cx.tcx()).expect("expected monomorphic const in codegen"),
|
||||
@ -466,10 +466,9 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
||||
// late-bound regions, since late-bound
|
||||
// regions must appear in the argument
|
||||
// listing.
|
||||
let main_ret_ty = cx.tcx().normalize_erasing_regions(
|
||||
ty::ParamEnv::reveal_all(),
|
||||
main_ret_ty.no_bound_vars().unwrap(),
|
||||
);
|
||||
let main_ret_ty = cx
|
||||
.tcx()
|
||||
.normalize_erasing_regions(cx.typing_env(), main_ret_ty.no_bound_vars().unwrap());
|
||||
|
||||
let Some(llfn) = cx.declare_c_main(llfty) else {
|
||||
// FIXME: We should be smart and show a better diagnostic here.
|
||||
@ -495,7 +494,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
||||
let start_def_id = cx.tcx().require_lang_item(LangItem::Start, None);
|
||||
let start_instance = ty::Instance::expect_resolve(
|
||||
cx.tcx(),
|
||||
ty::ParamEnv::reveal_all(),
|
||||
cx.typing_env(),
|
||||
start_def_id,
|
||||
cx.tcx().mk_args(&[main_ret_ty.into()]),
|
||||
DUMMY_SP,
|
||||
|
@ -21,9 +21,7 @@ use rustc_hir::definitions::{DefPathData, DefPathDataName, DisambiguatedDefPathD
|
||||
use rustc_hir::{CoroutineDesugaring, CoroutineKind, CoroutineSource, Mutability};
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::ty::layout::{IntegerExt, TyAndLayout};
|
||||
use rustc_middle::ty::{
|
||||
self, ExistentialProjection, GenericArgKind, GenericArgsRef, ParamEnv, Ty, TyCtxt,
|
||||
};
|
||||
use rustc_middle::ty::{self, ExistentialProjection, GenericArgKind, GenericArgsRef, Ty, TyCtxt};
|
||||
use smallvec::SmallVec;
|
||||
|
||||
use crate::debuginfo::wants_c_like_enum_debuginfo;
|
||||
@ -82,7 +80,7 @@ fn push_debuginfo_type_name<'tcx>(
|
||||
ty::Adt(def, args) => {
|
||||
// `layout_for_cpp_like_fallback` will be `Some` if we want to use the fallback encoding.
|
||||
let layout_for_cpp_like_fallback = if cpp_like_debuginfo && def.is_enum() {
|
||||
match tcx.layout_of(ParamEnv::reveal_all().and(t)) {
|
||||
match tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(t)) {
|
||||
Ok(layout) => {
|
||||
if !wants_c_like_enum_debuginfo(tcx, layout) {
|
||||
Some(layout)
|
||||
@ -248,8 +246,10 @@ fn push_debuginfo_type_name<'tcx>(
|
||||
};
|
||||
|
||||
if let Some(principal) = trait_data.principal() {
|
||||
let principal =
|
||||
tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), principal);
|
||||
let principal = tcx.normalize_erasing_late_bound_regions(
|
||||
ty::TypingEnv::fully_monomorphized(),
|
||||
principal,
|
||||
);
|
||||
push_item_name(tcx, principal.def_id, qualified, output);
|
||||
let principal_has_generic_params =
|
||||
push_generic_params_internal(tcx, principal.args, output, visited);
|
||||
@ -350,8 +350,10 @@ fn push_debuginfo_type_name<'tcx>(
|
||||
return;
|
||||
}
|
||||
|
||||
let sig =
|
||||
tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), t.fn_sig(tcx));
|
||||
let sig = tcx.normalize_erasing_late_bound_regions(
|
||||
ty::TypingEnv::fully_monomorphized(),
|
||||
t.fn_sig(tcx),
|
||||
);
|
||||
|
||||
if cpp_like_debuginfo {
|
||||
// Format as a C++ function pointer: return_type (*)(params...)
|
||||
@ -415,7 +417,8 @@ fn push_debuginfo_type_name<'tcx>(
|
||||
// In the case of cpp-like debuginfo, the name additionally gets wrapped inside of
|
||||
// an artificial `enum2$<>` type, as defined in msvc_enum_fallback().
|
||||
if cpp_like_debuginfo && t.is_coroutine() {
|
||||
let ty_and_layout = tcx.layout_of(ParamEnv::reveal_all().and(t)).unwrap();
|
||||
let ty_and_layout =
|
||||
tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(t)).unwrap();
|
||||
msvc_enum_fallback(
|
||||
tcx,
|
||||
ty_and_layout,
|
||||
@ -529,8 +532,8 @@ pub fn compute_debuginfo_vtable_name<'tcx>(
|
||||
}
|
||||
|
||||
if let Some(trait_ref) = trait_ref {
|
||||
let trait_ref =
|
||||
tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), trait_ref);
|
||||
let trait_ref = tcx
|
||||
.normalize_erasing_late_bound_regions(ty::TypingEnv::fully_monomorphized(), trait_ref);
|
||||
push_item_name(tcx, trait_ref.def_id, true, &mut vtable_name);
|
||||
visited.clear();
|
||||
push_generic_params_internal(tcx, trait_ref.args, &mut vtable_name, &mut visited);
|
||||
@ -639,7 +642,7 @@ fn push_generic_params_internal<'tcx>(
|
||||
output: &mut String,
|
||||
visited: &mut FxHashSet<Ty<'tcx>>,
|
||||
) -> bool {
|
||||
assert_eq!(args, tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), args));
|
||||
assert_eq!(args, tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), args));
|
||||
let mut args = args.non_erasable_generics().peekable();
|
||||
if args.peek().is_none() {
|
||||
return false;
|
||||
@ -678,14 +681,14 @@ fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: ty::Const<'tcx>, output: &mut S
|
||||
// FIXME: directly extract the bits from a valtree instead of evaluating an
|
||||
// already evaluated `Const` in order to get the bits.
|
||||
let bits = ct
|
||||
.try_to_bits(tcx, ty::ParamEnv::reveal_all())
|
||||
.try_to_bits(tcx, ty::TypingEnv::fully_monomorphized())
|
||||
.expect("expected monomorphic const in codegen");
|
||||
let val = Integer::from_int_ty(&tcx, *ity).size().sign_extend(bits) as i128;
|
||||
write!(output, "{val}")
|
||||
}
|
||||
ty::Uint(_) => {
|
||||
let val = ct
|
||||
.try_to_bits(tcx, ty::ParamEnv::reveal_all())
|
||||
.try_to_bits(tcx, ty::TypingEnv::fully_monomorphized())
|
||||
.expect("expected monomorphic const in codegen");
|
||||
write!(output, "{val}")
|
||||
}
|
||||
|
@ -777,7 +777,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
|
||||
let do_panic = !bx
|
||||
.tcx()
|
||||
.check_validity_requirement((requirement, bx.param_env().and(ty)))
|
||||
.check_validity_requirement((requirement, bx.typing_env().as_query_input(ty)))
|
||||
.expect("expect to have layout during codegen");
|
||||
|
||||
let layout = bx.layout_of(ty);
|
||||
@ -848,14 +848,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
let (instance, mut llfn) = match *callee.layout.ty.kind() {
|
||||
ty::FnDef(def_id, args) => (
|
||||
Some(
|
||||
ty::Instance::expect_resolve(
|
||||
bx.tcx(),
|
||||
ty::ParamEnv::reveal_all(),
|
||||
def_id,
|
||||
args,
|
||||
fn_span,
|
||||
)
|
||||
.polymorphize(bx.tcx()),
|
||||
ty::Instance::expect_resolve(bx.tcx(), bx.typing_env(), def_id, args, fn_span)
|
||||
.polymorphize(bx.tcx()),
|
||||
),
|
||||
None,
|
||||
),
|
||||
@ -1191,7 +1185,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
if let ty::FnDef(def_id, args) = *const_.ty().kind() {
|
||||
let instance = ty::Instance::resolve_for_fn_ptr(
|
||||
bx.tcx(),
|
||||
ty::ParamEnv::reveal_all(),
|
||||
bx.typing_env(),
|
||||
def_id,
|
||||
args,
|
||||
)
|
||||
|
@ -1,6 +1,6 @@
|
||||
use rustc_abi::BackendRepr;
|
||||
use rustc_middle::mir::interpret::ErrorHandled;
|
||||
use rustc_middle::ty::layout::HasTyCtxt;
|
||||
use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv};
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use rustc_middle::{bug, mir, span_bug};
|
||||
|
||||
@ -24,7 +24,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
// `MirUsedCollector` visited all required_consts before codegen began, so if we got here
|
||||
// there can be no more constants that fail to evaluate.
|
||||
self.monomorphize(constant.const_)
|
||||
.eval(self.cx.tcx(), ty::ParamEnv::reveal_all(), constant.span)
|
||||
.eval(self.cx.tcx(), self.cx.typing_env(), constant.span)
|
||||
.expect("erroneous constant missed by mono item collection")
|
||||
}
|
||||
|
||||
@ -57,7 +57,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
other => span_bug!(constant.span, "{other:#?}"),
|
||||
};
|
||||
let uv = self.monomorphize(uv);
|
||||
self.cx.tcx().const_eval_resolve_for_typeck(ty::ParamEnv::reveal_all(), uv, constant.span)
|
||||
self.cx.tcx().const_eval_resolve_for_typeck(self.cx.typing_env(), uv, constant.span)
|
||||
}
|
||||
|
||||
/// process constant containing SIMD shuffle indices & constant vectors
|
||||
|
@ -59,14 +59,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
llresult: Bx::Value,
|
||||
span: Span,
|
||||
) -> Result<(), ty::Instance<'tcx>> {
|
||||
let callee_ty = instance.ty(bx.tcx(), ty::ParamEnv::reveal_all());
|
||||
let callee_ty = instance.ty(bx.tcx(), bx.typing_env());
|
||||
|
||||
let ty::FnDef(def_id, fn_args) = *callee_ty.kind() else {
|
||||
bug!("expected fn item type, found {}", callee_ty);
|
||||
};
|
||||
|
||||
let sig = callee_ty.fn_sig(bx.tcx());
|
||||
let sig = bx.tcx().normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), sig);
|
||||
let sig = bx.tcx().normalize_erasing_late_bound_regions(bx.typing_env(), sig);
|
||||
let arg_tys = sig.inputs();
|
||||
let ret_ty = sig.output();
|
||||
let name = bx.tcx().item_name(def_id);
|
||||
|
@ -4,7 +4,7 @@ use rustc_index::IndexVec;
|
||||
use rustc_index::bit_set::BitSet;
|
||||
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
||||
use rustc_middle::mir::{UnwindTerminateReason, traversal};
|
||||
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, TyAndLayout};
|
||||
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, HasTypingEnv, TyAndLayout};
|
||||
use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
|
||||
use rustc_middle::{bug, mir, span_bug};
|
||||
use rustc_target::callconv::{FnAbi, PassMode};
|
||||
@ -128,7 +128,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
debug!("monomorphize: self.instance={:?}", self.instance);
|
||||
self.instance.instantiate_mir_and_normalize_erasing_regions(
|
||||
self.cx.tcx(),
|
||||
ty::ParamEnv::reveal_all(),
|
||||
self.cx.typing_env(),
|
||||
ty::EarlyBinder::bind(value),
|
||||
)
|
||||
}
|
||||
|
@ -474,7 +474,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
ty::FnDef(def_id, args) => {
|
||||
let instance = ty::Instance::resolve_for_fn_ptr(
|
||||
bx.tcx(),
|
||||
ty::ParamEnv::reveal_all(),
|
||||
bx.typing_env(),
|
||||
def_id,
|
||||
args,
|
||||
)
|
||||
@ -709,7 +709,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
mir::NullOp::OffsetOf(fields) => {
|
||||
let val = bx
|
||||
.tcx()
|
||||
.offset_of_subfield(bx.param_env(), layout, fields.iter())
|
||||
.offset_of_subfield(bx.typing_env(), layout, fields.iter())
|
||||
.bytes();
|
||||
bx.cx().const_usize(val)
|
||||
}
|
||||
@ -727,7 +727,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
|
||||
mir::Rvalue::ThreadLocalRef(def_id) => {
|
||||
assert!(bx.cx().tcx().is_static(def_id));
|
||||
let layout = bx.layout_of(bx.cx().tcx().static_ptr_ty(def_id));
|
||||
let layout = bx.layout_of(bx.cx().tcx().static_ptr_ty(def_id, bx.typing_env()));
|
||||
let static_ = if !def_id.is_local() && bx.cx().tcx().needs_thread_local_shim(def_id)
|
||||
{
|
||||
let instance = ty::Instance {
|
||||
|
@ -1,6 +1,6 @@
|
||||
use rustc_abi::{AddressSpace, Float, Integer};
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::ty::layout::{HasTyCtxt, TyAndLayout};
|
||||
use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, TyAndLayout};
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use rustc_target::callconv::{ArgAbi, CastTarget, FnAbi, Reg};
|
||||
|
||||
@ -41,7 +41,7 @@ pub trait BaseTypeCodegenMethods<'tcx>: BackendTypes {
|
||||
}
|
||||
|
||||
pub trait DerivedTypeCodegenMethods<'tcx>:
|
||||
BaseTypeCodegenMethods<'tcx> + MiscCodegenMethods<'tcx> + HasTyCtxt<'tcx>
|
||||
BaseTypeCodegenMethods<'tcx> + MiscCodegenMethods<'tcx> + HasTyCtxt<'tcx> + HasTypingEnv<'tcx>
|
||||
{
|
||||
fn type_int(&self) -> Self::Type {
|
||||
match &self.sess().target.c_int_width[..] {
|
||||
@ -74,7 +74,7 @@ pub trait DerivedTypeCodegenMethods<'tcx>:
|
||||
}
|
||||
|
||||
fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool {
|
||||
ty.needs_drop(self.tcx(), ty::ParamEnv::reveal_all())
|
||||
ty.needs_drop(self.tcx(), self.typing_env())
|
||||
}
|
||||
|
||||
fn type_is_sized(&self, ty: Ty<'tcx>) -> bool {
|
||||
@ -86,12 +86,11 @@ pub trait DerivedTypeCodegenMethods<'tcx>:
|
||||
}
|
||||
|
||||
fn type_has_metadata(&self, ty: Ty<'tcx>) -> bool {
|
||||
let param_env = ty::ParamEnv::reveal_all();
|
||||
if ty.is_sized(self.tcx(), param_env) {
|
||||
if ty.is_sized(self.tcx(), self.param_env()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let tail = self.tcx().struct_tail_for_codegen(ty, param_env);
|
||||
let tail = self.tcx().struct_tail_for_codegen(ty, self.typing_env());
|
||||
match tail.kind() {
|
||||
ty::Foreign(..) => false,
|
||||
ty::Str | ty::Slice(..) | ty::Dynamic(..) => true,
|
||||
@ -101,7 +100,10 @@ pub trait DerivedTypeCodegenMethods<'tcx>:
|
||||
}
|
||||
|
||||
impl<'tcx, T> DerivedTypeCodegenMethods<'tcx> for T where
|
||||
Self: BaseTypeCodegenMethods<'tcx> + MiscCodegenMethods<'tcx> + HasTyCtxt<'tcx>
|
||||
Self: BaseTypeCodegenMethods<'tcx>
|
||||
+ MiscCodegenMethods<'tcx>
|
||||
+ HasTyCtxt<'tcx>
|
||||
+ HasTypingEnv<'tcx>
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -388,7 +388,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
|
||||
return false;
|
||||
}
|
||||
|
||||
let infcx = tcx.infer_ctxt().build(self.body.typing_mode(tcx));
|
||||
let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(self.body.typing_env(tcx));
|
||||
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
|
||||
|
||||
let body_id = self.body.source.def_id().expect_local();
|
||||
@ -398,11 +398,8 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
|
||||
ty::BoundConstness::Const
|
||||
}
|
||||
};
|
||||
let const_conditions = ocx.normalize(
|
||||
&ObligationCause::misc(call_span, body_id),
|
||||
self.param_env,
|
||||
const_conditions,
|
||||
);
|
||||
let const_conditions =
|
||||
ocx.normalize(&ObligationCause::misc(call_span, body_id), param_env, const_conditions);
|
||||
ocx.register_obligations(const_conditions.into_iter().map(|(trait_ref, span)| {
|
||||
Obligation::new(
|
||||
tcx,
|
||||
@ -411,7 +408,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
|
||||
body_id,
|
||||
ObligationCauseCode::WhereClause(callee, span),
|
||||
),
|
||||
self.param_env,
|
||||
param_env,
|
||||
trait_ref.to_host_effect_clause(tcx, host_polarity),
|
||||
)
|
||||
}));
|
||||
|
@ -24,17 +24,15 @@ mod resolver;
|
||||
pub struct ConstCx<'mir, 'tcx> {
|
||||
pub body: &'mir mir::Body<'tcx>,
|
||||
pub tcx: TyCtxt<'tcx>,
|
||||
pub param_env: ty::ParamEnv<'tcx>,
|
||||
pub typing_env: ty::TypingEnv<'tcx>,
|
||||
pub const_kind: Option<hir::ConstContext>,
|
||||
}
|
||||
|
||||
impl<'mir, 'tcx> ConstCx<'mir, 'tcx> {
|
||||
pub fn new(tcx: TyCtxt<'tcx>, body: &'mir mir::Body<'tcx>) -> Self {
|
||||
let def_id = body.source.def_id().expect_local();
|
||||
let param_env = tcx.param_env(def_id);
|
||||
|
||||
let typing_env = body.typing_env(tcx);
|
||||
let const_kind = tcx.hir().body_const_context(body.source.def_id().expect_local());
|
||||
ConstCx { body, tcx, param_env, const_kind }
|
||||
ConstCx { body, tcx, typing_env, const_kind }
|
||||
}
|
||||
|
||||
pub(crate) fn dcx(&self) -> DiagCtxtHandle<'tcx> {
|
||||
|
@ -120,7 +120,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
|
||||
#[allow(rustc::untranslatable_diagnostic)]
|
||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, _: Span) -> Diag<'tcx> {
|
||||
let FnCallNonConst { callee, args, span, call_source } = *self;
|
||||
let ConstCx { tcx, param_env, .. } = *ccx;
|
||||
let ConstCx { tcx, typing_env, .. } = *ccx;
|
||||
let caller = ccx.def_id();
|
||||
|
||||
let diag_trait = |err, self_ty: Ty<'_>, trait_id| {
|
||||
@ -146,13 +146,11 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
|
||||
}
|
||||
}
|
||||
ty::Adt(..) => {
|
||||
let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env);
|
||||
let obligation =
|
||||
Obligation::new(tcx, ObligationCause::dummy(), param_env, trait_ref);
|
||||
|
||||
let infcx = tcx.infer_ctxt().build(ccx.body.typing_mode(tcx));
|
||||
let mut selcx = SelectionContext::new(&infcx);
|
||||
let implsrc = selcx.select(&obligation);
|
||||
|
||||
if let Ok(Some(ImplSource::UserDefined(data))) = implsrc {
|
||||
// FIXME(const_trait_impl) revisit this
|
||||
if !tcx.is_const_trait_impl(data.impl_def_id) {
|
||||
@ -166,7 +164,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
|
||||
};
|
||||
|
||||
let call_kind =
|
||||
call_kind(tcx, ccx.param_env, callee, args, span, call_source.from_hir_call(), None);
|
||||
call_kind(tcx, ccx.typing_env, callee, args, span, call_source.from_hir_call(), None);
|
||||
|
||||
debug!(?call_kind);
|
||||
|
||||
|
@ -32,17 +32,15 @@ pub fn checking_enabled(ccx: &ConstCx<'_, '_>) -> bool {
|
||||
/// This is separate from the rest of the const checking logic because it must run after drop
|
||||
/// elaboration.
|
||||
pub fn check_live_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mir::Body<'tcx>) {
|
||||
let def_id = body.source.def_id().expect_local();
|
||||
let const_kind = tcx.hir().body_const_context(def_id);
|
||||
if const_kind.is_none() {
|
||||
let ccx = ConstCx::new(tcx, body);
|
||||
if ccx.const_kind.is_none() {
|
||||
return;
|
||||
}
|
||||
|
||||
if tcx.has_attr(def_id, sym::rustc_do_not_const_check) {
|
||||
if tcx.has_attr(body.source.def_id(), sym::rustc_do_not_const_check) {
|
||||
return;
|
||||
}
|
||||
|
||||
let ccx = ConstCx { body, tcx, const_kind, param_env: tcx.param_env(def_id) };
|
||||
if !checking_enabled(&ccx) {
|
||||
return;
|
||||
}
|
||||
|
@ -106,20 +106,24 @@ impl Qualif for HasMutInterior {
|
||||
// Instead we invoke an obligation context manually, and provide the opaque type inference settings
|
||||
// that allow the trait solver to just error out instead of cycling.
|
||||
let freeze_def_id = cx.tcx.require_lang_item(LangItem::Freeze, Some(cx.body.span));
|
||||
|
||||
// FIXME(#132279): Once we've got a typing mode which reveals opaque types using the HIR
|
||||
// typeck results without causing query cycles, we should use this here instead of defining
|
||||
// opaque types.
|
||||
let typing_env = ty::TypingEnv {
|
||||
typing_mode: ty::TypingMode::analysis_in_body(
|
||||
cx.tcx,
|
||||
cx.body.source.def_id().expect_local(),
|
||||
),
|
||||
param_env: cx.typing_env.param_env,
|
||||
};
|
||||
let (infcx, param_env) = cx.tcx.infer_ctxt().build_with_typing_env(typing_env);
|
||||
let ocx = ObligationCtxt::new(&infcx);
|
||||
let obligation = Obligation::new(
|
||||
cx.tcx,
|
||||
ObligationCause::dummy_with_span(cx.body.span),
|
||||
cx.param_env,
|
||||
param_env,
|
||||
ty::TraitRef::new(cx.tcx, freeze_def_id, [ty::GenericArg::from(ty)]),
|
||||
);
|
||||
|
||||
// FIXME(#132279): This should eventually use the already defined hidden types.
|
||||
let infcx = cx.tcx.infer_ctxt().build(ty::TypingMode::analysis_in_body(
|
||||
cx.tcx,
|
||||
cx.body.source.def_id().expect_local(),
|
||||
));
|
||||
let ocx = ObligationCtxt::new(&infcx);
|
||||
ocx.register_obligation(obligation);
|
||||
let errors = ocx.select_all_or_error();
|
||||
!errors.is_empty()
|
||||
@ -156,7 +160,7 @@ impl Qualif for NeedsDrop {
|
||||
}
|
||||
|
||||
fn in_any_value_of_ty<'tcx>(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
ty.needs_drop(cx.tcx, cx.param_env)
|
||||
ty.needs_drop(cx.tcx, cx.typing_env)
|
||||
}
|
||||
|
||||
fn in_adt_inherently<'tcx>(
|
||||
|
@ -120,7 +120,10 @@ where
|
||||
///
|
||||
/// [rust-lang/unsafe-code-guidelines#134]: https://github.com/rust-lang/unsafe-code-guidelines/issues/134
|
||||
fn shared_borrow_allows_mutation(&self, place: mir::Place<'tcx>) -> bool {
|
||||
!place.ty(self.ccx.body, self.ccx.tcx).ty.is_freeze(self.ccx.tcx, self.ccx.param_env)
|
||||
!place
|
||||
.ty(self.ccx.body, self.ccx.tcx)
|
||||
.ty
|
||||
.is_freeze(self.ccx.tcx, self.ccx.typing_env.param_env)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -221,7 +221,7 @@ pub(super) fn op_to_const<'tcx>(
|
||||
let pointee_ty = imm.layout.ty.builtin_deref(false).unwrap(); // `false` = no raw ptrs
|
||||
debug_assert!(
|
||||
matches!(
|
||||
ecx.tcx.struct_tail_for_codegen(pointee_ty, ecx.param_env).kind(),
|
||||
ecx.tcx.struct_tail_for_codegen(pointee_ty, ecx.typing_env()).kind(),
|
||||
ty::Str | ty::Slice(..),
|
||||
),
|
||||
"`ConstValue::Slice` is for slice-tailed types only, but got {}",
|
||||
@ -280,11 +280,13 @@ pub fn eval_to_const_value_raw_provider<'tcx>(
|
||||
// opaque types. This is needed for trivial things like `size_of`, but also for using associated
|
||||
// types that are not specified in the opaque type.
|
||||
assert_eq!(key.param_env.reveal(), Reveal::All);
|
||||
let typing_env =
|
||||
ty::TypingEnv { typing_mode: ty::TypingMode::PostAnalysis, param_env: key.param_env };
|
||||
|
||||
// We call `const_eval` for zero arg intrinsics, too, in order to cache their value.
|
||||
// Catch such calls and evaluate them instead of trying to load a constant's MIR.
|
||||
if let ty::InstanceKind::Intrinsic(def_id) = key.value.instance.def {
|
||||
let ty = key.value.instance.ty(tcx, key.param_env);
|
||||
let ty = key.value.instance.ty(tcx, typing_env);
|
||||
let ty::FnDef(_, args) = ty.kind() else {
|
||||
bug!("intrinsic with type {:?}", ty);
|
||||
};
|
||||
|
@ -249,9 +249,10 @@ impl<'tcx> CompileTimeInterpCx<'tcx> {
|
||||
} else if self.tcx.is_lang_item(def_id, LangItem::PanicFmt) {
|
||||
// For panic_fmt, call const_panic_fmt instead.
|
||||
let const_def_id = self.tcx.require_lang_item(LangItem::ConstPanicFmt, None);
|
||||
// FIXME(@lcnr): why does this use an empty env if we've got a `param_env` right here.
|
||||
let new_instance = ty::Instance::expect_resolve(
|
||||
*self.tcx,
|
||||
ty::ParamEnv::reveal_all(),
|
||||
ty::TypingEnv::fully_monomorphized(),
|
||||
const_def_id,
|
||||
instance.args,
|
||||
self.cur_span(),
|
||||
|
@ -2,6 +2,7 @@ use rustc_abi::{BackendRepr, VariantIdx};
|
||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId};
|
||||
use rustc_middle::ty::layout::{LayoutCx, LayoutOf, TyAndLayout};
|
||||
use rustc_middle::ty::solve::Reveal;
|
||||
use rustc_middle::ty::{self, ScalarInt, Ty, TyCtxt};
|
||||
use rustc_middle::{bug, mir};
|
||||
use rustc_span::DUMMY_SP;
|
||||
@ -281,8 +282,9 @@ pub fn valtree_to_const_value<'tcx>(
|
||||
// the `ValTree` and using `place_projection` and `place_field` to
|
||||
// create inner `MPlace`s which are filled recursively.
|
||||
// FIXME Does this need an example?
|
||||
|
||||
let (param_env, ty) = param_env_ty.into_parts();
|
||||
debug_assert_eq!(param_env.reveal(), Reveal::All);
|
||||
let typing_env = ty::TypingEnv { typing_mode: ty::TypingMode::PostAnalysis, param_env };
|
||||
|
||||
match *ty.kind() {
|
||||
ty::FnDef(..) => {
|
||||
@ -302,11 +304,12 @@ pub fn valtree_to_const_value<'tcx>(
|
||||
let mut ecx =
|
||||
mk_eval_cx_to_read_const_val(tcx, DUMMY_SP, param_env, CanAccessMutGlobal::No);
|
||||
let imm = valtree_to_ref(&mut ecx, valtree, inner_ty);
|
||||
let imm = ImmTy::from_immediate(imm, tcx.layout_of(param_env_ty).unwrap());
|
||||
let imm =
|
||||
ImmTy::from_immediate(imm, tcx.layout_of(typing_env.as_query_input(ty)).unwrap());
|
||||
op_to_const(&ecx, &imm.into(), /* for diagnostics */ false)
|
||||
}
|
||||
ty::Tuple(_) | ty::Array(_, _) | ty::Adt(..) => {
|
||||
let layout = tcx.layout_of(param_env_ty).unwrap();
|
||||
let layout = tcx.layout_of(typing_env.as_query_input(ty)).unwrap();
|
||||
if layout.is_zst() {
|
||||
// Fast path to avoid some allocations.
|
||||
return mir::ConstValue::ZeroSized;
|
||||
@ -319,7 +322,7 @@ pub fn valtree_to_const_value<'tcx>(
|
||||
let branches = valtree.unwrap_branch();
|
||||
// Find the non-ZST field. (There can be aligned ZST!)
|
||||
for (i, &inner_valtree) in branches.iter().enumerate() {
|
||||
let field = layout.field(&LayoutCx::new(tcx, param_env), i);
|
||||
let field = layout.field(&LayoutCx::new(tcx, typing_env), i);
|
||||
if !field.is_zst() {
|
||||
return valtree_to_const_value(tcx, param_env.and(field.ty), inner_valtree);
|
||||
}
|
||||
|
@ -215,7 +215,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
// Even if `ty` is normalized, the search for the unsized tail will project
|
||||
// to fields, which can yield non-normalized types. So we need to provide a
|
||||
// normalization function.
|
||||
let normalize = |ty| self.tcx.normalize_erasing_regions(self.param_env, ty);
|
||||
let normalize = |ty| self.tcx.normalize_erasing_regions(self.typing_env(), ty);
|
||||
ty.ptr_metadata_ty(*self.tcx, normalize)
|
||||
};
|
||||
return interp_ok(meta_ty(caller) == meta_ty(callee));
|
||||
@ -652,35 +652,35 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
};
|
||||
|
||||
// Obtain the underlying trait we are working on, and the adjusted receiver argument.
|
||||
let (trait_, dyn_ty, adjusted_recv) = if let ty::Dynamic(data, _, ty::DynStar) =
|
||||
receiver_place.layout.ty.kind()
|
||||
{
|
||||
let recv = self.unpack_dyn_star(&receiver_place, data)?;
|
||||
let (trait_, dyn_ty, adjusted_recv) =
|
||||
if let ty::Dynamic(data, _, ty::DynStar) = receiver_place.layout.ty.kind() {
|
||||
let recv = self.unpack_dyn_star(&receiver_place, data)?;
|
||||
|
||||
(data.principal(), recv.layout.ty, recv.ptr())
|
||||
} else {
|
||||
// Doesn't have to be a `dyn Trait`, but the unsized tail must be `dyn Trait`.
|
||||
// (For that reason we also cannot use `unpack_dyn_trait`.)
|
||||
let receiver_tail =
|
||||
self.tcx.struct_tail_for_codegen(receiver_place.layout.ty, self.param_env);
|
||||
let ty::Dynamic(receiver_trait, _, ty::Dyn) = receiver_tail.kind() else {
|
||||
span_bug!(
|
||||
self.cur_span(),
|
||||
"dynamic call on non-`dyn` type {}",
|
||||
receiver_tail
|
||||
)
|
||||
(data.principal(), recv.layout.ty, recv.ptr())
|
||||
} else {
|
||||
// Doesn't have to be a `dyn Trait`, but the unsized tail must be `dyn Trait`.
|
||||
// (For that reason we also cannot use `unpack_dyn_trait`.)
|
||||
let receiver_tail = self
|
||||
.tcx
|
||||
.struct_tail_for_codegen(receiver_place.layout.ty, self.typing_env());
|
||||
let ty::Dynamic(receiver_trait, _, ty::Dyn) = receiver_tail.kind() else {
|
||||
span_bug!(
|
||||
self.cur_span(),
|
||||
"dynamic call on non-`dyn` type {}",
|
||||
receiver_tail
|
||||
)
|
||||
};
|
||||
assert!(receiver_place.layout.is_unsized());
|
||||
|
||||
// Get the required information from the vtable.
|
||||
let vptr = receiver_place.meta().unwrap_meta().to_pointer(self)?;
|
||||
let dyn_ty = self.get_ptr_vtable_ty(vptr, Some(receiver_trait))?;
|
||||
|
||||
// It might be surprising that we use a pointer as the receiver even if this
|
||||
// is a by-val case; this works because by-val passing of an unsized `dyn
|
||||
// Trait` to a function is actually desugared to a pointer.
|
||||
(receiver_trait.principal(), dyn_ty, receiver_place.ptr())
|
||||
};
|
||||
assert!(receiver_place.layout.is_unsized());
|
||||
|
||||
// Get the required information from the vtable.
|
||||
let vptr = receiver_place.meta().unwrap_meta().to_pointer(self)?;
|
||||
let dyn_ty = self.get_ptr_vtable_ty(vptr, Some(receiver_trait))?;
|
||||
|
||||
// It might be surprising that we use a pointer as the receiver even if this
|
||||
// is a by-val case; this works because by-val passing of an unsized `dyn
|
||||
// Trait` to a function is actually desugared to a pointer.
|
||||
(receiver_trait.principal(), dyn_ty, receiver_place.ptr())
|
||||
};
|
||||
|
||||
// Now determine the actual method to call. Usually we use the easy way of just
|
||||
// looking up the method at index `idx`.
|
||||
@ -704,7 +704,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
|
||||
let concrete_method = Instance::expect_resolve_for_vtable(
|
||||
tcx,
|
||||
self.param_env,
|
||||
self.typing_env(),
|
||||
def_id,
|
||||
instance.args.rebase_onto(tcx, trait_def_id, concrete_trait_ref.args),
|
||||
self.cur_span(),
|
||||
|
@ -83,7 +83,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
ty::FnDef(def_id, args) => {
|
||||
let instance = ty::Instance::resolve_for_fn_ptr(
|
||||
*self.tcx,
|
||||
self.param_env,
|
||||
self.typing_env(),
|
||||
def_id,
|
||||
args,
|
||||
)
|
||||
@ -384,7 +384,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
) -> InterpResult<'tcx> {
|
||||
// A<Struct> -> A<Trait> conversion
|
||||
let (src_pointee_ty, dest_pointee_ty) =
|
||||
self.tcx.struct_lockstep_tails_for_codegen(source_ty, cast_ty, self.param_env);
|
||||
self.tcx.struct_lockstep_tails_for_codegen(source_ty, cast_ty, self.typing_env());
|
||||
|
||||
match (src_pointee_ty.kind(), dest_pointee_ty.kind()) {
|
||||
(&ty::Array(_, length), &ty::Slice(_)) => {
|
||||
|
@ -10,9 +10,7 @@ use rustc_middle::query::TyCtxtAt;
|
||||
use rustc_middle::ty::layout::{
|
||||
self, FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOfHelpers, TyAndLayout,
|
||||
};
|
||||
use rustc_middle::ty::{
|
||||
self, GenericArgsRef, ParamEnv, Ty, TyCtxt, TypeFoldable, TypingMode, Variance,
|
||||
};
|
||||
use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypeFoldable, TypingEnv, Variance};
|
||||
use rustc_middle::{mir, span_bug};
|
||||
use rustc_session::Limit;
|
||||
use rustc_span::Span;
|
||||
@ -65,12 +63,12 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, M> layout::HasParamEnv<'tcx> for InterpCx<'tcx, M>
|
||||
impl<'tcx, M> layout::HasTypingEnv<'tcx> for InterpCx<'tcx, M>
|
||||
where
|
||||
M: Machine<'tcx>,
|
||||
{
|
||||
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
||||
self.param_env
|
||||
fn typing_env(&self) -> ty::TypingEnv<'tcx> {
|
||||
self.typing_env()
|
||||
}
|
||||
}
|
||||
|
||||
@ -116,8 +114,7 @@ impl<'tcx, M: Machine<'tcx>> FnAbiOfHelpers<'tcx> for InterpCx<'tcx, M> {
|
||||
/// This test should be symmetric, as it is primarily about layout compatibility.
|
||||
pub(super) fn mir_assign_valid_types<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
typing_mode: TypingMode<'tcx>,
|
||||
param_env: ParamEnv<'tcx>,
|
||||
typing_env: TypingEnv<'tcx>,
|
||||
src: TyAndLayout<'tcx>,
|
||||
dest: TyAndLayout<'tcx>,
|
||||
) -> bool {
|
||||
@ -125,7 +122,7 @@ pub(super) fn mir_assign_valid_types<'tcx>(
|
||||
// all normal lifetimes are erased, higher-ranked types with their
|
||||
// late-bound lifetimes are still around and can lead to type
|
||||
// differences.
|
||||
if util::relate_types(tcx, typing_mode, param_env, Variance::Covariant, src.ty, dest.ty) {
|
||||
if util::relate_types(tcx, typing_env, Variance::Covariant, src.ty, dest.ty) {
|
||||
// Make sure the layout is equal, too -- just to be safe. Miri really
|
||||
// needs layout equality. For performance reason we skip this check when
|
||||
// the types are equal. Equal types *can* have different layouts when
|
||||
@ -145,8 +142,7 @@ pub(super) fn mir_assign_valid_types<'tcx>(
|
||||
#[cfg_attr(not(debug_assertions), inline(always))]
|
||||
pub(super) fn from_known_layout<'tcx>(
|
||||
tcx: TyCtxtAt<'tcx>,
|
||||
typing_mode: TypingMode<'tcx>,
|
||||
param_env: ParamEnv<'tcx>,
|
||||
typing_env: TypingEnv<'tcx>,
|
||||
known_layout: Option<TyAndLayout<'tcx>>,
|
||||
compute: impl FnOnce() -> InterpResult<'tcx, TyAndLayout<'tcx>>,
|
||||
) -> InterpResult<'tcx, TyAndLayout<'tcx>> {
|
||||
@ -155,13 +151,7 @@ pub(super) fn from_known_layout<'tcx>(
|
||||
Some(known_layout) => {
|
||||
if cfg!(debug_assertions) {
|
||||
let check_layout = compute()?;
|
||||
if !mir_assign_valid_types(
|
||||
tcx.tcx,
|
||||
typing_mode,
|
||||
param_env,
|
||||
check_layout,
|
||||
known_layout,
|
||||
) {
|
||||
if !mir_assign_valid_types(tcx.tcx, typing_env, check_layout, known_layout) {
|
||||
span_bug!(
|
||||
tcx.span,
|
||||
"expected type differs from actual type.\nexpected: {}\nactual: {}",
|
||||
@ -211,9 +201,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn typing_mode(&self) -> TypingMode<'tcx> {
|
||||
/// During CTFE we're always in `PostAnalysis` mode.
|
||||
#[inline(always)]
|
||||
pub fn typing_env(&self) -> ty::TypingEnv<'tcx> {
|
||||
debug_assert_eq!(self.param_env.reveal(), Reveal::All);
|
||||
TypingMode::PostAnalysis
|
||||
ty::TypingEnv { typing_mode: ty::TypingMode::PostAnalysis, param_env: self.param_env }
|
||||
}
|
||||
|
||||
/// Returns the span of the currently executed statement/terminator.
|
||||
@ -304,13 +296,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
.instance
|
||||
.try_instantiate_mir_and_normalize_erasing_regions(
|
||||
*self.tcx,
|
||||
self.param_env,
|
||||
self.typing_env(),
|
||||
ty::EarlyBinder::bind(value),
|
||||
)
|
||||
.map_err(|_| ErrorHandled::TooGeneric(self.cur_span()))
|
||||
}
|
||||
|
||||
/// The `args` are assumed to already be in our interpreter "universe" (param_env).
|
||||
/// The `args` are assumed to already be in our interpreter "universe".
|
||||
pub(super) fn resolve(
|
||||
&self,
|
||||
def: DefId,
|
||||
@ -319,7 +311,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
trace!("resolve: {:?}, {:#?}", def, args);
|
||||
trace!("param_env: {:#?}", self.param_env);
|
||||
trace!("args: {:#?}", args);
|
||||
match ty::Instance::try_resolve(*self.tcx, self.param_env, def, args) {
|
||||
match ty::Instance::try_resolve(*self.tcx, self.typing_env(), def, args) {
|
||||
Ok(Some(instance)) => interp_ok(instance),
|
||||
Ok(None) => throw_inval!(TooGeneric),
|
||||
|
||||
@ -328,7 +320,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if the two things are equal in the current param_env, using an infctx to get proper
|
||||
/// Check if the two things are equal in the current param_env, using an infcx to get proper
|
||||
/// equality checks.
|
||||
#[instrument(level = "trace", skip(self), ret)]
|
||||
pub(super) fn eq_in_param_env<T>(&self, a: T, b: T) -> bool
|
||||
@ -340,14 +332,14 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
return true;
|
||||
}
|
||||
// Slow path: spin up an inference context to check if these traits are sufficiently equal.
|
||||
let infcx = self.tcx.infer_ctxt().build(self.typing_mode());
|
||||
let (infcx, param_env) = self.tcx.infer_ctxt().build_with_typing_env(self.typing_env());
|
||||
let ocx = ObligationCtxt::new(&infcx);
|
||||
let cause = ObligationCause::dummy_with_span(self.cur_span());
|
||||
// equate the two trait refs after normalization
|
||||
let a = ocx.normalize(&cause, self.param_env, a);
|
||||
let b = ocx.normalize(&cause, self.param_env, b);
|
||||
let a = ocx.normalize(&cause, param_env, a);
|
||||
let b = ocx.normalize(&cause, param_env, b);
|
||||
|
||||
if let Err(terr) = ocx.eq(&cause, self.param_env, a, b) {
|
||||
if let Err(terr) = ocx.eq(&cause, param_env, a, b) {
|
||||
trace!(?terr);
|
||||
return false;
|
||||
}
|
||||
@ -572,7 +564,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
let val = if self.tcx.is_static(gid.instance.def_id()) {
|
||||
let alloc_id = self.tcx.reserve_and_set_static_alloc(gid.instance.def_id());
|
||||
|
||||
let ty = instance.ty(self.tcx.tcx, self.param_env);
|
||||
let ty = instance.ty(self.tcx.tcx, self.typing_env());
|
||||
mir::ConstAlloc { alloc_id, ty }
|
||||
} else {
|
||||
self.ctfe_query(|tcx| tcx.eval_to_allocation_raw(self.param_env.and(gid)))?
|
||||
@ -587,7 +579,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
layout: Option<TyAndLayout<'tcx>>,
|
||||
) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
|
||||
M::eval_mir_constant(self, *val, span, layout, |ecx, val, span, layout| {
|
||||
let const_val = val.eval(*ecx.tcx, ecx.param_env, span).map_err(|err| {
|
||||
let const_val = val.eval(*ecx.tcx, ecx.typing_env(), span).map_err(|err| {
|
||||
if M::ALL_CONSTS_ARE_PRECHECKED {
|
||||
match err {
|
||||
ErrorHandled::TooGeneric(..) => {},
|
||||
|
@ -40,6 +40,7 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>(
|
||||
) -> InterpResult<'tcx, ConstValue<'tcx>> {
|
||||
let tp_ty = args.type_at(0);
|
||||
let name = tcx.item_name(def_id);
|
||||
let typing_env = ty::TypingEnv { typing_mode: ty::TypingMode::PostAnalysis, param_env };
|
||||
interp_ok(match name {
|
||||
sym::type_name => {
|
||||
ensure_monomorphic_enough(tcx, tp_ty)?;
|
||||
@ -48,11 +49,13 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>(
|
||||
}
|
||||
sym::needs_drop => {
|
||||
ensure_monomorphic_enough(tcx, tp_ty)?;
|
||||
ConstValue::from_bool(tp_ty.needs_drop(tcx, param_env))
|
||||
ConstValue::from_bool(tp_ty.needs_drop(tcx, typing_env))
|
||||
}
|
||||
sym::pref_align_of => {
|
||||
// Correctly handles non-monomorphic calls, so there is no need for ensure_monomorphic_enough.
|
||||
let layout = tcx.layout_of(param_env.and(tp_ty)).map_err(|e| err_inval!(Layout(*e)))?;
|
||||
let layout = tcx
|
||||
.layout_of(typing_env.as_query_input(tp_ty))
|
||||
.map_err(|e| err_inval!(Layout(*e)))?;
|
||||
ConstValue::from_target_usize(layout.align.pref.bytes(), &tcx)
|
||||
}
|
||||
sym::type_id => {
|
||||
@ -355,7 +358,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
|
||||
let should_panic = !self
|
||||
.tcx
|
||||
.check_validity_requirement((requirement, self.param_env.and(ty)))
|
||||
.check_validity_requirement((requirement, self.typing_env().as_query_input(ty)))
|
||||
.map_err(|_| err_inval!(TooGeneric))?;
|
||||
|
||||
if should_panic {
|
||||
|
@ -859,7 +859,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
|
||||
// # Global allocations
|
||||
if let Some(global_alloc) = self.tcx.try_get_global_alloc(id) {
|
||||
let (size, align) = global_alloc.size_and_align(*self.tcx, self.param_env);
|
||||
let (size, align) = global_alloc.size_and_align(*self.tcx, self.typing_env());
|
||||
let mutbl = global_alloc.mutability(*self.tcx, self.param_env);
|
||||
let kind = match global_alloc {
|
||||
GlobalAlloc::Static { .. } | GlobalAlloc::Memory { .. } => AllocKind::LiveData,
|
||||
|
@ -8,7 +8,7 @@ use rustc_abi as abi;
|
||||
use rustc_abi::{BackendRepr, HasDataLayout, Size};
|
||||
use rustc_hir::def::Namespace;
|
||||
use rustc_middle::mir::interpret::ScalarSizeMismatch;
|
||||
use rustc_middle::ty::layout::{HasParamEnv, HasTyCtxt, LayoutOf, TyAndLayout};
|
||||
use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutOf, TyAndLayout};
|
||||
use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter};
|
||||
use rustc_middle::ty::{ConstInt, ScalarInt, Ty, TyCtxt};
|
||||
use rustc_middle::{bug, mir, span_bug, ty};
|
||||
@ -297,21 +297,25 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
|
||||
|
||||
#[inline]
|
||||
pub fn from_bool(b: bool, tcx: TyCtxt<'tcx>) -> Self {
|
||||
let layout = tcx.layout_of(ty::ParamEnv::reveal_all().and(tcx.types.bool)).unwrap();
|
||||
let layout = tcx
|
||||
.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(tcx.types.bool))
|
||||
.unwrap();
|
||||
Self::from_scalar(Scalar::from_bool(b), layout)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn from_ordering(c: std::cmp::Ordering, tcx: TyCtxt<'tcx>) -> Self {
|
||||
let ty = tcx.ty_ordering_enum(None);
|
||||
let layout = tcx.layout_of(ty::ParamEnv::reveal_all().and(ty)).unwrap();
|
||||
let layout =
|
||||
tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)).unwrap();
|
||||
Self::from_scalar(Scalar::from_i8(c as i8), layout)
|
||||
}
|
||||
|
||||
pub fn from_pair(a: Self, b: Self, tcx: TyCtxt<'tcx>) -> Self {
|
||||
let layout = tcx
|
||||
.layout_of(
|
||||
ty::ParamEnv::reveal_all().and(Ty::new_tup(tcx, &[a.layout.ty, b.layout.ty])),
|
||||
ty::TypingEnv::fully_monomorphized()
|
||||
.as_query_input(Ty::new_tup(tcx, &[a.layout.ty, b.layout.ty])),
|
||||
)
|
||||
.unwrap();
|
||||
Self::from_scalar_pair(a.to_scalar(), b.to_scalar(), layout)
|
||||
@ -341,7 +345,7 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
|
||||
|
||||
#[inline]
|
||||
#[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980)
|
||||
pub fn to_pair(self, cx: &(impl HasTyCtxt<'tcx> + HasParamEnv<'tcx>)) -> (Self, Self) {
|
||||
pub fn to_pair(self, cx: &(impl HasTyCtxt<'tcx> + HasTypingEnv<'tcx>)) -> (Self, Self) {
|
||||
let layout = self.layout;
|
||||
let (val0, val1) = self.to_scalar_pair();
|
||||
(
|
||||
@ -773,8 +777,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
)?;
|
||||
if !mir_assign_valid_types(
|
||||
*self.tcx,
|
||||
self.typing_mode(),
|
||||
self.param_env,
|
||||
self.typing_env(),
|
||||
self.layout_of(normalized_place_ty)?,
|
||||
op.layout,
|
||||
) {
|
||||
@ -833,9 +836,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
})
|
||||
};
|
||||
let layout =
|
||||
from_known_layout(self.tcx, self.typing_mode(), self.param_env, layout, || {
|
||||
self.layout_of(ty).into()
|
||||
})?;
|
||||
from_known_layout(self.tcx, self.typing_env(), layout, || self.layout_of(ty).into())?;
|
||||
let imm = match val_val {
|
||||
mir::ConstValue::Indirect { alloc_id, offset } => {
|
||||
// This is const data, no mutation allowed.
|
||||
|
@ -533,7 +533,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
}
|
||||
OffsetOf(fields) => {
|
||||
let val =
|
||||
self.tcx.offset_of_subfield(self.param_env, layout, fields.iter()).bytes();
|
||||
self.tcx.offset_of_subfield(self.typing_env(), layout, fields.iter()).bytes();
|
||||
ImmTy::from_uint(val, usize_layout())
|
||||
}
|
||||
UbChecks => ImmTy::from_bool(M::ub_checks(self)?, *self.tcx),
|
||||
|
@ -540,8 +540,7 @@ where
|
||||
)?;
|
||||
if !mir_assign_valid_types(
|
||||
*self.tcx,
|
||||
self.typing_mode(),
|
||||
self.param_env,
|
||||
self.typing_env(),
|
||||
self.layout_of(normalized_place_ty)?,
|
||||
place.layout,
|
||||
) {
|
||||
@ -871,13 +870,8 @@ where
|
||||
) -> InterpResult<'tcx> {
|
||||
// We do NOT compare the types for equality, because well-typed code can
|
||||
// actually "transmute" `&mut T` to `&T` in an assignment without a cast.
|
||||
let layout_compat = mir_assign_valid_types(
|
||||
*self.tcx,
|
||||
self.typing_mode(),
|
||||
self.param_env,
|
||||
src.layout(),
|
||||
dest.layout(),
|
||||
);
|
||||
let layout_compat =
|
||||
mir_assign_valid_types(*self.tcx, self.typing_env(), src.layout(), dest.layout());
|
||||
if !allow_transmute && !layout_compat {
|
||||
span_bug!(
|
||||
self.cur_span(),
|
||||
|
@ -379,7 +379,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
for &const_ in body.required_consts() {
|
||||
let c =
|
||||
self.instantiate_from_current_frame_and_normalize_erasing_regions(const_.const_)?;
|
||||
c.eval(*self.tcx, self.param_env, const_.span).map_err(|err| {
|
||||
c.eval(*self.tcx, self.typing_env(), const_.span).map_err(|err| {
|
||||
err.emit_note(*self.tcx);
|
||||
err
|
||||
})?;
|
||||
@ -596,13 +596,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
return interp_ok(layout);
|
||||
}
|
||||
|
||||
let layout =
|
||||
from_known_layout(self.tcx, self.typing_mode(), self.param_env, layout, || {
|
||||
let local_ty = frame.body.local_decls[local].ty;
|
||||
let local_ty =
|
||||
self.instantiate_from_frame_and_normalize_erasing_regions(frame, local_ty)?;
|
||||
self.layout_of(local_ty).into()
|
||||
})?;
|
||||
let layout = from_known_layout(self.tcx, self.typing_env(), layout, || {
|
||||
let local_ty = frame.body.local_decls[local].ty;
|
||||
let local_ty =
|
||||
self.instantiate_from_frame_and_normalize_erasing_regions(frame, local_ty)?;
|
||||
self.layout_of(local_ty).into()
|
||||
})?;
|
||||
|
||||
// Layouts of locals are requested a lot, so we cache them.
|
||||
state.layout.set(Some(layout));
|
||||
|
@ -418,7 +418,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
.collect::<InterpResult<'tcx, Vec<_>>>()?;
|
||||
|
||||
let fn_sig_binder = func.layout.ty.fn_sig(*self.tcx);
|
||||
let fn_sig = self.tcx.normalize_erasing_late_bound_regions(self.param_env, fn_sig_binder);
|
||||
let fn_sig =
|
||||
self.tcx.normalize_erasing_late_bound_regions(self.typing_env(), fn_sig_binder);
|
||||
let extra_args = &args[fn_sig.inputs().len()..];
|
||||
let extra_args =
|
||||
self.tcx.mk_type_list_from_iter(extra_args.iter().map(|arg| arg.layout().ty));
|
||||
|
@ -448,7 +448,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
|
||||
meta: MemPlaceMeta<M::Provenance>,
|
||||
pointee: TyAndLayout<'tcx>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let tail = self.ecx.tcx.struct_tail_for_codegen(pointee.ty, self.ecx.param_env);
|
||||
let tail = self.ecx.tcx.struct_tail_for_codegen(pointee.ty, self.ecx.typing_env());
|
||||
match tail.kind() {
|
||||
ty::Dynamic(data, _, ty::Dyn) => {
|
||||
let vtable = meta.unwrap_meta().to_pointer(self.ecx)?;
|
||||
@ -568,7 +568,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
|
||||
throw_validation_failure!(self.path, DanglingPtrUseAfterFree { ptr_kind });
|
||||
};
|
||||
let (size, _align) =
|
||||
global_alloc.size_and_align(*self.ecx.tcx, self.ecx.param_env);
|
||||
global_alloc.size_and_align(*self.ecx.tcx, self.ecx.typing_env());
|
||||
|
||||
if let GlobalAlloc::Static(did) = global_alloc {
|
||||
let DefKind::Static { nested, .. } = self.ecx.tcx.def_kind(did) else {
|
||||
@ -955,7 +955,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
|
||||
) -> Cow<'e, RangeSet> {
|
||||
assert!(layout.ty.is_union());
|
||||
assert!(layout.is_sized(), "there are no unsized unions");
|
||||
let layout_cx = LayoutCx::new(*ecx.tcx, ecx.param_env);
|
||||
let layout_cx = LayoutCx::new(*ecx.tcx, ecx.typing_env());
|
||||
return M::cached_union_data_range(ecx, layout.ty, || {
|
||||
let mut out = RangeSet(Vec::new());
|
||||
union_data_range_uncached(&layout_cx, layout, Size::ZERO, &mut out);
|
||||
|
@ -47,7 +47,7 @@ pub fn provide(providers: &mut Providers) {
|
||||
providers.hooks.try_destructure_mir_constant_for_user_output =
|
||||
const_eval::try_destructure_mir_constant_for_user_output;
|
||||
providers.valtree_to_const_val = |tcx, (ty, valtree)| {
|
||||
const_eval::valtree_to_const_value(tcx, ty::ParamEnv::empty().and(ty), valtree)
|
||||
const_eval::valtree_to_const_value(tcx, ty::ParamEnv::reveal_all().and(ty), valtree)
|
||||
};
|
||||
providers.check_validity_requirement = |tcx, (init_kind, param_env_and_ty)| {
|
||||
util::check_validity_requirement(tcx, init_kind, param_env_and_ty)
|
||||
|
@ -9,7 +9,7 @@ use tracing::debug;
|
||||
pub fn is_disaligned<'tcx, L>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
local_decls: &L,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
place: Place<'tcx>,
|
||||
) -> bool
|
||||
where
|
||||
@ -22,8 +22,8 @@ where
|
||||
};
|
||||
|
||||
let ty = place.ty(local_decls, tcx).ty;
|
||||
let unsized_tail = || tcx.struct_tail_for_codegen(ty, param_env);
|
||||
match tcx.layout_of(param_env.and(ty)) {
|
||||
let unsized_tail = || tcx.struct_tail_for_codegen(ty, typing_env);
|
||||
match tcx.layout_of(typing_env.as_query_input(ty)) {
|
||||
Ok(layout)
|
||||
if layout.align.abi <= pack
|
||||
&& (layout.is_sized()
|
||||
|
@ -3,7 +3,7 @@ use rustc_middle::bug;
|
||||
use rustc_middle::ty::layout::{
|
||||
HasTyCtxt, LayoutCx, LayoutError, LayoutOf, TyAndLayout, ValidityRequirement,
|
||||
};
|
||||
use rustc_middle::ty::{ParamEnvAnd, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{PseudoCanonicalInput, Ty, TyCtxt};
|
||||
|
||||
use crate::const_eval::{CanAccessMutGlobal, CheckAlignment, CompileTimeMachine};
|
||||
use crate::interpret::{InterpCx, MemoryKind};
|
||||
@ -23,16 +23,16 @@ use crate::interpret::{InterpCx, MemoryKind};
|
||||
pub fn check_validity_requirement<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
kind: ValidityRequirement,
|
||||
param_env_and_ty: ParamEnvAnd<'tcx, Ty<'tcx>>,
|
||||
input: PseudoCanonicalInput<'tcx, Ty<'tcx>>,
|
||||
) -> Result<bool, &'tcx LayoutError<'tcx>> {
|
||||
let layout = tcx.layout_of(param_env_and_ty)?;
|
||||
let layout = tcx.layout_of(input)?;
|
||||
|
||||
// There is nothing strict or lax about inhabitedness.
|
||||
if kind == ValidityRequirement::Inhabited {
|
||||
return Ok(!layout.is_uninhabited());
|
||||
}
|
||||
|
||||
let layout_cx = LayoutCx::new(tcx, param_env_and_ty.param_env);
|
||||
let layout_cx = LayoutCx::new(tcx, input.typing_env);
|
||||
if kind == ValidityRequirement::Uninit || tcx.sess.opts.unstable_opts.strict_init_checks {
|
||||
check_validity_requirement_strict(layout, &layout_cx, kind)
|
||||
} else {
|
||||
@ -49,7 +49,7 @@ fn check_validity_requirement_strict<'tcx>(
|
||||
) -> Result<bool, &'tcx LayoutError<'tcx>> {
|
||||
let machine = CompileTimeMachine::new(CanAccessMutGlobal::No, CheckAlignment::Error);
|
||||
|
||||
let mut cx = InterpCx::new(cx.tcx(), rustc_span::DUMMY_SP, cx.param_env, machine);
|
||||
let mut cx = InterpCx::new(cx.tcx(), rustc_span::DUMMY_SP, cx.typing_env.param_env, machine);
|
||||
|
||||
let allocated = cx
|
||||
.allocate(ty, MemoryKind::Machine(crate::const_eval::MemoryKind::Heap))
|
||||
|
@ -5,18 +5,17 @@
|
||||
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_middle::traits::ObligationCause;
|
||||
use rustc_middle::ty::{ParamEnv, Ty, TyCtxt, TypingMode, Variance};
|
||||
use rustc_middle::ty::{Ty, TyCtxt, TypingEnv, Variance};
|
||||
use rustc_trait_selection::traits::ObligationCtxt;
|
||||
|
||||
/// Returns whether `src` is a subtype of `dest`, i.e. `src <: dest`.
|
||||
pub fn sub_types<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
typing_mode: TypingMode<'tcx>,
|
||||
param_env: ParamEnv<'tcx>,
|
||||
typing_env: TypingEnv<'tcx>,
|
||||
src: Ty<'tcx>,
|
||||
dest: Ty<'tcx>,
|
||||
) -> bool {
|
||||
relate_types(tcx, typing_mode, param_env, Variance::Covariant, src, dest)
|
||||
relate_types(tcx, typing_env, Variance::Covariant, src, dest)
|
||||
}
|
||||
|
||||
/// Returns whether `src` is a subtype of `dest`, i.e. `src <: dest`.
|
||||
@ -26,8 +25,7 @@ pub fn sub_types<'tcx>(
|
||||
/// because we want to check for type equality.
|
||||
pub fn relate_types<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
typing_mode: TypingMode<'tcx>,
|
||||
param_env: ParamEnv<'tcx>,
|
||||
typing_env: TypingEnv<'tcx>,
|
||||
variance: Variance,
|
||||
src: Ty<'tcx>,
|
||||
dest: Ty<'tcx>,
|
||||
@ -36,8 +34,7 @@ pub fn relate_types<'tcx>(
|
||||
return true;
|
||||
}
|
||||
|
||||
let mut builder = tcx.infer_ctxt().ignoring_regions();
|
||||
let infcx = builder.build(typing_mode);
|
||||
let (infcx, param_env) = tcx.infer_ctxt().ignoring_regions().build_with_typing_env(typing_env);
|
||||
let ocx = ObligationCtxt::new(&infcx);
|
||||
let cause = ObligationCause::dummy();
|
||||
let src = ocx.normalize(&cause, param_env, src);
|
||||
|
@ -21,8 +21,7 @@ use rustc_middle::ty::fold::BottomUpFolder;
|
||||
use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES};
|
||||
use rustc_middle::ty::util::{Discr, InspectCoroutineFields, IntTypeExt};
|
||||
use rustc_middle::ty::{
|
||||
AdtDef, GenericArgKind, ParamEnv, RegionKind, TypeSuperVisitable, TypeVisitable,
|
||||
TypeVisitableExt,
|
||||
AdtDef, GenericArgKind, RegionKind, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
|
||||
};
|
||||
use rustc_session::lint::builtin::UNINHABITED_STATIC;
|
||||
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
||||
@ -114,15 +113,15 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b
|
||||
}
|
||||
}
|
||||
|
||||
let param_env = tcx.param_env(item_def_id);
|
||||
let typing_env = ty::TypingEnv::non_body_analysis(tcx, item_def_id);
|
||||
for field in &def.non_enum_variant().fields {
|
||||
let Ok(field_ty) = tcx.try_normalize_erasing_regions(param_env, field.ty(tcx, args))
|
||||
let Ok(field_ty) = tcx.try_normalize_erasing_regions(typing_env, field.ty(tcx, args))
|
||||
else {
|
||||
tcx.dcx().span_delayed_bug(span, "could not normalize field type");
|
||||
continue;
|
||||
};
|
||||
|
||||
if !allowed_union_field(field_ty, tcx, param_env) {
|
||||
if !allowed_union_field(field_ty, tcx, typing_env.param_env) {
|
||||
let (field_span, ty_span) = match tcx.hir().get_if_local(field.did) {
|
||||
// We are currently checking the type this field came from, so it must be local.
|
||||
Some(Node::Field(field)) => (field.span, field.ty.span),
|
||||
@ -137,7 +136,7 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b
|
||||
note: (),
|
||||
});
|
||||
return false;
|
||||
} else if field_ty.needs_drop(tcx, param_env) {
|
||||
} else if field_ty.needs_drop(tcx, typing_env) {
|
||||
// This should never happen. But we can get here e.g. in case of name resolution errors.
|
||||
tcx.dcx()
|
||||
.span_delayed_bug(span, "we should never accept maybe-dropping union fields");
|
||||
@ -158,7 +157,7 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
||||
// reason to allow any statics to be uninhabited.
|
||||
let ty = tcx.type_of(def_id).instantiate_identity();
|
||||
let span = tcx.def_span(def_id);
|
||||
let layout = match tcx.layout_of(ParamEnv::reveal_all().and(ty)) {
|
||||
let layout = match tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)) {
|
||||
Ok(l) => l,
|
||||
// Foreign statics that overflow their allowed size should emit an error
|
||||
Err(LayoutError::SizeOverflow(_))
|
||||
@ -237,7 +236,10 @@ pub(super) fn check_opaque_for_cycles<'tcx>(
|
||||
|
||||
// And also look for cycle errors in the layout of coroutines.
|
||||
if let Err(&LayoutError::Cycle(guar)) =
|
||||
tcx.layout_of(tcx.param_env(def_id).and(Ty::new_opaque(tcx, def_id.to_def_id(), args)))
|
||||
tcx.layout_of(
|
||||
ty::TypingEnv::post_analysis(tcx, def_id.to_def_id())
|
||||
.as_query_input(Ty::new_opaque(tcx, def_id.to_def_id(), args)),
|
||||
)
|
||||
{
|
||||
return Err(guar);
|
||||
}
|
||||
@ -1307,8 +1309,8 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
|
||||
// "known" respecting #[non_exhaustive] attributes.
|
||||
let field_infos = adt.all_fields().map(|field| {
|
||||
let ty = field.ty(tcx, GenericArgs::identity_for_item(tcx, field.did));
|
||||
let param_env = tcx.param_env(field.did);
|
||||
let layout = tcx.layout_of(param_env.and(ty));
|
||||
let typing_env = ty::TypingEnv::non_body_analysis(tcx, field.did);
|
||||
let layout = tcx.layout_of(typing_env.as_query_input(ty));
|
||||
// We are currently checking the type this field came from, so it must be local
|
||||
let span = tcx.hir().span_if_local(field.did).unwrap();
|
||||
let trivial = layout.is_ok_and(|layout| layout.is_1zst());
|
||||
|
@ -1126,7 +1126,7 @@ fn check_type_defn<'tcx>(
|
||||
let ty = tcx.type_of(variant.tail().did).instantiate_identity();
|
||||
let ty = tcx.erase_regions(ty);
|
||||
assert!(!ty.has_infer());
|
||||
ty.needs_drop(tcx, tcx.param_env(item.owner_id))
|
||||
ty.needs_drop(tcx, wfcx.infcx.typing_env(wfcx.param_env))
|
||||
}
|
||||
};
|
||||
// All fields (except for possibly the last) should be sized.
|
||||
@ -1281,7 +1281,8 @@ fn check_item_type(
|
||||
UnsizedHandling::Forbid => true,
|
||||
UnsizedHandling::Allow => false,
|
||||
UnsizedHandling::AllowIfForeignTail => {
|
||||
let tail = tcx.struct_tail_for_codegen(item_ty, wfcx.param_env);
|
||||
let tail =
|
||||
tcx.struct_tail_for_codegen(item_ty, wfcx.infcx.typing_env(wfcx.param_env));
|
||||
!matches!(tail.kind(), ty::Foreign(_))
|
||||
}
|
||||
};
|
||||
|
@ -259,7 +259,9 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
|
||||
let ty_a = field.ty(tcx, args_a);
|
||||
let ty_b = field.ty(tcx, args_b);
|
||||
|
||||
if let Ok(layout) = tcx.layout_of(param_env.and(ty_a)) {
|
||||
if let Ok(layout) =
|
||||
tcx.layout_of(infcx.typing_env(param_env).as_query_input(ty_a))
|
||||
{
|
||||
if layout.is_1zst() {
|
||||
// ignore 1-ZST fields
|
||||
return false;
|
||||
|
@ -3,7 +3,7 @@ use rustc_errors::{DiagCtxtHandle, E0781, struct_span_code_err};
|
||||
use rustc_hir::{self as hir, HirId};
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::ty::layout::LayoutError;
|
||||
use rustc_middle::ty::{self, ParamEnv, TyCtxt};
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
|
||||
use crate::errors;
|
||||
|
||||
@ -130,7 +130,7 @@ fn is_valid_cmse_inputs<'tcx>(
|
||||
let fn_sig = tcx.instantiate_bound_regions_with_erased(fn_sig);
|
||||
|
||||
for (index, ty) in fn_sig.inputs().iter().enumerate() {
|
||||
let layout = tcx.layout_of(ParamEnv::reveal_all().and(*ty))?;
|
||||
let layout = tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(*ty))?;
|
||||
|
||||
let align = layout.layout.align().abi.bytes();
|
||||
let size = layout.layout.size().bytes();
|
||||
@ -158,8 +158,10 @@ fn is_valid_cmse_output<'tcx>(
|
||||
// this type is only used for layout computation, which does not rely on regions
|
||||
let fn_sig = tcx.instantiate_bound_regions_with_erased(fn_sig);
|
||||
|
||||
let typing_env = ty::TypingEnv::fully_monomorphized();
|
||||
|
||||
let mut ret_ty = fn_sig.output();
|
||||
let layout = tcx.layout_of(ParamEnv::reveal_all().and(ret_ty))?;
|
||||
let layout = tcx.layout_of(typing_env.as_query_input(ret_ty))?;
|
||||
let size = layout.layout.size().bytes();
|
||||
|
||||
if size <= 4 {
|
||||
@ -182,7 +184,7 @@ fn is_valid_cmse_output<'tcx>(
|
||||
for variant_def in adt_def.variants() {
|
||||
for field_def in variant_def.fields.iter() {
|
||||
let ty = field_def.ty(tcx, args);
|
||||
let layout = tcx.layout_of(ParamEnv::reveal_all().and(ty))?;
|
||||
let layout = tcx.layout_of(typing_env.as_query_input(ty))?;
|
||||
|
||||
if !layout.layout.is_1zst() {
|
||||
ret_ty = ty;
|
||||
|
@ -2357,8 +2357,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// Only assoc fns that return `Self`
|
||||
let fn_sig = self.tcx.fn_sig(item.def_id).skip_binder();
|
||||
let ret_ty = fn_sig.output();
|
||||
let ret_ty =
|
||||
self.tcx.normalize_erasing_late_bound_regions(self.param_env, ret_ty);
|
||||
let ret_ty = self.tcx.normalize_erasing_late_bound_regions(
|
||||
self.typing_env(self.param_env),
|
||||
ret_ty,
|
||||
);
|
||||
if !self.can_eq(self.param_env, ret_ty, adt_ty) {
|
||||
return None;
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let span = tcx.hir().span(hir_id);
|
||||
let normalize = |ty| {
|
||||
let ty = self.resolve_vars_if_possible(ty);
|
||||
self.tcx.normalize_erasing_regions(self.param_env, ty)
|
||||
self.tcx.normalize_erasing_regions(self.typing_env(self.param_env), ty)
|
||||
};
|
||||
let from = normalize(from);
|
||||
let to = normalize(to);
|
||||
@ -62,7 +62,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
return;
|
||||
}
|
||||
|
||||
let skel = |ty| SizeSkeleton::compute(ty, tcx, self.param_env);
|
||||
let skel = |ty| SizeSkeleton::compute(ty, tcx, self.typing_env(self.param_env));
|
||||
let sk_from = skel(from);
|
||||
let sk_to = skel(to);
|
||||
trace!(?sk_from, ?sk_to);
|
||||
|
@ -1257,7 +1257,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
) -> Option<FxIndexSet<UpvarMigrationInfo>> {
|
||||
let ty = self.resolve_vars_if_possible(self.node_ty(var_hir_id));
|
||||
|
||||
if !ty.has_significant_drop(self.tcx, self.tcx.param_env(closure_def_id)) {
|
||||
// FIXME(#132279): Using `non_body_analysis` here feels wrong.
|
||||
if !ty.has_significant_drop(
|
||||
self.tcx,
|
||||
ty::TypingEnv::non_body_analysis(self.tcx, closure_def_id),
|
||||
) {
|
||||
debug!("does not have significant drop");
|
||||
return None;
|
||||
}
|
||||
@ -1535,8 +1539,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
base_path_ty: Ty<'tcx>,
|
||||
captured_by_move_projs: Vec<&[Projection<'tcx>]>,
|
||||
) -> bool {
|
||||
let needs_drop =
|
||||
|ty: Ty<'tcx>| ty.has_significant_drop(self.tcx, self.tcx.param_env(closure_def_id));
|
||||
// FIXME(#132279): Using `non_body_analysis` here feels wrong.
|
||||
let needs_drop = |ty: Ty<'tcx>| {
|
||||
ty.has_significant_drop(
|
||||
self.tcx,
|
||||
ty::TypingEnv::non_body_analysis(self.tcx, closure_def_id),
|
||||
)
|
||||
};
|
||||
|
||||
let is_drop_defined_for_ty = |ty: Ty<'tcx>| {
|
||||
let drop_trait = self.tcx.require_lang_item(hir::LangItem::Drop, Some(closure_span));
|
||||
|
@ -881,6 +881,8 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for EagerlyNormalizeConsts<'tcx> {
|
||||
}
|
||||
|
||||
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
|
||||
self.tcx.try_normalize_erasing_regions(self.param_env, ct).unwrap_or(ct)
|
||||
self.tcx
|
||||
.try_normalize_erasing_regions(ty::TypingEnv::from_param_env(self.param_env), ct)
|
||||
.unwrap_or(ct)
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +38,8 @@ use rustc_middle::ty::fold::{
|
||||
use rustc_middle::ty::visit::TypeVisitableExt;
|
||||
use rustc_middle::ty::{
|
||||
self, ConstVid, FloatVid, GenericArg, GenericArgKind, GenericArgs, GenericArgsRef,
|
||||
GenericParamDefKind, InferConst, IntVid, Ty, TyCtxt, TyVid, TypingMode,
|
||||
GenericParamDefKind, InferConst, IntVid, PseudoCanonicalInput, Ty, TyCtxt, TyVid,
|
||||
TypeVisitable, TypingEnv, TypingMode,
|
||||
};
|
||||
use rustc_span::Span;
|
||||
use rustc_span::symbol::Symbol;
|
||||
@ -565,6 +566,13 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
|
||||
(infcx, value, args)
|
||||
}
|
||||
|
||||
pub fn build_with_typing_env(
|
||||
mut self,
|
||||
TypingEnv { typing_mode, param_env }: TypingEnv<'tcx>,
|
||||
) -> (InferCtxt<'tcx>, ty::ParamEnv<'tcx>) {
|
||||
(self.build(typing_mode), param_env)
|
||||
}
|
||||
|
||||
pub fn build(&mut self, typing_mode: TypingMode<'tcx>) -> InferCtxt<'tcx> {
|
||||
let InferCtxtBuilder { tcx, considering_regions, skip_leak_check, next_trait_solver } =
|
||||
*self;
|
||||
@ -1278,6 +1286,42 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
u
|
||||
}
|
||||
|
||||
/// Extract [`ty::TypingMode`] of this inference context to get a `TypingEnv`
|
||||
/// which contains the necessary information to use the trait system without
|
||||
/// using canonicalization or carrying this inference context around.
|
||||
pub fn typing_env(&self, param_env: ty::ParamEnv<'tcx>) -> ty::TypingEnv<'tcx> {
|
||||
let typing_mode = match self.typing_mode(param_env) {
|
||||
ty::TypingMode::Coherence => ty::TypingMode::Coherence,
|
||||
// FIXME(#132279): This erases the `defining_opaque_types` as it isn't possible
|
||||
// to handle them without proper canonicalization. This means we may cause cycle
|
||||
// errors and fail to reveal opaques while inside of bodies. We should rename this
|
||||
// function and require explicit comments on all use-sites in the future.
|
||||
ty::TypingMode::Analysis { defining_opaque_types: _ } => {
|
||||
TypingMode::non_body_analysis()
|
||||
}
|
||||
ty::TypingMode::PostAnalysis => ty::TypingMode::PostAnalysis,
|
||||
};
|
||||
ty::TypingEnv { typing_mode, param_env }
|
||||
}
|
||||
|
||||
/// Similar to [`Self::canonicalize_query`], except that it returns
|
||||
/// a [`PseudoCanonicalInput`] and requires both the `value` and the
|
||||
/// `param_env` to not contain any inference variables or placeholders.
|
||||
pub fn pseudo_canonicalize_query<V>(
|
||||
&self,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
value: V,
|
||||
) -> PseudoCanonicalInput<'tcx, V>
|
||||
where
|
||||
V: TypeVisitable<TyCtxt<'tcx>>,
|
||||
{
|
||||
debug_assert!(!value.has_infer());
|
||||
debug_assert!(!value.has_placeholders());
|
||||
debug_assert!(!param_env.has_infer());
|
||||
debug_assert!(!param_env.has_placeholders());
|
||||
self.typing_env(param_env).as_query_input(value)
|
||||
}
|
||||
|
||||
/// The returned function is used in a fast path. If it returns `true` the variable is
|
||||
/// unchanged, `false` indicates that the status is unknown.
|
||||
#[inline]
|
||||
|
@ -2485,7 +2485,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
|
||||
});
|
||||
|
||||
// Check if this ADT has a constrained layout (like `NonNull` and friends).
|
||||
if let Ok(layout) = cx.tcx.layout_of(cx.param_env.and(ty)) {
|
||||
if let Ok(layout) = cx.tcx.layout_of(cx.typing_env().as_query_input(ty)) {
|
||||
if let BackendRepr::Scalar(scalar) | BackendRepr::ScalarPair(scalar, _) =
|
||||
&layout.backend_repr
|
||||
{
|
||||
@ -2521,7 +2521,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
|
||||
ty: Ty<'tcx>,
|
||||
init: InitKind,
|
||||
) -> Option<InitError> {
|
||||
let ty = cx.tcx.try_normalize_erasing_regions(cx.param_env, ty).unwrap_or(ty);
|
||||
let ty = cx.tcx.try_normalize_erasing_regions(cx.typing_env(), ty).unwrap_or(ty);
|
||||
|
||||
use rustc_type_ir::TyKind::*;
|
||||
match ty.kind() {
|
||||
@ -2568,7 +2568,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
|
||||
let definitely_inhabited = match variant
|
||||
.inhabited_predicate(cx.tcx, *adt_def)
|
||||
.instantiate(cx.tcx, args)
|
||||
.apply_any_module(cx.tcx, cx.param_env)
|
||||
.apply_any_module(cx.tcx, cx.typing_env())
|
||||
{
|
||||
// Entirely skip uninhabited variants.
|
||||
Some(false) => return None,
|
||||
|
@ -19,7 +19,7 @@ use rustc_middle::bug;
|
||||
use rustc_middle::middle::privacy::EffectiveVisibilities;
|
||||
use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout};
|
||||
use rustc_middle::ty::print::{PrintError, PrintTraitRefExt as _, Printer, with_no_trimmed_paths};
|
||||
use rustc_middle::ty::{self, GenericArg, RegisteredTools, Ty, TyCtxt, TypingMode};
|
||||
use rustc_middle::ty::{self, GenericArg, RegisteredTools, Ty, TyCtxt, TypingEnv, TypingMode};
|
||||
use rustc_session::lint::{
|
||||
BuiltinLintDiag, FutureIncompatibleInfo, Level, Lint, LintBuffer, LintExpectationId, LintId,
|
||||
};
|
||||
@ -708,6 +708,10 @@ impl<'tcx> LateContext<'tcx> {
|
||||
TypingMode::non_body_analysis()
|
||||
}
|
||||
|
||||
pub fn typing_env(&self) -> TypingEnv<'tcx> {
|
||||
TypingEnv { typing_mode: self.typing_mode(), param_env: self.param_env }
|
||||
}
|
||||
|
||||
/// Gets the type-checking results for the current body,
|
||||
/// or `None` if outside a body.
|
||||
pub fn maybe_typeck_results(&self) -> Option<&'tcx ty::TypeckResults<'tcx>> {
|
||||
@ -906,7 +910,7 @@ impl<'tcx> LateContext<'tcx> {
|
||||
.find_by_name_and_kind(tcx, Ident::from_str(name), ty::AssocKind::Type, trait_id)
|
||||
.and_then(|assoc| {
|
||||
let proj = Ty::new_projection(tcx, assoc.def_id, [self_ty]);
|
||||
tcx.try_normalize_erasing_regions(self.param_env, proj).ok()
|
||||
tcx.try_normalize_erasing_regions(self.typing_env(), proj).ok()
|
||||
})
|
||||
}
|
||||
|
||||
@ -1010,10 +1014,10 @@ impl<'tcx> ty::layout::HasTyCtxt<'tcx> for LateContext<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> ty::layout::HasParamEnv<'tcx> for LateContext<'tcx> {
|
||||
impl<'tcx> ty::layout::HasTypingEnv<'tcx> for LateContext<'tcx> {
|
||||
#[inline]
|
||||
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
||||
self.param_env
|
||||
fn typing_env(&self) -> ty::TypingEnv<'tcx> {
|
||||
self.typing_env()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -166,7 +166,7 @@ fn suggest_question_mark<'tcx>(
|
||||
}
|
||||
|
||||
let ty = args.type_at(0);
|
||||
let infcx = cx.tcx.infer_ctxt().build(cx.typing_mode());
|
||||
let (infcx, param_env) = cx.tcx.infer_ctxt().build_with_typing_env(cx.typing_env());
|
||||
let ocx = ObligationCtxt::new(&infcx);
|
||||
|
||||
let body_def_id = cx.tcx.hir().body_owner_def_id(body_id);
|
||||
@ -175,7 +175,7 @@ fn suggest_question_mark<'tcx>(
|
||||
|
||||
ocx.register_bound(
|
||||
cause,
|
||||
cx.param_env,
|
||||
param_env,
|
||||
// Erase any region vids from the type, which may not be resolved
|
||||
infcx.tcx.erase_regions(ty),
|
||||
into_iterator_did,
|
||||
|
@ -131,7 +131,7 @@ impl ClashingExternDeclarations {
|
||||
// Check that the declarations match.
|
||||
if !structurally_same_type(
|
||||
tcx,
|
||||
tcx.param_env(this_fi.owner_id),
|
||||
ty::TypingEnv::non_body_analysis(tcx, this_fi.owner_id),
|
||||
existing_decl_ty,
|
||||
this_decl_ty,
|
||||
types::CItemKind::Declaration,
|
||||
@ -205,18 +205,18 @@ fn get_relevant_span(tcx: TyCtxt<'_>, fi: hir::OwnerId) -> Span {
|
||||
/// with the same members (as the declarations shouldn't clash).
|
||||
fn structurally_same_type<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
a: Ty<'tcx>,
|
||||
b: Ty<'tcx>,
|
||||
ckind: types::CItemKind,
|
||||
) -> bool {
|
||||
let mut seen_types = UnordSet::default();
|
||||
let result = structurally_same_type_impl(&mut seen_types, tcx, param_env, a, b, ckind);
|
||||
let result = structurally_same_type_impl(&mut seen_types, tcx, typing_env, a, b, ckind);
|
||||
if cfg!(debug_assertions) && result {
|
||||
// Sanity-check: must have same ABI, size and alignment.
|
||||
// `extern` blocks cannot be generic, so we'll always get a layout here.
|
||||
let a_layout = tcx.layout_of(param_env.and(a)).unwrap();
|
||||
let b_layout = tcx.layout_of(param_env.and(b)).unwrap();
|
||||
let a_layout = tcx.layout_of(typing_env.as_query_input(a)).unwrap();
|
||||
let b_layout = tcx.layout_of(typing_env.as_query_input(b)).unwrap();
|
||||
assert_eq!(a_layout.backend_repr, b_layout.backend_repr);
|
||||
assert_eq!(a_layout.size, b_layout.size);
|
||||
assert_eq!(a_layout.align, b_layout.align);
|
||||
@ -227,7 +227,7 @@ fn structurally_same_type<'tcx>(
|
||||
fn structurally_same_type_impl<'tcx>(
|
||||
seen_types: &mut UnordSet<(Ty<'tcx>, Ty<'tcx>)>,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
a: Ty<'tcx>,
|
||||
b: Ty<'tcx>,
|
||||
ckind: types::CItemKind,
|
||||
@ -303,7 +303,7 @@ fn structurally_same_type_impl<'tcx>(
|
||||
structurally_same_type_impl(
|
||||
seen_types,
|
||||
tcx,
|
||||
param_env,
|
||||
typing_env,
|
||||
tcx.type_of(a_did).instantiate(tcx, a_gen_args),
|
||||
tcx.type_of(b_did).instantiate(tcx, b_gen_args),
|
||||
ckind,
|
||||
@ -315,23 +315,23 @@ fn structurally_same_type_impl<'tcx>(
|
||||
// For arrays, we also check the length.
|
||||
a_len == b_len
|
||||
&& structurally_same_type_impl(
|
||||
seen_types, tcx, param_env, *a_ty, *b_ty, ckind,
|
||||
seen_types, tcx, typing_env, *a_ty, *b_ty, ckind,
|
||||
)
|
||||
}
|
||||
(Slice(a_ty), Slice(b_ty)) => {
|
||||
structurally_same_type_impl(seen_types, tcx, param_env, *a_ty, *b_ty, ckind)
|
||||
structurally_same_type_impl(seen_types, tcx, typing_env, *a_ty, *b_ty, ckind)
|
||||
}
|
||||
(RawPtr(a_ty, a_mutbl), RawPtr(b_ty, b_mutbl)) => {
|
||||
a_mutbl == b_mutbl
|
||||
&& structurally_same_type_impl(
|
||||
seen_types, tcx, param_env, *a_ty, *b_ty, ckind,
|
||||
seen_types, tcx, typing_env, *a_ty, *b_ty, ckind,
|
||||
)
|
||||
}
|
||||
(Ref(_a_region, a_ty, a_mut), Ref(_b_region, b_ty, b_mut)) => {
|
||||
// For structural sameness, we don't need the region to be same.
|
||||
a_mut == b_mut
|
||||
&& structurally_same_type_impl(
|
||||
seen_types, tcx, param_env, *a_ty, *b_ty, ckind,
|
||||
seen_types, tcx, typing_env, *a_ty, *b_ty, ckind,
|
||||
)
|
||||
}
|
||||
(FnDef(..), FnDef(..)) => {
|
||||
@ -346,12 +346,12 @@ fn structurally_same_type_impl<'tcx>(
|
||||
(a_sig.abi, a_sig.safety, a_sig.c_variadic)
|
||||
== (b_sig.abi, b_sig.safety, b_sig.c_variadic)
|
||||
&& a_sig.inputs().iter().eq_by(b_sig.inputs().iter(), |a, b| {
|
||||
structurally_same_type_impl(seen_types, tcx, param_env, *a, *b, ckind)
|
||||
structurally_same_type_impl(seen_types, tcx, typing_env, *a, *b, ckind)
|
||||
})
|
||||
&& structurally_same_type_impl(
|
||||
seen_types,
|
||||
tcx,
|
||||
param_env,
|
||||
typing_env,
|
||||
a_sig.output(),
|
||||
b_sig.output(),
|
||||
ckind,
|
||||
@ -379,14 +379,14 @@ fn structurally_same_type_impl<'tcx>(
|
||||
// An Adt and a primitive or pointer type. This can be FFI-safe if non-null
|
||||
// enum layout optimisation is being applied.
|
||||
(Adt(..), _) if is_primitive_or_pointer(b) => {
|
||||
if let Some(a_inner) = types::repr_nullable_ptr(tcx, param_env, a, ckind) {
|
||||
if let Some(a_inner) = types::repr_nullable_ptr(tcx, typing_env, a, ckind) {
|
||||
a_inner == b
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
(_, Adt(..)) if is_primitive_or_pointer(a) => {
|
||||
if let Some(b_inner) = types::repr_nullable_ptr(tcx, param_env, b, ckind) {
|
||||
if let Some(b_inner) = types::repr_nullable_ptr(tcx, typing_env, b, ckind) {
|
||||
b_inner == a
|
||||
} else {
|
||||
false
|
||||
|
@ -368,7 +368,7 @@ impl<'tcx, 'a> Visitor<'tcx> for FindSignificantDropper<'tcx, 'a> {
|
||||
.cx
|
||||
.typeck_results()
|
||||
.expr_ty(expr)
|
||||
.has_significant_drop(self.cx.tcx, self.cx.param_env)
|
||||
.has_significant_drop(self.cx.tcx, self.cx.typing_env())
|
||||
{
|
||||
return ControlFlow::Break(expr.span);
|
||||
}
|
||||
|
@ -103,7 +103,8 @@ declare_lint_pass!(QueryStability => [POTENTIAL_QUERY_INSTABILITY, UNTRACKED_QUE
|
||||
impl LateLintPass<'_> for QueryStability {
|
||||
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
|
||||
let Some((span, def_id, args)) = typeck_results_of_method_fn(cx, expr) else { return };
|
||||
if let Ok(Some(instance)) = ty::Instance::try_resolve(cx.tcx, cx.param_env, def_id, args) {
|
||||
if let Ok(Some(instance)) = ty::Instance::try_resolve(cx.tcx, cx.typing_env(), def_id, args)
|
||||
{
|
||||
let def_id = instance.def_id();
|
||||
if cx.tcx.has_attr(def_id, sym::rustc_lint_query_instability) {
|
||||
cx.emit_span_lint(POTENTIAL_QUERY_INSTABILITY, span, QueryInstability {
|
||||
@ -544,7 +545,7 @@ impl Diagnostics {
|
||||
) {
|
||||
// Is the callee marked with `#[rustc_lint_diagnostics]`?
|
||||
let Some(inst) =
|
||||
ty::Instance::try_resolve(cx.tcx, cx.param_env, def_id, fn_gen_args).ok().flatten()
|
||||
ty::Instance::try_resolve(cx.tcx, cx.typing_env(), def_id, fn_gen_args).ok().flatten()
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
@ -128,7 +128,7 @@ impl<'tcx> LateLintPass<'tcx> for LetUnderscore {
|
||||
|
||||
// If the type has a trivial Drop implementation, then it doesn't
|
||||
// matter that we drop the value immediately.
|
||||
if !ty.needs_drop(cx.tcx, cx.param_env) {
|
||||
if !ty.needs_drop(cx.tcx, cx.typing_env()) {
|
||||
return;
|
||||
}
|
||||
// Lint for patterns like `mutex.lock()`, which returns `Result<MutexGuard, _>` as well.
|
||||
|
@ -157,15 +157,17 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
|
||||
Some(ty_def) if cx.tcx.is_lang_item(ty_def.did(), LangItem::String),
|
||||
);
|
||||
|
||||
let infcx = cx.tcx.infer_ctxt().build(cx.typing_mode());
|
||||
let (infcx, param_env) = cx.tcx.infer_ctxt().build_with_typing_env(cx.typing_env());
|
||||
let suggest_display = is_str
|
||||
|| cx.tcx.get_diagnostic_item(sym::Display).is_some_and(|t| {
|
||||
infcx.type_implements_trait(t, [ty], cx.param_env).may_apply()
|
||||
});
|
||||
|| cx
|
||||
.tcx
|
||||
.get_diagnostic_item(sym::Display)
|
||||
.is_some_and(|t| infcx.type_implements_trait(t, [ty], param_env).may_apply());
|
||||
let suggest_debug = !suggest_display
|
||||
&& cx.tcx.get_diagnostic_item(sym::Debug).is_some_and(|t| {
|
||||
infcx.type_implements_trait(t, [ty], cx.param_env).may_apply()
|
||||
});
|
||||
&& cx
|
||||
.tcx
|
||||
.get_diagnostic_item(sym::Debug)
|
||||
.is_some_and(|t| infcx.type_implements_trait(t, [ty], param_env).may_apply());
|
||||
|
||||
let suggest_panic_any = !is_str && panic == sym::std_panic_macro;
|
||||
|
||||
|
@ -94,9 +94,9 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
|
||||
|
||||
let args = cx
|
||||
.tcx
|
||||
.normalize_erasing_regions(cx.param_env, cx.typeck_results().node_args(expr.hir_id));
|
||||
.normalize_erasing_regions(cx.typing_env(), cx.typeck_results().node_args(expr.hir_id));
|
||||
// Resolve the trait method instance.
|
||||
let Ok(Some(i)) = ty::Instance::try_resolve(cx.tcx, cx.param_env, did, args) else {
|
||||
let Ok(Some(i)) = ty::Instance::try_resolve(cx.tcx, cx.typing_env(), did, args) else {
|
||||
return;
|
||||
};
|
||||
// (Re)check that it implements the noop diagnostic.
|
||||
|
@ -103,7 +103,7 @@ impl TailExprDropOrder {
|
||||
if matches!(fn_kind, hir::intravisit::FnKind::Closure) {
|
||||
for &capture in cx.tcx.closure_captures(def_id) {
|
||||
if matches!(capture.info.capture_kind, ty::UpvarCapture::ByValue)
|
||||
&& capture.place.ty().has_significant_drop(cx.tcx, cx.param_env)
|
||||
&& capture.place.ty().has_significant_drop(cx.tcx, cx.typing_env())
|
||||
{
|
||||
locals.push(capture.var_ident.span);
|
||||
}
|
||||
@ -113,7 +113,7 @@ impl TailExprDropOrder {
|
||||
if cx
|
||||
.typeck_results()
|
||||
.node_type(param.hir_id)
|
||||
.has_significant_drop(cx.tcx, cx.param_env)
|
||||
.has_significant_drop(cx.tcx, cx.typing_env())
|
||||
{
|
||||
locals.push(param.span);
|
||||
}
|
||||
@ -158,7 +158,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LocalCollector<'a, 'tcx> {
|
||||
fn visit_pat(&mut self, pat: &'tcx Pat<'tcx>) {
|
||||
if let PatKind::Binding(_binding_mode, id, ident, pat) = pat.kind {
|
||||
let ty = self.cx.typeck_results().node_type(id);
|
||||
if ty.has_significant_drop(self.cx.tcx, self.cx.param_env) {
|
||||
if ty.has_significant_drop(self.cx.tcx, self.cx.typing_env()) {
|
||||
self.locals.push(ident.span);
|
||||
}
|
||||
if let Some(pat) = pat {
|
||||
@ -234,7 +234,10 @@ impl<'a, 'tcx> LintTailExpr<'a, 'tcx> {
|
||||
if Self::expr_eventually_point_into_local(expr) {
|
||||
return false;
|
||||
}
|
||||
self.cx.typeck_results().expr_ty(expr).has_significant_drop(self.cx.tcx, self.cx.param_env)
|
||||
self.cx
|
||||
.typeck_results()
|
||||
.expr_ty(expr)
|
||||
.has_significant_drop(self.cx.tcx, self.cx.typing_env())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -613,10 +613,11 @@ pub(crate) fn transparent_newtype_field<'a, 'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
variant: &'a ty::VariantDef,
|
||||
) -> Option<&'a ty::FieldDef> {
|
||||
let param_env = tcx.param_env(variant.def_id);
|
||||
let typing_env = ty::TypingEnv::non_body_analysis(tcx, variant.def_id);
|
||||
variant.fields.iter().find(|field| {
|
||||
let field_ty = tcx.type_of(field.did).instantiate_identity();
|
||||
let is_1zst = tcx.layout_of(param_env.and(field_ty)).is_ok_and(|layout| layout.is_1zst());
|
||||
let is_1zst =
|
||||
tcx.layout_of(typing_env.as_query_input(field_ty)).is_ok_and(|layout| layout.is_1zst());
|
||||
!is_1zst
|
||||
})
|
||||
}
|
||||
@ -624,11 +625,11 @@ pub(crate) fn transparent_newtype_field<'a, 'tcx>(
|
||||
/// Is type known to be non-null?
|
||||
fn ty_is_known_nonnull<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
mode: CItemKind,
|
||||
) -> bool {
|
||||
let ty = tcx.try_normalize_erasing_regions(param_env, ty).unwrap_or(ty);
|
||||
let ty = tcx.try_normalize_erasing_regions(typing_env, ty).unwrap_or(ty);
|
||||
|
||||
match ty.kind() {
|
||||
ty::FnPtr(..) => true,
|
||||
@ -649,7 +650,7 @@ fn ty_is_known_nonnull<'tcx>(
|
||||
def.variants()
|
||||
.iter()
|
||||
.filter_map(|variant| transparent_newtype_field(tcx, variant))
|
||||
.any(|field| ty_is_known_nonnull(tcx, param_env, field.ty(tcx, args), mode))
|
||||
.any(|field| ty_is_known_nonnull(tcx, typing_env, field.ty(tcx, args), mode))
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
@ -659,10 +660,10 @@ fn ty_is_known_nonnull<'tcx>(
|
||||
/// If the type passed in was not scalar, returns None.
|
||||
fn get_nullable_type<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> Option<Ty<'tcx>> {
|
||||
let ty = tcx.try_normalize_erasing_regions(param_env, ty).unwrap_or(ty);
|
||||
let ty = tcx.try_normalize_erasing_regions(typing_env, ty).unwrap_or(ty);
|
||||
|
||||
Some(match *ty.kind() {
|
||||
ty::Adt(field_def, field_args) => {
|
||||
@ -679,7 +680,7 @@ fn get_nullable_type<'tcx>(
|
||||
.expect("No non-zst fields in transparent type.")
|
||||
.ty(tcx, field_args)
|
||||
};
|
||||
return get_nullable_type(tcx, param_env, inner_field_ty);
|
||||
return get_nullable_type(tcx, typing_env, inner_field_ty);
|
||||
}
|
||||
ty::Int(ty) => Ty::new_int(tcx, ty),
|
||||
ty::Uint(ty) => Ty::new_uint(tcx, ty),
|
||||
@ -708,10 +709,10 @@ fn get_nullable_type<'tcx>(
|
||||
/// - Does not have the `#[non_exhaustive]` attribute.
|
||||
fn is_niche_optimization_candidate<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> bool {
|
||||
if tcx.layout_of(param_env.and(ty)).is_ok_and(|layout| !layout.is_1zst()) {
|
||||
if tcx.layout_of(typing_env.as_query_input(ty)).is_ok_and(|layout| !layout.is_1zst()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -734,7 +735,7 @@ fn is_niche_optimization_candidate<'tcx>(
|
||||
/// `core::ptr::NonNull`, and `#[repr(transparent)]` newtypes.
|
||||
pub(crate) fn repr_nullable_ptr<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
ckind: CItemKind,
|
||||
) -> Option<Ty<'tcx>> {
|
||||
@ -747,9 +748,9 @@ pub(crate) fn repr_nullable_ptr<'tcx>(
|
||||
let ty1 = field1.ty(tcx, args);
|
||||
let ty2 = field2.ty(tcx, args);
|
||||
|
||||
if is_niche_optimization_candidate(tcx, param_env, ty1) {
|
||||
if is_niche_optimization_candidate(tcx, typing_env, ty1) {
|
||||
ty2
|
||||
} else if is_niche_optimization_candidate(tcx, param_env, ty2) {
|
||||
} else if is_niche_optimization_candidate(tcx, typing_env, ty2) {
|
||||
ty1
|
||||
} else {
|
||||
return None;
|
||||
@ -760,20 +761,20 @@ pub(crate) fn repr_nullable_ptr<'tcx>(
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
if !ty_is_known_nonnull(tcx, param_env, field_ty, ckind) {
|
||||
if !ty_is_known_nonnull(tcx, typing_env, field_ty, ckind) {
|
||||
return None;
|
||||
}
|
||||
|
||||
// At this point, the field's type is known to be nonnull and the parent enum is Option-like.
|
||||
// If the computed size for the field and the enum are different, the nonnull optimization isn't
|
||||
// being applied (and we've got a problem somewhere).
|
||||
let compute_size_skeleton = |t| SizeSkeleton::compute(t, tcx, param_env).ok();
|
||||
let compute_size_skeleton = |t| SizeSkeleton::compute(t, tcx, typing_env).ok();
|
||||
if !compute_size_skeleton(ty)?.same_size(compute_size_skeleton(field_ty)?) {
|
||||
bug!("improper_ctypes: Option nonnull optimization not applied?");
|
||||
}
|
||||
|
||||
// Return the nullable type this Option-like enum can be safely represented with.
|
||||
let field_ty_layout = tcx.layout_of(param_env.and(field_ty));
|
||||
let field_ty_layout = tcx.layout_of(typing_env.as_query_input(field_ty));
|
||||
if field_ty_layout.is_err() && !field_ty.has_non_region_param() {
|
||||
bug!("should be able to compute the layout of non-polymorphic type");
|
||||
}
|
||||
@ -784,10 +785,10 @@ pub(crate) fn repr_nullable_ptr<'tcx>(
|
||||
WrappingRange { start: 0, end }
|
||||
if end == field_ty_scalar.size(&tcx).unsigned_int_max() - 1 =>
|
||||
{
|
||||
return Some(get_nullable_type(tcx, param_env, field_ty).unwrap());
|
||||
return Some(get_nullable_type(tcx, typing_env, field_ty).unwrap());
|
||||
}
|
||||
WrappingRange { start: 1, .. } => {
|
||||
return Some(get_nullable_type(tcx, param_env, field_ty).unwrap());
|
||||
return Some(get_nullable_type(tcx, typing_env, field_ty).unwrap());
|
||||
}
|
||||
WrappingRange { start, end } => {
|
||||
unreachable!("Unhandled start and end range: ({}, {})", start, end)
|
||||
@ -825,7 +826,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
||||
let field_ty = self
|
||||
.cx
|
||||
.tcx
|
||||
.try_normalize_erasing_regions(self.cx.param_env, field_ty)
|
||||
.try_normalize_erasing_regions(self.cx.typing_env(), field_ty)
|
||||
.unwrap_or(field_ty);
|
||||
self.check_type_for_ffi(acc, field_ty)
|
||||
}
|
||||
@ -988,7 +989,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
||||
{
|
||||
// Special-case types like `Option<extern fn()>` and `Result<extern fn(), ()>`
|
||||
if let Some(ty) =
|
||||
repr_nullable_ptr(self.cx.tcx, self.cx.param_env, ty, self.mode)
|
||||
repr_nullable_ptr(self.cx.tcx, self.cx.typing_env(), ty, self.mode)
|
||||
{
|
||||
return self.check_type_for_ffi(acc, ty);
|
||||
}
|
||||
@ -1196,7 +1197,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
||||
if let Some(ty) = self
|
||||
.cx
|
||||
.tcx
|
||||
.try_normalize_erasing_regions(self.cx.param_env, ty)
|
||||
.try_normalize_erasing_regions(self.cx.typing_env(), ty)
|
||||
.unwrap_or(ty)
|
||||
.visit_with(&mut ProhibitOpaqueTypes)
|
||||
.break_value()
|
||||
@ -1220,7 +1221,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
||||
return;
|
||||
}
|
||||
|
||||
let ty = self.cx.tcx.try_normalize_erasing_regions(self.cx.param_env, ty).unwrap_or(ty);
|
||||
let ty = self.cx.tcx.try_normalize_erasing_regions(self.cx.typing_env(), ty).unwrap_or(ty);
|
||||
|
||||
// C doesn't really support passing arrays by value - the only way to pass an array by value
|
||||
// is through a struct. So, first test that the top level isn't an array, and then
|
||||
|
@ -272,7 +272,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
||||
|| !ty.is_inhabited_from(
|
||||
cx.tcx,
|
||||
cx.tcx.parent_module(expr.hir_id).to_def_id(),
|
||||
cx.param_env,
|
||||
cx.typing_env(),
|
||||
)
|
||||
{
|
||||
return Some(MustUsePath::Suppressed);
|
||||
@ -556,7 +556,7 @@ impl<'tcx> LateLintPass<'tcx> for PathStatements {
|
||||
if let hir::StmtKind::Semi(expr) = s.kind {
|
||||
if let hir::ExprKind::Path(_) = expr.kind {
|
||||
let ty = cx.typeck_results().expr_ty(expr);
|
||||
if ty.needs_drop(cx.tcx, cx.param_env) {
|
||||
if ty.needs_drop(cx.tcx, cx.typing_env()) {
|
||||
let sub = if let Ok(snippet) = cx.sess().source_map().span_to_snippet(expr.span)
|
||||
{
|
||||
PathStatementDropSub::Suggestion { span: s.span, snippet }
|
||||
|
@ -6,7 +6,7 @@ use rustc_ast::CRATE_NODE_ID;
|
||||
use rustc_attr as attr;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_middle::query::LocalCrate;
|
||||
use rustc_middle::ty::{List, ParamEnv, ParamEnvAnd, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{self, List, Ty, TyCtxt};
|
||||
use rustc_session::Session;
|
||||
use rustc_session::config::CrateType;
|
||||
use rustc_session::cstore::{
|
||||
@ -613,7 +613,7 @@ impl<'tcx> Collector<'tcx> {
|
||||
.map(|ty| {
|
||||
let layout = self
|
||||
.tcx
|
||||
.layout_of(ParamEnvAnd { param_env: ParamEnv::empty(), value: ty })
|
||||
.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty))
|
||||
.expect("layout")
|
||||
.layout;
|
||||
// In both stdcall and fastcall, we always round up the argument size to the
|
||||
|
@ -102,10 +102,11 @@ impl<'tcx> ConstValue<'tcx> {
|
||||
pub fn try_to_bits_for_ty(
|
||||
&self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> Option<u128> {
|
||||
let size = tcx.layout_of(param_env.with_reveal_all_normalized(tcx).and(ty)).ok()?.size;
|
||||
let size =
|
||||
tcx.layout_of(typing_env.with_reveal_all_normalized(tcx).as_query_input(ty)).ok()?.size;
|
||||
self.try_to_bits(size)
|
||||
}
|
||||
|
||||
@ -314,7 +315,7 @@ impl<'tcx> Const<'tcx> {
|
||||
pub fn eval(
|
||||
self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
span: Span,
|
||||
) -> Result<ConstValue<'tcx>, ErrorHandled> {
|
||||
match self {
|
||||
@ -333,7 +334,7 @@ impl<'tcx> Const<'tcx> {
|
||||
}
|
||||
Const::Unevaluated(uneval, _) => {
|
||||
// FIXME: We might want to have a `try_eval`-like function on `Unevaluated`
|
||||
tcx.const_eval_resolve(param_env, uneval, span)
|
||||
tcx.const_eval_resolve(typing_env, uneval, span)
|
||||
}
|
||||
Const::Val(val, _) => Ok(val),
|
||||
}
|
||||
@ -343,7 +344,7 @@ impl<'tcx> Const<'tcx> {
|
||||
pub fn try_eval_scalar(
|
||||
self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
) -> Option<Scalar> {
|
||||
if let Const::Ty(_, c) = self
|
||||
&& let ty::ConstKind::Value(ty, val) = c.kind()
|
||||
@ -354,7 +355,7 @@ impl<'tcx> Const<'tcx> {
|
||||
// pointer here, which valtrees don't represent.)
|
||||
Some(val.unwrap_leaf().into())
|
||||
} else {
|
||||
self.eval(tcx, param_env, DUMMY_SP).ok()?.try_to_scalar()
|
||||
self.eval(tcx, typing_env, DUMMY_SP).ok()?.try_to_scalar()
|
||||
}
|
||||
}
|
||||
|
||||
@ -362,23 +363,29 @@ impl<'tcx> Const<'tcx> {
|
||||
pub fn try_eval_scalar_int(
|
||||
self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
) -> Option<ScalarInt> {
|
||||
self.try_eval_scalar(tcx, param_env)?.try_to_scalar_int().ok()
|
||||
self.try_eval_scalar(tcx, typing_env)?.try_to_scalar_int().ok()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn try_eval_bits(&self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Option<u128> {
|
||||
let int = self.try_eval_scalar_int(tcx, param_env)?;
|
||||
let size =
|
||||
tcx.layout_of(param_env.with_reveal_all_normalized(tcx).and(self.ty())).ok()?.size;
|
||||
pub fn try_eval_bits(
|
||||
&self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
) -> Option<u128> {
|
||||
let int = self.try_eval_scalar_int(tcx, typing_env)?;
|
||||
let size = tcx
|
||||
.layout_of(typing_env.with_reveal_all_normalized(tcx).as_query_input(self.ty()))
|
||||
.ok()?
|
||||
.size;
|
||||
Some(int.to_bits(size))
|
||||
}
|
||||
|
||||
/// Panics if the value cannot be evaluated or doesn't contain a valid integer of the given type.
|
||||
#[inline]
|
||||
pub fn eval_bits(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> u128 {
|
||||
self.try_eval_bits(tcx, param_env)
|
||||
pub fn eval_bits(self, tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> u128 {
|
||||
self.try_eval_bits(tcx, typing_env)
|
||||
.unwrap_or_else(|| bug!("expected bits of {:#?}, got {:#?}", self.ty(), self))
|
||||
}
|
||||
|
||||
@ -386,21 +393,21 @@ impl<'tcx> Const<'tcx> {
|
||||
pub fn try_eval_target_usize(
|
||||
self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
) -> Option<u64> {
|
||||
Some(self.try_eval_scalar_int(tcx, param_env)?.to_target_usize(tcx))
|
||||
Some(self.try_eval_scalar_int(tcx, typing_env)?.to_target_usize(tcx))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Panics if the value cannot be evaluated or doesn't contain a valid `usize`.
|
||||
pub fn eval_target_usize(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> u64 {
|
||||
self.try_eval_target_usize(tcx, param_env)
|
||||
pub fn eval_target_usize(self, tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> u64 {
|
||||
self.try_eval_target_usize(tcx, typing_env)
|
||||
.unwrap_or_else(|| bug!("expected usize, got {:#?}", self))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn try_eval_bool(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Option<bool> {
|
||||
self.try_eval_scalar_int(tcx, param_env)?.try_into().ok()
|
||||
pub fn try_eval_bool(self, tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> Option<bool> {
|
||||
self.try_eval_scalar_int(tcx, typing_env)?.try_into().ok()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -411,17 +418,16 @@ impl<'tcx> Const<'tcx> {
|
||||
pub fn from_bits(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
bits: u128,
|
||||
param_env_ty: ty::ParamEnvAnd<'tcx, Ty<'tcx>>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> Self {
|
||||
let size = tcx
|
||||
.layout_of(param_env_ty)
|
||||
.unwrap_or_else(|e| {
|
||||
bug!("could not compute layout for {:?}: {:?}", param_env_ty.value, e)
|
||||
})
|
||||
.layout_of(typing_env.as_query_input(ty))
|
||||
.unwrap_or_else(|e| bug!("could not compute layout for {ty:?}: {e:?}"))
|
||||
.size;
|
||||
let cv = ConstValue::Scalar(Scalar::from_uint(bits, size));
|
||||
|
||||
Self::Val(cv, param_env_ty.value)
|
||||
Self::Val(cv, ty)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -438,7 +444,8 @@ impl<'tcx> Const<'tcx> {
|
||||
|
||||
pub fn from_usize(tcx: TyCtxt<'tcx>, n: u64) -> Self {
|
||||
let ty = tcx.types.usize;
|
||||
Self::from_bits(tcx, n as u128, ty::ParamEnv::empty().and(ty))
|
||||
let typing_env = ty::TypingEnv::fully_monomorphized();
|
||||
Self::from_bits(tcx, n as u128, typing_env, ty)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -351,7 +351,11 @@ impl<'tcx> GlobalAlloc<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn size_and_align(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> (Size, Align) {
|
||||
pub fn size_and_align(
|
||||
&self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
) -> (Size, Align) {
|
||||
match self {
|
||||
GlobalAlloc::Static(def_id) => {
|
||||
let DefKind::Static { nested, .. } = tcx.def_kind(def_id) else {
|
||||
@ -374,7 +378,7 @@ impl<'tcx> GlobalAlloc<'tcx> {
|
||||
.type_of(def_id)
|
||||
.no_bound_vars()
|
||||
.expect("statics should not have generic parameters");
|
||||
let layout = tcx.layout_of(param_env.and(ty)).unwrap();
|
||||
let layout = tcx.layout_of(typing_env.as_query_input(ty)).unwrap();
|
||||
assert!(layout.is_sized());
|
||||
(layout.size, layout.align.abi)
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
pub fn const_eval_resolve(
|
||||
self,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
ct: mir::UnevaluatedConst<'tcx>,
|
||||
span: Span,
|
||||
) -> EvalToConstValueResult<'tcx> {
|
||||
@ -72,14 +72,11 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
bug!("did not expect inference variables here");
|
||||
}
|
||||
|
||||
match ty::Instance::try_resolve(
|
||||
self, param_env,
|
||||
// FIXME: maybe have a separate version for resolving mir::UnevaluatedConst?
|
||||
ct.def, ct.args,
|
||||
) {
|
||||
// FIXME: maybe have a separate version for resolving mir::UnevaluatedConst?
|
||||
match ty::Instance::try_resolve(self, typing_env, ct.def, ct.args) {
|
||||
Ok(Some(instance)) => {
|
||||
let cid = GlobalId { instance, promoted: ct.promoted };
|
||||
self.const_eval_global_id(param_env, cid, span)
|
||||
self.const_eval_global_id(typing_env.param_env, cid, span)
|
||||
}
|
||||
// For errors during resolution, we deliberately do not point at the usage site of the constant,
|
||||
// since for these errors the place the constant is used shouldn't matter.
|
||||
@ -91,7 +88,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
pub fn const_eval_resolve_for_typeck(
|
||||
self,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
ct: ty::UnevaluatedConst<'tcx>,
|
||||
span: Span,
|
||||
) -> EvalToValTreeResult<'tcx> {
|
||||
@ -105,10 +102,10 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
bug!("did not expect inference variables here");
|
||||
}
|
||||
|
||||
match ty::Instance::try_resolve(self, param_env, ct.def, ct.args) {
|
||||
match ty::Instance::try_resolve(self, typing_env, ct.def, ct.args) {
|
||||
Ok(Some(instance)) => {
|
||||
let cid = GlobalId { instance, promoted: None };
|
||||
self.const_eval_global_id_for_typeck(param_env, cid, span).inspect(|_| {
|
||||
self.const_eval_global_id_for_typeck(typing_env.param_env, cid, span).inspect(|_| {
|
||||
// We are emitting the lint here instead of in `is_const_evaluatable`
|
||||
// as we normalize obligations before checking them, and normalization
|
||||
// uses this function to evaluate this constant.
|
||||
|
@ -39,7 +39,7 @@ use crate::ty::fold::{FallibleTypeFolder, TypeFoldable};
|
||||
use crate::ty::print::{FmtPrinter, Printer, pretty_print_const, with_no_trimmed_paths};
|
||||
use crate::ty::visit::TypeVisitableExt;
|
||||
use crate::ty::{
|
||||
self, AdtDef, GenericArg, GenericArgsRef, Instance, InstanceKind, List, Ty, TyCtxt, TypingMode,
|
||||
self, AdtDef, GenericArg, GenericArgsRef, Instance, InstanceKind, List, Ty, TyCtxt, TypingEnv,
|
||||
UserTypeAnnotationIndex,
|
||||
};
|
||||
|
||||
@ -452,12 +452,17 @@ impl<'tcx> Body<'tcx> {
|
||||
self.basic_blocks.as_mut()
|
||||
}
|
||||
|
||||
pub fn typing_mode(&self, _tcx: TyCtxt<'tcx>) -> TypingMode<'tcx> {
|
||||
pub fn typing_env(&self, tcx: TyCtxt<'tcx>) -> TypingEnv<'tcx> {
|
||||
match self.phase {
|
||||
// FIXME(#132279): the MIR is quite clearly inside of a body, so we
|
||||
// should instead reveal opaques defined by that body here.
|
||||
MirPhase::Built | MirPhase::Analysis(_) => TypingMode::non_body_analysis(),
|
||||
MirPhase::Runtime(_) => TypingMode::PostAnalysis,
|
||||
// FIXME(#132279): we should reveal the opaques defined in the body during analysis.
|
||||
MirPhase::Built | MirPhase::Analysis(_) => TypingEnv {
|
||||
typing_mode: ty::TypingMode::non_body_analysis(),
|
||||
param_env: tcx.param_env(self.source.def_id()),
|
||||
},
|
||||
MirPhase::Runtime(_) => TypingEnv {
|
||||
typing_mode: ty::TypingMode::PostAnalysis,
|
||||
param_env: tcx.param_env_reveal_all_normalized(self.source.def_id()),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@ -618,7 +623,7 @@ impl<'tcx> Body<'tcx> {
|
||||
}
|
||||
|
||||
/// If this basic block ends with a [`TerminatorKind::SwitchInt`] for which we can evaluate the
|
||||
/// dimscriminant in monomorphization, we return the discriminant bits and the
|
||||
/// discriminant in monomorphization, we return the discriminant bits and the
|
||||
/// [`SwitchTargets`], just so the caller doesn't also have to match on the terminator.
|
||||
fn try_const_mono_switchint<'a>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
@ -627,13 +632,15 @@ impl<'tcx> Body<'tcx> {
|
||||
) -> Option<(u128, &'a SwitchTargets)> {
|
||||
// There are two places here we need to evaluate a constant.
|
||||
let eval_mono_const = |constant: &ConstOperand<'tcx>| {
|
||||
let env = ty::ParamEnv::reveal_all();
|
||||
// FIXME(#132279): what is this, why are we using an empty environment with
|
||||
// `RevealAll` here.
|
||||
let typing_env = ty::TypingEnv::fully_monomorphized();
|
||||
let mono_literal = instance.instantiate_mir_and_normalize_erasing_regions(
|
||||
tcx,
|
||||
env,
|
||||
typing_env,
|
||||
crate::ty::EarlyBinder::bind(constant.const_),
|
||||
);
|
||||
mono_literal.try_eval_bits(tcx, env)
|
||||
mono_literal.try_eval_bits(tcx, typing_env)
|
||||
};
|
||||
|
||||
let TerminatorKind::SwitchInt { discr, targets } = &block.terminator().kind else {
|
||||
|
@ -332,9 +332,9 @@ impl<'tcx> Operand<'tcx> {
|
||||
span: Span,
|
||||
) -> Operand<'tcx> {
|
||||
debug_assert!({
|
||||
let param_env_and_ty = ty::ParamEnv::empty().and(ty);
|
||||
let typing_env = ty::TypingEnv::fully_monomorphized();
|
||||
let type_size = tcx
|
||||
.layout_of(param_env_and_ty)
|
||||
.layout_of(typing_env.as_query_input(ty))
|
||||
.unwrap_or_else(|e| panic!("could not compute layout for {ty:?}: {e:?}"))
|
||||
.size;
|
||||
let scalar_size = match val {
|
||||
|
@ -20,7 +20,7 @@ use smallvec::SmallVec;
|
||||
use super::{BasicBlock, Const, Local, UserTypeProjection};
|
||||
use crate::mir::coverage::CoverageKind;
|
||||
use crate::ty::adjustment::PointerCoercion;
|
||||
use crate::ty::{self, GenericArgsRef, List, Region, Ty, TyCtxt, UserTypeAnnotationIndex};
|
||||
use crate::ty::{self, GenericArgsRef, List, Region, Ty, UserTypeAnnotationIndex};
|
||||
|
||||
/// Represents the "flavors" of MIR.
|
||||
///
|
||||
@ -100,13 +100,6 @@ impl MirPhase {
|
||||
MirPhase::Runtime(RuntimePhase::Optimized) => "runtime-optimized",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn param_env<'tcx>(&self, tcx: TyCtxt<'tcx>, body_def_id: DefId) -> ty::ParamEnv<'tcx> {
|
||||
match self {
|
||||
MirPhase::Built | MirPhase::Analysis(_) => tcx.param_env(body_def_id),
|
||||
MirPhase::Runtime(_) => tcx.param_env_reveal_all_normalized(body_def_id),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// See [`MirPhase::Analysis`].
|
||||
|
@ -467,6 +467,18 @@ impl<'tcx, T: Key> Key for ty::ParamEnvAnd<'tcx, T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T: Key> Key for ty::PseudoCanonicalInput<'tcx, T> {
|
||||
type Cache<V> = DefaultCache<Self, V>;
|
||||
|
||||
fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
|
||||
self.value.default_span(tcx)
|
||||
}
|
||||
|
||||
fn ty_def_id(&self) -> Option<DefId> {
|
||||
self.value.ty_def_id()
|
||||
}
|
||||
}
|
||||
|
||||
impl Key for Symbol {
|
||||
type Cache<V> = DefaultCache<Self, V>;
|
||||
|
||||
@ -575,7 +587,7 @@ impl Key for (LocalDefId, HirId) {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Key for (ValidityRequirement, ty::ParamEnvAnd<'tcx, Ty<'tcx>>) {
|
||||
impl<'tcx> Key for (ValidityRequirement, ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) {
|
||||
type Cache<V> = DefaultCache<Self, V>;
|
||||
|
||||
// Just forward to `Ty<'tcx>`
|
||||
|
@ -81,8 +81,8 @@ use crate::ty::layout::ValidityRequirement;
|
||||
use crate::ty::print::{PrintTraitRefExt, describe_as_module};
|
||||
use crate::ty::util::AlwaysRequiresDrop;
|
||||
use crate::ty::{
|
||||
self, CrateInherentImpls, GenericArg, GenericArgsRef, ParamEnvAnd, Ty, TyCtxt, TyCtxtFeed,
|
||||
UnusedGenericParams,
|
||||
self, CrateInherentImpls, GenericArg, GenericArgsRef, PseudoCanonicalInput, Ty, TyCtxt,
|
||||
TyCtxtFeed, UnusedGenericParams,
|
||||
};
|
||||
use crate::{dep_graph, mir, thir};
|
||||
|
||||
@ -1341,10 +1341,10 @@ rustc_queries! {
|
||||
}
|
||||
|
||||
query codegen_select_candidate(
|
||||
key: (ty::ParamEnv<'tcx>, ty::TraitRef<'tcx>)
|
||||
key: PseudoCanonicalInput<'tcx, ty::TraitRef<'tcx>>
|
||||
) -> Result<&'tcx ImplSource<'tcx, ()>, CodegenObligationError> {
|
||||
cache_on_disk_if { true }
|
||||
desc { |tcx| "computing candidate for `{}`", key.1 }
|
||||
desc { |tcx| "computing candidate for `{}`", key.value }
|
||||
}
|
||||
|
||||
/// Return all `impl` blocks in the current crate.
|
||||
@ -1406,15 +1406,15 @@ rustc_queries! {
|
||||
desc { "computing whether `{}` is `Unpin`", env.value }
|
||||
}
|
||||
/// Query backing `Ty::needs_drop`.
|
||||
query needs_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
|
||||
query needs_drop_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool {
|
||||
desc { "computing whether `{}` needs drop", env.value }
|
||||
}
|
||||
/// Query backing `Ty::needs_async_drop`.
|
||||
query needs_async_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
|
||||
query needs_async_drop_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool {
|
||||
desc { "computing whether `{}` needs async drop", env.value }
|
||||
}
|
||||
/// Query backing `Ty::has_significant_drop_raw`.
|
||||
query has_significant_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
|
||||
query has_significant_drop_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool {
|
||||
desc { "computing whether `{}` has a significant drop", env.value }
|
||||
}
|
||||
|
||||
@ -1451,7 +1451,7 @@ rustc_queries! {
|
||||
/// Computes the layout of a type. Note that this implicitly
|
||||
/// executes in "reveal all" mode, and will normalize the input type.
|
||||
query layout_of(
|
||||
key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>
|
||||
key: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>
|
||||
) -> Result<ty::layout::TyAndLayout<'tcx>, &'tcx ty::layout::LayoutError<'tcx>> {
|
||||
depth_limit
|
||||
desc { "computing layout of `{}`", key.value }
|
||||
@ -1464,7 +1464,7 @@ rustc_queries! {
|
||||
/// NB: this doesn't handle virtual calls - those should use `fn_abi_of_instance`
|
||||
/// instead, where the instance is an `InstanceKind::Virtual`.
|
||||
query fn_abi_of_fn_ptr(
|
||||
key: ty::ParamEnvAnd<'tcx, (ty::PolyFnSig<'tcx>, &'tcx ty::List<Ty<'tcx>>)>
|
||||
key: ty::PseudoCanonicalInput<'tcx, (ty::PolyFnSig<'tcx>, &'tcx ty::List<Ty<'tcx>>)>
|
||||
) -> Result<&'tcx rustc_target::callconv::FnAbi<'tcx, Ty<'tcx>>, &'tcx ty::layout::FnAbiError<'tcx>> {
|
||||
desc { "computing call ABI of `{}` function pointers", key.value.0 }
|
||||
}
|
||||
@ -1475,7 +1475,7 @@ rustc_queries! {
|
||||
/// NB: that includes virtual calls, which are represented by "direct calls"
|
||||
/// to an `InstanceKind::Virtual` instance (of `<dyn Trait as Trait>::fn`).
|
||||
query fn_abi_of_instance(
|
||||
key: ty::ParamEnvAnd<'tcx, (ty::Instance<'tcx>, &'tcx ty::List<Ty<'tcx>>)>
|
||||
key: ty::PseudoCanonicalInput<'tcx, (ty::Instance<'tcx>, &'tcx ty::List<Ty<'tcx>>)>
|
||||
) -> Result<&'tcx rustc_target::callconv::FnAbi<'tcx, Ty<'tcx>>, &'tcx ty::layout::FnAbiError<'tcx>> {
|
||||
desc { "computing call ABI of `{}`", key.value.0 }
|
||||
}
|
||||
@ -2088,7 +2088,7 @@ rustc_queries! {
|
||||
|
||||
/// Do not call this query directly: invoke `try_normalize_erasing_regions` instead.
|
||||
query try_normalize_generic_arg_after_erasing_regions(
|
||||
goal: ParamEnvAnd<'tcx, GenericArg<'tcx>>
|
||||
goal: PseudoCanonicalInput<'tcx, GenericArg<'tcx>>
|
||||
) -> Result<GenericArg<'tcx>, NoSolution> {
|
||||
desc { "normalizing `{}`", goal.value }
|
||||
}
|
||||
@ -2245,7 +2245,7 @@ rustc_queries! {
|
||||
/// from `Ok(None)` to avoid misleading diagnostics when an error
|
||||
/// has already been/will be emitted, for the original cause.
|
||||
query resolve_instance_raw(
|
||||
key: ty::ParamEnvAnd<'tcx, (DefId, GenericArgsRef<'tcx>)>
|
||||
key: ty::PseudoCanonicalInput<'tcx, (DefId, GenericArgsRef<'tcx>)>
|
||||
) -> Result<Option<ty::Instance<'tcx>>, ErrorGuaranteed> {
|
||||
desc { "resolving instance `{}`", ty::Instance::new(key.value.0, key.value.1) }
|
||||
}
|
||||
@ -2283,7 +2283,7 @@ rustc_queries! {
|
||||
desc { "computing the backend features for CLI flags" }
|
||||
}
|
||||
|
||||
query check_validity_requirement(key: (ValidityRequirement, ty::ParamEnvAnd<'tcx, Ty<'tcx>>)) -> Result<bool, &'tcx ty::layout::LayoutError<'tcx>> {
|
||||
query check_validity_requirement(key: (ValidityRequirement, ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>)) -> Result<bool, &'tcx ty::layout::LayoutError<'tcx>> {
|
||||
desc { "checking validity requirement for `{}`: {}", key.1.value, key.0 }
|
||||
}
|
||||
|
||||
|
@ -905,7 +905,7 @@ impl<'tcx> PatRange<'tcx> {
|
||||
&self,
|
||||
value: mir::Const<'tcx>,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
) -> Option<bool> {
|
||||
use Ordering::*;
|
||||
debug_assert_eq!(self.ty, value.ty());
|
||||
@ -913,10 +913,10 @@ impl<'tcx> PatRange<'tcx> {
|
||||
let value = PatRangeBoundary::Finite(value);
|
||||
// For performance, it's important to only do the second comparison if necessary.
|
||||
Some(
|
||||
match self.lo.compare_with(value, ty, tcx, param_env)? {
|
||||
match self.lo.compare_with(value, ty, tcx, typing_env)? {
|
||||
Less | Equal => true,
|
||||
Greater => false,
|
||||
} && match value.compare_with(self.hi, ty, tcx, param_env)? {
|
||||
} && match value.compare_with(self.hi, ty, tcx, typing_env)? {
|
||||
Less => true,
|
||||
Equal => self.end == RangeEnd::Included,
|
||||
Greater => false,
|
||||
@ -929,17 +929,17 @@ impl<'tcx> PatRange<'tcx> {
|
||||
&self,
|
||||
other: &Self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
) -> Option<bool> {
|
||||
use Ordering::*;
|
||||
debug_assert_eq!(self.ty, other.ty);
|
||||
// For performance, it's important to only do the second comparison if necessary.
|
||||
Some(
|
||||
match other.lo.compare_with(self.hi, self.ty, tcx, param_env)? {
|
||||
match other.lo.compare_with(self.hi, self.ty, tcx, typing_env)? {
|
||||
Less => true,
|
||||
Equal => self.end == RangeEnd::Included,
|
||||
Greater => false,
|
||||
} && match self.lo.compare_with(other.hi, self.ty, tcx, param_env)? {
|
||||
} && match self.lo.compare_with(other.hi, self.ty, tcx, typing_env)? {
|
||||
Less => true,
|
||||
Equal => other.end == RangeEnd::Included,
|
||||
Greater => false,
|
||||
@ -985,9 +985,14 @@ impl<'tcx> PatRangeBoundary<'tcx> {
|
||||
Self::NegInfinity | Self::PosInfinity => None,
|
||||
}
|
||||
}
|
||||
pub fn eval_bits(self, ty: Ty<'tcx>, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> u128 {
|
||||
pub fn eval_bits(
|
||||
self,
|
||||
ty: Ty<'tcx>,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
) -> u128 {
|
||||
match self {
|
||||
Self::Finite(value) => value.eval_bits(tcx, param_env),
|
||||
Self::Finite(value) => value.eval_bits(tcx, typing_env),
|
||||
Self::NegInfinity => {
|
||||
// Unwrap is ok because the type is known to be numeric.
|
||||
ty.numeric_min_and_max_as_bits(tcx).unwrap().0
|
||||
@ -999,13 +1004,13 @@ impl<'tcx> PatRangeBoundary<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(tcx, param_env), level = "debug", ret)]
|
||||
#[instrument(skip(tcx, typing_env), level = "debug", ret)]
|
||||
pub fn compare_with(
|
||||
self,
|
||||
other: Self,
|
||||
ty: Ty<'tcx>,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
) -> Option<Ordering> {
|
||||
use PatRangeBoundary::*;
|
||||
match (self, other) {
|
||||
@ -1034,8 +1039,8 @@ impl<'tcx> PatRangeBoundary<'tcx> {
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let a = self.eval_bits(ty, tcx, param_env);
|
||||
let b = other.eval_bits(ty, tcx, param_env);
|
||||
let a = self.eval_bits(ty, tcx, typing_env);
|
||||
let b = other.eval_bits(ty, tcx, typing_env);
|
||||
|
||||
match ty.kind() {
|
||||
ty::Float(ty::FloatTy::F16) => {
|
||||
|
@ -498,12 +498,13 @@ impl<'tcx> AdtDef<'tcx> {
|
||||
expr_did: DefId,
|
||||
) -> Result<Discr<'tcx>, ErrorGuaranteed> {
|
||||
assert!(self.is_enum());
|
||||
let param_env = tcx.param_env(expr_did);
|
||||
|
||||
let repr_type = self.repr().discr_type();
|
||||
match tcx.const_eval_poly(expr_did) {
|
||||
Ok(val) => {
|
||||
let typing_env = ty::TypingEnv::post_analysis(tcx, expr_did);
|
||||
let ty = repr_type.to_ty(tcx);
|
||||
if let Some(b) = val.try_to_bits_for_ty(tcx, param_env, ty) {
|
||||
if let Some(b) = val.try_to_bits_for_ty(tcx, typing_env, ty) {
|
||||
trace!("discriminants: {} ({:?})", b, repr_type);
|
||||
Ok(Discr { val: b, ty })
|
||||
} else {
|
||||
|
@ -9,7 +9,7 @@ use tracing::{debug, instrument};
|
||||
|
||||
use crate::middle::resolve_bound_vars as rbv;
|
||||
use crate::mir::interpret::{LitToConstInput, Scalar};
|
||||
use crate::ty::{self, GenericArgs, ParamEnv, ParamEnvAnd, Ty, TyCtxt, TypeVisitableExt};
|
||||
use crate::ty::{self, GenericArgs, Ty, TyCtxt, TypeVisitableExt};
|
||||
|
||||
mod int;
|
||||
mod kind;
|
||||
@ -330,17 +330,22 @@ impl<'tcx> Const<'tcx> {
|
||||
None
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Creates a constant with the given integer value and interns it.
|
||||
pub fn from_bits(tcx: TyCtxt<'tcx>, bits: u128, ty: ParamEnvAnd<'tcx, Ty<'tcx>>) -> Self {
|
||||
#[inline]
|
||||
pub fn from_bits(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
bits: u128,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> Self {
|
||||
let size = tcx
|
||||
.layout_of(ty)
|
||||
.layout_of(typing_env.as_query_input(ty))
|
||||
.unwrap_or_else(|e| panic!("could not compute layout for {ty:?}: {e:?}"))
|
||||
.size;
|
||||
ty::Const::new_value(
|
||||
tcx,
|
||||
ty::ValTree::from_scalar_int(ScalarInt::try_from_uint(bits, size).unwrap()),
|
||||
ty.value,
|
||||
ty,
|
||||
)
|
||||
}
|
||||
|
||||
@ -353,13 +358,13 @@ impl<'tcx> Const<'tcx> {
|
||||
#[inline]
|
||||
/// Creates an interned bool constant.
|
||||
pub fn from_bool(tcx: TyCtxt<'tcx>, v: bool) -> Self {
|
||||
Self::from_bits(tcx, v as u128, ParamEnv::empty().and(tcx.types.bool))
|
||||
Self::from_bits(tcx, v as u128, ty::TypingEnv::fully_monomorphized(), tcx.types.bool)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Creates an interned usize constant.
|
||||
pub fn from_target_usize(tcx: TyCtxt<'tcx>, n: u64) -> Self {
|
||||
Self::from_bits(tcx, n as u128, ParamEnv::empty().and(tcx.types.usize))
|
||||
Self::from_bits(tcx, n as u128, ty::TypingEnv::fully_monomorphized(), tcx.types.usize)
|
||||
}
|
||||
|
||||
/// Panics if self.kind != ty::ConstKind::Value
|
||||
@ -393,15 +398,15 @@ impl<'tcx> Const<'tcx> {
|
||||
self.try_to_valtree()?.0.try_to_target_usize(tcx)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Attempts to evaluate the given constant to bits. Can fail to evaluate in the presence of
|
||||
/// generics (or erroneous code) or if the value can't be represented as bits (e.g. because it
|
||||
/// contains const generic parameters or pointers).
|
||||
pub fn try_to_bits(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Option<u128> {
|
||||
#[inline]
|
||||
pub fn try_to_bits(self, tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> Option<u128> {
|
||||
let (scalar, ty) = self.try_to_scalar()?;
|
||||
let scalar = scalar.try_to_scalar_int().ok()?;
|
||||
let size = tcx.layout_of(param_env.with_reveal_all_normalized(tcx).and(ty)).ok()?.size;
|
||||
// if `ty` does not depend on generic parameters, use an empty param_env
|
||||
let input = typing_env.with_reveal_all_normalized(tcx).as_query_input(ty);
|
||||
let size = tcx.layout_of(input).ok()?.size;
|
||||
Some(scalar.to_bits(size))
|
||||
}
|
||||
|
||||
|
@ -596,8 +596,16 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
||||
self.coroutine_is_async_gen(coroutine_def_id)
|
||||
}
|
||||
|
||||
fn layout_is_pointer_like(self, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
self.layout_of(self.erase_regions(param_env.and(ty)))
|
||||
// We don't use `TypingEnv` here as it's only defined in `rustc_middle` and
|
||||
// `rustc_next_trait_solver` shouldn't have to know about it.
|
||||
fn layout_is_pointer_like(
|
||||
self,
|
||||
typing_mode: ty::TypingMode<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> bool {
|
||||
let typing_env = ty::TypingEnv { typing_mode, param_env };
|
||||
self.layout_of(self.erase_regions(typing_env).as_query_input(self.erase_regions(ty)))
|
||||
.is_ok_and(|layout| layout.layout.is_pointer_like(&self.data_layout))
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user