Commit e6ebf56dd6

Veikka Tuominen <git@vexu.eu>
2022-06-30 16:38:04
Sema: validate `@intToEnum` int operand type
1 parent ae7b32e
src/Sema.zig
@@ -2439,9 +2439,9 @@ fn zirEnumDecl(
             const field_src = enumFieldSrcLoc(sema.mod.declPtr(block.src_decl), tree.*, src.node_offset.x, field_i);
             const other_tag_src = enumFieldSrcLoc(sema.mod.declPtr(block.src_decl), tree.*, src.node_offset.x, gop.index);
             const msg = msg: {
-                const msg = try sema.errMsg(block, field_src, "duplicate enum tag", .{});
+                const msg = try sema.errMsg(block, field_src, "duplicate enum field '{s}'", .{field_name});
                 errdefer msg.destroy(gpa);
-                try sema.errNote(block, other_tag_src, msg, "other tag here", .{});
+                try sema.errNote(block, other_tag_src, msg, "other field here", .{});
                 break :msg msg;
             };
             return sema.failWithOwnedErrorMsg(block, msg);
@@ -2751,7 +2751,7 @@ fn zirEnsureResultNonError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
     const src = inst_data.src();
     const operand_ty = sema.typeOf(operand);
     switch (operand_ty.zigTypeTag()) {
-        .ErrorSet, .ErrorUnion => return sema.fail(block, src, "error is discarded", .{}),
+        .ErrorSet, .ErrorUnion => return sema.fail(block, src, "error is discardederror is discarded. consider using `try`, `catch`, or `if`", .{}),
         else => return,
     }
 }
@@ -6444,6 +6444,7 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
     if (dest_ty.zigTypeTag() != .Enum) {
         return sema.fail(block, dest_ty_src, "expected enum, found '{}'", .{dest_ty.fmt(sema.mod)});
     }
+    _ = try sema.checkIntType(block, operand_src, sema.typeOf(operand));
 
     if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |int_val| {
         if (dest_ty.isNonexhaustiveEnum()) {
test/cases/compile_errors/stage1/obj/discarding_error_value.zig → test/cases/compile_errors/discarding_error_value.zig
@@ -6,7 +6,7 @@ fn foo() !void {
 }
 
 // error
-// backend=stage1
+// backend=stage2
 // target=native
 //
-// tmp.zig:2:12: error: error is discarded. consider using `try`, `catch`, or `if`
+// :2:12: error: error is discarded. consider using `try`, `catch`, or `if`
test/cases/compile_errors/stage1/obj/duplicate_enum_field.zig → test/cases/compile_errors/duplicate_enum_field.zig
@@ -9,8 +9,8 @@ export fn entry() void {
 }
 
 // error
-// backend=stage1
+// backend=stage2
 // target=native
 //
-// tmp.zig:3:5: error: duplicate enum field: 'Bar'
-// tmp.zig:2:5: note: other field here
+// :3:5: error: duplicate enum field 'Bar'
+// :2:5: note: other field here
test/cases/compile_errors/stage1/obj/duplicate_error_in_switch.zig → test/cases/compile_errors/duplicate_error_in_switch.zig
@@ -15,8 +15,8 @@ fn foo(x: i32) !void {
 }
 
 // error
-// backend=stage1
+// backend=llvm
 // target=native
 //
-// tmp.zig:5:14: error: duplicate switch value: '@typeInfo(@typeInfo(@TypeOf(foo)).Fn.return_type.?).ErrorUnion.error_set.Foo'
-// tmp.zig:3:14: note: other value here
+// :5:9: error: duplicate switch value
+// :3:9: note: other value here
test/cases/compile_errors/stage1/obj/explicitly_casting_non_tag_type_to_enum.zig → test/cases/compile_errors/explicitly_casting_non_tag_type_to_enum.zig
@@ -12,7 +12,7 @@ export fn entry() void {
 }
 
 // error
-// backend=stage1
+// backend=stage2
 // target=native
 //
-// tmp.zig:10:31: error: expected integer type, found 'f32'
+// :10:31: error: expected integer type, found 'f32'
test/stage2/cbe.zig
@@ -729,8 +729,8 @@ pub fn addCases(ctx: *TestContext) !void {
             \\    _ = E1.a;
             \\}
         , &.{
-            ":1:28: error: duplicate enum tag",
-            ":1:22: note: other tag here",
+            ":1:28: error: duplicate enum field 'b'",
+            ":1:22: note: other field here",
         });
 
         case.addError(