void expand_macro(AstCall** pcall, AstFunction* template);
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);
+Type* polymorphic_struct_lookup(AstPolyStructType* ps_type, bh_arr(AstPolySolution) slns, OnyxFilePos pos, b32 error_if_failed);
// NOTE: Useful inlined functions
static inline b32 is_lval(AstNode* node) {
YIELD(s_node->token->pos, "Waiting for struct member defaults to pass symbol resolution.");
if (s_node->constraints.constraints) {
- s_node->constraints.produce_errors = 1;
+ s_node->constraints.produce_errors = (s_node->flags & Ast_Flag_Header_Check_No_Error) == 0;
CHECK(constraint_context, &s_node->constraints, s_node->scope, s_node->token->pos);
}
expect_default_param = 1;
}
- if (local->type_node != NULL) CHECK(type, local->type_node);
+ if (local->type_node != NULL) {
+ // If the function has the no_error flag, then the type node should have it set too.
+ // This allows for polymorphic structures with constraints to fail gracefully.
+ local->type_node->flags |= (func->flags & Ast_Flag_Header_Check_No_Error);
+ CHECK(type, local->type_node);
+ }
fill_in_type((AstTyped *) local);
if (local->type == NULL) {
- // onyx_report_error(param->local->token->pos,
- // "Unable to resolve type for parameter, '%b'",
- // local->token->text,
- // local->token->length);
YIELD(local->token->pos, "Waiting for parameter type to be known.");
}
onyx_report_error(constraint->exprs[constraint->expr_idx]->token->pos, "Failed to satisfy constraint where %s.", constraint_map);
onyx_report_error(constraint->token->pos, "Here is where the interface was used.");
- }
- return Check_Error;
+ return Check_Error;
+
+ } else {
+ // If no error are suppose to be produced, we still need to signal that
+ // the node reached a completed state.
+ return Check_Failed;
+ }
}
if (cc->constraint_checks[i] == Constraint_Check_Status_Queued) {
return bh_aprintf(global_heap_allocator, "%s", name_buf);
}
-Type* polymorphic_struct_lookup(AstPolyStructType* ps_type, bh_arr(AstPolySolution) slns, OnyxFilePos pos) {
+Type* polymorphic_struct_lookup(AstPolyStructType* ps_type, bh_arr(AstPolySolution) slns, OnyxFilePos pos, b32 error_if_failed) {
// @Cleanup
assert(ps_type->scope != NULL);
i32 i = 0;
bh_arr_each(AstPolySolution, sln, slns) {
sln->poly_sym = (AstNode *) &ps_type->poly_params[i];
-
+
PolySolutionKind expected_kind = PSK_Undefined;
if ((AstNode *) ps_type->poly_params[i].type_node == (AstNode *) &basic_type_type_expr) {
expected_kind = PSK_Type;
insert_poly_slns_into_scope(sln_scope, slns);
AstStructType* concrete_struct = (AstStructType *) ast_clone(context.ast_alloc, ps_type->base_struct);
+ BH_MASK_SET(concrete_struct->flags, !error_if_failed, Ast_Flag_Header_Check_No_Error);
shput(ps_type->concrete_structs, unique_key, concrete_struct);
add_entities_for_node(NULL, (AstNode *) concrete_struct, sln_scope, NULL);
}
}
- Type* concrete = polymorphic_struct_lookup(ps_type, slns, pc_type->token->pos);
+ Type* concrete = polymorphic_struct_lookup(ps_type, slns, pc_type->token->pos, (pc_type->flags & Ast_Flag_Header_Check_No_Error) == 0);
// This should be copied in the previous function.
// CLEANUP: Maybe don't copy it and just use this one since it is allocated on the heap?
to_try := heap.make(queued, (x, y) => x.cost - y.cost);
tried := set.make(pos);
- heap.insert(^to_try, .{ 0, 0, -cast(i32) (cells[0] - #char "0") });
+ to_try << .{ 0, 0, -cast(i32) (cells[0] - #char "0") };
minimum := 0;
while to_try.data.count != 0 {
if found := array.find_ptr(to_try.data, .{try.x + dx, try.y + dy, 0}); found != null {
found.cost = math.min(cell_value, found.cost);
} else {
- heap.insert(^to_try, .{try.x + dx, try.y + dy, cell_value });
+ to_try << .{try.x + dx, try.y + dy, cell_value };
}
}
}