diff --git a/src/zir_sema.zig b/src/zir_sema.zig index 6203b96215fe..54198de9dc94 100644 --- a/src/zir_sema.zig +++ b/src/zir_sema.zig @@ -1388,9 +1388,8 @@ fn validateSwitch(mod: *Module, scope: *Scope, target: *Inst, inst: *zir.Inst.Sw const gotten_err_set = target.ty.getErrs(); const is_anyerror = gotten_err_set == .anyerror; var is_single = gotten_err_set == .err_single; - if (is_anyerror and !(inst.kw_args.special_prong == .@"else")) { + if (is_anyerror and !(inst.kw_args.special_prong == .@"else")) return mod.fail(scope, inst.base.src, "else prong required when switching on type 'anyerror'", .{}); - } var seen_values = std.HashMap(Value, usize, Value.hash, Value.eql, std.hash_map.DefaultMaxLoadPercentage).init(mod.gpa); defer seen_values.deinit(); for (inst.positionals.items) |item| { @@ -1413,8 +1412,22 @@ fn validateSwitch(mod: *Module, scope: *Scope, target: *Inst, inst: *zir.Inst.Sw // } // } } - if (!is_single and !is_anyerror and gotten_err_set.multiple.size > inst.positionals.items.len and !(inst.kw_args.special_prong == .@"else")) - return mod.fail(scope, inst.base.src, "switch must handle all possibilities", .{}); + if (!is_single and !is_anyerror and gotten_err_set.multiple.size > inst.positionals.items.len and !(inst.kw_args.special_prong == .@"else")) { + var not_handled = false; + var it = gotten_err_set.multiple.iterator(); + while (it.next()) |entry| { + var err: Value.Payload.Error = .{ .name = entry.key, .value = entry.value }; + const e_val = Value.initPayload(&err.base); + if (seen_values.get(e_val) == null) { + switch (mod.fail(scope, inst.base.src, "error.{} not handled in switch", .{entry.key})) { + error.AnalysisFail => {}, + else => |e| return e, + } + not_handled = true; + } + } + if (not_handled) return error.AnalysisFail; + } }, .Int, .ComptimeInt => { var range_set = @import("RangeSet.zig").init(mod.gpa);