From 09d04edfcf2fef78e84dca5e841e99d86a8536af Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Tue, 23 Jul 2013 14:18:38 -0700 Subject: [PATCH] go.tools/go/types: declare typeswitch local variable in correct scope R=adonovan CC=golang-dev https://golang.org/cl/11534044 --- go/types/stmt.go | 23 +++++++++++------------ go/types/testdata/stmt0.src | 14 ++++++++++++++ 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/go/types/stmt.go b/go/types/stmt.go index 19e88fbf..5930a3c3 100644 --- a/go/types/stmt.go +++ b/go/types/stmt.go @@ -381,12 +381,6 @@ func (check *checker) stmt(s ast.Stmt) { 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) for _, s := range s.Body.List { clause, _ := s.(*ast.CaseClause) @@ -411,14 +405,19 @@ func (check *checker) stmt(s ast.Stmt) { } } 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 { - // A single-type case clause implicitly declares a new variable shadowing lhs. - if len(clause.List) == 1 && typ != nil { - obj := NewVar(lhs.Pos(), check.pkg, lhs.Name, typ) - check.declare(check.topScope, nil, obj) - check.recordImplicit(clause, obj) + // spec: "The TypeSwitchGuard may include a short variable declaration. + // 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) + check.declare(check.topScope, nil, obj) + check.recordImplicit(clause, obj) } check.stmtList(clause.Body) check.closeScope() diff --git a/go/types/testdata/stmt0.src b/go/types/testdata/stmt0.src index 7e098177..f00e98c6 100644 --- a/go/types/testdata/stmt0.src +++ b/go/types/testdata/stmt0.src @@ -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() { var ( x int