@@ -14,10 +14,16 @@ use rustc_target::abi::Size;
1414#[ derive( Hash , HashStable ) ]
1515pub struct Unevaluated < ' tcx > {
1616 pub def : ty:: WithOptConstParam < DefId > ,
17- pub substs : SubstsRef < ' tcx > ,
17+ pub non_default_substs : Option < SubstsRef < ' tcx > > ,
1818 pub promoted : Option < Promoted > ,
1919}
2020
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+
2127/// Represents a constant in Rust.
2228#[ derive( Copy , Clone , Debug , Eq , PartialEq , PartialOrd , Ord , TyEncodable , TyDecodable ) ]
2329#[ derive( Hash , HashStable ) ]
@@ -102,7 +108,7 @@ impl<'tcx> ConstKind<'tcx> {
102108 tcx : TyCtxt < ' tcx > ,
103109 param_env : ParamEnv < ' tcx > ,
104110 ) -> Option < Result < ConstValue < ' tcx > , ErrorReported > > {
105- if let ConstKind :: Unevaluated ( Unevaluated { def , substs , promoted } ) = self {
111+ if let ConstKind :: Unevaluated ( unevaluated ) = self {
106112 use crate :: mir:: interpret:: ErrorHandled ;
107113
108114 // HACK(eddyb) this erases lifetimes even though `const_eval_resolve`
@@ -111,29 +117,35 @@ impl<'tcx> ConstKind<'tcx> {
111117 // Note that we erase regions *before* calling `with_reveal_all_normalized`,
112118 // so that we don't try to invoke this query with
113119 // any region variables.
114- let param_env_and_substs = tcx
120+ let param_env_and = tcx
115121 . erase_regions ( param_env)
116122 . with_reveal_all_normalized ( tcx)
117- . and ( tcx. erase_regions ( substs ) ) ;
123+ . and ( tcx. erase_regions ( unevaluated ) ) ;
118124
119125 // HACK(eddyb) when the query key would contain inference variables,
120126 // attempt using identity substs and `ParamEnv` instead, that will succeed
121127 // when the expression doesn't depend on any parameters.
122128 // FIXME(eddyb, skinny121) pass `InferCtxt` into here when it's available, so that
123129 // 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+ } )
126139 } else {
127- param_env_and_substs
140+ param_env_and
128141 } ;
129142
130143 // 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 ( ) ;
133146 // try to resolve e.g. associated constants to their definition on an impl, and then
134147 // 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 ) {
137149 // NOTE(eddyb) `val` contains no lifetimes/types/consts,
138150 // and we use the original type, so nothing from `substs`
139151 // (which may be identity substs, see above),
0 commit comments