mirror of
https://github.com/ziglang/zig.git
synced 2026-01-20 22:35:24 +00:00
stage2: clean up RangeSet and fix swapped Sema switch logic for lhs/rhs
This commit is contained in:
parent
e272c29c16
commit
abd06d8eab
21
BRANCH_TODO
21
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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user