| ... | @@ -19596,13 +19596,17 @@ fn coerceEnumToUnion( | ... | @@ -19596,13 +19596,17 @@ fn coerceEnumToUnion( |
| 19596 | const field = union_obj.fields.values()[field_index]; | 19596 | const field = union_obj.fields.values()[field_index]; |
| 19597 | const field_ty = try sema.resolveTypeFields(block, inst_src, field.ty); | 19597 | const field_ty = try sema.resolveTypeFields(block, inst_src, field.ty); |
| 19598 | const opv = (try sema.typeHasOnePossibleValue(block, inst_src, field_ty)) orelse { | 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 | const msg = msg: { | 19599 | const msg = msg: { |
| 19602 | const msg = try sema.errMsg(block, inst_src, "coercion to union {} must initialize {} field", .{ | 19600 | const field_name = union_obj.fields.keys()[field_index]; |
| 19603 | union_ty.fmt(target), field_ty.fmt(target), | 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 | errdefer msg.destroy(sema.gpa); | 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 | try sema.addDeclaredHereNote(msg, union_ty); | 19610 | try sema.addDeclaredHereNote(msg, union_ty); |
| 19607 | break :msg msg; | 19611 | break :msg msg; |
| 19608 | }; | 19612 | }; |
| ... | @@ -19634,13 +19638,27 @@ fn coerceEnumToUnion( | ... | @@ -19634,13 +19638,27 @@ fn coerceEnumToUnion( |
| 19634 | return block.addBitCast(union_ty, enum_tag); | 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 | const msg = msg: { | 19641 | const msg = msg: { |
| 19640 | const msg = try sema.errMsg(block, inst_src, "runtime coercion to union {} which has non-void fields", .{ | 19642 | const union_obj = union_ty.cast(Type.Payload.Union).?.data; |
| 19641 | union_ty.fmt(target), | 19643 | const msg = try sema.errMsg( |
| 19642 | }); | 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 | errdefer msg.destroy(sema.gpa); | 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 | try sema.addDeclaredHereNote(msg, union_ty); | 19662 | try sema.addDeclaredHereNote(msg, union_ty); |
| 19645 | break :msg msg; | 19663 | break :msg msg; |
| 19646 | }; | 19664 | }; |