@@ -971,18 +971,39 @@ impl<'tcx> rustc_type_ir::Flags for Clauses<'tcx> {
971971#[ derive( Debug , Copy , Clone , Hash , PartialEq , Eq ) ]
972972#[ derive( HashStable , TypeVisitable , TypeFoldable ) ]
973973pub struct ParamEnvInner < ' tcx > {
974- /// Caller bounds are `Obligation`s that the caller must satisfy. This is
975- /// basically the set of bounds on the in-scope type parameters, translated
976- /// into `Obligation`s, and elaborated and normalized.
977- ///
978- /// Use the `caller_bounds()` method to access.
979- caller_bounds : Clauses < ' tcx > ,
980- }
981-
982- /// When interacting with the type system we must provide information about the
983- /// environment. `ParamEnv` is the type that represents this information. See the
974+ /// Corresponds to `where Foo: Bar<A, B, C>`. `Foo` here would be
975+ /// the `Self` type of the trait reference and `A`, `B`, and `C`
976+ /// would be the type parameters.
977+ trait_clauses : Clauses < ' tcx > ,
978+ /// `where 'a: 'r`
979+ region_outlives_clauses : Clauses < ' tcx > ,
980+ /// `where T: 'r`
981+ type_outlives_clauses : Clauses < ' tcx > ,
982+ /// `where <T as TraitRef>::Name == X`, approximately.
983+ /// See the `ProjectionPredicate` struct for details.
984+ projection_clauses : Clauses < ' tcx > ,
985+ /// Ensures that a const generic argument to a parameter `const N: u8`
986+ /// is of type `u8`.
987+ const_arg_has_type_clauses : Clauses < ' tcx > ,
988+ /// No syntax: `T` well-formed.
989+ well_formed_clauses : Clauses < ' tcx > ,
990+ /// Constant initializer must evaluate successfully.
991+ const_evaluatable_clauses : Clauses < ' tcx > ,
992+ /// Enforces the constness of the predicate we're calling. Like a projection
993+ /// goal from a where clause, it's always going to be paired with a
994+ /// corresponding trait clause; this just enforces the *constness* of that
995+ /// implementation.
996+ host_effect_clauses : Clauses < ' tcx > ,
997+ }
998+
999+ /// When interacting with the type system we must provide information about the environment.
1000+ /// `ParamEnv` is the type that represents this information. See the
9841001/// [dev guide chapter][param_env_guide] for more information.
9851002///
1003+ /// Contains various kinds of caller bounds - `Obligation`s that the caller must satisfy. This is
1004+ /// basically the set of bounds on the in-scope type parameters, translated into `Obligation`s,
1005+ /// and elaborated and normalized.
1006+ ///
9861007/// [param_env_guide]: https://rustc-dev-guide.rust-lang.org/typing_parameter_envs.html
9871008#[ derive( Debug , Copy , Clone , Hash , PartialEq , Eq ) ]
9881009#[ derive( HashStable ) ]
@@ -997,64 +1018,117 @@ impl<'tcx> ParamEnv<'tcx> {
9971018 /// [param_env_guide]: https://rustc-dev-guide.rust-lang.org/typing_parameter_envs.html
9981019 #[ inline]
9991020 pub fn empty ( tcx : TyCtxt < ' tcx > ) -> Self {
1000- tcx. mk_param_env ( ParamEnvInner { caller_bounds : ListWithCachedTypeInfo :: empty ( ) } )
1021+ tcx. mk_param_env ( ParamEnvInner {
1022+ trait_clauses : ListWithCachedTypeInfo :: empty ( ) ,
1023+ region_outlives_clauses : ListWithCachedTypeInfo :: empty ( ) ,
1024+ type_outlives_clauses : ListWithCachedTypeInfo :: empty ( ) ,
1025+ projection_clauses : ListWithCachedTypeInfo :: empty ( ) ,
1026+ const_arg_has_type_clauses : ListWithCachedTypeInfo :: empty ( ) ,
1027+ well_formed_clauses : ListWithCachedTypeInfo :: empty ( ) ,
1028+ const_evaluatable_clauses : ListWithCachedTypeInfo :: empty ( ) ,
1029+ host_effect_clauses : ListWithCachedTypeInfo :: empty ( ) ,
1030+ } )
10011031 }
10021032
10031033 #[ inline]
10041034 pub fn all_clauses ( self ) -> impl Iterator < Item = Clause < ' tcx > > {
1005- self . 0 . 0 . caller_bounds . iter ( )
1035+ let trait_clauses = self . 0 . 0 . trait_clauses . iter ( ) ;
1036+ let region_outlives_clauses = self . 0 . 0 . region_outlives_clauses . iter ( ) ;
1037+ let type_outlives_clauses = self . 0 . 0 . type_outlives_clauses . iter ( ) ;
1038+ let projection_clauses = self . 0 . 0 . projection_clauses . iter ( ) ;
1039+ let const_arg_has_type_clauses = self . 0 . 0 . const_arg_has_type_clauses . iter ( ) ;
1040+ let well_formed_clauses = self . 0 . 0 . well_formed_clauses . iter ( ) ;
1041+ let const_evaluatable_clauses = self . 0 . 0 . const_evaluatable_clauses . iter ( ) ;
1042+ let host_effect_clauses = self . 0 . 0 . host_effect_clauses . iter ( ) ;
1043+
1044+ trait_clauses. chain ( region_outlives_clauses. chain ( type_outlives_clauses. chain (
1045+ projection_clauses. chain ( const_arg_has_type_clauses. chain (
1046+ well_formed_clauses. chain ( const_evaluatable_clauses. chain ( host_effect_clauses) ) ,
1047+ ) ) ,
1048+ ) ) )
10061049 }
10071050
10081051 #[ inline]
10091052 pub fn trait_clauses ( self ) -> impl Iterator < Item = PolyTraitPredicate < ' tcx > > {
1010- self . 0 . 0 . caller_bounds . iter ( ) . filter_map ( |c| c. as_trait_clause ( ) )
1053+ self . 0 . 0 . trait_clauses . iter ( ) . filter_map ( |c| c. as_trait_clause ( ) )
10111054 }
10121055
10131056 #[ inline]
10141057 pub fn region_outlives_clauses (
10151058 self ,
10161059 ) -> impl Iterator < Item = PolyRegionOutlivesPredicate < ' tcx > > {
1017- self . 0 . 0 . caller_bounds . iter ( ) . filter_map ( |c| c. as_region_outlives_clause ( ) )
1060+ self . 0 . 0 . region_outlives_clauses . iter ( ) . filter_map ( |c| c. as_region_outlives_clause ( ) )
10181061 }
10191062
10201063 #[ inline]
10211064 pub fn type_outlives_clauses ( self ) -> impl Iterator < Item = PolyTypeOutlivesPredicate < ' tcx > > {
1022- self . 0 . 0 . caller_bounds . iter ( ) . filter_map ( |c| c. as_type_outlives_clause ( ) )
1065+ self . 0 . 0 . type_outlives_clauses . iter ( ) . filter_map ( |c| c. as_type_outlives_clause ( ) )
10231066 }
10241067
10251068 #[ inline]
10261069 pub fn projection_clauses ( self ) -> impl Iterator < Item = PolyProjectionPredicate < ' tcx > > {
1027- self . 0 . 0 . caller_bounds . iter ( ) . filter_map ( |c| c. as_projection_clause ( ) )
1070+ self . 0 . 0 . projection_clauses . iter ( ) . filter_map ( |c| c. as_projection_clause ( ) )
10281071 }
10291072
10301073 #[ inline]
10311074 pub fn const_arg_has_type_clauses (
10321075 self ,
10331076 ) -> impl Iterator < Item = PolyConstArgHasTypePredicate < ' tcx > > {
1034- self . 0 . 0 . caller_bounds . iter ( ) . filter_map ( |c| c. as_const_arg_has_type_clause ( ) )
1077+ self . 0 . 0 . const_arg_has_type_clauses . iter ( ) . filter_map ( |c| c. as_const_arg_has_type_clause ( ) )
10351078 }
10361079
10371080 #[ inline]
10381081 pub fn well_formed_clauses ( self ) -> impl Iterator < Item = PolyWellFormedPredicate < ' tcx > > {
1039- self . 0 . 0 . caller_bounds . iter ( ) . filter_map ( |c| c. as_well_formed_clause ( ) )
1082+ self . 0 . 0 . well_formed_clauses . iter ( ) . filter_map ( |c| c. as_well_formed_clause ( ) )
10401083 }
10411084
10421085 #[ inline]
10431086 pub fn const_evaluatable_clauses (
10441087 self ,
10451088 ) -> impl Iterator < Item = PolyConstEvaluatablePredicate < ' tcx > > {
1046- self . 0 . 0 . caller_bounds . iter ( ) . filter_map ( |c| c. as_const_evaluatable_clause ( ) )
1089+ self . 0 . 0 . const_evaluatable_clauses . iter ( ) . filter_map ( |c| c. as_const_evaluatable_clause ( ) )
10471090 }
10481091
10491092 #[ inline]
10501093 pub fn host_effect_clauses ( self ) -> impl Iterator < Item = PolyHostEffectPredicate < ' tcx > > {
1051- self . 0 . 0 . caller_bounds . iter ( ) . filter_map ( |c| c. as_host_effect_clause ( ) )
1094+ self . 0 . 0 . host_effect_clauses . iter ( ) . filter_map ( |c| c. as_host_effect_clause ( ) )
10521095 }
10531096
10541097 /// Construct a trait environment with the given set of predicates.
10551098 #[ inline]
1056- pub fn new ( tcx : TyCtxt < ' tcx > , caller_bounds : Clauses < ' tcx > ) -> Self {
1057- tcx. mk_param_env ( ParamEnvInner { caller_bounds } )
1099+ pub fn from_iter ( tcx : TyCtxt < ' tcx > , clauses : impl Iterator < Item = Clause < ' tcx > > ) -> Self {
1100+ let mut trait_clauses = Vec :: new ( ) ;
1101+ let mut region_outlives_clauses = Vec :: new ( ) ;
1102+ let mut type_outlives_clauses = Vec :: new ( ) ;
1103+ let mut projection_clauses = Vec :: new ( ) ;
1104+ let mut const_arg_has_type_clauses = Vec :: new ( ) ;
1105+ let mut well_formed_clauses = Vec :: new ( ) ;
1106+ let mut const_evaluatable_clauses = Vec :: new ( ) ;
1107+ let mut host_effect_clauses = Vec :: new ( ) ;
1108+
1109+ for clause in clauses {
1110+ match clause. kind ( ) . skip_binder ( ) {
1111+ ClauseKind :: Trait ( ..) => trait_clauses. push ( clause) ,
1112+ ClauseKind :: RegionOutlives ( ..) => region_outlives_clauses. push ( clause) ,
1113+ ClauseKind :: TypeOutlives ( ..) => type_outlives_clauses. push ( clause) ,
1114+ ClauseKind :: Projection ( ..) => projection_clauses. push ( clause) ,
1115+ ClauseKind :: ConstArgHasType ( ..) => const_arg_has_type_clauses. push ( clause) ,
1116+ ClauseKind :: WellFormed ( ..) => well_formed_clauses. push ( clause) ,
1117+ ClauseKind :: ConstEvaluatable ( ..) => const_evaluatable_clauses. push ( clause) ,
1118+ ClauseKind :: HostEffect ( ..) => host_effect_clauses. push ( clause) ,
1119+ }
1120+ }
1121+
1122+ tcx. mk_param_env ( ParamEnvInner {
1123+ trait_clauses : tcx. mk_clauses ( & trait_clauses) ,
1124+ region_outlives_clauses : tcx. mk_clauses ( & region_outlives_clauses) ,
1125+ type_outlives_clauses : tcx. mk_clauses ( & type_outlives_clauses) ,
1126+ projection_clauses : tcx. mk_clauses ( & projection_clauses) ,
1127+ const_arg_has_type_clauses : tcx. mk_clauses ( & const_arg_has_type_clauses) ,
1128+ well_formed_clauses : tcx. mk_clauses ( & well_formed_clauses) ,
1129+ const_evaluatable_clauses : tcx. mk_clauses ( & const_evaluatable_clauses) ,
1130+ host_effect_clauses : tcx. mk_clauses ( & host_effect_clauses) ,
1131+ } )
10581132 }
10591133
10601134 /// Creates a pair of param-env and value for use in queries.
@@ -1065,35 +1139,35 @@ impl<'tcx> ParamEnv<'tcx> {
10651139
10661140impl < ' tcx > rustc_type_ir:: inherent:: ParamEnv < TyCtxt < ' tcx > > for ParamEnv < ' tcx > {
10671141 fn trait_clauses ( self ) -> impl Iterator < Item = Clause < ' tcx > > {
1068- self . all_clauses ( ) . filter ( |c| c . as_trait_clause ( ) . is_some ( ) )
1142+ self . 0 . 0 . trait_clauses . iter ( )
10691143 }
10701144
10711145 fn region_outlives_clauses ( self ) -> impl Iterator < Item = Clause < ' tcx > > {
1072- self . all_clauses ( ) . filter ( |c| c . as_region_outlives_clause ( ) . is_some ( ) )
1146+ self . 0 . 0 . region_outlives_clauses . iter ( )
10731147 }
10741148
10751149 fn type_outlives_clauses ( self ) -> impl Iterator < Item = Clause < ' tcx > > {
1076- self . all_clauses ( ) . filter ( |c| c . as_type_outlives_clause ( ) . is_some ( ) )
1150+ self . 0 . 0 . type_outlives_clauses . iter ( )
10771151 }
10781152
10791153 fn projection_clauses ( self ) -> impl Iterator < Item = Clause < ' tcx > > {
1080- self . all_clauses ( ) . filter ( |c| c . as_projection_clause ( ) . is_some ( ) )
1154+ self . 0 . 0 . projection_clauses . iter ( )
10811155 }
10821156
10831157 fn const_arg_has_type_clauses ( self ) -> impl Iterator < Item = Clause < ' tcx > > {
1084- self . all_clauses ( ) . filter ( |c| c . as_const_arg_has_type_clause ( ) . is_some ( ) )
1158+ self . 0 . 0 . const_arg_has_type_clauses . iter ( )
10851159 }
10861160
10871161 fn well_formed_clauses ( self ) -> impl Iterator < Item = Clause < ' tcx > > {
1088- self . all_clauses ( ) . filter ( |c| c . as_well_formed_clause ( ) . is_some ( ) )
1162+ self . 0 . 0 . well_formed_clauses . iter ( )
10891163 }
10901164
10911165 fn const_evaluatable_clauses ( self ) -> impl Iterator < Item = Clause < ' tcx > > {
1092- self . all_clauses ( ) . filter ( |c| c . as_const_evaluatable_clause ( ) . is_some ( ) )
1166+ self . 0 . 0 . const_evaluatable_clauses . iter ( )
10931167 }
10941168
10951169 fn host_effect_clauses ( self ) -> impl Iterator < Item = Clause < ' tcx > > {
1096- self . all_clauses ( ) . filter ( |c| c . as_host_effect_clause ( ) . is_some ( ) )
1170+ self . 0 . 0 . host_effect_clauses . iter ( )
10971171 }
10981172}
10991173
0 commit comments