| ... | @@ -3406,45 +3406,36 @@ fn assignDestructure(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerErro | ... | @@ -3406,45 +3406,36 @@ fn assignDestructure(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerErro |
| 3406 | try emitDbgNode(gz, node); | 3406 | try emitDbgNode(gz, node); |
| 3407 | const astgen = gz.astgen; | 3407 | const astgen = gz.astgen; |
| 3408 | const tree = astgen.tree; | 3408 | const tree = astgen.tree; |
| 3409 | const token_tags = tree.tokens.items(.tag); | | |
| 3410 | const node_datas = tree.nodes.items(.data); | | |
| 3411 | const main_tokens = tree.nodes.items(.main_token); | 3409 | const main_tokens = tree.nodes.items(.main_token); |
| 3412 | const node_tags = tree.nodes.items(.tag); | 3410 | const node_tags = tree.nodes.items(.tag); |
| 3413 | | 3411 | |
| 3414 | const extra_index = node_datas[node].lhs; | 3412 | const full = tree.assignDestructure(node); |
| 3415 | const lhs_count = tree.extra_data[extra_index]; | 3413 | if (full.comptime_token != null and gz.is_comptime) { |
| 3416 | const lhs_nodes: []const Ast.Node.Index = @ptrCast(tree.extra_data[extra_index + 1 ..][0..lhs_count]); | | |
| 3417 | const rhs = node_datas[node].rhs; | | |
| 3418 | | | |
| 3419 | const maybe_comptime_token = tree.firstToken(node) - 1; | | |
| 3420 | const declared_comptime = token_tags[maybe_comptime_token] == .keyword_comptime; | | |
| 3421 | | | |
| 3422 | if (declared_comptime and gz.is_comptime) { | | |
| 3423 | return astgen.failNode(node, "redundant comptime keyword in already comptime scope", .{}); | 3414 | return astgen.failNode(node, "redundant comptime keyword in already comptime scope", .{}); |
| 3424 | } | 3415 | } |
| 3425 | | 3416 | |
| 3426 | // If this expression is marked comptime, we must wrap the whole thing in a comptime block. | 3417 | // If this expression is marked comptime, we must wrap the whole thing in a comptime block. |
| 3427 | var gz_buf: GenZir = undefined; | 3418 | var gz_buf: GenZir = undefined; |
| 3428 | const inner_gz = if (declared_comptime) bs: { | 3419 | const inner_gz = if (full.comptime_token) |_| bs: { |
| 3429 | gz_buf = gz.makeSubBlock(scope); | 3420 | gz_buf = gz.makeSubBlock(scope); |
| 3430 | gz_buf.is_comptime = true; | 3421 | gz_buf.is_comptime = true; |
| 3431 | break :bs &gz_buf; | 3422 | break :bs &gz_buf; |
| 3432 | } else gz; | 3423 | } else gz; |
| 3433 | defer if (declared_comptime) inner_gz.unstack(); | 3424 | defer if (full.comptime_token) |_| inner_gz.unstack(); |
| 3434 | | 3425 | |
| 3435 | const rl_components = try astgen.arena.alloc(ResultInfo.Loc.DestructureComponent, lhs_nodes.len); | 3426 | const rl_components = try astgen.arena.alloc(ResultInfo.Loc.DestructureComponent, full.ast.variables.len); |
| 3436 | for (rl_components, lhs_nodes) |*lhs_rl, lhs_node| { | 3427 | for (rl_components, full.ast.variables) |*variable_rl, variable_node| { |
| 3437 | if (node_tags[lhs_node] == .identifier) { | 3428 | if (node_tags[variable_node] == .identifier) { |
| 3438 | // This intentionally does not support `@"_"` syntax. | 3429 | // This intentionally does not support `@"_"` syntax. |
| 3439 | const ident_name = tree.tokenSlice(main_tokens[lhs_node]); | 3430 | const ident_name = tree.tokenSlice(main_tokens[variable_node]); |
| 3440 | if (mem.eql(u8, ident_name, "_")) { | 3431 | if (mem.eql(u8, ident_name, "_")) { |
| 3441 | lhs_rl.* = .discard; | 3432 | variable_rl.* = .discard; |
| 3442 | continue; | 3433 | continue; |
| 3443 | } | 3434 | } |
| 3444 | } | 3435 | } |
| 3445 | lhs_rl.* = .{ .typed_ptr = .{ | 3436 | variable_rl.* = .{ .typed_ptr = .{ |
| 3446 | .inst = try lvalExpr(inner_gz, scope, lhs_node), | 3437 | .inst = try lvalExpr(inner_gz, scope, variable_node), |
| 3447 | .src_node = lhs_node, | 3438 | .src_node = variable_node, |
| 3448 | } }; | 3439 | } }; |
| 3449 | } | 3440 | } |
| 3450 | | 3441 | |
| ... | @@ -3453,9 +3444,9 @@ fn assignDestructure(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerErro | ... | @@ -3453,9 +3444,9 @@ fn assignDestructure(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerErro |
| 3453 | .components = rl_components, | 3444 | .components = rl_components, |
| 3454 | } } }; | 3445 | } } }; |
| 3455 | | 3446 | |
| 3456 | _ = try expr(inner_gz, scope, ri, rhs); | 3447 | _ = try expr(inner_gz, scope, ri, full.ast.value_expr); |
| 3457 | | 3448 | |
| 3458 | if (declared_comptime) { | 3449 | if (full.comptime_token) |_| { |
| 3459 | const comptime_block_inst = try gz.makeBlockInst(.block_comptime, node); | 3450 | const comptime_block_inst = try gz.makeBlockInst(.block_comptime, node); |
| 3460 | _ = try inner_gz.addBreak(.@"break", comptime_block_inst, .void_value); | 3451 | _ = try inner_gz.addBreak(.@"break", comptime_block_inst, .void_value); |
| 3461 | try inner_gz.setBlockBody(comptime_block_inst); | 3452 | try inner_gz.setBlockBody(comptime_block_inst); |
| ... | @@ -3474,23 +3465,16 @@ fn assignDestructureMaybeDecls( | ... | @@ -3474,23 +3465,16 @@ fn assignDestructureMaybeDecls( |
| 3474 | const astgen = gz.astgen; | 3465 | const astgen = gz.astgen; |
| 3475 | const tree = astgen.tree; | 3466 | const tree = astgen.tree; |
| 3476 | const token_tags = tree.tokens.items(.tag); | 3467 | const token_tags = tree.tokens.items(.tag); |
| 3477 | const node_datas = tree.nodes.items(.data); | | |
| 3478 | const main_tokens = tree.nodes.items(.main_token); | 3468 | const main_tokens = tree.nodes.items(.main_token); |
| 3479 | const node_tags = tree.nodes.items(.tag); | 3469 | const node_tags = tree.nodes.items(.tag); |
| 3480 | | 3470 | |
| 3481 | const extra_index = node_datas[node].lhs; | 3471 | const full = tree.assignDestructure(node); |
| 3482 | const lhs_count = tree.extra_data[extra_index]; | 3472 | if (full.comptime_token != null and gz.is_comptime) { |
| 3483 | const lhs_nodes: []const Ast.Node.Index = @ptrCast(tree.extra_data[extra_index + 1 ..][0..lhs_count]); | | |
| 3484 | const rhs = node_datas[node].rhs; | | |
| 3485 | | | |
| 3486 | const maybe_comptime_token = tree.firstToken(node) - 1; | | |
| 3487 | const declared_comptime = token_tags[maybe_comptime_token] == .keyword_comptime; | | |
| 3488 | if (declared_comptime and gz.is_comptime) { | | |
| 3489 | return astgen.failNode(node, "redundant comptime keyword in already comptime scope", .{}); | 3473 | return astgen.failNode(node, "redundant comptime keyword in already comptime scope", .{}); |
| 3490 | } | 3474 | } |
| 3491 | | 3475 | |
| 3492 | const is_comptime = declared_comptime or gz.is_comptime; | 3476 | const is_comptime = full.comptime_token != null or gz.is_comptime; |
| 3493 | const rhs_is_comptime = tree.nodes.items(.tag)[rhs] == .@"comptime"; | 3477 | const value_is_comptime = node_tags[full.ast.value_expr] == .@"comptime"; |
| 3494 | | 3478 | |
| 3495 | // When declaring consts via a destructure, we always use a result pointer. | 3479 | // When declaring consts via a destructure, we always use a result pointer. |
| 3496 | // This avoids the need to create tuple types, and is also likely easier to | 3480 | // This avoids the need to create tuple types, and is also likely easier to |
| ... | @@ -3499,24 +3483,24 @@ fn assignDestructureMaybeDecls( | ... | @@ -3499,24 +3483,24 @@ fn assignDestructureMaybeDecls( |
| 3499 | | 3483 | |
| 3500 | // We know this rl information won't live past the evaluation of this | 3484 | // We know this rl information won't live past the evaluation of this |
| 3501 | // expression, so it may as well go in the block arena. | 3485 | // expression, so it may as well go in the block arena. |
| 3502 | const rl_components = try block_arena.alloc(ResultInfo.Loc.DestructureComponent, lhs_nodes.len); | 3486 | const rl_components = try block_arena.alloc(ResultInfo.Loc.DestructureComponent, full.ast.variables.len); |
| 3503 | var any_non_const_lhs = false; | 3487 | var any_non_const_variables = false; |
| 3504 | var any_lvalue_expr = false; | 3488 | var any_lvalue_expr = false; |
| 3505 | for (rl_components, lhs_nodes) |*lhs_rl, lhs_node| { | 3489 | for (rl_components, full.ast.variables) |*variable_rl, variable_node| { |
| 3506 | switch (node_tags[lhs_node]) { | 3490 | switch (node_tags[variable_node]) { |
| 3507 | .identifier => { | 3491 | .identifier => { |
| 3508 | // This intentionally does not support `@"_"` syntax. | 3492 | // This intentionally does not support `@"_"` syntax. |
| 3509 | const ident_name = tree.tokenSlice(main_tokens[lhs_node]); | 3493 | const ident_name = tree.tokenSlice(main_tokens[variable_node]); |
| 3510 | if (mem.eql(u8, ident_name, "_")) { | 3494 | if (mem.eql(u8, ident_name, "_")) { |
| 3511 | any_non_const_lhs = true; | 3495 | any_non_const_variables = true; |
| 3512 | lhs_rl.* = .discard; | 3496 | variable_rl.* = .discard; |
| 3513 | continue; | 3497 | continue; |
| 3514 | } | 3498 | } |
| 3515 | }, | 3499 | }, |
| 3516 | .global_var_decl, .local_var_decl, .simple_var_decl, .aligned_var_decl => { | 3500 | .global_var_decl, .local_var_decl, .simple_var_decl, .aligned_var_decl => { |
| 3517 | const full = tree.fullVarDecl(lhs_node).?; | 3501 | const full_var_decl = tree.fullVarDecl(variable_node).?; |
| 3518 | | 3502 | |
| 3519 | const name_token = full.ast.mut_token + 1; | 3503 | const name_token = full_var_decl.ast.mut_token + 1; |
| 3520 | const ident_name_raw = tree.tokenSlice(name_token); | 3504 | const ident_name_raw = tree.tokenSlice(name_token); |
| 3521 | if (mem.eql(u8, ident_name_raw, "_")) { | 3505 | if (mem.eql(u8, ident_name_raw, "_")) { |
| 3522 | return astgen.failTok(name_token, "'_' used as an identifier without @\"_\" syntax", .{}); | 3506 | return astgen.failTok(name_token, "'_' used as an identifier without @\"_\" syntax", .{}); |
| ... | @@ -3524,35 +3508,35 @@ fn assignDestructureMaybeDecls( | ... | @@ -3524,35 +3508,35 @@ fn assignDestructureMaybeDecls( |
| 3524 | | 3508 | |
| 3525 | // We detect shadowing in the second pass over these, while we're creating scopes. | 3509 | // We detect shadowing in the second pass over these, while we're creating scopes. |
| 3526 | | 3510 | |
| 3527 | if (full.ast.addrspace_node != 0) { | 3511 | if (full_var_decl.ast.addrspace_node != 0) { |
| 3528 | return astgen.failTok(main_tokens[full.ast.addrspace_node], "cannot set address space of local variable '{s}'", .{ident_name_raw}); | 3512 | return astgen.failTok(main_tokens[full_var_decl.ast.addrspace_node], "cannot set address space of local variable '{s}'", .{ident_name_raw}); |
| 3529 | } | 3513 | } |
| 3530 | if (full.ast.section_node != 0) { | 3514 | if (full_var_decl.ast.section_node != 0) { |
| 3531 | return astgen.failTok(main_tokens[full.ast.section_node], "cannot set section of local variable '{s}'", .{ident_name_raw}); | 3515 | return astgen.failTok(main_tokens[full_var_decl.ast.section_node], "cannot set section of local variable '{s}'", .{ident_name_raw}); |
| 3532 | } | 3516 | } |
| 3533 | | 3517 | |
| 3534 | const is_const = switch (token_tags[full.ast.mut_token]) { | 3518 | const is_const = switch (token_tags[full_var_decl.ast.mut_token]) { |
| 3535 | .keyword_var => false, | 3519 | .keyword_var => false, |
| 3536 | .keyword_const => true, | 3520 | .keyword_const => true, |
| 3537 | else => unreachable, | 3521 | else => unreachable, |
| 3538 | }; | 3522 | }; |
| 3539 | if (!is_const) any_non_const_lhs = true; | 3523 | if (!is_const) any_non_const_variables = true; |
| 3540 | | 3524 | |
| 3541 | // We also mark `const`s as comptime if the RHS is definitely comptime-known. | 3525 | // We also mark `const`s as comptime if the RHS is definitely comptime-known. |
| 3542 | const this_lhs_comptime = is_comptime or (is_const and rhs_is_comptime); | 3526 | const this_variable_comptime = is_comptime or (is_const and value_is_comptime); |
| 3543 | | 3527 | |
| 3544 | const align_inst: Zir.Inst.Ref = if (full.ast.align_node != 0) | 3528 | const align_inst: Zir.Inst.Ref = if (full_var_decl.ast.align_node != 0) |
| 3545 | try expr(gz, scope, coerced_align_ri, full.ast.align_node) | 3529 | try expr(gz, scope, coerced_align_ri, full_var_decl.ast.align_node) |
| 3546 | else | 3530 | else |
| 3547 | .none; | 3531 | .none; |
| 3548 | | 3532 | |
| 3549 | if (full.ast.type_node != 0) { | 3533 | if (full_var_decl.ast.type_node != 0) { |
| 3550 | // Typed alloc | 3534 | // Typed alloc |
| 3551 | const type_inst = try typeExpr(gz, scope, full.ast.type_node); | 3535 | const type_inst = try typeExpr(gz, scope, full_var_decl.ast.type_node); |
| 3552 | const ptr = if (align_inst == .none) ptr: { | 3536 | const ptr = if (align_inst == .none) ptr: { |
| 3553 | const tag: Zir.Inst.Tag = if (is_const) | 3537 | const tag: Zir.Inst.Tag = if (is_const) |
| 3554 | .alloc | 3538 | .alloc |
| 3555 | else if (this_lhs_comptime) | 3539 | else if (this_variable_comptime) |
| 3556 | .alloc_comptime_mut | 3540 | .alloc_comptime_mut |
| 3557 | else | 3541 | else |
| 3558 | .alloc_mut; | 3542 | .alloc_mut; |
| ... | @@ -3562,16 +3546,16 @@ fn assignDestructureMaybeDecls( | ... | @@ -3562,16 +3546,16 @@ fn assignDestructureMaybeDecls( |
| 3562 | .type_inst = type_inst, | 3546 | .type_inst = type_inst, |
| 3563 | .align_inst = align_inst, | 3547 | .align_inst = align_inst, |
| 3564 | .is_const = is_const, | 3548 | .is_const = is_const, |
| 3565 | .is_comptime = this_lhs_comptime, | 3549 | .is_comptime = this_variable_comptime, |
| 3566 | }); | 3550 | }); |
| 3567 | lhs_rl.* = .{ .typed_ptr = .{ .inst = ptr } }; | 3551 | variable_rl.* = .{ .typed_ptr = .{ .inst = ptr } }; |
| 3568 | } else { | 3552 | } else { |
| 3569 | // Inferred alloc | 3553 | // Inferred alloc |
| 3570 | const ptr = if (align_inst == .none) ptr: { | 3554 | const ptr = if (align_inst == .none) ptr: { |
| 3571 | const tag: Zir.Inst.Tag = if (is_const) tag: { | 3555 | const tag: Zir.Inst.Tag = if (is_const) tag: { |
| 3572 | break :tag if (this_lhs_comptime) .alloc_inferred_comptime else .alloc_inferred; | 3556 | break :tag if (this_variable_comptime) .alloc_inferred_comptime else .alloc_inferred; |
| 3573 | } else tag: { | 3557 | } else tag: { |
| 3574 | break :tag if (this_lhs_comptime) .alloc_inferred_comptime_mut else .alloc_inferred_mut; | 3558 | break :tag if (this_variable_comptime) .alloc_inferred_comptime_mut else .alloc_inferred_mut; |
| 3575 | }; | 3559 | }; |
| 3576 | break :ptr try gz.addNode(tag, node); | 3560 | break :ptr try gz.addNode(tag, node); |
| 3577 | } else try gz.addAllocExtended(.{ | 3561 | } else try gz.addAllocExtended(.{ |
| ... | @@ -3579,48 +3563,48 @@ fn assignDestructureMaybeDecls( | ... | @@ -3579,48 +3563,48 @@ fn assignDestructureMaybeDecls( |
| 3579 | .type_inst = .none, | 3563 | .type_inst = .none, |
| 3580 | .align_inst = align_inst, | 3564 | .align_inst = align_inst, |
| 3581 | .is_const = is_const, | 3565 | .is_const = is_const, |
| 3582 | .is_comptime = this_lhs_comptime, | 3566 | .is_comptime = this_variable_comptime, |
| 3583 | }); | 3567 | }); |
| 3584 | lhs_rl.* = .{ .inferred_ptr = ptr }; | 3568 | variable_rl.* = .{ .inferred_ptr = ptr }; |
| 3585 | } | 3569 | } |
| 3586 | | 3570 | |
| 3587 | continue; | 3571 | continue; |
| 3588 | }, | 3572 | }, |
| 3589 | else => {}, | 3573 | else => {}, |
| 3590 | } | 3574 | } |
| 3591 | // This LHS is just an lvalue expression. | 3575 | // This variable is just an lvalue expression. |
| 3592 | // We will fill in its result pointer later, inside a comptime block. | 3576 | // We will fill in its result pointer later, inside a comptime block. |
| 3593 | any_non_const_lhs = true; | 3577 | any_non_const_variables = true; |
| 3594 | any_lvalue_expr = true; | 3578 | any_lvalue_expr = true; |
| 3595 | lhs_rl.* = .{ .typed_ptr = .{ | 3579 | variable_rl.* = .{ .typed_ptr = .{ |
| 3596 | .inst = undefined, | 3580 | .inst = undefined, |
| 3597 | .src_node = lhs_node, | 3581 | .src_node = variable_node, |
| 3598 | } }; | 3582 | } }; |
| 3599 | } | 3583 | } |
| 3600 | | 3584 | |
| 3601 | if (declared_comptime and !any_non_const_lhs) { | 3585 | if (full.comptime_token != null and !any_non_const_variables) { |
| 3602 | try astgen.appendErrorTok(maybe_comptime_token, "'comptime const' is redundant; instead wrap the initialization expression with 'comptime'", .{}); | 3586 | try astgen.appendErrorTok(full.comptime_token.?, "'comptime const' is redundant; instead wrap the initialization expression with 'comptime'", .{}); |
| 3603 | } | 3587 | } |
| 3604 | | 3588 | |
| 3605 | // If this expression is marked comptime, we must wrap it in a comptime block. | 3589 | // If this expression is marked comptime, we must wrap it in a comptime block. |
| 3606 | var gz_buf: GenZir = undefined; | 3590 | var gz_buf: GenZir = undefined; |
| 3607 | const inner_gz = if (declared_comptime) bs: { | 3591 | const inner_gz = if (full.comptime_token) |_| bs: { |
| 3608 | gz_buf = gz.makeSubBlock(scope); | 3592 | gz_buf = gz.makeSubBlock(scope); |
| 3609 | gz_buf.is_comptime = true; | 3593 | gz_buf.is_comptime = true; |
| 3610 | break :bs &gz_buf; | 3594 | break :bs &gz_buf; |
| 3611 | } else gz; | 3595 | } else gz; |
| 3612 | defer if (declared_comptime) inner_gz.unstack(); | 3596 | defer if (full.comptime_token) |_| inner_gz.unstack(); |
| 3613 | | 3597 | |
| 3614 | if (any_lvalue_expr) { | 3598 | if (any_lvalue_expr) { |
| 3615 | // At least one LHS was an lvalue expr. Iterate again in order to | 3599 | // At least one variable was an lvalue expr. Iterate again in order to |
| 3616 | // evaluate the lvalues from within the possible block_comptime. | 3600 | // evaluate the lvalues from within the possible block_comptime. |
| 3617 | for (rl_components, lhs_nodes) |*lhs_rl, lhs_node| { | 3601 | for (rl_components, full.ast.variables) |*variable_rl, variable_node| { |
| 3618 | if (lhs_rl.* != .typed_ptr) continue; | 3602 | if (variable_rl.* != .typed_ptr) continue; |
| 3619 | switch (node_tags[lhs_node]) { | 3603 | switch (node_tags[variable_node]) { |
| 3620 | .global_var_decl, .local_var_decl, .simple_var_decl, .aligned_var_decl => continue, | 3604 | .global_var_decl, .local_var_decl, .simple_var_decl, .aligned_var_decl => continue, |
| 3621 | else => {}, | 3605 | else => {}, |
| 3622 | } | 3606 | } |
| 3623 | lhs_rl.typed_ptr.inst = try lvalExpr(inner_gz, scope, lhs_node); | 3607 | variable_rl.typed_ptr.inst = try lvalExpr(inner_gz, scope, variable_node); |
| 3624 | } | 3608 | } |
| 3625 | } | 3609 | } |
| 3626 | | 3610 | |
| ... | @@ -3629,9 +3613,9 @@ fn assignDestructureMaybeDecls( | ... | @@ -3629,9 +3613,9 @@ fn assignDestructureMaybeDecls( |
| 3629 | _ = try reachableExpr(inner_gz, scope, .{ .rl = .{ .destructure = .{ | 3613 | _ = try reachableExpr(inner_gz, scope, .{ .rl = .{ .destructure = .{ |
| 3630 | .src_node = node, | 3614 | .src_node = node, |
| 3631 | .components = rl_components, | 3615 | .components = rl_components, |
| 3632 | } } }, rhs, node); | 3616 | } } }, full.ast.value_expr, node); |
| 3633 | | 3617 | |
| 3634 | if (declared_comptime) { | 3618 | if (full.comptime_token) |_| { |
| 3635 | // Finish the block_comptime. Inferred alloc resolution etc will occur | 3619 | // Finish the block_comptime. Inferred alloc resolution etc will occur |
| 3636 | // in the parent block. | 3620 | // in the parent block. |
| 3637 | const comptime_block_inst = try gz.makeBlockInst(.block_comptime, node); | 3621 | const comptime_block_inst = try gz.makeBlockInst(.block_comptime, node); |
| ... | @@ -3640,37 +3624,37 @@ fn assignDestructureMaybeDecls( | ... | @@ -3640,37 +3624,37 @@ fn assignDestructureMaybeDecls( |
| 3640 | try gz.instructions.append(gz.astgen.gpa, comptime_block_inst); | 3624 | try gz.instructions.append(gz.astgen.gpa, comptime_block_inst); |
| 3641 | } | 3625 | } |
| 3642 | | 3626 | |
| 3643 | // Now, iterate over the LHS exprs to construct any new scopes. | 3627 | // Now, iterate over the variable exprs to construct any new scopes. |
| 3644 | // If there were any inferred allocations, resolve them. | 3628 | // If there were any inferred allocations, resolve them. |
| 3645 | // If there were any `const` decls, make the pointer constant. | 3629 | // If there were any `const` decls, make the pointer constant. |
| 3646 | var cur_scope = scope; | 3630 | var cur_scope = scope; |
| 3647 | for (rl_components, lhs_nodes) |lhs_rl, lhs_node| { | 3631 | for (rl_components, full.ast.variables) |variable_rl, variable_node| { |
| 3648 | switch (node_tags[lhs_node]) { | 3632 | switch (node_tags[variable_node]) { |
| 3649 | .local_var_decl, .simple_var_decl, .aligned_var_decl => {}, | 3633 | .local_var_decl, .simple_var_decl, .aligned_var_decl => {}, |
| 3650 | else => continue, // We were mutating an existing lvalue - nothing to do | 3634 | else => continue, // We were mutating an existing lvalue - nothing to do |
| 3651 | } | 3635 | } |
| 3652 | const full = tree.fullVarDecl(lhs_node).?; | 3636 | const full_var_decl = tree.fullVarDecl(variable_node).?; |
| 3653 | const raw_ptr = switch (lhs_rl) { | 3637 | const raw_ptr = switch (variable_rl) { |
| 3654 | .discard => unreachable, | 3638 | .discard => unreachable, |
| 3655 | .typed_ptr => |typed_ptr| typed_ptr.inst, | 3639 | .typed_ptr => |typed_ptr| typed_ptr.inst, |
| 3656 | .inferred_ptr => |ptr_inst| ptr_inst, | 3640 | .inferred_ptr => |ptr_inst| ptr_inst, |
| 3657 | }; | 3641 | }; |
| 3658 | // If the alloc was inferred, resolve it. | 3642 | // If the alloc was inferred, resolve it. |
| 3659 | if (full.ast.type_node == 0) { | 3643 | if (full_var_decl.ast.type_node == 0) { |
| 3660 | _ = try gz.addUnNode(.resolve_inferred_alloc, raw_ptr, lhs_node); | 3644 | _ = try gz.addUnNode(.resolve_inferred_alloc, raw_ptr, variable_node); |
| 3661 | } | 3645 | } |
| 3662 | const is_const = switch (token_tags[full.ast.mut_token]) { | 3646 | const is_const = switch (token_tags[full_var_decl.ast.mut_token]) { |
| 3663 | .keyword_var => false, | 3647 | .keyword_var => false, |
| 3664 | .keyword_const => true, | 3648 | .keyword_const => true, |
| 3665 | else => unreachable, | 3649 | else => unreachable, |
| 3666 | }; | 3650 | }; |
| 3667 | // If the alloc was const, make it const. | 3651 | // If the alloc was const, make it const. |
| 3668 | const var_ptr = if (is_const and full.ast.type_node != 0) make_const: { | 3652 | const var_ptr = if (is_const and full_var_decl.ast.type_node != 0) make_const: { |
| 3669 | // Note that we don't do this if type_node == 0 since `resolve_inferred_alloc` | 3653 | // Note that we don't do this if type_node == 0 since `resolve_inferred_alloc` |
| 3670 | // handles it for us. | 3654 | // handles it for us. |
| 3671 | break :make_const try gz.addUnNode(.make_ptr_const, raw_ptr, node); | 3655 | break :make_const try gz.addUnNode(.make_ptr_const, raw_ptr, node); |
| 3672 | } else raw_ptr; | 3656 | } else raw_ptr; |
| 3673 | const name_token = full.ast.mut_token + 1; | 3657 | const name_token = full_var_decl.ast.mut_token + 1; |
| 3674 | const ident_name_raw = tree.tokenSlice(name_token); | 3658 | const ident_name_raw = tree.tokenSlice(name_token); |
| 3675 | const ident_name = try astgen.identAsString(name_token); | 3659 | const ident_name = try astgen.identAsString(name_token); |
| 3676 | try astgen.detectLocalShadowing( | 3660 | try astgen.detectLocalShadowing( |