| ... | ... | @@ -19596,13 +19596,17 @@ fn coerceEnumToUnion( |
| 19596 | 19596 | const field = union_obj.fields.values()[field_index]; |
| 19597 | 19597 | const field_ty = try sema.resolveTypeFields(block, inst_src, field.ty); |
| 19598 | 19598 | const opv = (try sema.typeHasOnePossibleValue(block, inst_src, field_ty)) orelse { |
| 19599 | | // TODO resolve the field names and include in the error message, |
| 19600 | | // also instead of 'union declared here' make it 'field "foo" declared here'. |
| 19601 | 19599 | const msg = msg: { |
| 19602 | | const msg = try sema.errMsg(block, inst_src, "coercion to union {} must initialize {} field", .{ |
| 19603 | | union_ty.fmt(target), field_ty.fmt(target), |
| 19600 | const field_name = union_obj.fields.keys()[field_index]; |
| 19601 | const msg = try sema.errMsg(block, inst_src, "coercion from enum '{}' to union '{}' must initialize '{}' field '{s}'", .{ |
| 19602 | inst_ty.fmt(target), union_ty.fmt(target), field_ty.fmt(target), field_name, |
| 19604 | 19603 | }); |
| 19605 | 19604 | errdefer msg.destroy(sema.gpa); |
| 19605 | |
| 19606 | const tree = try sema.getAstTree(block); |
| 19607 | const union_decl = union_obj.owner_decl; |
| 19608 | const field_src = enumFieldSrcLoc(union_decl, tree.*, union_obj.node_offset, field_index); |
| 19609 | try sema.mod.errNoteNonLazy(field_src.toSrcLoc(union_decl), msg, "field '{s}' declared here", .{field_name}); |
| 19606 | 19610 | try sema.addDeclaredHereNote(msg, union_ty); |
| 19607 | 19611 | break :msg msg; |
| 19608 | 19612 | }; |
| ... | ... | @@ -19634,13 +19638,27 @@ fn coerceEnumToUnion( |
| 19634 | 19638 | return block.addBitCast(union_ty, enum_tag); |
| 19635 | 19639 | } |
| 19636 | 19640 | |
| 19637 | | // TODO resolve the field names and add a hint that says "field 'foo' has type 'bar'" |
| 19638 | | // instead of the "union declared here" hint |
| 19639 | 19641 | const msg = msg: { |
| 19640 | | const msg = try sema.errMsg(block, inst_src, "runtime coercion to union {} which has non-void fields", .{ |
| 19641 | | union_ty.fmt(target), |
| 19642 | | }); |
| 19642 | const union_obj = union_ty.cast(Type.Payload.Union).?.data; |
| 19643 | const msg = try sema.errMsg( |
| 19644 | block, |
| 19645 | inst_src, |
| 19646 | "runtime coercion from enum '{}' to union '{}' which has non-void fields", |
| 19647 | .{ tag_ty.fmt(target), union_ty.fmt(target) }, |
| 19648 | ); |
| 19643 | 19649 | errdefer msg.destroy(sema.gpa); |
| 19650 | |
| 19651 | const tree = try sema.getAstTree(block); |
| 19652 | const union_decl = union_obj.owner_decl; |
| 19653 | var it = union_obj.fields.iterator(); |
| 19654 | var field_index: usize = 0; |
| 19655 | while (it.next()) |field| { |
| 19656 | const field_name = field.key_ptr.*; |
| 19657 | const field_ty = field.value_ptr.ty; |
| 19658 | const field_src = enumFieldSrcLoc(union_decl, tree.*, union_obj.node_offset, field_index); |
| 19659 | try sema.mod.errNoteNonLazy(field_src.toSrcLoc(union_decl), msg, "field '{s}' has type '{}'", .{ field_name, field_ty.fmt(target) }); |
| 19660 | field_index += 1; |
| 19661 | } |
| 19644 | 19662 | try sema.addDeclaredHereNote(msg, union_ty); |
| 19645 | 19663 | break :msg msg; |
| 19646 | 19664 | }; |