Skip to content

Commit a49867f

Browse files
committed
internal/imports: don't add imports that shadow predeclared names
Also, a test. Fixes golang/go#63592 Change-Id: I36cab69cb224f90cc8459c3fced2408486193a1f Reviewed-on: https://go-review.googlesource.com/c/tools/+/557216 LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Robert Findley <[email protected]>
1 parent e2ca594 commit a49867f

File tree

2 files changed

+67
-0
lines changed

2 files changed

+67
-0
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
This is a regression test for bug #63592 in "organize imports" whereby
2+
the new imports would shadow predeclared names.
3+
4+
In the original example, the conflict was between predeclared error
5+
type and the unfortunately named package github.com/coreos/etcd/error,
6+
but this example uses a package with the ludicrous name of complex128.
7+
8+
The new behavior is that we will not attempt to import packages
9+
that shadow predeclared names. (Ideally we would do that only if
10+
the predeclared name is actually referenced in the file, which
11+
complex128 happens to be in this example, but that's a trickier
12+
analysis than the internal/imports package is game for.)
13+
14+
The name complex127 works as usual.
15+
16+
-- go.mod --
17+
module example.com
18+
go 1.18
19+
20+
-- complex128/a.go --
21+
package complex128
22+
23+
var V int
24+
25+
-- complex127/a.go --
26+
package complex127
27+
28+
var V int
29+
30+
-- main.go --
31+
package main
32+
33+
import () //@codeaction("import", "", "source.organizeImports", out)
34+
35+
func main() {
36+
complex128.V() //@diag("V", re"type complex128 has no field")
37+
complex127.V() //@diag("complex127", re"(undeclared|undefined)")
38+
}
39+
40+
func _() {
41+
var _ complex128 = 1 + 2i
42+
}
43+
-- @out/main.go --
44+
package main
45+
46+
import "example.com/complex127" //@codeaction("import", "", "source.organizeImports", out)
47+
48+
func main() {
49+
complex128.V() //@diag("V", re"type complex128 has no field")
50+
complex127.V() //@diag("complex127", re"(undeclared|undefined)")
51+
}
52+
53+
func _() {
54+
var _ complex128 = 1 + 2i
55+
}

internal/imports/fix.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"go/build"
1414
"go/parser"
1515
"go/token"
16+
"go/types"
1617
"io/fs"
1718
"io/ioutil"
1819
"os"
@@ -1151,6 +1152,17 @@ func addExternalCandidates(ctx context.Context, pass *pass, refs references, fil
11511152
}()
11521153

11531154
for result := range results {
1155+
// Don't offer completions that would shadow predeclared
1156+
// names, such as github.com/coreos/etcd/error.
1157+
if types.Universe.Lookup(result.pkg.name) != nil { // predeclared
1158+
// Ideally we would skip this candidate only
1159+
// if the predeclared name is actually
1160+
// referenced by the file, but that's a lot
1161+
// trickier to compute and would still create
1162+
// an import that is likely to surprise the
1163+
// user before long.
1164+
continue
1165+
}
11541166
pass.addCandidate(result.imp, result.pkg)
11551167
}
11561168
return firstErr

0 commit comments

Comments
 (0)