mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
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 <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
parent
e1b1b7856f
commit
616c39f6a6
4 changed files with 33 additions and 78 deletions
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
t = types.NewDDDArray(r.Type)
|
||||
} 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)
|
||||
}
|
||||
|
||||
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())
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue