Skip to content

Commit a84e523

Browse files
committed
go/analysis/passes/shadow: add filename if shadowed variable is in other file
1 parent f7d99c1 commit a84e523

File tree

4 files changed

+38
-2
lines changed

4 files changed

+38
-2
lines changed

go/analysis/passes/shadow/shadow.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@ package shadow
66

77
import (
88
_ "embed"
9+
"fmt"
910
"go/ast"
1011
"go/token"
1112
"go/types"
13+
"path/filepath"
1214

1315
"golang.org/x/tools/go/analysis"
1416
"golang.org/x/tools/go/analysis/passes/inspect"
@@ -262,7 +264,14 @@ func checkShadowing(pass *analysis.Pass, spans map[types.Object]span, ident *ast
262264
}
263265
// Don't complain if the types differ: that implies the programmer really wants two different things.
264266
if types.Identical(obj.Type(), shadowed.Type()) {
265-
line := pass.Fset.Position(shadowed.Pos()).Line
266-
pass.ReportRangef(ident, "declaration of %q shadows declaration at line %d", obj.Name(), line)
267+
shadowedPos := pass.Fset.Position(shadowed.Pos())
268+
269+
// Build the message, adding filename only if in a different file
270+
message := fmt.Sprintf("declaration of %q shadows declaration at line %d", obj.Name(), shadowedPos.Line)
271+
currentFile := pass.Fset.Position(ident.Pos()).Filename
272+
if shadowedPos.Filename != currentFile {
273+
message += fmt.Sprintf(" in %s", filepath.Base(shadowedPos.Filename))
274+
}
275+
pass.ReportRangef(ident, message)
267276
}
268277
}

go/analysis/passes/shadow/shadow_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,8 @@ func Test(t *testing.T) {
1515
testdata := analysistest.TestData()
1616
analysistest.Run(t, testdata, shadow.Analyzer, "a")
1717
}
18+
19+
func TestCrossFile(t *testing.T) {
20+
testdata := analysistest.TestData()
21+
analysistest.Run(t, testdata, shadow.Analyzer, "crossfile")
22+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright 2025 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
// This file contains a test for the shadowed variable checker with cross-file reference.
6+
7+
package crossfile
8+
9+
func ShadowGlobal() {
10+
{
11+
global := 1 // want "declaration of .global. shadows declaration at line 7 in other.go"
12+
_ = global
13+
}
14+
_ = global
15+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// Copyright 2025 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package crossfile
6+
7+
var global int

0 commit comments

Comments
 (0)