@@ -44,7 +44,7 @@ pub fn typecheck_returning_context<'a>(
4444 . map ( |c| ( c. name . clone ( ) , c) )
4545 . collect ( ) ;
4646
47- let enums = hir
47+ let enums: BamlMap < String , hir :: Enum > = hir
4848 . enums
4949 . clone ( )
5050 . into_iter ( )
@@ -54,6 +54,7 @@ pub fn typecheck_returning_context<'a>(
5454 // Create typing context with all functions
5555 let mut typing_context = TypeContext :: new ( ) ;
5656 typing_context. classes . extend ( classes. clone ( ) ) ;
57+ typing_context. enums . extend ( enums. clone ( ) ) ;
5758
5859 // Add expr functions to typing context
5960 for func in & hir. expr_functions {
@@ -271,11 +272,32 @@ pub fn typecheck_returning_context<'a>(
271272 } )
272273 . collect ( ) ;
273274
275+ // TODO: Those are HIR enums, figure out if there's something different we
276+ // would need in a THIR enum? Does it need a "type"?.
277+ let thir_enums = enums
278+ . iter ( )
279+ . map ( |( name, enum_def) | {
280+ (
281+ name. clone ( ) ,
282+ thir:: Enum {
283+ name : enum_def. name . clone ( ) ,
284+ variants : enum_def. variants . clone ( ) ,
285+ span : enum_def. span . clone ( ) ,
286+ ty : TypeIR :: Enum {
287+ name : enum_def. name . clone ( ) ,
288+ dynamic : false ,
289+ meta : Default :: default ( ) ,
290+ } ,
291+ } ,
292+ )
293+ } )
294+ . collect ( ) ;
295+
274296 (
275297 THir {
276298 llm_functions : hir. llm_functions . clone ( ) ,
277299 classes : thir_classes,
278- enums,
300+ enums : thir_enums ,
279301 expr_functions,
280302 global_assignments : BamlMap :: new ( ) ,
281303 } ,
@@ -302,6 +324,7 @@ pub struct TypeContext<'func> {
302324 // Variables in scope with mutability info
303325 pub vars : BamlMap < String , VarInfo > ,
304326 pub classes : BamlMap < String , hir:: Class > ,
327+ pub enums : BamlMap < String , hir:: Enum > ,
305328 // Used for knowing whether `break` and `continue` are inside a loop or not.
306329 pub is_inside_loop : bool ,
307330
@@ -336,6 +359,7 @@ impl TypeContext<'_> {
336359 symbols : BamlMap :: new ( ) ,
337360 vars,
338361 classes : BamlMap :: new ( ) ,
362+ enums : BamlMap :: new ( ) ,
339363 is_inside_loop : false ,
340364 function_return_type : None ,
341365 }
@@ -428,7 +452,9 @@ impl TypeContext<'_> {
428452 }
429453 hir:: Expression :: Identifier ( name, _) => {
430454 // Look up type in context
431- self . get_type ( name) . cloned ( )
455+ self . get_type ( name)
456+ . cloned ( )
457+ . or_else ( || self . enums . get ( name) . map ( |e| TypeIR :: r#enum ( & e. name ) ) )
432458 }
433459 hir:: Expression :: Array ( items, _) => {
434460 // Infer array type from first item
@@ -575,6 +601,14 @@ impl TypeContext<'_> {
575601 None
576602 }
577603 }
604+ TypeIR :: Enum {
605+ name : enum_name, ..
606+ } => {
607+ // Look up field in enum definition
608+ self . enums
609+ . get ( & enum_name)
610+ . map ( |enum_def| TypeIR :: r#enum ( & enum_def. name ) )
611+ }
578612 _ => None , // Not a class
579613 }
580614 } else {
@@ -1162,6 +1196,14 @@ pub fn typecheck_expression(
11621196 BamlValueWithMeta :: String ( value. clone ( ) , ( span. clone ( ) , Some ( TypeIR :: string ( ) ) ) ) ,
11631197 ) ,
11641198 hir:: Expression :: Identifier ( name, span) => {
1199+ // Enum access: let x = Shape.Rectangle
1200+ if let Some ( enum_def) = context. enums . get ( name) {
1201+ return thir:: Expr :: Var (
1202+ name. clone ( ) ,
1203+ ( span. clone ( ) , Some ( TypeIR :: r#enum ( & enum_def. name ) ) ) ,
1204+ ) ;
1205+ }
1206+
11651207 // Look up type in context
11661208 let var_type = context. get_type ( name) . cloned ( ) ;
11671209 if var_type. is_none ( ) {
@@ -1740,6 +1782,20 @@ pub fn typecheck_expression(
17401782 None
17411783 }
17421784 }
1785+ Some ( TypeIR :: Enum {
1786+ name : enum_name, ..
1787+ } ) => {
1788+ // Look up field in enum definition
1789+ if let Some ( enum_def) = context. enums . get ( enum_name) {
1790+ Some ( TypeIR :: r#enum ( & enum_def. name ) )
1791+ } else {
1792+ diagnostics. push_error ( DatamodelError :: new_validation_error (
1793+ & format ! ( "Enum {enum_name} not found" ) ,
1794+ span. clone ( ) ,
1795+ ) ) ;
1796+ None
1797+ }
1798+ }
17431799 _ => {
17441800 diagnostics. push_error ( DatamodelError :: new_validation_error (
17451801 "Can only access fields on class instances" ,
0 commit comments