made type constraints nicer to use
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 12 Nov 2021 18:12:44 +0000 (12:12 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 12 Nov 2021 18:12:44 +0000 (12:12 -0600)
core/container/map.onyx
include/astnodes.h
include/bh.h
src/checker.c
src/parser.c
src/polymorph.c
src/utils.c

index 02ad27992c4feb40729a711e6d74c51ad6476911..f99b5dd80d173ed160c923080331cca682d7f3ec 100644 (file)
@@ -11,6 +11,10 @@ package core.map
 
 #private_file {
     ValidKey :: interface (T: type_expr) {
+        // In order to use a certain type as a key in a Map, you must
+        // provide an implementation of core.hash.to_u32() for that type,
+        // and you must provide an operator overload for ==.
+
         hash.to_u32(T);
         T == T;
     }
index 4545ce9c57fb40354c7bbb60982b82f6641ee739..6c9e8d5ca802b61b807e37fc92bb801ab2cdf59b 100644 (file)
@@ -251,6 +251,8 @@ typedef enum AstFlags {
     Ast_Flag_Static_If_Resolved    = BH_BIT(17),
 
     Ast_Flag_Symbol_Invisible      = BH_BIT(18),
+
+    Ast_Flag_Header_Check_No_Error = BH_BIT(19),
 } AstFlags;
 
 typedef enum UnaryOp {
@@ -1500,7 +1502,7 @@ AstFunction* polymorphic_proc_lookup(AstPolyProc* pp, PolyProcLookupMethod pp_lo
 AstFunction* polymorphic_proc_solidify(AstPolyProc* pp, bh_arr(AstPolySolution) slns, OnyxToken* tkn);
 AstNode* polymorphic_proc_try_solidify(AstPolyProc* pp, bh_arr(AstPolySolution) slns, OnyxToken* tkn);
 AstFunction* polymorphic_proc_build_only_header(AstPolyProc* pp, PolyProcLookupMethod pp_lookup, ptr actual);
-AstFunction* polymorphic_proc_build_only_header_with_slns(AstPolyProc* pp, bh_arr(AstPolySolution) slns);
+AstFunction* polymorphic_proc_build_only_header_with_slns(AstPolyProc* pp, bh_arr(AstPolySolution) slns, b32 error_if_failed);
 
 void add_overload_option(bh_arr(OverloadOption)* poverloads, u64 precedence, AstTyped* overload);
 AstTyped* find_matching_overload_by_arguments(bh_arr(OverloadOption) overloads, Arguments* args);
@@ -1508,7 +1510,7 @@ AstTyped* find_matching_overload_by_type(bh_arr(OverloadOption) overloads, Type*
 void report_unable_to_match_overload(AstCall* call);
 
 void expand_macro(AstCall** pcall, AstFunction* template);
-AstFunction* macro_resolve_header(AstMacro* macro, Arguments* args, OnyxToken* callsite);
+AstFunction* macro_resolve_header(AstMacro* macro, Arguments* args, OnyxToken* callsite, b32 error_if_failed);
 
 Type* polymorphic_struct_lookup(AstPolyStructType* ps_type, bh_arr(AstPolySolution) slns, OnyxFilePos pos);
 
@@ -1520,7 +1522,8 @@ static inline b32 is_lval(AstNode* node) {
         || (node->kind == Ast_Kind_Dereference)
         || (node->kind == Ast_Kind_Subscript)
         || (node->kind == Ast_Kind_Field_Access)
-        || (node->kind == Ast_Kind_Memres))
+        || (node->kind == Ast_Kind_Memres)
+        || (node->kind == Ast_Kind_Constraint_Sentinel)) // Bit of a hack, but this makes constraints like 'T->foo()' work.
         return 1;
 
     if (node->kind == Ast_Kind_Compound) {
index a3a56f19ce10a1b8a2d394caff74b61395dcb02e..dd33f3e98d15761dd7f997de3bfbca08fa48a1fe 100644 (file)
@@ -180,7 +180,7 @@ u8* double_to_ieee754(f64 f, b32 reverse);
 
 #define bh_pointer_add(ptr, amm)        ((void *)((u8 *) ptr + amm))
 #define BH_BIT(x)                        (1 << (x))
-#define BH_MASK_SET(var, set, mask)     ((set) ? (var) |= (mask) : (var) &= ~(mask))
+#define BH_MASK_SET(var, set, mask)     ((set) ? ((var) |= (mask)) : ((var) &= ~(mask)))
 
 #define fori(var, lo, hi)                 for (i64 var = (lo); var < (hi); var++)
 #define forir(var, hi, lo)                for (i64 var = (hi); var >= (lo); var--)
index 70395c3525e0947fcff34326be2154e2760b3988..253f4db72f099df981c6130db54d3bfee20948bc 100644 (file)
@@ -433,7 +433,7 @@ static CheckStatus check_resolve_callee(AstCall* call, AstTyped** effective_call
         calling_a_macro = 1;
         call->callee = callee;
 
-        AstTyped* new_callee = (AstTyped *) macro_resolve_header((AstMacro *) callee, &call->args, call->token);
+        AstTyped* new_callee = (AstTyped *) macro_resolve_header((AstMacro *) callee, &call->args, call->token, 1);
         if (new_callee == NULL) return Check_Error;
         if (new_callee == (AstTyped *) &node_that_signals_a_yield) {
             YIELD(call->token->pos, "Waiting for macro header to pass type-checking.");
@@ -1336,7 +1336,8 @@ CheckStatus check_address_of(AstAddressOf** paof) {
             && expr->kind != Ast_Kind_Dereference
             && expr->kind != Ast_Kind_Field_Access
             && expr->kind != Ast_Kind_Memres
-            && expr->kind != Ast_Kind_Local)
+            && expr->kind != Ast_Kind_Local
+            && expr->kind != Ast_Kind_Constraint_Sentinel)
             || (expr->flags & Ast_Flag_Cannot_Take_Addr) != 0) {
         ERROR_(aof->token->pos, "Cannot take the address of something that is not an l-value. %s", onyx_ast_node_kind_string(expr->kind));
     }
@@ -2028,7 +2029,10 @@ CheckStatus check_struct_defaults(AstStructType* s_node) {
 CheckStatus check_temp_function_header(AstFunction* func) {
     CheckStatus cs = check_function_header(func);
     if (cs == Check_Error) {
-        onyx_clear_errors();
+        if (func->flags & Ast_Flag_Header_Check_No_Error) {
+            onyx_clear_errors();
+        }
+
         return Check_Failed;
     }
 
index 50b57a7bba9ada8873ae9305511ec339e23cd9ad..263fd460cd88a2066116192c8a50af4b207c205a 100644 (file)
@@ -2373,6 +2373,7 @@ static b32 parse_possible_function_definition_no_consume(OnyxParser* parser) {
             && token_after_paren->type != '{'
             && token_after_paren->type != Token_Type_Keyword_Do
             && token_after_paren->type != Token_Type_Empty_Block
+            && token_after_paren->type != Token_Type_Keyword_Where
             && (token_after_paren->type != '=' || (token_after_paren + 1)->type != '>'))
             return 0;
 
index 7af1daaf158f74e731af23d3eb846268d3709e48..dda7b615f67bf4df9abd4f3b621adff3481338a9 100644 (file)
@@ -708,10 +708,10 @@ AstFunction* polymorphic_proc_build_only_header(AstPolyProc* pp, PolyProcLookupM
 
     ensure_polyproc_cache_is_created(pp);
 
-    return polymorphic_proc_build_only_header_with_slns(pp, slns);
+    return polymorphic_proc_build_only_header_with_slns(pp, slns, 0);
 }
 
-AstFunction* polymorphic_proc_build_only_header_with_slns(AstPolyProc* pp, bh_arr(AstPolySolution) slns) {
+AstFunction* polymorphic_proc_build_only_header_with_slns(AstPolyProc* pp, bh_arr(AstPolySolution) slns, b32 error_if_failed) {
     AstSolidifiedFunction solidified_func;
 
     char* unique_key = build_poly_slns_unique_key(slns);
@@ -732,6 +732,8 @@ AstFunction* polymorphic_proc_build_only_header_with_slns(AstPolyProc* pp, bh_ar
         return (AstFunction *) &node_that_signals_a_yield;
     }
 
+    BH_MASK_SET(solidified_func.func->flags, !error_if_failed, Ast_Flag_Header_Check_No_Error);
+
     Entity func_header_entity = {
         .state = Entity_State_Resolve_Symbols,
         .type = Entity_Type_Temp_Function_Header,
index a4b3642ee9dc568af6d89d9f868ff2e8210ca947..ddd436a58b3b5b230f13d898d7372f9ec0c083b7 100644 (file)
@@ -358,7 +358,7 @@ AstTyped* find_matching_overload_by_arguments(bh_arr(OverloadOption) overloads,
         AstFunction* overload = NULL;
         switch (node->kind) {
             case Ast_Kind_Function:         overload = (AstFunction *) node; break;
-            case Ast_Kind_Macro:            overload = macro_resolve_header((AstMacro *) node, param_args, NULL); break;
+            case Ast_Kind_Macro:            overload = macro_resolve_header((AstMacro *) node, param_args, NULL, 0); break;
             case Ast_Kind_Polymorphic_Proc: overload = polymorphic_proc_build_only_header((AstPolyProc *) node, PPLM_By_Arguments, param_args); break;
         }
 
@@ -514,7 +514,7 @@ void expand_macro(AstCall** pcall, AstFunction* template) {
     return;
 }
 
-AstFunction* macro_resolve_header(AstMacro* macro, Arguments* args, OnyxToken* callsite) {
+AstFunction* macro_resolve_header(AstMacro* macro, Arguments* args, OnyxToken* callsite, b32 error_if_failed) {
     switch (macro->body->kind) {
         case Ast_Kind_Function: return (AstFunction *) macro->body;
 
@@ -536,8 +536,7 @@ AstFunction* macro_resolve_header(AstMacro* macro, Arguments* args, OnyxToken* c
                 return NULL;
             }
 
-            // CLEANUP Copy'n'pasted from polymorphic_proc_build_only_header
-            return polymorphic_proc_build_only_header_with_slns(pp, slns);
+            return polymorphic_proc_build_only_header_with_slns(pp, slns, error_if_failed);
         }
 
         default: assert(("Bad macro body type.", 0));