diff --git a/src/check_expr.cpp b/src/check_expr.cpp index d28419ccf..3d4dd9147 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -7677,7 +7677,8 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t isize index = 0; isize elem_count = cl->elems.count; - if (is_type_any(base_type(elem_type))) { + Type *bet = base_type(elem_type); + if (!elem_type_can_be_constant(bet)) { is_constant = false; } diff --git a/src/ir.cpp b/src/ir.cpp index 2fbcee70a..743e97071 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -5077,7 +5077,7 @@ irValue *ir_get_using_variable(irProcedure *proc, Entity *e) { } bool ir_is_elem_const(irModule *m, AstNode *elem, Type *elem_type) { - if (base_type(elem_type) == t_any) { + if (!elem_type_can_be_constant(elem_type)) { return false; } if (elem->kind == AstNode_FieldValue) { @@ -5592,6 +5592,27 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) { } } break; + case Type_Map: { + if (cl->elems.count == 0) { + break; + } + gbAllocator a = proc->module->allocator; + { + irValue **args = gb_alloc_array(a, irValue *, 2); + args[0] = ir_gen_map_header(proc, v, type); + args[1] = ir_const_int(a, 2*cl->elems.count); + ir_emit_global_call(proc, "__dynamic_map_reserve", args, 2); + } + for_array(field_index, cl->elems) { + AstNode *elem = cl->elems[field_index]; + ast_node(fv, FieldValue, elem); + + irValue *key = ir_build_expr(proc, fv->field); + irValue *value = ir_build_expr(proc, fv->value); + ir_insert_dynamic_map_key_and_value(proc, v, type, key, value); + } + } break; + case Type_DynamicArray: { if (cl->elems.count == 0) { break; @@ -5630,27 +5651,6 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) { } } break; - case Type_Map: { - if (cl->elems.count == 0) { - break; - } - gbAllocator a = proc->module->allocator; - { - irValue **args = gb_alloc_array(a, irValue *, 2); - args[0] = ir_gen_map_header(proc, v, type); - args[1] = ir_const_int(a, 2*cl->elems.count); - ir_emit_global_call(proc, "__dynamic_map_reserve", args, 2); - } - for_array(field_index, cl->elems) { - AstNode *elem = cl->elems[field_index]; - ast_node(fv, FieldValue, elem); - - irValue *key = ir_build_expr(proc, fv->field); - irValue *value = ir_build_expr(proc, fv->value); - ir_insert_dynamic_map_key_and_value(proc, v, type, key, value); - } - } break; - case Type_Array: { if (cl->elems.count > 0) { ir_emit_store(proc, v, ir_add_module_constant(proc->module, type, exact_value_compound(expr))); diff --git a/src/ir_print.cpp b/src/ir_print.cpp index 6381b5d68..ec60bbc41 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -399,7 +399,7 @@ void ir_print_compound_element(irFileBuffer *f, irModule *m, ExactValue v, Type ir_print_type(f, m, elem_type); ir_write_byte(f, ' '); - if (v.kind == ExactValue_Invalid || base_type(elem_type) == t_any) { + if (v.kind == ExactValue_Invalid || !elem_type_can_be_constant(elem_type)) { if (ir_type_has_default_values(elem_type)) { ir_print_exact_value(f, m, v, elem_type); } else { diff --git a/src/types.cpp b/src/types.cpp index dec7428eb..3aeb4f3e4 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -1037,6 +1037,13 @@ bool type_has_nil(Type *t) { return false; } +bool elem_type_can_be_constant(Type *t) { + if (is_type_any(t) || is_type_union(t)) { + return false; + } + return true; +} + bool is_type_comparable(Type *t) { t = base_type(t);