@@ -3,7 +3,7 @@ use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKi
33use rustc_infer:: traits:: { FulfillmentError , TraitEngine } ;
44use rustc_middle:: ty:: { self , Ty } ;
55
6- use crate :: traits:: { query :: evaluate_obligation :: InferCtxtExt , NormalizeExt , Obligation } ;
6+ use crate :: traits:: { NormalizeExt , Obligation } ;
77
88pub trait StructurallyNormalizeExt < ' tcx > {
99 fn structurally_normalize (
@@ -16,42 +16,43 @@ pub trait StructurallyNormalizeExt<'tcx> {
1616impl < ' tcx > StructurallyNormalizeExt < ' tcx > for At < ' _ , ' tcx > {
1717 fn structurally_normalize (
1818 & self ,
19- mut ty : Ty < ' tcx > ,
19+ ty : Ty < ' tcx > ,
2020 fulfill_cx : & mut dyn TraitEngine < ' tcx > ,
2121 ) -> Result < Ty < ' tcx > , Vec < FulfillmentError < ' tcx > > > {
2222 assert ! ( !ty. is_ty_var( ) , "should have resolved vars before calling" ) ;
2323
2424 if self . infcx . next_trait_solver ( ) {
25- // FIXME(-Znext-solver): correctly handle
26- // overflow here.
27- for _ in 0 ..256 {
28- let ty:: Alias ( ty:: Projection | ty:: Inherent | ty:: Weak , alias) = * ty. kind ( ) else {
29- break ;
30- } ;
31-
32- let new_infer_ty = self . infcx . next_ty_var ( TypeVariableOrigin {
33- kind : TypeVariableOriginKind :: NormalizeProjectionType ,
34- span : self . cause . span ,
35- } ) ;
36- let obligation = Obligation :: new (
37- self . infcx . tcx ,
38- self . cause . clone ( ) ,
39- self . param_env ,
40- ty:: NormalizesTo { alias, term : new_infer_ty. into ( ) } ,
41- ) ;
42- if self . infcx . predicate_may_hold ( & obligation) {
43- fulfill_cx. register_predicate_obligation ( self . infcx , obligation) ;
44- let errors = fulfill_cx. select_where_possible ( self . infcx ) ;
45- if !errors. is_empty ( ) {
46- return Err ( errors) ;
47- }
48- ty = self . infcx . resolve_vars_if_possible ( new_infer_ty) ;
49- } else {
50- break ;
51- }
25+ // FIXME(-Znext-solver): Should we resolve opaques here?
26+ let ty:: Alias ( ty:: Projection | ty:: Inherent | ty:: Weak , _) = * ty. kind ( ) else {
27+ return Ok ( ty) ;
28+ } ;
29+
30+ let new_infer_ty = self . infcx . next_ty_var ( TypeVariableOrigin {
31+ kind : TypeVariableOriginKind :: NormalizeProjectionType ,
32+ span : self . cause . span ,
33+ } ) ;
34+
35+ // We simply emit an `alias-eq` goal here, since that will take care of
36+ // normalizing the LHS of the projection until it is a rigid projection
37+ // (or a not-yet-defined opaque in scope).
38+ let obligation = Obligation :: new (
39+ self . infcx . tcx ,
40+ self . cause . clone ( ) ,
41+ self . param_env ,
42+ ty:: PredicateKind :: AliasRelate (
43+ ty. into ( ) ,
44+ new_infer_ty. into ( ) ,
45+ ty:: AliasRelationDirection :: Equate ,
46+ ) ,
47+ ) ;
48+
49+ fulfill_cx. register_predicate_obligation ( self . infcx , obligation) ;
50+ let errors = fulfill_cx. select_where_possible ( self . infcx ) ;
51+ if !errors. is_empty ( ) {
52+ return Err ( errors) ;
5253 }
5354
54- Ok ( ty )
55+ Ok ( self . infcx . resolve_vars_if_possible ( new_infer_ty ) )
5556 } else {
5657 Ok ( self . normalize ( ty) . into_value_registering_obligations ( self . infcx , fulfill_cx) )
5758 }
0 commit comments