diff --git a/src/AstGen.zig b/src/AstGen.zig index 31e7f040a28ba2748e278b12fc12849b3f4507ec..8fb7cde6de367505ad2ad9922316eda6550f47a2 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -5009,6 +5009,7 @@ fn ifExpr( const token_name_str = tree.tokenSlice(token_name_index); if (mem.eql(u8, "_", token_name_str)) break :s &then_scope.base; + try astgen.detectLocalShadowing(&then_scope.base, ident_name, token_name_index); payload_val_scope = .{ .parent = &then_scope.base, .gen_zir = &then_scope, @@ -5031,6 +5032,7 @@ fn ifExpr( break :s &then_scope.base; const payload_inst = try then_scope.addUnNode(tag, cond.inst, node); const ident_name = try astgen.identAsString(ident_token); + try astgen.detectLocalShadowing(&then_scope.base, ident_name, ident_token); payload_val_scope = .{ .parent = &then_scope.base, .gen_zir = &then_scope, @@ -5072,6 +5074,7 @@ fn ifExpr( const error_token_str = tree.tokenSlice(error_token); if (mem.eql(u8, "_", error_token_str)) break :s &else_scope.base; + try astgen.detectLocalShadowing(&else_scope.base, ident_name, error_token); payload_val_scope = .{ .parent = &else_scope.base, .gen_zir = &else_scope, @@ -5265,7 +5268,9 @@ fn whileExpr( const ident_token = if (payload_is_ref) payload_token + 1 else payload_token; if (mem.eql(u8, "_", tree.tokenSlice(ident_token))) break :s &then_scope.base; - const ident_name = try astgen.identAsString(payload_token + @boolToInt(payload_is_ref)); + const payload_name_loc = payload_token + @boolToInt(payload_is_ref); + const ident_name = try astgen.identAsString(payload_name_loc); + try astgen.detectLocalShadowing(&then_scope.base, ident_name, payload_name_loc); payload_val_scope = .{ .parent = &then_scope.base, .gen_zir = &then_scope, @@ -5288,6 +5293,7 @@ fn whileExpr( const ident_name = try astgen.identAsString(ident_token); if (mem.eql(u8, "_", tree.tokenSlice(ident_token))) break :s &then_scope.base; + try astgen.detectLocalShadowing(&then_scope.base, ident_name, ident_token); payload_val_scope = .{ .parent = &then_scope.base, .gen_zir = &then_scope, @@ -5345,6 +5351,7 @@ fn whileExpr( const ident_name = try astgen.identAsString(error_token); if (mem.eql(u8, tree.tokenSlice(error_token), "_")) break :s &else_scope.base; + try astgen.detectLocalShadowing(&else_scope.base, ident_name, error_token); payload_val_scope = .{ .parent = &else_scope.base, .gen_zir = &else_scope, @@ -5484,6 +5491,7 @@ fn forExpr( const name_str_index = try astgen.identAsString(ident); const tag: Zir.Inst.Tag = if (is_ptr) .elem_ptr else .elem_val; const payload_inst = try then_scope.addBin(tag, array_ptr, index); + try astgen.detectLocalShadowing(&then_scope.base, name_str_index, ident); payload_val_scope = .{ .parent = &then_scope.base, .gen_zir = &then_scope, @@ -5507,6 +5515,7 @@ fn forExpr( return astgen.failTok(index_token, "discard of index capture; omit it instead", .{}); } const index_name = try astgen.identAsString(index_token); + try astgen.detectLocalShadowing(payload_sub_scope, index_name, index_token); index_scope = .{ .parent = payload_sub_scope, .gen_zir = &then_scope, diff --git a/test/cases.zig b/test/cases.zig index fe1579be440d94239b237ed546942d351dad3e5e..f235992f718e64156c28ad00d4c1f855332706f6 100644 --- a/test/cases.zig +++ b/test/cases.zig @@ -1065,6 +1065,76 @@ pub fn addCases(ctx: *TestContext) !void { ":5:19: error: redeclaration of local constant 'c'", ":4:19: note: previous declaration here", }); + case.addError( + \\pub fn main() void { + \\ var i = 0; + \\ for (n) |_, i| { + \\ } + \\} + , &[_][]const u8{ + ":3:17: error: redeclaration of local variable 'i'", + ":2:9: note: previous declaration here", + }); + case.addError( + \\pub fn main() void { + \\ var i = 0; + \\ for (n) |i| { + \\ } + \\} + , &[_][]const u8{ + ":3:14: error: redeclaration of local variable 'i'", + ":2:9: note: previous declaration here", + }); + case.addError( + \\pub fn main() void { + \\ var i = 0; + \\ while (n) |i| { + \\ } + \\} + , &[_][]const u8{ + ":3:16: error: redeclaration of local variable 'i'", + ":2:9: note: previous declaration here", + }); + case.addError( + \\pub fn main() void { + \\ var i = 0; + \\ while (n) |bruh| { + \\ _ = bruh; + \\ } else |i| { + \\ + \\ } + \\} + , &[_][]const u8{ + ":5:13: error: redeclaration of local variable 'i'", + ":2:9: note: previous declaration here", + }); + case.addError( + \\pub fn main() void { + \\ var i = 0; + \\ if (true) |i| {} + \\} + , &[_][]const u8{ + ":3:16: error: redeclaration of local variable 'i'", + ":2:9: note: previous declaration here", + }); + case.addError( + \\pub fn main() void { + \\ var i = 0; + \\ if (true) |i| {} else |e| {} + \\} + , &[_][]const u8{ + ":3:16: error: redeclaration of local variable 'i'", + ":2:9: note: previous declaration here", + }); + case.addError( + \\pub fn main() void { + \\ var i = 0; + \\ if (true) |_| {} else |i| {} + \\} + , &[_][]const u8{ + ":3:28: error: redeclaration of local variable 'i'", + ":2:9: note: previous declaration here", + }); } {