mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-21 14:23:45 +00:00
use TypingEnv
when no infcx
is available
the behavior of the type system not only depends on the current assumptions, but also the currentnphase of the compiler. This is mostly necessary as we need to decide whether and how to reveal opaque types. We track this via the `TypingMode`.
This commit is contained in:
parent
bf6adec108
commit
9cba14b95b
@ -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 {
|
||||
@ -3831,11 +3835,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, ty::TypingEnv::non_body_analysis(tcx, item.owner_id.def_id))
|
||||
}
|
||||
};
|
||||
// All fields (except for possibly the last) should be sized.
|
||||
@ -1281,7 +1281,8 @@ fn check_item_type(
|
||||
UnsizedHandling::Forbid => true,
|
||||
UnsizedHandling::Allow => false,
|
||||
UnsizedHandling::AllowIfForeignTail => {
|
||||
let tail = tcx.struct_tail_for_codegen(item_ty, wfcx.param_env);
|
||||
let tail =
|
||||
tcx.struct_tail_for_codegen(item_ty, wfcx.infcx.typing_env(wfcx.param_env));
|
||||
!matches!(tail.kind(), ty::Foreign(_))
|
||||
}
|
||||
};
|
||||
|
@ -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