@@ -245,31 +245,34 @@ func checkShadowing(pass *analysis.Pass, spans map[types.Object]span, ident *ast
245245 if shadowed .Parent () == types .Universe {
246246 return
247247 }
248+
249+ shadowedPos := pass .Fset .Position (shadowed .Pos ())
250+ identPos := pass .Fset .Position (ident .Pos ())
251+
248252 if strict {
249253 // The shadowed identifier must appear before this one to be an instance of shadowing.
250254 if shadowed .Pos () > ident .Pos () {
251255 return
252256 }
253257 } else {
254258 // 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.
256261 span , ok := spans [shadowed ]
257262 if ! ok {
258263 pass .ReportRangef (ident , "internal error: no range for %q" , ident .Name )
259264 return
260265 }
261- if ! span .contains (ident .Pos ()) {
266+
267+ if shadowedPos .Filename == identPos .Filename && ! span .contains (ident .Pos ()) {
262268 return
263269 }
264270 }
265271 // Don't complain if the types differ: that implies the programmer really wants two different things.
266272 if types .Identical (obj .Type (), shadowed .Type ()) {
267- shadowedPos := pass .Fset .Position (shadowed .Pos ())
268-
269273 // Build the message, adding filename only if in a different file
270274 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 {
273276 message += fmt .Sprintf (" in %s" , filepath .Base (shadowedPos .Filename ))
274277 }
275278
0 commit comments