| author | |
| committer | |
| log | 4dd958d585256df3119d5617d22492f41ed02884 |
| tree | 6be6266e06c0b1dd5ad13992292046a6bae1537d |
| parent | 601db3981ce820cfbca6001cbdfa87e24aa35ab5 |
4 files changed, 74 insertions(+), 7 deletions(-)
lib/std/crypto/aes/soft.zig+1-1| ... | ... | @@ -420,7 +420,7 @@ const powx = init: { |
| 420 | 420 | var array: [16]u8 = undefined; |
| 421 | 421 | |
| 422 | 422 | var value = 1; |
| 423 | for (array) |*power| { | |
| 423 | for (&array) |*power| { | |
| 424 | 424 | power.* = value; |
| 425 | 425 | value = mul(value, 2); |
| 426 | 426 | } |
src/Module.zig+49| ... | ... | @@ -2469,6 +2469,48 @@ pub const SrcLoc = struct { |
| 2469 | 2469 | const src_node = for_full.ast.inputs[for_input.input_index]; |
| 2470 | 2470 | return nodeToSpan(tree, src_node); |
| 2471 | 2471 | }, |
| 2472 | .for_capture_from_input => |node_off| { | |
| 2473 | const tree = try src_loc.file_scope.getTree(gpa); | |
| 2474 | const token_tags = tree.tokens.items(.tag); | |
| 2475 | const input_node = src_loc.declRelativeToNodeIndex(node_off); | |
| 2476 | // We have to actually linear scan the whole AST to find the for loop | |
| 2477 | // that contains this input. | |
| 2478 | const node_tags = tree.nodes.items(.tag); | |
| 2479 | for (node_tags, 0..) |node_tag, node_usize| { | |
| 2480 | const node = @intCast(Ast.Node.Index, node_usize); | |
| 2481 | switch (node_tag) { | |
| 2482 | .for_simple, .@"for" => { | |
| 2483 | const for_full = tree.fullFor(node).?; | |
| 2484 | for (for_full.ast.inputs, 0..) |input, input_index| { | |
| 2485 | if (input_node == input) { | |
| 2486 | var count = input_index; | |
| 2487 | var tok = for_full.payload_token; | |
| 2488 | while (true) { | |
| 2489 | switch (token_tags[tok]) { | |
| 2490 | .comma => { | |
| 2491 | count -= 1; | |
| 2492 | tok += 1; | |
| 2493 | }, | |
| 2494 | .identifier => { | |
| 2495 | if (count == 0) | |
| 2496 | return tokensToSpan(tree, tok, tok + 1, tok); | |
| 2497 | tok += 1; | |
| 2498 | }, | |
| 2499 | .asterisk => { | |
| 2500 | if (count == 0) | |
| 2501 | return tokensToSpan(tree, tok, tok + 2, tok); | |
| 2502 | tok += 1; | |
| 2503 | }, | |
| 2504 | else => unreachable, | |
| 2505 | } | |
| 2506 | } | |
| 2507 | } | |
| 2508 | } | |
| 2509 | }, | |
| 2510 | else => continue, | |
| 2511 | } | |
| 2512 | } else unreachable; | |
| 2513 | }, | |
| 2472 | 2514 | .node_offset_bin_lhs => |node_off| { |
| 2473 | 2515 | const tree = try src_loc.file_scope.getTree(gpa); |
| 2474 | 2516 | const node = src_loc.declRelativeToNodeIndex(node_off); |
| ... | ... | @@ -3129,6 +3171,12 @@ pub const LazySrcLoc = union(enum) { |
| 3129 | 3171 | /// Picks one of the inputs from the condition. |
| 3130 | 3172 | input_index: u32, |
| 3131 | 3173 | }, |
| 3174 | /// The source location points to one of the captures of a for loop, found | |
| 3175 | /// by taking this AST node index offset from the containing | |
| 3176 | /// Decl AST node, which points to one of the input nodes of a for loop. | |
| 3177 | /// Next, navigate to the corresponding capture. | |
| 3178 | /// The Decl is determined contextually. | |
| 3179 | for_capture_from_input: i32, | |
| 3132 | 3180 | |
| 3133 | 3181 | pub const nodeOffset = if (TracedOffset.want_tracing) nodeOffsetDebug else nodeOffsetRelease; |
| 3134 | 3182 | |
| ... | ... | @@ -3216,6 +3264,7 @@ pub const LazySrcLoc = union(enum) { |
| 3216 | 3264 | .node_offset_store_ptr, |
| 3217 | 3265 | .node_offset_store_operand, |
| 3218 | 3266 | .for_input, |
| 3267 | .for_capture_from_input, | |
| 3219 | 3268 | => .{ |
| 3220 | 3269 | .file_scope = decl.getFileScope(), |
| 3221 | 3270 | .parent_decl_node = decl.src_node, |
src/Sema.zig+16-6| ... | ... | @@ -9716,6 +9716,21 @@ fn zirElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 9716 | 9716 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 9717 | 9717 | const array_ptr = try sema.resolveInst(extra.lhs); |
| 9718 | 9718 | const elem_index = try sema.resolveInst(extra.rhs); |
| 9719 | const indexable_ty = sema.typeOf(array_ptr); | |
| 9720 | if (indexable_ty.zigTypeTag() != .Pointer) { | |
| 9721 | const capture_src: LazySrcLoc = .{ .for_capture_from_input = inst_data.src_node }; | |
| 9722 | const msg = msg: { | |
| 9723 | const msg = try sema.errMsg(block, capture_src, "pointer capture of non pointer type '{}'", .{ | |
| 9724 | indexable_ty.fmt(sema.mod), | |
| 9725 | }); | |
| 9726 | errdefer msg.destroy(sema.gpa); | |
| 9727 | if (indexable_ty.zigTypeTag() == .Array) { | |
| 9728 | try sema.errNote(block, src, msg, "consider using '&' here", .{}); | |
| 9729 | } | |
| 9730 | break :msg msg; | |
| 9731 | }; | |
| 9732 | return sema.failWithOwnedErrorMsg(msg); | |
| 9733 | } | |
| 9719 | 9734 | return sema.elemPtrOneLayerOnly(block, src, array_ptr, elem_index, src, false); |
| 9720 | 9735 | } |
| 9721 | 9736 | |
| ... | ... | @@ -24195,12 +24210,7 @@ fn elemPtrOneLayerOnly( |
| 24195 | 24210 | }, |
| 24196 | 24211 | } |
| 24197 | 24212 | }, |
| 24198 | else => { | |
| 24199 | // TODO add note pointing at corresponding for loop input and suggest using '&' | |
| 24200 | return sema.fail(block, indexable_src, "pointer capture of non pointer type '{}'", .{ | |
| 24201 | indexable_ty.fmt(sema.mod), | |
| 24202 | }); | |
| 24203 | }, | |
| 24213 | else => unreachable, | |
| 24204 | 24214 | } |
| 24205 | 24215 | } |
| 24206 | 24216 |
test/cases/compile_errors/for.zig+8| ... | ... | @@ -10,6 +10,12 @@ export fn b() void { |
| 10 | 10 | _ = i; _ = j; |
| 11 | 11 | } |
| 12 | 12 | } |
| 13 | export fn c() void { | |
| 14 | var buf: [10]u8 = undefined; | |
| 15 | for (buf) |*byte| { | |
| 16 | _ = byte; | |
| 17 | } | |
| 18 | } | |
| 13 | 19 | |
| 14 | 20 | // error |
| 15 | 21 | // backend=stage2 |
| ... | ... | @@ -20,3 +26,5 @@ export fn b() void { |
| 20 | 26 | // :2:19: note: length 11 here |
| 21 | 27 | // :9:14: error: type 'bool' does not support indexing |
| 22 | 28 | // :9:14: note: for loop operand must be an array, slice, tuple, or vector |
| 29 | // :15:16: error: pointer capture of non pointer type '[10]u8' | |
| 30 | // :15:10: note: consider using '&' here |