diff --git a/src/Sema.zig b/src/Sema.zig index d31447544c..66aa06c5c3 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -31609,13 +31609,7 @@ fn analyzeIsNonErrComptimeOnly( return .bool_false; } - if (operand.toIndex()) |operand_inst| { - switch (sema.air_instructions.items(.tag)[@intFromEnum(operand_inst)]) { - .wrap_errunion_payload => return .bool_true, - .wrap_errunion_err => return .bool_false, - else => {}, - } - } else if (operand == .undef) { + if (operand == .undef) { return .undef_bool; } else if (@intFromEnum(operand) < InternPool.static_len) { // None of the ref tags can be errors. diff --git a/test/cases/error_union_variant_is_runtime_known.zig b/test/cases/error_union_variant_is_runtime_known.zig new file mode 100644 index 0000000000..2128ffa804 --- /dev/null +++ b/test/cases/error_union_variant_is_runtime_known.zig @@ -0,0 +1,22 @@ +// This tests that the variant of an error union is runtime-known when the value is runtime-known. +// This might seem obvious but previously the compiler special-cased the situation where a const +// was assigned a payload or error value, i.e. instead of another error union. + +export fn foo() void { + var runtime_payload: u8 = 0; + _ = &runtime_payload; + const eu: error{a}!u8 = runtime_payload; + if (eu) |_| {} else |_| @compileError("analyzed"); +} + +export fn bar() void { + var runtime_error: error{a} = error.a; + _ = &runtime_error; + const eu: error{a}!u8 = runtime_error; + if (eu) |_| @compileError("analyzed") else |_| {} +} + +// error +// +// :9:29: error: analyzed +// :16:17: error: analyzed