@@ -20,7 +20,6 @@ use crate::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime};
2020use crate :: traits:: error_reporting:: TypeErrCtxtExt as _;
2121use crate :: traits:: query:: evaluate_obligation:: InferCtxtExt as _;
2222use crate :: traits:: select:: ProjectionMatchesProjection ;
23- use crate :: traits:: TraitEngineExt as _;
2423use rustc_data_structures:: sso:: SsoHashSet ;
2524use rustc_data_structures:: stack:: ensure_sufficient_stack;
2625use rustc_errors:: ErrorGuaranteed ;
@@ -32,7 +31,6 @@ use rustc_infer::infer::DefineOpaqueTypes;
3231use rustc_infer:: traits:: FulfillmentError ;
3332use rustc_infer:: traits:: ObligationCauseCode ;
3433use rustc_infer:: traits:: TraitEngine ;
35- use rustc_infer:: traits:: TraitEngineExt as _;
3634use rustc_middle:: traits:: select:: OverflowError ;
3735use rustc_middle:: ty:: fold:: { TypeFoldable , TypeFolder , TypeSuperFoldable } ;
3836use rustc_middle:: ty:: visit:: { MaxUniverse , TypeVisitable , TypeVisitableExt } ;
@@ -59,17 +57,17 @@ pub trait NormalizeExt<'tcx> {
5957 fn normalize < T : TypeFoldable < TyCtxt < ' tcx > > > ( & self , t : T ) -> InferOk < ' tcx , T > ;
6058
6159 /// Deeply normalizes `value`, replacing all aliases which can by normalized in
62- /// the current environment. Unlike other normalization routines, this errors
63- /// in case normalization fails or is ambiguous.
60+ /// the current environment. In the new solver this errors in case normalization
61+ /// fails or is ambiguous. This only normalize opaque types with `Reveal::All` .
6462 ///
65- /// In the old solver this simply uses `normalize` and errors in
66- /// case of ambiguity. The new solver only normalizes in this function and
67- /// `normalize` is a noop.
68- ///
69- /// This only normalize opaque types with `Reveal::All`.
63+ /// In the old solver this simply uses `normalizes` and adds the nested obligations
64+ /// to the `fulfill_cx`. This is necessary as we otherwise end up recomputing the
65+ /// same goals in both a temporary and the shared context which negatively impacts
66+ /// performance as these don't share caching.
7067 fn deeply_normalize < T : TypeFoldable < TyCtxt < ' tcx > > > (
7168 self ,
7269 value : T ,
70+ fulfill_cx : & mut dyn TraitEngine < ' tcx > ,
7371 ) -> Result < T , Vec < FulfillmentError < ' tcx > > > ;
7472}
7573
@@ -88,15 +86,16 @@ impl<'tcx> NormalizeExt<'tcx> for At<'_, 'tcx> {
8886 fn deeply_normalize < T : TypeFoldable < TyCtxt < ' tcx > > > (
8987 self ,
9088 value : T ,
89+ fulfill_cx : & mut dyn TraitEngine < ' tcx > ,
9190 ) -> Result < T , Vec < FulfillmentError < ' tcx > > > {
9291 if self . infcx . next_trait_solver ( ) {
9392 crate :: solve:: deeply_normalize ( self , value)
9493 } else {
95- let mut fulfill_cx = <dyn TraitEngine < ' tcx > >:: new ( & self . infcx ) ;
9694 let value = self
9795 . normalize ( value)
9896 . into_value_registering_obligations ( self . infcx , & mut * fulfill_cx) ;
99- let errors = fulfill_cx. select_all_or_error ( self . infcx ) ;
97+ let errors = fulfill_cx. select_where_possible ( self . infcx ) ;
98+ let value = self . infcx . resolve_vars_if_possible ( value) ;
10099 if errors. is_empty ( ) { Ok ( value) } else { Err ( errors) }
101100 }
102101 }
0 commit comments