authorgravatar for john.schmidt.h@gmail.comJohn Schmidt <john.schmidt.h@gmail.com> 2022-03-19 12:55:58+01:00
committergravatar for john.schmidt.h@gmail.comJohn Schmidt <john.schmidt.h@gmail.com> 2022-04-03 13:49:34+02:00
logf7f4702795d76c606d119941e2cf5d5c3e2045b6
tree49f45c84e078ae18de65e2988289d82137ea6bdc
parent8f0dac01ef00574167ca99b716d9903c86a96a3d

sema: add more info to error messages for enum->union coercion


1 files changed, 27 insertions(+), 9 deletions(-)

src/Sema.zig+27-9
...@@ -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 }
1963619640
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 };