| ... | @@ -2004,7 +2004,8 @@ fn blockExpr( | ... | @@ -2004,7 +2004,8 @@ fn blockExpr( |
| 2004 | return labeledBlockExpr(gz, scope, rl, block_node, statements); | 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 | return rvalue(gz, rl, .void_value, block_node); | 2009 | return rvalue(gz, rl, .void_value, block_node); |
| 2009 | } | 2010 | } |
| 2010 | | 2011 | |
| ... | @@ -2772,7 +2773,13 @@ fn varDecl( | ... | @@ -2772,7 +2773,13 @@ fn varDecl( |
| 2772 | } | 2773 | } |
| 2773 | const ident_name = try astgen.identAsString(name_token); | 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 | if (var_decl.ast.init_node == 0) { | 2784 | if (var_decl.ast.init_node == 0) { |
| 2778 | return astgen.failNode(node, "variables must be initialized", .{}); | 2785 | return astgen.failNode(node, "variables must be initialized", .{}); |
| ... | @@ -3502,7 +3509,7 @@ fn fnDecl( | ... | @@ -3502,7 +3509,7 @@ fn fnDecl( |
| 3502 | | 3509 | |
| 3503 | const param_name = try astgen.identAsString(name_token); | 3510 | const param_name = try astgen.identAsString(name_token); |
| 3504 | if (!is_extern) { | 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 | break :blk param_name; | 3514 | break :blk param_name; |
| 3508 | } else if (!is_extern) { | 3515 | } else if (!is_extern) { |
| ... | @@ -5181,7 +5188,7 @@ fn orelseCatchExpr( | ... | @@ -5181,7 +5188,7 @@ fn orelseCatchExpr( |
| 5181 | } | 5188 | } |
| 5182 | const err_name = try astgen.identAsString(payload); | 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 | err_val_scope = .{ | 5193 | err_val_scope = .{ |
| 5187 | .parent = &else_scope.base, | 5194 | .parent = &else_scope.base, |
| ... | @@ -5480,7 +5487,7 @@ fn ifExpr( | ... | @@ -5480,7 +5487,7 @@ fn ifExpr( |
| 5480 | const token_name_str = tree.tokenSlice(token_name_index); | 5487 | const token_name_str = tree.tokenSlice(token_name_index); |
| 5481 | if (mem.eql(u8, "_", token_name_str)) | 5488 | if (mem.eql(u8, "_", token_name_str)) |
| 5482 | break :s &then_scope.base; | 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 | payload_val_scope = .{ | 5491 | payload_val_scope = .{ |
| 5485 | .parent = &then_scope.base, | 5492 | .parent = &then_scope.base, |
| 5486 | .gen_zir = &then_scope, | 5493 | .gen_zir = &then_scope, |
| ... | @@ -5505,7 +5512,7 @@ fn ifExpr( | ... | @@ -5505,7 +5512,7 @@ fn ifExpr( |
| 5505 | break :s &then_scope.base; | 5512 | break :s &then_scope.base; |
| 5506 | const payload_inst = try then_scope.addUnNode(tag, cond.inst, if_full.ast.then_expr); | 5513 | const payload_inst = try then_scope.addUnNode(tag, cond.inst, if_full.ast.then_expr); |
| 5507 | const ident_name = try astgen.identAsString(ident_token); | 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 | payload_val_scope = .{ | 5516 | payload_val_scope = .{ |
| 5510 | .parent = &then_scope.base, | 5517 | .parent = &then_scope.base, |
| 5511 | .gen_zir = &then_scope, | 5518 | .gen_zir = &then_scope, |
| ... | @@ -5551,7 +5558,7 @@ fn ifExpr( | ... | @@ -5551,7 +5558,7 @@ fn ifExpr( |
| 5551 | const error_token_str = tree.tokenSlice(error_token); | 5558 | const error_token_str = tree.tokenSlice(error_token); |
| 5552 | if (mem.eql(u8, "_", error_token_str)) | 5559 | if (mem.eql(u8, "_", error_token_str)) |
| 5553 | break :s &else_scope.base; | 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 | payload_val_scope = .{ | 5562 | payload_val_scope = .{ |
| 5556 | .parent = &else_scope.base, | 5563 | .parent = &else_scope.base, |
| 5557 | .gen_zir = &else_scope, | 5564 | .gen_zir = &else_scope, |
| ... | @@ -5816,7 +5823,7 @@ fn whileExpr( | ... | @@ -5816,7 +5823,7 @@ fn whileExpr( |
| 5816 | break :s &then_scope.base; | 5823 | break :s &then_scope.base; |
| 5817 | const payload_name_loc = payload_token + @boolToInt(payload_is_ref); | 5824 | const payload_name_loc = payload_token + @boolToInt(payload_is_ref); |
| 5818 | const ident_name = try astgen.identAsString(payload_name_loc); | 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 | payload_val_scope = .{ | 5827 | payload_val_scope = .{ |
| 5821 | .parent = &then_scope.base, | 5828 | .parent = &then_scope.base, |
| 5822 | .gen_zir = &then_scope, | 5829 | .gen_zir = &then_scope, |
| ... | @@ -5843,7 +5850,7 @@ fn whileExpr( | ... | @@ -5843,7 +5850,7 @@ fn whileExpr( |
| 5843 | const ident_bytes = tree.tokenSlice(ident_token); | 5850 | const ident_bytes = tree.tokenSlice(ident_token); |
| 5844 | if (mem.eql(u8, "_", ident_bytes)) | 5851 | if (mem.eql(u8, "_", ident_bytes)) |
| 5845 | break :s &then_scope.base; | 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 | payload_val_scope = .{ | 5854 | payload_val_scope = .{ |
| 5848 | .parent = &then_scope.base, | 5855 | .parent = &then_scope.base, |
| 5849 | .gen_zir = &then_scope, | 5856 | .gen_zir = &then_scope, |
| ... | @@ -5919,7 +5926,7 @@ fn whileExpr( | ... | @@ -5919,7 +5926,7 @@ fn whileExpr( |
| 5919 | const ident_bytes = tree.tokenSlice(error_token); | 5926 | const ident_bytes = tree.tokenSlice(error_token); |
| 5920 | if (mem.eql(u8, ident_bytes, "_")) | 5927 | if (mem.eql(u8, ident_bytes, "_")) |
| 5921 | break :s &else_scope.base; | 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 | payload_val_scope = .{ | 5930 | payload_val_scope = .{ |
| 5924 | .parent = &else_scope.base, | 5931 | .parent = &else_scope.base, |
| 5925 | .gen_zir = &else_scope, | 5932 | .gen_zir = &else_scope, |
| ... | @@ -6092,7 +6099,7 @@ fn forExpr( | ... | @@ -6092,7 +6099,7 @@ fn forExpr( |
| 6092 | .lhs = array_ptr, | 6099 | .lhs = array_ptr, |
| 6093 | .rhs = index, | 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 | payload_val_scope = .{ | 6103 | payload_val_scope = .{ |
| 6097 | .parent = &then_scope.base, | 6104 | .parent = &then_scope.base, |
| 6098 | .gen_zir = &then_scope, | 6105 | .gen_zir = &then_scope, |
| ... | @@ -6118,7 +6125,7 @@ fn forExpr( | ... | @@ -6118,7 +6125,7 @@ fn forExpr( |
| 6118 | return astgen.failTok(index_token, "discard of index capture; omit it instead", .{}); | 6125 | return astgen.failTok(index_token, "discard of index capture; omit it instead", .{}); |
| 6119 | } | 6126 | } |
| 6120 | const index_name = try astgen.identAsString(index_token); | 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 | index_scope = .{ | 6129 | index_scope = .{ |
| 6123 | .parent = payload_sub_scope, | 6130 | .parent = payload_sub_scope, |
| 6124 | .gen_zir = &then_scope, | 6131 | .gen_zir = &then_scope, |
| ... | @@ -6433,7 +6440,7 @@ fn switchExpr( | ... | @@ -6433,7 +6440,7 @@ fn switchExpr( |
| 6433 | }); | 6440 | }); |
| 6434 | } | 6441 | } |
| 6435 | const capture_name = try astgen.identAsString(ident); | 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 | capture_val_scope = .{ | 6444 | capture_val_scope = .{ |
| 6438 | .parent = &case_scope.base, | 6445 | .parent = &case_scope.base, |
| 6439 | .gen_zir = &case_scope, | 6446 | .gen_zir = &case_scope, |
| ... | @@ -6458,7 +6465,7 @@ fn switchExpr( | ... | @@ -6458,7 +6465,7 @@ fn switchExpr( |
| 6458 | return astgen.failTok(tag_token, "tag capture on non-inline prong", .{}); | 6465 | return astgen.failTok(tag_token, "tag capture on non-inline prong", .{}); |
| 6459 | } | 6466 | } |
| 6460 | const tag_name = try astgen.identAsString(tag_token); | 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 | tag_inst = @intCast(Zir.Inst.Index, astgen.instructions.len); | 6469 | tag_inst = @intCast(Zir.Inst.Index, astgen.instructions.len); |
| 6463 | try astgen.instructions.append(gpa, .{ | 6470 | try astgen.instructions.append(gpa, .{ |
| 6464 | .tag = .switch_capture_tag, | 6471 | .tag = .switch_capture_tag, |
| ... | @@ -11669,6 +11676,7 @@ fn detectLocalShadowing( | ... | @@ -11669,6 +11676,7 @@ fn detectLocalShadowing( |
| 11669 | ident_name: u32, | 11676 | ident_name: u32, |
| 11670 | name_token: Ast.TokenIndex, | 11677 | name_token: Ast.TokenIndex, |
| 11671 | token_bytes: []const u8, | 11678 | token_bytes: []const u8, |
| | 11679 | id_cat: Scope.IdCat, |
| 11672 | ) !void { | 11680 | ) !void { |
| 11673 | const gpa = astgen.gpa; | 11681 | const gpa = astgen.gpa; |
| 11674 | if (token_bytes[0] != '@' and isPrimitive(token_bytes)) { | 11682 | if (token_bytes[0] != '@' and isPrimitive(token_bytes)) { |
| ... | @@ -11682,6 +11690,7 @@ fn detectLocalShadowing( | ... | @@ -11682,6 +11690,7 @@ fn detectLocalShadowing( |
| 11682 | } | 11690 | } |
| 11683 | | 11691 | |
| 11684 | var s = scope; | 11692 | var s = scope; |
| | 11693 | var outer_scope = false; |
| 11685 | while (true) switch (s.tag) { | 11694 | while (true) switch (s.tag) { |
| 11686 | .local_val => { | 11695 | .local_val => { |
| 11687 | const local_val = s.cast(Scope.LocalVal).?; | 11696 | const local_val = s.cast(Scope.LocalVal).?; |
| ... | @@ -11689,6 +11698,17 @@ fn detectLocalShadowing( | ... | @@ -11689,6 +11698,17 @@ fn detectLocalShadowing( |
| 11689 | const name_slice = mem.span(astgen.nullTerminatedString(ident_name)); | 11698 | const name_slice = mem.span(astgen.nullTerminatedString(ident_name)); |
| 11690 | const name = try gpa.dupe(u8, name_slice); | 11699 | const name = try gpa.dupe(u8, name_slice); |
| 11691 | defer gpa.free(name); | 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 | return astgen.failTokNotes(name_token, "redeclaration of {s} '{s}'", .{ | 11712 | return astgen.failTokNotes(name_token, "redeclaration of {s} '{s}'", .{ |
| 11693 | @tagName(local_val.id_cat), name, | 11713 | @tagName(local_val.id_cat), name, |
| 11694 | }, &[_]u32{ | 11714 | }, &[_]u32{ |
| ... | @@ -11707,6 +11727,17 @@ fn detectLocalShadowing( | ... | @@ -11707,6 +11727,17 @@ fn detectLocalShadowing( |
| 11707 | const name_slice = mem.span(astgen.nullTerminatedString(ident_name)); | 11727 | const name_slice = mem.span(astgen.nullTerminatedString(ident_name)); |
| 11708 | const name = try gpa.dupe(u8, name_slice); | 11728 | const name = try gpa.dupe(u8, name_slice); |
| 11709 | defer gpa.free(name); | 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 | return astgen.failTokNotes(name_token, "redeclaration of {s} '{s}'", .{ | 11741 | return astgen.failTokNotes(name_token, "redeclaration of {s} '{s}'", .{ |
| 11711 | @tagName(local_ptr.id_cat), name, | 11742 | @tagName(local_ptr.id_cat), name, |
| 11712 | }, &[_]u32{ | 11743 | }, &[_]u32{ |
| ... | @@ -11720,6 +11751,7 @@ fn detectLocalShadowing( | ... | @@ -11720,6 +11751,7 @@ fn detectLocalShadowing( |
| 11720 | s = local_ptr.parent; | 11751 | s = local_ptr.parent; |
| 11721 | }, | 11752 | }, |
| 11722 | .namespace => { | 11753 | .namespace => { |
| | 11754 | outer_scope = true; |
| 11723 | const ns = s.cast(Scope.Namespace).?; | 11755 | const ns = s.cast(Scope.Namespace).?; |
| 11724 | const decl_node = ns.decls.get(ident_name) orelse { | 11756 | const decl_node = ns.decls.get(ident_name) orelse { |
| 11725 | s = ns.parent; | 11757 | s = ns.parent; |
| ... | @@ -11728,13 +11760,16 @@ fn detectLocalShadowing( | ... | @@ -11728,13 +11760,16 @@ fn detectLocalShadowing( |
| 11728 | const name_slice = mem.span(astgen.nullTerminatedString(ident_name)); | 11760 | const name_slice = mem.span(astgen.nullTerminatedString(ident_name)); |
| 11729 | const name = try gpa.dupe(u8, name_slice); | 11761 | const name = try gpa.dupe(u8, name_slice); |
| 11730 | defer gpa.free(name); | 11762 | defer gpa.free(name); |
| 11731 | return astgen.failTokNotes(name_token, "local shadows declaration of '{s}'", .{ | 11763 | return astgen.failTokNotes(name_token, "{s} shadows declaration of '{s}'", .{ |
| 11732 | name, | 11764 | @tagName(id_cat), name, |
| 11733 | }, &[_]u32{ | 11765 | }, &[_]u32{ |
| 11734 | try astgen.errNoteNode(decl_node, "declared here", .{}), | 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 | .defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent, | 11773 | .defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent, |
| 11739 | .top => break, | 11774 | .top => break, |
| 11740 | }; | 11775 | }; |
| ... | @@ -11844,8 +11879,8 @@ fn scanDecls(astgen: *AstGen, namespace: *Scope.Namespace, members: []const Ast. | ... | @@ -11844,8 +11879,8 @@ fn scanDecls(astgen: *AstGen, namespace: *Scope.Namespace, members: []const Ast. |
| 11844 | .local_val => { | 11879 | .local_val => { |
| 11845 | const local_val = s.cast(Scope.LocalVal).?; | 11880 | const local_val = s.cast(Scope.LocalVal).?; |
| 11846 | if (local_val.name == name_str_index) { | 11881 | if (local_val.name == name_str_index) { |
| 11847 | return astgen.failTokNotes(name_token, "redeclaration of {s} '{s}'", .{ | 11882 | return astgen.failTokNotes(name_token, "declaration '{s}' shadows {s} from outer scope", .{ |
| 11848 | @tagName(local_val.id_cat), token_bytes, | 11883 | token_bytes, @tagName(local_val.id_cat), |
| 11849 | }, &[_]u32{ | 11884 | }, &[_]u32{ |
| 11850 | try astgen.errNoteTok( | 11885 | try astgen.errNoteTok( |
| 11851 | local_val.token_src, | 11886 | local_val.token_src, |
| ... | @@ -11859,8 +11894,8 @@ fn scanDecls(astgen: *AstGen, namespace: *Scope.Namespace, members: []const Ast. | ... | @@ -11859,8 +11894,8 @@ fn scanDecls(astgen: *AstGen, namespace: *Scope.Namespace, members: []const Ast. |
| 11859 | .local_ptr => { | 11894 | .local_ptr => { |
| 11860 | const local_ptr = s.cast(Scope.LocalPtr).?; | 11895 | const local_ptr = s.cast(Scope.LocalPtr).?; |
| 11861 | if (local_ptr.name == name_str_index) { | 11896 | if (local_ptr.name == name_str_index) { |
| 11862 | return astgen.failTokNotes(name_token, "redeclaration of {s} '{s}'", .{ | 11897 | return astgen.failTokNotes(name_token, "declaration '{s}' shadows {s} from outer scope", .{ |
| 11863 | @tagName(local_ptr.id_cat), token_bytes, | 11898 | token_bytes, @tagName(local_ptr.id_cat), |
| 11864 | }, &[_]u32{ | 11899 | }, &[_]u32{ |
| 11865 | try astgen.errNoteTok( | 11900 | try astgen.errNoteTok( |
| 11866 | local_ptr.token_src, | 11901 | local_ptr.token_src, |