@@ -30,7 +30,6 @@ use rustc_errors::ErrorGuaranteed;
3030pub use rustc_infer:: traits:: * ;
3131use rustc_macros:: TypeVisitable ;
3232use rustc_middle:: query:: Providers ;
33- use rustc_middle:: span_bug;
3433use rustc_middle:: ty:: error:: { ExpectedFound , TypeError } ;
3534use rustc_middle:: ty:: {
3635 self , Clause , GenericArgs , GenericArgsRef , Ty , TyCtxt , TypeFoldable , TypeFolder ,
@@ -250,19 +249,79 @@ fn pred_known_to_hold_modulo_regions<'tcx>(
250249 }
251250}
252251
252+ fn set_projection_term_to_non_rigid < ' tcx , T : TypeFoldable < TyCtxt < ' tcx > > > (
253+ tcx : TyCtxt < ' tcx > ,
254+ value : T ,
255+ ) -> T {
256+ value. fold_with ( & mut ProjectionTermToNonRigid { tcx } )
257+ }
258+
259+ struct ProjectionTermToNonRigid < ' tcx > {
260+ tcx : TyCtxt < ' tcx > ,
261+ }
262+
263+ impl < ' tcx > TypeFolder < TyCtxt < ' tcx > > for ProjectionTermToNonRigid < ' tcx > {
264+ fn cx ( & self ) -> TyCtxt < ' tcx > {
265+ self . tcx
266+ }
267+
268+ fn fold_predicate ( & mut self , p : ty:: Predicate < ' tcx > ) -> ty:: Predicate < ' tcx > {
269+ if let ty:: PredicateKind :: Clause ( clause) = p. kind ( ) . skip_binder ( )
270+ && let ty:: ClauseKind :: Projection ( projection_pred) = clause
271+ {
272+ p. kind ( )
273+ . rebind ( ty:: ProjectionPredicate {
274+ projection_term : projection_pred. projection_term ,
275+ term : ty:: set_aliases_to_non_rigid ( self . tcx , projection_pred. term )
276+ . skip_norm_wip ( ) ,
277+ } )
278+ . upcast ( self . tcx )
279+ } else {
280+ p
281+ }
282+ }
283+ }
284+
285+ struct OpaqueToNonRigid < ' tcx > {
286+ tcx : TyCtxt < ' tcx > ,
287+ }
288+
289+ impl < ' tcx > TypeFolder < TyCtxt < ' tcx > > for OpaqueToNonRigid < ' tcx > {
290+ fn cx ( & self ) -> TyCtxt < ' tcx > {
291+ self . tcx
292+ }
293+
294+ fn fold_ty ( & mut self , t : Ty < ' tcx > ) -> Ty < ' tcx > {
295+ if !( t. has_rigid_aliases ( ) && t. has_opaque_types ( ) ) {
296+ return t;
297+ }
298+
299+ if let ty:: Alias ( ty:: IsRigid :: Yes , alias_ty @ ty:: AliasTy { kind : ty:: Opaque { .. } , .. } ) =
300+ t. kind ( )
301+ {
302+ let alias_ty = alias_ty. fold_with ( self ) ;
303+ Ty :: new_alias ( self . tcx , ty:: IsRigid :: No , alias_ty)
304+ } else {
305+ t. super_fold_with ( self )
306+ }
307+ }
308+
309+ fn fold_const ( & mut self , c : ty:: Const < ' tcx > ) -> ty:: Const < ' tcx > {
310+ if c. has_rigid_aliases ( ) && c. has_opaque_types ( ) { c. super_fold_with ( self ) } else { c }
311+ }
312+
313+ fn fold_predicate ( & mut self , p : ty:: Predicate < ' tcx > ) -> ty:: Predicate < ' tcx > {
314+ if p. has_rigid_aliases ( ) && p. has_opaque_types ( ) { p. super_fold_with ( self ) } else { p }
315+ }
316+ }
317+
253318#[ instrument( level = "debug" , skip( tcx, elaborated_env) ) ]
254319fn do_normalize_predicates < ' tcx > (
255320 tcx : TyCtxt < ' tcx > ,
256321 cause : ObligationCause < ' tcx > ,
257322 elaborated_env : ty:: ParamEnv < ' tcx > ,
258323 predicates : Vec < ty:: Clause < ' tcx > > ,
259324) -> Result < Vec < ty:: Clause < ' tcx > > , ErrorGuaranteed > {
260- // Even if we move back to eager normalization elsewhere,
261- // param env normalization remains lazy in the next solver.
262- if tcx. next_trait_solver_globally ( ) {
263- return Ok ( predicates) ;
264- }
265-
266325 // FIXME. We should really... do something with these region
267326 // obligations. But this call just continues the older
268327 // behavior (i.e., doesn't cause any new bugs), and it would
@@ -279,10 +338,30 @@ fn do_normalize_predicates<'tcx>(
279338 let span = cause. span ;
280339 let infcx = tcx. infer_ctxt ( ) . ignoring_regions ( ) . build ( TypingMode :: non_body_analysis ( ) ) ;
281340 let ocx = ObligationCtxt :: new_with_diagnostics ( & infcx) ;
341+ // FIXME: The `elaborated_env` is not really rigid. We do this to be
342+ // consistent with the old solver. It fixes several issues with
343+ // lazy norm of param env but unfix others.
344+ let elaborated_env = if tcx. next_trait_solver_globally ( ) && !tcx. disable_param_env_hack ( ) {
345+ // FIXME: combine them into one if the perf is bad.
346+ let elaborated_env = ty:: set_aliases_to_rigid ( tcx, elaborated_env) ;
347+ set_projection_term_to_non_rigid ( tcx, elaborated_env)
348+ } else {
349+ elaborated_env
350+ } ;
282351 let predicates = ocx. normalize ( & cause, elaborated_env, Unnormalized :: new_wip ( predicates) ) ;
283- // FIXME: opaque types in param env might be in defining scope but we're
284- // using non body analysis for here. So the rigidness marker is wrong.
285- let predicates = ty:: set_aliases_to_non_rigid ( tcx, predicates) . skip_norm_wip ( ) ;
352+ let predicates = if tcx. next_trait_solver_globally ( ) {
353+ if !tcx. disable_param_env_hack ( ) {
354+ let predicates = set_projection_term_to_non_rigid ( tcx, predicates) ;
355+ // FIXME(type_alias_impl_trait): opaque types in param env might be
356+ // in defining scope but we're using non body analysis here.
357+ // So the rigidness marker is wrong.
358+ predicates. fold_with ( & mut OpaqueToNonRigid { tcx } )
359+ } else {
360+ ty:: set_aliases_to_non_rigid ( tcx, predicates) . skip_norm_wip ( )
361+ }
362+ } else {
363+ predicates
364+ } ;
286365
287366 let errors = ocx. evaluate_obligations_error_on_ambiguity ( ) ;
288367 if !errors. is_empty ( ) {
@@ -294,17 +373,20 @@ fn do_normalize_predicates<'tcx>(
294373
295374 // We can use the `elaborated_env` here; the region code only
296375 // cares about declarations like `'a: 'b`.
376+ //
297377 // FIXME: It's very weird that we ignore region obligations but apparently
298378 // still need to use `resolve_regions` as we need the resolved regions in
299379 // the normalized predicates.
300- let errors = infcx. resolve_regions ( cause. body_id , elaborated_env, [ ] ) ;
301- if !errors. is_empty ( ) {
302- tcx. dcx ( ) . span_delayed_bug (
303- span,
304- format ! ( "failed region resolution while normalizing {elaborated_env:?}: {errors:?}" ) ,
305- ) ;
306- }
307-
380+ //
381+ // FIXME(-Zhigher-ranked-assumptions): We're ignoring region errors for now.
382+ // There're placeholder constraints `leaking` out. This is a hack to work around
383+ // the fact that we don't support placeholder assumptions right now and is necessary
384+ // for `compare_method_predicate_entailment`. We should remove this once we
385+ // have proper support for implied bounds on binders.
386+ //
387+ // This is required by trait-system-refactor-initiative#166. The new solver encounters
388+ // this more frequently as we entirely ignore outlives predicates with the old solver.
389+ let _errors = infcx. resolve_regions ( cause. body_id , elaborated_env, [ ] ) ;
308390 match infcx. fully_resolve ( predicates) {
309391 Ok ( predicates) => Ok ( predicates) ,
310392 Err ( fixup_err) => {
@@ -481,69 +563,6 @@ pub fn normalize_param_env_or_error<'tcx>(
481563 ty:: ParamEnv :: new ( tcx. mk_clauses ( & predicates) )
482564}
483565
484- /// Deeply normalize the param env using the next solver ignoring
485- /// region errors.
486- ///
487- /// FIXME(-Zhigher-ranked-assumptions): this is a hack to work around
488- /// the fact that we don't support placeholder assumptions right now
489- /// and is necessary for `compare_method_predicate_entailment`, see the
490- /// use of this function for more info. We should remove this once we
491- /// have proper support for implied bounds on binders.
492- #[ instrument( level = "debug" , skip( tcx) ) ]
493- pub fn deeply_normalize_param_env_ignoring_regions < ' tcx > (
494- tcx : TyCtxt < ' tcx > ,
495- unnormalized_env : ty:: ParamEnv < ' tcx > ,
496- cause : ObligationCause < ' tcx > ,
497- ) -> ty:: ParamEnv < ' tcx > {
498- let predicates: Vec < _ > =
499- util:: elaborate ( tcx, unnormalized_env. caller_bounds ( ) . into_iter ( ) ) . collect ( ) ;
500-
501- debug ! ( "normalize_param_env_or_error: elaborated-predicates={:?}" , predicates) ;
502-
503- let elaborated_env = ty:: ParamEnv :: new ( tcx. mk_clauses ( & predicates) ) ;
504- if !elaborated_env. has_aliases ( ) {
505- return elaborated_env;
506- }
507-
508- let span = cause. span ;
509- let infcx = tcx
510- . infer_ctxt ( )
511- . with_next_trait_solver ( true )
512- . ignoring_regions ( )
513- . build ( TypingMode :: non_body_analysis ( ) ) ;
514- let predicates = match crate :: solve:: deeply_normalize :: < _ , FulfillmentError < ' tcx > > (
515- infcx. at ( & cause, elaborated_env) ,
516- Unnormalized :: new_wip ( predicates) ,
517- ) {
518- Ok ( predicates) => predicates,
519- Err ( errors) => {
520- infcx. err_ctxt ( ) . report_fulfillment_errors ( errors) ;
521- // An unnormalized env is better than nothing.
522- debug ! ( "normalize_param_env_or_error: errored resolving predicates" ) ;
523- return elaborated_env;
524- }
525- } ;
526-
527- debug ! ( "do_normalize_predicates: normalized predicates = {:?}" , predicates) ;
528- // FIXME(-Zhigher-ranked-assumptions): We're ignoring region errors for now.
529- // There're placeholder constraints `leaking` out.
530- // See the fixme in the enclosing function's docs for more.
531- let _errors = infcx. resolve_regions ( cause. body_id , elaborated_env, [ ] ) ;
532-
533- let predicates = match infcx. fully_resolve ( predicates) {
534- Ok ( predicates) => predicates,
535- Err ( fixup_err) => {
536- span_bug ! (
537- span,
538- "inference variables in normalized parameter environment: {}" ,
539- fixup_err
540- )
541- }
542- } ;
543- debug ! ( "normalize_param_env_or_error: final predicates={:?}" , predicates) ;
544- ty:: ParamEnv :: new ( tcx. mk_clauses ( & predicates) )
545- }
546-
547566#[ derive( Debug ) ]
548567pub enum EvaluateConstErr {
549568 /// The constant being evaluated was either a generic parameter or inference variable, *or*,
0 commit comments