@@ -92,7 +92,6 @@ typedef enum CheckStatus {
92
92
Check_Complete , // The node is done processing
93
93
94
94
Check_Errors_Start ,
95
- // Check_Return_To_Symres, // Return this node for further symres processing
96
95
Check_Goto_Parse ,
97
96
Check_Yield ,
98
97
Check_Failed , // The node is done processing and should be put in the state of Failed.
@@ -206,7 +205,7 @@ CHECK_FUNC(symbol, AstNode** symbol_node) {
206
205
OnyxToken * token = (* symbol_node )-> token ;
207
206
AstNode * res = symbol_resolve (context , context -> checker .current_scope , token );
208
207
209
- if (!res ) { // :SymresStall
208
+ if (!res ) {
210
209
if (context -> cycle_detected ) {
211
210
token_toggle_end (token );
212
211
char * closest = find_closest_symbol_in_scope_and_parents (context , context -> checker .current_scope , token -> text );
@@ -435,6 +434,15 @@ CHECK_FUNC(for, AstFor* fornode) {
435
434
CHECK (expression , & fornode -> iter );
436
435
resolve_expression_type (context , fornode -> iter );
437
436
437
+ //
438
+ // These locals have to be checked after the iterator value to avoid incorrect
439
+ // symbol resolutions.
440
+ //
441
+ // for a in x {
442
+ // for a in a { // <-
443
+ // }
444
+ // }
445
+ //
438
446
CHECK (local , & fornode -> var );
439
447
if (fornode -> index_var ) {
440
448
fornode -> index_var -> flags |= Ast_Flag_Cannot_Take_Addr ;
@@ -697,6 +705,15 @@ CHECK_FUNC(case, AstSwitchCase *casenode) {
697
705
}
698
706
699
707
CHECK_FUNC (switch , AstSwitch * switchnode ) {
708
+ //
709
+ // Checking switches is quite complicated and tricky because of the feature-set Onyx
710
+ // supports. Switch bodies can contain arbitrary statements at parse-time, but must
711
+ // be expanded to a tree of block-nodes with case-nodes as the leaves. This complicates
712
+ // the checking, because case-bodies cannot be checked before they know the type of their
713
+ // captured variables (if there are any), but the case values must be checked before the
714
+ // switch node can do proper type checking.
715
+ //
716
+
700
717
if (switchnode -> initialization ) {
701
718
if (switchnode -> scope == NULL ) {
702
719
switchnode -> scope = scope_create (context , context -> checker .current_scope , switchnode -> token -> pos );
@@ -746,11 +763,13 @@ CHECK_FUNC(switch, AstSwitch* switchnode) {
746
763
switchnode -> flags |= Ast_Flag_Has_Been_Checked ;
747
764
}
748
765
749
- // Should the case block code be checked here?
750
- // Or should this just exist to resolve macros and expand #unquotes
751
- // then the cases are consumed into the array or cases, THEN the blocks
752
- // are actually checked?
753
766
if (switchnode -> cases == NULL ) {
767
+ //
768
+ // Set CM_Dont_Check_Case_Bodies so the bodies of case nodes will be skipped.
769
+ // This avoids weird type-checking and symbol resolution issues when a case
770
+ // node comes from an #insert or macro expansion. They will be re-checked
771
+ // fully in the next check_block below.
772
+ //
754
773
enable_mode (context , CM_Dont_Check_Case_Bodies );
755
774
CHECK (block , switchnode -> case_block );
756
775
disable_mode (context , CM_Dont_Check_Case_Bodies );
@@ -2657,7 +2676,6 @@ CHECK_FUNC(field_access, AstFieldAccess** pfield) {
2657
2676
expr -> kind == Ast_Kind_Compiler_Extension ||
2658
2677
expr -> kind == Ast_Kind_Package ) {
2659
2678
goto try_resolve_from_node ;
2660
- // return Check_Return_To_Symres;
2661
2679
}
2662
2680
}
2663
2681
@@ -3768,10 +3786,6 @@ CHECK_FUNC(block, AstBlock* block) {
3768
3786
block -> statement_idx ++ ;
3769
3787
break ;
3770
3788
3771
- // case Check_Return_To_Symres:
3772
- // block->statement_idx = 0;
3773
- // return cs;
3774
-
3775
3789
case Check_Failed :
3776
3790
case Check_Error :
3777
3791
if (block -> macro_generated_from ) {
@@ -3808,7 +3822,6 @@ CHECK_FUNC(polyproc, AstFunction* pp) {
3808
3822
AstParam * param = & pp -> params [p -> idx ];
3809
3823
if (param -> default_value != NULL ) {
3810
3824
CHECK (expression , & param -> default_value );
3811
- // if (onyx_has_errors(context)) return Symres_Error;
3812
3825
}
3813
3826
}
3814
3827
@@ -3837,7 +3850,6 @@ CHECK_FUNC(function, AstFunction* func) {
3837
3850
scope_enter (context , func -> scope );
3838
3851
3839
3852
if ((func -> flags & Ast_Flag_Has_Been_Symres ) == 0 ) {
3840
- // :EliminatingSymres
3841
3853
bh_arr_each (AstParam , param , func -> params ) {
3842
3854
// CLEANUP: Currently, in order to 'use' parameters, the type must be completely
3843
3855
// resolved and built. This is excessive because all that should need to be known
@@ -5552,12 +5564,9 @@ CHECK_FUNC(constraint_context, ConstraintContext *cc, Scope *scope, OnyxFilePos
5552
5564
}
5553
5565
5554
5566
CHECK_FUNC (polyquery , AstPolyQuery * query ) {
5555
- query -> successful_symres = 0 ;
5556
-
5557
5567
if (query -> function_header -> scope == NULL )
5558
5568
query -> function_header -> scope = scope_create (context , query -> proc -> parent_scope_of_poly_proc , query -> token -> pos );
5559
5569
5560
- // query->function_header->flags |= Ast_Flag_Hack_Only_Check_Types;
5561
5570
enable_mode (context , CM_Dont_Resolve_Symbols );
5562
5571
check_temp_function_header (context , query -> function_header );
5563
5572
disable_mode (context , CM_Dont_Resolve_Symbols );
@@ -5578,6 +5587,7 @@ CHECK_FUNC(polyquery, AstPolyQuery *query) {
5578
5587
}
5579
5588
}
5580
5589
5590
+ b32 solved_something = 0 ;
5581
5591
bh_arr_each (AstParam , param , query -> function_header -> params ) {
5582
5592
if (param -> local -> type_node != NULL ) {
5583
5593
context -> checker .resolved_a_symbol = 0 ;
@@ -5588,11 +5598,12 @@ CHECK_FUNC(polyquery, AstPolyQuery *query) {
5588
5598
param -> local -> flags &= ~Ast_Flag_Symbol_Invisible ;
5589
5599
onyx_errors_enable (context );
5590
5600
5591
- if (context -> checker .resolved_a_symbol ) query -> successful_symres = 1 ;
5601
+ if (context -> checker .resolved_a_symbol ) {
5602
+ solved_something = 1 ;
5603
+ }
5592
5604
}
5593
5605
}
5594
5606
5595
- b32 solved_something = 0 ;
5596
5607
i32 solved_count = 0 ;
5597
5608
OnyxError err_msg = { 0 };
5598
5609
@@ -5623,7 +5634,7 @@ CHECK_FUNC(polyquery, AstPolyQuery *query) {
5623
5634
5624
5635
case TYPE_MATCH_YIELD :
5625
5636
case TYPE_MATCH_FAILED : {
5626
- if (query -> successful_symres || solved_something ) continue ;
5637
+ if (solved_something ) continue ;
5627
5638
5628
5639
if (query -> error_on_fail || context -> cycle_detected ) {
5629
5640
ONYX_ERROR (query -> token -> pos , Error_Critical , "Error solving for polymorphic variable '%b'." , param -> poly_sym -> token -> text , param -> poly_sym -> token -> length );
@@ -5647,7 +5658,7 @@ CHECK_FUNC(polyquery, AstPolyQuery *query) {
5647
5658
scope_leave (context );
5648
5659
5649
5660
if (solved_count != bh_arr_length (query -> proc -> poly_params )) {
5650
- if (solved_something || query -> successful_symres ) {
5661
+ if (solved_something ) {
5651
5662
return Check_Yield ;
5652
5663
} else {
5653
5664
return Check_Failed ;
@@ -5824,22 +5835,10 @@ CHECK_FUNC(import, AstImport* import) {
5824
5835
// use X { a, b, c }
5825
5836
bh_arr_each (QualifiedImport , qi , import -> only ) {
5826
5837
AstNode * imported = symbol_resolve (context , import_scope , qi -> symbol_name );
5827
- if (imported == NULL ) { // :SymresStall
5838
+ if (imported == NULL ) {
5828
5839
YIELD_ (qi -> symbol_name -> pos ,
5829
- "The symbol '%b' was not found the package '%s'." ,
5840
+ "The symbol '%b' was not found package '%s'." ,
5830
5841
qi -> symbol_name -> text , qi -> symbol_name -> length , package -> package -> name );
5831
-
5832
- // if (context->checker.report_unresolved_symbols) {
5833
- // // TODO: Change package->name to package->qualified_name when
5834
- // // merged with the documentation generation branch.
5835
- // ONYX_ERROR(qi->symbol_name->pos, Error_Critical,
5836
- // "The symbol '%b' was not found the package '%s'.",
5837
- // qi->symbol_name->text, qi->symbol_name->length, package->package->name);
5838
-
5839
- // return Symres_Error;
5840
- // } else {
5841
- // return Symres_Yield_Macro;
5842
- // }
5843
5842
}
5844
5843
5845
5844
symbol_introduce (context , context -> checker .current_scope , qi -> as_name , imported );
0 commit comments