]> Cypherpunks repositories - gostls13.git/commitdiff
go/types: fix Info.Implicits entries
authorgriesemer <gri@golang.org>
Thu, 31 Aug 2017 15:41:51 +0000 (17:41 +0200)
committerRobert Griesemer <gri@golang.org>
Fri, 1 Sep 2017 08:06:49 +0000 (08:06 +0000)
Packages of dot imports don't appear in the Info.Implicits map
since they are already taken care of by the Info.Defs map. Fix
documentation.

Implicitly dot-imported objects of a package shouldn't appear
in the Info.Implicits map because the documentation never said
so and there's no way to map multiple objects to the same
*ast.ImportSpec with the current data structure.

Added missing test for Info.Implicits.

The fix is a trivial one-line deletion, the rest is documentation
and test.

Fixes #21591.

Change-Id: I12a37dab85c531911c9363ec3d58daa095c7eb24
Reviewed-on: https://go-review.googlesource.com/60672
Reviewed-by: Alan Donovan <adonovan@google.com>
src/go/types/api.go
src/go/types/api_test.go
src/go/types/resolver.go

index 11e76867a1f74fb20e4dad26aa685bb31c57e6b0..81b83da221bceef8400f1676b7398b3e5bbeae1f 100644 (file)
@@ -176,11 +176,11 @@ type Info struct {
        // Implicits maps nodes to their implicitly declared objects, if any.
        // The following node and object types may appear:
        //
-       //      node               declared object
+       //     node               declared object
        //
-       //      *ast.ImportSpec    *PkgName for dot-imports and imports without renames
-       //      *ast.CaseClause    type-specific *Var for each type switch case clause (incl. default)
-       //      *ast.Field         anonymous parameter *Var
+       //     *ast.ImportSpec    *PkgName for imports without renames
+       //     *ast.CaseClause    type-specific *Var for each type switch case clause (incl. default)
+       //     *ast.Field         anonymous parameter *Var
        //
        Implicits map[ast.Node]Object
 
@@ -200,16 +200,16 @@ type Info struct {
        //
        // The following node types may appear in Scopes:
        //
-       //      *ast.File
-       //      *ast.FuncType
-       //      *ast.BlockStmt
-       //      *ast.IfStmt
-       //      *ast.SwitchStmt
-       //      *ast.TypeSwitchStmt
-       //      *ast.CaseClause
-       //      *ast.CommClause
-       //      *ast.ForStmt
-       //      *ast.RangeStmt
+       //     *ast.File
+       //     *ast.FuncType
+       //     *ast.BlockStmt
+       //     *ast.IfStmt
+       //     *ast.SwitchStmt
+       //     *ast.TypeSwitchStmt
+       //     *ast.CaseClause
+       //     *ast.CommClause
+       //     *ast.ForStmt
+       //     *ast.RangeStmt
        //
        Scopes map[ast.Node]*Scope
 
index d4f3f3571706ea946046542fa41a012aeeaf6d56..ab08a2669d521bd8067f5c8c3607d36bd99f19da 100644 (file)
@@ -257,6 +257,63 @@ func TestTypesInfo(t *testing.T) {
        }
 }
 
+func TestImplicitsInfo(t *testing.T) {
+       testenv.MustHaveGoBuild(t)
+
+       var tests = []struct {
+               src  string
+               want string
+       }{
+               {`package p2; import . "fmt"; var _ = Println`, ""},           // no Implicits entry
+               {`package p0; import local "fmt"; var _ = local.Println`, ""}, // no Implicits entry
+               {`package p1; import "fmt"; var _ = fmt.Println`, "importSpec: package fmt"},
+
+               {`package p3; func f(x interface{}) { switch x.(type) { case int: } }`, ""}, // no Implicits entry
+               {`package p4; func f(x interface{}) { switch t := x.(type) { case int: _ = t } }`, "caseClause: var t int"},
+               {`package p5; func f(x interface{}) { switch t := x.(type) { case int, uint: _ = t } }`, "caseClause: var t interface{}"},
+               {`package p6; func f(x interface{}) { switch t := x.(type) { default: _ = t } }`, "caseClause: var t interface{}"},
+
+               {`package p7; func f(x int) {}`, ""}, // no Implicits entry
+               {`package p8; func f(int) {}`, "field: var  int"},
+               {`package p9; func f() (complex64) { return 0 }`, "field: var  complex64"},
+               {`package p10; type T struct{}; func (*T) f() {}`, "field: var  *p10.T"},
+       }
+
+       for _, test := range tests {
+               info := Info{
+                       Implicits: make(map[ast.Node]Object),
+               }
+               name := mustTypecheck(t, "ImplicitsInfo", test.src, &info)
+
+               // the test cases expect at most one Implicits entry
+               if len(info.Implicits) > 1 {
+                       t.Errorf("package %s: %d Implicits entries found", name, len(info.Implicits))
+                       continue
+               }
+
+               // extract Implicits entry, if any
+               var got string
+               for n, obj := range info.Implicits {
+                       switch x := n.(type) {
+                       case *ast.ImportSpec:
+                               got = "importSpec"
+                       case *ast.CaseClause:
+                               got = "caseClause"
+                       case *ast.Field:
+                               got = "field"
+                       default:
+                               t.Fatalf("package %s: unexpected %T", name, x)
+                       }
+                       got += ": " + obj.String()
+               }
+
+               // verify entry
+               if got != test.want {
+                       t.Errorf("package %s: got %q; want %q", name, got, test.want)
+               }
+       }
+}
+
 func predString(tv TypeAndValue) string {
        var buf bytes.Buffer
        pred := func(b bool, s string) {
index 05603b3442d00db23436bad759e4d0cf9e7400e5..ba75a0dc2398c67454407af4bb49a936ac33adb0 100644 (file)
@@ -303,7 +303,6 @@ func (check *Checker) collectObjects() {
                                                                        // via Config.Packages - may be dot-imported in
                                                                        // another package!)
                                                                        check.declare(fileScope, nil, obj, token.NoPos)
-                                                                       check.recordImplicit(s, obj)
                                                                }
                                                        }
                                                        // add position to set of dot-import positions for this file