mirror of
https://github.com/golang/go.git
synced 2024-09-29 06:17:11 +00:00
go/types: fix scope extents for range and type switch variables
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>
This commit is contained in:
parent
604efe1281
commit
fd8028dec9
@ -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"
|
||||
}-->
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user