]> Cypherpunks repositories - gostls13.git/commitdiff
go/types: fix scope extents for range and type switch variables
authorRobert Griesemer <gri@golang.org>
Wed, 17 Aug 2016 22:35:15 +0000 (15:35 -0700)
committerRobert Griesemer <gri@golang.org>
Thu, 18 Aug 2016 20:07:05 +0000 (20:07 +0000)
The changes match the existing compilers, and assume an adjusted
spec (per issue #16794).

Fixes #15686.

Change-Id: I72677ce75888c41a8f3c2963117a2f2d5501c42b
Reviewed-on: https://go-review.googlesource.com/27290
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
doc/go_spec.html
src/go/types/api_test.go
src/go/types/stmt.go

index 731186e66b23f6c79c2d19edd56d13b7a5e3bd41..4ce75e4f88f9ea4b7a73a375cda76165d270d93e 100644 (file)
@@ -1,6 +1,6 @@
 <!--{
        "Title": "The Go Programming Language Specification",
-       "Subtitle": "Version of May 31, 2016",
+       "Subtitle": "Version of August 18, 2016",
        "Path": "/ref/spec"
 }-->
 
index e011e6daef4a241a54fe8bea562908068064b607..1d74612dc0feb7c3b5c16e2f88580d26caf9a529 100644 (file)
@@ -1016,7 +1016,11 @@ func TestScopeLookupParent(t *testing.T) {
        }
        var info Info
        makePkg := func(path string, files ...*ast.File) {
-               imports[path], _ = conf.Check(path, fset, files, &info)
+               var err error
+               imports[path], err = conf.Check(path, fset, files, &info)
+               if err != nil {
+                       t.Fatal(err)
+               }
        }
 
        makePkg("lib", mustParse("package lib; var X int"))
@@ -1024,17 +1028,44 @@ func TestScopeLookupParent(t *testing.T) {
        // name at that point and checks that it resolves to a decl of
        // the specified kind and line number.  "undef" means undefined.
        mainSrc := `
+/*lib=pkgname:5*/ /*X=var:1*/ /*Pi=const:8*/ /*T=typename:9*/ /*Y=var:10*/ /*F=func:12*/
 package main
+
 import "lib"
-var Y = lib.X
-func f() {
-       print(Y) /*Y=var:4*/
-       z /*z=undef*/ := /*z=undef*/ 1 /*z=var:7*/
-       print(z)
-       /*f=func:5*/ /*lib=pkgname:3*/
-       type /*T=undef*/ T /*T=typename:10*/ *T
+import . "lib"
+
+const Pi = 3.1415
+type T struct{}
+var Y, _ = lib.X, X
+
+func F(){
+       const pi, e = 3.1415, /*pi=undef*/ 2.71828 /*pi=const:13*/ /*e=const:13*/
+       type /*t=undef*/ t /*t=typename:14*/ *t
+       print(Y) /*Y=var:10*/
+       x, Y := Y, /*x=undef*/ /*Y=var:10*/ Pi /*x=var:16*/ /*Y=var:16*/ ; _ = x; _ = Y
+       var F = /*F=func:12*/ F /*F=var:17*/ ; _ = F
+
+       var a []int
+       for i, x := range /*i=undef*/ /*x=var:16*/ a /*i=var:20*/ /*x=var:20*/ { _ = i; _ = x }
+
+       var i interface{}
+       switch y := i.(type) { /*y=undef*/
+       case /*y=undef*/ int /*y=var:23*/ :
+       case float32, /*y=undef*/ float64 /*y=var:23*/ :
+       default /*y=var:23*/:
+               println(y)
+       }
+       /*y=undef*/
+
+        switch int := i.(type) {
+        case /*int=typename:0*/ int /*int=var:31*/ :
+               println(int)
+        default /*int=var:31*/ :
+        }
 }
+/*main=undef*/
 `
+
        info.Uses = make(map[*ast.Ident]Object)
        f := mustParse(mainSrc)
        makePkg("main", f)
index b8c89a0afa3c08e0063cd25d098a213cb6a9e580..4e423bd686ffbb08066e32fe8a4237fb98ebd216 100644 (file)
@@ -628,9 +628,9 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) {
                                        T = x.typ
                                }
                                obj := NewVar(lhs.Pos(), check.pkg, lhs.Name, T)
-                               scopePos := clause.End()
-                               if len(clause.Body) > 0 {
-                                       scopePos = clause.Body[0].Pos()
+                               scopePos := clause.Pos() + token.Pos(len("default")) // for default clause (len(List) == 0)
+                               if n := len(clause.List); n > 0 {
+                                       scopePos = clause.List[n-1].End()
                                }
                                check.declare(check.scope, nil, obj, scopePos)
                                check.recordImplicit(clause, obj)
@@ -822,12 +822,12 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) {
 
                        // declare variables
                        if len(vars) > 0 {
+                               scopePos := s.X.End()
                                for _, obj := range vars {
                                        // spec: "The scope of a constant or variable identifier declared inside
                                        // a function begins at the end of the ConstSpec or VarSpec (ShortVarDecl
                                        // for short variable declarations) and ends at the end of the innermost
                                        // containing block."
-                                       scopePos := s.End()
                                        check.declare(check.scope, nil /* recordDef already called */, obj, scopePos)
                                }
                        } else {