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:
3838 * make decl references in ZIR be u32 indexes to the Decl dependencies array hash map
3939 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
6241 const item = try sema.resolveInst(item_ref);
6342 if ((try sema.resolveConstValue(block, item.src, item)).toBool()) {
6443 true_count += 1;
src/RangeSet.zig+14-17
......@@ -7,8 +7,8 @@ const SwitchProngSrc = @import("AstGen.zig").SwitchProngSrc;
77ranges: std.ArrayList(Range),
88
99pub const Range = struct {
10 start: Value,
11 end: Value,
10 first: Value,
11 last: Value,
1212 src: SwitchProngSrc,
1313};
1414
......@@ -22,18 +22,15 @@ pub fn deinit(self: *RangeSet) void {
2222 self.ranges.deinit();
2323}
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 {
2626 for (self.ranges.items) |range| {
27 if ((start.compare(.gte, range.start) and start.compare(.lte, range.end)) or
28 (end.compare(.gte, range.start) and end.compare(.lte, range.end)))
29 {
30 // ranges overlap
31 return range.src;
27 if (last.compare(.gte, range.first) and first.compare(.lte, range.last)) {
28 return range.src; // They overlap.
3229 }
3330 }
3431 try self.ranges.append(.{
35 .start = start,
36 .end = end,
32 .first = first,
33 .last = last,
3734 .src = src,
3835 });
3936 return null;
......@@ -41,17 +38,17 @@ pub fn add(self: *RangeSet, start: Value, end: Value, src: SwitchProngSrc) !?Swi
4138
4239/// Assumes a and b do not overlap
4340fn lessThan(_: void, a: Range, b: Range) bool {
44 return a.start.compare(.lt, b.start);
41 return a.first.compare(.lt, b.first);
4542}
4643
47pub fn spans(self: *RangeSet, start: Value, end: Value) !bool {
44pub fn spans(self: *RangeSet, first: Value, last: Value) !bool {
4845 if (self.ranges.items.len == 0)
4946 return false;
5047
5148 std.sort.sort(Range, self.ranges.items, {}, lessThan);
5249
53 if (!self.ranges.items[0].start.eql(start) or
54 !self.ranges.items[self.ranges.items.len - 1].end.eql(end))
50 if (!self.ranges.items[0].first.eql(first) or
51 !self.ranges.items[self.ranges.items.len - 1].last.eql(last))
5552 {
5653 return false;
5754 }
......@@ -66,11 +63,11 @@ pub fn spans(self: *RangeSet, start: Value, end: Value) !bool {
6663 // i starts counting from the second item.
6764 const prev = self.ranges.items[i];
6865
69 // prev.end + 1 == cur.start
70 try counter.copy(prev.end.toBigInt(&space));
66 // prev.last + 1 == cur.first
67 try counter.copy(prev.last.toBigInt(&space));
7168 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);
7471 if (!cur_start_int.eq(counter.toConst())) {
7572 return false;
7673 }
src/Sema.zig+2-2
......@@ -2888,7 +2888,7 @@ fn validateSwitchRange(
28882888 // because we only have the switch AST node. Only if we know for sure we need to report
28892889 // a compile error do we resolve the full source locations.
28902890 const first_val = val: {
2891 if (last.value()) |val| {
2891 if (first.value()) |val| {
28922892 if (val.isUndef()) {
28932893 const src = switch_prong_src.resolve(block.src_decl, src_node_offset, .first);
28942894 return sema.failWithUseOfUndef(block, src);
......@@ -2899,7 +2899,7 @@ fn validateSwitchRange(
28992899 return sema.failWithNeededComptime(block, src);
29002900 };
29012901 const last_val = val: {
2902 if (first.value()) |val| {
2902 if (last.value()) |val| {
29032903 if (val.isUndef()) {
29042904 const src = switch_prong_src.resolve(block.src_decl, src_node_offset, .last);
29052905 return sema.failWithUseOfUndef(block, src);