]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile/internal/types2: review of stmt.go
authorRobert Griesemer <gri@golang.org>
Mon, 29 Mar 2021 20:36:53 +0000 (13:36 -0700)
committerRobert Griesemer <gri@golang.org>
Sat, 3 Apr 2021 01:45:13 +0000 (01:45 +0000)
The changes between (equivalent, and reviewed) go/types/stmt.go
and stmt.go can be seen by comparing patchset 1 and 2. The actual
changes are removing the "// UNREVIEWED" marker, and minor adjustments
to get the code slightly closer to go/types/stmt.go.

The primary differences compared to go/types are:
- use of syntax rather than go/ast package, with significant
  differences in the representation of switch and select statements,
  range clauses of for statements, and inc/dec statements.
- no reporting of error codes
- use or error_ for collecting addition error information

Change-Id: I4409f62ecafd0653e4c8ef087c2580d8f0544efc
Reviewed-on: https://go-review.googlesource.com/c/go/+/305576
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
src/cmd/compile/internal/types2/stmt.go

index 367146b5287bcce40862a7b9976183f2d0c3a80f..319354bea2634d2c08e2eb90122f3aa25bf65d27 100644 (file)
@@ -1,4 +1,3 @@
-// UNREVIEWED
 // Copyright 2012 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
@@ -265,7 +264,7 @@ L:
        }
 }
 
-func (check *Checker) caseTypes(x *operand, xtyp *Interface, types []syntax.Expr, seen map[Type]syntax.Pos) (T Type) {
+func (check *Checker) caseTypes(x *operand, xtyp *Interface, types []syntax.Expr, seen map[Type]syntax.Expr) (T Type) {
 L:
        for _, e := range types {
                T = check.typOrNil(e)
@@ -277,7 +276,7 @@ L:
                }
                // look for duplicate types
                // (quadratic algorithm, but type switches tend to be reasonably small)
-               for t, pos := range seen {
+               for t, other := range seen {
                        if T == nil && t == nil || T != nil && t != nil && check.identical(T, t) {
                                // talk about "case" rather than "type" because of nil case
                                Ts := "nil"
@@ -286,12 +285,12 @@ L:
                                }
                                var err error_
                                err.errorf(e, "duplicate case %s in type switch", Ts)
-                               err.errorf(pos, "previous case")
+                               err.errorf(other, "previous case")
                                check.report(&err)
                                continue L
                        }
                }
-               seen[T] = e.Pos()
+               seen[T] = e
                if T != nil {
                        check.typeAssertion(e.Pos(), x, xtyp, T)
                }
@@ -409,11 +408,6 @@ func (check *Checker) stmt(ctxt stmtContext, s syntax.Stmt) {
                check.binary(&x, nil, lhs[0], rhs[0], s.Op)
                check.assignVar(lhs[0], &x)
 
-       // case *syntax.GoStmt:
-       //      check.suspendedCall("go", s.Call)
-
-       // case *syntax.DeferStmt:
-       //      check.suspendedCall("defer", s.Call)
        case *syntax.CallStmt:
                // TODO(gri) get rid of this conversion to string
                kind := "go"
@@ -686,6 +680,10 @@ func (check *Checker) typeSwitchStmt(inner stmtContext, s *syntax.SwitchStmt, gu
        if x.mode == invalid {
                return
        }
+       // Caution: We're not using asInterface here because we don't want
+       //          to switch on a suitably constrained type parameter (for
+       //          now).
+       // TODO(gri) Need to revisit this.
        xtyp, _ := under(x.typ).(*Interface)
        if xtyp == nil {
                check.errorf(&x, "%s is not an interface type", &x)
@@ -695,8 +693,8 @@ func (check *Checker) typeSwitchStmt(inner stmtContext, s *syntax.SwitchStmt, gu
 
        check.multipleSwitchDefaults(s.Body)
 
-       var lhsVars []*Var                // list of implicitly declared lhs variables
-       seen := make(map[Type]syntax.Pos) // map of seen types to positions
+       var lhsVars []*Var                 // list of implicitly declared lhs variables
+       seen := make(map[Type]syntax.Expr) // map of seen types to positions
        for i, clause := range s.Body {
                if clause == nil {
                        check.error(s, invalidAST+"incorrect type switch case")
@@ -739,6 +737,9 @@ func (check *Checker) typeSwitchStmt(inner stmtContext, s *syntax.SwitchStmt, gu
        }
 
        // If lhs exists, we must have at least one lhs variable that was used.
+       // (We can't use check.usage because that only looks at one scope; and
+       // we don't want to use the same variable for all scopes and change the
+       // variable type underfoot.)
        if lhs != nil {
                var used bool
                for _, v := range lhsVars {