From 88634f0481fb1bd78f8d018b76cab6590691c8a9 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Tue, 29 Dec 2020 12:58:47 +0100 Subject: [PATCH 1/2] stage1: Allow variable capture for multi-prong switch arms Handle the multi-prong case as we do with range cases. Closes #7188 --- src/stage1/ir.cpp | 2 ++ test/stage1/behavior/switch.zig | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/stage1/ir.cpp b/src/stage1/ir.cpp index d3ed3cfaab..edda765ff9 100644 --- a/src/stage1/ir.cpp +++ b/src/stage1/ir.cpp @@ -24207,6 +24207,8 @@ static IrInstGen *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstSrcSwi ref_type->data.pointer.allow_zero); return ir_analyze_ptr_cast(ira, &instruction->base.base, target_value_ptr, &instruction->target_value_ptr->base, new_target_value_ptr_type, &instruction->base.base, false, false); + } else if (instruction->prongs_len > 1) { + return target_value_ptr; } else { ir_add_error(ira, &instruction->base.base, buf_sprintf("switch on type '%s' provides no expression parameter", buf_ptr(&target_type->name))); diff --git a/test/stage1/behavior/switch.zig b/test/stage1/behavior/switch.zig index 28979b8ae8..20ca0d3146 100644 --- a/test/stage1/behavior/switch.zig +++ b/test/stage1/behavior/switch.zig @@ -436,6 +436,26 @@ test "switch with disjoint range" { } } +test "switch variable for range and multiple prongs" { + const S = struct { + fn doTheTest() void { + var u: u8 = 16; + doTheSwitch(u); + comptime doTheSwitch(u); + var v: u8 = 42; + doTheSwitch(v); + comptime doTheSwitch(v); + } + fn doTheSwitch(q: u8) void { + switch (q) { + 0...40 => |x| expect(x == 16), + 41, 42, 43 => |x| expect(x == 42), + else => expect(false), + } + } + }; +} + var state: u32 = 0; fn poll() void { switch (state) { From 2561168adbe642287c1eccd73fc29576ff0216f3 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Tue, 29 Dec 2020 13:00:01 +0100 Subject: [PATCH 2/2] std: Clean up some tests No functional changes, remove some dead code. --- lib/std/dwarf.zig | 10 ++-------- test/stage1/behavior/union.zig | 4 ++-- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/lib/std/dwarf.zig b/lib/std/dwarf.zig index 3ef0540bdd..e1dd85855f 100644 --- a/lib/std/dwarf.zig +++ b/lib/std/dwarf.zig @@ -413,10 +413,7 @@ pub const DwarfInfo = struct { var this_unit_offset: u64 = 0; while (this_unit_offset < try seekable.getEndPos()) { - seekable.seekTo(this_unit_offset) catch |err| switch (err) { - error.EndOfStream => unreachable, - else => return err, - }; + try seekable.seekTo(this_unit_offset); var is_64: bool = undefined; const unit_length = try readUnitLength(in, di.endian, &is_64); @@ -520,10 +517,7 @@ pub const DwarfInfo = struct { var this_unit_offset: u64 = 0; while (this_unit_offset < try seekable.getEndPos()) { - seekable.seekTo(this_unit_offset) catch |err| switch (err) { - error.EndOfStream => unreachable, - else => return err, - }; + try seekable.seekTo(this_unit_offset); var is_64: bool = undefined; const unit_length = try readUnitLength(in, di.endian, &is_64); diff --git a/test/stage1/behavior/union.zig b/test/stage1/behavior/union.zig index d350ae369a..544adaf979 100644 --- a/test/stage1/behavior/union.zig +++ b/test/stage1/behavior/union.zig @@ -742,7 +742,7 @@ test "@unionInit on union w/ tag but no fields" { const Data = union(Type) { no_op: void, - pub fn decode(buf: []const u8) !Data { + pub fn decode(buf: []const u8) Data { return @unionInit(Data, "no_op", {}); } }; @@ -753,7 +753,7 @@ test "@unionInit on union w/ tag but no fields" { fn doTheTest() void { var data: Data = .{ .no_op = .{} }; - var o = try Data.decode(&[_]u8{}); + var o = Data.decode(&[_]u8{}); expectEqual(Type.no_op, o); } };