authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-03-31 15:39:04-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-03-31 15:39:04-07:00
logabd06d8eab508319e5f7839c802f4a81d80a0025
tree4c718b756e129b76477e1fa850343cfe8c9191cb
parente272c29c163538159eb81f60cb5da3d7ebe099f9

stage2: clean up RangeSet and fix swapped Sema switch logic for lhs/rhs


3 files changed, 16 insertions(+), 40 deletions(-)

BRANCH_TODO-21
...@@ -38,27 +38,6 @@ Performance optimizations to look into:...@@ -38,27 +38,6 @@ Performance optimizations to look into:
38 * make decl references in ZIR be u32 indexes to the Decl dependencies array hash map38 * make decl references in ZIR be u32 indexes to the Decl dependencies array hash map
39 instead of duplicating *Decl entries in zir.Code.39 instead of duplicating *Decl entries in zir.Code.
4040
41 if (maybe_src) |previous_src| {
42 return sema.mod.fail(&block.base, item.src, "duplicate switch value", .{});
43 // TODO notes "previous value is here" previous_src
44 }
45
46 const item = try sema.resolveInst(item_ref);
47 const value = try sema.resolveConstValue(block, item.src, item);
48 const maybe_src = try range_set.add(value, value, item.src);
49 try sema.validateSwitchDupeValue(parent_block, maybe_src, item.src);
50
51
52 const first = try sema.resolveInst(item_first);
53 const last = try sema.resolveInst(item_last);
54 const maybe_src = try range_set.add(
55 try sema.resolveConstValue(block, range_first_src, first_casted),
56 try sema.resolveConstValue(block, range_last_src, last_casted),
57 item.src,
58 );
59 };
60
61
62 const item = try sema.resolveInst(item_ref);41 const item = try sema.resolveInst(item_ref);
63 if ((try sema.resolveConstValue(block, item.src, item)).toBool()) {42 if ((try sema.resolveConstValue(block, item.src, item)).toBool()) {
64 true_count += 1;43 true_count += 1;
src/RangeSet.zig+14-17
...@@ -7,8 +7,8 @@ const SwitchProngSrc = @import("AstGen.zig").SwitchProngSrc;...@@ -7,8 +7,8 @@ const SwitchProngSrc = @import("AstGen.zig").SwitchProngSrc;
7ranges: std.ArrayList(Range),7ranges: std.ArrayList(Range),
88
9pub const Range = struct {9pub const Range = struct {
10 start: Value,10 first: Value,
11 end: Value,11 last: Value,
12 src: SwitchProngSrc,12 src: SwitchProngSrc,
13};13};
1414
...@@ -22,18 +22,15 @@ pub fn deinit(self: *RangeSet) void {...@@ -22,18 +22,15 @@ pub fn deinit(self: *RangeSet) void {
22 self.ranges.deinit();22 self.ranges.deinit();
23}23}
2424
25pub fn add(self: *RangeSet, start: Value, end: Value, src: SwitchProngSrc) !?SwitchProngSrc {25pub fn add(self: *RangeSet, first: Value, last: Value, src: SwitchProngSrc) !?SwitchProngSrc {
26 for (self.ranges.items) |range| {26 for (self.ranges.items) |range| {
27 if ((start.compare(.gte, range.start) and start.compare(.lte, range.end)) or27 if (last.compare(.gte, range.first) and first.compare(.lte, range.last)) {
28 (end.compare(.gte, range.start) and end.compare(.lte, range.end)))28 return range.src; // They overlap.
29 {
30 // ranges overlap
31 return range.src;
32 }29 }
33 }30 }
34 try self.ranges.append(.{31 try self.ranges.append(.{
35 .start = start,32 .first = first,
36 .end = end,33 .last = last,
37 .src = src,34 .src = src,
38 });35 });
39 return null;36 return null;
...@@ -41,17 +38,17 @@ pub fn add(self: *RangeSet, start: Value, end: Value, src: SwitchProngSrc) !?Swi...@@ -41,17 +38,17 @@ pub fn add(self: *RangeSet, start: Value, end: Value, src: SwitchProngSrc) !?Swi
4138
42/// Assumes a and b do not overlap39/// Assumes a and b do not overlap
43fn lessThan(_: void, a: Range, b: Range) bool {40fn lessThan(_: void, a: Range, b: Range) bool {
44 return a.start.compare(.lt, b.start);41 return a.first.compare(.lt, b.first);
45}42}
4643
47pub fn spans(self: *RangeSet, start: Value, end: Value) !bool {44pub fn spans(self: *RangeSet, first: Value, last: Value) !bool {
48 if (self.ranges.items.len == 0)45 if (self.ranges.items.len == 0)
49 return false;46 return false;
5047
51 std.sort.sort(Range, self.ranges.items, {}, lessThan);48 std.sort.sort(Range, self.ranges.items, {}, lessThan);
5249
53 if (!self.ranges.items[0].start.eql(start) or50 if (!self.ranges.items[0].first.eql(first) or
54 !self.ranges.items[self.ranges.items.len - 1].end.eql(end))51 !self.ranges.items[self.ranges.items.len - 1].last.eql(last))
55 {52 {
56 return false;53 return false;
57 }54 }
...@@ -66,11 +63,11 @@ pub fn spans(self: *RangeSet, start: Value, end: Value) !bool {...@@ -66,11 +63,11 @@ pub fn spans(self: *RangeSet, start: Value, end: Value) !bool {
66 // i starts counting from the second item.63 // i starts counting from the second item.
67 const prev = self.ranges.items[i];64 const prev = self.ranges.items[i];
6865
69 // prev.end + 1 == cur.start66 // prev.last + 1 == cur.first
70 try counter.copy(prev.end.toBigInt(&space));67 try counter.copy(prev.last.toBigInt(&space));
71 try counter.addScalar(counter.toConst(), 1);68 try counter.addScalar(counter.toConst(), 1);
7269
73 const cur_start_int = cur.start.toBigInt(&space);70 const cur_start_int = cur.first.toBigInt(&space);
74 if (!cur_start_int.eq(counter.toConst())) {71 if (!cur_start_int.eq(counter.toConst())) {
75 return false;72 return false;
76 }73 }
src/Sema.zig+2-2
...@@ -2888,7 +2888,7 @@ fn validateSwitchRange(...@@ -2888,7 +2888,7 @@ fn validateSwitchRange(
2888 // because we only have the switch AST node. Only if we know for sure we need to report2888 // because we only have the switch AST node. Only if we know for sure we need to report
2889 // a compile error do we resolve the full source locations.2889 // a compile error do we resolve the full source locations.
2890 const first_val = val: {2890 const first_val = val: {
2891 if (last.value()) |val| {2891 if (first.value()) |val| {
2892 if (val.isUndef()) {2892 if (val.isUndef()) {
2893 const src = switch_prong_src.resolve(block.src_decl, src_node_offset, .first);2893 const src = switch_prong_src.resolve(block.src_decl, src_node_offset, .first);
2894 return sema.failWithUseOfUndef(block, src);2894 return sema.failWithUseOfUndef(block, src);
...@@ -2899,7 +2899,7 @@ fn validateSwitchRange(...@@ -2899,7 +2899,7 @@ fn validateSwitchRange(
2899 return sema.failWithNeededComptime(block, src);2899 return sema.failWithNeededComptime(block, src);
2900 };2900 };
2901 const last_val = val: {2901 const last_val = val: {
2902 if (first.value()) |val| {2902 if (last.value()) |val| {
2903 if (val.isUndef()) {2903 if (val.isUndef()) {
2904 const src = switch_prong_src.resolve(block.src_decl, src_node_offset, .last);2904 const src = switch_prong_src.resolve(block.src_decl, src_node_offset, .last);
2905 return sema.failWithUseOfUndef(block, src);2905 return sema.failWithUseOfUndef(block, src);