]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: remove DDD array types
authorMatthew Dempsky <mdempsky@google.com>
Thu, 26 Sep 2019 19:37:36 +0000 (12:37 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Thu, 26 Sep 2019 20:45:09 +0000 (20:45 +0000)
Currently we handle [...]T array literals by treating [...]T as
special "DDD array" types. However, these array literals are just
composite literal syntax, not a distinct Go type. Moreover,
representing them as Go types contributes to complexity in a number of
unrelated bits of code.

This CL changes OCOMPLIT typechecking to look for the [...]T syntax
and handle it specially, so we can remove DDD arrays.

Passes toolstash-check.

Change-Id: Ibbf701eac4caa7a321e2d10e256658fdfaa8a160
Reviewed-on: https://go-review.googlesource.com/c/go/+/197604
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
src/cmd/compile/internal/gc/align.go
src/cmd/compile/internal/gc/fmt.go
src/cmd/compile/internal/gc/typecheck.go
src/cmd/compile/internal/types/type.go

index bd6176e4794d4f6f348fd76505c4b4c6d40b4c17..a2b5b53740806205e626abe49039c1b163cb61ef 100644 (file)
@@ -324,13 +324,6 @@ func dowidth(t *types.Type) {
                if t.Elem() == nil {
                        break
                }
-               if t.IsDDDArray() {
-                       if !t.Broke() {
-                               yyerror("use of [...] array outside of array literal")
-                               t.SetBroke(true)
-                       }
-                       break
-               }
 
                dowidth(t.Elem())
                if t.Elem().Width != 0 {
index e449444ca576cec2338afc310bde5cbeb8157ec7..7b974cc8662bec3f257c45a7ea1b83e148e20255 100644 (file)
@@ -720,9 +720,6 @@ func typefmt(t *types.Type, flag FmtFlag, mode fmtMode, depth int) string {
                return "*" + tmodeString(t.Elem(), mode, depth)
 
        case TARRAY:
-               if t.IsDDDArray() {
-                       return "[...]" + tmodeString(t.Elem(), mode, depth)
-               }
                return "[" + strconv.FormatInt(t.NumElem(), 10) + "]" + tmodeString(t.Elem(), mode, depth)
 
        case TSLICE:
index b13f2e2e1caaabe0b0d597c882b0ead9f74cc445..ab45fb5a2d64758b5c7d6db6131b85f392ec9dc8 100644 (file)
@@ -62,7 +62,6 @@ const (
        ctxCallee              // call-only expressions are ok
        ctxMultiOK             // multivalue function returns are ok
        ctxAssign              // assigning to expression
-       ctxCompLit             // type in composite literal
 )
 
 // type checks the whole tree of an expression.
@@ -413,15 +412,12 @@ func typecheck1(n *Node, top int) (res *Node) {
                if n.Left == nil {
                        t = types.NewSlice(r.Type)
                } else if n.Left.Op == ODDD {
-                       if top&ctxCompLit == 0 {
-                               if !n.Diag() {
-                                       n.SetDiag(true)
-                                       yyerror("use of [...] array outside of array literal")
-                               }
-                               n.Type = nil
-                               return n
+                       if !n.Diag() {
+                               n.SetDiag(true)
+                               yyerror("use of [...] array outside of array literal")
                        }
-                       t = types.NewDDDArray(r.Type)
+                       n.Type = nil
+                       return n
                } else {
                        n.Left = indexlit(typecheck(n.Left, ctxExpr))
                        l := n.Left
@@ -457,9 +453,7 @@ func typecheck1(n *Node, top int) (res *Node) {
                setTypeNode(n, t)
                n.Left = nil
                n.Right = nil
-               if !t.IsDDDArray() {
-                       checkwidth(t)
-               }
+               checkwidth(t)
 
        case OTMAP:
                ok |= ctxType
@@ -517,7 +511,7 @@ func typecheck1(n *Node, top int) (res *Node) {
 
        // type or expr
        case ODEREF:
-               n.Left = typecheck(n.Left, ctxExpr|ctxType|top&ctxCompLit)
+               n.Left = typecheck(n.Left, ctxExpr|ctxType)
                l := n.Left
                t := l.Type
                if t == nil {
@@ -527,13 +521,9 @@ func typecheck1(n *Node, top int) (res *Node) {
                if l.Op == OTYPE {
                        ok |= ctxType
                        setTypeNode(n, types.NewPtr(l.Type))
-                       // Ensure l.Type gets dowidth'd for the backend. Issue 20174.
-                       // Don't checkwidth [...] arrays, though, since they
-                       // will be replaced by concrete-sized arrays. Issue 20333.
-                       if !l.Type.IsDDDArray() {
-                               checkwidth(l.Type)
-                       }
                        n.Left = nil
+                       // Ensure l.Type gets dowidth'd for the backend. Issue 20174.
+                       checkwidth(l.Type)
                        break
                }
 
@@ -1257,7 +1247,7 @@ func typecheck1(n *Node, top int) (res *Node) {
                n.Left = defaultlit(n.Left, nil)
                l = n.Left
                if l.Op == OTYPE {
-                       if n.IsDDD() || l.Type.IsDDDArray() {
+                       if n.IsDDD() {
                                if !l.Type.Broke() {
                                        yyerror("invalid use of ... in type conversion to %v", l.Type)
                                }
@@ -2777,17 +2767,33 @@ func typecheckcomplit(n *Node) (res *Node) {
        }
 
        // Save original node (including n.Right)
-       norig := n.copy()
+       n.Orig = n.copy()
 
        setlineno(n.Right)
-       n.Right = typecheck(n.Right, ctxType|ctxCompLit)
-       l := n.Right // sic
-       t := l.Type
+
+       // Need to handle [...]T arrays specially.
+       if n.Right.Op == OTARRAY && n.Right.Left != nil && n.Right.Left.Op == ODDD {
+               n.Right.Right = typecheck(n.Right.Right, ctxType)
+               if n.Right.Right.Type == nil {
+                       n.Type = nil
+                       return n
+               }
+               elemType := n.Right.Right.Type
+
+               length := typecheckarraylit(elemType, -1, n.List.Slice())
+
+               n.Op = OARRAYLIT
+               n.Type = types.NewArray(elemType, length)
+               n.Right = nil
+               return n
+       }
+
+       n.Right = typecheck(n.Right, ctxType)
+       t := n.Right.Type
        if t == nil {
                n.Type = nil
                return n
        }
-       nerr := nerrors
        n.Type = t
 
        switch t.Etype {
@@ -2796,12 +2802,7 @@ func typecheckcomplit(n *Node) (res *Node) {
                n.Type = nil
 
        case TARRAY:
-               if t.IsDDDArray() {
-                       length := typecheckarraylit(t.Elem(), -1, n.List.Slice())
-                       t.SetNumElem(length)
-               } else {
-                       typecheckarraylit(t.Elem(), t.NumElem(), n.List.Slice())
-               }
+               typecheckarraylit(t.Elem(), t.NumElem(), n.List.Slice())
                n.Op = OARRAYLIT
                n.Right = nil
 
@@ -2954,11 +2955,6 @@ func typecheckcomplit(n *Node) (res *Node) {
                n.Right = nil
        }
 
-       if nerr != nerrors {
-               return n
-       }
-
-       n.Orig = norig
        return n
 }
 
index e61a5573dd917532f7d5d827e986ba40ffd8be4a..3b7b31c5d60b4a65ddcf43a667fe888f4682596f 100644 (file)
@@ -495,14 +495,6 @@ func NewSlice(elem *Type) *Type {
        return t
 }
 
-// NewDDDArray returns a new [...]T array Type.
-func NewDDDArray(elem *Type) *Type {
-       t := New(TARRAY)
-       t.Extra = &Array{Elem: elem, Bound: -1}
-       t.SetNotInHeap(elem.NotInHeap())
-       return t
-}
-
 // NewChan returns a new chan Type with direction dir.
 func NewChan(elem *Type, dir ChanDir) *Type {
        t := New(TCHAN)
@@ -882,13 +874,6 @@ func (t *Type) SetInterface(methods []*Field) {
        t.Methods().Set(methods)
 }
 
-func (t *Type) IsDDDArray() bool {
-       if t.Etype != TARRAY {
-               return false
-       }
-       return t.Extra.(*Array).Bound < 0
-}
-
 func (t *Type) WidthCalculated() bool {
        return t.Align > 0
 }
@@ -1325,23 +1310,7 @@ func (t *Type) FieldName(i int) string {
 
 func (t *Type) NumElem() int64 {
        t.wantEtype(TARRAY)
-       at := t.Extra.(*Array)
-       if at.Bound < 0 {
-               Fatalf("NumElem array %v does not have bound yet", t)
-       }
-       return at.Bound
-}
-
-// SetNumElem sets the number of elements in an array type.
-// The only allowed use is on array types created with NewDDDArray.
-// For other uses, create a new array with NewArray instead.
-func (t *Type) SetNumElem(n int64) {
-       t.wantEtype(TARRAY)
-       at := t.Extra.(*Array)
-       if at.Bound >= 0 {
-               Fatalf("SetNumElem array %v already has bound %d", t, at.Bound)
-       }
-       at.Bound = n
+       return t.Extra.(*Array).Bound
 }
 
 type componentsIncludeBlankFields bool