@@ -46,6 +46,7 @@ pub enum Type {
4646 Record ( RecordTypeId ) ,
4747 OneOf ( OneOfId ) ,
4848 Ref ( TypeDeclId ) ,
49+ ExVar ( ExVarId ) ,
4950 Error ,
5051}
5152
@@ -78,6 +79,7 @@ pub const BYTE_STREAM_TYPE: TypeId = TypeId(13);
7879pub const ERROR_TYPE : TypeId = TypeId ( 14 ) ;
7980pub const TOP_TYPE : TypeId = TypeId ( 15 ) ;
8081
82+ #[ derive( Debug , Clone , PartialEq , Eq ) ]
8183pub struct ExVarId ( pub usize ) ;
8284
8385pub struct Typechecker < ' a > {
@@ -87,7 +89,7 @@ pub struct Typechecker<'a> {
8789 /// Types referenced by TypeId
8890 types : Vec < Type > ,
8991 /// Existential type variables referenced by ExVarId
90- ex_vars : Vec < ( ) > ,
92+ ex_vars : Vec < Option < TypeId > > ,
9193
9294 /// Types of nodes. Each type in this vector matches a node in compiler.ast_nodes at the same position.
9395 pub node_types : Vec < TypeId > ,
@@ -1025,6 +1027,35 @@ impl<'a> Typechecker<'a> {
10251027 }
10261028 }
10271029
1030+ /// Try constraining `sub` to be a subtype of `supe`. Returns whether it was successful
1031+ fn constrain_subtype ( & mut self , sub : TypeId , supe : TypeId ) -> bool {
1032+ match ( self . types [ sub. 0 ] , self . types [ supe. 0 ] ) {
1033+ ( Type :: ExVar ( a) , Type :: ExVar ( b) ) => a == b,
1034+ ( Type :: ExVar ( a) , b) => todo ! ( ) ,
1035+ ( a, Type :: ExVar ( b) ) => todo ! ( ) ,
1036+ // todo handle lists, unions, and records containing existential variables within
1037+ ( a, b) => self . is_subtype ( a, b) ,
1038+ }
1039+ }
1040+
1041+ /// Constrain an existential variable to be a subtype of `supe`
1042+ fn constrain_ex_sub ( & mut self , ex : ExVarId , supe : TypeId ) {
1043+ match self . types [ supe. 0 ] {
1044+ Type :: ExVar ( other) => {
1045+ if ex. 0 < other. 0 {
1046+ self . ex_vars [ other. 0 ] = ex;
1047+ } else {
1048+ todo ! ( "add constraint that ex = other" ) ;
1049+ }
1050+ }
1051+ }
1052+ }
1053+
1054+ /// Constrain an existential variable to be a supertype of `sub`
1055+ fn constrain_ex_supe ( & mut self , ex : ExVarId , sub : TypeId ) {
1056+ todo ! ( )
1057+ }
1058+
10281059 /// Check if `sub` is a subtype of `supe`
10291060 fn is_subtype ( & self , sub : Type , supe : Type ) -> bool {
10301061 match ( sub, supe) {
0 commit comments