Commit 6d24c40b6e

Veikka Tuominen <git@vexu.eu>
2022-06-30 15:10:15
Sema: improve bitcast to enum error
1 parent 902dc8c
Changed files (3)
src
test
cases
src/Sema.zig
@@ -7617,11 +7617,11 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
     const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
 
     const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);
+    const operand = try sema.resolveInst(extra.rhs);
     switch (dest_ty.zigTypeTag()) {
         .AnyFrame,
         .ComptimeFloat,
         .ComptimeInt,
-        .Enum,
         .EnumLiteral,
         .ErrorSet,
         .ErrorUnion,
@@ -7634,7 +7634,21 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
         .Type,
         .Undefined,
         .Void,
-        => return sema.fail(block, dest_ty_src, "invalid type '{}' for @bitCast", .{dest_ty.fmt(sema.mod)}),
+        => return sema.fail(block, dest_ty_src, "cannot @bitCast to '{}'", .{dest_ty.fmt(sema.mod)}),
+
+        .Enum => {
+            const msg = msg: {
+                const msg = try sema.errMsg(block, dest_ty_src, "cannot @bitCast to '{}'", .{dest_ty.fmt(sema.mod)});
+                errdefer msg.destroy(sema.gpa);
+                switch (sema.typeOf(operand).zigTypeTag()) {
+                    .Int, .ComptimeInt => try sema.errNote(block, dest_ty_src, msg, "use @intToEnum for type coercion", .{}),
+                    else => {},
+                }
+
+                break :msg msg;
+            };
+            return sema.failWithOwnedErrorMsg(block, msg);
+        },
 
         .Pointer => return sema.fail(block, dest_ty_src, "cannot @bitCast to '{}', use @ptrCast to cast to a pointer", .{
             dest_ty.fmt(sema.mod),
@@ -7658,8 +7672,6 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
         .Vector,
         => {},
     }
-
-    const operand = try sema.resolveInst(extra.rhs);
     return sema.bitCast(block, dest_ty, operand, operand_src);
 }
 
test/cases/compile_errors/stage1/obj/bitCast_to_enum_type.zig
@@ -1,10 +0,0 @@
-export fn entry() void {
-    const y = @bitCast(enum(u32) { a, b }, @as(u32, 3));
-    _ = y;
-}
-
-// error
-// backend=stage1
-// target=native
-//
-// tmp.zig:2:24: error: cannot cast a value of type 'y'
test/cases/compile_errors/bitCast_to_enum_type.zig
@@ -0,0 +1,12 @@
+export fn entry() void {
+    const E = enum(u32) { a, b };
+    const y = @bitCast(E, @as(u32, 3));
+    _ = y;
+}
+
+// error
+// backend=stage2
+// target=native
+//
+// :3:24: error: cannot @bitCast to 'tmp.entry.E'
+// :3:24: note: use @intToEnum for type coercion