diff --git a/src/check_expr.cpp b/src/check_expr.cpp index dd172634b..afa8327a0 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -58,6 +58,7 @@ void check_expr_with_type_hint (Checker *c, Operand *o, AstNode *e, Typ Type * check_type (Checker *c, AstNode *expression, Type *named_type = nullptr); void check_type_decl (Checker *c, Entity *e, AstNode *type_expr, Type *def); Entity * check_selector (Checker *c, Operand *operand, AstNode *node, Type *type_hint); +Entity * check_ident (Checker *c, Operand *o, AstNode *n, Type *named_type, Type *type_hint, bool allow_import_name); void check_not_tuple (Checker *c, Operand *operand); void convert_to_typed (Checker *c, Operand *operand, Type *target_type, i32 level); gbString expr_to_string (AstNode *expression); @@ -1037,9 +1038,23 @@ Array check_struct_fields(Checker *c, AstNode *node, Array } else if (o.mode != Addressing_Constant) { if (default_value->kind == AstNode_ProcLit) { value = exact_value_procedure(default_value); - // error(default_value, "A procedure literal as a default param is not yet supported"); } else { - error(default_value, "Default parameter must be a constant"); + Entity *e = nullptr; + if (o.mode == Addressing_Value && is_type_proc(o.type)) { + Operand x = {}; + if (default_value->kind == AstNode_Ident) { + e = check_ident(c, &x, default_value, nullptr, nullptr, false); + } else if (default_value->kind == AstNode_SelectorExpr) { + e = check_selector(c, &x, default_value, nullptr); + } + } + + if (e != nullptr && e->kind == Entity_Procedure) { + value = exact_value_procedure(e->identifier); + add_entity_use(c, e->identifier, e); + } else { + error(default_value, "Default parameter must be a constant"); + } } } else { value = o.value; diff --git a/src/ir.cpp b/src/ir.cpp index 0fe5f544e..9a18f9195 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -3813,8 +3813,9 @@ void ir_gen_global_type_name(irModule *m, Entity *e, String name) { if (f->Variable.default_value.kind == ExactValue_Procedure) { AstNode *expr = f->Variable.default_value.value_procedure; GB_ASSERT(expr != nullptr); - GB_ASSERT(expr->kind == AstNode_ProcLit); - ir_gen_anonymous_proc_lit(m, e->token.string, expr); + if (expr->kind == AstNode_ProcLit) { + ir_gen_anonymous_proc_lit(m, e->token.string, expr); + } } } } @@ -8570,7 +8571,6 @@ void ir_gen_tree(irGen *s) { for_array(i, m->procs_to_generate) { irValue *p = m->procs_to_generate[i]; - gb_printf_err("%.*s\n", LIT(p->Proc.name)); ir_build_proc(p, p->Proc.parent); } diff --git a/src/ir_print.cpp b/src/ir_print.cpp index 8b728acdf..a1b2a1d03 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -701,10 +701,18 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type * } case ExactValue_Procedure: { + irValue **found = nullptr; AstNode *expr = value.value_procedure; GB_ASSERT(expr != nullptr); - GB_ASSERT(expr->kind == AstNode_ProcLit); - irValue **found = map_get(&m->anonymous_proc_lits, hash_pointer(expr)); + + if (expr->kind == AstNode_ProcLit) { + found = map_get(&m->anonymous_proc_lits, hash_pointer(expr)); + } else { + GB_ASSERT(expr->kind == AstNode_Ident); + Entity *e = entity_of_ident(m->info, expr); + GB_ASSERT(e != nullptr); + found = map_get(&m->values, hash_entity(e)); + } GB_ASSERT(found != nullptr); irValue *val = *found; ir_print_value(f, m, val, type);