authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-05-07 16:43:20-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-05-07 16:43:20-04:00
log77a1a216d2b3ceb956869ba1716fbb6c0c7eabe8
treef4b33b6b983451391e4d627acc45411e3730c8d5
parent2f633452bb337a3f173c4fd82c2b4a0880f981f5

tagged union field access prioritizes members over enum tags

closes #959

2 files changed, 22 insertions(+), 9 deletions(-)

src/ir.cpp+10-9
...@@ -13736,7 +13736,16 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru...@@ -13736,7 +13736,16 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru
13736 create_const_enum(child_type, &field->value), child_type,13736 create_const_enum(child_type, &field->value), child_type,
13737 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile);13737 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile);
13738 }13738 }
13739 } else if (child_type->id == TypeTableEntryIdUnion &&13739 }
13740 ScopeDecls *container_scope = get_container_scope(child_type);
13741 if (container_scope != nullptr) {
13742 auto entry = container_scope->decl_table.maybe_get(field_name);
13743 Tld *tld = entry ? entry->value : nullptr;
13744 if (tld) {
13745 return ir_analyze_decl_ref(ira, &field_ptr_instruction->base, tld);
13746 }
13747 }
13748 if (child_type->id == TypeTableEntryIdUnion &&
13740 (child_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr ||13749 (child_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr ||
13741 child_type->data.unionation.decl_node->data.container_decl.auto_enum))13750 child_type->data.unionation.decl_node->data.container_decl.auto_enum))
13742 {13751 {
...@@ -13753,14 +13762,6 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru...@@ -13753,14 +13762,6 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru
13753 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile);13762 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile);
13754 }13763 }
13755 }13764 }
13756 ScopeDecls *container_scope = get_container_scope(child_type);
13757 if (container_scope != nullptr) {
13758 auto entry = container_scope->decl_table.maybe_get(field_name);
13759 Tld *tld = entry ? entry->value : nullptr;
13760 if (tld) {
13761 return ir_analyze_decl_ref(ira, &field_ptr_instruction->base, tld);
13762 }
13763 }
13764 ir_add_error(ira, &field_ptr_instruction->base,13765 ir_add_error(ira, &field_ptr_instruction->base,
13765 buf_sprintf("container '%s' has no member called '%s'",13766 buf_sprintf("container '%s' has no member called '%s'",
13766 buf_ptr(&child_type->name), buf_ptr(field_name)));13767 buf_ptr(&child_type->name), buf_ptr(field_name)));
test/cases/union.zig+12
...@@ -272,3 +272,15 @@ const PartialInstWithPayload = union(enum) {...@@ -272,3 +272,15 @@ const PartialInstWithPayload = union(enum) {
272 Compiled: i32,272 Compiled: i32,
273};273};
274274
275
276test "access a member of tagged union with conflicting enum tag name" {
277 const Bar = union(enum) {
278 A: A,
279 B: B,
280
281 const A = u8;
282 const B = void;
283 };
284
285 comptime assert(Bar.A == u8);
286}