diff --git a/src/Sema.zig b/src/Sema.zig index 8f097bb35f..0a609ff0f4 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -8980,36 +8980,41 @@ fn zirDeclLiteral(sema: *Sema, block: *Block, inst: Zir.Inst.Index, do_coerce: b sema.code.nullTerminatedString(extra.field_name_start), .no_embedded_nulls, ); + const orig_ty = sema.resolveType(block, src, extra.lhs) catch |err| switch (err) { - error.GenericPoison => { - // Treat this as a normal enum literal. - return Air.internedToRef(try pt.intern(.{ .enum_literal = name })); - }, + error.GenericPoison => Type.generic_poison, else => |e| return e, }; - var ty = orig_ty; - while (true) switch (ty.zigTypeTag(zcu)) { - .error_union => ty = ty.errorUnionPayload(zcu), - .optional => ty = ty.optionalChild(zcu), - .enum_literal, .error_set => { + const uncoerced_result = res: { + if (orig_ty.toIntern() == .generic_poison_type) { // Treat this as a normal enum literal. - return Air.internedToRef(try pt.intern(.{ .enum_literal = name })); - }, - else => break, + break :res Air.internedToRef(try pt.intern(.{ .enum_literal = name })); + } + + var ty = orig_ty; + while (true) switch (ty.zigTypeTag(zcu)) { + .error_union => ty = ty.errorUnionPayload(zcu), + .optional => ty = ty.optionalChild(zcu), + .enum_literal, .error_set => { + // Treat this as a normal enum literal. + break :res Air.internedToRef(try pt.intern(.{ .enum_literal = name })); + }, + else => break, + }; + + break :res try sema.fieldVal(block, src, Air.internedToRef(ty.toIntern()), name, src); }; - const result = try sema.fieldVal(block, src, Air.internedToRef(ty.toIntern()), name, src); - // Decl literals cannot lookup runtime `var`s. - if (!try sema.isComptimeKnown(result)) { + if (!try sema.isComptimeKnown(uncoerced_result)) { return sema.fail(block, src, "decl literal must be comptime-known", .{}); } if (do_coerce) { - return sema.coerce(block, orig_ty, result, src); + return sema.coerce(block, orig_ty, uncoerced_result, src); } else { - return result; + return uncoerced_result; } } diff --git a/test/cases/compile_errors/error_set_decl_literal.zig b/test/cases/compile_errors/error_set_decl_literal.zig new file mode 100644 index 0000000000..b825c09ae5 --- /dev/null +++ b/test/cases/compile_errors/error_set_decl_literal.zig @@ -0,0 +1,9 @@ +export fn entry() void { + const E = error{Foo}; + const e: E = .Foo; + _ = e; +} + +// error +// +// :3:19: error: expected type 'error{Foo}', found '@TypeOf(.enum_literal)'