| ... | @@ -2385,7 +2385,7 @@ fn varDecl( | ... | @@ -2385,7 +2385,7 @@ fn varDecl( |
| 2385 | } | 2385 | } |
| 2386 | const ident_name = try astgen.identAsString(name_token); | 2386 | const ident_name = try astgen.identAsString(name_token); |
| 2387 | | 2387 | |
| 2388 | try astgen.detectLocalShadowing(scope, ident_name, name_token); | 2388 | try astgen.detectLocalShadowing(scope, ident_name, name_token, ident_name_raw); |
| 2389 | | 2389 | |
| 2390 | if (var_decl.ast.init_node == 0) { | 2390 | if (var_decl.ast.init_node == 0) { |
| 2391 | return astgen.failNode(node, "variables must be initialized", .{}); | 2391 | return astgen.failNode(node, "variables must be initialized", .{}); |
| ... | @@ -2952,12 +2952,13 @@ fn fnDecl( | ... | @@ -2952,12 +2952,13 @@ fn fnDecl( |
| 2952 | } else false; | 2952 | } else false; |
| 2953 | | 2953 | |
| 2954 | const param_name: u32 = if (param.name_token) |name_token| blk: { | 2954 | const param_name: u32 = if (param.name_token) |name_token| blk: { |
| 2955 | if (mem.eql(u8, "_", tree.tokenSlice(name_token))) | 2955 | const name_bytes = tree.tokenSlice(name_token); |
| | 2956 | if (mem.eql(u8, "_", name_bytes)) |
| 2956 | break :blk 0; | 2957 | break :blk 0; |
| 2957 | | 2958 | |
| 2958 | const param_name = try astgen.identAsString(name_token); | 2959 | const param_name = try astgen.identAsString(name_token); |
| 2959 | if (!is_extern) { | 2960 | if (!is_extern) { |
| 2960 | try astgen.detectLocalShadowing(params_scope, param_name, name_token); | 2961 | try astgen.detectLocalShadowing(params_scope, param_name, name_token, name_bytes); |
| 2961 | } | 2962 | } |
| 2962 | break :blk param_name; | 2963 | break :blk param_name; |
| 2963 | } else if (!is_extern) { | 2964 | } else if (!is_extern) { |
| ... | @@ -5035,7 +5036,7 @@ fn ifExpr( | ... | @@ -5035,7 +5036,7 @@ fn ifExpr( |
| 5035 | const token_name_str = tree.tokenSlice(token_name_index); | 5036 | const token_name_str = tree.tokenSlice(token_name_index); |
| 5036 | if (mem.eql(u8, "_", token_name_str)) | 5037 | if (mem.eql(u8, "_", token_name_str)) |
| 5037 | break :s &then_scope.base; | 5038 | break :s &then_scope.base; |
| 5038 | try astgen.detectLocalShadowing(&then_scope.base, ident_name, token_name_index); | 5039 | try astgen.detectLocalShadowing(&then_scope.base, ident_name, token_name_index, token_name_str); |
| 5039 | payload_val_scope = .{ | 5040 | payload_val_scope = .{ |
| 5040 | .parent = &then_scope.base, | 5041 | .parent = &then_scope.base, |
| 5041 | .gen_zir = &then_scope, | 5042 | .gen_zir = &then_scope, |
| ... | @@ -5054,11 +5055,12 @@ fn ifExpr( | ... | @@ -5054,11 +5055,12 @@ fn ifExpr( |
| 5054 | .optional_payload_unsafe_ptr | 5055 | .optional_payload_unsafe_ptr |
| 5055 | else | 5056 | else |
| 5056 | .optional_payload_unsafe; | 5057 | .optional_payload_unsafe; |
| 5057 | if (mem.eql(u8, "_", tree.tokenSlice(ident_token))) | 5058 | const ident_bytes = tree.tokenSlice(ident_token); |
| | 5059 | if (mem.eql(u8, "_", ident_bytes)) |
| 5058 | break :s &then_scope.base; | 5060 | break :s &then_scope.base; |
| 5059 | const payload_inst = try then_scope.addUnNode(tag, cond.inst, node); | 5061 | const payload_inst = try then_scope.addUnNode(tag, cond.inst, node); |
| 5060 | const ident_name = try astgen.identAsString(ident_token); | 5062 | const ident_name = try astgen.identAsString(ident_token); |
| 5061 | try astgen.detectLocalShadowing(&then_scope.base, ident_name, ident_token); | 5063 | try astgen.detectLocalShadowing(&then_scope.base, ident_name, ident_token, ident_bytes); |
| 5062 | payload_val_scope = .{ | 5064 | payload_val_scope = .{ |
| 5063 | .parent = &then_scope.base, | 5065 | .parent = &then_scope.base, |
| 5064 | .gen_zir = &then_scope, | 5066 | .gen_zir = &then_scope, |
| ... | @@ -5100,7 +5102,7 @@ fn ifExpr( | ... | @@ -5100,7 +5102,7 @@ fn ifExpr( |
| 5100 | const error_token_str = tree.tokenSlice(error_token); | 5102 | const error_token_str = tree.tokenSlice(error_token); |
| 5101 | if (mem.eql(u8, "_", error_token_str)) | 5103 | if (mem.eql(u8, "_", error_token_str)) |
| 5102 | break :s &else_scope.base; | 5104 | break :s &else_scope.base; |
| 5103 | try astgen.detectLocalShadowing(&else_scope.base, ident_name, error_token); | 5105 | try astgen.detectLocalShadowing(&else_scope.base, ident_name, error_token, error_token_str); |
| 5104 | payload_val_scope = .{ | 5106 | payload_val_scope = .{ |
| 5105 | .parent = &else_scope.base, | 5107 | .parent = &else_scope.base, |
| 5106 | .gen_zir = &else_scope, | 5108 | .gen_zir = &else_scope, |
| ... | @@ -5291,11 +5293,12 @@ fn whileExpr( | ... | @@ -5291,11 +5293,12 @@ fn whileExpr( |
| 5291 | .err_union_payload_unsafe; | 5293 | .err_union_payload_unsafe; |
| 5292 | const payload_inst = try then_scope.addUnNode(tag, cond.inst, node); | 5294 | const payload_inst = try then_scope.addUnNode(tag, cond.inst, node); |
| 5293 | const ident_token = if (payload_is_ref) payload_token + 1 else payload_token; | 5295 | const ident_token = if (payload_is_ref) payload_token + 1 else payload_token; |
| 5294 | if (mem.eql(u8, "_", tree.tokenSlice(ident_token))) | 5296 | const ident_bytes = tree.tokenSlice(ident_token); |
| | 5297 | if (mem.eql(u8, "_", ident_bytes)) |
| 5295 | break :s &then_scope.base; | 5298 | break :s &then_scope.base; |
| 5296 | const payload_name_loc = payload_token + @boolToInt(payload_is_ref); | 5299 | const payload_name_loc = payload_token + @boolToInt(payload_is_ref); |
| 5297 | const ident_name = try astgen.identAsString(payload_name_loc); | 5300 | const ident_name = try astgen.identAsString(payload_name_loc); |
| 5298 | try astgen.detectLocalShadowing(&then_scope.base, ident_name, payload_name_loc); | 5301 | try astgen.detectLocalShadowing(&then_scope.base, ident_name, payload_name_loc, ident_bytes); |
| 5299 | payload_val_scope = .{ | 5302 | payload_val_scope = .{ |
| 5300 | .parent = &then_scope.base, | 5303 | .parent = &then_scope.base, |
| 5301 | .gen_zir = &then_scope, | 5304 | .gen_zir = &then_scope, |
| ... | @@ -5316,9 +5319,10 @@ fn whileExpr( | ... | @@ -5316,9 +5319,10 @@ fn whileExpr( |
| 5316 | .optional_payload_unsafe; | 5319 | .optional_payload_unsafe; |
| 5317 | const payload_inst = try then_scope.addUnNode(tag, cond.inst, node); | 5320 | const payload_inst = try then_scope.addUnNode(tag, cond.inst, node); |
| 5318 | const ident_name = try astgen.identAsString(ident_token); | 5321 | const ident_name = try astgen.identAsString(ident_token); |
| 5319 | if (mem.eql(u8, "_", tree.tokenSlice(ident_token))) | 5322 | const ident_bytes = tree.tokenSlice(ident_token); |
| | 5323 | if (mem.eql(u8, "_", ident_bytes)) |
| 5320 | break :s &then_scope.base; | 5324 | break :s &then_scope.base; |
| 5321 | try astgen.detectLocalShadowing(&then_scope.base, ident_name, ident_token); | 5325 | try astgen.detectLocalShadowing(&then_scope.base, ident_name, ident_token, ident_bytes); |
| 5322 | payload_val_scope = .{ | 5326 | payload_val_scope = .{ |
| 5323 | .parent = &then_scope.base, | 5327 | .parent = &then_scope.base, |
| 5324 | .gen_zir = &then_scope, | 5328 | .gen_zir = &then_scope, |
| ... | @@ -5374,9 +5378,10 @@ fn whileExpr( | ... | @@ -5374,9 +5378,10 @@ fn whileExpr( |
| 5374 | .err_union_code; | 5378 | .err_union_code; |
| 5375 | const payload_inst = try else_scope.addUnNode(tag, cond.inst, node); | 5379 | const payload_inst = try else_scope.addUnNode(tag, cond.inst, node); |
| 5376 | const ident_name = try astgen.identAsString(error_token); | 5380 | const ident_name = try astgen.identAsString(error_token); |
| 5377 | if (mem.eql(u8, tree.tokenSlice(error_token), "_")) | 5381 | const ident_bytes = tree.tokenSlice(error_token); |
| | 5382 | if (mem.eql(u8, ident_bytes, "_")) |
| 5378 | break :s &else_scope.base; | 5383 | break :s &else_scope.base; |
| 5379 | try astgen.detectLocalShadowing(&else_scope.base, ident_name, error_token); | 5384 | try astgen.detectLocalShadowing(&else_scope.base, ident_name, error_token, ident_bytes); |
| 5380 | payload_val_scope = .{ | 5385 | payload_val_scope = .{ |
| 5381 | .parent = &else_scope.base, | 5386 | .parent = &else_scope.base, |
| 5382 | .gen_zir = &else_scope, | 5387 | .gen_zir = &else_scope, |
| ... | @@ -5523,7 +5528,7 @@ fn forExpr( | ... | @@ -5523,7 +5528,7 @@ fn forExpr( |
| 5523 | const name_str_index = try astgen.identAsString(ident); | 5528 | const name_str_index = try astgen.identAsString(ident); |
| 5524 | const tag: Zir.Inst.Tag = if (is_ptr) .elem_ptr else .elem_val; | 5529 | const tag: Zir.Inst.Tag = if (is_ptr) .elem_ptr else .elem_val; |
| 5525 | const payload_inst = try then_scope.addBin(tag, array_ptr, index); | 5530 | const payload_inst = try then_scope.addBin(tag, array_ptr, index); |
| 5526 | try astgen.detectLocalShadowing(&then_scope.base, name_str_index, ident); | 5531 | try astgen.detectLocalShadowing(&then_scope.base, name_str_index, ident, value_name); |
| 5527 | payload_val_scope = .{ | 5532 | payload_val_scope = .{ |
| 5528 | .parent = &then_scope.base, | 5533 | .parent = &then_scope.base, |
| 5529 | .gen_zir = &then_scope, | 5534 | .gen_zir = &then_scope, |
| ... | @@ -5543,11 +5548,12 @@ fn forExpr( | ... | @@ -5543,11 +5548,12 @@ fn forExpr( |
| 5543 | ident + 2 | 5548 | ident + 2 |
| 5544 | else | 5549 | else |
| 5545 | break :blk payload_sub_scope; | 5550 | break :blk payload_sub_scope; |
| 5546 | if (mem.eql(u8, tree.tokenSlice(index_token), "_")) { | 5551 | const token_bytes = tree.tokenSlice(index_token); |
| | 5552 | if (mem.eql(u8, token_bytes, "_")) { |
| 5547 | return astgen.failTok(index_token, "discard of index capture; omit it instead", .{}); | 5553 | return astgen.failTok(index_token, "discard of index capture; omit it instead", .{}); |
| 5548 | } | 5554 | } |
| 5549 | const index_name = try astgen.identAsString(index_token); | 5555 | const index_name = try astgen.identAsString(index_token); |
| 5550 | try astgen.detectLocalShadowing(payload_sub_scope, index_name, index_token); | 5556 | try astgen.detectLocalShadowing(payload_sub_scope, index_name, index_token, token_bytes); |
| 5551 | index_scope = .{ | 5557 | index_scope = .{ |
| 5552 | .parent = payload_sub_scope, | 5558 | .parent = payload_sub_scope, |
| 5553 | .gen_zir = &then_scope, | 5559 | .gen_zir = &then_scope, |
| ... | @@ -10059,7 +10065,7 @@ fn declareNewName( | ... | @@ -10059,7 +10065,7 @@ fn declareNewName( |
| 10059 | const ns = scope.cast(Scope.Namespace).?; | 10065 | const ns = scope.cast(Scope.Namespace).?; |
| 10060 | const gop = try ns.decls.getOrPut(gpa, name_index); | 10066 | const gop = try ns.decls.getOrPut(gpa, name_index); |
| 10061 | if (gop.found_existing) { | 10067 | if (gop.found_existing) { |
| 10062 | const name = try gpa.dupe(u8, mem.spanZ(astgen.nullTerminatedString(name_index))); | 10068 | const name = try gpa.dupe(u8, mem.span(astgen.nullTerminatedString(name_index))); |
| 10063 | defer gpa.free(name); | 10069 | defer gpa.free(name); |
| 10064 | return astgen.failNodeNotes(node, "redeclaration of '{s}'", .{ | 10070 | return astgen.failNodeNotes(node, "redeclaration of '{s}'", .{ |
| 10065 | name, | 10071 | name, |
| ... | @@ -10094,13 +10100,17 @@ fn detectLocalShadowing( | ... | @@ -10094,13 +10100,17 @@ fn detectLocalShadowing( |
| 10094 | scope: *Scope, | 10100 | scope: *Scope, |
| 10095 | ident_name: u32, | 10101 | ident_name: u32, |
| 10096 | name_token: ast.TokenIndex, | 10102 | name_token: ast.TokenIndex, |
| | 10103 | token_bytes: []const u8, |
| 10097 | ) !void { | 10104 | ) !void { |
| 10098 | const gpa = astgen.gpa; | 10105 | const gpa = astgen.gpa; |
| 10099 | const name_slice = mem.spanZ(astgen.nullTerminatedString(ident_name)); | 10106 | if (token_bytes[0] != '@' and isPrimitive(token_bytes)) { |
| 10100 | if (isPrimitive(name_slice)) { | 10107 | return astgen.failTokNotes(name_token, "name shadows primitive '{s}'", .{ |
| 10101 | const name = try gpa.dupe(u8, name_slice); | 10108 | token_bytes, |
| 10102 | defer gpa.free(name); | 10109 | }, &[_]u32{ |
| 10103 | return astgen.failTok(name_token, "local shadows primitive '{s}'", .{name}); | 10110 | try astgen.errNoteTok(name_token, "consider using @\"{s}\" to disambiguate", .{ |
| | 10111 | token_bytes, |
| | 10112 | }), |
| | 10113 | }); |
| 10104 | } | 10114 | } |
| 10105 | | 10115 | |
| 10106 | var s = scope; | 10116 | var s = scope; |
| ... | @@ -10108,6 +10118,7 @@ fn detectLocalShadowing( | ... | @@ -10108,6 +10118,7 @@ fn detectLocalShadowing( |
| 10108 | .local_val => { | 10118 | .local_val => { |
| 10109 | const local_val = s.cast(Scope.LocalVal).?; | 10119 | const local_val = s.cast(Scope.LocalVal).?; |
| 10110 | if (local_val.name == ident_name) { | 10120 | if (local_val.name == ident_name) { |
| | 10121 | const name_slice = mem.span(astgen.nullTerminatedString(ident_name)); |
| 10111 | const name = try gpa.dupe(u8, name_slice); | 10122 | const name = try gpa.dupe(u8, name_slice); |
| 10112 | defer gpa.free(name); | 10123 | defer gpa.free(name); |
| 10113 | return astgen.failTokNotes(name_token, "redeclaration of {s} '{s}'", .{ | 10124 | return astgen.failTokNotes(name_token, "redeclaration of {s} '{s}'", .{ |
| ... | @@ -10125,6 +10136,7 @@ fn detectLocalShadowing( | ... | @@ -10125,6 +10136,7 @@ fn detectLocalShadowing( |
| 10125 | .local_ptr => { | 10136 | .local_ptr => { |
| 10126 | const local_ptr = s.cast(Scope.LocalPtr).?; | 10137 | const local_ptr = s.cast(Scope.LocalPtr).?; |
| 10127 | if (local_ptr.name == ident_name) { | 10138 | if (local_ptr.name == ident_name) { |
| | 10139 | const name_slice = mem.span(astgen.nullTerminatedString(ident_name)); |
| 10128 | const name = try gpa.dupe(u8, name_slice); | 10140 | const name = try gpa.dupe(u8, name_slice); |
| 10129 | defer gpa.free(name); | 10141 | defer gpa.free(name); |
| 10130 | return astgen.failTokNotes(name_token, "redeclaration of {s} '{s}'", .{ | 10142 | return astgen.failTokNotes(name_token, "redeclaration of {s} '{s}'", .{ |
| ... | @@ -10145,6 +10157,7 @@ fn detectLocalShadowing( | ... | @@ -10145,6 +10157,7 @@ fn detectLocalShadowing( |
| 10145 | s = ns.parent; | 10157 | s = ns.parent; |
| 10146 | continue; | 10158 | continue; |
| 10147 | }; | 10159 | }; |
| | 10160 | const name_slice = mem.span(astgen.nullTerminatedString(ident_name)); |
| 10148 | const name = try gpa.dupe(u8, name_slice); | 10161 | const name = try gpa.dupe(u8, name_slice); |
| 10149 | defer gpa.free(name); | 10162 | defer gpa.free(name); |
| 10150 | return astgen.failTokNotes(name_token, "local shadows declaration of '{s}'", .{ | 10163 | return astgen.failTokNotes(name_token, "local shadows declaration of '{s}'", .{ |