| ... | ... | @@ -21892,17 +21892,18 @@ fn unionFieldPtr( |
| 21892 | 21892 | if (union_val.isUndef()) { |
| 21893 | 21893 | return sema.failWithUseOfUndef(block, src); |
| 21894 | 21894 | } |
| 21895 | const enum_field_index = union_obj.tag_ty.enumFieldIndex(field_name).?; |
| 21895 | 21896 | const tag_and_val = union_val.castTag(.@"union").?.data; |
| 21896 | 21897 | var field_tag_buf: Value.Payload.U32 = .{ |
| 21897 | 21898 | .base = .{ .tag = .enum_field_index }, |
| 21898 | | .data = field_index, |
| 21899 | .data = @intCast(u32, enum_field_index), |
| 21899 | 21900 | }; |
| 21900 | 21901 | const field_tag = Value.initPayload(&field_tag_buf.base); |
| 21901 | 21902 | const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty, sema.mod); |
| 21902 | 21903 | if (!tag_matches) { |
| 21903 | 21904 | const msg = msg: { |
| 21904 | 21905 | const active_index = tag_and_val.tag.castTag(.enum_field_index).?.data; |
| 21905 | | const active_field_name = union_obj.fields.keys()[active_index]; |
| 21906 | const active_field_name = union_obj.tag_ty.enumFieldName(active_index); |
| 21906 | 21907 | const msg = try sema.errMsg(block, src, "access of union field '{s}' while field '{s}' is active", .{ field_name, active_field_name }); |
| 21907 | 21908 | errdefer msg.destroy(sema.gpa); |
| 21908 | 21909 | try sema.addDeclaredHereNote(msg, union_ty); |
| ... | ... | @@ -21927,12 +21928,11 @@ fn unionFieldPtr( |
| 21927 | 21928 | if (!initializing and union_obj.layout == .Auto and block.wantSafety() and |
| 21928 | 21929 | union_ty.unionTagTypeSafety() != null and union_obj.fields.count() > 1) |
| 21929 | 21930 | { |
| 21930 | | const enum_ty = union_ty.unionTagTypeHypothetical(); |
| 21931 | 21931 | const wanted_tag_val = try Value.Tag.enum_field_index.create(sema.arena, field_index); |
| 21932 | | const wanted_tag = try sema.addConstant(enum_ty, wanted_tag_val); |
| 21932 | const wanted_tag = try sema.addConstant(union_obj.tag_ty, wanted_tag_val); |
| 21933 | 21933 | // TODO would it be better if get_union_tag supported pointers to unions? |
| 21934 | 21934 | const union_val = try block.addTyOp(.load, union_ty, union_ptr); |
| 21935 | | const active_tag = try block.addTyOp(.get_union_tag, enum_ty, union_val); |
| 21935 | const active_tag = try block.addTyOp(.get_union_tag, union_obj.tag_ty, union_val); |
| 21936 | 21936 | const ok = try block.addBinOp(.cmp_eq, active_tag, wanted_tag); |
| 21937 | 21937 | try sema.addSafetyCheck(block, ok, .inactive_union_field); |
| 21938 | 21938 | } |
| ... | ... | @@ -21963,9 +21963,10 @@ fn unionFieldVal( |
| 21963 | 21963 | if (union_val.isUndef()) return sema.addConstUndef(field.ty); |
| 21964 | 21964 | |
| 21965 | 21965 | const tag_and_val = union_val.castTag(.@"union").?.data; |
| 21966 | const enum_field_index = union_obj.tag_ty.enumFieldIndex(field_name).?; |
| 21966 | 21967 | var field_tag_buf: Value.Payload.U32 = .{ |
| 21967 | 21968 | .base = .{ .tag = .enum_field_index }, |
| 21968 | | .data = field_index, |
| 21969 | .data = @intCast(u32, enum_field_index), |
| 21969 | 21970 | }; |
| 21970 | 21971 | const field_tag = Value.initPayload(&field_tag_buf.base); |
| 21971 | 21972 | const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty, sema.mod); |
| ... | ... | @@ -21976,7 +21977,7 @@ fn unionFieldVal( |
| 21976 | 21977 | } else { |
| 21977 | 21978 | const msg = msg: { |
| 21978 | 21979 | const active_index = tag_and_val.tag.castTag(.enum_field_index).?.data; |
| 21979 | | const active_field_name = union_obj.fields.keys()[active_index]; |
| 21980 | const active_field_name = union_obj.tag_ty.enumFieldName(active_index); |
| 21980 | 21981 | const msg = try sema.errMsg(block, src, "access of union field '{s}' while field '{s}' is active", .{ field_name, active_field_name }); |
| 21981 | 21982 | errdefer msg.destroy(sema.gpa); |
| 21982 | 21983 | try sema.addDeclaredHereNote(msg, union_ty); |
| ... | ... | @@ -22001,10 +22002,9 @@ fn unionFieldVal( |
| 22001 | 22002 | if (union_obj.layout == .Auto and block.wantSafety() and |
| 22002 | 22003 | union_ty.unionTagTypeSafety() != null and union_obj.fields.count() > 1) |
| 22003 | 22004 | { |
| 22004 | | const enum_ty = union_ty.unionTagTypeHypothetical(); |
| 22005 | 22005 | const wanted_tag_val = try Value.Tag.enum_field_index.create(sema.arena, field_index); |
| 22006 | | const wanted_tag = try sema.addConstant(enum_ty, wanted_tag_val); |
| 22007 | | const active_tag = try block.addTyOp(.get_union_tag, enum_ty, union_byval); |
| 22006 | const wanted_tag = try sema.addConstant(union_obj.tag_ty, wanted_tag_val); |
| 22007 | const active_tag = try block.addTyOp(.get_union_tag, union_obj.tag_ty, union_byval); |
| 22008 | 22008 | const ok = try block.addBinOp(.cmp_eq, active_tag, wanted_tag); |
| 22009 | 22009 | try sema.addSafetyCheck(block, ok, .inactive_union_field); |
| 22010 | 22010 | } |