From: Matthew Dempsky Date: Thu, 26 Sep 2019 19:37:36 +0000 (-0700) Subject: cmd/compile: remove DDD array types X-Git-Tag: go1.14beta1~944 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=616c39f6a636166447bdaac4f0871a5ca52bae8c;p=gostls13.git cmd/compile: remove DDD array types 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 TryBot-Result: Gobot Gobot Reviewed-by: Robert Griesemer --- diff --git a/src/cmd/compile/internal/gc/align.go b/src/cmd/compile/internal/gc/align.go index bd6176e479..a2b5b53740 100644 --- a/src/cmd/compile/internal/gc/align.go +++ b/src/cmd/compile/internal/gc/align.go @@ -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 { diff --git a/src/cmd/compile/internal/gc/fmt.go b/src/cmd/compile/internal/gc/fmt.go index e449444ca5..7b974cc866 100644 --- a/src/cmd/compile/internal/gc/fmt.go +++ b/src/cmd/compile/internal/gc/fmt.go @@ -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: diff --git a/src/cmd/compile/internal/gc/typecheck.go b/src/cmd/compile/internal/gc/typecheck.go index b13f2e2e1c..ab45fb5a2d 100644 --- a/src/cmd/compile/internal/gc/typecheck.go +++ b/src/cmd/compile/internal/gc/typecheck.go @@ -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 } diff --git a/src/cmd/compile/internal/types/type.go b/src/cmd/compile/internal/types/type.go index e61a5573dd..3b7b31c5d6 100644 --- a/src/cmd/compile/internal/types/type.go +++ b/src/cmd/compile/internal/types/type.go @@ -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