@@ -12,12 +12,31 @@ use rustc_target::abi::Size;
1212
1313use super :: ScalarInt ;
1414/// An unevaluated, potentially generic, constant.
15- #[ derive( Copy , Clone , Debug , Eq , PartialEq , PartialOrd , Ord , TyEncodable , TyDecodable ) ]
15+ #[ derive( Copy , Clone , Debug , Eq , PartialEq , PartialOrd , Ord , TyEncodable , TyDecodable , Lift ) ]
1616#[ derive( Hash , HashStable ) ]
17- pub struct Unevaluated < ' tcx > {
17+ pub struct Unevaluated < ' tcx , P = Option < Promoted > > {
1818 pub def : ty:: WithOptConstParam < DefId > ,
1919 pub substs : SubstsRef < ' tcx > ,
20- pub promoted : Option < Promoted > ,
20+ pub promoted : P ,
21+ }
22+
23+ impl < ' tcx > Unevaluated < ' tcx > {
24+ pub fn shrink ( self ) -> Unevaluated < ' tcx , ( ) > {
25+ debug_assert_eq ! ( self . promoted, None ) ;
26+ Unevaluated { def : self . def , substs : self . substs , promoted : ( ) }
27+ }
28+ }
29+
30+ impl < ' tcx > Unevaluated < ' tcx , ( ) > {
31+ pub fn expand ( self ) -> Unevaluated < ' tcx > {
32+ Unevaluated { def : self . def , substs : self . substs , promoted : None }
33+ }
34+ }
35+
36+ impl < ' tcx , P : Default > Unevaluated < ' tcx , P > {
37+ pub fn new ( def : ty:: WithOptConstParam < DefId > , substs : SubstsRef < ' tcx > ) -> Unevaluated < ' tcx , P > {
38+ Unevaluated { def, substs, promoted : Default :: default ( ) }
39+ }
2140}
2241
2342/// Represents a constant in Rust.
@@ -109,7 +128,7 @@ impl<'tcx> ConstKind<'tcx> {
109128 tcx : TyCtxt < ' tcx > ,
110129 param_env : ParamEnv < ' tcx > ,
111130 ) -> Option < Result < ConstValue < ' tcx > , ErrorReported > > {
112- if let ConstKind :: Unevaluated ( Unevaluated { def , substs , promoted } ) = self {
131+ if let ConstKind :: Unevaluated ( unevaluated ) = self {
113132 use crate :: mir:: interpret:: ErrorHandled ;
114133
115134 // HACK(eddyb) this erases lifetimes even though `const_eval_resolve`
@@ -118,29 +137,32 @@ impl<'tcx> ConstKind<'tcx> {
118137 // Note that we erase regions *before* calling `with_reveal_all_normalized`,
119138 // so that we don't try to invoke this query with
120139 // any region variables.
121- let param_env_and_substs = tcx
140+ let param_env_and = tcx
122141 . erase_regions ( param_env)
123142 . with_reveal_all_normalized ( tcx)
124- . and ( tcx. erase_regions ( substs ) ) ;
143+ . and ( tcx. erase_regions ( unevaluated ) ) ;
125144
126145 // HACK(eddyb) when the query key would contain inference variables,
127146 // attempt using identity substs and `ParamEnv` instead, that will succeed
128147 // when the expression doesn't depend on any parameters.
129148 // FIXME(eddyb, skinny121) pass `InferCtxt` into here when it's available, so that
130149 // we can call `infcx.const_eval_resolve` which handles inference variables.
131- let param_env_and_substs = if param_env_and_substs. needs_infer ( ) {
132- tcx. param_env ( def. did ) . and ( InternalSubsts :: identity_for_item ( tcx, def. did ) )
150+ let param_env_and = if param_env_and. needs_infer ( ) {
151+ tcx. param_env ( unevaluated. def . did ) . and ( ty:: Unevaluated {
152+ def : unevaluated. def ,
153+ substs : InternalSubsts :: identity_for_item ( tcx, unevaluated. def . did ) ,
154+ promoted : unevaluated. promoted ,
155+ } )
133156 } else {
134- param_env_and_substs
157+ param_env_and
135158 } ;
136159
137160 // FIXME(eddyb) maybe the `const_eval_*` methods should take
138- // `ty::ParamEnvAnd<SubstsRef> ` instead of having them separate.
139- let ( param_env, substs ) = param_env_and_substs . into_parts ( ) ;
161+ // `ty::ParamEnvAnd` instead of having them separate.
162+ let ( param_env, unevaluated ) = param_env_and . into_parts ( ) ;
140163 // try to resolve e.g. associated constants to their definition on an impl, and then
141164 // evaluate the const.
142- match tcx. const_eval_resolve ( param_env, ty:: Unevaluated { def, substs, promoted } , None )
143- {
165+ match tcx. const_eval_resolve ( param_env, unevaluated, None ) {
144166 // NOTE(eddyb) `val` contains no lifetimes/types/consts,
145167 // and we use the original type, so nothing from `substs`
146168 // (which may be identity substs, see above),
0 commit comments