@@ -320,7 +320,7 @@ impl<I: Interner> Ty<I> {
320320
321321 /// If this is a `TyData::InferenceVar(d)`, returns `Some(d)` else `None`.
322322 pub fn inference_var ( & self , interner : & I ) -> Option < InferenceVar > {
323- if let TyData :: InferenceVar ( depth) = self . data ( interner) {
323+ if let TyData :: InferenceVar ( depth, _ ) = self . data ( interner) {
324324 Some ( * depth)
325325 } else {
326326 None
@@ -330,7 +330,7 @@ impl<I: Interner> Ty<I> {
330330 /// Returns true if this is a `BoundVar` or `InferenceVar`.
331331 pub fn is_var ( & self , interner : & I ) -> bool {
332332 match self . data ( interner) {
333- TyData :: BoundVar ( _) | TyData :: InferenceVar ( _) => true ,
333+ TyData :: BoundVar ( _) | TyData :: InferenceVar ( _, _ ) => true ,
334334 _ => false ,
335335 }
336336 }
@@ -342,6 +342,32 @@ impl<I: Interner> Ty<I> {
342342 }
343343 }
344344
345+ /// Returns true if this is an `IntTy` or `UintTy`
346+ pub fn is_integer ( & self , interner : & I ) -> bool {
347+ match self . data ( interner) {
348+ TyData :: Apply ( ApplicationTy {
349+ name : TypeName :: Scalar ( Scalar :: Int ( _) ) ,
350+ ..
351+ } )
352+ | TyData :: Apply ( ApplicationTy {
353+ name : TypeName :: Scalar ( Scalar :: Uint ( _) ) ,
354+ ..
355+ } ) => true ,
356+ _ => false ,
357+ }
358+ }
359+
360+ /// Returns true if this is a `FloatTy`
361+ pub fn is_float ( & self , interner : & I ) -> bool {
362+ match self . data ( interner) {
363+ TyData :: Apply ( ApplicationTy {
364+ name : TypeName :: Scalar ( Scalar :: Float ( _) ) ,
365+ ..
366+ } ) => true ,
367+ _ => false ,
368+ }
369+ }
370+
345371 /// True if this type contains "bound" types/lifetimes, and hence
346372 /// needs to be shifted across binders. This is a very inefficient
347373 /// check, intended only for debug assertions, because I am lazy.
@@ -390,7 +416,7 @@ pub enum TyData<I: Interner> {
390416 BoundVar ( BoundVar ) ,
391417
392418 /// Inference variable defined in the current inference context.
393- InferenceVar ( InferenceVar ) ,
419+ InferenceVar ( InferenceVar , TyKind ) ,
394420}
395421
396422impl < I : Interner > TyData < I > {
@@ -682,8 +708,8 @@ impl InferenceVar {
682708 self . index
683709 }
684710
685- pub fn to_ty < I : Interner > ( self , interner : & I ) -> Ty < I > {
686- TyData :: < I > :: InferenceVar ( self ) . intern ( interner)
711+ pub fn to_ty < I : Interner > ( self , interner : & I , kind : TyKind ) -> Ty < I > {
712+ TyData :: < I > :: InferenceVar ( self , kind ) . intern ( interner)
687713 }
688714
689715 pub fn to_lifetime < I : Interner > ( self , interner : & I ) -> Lifetime < I > {
@@ -910,17 +936,34 @@ impl<I: Interner> ApplicationTy<I> {
910936 }
911937}
912938
939+ /// Represents some extra knowledge we may have about the type variable.
940+ /// ```ignore
941+ /// let x: &[u32];
942+ /// let i = 1;
943+ /// x[i]
944+ /// ```
945+ /// In this example, `i` is known to be some type of integer. We can infer that
946+ /// it is `usize` because that is the only integer type that slices have an
947+ /// `Index` impl for. `i` would have a `TyKind` of `Integer` to guide the
948+ /// inference process.
949+ #[ derive( Copy , Clone , Debug , PartialEq , Eq , Hash ) ]
950+ pub enum TyKind {
951+ General ,
952+ Integer ,
953+ Float ,
954+ }
955+
913956#[ derive( Clone , PartialEq , Eq , Hash ) ]
914957pub enum VariableKind < I : Interner > {
915- Ty ,
958+ Ty ( TyKind ) ,
916959 Lifetime ,
917960 Const ( Ty < I > ) ,
918961}
919962
920963impl < I : Interner > VariableKind < I > {
921964 fn to_bound_variable ( & self , interner : & I , bound_var : BoundVar ) -> GenericArg < I > {
922965 match self {
923- VariableKind :: Ty => {
966+ VariableKind :: Ty ( _ ) => {
924967 GenericArgData :: Ty ( TyData :: BoundVar ( bound_var) . intern ( interner) ) . intern ( interner)
925968 }
926969 VariableKind :: Lifetime => {
@@ -1524,7 +1567,7 @@ impl<T: HasInterner> Binders<T> {
15241567 // The new variable is at the front and everything afterwards is shifted up by 1
15251568 let new_var = TyData :: BoundVar ( BoundVar :: new ( DebruijnIndex :: INNERMOST , 0 ) ) . intern ( interner) ;
15261569 let value = op ( new_var) ;
1527- let binders = VariableKinds :: from ( interner, iter:: once ( VariableKind :: Ty ) ) ;
1570+ let binders = VariableKinds :: from ( interner, iter:: once ( VariableKind :: Ty ( TyKind :: General ) ) ) ;
15281571 Binders { binders, value }
15291572 }
15301573
@@ -1940,7 +1983,7 @@ impl<T: HasInterner> UCanonical<T> {
19401983 . map ( |( index, pk) | {
19411984 let bound_var = BoundVar :: new ( DebruijnIndex :: INNERMOST , index) ;
19421985 match & pk. kind {
1943- VariableKind :: Ty => {
1986+ VariableKind :: Ty ( _ ) => {
19441987 GenericArgData :: Ty ( TyData :: BoundVar ( bound_var) . intern ( interner) )
19451988 . intern ( interner)
19461989 }
0 commit comments