From 520ebcb3e997aa478760a935d084af7e40a112bf Mon Sep 17 00:00:00 2001 From: David Wood Date: Tue, 8 Apr 2025 20:13:00 +0000 Subject: [PATCH 1/3] middle: `ClauseKind`-specific `ParamEnv` accessors Replace the `caller_bounds` function of `ParamEnv` with `ClauseKind`-specific accessors (i.e. `trait_clauses`, `region_outlives_clauses`) which will make it easier to later change the internals of `ParamEnv`. --- .../src/diagnostics/conflict_errors.rs | 6 +- .../src/type_check/free_region_relations.rs | 16 ++- .../src/check/compare_impl_item.rs | 6 +- .../rustc_hir_analysis/src/check/wfcheck.rs | 5 +- compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs | 21 ++-- compiler/rustc_hir_typeck/src/method/probe.rs | 22 +--- .../src/infer/outlives/for_liveness.rs | 6 +- .../rustc_infer/src/infer/outlives/mod.rs | 6 +- compiler/rustc_middle/src/query/mod.rs | 2 +- compiler/rustc_middle/src/ty/codec.rs | 6 +- compiler/rustc_middle/src/ty/mod.rs | 112 ++++++++++++++---- compiler/rustc_middle/src/ty/predicate.rs | 61 ++++++++-- compiler/rustc_middle/src/ty/sty.rs | 16 +-- compiler/rustc_middle/src/ty/util.rs | 4 +- .../src/function_item_references.rs | 15 +-- .../src/solve/assembly/mod.rs | 5 +- .../src/solve/effect_goals.rs | 4 + .../src/solve/normalizes_to/mod.rs | 4 + .../src/solve/trait_goals.rs | 8 +- .../src/error_reporting/traits/suggestions.rs | 15 +-- compiler/rustc_trait_selection/src/regions.rs | 22 ++-- .../src/traits/auto_trait.rs | 12 +- .../src/traits/const_evaluatable.rs | 17 +-- .../src/traits/effects.rs | 7 +- .../rustc_trait_selection/src/traits/mod.rs | 2 +- .../src/traits/project.rs | 67 +++++------ .../src/traits/select/candidate_assembly.rs | 4 +- .../src/traits/select/mod.rs | 2 +- .../src/traits/specialize/mod.rs | 15 +-- compiler/rustc_ty_utils/src/layout.rs | 5 +- compiler/rustc_type_ir/src/inherent.rs | 16 ++- src/librustdoc/clean/auto_trait.rs | 6 +- .../src/methods/needless_collect.rs | 14 +-- .../src/methods/unnecessary_to_owned.rs | 11 +- .../src/needless_borrows_for_generic_args.rs | 31 ++--- .../src/needless_pass_by_value.rs | 2 +- src/tools/clippy/clippy_utils/src/ty/mod.rs | 4 +- .../in-where-clause.stderr | 2 +- 38 files changed, 325 insertions(+), 254 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 1f4eb0c449f8a..7eb23a9ee7058 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -254,10 +254,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let place = &self.move_data.move_paths[mpi].place; let ty = place.ty(self.body, self.infcx.tcx).ty; - if self.infcx.param_env.caller_bounds().iter().any(|c| { - c.as_trait_clause().is_some_and(|pred| { - pred.skip_binder().self_ty() == ty && self.infcx.tcx.is_fn_trait(pred.def_id()) - }) + if self.infcx.param_env.trait_clauses().any(|pred| { + pred.skip_binder().self_ty() == ty && self.infcx.tcx.is_fn_trait(pred.def_id()) }) { // Suppress the next suggestion since we don't want to put more bounds onto // something that already has `Fn`-like bounds (or is a closure), so we can't diff --git a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs index eaac633b512d6..40c0ebca7d9f4 100644 --- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs +++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs @@ -226,15 +226,13 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> { // Normalize the assumptions we use to borrowck the program. let mut constraints = vec![]; let mut known_type_outlives_obligations = vec![]; - for bound in param_env.caller_bounds() { - if let Some(outlives) = bound.as_type_outlives_clause() { - self.normalize_and_push_type_outlives_obligation( - outlives, - span, - &mut known_type_outlives_obligations, - &mut constraints, - ); - }; + for outlives in param_env.type_outlives_clauses() { + self.normalize_and_push_type_outlives_obligation( + outlives, + span, + &mut known_type_outlives_obligations, + &mut constraints, + ); } let unnormalized_input_output_tys = self diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 32a8f101849c8..4825c11ea30cd 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -235,7 +235,7 @@ fn compare_method_predicate_entailment<'tcx>( let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_def_id); let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds)); let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause); - debug!(caller_bounds=?param_env.caller_bounds()); + debug!(?param_env); let infcx = &tcx.infer_ctxt().build(TypingMode::non_body_analysis()); let ocx = ObligationCtxt::new_with_diagnostics(infcx); @@ -1990,7 +1990,7 @@ fn compare_type_predicate_entailment<'tcx>( let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds)); let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause); - debug!(caller_bounds=?param_env.caller_bounds()); + debug!(?param_env); let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis()); let ocx = ObligationCtxt::new_with_diagnostics(&infcx); @@ -2229,7 +2229,7 @@ fn param_env_with_gat_bounds<'tcx>( ) -> ty::ParamEnv<'tcx> { let param_env = tcx.param_env(impl_ty.def_id); let container_id = impl_ty.container_id(tcx); - let mut predicates = param_env.caller_bounds().to_vec(); + let mut predicates = param_env.all_clauses().collect::>(); // for RPITITs, we should install predicates that allow us to project all // of the RPITITs associated with the same body. This is because checking diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 6292d03bf6ac9..cdd3d5e0f70f9 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -586,9 +586,8 @@ fn augment_param_env<'tcx>( return param_env; } - let bounds = tcx.mk_clauses_from_iter( - param_env.caller_bounds().iter().chain(new_predicates.iter().cloned()), - ); + let bounds = + tcx.mk_clauses_from_iter(param_env.all_clauses().chain(new_predicates.iter().cloned())); // FIXME(compiler-errors): Perhaps there is a case where we need to normalize this // i.e. traits::normalize_param_env_or_error ty::ParamEnv::new(bounds) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index e14f1528d2c4c..581545ad1651f 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -15,7 +15,7 @@ use rustc_hir::{self as hir, HirId, ItemLocalMap}; use rustc_hir_analysis::hir_ty_lowering::{HirTyLowerer, RegionInferReason}; use rustc_infer::infer; use rustc_infer::traits::Obligation; -use rustc_middle::ty::{self, Const, Ty, TyCtxt, TypeVisitableExt}; +use rustc_middle::ty::{self, Const, Ty, TyCtxt, TypeVisitableExt, Upcast}; use rustc_session::Session; use rustc_span::{self, DUMMY_SP, ErrorGuaranteed, Ident, Span, sym}; use rustc_trait_selection::error_reporting::TypeErrCtxt; @@ -296,16 +296,15 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> { // HACK(eddyb) should get the original `Span`. let span = tcx.def_span(def_id); - ty::EarlyBinder::bind(tcx.arena.alloc_from_iter( - self.param_env.caller_bounds().iter().filter_map(|predicate| { - match predicate.kind().skip_binder() { - ty::ClauseKind::Trait(data) if data.self_ty().is_param(index) => { - Some((predicate, span)) - } - _ => None, - } - }), - )) + ty::EarlyBinder::bind(tcx.arena.alloc_from_iter(self.param_env.trait_clauses().filter_map( + |predicate| { + predicate + .self_ty() + .skip_binder() + .is_param(index) + .then_some((predicate.upcast(tcx), span)) + }, + ))) } fn lower_assoc_shared( diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 0a01ec89a327d..e53797d54b48c 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -909,24 +909,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { #[instrument(level = "debug", skip(self))] fn assemble_inherent_candidates_from_param(&mut self, param_ty: ty::ParamTy) { - let bounds = self.param_env.caller_bounds().iter().filter_map(|predicate| { - let bound_predicate = predicate.kind(); - match bound_predicate.skip_binder() { - ty::ClauseKind::Trait(trait_predicate) => { - match *trait_predicate.trait_ref.self_ty().kind() { - ty::Param(p) if p == param_ty => { - Some(bound_predicate.rebind(trait_predicate.trait_ref)) - } - _ => None, - } - } - ty::ClauseKind::RegionOutlives(_) - | ty::ClauseKind::TypeOutlives(_) - | ty::ClauseKind::Projection(_) - | ty::ClauseKind::ConstArgHasType(_, _) - | ty::ClauseKind::WellFormed(_) - | ty::ClauseKind::ConstEvaluatable(_) - | ty::ClauseKind::HostEffect(..) => None, + let bounds = self.param_env.trait_clauses().filter_map(|trait_predicate| { + match *trait_predicate.self_ty().skip_binder().kind() { + ty::Param(p) if p == param_ty => Some(trait_predicate.map_bound(|p| p.trait_ref)), + _ => None, } }); diff --git a/compiler/rustc_infer/src/infer/outlives/for_liveness.rs b/compiler/rustc_infer/src/infer/outlives/for_liveness.rs index c44d9723f29d7..4a47b12aea29a 100644 --- a/compiler/rustc_infer/src/infer/outlives/for_liveness.rs +++ b/compiler/rustc_infer/src/infer/outlives/for_liveness.rs @@ -65,9 +65,9 @@ where let outlives_bounds: Vec<_> = tcx .item_bounds(def_id) .iter_instantiated(tcx, args) - .chain(param_env.caller_bounds()) - .filter_map(|clause| { - let outlives = clause.as_type_outlives_clause()?; + .filter_map(|clause| clause.as_type_outlives_clause()) + .chain(param_env.type_outlives_clauses()) + .filter_map(|outlives| { if let Some(outlives) = outlives.no_bound_vars() && outlives.0 == ty { diff --git a/compiler/rustc_infer/src/infer/outlives/mod.rs b/compiler/rustc_infer/src/infer/outlives/mod.rs index 2a4544c1140d1..0e30303ce6553 100644 --- a/compiler/rustc_infer/src/infer/outlives/mod.rs +++ b/compiler/rustc_infer/src/infer/outlives/mod.rs @@ -17,14 +17,12 @@ pub mod obligations; pub mod test_type_match; pub(crate) mod verify; -#[instrument(level = "debug", skip(param_env), ret)] +#[instrument(level = "debug", skip(param_env))] pub fn explicit_outlives_bounds<'tcx>( param_env: ty::ParamEnv<'tcx>, ) -> impl Iterator> { param_env - .caller_bounds() - .into_iter() - .filter_map(ty::Clause::as_region_outlives_clause) + .region_outlives_clauses() .filter_map(ty::Binder::no_bound_vars) .map(|ty::OutlivesPredicate(r_a, r_b)| OutlivesBound::RegionSubRegion(r_b, r_a)) } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index a1df27ac788cb..b063877bdcc43 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -2437,7 +2437,7 @@ rustc_queries! { desc { "resolving instance `{}`", ty::Instance::new(key.value.0, key.value.1) } } - query reveal_opaque_types_in_bounds(key: ty::Clauses<'tcx>) -> ty::Clauses<'tcx> { + query reveal_opaque_types_in_bounds(key: ty::ParamEnv<'tcx>) -> ty::ParamEnv<'tcx> { desc { "revealing opaque types in `{:?}`", key } } diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index 23927c112bcd4..efa0feb35c919 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -209,7 +209,7 @@ impl<'tcx, E: TyEncoder<'tcx>> Encodable for CtfeProvenance { impl<'tcx, E: TyEncoder<'tcx>> Encodable for ty::ParamEnv<'tcx> { fn encode(&self, e: &mut E) { - self.caller_bounds().encode(e); + self.caller_bounds.encode(e); } } @@ -340,8 +340,8 @@ impl<'tcx, D: TyDecoder<'tcx>> Decodable for ty::SymbolName<'tcx> { impl<'tcx, D: TyDecoder<'tcx>> Decodable for ty::ParamEnv<'tcx> { fn decode(d: &mut D) -> Self { - let caller_bounds = Decodable::decode(d); - ty::ParamEnv::new(caller_bounds) + let all_clauses = Decodable::decode(d); + ty::ParamEnv::new(all_clauses) } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 80f1bd7c6f464..e109a27cfffe0 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -79,10 +79,12 @@ pub use self::predicate::{ AliasTerm, Clause, ClauseKind, CoercePredicate, ExistentialPredicate, ExistentialPredicateStableCmpExt, ExistentialProjection, ExistentialTraitRef, HostEffectPredicate, NormalizesTo, OutlivesPredicate, PolyCoercePredicate, - PolyExistentialPredicate, PolyExistentialProjection, PolyExistentialTraitRef, + PolyConstArgHasTypePredicate, PolyConstEvaluatablePredicate, PolyExistentialPredicate, + PolyExistentialProjection, PolyExistentialTraitRef, PolyHostEffectPredicate, PolyProjectionPredicate, PolyRegionOutlivesPredicate, PolySubtypePredicate, PolyTraitPredicate, - PolyTraitRef, PolyTypeOutlivesPredicate, Predicate, PredicateKind, ProjectionPredicate, - RegionOutlivesPredicate, SubtypePredicate, TraitPredicate, TraitRef, TypeOutlivesPredicate, + PolyTraitRef, PolyTypeOutlivesPredicate, PolyWellFormedPredicate, Predicate, PredicateKind, + ProjectionPredicate, RegionOutlivesPredicate, SubtypePredicate, TraitPredicate, TraitRef, + TypeOutlivesPredicate, }; pub use self::region::{ BoundRegion, BoundRegionKind, EarlyParamRegion, LateParamRegion, LateParamRegionKind, Region, @@ -870,19 +872,13 @@ pub struct Placeholder { } impl Placeholder { pub fn find_const_ty_from_env<'tcx>(self, env: ParamEnv<'tcx>) -> Ty<'tcx> { - let mut candidates = env.caller_bounds().iter().filter_map(|clause| { + let mut candidates = env.const_arg_has_type_clauses().filter_map(|clause| { // `ConstArgHasType` are never desugared to be higher ranked. - match clause.kind().skip_binder() { - ty::ClauseKind::ConstArgHasType(placeholder_ct, ty) => { - assert!(!(placeholder_ct, ty).has_escaping_bound_vars()); - - match placeholder_ct.kind() { - ty::ConstKind::Placeholder(placeholder_ct) if placeholder_ct == self => { - Some(ty) - } - _ => None, - } - } + let (placeholder_ct, ty) = clause.skip_binder(); + assert!(!(placeholder_ct, ty).has_escaping_bound_vars()); + + match placeholder_ct.kind() { + ty::ConstKind::Placeholder(placeholder_ct) if placeholder_ct == self => Some(ty), _ => None, } }); @@ -989,8 +985,36 @@ pub struct ParamEnv<'tcx> { } impl<'tcx> rustc_type_ir::inherent::ParamEnv> for ParamEnv<'tcx> { - fn caller_bounds(self) -> impl inherent::SliceLike> { - self.caller_bounds() + fn trait_clauses(self) -> impl Iterator> { + self.all_clauses().filter(|c| c.as_trait_clause().is_some()) + } + + fn region_outlives_clauses(self) -> impl Iterator> { + self.all_clauses().filter(|c| c.as_region_outlives_clause().is_some()) + } + + fn type_outlives_clauses(self) -> impl Iterator> { + self.all_clauses().filter(|c| c.as_type_outlives_clause().is_some()) + } + + fn projection_clauses(self) -> impl Iterator> { + self.all_clauses().filter(|c| c.as_projection_clause().is_some()) + } + + fn const_arg_has_type_clauses(self) -> impl Iterator> { + self.all_clauses().filter(|c| c.as_const_arg_has_type_clause().is_some()) + } + + fn well_formed_clauses(self) -> impl Iterator> { + self.all_clauses().filter(|c| c.as_well_formed_clause().is_some()) + } + + fn const_evaluatable_clauses(self) -> impl Iterator> { + self.all_clauses().filter(|c| c.as_const_evaluatable_clause().is_some()) + } + + fn host_effect_clauses(self) -> impl Iterator> { + self.all_clauses().filter(|c| c.as_host_effect_clause().is_some()) } } @@ -1007,8 +1031,54 @@ impl<'tcx> ParamEnv<'tcx> { } #[inline] - pub fn caller_bounds(self) -> Clauses<'tcx> { - self.caller_bounds + pub fn all_clauses(self) -> impl Iterator> { + self.caller_bounds.iter() + } + + #[inline] + pub fn trait_clauses(self) -> impl Iterator> { + self.caller_bounds.iter().filter_map(|c| c.as_trait_clause()) + } + + #[inline] + pub fn region_outlives_clauses( + self, + ) -> impl Iterator> { + self.caller_bounds.iter().filter_map(|c| c.as_region_outlives_clause()) + } + + #[inline] + pub fn type_outlives_clauses(self) -> impl Iterator> { + self.caller_bounds.iter().filter_map(|c| c.as_type_outlives_clause()) + } + + #[inline] + pub fn projection_clauses(self) -> impl Iterator> { + self.caller_bounds.iter().filter_map(|c| c.as_projection_clause()) + } + + #[inline] + pub fn const_arg_has_type_clauses( + self, + ) -> impl Iterator> { + self.caller_bounds.iter().filter_map(|c| c.as_const_arg_has_type_clause()) + } + + #[inline] + pub fn well_formed_clauses(self) -> impl Iterator> { + self.caller_bounds.iter().filter_map(|c| c.as_well_formed_clause()) + } + + #[inline] + pub fn const_evaluatable_clauses( + self, + ) -> impl Iterator> { + self.caller_bounds.iter().filter_map(|c| c.as_const_evaluatable_clause()) + } + + #[inline] + pub fn host_effect_clauses(self) -> impl Iterator> { + self.caller_bounds.iter().filter_map(|c| c.as_host_effect_clause()) } /// Construct a trait environment with the given set of predicates. @@ -1095,9 +1165,9 @@ impl<'tcx> TypingEnv<'tcx> { // No need to reveal opaques with the new solver enabled, // since we have lazy norm. let param_env = if tcx.next_trait_solver_globally() { - ParamEnv::new(param_env.caller_bounds()) + param_env } else { - ParamEnv::new(tcx.reveal_opaque_types_in_bounds(param_env.caller_bounds())) + tcx.reveal_opaque_types_in_bounds(param_env) }; TypingEnv { typing_mode: TypingMode::PostAnalysis, param_env } } diff --git a/compiler/rustc_middle/src/ty/predicate.rs b/compiler/rustc_middle/src/ty/predicate.rs index 02e316dfc3db7..d4b58f46730b9 100644 --- a/compiler/rustc_middle/src/ty/predicate.rs +++ b/compiler/rustc_middle/src/ty/predicate.rs @@ -18,6 +18,9 @@ pub type ExistentialTraitRef<'tcx> = ir::ExistentialTraitRef>; pub type ExistentialProjection<'tcx> = ir::ExistentialProjection>; pub type TraitPredicate<'tcx> = ir::TraitPredicate>; pub type HostEffectPredicate<'tcx> = ir::HostEffectPredicate>; +pub type ConstArgHasTypePredicate<'tcx> = (ty::Const<'tcx>, Ty<'tcx>); +pub type WellFormedPredicate<'tcx> = ty::GenericArg<'tcx>; +pub type ConstEvaluatablePredicate<'tcx> = ty::Const<'tcx>; pub type ClauseKind<'tcx> = ir::ClauseKind>; pub type PredicateKind<'tcx> = ir::PredicateKind>; pub type NormalizesTo<'tcx> = ir::NormalizesTo>; @@ -27,11 +30,15 @@ pub type OutlivesPredicate<'tcx, T> = ir::OutlivesPredicate, T>; pub type RegionOutlivesPredicate<'tcx> = OutlivesPredicate<'tcx, ty::Region<'tcx>>; pub type TypeOutlivesPredicate<'tcx> = OutlivesPredicate<'tcx, Ty<'tcx>>; pub type PolyTraitPredicate<'tcx> = ty::Binder<'tcx, TraitPredicate<'tcx>>; +pub type PolyHostEffectPredicate<'tcx> = ty::Binder<'tcx, HostEffectPredicate<'tcx>>; pub type PolyRegionOutlivesPredicate<'tcx> = ty::Binder<'tcx, RegionOutlivesPredicate<'tcx>>; pub type PolyTypeOutlivesPredicate<'tcx> = ty::Binder<'tcx, TypeOutlivesPredicate<'tcx>>; pub type PolySubtypePredicate<'tcx> = ty::Binder<'tcx, SubtypePredicate<'tcx>>; pub type PolyCoercePredicate<'tcx> = ty::Binder<'tcx, CoercePredicate<'tcx>>; pub type PolyProjectionPredicate<'tcx> = ty::Binder<'tcx, ProjectionPredicate<'tcx>>; +pub type PolyConstArgHasTypePredicate<'tcx> = ty::Binder<'tcx, ConstArgHasTypePredicate<'tcx>>; +pub type PolyWellFormedPredicate<'tcx> = ty::Binder<'tcx, WellFormedPredicate<'tcx>>; +pub type PolyConstEvaluatablePredicate<'tcx> = ty::Binder<'tcx, ConstEvaluatablePredicate<'tcx>>; /// A statement that can be proven by a trait solver. This includes things that may /// show up in where clauses, such as trait predicates and projection predicates, @@ -199,7 +206,7 @@ impl<'tcx> Clause<'tcx> { }) } - pub fn as_trait_clause(self) -> Option>> { + pub fn as_trait_clause(self) -> Option> { let clause = self.kind(); if let ty::ClauseKind::Trait(trait_clause) = clause.skip_binder() { Some(clause.rebind(trait_clause)) @@ -208,16 +215,16 @@ impl<'tcx> Clause<'tcx> { } } - pub fn as_projection_clause(self) -> Option>> { + pub fn as_region_outlives_clause(self) -> Option> { let clause = self.kind(); - if let ty::ClauseKind::Projection(projection_clause) = clause.skip_binder() { - Some(clause.rebind(projection_clause)) + if let ty::ClauseKind::RegionOutlives(o) = clause.skip_binder() { + Some(clause.rebind(o)) } else { None } } - pub fn as_type_outlives_clause(self) -> Option>> { + pub fn as_type_outlives_clause(self) -> Option> { let clause = self.kind(); if let ty::ClauseKind::TypeOutlives(o) = clause.skip_binder() { Some(clause.rebind(o)) @@ -226,12 +233,46 @@ impl<'tcx> Clause<'tcx> { } } - pub fn as_region_outlives_clause( - self, - ) -> Option>> { + pub fn as_projection_clause(self) -> Option> { let clause = self.kind(); - if let ty::ClauseKind::RegionOutlives(o) = clause.skip_binder() { - Some(clause.rebind(o)) + if let ty::ClauseKind::Projection(projection_clause) = clause.skip_binder() { + Some(clause.rebind(projection_clause)) + } else { + None + } + } + + pub fn as_const_arg_has_type_clause(self) -> Option> { + let clause = self.kind(); + if let ty::ClauseKind::ConstArgHasType(ct, ty) = clause.skip_binder() { + Some(clause.rebind((ct, ty))) + } else { + None + } + } + + pub fn as_well_formed_clause(self) -> Option> { + let clause = self.kind(); + if let ty::ClauseKind::WellFormed(arg) = clause.skip_binder() { + Some(clause.rebind(arg)) + } else { + None + } + } + + pub fn as_const_evaluatable_clause(self) -> Option> { + let clause = self.kind(); + if let ty::ClauseKind::ConstEvaluatable(ct) = clause.skip_binder() { + Some(clause.rebind(ct)) + } else { + None + } + } + + pub fn as_host_effect_clause(self) -> Option> { + let clause = self.kind(); + if let ty::ClauseKind::HostEffect(host_effect_clause) = clause.skip_binder() { + Some(clause.rebind(host_effect_clause)) } else { None } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 27ee363f1c142..652121ea375da 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -343,17 +343,13 @@ impl ParamConst { #[instrument(level = "debug")] pub fn find_ty_from_env<'tcx>(self, env: ParamEnv<'tcx>) -> Ty<'tcx> { - let mut candidates = env.caller_bounds().iter().filter_map(|clause| { + let mut candidates = env.const_arg_has_type_clauses().filter_map(|clause| { // `ConstArgHasType` are never desugared to be higher ranked. - match clause.kind().skip_binder() { - ty::ClauseKind::ConstArgHasType(param_ct, ty) => { - assert!(!(param_ct, ty).has_escaping_bound_vars()); - - match param_ct.kind() { - ty::ConstKind::Param(param_ct) if param_ct.index == self.index => Some(ty), - _ => None, - } - } + let (param_ct, ty) = clause.skip_binder(); + assert!(!(param_ct, ty).has_escaping_bound_vars()); + + match param_ct.kind() { + ty::ConstKind::Param(param_ct) if param_ct.index == self.index => Some(ty), _ => None, } }); diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 857b462b9eb1e..ee9c3948bd503 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -1684,8 +1684,8 @@ pub struct AlwaysRequiresDrop; /// with their underlying types. pub fn reveal_opaque_types_in_bounds<'tcx>( tcx: TyCtxt<'tcx>, - val: ty::Clauses<'tcx>, -) -> ty::Clauses<'tcx> { + val: ty::ParamEnv<'tcx>, +) -> ty::ParamEnv<'tcx> { assert!(!tcx.next_trait_solver_globally()); let mut visitor = OpaqueTypeExpander { seen_opaque_tys: FxHashSet::default(), diff --git a/compiler/rustc_mir_transform/src/function_item_references.rs b/compiler/rustc_mir_transform/src/function_item_references.rs index 38b5ccdb32e77..bc686905167fe 100644 --- a/compiler/rustc_mir_transform/src/function_item_references.rs +++ b/compiler/rustc_mir_transform/src/function_item_references.rs @@ -72,8 +72,7 @@ impl<'tcx> FunctionItemRefChecker<'_, 'tcx> { source_info: SourceInfo, ) { let param_env = self.tcx.param_env(def_id); - let bounds = param_env.caller_bounds(); - for bound in bounds { + for bound in param_env.trait_clauses() { if let Some(bound_ty) = self.is_pointer_trait(bound) { // Get the argument types as they appear in the function signature. let arg_defs = @@ -106,14 +105,10 @@ impl<'tcx> FunctionItemRefChecker<'_, 'tcx> { } /// If the given predicate is the trait `fmt::Pointer`, returns the bound parameter type. - fn is_pointer_trait(&self, bound: ty::Clause<'tcx>) -> Option> { - if let ty::ClauseKind::Trait(predicate) = bound.kind().skip_binder() { - self.tcx - .is_diagnostic_item(sym::Pointer, predicate.def_id()) - .then(|| predicate.trait_ref.self_ty()) - } else { - None - } + fn is_pointer_trait(&self, predicate: ty::PolyTraitPredicate<'tcx>) -> Option> { + self.tcx + .is_diagnostic_item(sym::Pointer, predicate.def_id()) + .then(|| predicate.self_ty().skip_binder()) } /// If a type is a reference or raw pointer to the anonymous type of a function definition, diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index 384a304c4a9d6..f7ab91b252eec 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -48,6 +48,9 @@ where fn trait_def_id(self, cx: I) -> I::DefId; + /// Returns relevant bounds from a `ParamEnv` (e.g. trait bounds when this is a trait goal). + fn relevant_bounds_from_caller(goal: Goal) -> impl Iterator; + /// Try equating an assumption predicate against a goal's predicate. If it /// holds, then execute the `then` callback, which should do any additional /// work, then produce a response (typically by executing @@ -485,7 +488,7 @@ where goal: Goal, candidates: &mut Vec>, ) { - for (i, assumption) in goal.param_env.caller_bounds().iter().enumerate() { + for (i, assumption) in G::relevant_bounds_from_caller(goal).enumerate() { candidates.extend(G::probe_and_consider_implied_clause( self, CandidateSource::ParamEnv(i), diff --git a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs index 0b61c368d8e8d..6db9447178bd8 100644 --- a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs @@ -36,6 +36,10 @@ where self.def_id() } + fn relevant_bounds_from_caller(goal: Goal) -> impl Iterator { + goal.param_env.host_effect_clauses() + } + fn probe_and_match_goal_against_assumption( ecx: &mut EvalCtxt<'_, D>, source: rustc_type_ir::solve::CandidateSource, diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs index de6d21da0f592..a1a5d0b32bb1d 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs @@ -104,6 +104,10 @@ where self.trait_def_id(cx) } + fn relevant_bounds_from_caller(goal: Goal) -> impl Iterator { + goal.param_env.projection_clauses() + } + fn probe_and_match_goal_against_assumption( ecx: &mut EvalCtxt<'_, D>, source: CandidateSource, diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index d42c9980f4633..1844e7facc06e 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -41,6 +41,10 @@ where self.def_id() } + fn relevant_bounds_from_caller(goal: Goal) -> impl Iterator { + goal.param_env.trait_clauses() + } + fn consider_additional_alias_assumptions( _ecx: &mut EvalCtxt<'_, D>, _goal: Goal, @@ -1270,7 +1274,7 @@ where // (including global ones) over everything else. let has_non_global_where_bounds = candidates.iter().any(|c| match c.source { CandidateSource::ParamEnv(idx) => { - let where_bound = goal.param_env.caller_bounds().get(idx).unwrap(); + let where_bound = goal.param_env.trait_clauses().nth(idx).unwrap(); let ty::ClauseKind::Trait(trait_pred) = where_bound.kind().skip_binder() else { unreachable!("expected trait-bound: {where_bound:?}"); }; @@ -1283,7 +1287,7 @@ where // // See ui/traits/next-solver/normalization-shadowing/global-trait-with-project.rs // for an example where this is necessary. - for p in goal.param_env.caller_bounds().iter() { + for p in goal.param_env.projection_clauses() { if let ty::ClauseKind::Projection(proj) = p.kind().skip_binder() { if proj.projection_term.trait_ref(self.cx()) == trait_pred.trait_ref { return true; diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 38fcba4ea6256..bd908e3995c10 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -1128,19 +1128,16 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } else { DefIdOrName::Name("type parameter") }; - param_env.caller_bounds().iter().find_map(|pred| { - if let ty::ClauseKind::Projection(proj) = pred.kind().skip_binder() - && self - .tcx - .is_lang_item(proj.projection_term.def_id, LangItem::FnOnceOutput) - && proj.projection_term.self_ty() == found + param_env.projection_clauses().find_map(|proj| { + if self.tcx.is_lang_item(proj.item_def_id(), LangItem::FnOnceOutput) + && proj.skip_binder().self_ty() == found // args tuple will always be args[1] - && let ty::Tuple(args) = proj.projection_term.args.type_at(1).kind() + && let ty::Tuple(args) = proj.skip_binder().projection_term.args.type_at(1).kind() { Some(( name, - pred.kind().rebind(proj.term.expect_type()), - pred.kind().rebind(args.as_slice()), + proj.map_bound(|proj| proj.term.expect_type()), + proj.rebind(args.as_slice()), )) } else { None diff --git a/compiler/rustc_trait_selection/src/regions.rs b/compiler/rustc_trait_selection/src/regions.rs index 068e90b00b8d1..6c051f32e0325 100644 --- a/compiler/rustc_trait_selection/src/regions.rs +++ b/compiler/rustc_trait_selection/src/regions.rs @@ -29,21 +29,19 @@ impl<'tcx> OutlivesEnvironment<'tcx> { ) -> Self { let mut bounds = vec![]; - for bound in param_env.caller_bounds() { - if let Some(mut type_outlives) = bound.as_type_outlives_clause() { - if infcx.next_trait_solver() { - match crate::solve::deeply_normalize::<_, ScrubbedTraitError<'tcx>>( - infcx.at(&ObligationCause::dummy(), param_env), - type_outlives, - ) { - Ok(new) => type_outlives = new, - Err(_) => { - infcx.dcx().delayed_bug(format!("could not normalize `{bound}`")); - } + for mut type_outlives in param_env.type_outlives_clauses() { + if infcx.next_trait_solver() { + match crate::solve::deeply_normalize::<_, ScrubbedTraitError<'tcx>>( + infcx.at(&ObligationCause::dummy(), param_env), + type_outlives, + ) { + Ok(new) => type_outlives = new, + Err(_) => { + infcx.dcx().delayed_bug(format!("could not normalize `{type_outlives}`")); } } - bounds.push(type_outlives); } + bounds.push(type_outlives); } // FIXME: This needs to be modified so that we normalize the known type diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 02521c9453d98..912da632ef7c1 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -225,7 +225,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { // Don't try to process any nested obligations involving predicates // that are already in the `ParamEnv` (modulo regions): we already // know that they must hold. - for predicate in param_env.caller_bounds() { + for predicate in param_env.all_clauses() { fresh_preds.insert(self.clean_pred(infcx, predicate.as_predicate())); } @@ -240,9 +240,8 @@ impl<'tcx> AutoTraitFinder<'tcx> { polarity: ty::PredicatePolarity::Positive, })); - let computed_preds = param_env.caller_bounds().iter().map(|c| c.as_predicate()); let mut user_computed_preds: FxIndexSet<_> = - user_env.caller_bounds().iter().map(|c| c.as_predicate()).collect(); + user_env.all_clauses().map(|c| c.as_predicate()).collect(); let mut new_env = param_env; let dummy_cause = ObligationCause::dummy(); @@ -315,8 +314,11 @@ impl<'tcx> AutoTraitFinder<'tcx> { _ => panic!("Unexpected error for '{ty:?}': {result:?}"), }; - let normalized_preds = - elaborate(tcx, computed_preds.clone().chain(user_computed_preds.iter().cloned())); + let computed_preds = param_env + .all_clauses() + .map(|c| c.as_predicate()) + .chain(user_computed_preds.iter().cloned()); + let normalized_preds = elaborate(tcx, computed_preds); new_env = ty::ParamEnv::new( tcx.mk_clauses_from_iter(normalized_preds.filter_map(|p| p.as_clause())), ); diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 39333082acdff..781d2216e13ee 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -201,17 +201,12 @@ fn satisfied_from_param_env<'tcx>( let mut single_match: Option, ()>> = None; - for pred in param_env.caller_bounds() { - match pred.kind().skip_binder() { - ty::ClauseKind::ConstEvaluatable(ce) => { - let b_ct = tcx.expand_abstract_consts(ce); - let mut v = Visitor { ct, infcx, param_env, single_match }; - let _ = b_ct.visit_with(&mut v); - - single_match = v.single_match; - } - _ => {} // don't care - } + for ce in param_env.const_evaluatable_clauses() { + let b_ct = tcx.expand_abstract_consts(ce); + let mut v = Visitor { ct, infcx, param_env, single_match }; + let _ = b_ct.visit_with(&mut v); + + single_match = v.single_match; } if let Some(Ok(c)) = single_match { diff --git a/compiler/rustc_trait_selection/src/traits/effects.rs b/compiler/rustc_trait_selection/src/traits/effects.rs index defbafac20b39..cf472e3379b51 100644 --- a/compiler/rustc_trait_selection/src/traits/effects.rs +++ b/compiler/rustc_trait_selection/src/traits/effects.rs @@ -117,12 +117,7 @@ fn evaluate_host_effect_from_bounds<'tcx>( let drcx = DeepRejectCtxt::relate_rigid_rigid(selcx.tcx()); let mut candidate = None; - for clause in obligation.param_env.caller_bounds() { - let bound_clause = clause.kind(); - let ty::ClauseKind::HostEffect(data) = bound_clause.skip_binder() else { - continue; - }; - let data = bound_clause.rebind(data); + for data in obligation.param_env.host_effect_clauses() { if data.skip_binder().trait_ref.def_id != obligation.predicate.trait_ref.def_id { continue; } diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index de337710b5ef7..3831ff6d57e16 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -339,7 +339,7 @@ pub fn normalize_param_env_or_error<'tcx>( // can be sure that no errors should occur. let mut predicates: Vec<_> = util::elaborate( tcx, - unnormalized_env.caller_bounds().into_iter().map(|predicate| { + unnormalized_env.all_clauses().into_iter().map(|predicate| { if tcx.features().generic_const_exprs() { return predicate; } diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 349569d750e08..2d476767422e4 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -716,7 +716,7 @@ fn assemble_candidates_from_param_env<'cx, 'tcx>( obligation, candidate_set, ProjectionCandidate::ParamEnv, - obligation.param_env.caller_bounds().iter(), + obligation.param_env.projection_clauses(), false, ); } @@ -838,51 +838,46 @@ fn assemble_candidates_from_predicates<'cx, 'tcx>( obligation: &ProjectionTermObligation<'tcx>, candidate_set: &mut ProjectionCandidateSet<'tcx>, ctor: fn(ty::PolyProjectionPredicate<'tcx>) -> ProjectionCandidate<'tcx>, - env_predicates: impl Iterator>, + env_predicates: impl Iterator>, potentially_unnormalized_candidates: bool, ) { let infcx = selcx.infcx; let drcx = DeepRejectCtxt::relate_rigid_rigid(selcx.tcx()); - for predicate in env_predicates { - let bound_predicate = predicate.kind(); - if let ty::ClauseKind::Projection(data) = predicate.kind().skip_binder() { - let data = bound_predicate.rebind(data); - if data.item_def_id() != obligation.predicate.def_id { - continue; - } + for data in env_predicates { + if data.item_def_id() != obligation.predicate.def_id { + continue; + } - if !drcx - .args_may_unify(obligation.predicate.args, data.skip_binder().projection_term.args) - { - continue; - } + if !drcx.args_may_unify(obligation.predicate.args, data.skip_binder().projection_term.args) + { + continue; + } - let is_match = infcx.probe(|_| { - selcx.match_projection_projections( - obligation, - data, - potentially_unnormalized_candidates, - ) - }); + let is_match = infcx.probe(|_| { + selcx.match_projection_projections( + obligation, + data, + potentially_unnormalized_candidates, + ) + }); - match is_match { - ProjectionMatchesProjection::Yes => { - candidate_set.push_candidate(ctor(data)); + match is_match { + ProjectionMatchesProjection::Yes => { + candidate_set.push_candidate(ctor(data)); - if potentially_unnormalized_candidates - && !obligation.predicate.has_non_region_infer() - { - // HACK: Pick the first trait def candidate for a fully - // inferred predicate. This is to allow duplicates that - // differ only in normalization. - return; - } - } - ProjectionMatchesProjection::Ambiguous => { - candidate_set.mark_ambiguous(); + if potentially_unnormalized_candidates + && !obligation.predicate.has_non_region_infer() + { + // HACK: Pick the first trait def candidate for a fully + // inferred predicate. This is to allow duplicates that + // differ only in normalization. + return; } - ProjectionMatchesProjection::No => {} } + ProjectionMatchesProjection::Ambiguous => { + candidate_set.mark_ambiguous(); + } + ProjectionMatchesProjection::No => {} } } } diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index cf6d2bc151fb0..3ed47c6e102fe 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -225,9 +225,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let bounds = stack .obligation .param_env - .caller_bounds() - .iter() - .filter_map(|p| p.as_trait_clause()) + .trait_clauses() // Micro-optimization: filter out predicates relating to different traits. .filter(|p| p.def_id() == stack.obligation.predicate.def_id()) .filter(|p| p.polarity() == stack.obligation.predicate.polarity()); diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 56ff46e89e706..b2f8571a8ea30 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1001,7 +1001,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ) -> Result { if !matches!(self.infcx.typing_mode(), TypingMode::Coherence) && obligation.is_global() - && obligation.param_env.caller_bounds().iter().all(|bound| bound.has_param()) + && obligation.param_env.trait_clauses().all(|bound| bound.has_param()) { // If a param env has no global bounds, global obligations do not // depend on its particular value in order to work, so we can clear diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index 448ac558cad7f..011088e909594 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -203,10 +203,7 @@ fn fulfill_implication<'tcx>( debug!( "fulfill_implication: for impls on {:?} and {:?}, \ could not fulfill: {:?} given {:?}", - source_trait_ref, - target_trait_ref, - errors, - param_env.caller_bounds() + source_trait_ref, target_trait_ref, errors, param_env ); return Err(NoSolution); } @@ -337,10 +334,7 @@ pub(super) fn specializes( debug!( "fulfill_implication: for impls on {:?} and {:?}, \ could not fulfill: {:?} given {:?}", - specializing_impl_trait_ref, - parent_impl_trait_ref, - errors, - param_env.caller_bounds() + specializing_impl_trait_ref, parent_impl_trait_ref, errors, param_env ); return false; } @@ -373,10 +367,7 @@ pub(super) fn specializes( debug!( "fulfill_implication: for impls on {:?} and {:?}, \ could not fulfill: {:?} given {:?}", - specializing_impl_trait_ref, - parent_impl_trait_ref, - errors, - param_env.caller_bounds() + specializing_impl_trait_ref, parent_impl_trait_ref, errors, param_env ); return false; } diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 0017186c1b082..ee34b9c0b6c57 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -97,7 +97,7 @@ fn map_error<'tcx>( // This is sometimes not a compile error if there are trivially false where clauses. // See `tests/ui/layout/trivial-bounds-sized.rs` for an example. assert!(field.layout.is_unsized(), "invalid layout error {err:#?}"); - if cx.typing_env.param_env.caller_bounds().is_empty() { + if cx.typing_env.param_env.trait_clauses().next().is_none() { cx.tcx().dcx().delayed_bug(format!( "encountered unexpected unsized field in layout of {ty:?}: {field:#?}" )); @@ -639,7 +639,8 @@ fn record_layout_for_printing<'tcx>(cx: &LayoutCx<'tcx>, layout: TyAndLayout<'tc // Ignore layouts that are done with non-empty environments or // non-monomorphic layouts, as the user only wants to see the stuff // resulting from the final codegen session. - if layout.ty.has_non_region_param() || !cx.typing_env.param_env.caller_bounds().is_empty() { + if layout.ty.has_non_region_param() || cx.typing_env.param_env.trait_clauses().next().is_some() + { return; } diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index 59c2d3c2fc8d9..f07767e5d2aed 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -513,7 +513,21 @@ pub trait AdtDef: Copy + Debug + Hash + Eq { } pub trait ParamEnv: Copy + Debug + Hash + Eq + TypeFoldable { - fn caller_bounds(self) -> impl SliceLike; + fn trait_clauses(self) -> impl Iterator; + + fn region_outlives_clauses(self) -> impl Iterator; + + fn type_outlives_clauses(self) -> impl Iterator; + + fn projection_clauses(self) -> impl Iterator; + + fn const_arg_has_type_clauses(self) -> impl Iterator; + + fn well_formed_clauses(self) -> impl Iterator; + + fn const_evaluatable_clauses(self) -> impl Iterator; + + fn host_effect_clauses(self) -> impl Iterator; } pub trait Features: Copy { diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 138ac3c97f7b6..1507b61ffc11f 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -169,11 +169,9 @@ fn clean_param_env<'tcx>( .collect(); // FIXME(#111101): Incorporate the explicit predicates of the item here... - let item_predicates: FxIndexSet<_> = - tcx.param_env(item_def_id).caller_bounds().iter().collect(); + let item_predicates: FxIndexSet<_> = tcx.param_env(item_def_id).all_clauses().collect(); let where_predicates = param_env - .caller_bounds() - .iter() + .all_clauses() // FIXME: ...which hopefully allows us to simplify this: .filter(|pred| { !item_predicates.contains(pred) diff --git a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs index 56ff7e2c61b22..67a388ef5a963 100644 --- a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs +++ b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs @@ -17,7 +17,7 @@ use rustc_hir::{ }; use rustc_lint::LateContext; use rustc_middle::hir::nested_filter; -use rustc_middle::ty::{self, AssocKind, ClauseKind, EarlyBinder, GenericArg, GenericArgKind, Ty}; +use rustc_middle::ty::{self, AssocKind, EarlyBinder, GenericArg, GenericArgKind, Ty}; use rustc_span::symbol::Ident; use rustc_span::{Span, sym}; @@ -172,13 +172,13 @@ fn check_collect_into_intoiterator<'tcx>( if cx .tcx .param_env(id) - .caller_bounds() - .into_iter() - .filter_map(|p| { - if let ClauseKind::Trait(t) = p.kind().skip_binder() - && cx.tcx.is_diagnostic_item(sym::IntoIterator, t.trait_ref.def_id) + .trait_clauses() + .filter_map(|t| { + if cx + .tcx + .is_diagnostic_item(sym::IntoIterator, t.skip_binder().trait_ref.def_id) { - Some(t.self_ty()) + Some(t.self_ty().skip_binder()) } else { None } diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs index 62ba3012643ce..54532f4752a57 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs @@ -477,7 +477,7 @@ fn get_input_traits_and_projections<'tcx>( ) -> (Vec>, Vec>) { let mut trait_predicates = Vec::new(); let mut projection_predicates = Vec::new(); - for predicate in cx.tcx.param_env(callee_def_id).caller_bounds() { + for predicate in cx.tcx.param_env(callee_def_id).all_clauses() { match predicate.kind().skip_binder() { ClauseKind::Trait(trait_predicate) => { if trait_predicate.trait_ref.self_ty() == input { @@ -547,12 +547,9 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty< let mut trait_predicates = cx.tcx .param_env(callee_def_id) - .caller_bounds() - .iter() - .filter(|predicate| { - if let ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() - && trait_predicate.trait_ref.self_ty() == param_ty - { + .trait_clauses() + .filter(|trait_predicate| { + if trait_predicate.skip_binder().trait_ref.self_ty() == param_ty { true } else { false diff --git a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs index f686cc912ddb0..1255d293e05fd 100644 --- a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs +++ b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs @@ -177,28 +177,23 @@ fn needless_borrow_count<'tcx>( let drop_trait_def_id = cx.tcx.lang_items().drop_trait(); let fn_sig = cx.tcx.fn_sig(fn_id).instantiate_identity().skip_binder(); - let predicates = cx.tcx.param_env(fn_id).caller_bounds(); - let projection_predicates = predicates - .iter() - .filter_map(|predicate| { - if let ClauseKind::Projection(projection_predicate) = predicate.kind().skip_binder() { - Some(projection_predicate) - } else { - None - } - }) + let projection_predicates = cx + .tcx + .param_env(fn_id) + .projection_clauses() + .map(|p| p.skip_binder()) .collect::>(); let mut trait_with_ref_mut_self_method = false; // If no traits were found, or only the `Destruct`, `Sized`, or `Any` traits were found, return. - if predicates - .iter() - .filter_map(|predicate| { - if let ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() - && trait_predicate.trait_ref.self_ty() == param_ty.to_ty(cx.tcx) - { - Some(trait_predicate.trait_ref.def_id) + if cx + .tcx + .param_env(fn_id) + .trait_clauses() + .filter_map(|trait_predicate| { + if trait_predicate.skip_binder().trait_ref.self_ty() == param_ty.to_ty(cx.tcx) { + Some(trait_predicate.def_id()) } else { None } @@ -263,7 +258,7 @@ fn needless_borrow_count<'tcx>( return false; } - predicates.iter().all(|predicate| { + cx.tcx.param_env(fn_id).all_clauses().all(|predicate| { if let ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() && cx .tcx diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs index 978fde33d5170..b086846ad8e15 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs @@ -117,7 +117,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { let sized_trait = need!(cx.tcx.lang_items().sized_trait()); - let preds = traits::elaborate(cx.tcx, cx.param_env.caller_bounds().iter()) + let preds = traits::elaborate(cx.tcx, cx.param_env.all_clauses()) .filter(|p| !p.is_global()) .filter_map(|pred| { // Note that we do not want to deal with qualified predicates here. diff --git a/src/tools/clippy/clippy_utils/src/ty/mod.rs b/src/tools/clippy/clippy_utils/src/ty/mod.rs index 6fdf4c244f8d8..c97dd998369f9 100644 --- a/src/tools/clippy/clippy_utils/src/ty/mod.rs +++ b/src/tools/clippy/clippy_utils/src/ty/mod.rs @@ -755,9 +755,9 @@ pub fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option match cx.tcx.try_normalize_erasing_regions(cx.typing_env(), ty) { Ok(normalized_ty) if normalized_ty != ty => ty_sig(cx, normalized_ty), - _ => sig_for_projection(cx, proj).or_else(|| sig_from_bounds(cx, ty, cx.param_env.caller_bounds(), None)), + _ => sig_for_projection(cx, proj).or_else(|| sig_from_bounds(cx, ty, cx.param_env.all_clauses(), None)), }, - ty::Param(_) => sig_from_bounds(cx, ty, cx.param_env.caller_bounds(), None), + ty::Param(_) => sig_from_bounds(cx, ty, cx.param_env.all_clauses(), None), _ => None, } } diff --git a/tests/ui/type-alias-impl-trait/in-where-clause.stderr b/tests/ui/type-alias-impl-trait/in-where-clause.stderr index 9fcb26c20a682..e886701ee6ecd 100644 --- a/tests/ui/type-alias-impl-trait/in-where-clause.stderr +++ b/tests/ui/type-alias-impl-trait/in-where-clause.stderr @@ -62,7 +62,7 @@ LL | / fn foo() -> Bar LL | | where LL | | Bar: Send, | |______________^ - = note: ...which requires revealing opaque types in `[Binder { value: TraitPredicate(, polarity:Positive), bound_vars: [] }]`... + = note: ...which requires revealing opaque types in `ParamEnv { caller_bounds: [Binder { value: TraitPredicate(, polarity:Positive), bound_vars: [] }] }`... note: ...which requires computing type of `Bar::{opaque#0}`... --> $DIR/in-where-clause.rs:5:12 | From 5a320ea8f5510d3fab1e5dee0ca26e34902d3959 Mon Sep 17 00:00:00 2001 From: David Wood Date: Wed, 9 Apr 2025 08:07:42 +0000 Subject: [PATCH 2/3] middle: intern `ParamEnv` Adding multiple fields to `ParamEnv` will grow the type, which will negatively impact performance, and it is widely assumed that `ParamEnv` is `Copy` - intern it prior to adding the additional fields. --- .../rustc_codegen_cranelift/src/abi/mod.rs | 2 +- compiler/rustc_codegen_cranelift/src/base.rs | 10 +- .../rustc_codegen_cranelift/src/common.rs | 10 +- .../rustc_codegen_cranelift/src/constant.rs | 6 +- .../src/debuginfo/mod.rs | 7 +- .../src/debuginfo/types.rs | 2 +- .../rustc_codegen_cranelift/src/inline_asm.rs | 10 +- .../src/intrinsics/mod.rs | 4 +- .../rustc_codegen_cranelift/src/main_shim.rs | 6 +- compiler/rustc_codegen_cranelift/src/num.rs | 2 +- .../src/value_and_place.rs | 6 +- compiler/rustc_codegen_gcc/src/consts.rs | 2 +- compiler/rustc_codegen_gcc/src/context.rs | 4 +- compiler/rustc_codegen_gcc/src/int.rs | 2 +- .../rustc_codegen_gcc/src/intrinsic/simd.rs | 6 +- compiler/rustc_codegen_llvm/src/context.rs | 2 +- .../src/debuginfo/metadata/type_map.rs | 15 ++- .../src/back/symbol_export.rs | 2 +- compiler/rustc_codegen_ssa/src/base.rs | 2 +- .../src/debuginfo/type_names.rs | 19 +-- .../src/const_eval/eval_queries.rs | 2 +- .../rustc_const_eval/src/const_eval/mod.rs | 4 +- .../rustc_const_eval/src/interpret/operand.rs | 4 +- compiler/rustc_const_eval/src/lib.rs | 5 +- .../src/util/caller_location.rs | 2 +- .../src/util/check_validity_requirement.rs | 2 +- .../rustc_hir_analysis/src/check/check.rs | 2 +- .../src/check/compare_impl_item.rs | 10 +- .../src/check/compare_impl_item/refine.rs | 2 +- .../rustc_hir_analysis/src/check/entry.rs | 2 +- compiler/rustc_hir_analysis/src/check/mod.rs | 2 +- .../rustc_hir_analysis/src/check/wfcheck.rs | 4 +- .../src/coherence/orphan.rs | 6 +- .../rustc_hir_analysis/src/collect/dump.rs | 9 +- .../src/hir_ty_lowering/cmse.rs | 4 +- .../src/hir_ty_lowering/mod.rs | 2 +- compiler/rustc_hir_analysis/src/lib.rs | 2 +- compiler/rustc_lint/src/late.rs | 4 +- compiler/rustc_metadata/src/native_libs.rs | 2 +- compiler/rustc_middle/src/mir/consts.rs | 2 +- compiler/rustc_middle/src/mir/mod.rs | 2 +- compiler/rustc_middle/src/mir/statement.rs | 2 +- compiler/rustc_middle/src/ty/codec.rs | 8 +- compiler/rustc_middle/src/ty/consts.rs | 4 +- compiler/rustc_middle/src/ty/context.rs | 20 ++- compiler/rustc_middle/src/ty/instance.rs | 4 +- compiler/rustc_middle/src/ty/layout.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 120 ++++++++++-------- .../rustc_middle/src/ty/structural_impls.rs | 16 +++ compiler/rustc_middle/src/ty/util.rs | 6 +- compiler/rustc_middle/src/ty/vtable.rs | 4 +- .../src/builder/expr/as_rvalue.rs | 6 +- compiler/rustc_mir_build/src/builder/misc.rs | 3 +- compiler/rustc_monomorphize/src/collector.rs | 22 ++-- compiler/rustc_monomorphize/src/lib.rs | 6 +- .../src/mono_checks/abi_check.rs | 8 +- .../src/mono_checks/move_check.rs | 4 +- .../rustc_monomorphize/src/partitioning.rs | 2 +- .../src/partitioning/autodiff.rs | 2 +- compiler/rustc_monomorphize/src/util.rs | 2 +- compiler/rustc_passes/src/check_attr.rs | 2 +- .../src/cfi/typeid/itanium_cxx_abi/encode.rs | 4 +- .../src/cfi/typeid/itanium_cxx_abi/mod.rs | 2 +- .../cfi/typeid/itanium_cxx_abi/transform.rs | 10 +- compiler/rustc_smir/src/rustc_smir/alloc.rs | 2 +- compiler/rustc_smir/src/rustc_smir/builder.rs | 8 +- compiler/rustc_smir/src/rustc_smir/context.rs | 20 +-- compiler/rustc_symbol_mangling/src/legacy.rs | 2 +- compiler/rustc_symbol_mangling/src/v0.rs | 7 +- .../src/traits/auto_trait.rs | 2 + .../src/traits/coherence.rs | 20 ++- .../src/traits/dyn_compatibility.rs | 2 +- .../rustc_trait_selection/src/traits/mod.rs | 12 +- .../src/traits/select/mod.rs | 2 +- .../src/traits/vtable.rs | 12 +- .../src/maybe_transmutable/mod.rs | 2 +- compiler/rustc_ty_utils/src/abi.rs | 4 +- .../rustc_ty_utils/src/structural_match.rs | 7 +- compiler/rustc_ty_utils/src/ty.rs | 2 +- src/librustdoc/clean/blanket_impl.rs | 2 +- src/librustdoc/clean/utils.rs | 2 +- src/librustdoc/core.rs | 2 +- src/tools/clippy/clippy_lints/src/derive.rs | 21 +-- src/tools/miri/src/eval.rs | 2 +- .../in-where-clause.stderr | 2 +- 85 files changed, 330 insertions(+), 257 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs index ddd119e0c6108..f04597b94dcfb 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/abi/mod.rs @@ -394,7 +394,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::TypingEnv::fully_monomorphized(), + ty::TypingEnv::fully_monomorphized(fx.tcx), def_id, fn_args, source_info.span, diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index adaa754491e56..6b6192ca09e82 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -679,7 +679,7 @@ fn codegen_stmt<'tcx>( let func_ref = fx.get_function_ref( Instance::resolve_for_fn_ptr( fx.tcx, - ty::TypingEnv::fully_monomorphized(), + ty::TypingEnv::fully_monomorphized(fx.tcx), def_id, args, ) @@ -730,8 +730,10 @@ fn codegen_stmt<'tcx>( fn is_wide_ptr<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> bool { ty.builtin_deref(true).is_some_and(|pointee_ty| { - fx.tcx - .type_has_metadata(pointee_ty, ty::TypingEnv::fully_monomorphized()) + fx.tcx.type_has_metadata( + pointee_ty, + ty::TypingEnv::fully_monomorphized(fx.tcx), + ) }) } @@ -862,7 +864,7 @@ fn codegen_stmt<'tcx>( NullOp::OffsetOf(fields) => fx .tcx .offset_of_subfield( - ty::TypingEnv::fully_monomorphized(), + ty::TypingEnv::fully_monomorphized(fx.tcx), layout, fields.iter(), ) diff --git a/compiler/rustc_codegen_cranelift/src/common.rs b/compiler/rustc_codegen_cranelift/src/common.rs index abe2972ba0cbd..51229869ea9c9 100644 --- a/compiler/rustc_codegen_cranelift/src/common.rs +++ b/compiler/rustc_codegen_cranelift/src/common.rs @@ -71,7 +71,7 @@ fn clif_type_from_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option pointer_ty(tcx), ty::RawPtr(pointee_ty, _) | ty::Ref(_, pointee_ty, _) => { - if tcx.type_has_metadata(*pointee_ty, ty::TypingEnv::fully_monomorphized()) { + if tcx.type_has_metadata(*pointee_ty, ty::TypingEnv::fully_monomorphized(tcx)) { return None; } else { pointer_ty(tcx) @@ -91,7 +91,7 @@ fn clif_pair_type_from_ty<'tcx>( (clif_type_from_ty(tcx, types[0])?, clif_type_from_ty(tcx, types[1])?) } ty::RawPtr(pointee_ty, _) | ty::Ref(_, pointee_ty, _) => { - if tcx.type_has_metadata(*pointee_ty, ty::TypingEnv::fully_monomorphized()) { + if tcx.type_has_metadata(*pointee_ty, ty::TypingEnv::fully_monomorphized(tcx)) { (pointer_ty(tcx), pointer_ty(tcx)) } else { return None; @@ -327,7 +327,7 @@ impl<'tcx> rustc_abi::HasDataLayout for FunctionCx<'_, '_, 'tcx> { impl<'tcx> layout::HasTypingEnv<'tcx> for FunctionCx<'_, '_, 'tcx> { fn typing_env(&self) -> ty::TypingEnv<'tcx> { - ty::TypingEnv::fully_monomorphized() + ty::TypingEnv::fully_monomorphized(self.tcx) } } @@ -344,7 +344,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { { self.instance.instantiate_mir_and_normalize_erasing_regions( self.tcx, - ty::TypingEnv::fully_monomorphized(), + ty::TypingEnv::fully_monomorphized(self.tcx), ty::EarlyBinder::bind(value), ) } @@ -490,7 +490,7 @@ impl<'tcx> rustc_abi::HasDataLayout for FullyMonomorphizedLayoutCx<'tcx> { impl<'tcx> layout::HasTypingEnv<'tcx> for FullyMonomorphizedLayoutCx<'tcx> { fn typing_env(&self) -> ty::TypingEnv<'tcx> { - ty::TypingEnv::fully_monomorphized() + ty::TypingEnv::fully_monomorphized(self.0) } } diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index c8527c3a57dfe..04de4d3f507b6 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -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::TypingEnv::fully_monomorphized(), constant.span) + .eval(fx.tcx, ty::TypingEnv::fully_monomorphized(fx.tcx), constant.span) .expect("erroneous constant missed by mono item collection"); (val, cv.ty()) } @@ -267,9 +267,9 @@ fn data_id_for_static( assert!(!definition); assert!(!tcx.is_mutable_static(def_id)); - let ty = instance.ty(tcx, ty::TypingEnv::fully_monomorphized()); + let ty = instance.ty(tcx, ty::TypingEnv::fully_monomorphized(tcx)); let align = tcx - .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)) + .layout_of(ty::TypingEnv::fully_monomorphized(tcx).as_query_input(ty)) .unwrap() .align .abi diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs index 286e02b986b3c..abab02c4d0ab2 100644 --- a/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs @@ -210,7 +210,7 @@ impl DebugContext { type_names::push_generic_params( tcx, - tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), args), + tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(tcx), args), &mut name, ); @@ -275,9 +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::TypingEnv::fully_monomorphized()); + let static_type = + Instance::mono(tcx, def_id).ty(tcx, ty::TypingEnv::fully_monomorphized(tcx)); let static_layout = tcx - .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(static_type)) + .layout_of(ty::TypingEnv::fully_monomorphized(tcx).as_query_input(static_type)) .unwrap(); // FIXME use the actual type layout let type_id = self.debug_type(tcx, type_dbg, static_type); diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/types.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/types.rs index 25b922c8be4c7..8f7817cfa0f5b 100644 --- a/compiler/rustc_codegen_cranelift/src/debuginfo/types.rs +++ b/compiler/rustc_codegen_cranelift/src/debuginfo/types.rs @@ -129,7 +129,7 @@ impl DebugContext { let name = type_names::compute_debuginfo_type_name(tcx, ptr_type, true); - if !tcx.type_has_metadata(ptr_type, ty::TypingEnv::fully_monomorphized()) { + if !tcx.type_has_metadata(ptr_type, ty::TypingEnv::fully_monomorphized(tcx)) { let pointer_type_id = self.dwarf.unit.add(self.dwarf.unit.root(), gimli::DW_TAG_pointer_type); let pointer_entry = self.dwarf.unit.get_mut(pointer_type_id); diff --git a/compiler/rustc_codegen_cranelift/src/inline_asm.rs b/compiler/rustc_codegen_cranelift/src/inline_asm.rs index fbc33a642853c..67b20fee44bf2 100644 --- a/compiler/rustc_codegen_cranelift/src/inline_asm.rs +++ b/compiler/rustc_codegen_cranelift/src/inline_asm.rs @@ -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::TypingEnv::fully_monomorphized(), + ty::TypingEnv::fully_monomorphized(fx.tcx), def_id, args, ) @@ -225,11 +225,11 @@ pub(crate) fn codegen_naked_asm<'tcx>( InlineAsmOperand::Const { ref value } => { let cv = instance.instantiate_mir_and_normalize_erasing_regions( tcx, - ty::TypingEnv::fully_monomorphized(), + ty::TypingEnv::fully_monomorphized(tcx), ty::EarlyBinder::bind(value.const_), ); let const_value = cv - .eval(tcx, ty::TypingEnv::fully_monomorphized(), value.span) + .eval(tcx, ty::TypingEnv::fully_monomorphized(tcx), value.span) .expect("erroneous constant missed by mono item collection"); let value = rustc_codegen_ssa::common::asm_const_to_str( @@ -248,13 +248,13 @@ pub(crate) fn codegen_naked_asm<'tcx>( let const_ = instance.instantiate_mir_and_normalize_erasing_regions( tcx, - ty::TypingEnv::fully_monomorphized(), + ty::TypingEnv::fully_monomorphized(tcx), 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::TypingEnv::fully_monomorphized(), + ty::TypingEnv::fully_monomorphized(tcx), def_id, args, ) diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs index d3f47ad726334..99ff90c4279df 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs @@ -682,7 +682,7 @@ fn codegen_regular_intrinsic_call<'tcx>( .tcx .check_validity_requirement(( requirement, - ty::TypingEnv::fully_monomorphized().as_query_input(ty), + ty::TypingEnv::fully_monomorphized(fx.tcx).as_query_input(ty), )) .expect("expect to have layout during codegen"); @@ -743,7 +743,7 @@ fn codegen_regular_intrinsic_call<'tcx>( let const_val = fx .tcx .const_eval_instance( - ty::TypingEnv::fully_monomorphized(), + ty::TypingEnv::fully_monomorphized(fx.tcx), instance, source_info.span, ) diff --git a/compiler/rustc_codegen_cranelift/src/main_shim.rs b/compiler/rustc_codegen_cranelift/src/main_shim.rs index 6d5df2b00437b..8effe33d9095c 100644 --- a/compiler/rustc_codegen_cranelift/src/main_shim.rs +++ b/compiler/rustc_codegen_cranelift/src/main_shim.rs @@ -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::TypingEnv::fully_monomorphized(), + ty::TypingEnv::fully_monomorphized(tcx), 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, - ty::TypingEnv::fully_monomorphized(), + ty::TypingEnv::fully_monomorphized(tcx), 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, - ty::TypingEnv::fully_monomorphized(), + ty::TypingEnv::fully_monomorphized(tcx), start_def_id, tcx.mk_args(&[main_ret_ty.into()]), DUMMY_SP, diff --git a/compiler/rustc_codegen_cranelift/src/num.rs b/compiler/rustc_codegen_cranelift/src/num.rs index 2a4d1e3ae571d..ebde1f3ce0461 100644 --- a/compiler/rustc_codegen_cranelift/src/num.rs +++ b/compiler/rustc_codegen_cranelift/src/num.rs @@ -399,7 +399,7 @@ pub(crate) fn codegen_ptr_binop<'tcx>( .layout() .ty .builtin_deref(true) - .map(|ty| !fx.tcx.type_has_metadata(ty, ty::TypingEnv::fully_monomorphized())) + .map(|ty| !fx.tcx.type_has_metadata(ty, ty::TypingEnv::fully_monomorphized(fx.tcx))) .unwrap_or(true); if is_thin_ptr { diff --git a/compiler/rustc_codegen_cranelift/src/value_and_place.rs b/compiler/rustc_codegen_cranelift/src/value_and_place.rs index f8a19589fdd72..d945f87fda91f 100644 --- a/compiler/rustc_codegen_cranelift/src/value_and_place.rs +++ b/compiler/rustc_codegen_cranelift/src/value_and_place.rs @@ -746,7 +746,7 @@ impl<'tcx> CPlace<'tcx> { }; let (field_ptr, field_layout) = codegen_field(fx, base, extra, layout, field); - if fx.tcx.type_has_metadata(field_layout.ty, ty::TypingEnv::fully_monomorphized()) { + if fx.tcx.type_has_metadata(field_layout.ty, ty::TypingEnv::fully_monomorphized(fx.tcx)) { CPlace::for_ptr_with_extra(field_ptr, extra.unwrap(), field_layout) } else { CPlace::for_ptr(field_ptr, field_layout) @@ -832,7 +832,7 @@ impl<'tcx> CPlace<'tcx> { pub(crate) fn place_deref(self, fx: &mut FunctionCx<'_, '_, 'tcx>) -> CPlace<'tcx> { let inner_layout = fx.layout_of(self.layout().ty.builtin_deref(true).unwrap()); - if fx.tcx.type_has_metadata(inner_layout.ty, ty::TypingEnv::fully_monomorphized()) { + if fx.tcx.type_has_metadata(inner_layout.ty, ty::TypingEnv::fully_monomorphized(fx.tcx)) { let (addr, extra) = self.to_cvalue(fx).load_scalar_pair(fx); CPlace::for_ptr_with_extra(Pointer::new(addr), extra, inner_layout) } else { @@ -845,7 +845,7 @@ impl<'tcx> CPlace<'tcx> { fx: &mut FunctionCx<'_, '_, 'tcx>, layout: TyAndLayout<'tcx>, ) -> CValue<'tcx> { - if fx.tcx.type_has_metadata(self.layout().ty, ty::TypingEnv::fully_monomorphized()) { + if fx.tcx.type_has_metadata(self.layout().ty, ty::TypingEnv::fully_monomorphized(fx.tcx)) { let (ptr, extra) = self.to_ptr_unsized(); CValue::by_val_pair(ptr.get_addr(fx), extra, layout) } else { diff --git a/compiler/rustc_codegen_gcc/src/consts.rs b/compiler/rustc_codegen_gcc/src/consts.rs index acb3937462857..ba0c5a86a76ec 100644 --- a/compiler/rustc_codegen_gcc/src/consts.rs +++ b/compiler/rustc_codegen_gcc/src/consts.rs @@ -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::TypingEnv::fully_monomorphized()); + let ty = instance.ty(self.tcx, ty::TypingEnv::fully_monomorphized(self.tcx)); self.layout_of(ty).gcc_type(self) }; diff --git a/compiler/rustc_codegen_gcc/src/context.rs b/compiler/rustc_codegen_gcc/src/context.rs index 1e1f577bb3a15..094f8cc380ab8 100644 --- a/compiler/rustc_codegen_gcc/src/context.rs +++ b/compiler/rustc_codegen_gcc/src/context.rs @@ -145,7 +145,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { ) -> Self { let create_type = |ctype, rust_type| { let layout = tcx - .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(rust_type)) + .layout_of(ty::TypingEnv::fully_monomorphized(tcx).as_query_input(rust_type)) .unwrap(); let align = layout.align.abi.bytes(); #[cfg(feature = "master")] @@ -590,7 +590,7 @@ impl<'gcc, 'tcx> FnAbiOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> { impl<'tcx, 'gcc> HasTypingEnv<'tcx> for CodegenCx<'gcc, 'tcx> { fn typing_env(&self) -> ty::TypingEnv<'tcx> { - ty::TypingEnv::fully_monomorphized() + ty::TypingEnv::fully_monomorphized(self.tcx) } } diff --git a/compiler/rustc_codegen_gcc/src/int.rs b/compiler/rustc_codegen_gcc/src/int.rs index f3552d9b12fcb..e7e72f97d4df2 100644 --- a/compiler/rustc_codegen_gcc/src/int.rs +++ b/compiler/rustc_codegen_gcc/src/int.rs @@ -388,7 +388,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { }; let layout = self .tcx - .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(res_ty)) + .layout_of(ty::TypingEnv::fully_monomorphized(self.tcx).as_query_input(res_ty)) .unwrap(); let arg_abi = ArgAbi { layout, mode: PassMode::Direct(ArgAttributes::new()) }; diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs index 8b454ab2a4241..0aebd6dfea755 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs @@ -56,7 +56,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( let tcx = bx.tcx(); let sig = tcx.normalize_erasing_late_bound_regions( - ty::TypingEnv::fully_monomorphized(), + ty::TypingEnv::fully_monomorphized(tcx), callee_ty.fn_sig(tcx), ); let arg_tys = sig.inputs(); @@ -469,7 +469,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::TypingEnv::fully_monomorphized(), ty) + bx.tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(bx.tcx), ty) }); require!( metadata.is_unit(), @@ -483,7 +483,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::TypingEnv::fully_monomorphized(), ty) + bx.tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(bx.tcx), ty) }); require!( metadata.is_unit(), diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 4ec6999551898..a50843743a7cc 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -1288,7 +1288,7 @@ impl<'tcx> ty::layout::HasTyCtxt<'tcx> for CodegenCx<'_, 'tcx> { impl<'tcx, 'll> HasTypingEnv<'tcx> for CodegenCx<'ll, 'tcx> { fn typing_env(&self) -> ty::TypingEnv<'tcx> { - ty::TypingEnv::fully_monomorphized() + ty::TypingEnv::fully_monomorphized(self.tcx) } } diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs index ae2ab32ef533c..c831b90057296 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs @@ -49,14 +49,14 @@ 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(ty::TypingEnv::fully_monomorphized(), t)); + assert_eq!(t, tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(tcx), 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(ty::TypingEnv::fully_monomorphized(), enum_ty) + tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(tcx), enum_ty) ); UniqueTypeId::VariantPart(enum_ty, private::HiddenZst) } @@ -68,7 +68,7 @@ impl<'tcx> UniqueTypeId<'tcx> { ) -> Self { assert_eq!( enum_ty, - tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), enum_ty) + tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(tcx), enum_ty) ); UniqueTypeId::VariantStructType(enum_ty, variant_idx, private::HiddenZst) } @@ -80,7 +80,7 @@ impl<'tcx> UniqueTypeId<'tcx> { ) -> Self { assert_eq!( enum_ty, - tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), enum_ty) + tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(tcx), enum_ty) ); UniqueTypeId::VariantStructTypeCppLikeWrapper(enum_ty, variant_idx, private::HiddenZst) } @@ -92,11 +92,14 @@ impl<'tcx> UniqueTypeId<'tcx> { ) -> Self { assert_eq!( self_type, - tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), self_type) + tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(tcx), self_type) ); assert_eq!( implemented_trait, - tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), implemented_trait) + tcx.normalize_erasing_regions( + ty::TypingEnv::fully_monomorphized(tcx), + implemented_trait + ) ); UniqueTypeId::VTableTy(self_type, implemented_trait, private::HiddenZst) } diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index fd06c50eb8145..7ebc92b3eb4e5 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -613,7 +613,7 @@ fn calling_convention_for_symbol<'tcx>( instance .map(|i| { tcx.fn_abi_of_instance( - ty::TypingEnv::fully_monomorphized().as_query_input((i, ty::List::empty())), + ty::TypingEnv::fully_monomorphized(tcx).as_query_input((i, ty::List::empty())), ) .unwrap_or_else(|_| bug!("fn_abi_of_instance({i:?}) failed")) }) diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 1985b3b717063..3b2b6188bec49 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -122,7 +122,7 @@ pub fn validate_trivial_unsize<'tcx>( match (source_data.principal(), target_data.principal()) { (Some(hr_source_principal), Some(hr_target_principal)) => { let (infcx, param_env) = - tcx.infer_ctxt().build_with_typing_env(ty::TypingEnv::fully_monomorphized()); + tcx.infer_ctxt().build_with_typing_env(ty::TypingEnv::fully_monomorphized(tcx)); let universe = infcx.universe(); let ocx = ObligationCtxt::new(&infcx); infcx.enter_forall(hr_target_principal, |target_principal| { diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs index 18279a4d05fe0..9373274e99592 100644 --- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs +++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs @@ -81,7 +81,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(ty::TypingEnv::fully_monomorphized().as_query_input(t)) { + match tcx.layout_of(ty::TypingEnv::fully_monomorphized(tcx).as_query_input(t)) { Ok(layout) => { if !wants_c_like_enum_debuginfo(tcx, layout) { Some(layout) @@ -248,7 +248,7 @@ fn push_debuginfo_type_name<'tcx>( if let Some(principal) = trait_data.principal() { let principal = tcx.normalize_erasing_late_bound_regions( - ty::TypingEnv::fully_monomorphized(), + ty::TypingEnv::fully_monomorphized(tcx), principal, ); push_item_name(tcx, principal.def_id, qualified, output); @@ -352,7 +352,7 @@ fn push_debuginfo_type_name<'tcx>( } let sig = tcx.normalize_erasing_late_bound_regions( - ty::TypingEnv::fully_monomorphized(), + ty::TypingEnv::fully_monomorphized(tcx), t.fn_sig(tcx), ); @@ -416,8 +416,9 @@ 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(ty::TypingEnv::fully_monomorphized().as_query_input(t)).unwrap(); + let ty_and_layout = tcx + .layout_of(ty::TypingEnv::fully_monomorphized(tcx).as_query_input(t)) + .unwrap(); msvc_enum_fallback( tcx, ty_and_layout, @@ -530,7 +531,7 @@ pub fn compute_debuginfo_vtable_name<'tcx>( if let Some(trait_ref) = trait_ref { let trait_ref = - tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), trait_ref); + tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(tcx), 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); @@ -637,7 +638,7 @@ fn push_generic_params_internal<'tcx>( output: &mut String, visited: &mut FxHashSet>, ) -> bool { - assert_eq!(args, tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), args)); + assert_eq!(args, tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(tcx), args)); let mut args = args.non_erasable_generics().peekable(); if args.peek().is_none() { return false; @@ -674,14 +675,14 @@ fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: ty::Const<'tcx>, output: &mut S match cv.ty.kind() { ty::Int(ity) => { let bits = cv - .try_to_bits(tcx, ty::TypingEnv::fully_monomorphized()) + .try_to_bits(tcx, ty::TypingEnv::fully_monomorphized(tcx)) .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 = cv - .try_to_bits(tcx, ty::TypingEnv::fully_monomorphized()) + .try_to_bits(tcx, ty::TypingEnv::fully_monomorphized(tcx)) .expect("expected monomorphic const in codegen"); write!(output, "{val}") } diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index ce8eceebdf8d2..133b7d90113fb 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -308,7 +308,7 @@ pub fn eval_static_initializer_provider<'tcx>( let instance = ty::Instance::mono(tcx, def_id.to_def_id()); let cid = rustc_middle::mir::interpret::GlobalId { instance, promoted: None }; - eval_in_interpreter(tcx, cid, ty::TypingEnv::fully_monomorphized()) + eval_in_interpreter(tcx, cid, ty::TypingEnv::fully_monomorphized(tcx)) } pub trait InterpretationResult<'tcx> { diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs index c0438fb3ff81a..2c4cbc9491a80 100644 --- a/compiler/rustc_const_eval/src/const_eval/mod.rs +++ b/compiler/rustc_const_eval/src/const_eval/mod.rs @@ -39,7 +39,7 @@ pub(crate) fn try_destructure_mir_constant_for_user_output<'tcx>( val: mir::ConstValue<'tcx>, ty: Ty<'tcx>, ) -> Option> { - let typing_env = ty::TypingEnv::fully_monomorphized(); + let typing_env = ty::TypingEnv::fully_monomorphized(tcx); // FIXME: use a proper span here? let (ecx, op) = mk_eval_cx_for_const_val(tcx.at(rustc_span::DUMMY_SP), typing_env, val, ty)?; @@ -83,7 +83,7 @@ pub fn tag_for_variant_provider<'tcx>( let ecx = InterpCx::new( tcx, ty.default_span(tcx), - ty::TypingEnv::fully_monomorphized(), + ty::TypingEnv::fully_monomorphized(tcx), crate::const_eval::DummyMachine, ); diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 36da9037e43d9..a0fca051d3324 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -299,7 +299,7 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> { pub fn from_bool(b: bool, tcx: TyCtxt<'tcx>) -> Self { // Can use any typing env, since `bool` is always monomorphic. let layout = tcx - .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(tcx.types.bool)) + .layout_of(ty::TypingEnv::fully_monomorphized(tcx).as_query_input(tcx.types.bool)) .unwrap(); Self::from_scalar(Scalar::from_bool(b), layout) } @@ -309,7 +309,7 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> { // Can use any typing env, since `Ordering` is always monomorphic. let ty = tcx.ty_ordering_enum(None); let layout = - tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)).unwrap(); + tcx.layout_of(ty::TypingEnv::fully_monomorphized(tcx).as_query_input(ty)).unwrap(); Self::from_scalar(Scalar::from_i8(c as i8), layout) } diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index e03849c32f94f..8ed752e291e39 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -46,8 +46,9 @@ 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, cv| const_eval::valtree_to_const_value(tcx, ty::TypingEnv::fully_monomorphized(), cv); + providers.valtree_to_const_val = |tcx, cv| { + const_eval::valtree_to_const_value(tcx, ty::TypingEnv::fully_monomorphized(tcx), cv) + }; providers.check_validity_requirement = |tcx, (init_kind, param_env_and_ty)| { util::check_validity_requirement(tcx, init_kind, param_env_and_ty) }; diff --git a/compiler/rustc_const_eval/src/util/caller_location.rs b/compiler/rustc_const_eval/src/util/caller_location.rs index e926040e9ba15..b0c18764b26b2 100644 --- a/compiler/rustc_const_eval/src/util/caller_location.rs +++ b/compiler/rustc_const_eval/src/util/caller_location.rs @@ -56,7 +56,7 @@ pub(crate) fn const_caller_location_provider( let mut ecx = mk_eval_cx_to_read_const_val( tcx, rustc_span::DUMMY_SP, // FIXME: use a proper span here? - ty::TypingEnv::fully_monomorphized(), + ty::TypingEnv::fully_monomorphized(tcx), CanAccessMutGlobal::No, ); diff --git a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs index d7e97f32bae92..53db61d7f34b7 100644 --- a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs +++ b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs @@ -178,7 +178,7 @@ pub(crate) fn validate_scalar_in_layout<'tcx>( ) -> bool { let machine = CompileTimeMachine::new(CanAccessMutGlobal::No, CheckAlignment::Error); - let typing_env = ty::TypingEnv::fully_monomorphized(); + let typing_env = ty::TypingEnv::fully_monomorphized(tcx); let mut cx = InterpCx::new(tcx, DUMMY_SP, typing_env, machine); let Ok(layout) = cx.layout_of(ty) else { diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 18ef00dc8b18d..7296a029551ce 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -151,7 +151,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(ty::TypingEnv::fully_monomorphized().as_query_input(ty)) { + let layout = match tcx.layout_of(ty::TypingEnv::fully_monomorphized(tcx).as_query_input(ty)) { Ok(l) => l, // Foreign statics that overflow their allowed size should emit an error Err(LayoutError::SizeOverflow(_)) diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 4825c11ea30cd..c330eb08182cc 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -233,7 +233,7 @@ fn compare_method_predicate_entailment<'tcx>( } let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_def_id); - let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds)); + let param_env = ty::ParamEnv::new(tcx, tcx.mk_clauses(&hybrid_preds)); let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause); debug!(?param_env); @@ -523,7 +523,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( .into_iter() .chain(tcx.predicates_of(trait_m.def_id).instantiate_own(tcx, trait_to_impl_args)) .map(|(clause, _)| clause); - let param_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(hybrid_preds)); + let param_env = ty::ParamEnv::new(tcx, tcx.mk_clauses_from_iter(hybrid_preds)); let param_env = traits::normalize_param_env_or_error( tcx, param_env, @@ -1837,7 +1837,7 @@ fn compare_const_predicate_entailment<'tcx>( .map(|(predicate, _)| predicate), ); - let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds)); + let param_env = ty::ParamEnv::new(tcx, tcx.mk_clauses(&hybrid_preds)); let param_env = traits::normalize_param_env_or_error( tcx, param_env, @@ -1988,7 +1988,7 @@ fn compare_type_predicate_entailment<'tcx>( ); } - let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds)); + let param_env = ty::ParamEnv::new(tcx, tcx.mk_clauses(&hybrid_preds)); let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause); debug!(?param_env); @@ -2336,7 +2336,7 @@ fn param_env_with_gat_bounds<'tcx>( }; } - ty::ParamEnv::new(tcx.mk_clauses(&predicates)) + ty::ParamEnv::new(tcx, tcx.mk_clauses(&predicates)) } /// Manually check here that `async fn foo()` wasn't matched against `fn foo()`, diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs index 4973d84895978..393e593dc2ff1 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs @@ -132,7 +132,7 @@ pub(crate) fn check_refining_return_position_impl_trait_in_trait<'tcx>( .into_iter() .chain(tcx.predicates_of(trait_m.def_id).instantiate_own(tcx, trait_m_to_impl_m_args)) .map(|(clause, _)| clause); - let param_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(hybrid_preds)); + let param_env = ty::ParamEnv::new(tcx, tcx.mk_clauses_from_iter(hybrid_preds)); let param_env = normalize_param_env_or_error(tcx, param_env, ObligationCause::dummy()); let ref infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis()); diff --git a/compiler/rustc_hir_analysis/src/check/entry.rs b/compiler/rustc_hir_analysis/src/check/entry.rs index 3bad36da99909..535652dd1e7c8 100644 --- a/compiler/rustc_hir_analysis/src/check/entry.rs +++ b/compiler/rustc_hir_analysis/src/check/entry.rs @@ -117,7 +117,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) { } // Main should have no WC, so empty param env is OK here. - let param_env = ty::ParamEnv::empty(); + let param_env = ty::ParamEnv::empty(tcx); let expected_return_type; if let Some(term_did) = tcx.lang_items().termination() { let return_ty = main_fnsig.output(); diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 30921b6f055d5..25f12b3885d23 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -598,7 +598,7 @@ pub fn check_function_signature<'tcx>( let local_id = fn_id.as_local().unwrap_or(CRATE_DEF_ID); - let param_env = ty::ParamEnv::empty(); + let param_env = ty::ParamEnv::empty(tcx); let infcx = &tcx.infer_ctxt().build(TypingMode::non_body_analysis()); let ocx = ObligationCtxt::new_with_diagnostics(infcx); diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index cdd3d5e0f70f9..a919568247153 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -590,7 +590,7 @@ fn augment_param_env<'tcx>( tcx.mk_clauses_from_iter(param_env.all_clauses().chain(new_predicates.iter().cloned())); // FIXME(compiler-errors): Perhaps there is a case where we need to normalize this // i.e. traits::normalize_param_env_or_error - ty::ParamEnv::new(bounds) + ty::ParamEnv::new(tcx, bounds) } /// We use the following trait as an example throughout this function. @@ -2276,7 +2276,7 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> { fn check_false_global_bounds(&mut self) { let tcx = self.ocx.infcx.tcx; let mut span = self.span; - let empty_env = ty::ParamEnv::empty(); + let empty_env = ty::ParamEnv::empty(tcx); let predicates_with_span = tcx.predicates_of(self.body_def_id).predicates.iter().copied(); // Check elaborated bounds. diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index 74ba4ffe25ea1..1aa1048c7b01b 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -311,7 +311,7 @@ fn orphan_check<'tcx>( let ty::Alias(..) = user_ty.kind() else { return Ok(user_ty) }; let ocx = traits::ObligationCtxt::new(&infcx); - let ty = ocx.normalize(&cause, ty::ParamEnv::empty(), user_ty); + let ty = ocx.normalize(&cause, ty::ParamEnv::empty(tcx), user_ty); let ty = infcx.resolve_vars_if_possible(ty); let errors = ocx.select_where_possible(); if !errors.is_empty() { @@ -321,7 +321,7 @@ fn orphan_check<'tcx>( let ty = if infcx.next_trait_solver() { ocx.structurally_normalize_ty( &cause, - ty::ParamEnv::empty(), + ty::ParamEnv::empty(tcx), infcx.resolve_vars_if_possible(ty), ) .unwrap_or(ty) @@ -361,7 +361,7 @@ fn orphan_check<'tcx>( for (arg, id_arg) in std::iter::zip(args, ty::GenericArgs::identity_for_item(tcx, impl_def_id)) { - let _ = infcx.at(&cause, ty::ParamEnv::empty()).eq( + let _ = infcx.at(&cause, ty::ParamEnv::empty(tcx)).eq( DefineOpaqueTypes::No, arg, id_arg, diff --git a/compiler/rustc_hir_analysis/src/collect/dump.rs b/compiler/rustc_hir_analysis/src/collect/dump.rs index c3f965d845693..7c1fa949f4ead 100644 --- a/compiler/rustc_hir_analysis/src/collect/dump.rs +++ b/compiler/rustc_hir_analysis/src/collect/dump.rs @@ -123,9 +123,10 @@ pub(crate) fn vtables<'tcx>(tcx: TyCtxt<'tcx>) { ); continue; } - let Ok(trait_ref) = tcx - .try_normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), trait_ref) - else { + let Ok(trait_ref) = tcx.try_normalize_erasing_regions( + ty::TypingEnv::fully_monomorphized(tcx), + trait_ref, + ) else { tcx.dcx().span_err( attr.span(), "`rustc_dump_vtable` applied to impl header that cannot be normalized", @@ -144,7 +145,7 @@ pub(crate) fn vtables<'tcx>(tcx: TyCtxt<'tcx>) { continue; } let Ok(ty) = - tcx.try_normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), ty) + tcx.try_normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(tcx), ty) else { tcx.dcx().span_err( attr.span(), diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs index ecb453bced0a7..c7326141239a3 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs @@ -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(ty::TypingEnv::fully_monomorphized().as_query_input(*ty))?; + let layout = tcx.layout_of(ty::TypingEnv::fully_monomorphized(tcx).as_query_input(*ty))?; let align = layout.layout.align().abi.bytes(); let size = layout.layout.size().bytes(); @@ -158,7 +158,7 @@ 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 typing_env = ty::TypingEnv::fully_monomorphized(tcx); let mut ret_ty = fn_sig.output(); let layout = tcx.layout_of(typing_env.as_query_input(ret_ty))?; diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index b4a71edc118c4..4fa787ca05527 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -1743,7 +1743,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } infcx .can_eq( - ty::ParamEnv::empty(), + ty::ParamEnv::empty(infcx.tcx), trait_ref.self_ty(), value, ) && header.polarity != ty::ImplPolarity::Negative diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index e7ecd727a852f..c916450f54e4d 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -219,7 +219,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) { DefKind::Const if tcx.generics_of(item_def_id).is_empty() => { let instance = ty::Instance::new(item_def_id.into(), ty::GenericArgs::empty()); let cid = GlobalId { instance, promoted: None }; - let typing_env = ty::TypingEnv::fully_monomorphized(); + let typing_env = ty::TypingEnv::fully_monomorphized(tcx); tcx.ensure_ok().eval_to_const_value_raw(typing_env.as_query_input(cid)); } _ => (), diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs index 852bb01c09655..2dc97d9ae5297 100644 --- a/compiler/rustc_lint/src/late.rs +++ b/compiler/rustc_lint/src/late.rs @@ -343,7 +343,7 @@ pub fn late_lint_mod<'tcx, T: LateLintPass<'tcx> + 'tcx>( tcx, enclosing_body: None, cached_typeck_results: Cell::new(None), - param_env: ty::ParamEnv::empty(), + param_env: ty::ParamEnv::empty(tcx), effective_visibilities: tcx.effective_visibilities(()), last_node_with_lint_attrs: tcx.local_def_id_to_hir_id(module_def_id), generics: None, @@ -408,7 +408,7 @@ fn late_lint_crate<'tcx>(tcx: TyCtxt<'tcx>) { tcx, enclosing_body: None, cached_typeck_results: Cell::new(None), - param_env: ty::ParamEnv::empty(), + param_env: ty::ParamEnv::empty(tcx), effective_visibilities: tcx.effective_visibilities(()), last_node_with_lint_attrs: hir::CRATE_HIR_ID, generics: None, diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index cfb0de8475c8f..2b78740267793 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -634,7 +634,7 @@ impl<'tcx> Collector<'tcx> { .map(|ty| { let layout = self .tcx - .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)) + .layout_of(ty::TypingEnv::fully_monomorphized(self.tcx).as_query_input(ty)) .expect("layout") .layout; // In both stdcall and fastcall, we always round up the argument size to the diff --git a/compiler/rustc_middle/src/mir/consts.rs b/compiler/rustc_middle/src/mir/consts.rs index 2b2ffa7162880..da96148b0eeb9 100644 --- a/compiler/rustc_middle/src/mir/consts.rs +++ b/compiler/rustc_middle/src/mir/consts.rs @@ -472,7 +472,7 @@ impl<'tcx> Const<'tcx> { pub fn from_usize(tcx: TyCtxt<'tcx>, n: u64) -> Self { let ty = tcx.types.usize; - let typing_env = ty::TypingEnv::fully_monomorphized(); + let typing_env = ty::TypingEnv::fully_monomorphized(tcx); Self::from_bits(tcx, n as u128, typing_env, ty) } diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 4dfb362f3a22b..e3b43cfda0762 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -616,7 +616,7 @@ impl<'tcx> Body<'tcx> { // There are two places here we need to evaluate a constant. let eval_mono_const = |constant: &ConstOperand<'tcx>| { // FIXME(#132279): what is this, why are we using an empty environment here. - let typing_env = ty::TypingEnv::fully_monomorphized(); + let typing_env = ty::TypingEnv::fully_monomorphized(tcx); let mono_literal = instance.instantiate_mir_and_normalize_erasing_regions( tcx, typing_env, diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs index d59b6df44ed5d..4ae5a952411f5 100644 --- a/compiler/rustc_middle/src/mir/statement.rs +++ b/compiler/rustc_middle/src/mir/statement.rs @@ -533,7 +533,7 @@ impl<'tcx> Operand<'tcx> { span: Span, ) -> Operand<'tcx> { debug_assert!({ - let typing_env = ty::TypingEnv::fully_monomorphized(); + let typing_env = ty::TypingEnv::fully_monomorphized(tcx); let type_size = tcx .layout_of(typing_env.as_query_input(ty)) .unwrap_or_else(|e| panic!("could not compute layout for {ty:?}: {e:?}")) diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index efa0feb35c919..4997e15c0b06f 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -207,7 +207,7 @@ impl<'tcx, E: TyEncoder<'tcx>> Encodable for CtfeProvenance { } } -impl<'tcx, E: TyEncoder<'tcx>> Encodable for ty::ParamEnv<'tcx> { +impl<'tcx, E: TyEncoder<'tcx>> Encodable for ty::ParamEnvInner<'tcx> { fn encode(&self, e: &mut E) { self.caller_bounds.encode(e); } @@ -338,10 +338,10 @@ impl<'tcx, D: TyDecoder<'tcx>> Decodable for ty::SymbolName<'tcx> { } } -impl<'tcx, D: TyDecoder<'tcx>> Decodable for ty::ParamEnv<'tcx> { +impl<'tcx, D: TyDecoder<'tcx>> Decodable for ty::ParamEnvInner<'tcx> { fn decode(d: &mut D) -> Self { - let all_clauses = Decodable::decode(d); - ty::ParamEnv::new(all_clauses) + let caller_bounds = Decodable::decode(d); + ty::ParamEnvInner { caller_bounds } } } diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index ae1c6c670cbca..0615e9f832329 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -204,13 +204,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, ty::TypingEnv::fully_monomorphized(), tcx.types.bool) + Self::from_bits(tcx, v as u128, ty::TypingEnv::fully_monomorphized(tcx), 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, ty::TypingEnv::fully_monomorphized(), tcx.types.usize) + Self::from_bits(tcx, n as u128, ty::TypingEnv::fully_monomorphized(tcx), tcx.types.usize) } /// Panics if `self.kind != ty::ConstKind::Value`. diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 162ca1f4af850..abd0348aee1a7 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -78,10 +78,10 @@ use crate::traits::solve::{ use crate::ty::predicate::ExistentialPredicateStableCmpExt as _; use crate::ty::{ self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Clauses, Const, GenericArg, GenericArgs, - GenericArgsRef, GenericParamDefKind, List, ListWithCachedTypeInfo, ParamConst, ParamTy, - Pattern, PatternKind, PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind, - PredicatePolarity, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid, - ValTree, ValTreeKind, Visibility, + GenericArgsRef, GenericParamDefKind, List, ListWithCachedTypeInfo, ParamConst, ParamEnv, + ParamEnvInner, ParamTy, Pattern, PatternKind, PolyExistentialPredicate, PolyFnSig, Predicate, + PredicateKind, PredicatePolarity, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, + TyKind, TyVid, ValTree, ValTreeKind, Visibility, }; #[allow(rustc::usage_of_ty_tykind)] @@ -804,6 +804,7 @@ pub struct CtxtInterners<'tcx> { region: InternedSet<'tcx, RegionKind<'tcx>>, poly_existential_predicates: InternedSet<'tcx, List>>, predicate: InternedSet<'tcx, WithCachedTypeInfo>>>, + param_env: InternedSet<'tcx, ParamEnvInner<'tcx>>, clauses: InternedSet<'tcx, ListWithCachedTypeInfo>>, projs: InternedSet<'tcx, List>, place_elems: InternedSet<'tcx, List>>, @@ -840,6 +841,7 @@ impl<'tcx> CtxtInterners<'tcx> { poly_existential_predicates: InternedSet::with_capacity(N / 4), canonical_var_infos: InternedSet::with_capacity(N / 2), predicate: InternedSet::with_capacity(N), + param_env: InternedSet::with_capacity(N), clauses: InternedSet::with_capacity(N), projs: InternedSet::with_capacity(N * 4), place_elems: InternedSet::with_capacity(N * 2), @@ -2602,6 +2604,7 @@ direct_interners! { ExternalConstraints -> ExternalConstraints<'tcx>, predefined_opaques_in_body: pub mk_predefined_opaques_in_body(PredefinedOpaquesData>): PredefinedOpaques -> PredefinedOpaques<'tcx>, + param_env: pub mk_param_env(ParamEnvInner<'tcx>): ParamEnv -> ty::ParamEnv<'tcx>, } macro_rules! slice_interners { @@ -2707,6 +2710,15 @@ impl<'tcx> TyCtxt<'tcx> { if pred.kind() != binder { self.mk_predicate(binder) } else { pred } } + #[inline] + pub fn reuse_or_mk_param_env( + self, + env: ParamEnv<'tcx>, + inner: ParamEnvInner<'tcx>, + ) -> ParamEnv<'tcx> { + if *env != inner { self.mk_param_env(inner) } else { env } + } + pub fn check_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) -> bool { self.check_args_compatible_inner(def_id, args, false) } diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 07f2a602f2bf2..5b1e220ca2b12 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -717,7 +717,7 @@ impl<'tcx> Instance<'tcx> { let args = tcx.mk_args(&[ty.into()]); Instance::expect_resolve( tcx, - ty::TypingEnv::fully_monomorphized(), + ty::TypingEnv::fully_monomorphized(tcx), def_id, args, ty.ty_adt_def().and_then(|adt| tcx.hir_span_if_local(adt.did())).unwrap_or(DUMMY_SP), @@ -729,7 +729,7 @@ impl<'tcx> Instance<'tcx> { let args = tcx.mk_args(&[ty.into()]); Instance::expect_resolve( tcx, - ty::TypingEnv::fully_monomorphized(), + ty::TypingEnv::fully_monomorphized(tcx), def_id, args, ty.ty_adt_def().and_then(|adt| tcx.hir_span_if_local(adt.did())).unwrap_or(DUMMY_SP), diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 7ebfebea44e56..8d1f9699f3957 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -851,7 +851,7 @@ where // NOTE: using an fully monomorphized typing env and `unwrap`-ing // the `Result` should always work because the type is always either // `*mut ()` or `&'static mut ()`. - let typing_env = ty::TypingEnv::fully_monomorphized(); + let typing_env = ty::TypingEnv::fully_monomorphized(tcx); return TyMaybeWithLayout::TyAndLayout(TyAndLayout { ty: this.ty, ..tcx.layout_of(typing_env.as_query_input(unit_ptr_ty)).unwrap() diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index e109a27cfffe0..262ec8fd3f23a 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -968,14 +968,9 @@ impl<'tcx> rustc_type_ir::Flags for Clauses<'tcx> { } } -/// When interacting with the type system we must provide information about the -/// environment. `ParamEnv` is the type that represents this information. See the -/// [dev guide chapter][param_env_guide] for more information. -/// -/// [param_env_guide]: https://rustc-dev-guide.rust-lang.org/typing_parameter_envs.html #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] #[derive(HashStable, TypeVisitable, TypeFoldable)] -pub struct ParamEnv<'tcx> { +pub struct ParamEnvInner<'tcx> { /// Caller bounds are `Obligation`s that the caller must satisfy. This is /// basically the set of bounds on the in-scope type parameters, translated /// into `Obligation`s, and elaborated and normalized. @@ -984,39 +979,14 @@ pub struct ParamEnv<'tcx> { caller_bounds: Clauses<'tcx>, } -impl<'tcx> rustc_type_ir::inherent::ParamEnv> for ParamEnv<'tcx> { - fn trait_clauses(self) -> impl Iterator> { - self.all_clauses().filter(|c| c.as_trait_clause().is_some()) - } - - fn region_outlives_clauses(self) -> impl Iterator> { - self.all_clauses().filter(|c| c.as_region_outlives_clause().is_some()) - } - - fn type_outlives_clauses(self) -> impl Iterator> { - self.all_clauses().filter(|c| c.as_type_outlives_clause().is_some()) - } - - fn projection_clauses(self) -> impl Iterator> { - self.all_clauses().filter(|c| c.as_projection_clause().is_some()) - } - - fn const_arg_has_type_clauses(self) -> impl Iterator> { - self.all_clauses().filter(|c| c.as_const_arg_has_type_clause().is_some()) - } - - fn well_formed_clauses(self) -> impl Iterator> { - self.all_clauses().filter(|c| c.as_well_formed_clause().is_some()) - } - - fn const_evaluatable_clauses(self) -> impl Iterator> { - self.all_clauses().filter(|c| c.as_const_evaluatable_clause().is_some()) - } - - fn host_effect_clauses(self) -> impl Iterator> { - self.all_clauses().filter(|c| c.as_host_effect_clause().is_some()) - } -} +/// When interacting with the type system we must provide information about the +/// environment. `ParamEnv` is the type that represents this information. See the +/// [dev guide chapter][param_env_guide] for more information. +/// +/// [param_env_guide]: https://rustc-dev-guide.rust-lang.org/typing_parameter_envs.html +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +#[derive(HashStable)] +pub struct ParamEnv<'tcx>(Interned<'tcx, ParamEnvInner<'tcx>>); impl<'tcx> ParamEnv<'tcx> { /// Construct a trait environment suitable for contexts where there are @@ -1026,65 +996,65 @@ impl<'tcx> ParamEnv<'tcx> { /// /// [param_env_guide]: https://rustc-dev-guide.rust-lang.org/typing_parameter_envs.html #[inline] - pub fn empty() -> Self { - Self::new(ListWithCachedTypeInfo::empty()) + pub fn empty(tcx: TyCtxt<'tcx>) -> Self { + tcx.mk_param_env(ParamEnvInner { caller_bounds: ListWithCachedTypeInfo::empty() }) } #[inline] pub fn all_clauses(self) -> impl Iterator> { - self.caller_bounds.iter() + self.0.0.caller_bounds.iter() } #[inline] pub fn trait_clauses(self) -> impl Iterator> { - self.caller_bounds.iter().filter_map(|c| c.as_trait_clause()) + self.0.0.caller_bounds.iter().filter_map(|c| c.as_trait_clause()) } #[inline] pub fn region_outlives_clauses( self, ) -> impl Iterator> { - self.caller_bounds.iter().filter_map(|c| c.as_region_outlives_clause()) + self.0.0.caller_bounds.iter().filter_map(|c| c.as_region_outlives_clause()) } #[inline] pub fn type_outlives_clauses(self) -> impl Iterator> { - self.caller_bounds.iter().filter_map(|c| c.as_type_outlives_clause()) + self.0.0.caller_bounds.iter().filter_map(|c| c.as_type_outlives_clause()) } #[inline] pub fn projection_clauses(self) -> impl Iterator> { - self.caller_bounds.iter().filter_map(|c| c.as_projection_clause()) + self.0.0.caller_bounds.iter().filter_map(|c| c.as_projection_clause()) } #[inline] pub fn const_arg_has_type_clauses( self, ) -> impl Iterator> { - self.caller_bounds.iter().filter_map(|c| c.as_const_arg_has_type_clause()) + self.0.0.caller_bounds.iter().filter_map(|c| c.as_const_arg_has_type_clause()) } #[inline] pub fn well_formed_clauses(self) -> impl Iterator> { - self.caller_bounds.iter().filter_map(|c| c.as_well_formed_clause()) + self.0.0.caller_bounds.iter().filter_map(|c| c.as_well_formed_clause()) } #[inline] pub fn const_evaluatable_clauses( self, ) -> impl Iterator> { - self.caller_bounds.iter().filter_map(|c| c.as_const_evaluatable_clause()) + self.0.0.caller_bounds.iter().filter_map(|c| c.as_const_evaluatable_clause()) } #[inline] pub fn host_effect_clauses(self) -> impl Iterator> { - self.caller_bounds.iter().filter_map(|c| c.as_host_effect_clause()) + self.0.0.caller_bounds.iter().filter_map(|c| c.as_host_effect_clause()) } /// Construct a trait environment with the given set of predicates. #[inline] - pub fn new(caller_bounds: Clauses<'tcx>) -> Self { - ParamEnv { caller_bounds } + pub fn new(tcx: TyCtxt<'tcx>, caller_bounds: Clauses<'tcx>) -> Self { + tcx.mk_param_env(ParamEnvInner { caller_bounds }) } /// Creates a pair of param-env and value for use in queries. @@ -1093,6 +1063,48 @@ impl<'tcx> ParamEnv<'tcx> { } } +impl<'tcx> rustc_type_ir::inherent::ParamEnv> for ParamEnv<'tcx> { + fn trait_clauses(self) -> impl Iterator> { + self.all_clauses().filter(|c| c.as_trait_clause().is_some()) + } + + fn region_outlives_clauses(self) -> impl Iterator> { + self.all_clauses().filter(|c| c.as_region_outlives_clause().is_some()) + } + + fn type_outlives_clauses(self) -> impl Iterator> { + self.all_clauses().filter(|c| c.as_type_outlives_clause().is_some()) + } + + fn projection_clauses(self) -> impl Iterator> { + self.all_clauses().filter(|c| c.as_projection_clause().is_some()) + } + + fn const_arg_has_type_clauses(self) -> impl Iterator> { + self.all_clauses().filter(|c| c.as_const_arg_has_type_clause().is_some()) + } + + fn well_formed_clauses(self) -> impl Iterator> { + self.all_clauses().filter(|c| c.as_well_formed_clause().is_some()) + } + + fn const_evaluatable_clauses(self) -> impl Iterator> { + self.all_clauses().filter(|c| c.as_const_evaluatable_clause().is_some()) + } + + fn host_effect_clauses(self) -> impl Iterator> { + self.all_clauses().filter(|c| c.as_host_effect_clause().is_some()) + } +} + +impl<'tcx> std::ops::Deref for ParamEnv<'tcx> { + type Target = ParamEnvInner<'tcx>; + + fn deref(&self) -> &Self::Target { + self.0.deref() + } +} + #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable)] #[derive(HashStable)] pub struct ParamEnvAnd<'tcx, T> { @@ -1131,8 +1143,8 @@ impl<'tcx> TypingEnv<'tcx> { /// Do not use this for MIR optimizations, as even though they also /// use `TypingMode::PostAnalysis`, they may still have where-clauses /// in scope. - pub fn fully_monomorphized() -> TypingEnv<'tcx> { - TypingEnv { typing_mode: TypingMode::PostAnalysis, param_env: ParamEnv::empty() } + pub fn fully_monomorphized(tcx: TyCtxt<'tcx>) -> TypingEnv<'tcx> { + TypingEnv { typing_mode: TypingMode::PostAnalysis, param_env: ParamEnv::empty(tcx) } } /// Create a typing environment for use during analysis outside of a body. diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 798ef352c4082..1ac88f66f7578 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -513,6 +513,22 @@ impl<'tcx> TypeFoldable> for ty::Predicate<'tcx> { } } +impl<'tcx> TypeFoldable> for ty::ParamEnv<'tcx> { + fn try_fold_with>>( + self, + folder: &mut F, + ) -> Result { + let new = self.0.0.try_fold_with(folder)?; + Ok(folder.cx().reuse_or_mk_param_env(self, new)) + } +} + +impl<'tcx> TypeVisitable> for ty::ParamEnv<'tcx> { + fn visit_with>>(&self, visitor: &mut V) -> V::Result { + self.0.visit_with(visitor) + } +} + // FIXME(clause): This is wonky impl<'tcx> TypeFoldable> for ty::Clause<'tcx> { fn try_fold_with>>( diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index ee9c3948bd503..bfdc3b7ee18d8 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -477,7 +477,7 @@ impl<'tcx> TyCtxt<'tcx> { // Async drop glue morphology is an internal detail, so // using `TypingMode::PostAnalysis` probably should be fine. - let typing_env = ty::TypingEnv::fully_monomorphized(); + let typing_env = ty::TypingEnv::fully_monomorphized(self); if ty.needs_async_drop(self, typing_env) { AsyncDropGlueMorphology::Custom } else if ty.needs_drop(self, typing_env) { @@ -1175,7 +1175,7 @@ impl<'tcx> Ty<'tcx> { /// Returns the maximum value for the given numeric type (including `char`s) /// or returns `None` if the type is not numeric. pub fn numeric_max_val(self, tcx: TyCtxt<'tcx>) -> Option> { - let typing_env = TypingEnv::fully_monomorphized(); + let typing_env = TypingEnv::fully_monomorphized(tcx); self.numeric_min_and_max_as_bits(tcx) .map(|(_, max)| mir::Const::from_bits(tcx, max, typing_env, self)) } @@ -1183,7 +1183,7 @@ impl<'tcx> Ty<'tcx> { /// Returns the minimum value for the given numeric type (including `char`s) /// or returns `None` if the type is not numeric. pub fn numeric_min_val(self, tcx: TyCtxt<'tcx>) -> Option> { - let typing_env = TypingEnv::fully_monomorphized(); + let typing_env = TypingEnv::fully_monomorphized(tcx); self.numeric_min_and_max_as_bits(tcx) .map(|(min, _)| mir::Const::from_bits(tcx, min, typing_env, self)) } diff --git a/compiler/rustc_middle/src/ty/vtable.rs b/compiler/rustc_middle/src/ty/vtable.rs index 6c9e0e7c0eb8a..02f4e8dfa6e94 100644 --- a/compiler/rustc_middle/src/ty/vtable.rs +++ b/compiler/rustc_middle/src/ty/vtable.rs @@ -100,7 +100,7 @@ pub(super) fn vtable_allocation_provider<'tcx>( assert!(vtable_entries.len() >= vtable_min_entries(tcx, poly_trait_ref)); let layout = tcx - .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)) + .layout_of(ty::TypingEnv::fully_monomorphized(tcx).as_query_input(ty)) .expect("failed to build vtable representation"); assert!(layout.is_sized(), "can't create a vtable for an unsized type"); let size = layout.size.bytes(); @@ -120,7 +120,7 @@ pub(super) fn vtable_allocation_provider<'tcx>( let idx: u64 = u64::try_from(idx).unwrap(); let scalar = match *entry { VtblEntry::MetadataDropInPlace => { - if ty.needs_drop(tcx, ty::TypingEnv::fully_monomorphized()) { + if ty.needs_drop(tcx, ty::TypingEnv::fully_monomorphized(tcx)) { let instance = ty::Instance::resolve_drop_in_place(tcx, ty); let fn_alloc_id = tcx.reserve_and_set_fn_alloc(instance, CTFE_ALLOC_SALT); let fn_ptr = Pointer::from(fn_alloc_id); diff --git a/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs index f9791776f71e5..c8a0817b06e4c 100644 --- a/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs @@ -240,7 +240,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let range_val = Const::from_bits( this.tcx, range, - ty::TypingEnv::fully_monomorphized(), + ty::TypingEnv::fully_monomorphized(this.tcx), unsigned_ty, ); let lit_op = this.literal_operand(expr.span, range_val); @@ -854,7 +854,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Helper to get a `-1` value of the appropriate type fn neg_1_literal(&mut self, span: Span, ty: Ty<'tcx>) -> Operand<'tcx> { - let typing_env = ty::TypingEnv::fully_monomorphized(); + let typing_env = ty::TypingEnv::fully_monomorphized(self.tcx); let size = self.tcx.layout_of(typing_env.as_query_input(ty)).unwrap().size; let literal = Const::from_bits(self.tcx, size.unsigned_int_max(), typing_env, ty); @@ -864,7 +864,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Helper to get the minimum value of the appropriate type fn minval_literal(&mut self, span: Span, ty: Ty<'tcx>) -> Operand<'tcx> { assert!(ty.is_signed()); - let typing_env = ty::TypingEnv::fully_monomorphized(); + let typing_env = ty::TypingEnv::fully_monomorphized(self.tcx); let bits = self.tcx.layout_of(typing_env.as_query_input(ty)).unwrap().size.bits(); let n = 1 << (bits - 1); let literal = Const::from_bits(self.tcx, n, typing_env, ty); diff --git a/compiler/rustc_mir_build/src/builder/misc.rs b/compiler/rustc_mir_build/src/builder/misc.rs index 6e8e74fd4fc8d..e45eed9f3d5e6 100644 --- a/compiler/rustc_mir_build/src/builder/misc.rs +++ b/compiler/rustc_mir_build/src/builder/misc.rs @@ -32,7 +32,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// Returns a zero literal operand for the appropriate type, works for /// bool, char and integers. pub(crate) fn zero_literal(&mut self, span: Span, ty: Ty<'tcx>) -> Operand<'tcx> { - let literal = Const::from_bits(self.tcx, 0, ty::TypingEnv::fully_monomorphized(), ty); + let literal = + Const::from_bits(self.tcx, 0, ty::TypingEnv::fully_monomorphized(self.tcx), ty); self.literal_operand(span, literal) } diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 6e676ac6b8d53..9c8fed296d563 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -427,7 +427,7 @@ fn collect_items_rec<'tcx>( let DefKind::Static { nested, .. } = tcx.def_kind(def_id) else { bug!() }; // Nested statics have no type. if !nested { - let ty = instance.ty(tcx, ty::TypingEnv::fully_monomorphized()); + let ty = instance.ty(tcx, ty::TypingEnv::fully_monomorphized(tcx)); visit_drop_use(tcx, ty, true, starting_item.span, &mut used_items); } @@ -635,7 +635,7 @@ impl<'a, 'tcx> MirUsedCollector<'a, 'tcx> { trace!("monomorphize: self.instance={:?}", self.instance); self.instance.instantiate_mir_and_normalize_erasing_regions( self.tcx, - ty::TypingEnv::fully_monomorphized(), + ty::TypingEnv::fully_monomorphized(self.tcx), ty::EarlyBinder::bind(value), ) } @@ -650,7 +650,7 @@ impl<'a, 'tcx> MirUsedCollector<'a, 'tcx> { // a codegen-time error). rustc stops after collection if there was an error, so this // ensures codegen never has to worry about failing consts. // (codegen relies on this and ICEs will happen if this is violated.) - match const_.eval(self.tcx, ty::TypingEnv::fully_monomorphized(), constant.span) { + match const_.eval(self.tcx, ty::TypingEnv::fully_monomorphized(self.tcx), constant.span) { Ok(v) => Some(v), Err(ErrorHandled::TooGeneric(..)) => span_bug!( constant.span, @@ -866,7 +866,7 @@ fn visit_fn_use<'tcx>( let instance = if is_direct_call { ty::Instance::expect_resolve( tcx, - ty::TypingEnv::fully_monomorphized(), + ty::TypingEnv::fully_monomorphized(tcx), def_id, args, source, @@ -874,7 +874,7 @@ fn visit_fn_use<'tcx>( } else { match ty::Instance::resolve_for_fn_ptr( tcx, - ty::TypingEnv::fully_monomorphized(), + ty::TypingEnv::fully_monomorphized(tcx), def_id, args, ) { @@ -1043,7 +1043,7 @@ fn find_vtable_types_for_unsizing<'tcx>( target_ty: Ty<'tcx>, ) -> (Ty<'tcx>, Ty<'tcx>) { let ptr_vtable = |inner_source: Ty<'tcx>, inner_target: Ty<'tcx>| { - let typing_env = ty::TypingEnv::fully_monomorphized(); + let typing_env = ty::TypingEnv::fully_monomorphized(tcx.tcx); if tcx.type_has_metadata(inner_source, typing_env) { (inner_source, inner_target) } else { @@ -1291,7 +1291,7 @@ fn visit_mentioned_item<'tcx>( if let ty::FnDef(def_id, args) = *ty.kind() { let instance = Instance::expect_resolve( tcx, - ty::TypingEnv::fully_monomorphized(), + ty::TypingEnv::fully_monomorphized(tcx), def_id, args, span, @@ -1504,7 +1504,7 @@ impl<'v> RootCollector<'_, 'v> { _ => unreachable!(), }; let Ok(instance) = self.tcx.try_normalize_erasing_regions( - ty::TypingEnv::fully_monomorphized(), + ty::TypingEnv::fully_monomorphized(self.tcx), instance, ) else { // Don't ICE on an impossible-to-normalize closure. @@ -1571,13 +1571,13 @@ impl<'v> RootCollector<'_, 'v> { // regions must appear in the argument // listing. let main_ret_ty = self.tcx.normalize_erasing_regions( - ty::TypingEnv::fully_monomorphized(), + ty::TypingEnv::fully_monomorphized(self.tcx), main_ret_ty.no_bound_vars().unwrap(), ); let start_instance = Instance::expect_resolve( self.tcx, - ty::TypingEnv::fully_monomorphized(), + ty::TypingEnv::fully_monomorphized(self.tcx), start_def_id, self.tcx.mk_args(&[main_ret_ty.into()]), DUMMY_SP, @@ -1635,7 +1635,7 @@ fn create_mono_items_for_default_impls<'tcx>( return; } - let typing_env = ty::TypingEnv::fully_monomorphized(); + let typing_env = ty::TypingEnv::fully_monomorphized(tcx); 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) { diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs index 5dbae50c499f9..ac3fd0f4326d0 100644 --- a/compiler/rustc_monomorphize/src/lib.rs +++ b/compiler/rustc_monomorphize/src/lib.rs @@ -34,9 +34,9 @@ fn custom_coerce_unsize_info<'tcx>( [source_ty, target_ty], ); - match tcx - .codegen_select_candidate(ty::TypingEnv::fully_monomorphized().as_query_input(trait_ref)) - { + match tcx.codegen_select_candidate( + ty::TypingEnv::fully_monomorphized(tcx.tcx).as_query_input(trait_ref), + ) { Ok(traits::ImplSource::UserDefined(traits::ImplSourceUserDefinedData { impl_def_id, .. diff --git a/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs b/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs index 0f5bdc8d7683f..e56f4331ad0e7 100644 --- a/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs +++ b/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs @@ -101,7 +101,7 @@ fn wasm_abi_safe<'tcx>(tcx: TyCtxt<'tcx>, arg: &ArgAbi<'tcx, Ty<'tcx>>) -> bool // This matches `unwrap_trivial_aggregate` in the wasm ABI logic. if arg.layout.is_aggregate() { - let cx = LayoutCx::new(tcx, TypingEnv::fully_monomorphized()); + let cx = LayoutCx::new(tcx, TypingEnv::fully_monomorphized(tcx)); if let Some(unit) = arg.layout.homogeneous_aggregate(&cx).ok().and_then(|ha| ha.unit()) { let size = arg.layout.size; // Ensure there's just a single `unit` element in `arg`. @@ -151,7 +151,7 @@ fn do_check_wasm_abi<'tcx>( /// Checks that the ABI of a given instance of a function does not contain vector-passed arguments /// or return values for which the corresponding target feature is not enabled. fn check_instance_abi<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) { - let typing_env = ty::TypingEnv::fully_monomorphized(); + let typing_env = ty::TypingEnv::fully_monomorphized(tcx); let Ok(abi) = tcx.fn_abi_of_instance(typing_env.as_query_input((instance, ty::List::empty()))) else { // An error will be reported during codegen if we cannot determine the ABI of this @@ -181,7 +181,7 @@ fn check_call_site_abi<'tcx>( // we directly handle the soundness of Rust ABIs return; } - let typing_env = ty::TypingEnv::fully_monomorphized(); + let typing_env = ty::TypingEnv::fully_monomorphized(tcx); let callee_abi = match *callee.kind() { ty::FnPtr(..) => { tcx.fn_abi_of_fn_ptr(typing_env.as_query_input((callee.fn_sig(tcx), ty::List::empty()))) @@ -217,7 +217,7 @@ fn check_callees_abi<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>, body: &m let callee_ty = func.ty(body, tcx); let callee_ty = instance.instantiate_mir_and_normalize_erasing_regions( tcx, - ty::TypingEnv::fully_monomorphized(), + ty::TypingEnv::fully_monomorphized(tcx), ty::EarlyBinder::bind(callee_ty), ); check_call_site_abi(tcx, callee_ty, body.source.instance, || { diff --git a/compiler/rustc_monomorphize/src/mono_checks/move_check.rs b/compiler/rustc_monomorphize/src/mono_checks/move_check.rs index 838bfdab1ea59..a0934afbb56e5 100644 --- a/compiler/rustc_monomorphize/src/mono_checks/move_check.rs +++ b/compiler/rustc_monomorphize/src/mono_checks/move_check.rs @@ -60,7 +60,7 @@ impl<'tcx> MoveCheckVisitor<'tcx> { trace!("monomorphize: self.instance={:?}", self.instance); self.instance.instantiate_mir_and_normalize_erasing_regions( self.tcx, - ty::TypingEnv::fully_monomorphized(), + ty::TypingEnv::fully_monomorphized(self.tcx), ty::EarlyBinder::bind(value), ) } @@ -128,7 +128,7 @@ impl<'tcx> MoveCheckVisitor<'tcx> { let ty = operand.ty(self.body, self.tcx); let ty = self.monomorphize(ty); let Ok(layout) = - self.tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)) + self.tcx.layout_of(ty::TypingEnv::fully_monomorphized(self.tcx).as_query_input(ty)) else { return None; }; diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index b1b6f10e0fe2c..87cceb0343960 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -671,7 +671,7 @@ fn characteristic_def_id_of_mono_item<'tcx>( // This is a method within an impl, find out what the self-type is: let impl_self_ty = tcx.instantiate_and_normalize_erasing_regions( instance.args, - ty::TypingEnv::fully_monomorphized(), + ty::TypingEnv::fully_monomorphized(tcx), tcx.type_of(impl_def_id), ); if let Some(def_id) = characteristic_def_id_of_type(impl_self_ty) { diff --git a/compiler/rustc_monomorphize/src/partitioning/autodiff.rs b/compiler/rustc_monomorphize/src/partitioning/autodiff.rs index ebe0b258c1b6a..37ec9dc30ab6f 100644 --- a/compiler/rustc_monomorphize/src/partitioning/autodiff.rs +++ b/compiler/rustc_monomorphize/src/partitioning/autodiff.rs @@ -93,7 +93,7 @@ pub(crate) fn find_autodiff_source_functions<'tcx>( }; debug!("source_id: {:?}", inst.def_id()); - let fn_ty = inst.ty(tcx, ty::TypingEnv::fully_monomorphized()); + let fn_ty = inst.ty(tcx, ty::TypingEnv::fully_monomorphized(tcx)); assert!(fn_ty.is_fn()); adjust_activity_to_abi(tcx, fn_ty, &mut input_activities); let symb = symbol_name_for_instance_in_crate(tcx, inst.clone(), LOCAL_CRATE); diff --git a/compiler/rustc_monomorphize/src/util.rs b/compiler/rustc_monomorphize/src/util.rs index deb4ab433bfe9..be9da7753d396 100644 --- a/compiler/rustc_monomorphize/src/util.rs +++ b/compiler/rustc_monomorphize/src/util.rs @@ -22,7 +22,7 @@ pub(crate) fn dump_closure_profile<'tcx>(tcx: TyCtxt<'tcx>, closure_instance: In let typeck_results = tcx.typeck(closure_def_id); if typeck_results.closure_size_eval.contains_key(&closure_def_id) { - let typing_env = ty::TypingEnv::fully_monomorphized(); + let typing_env = ty::TypingEnv::fully_monomorphized(tcx); let ClosureSizeProfileData { before_feature_tys, after_feature_tys } = typeck_results.closure_size_eval[&closure_def_id]; diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 9161b23428a00..aa08222233aeb 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -2455,7 +2455,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { }; let def_id = hir_id.expect_owner().def_id; - let param_env = ty::ParamEnv::empty(); + let param_env = ty::ParamEnv::empty(tcx); let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis()); let ocx = ObligationCtxt::new_with_diagnostics(&infcx); diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs index d56ca9c245386..c1bcb4a8482a9 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs @@ -133,7 +133,7 @@ fn encode_const<'tcx>( match cv.ty.kind() { ty::Int(ity) => { let bits = cv - .try_to_bits(tcx, ty::TypingEnv::fully_monomorphized()) + .try_to_bits(tcx, ty::TypingEnv::fully_monomorphized(tcx)) .expect("expected monomorphic const in cfi"); let val = Integer::from_int_ty(&tcx, *ity).size().sign_extend(bits) as i128; if val < 0 { @@ -143,7 +143,7 @@ fn encode_const<'tcx>( } ty::Uint(_) => { let val = cv - .try_to_bits(tcx, ty::TypingEnv::fully_monomorphized()) + .try_to_bits(tcx, ty::TypingEnv::fully_monomorphized(tcx)) .expect("expected monomorphic const in cfi"); let _ = write!(s, "{val}"); } diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/mod.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/mod.rs index 562e288afaaf0..66f2f490b23b8 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/mod.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/mod.rs @@ -118,7 +118,7 @@ pub fn typeid_for_instance<'tcx>( let instance = transform_instance(tcx, instance, transform_ty_options); let fn_abi = tcx .fn_abi_of_instance( - ty::TypingEnv::fully_monomorphized().as_query_input((instance, ty::List::empty())), + ty::TypingEnv::fully_monomorphized(tcx).as_query_input((instance, ty::List::empty())), ) .unwrap_or_else(|error| { bug!("typeid_for_instance: couldn't get fn_abi of instance {instance:?}: {error:?}") diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs index 129a32c6edd81..c21aea981c87a 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs @@ -153,7 +153,7 @@ impl<'tcx> TypeFolder> for TransformTy<'tcx> { }); if let Some(field) = field { let ty0 = self.tcx.normalize_erasing_regions( - ty::TypingEnv::fully_monomorphized(), + ty::TypingEnv::fully_monomorphized(self.tcx), field.ty(self.tcx, args), ); // Generalize any repr(transparent) user-defined type that is either a @@ -216,7 +216,7 @@ impl<'tcx> TypeFolder> for TransformTy<'tcx> { } ty::Alias(..) => self.fold_ty( - self.tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), t), + self.tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(self.tcx), t), ), ty::Bound(..) | ty::Error(..) | ty::Infer(..) | ty::Param(..) | ty::Placeholder(..) => { @@ -247,7 +247,7 @@ fn trait_object_ty<'tcx>(tcx: TyCtxt<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tc let alias_ty = ty::AliasTy::new_from_args(tcx, assoc_ty.def_id, super_trait_ref.args); let resolved = tcx.normalize_erasing_regions( - ty::TypingEnv::fully_monomorphized(), + ty::TypingEnv::fully_monomorphized(tcx), alias_ty.to_ty(tcx), ); debug!("Resolved {:?} -> {resolved}", alias_ty.to_ty(tcx)); @@ -382,7 +382,7 @@ pub(crate) fn transform_instance<'tcx>( // implementation will not. We need to walk back to the more general trait method let trait_ref = tcx.instantiate_and_normalize_erasing_regions( instance.args, - ty::TypingEnv::fully_monomorphized(), + ty::TypingEnv::fully_monomorphized(tcx), trait_ref, ); let invoke_ty = trait_object_ty(tcx, ty::Binder::dummy(trait_ref)); @@ -403,7 +403,7 @@ pub(crate) fn transform_instance<'tcx>( } else if tcx.is_closure_like(instance.def_id()) { // We're either a closure or a coroutine. Our goal is to find the trait we're defined on, // instantiate it, and take the type of its only method as our own. - let closure_ty = instance.ty(tcx, ty::TypingEnv::fully_monomorphized()); + let closure_ty = instance.ty(tcx, ty::TypingEnv::fully_monomorphized(tcx)); let (trait_id, inputs) = match closure_ty.kind() { ty::Closure(..) => { let closure_args = instance.args.as_closure(); diff --git a/compiler/rustc_smir/src/rustc_smir/alloc.rs b/compiler/rustc_smir/src/rustc_smir/alloc.rs index 9cb89634c52e5..cdaa2fe6de549 100644 --- a/compiler/rustc_smir/src/rustc_smir/alloc.rs +++ b/compiler/rustc_smir/src/rustc_smir/alloc.rs @@ -39,7 +39,7 @@ pub(crate) fn try_new_allocation<'tcx>( ) -> Result { let layout = tables .tcx - .layout_of(rustc_middle::ty::TypingEnv::fully_monomorphized().as_query_input(ty)) + .layout_of(rustc_middle::ty::TypingEnv::fully_monomorphized(tables.tcx).as_query_input(ty)) .map_err(|e| e.stable(tables))?; Ok(match const_value { ConstValue::Scalar(scalar) => { diff --git a/compiler/rustc_smir/src/rustc_smir/builder.rs b/compiler/rustc_smir/src/rustc_smir/builder.rs index 64763b71d303d..6447fff9032e5 100644 --- a/compiler/rustc_smir/src/rustc_smir/builder.rs +++ b/compiler/rustc_smir/src/rustc_smir/builder.rs @@ -41,7 +41,7 @@ impl<'tcx> BodyBuilder<'tcx> { { let mut mono_body = self.instance.instantiate_mir_and_normalize_erasing_regions( tables.tcx, - ty::TypingEnv::fully_monomorphized(), + ty::TypingEnv::fully_monomorphized(tables.tcx), ty::EarlyBinder::bind(body), ); self.visit_body(&mut mono_body); @@ -61,7 +61,11 @@ impl<'tcx> MutVisitor<'tcx> for BodyBuilder<'tcx> { location: mir::Location, ) { let const_ = constant.const_; - let val = match const_.eval(self.tcx, ty::TypingEnv::fully_monomorphized(), constant.span) { + let val = match const_.eval( + self.tcx, + ty::TypingEnv::fully_monomorphized(self.tcx), + constant.span, + ) { Ok(v) => v, Err(mir::interpret::ErrorHandled::Reported(..)) => return, Err(mir::interpret::ErrorHandled::TooGeneric(..)) => { diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs index 240f6f7fe45a1..1cfbe8b28b2ff 100644 --- a/compiler/rustc_smir/src/rustc_smir/context.rs +++ b/compiler/rustc_smir/src/rustc_smir/context.rs @@ -419,7 +419,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> { let tcx = tables.tcx; let mir_const = cnst.internal(&mut *tables, tcx); mir_const - .try_eval_target_usize(tables.tcx, ty::TypingEnv::fully_monomorphized()) + .try_eval_target_usize(tables.tcx, ty::TypingEnv::fully_monomorphized(tables.tcx)) .ok_or_else(|| Error::new(format!("Const `{cnst:?}` cannot be encoded as u64"))) } fn eval_target_usize_ty(&self, cnst: &TyConst) -> Result { @@ -437,7 +437,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> { let ty_internal = ty.internal(&mut *tables, tcx); let size = tables .tcx - .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty_internal)) + .layout_of(ty::TypingEnv::fully_monomorphized(tcx).as_query_input(ty_internal)) .map_err(|err| { Error::new(format!( "Cannot create a zero-sized constant for type `{ty_internal}`: {err}" @@ -478,7 +478,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> { let ty = ty::Ty::new_uint(tcx, uint_ty.internal(&mut *tables, tcx)); let size = tables .tcx - .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)) + .layout_of(ty::TypingEnv::fully_monomorphized(tcx).as_query_input(ty)) .unwrap() .size; let scalar = ScalarInt::try_from_uint(value, size).ok_or_else(|| { @@ -497,7 +497,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> { let ty = ty::Ty::new_uint(tcx, uint_ty.internal(&mut *tables, tcx)); let size = tables .tcx - .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)) + .layout_of(ty::TypingEnv::fully_monomorphized(tcx).as_query_input(ty)) .unwrap() .size; @@ -538,7 +538,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> { .tcx .instantiate_and_normalize_erasing_regions( args, - ty::TypingEnv::fully_monomorphized(), + ty::TypingEnv::fully_monomorphized(tcx), def_ty, ) .stable(&mut *tables) @@ -590,7 +590,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> { let mut tables = self.0.borrow_mut(); let instance = tables.instances[def]; assert!(!instance.has_non_region_param(), "{instance:?} needs further instantiation"); - instance.ty(tables.tcx, ty::TypingEnv::fully_monomorphized()).stable(&mut *tables) + instance.ty(tables.tcx, ty::TypingEnv::fully_monomorphized(tables.tcx)).stable(&mut *tables) } fn instance_args(&self, def: InstanceDef) -> GenericArgs { @@ -661,7 +661,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> { let args_ref = args.internal(&mut *tables, tcx); match Instance::try_resolve( tables.tcx, - ty::TypingEnv::fully_monomorphized(), + ty::TypingEnv::fully_monomorphized(tcx), def_id, args_ref, ) { @@ -689,7 +689,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> { let args_ref = args.internal(&mut *tables, tcx); Instance::resolve_for_fn_ptr( tables.tcx, - ty::TypingEnv::fully_monomorphized(), + ty::TypingEnv::fully_monomorphized(tcx), def_id, args_ref, ) @@ -718,7 +718,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> { let instance = tables.instances[def]; let tcx = tables.tcx; let result = tcx.const_eval_instance( - ty::TypingEnv::fully_monomorphized(), + ty::TypingEnv::fully_monomorphized(tcx), instance, tcx.def_span(instance.def_id()), ); @@ -873,7 +873,7 @@ impl<'tcx> LayoutOfHelpers<'tcx> for Tables<'tcx> { impl<'tcx> HasTypingEnv<'tcx> for Tables<'tcx> { fn typing_env(&self) -> ty::TypingEnv<'tcx> { - ty::TypingEnv::fully_monomorphized() + ty::TypingEnv::fully_monomorphized(self.tcx) } } diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs index 2802e8918073f..020d849390255 100644 --- a/compiler/rustc_symbol_mangling/src/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs @@ -424,7 +424,7 @@ impl<'tcx> Printer<'tcx> for SymbolPrinter<'tcx> { polymorphic instance: {impl_def_id:?} {args:?}" ); ( - ty::TypingEnv::fully_monomorphized(), + ty::TypingEnv::fully_monomorphized(self.tcx), self_ty.instantiate(self.tcx, args), impl_trait_ref.map(|impl_trait_ref| impl_trait_ref.instantiate(self.tcx, args)), ) diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 8edfd16016c35..47fe5c7d9bbdd 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -29,7 +29,8 @@ pub(super) fn mangle<'tcx>( ) -> String { let def_id = instance.def_id(); // FIXME(eddyb) this should ideally not be needed. - let args = tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), instance.args); + let args = + tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(tcx), instance.args); let prefix = "_R"; let mut cx: SymbolMangler<'_> = SymbolMangler { @@ -317,7 +318,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> { polymorphic instance: {impl_def_id:?} {args:?}" ); ( - ty::TypingEnv::fully_monomorphized(), + ty::TypingEnv::fully_monomorphized(self.tcx), self_ty.instantiate(self.tcx, args), impl_trait_ref.map(|impl_trait_ref| impl_trait_ref.instantiate(self.tcx, args)), ) @@ -674,7 +675,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> { ct_ty.print(self)?; let mut bits = cv - .try_to_bits(self.tcx, ty::TypingEnv::fully_monomorphized()) + .try_to_bits(self.tcx, ty::TypingEnv::fully_monomorphized(self.tcx)) .expect("expected const to be monomorphic"); // Negative integer values are mangled using `n` as a "sign prefix". diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 912da632ef7c1..064b0849d6917 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -320,11 +320,13 @@ impl<'tcx> AutoTraitFinder<'tcx> { .chain(user_computed_preds.iter().cloned()); let normalized_preds = elaborate(tcx, computed_preds); new_env = ty::ParamEnv::new( + tcx, tcx.mk_clauses_from_iter(normalized_preds.filter_map(|p| p.as_clause())), ); } let final_user_env = ty::ParamEnv::new( + tcx, tcx.mk_clauses_from_iter(user_computed_preds.into_iter().filter_map(|p| p.as_clause())), ); debug!( diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 93c7dae9c5be6..457bd08979fb1 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -216,7 +216,7 @@ fn overlap<'tcx>( // types into scope; instead, we replace the generic types with // fresh type variables, and hence we do our evaluations in an // empty environment. - let param_env = ty::ParamEnv::empty(); + let param_env = ty::ParamEnv::empty(tcx); let impl1_header = fresh_impl_header_normalized(selcx.infcx, param_env, impl1_def_id); let impl2_header = fresh_impl_header_normalized(selcx.infcx, param_env, impl2_def_id); @@ -488,8 +488,10 @@ fn plug_infer_with_placeholders<'tcx>( fn visit_ty(&mut self, ty: Ty<'tcx>) { let ty = self.infcx.shallow_resolve(ty); if ty.is_ty_var() { - let Ok(InferOk { value: (), obligations }) = - self.infcx.at(&ObligationCause::dummy(), ty::ParamEnv::empty()).eq( + let Ok(InferOk { value: (), obligations }) = self + .infcx + .at(&ObligationCause::dummy(), ty::ParamEnv::empty(self.infcx.tcx)) + .eq( // Comparing against a type variable never registers hidden types anyway DefineOpaqueTypes::Yes, ty, @@ -516,8 +518,10 @@ fn plug_infer_with_placeholders<'tcx>( fn visit_const(&mut self, ct: ty::Const<'tcx>) { let ct = self.infcx.shallow_resolve_const(ct); if ct.is_ct_infer() { - let Ok(InferOk { value: (), obligations }) = - self.infcx.at(&ObligationCause::dummy(), ty::ParamEnv::empty()).eq( + let Ok(InferOk { value: (), obligations }) = self + .infcx + .at(&ObligationCause::dummy(), ty::ParamEnv::empty(self.infcx.tcx)) + .eq( // The types of the constants are the same, so there is no hidden type // registration happening anyway. DefineOpaqueTypes::Yes, @@ -545,8 +549,10 @@ fn plug_infer_with_placeholders<'tcx>( .unwrap_region_constraints() .opportunistic_resolve_var(self.infcx.tcx, vid); if r.is_var() { - let Ok(InferOk { value: (), obligations }) = - self.infcx.at(&ObligationCause::dummy(), ty::ParamEnv::empty()).eq( + let Ok(InferOk { value: (), obligations }) = self + .infcx + .at(&ObligationCause::dummy(), ty::ParamEnv::empty(self.infcx.tcx)) + .eq( // Lifetimes don't contain opaque types (or any types for that matter). DefineOpaqueTypes::Yes, r, diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs index bf9fcb0915a56..61331391823db 100644 --- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs +++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs @@ -612,7 +612,7 @@ fn receiver_is_dispatchable<'tcx>( normalize_param_env_or_error( tcx, - ty::ParamEnv::new(tcx.mk_clauses(&predicates)), + ty::ParamEnv::new(tcx, tcx.mk_clauses(&predicates)), ObligationCause::dummy_with_span(tcx.def_span(method.def_id)), ) }; diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 3831ff6d57e16..9d59b435a0209 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -367,7 +367,7 @@ pub fn normalize_param_env_or_error<'tcx>( && self.0.def_kind(uv.def) == DefKind::AnonConst { let infcx = self.0.infer_ctxt().build(TypingMode::non_body_analysis()); - let c = evaluate_const(&infcx, c, ty::ParamEnv::empty()); + let c = evaluate_const(&infcx, c, ty::ParamEnv::empty(infcx.tcx)); // We should never wind up with any `infcx` local state when normalizing anon consts // under min const generics. assert!(!c.has_infer() && !c.has_placeholders()); @@ -414,7 +414,7 @@ pub fn normalize_param_env_or_error<'tcx>( debug!("normalize_param_env_or_error: elaborated-predicates={:?}", predicates); - let elaborated_env = ty::ParamEnv::new(tcx.mk_clauses(&predicates)); + let elaborated_env = ty::ParamEnv::new(tcx, tcx.mk_clauses(&predicates)); if !elaborated_env.has_aliases() { return elaborated_env; } @@ -461,7 +461,7 @@ pub fn normalize_param_env_or_error<'tcx>( // here. I believe they should not matter, because we are ignoring TypeOutlives param-env // predicates here anyway. Keeping them here anyway because it seems safer. let outlives_env = non_outlives_predicates.iter().chain(&outlives_predicates).cloned(); - let outlives_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(outlives_env)); + let outlives_env = ty::ParamEnv::new(tcx, tcx.mk_clauses_from_iter(outlives_env)); let Ok(outlives_predicates) = do_normalize_predicates(tcx, cause, outlives_env, outlives_predicates) else { @@ -474,7 +474,7 @@ pub fn normalize_param_env_or_error<'tcx>( let mut predicates = non_outlives_predicates; predicates.extend(outlives_predicates); debug!("normalize_param_env_or_error: final predicates={:?}", predicates); - ty::ParamEnv::new(tcx.mk_clauses(&predicates)) + ty::ParamEnv::new(tcx, tcx.mk_clauses(&predicates)) } #[derive(Debug)] @@ -702,7 +702,7 @@ fn replace_param_and_infer_args_with_placeholder<'tcx>( pub fn impossible_predicates<'tcx>(tcx: TyCtxt<'tcx>, predicates: Vec>) -> bool { debug!("impossible_predicates(predicates={:?})", predicates); let (infcx, param_env) = - tcx.infer_ctxt().build_with_typing_env(ty::TypingEnv::fully_monomorphized()); + tcx.infer_ctxt().build_with_typing_env(ty::TypingEnv::fully_monomorphized(tcx)); let ocx = ObligationCtxt::new(&infcx); let predicates = ocx.normalize(&ObligationCause::dummy(), param_env, predicates); for predicate in predicates { @@ -804,7 +804,7 @@ fn is_impossible_associated_item( .ignoring_regions() .with_next_trait_solver(true) .build(TypingMode::Coherence); - let param_env = ty::ParamEnv::empty(); + let param_env = ty::ParamEnv::empty(tcx); let fresh_args = infcx.fresh_args_for_item(tcx.def_span(impl_def_id), impl_def_id); let impl_trait_ref = tcx diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index b2f8571a8ea30..79db3ddc2eee0 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1007,7 +1007,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // depend on its particular value in order to work, so we can clear // out the param env and get better caching. debug!("in global"); - obligation.param_env = ty::ParamEnv::empty(); + obligation.param_env = ty::ParamEnv::empty(self.infcx.tcx); } let stack = self.push_stack(previous_stack, &obligation); diff --git a/compiler/rustc_trait_selection/src/traits/vtable.rs b/compiler/rustc_trait_selection/src/traits/vtable.rs index 165174c0bcc15..f6ad225505046 100644 --- a/compiler/rustc_trait_selection/src/traits/vtable.rs +++ b/compiler/rustc_trait_selection/src/traits/vtable.rs @@ -129,7 +129,7 @@ fn prepare_vtable_segments_inner<'tcx, T>( }) .map(move |pred| { tcx.normalize_erasing_late_bound_regions( - ty::TypingEnv::fully_monomorphized(), + ty::TypingEnv::fully_monomorphized(tcx), pred, ) .trait_ref @@ -227,7 +227,7 @@ fn vtable_entries<'tcx>( ) -> &'tcx [VtblEntry<'tcx>] { debug_assert!(!trait_ref.has_non_region_infer() && !trait_ref.has_non_region_param()); debug_assert_eq!( - tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), trait_ref), + tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(tcx), trait_ref), trait_ref, "vtable trait ref should be normalized" ); @@ -254,7 +254,7 @@ fn vtable_entries<'tcx>( // The method may have some early-bound lifetimes; add regions for those. // FIXME: Is this normalize needed? let args = tcx.normalize_erasing_regions( - ty::TypingEnv::fully_monomorphized(), + ty::TypingEnv::fully_monomorphized(tcx), GenericArgs::for_item(tcx, def_id, |param, _| match param.kind { GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(), GenericParamDefKind::Type { .. } @@ -279,7 +279,7 @@ fn vtable_entries<'tcx>( let instance = ty::Instance::expect_resolve_for_vtable( tcx, - ty::TypingEnv::fully_monomorphized(), + ty::TypingEnv::fully_monomorphized(tcx), def_id, args, DUMMY_SP, @@ -309,7 +309,7 @@ fn vtable_entries<'tcx>( pub(crate) fn first_method_vtable_slot<'tcx>(tcx: TyCtxt<'tcx>, key: ty::TraitRef<'tcx>) -> usize { debug_assert!(!key.has_non_region_infer() && !key.has_non_region_param()); debug_assert_eq!( - tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), key), + tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(tcx), key), key, "vtable trait ref should be normalized" ); @@ -373,7 +373,7 @@ pub(crate) fn supertrait_vtable_slot<'tcx>( ) -> Option { debug_assert!(!key.has_non_region_infer() && !key.has_non_region_param()); debug_assert_eq!( - tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), key), + tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(tcx), key), key, "upcasting trait refs should be normalized" ); diff --git a/compiler/rustc_transmute/src/maybe_transmutable/mod.rs b/compiler/rustc_transmute/src/maybe_transmutable/mod.rs index 63fabc9c83d93..76d43bcc86fe1 100644 --- a/compiler/rustc_transmute/src/maybe_transmutable/mod.rs +++ b/compiler/rustc_transmute/src/maybe_transmutable/mod.rs @@ -43,7 +43,7 @@ mod rustc { pub(crate) fn answer(self) -> Answer< as QueryContext>::Ref> { let Self { src, dst, assume, context } = self; - let layout_cx = LayoutCx::new(context, TypingEnv::fully_monomorphized()); + let layout_cx = LayoutCx::new(context, TypingEnv::fully_monomorphized(context)); // Convert `src` and `dst` from their rustc representations, to `Tree`-based // representations. diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index 3d4ab33240af2..4603a1e467410 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -741,6 +741,8 @@ fn make_thin_self_ptr<'tcx>( // NOTE(eddyb) using an empty `ParamEnv`, and `unwrap`-ing the `Result` // should always work because the type is always `*mut ()`. - ..tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(unit_ptr_ty)).unwrap() + ..tcx + .layout_of(ty::TypingEnv::fully_monomorphized(tcx).as_query_input(unit_ptr_ty)) + .unwrap() } } diff --git a/compiler/rustc_ty_utils/src/structural_match.rs b/compiler/rustc_ty_utils/src/structural_match.rs index 0b4efab1d9c44..35e4e40323456 100644 --- a/compiler/rustc_ty_utils/src/structural_match.rs +++ b/compiler/rustc_ty_utils/src/structural_match.rs @@ -18,7 +18,12 @@ fn has_structural_eq_impl<'tcx>(tcx: TyCtxt<'tcx>, adt_ty: Ty<'tcx>) -> bool { // require `#[derive(PartialEq)]` let structural_peq_def_id = infcx.tcx.require_lang_item(LangItem::StructuralPeq, Some(cause.span)); - ocx.register_bound(cause.clone(), ty::ParamEnv::empty(), adt_ty, structural_peq_def_id); + ocx.register_bound( + cause.clone(), + ty::ParamEnv::empty(infcx.tcx), + adt_ty, + structural_peq_def_id, + ); // We deliberately skip *reporting* fulfillment errors (via // `report_fulfillment_errors`), for two reasons: diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 9dc4f11e456e2..2025b060780f4 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -163,7 +163,7 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { let local_did = def_id.as_local(); - let unnormalized_env = ty::ParamEnv::new(tcx.mk_clauses(&predicates)); + let unnormalized_env = ty::ParamEnv::new(tcx, tcx.mk_clauses(&predicates)); let body_id = local_did.unwrap_or(CRATE_DEF_ID); let cause = traits::ObligationCause::misc(tcx.def_span(def_id), body_id); diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index 89245fee51551..a286352cdbab5 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -41,7 +41,7 @@ pub(crate) fn synthesize_blanket_impls( let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis()); let args = infcx.fresh_args_for_item(DUMMY_SP, item_def_id); let impl_ty = ty.instantiate(tcx, args); - let param_env = ty::ParamEnv::empty(); + let param_env = ty::ParamEnv::empty(tcx); let impl_args = infcx.fresh_args_for_item(DUMMY_SP, impl_def_id); let impl_trait_ref = trait_ref.instantiate(tcx, impl_args); diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index afcca81a485ff..55bd994473003 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -441,7 +441,7 @@ fn print_const_with_custom_print_scalar<'tcx>( (mir::Const::Val(mir::ConstValue::Scalar(int), _), ty::Int(i)) => { let ty = ct.ty(); let size = tcx - .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)) + .layout_of(ty::TypingEnv::fully_monomorphized(tcx).as_query_input(ty)) .unwrap() .size; let sign_extended_data = int.assert_scalar_int().to_int(size); diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index c47e42670c909..6beec0417fb03 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -361,7 +361,7 @@ pub(crate) fn run_global_ctxt( let mut ctxt = DocContext { tcx, - param_env: ParamEnv::empty(), + param_env: ParamEnv::empty(tcx), external_traits: Default::default(), active_extern_traits: Default::default(), args: Default::default(), diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs index c85aca8d04efd..4842340d7ccbb 100644 --- a/src/tools/clippy/clippy_lints/src/derive.rs +++ b/src/tools/clippy/clippy_lints/src/derive.rs @@ -501,15 +501,18 @@ fn typing_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId) -> } } - let param_env = ParamEnv::new(tcx.mk_clauses_from_iter(ty_predicates.iter().map(|&(p, _)| p).chain( - params.iter().filter(|&&(_, needs_eq)| needs_eq).map(|&(param, _)| { - ClauseKind::Trait(TraitPredicate { - trait_ref: ty::TraitRef::new(tcx, eq_trait_id, [tcx.mk_param_from_def(param)]), - polarity: ty::PredicatePolarity::Positive, - }) - .upcast(tcx) - }), - ))); + let param_env = ParamEnv::new( + tcx, + tcx.mk_clauses_from_iter(ty_predicates.iter().map(|&(p, _)| p).chain( + params.iter().filter(|&&(_, needs_eq)| needs_eq).map(|&(param, _)| { + ClauseKind::Trait(TraitPredicate { + trait_ref: ty::TraitRef::new(tcx, eq_trait_id, [tcx.mk_param_from_def(param)]), + polarity: ty::PredicatePolarity::Positive, + }) + .upcast(tcx) + }), + )), + ); ty::TypingEnv { typing_mode: ty::TypingMode::non_body_analysis(), param_env, diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs index ed13f670a90e3..1b87ef12ddb2c 100644 --- a/src/tools/miri/src/eval.rs +++ b/src/tools/miri/src/eval.rs @@ -281,7 +281,7 @@ pub fn create_ecx<'tcx>( entry_type: MiriEntryFnType, config: &MiriConfig, ) -> InterpResult<'tcx, InterpCx<'tcx, MiriMachine<'tcx>>> { - let typing_env = ty::TypingEnv::fully_monomorphized(); + let typing_env = ty::TypingEnv::fully_monomorphized(tcx); let layout_cx = LayoutCx::new(tcx, typing_env); let mut ecx = InterpCx::new(tcx, rustc_span::DUMMY_SP, typing_env, MiriMachine::new(config, layout_cx)); diff --git a/tests/ui/type-alias-impl-trait/in-where-clause.stderr b/tests/ui/type-alias-impl-trait/in-where-clause.stderr index e886701ee6ecd..275544f2211b3 100644 --- a/tests/ui/type-alias-impl-trait/in-where-clause.stderr +++ b/tests/ui/type-alias-impl-trait/in-where-clause.stderr @@ -62,7 +62,7 @@ LL | / fn foo() -> Bar LL | | where LL | | Bar: Send, | |______________^ - = note: ...which requires revealing opaque types in `ParamEnv { caller_bounds: [Binder { value: TraitPredicate(, polarity:Positive), bound_vars: [] }] }`... + = note: ...which requires revealing opaque types in `ParamEnv(ParamEnvInner { caller_bounds: [Binder { value: TraitPredicate(, polarity:Positive), bound_vars: [] }] })`... note: ...which requires computing type of `Bar::{opaque#0}`... --> $DIR/in-where-clause.rs:5:12 | From 99aca75ea7e18204626890359ed5d127dfd7825a Mon Sep 17 00:00:00 2001 From: David Wood Date: Wed, 9 Apr 2025 09:51:06 +0000 Subject: [PATCH 3/3] middle: split `caller_bounds` into multiple fields Instead of filtering on `caller_bounds` at every use, instead filter them once when creating the `ParamEnv`. This will avoid unnecessary iteration over irrelevant bounds and improve performance. --- .../src/check/compare_impl_item.rs | 10 +- .../src/check/compare_impl_item/refine.rs | 2 +- .../rustc_hir_analysis/src/check/wfcheck.rs | 4 +- compiler/rustc_middle/src/ty/codec.rs | 29 +++- compiler/rustc_middle/src/ty/mod.rs | 134 ++++++++++++++---- .../src/traits/auto_trait.rs | 9 +- .../src/traits/dyn_compatibility.rs | 2 +- .../rustc_trait_selection/src/traits/mod.rs | 6 +- compiler/rustc_ty_utils/src/ty.rs | 2 +- src/tools/clippy/clippy_lints/src/derive.rs | 6 +- .../in-where-clause.stderr | 2 +- 11 files changed, 149 insertions(+), 57 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index c330eb08182cc..c0fcf419e964d 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -233,7 +233,7 @@ fn compare_method_predicate_entailment<'tcx>( } let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_def_id); - let param_env = ty::ParamEnv::new(tcx, tcx.mk_clauses(&hybrid_preds)); + let param_env = ty::ParamEnv::from_iter(tcx, hybrid_preds.iter().copied()); let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause); debug!(?param_env); @@ -523,7 +523,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( .into_iter() .chain(tcx.predicates_of(trait_m.def_id).instantiate_own(tcx, trait_to_impl_args)) .map(|(clause, _)| clause); - let param_env = ty::ParamEnv::new(tcx, tcx.mk_clauses_from_iter(hybrid_preds)); + let param_env = ty::ParamEnv::from_iter(tcx, hybrid_preds); let param_env = traits::normalize_param_env_or_error( tcx, param_env, @@ -1837,7 +1837,7 @@ fn compare_const_predicate_entailment<'tcx>( .map(|(predicate, _)| predicate), ); - let param_env = ty::ParamEnv::new(tcx, tcx.mk_clauses(&hybrid_preds)); + let param_env = ty::ParamEnv::from_iter(tcx, hybrid_preds.iter().copied()); let param_env = traits::normalize_param_env_or_error( tcx, param_env, @@ -1988,7 +1988,7 @@ fn compare_type_predicate_entailment<'tcx>( ); } - let param_env = ty::ParamEnv::new(tcx, tcx.mk_clauses(&hybrid_preds)); + let param_env = ty::ParamEnv::from_iter(tcx, hybrid_preds.iter().copied()); let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause); debug!(?param_env); @@ -2336,7 +2336,7 @@ fn param_env_with_gat_bounds<'tcx>( }; } - ty::ParamEnv::new(tcx, tcx.mk_clauses(&predicates)) + ty::ParamEnv::from_iter(tcx, predicates.iter().copied()) } /// Manually check here that `async fn foo()` wasn't matched against `fn foo()`, diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs index 393e593dc2ff1..732f7345727f0 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs @@ -132,7 +132,7 @@ pub(crate) fn check_refining_return_position_impl_trait_in_trait<'tcx>( .into_iter() .chain(tcx.predicates_of(trait_m.def_id).instantiate_own(tcx, trait_m_to_impl_m_args)) .map(|(clause, _)| clause); - let param_env = ty::ParamEnv::new(tcx, tcx.mk_clauses_from_iter(hybrid_preds)); + let param_env = ty::ParamEnv::from_iter(tcx, hybrid_preds); let param_env = normalize_param_env_or_error(tcx, param_env, ObligationCause::dummy()); let ref infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis()); diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index a919568247153..361656c7df2be 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -586,11 +586,9 @@ fn augment_param_env<'tcx>( return param_env; } - let bounds = - tcx.mk_clauses_from_iter(param_env.all_clauses().chain(new_predicates.iter().cloned())); // FIXME(compiler-errors): Perhaps there is a case where we need to normalize this // i.e. traits::normalize_param_env_or_error - ty::ParamEnv::new(tcx, bounds) + ty::ParamEnv::from_iter(tcx, param_env.all_clauses().chain(new_predicates.iter().cloned())) } /// We use the following trait as an example throughout this function. diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index 4997e15c0b06f..b683fd94465d3 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -209,7 +209,14 @@ impl<'tcx, E: TyEncoder<'tcx>> Encodable for CtfeProvenance { impl<'tcx, E: TyEncoder<'tcx>> Encodable for ty::ParamEnvInner<'tcx> { fn encode(&self, e: &mut E) { - self.caller_bounds.encode(e); + self.trait_clauses.encode(e); + self.region_outlives_clauses.encode(e); + self.type_outlives_clauses.encode(e); + self.projection_clauses.encode(e); + self.const_arg_has_type_clauses.encode(e); + self.well_formed_clauses.encode(e); + self.const_evaluatable_clauses.encode(e); + self.host_effect_clauses.encode(e); } } @@ -340,8 +347,24 @@ impl<'tcx, D: TyDecoder<'tcx>> Decodable for ty::SymbolName<'tcx> { impl<'tcx, D: TyDecoder<'tcx>> Decodable for ty::ParamEnvInner<'tcx> { fn decode(d: &mut D) -> Self { - let caller_bounds = Decodable::decode(d); - ty::ParamEnvInner { caller_bounds } + let trait_clauses = Decodable::decode(d); + let region_outlives_clauses = Decodable::decode(d); + let type_outlives_clauses = Decodable::decode(d); + let projection_clauses = Decodable::decode(d); + let const_arg_has_type_clauses = Decodable::decode(d); + let well_formed_clauses = Decodable::decode(d); + let const_evaluatable_clauses = Decodable::decode(d); + let host_effect_clauses = Decodable::decode(d); + ty::ParamEnvInner { + trait_clauses, + region_outlives_clauses, + type_outlives_clauses, + projection_clauses, + const_arg_has_type_clauses, + well_formed_clauses, + const_evaluatable_clauses, + host_effect_clauses, + } } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 262ec8fd3f23a..2fcb4604cd28f 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -971,18 +971,39 @@ impl<'tcx> rustc_type_ir::Flags for Clauses<'tcx> { #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] #[derive(HashStable, TypeVisitable, TypeFoldable)] pub struct ParamEnvInner<'tcx> { - /// Caller bounds are `Obligation`s that the caller must satisfy. This is - /// basically the set of bounds on the in-scope type parameters, translated - /// into `Obligation`s, and elaborated and normalized. - /// - /// Use the `caller_bounds()` method to access. - caller_bounds: Clauses<'tcx>, -} - -/// When interacting with the type system we must provide information about the -/// environment. `ParamEnv` is the type that represents this information. See the + /// Corresponds to `where Foo: Bar`. `Foo` here would be + /// the `Self` type of the trait reference and `A`, `B`, and `C` + /// would be the type parameters. + trait_clauses: Clauses<'tcx>, + /// `where 'a: 'r` + region_outlives_clauses: Clauses<'tcx>, + /// `where T: 'r` + type_outlives_clauses: Clauses<'tcx>, + /// `where ::Name == X`, approximately. + /// See the `ProjectionPredicate` struct for details. + projection_clauses: Clauses<'tcx>, + /// Ensures that a const generic argument to a parameter `const N: u8` + /// is of type `u8`. + const_arg_has_type_clauses: Clauses<'tcx>, + /// No syntax: `T` well-formed. + well_formed_clauses: Clauses<'tcx>, + /// Constant initializer must evaluate successfully. + const_evaluatable_clauses: Clauses<'tcx>, + /// Enforces the constness of the predicate we're calling. Like a projection + /// goal from a where clause, it's always going to be paired with a + /// corresponding trait clause; this just enforces the *constness* of that + /// implementation. + host_effect_clauses: Clauses<'tcx>, +} + +/// When interacting with the type system we must provide information about the environment. +/// `ParamEnv` is the type that represents this information. See the /// [dev guide chapter][param_env_guide] for more information. /// +/// Contains various kinds of caller bounds - `Obligation`s that the caller must satisfy. This is +/// basically the set of bounds on the in-scope type parameters, translated into `Obligation`s, +/// and elaborated and normalized. +/// /// [param_env_guide]: https://rustc-dev-guide.rust-lang.org/typing_parameter_envs.html #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] #[derive(HashStable)] @@ -997,64 +1018,117 @@ impl<'tcx> ParamEnv<'tcx> { /// [param_env_guide]: https://rustc-dev-guide.rust-lang.org/typing_parameter_envs.html #[inline] pub fn empty(tcx: TyCtxt<'tcx>) -> Self { - tcx.mk_param_env(ParamEnvInner { caller_bounds: ListWithCachedTypeInfo::empty() }) + tcx.mk_param_env(ParamEnvInner { + trait_clauses: ListWithCachedTypeInfo::empty(), + region_outlives_clauses: ListWithCachedTypeInfo::empty(), + type_outlives_clauses: ListWithCachedTypeInfo::empty(), + projection_clauses: ListWithCachedTypeInfo::empty(), + const_arg_has_type_clauses: ListWithCachedTypeInfo::empty(), + well_formed_clauses: ListWithCachedTypeInfo::empty(), + const_evaluatable_clauses: ListWithCachedTypeInfo::empty(), + host_effect_clauses: ListWithCachedTypeInfo::empty(), + }) } #[inline] pub fn all_clauses(self) -> impl Iterator> { - self.0.0.caller_bounds.iter() + let trait_clauses = self.0.0.trait_clauses.iter(); + let region_outlives_clauses = self.0.0.region_outlives_clauses.iter(); + let type_outlives_clauses = self.0.0.type_outlives_clauses.iter(); + let projection_clauses = self.0.0.projection_clauses.iter(); + let const_arg_has_type_clauses = self.0.0.const_arg_has_type_clauses.iter(); + let well_formed_clauses = self.0.0.well_formed_clauses.iter(); + let const_evaluatable_clauses = self.0.0.const_evaluatable_clauses.iter(); + let host_effect_clauses = self.0.0.host_effect_clauses.iter(); + + trait_clauses.chain(region_outlives_clauses.chain(type_outlives_clauses.chain( + projection_clauses.chain(const_arg_has_type_clauses.chain( + well_formed_clauses.chain(const_evaluatable_clauses.chain(host_effect_clauses)), + )), + ))) } #[inline] pub fn trait_clauses(self) -> impl Iterator> { - self.0.0.caller_bounds.iter().filter_map(|c| c.as_trait_clause()) + self.0.0.trait_clauses.iter().filter_map(|c| c.as_trait_clause()) } #[inline] pub fn region_outlives_clauses( self, ) -> impl Iterator> { - self.0.0.caller_bounds.iter().filter_map(|c| c.as_region_outlives_clause()) + self.0.0.region_outlives_clauses.iter().filter_map(|c| c.as_region_outlives_clause()) } #[inline] pub fn type_outlives_clauses(self) -> impl Iterator> { - self.0.0.caller_bounds.iter().filter_map(|c| c.as_type_outlives_clause()) + self.0.0.type_outlives_clauses.iter().filter_map(|c| c.as_type_outlives_clause()) } #[inline] pub fn projection_clauses(self) -> impl Iterator> { - self.0.0.caller_bounds.iter().filter_map(|c| c.as_projection_clause()) + self.0.0.projection_clauses.iter().filter_map(|c| c.as_projection_clause()) } #[inline] pub fn const_arg_has_type_clauses( self, ) -> impl Iterator> { - self.0.0.caller_bounds.iter().filter_map(|c| c.as_const_arg_has_type_clause()) + self.0.0.const_arg_has_type_clauses.iter().filter_map(|c| c.as_const_arg_has_type_clause()) } #[inline] pub fn well_formed_clauses(self) -> impl Iterator> { - self.0.0.caller_bounds.iter().filter_map(|c| c.as_well_formed_clause()) + self.0.0.well_formed_clauses.iter().filter_map(|c| c.as_well_formed_clause()) } #[inline] pub fn const_evaluatable_clauses( self, ) -> impl Iterator> { - self.0.0.caller_bounds.iter().filter_map(|c| c.as_const_evaluatable_clause()) + self.0.0.const_evaluatable_clauses.iter().filter_map(|c| c.as_const_evaluatable_clause()) } #[inline] pub fn host_effect_clauses(self) -> impl Iterator> { - self.0.0.caller_bounds.iter().filter_map(|c| c.as_host_effect_clause()) + self.0.0.host_effect_clauses.iter().filter_map(|c| c.as_host_effect_clause()) } /// Construct a trait environment with the given set of predicates. #[inline] - pub fn new(tcx: TyCtxt<'tcx>, caller_bounds: Clauses<'tcx>) -> Self { - tcx.mk_param_env(ParamEnvInner { caller_bounds }) + pub fn from_iter(tcx: TyCtxt<'tcx>, clauses: impl Iterator>) -> Self { + let mut trait_clauses = Vec::new(); + let mut region_outlives_clauses = Vec::new(); + let mut type_outlives_clauses = Vec::new(); + let mut projection_clauses = Vec::new(); + let mut const_arg_has_type_clauses = Vec::new(); + let mut well_formed_clauses = Vec::new(); + let mut const_evaluatable_clauses = Vec::new(); + let mut host_effect_clauses = Vec::new(); + + for clause in clauses { + match clause.kind().skip_binder() { + ClauseKind::Trait(..) => trait_clauses.push(clause), + ClauseKind::RegionOutlives(..) => region_outlives_clauses.push(clause), + ClauseKind::TypeOutlives(..) => type_outlives_clauses.push(clause), + ClauseKind::Projection(..) => projection_clauses.push(clause), + ClauseKind::ConstArgHasType(..) => const_arg_has_type_clauses.push(clause), + ClauseKind::WellFormed(..) => well_formed_clauses.push(clause), + ClauseKind::ConstEvaluatable(..) => const_evaluatable_clauses.push(clause), + ClauseKind::HostEffect(..) => host_effect_clauses.push(clause), + } + } + + tcx.mk_param_env(ParamEnvInner { + trait_clauses: tcx.mk_clauses(&trait_clauses), + region_outlives_clauses: tcx.mk_clauses(®ion_outlives_clauses), + type_outlives_clauses: tcx.mk_clauses(&type_outlives_clauses), + projection_clauses: tcx.mk_clauses(&projection_clauses), + const_arg_has_type_clauses: tcx.mk_clauses(&const_arg_has_type_clauses), + well_formed_clauses: tcx.mk_clauses(&well_formed_clauses), + const_evaluatable_clauses: tcx.mk_clauses(&const_evaluatable_clauses), + host_effect_clauses: tcx.mk_clauses(&host_effect_clauses), + }) } /// Creates a pair of param-env and value for use in queries. @@ -1065,35 +1139,35 @@ impl<'tcx> ParamEnv<'tcx> { impl<'tcx> rustc_type_ir::inherent::ParamEnv> for ParamEnv<'tcx> { fn trait_clauses(self) -> impl Iterator> { - self.all_clauses().filter(|c| c.as_trait_clause().is_some()) + self.0.0.trait_clauses.iter() } fn region_outlives_clauses(self) -> impl Iterator> { - self.all_clauses().filter(|c| c.as_region_outlives_clause().is_some()) + self.0.0.region_outlives_clauses.iter() } fn type_outlives_clauses(self) -> impl Iterator> { - self.all_clauses().filter(|c| c.as_type_outlives_clause().is_some()) + self.0.0.type_outlives_clauses.iter() } fn projection_clauses(self) -> impl Iterator> { - self.all_clauses().filter(|c| c.as_projection_clause().is_some()) + self.0.0.projection_clauses.iter() } fn const_arg_has_type_clauses(self) -> impl Iterator> { - self.all_clauses().filter(|c| c.as_const_arg_has_type_clause().is_some()) + self.0.0.const_arg_has_type_clauses.iter() } fn well_formed_clauses(self) -> impl Iterator> { - self.all_clauses().filter(|c| c.as_well_formed_clause().is_some()) + self.0.0.well_formed_clauses.iter() } fn const_evaluatable_clauses(self) -> impl Iterator> { - self.all_clauses().filter(|c| c.as_const_evaluatable_clause().is_some()) + self.0.0.const_evaluatable_clauses.iter() } fn host_effect_clauses(self) -> impl Iterator> { - self.all_clauses().filter(|c| c.as_host_effect_clause().is_some()) + self.0.0.host_effect_clauses.iter() } } diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 064b0849d6917..e92469d35f496 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -319,15 +319,12 @@ impl<'tcx> AutoTraitFinder<'tcx> { .map(|c| c.as_predicate()) .chain(user_computed_preds.iter().cloned()); let normalized_preds = elaborate(tcx, computed_preds); - new_env = ty::ParamEnv::new( - tcx, - tcx.mk_clauses_from_iter(normalized_preds.filter_map(|p| p.as_clause())), - ); + new_env = ty::ParamEnv::from_iter(tcx, normalized_preds.filter_map(|p| p.as_clause())); } - let final_user_env = ty::ParamEnv::new( + let final_user_env = ty::ParamEnv::from_iter( tcx, - tcx.mk_clauses_from_iter(user_computed_preds.into_iter().filter_map(|p| p.as_clause())), + user_computed_preds.into_iter().filter_map(|p| p.as_clause()), ); debug!( "evaluate_nested_obligations(ty={:?}, trait_did={:?}): succeeded with '{:?}' \ diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs index 61331391823db..58d6bf0f822ab 100644 --- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs +++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs @@ -612,7 +612,7 @@ fn receiver_is_dispatchable<'tcx>( normalize_param_env_or_error( tcx, - ty::ParamEnv::new(tcx, tcx.mk_clauses(&predicates)), + ty::ParamEnv::from_iter(tcx, predicates.iter().copied()), ObligationCause::dummy_with_span(tcx.def_span(method.def_id)), ) }; diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 9d59b435a0209..7675127bf7bad 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -414,7 +414,7 @@ pub fn normalize_param_env_or_error<'tcx>( debug!("normalize_param_env_or_error: elaborated-predicates={:?}", predicates); - let elaborated_env = ty::ParamEnv::new(tcx, tcx.mk_clauses(&predicates)); + let elaborated_env = ty::ParamEnv::from_iter(tcx, predicates.iter().copied()); if !elaborated_env.has_aliases() { return elaborated_env; } @@ -461,7 +461,7 @@ pub fn normalize_param_env_or_error<'tcx>( // here. I believe they should not matter, because we are ignoring TypeOutlives param-env // predicates here anyway. Keeping them here anyway because it seems safer. let outlives_env = non_outlives_predicates.iter().chain(&outlives_predicates).cloned(); - let outlives_env = ty::ParamEnv::new(tcx, tcx.mk_clauses_from_iter(outlives_env)); + let outlives_env = ty::ParamEnv::from_iter(tcx, outlives_env); let Ok(outlives_predicates) = do_normalize_predicates(tcx, cause, outlives_env, outlives_predicates) else { @@ -474,7 +474,7 @@ pub fn normalize_param_env_or_error<'tcx>( let mut predicates = non_outlives_predicates; predicates.extend(outlives_predicates); debug!("normalize_param_env_or_error: final predicates={:?}", predicates); - ty::ParamEnv::new(tcx, tcx.mk_clauses(&predicates)) + ty::ParamEnv::from_iter(tcx, predicates.iter().copied()) } #[derive(Debug)] diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 2025b060780f4..9598f6bec105e 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -163,7 +163,7 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { let local_did = def_id.as_local(); - let unnormalized_env = ty::ParamEnv::new(tcx, tcx.mk_clauses(&predicates)); + let unnormalized_env = ty::ParamEnv::from_iter(tcx, predicates.iter().copied()); let body_id = local_did.unwrap_or(CRATE_DEF_ID); let cause = traits::ObligationCause::misc(tcx.def_span(def_id), body_id); diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs index 4842340d7ccbb..93e2139abbd9b 100644 --- a/src/tools/clippy/clippy_lints/src/derive.rs +++ b/src/tools/clippy/clippy_lints/src/derive.rs @@ -501,9 +501,9 @@ fn typing_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId) -> } } - let param_env = ParamEnv::new( + let param_env = ParamEnv::from_iter( tcx, - tcx.mk_clauses_from_iter(ty_predicates.iter().map(|&(p, _)| p).chain( + ty_predicates.iter().map(|&(p, _)| p).chain( params.iter().filter(|&&(_, needs_eq)| needs_eq).map(|&(param, _)| { ClauseKind::Trait(TraitPredicate { trait_ref: ty::TraitRef::new(tcx, eq_trait_id, [tcx.mk_param_from_def(param)]), @@ -511,7 +511,7 @@ fn typing_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId) -> }) .upcast(tcx) }), - )), + ), ); ty::TypingEnv { typing_mode: ty::TypingMode::non_body_analysis(), diff --git a/tests/ui/type-alias-impl-trait/in-where-clause.stderr b/tests/ui/type-alias-impl-trait/in-where-clause.stderr index 275544f2211b3..d08b13e2aef8a 100644 --- a/tests/ui/type-alias-impl-trait/in-where-clause.stderr +++ b/tests/ui/type-alias-impl-trait/in-where-clause.stderr @@ -62,7 +62,7 @@ LL | / fn foo() -> Bar LL | | where LL | | Bar: Send, | |______________^ - = note: ...which requires revealing opaque types in `ParamEnv(ParamEnvInner { caller_bounds: [Binder { value: TraitPredicate(, polarity:Positive), bound_vars: [] }] })`... + = note: ...which requires revealing opaque types in `ParamEnv(ParamEnvInner { trait_clauses: [Binder { value: TraitPredicate(, polarity:Positive), bound_vars: [] }], region_outlives_clauses: [], type_outlives_clauses: [], projection_clauses: [], const_arg_has_type_clauses: [], well_formed_clauses: [], const_evaluatable_clauses: [], host_effect_clauses: [] })`... note: ...which requires computing type of `Bar::{opaque#0}`... --> $DIR/in-where-clause.rs:5:12 |