@@ -12,12 +12,31 @@ use rustc_target::abi::Size;
12
12
13
13
use super :: ScalarInt ;
14
14
/// 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 ) ]
16
16
#[ derive( Hash , HashStable ) ]
17
- pub struct Unevaluated < ' tcx > {
17
+ pub struct Unevaluated < ' tcx , P = Option < Promoted > > {
18
18
pub def : ty:: WithOptConstParam < DefId > ,
19
19
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
+ }
21
40
}
22
41
23
42
/// Represents a constant in Rust.
@@ -109,7 +128,7 @@ impl<'tcx> ConstKind<'tcx> {
109
128
tcx : TyCtxt < ' tcx > ,
110
129
param_env : ParamEnv < ' tcx > ,
111
130
) -> Option < Result < ConstValue < ' tcx > , ErrorReported > > {
112
- if let ConstKind :: Unevaluated ( Unevaluated { def , substs , promoted } ) = self {
131
+ if let ConstKind :: Unevaluated ( unevaluated ) = self {
113
132
use crate :: mir:: interpret:: ErrorHandled ;
114
133
115
134
// HACK(eddyb) this erases lifetimes even though `const_eval_resolve`
@@ -118,29 +137,32 @@ impl<'tcx> ConstKind<'tcx> {
118
137
// Note that we erase regions *before* calling `with_reveal_all_normalized`,
119
138
// so that we don't try to invoke this query with
120
139
// any region variables.
121
- let param_env_and_substs = tcx
140
+ let param_env_and = tcx
122
141
. erase_regions ( param_env)
123
142
. with_reveal_all_normalized ( tcx)
124
- . and ( tcx. erase_regions ( substs ) ) ;
143
+ . and ( tcx. erase_regions ( unevaluated ) ) ;
125
144
126
145
// HACK(eddyb) when the query key would contain inference variables,
127
146
// attempt using identity substs and `ParamEnv` instead, that will succeed
128
147
// when the expression doesn't depend on any parameters.
129
148
// FIXME(eddyb, skinny121) pass `InferCtxt` into here when it's available, so that
130
149
// 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
+ } )
133
156
} else {
134
- param_env_and_substs
157
+ param_env_and
135
158
} ;
136
159
137
160
// 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 ( ) ;
140
163
// try to resolve e.g. associated constants to their definition on an impl, and then
141
164
// 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 ) {
144
166
// NOTE(eddyb) `val` contains no lifetimes/types/consts,
145
167
// and we use the original type, so nothing from `substs`
146
168
// (which may be identity substs, see above),
0 commit comments