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