@@ -14,10 +14,16 @@ use rustc_target::abi::Size;
14
14
#[ derive( Hash , HashStable ) ]
15
15
pub struct Unevaluated < ' tcx > {
16
16
pub def : ty:: WithOptConstParam < DefId > ,
17
- pub substs : SubstsRef < ' tcx > ,
17
+ pub non_default_substs : Option < SubstsRef < ' tcx > > ,
18
18
pub promoted : Option < Promoted > ,
19
19
}
20
20
21
+ impl < ' tcx > Unevaluated < ' tcx > {
22
+ pub fn substs ( self , tcx : TyCtxt < ' tcx > ) -> SubstsRef < ' tcx > {
23
+ self . non_default_substs . unwrap_or_else ( || tcx. default_anon_const_substs ( self . def . did ) )
24
+ }
25
+ }
26
+
21
27
/// Represents a constant in Rust.
22
28
#[ derive( Copy , Clone , Debug , Eq , PartialEq , PartialOrd , Ord , TyEncodable , TyDecodable ) ]
23
29
#[ derive( Hash , HashStable ) ]
@@ -102,7 +108,7 @@ impl<'tcx> ConstKind<'tcx> {
102
108
tcx : TyCtxt < ' tcx > ,
103
109
param_env : ParamEnv < ' tcx > ,
104
110
) -> Option < Result < ConstValue < ' tcx > , ErrorReported > > {
105
- if let ConstKind :: Unevaluated ( Unevaluated { def , substs , promoted } ) = self {
111
+ if let ConstKind :: Unevaluated ( unevaluated ) = self {
106
112
use crate :: mir:: interpret:: ErrorHandled ;
107
113
108
114
// HACK(eddyb) this erases lifetimes even though `const_eval_resolve`
@@ -111,29 +117,35 @@ impl<'tcx> ConstKind<'tcx> {
111
117
// Note that we erase regions *before* calling `with_reveal_all_normalized`,
112
118
// so that we don't try to invoke this query with
113
119
// any region variables.
114
- let param_env_and_substs = tcx
120
+ let param_env_and = tcx
115
121
. erase_regions ( param_env)
116
122
. with_reveal_all_normalized ( tcx)
117
- . and ( tcx. erase_regions ( substs ) ) ;
123
+ . and ( tcx. erase_regions ( unevaluated ) ) ;
118
124
119
125
// HACK(eddyb) when the query key would contain inference variables,
120
126
// attempt using identity substs and `ParamEnv` instead, that will succeed
121
127
// when the expression doesn't depend on any parameters.
122
128
// FIXME(eddyb, skinny121) pass `InferCtxt` into here when it's available, so that
123
129
// we can call `infcx.const_eval_resolve` which handles inference variables.
124
- let param_env_and_substs = if param_env_and_substs. needs_infer ( ) {
125
- tcx. param_env ( def. did ) . and ( InternalSubsts :: identity_for_item ( tcx, def. did ) )
130
+ let param_env_and = if param_env_and. needs_infer ( ) {
131
+ tcx. param_env ( unevaluated. def . did ) . and ( ty:: Unevaluated {
132
+ def : unevaluated. def ,
133
+ non_default_substs : Some ( InternalSubsts :: identity_for_item (
134
+ tcx,
135
+ unevaluated. def . did ,
136
+ ) ) ,
137
+ promoted : unevaluated. promoted ,
138
+ } )
126
139
} else {
127
- param_env_and_substs
140
+ param_env_and
128
141
} ;
129
142
130
143
// FIXME(eddyb) maybe the `const_eval_*` methods should take
131
- // `ty::ParamEnvAnd<SubstsRef> ` instead of having them separate.
132
- let ( param_env, substs ) = param_env_and_substs . into_parts ( ) ;
144
+ // `ty::ParamEnvAnd` instead of having them separate.
145
+ let ( param_env, unevaluated ) = param_env_and . into_parts ( ) ;
133
146
// try to resolve e.g. associated constants to their definition on an impl, and then
134
147
// evaluate the const.
135
- match tcx. const_eval_resolve ( param_env, ty:: Unevaluated { def, substs, promoted } , None )
136
- {
148
+ match tcx. const_eval_resolve ( param_env, unevaluated, None ) {
137
149
// NOTE(eddyb) `val` contains no lifetimes/types/consts,
138
150
// and we use the original type, so nothing from `substs`
139
151
// (which may be identity substs, see above),
0 commit comments