go.tools/go/types: declare typeswitch local variable in correct scope
R=adonovan CC=golang-dev https://golang.org/cl/11534044
This commit is contained in:
parent
7bc647b29a
commit
09d04edfcf
|
@ -381,12 +381,6 @@ func (check *checker) stmt(s ast.Stmt) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var obj Object
|
|
||||||
if lhs != nil {
|
|
||||||
obj = NewVar(lhs.Pos(), check.pkg, lhs.Name, x.typ)
|
|
||||||
check.declare(check.topScope, lhs, obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
check.multipleDefaults(s.Body.List)
|
check.multipleDefaults(s.Body.List)
|
||||||
for _, s := range s.Body.List {
|
for _, s := range s.Body.List {
|
||||||
clause, _ := s.(*ast.CaseClause)
|
clause, _ := s.(*ast.CaseClause)
|
||||||
|
@ -411,15 +405,20 @@ func (check *checker) stmt(s ast.Stmt) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
check.openScope(clause)
|
check.openScope(clause)
|
||||||
// If lhs exists, declare a corresponding object in the case-local scope if necessary.
|
// If lhs exists, declare a corresponding variable in the case-local scope if necessary.
|
||||||
if lhs != nil {
|
if lhs != nil {
|
||||||
// A single-type case clause implicitly declares a new variable shadowing lhs.
|
// spec: "The TypeSwitchGuard may include a short variable declaration.
|
||||||
if len(clause.List) == 1 && typ != nil {
|
// When that form is used, the variable is declared at the beginning of
|
||||||
|
// the implicit block in each clause. In clauses with a case listing
|
||||||
|
// exactly one type, the variable has that type; otherwise, the variable
|
||||||
|
// has the type of the expression in the TypeSwitchGuard."
|
||||||
|
if len(clause.List) != 1 || typ == nil {
|
||||||
|
typ = x.typ
|
||||||
|
}
|
||||||
obj := NewVar(lhs.Pos(), check.pkg, lhs.Name, typ)
|
obj := NewVar(lhs.Pos(), check.pkg, lhs.Name, typ)
|
||||||
check.declare(check.topScope, nil, obj)
|
check.declare(check.topScope, nil, obj)
|
||||||
check.recordImplicit(clause, obj)
|
check.recordImplicit(clause, obj)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
check.stmtList(clause.Body)
|
check.stmtList(clause.Body)
|
||||||
check.closeScope()
|
check.closeScope()
|
||||||
}
|
}
|
||||||
|
|
|
@ -229,6 +229,20 @@ func typeswitch0() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test correct scope setup.
|
||||||
|
// (no redeclaration errors expected in the type switch)
|
||||||
|
func typeswitch1() {
|
||||||
|
var t I
|
||||||
|
switch t := t; t := t.(type) {
|
||||||
|
case nil:
|
||||||
|
var _ I = t
|
||||||
|
case T:
|
||||||
|
var _ T = t
|
||||||
|
default:
|
||||||
|
var _ I = t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func rangeloops() {
|
func rangeloops() {
|
||||||
var (
|
var (
|
||||||
x int
|
x int
|
||||||
|
|
Loading…
Reference in New Issue