| ... | ... | @@ -2004,7 +2004,8 @@ fn blockExpr( |
| 2004 | 2004 | return labeledBlockExpr(gz, scope, rl, block_node, statements); |
| 2005 | 2005 | } |
| 2006 | 2006 | |
| 2007 | | try blockExprStmts(gz, scope, statements); |
| 2007 | var sub_gz = gz.makeSubBlock(scope); |
| 2008 | try blockExprStmts(&sub_gz, &sub_gz.base, statements); |
| 2008 | 2009 | return rvalue(gz, rl, .void_value, block_node); |
| 2009 | 2010 | } |
| 2010 | 2011 | |
| ... | ... | @@ -2772,7 +2773,13 @@ fn varDecl( |
| 2772 | 2773 | } |
| 2773 | 2774 | const ident_name = try astgen.identAsString(name_token); |
| 2774 | 2775 | |
| 2775 | | try astgen.detectLocalShadowing(scope, ident_name, name_token, ident_name_raw); |
| 2776 | try astgen.detectLocalShadowing( |
| 2777 | scope, |
| 2778 | ident_name, |
| 2779 | name_token, |
| 2780 | ident_name_raw, |
| 2781 | if (token_tags[var_decl.ast.mut_token] == .keyword_const) .@"local constant" else .@"local variable", |
| 2782 | ); |
| 2776 | 2783 | |
| 2777 | 2784 | if (var_decl.ast.init_node == 0) { |
| 2778 | 2785 | return astgen.failNode(node, "variables must be initialized", .{}); |
| ... | ... | @@ -3502,7 +3509,7 @@ fn fnDecl( |
| 3502 | 3509 | |
| 3503 | 3510 | const param_name = try astgen.identAsString(name_token); |
| 3504 | 3511 | if (!is_extern) { |
| 3505 | | try astgen.detectLocalShadowing(params_scope, param_name, name_token, name_bytes); |
| 3512 | try astgen.detectLocalShadowing(params_scope, param_name, name_token, name_bytes, .@"function parameter"); |
| 3506 | 3513 | } |
| 3507 | 3514 | break :blk param_name; |
| 3508 | 3515 | } else if (!is_extern) { |
| ... | ... | @@ -5181,7 +5188,7 @@ fn orelseCatchExpr( |
| 5181 | 5188 | } |
| 5182 | 5189 | const err_name = try astgen.identAsString(payload); |
| 5183 | 5190 | |
| 5184 | | try astgen.detectLocalShadowing(scope, err_name, payload, err_str); |
| 5191 | try astgen.detectLocalShadowing(scope, err_name, payload, err_str, .@"capture"); |
| 5185 | 5192 | |
| 5186 | 5193 | err_val_scope = .{ |
| 5187 | 5194 | .parent = &else_scope.base, |
| ... | ... | @@ -5480,7 +5487,7 @@ fn ifExpr( |
| 5480 | 5487 | const token_name_str = tree.tokenSlice(token_name_index); |
| 5481 | 5488 | if (mem.eql(u8, "_", token_name_str)) |
| 5482 | 5489 | break :s &then_scope.base; |
| 5483 | | try astgen.detectLocalShadowing(&then_scope.base, ident_name, token_name_index, token_name_str); |
| 5490 | try astgen.detectLocalShadowing(&then_scope.base, ident_name, token_name_index, token_name_str, .@"capture"); |
| 5484 | 5491 | payload_val_scope = .{ |
| 5485 | 5492 | .parent = &then_scope.base, |
| 5486 | 5493 | .gen_zir = &then_scope, |
| ... | ... | @@ -5505,7 +5512,7 @@ fn ifExpr( |
| 5505 | 5512 | break :s &then_scope.base; |
| 5506 | 5513 | const payload_inst = try then_scope.addUnNode(tag, cond.inst, if_full.ast.then_expr); |
| 5507 | 5514 | const ident_name = try astgen.identAsString(ident_token); |
| 5508 | | try astgen.detectLocalShadowing(&then_scope.base, ident_name, ident_token, ident_bytes); |
| 5515 | try astgen.detectLocalShadowing(&then_scope.base, ident_name, ident_token, ident_bytes, .@"capture"); |
| 5509 | 5516 | payload_val_scope = .{ |
| 5510 | 5517 | .parent = &then_scope.base, |
| 5511 | 5518 | .gen_zir = &then_scope, |
| ... | ... | @@ -5551,7 +5558,7 @@ fn ifExpr( |
| 5551 | 5558 | const error_token_str = tree.tokenSlice(error_token); |
| 5552 | 5559 | if (mem.eql(u8, "_", error_token_str)) |
| 5553 | 5560 | break :s &else_scope.base; |
| 5554 | | try astgen.detectLocalShadowing(&else_scope.base, ident_name, error_token, error_token_str); |
| 5561 | try astgen.detectLocalShadowing(&else_scope.base, ident_name, error_token, error_token_str, .@"capture"); |
| 5555 | 5562 | payload_val_scope = .{ |
| 5556 | 5563 | .parent = &else_scope.base, |
| 5557 | 5564 | .gen_zir = &else_scope, |
| ... | ... | @@ -5816,7 +5823,7 @@ fn whileExpr( |
| 5816 | 5823 | break :s &then_scope.base; |
| 5817 | 5824 | const payload_name_loc = payload_token + @boolToInt(payload_is_ref); |
| 5818 | 5825 | const ident_name = try astgen.identAsString(payload_name_loc); |
| 5819 | | try astgen.detectLocalShadowing(&then_scope.base, ident_name, payload_name_loc, ident_bytes); |
| 5826 | try astgen.detectLocalShadowing(&then_scope.base, ident_name, payload_name_loc, ident_bytes, .@"capture"); |
| 5820 | 5827 | payload_val_scope = .{ |
| 5821 | 5828 | .parent = &then_scope.base, |
| 5822 | 5829 | .gen_zir = &then_scope, |
| ... | ... | @@ -5843,7 +5850,7 @@ fn whileExpr( |
| 5843 | 5850 | const ident_bytes = tree.tokenSlice(ident_token); |
| 5844 | 5851 | if (mem.eql(u8, "_", ident_bytes)) |
| 5845 | 5852 | break :s &then_scope.base; |
| 5846 | | try astgen.detectLocalShadowing(&then_scope.base, ident_name, ident_token, ident_bytes); |
| 5853 | try astgen.detectLocalShadowing(&then_scope.base, ident_name, ident_token, ident_bytes, .@"capture"); |
| 5847 | 5854 | payload_val_scope = .{ |
| 5848 | 5855 | .parent = &then_scope.base, |
| 5849 | 5856 | .gen_zir = &then_scope, |
| ... | ... | @@ -5919,7 +5926,7 @@ fn whileExpr( |
| 5919 | 5926 | const ident_bytes = tree.tokenSlice(error_token); |
| 5920 | 5927 | if (mem.eql(u8, ident_bytes, "_")) |
| 5921 | 5928 | break :s &else_scope.base; |
| 5922 | | try astgen.detectLocalShadowing(&else_scope.base, ident_name, error_token, ident_bytes); |
| 5929 | try astgen.detectLocalShadowing(&else_scope.base, ident_name, error_token, ident_bytes, .@"capture"); |
| 5923 | 5930 | payload_val_scope = .{ |
| 5924 | 5931 | .parent = &else_scope.base, |
| 5925 | 5932 | .gen_zir = &else_scope, |
| ... | ... | @@ -6092,7 +6099,7 @@ fn forExpr( |
| 6092 | 6099 | .lhs = array_ptr, |
| 6093 | 6100 | .rhs = index, |
| 6094 | 6101 | }); |
| 6095 | | try astgen.detectLocalShadowing(&then_scope.base, name_str_index, ident, value_name); |
| 6102 | try astgen.detectLocalShadowing(&then_scope.base, name_str_index, ident, value_name, .@"capture"); |
| 6096 | 6103 | payload_val_scope = .{ |
| 6097 | 6104 | .parent = &then_scope.base, |
| 6098 | 6105 | .gen_zir = &then_scope, |
| ... | ... | @@ -6118,7 +6125,7 @@ fn forExpr( |
| 6118 | 6125 | return astgen.failTok(index_token, "discard of index capture; omit it instead", .{}); |
| 6119 | 6126 | } |
| 6120 | 6127 | const index_name = try astgen.identAsString(index_token); |
| 6121 | | try astgen.detectLocalShadowing(payload_sub_scope, index_name, index_token, token_bytes); |
| 6128 | try astgen.detectLocalShadowing(payload_sub_scope, index_name, index_token, token_bytes, .@"loop index capture"); |
| 6122 | 6129 | index_scope = .{ |
| 6123 | 6130 | .parent = payload_sub_scope, |
| 6124 | 6131 | .gen_zir = &then_scope, |
| ... | ... | @@ -6433,7 +6440,7 @@ fn switchExpr( |
| 6433 | 6440 | }); |
| 6434 | 6441 | } |
| 6435 | 6442 | const capture_name = try astgen.identAsString(ident); |
| 6436 | | try astgen.detectLocalShadowing(&case_scope.base, capture_name, ident, ident_slice); |
| 6443 | try astgen.detectLocalShadowing(&case_scope.base, capture_name, ident, ident_slice, .@"capture"); |
| 6437 | 6444 | capture_val_scope = .{ |
| 6438 | 6445 | .parent = &case_scope.base, |
| 6439 | 6446 | .gen_zir = &case_scope, |
| ... | ... | @@ -6458,7 +6465,7 @@ fn switchExpr( |
| 6458 | 6465 | return astgen.failTok(tag_token, "tag capture on non-inline prong", .{}); |
| 6459 | 6466 | } |
| 6460 | 6467 | const tag_name = try astgen.identAsString(tag_token); |
| 6461 | | try astgen.detectLocalShadowing(payload_sub_scope, tag_name, tag_token, tag_slice); |
| 6468 | try astgen.detectLocalShadowing(payload_sub_scope, tag_name, tag_token, tag_slice, .@"switch tag capture"); |
| 6462 | 6469 | tag_inst = @intCast(Zir.Inst.Index, astgen.instructions.len); |
| 6463 | 6470 | try astgen.instructions.append(gpa, .{ |
| 6464 | 6471 | .tag = .switch_capture_tag, |
| ... | ... | @@ -11669,6 +11676,7 @@ fn detectLocalShadowing( |
| 11669 | 11676 | ident_name: u32, |
| 11670 | 11677 | name_token: Ast.TokenIndex, |
| 11671 | 11678 | token_bytes: []const u8, |
| 11679 | id_cat: Scope.IdCat, |
| 11672 | 11680 | ) !void { |
| 11673 | 11681 | const gpa = astgen.gpa; |
| 11674 | 11682 | if (token_bytes[0] != '@' and isPrimitive(token_bytes)) { |
| ... | ... | @@ -11682,6 +11690,7 @@ fn detectLocalShadowing( |
| 11682 | 11690 | } |
| 11683 | 11691 | |
| 11684 | 11692 | var s = scope; |
| 11693 | var outer_scope = false; |
| 11685 | 11694 | while (true) switch (s.tag) { |
| 11686 | 11695 | .local_val => { |
| 11687 | 11696 | const local_val = s.cast(Scope.LocalVal).?; |
| ... | ... | @@ -11689,6 +11698,17 @@ fn detectLocalShadowing( |
| 11689 | 11698 | const name_slice = mem.span(astgen.nullTerminatedString(ident_name)); |
| 11690 | 11699 | const name = try gpa.dupe(u8, name_slice); |
| 11691 | 11700 | defer gpa.free(name); |
| 11701 | if (outer_scope) { |
| 11702 | return astgen.failTokNotes(name_token, "{s} '{s}' shadows {s} from outer scope", .{ |
| 11703 | @tagName(id_cat), name, @tagName(local_val.id_cat), |
| 11704 | }, &[_]u32{ |
| 11705 | try astgen.errNoteTok( |
| 11706 | local_val.token_src, |
| 11707 | "previous declaration here", |
| 11708 | .{}, |
| 11709 | ), |
| 11710 | }); |
| 11711 | } |
| 11692 | 11712 | return astgen.failTokNotes(name_token, "redeclaration of {s} '{s}'", .{ |
| 11693 | 11713 | @tagName(local_val.id_cat), name, |
| 11694 | 11714 | }, &[_]u32{ |
| ... | ... | @@ -11707,6 +11727,17 @@ fn detectLocalShadowing( |
| 11707 | 11727 | const name_slice = mem.span(astgen.nullTerminatedString(ident_name)); |
| 11708 | 11728 | const name = try gpa.dupe(u8, name_slice); |
| 11709 | 11729 | defer gpa.free(name); |
| 11730 | if (outer_scope) { |
| 11731 | return astgen.failTokNotes(name_token, "{s} '{s}' shadows {s} from outer scope", .{ |
| 11732 | @tagName(id_cat), name, @tagName(local_ptr.id_cat), |
| 11733 | }, &[_]u32{ |
| 11734 | try astgen.errNoteTok( |
| 11735 | local_ptr.token_src, |
| 11736 | "previous declaration here", |
| 11737 | .{}, |
| 11738 | ), |
| 11739 | }); |
| 11740 | } |
| 11710 | 11741 | return astgen.failTokNotes(name_token, "redeclaration of {s} '{s}'", .{ |
| 11711 | 11742 | @tagName(local_ptr.id_cat), name, |
| 11712 | 11743 | }, &[_]u32{ |
| ... | ... | @@ -11720,6 +11751,7 @@ fn detectLocalShadowing( |
| 11720 | 11751 | s = local_ptr.parent; |
| 11721 | 11752 | }, |
| 11722 | 11753 | .namespace => { |
| 11754 | outer_scope = true; |
| 11723 | 11755 | const ns = s.cast(Scope.Namespace).?; |
| 11724 | 11756 | const decl_node = ns.decls.get(ident_name) orelse { |
| 11725 | 11757 | s = ns.parent; |
| ... | ... | @@ -11728,13 +11760,16 @@ fn detectLocalShadowing( |
| 11728 | 11760 | const name_slice = mem.span(astgen.nullTerminatedString(ident_name)); |
| 11729 | 11761 | const name = try gpa.dupe(u8, name_slice); |
| 11730 | 11762 | defer gpa.free(name); |
| 11731 | | return astgen.failTokNotes(name_token, "local shadows declaration of '{s}'", .{ |
| 11732 | | name, |
| 11763 | return astgen.failTokNotes(name_token, "{s} shadows declaration of '{s}'", .{ |
| 11764 | @tagName(id_cat), name, |
| 11733 | 11765 | }, &[_]u32{ |
| 11734 | 11766 | try astgen.errNoteNode(decl_node, "declared here", .{}), |
| 11735 | 11767 | }); |
| 11736 | 11768 | }, |
| 11737 | | .gen_zir => s = s.cast(GenZir).?.parent, |
| 11769 | .gen_zir => { |
| 11770 | s = s.cast(GenZir).?.parent; |
| 11771 | outer_scope = true; |
| 11772 | }, |
| 11738 | 11773 | .defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent, |
| 11739 | 11774 | .top => break, |
| 11740 | 11775 | }; |
| ... | ... | @@ -11844,8 +11879,8 @@ fn scanDecls(astgen: *AstGen, namespace: *Scope.Namespace, members: []const Ast. |
| 11844 | 11879 | .local_val => { |
| 11845 | 11880 | const local_val = s.cast(Scope.LocalVal).?; |
| 11846 | 11881 | if (local_val.name == name_str_index) { |
| 11847 | | return astgen.failTokNotes(name_token, "redeclaration of {s} '{s}'", .{ |
| 11848 | | @tagName(local_val.id_cat), token_bytes, |
| 11882 | return astgen.failTokNotes(name_token, "declaration '{s}' shadows {s} from outer scope", .{ |
| 11883 | token_bytes, @tagName(local_val.id_cat), |
| 11849 | 11884 | }, &[_]u32{ |
| 11850 | 11885 | try astgen.errNoteTok( |
| 11851 | 11886 | local_val.token_src, |
| ... | ... | @@ -11859,8 +11894,8 @@ fn scanDecls(astgen: *AstGen, namespace: *Scope.Namespace, members: []const Ast. |
| 11859 | 11894 | .local_ptr => { |
| 11860 | 11895 | const local_ptr = s.cast(Scope.LocalPtr).?; |
| 11861 | 11896 | if (local_ptr.name == name_str_index) { |
| 11862 | | return astgen.failTokNotes(name_token, "redeclaration of {s} '{s}'", .{ |
| 11863 | | @tagName(local_ptr.id_cat), token_bytes, |
| 11897 | return astgen.failTokNotes(name_token, "declaration '{s}' shadows {s} from outer scope", .{ |
| 11898 | token_bytes, @tagName(local_ptr.id_cat), |
| 11864 | 11899 | }, &[_]u32{ |
| 11865 | 11900 | try astgen.errNoteTok( |
| 11866 | 11901 | local_ptr.token_src, |