11use rustc_infer:: infer:: TyCtxtInferExt ;
22use rustc_middle:: traits:: query:: NoSolution ;
33use rustc_middle:: ty:: query:: Providers ;
4- use rustc_middle:: ty:: { self , ParamEnvAnd , TyCtxt , TypeFoldable } ;
4+ use rustc_middle:: ty:: {
5+ self , FallibleTypeFolder , ParamEnvAnd , Ty , TyCtxt , TypeFoldable , TypeSuperFoldable , TypeVisitable ,
6+ } ;
57use rustc_trait_selection:: traits:: query:: normalize:: AtExt ;
68use rustc_trait_selection:: traits:: { Normalized , ObligationCause } ;
79use std:: sync:: atomic:: Ordering ;
@@ -16,17 +18,33 @@ pub(crate) fn provide(p: &mut Providers) {
1618 . normalize_generic_arg_after_erasing_regions
1719 . fetch_add ( 1 , Ordering :: Relaxed ) ;
1820
19- try_normalize_after_erasing_regions ( tcx, goal)
21+ let ParamEnvAnd { param_env, value } = goal;
22+
23+ match value. unpack ( ) {
24+ ty:: GenericArgKind :: Type ( ty) => {
25+ let ty =
26+ ty. try_super_fold_with ( & mut NormalizeDeeperFolder { tcx, param_env } ) ?;
27+ if let ty:: Projection ( ..) | ty:: Opaque ( ..) = ty. kind ( ) {
28+ Ok ( try_normalize_after_erasing_regions ( tcx, param_env, ty) ?. into ( ) )
29+ } else {
30+ Ok ( ty. into ( ) )
31+ }
32+ }
33+ ty:: GenericArgKind :: Const ( _) => {
34+ try_normalize_after_erasing_regions ( tcx, param_env, value)
35+ }
36+ ty:: GenericArgKind :: Lifetime ( _) => unreachable ! ( ) ,
37+ }
2038 } ,
2139 ..* p
2240 } ;
2341}
2442
2543fn try_normalize_after_erasing_regions < ' tcx , T : TypeFoldable < ' tcx > + PartialEq + Copy > (
2644 tcx : TyCtxt < ' tcx > ,
27- goal : ParamEnvAnd < ' tcx , T > ,
45+ param_env : ty:: ParamEnv < ' tcx > ,
46+ value : T ,
2847) -> Result < T , NoSolution > {
29- let ParamEnvAnd { param_env, value } = goal;
3048 let infcx = tcx. infer_ctxt ( ) . ignoring_regions ( ) . build ( ) ;
3149 let cause = ObligationCause :: dummy ( ) ;
3250 match infcx. at ( & cause, param_env) . normalize ( value) {
@@ -52,6 +70,39 @@ fn try_normalize_after_erasing_regions<'tcx, T: TypeFoldable<'tcx> + PartialEq +
5270 }
5371}
5472
73+ struct NormalizeDeeperFolder < ' tcx > {
74+ tcx : TyCtxt < ' tcx > ,
75+ param_env : ty:: ParamEnv < ' tcx > ,
76+ }
77+
78+ impl < ' tcx > FallibleTypeFolder < ' tcx > for NormalizeDeeperFolder < ' tcx > {
79+ type Error = NoSolution ;
80+
81+ fn tcx ( & self ) -> TyCtxt < ' tcx > {
82+ self . tcx
83+ }
84+
85+ fn try_fold_ty ( & mut self , ty : Ty < ' tcx > ) -> Result < Ty < ' tcx > , Self :: Error > {
86+ if !ty. needs_normalization ( self . param_env . reveal ( ) ) {
87+ return Ok ( ty) ;
88+ }
89+
90+ let ty = ty. try_super_fold_with ( self ) ?;
91+ if let ty:: Projection ( ..) | ty:: Opaque ( ..) = ty. kind ( ) {
92+ Ok ( self
93+ . tcx
94+ . try_normalize_generic_arg_after_erasing_regions ( self . param_env . and ( ty. into ( ) ) ) ?
95+ . expect_ty ( ) )
96+ } else {
97+ Ok ( ty)
98+ }
99+ }
100+
101+ fn try_fold_const ( & mut self , c : ty:: Const < ' tcx > ) -> Result < ty:: Const < ' tcx > , Self :: Error > {
102+ try_normalize_after_erasing_regions ( self . tcx , self . param_env , c)
103+ }
104+ }
105+
55106fn not_outlives_predicate < ' tcx > ( p : ty:: Predicate < ' tcx > ) -> bool {
56107 match p. kind ( ) . skip_binder ( ) {
57108 ty:: PredicateKind :: RegionOutlives ( ..) | ty:: PredicateKind :: TypeOutlives ( ..) => false ,
0 commit comments