authorgravatar for me@tadeo.caTadeo Kondrak <me@tadeo.ca> 2020-08-26 08:43:03-06:00
committergravatar for me@tadeo.caTadeo Kondrak <me@tadeo.ca> 2020-09-07 06:23:24-06:00
logff2ed966bb37079217ee7a7753cb63a763b8c3b5
tree9c30a132c3b3cc8b37bc7c94421355491ef5a319
parentd7268cbb242d6bea6b6e4d929a8d6b99608b640a
signature Commit is signed but in an unrecognized format.

Implement @Type for Union

This removes TypeInfo.UnionField.enum_field, which is redundant with TypeInfo.Union.tag_type.

6 files changed, 377 insertions(+), 159 deletions(-)

lib/std/builtin.zig-1
...@@ -317,7 +317,6 @@ pub const TypeInfo = union(enum) {...@@ -317,7 +317,6 @@ pub const TypeInfo = union(enum) {
317 /// therefore must be kept in sync with the compiler implementation.317 /// therefore must be kept in sync with the compiler implementation.
318 pub const UnionField = struct {318 pub const UnionField = struct {
319 name: []const u8,319 name: []const u8,
320 enum_field: ?EnumField,
321 field_type: type,320 field_type: type,
322 };321 };
323322
src/analyze.cpp+163-133
...@@ -2372,7 +2372,10 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) {...@@ -2372,7 +2372,10 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) {
2372 if (field->gen_index == UINT32_MAX)2372 if (field->gen_index == UINT32_MAX)
2373 continue;2373 continue;
23742374
2375 AstNode *align_expr = field->decl_node->data.struct_field.align_expr;2375 AstNode *align_expr = nullptr;
2376 if (union_type->data.unionation.decl_node->type == NodeTypeContainerDecl) {
2377 align_expr = field->decl_node->data.struct_field.align_expr;
2378 }
2376 if (align_expr != nullptr) {2379 if (align_expr != nullptr) {
2377 if (!analyze_const_align(g, &union_type->data.unionation.decls_scope->base, align_expr,2380 if (!analyze_const_align(g, &union_type->data.unionation.decls_scope->base, align_expr,
2378 &field->align))2381 &field->align))
...@@ -2468,9 +2471,6 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) {...@@ -2468,9 +2471,6 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) {
24682471
2469 AstNode *decl_node = union_type->data.unionation.decl_node;2472 AstNode *decl_node = union_type->data.unionation.decl_node;
24702473
2471
2472 assert(decl_node->type == NodeTypeContainerDecl);
2473
2474 uint32_t field_count = union_type->data.unionation.src_field_count;2474 uint32_t field_count = union_type->data.unionation.src_field_count;
2475 TypeUnionField *most_aligned_union_member = union_type->data.unionation.most_aligned_union_member;2475 TypeUnionField *most_aligned_union_member = union_type->data.unionation.most_aligned_union_member;
24762476
...@@ -3055,7 +3055,6 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {...@@ -3055,7 +3055,6 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {
3055 return ErrorNone;3055 return ErrorNone;
30563056
3057 AstNode *decl_node = union_type->data.unionation.decl_node;3057 AstNode *decl_node = union_type->data.unionation.decl_node;
3058 assert(decl_node->type == NodeTypeContainerDecl);
30593058
3060 if (union_type->data.unionation.resolve_loop_flag_zero_bits) {3059 if (union_type->data.unionation.resolve_loop_flag_zero_bits) {
3061 if (union_type->data.unionation.resolve_status != ResolveStatusInvalid) {3060 if (union_type->data.unionation.resolve_status != ResolveStatusInvalid) {
...@@ -3069,30 +3068,50 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {...@@ -3069,30 +3068,50 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {
30693068
3070 union_type->data.unionation.resolve_loop_flag_zero_bits = true;3069 union_type->data.unionation.resolve_loop_flag_zero_bits = true;
30713070
3072 assert(union_type->data.unionation.fields == nullptr);3071 uint32_t field_count;
3073 uint32_t field_count = (uint32_t)decl_node->data.container_decl.fields.length;3072 if (decl_node->type == NodeTypeContainerDecl) {
3074 if (field_count == 0) {3073 assert(union_type->data.unionation.fields == nullptr);
3075 add_node_error(g, decl_node, buf_sprintf("unions must have 1 or more fields"));3074 field_count = (uint32_t)decl_node->data.container_decl.fields.length;
3075 if (field_count == 0) {
3076 add_node_error(g, decl_node, buf_sprintf("unions must have 1 or more fields"));
3077 union_type->data.unionation.src_field_count = field_count;
3078 union_type->data.unionation.resolve_status = ResolveStatusInvalid;
3079 return ErrorSemanticAnalyzeFail;
3080 }
3076 union_type->data.unionation.src_field_count = field_count;3081 union_type->data.unionation.src_field_count = field_count;
3077 union_type->data.unionation.resolve_status = ResolveStatusInvalid;3082 union_type->data.unionation.fields = heap::c_allocator.allocate<TypeUnionField>(field_count);
3078 return ErrorSemanticAnalyzeFail;3083 union_type->data.unionation.fields_by_name.init(field_count);
3084 } else {
3085 assert(union_type->data.unionation.fields != nullptr);
3086 field_count = union_type->data.unionation.src_field_count;
3079 }3087 }
3080 union_type->data.unionation.src_field_count = field_count;
3081 union_type->data.unionation.fields = heap::c_allocator.allocate<TypeUnionField>(field_count);
3082 union_type->data.unionation.fields_by_name.init(field_count);
30833088
3084 Scope *scope = &union_type->data.unionation.decls_scope->base;3089 Scope *scope = &union_type->data.unionation.decls_scope->base;
30853090
3086 HashMap<BigInt, AstNode *, bigint_hash, bigint_eql> occupied_tag_values = {};3091 HashMap<BigInt, AstNode *, bigint_hash, bigint_eql> occupied_tag_values = {};
30873092
3088 AstNode *enum_type_node = decl_node->data.container_decl.init_arg_expr;3093 bool is_auto_enum; // union(enum) or union(enum(expr))
3089 union_type->data.unionation.have_explicit_tag_type = decl_node->data.container_decl.auto_enum ||3094 bool is_explicit_enum; // union(expr)
3090 enum_type_node != nullptr;3095 AstNode *enum_type_node; // expr in union(enum(expr)) or union(expr)
3091 bool auto_layout = (union_type->data.unionation.layout == ContainerLayoutAuto);3096 if (decl_node->type == NodeTypeContainerDecl) {
3092 bool want_safety = (field_count >= 2) && (auto_layout || enum_type_node != nullptr) && !(g->build_mode == BuildModeFastRelease || g->build_mode == BuildModeSmallRelease);3097 is_auto_enum = decl_node->data.container_decl.auto_enum;
3098 is_explicit_enum = decl_node->data.container_decl.init_arg_expr != nullptr;
3099 enum_type_node = decl_node->data.container_decl.init_arg_expr;
3100 } else {
3101 is_auto_enum = false;
3102 is_explicit_enum = union_type->data.unionation.tag_type != nullptr;
3103 enum_type_node = nullptr;
3104 }
3105 union_type->data.unionation.have_explicit_tag_type = is_auto_enum || is_explicit_enum;
3106
3107 bool is_auto_layout = union_type->data.unionation.layout == ContainerLayoutAuto;
3108 bool want_safety = (field_count >= 2)
3109 && (is_auto_layout || is_explicit_enum)
3110 && !(g->build_mode == BuildModeFastRelease || g->build_mode == BuildModeSmallRelease);
3093 ZigType *tag_type;3111 ZigType *tag_type;
3094 bool create_enum_type = decl_node->data.container_decl.auto_enum || (enum_type_node == nullptr && want_safety);3112 bool create_enum_type = is_auto_enum || (!is_explicit_enum && want_safety);
3095 bool *covered_enum_fields;3113 bool *covered_enum_fields;
3114 bool *is_zero_bits = heap::c_allocator.allocate<bool>(field_count);
3096 ZigLLVMDIEnumerator **di_enumerators;3115 ZigLLVMDIEnumerator **di_enumerators;
3097 if (create_enum_type) {3116 if (create_enum_type) {
3098 occupied_tag_values.init(field_count);3117 occupied_tag_values.init(field_count);
...@@ -3150,105 +3169,111 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {...@@ -3150,105 +3169,111 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {
3150 return err;3169 return err;
3151 }3170 }
3152 tag_type = enum_type;3171 tag_type = enum_type;
3153 covered_enum_fields = heap::c_allocator.allocate<bool>(enum_type->data.enumeration.src_field_count);
3154 } else {3172 } else {
3155 tag_type = nullptr;3173 if (decl_node->type == NodeTypeContainerDecl) {
3174 tag_type = nullptr;
3175 } else {
3176 tag_type = union_type->data.unionation.tag_type;
3177 }
3178 }
3179 if (tag_type != nullptr) {
3180 covered_enum_fields = heap::c_allocator.allocate<bool>(tag_type->data.enumeration.src_field_count);
3156 }3181 }
3157 union_type->data.unionation.tag_type = tag_type;3182 union_type->data.unionation.tag_type = tag_type;
31583183
3159 uint32_t gen_field_index = 0;
3160 for (uint32_t i = 0; i < field_count; i += 1) {3184 for (uint32_t i = 0; i < field_count; i += 1) {
3161 AstNode *field_node = decl_node->data.container_decl.fields.at(i);
3162 Buf *field_name = field_node->data.struct_field.name;
3163 TypeUnionField *union_field = &union_type->data.unionation.fields[i];3185 TypeUnionField *union_field = &union_type->data.unionation.fields[i];
3164 union_field->name = field_node->data.struct_field.name;3186 if (decl_node->type == NodeTypeContainerDecl) {
3165 union_field->decl_node = field_node;3187 AstNode *field_node = decl_node->data.container_decl.fields.at(i);
3166 union_field->gen_index = UINT32_MAX;3188 union_field->name = field_node->data.struct_field.name;
31673189 union_field->decl_node = field_node;
3168 auto field_entry = union_type->data.unionation.fields_by_name.put_unique(union_field->name, union_field);3190 union_field->gen_index = UINT32_MAX;
3169 if (field_entry != nullptr) {3191 is_zero_bits[i] = false;
3170 ErrorMsg *msg = add_node_error(g, field_node,
3171 buf_sprintf("duplicate union field: '%s'", buf_ptr(union_field->name)));
3172 add_error_note(g, msg, field_entry->value->decl_node, buf_sprintf("other field here"));
3173 union_type->data.unionation.resolve_status = ResolveStatusInvalid;
3174 return ErrorSemanticAnalyzeFail;
3175 }
31763192
3177 bool field_is_zero_bits;3193 auto field_entry = union_type->data.unionation.fields_by_name.put_unique(union_field->name, union_field);
3178 if (field_node->data.struct_field.type == nullptr) {3194 if (field_entry != nullptr) {
3179 if (decl_node->data.container_decl.auto_enum ||3195 ErrorMsg *msg = add_node_error(g, union_field->decl_node,
3180 decl_node->data.container_decl.init_arg_expr != nullptr)3196 buf_sprintf("duplicate union field: '%s'", buf_ptr(union_field->name)));
3181 {3197 add_error_note(g, msg, field_entry->value->decl_node, buf_sprintf("other field here"));
3182 union_field->type_entry = g->builtin_types.entry_void;
3183 field_is_zero_bits = true;
3184 } else {
3185 add_node_error(g, field_node, buf_sprintf("union field missing type"));
3186 union_type->data.unionation.resolve_status = ResolveStatusInvalid;
3187 return ErrorSemanticAnalyzeFail;
3188 }
3189 } else {
3190 ZigValue *field_type_val = analyze_const_value(g, scope,
3191 field_node->data.struct_field.type, g->builtin_types.entry_type, nullptr, LazyOkNoUndef);
3192 if (type_is_invalid(field_type_val->type)) {
3193 union_type->data.unionation.resolve_status = ResolveStatusInvalid;3198 union_type->data.unionation.resolve_status = ResolveStatusInvalid;
3194 return ErrorSemanticAnalyzeFail;3199 return ErrorSemanticAnalyzeFail;
3195 }3200 }
3196 assert(field_type_val->special != ConstValSpecialRuntime);
3197 union_field->type_val = field_type_val;
3198 if (union_type->data.unionation.resolve_status == ResolveStatusInvalid)
3199 return ErrorSemanticAnalyzeFail;
32003201
3201 bool field_is_opaque_type;3202 if (field_node->data.struct_field.type == nullptr) {
3202 if ((err = type_val_resolve_is_opaque_type(g, field_type_val, &field_is_opaque_type))) {3203 if (is_auto_enum || is_explicit_enum) {
3203 union_type->data.unionation.resolve_status = ResolveStatusInvalid;3204 union_field->type_entry = g->builtin_types.entry_void;
3204 return ErrorSemanticAnalyzeFail;3205 is_zero_bits[i] = true;
3205 }3206 } else {
3206 if (field_is_opaque_type) {3207 add_node_error(g, field_node, buf_sprintf("union field missing type"));
3207 add_node_error(g, field_node,3208 union_type->data.unionation.resolve_status = ResolveStatusInvalid;
3208 buf_create_from_str(3209 return ErrorSemanticAnalyzeFail;
3209 "opaque types have unknown size and therefore cannot be directly embedded in unions"));3210 }
3210 union_type->data.unionation.resolve_status = ResolveStatusInvalid;3211 } else {
3211 return ErrorSemanticAnalyzeFail;3212 ZigValue *field_type_val = analyze_const_value(g, scope,
3212 }3213 field_node->data.struct_field.type, g->builtin_types.entry_type, nullptr, LazyOkNoUndef);
3214 if (type_is_invalid(field_type_val->type)) {
3215 union_type->data.unionation.resolve_status = ResolveStatusInvalid;
3216 return ErrorSemanticAnalyzeFail;
3217 }
3218 assert(field_type_val->special != ConstValSpecialRuntime);
3219 union_field->type_val = field_type_val;
3220 if (union_type->data.unionation.resolve_status == ResolveStatusInvalid)
3221 return ErrorSemanticAnalyzeFail;
32133222
3214 switch (type_val_resolve_requires_comptime(g, field_type_val)) {3223 bool field_is_opaque_type;
3215 case ReqCompTimeInvalid:3224 if ((err = type_val_resolve_is_opaque_type(g, field_type_val, &field_is_opaque_type))) {
3216 if (g->trace_err != nullptr) {
3217 g->trace_err = add_error_note(g, g->trace_err, field_node,
3218 buf_create_from_str("while checking this field"));
3219 }
3220 union_type->data.unionation.resolve_status = ResolveStatusInvalid;3225 union_type->data.unionation.resolve_status = ResolveStatusInvalid;
3221 return ErrorSemanticAnalyzeFail;3226 return ErrorSemanticAnalyzeFail;
3222 case ReqCompTimeYes:3227 }
3223 union_type->data.unionation.requires_comptime = true;3228 if (field_is_opaque_type) {
3224 break;3229 add_node_error(g, field_node,
3225 case ReqCompTimeNo:3230 buf_create_from_str(
3226 break;3231 "opaque types have unknown size and therefore cannot be directly embedded in unions"));
3227 }3232 union_type->data.unionation.resolve_status = ResolveStatusInvalid;
3233 return ErrorSemanticAnalyzeFail;
3234 }
32283235
3229 if ((err = type_val_resolve_zero_bits(g, field_type_val, union_type, nullptr, &field_is_zero_bits))) {3236 switch (type_val_resolve_requires_comptime(g, field_type_val)) {
3230 union_type->data.unionation.resolve_status = ResolveStatusInvalid;3237 case ReqCompTimeInvalid:
3231 return ErrorSemanticAnalyzeFail;3238 if (g->trace_err != nullptr) {
3239 g->trace_err = add_error_note(g, g->trace_err, field_node,
3240 buf_create_from_str("while checking this field"));
3241 }
3242 union_type->data.unionation.resolve_status = ResolveStatusInvalid;
3243 return ErrorSemanticAnalyzeFail;
3244 case ReqCompTimeYes:
3245 union_type->data.unionation.requires_comptime = true;
3246 break;
3247 case ReqCompTimeNo:
3248 break;
3249 }
3250
3251 if ((err = type_val_resolve_zero_bits(g, field_type_val, union_type, nullptr, &is_zero_bits[i]))) {
3252 union_type->data.unionation.resolve_status = ResolveStatusInvalid;
3253 return ErrorSemanticAnalyzeFail;
3254 }
3232 }3255 }
3233 }
32343256
3235 if (field_node->data.struct_field.value != nullptr && !decl_node->data.container_decl.auto_enum) {3257 if (field_node->data.struct_field.value != nullptr && !is_auto_enum) {
3236 ErrorMsg *msg = add_node_error(g, field_node->data.struct_field.value,3258 ErrorMsg *msg = add_node_error(g, field_node->data.struct_field.value,
3237 buf_create_from_str("untagged union field assignment"));3259 buf_create_from_str("untagged union field assignment"));
3238 add_error_note(g, msg, decl_node, buf_create_from_str("consider 'union(enum)' here"));3260 add_error_note(g, msg, decl_node, buf_create_from_str("consider 'union(enum)' here"));
3261 }
3239 }3262 }
32403263
3241 if (create_enum_type) {3264 if (create_enum_type) {
3242 di_enumerators[i] = ZigLLVMCreateDebugEnumerator(g->dbuilder, buf_ptr(field_name), i);3265 di_enumerators[i] = ZigLLVMCreateDebugEnumerator(g->dbuilder, buf_ptr(union_field->name), i);
3243 union_field->enum_field = &tag_type->data.enumeration.fields[i];3266 union_field->enum_field = &tag_type->data.enumeration.fields[i];
3244 union_field->enum_field->name = field_name;3267 union_field->enum_field->name = union_field->name;
3245 union_field->enum_field->decl_index = i;3268 union_field->enum_field->decl_index = i;
3246 union_field->enum_field->decl_node = field_node;3269 union_field->enum_field->decl_node = union_field->decl_node;
32473270
3248 auto prev_entry = tag_type->data.enumeration.fields_by_name.put_unique(union_field->enum_field->name, union_field->enum_field);3271 auto prev_entry = tag_type->data.enumeration.fields_by_name.put_unique(union_field->enum_field->name, union_field->enum_field);
3249 assert(prev_entry == nullptr); // caught by union de-duplicator above3272 assert(prev_entry == nullptr); // caught by union de-duplicator above
32503273
3251 AstNode *tag_value = field_node->data.struct_field.value;3274 AstNode *tag_value = decl_node->type == NodeTypeContainerDecl
3275 ? union_field->decl_node->data.struct_field.value : nullptr;
3276
3252 // In this first pass we resolve explicit tag values.3277 // In this first pass we resolve explicit tag values.
3253 // In a second pass we will fill in the unspecified ones.3278 // In a second pass we will fill in the unspecified ones.
3254 if (tag_value != nullptr) {3279 if (tag_value != nullptr) {
...@@ -3276,11 +3301,11 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {...@@ -3276,11 +3301,11 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {
3276 return ErrorSemanticAnalyzeFail;3301 return ErrorSemanticAnalyzeFail;
3277 }3302 }
3278 }3303 }
3279 } else if (enum_type_node != nullptr) {3304 } else if (tag_type != nullptr) {
3280 union_field->enum_field = find_enum_type_field(tag_type, field_name);3305 union_field->enum_field = find_enum_type_field(tag_type, union_field->name);
3281 if (union_field->enum_field == nullptr) {3306 if (union_field->enum_field == nullptr) {
3282 ErrorMsg *msg = add_node_error(g, field_node,3307 ErrorMsg *msg = add_node_error(g, union_field->decl_node,
3283 buf_sprintf("enum field not found: '%s'", buf_ptr(field_name)));3308 buf_sprintf("enum field not found: '%s'", buf_ptr(union_field->name)));
3284 add_error_note(g, msg, tag_type->data.enumeration.decl_node,3309 add_error_note(g, msg, tag_type->data.enumeration.decl_node,
3285 buf_sprintf("enum declared here"));3310 buf_sprintf("enum declared here"));
3286 union_type->data.unionation.resolve_status = ResolveStatusInvalid;3311 union_type->data.unionation.resolve_status = ResolveStatusInvalid;
...@@ -3289,21 +3314,23 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {...@@ -3289,21 +3314,23 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {
3289 covered_enum_fields[union_field->enum_field->decl_index] = true;3314 covered_enum_fields[union_field->enum_field->decl_index] = true;
3290 } else {3315 } else {
3291 union_field->enum_field = heap::c_allocator.create<TypeEnumField>();3316 union_field->enum_field = heap::c_allocator.create<TypeEnumField>();
3292 union_field->enum_field->name = field_name;3317 union_field->enum_field->name = union_field->name;
3293 union_field->enum_field->decl_index = i;3318 union_field->enum_field->decl_index = i;
3294 bigint_init_unsigned(&union_field->enum_field->value, i);3319 bigint_init_unsigned(&union_field->enum_field->value, i);
3295 }3320 }
3296 assert(union_field->enum_field != nullptr);3321 assert(union_field->enum_field != nullptr);
3322 }
32973323
3298 if (field_is_zero_bits)3324 uint32_t gen_field_index = 0;
3299 continue;3325 for (uint32_t i = 0; i < field_count; i += 1) {
33003326 TypeUnionField *union_field = &union_type->data.unionation.fields[i];
3301 union_field->gen_index = gen_field_index;3327 if (!is_zero_bits[i]) {
3302 gen_field_index += 1;3328 union_field->gen_index = gen_field_index;
3329 gen_field_index += 1;
3330 }
3303 }3331 }
33043332
3305 bool src_have_tag = decl_node->data.container_decl.auto_enum ||3333 bool src_have_tag = is_auto_enum || is_explicit_enum;
3306 decl_node->data.container_decl.init_arg_expr != nullptr;
33073334
3308 if (src_have_tag && union_type->data.unionation.layout != ContainerLayoutAuto) {3335 if (src_have_tag && union_type->data.unionation.layout != ContainerLayoutAuto) {
3309 const char *qual_str;3336 const char *qual_str;
...@@ -3317,8 +3344,7 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {...@@ -3317,8 +3344,7 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {
3317 qual_str = "extern";3344 qual_str = "extern";
3318 break;3345 break;
3319 }3346 }
3320 AstNode *source_node = (decl_node->data.container_decl.init_arg_expr != nullptr) ?3347 AstNode *source_node = enum_type_node != nullptr ? enum_type_node : decl_node;
3321 decl_node->data.container_decl.init_arg_expr : decl_node;
3322 add_node_error(g, source_node,3348 add_node_error(g, source_node,
3323 buf_sprintf("%s union does not support enum tag type", qual_str));3349 buf_sprintf("%s union does not support enum tag type", qual_str));
3324 union_type->data.unionation.resolve_status = ResolveStatusInvalid;3350 union_type->data.unionation.resolve_status = ResolveStatusInvalid;
...@@ -3326,43 +3352,47 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {...@@ -3326,43 +3352,47 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {
3326 }3352 }
33273353
3328 if (create_enum_type) {3354 if (create_enum_type) {
3329 // Now iterate again and populate the unspecified tag values3355 if (decl_node->type == NodeTypeContainerDecl) {
3330 uint32_t next_maybe_unoccupied_index = 0;3356 // Now iterate again and populate the unspecified tag values
3357 uint32_t next_maybe_unoccupied_index = 0;
33313358
3332 for (uint32_t field_i = 0; field_i < field_count; field_i += 1) {3359 for (uint32_t field_i = 0; field_i < field_count; field_i += 1) {
3333 AstNode *field_node = decl_node->data.container_decl.fields.at(field_i);3360 AstNode *field_node = decl_node->data.container_decl.fields.at(field_i);
3334 TypeUnionField *union_field = &union_type->data.unionation.fields[field_i];3361 TypeUnionField *union_field = &union_type->data.unionation.fields[field_i];
3335 AstNode *tag_value = field_node->data.struct_field.value;3362 AstNode *tag_value = field_node->data.struct_field.value;
33363363
3337 if (tag_value == nullptr) {3364 if (tag_value == nullptr) {
3338 if (occupied_tag_values.size() == 0) {3365 if (occupied_tag_values.size() == 0) {
3339 bigint_init_unsigned(&union_field->enum_field->value, next_maybe_unoccupied_index);3366 bigint_init_unsigned(&union_field->enum_field->value, next_maybe_unoccupied_index);
3340 next_maybe_unoccupied_index += 1;
3341 } else {
3342 BigInt proposed_value;
3343 for (;;) {
3344 bigint_init_unsigned(&proposed_value, next_maybe_unoccupied_index);
3345 next_maybe_unoccupied_index += 1;3367 next_maybe_unoccupied_index += 1;
3346 auto entry = occupied_tag_values.put_unique(proposed_value, field_node);3368 } else {
3347 if (entry != nullptr) {3369 BigInt proposed_value;
3348 continue;3370 for (;;) {
3371 bigint_init_unsigned(&proposed_value, next_maybe_unoccupied_index);
3372 next_maybe_unoccupied_index += 1;
3373 auto entry = occupied_tag_values.put_unique(proposed_value, field_node);
3374 if (entry != nullptr) {
3375 continue;
3376 }
3377 break;
3349 }3378 }
3350 break;3379 bigint_init_bigint(&union_field->enum_field->value, &proposed_value);
3351 }3380 }
3352 bigint_init_bigint(&union_field->enum_field->value, &proposed_value);
3353 }3381 }
3354 }3382 }
3355 }3383 }
3356 } else if (enum_type_node != nullptr) {3384 } else if (tag_type != nullptr) {
3357 for (uint32_t i = 0; i < tag_type->data.enumeration.src_field_count; i += 1) {3385 for (uint32_t i = 0; i < tag_type->data.enumeration.src_field_count; i += 1) {
3358 TypeEnumField *enum_field = &tag_type->data.enumeration.fields[i];3386 TypeEnumField *enum_field = &tag_type->data.enumeration.fields[i];
3359 if (!covered_enum_fields[i]) {3387 if (!covered_enum_fields[i]) {
3360 AstNode *enum_decl_node = tag_type->data.enumeration.decl_node;
3361 AstNode *field_node = enum_decl_node->data.container_decl.fields.at(i);
3362 ErrorMsg *msg = add_node_error(g, decl_node,3388 ErrorMsg *msg = add_node_error(g, decl_node,
3363 buf_sprintf("enum field missing: '%s'", buf_ptr(enum_field->name)));3389 buf_sprintf("enum field missing: '%s'", buf_ptr(enum_field->name)));
3364 add_error_note(g, msg, field_node,3390 if (decl_node->type == NodeTypeContainerDecl) {
3365 buf_sprintf("declared here"));3391 AstNode *enum_decl_node = tag_type->data.enumeration.decl_node;
3392 AstNode *field_node = enum_decl_node->data.container_decl.fields.at(i);
3393 add_error_note(g, msg, field_node,
3394 buf_sprintf("declared here"));
3395 }
3366 union_type->data.unionation.resolve_status = ResolveStatusInvalid;3396 union_type->data.unionation.resolve_status = ResolveStatusInvalid;
3367 }3397 }
3368 }3398 }
...@@ -8350,7 +8380,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS...@@ -8350,7 +8380,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
8350 ZigLLVMDIFile *di_file;8380 ZigLLVMDIFile *di_file;
8351 ZigLLVMDIScope *di_scope;8381 ZigLLVMDIScope *di_scope;
8352 unsigned line;8382 unsigned line;
8353 if (decl_node != nullptr && !struct_type->data.structure.created_by_at_type) {8383 if (decl_node != nullptr) {
8354 Scope *scope = &struct_type->data.structure.decls_scope->base;8384 Scope *scope = &struct_type->data.structure.decls_scope->base;
8355 ZigType *import = get_scope_import(scope);8385 ZigType *import = get_scope_import(scope);
8356 di_file = import->data.structure.root_struct->di_file;8386 di_file = import->data.structure.root_struct->di_file;
...@@ -8713,7 +8743,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta...@@ -8713,7 +8743,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta
87138743
8714 uint64_t store_size_in_bits = union_field->type_entry->size_in_bits;8744 uint64_t store_size_in_bits = union_field->type_entry->size_in_bits;
8715 uint64_t abi_align_in_bits = 8*union_field->type_entry->abi_align;8745 uint64_t abi_align_in_bits = 8*union_field->type_entry->abi_align;
8716 AstNode *field_node = decl_node->data.container_decl.fields.at(i);8746 AstNode *field_node = union_field->decl_node;
8717 union_inner_di_types[union_field->gen_index] = ZigLLVMCreateDebugMemberType(g->dbuilder,8747 union_inner_di_types[union_field->gen_index] = ZigLLVMCreateDebugMemberType(g->dbuilder,
8718 ZigLLVMTypeToScope(union_type->llvm_di_type), buf_ptr(union_field->enum_field->name),8748 ZigLLVMTypeToScope(union_type->llvm_di_type), buf_ptr(union_field->enum_field->name),
8719 import->data.structure.root_struct->di_file, (unsigned)(field_node->line + 1),8749 import->data.structure.root_struct->di_file, (unsigned)(field_node->line + 1),
src/ir.cpp+80-20
...@@ -25424,8 +25424,6 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy...@@ -25424,8 +25424,6 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
2542425424
25425 init_const_slice(ira->codegen, fields[2], union_field_array, 0, union_field_count, false);25425 init_const_slice(ira->codegen, fields[2], union_field_array, 0, union_field_count, false);
2542625426
25427 ZigType *type_info_enum_field_type = ir_type_info_get_type(ira, "EnumField", nullptr);
25428
25429 for (uint32_t union_field_index = 0; union_field_index < union_field_count; union_field_index++) {25427 for (uint32_t union_field_index = 0; union_field_index < union_field_count; union_field_index++) {
25430 TypeUnionField *union_field = &type_entry->data.unionation.fields[union_field_index];25428 TypeUnionField *union_field = &type_entry->data.unionation.fields[union_field_index];
25431 ZigValue *union_field_val = &union_field_array->data.x_array.data.s_none.elements[union_field_index];25429 ZigValue *union_field_val = &union_field_array->data.x_array.data.s_none.elements[union_field_index];
...@@ -25433,20 +25431,10 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy...@@ -25433,20 +25431,10 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
25433 union_field_val->special = ConstValSpecialStatic;25431 union_field_val->special = ConstValSpecialStatic;
25434 union_field_val->type = type_info_union_field_type;25432 union_field_val->type = type_info_union_field_type;
2543525433
25436 ZigValue **inner_fields = alloc_const_vals_ptrs(ira->codegen, 3);25434 ZigValue **inner_fields = alloc_const_vals_ptrs(ira->codegen, 2);
25437 inner_fields[1]->special = ConstValSpecialStatic;25435 inner_fields[1]->special = ConstValSpecialStatic;
25438 inner_fields[1]->type = get_optional_type(ira->codegen, type_info_enum_field_type);25436 inner_fields[1]->type = ira->codegen->builtin_types.entry_type;
2543925437 inner_fields[1]->data.x_type = union_field->type_entry;
25440 if (fields[1]->data.x_optional == nullptr) {
25441 inner_fields[1]->data.x_optional = nullptr;
25442 } else {
25443 inner_fields[1]->data.x_optional = ira->codegen->pass1_arena->create<ZigValue>();
25444 make_enum_field_val(ira, inner_fields[1]->data.x_optional, union_field->enum_field, type_info_enum_field_type);
25445 }
25446
25447 inner_fields[2]->special = ConstValSpecialStatic;
25448 inner_fields[2]->type = ira->codegen->builtin_types.entry_type;
25449 inner_fields[2]->data.x_type = union_field->type_entry;
2545025438
25451 ZigValue *name = create_const_str_lit(ira->codegen, union_field->name)->data.x_ptr.data.ref.pointee;25439 ZigValue *name = create_const_str_lit(ira->codegen, union_field->name)->data.x_ptr.data.ref.pointee;
25452 init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(union_field->name), true);25440 init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(union_field->name), true);
...@@ -26102,7 +26090,8 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI...@@ -26102,7 +26090,8 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
26102 entry->data.structure.layout = layout;26090 entry->data.structure.layout = layout;
26103 entry->data.structure.special = is_tuple ? StructSpecialInferredTuple : StructSpecialNone;26091 entry->data.structure.special = is_tuple ? StructSpecialInferredTuple : StructSpecialNone;
26104 entry->data.structure.created_by_at_type = true;26092 entry->data.structure.created_by_at_type = true;
26105 entry->data.structure.decls_scope = create_decls_scope(ira->codegen, nullptr, nullptr, entry, entry, &entry->name);26093 entry->data.structure.decls_scope = create_decls_scope(
26094 ira->codegen, source_instr->source_node, source_instr->scope, entry, get_scope_import(source_instr->scope), &entry->name);
2610626095
26107 assert(fields_ptr->data.x_ptr.special == ConstPtrSpecialBaseArray);26096 assert(fields_ptr->data.x_ptr.special == ConstPtrSpecialBaseArray);
26108 assert(fields_ptr->data.x_ptr.data.base_array.elem_index == 0);26097 assert(fields_ptr->data.x_ptr.data.base_array.elem_index == 0);
...@@ -26226,13 +26215,84 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI...@@ -26226,13 +26215,84 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
26226 return ira->codegen->invalid_inst_gen->value->type;26215 return ira->codegen->invalid_inst_gen->value->type;
26227 field->value = *field_int_value;26216 field->value = *field_int_value;
26228 }26217 }
26218 return entry;
26219 }
26220 case ZigTypeIdUnion: {
26221 assert(payload->special == ConstValSpecialStatic);
26222 assert(payload->type == ir_type_info_get_type(ira, "Union", nullptr));
2622926223
26224 ZigValue *layout_value = get_const_field(ira, source_instr->source_node, payload, "layout", 0);
26225 assert(layout_value->special == ConstValSpecialStatic);
26226 assert(layout_value->type == ir_type_info_get_type(ira, "ContainerLayout", nullptr));
26227 ContainerLayout layout = (ContainerLayout)bigint_as_u32(&layout_value->data.x_enum_tag);
26228
26229 ZigType *tag_type = get_const_field_meta_type_optional(ira, source_instr->source_node, payload, "tag_type", 1);
26230 if (tag_type != nullptr && tag_type->id != ZigTypeIdEnum) {
26231 ir_add_error(ira, source_instr, buf_sprintf(
26232 "union tag type must be an enum, not %s", type_id_name(tag_type->id)));
26233 return ira->codegen->invalid_inst_gen->value->type;
26234 }
26235
26236 ZigValue *fields_value = get_const_field(ira, source_instr->source_node, payload, "fields", 2);
26237 if (fields_value == nullptr)
26238 return ira->codegen->invalid_inst_gen->value->type;
26239
26240 assert(fields_value->special == ConstValSpecialStatic);
26241 assert(is_slice(fields_value->type));
26242 ZigValue *fields_ptr = fields_value->data.x_struct.fields[slice_ptr_index];
26243 ZigValue *fields_len_value = fields_value->data.x_struct.fields[slice_len_index];
26244 size_t fields_len = bigint_as_usize(&fields_len_value->data.x_bigint);
26245
26246 ZigValue *decls_value = get_const_field(ira, source_instr->source_node, payload, "decls", 3);
26247 if (decls_value == nullptr)
26248 return ira->codegen->invalid_inst_gen->value->type;
26249
26250 assert(decls_value->special == ConstValSpecialStatic);
26251 assert(is_slice(decls_value->type));
26252 ZigValue *decls_len_value = decls_value->data.x_struct.fields[slice_len_index];
26253 size_t decls_len = bigint_as_usize(&decls_len_value->data.x_bigint);
26254 if (decls_len != 0) {
26255 ir_add_error(ira, source_instr, buf_create_from_str("TypeInfo.Union.decls must be empty for @Type"));
26256 return ira->codegen->invalid_inst_gen->value->type;
26257 }
26258
26259 ZigType *entry = new_type_table_entry(ZigTypeIdUnion);
26260 buf_init_from_buf(&entry->name,
26261 get_anon_type_name(ira->codegen, ira->old_irb.exec, "union", source_instr->scope, source_instr->source_node, &entry->name));
26262 entry->data.unionation.decl_node = source_instr->source_node;
26263 entry->data.unionation.fields = heap::c_allocator.allocate<TypeUnionField>(fields_len);
26264 entry->data.unionation.fields_by_name.init(fields_len);
26265 entry->data.unionation.decls_scope = create_decls_scope(
26266 ira->codegen, source_instr->source_node, source_instr->scope, entry, get_scope_import(source_instr->scope), &entry->name);
26267 entry->data.unionation.tag_type = tag_type;
26268 entry->data.unionation.src_field_count = fields_len;
26269 entry->data.unionation.layout = layout;
26270
26271 assert(fields_ptr->data.x_ptr.special == ConstPtrSpecialBaseArray);
26272 assert(fields_ptr->data.x_ptr.data.base_array.elem_index == 0);
26273 ZigValue *fields_arr = fields_ptr->data.x_ptr.data.base_array.array_val;
26274 assert(fields_arr->special == ConstValSpecialStatic);
26275 assert(fields_arr->data.x_array.special == ConstArraySpecialNone);
26276 for (size_t i = 0; i < fields_len; i++) {
26277 ZigValue *field_value = &fields_arr->data.x_array.data.s_none.elements[i];
26278 assert(field_value->type == ir_type_info_get_type(ira, "UnionField", nullptr));
26279 TypeUnionField *field = &entry->data.unionation.fields[i];
26280 field->name = buf_alloc();
26281 if ((err = get_const_field_buf(ira, source_instr->source_node, field_value, "name", 0, field->name)))
26282 return ira->codegen->invalid_inst_gen->value->type;
26283 if (entry->data.unionation.fields_by_name.put_unique(field->name, field) != nullptr) {
26284 ir_add_error(ira, source_instr, buf_sprintf("duplicate union field '%s'", buf_ptr(field->name)));
26285 return ira->codegen->invalid_inst_gen->value->type;
26286 }
26287 field->decl_node = source_instr->source_node;
26288 ZigValue *type_value = get_const_field(ira, source_instr->source_node, field_value, "field_type", 1);
26289 if (type_value == nullptr)
26290 return ira->codegen->invalid_inst_gen->value->type;
26291 field->type_val = type_value;
26292 field->type_entry = type_value->data.x_type;
26293 }
26230 return entry;26294 return entry;
26231 }26295 }
26232 case ZigTypeIdUnion:
26233 ir_add_error(ira, source_instr, buf_sprintf(
26234 "TODO implement @Type for 'TypeInfo.%s': see https://github.com/ziglang/zig/issues/2907", type_id_name(tagTypeId)));
26235 return ira->codegen->invalid_inst_gen->value->type;
26236 case ZigTypeIdFn:26296 case ZigTypeIdFn:
26237 case ZigTypeIdBoundFn:26297 case ZigTypeIdBoundFn:
26238 ir_add_error(ira, source_instr, buf_sprintf(26298 ir_add_error(ira, source_instr, buf_sprintf(
test/compile_errors.zig+73-1
...@@ -10,6 +10,78 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -10,6 +10,78 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
10 "tmp.zig:2:37: error: expected type '[:1]const u8', found '*const [2:2]u8'",10 "tmp.zig:2:37: error: expected type '[:1]const u8', found '*const [2:2]u8'",
11 });11 });
1212
13 cases.add("@Type for tagged union with extra union field",
14 \\const TypeInfo = @import("builtin").TypeInfo;
15 \\const Tag = @Type(.{
16 \\ .Enum = .{
17 \\ .layout = .Auto,
18 \\ .tag_type = u1,
19 \\ .fields = &[_]TypeInfo.EnumField{
20 \\ .{ .name = "signed", .value = 0 },
21 \\ .{ .name = "unsigned", .value = 1 },
22 \\ },
23 \\ .decls = &[_]TypeInfo.Declaration{},
24 \\ .is_exhaustive = true,
25 \\ },
26 \\});
27 \\const Tagged = @Type(.{
28 \\ .Union = .{
29 \\ .layout = .Auto,
30 \\ .tag_type = Tag,
31 \\ .fields = &[_]TypeInfo.UnionField{
32 \\ .{ .name = "signed", .field_type = i32 },
33 \\ .{ .name = "unsigned", .field_type = u32 },
34 \\ .{ .name = "arst", .field_type = f32 },
35 \\ },
36 \\ .decls = &[_]TypeInfo.Declaration{},
37 \\ },
38 \\});
39 \\export fn entry() void {
40 \\ var tagged = Tagged{ .signed = -1 };
41 \\ tagged = .{ .unsigned = 1 };
42 \\}
43 , &[_][]const u8{
44 "tmp.zig:14:23: error: enum field not found: 'arst'",
45 "tmp.zig:2:20: note: enum declared here",
46 "tmp.zig:27:24: note: referenced here",
47 });
48
49 cases.add("@Type for tagged union with extra enum field",
50 \\const TypeInfo = @import("builtin").TypeInfo;
51 \\const Tag = @Type(.{
52 \\ .Enum = .{
53 \\ .layout = .Auto,
54 \\ .tag_type = u2,
55 \\ .fields = &[_]TypeInfo.EnumField{
56 \\ .{ .name = "signed", .value = 0 },
57 \\ .{ .name = "unsigned", .value = 1 },
58 \\ .{ .name = "arst", .field_type = 2 },
59 \\ },
60 \\ .decls = &[_]TypeInfo.Declaration{},
61 \\ .is_exhaustive = true,
62 \\ },
63 \\});
64 \\const Tagged = @Type(.{
65 \\ .Union = .{
66 \\ .layout = .Auto,
67 \\ .tag_type = Tag,
68 \\ .fields = &[_]TypeInfo.UnionField{
69 \\ .{ .name = "signed", .field_type = i32 },
70 \\ .{ .name = "unsigned", .field_type = u32 },
71 \\ },
72 \\ .decls = &[_]TypeInfo.Declaration{},
73 \\ },
74 \\});
75 \\export fn entry() void {
76 \\ var tagged = Tagged{ .signed = -1 };
77 \\ tagged = .{ .unsigned = 1 };
78 \\}
79 , &[_][]const u8{
80 "tmp.zig:9:32: error: no member named 'field_type' in struct 'std.builtin.EnumField'",
81 "tmp.zig:18:21: note: referenced here",
82 "tmp.zig:27:18: note: referenced here",
83 });
84
13 cases.add("@Type with undefined",85 cases.add("@Type with undefined",
14 \\comptime {86 \\comptime {
15 \\ _ = @Type(.{ .Array = .{ .len = 0, .child = u8, .sentinel = undefined } });87 \\ _ = @Type(.{ .Array = .{ .len = 0, .child = u8, .sentinel = undefined } });
...@@ -7419,7 +7491,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7419,7 +7491,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7419 });7491 });
74207492
7421 cases.add( // fixed bug #20327493 cases.add( // fixed bug #2032
7422 "compile diagnostic string for top level decl type",7494 "compile diagnostic string for top level decl type",
7423 \\export fn entry() void {7495 \\export fn entry() void {
7424 \\ var foo: u32 = @This(){};7496 \\ var foo: u32 = @This(){};
7425 \\}7497 \\}
test/stage1/behavior/type.zig+61
...@@ -313,3 +313,64 @@ test "Type.Enum" {...@@ -313,3 +313,64 @@ test "Type.Enum" {
313 testing.expectEqual(@as(u32, 5), @enumToInt(Bar.b));313 testing.expectEqual(@as(u32, 5), @enumToInt(Bar.b));
314 testing.expectEqual(@as(u32, 6), @enumToInt(@intToEnum(Bar, 6)));314 testing.expectEqual(@as(u32, 6), @enumToInt(@intToEnum(Bar, 6)));
315}315}
316
317test "Type.Union" {
318 const Untagged = @Type(.{
319 .Union = .{
320 .layout = .Auto,
321 .tag_type = null,
322 .fields = &[_]TypeInfo.UnionField{
323 .{ .name = "int", .field_type = i32 },
324 .{ .name = "float", .field_type = f32 },
325 },
326 .decls = &[_]TypeInfo.Declaration{},
327 },
328 });
329 var untagged = Untagged{ .int = 1 };
330 untagged.float = 2.0;
331 untagged.int = 3;
332 testing.expectEqual(@as(i32, 3), untagged.int);
333
334 const PackedUntagged = @Type(.{
335 .Union = .{
336 .layout = .Packed,
337 .tag_type = null,
338 .fields = &[_]TypeInfo.UnionField{
339 .{ .name = "signed", .field_type = i32 },
340 .{ .name = "unsigned", .field_type = u32 },
341 },
342 .decls = &[_]TypeInfo.Declaration{},
343 },
344 });
345 var packed_untagged = PackedUntagged{ .signed = -1 };
346 testing.expectEqual(@as(i32, -1), packed_untagged.signed);
347 testing.expectEqual(~@as(u32, 0), packed_untagged.unsigned);
348
349 const Tag = @Type(.{
350 .Enum = .{
351 .layout = .Auto,
352 .tag_type = u1,
353 .fields = &[_]TypeInfo.EnumField{
354 .{ .name = "signed", .value = 0 },
355 .{ .name = "unsigned", .value = 1 },
356 },
357 .decls = &[_]TypeInfo.Declaration{},
358 .is_exhaustive = true,
359 },
360 });
361 const Tagged = @Type(.{
362 .Union = .{
363 .layout = .Auto,
364 .tag_type = Tag,
365 .fields = &[_]TypeInfo.UnionField{
366 .{ .name = "signed", .field_type = i32 },
367 .{ .name = "unsigned", .field_type = u32 },
368 },
369 .decls = &[_]TypeInfo.Declaration{},
370 },
371 });
372 var tagged = Tagged{ .signed = -1 };
373 testing.expectEqual(Tag.signed, tagged);
374 tagged = .{ .unsigned = 1 };
375 testing.expectEqual(Tag.unsigned, tagged);
376}
test/stage1/behavior/type_info.zig-4
...@@ -198,8 +198,6 @@ fn testUnion() void {...@@ -198,8 +198,6 @@ fn testUnion() void {
198 expect(typeinfo_info.Union.layout == .Auto);198 expect(typeinfo_info.Union.layout == .Auto);
199 expect(typeinfo_info.Union.tag_type.? == TypeId);199 expect(typeinfo_info.Union.tag_type.? == TypeId);
200 expect(typeinfo_info.Union.fields.len == 25);200 expect(typeinfo_info.Union.fields.len == 25);
201 expect(typeinfo_info.Union.fields[4].enum_field != null);
202 expect(typeinfo_info.Union.fields[4].enum_field.?.value == 4);
203 expect(typeinfo_info.Union.fields[4].field_type == @TypeOf(@typeInfo(u8).Int));201 expect(typeinfo_info.Union.fields[4].field_type == @TypeOf(@typeInfo(u8).Int));
204 expect(typeinfo_info.Union.decls.len == 21);202 expect(typeinfo_info.Union.decls.len == 21);
205203
...@@ -213,7 +211,6 @@ fn testUnion() void {...@@ -213,7 +211,6 @@ fn testUnion() void {
213 expect(notag_union_info.Union.tag_type == null);211 expect(notag_union_info.Union.tag_type == null);
214 expect(notag_union_info.Union.layout == .Auto);212 expect(notag_union_info.Union.layout == .Auto);
215 expect(notag_union_info.Union.fields.len == 2);213 expect(notag_union_info.Union.fields.len == 2);
216 expect(notag_union_info.Union.fields[0].enum_field == null);
217 expect(notag_union_info.Union.fields[1].field_type == u32);214 expect(notag_union_info.Union.fields[1].field_type == u32);
218215
219 const TestExternUnion = extern union {216 const TestExternUnion = extern union {
...@@ -223,7 +220,6 @@ fn testUnion() void {...@@ -223,7 +220,6 @@ fn testUnion() void {
223 const extern_union_info = @typeInfo(TestExternUnion);220 const extern_union_info = @typeInfo(TestExternUnion);
224 expect(extern_union_info.Union.layout == .Extern);221 expect(extern_union_info.Union.layout == .Extern);
225 expect(extern_union_info.Union.tag_type == null);222 expect(extern_union_info.Union.tag_type == null);
226 expect(extern_union_info.Union.fields[0].enum_field == null);
227 expect(extern_union_info.Union.fields[0].field_type == *c_void);223 expect(extern_union_info.Union.fields[0].field_type == *c_void);
228}224}
229225