| author | |
| committer | |
| log | cf207df5926c2f303ad92069e44bec51bfa44148 |
| tree | 093fb27867621e32699bd7fdd179b4e045846917 |
| parent | 1463144fc88550ba1dca3888acdcdd4903781222 |
```zig
const U = union { foo: u32, bar: u32 };
test {
var a = U{ .foo = 1213, .bar = 1123 };
_ = a;
}
test {
var a: (123 + 5238094) = 0;
_ = a;
}
```
before:
```
:30: note: additional initializer here
var a = U{ .foo = 1213, .bar = 1123 };
^~~
:12: error: expected type 'type', found 'comptime_int'
var a: (123 + 5238094) = 0;
^
```
after:
```
:30: note: additional initializer here
var a = U{ .foo = 1213, .bar = 1123 };
~^~~~~~~~~~
:12: error: expected type 'type', found 'comptime_int'
var a: (123 + 5238094) = 0;
^~~~~~~~~~~~~~~
```2 files changed, 38 insertions(+), 33 deletions(-)
src/Module.zig+30-25| ... | ... | @@ -2132,13 +2132,15 @@ pub const SrcLoc = struct { |
| 2132 | 2132 | assert(src_loc.file_scope.tree_loaded); |
| 2133 | 2133 | return nodeToSpan(tree, node); |
| 2134 | 2134 | }, |
| 2135 | .node_offset_back2tok => |node_off| { | |
| 2135 | .node_offset_initializer => |node_off| { | |
| 2136 | 2136 | const tree = try src_loc.file_scope.getTree(gpa); |
| 2137 | 2137 | const node = src_loc.declRelativeToNodeIndex(node_off); |
| 2138 | const tok_index = tree.firstToken(node) - 2; | |
| 2139 | const start = tree.tokens.items(.start)[tok_index]; | |
| 2140 | const end = start + @intCast(u32, tree.tokenSlice(tok_index).len); | |
| 2141 | return Span{ .start = start, .end = end, .main = start }; | |
| 2138 | return tokensToSpan( | |
| 2139 | tree, | |
| 2140 | tree.firstToken(node) - 3, | |
| 2141 | tree.lastToken(node), | |
| 2142 | tree.nodes.items(.main_token)[node] - 2, | |
| 2143 | ); | |
| 2142 | 2144 | }, |
| 2143 | 2145 | .node_offset_var_decl_ty => |node_off| { |
| 2144 | 2146 | const tree = try src_loc.file_scope.getTree(gpa); |
| ... | ... | @@ -2151,12 +2153,10 @@ pub const SrcLoc = struct { |
| 2151 | 2153 | .aligned_var_decl => tree.alignedVarDecl(node), |
| 2152 | 2154 | else => unreachable, |
| 2153 | 2155 | }; |
| 2154 | const tok_index = if (full.ast.type_node != 0) blk: { | |
| 2155 | const main_tokens = tree.nodes.items(.main_token); | |
| 2156 | break :blk main_tokens[full.ast.type_node]; | |
| 2157 | } else blk: { | |
| 2158 | break :blk full.ast.mut_token + 1; // the name token | |
| 2159 | }; | |
| 2156 | if (full.ast.type_node != 0) { | |
| 2157 | return nodeToSpan(tree, full.ast.type_node); | |
| 2158 | } | |
| 2159 | const tok_index = full.ast.mut_token + 1; // the name token | |
| 2160 | 2160 | const start = tree.tokens.items(.start)[tok_index]; |
| 2161 | 2161 | const end = start + @intCast(u32, tree.tokenSlice(tok_index).len); |
| 2162 | 2162 | return Span{ .start = start, .end = end, .main = start }; |
| ... | ... | @@ -2492,26 +2492,32 @@ pub const SrcLoc = struct { |
| 2492 | 2492 | } |
| 2493 | 2493 | |
| 2494 | 2494 | pub fn nodeToSpan(tree: *const Ast, node: u32) Span { |
| 2495 | return tokensToSpan( | |
| 2496 | tree, | |
| 2497 | tree.firstToken(node), | |
| 2498 | tree.lastToken(node), | |
| 2499 | tree.nodes.items(.main_token)[node], | |
| 2500 | ); | |
| 2501 | } | |
| 2502 | ||
| 2503 | fn tokensToSpan(tree: *const Ast, start: Ast.TokenIndex, end: Ast.TokenIndex, main: Ast.TokenIndex) Span { | |
| 2495 | 2504 | const token_starts = tree.tokens.items(.start); |
| 2496 | const main_token = tree.nodes.items(.main_token)[node]; | |
| 2497 | const start = tree.firstToken(node); | |
| 2498 | const end = tree.lastToken(node); | |
| 2499 | 2505 | var start_tok = start; |
| 2500 | 2506 | var end_tok = end; |
| 2501 | 2507 | |
| 2502 | 2508 | if (tree.tokensOnSameLine(start, end)) { |
| 2503 | 2509 | // do nothing |
| 2504 | } else if (tree.tokensOnSameLine(start, main_token)) { | |
| 2505 | end_tok = main_token; | |
| 2506 | } else if (tree.tokensOnSameLine(main_token, end)) { | |
| 2507 | start_tok = main_token; | |
| 2510 | } else if (tree.tokensOnSameLine(start, main)) { | |
| 2511 | end_tok = main; | |
| 2512 | } else if (tree.tokensOnSameLine(main, end)) { | |
| 2513 | start_tok = main; | |
| 2508 | 2514 | } else { |
| 2509 | start_tok = main_token; | |
| 2510 | end_tok = main_token; | |
| 2515 | start_tok = main; | |
| 2516 | end_tok = main; | |
| 2511 | 2517 | } |
| 2512 | 2518 | const start_off = token_starts[start_tok]; |
| 2513 | 2519 | const end_off = token_starts[end_tok] + @intCast(u32, tree.tokenSlice(end_tok).len); |
| 2514 | return Span{ .start = start_off, .end = end_off, .main = token_starts[main_token] }; | |
| 2520 | return Span{ .start = start_off, .end = end_off, .main = token_starts[main] }; | |
| 2515 | 2521 | } |
| 2516 | 2522 | }; |
| 2517 | 2523 | |
| ... | ... | @@ -2565,10 +2571,9 @@ pub const LazySrcLoc = union(enum) { |
| 2565 | 2571 | /// from its containing Decl node AST index. |
| 2566 | 2572 | /// The Decl is determined contextually. |
| 2567 | 2573 | node_offset: TracedOffset, |
| 2568 | /// The source location points to two tokens left of the first token of an AST node, | |
| 2569 | /// which is this value offset from its containing Decl node AST index. | |
| 2574 | /// The source location points to the beginning of a struct initializer. | |
| 2570 | 2575 | /// The Decl is determined contextually. |
| 2571 | node_offset_back2tok: i32, | |
| 2576 | node_offset_initializer: i32, | |
| 2572 | 2577 | /// The source location points to a variable declaration type expression, |
| 2573 | 2578 | /// found by taking this AST node index offset from the containing |
| 2574 | 2579 | /// Decl AST node, which points to a variable declaration AST node. Next, navigate |
| ... | ... | @@ -2764,7 +2769,7 @@ pub const LazySrcLoc = union(enum) { |
| 2764 | 2769 | .byte_offset, |
| 2765 | 2770 | .token_offset, |
| 2766 | 2771 | .node_offset, |
| 2767 | .node_offset_back2tok, | |
| 2772 | .node_offset_initializer, | |
| 2768 | 2773 | .node_offset_var_decl_ty, |
| 2769 | 2774 | .node_offset_for_cond, |
| 2770 | 2775 | .node_offset_builtin_call_arg0, |
src/Sema.zig+8-8| ... | ... | @@ -3403,7 +3403,7 @@ fn validateUnionInit( |
| 3403 | 3403 | |
| 3404 | 3404 | for (instrs[1..]) |inst| { |
| 3405 | 3405 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| 3406 | const inst_src: LazySrcLoc = .{ .node_offset_back2tok = inst_data.src_node }; | |
| 3406 | const inst_src: LazySrcLoc = .{ .node_offset_initializer = inst_data.src_node }; | |
| 3407 | 3407 | try sema.errNote(block, inst_src, msg, "additional initializer here", .{}); |
| 3408 | 3408 | } |
| 3409 | 3409 | try sema.addDeclaredHereNote(msg, union_ty); |
| ... | ... | @@ -3421,7 +3421,7 @@ fn validateUnionInit( |
| 3421 | 3421 | |
| 3422 | 3422 | const field_ptr = instrs[0]; |
| 3423 | 3423 | const field_ptr_data = sema.code.instructions.items(.data)[field_ptr].pl_node; |
| 3424 | const field_src: LazySrcLoc = .{ .node_offset_back2tok = field_ptr_data.src_node }; | |
| 3424 | const field_src: LazySrcLoc = .{ .node_offset_initializer = field_ptr_data.src_node }; | |
| 3425 | 3425 | const field_ptr_extra = sema.code.extraData(Zir.Inst.Field, field_ptr_data.payload_index).data; |
| 3426 | 3426 | const field_name = sema.code.nullTerminatedString(field_ptr_extra.field_name_start); |
| 3427 | 3427 | const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_src); |
| ... | ... | @@ -3523,7 +3523,7 @@ fn validateStructInit( |
| 3523 | 3523 | |
| 3524 | 3524 | for (instrs) |field_ptr| { |
| 3525 | 3525 | const field_ptr_data = sema.code.instructions.items(.data)[field_ptr].pl_node; |
| 3526 | const field_src: LazySrcLoc = .{ .node_offset_back2tok = field_ptr_data.src_node }; | |
| 3526 | const field_src: LazySrcLoc = .{ .node_offset_initializer = field_ptr_data.src_node }; | |
| 3527 | 3527 | const field_ptr_extra = sema.code.extraData(Zir.Inst.Field, field_ptr_data.payload_index).data; |
| 3528 | 3528 | struct_ptr_zir_ref = field_ptr_extra.lhs; |
| 3529 | 3529 | const field_name = sema.code.nullTerminatedString(field_ptr_extra.field_name_start); |
| ... | ... | @@ -3531,7 +3531,7 @@ fn validateStructInit( |
| 3531 | 3531 | if (found_fields[field_index] != 0) { |
| 3532 | 3532 | const other_field_ptr = found_fields[field_index]; |
| 3533 | 3533 | const other_field_ptr_data = sema.code.instructions.items(.data)[other_field_ptr].pl_node; |
| 3534 | const other_field_src: LazySrcLoc = .{ .node_offset_back2tok = other_field_ptr_data.src_node }; | |
| 3534 | const other_field_src: LazySrcLoc = .{ .node_offset_initializer = other_field_ptr_data.src_node }; | |
| 3535 | 3535 | const msg = msg: { |
| 3536 | 3536 | const msg = try sema.errMsg(block, field_src, "duplicate field", .{}); |
| 3537 | 3537 | errdefer msg.destroy(gpa); |
| ... | ... | @@ -3606,7 +3606,7 @@ fn validateStructInit( |
| 3606 | 3606 | field: for (found_fields) |field_ptr, i| { |
| 3607 | 3607 | if (field_ptr != 0) { |
| 3608 | 3608 | const field_ptr_data = sema.code.instructions.items(.data)[field_ptr].pl_node; |
| 3609 | const field_src: LazySrcLoc = .{ .node_offset_back2tok = field_ptr_data.src_node }; | |
| 3609 | const field_src: LazySrcLoc = .{ .node_offset_initializer = field_ptr_data.src_node }; | |
| 3610 | 3610 | |
| 3611 | 3611 | // Determine whether the value stored to this pointer is comptime-known. |
| 3612 | 3612 | const field_ty = struct_ty.structFieldType(i); |
| ... | ... | @@ -13999,14 +13999,14 @@ fn zirStructInit( |
| 13999 | 13999 | extra_index = item.end; |
| 14000 | 14000 | |
| 14001 | 14001 | const field_type_data = zir_datas[item.data.field_type].pl_node; |
| 14002 | const field_src: LazySrcLoc = .{ .node_offset_back2tok = field_type_data.src_node }; | |
| 14002 | const field_src: LazySrcLoc = .{ .node_offset_initializer = field_type_data.src_node }; | |
| 14003 | 14003 | const field_type_extra = sema.code.extraData(Zir.Inst.FieldType, field_type_data.payload_index).data; |
| 14004 | 14004 | const field_name = sema.code.nullTerminatedString(field_type_extra.name_start); |
| 14005 | 14005 | const field_index = try sema.structFieldIndex(block, resolved_ty, field_name, field_src); |
| 14006 | 14006 | if (field_inits[field_index] != .none) { |
| 14007 | 14007 | const other_field_type = found_fields[field_index]; |
| 14008 | 14008 | const other_field_type_data = zir_datas[other_field_type].pl_node; |
| 14009 | const other_field_src: LazySrcLoc = .{ .node_offset_back2tok = other_field_type_data.src_node }; | |
| 14009 | const other_field_src: LazySrcLoc = .{ .node_offset_initializer = other_field_type_data.src_node }; | |
| 14010 | 14010 | const msg = msg: { |
| 14011 | 14011 | const msg = try sema.errMsg(block, field_src, "duplicate field", .{}); |
| 14012 | 14012 | errdefer msg.destroy(gpa); |
| ... | ... | @@ -14028,7 +14028,7 @@ fn zirStructInit( |
| 14028 | 14028 | const item = sema.code.extraData(Zir.Inst.StructInit.Item, extra.end); |
| 14029 | 14029 | |
| 14030 | 14030 | const field_type_data = zir_datas[item.data.field_type].pl_node; |
| 14031 | const field_src: LazySrcLoc = .{ .node_offset_back2tok = field_type_data.src_node }; | |
| 14031 | const field_src: LazySrcLoc = .{ .node_offset_initializer = field_type_data.src_node }; | |
| 14032 | 14032 | const field_type_extra = sema.code.extraData(Zir.Inst.FieldType, field_type_data.payload_index).data; |
| 14033 | 14033 | const field_name = sema.code.nullTerminatedString(field_type_extra.name_start); |
| 14034 | 14034 | const field_index = try sema.unionFieldIndex(block, resolved_ty, field_name, field_src); |