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

This commit is contained in:
Andrew Kelley 2021-03-31 15:39:04 -07:00
parent e272c29c16
commit abd06d8eab
3 changed files with 16 additions and 40 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -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);