| ... | @@ -2569,16 +2569,8 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { | ... | @@ -2569,16 +2569,8 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { |
| 2569 | return ErrorSemanticAnalyzeFail; | 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 | Scope *scope = &enum_type->data.enumeration.decls_scope->base; | 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 | ZigType *tag_int_type; | 2574 | ZigType *tag_int_type; |
| 2583 | if (enum_type->data.enumeration.layout == ContainerLayoutExtern) { | 2575 | if (enum_type->data.enumeration.layout == ContainerLayoutExtern) { |
| 2584 | tag_int_type = get_c_int_type(g, CIntTypeInt); | 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,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 | enum_type->data.enumeration.tag_int_type = tag_int_type; | 2616 | enum_type->data.enumeration.tag_int_type = tag_int_type; |
| 2624 | enum_type->size_in_bits = tag_int_type->size_in_bits; | 2617 | enum_type->size_in_bits = tag_int_type->size_in_bits; |
| 2625 | enum_type->abi_size = tag_int_type->abi_size; | 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,6 +2621,31 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { |
| 2628 | BigInt bi_one; | 2621 | BigInt bi_one; |
| 2629 | bigint_init_unsigned(&bi_one, 1); | 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 | TypeEnumField *last_enum_field = nullptr; | 2649 | TypeEnumField *last_enum_field = nullptr; |
| 2632 | | 2650 | |
| 2633 | for (uint32_t field_i = 0; field_i < field_count; field_i += 1) { | 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,27 +2667,9 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { |
| 2649 | buf_sprintf("consider 'union(enum)' here")); | 2667 | buf_sprintf("consider 'union(enum)' here")); |
| 2650 | } | 2668 | } |
| 2651 | | 2669 | |
| 2652 | AstNode *tag_value = field_node->data.struct_field.value; | | |
| 2653 | | | |
| 2654 | if (buf_eql_str(type_enum_field->name, "_")) { | 2670 | if (buf_eql_str(type_enum_field->name, "_")) { |
| 2655 | if (decl_node->data.container_decl.init_arg_expr == nullptr) { | 2671 | add_node_error(g, field_node, buf_sprintf("'_' field of non-exhaustive enum must be last")); |
| 2656 | add_node_error(g, field_node, buf_sprintf("non-exhaustive enum must specify size")); | 2672 | enum_type->data.enumeration.resolve_status = ResolveStatusInvalid; |
| 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; | | |
| 2673 | } | 2673 | } |
| 2674 | | 2674 | |
| 2675 | auto field_entry = enum_type->data.enumeration.fields_by_name.put_unique(type_enum_field->name, type_enum_field); | 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,6 +2681,8 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { |
| 2681 | continue; | 2681 | continue; |
| 2682 | } | 2682 | } |
| 2683 | | 2683 | |
| | 2684 | AstNode *tag_value = field_node->data.struct_field.value; |
| | 2685 | |
| 2684 | if (tag_value != nullptr) { | 2686 | if (tag_value != nullptr) { |
| 2685 | // A user-specified value is available | 2687 | // A user-specified value is available |
| 2686 | ZigValue *result = analyze_const_value(g, scope, tag_value, tag_int_type, | 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,7 +3295,7 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) { |
| 3293 | } else if (enum_type_node != nullptr) { | 3295 | } else if (enum_type_node != nullptr) { |
| 3294 | for (uint32_t i = 0; i < tag_type->data.enumeration.src_field_count; i += 1) { | 3296 | for (uint32_t i = 0; i < tag_type->data.enumeration.src_field_count; i += 1) { |
| 3295 | TypeEnumField *enum_field = &tag_type->data.enumeration.fields[i]; | 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 | AstNode *enum_decl_node = tag_type->data.enumeration.decl_node; | 3299 | AstNode *enum_decl_node = tag_type->data.enumeration.decl_node; |
| 3298 | AstNode *field_node = enum_decl_node->data.container_decl.fields.at(i); | 3300 | AstNode *field_node = enum_decl_node->data.container_decl.fields.at(i); |
| 3299 | ErrorMsg *msg = add_node_error(g, decl_node, | 3301 | ErrorMsg *msg = add_node_error(g, decl_node, |