Commit abd06d8eab

Andrew Kelley <andrew@ziglang.org>
2021-04-01 00:39:04
stage2: clean up RangeSet and fix swapped Sema switch logic for lhs/rhs
1 parent e272c29
Changed files (3)
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;
         }
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);
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;