From abd06d8eab508319e5f7839c802f4a81d80a0025 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 31 Mar 2021 15:39:04 -0700 Subject: [PATCH] stage2: clean up RangeSet and fix swapped Sema switch logic for lhs/rhs --- BRANCH_TODO | 21 --------------------- src/RangeSet.zig | 31 ++++++++++++++----------------- src/Sema.zig | 4 ++-- 3 files changed, 16 insertions(+), 40 deletions(-) diff --git a/BRANCH_TODO b/BRANCH_TODO index a3a97ae5b5..671c77c683 100644 --- a/BRANCH_TODO +++ b/BRANCH_TODO @@ -38,27 +38,6 @@ Performance optimizations to look into: * make decl references in ZIR be u32 indexes to the Decl dependencies array hash map instead of duplicating *Decl entries in zir.Code. - if (maybe_src) |previous_src| { - return sema.mod.fail(&block.base, item.src, "duplicate switch value", .{}); - // TODO notes "previous value is here" previous_src - } - - const item = try sema.resolveInst(item_ref); - const value = try sema.resolveConstValue(block, item.src, item); - const maybe_src = try range_set.add(value, value, item.src); - try sema.validateSwitchDupeValue(parent_block, maybe_src, item.src); - - - const first = try sema.resolveInst(item_first); - const last = try sema.resolveInst(item_last); - const maybe_src = try range_set.add( - try sema.resolveConstValue(block, range_first_src, first_casted), - try sema.resolveConstValue(block, range_last_src, last_casted), - item.src, - ); - }; - - const item = try sema.resolveInst(item_ref); if ((try sema.resolveConstValue(block, item.src, item)).toBool()) { true_count += 1; diff --git a/src/RangeSet.zig b/src/RangeSet.zig index 4ae85d0f0b..bd511a5921 100644 --- a/src/RangeSet.zig +++ b/src/RangeSet.zig @@ -7,8 +7,8 @@ const SwitchProngSrc = @import("AstGen.zig").SwitchProngSrc; ranges: std.ArrayList(Range), pub const Range = struct { - start: Value, - end: Value, + first: Value, + last: Value, src: SwitchProngSrc, }; @@ -22,18 +22,15 @@ pub fn deinit(self: *RangeSet) void { self.ranges.deinit(); } -pub fn add(self: *RangeSet, start: Value, end: Value, src: SwitchProngSrc) !?SwitchProngSrc { +pub fn add(self: *RangeSet, first: Value, last: Value, src: SwitchProngSrc) !?SwitchProngSrc { for (self.ranges.items) |range| { - if ((start.compare(.gte, range.start) and start.compare(.lte, range.end)) or - (end.compare(.gte, range.start) and end.compare(.lte, range.end))) - { - // ranges overlap - return range.src; + if (last.compare(.gte, range.first) and first.compare(.lte, range.last)) { + return range.src; // They overlap. } } try self.ranges.append(.{ - .start = start, - .end = end, + .first = first, + .last = last, .src = src, }); return null; @@ -41,17 +38,17 @@ pub fn add(self: *RangeSet, start: Value, end: Value, src: SwitchProngSrc) !?Swi /// Assumes a and b do not overlap fn lessThan(_: void, a: Range, b: Range) bool { - return a.start.compare(.lt, b.start); + return a.first.compare(.lt, b.first); } -pub fn spans(self: *RangeSet, start: Value, end: Value) !bool { +pub fn spans(self: *RangeSet, first: Value, last: Value) !bool { if (self.ranges.items.len == 0) return false; std.sort.sort(Range, self.ranges.items, {}, lessThan); - if (!self.ranges.items[0].start.eql(start) or - !self.ranges.items[self.ranges.items.len - 1].end.eql(end)) + if (!self.ranges.items[0].first.eql(first) or + !self.ranges.items[self.ranges.items.len - 1].last.eql(last)) { return false; } @@ -66,11 +63,11 @@ pub fn spans(self: *RangeSet, start: Value, end: Value) !bool { // i starts counting from the second item. const prev = self.ranges.items[i]; - // prev.end + 1 == cur.start - try counter.copy(prev.end.toBigInt(&space)); + // prev.last + 1 == cur.first + try counter.copy(prev.last.toBigInt(&space)); try counter.addScalar(counter.toConst(), 1); - const cur_start_int = cur.start.toBigInt(&space); + const cur_start_int = cur.first.toBigInt(&space); if (!cur_start_int.eq(counter.toConst())) { return false; } diff --git a/src/Sema.zig b/src/Sema.zig index e702a058dd..6af8cd7b9a 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -2888,7 +2888,7 @@ fn validateSwitchRange( // because we only have the switch AST node. Only if we know for sure we need to report // a compile error do we resolve the full source locations. const first_val = val: { - if (last.value()) |val| { + if (first.value()) |val| { if (val.isUndef()) { const src = switch_prong_src.resolve(block.src_decl, src_node_offset, .first); return sema.failWithUseOfUndef(block, src); @@ -2899,7 +2899,7 @@ fn validateSwitchRange( return sema.failWithNeededComptime(block, src); }; const last_val = val: { - if (first.value()) |val| { + if (last.value()) |val| { if (val.isUndef()) { const src = switch_prong_src.resolve(block.src_decl, src_node_offset, .last); return sema.failWithUseOfUndef(block, src);