#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;
}
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 {
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);
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);
|| (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) {
#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--)
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.");
&& 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));
}
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;
}
&& 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;
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);
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,
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;
}
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;
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));