| ... | ... | @@ -2569,16 +2569,8 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { |
| 2569 | 2569 | return ErrorSemanticAnalyzeFail; |
| 2570 | 2570 | } |
| 2571 | 2571 | |
| 2572 | | enum_type->data.enumeration.src_field_count = field_count; |
| 2573 | | enum_type->data.enumeration.fields = allocate<TypeEnumField>(field_count); |
| 2574 | | enum_type->data.enumeration.fields_by_name.init(field_count); |
| 2575 | | enum_type->data.enumeration.non_exhaustive = false; |
| 2576 | | |
| 2577 | 2572 | Scope *scope = &enum_type->data.enumeration.decls_scope->base; |
| 2578 | 2573 | |
| 2579 | | HashMap<BigInt, AstNode *, bigint_hash, bigint_eql> occupied_tag_values = {}; |
| 2580 | | occupied_tag_values.init(field_count); |
| 2581 | | |
| 2582 | 2574 | ZigType *tag_int_type; |
| 2583 | 2575 | if (enum_type->data.enumeration.layout == ContainerLayoutExtern) { |
| 2584 | 2576 | tag_int_type = get_c_int_type(g, CIntTypeInt); |
| ... | ... | @@ -2620,6 +2612,7 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { |
| 2620 | 2612 | } |
| 2621 | 2613 | } |
| 2622 | 2614 | |
| 2615 | enum_type->data.enumeration.non_exhaustive = false; |
| 2623 | 2616 | enum_type->data.enumeration.tag_int_type = tag_int_type; |
| 2624 | 2617 | enum_type->size_in_bits = tag_int_type->size_in_bits; |
| 2625 | 2618 | enum_type->abi_size = tag_int_type->abi_size; |
| ... | ... | @@ -2628,6 +2621,31 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { |
| 2628 | 2621 | BigInt bi_one; |
| 2629 | 2622 | bigint_init_unsigned(&bi_one, 1); |
| 2630 | 2623 | |
| 2624 | AstNode *last_field_node = decl_node->data.container_decl.fields.at(field_count - 1); |
| 2625 | if (buf_eql_str(last_field_node->data.struct_field.name, "_")) { |
| 2626 | field_count -= 1; |
| 2627 | if (field_count > 1 && log2_u64(field_count) == enum_type->size_in_bits) { |
| 2628 | add_node_error(g, last_field_node, buf_sprintf("non-exhaustive enum specifies every value")); |
| 2629 | enum_type->data.enumeration.resolve_status = ResolveStatusInvalid; |
| 2630 | } |
| 2631 | if (decl_node->data.container_decl.init_arg_expr == nullptr) { |
| 2632 | add_node_error(g, last_field_node, buf_sprintf("non-exhaustive enum must specify size")); |
| 2633 | enum_type->data.enumeration.resolve_status = ResolveStatusInvalid; |
| 2634 | } |
| 2635 | if (last_field_node->data.struct_field.value != nullptr) { |
| 2636 | add_node_error(g, last_field_node, buf_sprintf("value assigned to '_' field of non-exhaustive enum")); |
| 2637 | enum_type->data.enumeration.resolve_status = ResolveStatusInvalid; |
| 2638 | } |
| 2639 | enum_type->data.enumeration.non_exhaustive = true; |
| 2640 | } |
| 2641 | |
| 2642 | enum_type->data.enumeration.src_field_count = field_count; |
| 2643 | enum_type->data.enumeration.fields = allocate<TypeEnumField>(field_count); |
| 2644 | enum_type->data.enumeration.fields_by_name.init(field_count); |
| 2645 | |
| 2646 | HashMap<BigInt, AstNode *, bigint_hash, bigint_eql> occupied_tag_values = {}; |
| 2647 | occupied_tag_values.init(field_count); |
| 2648 | |
| 2631 | 2649 | TypeEnumField *last_enum_field = nullptr; |
| 2632 | 2650 | |
| 2633 | 2651 | for (uint32_t field_i = 0; field_i < field_count; field_i += 1) { |
| ... | ... | @@ -2649,27 +2667,9 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { |
| 2649 | 2667 | buf_sprintf("consider 'union(enum)' here")); |
| 2650 | 2668 | } |
| 2651 | 2669 | |
| 2652 | | AstNode *tag_value = field_node->data.struct_field.value; |
| 2653 | | |
| 2654 | 2670 | if (buf_eql_str(type_enum_field->name, "_")) { |
| 2655 | | if (decl_node->data.container_decl.init_arg_expr == nullptr) { |
| 2656 | | add_node_error(g, field_node, buf_sprintf("non-exhaustive enum must specify size")); |
| 2657 | | enum_type->data.enumeration.resolve_status = ResolveStatusInvalid; |
| 2658 | | } |
| 2659 | | if (field_count > 1 && log2_u64(field_count - 1) == enum_type->size_in_bits) { |
| 2660 | | add_node_error(g, field_node, buf_sprintf("non-exhaustive enum specifies every value")); |
| 2661 | | enum_type->data.enumeration.resolve_status = ResolveStatusInvalid; |
| 2662 | | } |
| 2663 | | if (field_i != field_count - 1) { |
| 2664 | | add_node_error(g, field_node, buf_sprintf("'_' field of non-exhaustive enum must be last")); |
| 2665 | | enum_type->data.enumeration.resolve_status = ResolveStatusInvalid; |
| 2666 | | } |
| 2667 | | if (tag_value != nullptr) { |
| 2668 | | add_node_error(g, field_node, buf_sprintf("value assigned to '_' field of non-exhaustive enum")); |
| 2669 | | enum_type->data.enumeration.resolve_status = ResolveStatusInvalid; |
| 2670 | | } |
| 2671 | | enum_type->data.enumeration.non_exhaustive = true; |
| 2672 | | continue; |
| 2671 | add_node_error(g, field_node, buf_sprintf("'_' field of non-exhaustive enum must be last")); |
| 2672 | enum_type->data.enumeration.resolve_status = ResolveStatusInvalid; |
| 2673 | 2673 | } |
| 2674 | 2674 | |
| 2675 | 2675 | auto field_entry = enum_type->data.enumeration.fields_by_name.put_unique(type_enum_field->name, type_enum_field); |
| ... | ... | @@ -2681,6 +2681,8 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { |
| 2681 | 2681 | continue; |
| 2682 | 2682 | } |
| 2683 | 2683 | |
| 2684 | AstNode *tag_value = field_node->data.struct_field.value; |
| 2685 | |
| 2684 | 2686 | if (tag_value != nullptr) { |
| 2685 | 2687 | // A user-specified value is available |
| 2686 | 2688 | ZigValue *result = analyze_const_value(g, scope, tag_value, tag_int_type, |
| ... | ... | @@ -3293,7 +3295,7 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) { |
| 3293 | 3295 | } else if (enum_type_node != nullptr) { |
| 3294 | 3296 | for (uint32_t i = 0; i < tag_type->data.enumeration.src_field_count; i += 1) { |
| 3295 | 3297 | TypeEnumField *enum_field = &tag_type->data.enumeration.fields[i]; |
| 3296 | | if (!covered_enum_fields[i] && !buf_eql_str(enum_field->name, "_")) { |
| 3298 | if (!covered_enum_fields[i]) { |
| 3297 | 3299 | AstNode *enum_decl_node = tag_type->data.enumeration.decl_node; |
| 3298 | 3300 | AstNode *field_node = enum_decl_node->data.container_decl.fields.at(i); |
| 3299 | 3301 | ErrorMsg *msg = add_node_error(g, decl_node, |