@@ -245,31 +245,34 @@ func checkShadowing(pass *analysis.Pass, spans map[types.Object]span, ident *ast
245
245
if shadowed .Parent () == types .Universe {
246
246
return
247
247
}
248
+
249
+ shadowedPos := pass .Fset .Position (shadowed .Pos ())
250
+ identPos := pass .Fset .Position (ident .Pos ())
251
+
248
252
if strict {
249
253
// The shadowed identifier must appear before this one to be an instance of shadowing.
250
254
if shadowed .Pos () > ident .Pos () {
251
255
return
252
256
}
253
257
} else {
254
258
// Don't complain if the span of validity of the shadowed identifier doesn't include
255
- // the shadowing identifier.
259
+ // the shadowing identifier, except for cross-file shadowing where file processing
260
+ // order affects span checks.
256
261
span , ok := spans [shadowed ]
257
262
if ! ok {
258
263
pass .ReportRangef (ident , "internal error: no range for %q" , ident .Name )
259
264
return
260
265
}
261
- if ! span .contains (ident .Pos ()) {
266
+
267
+ if shadowedPos .Filename == identPos .Filename && ! span .contains (ident .Pos ()) {
262
268
return
263
269
}
264
270
}
265
271
// Don't complain if the types differ: that implies the programmer really wants two different things.
266
272
if types .Identical (obj .Type (), shadowed .Type ()) {
267
- shadowedPos := pass .Fset .Position (shadowed .Pos ())
268
-
269
273
// Build the message, adding filename only if in a different file
270
274
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 {
275
+ if shadowedPos .Filename != identPos .Filename {
273
276
message += fmt .Sprintf (" in %s" , filepath .Base (shadowedPos .Filename ))
274
277
}
275
278
0 commit comments