From 300d4a55c9e866225319536d10a6b320a96403a7 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 12 Mar 2024 15:24:48 -0400 Subject: [PATCH 1/2] Explicitly don't normalize in new solver --- .../src/check/compare_impl_item.rs | 20 ++++++++++--- .../src/check/compare_impl_item/refine.rs | 5 +++- .../rustc_trait_selection/src/traits/mod.rs | 30 +++++++++++-------- compiler/rustc_ty_utils/src/ty.rs | 6 ++-- 4 files changed, 41 insertions(+), 20 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 ec9e928ce593d..8d196ae7596db 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -221,7 +221,10 @@ fn compare_method_predicate_entailment<'tcx>( // The key step here is to update the caller_bounds's predicates to be // the new hybrid bounds we computed. let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_def_id); - let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds.predicates), Reveal::UserFacing); + let param_env = ty::ParamEnv::new( + tcx.mk_clauses_from_iter(util::elaborate(tcx, hybrid_preds.predicates)), + Reveal::UserFacing, + ); let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause); let infcx = &tcx.infer_ctxt().build(); @@ -485,7 +488,10 @@ 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_placeholder_args)) .map(|(clause, _)| clause); - let param_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(hybrid_preds), Reveal::UserFacing); + let param_env = ty::ParamEnv::new( + tcx.mk_clauses_from_iter(util::elaborate(tcx, hybrid_preds)), + Reveal::UserFacing, + ); let param_env = traits::normalize_param_env_or_error( tcx, param_env, @@ -1776,7 +1782,10 @@ fn compare_const_predicate_entailment<'tcx>( .map(|(predicate, _)| predicate), ); - let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds.predicates), Reveal::UserFacing); + let param_env = ty::ParamEnv::new( + tcx.mk_clauses_from_iter(util::elaborate(tcx, hybrid_preds.predicates)), + Reveal::UserFacing, + ); let param_env = traits::normalize_param_env_or_error( tcx, param_env, @@ -1915,7 +1924,10 @@ fn compare_type_predicate_entailment<'tcx>( let impl_ty_span = tcx.def_span(impl_ty_def_id); let normalize_cause = ObligationCause::misc(impl_ty_span, impl_ty_def_id); - let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds.predicates), Reveal::UserFacing); + let param_env = ty::ParamEnv::new( + tcx.mk_clauses_from_iter(util::elaborate(tcx, hybrid_preds.predicates)), + Reveal::UserFacing, + ); let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause); let infcx = tcx.infer_ctxt().build(); let ocx = ObligationCtxt::new(&infcx); 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 a2a20082bb03e..2e9245a4745a0 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 @@ -123,7 +123,10 @@ pub(super) 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), Reveal::UserFacing); + let param_env = ty::ParamEnv::new( + tcx.mk_clauses_from_iter(elaborate(tcx, hybrid_preds)), + Reveal::UserFacing, + ); let param_env = normalize_param_env_or_error(tcx, param_env, ObligationCause::dummy()); let ref infcx = tcx.infer_ctxt().build(); diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index cc8b8f72cf359..c8656f59eec48 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -207,6 +207,10 @@ pub fn normalize_param_env_or_error<'tcx>( unnormalized_env: ty::ParamEnv<'tcx>, cause: ObligationCause<'tcx>, ) -> ty::ParamEnv<'tcx> { + if tcx.next_trait_solver_globally() { + return unnormalized_env; + } + // I'm not wild about reporting errors here; I'd prefer to // have the errors get reported at a defined place (e.g., // during typeck). Instead I have all parameter @@ -221,9 +225,10 @@ pub fn normalize_param_env_or_error<'tcx>( // parameter environments once for every fn as it goes, // and errors will get reported then; so outside of type inference we // can be sure that no errors should occur. - let mut predicates: Vec<_> = util::elaborate( - tcx, - unnormalized_env.caller_bounds().into_iter().map(|predicate| { + let mut predicates: Vec<_> = unnormalized_env + .caller_bounds() + .into_iter() + .map(|predicate| { if tcx.features().generic_const_exprs { return predicate; } @@ -280,13 +285,13 @@ pub fn normalize_param_env_or_error<'tcx>( // // FIXME(-Znext-solver): remove this hack since we have deferred projection equality predicate.fold_with(&mut ConstNormalizer(tcx)) - }), - ) - .collect(); + }) + .collect(); debug!("normalize_param_env_or_error: elaborated-predicates={:?}", predicates); - let elaborated_env = ty::ParamEnv::new(tcx.mk_clauses(&predicates), unnormalized_env.reveal()); + let reveal = unnormalized_env.reveal(); + let eager_evaluated_env = ty::ParamEnv::new(tcx.mk_clauses(&predicates), reveal); // HACK: we are trying to normalize the param-env inside *itself*. The problem is that // normalization expects its param-env to be already normalized, which means we have @@ -317,11 +322,11 @@ pub fn normalize_param_env_or_error<'tcx>( predicates, outlives_predicates ); let Ok(non_outlives_predicates) = - do_normalize_predicates(tcx, cause.clone(), elaborated_env, predicates) + do_normalize_predicates(tcx, cause.clone(), eager_evaluated_env, predicates) else { // An unnormalized env is better than nothing. debug!("normalize_param_env_or_error: errored resolving non-outlives predicates"); - return elaborated_env; + return eager_evaluated_env; }; debug!("normalize_param_env_or_error: non-outlives predicates={:?}", non_outlives_predicates); @@ -330,21 +335,20 @@ 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), unnormalized_env.reveal()); + let outlives_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(outlives_env), reveal); let Ok(outlives_predicates) = do_normalize_predicates(tcx, cause, outlives_env, outlives_predicates) else { // An unnormalized env is better than nothing. debug!("normalize_param_env_or_error: errored resolving outlives predicates"); - return elaborated_env; + return eager_evaluated_env; }; debug!("normalize_param_env_or_error: outlives predicates={:?}", outlives_predicates); 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), unnormalized_env.reveal()) + ty::ParamEnv::new(tcx.mk_clauses(&predicates), reveal) } /// Normalize a type and process all resulting obligations, returning any errors. diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 547a3cb5a8c3f..9c26e747d4bfe 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -146,8 +146,10 @@ 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), traits::Reveal::UserFacing); + let unnormalized_env = ty::ParamEnv::new( + tcx.mk_clauses_from_iter(traits::elaborate(tcx, predicates)), + traits::Reveal::UserFacing, + ); let body_id = local_did.unwrap_or(CRATE_DEF_ID); let cause = traits::ObligationCause::misc(tcx.def_span(def_id), body_id); From eacc881cf3bc115453fe6feb6f8bc1f6314bfcae Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 19 Mar 2024 11:28:51 -0400 Subject: [PATCH 2/2] ParamEnv::new -> ParamEnv::from_elaborated_clauses --- .../src/check/compare_impl_item.rs | 10 +++++----- .../src/check/compare_impl_item/refine.rs | 2 +- compiler/rustc_hir_analysis/src/check/wfcheck.rs | 5 ++--- compiler/rustc_middle/src/ty/codec.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 14 ++++++++++---- .../rustc_trait_selection/src/traits/auto_trait.rs | 4 ++-- compiler/rustc_trait_selection/src/traits/mod.rs | 8 +++++--- .../src/traits/object_safety.rs | 5 ++++- compiler/rustc_ty_utils/src/ty.rs | 2 +- src/tools/clippy/clippy_lints/src/derive.rs | 2 +- 10 files changed, 32 insertions(+), 22 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 8d196ae7596db..91714eec990ba 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -221,7 +221,7 @@ fn compare_method_predicate_entailment<'tcx>( // The key step here is to update the caller_bounds's predicates to be // the new hybrid bounds we computed. let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_def_id); - let param_env = ty::ParamEnv::new( + let param_env = ty::ParamEnv::from_elaborated_clauses( tcx.mk_clauses_from_iter(util::elaborate(tcx, hybrid_preds.predicates)), Reveal::UserFacing, ); @@ -488,7 +488,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_placeholder_args)) .map(|(clause, _)| clause); - let param_env = ty::ParamEnv::new( + let param_env = ty::ParamEnv::from_elaborated_clauses( tcx.mk_clauses_from_iter(util::elaborate(tcx, hybrid_preds)), Reveal::UserFacing, ); @@ -1782,7 +1782,7 @@ fn compare_const_predicate_entailment<'tcx>( .map(|(predicate, _)| predicate), ); - let param_env = ty::ParamEnv::new( + let param_env = ty::ParamEnv::from_elaborated_clauses( tcx.mk_clauses_from_iter(util::elaborate(tcx, hybrid_preds.predicates)), Reveal::UserFacing, ); @@ -1924,7 +1924,7 @@ fn compare_type_predicate_entailment<'tcx>( let impl_ty_span = tcx.def_span(impl_ty_def_id); let normalize_cause = ObligationCause::misc(impl_ty_span, impl_ty_def_id); - let param_env = ty::ParamEnv::new( + let param_env = ty::ParamEnv::from_elaborated_clauses( tcx.mk_clauses_from_iter(util::elaborate(tcx, hybrid_preds.predicates)), Reveal::UserFacing, ); @@ -2236,7 +2236,7 @@ fn param_env_with_gat_bounds<'tcx>( }; } - ty::ParamEnv::new(tcx.mk_clauses(&predicates), Reveal::UserFacing) + ty::ParamEnv::from_elaborated_clauses(tcx.mk_clauses(&predicates), Reveal::UserFacing) } fn assoc_item_kind_str(impl_item: &ty::AssocItem) -> &'static str { 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 2e9245a4745a0..072c61dfa6fa9 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 @@ -123,7 +123,7 @@ pub(super) 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( + let param_env = ty::ParamEnv::from_elaborated_clauses( tcx.mk_clauses_from_iter(elaborate(tcx, hybrid_preds)), Reveal::UserFacing, ); diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 41b03f0b66e4f..3b416ea830e16 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -605,9 +605,8 @@ fn augment_param_env<'tcx>( let bounds = tcx.mk_clauses_from_iter( param_env.caller_bounds().iter().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, param_env.reveal()) + + ty::ParamEnv::from_elaborated_clauses(bounds, param_env.reveal()) } /// 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 ddbc0bffaedde..1bbbd83bdefe4 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -323,7 +323,7 @@ impl<'tcx, D: TyDecoder>> Decodable for ty::ParamEnv<'tcx> { fn decode(d: &mut D) -> Self { let caller_bounds = Decodable::decode(d); let reveal = Decodable::decode(d); - ty::ParamEnv::new(caller_bounds, reveal) + ty::ParamEnv::from_elaborated_clauses(caller_bounds, reveal) } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 8565f90957f23..46d79c6ff74d6 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1037,7 +1037,7 @@ impl<'tcx> TypeFoldable> for ParamEnv<'tcx> { self, folder: &mut F, ) -> Result { - Ok(ParamEnv::new( + Ok(ParamEnv::from_elaborated_clauses( self.caller_bounds().try_fold_with(folder)?, self.reveal().try_fold_with(folder)?, )) @@ -1076,7 +1076,7 @@ impl<'tcx> ParamEnv<'tcx> { /// are revealed. This is suitable for monomorphized, post-typeck /// environments like codegen or doing optimizations. /// - /// N.B., if you want to have predicates in scope, use `ParamEnv::new`, + /// N.B., if you want to have predicates in scope, use `ParamEnv::from_elaborated_clauses`, /// or invoke `param_env.with_reveal_all()`. #[inline] pub fn reveal_all() -> Self { @@ -1085,7 +1085,10 @@ impl<'tcx> ParamEnv<'tcx> { /// Construct a trait environment with the given set of predicates. #[inline] - pub fn new(caller_bounds: &'tcx List>, reveal: Reveal) -> Self { + pub fn from_elaborated_clauses( + caller_bounds: &'tcx List>, + reveal: Reveal, + ) -> Self { ty::ParamEnv { packed: CopyTaggedPtr::new(caller_bounds, ParamTag { reveal }) } } @@ -1108,7 +1111,10 @@ impl<'tcx> ParamEnv<'tcx> { return self; } - ParamEnv::new(tcx.reveal_opaque_types_in_bounds(self.caller_bounds()), Reveal::All) + ParamEnv::from_elaborated_clauses( + tcx.reveal_opaque_types_in_bounds(self.caller_bounds()), + Reveal::All, + ) } /// Returns this same environment but with no caller bounds. diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 0796ffcbc45a0..db0df301ba7c1 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -340,13 +340,13 @@ impl<'tcx> AutoTraitFinder<'tcx> { let normalized_preds = elaborate(tcx, computed_preds.clone().chain(user_computed_preds.iter().cloned())); - new_env = ty::ParamEnv::new( + new_env = ty::ParamEnv::from_elaborated_clauses( tcx.mk_clauses_from_iter(normalized_preds.filter_map(|p| p.as_clause())), param_env.reveal(), ); } - let final_user_env = ty::ParamEnv::new( + let final_user_env = ty::ParamEnv::from_elaborated_clauses( tcx.mk_clauses_from_iter(user_computed_preds.into_iter().filter_map(|p| p.as_clause())), user_env.reveal(), ); diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index c8656f59eec48..528ef4e0d28cf 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -291,7 +291,8 @@ pub fn normalize_param_env_or_error<'tcx>( debug!("normalize_param_env_or_error: elaborated-predicates={:?}", predicates); let reveal = unnormalized_env.reveal(); - let eager_evaluated_env = ty::ParamEnv::new(tcx.mk_clauses(&predicates), reveal); + let eager_evaluated_env = + ty::ParamEnv::from_elaborated_clauses(tcx.mk_clauses(&predicates), reveal); // HACK: we are trying to normalize the param-env inside *itself*. The problem is that // normalization expects its param-env to be already normalized, which means we have @@ -335,7 +336,8 @@ 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), reveal); + let outlives_env = + ty::ParamEnv::from_elaborated_clauses(tcx.mk_clauses_from_iter(outlives_env), reveal); let Ok(outlives_predicates) = do_normalize_predicates(tcx, cause, outlives_env, outlives_predicates) else { @@ -348,7 +350,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), reveal) + ty::ParamEnv::from_elaborated_clauses(tcx.mk_clauses(&predicates), reveal) } /// Normalize a type and process all resulting obligations, returning any errors. diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 1816b98a636c6..499216e269cce 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -767,7 +767,10 @@ fn receiver_is_dispatchable<'tcx>( let caller_bounds = param_env.caller_bounds().iter().chain([unsize_predicate, trait_predicate]); - ty::ParamEnv::new(tcx.mk_clauses_from_iter(caller_bounds), param_env.reveal()) + ty::ParamEnv::from_elaborated_clauses( + tcx.mk_clauses_from_iter(caller_bounds), + param_env.reveal(), + ) }; // Receiver: DispatchFromDyn U]> diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 9c26e747d4bfe..3bd62dd688eb0 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -146,7 +146,7 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { let local_did = def_id.as_local(); - let unnormalized_env = ty::ParamEnv::new( + let unnormalized_env = ty::ParamEnv::from_elaborated_clauses( tcx.mk_clauses_from_iter(traits::elaborate(tcx, predicates)), traits::Reveal::UserFacing, ); diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs index f0f2c7d6658f1..987ca673c6fec 100644 --- a/src/tools/clippy/clippy_lints/src/derive.rs +++ b/src/tools/clippy/clippy_lints/src/derive.rs @@ -497,7 +497,7 @@ fn param_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId) -> } } - ParamEnv::new( + ParamEnv::from_elaborated_clauses( tcx.mk_clauses_from_iter(ty_predicates.iter().map(|&(p, _)| p).chain( params.iter().filter(|&&(_, needs_eq)| needs_eq).map(|&(param, _)| { ClauseKind::Trait(TraitPredicate {