]> Cypherpunks repositories - gostls13.git/commitdiff
go/types: better cycle reporting for some cyclic composite literals
authorRobert Griesemer <gri@golang.org>
Wed, 9 May 2018 01:01:16 +0000 (18:01 -0700)
committerRobert Griesemer <gri@golang.org>
Thu, 31 May 2018 18:22:15 +0000 (18:22 +0000)
To evaluate the type of composite literals, the type checker called
Checker.typ which breaks cycles. As a result, certain cycles were
not reported with actual cycle reporting, but caught due to other
uninitialized fields (with less nice error message).

The change now calls Checker.typExpr at the relevant call site.

For #18643.

Change-Id: Iecb3f0e1afb4585b85553b6c581212f52ac3a1c4
Reviewed-on: https://go-review.googlesource.com/115456
Reviewed-by: Alan Donovan <adonovan@google.com>
src/go/types/builtins.go
src/go/types/expr.go
src/go/types/testdata/cycles.src
src/go/types/typexpr.go

index afe5f5d0fcb448d94bda61519309954cca10722f..05e032423ca2c84cb84c67ca5da1b81454c87c59 100644 (file)
@@ -174,7 +174,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
                        }
                }
 
-               if mode == invalid {
+               if mode == invalid && typ != Typ[Invalid] {
                        check.invalidArg(x.pos(), "%s for %s", x, bin.name)
                        return
                }
index 0a2a811bd88986684f795c04f297eef0cd76e6b8..3f3c4f83c6489ec0a140273e00a6be0f2d707c0d 100644 (file)
@@ -1064,7 +1064,7 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind {
                                        break
                                }
                        }
-                       typ = check.typ(e.Type)
+                       typ = check.typExpr(e.Type, nil, nil)
                        base = typ
 
                case hint != nil:
index 79e75e9316d7f393933581a08d2e4c29eaf15bd3..59f112dba1db7f7a808d0579278e5ec7707a0f60 100644 (file)
@@ -147,7 +147,7 @@ type (
 // test cases for issue 18643
 // (type cycle detection when non-type expressions are involved)
 type (
-       T14 [len(T14 /* ERROR cycle */ {})]int
+       T14 /* ERROR cycle */ [len(T14{})]int
        T15 [][len(T15 /* ERROR cycle */ {})]int
        T16 map[[len(T16 /* ERROR cycle */ {1:2})]int]int
        T17 map[int][len(T17 /* ERROR cycle */ {1:2})]int
index e3f50000ec807e75c11d47cb2be09b5821cdebce..45ada5874bc193adbcd3ae37c69ca7a0bfad154e 100644 (file)
@@ -161,6 +161,11 @@ func (check *Checker) typExpr(e ast.Expr, def *Named, path []*TypeName) (T Type)
        return
 }
 
+// typ is like typExpr (with a nil argument for the def parameter),
+// but typ breaks type cycles. It should be called for components of
+// types that break cycles, such as pointer base types, slice or map
+// element types, etc. See the comment in typExpr for details.
+//
 func (check *Checker) typ(e ast.Expr) Type {
        // typExpr is called with a nil path indicating an indirection:
        // push indir sentinel on object path