diff --git a/src/atomic_context.rs b/src/atomic_context.rs index 32e2258..55b0c1f 100644 --- a/src/atomic_context.rs +++ b/src/atomic_context.rs @@ -5,7 +5,7 @@ use rustc_hir::def_id::LocalDefId; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::mir::mono::MonoItem; -use rustc_middle::ty::{GenericArgs, Instance, ParamEnv, TyCtxt}; +use rustc_middle::ty::{GenericArgs, Instance, TyCtxt, TypingEnv}; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::Span; @@ -402,13 +402,10 @@ impl<'tcx> LateLintPass<'tcx> for AtomicContext<'tcx> { .tcx .erase_regions(GenericArgs::identity_for_item(self.cx.tcx, def_id)); let instance = Instance::new(def_id.into(), identity); - let param_and_instance = self - .cx - .param_env_reveal_all_normalized(def_id) - .and(instance); - let _ = self.cx.instance_adjustment(param_and_instance); - let _ = self.cx.instance_expectation(param_and_instance); - let _ = self.cx.instance_check(param_and_instance); + let poly_instance = TypingEnv::post_analysis(*self.cx, def_id).as_query_input(instance); + let _ = self.cx.instance_adjustment(poly_instance); + let _ = self.cx.instance_expectation(poly_instance); + let _ = self.cx.instance_check(poly_instance); } fn check_crate_post(&mut self, cx: &LateContext<'tcx>) { @@ -420,11 +417,11 @@ impl<'tcx> LateLintPass<'tcx> for AtomicContext<'tcx> { for mono_item in mono_items { if let MonoItem::Fn(instance) = mono_item { - let param_and_instance = ParamEnv::reveal_all().and(instance); - if let Err(Error::TooGeneric) = self.cx.instance_adjustment(param_and_instance) { + let poly_instance = TypingEnv::fully_monomorphized().as_query_input(instance); + if let Err(Error::TooGeneric) = self.cx.instance_adjustment(poly_instance) { bug!("monomorphized function should not be too generic"); } - if let Err(Error::TooGeneric) = self.cx.instance_expectation(param_and_instance) { + if let Err(Error::TooGeneric) = self.cx.instance_expectation(poly_instance) { bug!("monomorphized function should not be too generic"); } } diff --git a/src/mir/drop_shim.rs b/src/mir/drop_shim.rs index 9b1a7e3..7c51400 100644 --- a/src/mir/drop_shim.rs +++ b/src/mir/drop_shim.rs @@ -9,7 +9,7 @@ use rustc_hir::def_id::DefId; use rustc_index::{Idx, IndexVec}; use rustc_middle::mir::patch::MirPatch; use rustc_middle::mir::*; -use rustc_middle::ty::{self, EarlyBinder, ParamEnv, Ty, TyCtxt}; +use rustc_middle::ty::{self, EarlyBinder, Ty, TyCtxt, TypingEnv}; use rustc_mir_dataflow::elaborate_drops::{self, *}; use rustc_span::Span; use rustc_target::abi::{FieldIdx, VariantIdx}; @@ -34,7 +34,7 @@ fn local_decls_for_sig<'tcx>( pub fn build_drop_shim<'tcx>( cx: &AnalysisCtxt<'tcx>, def_id: DefId, - param_env: ParamEnv<'tcx>, + typing_env: TypingEnv<'tcx>, ty: Ty<'tcx>, ) -> Body<'tcx> { if let ty::Coroutine(gen_def_id, args) = ty.kind() { @@ -83,7 +83,7 @@ pub fn build_drop_shim<'tcx>( body: &body, patch: MirPatch::new(&body), tcx: cx.tcx, - param_env, + typing_env, }; let dropee = cx.mk_place_deref(dropee_ptr); let resume_block = elaborator.patch.resume_block(); @@ -137,7 +137,7 @@ pub struct DropShimElaborator<'a, 'tcx> { pub body: &'a Body<'tcx>, pub patch: MirPatch<'tcx>, pub tcx: TyCtxt<'tcx>, - pub param_env: ty::ParamEnv<'tcx>, + pub typing_env: ty::TypingEnv<'tcx>, } impl fmt::Debug for DropShimElaborator<'_, '_> { @@ -158,8 +158,8 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for DropShimElaborator<'a, 'tcx> { fn tcx(&self) -> TyCtxt<'tcx> { self.tcx } - fn param_env(&self) -> ty::ParamEnv<'tcx> { - self.param_env + fn typing_env(&self) -> ty::TypingEnv<'tcx> { + self.typing_env } fn drop_style(&self, _path: Self::Path, mode: DropFlagMode) -> DropStyle { diff --git a/src/monomorphize_collector.rs b/src/monomorphize_collector.rs index 07fef2a..6bd29e2 100644 --- a/src/monomorphize_collector.rs +++ b/src/monomorphize_collector.rs @@ -39,7 +39,7 @@ use std::path::PathBuf; // From rustc_monomorphize/lib.rs fn custom_coerce_unsize_info<'tcx>( tcx: TyCtxtAt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, source_ty: Ty<'tcx>, target_ty: Ty<'tcx>, ) -> Result { @@ -49,7 +49,7 @@ fn custom_coerce_unsize_info<'tcx>( [source_ty, target_ty], ); - match tcx.codegen_select_candidate((param_env, trait_ref)) { + match tcx.codegen_select_candidate(typing_env.as_query_input(trait_ref)) { Ok(traits::ImplSource::UserDefined(traits::ImplSourceUserDefinedData { impl_def_id, .. @@ -250,7 +250,7 @@ fn collect_items_rec<'tcx>( // Sanity check whether this ended up being collected accidentally debug_assert!(should_codegen_locally(tcx, &instance)); - let ty = instance.ty(tcx, ty::ParamEnv::reveal_all()); + let ty = instance.ty(tcx, ty::TypingEnv::fully_monomorphized()); visit_drop_use(tcx, ty, true, starting_item.span, &mut used_items); recursion_depth_reset = None; @@ -497,7 +497,7 @@ impl<'a, 'tcx> MirUsedCollector<'a, 'tcx> { debug!("monomorphize: self.instance={:?}", self.instance); self.instance.instantiate_mir_and_normalize_erasing_regions( self.tcx, - ty::ParamEnv::reveal_all(), + ty::TypingEnv::fully_monomorphized(), ty::EarlyBinder::bind(value), ) } @@ -524,7 +524,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> { let source_ty = self.monomorphize(source_ty); let (source_ty, target_ty) = find_vtable_types_for_unsizing( self.tcx.at(span), - ty::ParamEnv::reveal_all(), + ty::TypingEnv::fully_monomorphized(), source_ty, target_ty, ); @@ -589,8 +589,8 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> { /// work, as some constants cannot be represented in the type system. fn visit_const_operand(&mut self, constant: &mir::ConstOperand<'tcx>, location: Location) { let const_ = self.monomorphize(constant.const_); - let param_env = ty::ParamEnv::reveal_all(); - let val = match const_.eval(self.tcx, param_env, constant.span) { + let typing_env = ty::TypingEnv::fully_monomorphized(); + let val = match const_.eval(self.tcx, typing_env, constant.span) { Ok(v) => v, Err(ErrorHandled::TooGeneric(..)) => span_bug!( self.body.source_info(location).span, @@ -704,9 +704,20 @@ fn visit_fn_use<'tcx>( ) { if let ty::FnDef(def_id, args) = *ty.kind() { let instance = if is_direct_call { - ty::Instance::expect_resolve(tcx, ty::ParamEnv::reveal_all(), def_id, args, source) + ty::Instance::expect_resolve( + tcx, + ty::TypingEnv::fully_monomorphized(), + def_id, + args, + source, + ) } else { - match ty::Instance::resolve_for_fn_ptr(tcx, ty::ParamEnv::reveal_all(), def_id, args) { + match ty::Instance::resolve_for_fn_ptr( + tcx, + ty::TypingEnv::fully_monomorphized(), + def_id, + args, + ) { Some(instance) => instance, _ => bug!("failed to resolve instance for {ty}"), } @@ -839,16 +850,16 @@ pub fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: &Instance<'tcx> /// smart pointers such as `Rc` and `Arc`. pub fn find_vtable_types_for_unsizing<'tcx>( tcx: TyCtxtAt<'tcx>, - param_env: ty::ParamEnv<'tcx>, + typing_env: ty::TypingEnv<'tcx>, source_ty: Ty<'tcx>, target_ty: Ty<'tcx>, ) -> (Ty<'tcx>, Ty<'tcx>) { let ptr_vtable = |inner_source: Ty<'tcx>, inner_target: Ty<'tcx>| { let type_has_metadata = |ty: Ty<'tcx>| -> bool { - if ty.is_sized(tcx.tcx, param_env) { + if ty.is_sized(tcx.tcx, typing_env.param_env) { return false; } - let tail = tcx.struct_tail_for_codegen(ty, param_env); + let tail = tcx.struct_tail_for_codegen(ty, typing_env); match tail.kind() { ty::Foreign(..) => false, ty::Str | ty::Slice(..) | ty::Dynamic(..) => true, @@ -858,7 +869,7 @@ pub fn find_vtable_types_for_unsizing<'tcx>( if type_has_metadata(inner_source) { (inner_source, inner_target) } else { - tcx.struct_lockstep_tails_for_codegen(inner_source, inner_target, param_env) + tcx.struct_lockstep_tails_for_codegen(inner_source, inner_target, typing_env) } }; @@ -879,7 +890,7 @@ pub fn find_vtable_types_for_unsizing<'tcx>( assert_eq!(source_adt_def, target_adt_def); let CustomCoerceUnsized::Struct(coerce_index) = - match custom_coerce_unsize_info(tcx, param_env, source_ty, target_ty) { + match custom_coerce_unsize_info(tcx, typing_env, source_ty, target_ty) { Ok(ccu) => ccu, Err(e) => { let e = Ty::new_error(tcx.tcx, e); @@ -897,7 +908,7 @@ pub fn find_vtable_types_for_unsizing<'tcx>( find_vtable_types_for_unsizing( tcx, - param_env, + typing_env, source_fields[coerce_index].ty(*tcx, source_args), target_fields[coerce_index].ty(*tcx, target_args), ) @@ -980,7 +991,7 @@ impl<'v> RootCollector<'_, 'v> { let item = self.tcx.hir().item(id); let ty = Instance::new(item.owner_id.to_def_id(), GenericArgs::empty()) - .ty(self.tcx, ty::ParamEnv::reveal_all()); + .ty(self.tcx, ty::TypingEnv::fully_monomorphized()); visit_drop_use(self.tcx, ty, true, DUMMY_SP, self.output); } } @@ -1078,13 +1089,13 @@ impl<'v> RootCollector<'_, 'v> { // regions must appear in the argument // listing. let main_ret_ty = self.tcx.normalize_erasing_regions( - ty::ParamEnv::reveal_all(), + ty::TypingEnv::fully_monomorphized(), main_ret_ty.no_bound_vars().unwrap(), ); let start_instance = Instance::try_resolve( self.tcx, - ty::ParamEnv::reveal_all(), + ty::TypingEnv::fully_monomorphized(), start_def_id, self.tcx.mk_args(&[main_ret_ty.into()]), ) @@ -1124,8 +1135,8 @@ fn create_mono_items_for_default_impls<'tcx>( let trait_ref = trait_ref.instantiate_identity(); - let param_env = ty::ParamEnv::reveal_all(); - let trait_ref = tcx.normalize_erasing_regions(param_env, trait_ref); + let typing_env = ty::TypingEnv::fully_monomorphized(); + let trait_ref = tcx.normalize_erasing_regions(typing_env, trait_ref); let overridden_methods = tcx.impl_item_implementor_ids(item.owner_id); for method in tcx.provided_trait_methods(trait_ref.def_id) { @@ -1146,7 +1157,7 @@ fn create_mono_items_for_default_impls<'tcx>( trait_ref.args[param.index as usize] } }); - let instance = ty::Instance::expect_resolve(tcx, param_env, method.def_id, args, DUMMY_SP); + let instance = ty::Instance::expect_resolve(tcx, typing_env, method.def_id, args, DUMMY_SP); let mono_item = create_fn_mono_item(tcx, instance, DUMMY_SP); if mono_item.node.is_instantiable(tcx) { diff --git a/src/preempt_count/adjustment.rs b/src/preempt_count/adjustment.rs index d539871..fca951c 100644 --- a/src/preempt_count/adjustment.rs +++ b/src/preempt_count/adjustment.rs @@ -6,7 +6,9 @@ use rustc_errors::{Diag, EmissionGuarantee, ErrorGuaranteed, MultiSpan}; use rustc_hir::def_id::{CrateNum, DefId}; use rustc_hir::LangItem; use rustc_middle::mir::{Body, TerminatorKind, UnwindAction}; -use rustc_middle::ty::{self, GenericArgs, Instance, ParamEnv, ParamEnvAnd, Ty, TypingMode}; +use rustc_middle::ty::{ + self, GenericArgs, Instance, PseudoCanonicalInput, Ty, TypingEnv, TypingMode, +}; use rustc_mir_dataflow::Analysis; use rustc_mir_dataflow::JoinSemiLattice; use rustc_trait_selection::infer::TyCtxtInferExt; @@ -16,7 +18,10 @@ use super::{Error, PolyDisplay, UseSiteKind}; use crate::ctxt::AnalysisCtxt; impl<'tcx> AnalysisCtxt<'tcx> { - fn drop_adjustment_overflow(&self, poly_ty: ParamEnvAnd<'tcx, Ty<'tcx>>) -> Result { + fn drop_adjustment_overflow( + &self, + poly_ty: PseudoCanonicalInput<'tcx, Ty<'tcx>>, + ) -> Result { let diag = self.dcx().struct_err(format!( "preemption count overflow when trying to compute adjustment of type `{}", PolyDisplay(&poly_ty) @@ -24,10 +29,10 @@ impl<'tcx> AnalysisCtxt<'tcx> { Err(Error::Error(self.emit_with_use_site_info(diag))) } - fn poly_instance_of_def_id(&self, def_id: DefId) -> ParamEnvAnd<'tcx, Instance<'tcx>> { - let poly_param_env = self.param_env_reveal_all_normalized(def_id); + fn poly_instance_of_def_id(&self, def_id: DefId) -> PseudoCanonicalInput<'tcx, Instance<'tcx>> { + let poly_typing_env = TypingEnv::post_analysis(self.tcx, def_id); let poly_args = self.erase_regions(GenericArgs::identity_for_item(self.tcx, def_id)); - poly_param_env.and(Instance::new(def_id, poly_args)) + poly_typing_env.as_query_input(Instance::new(def_id, poly_args)) } pub fn emit_with_use_site_info( @@ -266,7 +271,7 @@ impl<'tcx> AnalysisCtxt<'tcx> { pub fn do_infer_adjustment( &self, - param_env: ParamEnv<'tcx>, + typing_env: TypingEnv<'tcx>, instance: Instance<'tcx>, body: &Body<'tcx>, ) -> Result { @@ -285,7 +290,7 @@ impl<'tcx> AnalysisCtxt<'tcx> { let mut analysis_result = AdjustmentComputation { checker: self, body, - param_env, + typing_env, instance, } .iterate_to_fixpoint(self.tcx, body, None) @@ -320,7 +325,7 @@ impl<'tcx> AnalysisCtxt<'tcx> { pub fn infer_adjustment( &self, - param_env: ParamEnv<'tcx>, + typing_env: TypingEnv<'tcx>, instance: Instance<'tcx>, body: &Body<'tcx>, ) -> Result { @@ -330,12 +335,12 @@ impl<'tcx> AnalysisCtxt<'tcx> { { self.emit_with_use_site_info(self.dcx().struct_fatal(format!( "reached the recursion limit while checking adjustment for `{}`", - PolyDisplay(¶m_env.and(instance)) + PolyDisplay(&typing_env.as_query_input(instance)) ))); } rustc_data_structures::stack::ensure_sufficient_stack(|| { - self.do_infer_adjustment(param_env, instance, body) + self.do_infer_adjustment(typing_env, instance, body) }) } } @@ -344,18 +349,23 @@ memoize!( #[instrument(skip(cx), fields(poly_ty = %PolyDisplay(&poly_ty)), ret)] pub fn drop_adjustment<'tcx>( cx: &AnalysisCtxt<'tcx>, - poly_ty: ParamEnvAnd<'tcx, Ty<'tcx>>, + poly_ty: PseudoCanonicalInput<'tcx, Ty<'tcx>>, ) -> Result { - let (param_env, ty) = poly_ty.into_parts(); + let PseudoCanonicalInput { + typing_env, + value: ty, + } = poly_ty; // If the type doesn't need drop, then there is trivially no adjustment. - if !ty.needs_drop(cx.tcx, param_env) { + if !ty.needs_drop(cx.tcx, typing_env) { return Ok(0); } match ty.kind() { ty::Closure(_, args) => { - return cx.drop_adjustment(param_env.and(args.as_closure().tupled_upvars_ty())); + return cx.drop_adjustment( + typing_env.as_query_input(args.as_closure().tupled_upvars_ty()), + ); } // Coroutine drops are non-trivial, use the generated drop shims instead. @@ -364,7 +374,7 @@ memoize!( ty::Tuple(list) => { let mut adj = 0i32; for elem_ty in list.iter() { - let elem_adj = cx.drop_adjustment(param_env.and(elem_ty))?; + let elem_adj = cx.drop_adjustment(typing_env.as_query_input(elem_ty))?; let Some(new_adj) = adj.checked_add(elem_adj) else { cx.drop_adjustment_overflow(poly_ty)? }; @@ -374,14 +384,18 @@ memoize!( } _ if let Some(boxed_ty) = ty.boxed_ty() => { - let adj = cx.drop_adjustment(param_env.and(boxed_ty))?; + let adj = cx.drop_adjustment(typing_env.as_query_input(boxed_ty))?; let drop_trait = cx.require_lang_item(LangItem::Drop, None); let drop_fn = cx.associated_item_def_ids(drop_trait)[0]; - let box_free = - ty::Instance::try_resolve(cx.tcx, param_env, drop_fn, cx.mk_args(&[ty.into()])) - .unwrap() - .unwrap(); - let box_free_adj = cx.instance_adjustment(param_env.and(box_free))?; + let box_free = ty::Instance::try_resolve( + cx.tcx, + typing_env, + drop_fn, + cx.mk_args(&[ty.into()]), + ) + .unwrap() + .unwrap(); + let box_free_adj = cx.instance_adjustment(typing_env.as_query_input(box_free))?; let Some(adj) = adj.checked_add(box_free_adj) else { cx.drop_adjustment_overflow(poly_ty)? }; @@ -391,10 +405,10 @@ memoize!( ty::Adt(def, _) => { // For Adts, we first try to not use any of the args and just try the most // polymorphic version of the type. - let poly_param_env = cx.param_env_reveal_all_normalized(def.did()); + let poly_typing_env = TypingEnv::post_analysis(cx.tcx, def.did()); let poly_args = cx.erase_regions(GenericArgs::identity_for_item(cx.tcx, def.did())); - let poly_poly_ty = - poly_param_env.and(cx.tcx.mk_ty_from_kind(ty::Adt(*def, poly_args))); + let poly_poly_ty = poly_typing_env + .as_query_input(cx.tcx.mk_ty_from_kind(ty::Adt(*def, poly_args))); if poly_poly_ty != poly_ty { match cx.drop_adjustment(poly_poly_ty) { Err(Error::TooGeneric) => (), @@ -425,13 +439,17 @@ memoize!( ty::Array(elem_ty, size) => { let infcx = cx.tcx.infer_ctxt().build(TypingMode::PostAnalysis); - let size = rustc_trait_selection::traits::evaluate_const(&infcx, *size, param_env) - .try_to_target_usize(cx.tcx) - .ok_or(Error::TooGeneric); + let size = rustc_trait_selection::traits::evaluate_const( + &infcx, + *size, + typing_env.param_env, + ) + .try_to_target_usize(cx.tcx) + .ok_or(Error::TooGeneric); if size == Ok(0) { return Ok(0); } - let elem_adj = cx.drop_adjustment(param_env.and(*elem_ty))?; + let elem_adj = cx.drop_adjustment(typing_env.as_query_input(*elem_ty))?; if elem_adj == 0 { return Ok(0); } @@ -445,7 +463,7 @@ memoize!( } ty::Slice(elem_ty) => { - let elem_adj = cx.drop_adjustment(param_env.and(*elem_ty))?; + let elem_adj = cx.drop_adjustment(typing_env.as_query_input(*elem_ty))?; if elem_adj != 0 { let mut diag = cx.dcx().struct_err( "dropping element of slice causes non-zero preemption count adjustment", @@ -466,13 +484,13 @@ memoize!( _ => return Err(Error::TooGeneric), } - // Do not call `resolve_drop_in_place` because we need param_env. + // Do not call `resolve_drop_in_place` because we need typing_env. let drop_in_place = cx.require_lang_item(LangItem::DropInPlace, None); let args = cx.mk_args(&[ty.into()]); - let instance = ty::Instance::try_resolve(cx.tcx, param_env, drop_in_place, args) + let instance = ty::Instance::try_resolve(cx.tcx, typing_env, drop_in_place, args) .unwrap() .unwrap(); - let poly_instance = param_env.and(instance); + let poly_instance = typing_env.as_query_input(instance); assert!(matches!( instance.def, @@ -487,7 +505,7 @@ memoize!( .any(|x| x.instance == poly_instance) { // Recursion encountered. - if param_env.caller_bounds().is_empty() { + if typing_env.param_env.caller_bounds().is_empty() { return Ok(0); } else { // If we are handling generic functions, then defer decision to monomorphization time. @@ -495,8 +513,8 @@ memoize!( } } - let mir = crate::mir::drop_shim::build_drop_shim(cx, instance.def_id(), param_env, ty); - let result = cx.infer_adjustment(param_env, instance, &mir); + let mir = crate::mir::drop_shim::build_drop_shim(cx, instance.def_id(), typing_env, ty); + let result = cx.infer_adjustment(typing_env, instance, &mir); // Recursion encountered. if let Some(&recur) = cx.query_cache::().borrow().get(&poly_ty) { @@ -530,13 +548,16 @@ memoize!( #[instrument(skip(cx), fields(poly_ty = %PolyDisplay(&poly_ty)), ret)] pub fn drop_adjustment_check<'tcx>( cx: &AnalysisCtxt<'tcx>, - poly_ty: ParamEnvAnd<'tcx, Ty<'tcx>>, + poly_ty: PseudoCanonicalInput<'tcx, Ty<'tcx>>, ) -> Result<(), Error> { let adjustment = cx.drop_adjustment(poly_ty)?; - let (param_env, ty) = poly_ty.into_parts(); + let PseudoCanonicalInput { + typing_env, + value: ty, + } = poly_ty; // If the type doesn't need drop, then there is trivially no adjustment. - if !ty.needs_drop(cx.tcx, param_env) { + if !ty.needs_drop(cx.tcx, typing_env) { return Ok(()); } @@ -555,10 +576,10 @@ memoize!( ty::Adt(def, _) => { // For Adts, we first try to not use any of the args and just try the most // polymorphic version of the type. - let poly_param_env = cx.param_env_reveal_all_normalized(def.did()); + let poly_typing_env = TypingEnv::post_analysis(cx.tcx, def.did()); let poly_args = cx.erase_regions(GenericArgs::identity_for_item(cx.tcx, def.did())); - let poly_poly_ty = - poly_param_env.and(cx.tcx.mk_ty_from_kind(ty::Adt(*def, poly_args))); + let poly_poly_ty = poly_typing_env + .as_query_input(cx.tcx.mk_ty_from_kind(ty::Adt(*def, poly_args))); if poly_poly_ty != poly_ty { match cx.drop_adjustment_check(poly_poly_ty) { Err(Error::TooGeneric) => (), @@ -584,10 +605,10 @@ memoize!( return Ok(()); } - // Do not call `resolve_drop_in_place` because we need param_env. + // Do not call `resolve_drop_in_place` because we need typing_env. let drop_in_place = cx.require_lang_item(LangItem::DropInPlace, None); let args = cx.mk_args(&[ty.into()]); - let instance = ty::Instance::try_resolve(cx.tcx, param_env, drop_in_place, args) + let instance = ty::Instance::try_resolve(cx.tcx, typing_env, drop_in_place, args) .unwrap() .unwrap(); @@ -596,8 +617,8 @@ memoize!( ty::InstanceKind::DropGlue(_, Some(_)) )); - let mir = crate::mir::drop_shim::build_drop_shim(cx, instance.def_id(), param_env, ty); - let adjustment_infer = cx.infer_adjustment(param_env, instance, &mir)?; + let mir = crate::mir::drop_shim::build_drop_shim(cx, instance.def_id(), typing_env, ty); + let adjustment_infer = cx.infer_adjustment(typing_env, instance, &mir)?; // Check if the inferred adjustment matches the annotation. if let Some(adjustment) = annotation.adjustment { if adjustment != adjustment_infer { @@ -620,16 +641,19 @@ memoize!( #[instrument(skip(cx), fields(poly_instance = %PolyDisplay(&poly_instance)), ret)] pub fn instance_adjustment<'tcx>( cx: &AnalysisCtxt<'tcx>, - poly_instance: ParamEnvAnd<'tcx, Instance<'tcx>>, + poly_instance: PseudoCanonicalInput<'tcx, Instance<'tcx>>, ) -> Result { - let (param_env, instance) = poly_instance.into_parts(); + let PseudoCanonicalInput { + typing_env, + value: instance, + } = poly_instance; match instance.def { // No Rust built-in intrinsics will mess with preemption count. ty::InstanceKind::Intrinsic(_) => return Ok(0), // Empty drop glue, then it definitely won't mess with preemption count. ty::InstanceKind::DropGlue(_, None) => return Ok(0), ty::InstanceKind::DropGlue(_, Some(ty)) => { - return cx.drop_adjustment(param_env.and(ty)) + return cx.drop_adjustment(typing_env.as_query_input(ty)) } ty::InstanceKind::Virtual(def_id, _) => { if let Some(adj) = cx.preemption_count_annotation(def_id).adjustment { @@ -643,11 +667,11 @@ memoize!( let mut generic = false; if matches!(instance.def, ty::InstanceKind::Item(_)) { - let poly_param_env = cx.param_env_reveal_all_normalized(instance.def_id()); + let poly_typing_env = TypingEnv::post_analysis(cx.tcx, instance.def_id()); let poly_args = cx.erase_regions(GenericArgs::identity_for_item(cx.tcx, instance.def_id())); let poly_poly_instance = - poly_param_env.and(Instance::new(instance.def_id(), poly_args)); + poly_typing_env.as_query_input(Instance::new(instance.def_id(), poly_args)); generic = poly_poly_instance == poly_instance; if !generic { match cx.instance_adjustment(poly_poly_instance) { @@ -690,7 +714,7 @@ memoize!( .any(|x| x.instance == poly_instance) { // Recursion encountered. - if param_env.caller_bounds().is_empty() { + if typing_env.param_env.caller_bounds().is_empty() { return Ok(0); } else { // If we are handling generic functions, then defer decision to monomorphization time. @@ -699,7 +723,7 @@ memoize!( } let mir = cx.analysis_instance_mir(instance.def); - let mut result = cx.infer_adjustment(param_env, instance, mir); + let mut result = cx.infer_adjustment(typing_env, instance, mir); // Recursion encountered. if let Some(&recur) = cx @@ -746,7 +770,9 @@ memoize!( } } - if instance.def_id().is_local() && (generic || param_env.caller_bounds().is_empty()) { + if instance.def_id().is_local() + && (generic || typing_env.param_env.caller_bounds().is_empty()) + { cx.sql_store::(poly_instance, result); } @@ -772,10 +798,13 @@ memoize!( #[instrument(skip(cx), fields(poly_instance = %PolyDisplay(&poly_instance)), ret)] pub fn instance_adjustment_check<'tcx>( cx: &AnalysisCtxt<'tcx>, - poly_instance: ParamEnvAnd<'tcx, Instance<'tcx>>, + poly_instance: PseudoCanonicalInput<'tcx, Instance<'tcx>>, ) -> Result<(), Error> { let adjustment = cx.instance_adjustment(poly_instance)?; - let (param_env, instance) = poly_instance.into_parts(); + let PseudoCanonicalInput { + typing_env, + value: instance, + } = poly_instance; // Only check locally codegenned instances. if !crate::monomorphize_collector::should_codegen_locally(cx.tcx, &instance) { @@ -788,7 +817,7 @@ memoize!( // Empty drop glue, then it definitely won't mess with preemption count. ty::InstanceKind::DropGlue(_, None) => return Ok(()), ty::InstanceKind::DropGlue(_, Some(ty)) => { - return cx.drop_adjustment_check(param_env.and(ty)); + return cx.drop_adjustment_check(typing_env.as_query_input(ty)); } // Checked by indirect checks ty::InstanceKind::Virtual(_, _) => return Ok(()), @@ -797,11 +826,11 @@ memoize!( // Prefer to do polymorphic check if possible. if matches!(instance.def, ty::InstanceKind::Item(_)) { - let poly_param_env = cx.param_env_reveal_all_normalized(instance.def_id()); + let poly_typing_env = TypingEnv::post_analysis(cx.tcx, instance.def_id()); let poly_args = cx.erase_regions(GenericArgs::identity_for_item(cx.tcx, instance.def_id())); let poly_poly_instance = - poly_param_env.and(Instance::new(instance.def_id(), poly_args)); + poly_typing_env.as_query_input(Instance::new(instance.def_id(), poly_args)); let generic = poly_poly_instance == poly_instance; if !generic { match cx.instance_adjustment_check(poly_poly_instance) { @@ -825,7 +854,7 @@ memoize!( if annotation.adjustment.is_some() && !annotation.unchecked { let mir = cx.analysis_instance_mir(instance.def); - let adjustment_infer = cx.infer_adjustment(param_env, instance, mir)?; + let adjustment_infer = cx.infer_adjustment(typing_env, instance, mir)?; // Check if the inferred adjustment matches the annotation. if adjustment != adjustment_infer { let mut diag = cx.dcx().struct_span_err( diff --git a/src/preempt_count/check.rs b/src/preempt_count/check.rs index 9ce8115..6b8d4cc 100644 --- a/src/preempt_count/check.rs +++ b/src/preempt_count/check.rs @@ -9,8 +9,8 @@ use rustc_middle::mir::interpret::{AllocId, ErrorHandled, GlobalAlloc, Scalar}; use rustc_middle::mir::{self, visit::Visitor as MirVisitor, Body, Location}; use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::{ - self, GenericArgs, GenericParamDefKind, Instance, ParamEnv, ParamEnvAnd, Ty, TyCtxt, - TypeFoldable, TypeVisitableExt, Upcast, + self, GenericArgs, GenericParamDefKind, Instance, PseudoCanonicalInput, Ty, TyCtxt, + TypeFoldable, TypeVisitableExt, TypingEnv, Upcast, }; use rustc_span::Span; @@ -20,7 +20,7 @@ use crate::ctxt::AnalysisCtxt; struct MirNeighborVisitor<'mir, 'tcx, 'cx> { cx: &'cx AnalysisCtxt<'tcx>, body: &'mir Body<'tcx>, - param_env: ParamEnv<'tcx>, + typing_env: TypingEnv<'tcx>, instance: Instance<'tcx>, result: Result<(), Error>, } @@ -29,7 +29,7 @@ impl<'mir, 'tcx, 'cx> MirNeighborVisitor<'mir, 'tcx, 'cx> { fn monomorphize> + Clone>(&self, v: T) -> T { self.instance.instantiate_mir_and_normalize_erasing_regions( self.cx.tcx, - self.param_env, + self.typing_env, ty::EarlyBinder::bind(v), ) } @@ -98,24 +98,24 @@ impl<'mir, 'tcx, 'cx> MirNeighborVisitor<'mir, 'tcx, 'cx> { span: Span, ) -> Result<(), Error> { self.cx.call_stack.borrow_mut().push(UseSite { - instance: self.param_env.and(self.instance), + instance: self.typing_env.as_query_input(self.instance), kind: UseSiteKind::Vtable(span), }); let result = self .cx - .vtable_construction_check_indirect(self.param_env.and((ty, trait_ref))); + .vtable_construction_check_indirect(self.typing_env.as_query_input((ty, trait_ref))); self.cx.call_stack.borrow_mut().pop(); result } fn check_fn_pointer_cast(&mut self, instance: Instance<'tcx>, span: Span) -> Result<(), Error> { self.cx.call_stack.borrow_mut().push(UseSite { - instance: self.param_env.and(self.instance), + instance: self.typing_env.as_query_input(self.instance), kind: UseSiteKind::PointerCoercion(span), }); let result = self .cx - .function_pointer_cast_check_indirect(self.param_env.and(instance)); + .function_pointer_cast_check_indirect(self.typing_env.as_query_input(instance)); self.cx.call_stack.borrow_mut().pop(); result } @@ -140,7 +140,7 @@ impl<'mir, 'tcx, 'cx> MirNeighborVisitor<'mir, 'tcx, 'cx> { let (source_ty, target_ty) = crate::monomorphize_collector::find_vtable_types_for_unsizing( self.cx.tcx.at(span), - self.param_env, + self.typing_env, source_ty, target_ty, ); @@ -163,7 +163,7 @@ impl<'mir, 'tcx, 'cx> MirNeighborVisitor<'mir, 'tcx, 'cx> { let fn_ty = self.monomorphize(fn_ty); if let ty::FnDef(def_id, args) = *fn_ty.kind() { let instance = - ty::Instance::try_resolve(self.cx.tcx, self.param_env, def_id, args) + ty::Instance::try_resolve(self.cx.tcx, self.typing_env, def_id, args) .unwrap() .ok_or(Error::TooGeneric)?; self.check_fn_pointer_cast(instance, span)?; @@ -258,14 +258,16 @@ impl<'mir, 'tcx, 'cx> MirNeighborVisitor<'mir, 'tcx, 'cx> { if let ty::FnDef(def_id, args) = *callee_ty.kind() { let instance = - ty::Instance::try_resolve(self.cx.tcx, self.param_env, def_id, args) + ty::Instance::try_resolve(self.cx.tcx, self.typing_env, def_id, args) .unwrap() .ok_or(Error::TooGeneric)?; self.cx.call_stack.borrow_mut().push(UseSite { - instance: self.param_env.and(self.instance), + instance: self.typing_env.as_query_input(self.instance), kind: UseSiteKind::Call(span), }); - let result = self.cx.instance_check(self.param_env.and(instance)); + let result = self + .cx + .instance_check(self.typing_env.as_query_input(instance)); self.cx.call_stack.borrow_mut().pop(); result? } @@ -274,13 +276,13 @@ impl<'mir, 'tcx, 'cx> MirNeighborVisitor<'mir, 'tcx, 'cx> { let ty = place.ty(self.body, self.cx.tcx).ty; let ty = self.monomorphize(ty); self.cx.call_stack.borrow_mut().push(UseSite { - instance: self.param_env.and(self.instance), + instance: self.typing_env.as_query_input(self.instance), kind: UseSiteKind::Drop { drop_span: span, place_span: self.body.local_decls[place.local].source_info.span, }, }); - let result = self.cx.drop_check(self.param_env.and(ty)); + let result = self.cx.drop_check(self.typing_env.as_query_input(ty)); self.cx.call_stack.borrow_mut().pop(); result? } @@ -292,7 +294,7 @@ impl<'mir, 'tcx, 'cx> MirNeighborVisitor<'mir, 'tcx, 'cx> { if let ty::FnDef(def_id, args) = *fn_ty.kind() { let instance = ty::Instance::try_resolve( self.cx.tcx, - self.param_env, + self.typing_env, def_id, args, ) @@ -363,8 +365,8 @@ impl<'mir, 'tcx, 'cx> MirVisitor<'tcx> for MirNeighborVisitor<'mir, 'tcx, 'cx> { } let const_ = self.monomorphize(constant.const_); - let param_env = ty::ParamEnv::reveal_all(); - let val = match const_.eval(self.cx.tcx, param_env, constant.span) { + let typing_env = ty::TypingEnv::fully_monomorphized(); + let val = match const_.eval(self.cx.tcx, typing_env, constant.span) { Ok(v) => v, Err(ErrorHandled::Reported(..)) => return, Err(ErrorHandled::TooGeneric(..)) => { @@ -402,13 +404,13 @@ impl<'mir, 'tcx, 'cx> MirVisitor<'tcx> for MirNeighborVisitor<'mir, 'tcx, 'cx> { impl<'tcx> AnalysisCtxt<'tcx> { pub fn do_indirect_check( &self, - param_env: ParamEnv<'tcx>, + typing_env: TypingEnv<'tcx>, instance: Instance<'tcx>, body: &Body<'tcx>, ) -> Result<(), Error> { let mut visitor = MirNeighborVisitor { cx: self, - param_env, + typing_env, instance, body, result: Ok(()), @@ -419,7 +421,7 @@ impl<'tcx> AnalysisCtxt<'tcx> { pub fn indirect_check( &self, - param_env: ParamEnv<'tcx>, + typing_env: TypingEnv<'tcx>, instance: Instance<'tcx>, body: &Body<'tcx>, ) -> Result<(), Error> { @@ -429,12 +431,12 @@ impl<'tcx> AnalysisCtxt<'tcx> { { self.emit_with_use_site_info(self.dcx().struct_fatal(format!( "reached the recursion limit while checking indirect calls for `{}`", - PolyDisplay(¶m_env.and(instance)) + PolyDisplay(&typing_env.as_query_input(instance)) ))); } rustc_data_structures::stack::ensure_sufficient_stack(|| { - self.do_indirect_check(param_env, instance, body) + self.do_indirect_check(typing_env, instance, body) }) } } @@ -445,7 +447,7 @@ memoize!( #[instrument(skip(cx), fields(poly_instance = %PolyDisplay(&poly_instance)), ret)] fn function_pointer_cast_check_indirect<'tcx>( cx: &AnalysisCtxt<'tcx>, - poly_instance: ParamEnvAnd<'tcx, Instance<'tcx>>, + poly_instance: PseudoCanonicalInput<'tcx, Instance<'tcx>>, ) -> Result<(), Error> { cx.instance_check(poly_instance)?; @@ -484,16 +486,22 @@ memoize!( #[instrument( skip(cx, poly_ty_trait_ref), fields( - poly_ty = %PolyDisplay(&poly_ty_trait_ref.param_env.and(poly_ty_trait_ref.value.0)), + poly_ty = %PolyDisplay(&poly_ty_trait_ref.typing_env.as_query_input(poly_ty_trait_ref.value.0)), trait_ref = ?poly_ty_trait_ref.value.1 ), ret )] fn vtable_construction_check_indirect<'tcx>( cx: &AnalysisCtxt<'tcx>, - poly_ty_trait_ref: ParamEnvAnd<'tcx, (Ty<'tcx>, Option>)>, + poly_ty_trait_ref: PseudoCanonicalInput< + 'tcx, + (Ty<'tcx>, Option>), + >, ) -> Result<(), Error> { - let (param_env, (ty, trait_ref)) = poly_ty_trait_ref.into_parts(); + let PseudoCanonicalInput { + typing_env, + value: (ty, trait_ref), + } = poly_ty_trait_ref; let mut diag = None; if let Some(principal) = trait_ref { @@ -530,7 +538,7 @@ memoize!( } }) }); - let args = cx.normalize_erasing_late_bound_regions(param_env, args); + let args = cx.normalize_erasing_late_bound_regions(typing_env, args); let predicates = cx.predicates_of(entry).instantiate_own(cx.tcx, args); if rustc_trait_selection::traits::impossible_predicates( @@ -540,10 +548,10 @@ memoize!( continue; } - let instance = ty::Instance::try_resolve(cx.tcx, param_env, entry, args) + let instance = ty::Instance::try_resolve(cx.tcx, typing_env, entry, args) .unwrap() .ok_or(Error::TooGeneric)?; - let poly_instance = param_env.and(instance); + let poly_instance = typing_env.as_query_input(instance); cx.instance_check(poly_instance)?; // Find the `DefId` of the trait method. @@ -596,7 +604,7 @@ memoize!( } // Check destructor - let poly_ty = param_env.and(ty); + let poly_ty = typing_env.as_query_input(ty); let drop_annotation = trait_ref .map(|x| cx.drop_preemption_count_annotation(x.def_id())) @@ -645,21 +653,25 @@ memoize!( #[instrument(skip(cx), fields(poly_ty = %PolyDisplay(&poly_ty)), ret)] fn drop_check<'tcx>( cx: &AnalysisCtxt<'tcx>, - poly_ty: ParamEnvAnd<'tcx, Ty<'tcx>>, + poly_ty: PseudoCanonicalInput<'tcx, Ty<'tcx>>, ) -> Result<(), Error> { cx.drop_adjustment_check(poly_ty)?; cx.drop_expectation_check(poly_ty)?; - let (param_env, ty) = poly_ty.into_parts(); + let PseudoCanonicalInput { + typing_env, + value: ty, + } = poly_ty; // If the type doesn't need drop, then it trivially refers to nothing. - if !ty.needs_drop(cx.tcx, param_env) { + if !ty.needs_drop(cx.tcx, typing_env) { return Ok(()); } match ty.kind() { ty::Closure(_, args) => { - return cx.drop_check(param_env.and(args.as_closure().tupled_upvars_ty())); + return cx + .drop_check(typing_env.as_query_input(args.as_closure().tupled_upvars_ty())); } // Coroutine drops are non-trivial, use the generated drop shims instead. @@ -667,30 +679,34 @@ memoize!( ty::Tuple(list) => { for ty in list.iter() { - cx.drop_check(param_env.and(ty))?; + cx.drop_check(typing_env.as_query_input(ty))?; } return Ok(()); } _ if let Some(boxed_ty) = ty.boxed_ty() => { - cx.drop_check(param_env.and(boxed_ty))?; + cx.drop_check(typing_env.as_query_input(boxed_ty))?; let drop_trait = cx.require_lang_item(LangItem::Drop, None); let drop_fn = cx.associated_item_def_ids(drop_trait)[0]; - let box_free = - ty::Instance::try_resolve(cx.tcx, param_env, drop_fn, cx.mk_args(&[ty.into()])) - .unwrap() - .unwrap(); - cx.instance_check(param_env.and(box_free))?; + let box_free = ty::Instance::try_resolve( + cx.tcx, + typing_env, + drop_fn, + cx.mk_args(&[ty.into()]), + ) + .unwrap() + .unwrap(); + cx.instance_check(typing_env.as_query_input(box_free))?; return Ok(()); } ty::Adt(def, _) => { // For Adts, we first try to not use any of the args and just try the most // polymorphic version of the type. - let poly_param_env = cx.param_env_reveal_all_normalized(def.did()); + let poly_typing_env = TypingEnv::post_analysis(cx.tcx, def.did()); let poly_args = cx.erase_regions(GenericArgs::identity_for_item(cx.tcx, def.did())); - let poly_poly_ty = - poly_param_env.and(cx.tcx.mk_ty_from_kind(ty::Adt(*def, poly_args))); + let poly_poly_ty = poly_typing_env + .as_query_input(cx.tcx.mk_ty_from_kind(ty::Adt(*def, poly_args))); if poly_poly_ty != poly_ty { match cx.drop_check(poly_poly_ty) { Err(Error::TooGeneric) => (), @@ -706,19 +722,19 @@ memoize!( // Array and slice drops only refer to respective element destructor. ty::Array(elem_ty, _) | ty::Slice(elem_ty) => { - return cx.drop_check(param_env.and(*elem_ty)); + return cx.drop_check(typing_env.as_query_input(*elem_ty)); } _ => return Err(Error::TooGeneric), } - // Do not call `resolve_drop_in_place` because we need param_env. + // Do not call `resolve_drop_in_place` because we need typing_env. let drop_in_place = cx.require_lang_item(LangItem::DropInPlace, None); let args = cx.mk_args(&[ty.into()]); - let instance = ty::Instance::try_resolve(cx.tcx, param_env, drop_in_place, args) + let instance = ty::Instance::try_resolve(cx.tcx, typing_env, drop_in_place, args) .unwrap() .unwrap(); - let poly_instance = param_env.and(instance); + let poly_instance = typing_env.as_query_input(instance); assert!(matches!( instance.def, @@ -736,8 +752,8 @@ memoize!( return Ok(()); } - let mir = crate::mir::drop_shim::build_drop_shim(cx, instance.def_id(), param_env, ty); - let result = cx.indirect_check(param_env, instance, &mir); + let mir = crate::mir::drop_shim::build_drop_shim(cx, instance.def_id(), typing_env, ty); + let result = cx.indirect_check(typing_env, instance, &mir); result } @@ -747,9 +763,12 @@ memoize!( #[instrument(skip(cx), fields(poly_instance = %PolyDisplay(&poly_instance)), ret)] pub fn instance_check<'tcx>( cx: &AnalysisCtxt<'tcx>, - poly_instance: ParamEnvAnd<'tcx, Instance<'tcx>>, + poly_instance: PseudoCanonicalInput<'tcx, Instance<'tcx>>, ) -> Result<(), Error> { - let (param_env, instance) = poly_instance.into_parts(); + let PseudoCanonicalInput { + typing_env, + value: instance, + } = poly_instance; if !crate::monomorphize_collector::should_codegen_locally(cx.tcx, &instance) { return Ok(()); } @@ -762,18 +781,20 @@ memoize!( ty::InstanceKind::Intrinsic(_) => return Ok(()), // Empty drop glue, then it is a no-op. ty::InstanceKind::DropGlue(_, None) => return Ok(()), - ty::InstanceKind::DropGlue(_, Some(ty)) => return cx.drop_check(param_env.and(ty)), + ty::InstanceKind::DropGlue(_, Some(ty)) => { + return cx.drop_check(typing_env.as_query_input(ty)) + } // Can't check further here. Will be checked at vtable generation site. ty::InstanceKind::Virtual(_, _) => return Ok(()), _ => (), } if matches!(instance.def, ty::InstanceKind::Item(_)) { - let poly_param_env = cx.param_env_reveal_all_normalized(instance.def_id()); + let poly_typing_env = TypingEnv::post_analysis(cx.tcx, instance.def_id()); let poly_args = cx.erase_regions(GenericArgs::identity_for_item(cx.tcx, instance.def_id())); let poly_poly_instance = - poly_param_env.and(Instance::new(instance.def_id(), poly_args)); + poly_typing_env.as_query_input(Instance::new(instance.def_id(), poly_args)); let generic = poly_poly_instance == poly_instance; if !generic { match cx.instance_check(poly_poly_instance) { @@ -800,7 +821,7 @@ memoize!( } let mir = cx.analysis_instance_mir(instance.def); - let result = cx.indirect_check(param_env, instance, mir); + let result = cx.indirect_check(typing_env, instance, mir); result } diff --git a/src/preempt_count/dataflow.rs b/src/preempt_count/dataflow.rs index 82ae1de..dc75fde 100644 --- a/src/preempt_count/dataflow.rs +++ b/src/preempt_count/dataflow.rs @@ -3,7 +3,7 @@ // SPDX-License-Identifier: MIT OR Apache-2.0 use rustc_middle::mir::{BasicBlock, Body, TerminatorEdges, TerminatorKind}; -use rustc_middle::ty::{self, Instance, ParamEnv}; +use rustc_middle::ty::{self, Instance, TypingEnv}; use rustc_mir_dataflow::JoinSemiLattice; use rustc_mir_dataflow::{fmt::DebugWithContext, Analysis}; @@ -193,7 +193,7 @@ impl JoinSemiLattice for AdjustmentBoundsOrError { pub struct AdjustmentComputation<'mir, 'tcx, 'checker> { pub checker: &'checker AnalysisCtxt<'tcx>, pub body: &'mir Body<'tcx>, - pub param_env: ParamEnv<'tcx>, + pub typing_env: TypingEnv<'tcx>, pub instance: Instance<'tcx>, } @@ -244,7 +244,7 @@ impl<'tcx> Analysis<'tcx> for AdjustmentComputation<'_, 'tcx, '_> { let callee_ty = func.ty(self.body, self.checker.tcx); let callee_ty = self.instance.instantiate_mir_and_normalize_erasing_regions( self.checker.tcx, - self.param_env, + self.typing_env, ty::EarlyBinder::bind(callee_ty), ); if let ty::FnDef(def_id, args) = *callee_ty.kind() { @@ -255,7 +255,7 @@ impl<'tcx> Analysis<'tcx> for AdjustmentComputation<'_, 'tcx, '_> { } else { match ty::Instance::try_resolve( self.checker.tcx, - self.param_env, + self.typing_env, def_id, args, ) @@ -263,12 +263,12 @@ impl<'tcx> Analysis<'tcx> for AdjustmentComputation<'_, 'tcx, '_> { { Some(instance) => { self.checker.call_stack.borrow_mut().push(UseSite { - instance: self.param_env.and(self.instance), + instance: self.typing_env.as_query_input(self.instance), kind: UseSiteKind::Call(terminator.source_info.span), }); let result = self .checker - .instance_adjustment(self.param_env.and(instance)); + .instance_adjustment(self.typing_env.as_query_input(instance)); self.checker.call_stack.borrow_mut().pop(); result } @@ -283,18 +283,20 @@ impl<'tcx> Analysis<'tcx> for AdjustmentComputation<'_, 'tcx, '_> { let ty = place.ty(self.body, self.checker.tcx).ty; let ty = self.instance.instantiate_mir_and_normalize_erasing_regions( self.checker.tcx, - self.param_env, + self.typing_env, ty::EarlyBinder::bind(ty), ); self.checker.call_stack.borrow_mut().push(UseSite { - instance: self.param_env.and(self.instance), + instance: self.typing_env.as_query_input(self.instance), kind: UseSiteKind::Drop { drop_span: terminator.source_info.span, place_span: self.body.local_decls[place.local].source_info.span, }, }); - let result = self.checker.drop_adjustment(self.param_env.and(ty)); + let result = self + .checker + .drop_adjustment(self.typing_env.as_query_input(ty)); self.checker.call_stack.borrow_mut().pop(); result } diff --git a/src/preempt_count/expectation.rs b/src/preempt_count/expectation.rs index d238055..b51e121 100644 --- a/src/preempt_count/expectation.rs +++ b/src/preempt_count/expectation.rs @@ -6,7 +6,9 @@ use rustc_errors::{EmissionGuarantee, MultiSpan}; use rustc_hir::def_id::CrateNum; use rustc_hir::LangItem; use rustc_middle::mir::{self, Body, TerminatorKind}; -use rustc_middle::ty::{self, GenericArgs, Instance, ParamEnv, ParamEnvAnd, Ty, TypingMode}; +use rustc_middle::ty::{ + self, GenericArgs, Instance, PseudoCanonicalInput, Ty, TypingEnv, TypingMode, +}; use rustc_mir_dataflow::lattice::MeetSemiLattice; use rustc_mir_dataflow::Analysis; use rustc_span::DUMMY_SP; @@ -19,7 +21,7 @@ use crate::ctxt::AnalysisCtxt; impl<'tcx> AnalysisCtxt<'tcx> { pub fn terminator_expectation( &self, - param_env: ParamEnv<'tcx>, + typing_env: TypingEnv<'tcx>, instance: Instance<'tcx>, body: &Body<'tcx>, terminator: &mir::Terminator<'tcx>, @@ -29,7 +31,7 @@ impl<'tcx> AnalysisCtxt<'tcx> { let callee_ty = func.ty(body, self.tcx); let callee_ty = instance.instantiate_mir_and_normalize_erasing_regions( self.tcx, - param_env, + typing_env, ty::EarlyBinder::bind(callee_ty), ); if let ty::FnDef(def_id, args) = *callee_ty.kind() { @@ -39,14 +41,15 @@ impl<'tcx> AnalysisCtxt<'tcx> { v } else { let callee_instance = - ty::Instance::try_resolve(self.tcx, param_env, def_id, args) + ty::Instance::try_resolve(self.tcx, typing_env, def_id, args) .unwrap() .ok_or(Error::TooGeneric)?; self.call_stack.borrow_mut().push(UseSite { - instance: param_env.and(instance), + instance: typing_env.as_query_input(instance), kind: UseSiteKind::Call(terminator.source_info.span), }); - let result = self.instance_expectation(param_env.and(callee_instance)); + let result = + self.instance_expectation(typing_env.as_query_input(callee_instance)); self.call_stack.borrow_mut().pop(); result? } @@ -58,18 +61,18 @@ impl<'tcx> AnalysisCtxt<'tcx> { let ty = place.ty(body, self.tcx).ty; let ty = instance.instantiate_mir_and_normalize_erasing_regions( self.tcx, - param_env, + typing_env, ty::EarlyBinder::bind(ty), ); self.call_stack.borrow_mut().push(UseSite { - instance: param_env.and(instance), + instance: typing_env.as_query_input(instance), kind: UseSiteKind::Drop { drop_span: terminator.source_info.span, place_span: body.local_decls[place.local].source_info.span, }, }); - let result = self.drop_expectation(param_env.and(ty)); + let result = self.drop_expectation(typing_env.as_query_input(ty)); self.call_stack.borrow_mut().pop(); result? } @@ -77,10 +80,10 @@ impl<'tcx> AnalysisCtxt<'tcx> { }) } - #[instrument(skip(self, param_env, body, diag), fields(instance = %PolyDisplay(¶m_env.and(instance))), ret)] + #[instrument(skip(self, typing_env, body, diag), fields(instance = %PolyDisplay(&typing_env.as_query_input(instance))), ret)] pub fn report_body_expectation_error( &self, - param_env: ParamEnv<'tcx>, + typing_env: TypingEnv<'tcx>, instance: Instance<'tcx>, body: &Body<'tcx>, expected: ExpectationRange, @@ -90,7 +93,7 @@ impl<'tcx> AnalysisCtxt<'tcx> { let mut analysis_result = AdjustmentComputation { checker: self, body, - param_env, + typing_env, instance, } .iterate_to_fixpoint(self.tcx, body, None) @@ -102,7 +105,7 @@ impl<'tcx> AnalysisCtxt<'tcx> { } let expectation = - self.terminator_expectation(param_env, instance, body, data.terminator())?; + self.terminator_expectation(typing_env, instance, body, data.terminator())?; // Special case for no expectation at all. No need to check adjustment here. if expectation == ExpectationRange::top() { @@ -126,7 +129,7 @@ impl<'tcx> AnalysisCtxt<'tcx> { let callee_ty = func.ty(body, self.tcx); let callee_ty = instance.instantiate_mir_and_normalize_erasing_regions( self.tcx, - param_env, + typing_env, ty::EarlyBinder::bind(callee_ty), ); if let ty::FnDef(def_id, args) = *callee_ty.kind() { @@ -149,7 +152,7 @@ impl<'tcx> AnalysisCtxt<'tcx> { return Ok(()); } else { let callee_instance = - ty::Instance::try_resolve(self.tcx, param_env, def_id, args) + ty::Instance::try_resolve(self.tcx, typing_env, def_id, args) .unwrap() .ok_or(Error::TooGeneric)?; @@ -173,11 +176,11 @@ impl<'tcx> AnalysisCtxt<'tcx> { } self.call_stack.borrow_mut().push(UseSite { - instance: param_env.and(instance), + instance: typing_env.as_query_input(instance), kind: UseSiteKind::Call(span.primary_span().unwrap_or(DUMMY_SP)), }); let result = self.report_instance_expectation_error( - param_env, + typing_env, callee_instance, call_expected, span, @@ -214,12 +217,12 @@ impl<'tcx> AnalysisCtxt<'tcx> { let ty = place.ty(body, self.tcx).ty; let ty = instance.instantiate_mir_and_normalize_erasing_regions( self.tcx, - param_env, + typing_env, ty::EarlyBinder::bind(ty), ); self.call_stack.borrow_mut().push(UseSite { - instance: param_env.and(instance), + instance: typing_env.as_query_input(instance), kind: UseSiteKind::Drop { drop_span: data.terminator().source_info.span, place_span: body.local_decls[place.local].source_info.span, @@ -227,7 +230,7 @@ impl<'tcx> AnalysisCtxt<'tcx> { }); let result = self.report_drop_expectation_error( - param_env, + typing_env, ty, call_expected, span, @@ -253,7 +256,7 @@ impl<'tcx> AnalysisCtxt<'tcx> { // Must only be called on instances that actually are errors. pub fn report_instance_expectation_error( &self, - param_env: ParamEnv<'tcx>, + typing_env: TypingEnv<'tcx>, instance: Instance<'tcx>, expected: ExpectationRange, span: MultiSpan, @@ -265,7 +268,7 @@ impl<'tcx> AnalysisCtxt<'tcx> { // Empty drop glue, then it definitely won't mess with preemption count. ty::InstanceKind::DropGlue(_, None) => unreachable!(), ty::InstanceKind::DropGlue(_, Some(ty)) => { - return self.report_drop_expectation_error(param_env, ty, expected, span, diag); + return self.report_drop_expectation_error(typing_env, ty, expected, span, diag); } // Checked by indirect checks ty::InstanceKind::Virtual(def_id, _) => { @@ -307,7 +310,7 @@ impl<'tcx> AnalysisCtxt<'tcx> { // Only check locally codegenned instances. if !crate::monomorphize_collector::should_codegen_locally(self.tcx, &instance) { - let expectation = self.instance_expectation(param_env.and(instance))?; + let expectation = self.instance_expectation(typing_env.as_query_input(instance))?; diag.span_note( span, format!( @@ -331,24 +334,24 @@ impl<'tcx> AnalysisCtxt<'tcx> { ); let body = self.analysis_instance_mir(instance.def); - self.report_body_expectation_error(param_env, instance, body, expected, None, diag) + self.report_body_expectation_error(typing_env, instance, body, expected, None, diag) } pub fn report_drop_expectation_error( &self, - param_env: ParamEnv<'tcx>, + typing_env: TypingEnv<'tcx>, ty: Ty<'tcx>, expected: ExpectationRange, span: MultiSpan, diag: &mut rustc_errors::Diag<'_, G>, ) -> Result<(), Error> { // If the type doesn't need drop, then there is trivially no expectation. - assert!(ty.needs_drop(self.tcx, param_env)); + assert!(ty.needs_drop(self.tcx, typing_env)); match ty.kind() { ty::Closure(_, args) => { return self.report_drop_expectation_error( - param_env, + typing_env, args.as_closure().tupled_upvars_ty(), expected, span, @@ -362,25 +365,25 @@ impl<'tcx> AnalysisCtxt<'tcx> { ty::Tuple(_list) => (), _ if let Some(boxed_ty) = ty.boxed_ty() => { - let exp = self.drop_expectation(param_env.and(boxed_ty))?; + let exp = self.drop_expectation(typing_env.as_query_input(boxed_ty))?; if !exp.contains_range(expected) { return self - .report_drop_expectation_error(param_env, boxed_ty, expected, span, diag); + .report_drop_expectation_error(typing_env, boxed_ty, expected, span, diag); } - let adj = self.drop_adjustment(param_env.and(boxed_ty))?; + let adj = self.drop_adjustment(typing_env.as_query_input(boxed_ty))?; let drop_trait = self.require_lang_item(LangItem::Drop, None); let drop_fn = self.associated_item_def_ids(drop_trait)[0]; let box_free = ty::Instance::try_resolve( self.tcx, - param_env, + typing_env, drop_fn, self.mk_args(&[ty.into()]), ) .unwrap() .unwrap(); return self.report_instance_expectation_error( - param_env, + typing_env, box_free, expected + AdjustmentBounds::single_value(adj), span, @@ -416,18 +419,22 @@ impl<'tcx> AnalysisCtxt<'tcx> { } ty::Array(elem_ty, size) => { - let param_and_elem_ty = param_env.and(*elem_ty); + let param_and_elem_ty = typing_env.as_query_input(*elem_ty); let elem_exp = self.drop_expectation(param_and_elem_ty)?; if !elem_exp.contains_range(expected) { return self - .report_drop_expectation_error(param_env, *elem_ty, expected, span, diag); + .report_drop_expectation_error(typing_env, *elem_ty, expected, span, diag); } let elem_adj = self.drop_adjustment(param_and_elem_ty)?; let infcx = self.tcx.infer_ctxt().build(TypingMode::PostAnalysis); - let size = rustc_trait_selection::traits::evaluate_const(&infcx, *size, param_env) - .try_to_target_usize(self.tcx) - .ok_or(Error::TooGeneric)?; + let size = rustc_trait_selection::traits::evaluate_const( + &infcx, + *size, + typing_env.param_env, + ) + .try_to_target_usize(self.tcx) + .ok_or(Error::TooGeneric)?; let Ok(size) = i32::try_from(size) else { return Ok(()); }; @@ -436,7 +443,7 @@ impl<'tcx> AnalysisCtxt<'tcx> { }; let last_adj_bound = AdjustmentBounds::single_value(last_adj); return self.report_drop_expectation_error( - param_env, + typing_env, *elem_ty, expected + last_adj_bound, span, @@ -446,7 +453,7 @@ impl<'tcx> AnalysisCtxt<'tcx> { ty::Slice(elem_ty) => { return self - .report_drop_expectation_error(param_env, *elem_ty, expected, span, diag); + .report_drop_expectation_error(typing_env, *elem_ty, expected, span, diag); } _ => unreachable!(), @@ -456,22 +463,22 @@ impl<'tcx> AnalysisCtxt<'tcx> { span, format!( "which may drop type `{}` with preemption count {}", - PolyDisplay(¶m_env.and(ty)), + PolyDisplay(&typing_env.as_query_input(ty)), expected, ), ); let span = MultiSpan::new(); - // Do not call `resolve_drop_in_place` because we need param_env. + // Do not call `resolve_drop_in_place` because we need typing_env. let drop_in_place = self.require_lang_item(LangItem::DropInPlace, None); let args = self.mk_args(&[ty.into()]); - let instance = ty::Instance::try_resolve(self.tcx, param_env, drop_in_place, args) + let instance = ty::Instance::try_resolve(self.tcx, typing_env, drop_in_place, args) .unwrap() .unwrap(); - let mir = crate::mir::drop_shim::build_drop_shim(self, instance.def_id(), param_env, ty); + let mir = crate::mir::drop_shim::build_drop_shim(self, instance.def_id(), typing_env, ty); return self.report_body_expectation_error( - param_env, + typing_env, instance, &mir, expected, @@ -482,7 +489,7 @@ impl<'tcx> AnalysisCtxt<'tcx> { pub fn do_infer_expectation( &self, - param_env: ParamEnv<'tcx>, + typing_env: TypingEnv<'tcx>, instance: Instance<'tcx>, body: &Body<'tcx>, ) -> Result { @@ -501,7 +508,7 @@ impl<'tcx> AnalysisCtxt<'tcx> { let mut analysis_result = AdjustmentComputation { checker: self, body, - param_env, + typing_env, instance, } .iterate_to_fixpoint(self.tcx, body, None) @@ -518,7 +525,7 @@ impl<'tcx> AnalysisCtxt<'tcx> { let callee_ty = func.ty(body, self.tcx); let callee_ty = instance.instantiate_mir_and_normalize_erasing_regions( self.tcx, - param_env, + typing_env, ty::EarlyBinder::bind(callee_ty), ); if let ty::FnDef(def_id, args) = *callee_ty.kind() { @@ -528,14 +535,15 @@ impl<'tcx> AnalysisCtxt<'tcx> { v } else { let callee_instance = - ty::Instance::try_resolve(self.tcx, param_env, def_id, args) + ty::Instance::try_resolve(self.tcx, typing_env, def_id, args) .unwrap() .ok_or(Error::TooGeneric)?; self.call_stack.borrow_mut().push(UseSite { - instance: param_env.and(instance), + instance: typing_env.as_query_input(instance), kind: UseSiteKind::Call(data.terminator().source_info.span), }); - let result = self.instance_expectation(param_env.and(callee_instance)); + let result = self + .instance_expectation(typing_env.as_query_input(callee_instance)); self.call_stack.borrow_mut().pop(); result? } @@ -547,18 +555,18 @@ impl<'tcx> AnalysisCtxt<'tcx> { let ty = place.ty(body, self.tcx).ty; let ty = instance.instantiate_mir_and_normalize_erasing_regions( self.tcx, - param_env, + typing_env, ty::EarlyBinder::bind(ty), ); self.call_stack.borrow_mut().push(UseSite { - instance: param_env.and(instance), + instance: typing_env.as_query_input(instance), kind: UseSiteKind::Drop { drop_span: data.terminator().source_info.span, place_span: body.local_decls[place.local].source_info.span, }, }); - let result = self.drop_expectation(param_env.and(ty)); + let result = self.drop_expectation(typing_env.as_query_input(ty)); self.call_stack.borrow_mut().pop(); result? } @@ -604,7 +612,7 @@ impl<'tcx> AnalysisCtxt<'tcx> { let ty = place.ty(body, self.tcx).ty; let ty = instance.instantiate_mir_and_normalize_erasing_regions( self.tcx, - param_env, + typing_env, ty::EarlyBinder::bind(ty), ); diag.span_label(span, format!("the type being dropped is `{ty}`")); @@ -627,7 +635,7 @@ impl<'tcx> AnalysisCtxt<'tcx> { pub fn infer_expectation( &self, - param_env: ParamEnv<'tcx>, + typing_env: TypingEnv<'tcx>, instance: Instance<'tcx>, body: &Body<'tcx>, ) -> Result { @@ -637,12 +645,12 @@ impl<'tcx> AnalysisCtxt<'tcx> { { self.emit_with_use_site_info(self.dcx().struct_fatal(format!( "reached the recursion limit while checking expectation for `{}`", - PolyDisplay(¶m_env.and(instance)) + PolyDisplay(&typing_env.as_query_input(instance)) ))); } rustc_data_structures::stack::ensure_sufficient_stack(|| { - self.do_infer_expectation(param_env, instance, body) + self.do_infer_expectation(typing_env, instance, body) }) } } @@ -651,18 +659,23 @@ memoize!( #[instrument(skip(cx), fields(poly_ty = %PolyDisplay(&poly_ty)), ret)] pub fn drop_expectation<'tcx>( cx: &AnalysisCtxt<'tcx>, - poly_ty: ParamEnvAnd<'tcx, Ty<'tcx>>, + poly_ty: PseudoCanonicalInput<'tcx, Ty<'tcx>>, ) -> Result { - let (param_env, ty) = poly_ty.into_parts(); + let PseudoCanonicalInput { + typing_env, + value: ty, + } = poly_ty; // If the type doesn't need drop, then there is trivially no expectation. - if !ty.needs_drop(cx.tcx, param_env) { + if !ty.needs_drop(cx.tcx, typing_env) { return Ok(ExpectationRange::top()); } match ty.kind() { ty::Closure(_, args) => { - return cx.drop_expectation(param_env.and(args.as_closure().tupled_upvars_ty())); + return cx.drop_expectation( + typing_env.as_query_input(args.as_closure().tupled_upvars_ty()), + ); } // Coroutine drops are non-trivial, use the generated drop shims instead. @@ -671,21 +684,25 @@ memoize!( ty::Tuple(_list) => (), _ if let Some(boxed_ty) = ty.boxed_ty() => { - let exp = cx.drop_expectation(param_env.and(boxed_ty))?; + let exp = cx.drop_expectation(typing_env.as_query_input(boxed_ty))?; let drop_trait = cx.require_lang_item(LangItem::Drop, None); let drop_fn = cx.associated_item_def_ids(drop_trait)[0]; - let box_free = - ty::Instance::try_resolve(cx.tcx, param_env, drop_fn, cx.mk_args(&[ty.into()])) - .unwrap() - .unwrap(); - let box_free_exp = cx.instance_expectation(param_env.and(box_free))?; + let box_free = ty::Instance::try_resolve( + cx.tcx, + typing_env, + drop_fn, + cx.mk_args(&[ty.into()]), + ) + .unwrap() + .unwrap(); + let box_free_exp = cx.instance_expectation(typing_env.as_query_input(box_free))?; // Usuaully freeing the box shouldn't have any instance expectations, so short circuit here. if box_free_exp == ExpectationRange::top() { return Ok(exp); } - let adj = cx.drop_adjustment(param_env.and(boxed_ty))?; + let adj = cx.drop_adjustment(typing_env.as_query_input(boxed_ty))?; let adj_bound = AdjustmentBounds::single_value(adj); let mut expected = box_free_exp - adj_bound; @@ -709,10 +726,10 @@ memoize!( ty::Adt(def, _) => { // For Adts, we first try to not use any of the args and just try the most // polymorphic version of the type. - let poly_param_env = cx.param_env_reveal_all_normalized(def.did()); + let poly_typing_env = TypingEnv::post_analysis(cx.tcx, def.did()); let poly_args = cx.erase_regions(GenericArgs::identity_for_item(cx.tcx, def.did())); - let poly_poly_ty = - poly_param_env.and(cx.tcx.mk_ty_from_kind(ty::Adt(*def, poly_args))); + let poly_poly_ty = poly_typing_env + .as_query_input(cx.tcx.mk_ty_from_kind(ty::Adt(*def, poly_args))); if poly_poly_ty != poly_ty { match cx.drop_expectation(poly_poly_ty) { Err(Error::TooGeneric) => (), @@ -743,15 +760,19 @@ memoize!( ty::Array(elem_ty, size) => { let infcx = cx.tcx.infer_ctxt().build(TypingMode::PostAnalysis); - let size = rustc_trait_selection::traits::evaluate_const(&infcx, *size, param_env) - .try_to_target_usize(cx.tcx) - .ok_or(Error::TooGeneric); + let size = rustc_trait_selection::traits::evaluate_const( + &infcx, + *size, + typing_env.param_env, + ) + .try_to_target_usize(cx.tcx) + .ok_or(Error::TooGeneric); if size == Ok(0) { return Ok(ExpectationRange::top()); } // Special case for no expectation at all. No need to check adjustment here. - let param_and_elem_ty = param_env.and(*elem_ty); + let param_and_elem_ty = typing_env.as_query_input(*elem_ty); let elem_exp = cx.drop_expectation(param_and_elem_ty)?; if elem_exp == ExpectationRange::top() { return Ok(ExpectationRange::top()); @@ -794,19 +815,19 @@ memoize!( ty::Slice(elem_ty) => { // We can assume adjustment here is 0 otherwise the adjustment calculation // logic would have complained. - return cx.drop_expectation(param_env.and(*elem_ty)); + return cx.drop_expectation(typing_env.as_query_input(*elem_ty)); } _ => return Err(Error::TooGeneric), } - // Do not call `resolve_drop_in_place` because we need param_env. + // Do not call `resolve_drop_in_place` because we need typing_env. let drop_in_place = cx.require_lang_item(LangItem::DropInPlace, None); let args = cx.mk_args(&[ty.into()]); - let instance = ty::Instance::try_resolve(cx.tcx, param_env, drop_in_place, args) + let instance = ty::Instance::try_resolve(cx.tcx, typing_env, drop_in_place, args) .unwrap() .unwrap(); - let poly_instance = param_env.and(instance); + let poly_instance = typing_env.as_query_input(instance); assert!(matches!( instance.def, @@ -821,7 +842,7 @@ memoize!( .any(|x| x.instance == poly_instance) { // Recursion encountered. - if param_env.caller_bounds().is_empty() { + if typing_env.param_env.caller_bounds().is_empty() { return Ok(ExpectationRange::top()); } else { // If we are handling generic functions, then defer decision to monomorphization time. @@ -829,8 +850,8 @@ memoize!( } } - let mir = crate::mir::drop_shim::build_drop_shim(cx, instance.def_id(), param_env, ty); - let result = cx.infer_expectation(param_env, instance, &mir); + let mir = crate::mir::drop_shim::build_drop_shim(cx, instance.def_id(), typing_env, ty); + let result = cx.infer_expectation(typing_env, instance, &mir); // Recursion encountered. if let Some(&recur) = cx.query_cache::().borrow().get(&poly_ty) { @@ -856,7 +877,7 @@ memoize!( } } - // if instance.def_id().is_local() && param_env.caller_bounds().is_empty() { + // if instance.def_id().is_local() && typing_env.param_env.caller_bounds().is_empty() { // cx.sql_store::(poly_instance, result); // } @@ -868,13 +889,16 @@ memoize!( #[instrument(skip(cx), fields(poly_ty = %PolyDisplay(&poly_ty)), ret)] pub fn drop_expectation_check<'tcx>( cx: &AnalysisCtxt<'tcx>, - poly_ty: ParamEnvAnd<'tcx, Ty<'tcx>>, + poly_ty: PseudoCanonicalInput<'tcx, Ty<'tcx>>, ) -> Result<(), Error> { let expectation = cx.drop_expectation(poly_ty)?; - let (param_env, ty) = poly_ty.into_parts(); + let PseudoCanonicalInput { + typing_env, + value: ty, + } = poly_ty; // If the type doesn't need drop, then there is trivially no expectation. - if !ty.needs_drop(cx.tcx, param_env) { + if !ty.needs_drop(cx.tcx, typing_env) { return Ok(()); } @@ -894,10 +918,10 @@ memoize!( ty::Adt(def, _) => { // For Adts, we first try to not use any of the args and just try the most // polymorphic version of the type. - let poly_param_env = cx.param_env_reveal_all_normalized(def.did()); + let poly_typing_env = TypingEnv::post_analysis(cx.tcx, def.did()); let poly_args = cx.erase_regions(GenericArgs::identity_for_item(cx.tcx, def.did())); - let poly_poly_ty = - poly_param_env.and(cx.tcx.mk_ty_from_kind(ty::Adt(*def, poly_args))); + let poly_poly_ty = poly_typing_env + .as_query_input(cx.tcx.mk_ty_from_kind(ty::Adt(*def, poly_args))); if poly_poly_ty != poly_ty { match cx.drop_expectation_check(poly_poly_ty) { Err(Error::TooGeneric) => (), @@ -923,10 +947,10 @@ memoize!( return Ok(()); } - // Do not call `resolve_drop_in_place` because we need param_env. + // Do not call `resolve_drop_in_place` because we need typing_env. let drop_in_place = cx.require_lang_item(LangItem::DropInPlace, None); let args = cx.mk_args(&[ty.into()]); - let instance = ty::Instance::try_resolve(cx.tcx, param_env, drop_in_place, args) + let instance = ty::Instance::try_resolve(cx.tcx, typing_env, drop_in_place, args) .unwrap() .unwrap(); @@ -935,8 +959,8 @@ memoize!( ty::InstanceKind::DropGlue(_, Some(_)) )); - let mir = crate::mir::drop_shim::build_drop_shim(cx, instance.def_id(), param_env, ty); - let expectation_infer = cx.infer_expectation(param_env, instance, &mir)?; + let mir = crate::mir::drop_shim::build_drop_shim(cx, instance.def_id(), typing_env, ty); + let expectation_infer = cx.infer_expectation(typing_env, instance, &mir)?; // Check if the inferred expectation matches the annotation. if !expectation_infer.contains_range(expectation) { let mut diag = cx.dcx().struct_span_err( @@ -960,16 +984,19 @@ memoize!( #[instrument(skip(cx), fields(poly_instance = %PolyDisplay(&poly_instance)), ret)] pub fn instance_expectation<'tcx>( cx: &AnalysisCtxt<'tcx>, - poly_instance: ParamEnvAnd<'tcx, Instance<'tcx>>, + poly_instance: PseudoCanonicalInput<'tcx, Instance<'tcx>>, ) -> Result { - let (param_env, instance) = poly_instance.into_parts(); + let PseudoCanonicalInput { + typing_env, + value: instance, + } = poly_instance; match instance.def { // No Rust built-in intrinsics will mess with preemption count. ty::InstanceKind::Intrinsic(_) => return Ok(ExpectationRange::top()), // Empty drop glue, then it definitely won't mess with preemption count. ty::InstanceKind::DropGlue(_, None) => return Ok(ExpectationRange::top()), ty::InstanceKind::DropGlue(_, Some(ty)) => { - return cx.drop_expectation(param_env.and(ty)) + return cx.drop_expectation(typing_env.as_query_input(ty)) } ty::InstanceKind::Virtual(def_id, _) => { if let Some(exp) = cx.preemption_count_annotation(def_id).expectation { @@ -983,11 +1010,11 @@ memoize!( let mut generic = false; if matches!(instance.def, ty::InstanceKind::Item(_)) { - let poly_param_env = cx.param_env_reveal_all_normalized(instance.def_id()); + let poly_typing_env = TypingEnv::post_analysis(cx.tcx, instance.def_id()); let poly_args = cx.erase_regions(GenericArgs::identity_for_item(cx.tcx, instance.def_id())); let poly_poly_instance = - poly_param_env.and(Instance::new(instance.def_id(), poly_args)); + poly_typing_env.as_query_input(Instance::new(instance.def_id(), poly_args)); generic = poly_poly_instance == poly_instance; if !generic { match cx.instance_expectation(poly_poly_instance) { @@ -1033,7 +1060,7 @@ memoize!( .any(|x| x.instance == poly_instance) { // Recursion encountered. - if param_env.caller_bounds().is_empty() { + if typing_env.param_env.caller_bounds().is_empty() { return Ok(ExpectationRange::top()); } else { // If we are handling generic functions, then defer decision to monomorphization time. @@ -1042,7 +1069,7 @@ memoize!( } let mir = cx.analysis_instance_mir(instance.def); - let result = cx.infer_expectation(param_env, instance, mir); + let result = cx.infer_expectation(typing_env, instance, mir); // Recursion encountered. if let Some(recur) = cx @@ -1078,7 +1105,9 @@ memoize!( } } - if instance.def_id().is_local() && (generic || param_env.caller_bounds().is_empty()) { + if instance.def_id().is_local() + && (generic || typing_env.param_env.caller_bounds().is_empty()) + { cx.sql_store::(poly_instance, result); } @@ -1113,10 +1142,13 @@ memoize!( #[instrument(skip(cx), fields(poly_instance = %PolyDisplay(&poly_instance)), ret)] pub fn instance_expectation_check<'tcx>( cx: &AnalysisCtxt<'tcx>, - poly_instance: ParamEnvAnd<'tcx, Instance<'tcx>>, + poly_instance: PseudoCanonicalInput<'tcx, Instance<'tcx>>, ) -> Result<(), Error> { let expectation = cx.instance_expectation(poly_instance)?; - let (param_env, instance) = poly_instance.into_parts(); + let PseudoCanonicalInput { + typing_env, + value: instance, + } = poly_instance; // Only check locally codegenned instances. if !crate::monomorphize_collector::should_codegen_locally(cx.tcx, &instance) { @@ -1129,7 +1161,7 @@ memoize!( // Empty drop glue, then it definitely won't mess with preemption count. ty::InstanceKind::DropGlue(_, None) => return Ok(()), ty::InstanceKind::DropGlue(_, Some(ty)) => { - return cx.drop_expectation_check(param_env.and(ty)) + return cx.drop_expectation_check(typing_env.as_query_input(ty)) } // Checked by indirect checks ty::InstanceKind::Virtual(_, _) => return Ok(()), @@ -1138,11 +1170,11 @@ memoize!( // Prefer to do polymorphic check if possible. if matches!(instance.def, ty::InstanceKind::Item(_)) { - let poly_param_env = cx.param_env_reveal_all_normalized(instance.def_id()); + let poly_typing_env = TypingEnv::post_analysis(cx.tcx, instance.def_id()); let poly_args = cx.erase_regions(GenericArgs::identity_for_item(cx.tcx, instance.def_id())); let poly_poly_instance = - poly_param_env.and(Instance::new(instance.def_id(), poly_args)); + poly_typing_env.as_query_input(Instance::new(instance.def_id(), poly_args)); let generic = poly_poly_instance == poly_instance; if !generic { match cx.instance_expectation_check(poly_poly_instance) { @@ -1172,7 +1204,7 @@ memoize!( if annotation.expectation.is_some() && !annotation.unchecked { let mir = body.unwrap(); - let expectation_infer = cx.infer_expectation(param_env, instance, mir)?; + let expectation_infer = cx.infer_expectation(typing_env, instance, mir)?; // Check if the inferred expectation matches the annotation. if !expectation_infer.contains_range(expectation) { let mut diag = cx.dcx().struct_span_err( @@ -1186,7 +1218,7 @@ memoize!( "but the expectation inferred is {expectation_infer}" )); cx.report_body_expectation_error( - param_env, + typing_env, instance, mir, expectation, @@ -1233,7 +1265,7 @@ memoize!( ); if let Some(body) = body { cx.report_body_expectation_error( - param_env, + typing_env, instance, body, ancestor_exp, @@ -1274,7 +1306,7 @@ memoize!( )); if let Some(body) = body { cx.report_body_expectation_error( - param_env, + typing_env, instance, body, ffi_property.1, diff --git a/src/preempt_count/mod.rs b/src/preempt_count/mod.rs index c6657f1..c73ba4d 100644 --- a/src/preempt_count/mod.rs +++ b/src/preempt_count/mod.rs @@ -9,7 +9,7 @@ pub mod dataflow; pub mod expectation; use rustc_errors::ErrorGuaranteed; -use rustc_middle::ty::{Instance, ParamEnvAnd}; +use rustc_middle::ty::{Instance, PseudoCanonicalInput}; use rustc_mir_dataflow::lattice::MeetSemiLattice; use rustc_span::Span; @@ -21,18 +21,18 @@ pub enum Error { Error(ErrorGuaranteed), } -pub struct PolyDisplay<'a, 'tcx, T>(pub &'a ParamEnvAnd<'tcx, T>); +pub struct PolyDisplay<'a, 'tcx, T>(pub &'a PseudoCanonicalInput<'tcx, T>); impl std::fmt::Display for PolyDisplay<'_, '_, T> where T: std::fmt::Display + Copy, { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let (param_env, instance) = self.0.into_parts(); - write!(f, "{}", instance)?; - if !param_env.caller_bounds().is_empty() { + let PseudoCanonicalInput { typing_env, value } = self.0; + write!(f, "{}", value)?; + if !typing_env.param_env.caller_bounds().is_empty() { write!(f, " where ")?; - for (i, predicate) in param_env.caller_bounds().iter().enumerate() { + for (i, predicate) in typing_env.param_env.caller_bounds().iter().enumerate() { if i > 0 { write!(f, ", ")?; } @@ -178,6 +178,6 @@ pub enum UseSiteKind { #[derive(Debug)] pub struct UseSite<'tcx> { - pub instance: ParamEnvAnd<'tcx, Instance<'tcx>>, + pub instance: PseudoCanonicalInput<'tcx, Instance<'tcx>>, pub kind: UseSiteKind, }