Commit 27ee414159

Veikka Tuominen <git@vexu.eu>
2022-07-06 11:17:04
Sema: improve slice source locations
1 parent 2ca752e
Changed files (3)
src
test
cases
compile_errors
src/Module.zig
@@ -2171,7 +2171,11 @@ pub const SrcLoc = struct {
                 const token_starts = tree.tokens.items(.start);
                 return token_starts[tok_index];
             },
-            .node_offset_slice_sentinel => |node_off| {
+            .node_offset_slice_ptr,
+            .node_offset_slice_start,
+            .node_offset_slice_end,
+            .node_offset_slice_sentinel,
+            => |node_off| {
                 const tree = try src_loc.file_scope.getTree(gpa);
                 const node_tags = tree.nodes.items(.tag);
                 const node = src_loc.declRelativeToNodeIndex(node_off);
@@ -2182,7 +2186,15 @@ pub const SrcLoc = struct {
                     else => unreachable,
                 };
                 const main_tokens = tree.nodes.items(.main_token);
-                const tok_index = main_tokens[full.ast.sentinel];
+                const tok_index = main_tokens[
+                    switch (src_loc.lazy) {
+                        .node_offset_slice_ptr => full.ast.sliced,
+                        .node_offset_slice_start => full.ast.start,
+                        .node_offset_slice_end => full.ast.end,
+                        .node_offset_slice_sentinel => full.ast.sentinel,
+                        else => unreachable,
+                    }
+                ];
                 const token_starts = tree.tokens.items(.start);
                 return token_starts[tok_index];
             },
@@ -2624,6 +2636,24 @@ pub const LazySrcLoc = union(enum) {
     /// to the index expression.
     /// The Decl is determined contextually.
     node_offset_array_access_index: i32,
+    /// The source location points to the LHS of a slice expression
+    /// expression, found by taking this AST node index offset from the containing
+    /// Decl AST node, which points to a slice AST node. Next, navigate
+    /// to the sentinel expression.
+    /// The Decl is determined contextually.
+    node_offset_slice_ptr: i32,
+    /// The source location points to start expression of a slice expression
+    /// expression, found by taking this AST node index offset from the containing
+    /// Decl AST node, which points to a slice AST node. Next, navigate
+    /// to the sentinel expression.
+    /// The Decl is determined contextually.
+    node_offset_slice_start: i32,
+    /// The source location points to the end expression of a slice
+    /// expression, found by taking this AST node index offset from the containing
+    /// Decl AST node, which points to a slice AST node. Next, navigate
+    /// to the sentinel expression.
+    /// The Decl is determined contextually.
+    node_offset_slice_end: i32,
     /// The source location points to the sentinel expression of a slice
     /// expression, found by taking this AST node index offset from the containing
     /// Decl AST node, which points to a slice AST node. Next, navigate
@@ -2781,6 +2811,9 @@ pub const LazySrcLoc = union(enum) {
             .node_offset_builtin_call_arg4,
             .node_offset_builtin_call_arg5,
             .node_offset_array_access_index,
+            .node_offset_slice_ptr,
+            .node_offset_slice_start,
+            .node_offset_slice_end,
             .node_offset_slice_sentinel,
             .node_offset_call_func,
             .node_offset_field_name,
src/Sema.zig
@@ -22615,9 +22615,9 @@ fn analyzeSlice(
     sentinel_opt: Air.Inst.Ref,
     sentinel_src: LazySrcLoc,
 ) CompileError!Air.Inst.Ref {
-    const ptr_src = src; // TODO better source location
-    const start_src = src; // TODO better source location
-    const end_src = src; // TODO better source location
+    const ptr_src: LazySrcLoc = .{ .node_offset_slice_ptr = src.node_offset.x };
+    const start_src: LazySrcLoc = .{ .node_offset_slice_start = src.node_offset.x };
+    const end_src: LazySrcLoc = .{ .node_offset_slice_end = src.node_offset.x };
     // Slice expressions can operate on a variable whose type is an array. This requires
     // the slice operand to be a pointer. In the case of a non-array, it will be a double pointer.
     const ptr_ptr_ty = sema.typeOf(ptr_ptr);
@@ -22647,7 +22647,7 @@ fn analyzeSlice(
                     array_ty = double_child_ty;
                     elem_ty = double_child_ty.childType();
                 } else {
-                    return sema.fail(block, ptr_src, "slice of single-item pointer", .{});
+                    return sema.fail(block, src, "slice of single-item pointer", .{});
                 }
             },
             .Many, .C => {
@@ -22660,7 +22660,7 @@ fn analyzeSlice(
                 if (ptr_ptr_child_ty.ptrSize() == .C) {
                     if (try sema.resolveDefinedValue(block, ptr_src, ptr_or_slice)) |ptr_val| {
                         if (ptr_val.isNull()) {
-                            return sema.fail(block, ptr_src, "slice of null pointer", .{});
+                            return sema.fail(block, src, "slice of null pointer", .{});
                         }
                     }
                 }
@@ -22673,7 +22673,7 @@ fn analyzeSlice(
                 elem_ty = ptr_ptr_child_ty.childType();
             },
         },
-        else => return sema.fail(block, ptr_src, "slice of non-array type '{}'", .{ptr_ptr_child_ty.fmt(mod)}),
+        else => return sema.fail(block, src, "slice of non-array type '{}'", .{ptr_ptr_child_ty.fmt(mod)}),
     }
 
     const ptr = if (slice_ty.isSlice())
@@ -22846,7 +22846,7 @@ fn analyzeSlice(
             return sema.addConstUndef(return_ty);
         }
 
-        return sema.fail(block, ptr_src, "non-zero length slice of undefined pointer", .{});
+        return sema.fail(block, src, "non-zero length slice of undefined pointer", .{});
     }
 
     const return_ty = try Type.ptr(sema.arena, mod, .{
test/cases/compile_errors/stage2/out_of_bounds_index.zig
@@ -23,7 +23,7 @@ comptime {
 // error
 // target=native
 //
-// :4:26: error: end index 6 out of bounds for slice of length 4 +1 (sentinel)
-// :9:22: error: end index 6 out of bounds for array of length 4 +1 (sentinel)
-// :14:22: error: end index 5 out of bounds for array of length 4
-// :19:22: error: start index 3 is larger than end index 2
+// :4:30: error: end index 6 out of bounds for slice of length 4 +1 (sentinel)
+// :9:26: error: end index 6 out of bounds for array of length 4 +1 (sentinel)
+// :14:26: error: end index 5 out of bounds for array of length 4
+// :19:23: error: start index 3 is larger than end index 2