]> Cypherpunks repositories - gostls13.git/commitdiff
go/parser: don't parse a nil IndexExpr.Index
authorRob Findley <rfindley@google.com>
Fri, 30 Apr 2021 20:58:56 +0000 (16:58 -0400)
committerRobert Findley <rfindley@google.com>
Wed, 5 May 2021 20:58:39 +0000 (20:58 +0000)
When parsing type parameters, an empty type instantiation was parsed as
an IndexExpr with nil Index. This should be considered a breaking change
to parsing: ast.Walk previously assumed that Index was non-nil.

Back out the nil check in ast.Walk, and for now pack an empty argument
list as a non-nil ListExpr with nil Elems.

Alternatives considered:
 - Parsing the entire index expression as a BadExpr: this led to
   inferior errors while type checking.
 - Parsing the Index as a BadExpr: this seems reasonable, but encodes
   strictly less information into the AST.

We may want to opt for one of these alternatives in the future, but for
now let's just fix the breaking change.

Change-Id: I93f2b89641692ac014b8ee98bfa031ed3477afb8
Reviewed-on: https://go-review.googlesource.com/c/go/+/315851
Trust: Robert Findley <rfindley@google.com>
Trust: Robert Griesemer <gri@golang.org>
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
src/go/ast/walk.go
src/go/internal/typeparams/notypeparams.go
src/go/internal/typeparams/typeparams.go
src/go/parser/parser.go

index ac1395fafdb57ec5aa228bf98f3f3055483bdbf2..9224264e291e2fc8904fc208d94d0915f2e626f4 100644 (file)
@@ -112,11 +112,7 @@ func Walk(v Visitor, node Node) {
 
        case *IndexExpr:
                Walk(v, n.X)
-               // n.Index may be nil for invalid type instantiation expressions, e.g.
-               // var x T[].
-               if n.Index != nil {
-                       Walk(v, n.Index)
-               }
+               Walk(v, n.Index)
 
        case *SliceExpr:
                Walk(v, n.X)
index a8c25ac2b1fb141b138f0e522700cc5a0d70dcbd..2ceafaac1c356d95958c92b727f7756fb858d044 100644 (file)
@@ -15,8 +15,6 @@ const Enabled = false
 
 func PackExpr(list []ast.Expr) ast.Expr {
        switch len(list) {
-       case 0:
-               return nil
        case 1:
                return list[0]
        default:
index 66f66afb2845d9e95818027af7e2874a2d6110c9..871e95d9984d7ad8bc54b01464233609323d65f6 100644 (file)
@@ -17,7 +17,10 @@ const Enabled = true
 func PackExpr(list []ast.Expr) ast.Expr {
        switch len(list) {
        case 0:
-               return nil
+               // Return an empty ListExpr here, rather than nil, as IndexExpr.Index must
+               // never be nil.
+               // TODO(rFindley) would a BadExpr be more appropriate here?
+               return &ast.ListExpr{}
        case 1:
                return list[0]
        default:
index 36a044e3a29fc09b1206e936e81dcb4c74919c21..3965641713a19fe89eb9405eb6db8222c1575f15 100644 (file)
@@ -1095,6 +1095,7 @@ func (p *parser) parseChanType() *ast.ChanType {
 }
 
 func (p *parser) parseTypeInstance(typ ast.Expr) ast.Expr {
+       assert(p.parseTypeParams(), "parseTypeInstance while not parsing type params")
        if p.trace {
                defer un(trace(p, "TypeInstance"))
        }