@@ -22,7 +22,7 @@ pub enum ConstKind<I: Interner> {
2222 Param ( I :: ParamConst ) ,
2323
2424 /// Infer the value of the const.
25- Infer ( I :: InferConst ) ,
25+ Infer ( InferConst ) ,
2626
2727 /// Bound const variable, used only when preparing a trait query.
2828 Bound ( DebruijnIndex , I :: BoundConst ) ,
@@ -65,7 +65,6 @@ const fn const_kind_discriminant<I: Interner>(value: &ConstKind<I>) -> usize {
6565impl < CTX : crate :: HashStableContext , I : Interner > HashStable < CTX > for ConstKind < I >
6666where
6767 I :: ParamConst : HashStable < CTX > ,
68- I :: InferConst : HashStable < CTX > ,
6968 I :: BoundConst : HashStable < CTX > ,
7069 I :: PlaceholderConst : HashStable < CTX > ,
7170 I :: AliasConst : HashStable < CTX > ,
@@ -136,3 +135,77 @@ impl<I: Interner> DebugWithInfcx<I> for ConstKind<I> {
136135 }
137136 }
138137}
138+
139+ rustc_index:: newtype_index! {
140+ /// A **`const`** **v**ariable **ID**.
141+ #[ debug_format = "?{}c" ]
142+ #[ gate_rustc_only]
143+ pub struct ConstVid { }
144+ }
145+
146+ rustc_index:: newtype_index! {
147+ /// An **effect** **v**ariable **ID**.
148+ ///
149+ /// Handling effect infer variables happens separately from const infer variables
150+ /// because we do not want to reuse any of the const infer machinery. If we try to
151+ /// relate an effect variable with a normal one, we would ICE, which can catch bugs
152+ /// where we are not correctly using the effect var for an effect param. Fallback
153+ /// is also implemented on top of having separate effect and normal const variables.
154+ #[ debug_format = "?{}e" ]
155+ #[ gate_rustc_only]
156+ pub struct EffectVid { }
157+ }
158+
159+ /// An inference variable for a const, for use in const generics.
160+ #[ derive( Copy , Clone , Eq , PartialEq , PartialOrd , Ord , Hash ) ]
161+ #[ cfg_attr( feature = "nightly" , derive( TyEncodable , TyDecodable ) ) ]
162+ pub enum InferConst {
163+ /// Infer the value of the const.
164+ Var ( ConstVid ) ,
165+ /// Infer the value of the effect.
166+ ///
167+ /// For why this is separate from the `Var` variant above, see the
168+ /// documentation on `EffectVid`.
169+ EffectVar ( EffectVid ) ,
170+ /// A fresh const variable. See `infer::freshen` for more details.
171+ Fresh ( u32 ) ,
172+ }
173+
174+ impl fmt:: Debug for InferConst {
175+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
176+ match self {
177+ InferConst :: Var ( var) => write ! ( f, "{var:?}" ) ,
178+ InferConst :: EffectVar ( var) => write ! ( f, "{var:?}" ) ,
179+ InferConst :: Fresh ( var) => write ! ( f, "Fresh({var:?})" ) ,
180+ }
181+ }
182+ }
183+ impl < I : Interner > DebugWithInfcx < I > for InferConst {
184+ fn fmt < Infcx : InferCtxtLike < Interner = I > > (
185+ this : WithInfcx < ' _ , Infcx , & Self > ,
186+ f : & mut core:: fmt:: Formatter < ' _ > ,
187+ ) -> core:: fmt:: Result {
188+ match this. infcx . universe_of_ct ( * this. data ) {
189+ None => write ! ( f, "{:?}" , this. data) ,
190+ Some ( universe) => match * this. data {
191+ InferConst :: Var ( vid) => write ! ( f, "?{}_{}c" , vid. index( ) , universe. index( ) ) ,
192+ InferConst :: EffectVar ( vid) => write ! ( f, "?{}_{}e" , vid. index( ) , universe. index( ) ) ,
193+ InferConst :: Fresh ( _) => {
194+ unreachable ! ( )
195+ }
196+ } ,
197+ }
198+ }
199+ }
200+
201+ #[ cfg( feature = "nightly" ) ]
202+ impl < CTX > HashStable < CTX > for InferConst {
203+ fn hash_stable ( & self , hcx : & mut CTX , hasher : & mut StableHasher ) {
204+ match self {
205+ InferConst :: Var ( _) | InferConst :: EffectVar ( _) => {
206+ panic ! ( "const variables should not be hashed: {self:?}" )
207+ }
208+ InferConst :: Fresh ( i) => i. hash_stable ( hcx, hasher) ,
209+ }
210+ }
211+ }
0 commit comments