Skip to content

Commit 616c39f

Browse files
committed
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 <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Robert Griesemer <[email protected]>
1 parent e1b1b78 commit 616c39f

File tree

4 files changed

+33
-78
lines changed

4 files changed

+33
-78
lines changed

src/cmd/compile/internal/gc/align.go

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -324,13 +324,6 @@ func dowidth(t *types.Type) {
324324
if t.Elem() == nil {
325325
break
326326
}
327-
if t.IsDDDArray() {
328-
if !t.Broke() {
329-
yyerror("use of [...] array outside of array literal")
330-
t.SetBroke(true)
331-
}
332-
break
333-
}
334327

335328
dowidth(t.Elem())
336329
if t.Elem().Width != 0 {

src/cmd/compile/internal/gc/fmt.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -720,9 +720,6 @@ func typefmt(t *types.Type, flag FmtFlag, mode fmtMode, depth int) string {
720720
return "*" + tmodeString(t.Elem(), mode, depth)
721721

722722
case TARRAY:
723-
if t.IsDDDArray() {
724-
return "[...]" + tmodeString(t.Elem(), mode, depth)
725-
}
726723
return "[" + strconv.FormatInt(t.NumElem(), 10) + "]" + tmodeString(t.Elem(), mode, depth)
727724

728725
case TSLICE:

src/cmd/compile/internal/gc/typecheck.go

Lines changed: 32 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ const (
6262
ctxCallee // call-only expressions are ok
6363
ctxMultiOK // multivalue function returns are ok
6464
ctxAssign // assigning to expression
65-
ctxCompLit // type in composite literal
6665
)
6766

6867
// type checks the whole tree of an expression.
@@ -413,15 +412,12 @@ func typecheck1(n *Node, top int) (res *Node) {
413412
if n.Left == nil {
414413
t = types.NewSlice(r.Type)
415414
} else if n.Left.Op == ODDD {
416-
if top&ctxCompLit == 0 {
417-
if !n.Diag() {
418-
n.SetDiag(true)
419-
yyerror("use of [...] array outside of array literal")
420-
}
421-
n.Type = nil
422-
return n
415+
if !n.Diag() {
416+
n.SetDiag(true)
417+
yyerror("use of [...] array outside of array literal")
423418
}
424-
t = types.NewDDDArray(r.Type)
419+
n.Type = nil
420+
return n
425421
} else {
426422
n.Left = indexlit(typecheck(n.Left, ctxExpr))
427423
l := n.Left
@@ -457,9 +453,7 @@ func typecheck1(n *Node, top int) (res *Node) {
457453
setTypeNode(n, t)
458454
n.Left = nil
459455
n.Right = nil
460-
if !t.IsDDDArray() {
461-
checkwidth(t)
462-
}
456+
checkwidth(t)
463457

464458
case OTMAP:
465459
ok |= ctxType
@@ -517,7 +511,7 @@ func typecheck1(n *Node, top int) (res *Node) {
517511

518512
// type or expr
519513
case ODEREF:
520-
n.Left = typecheck(n.Left, ctxExpr|ctxType|top&ctxCompLit)
514+
n.Left = typecheck(n.Left, ctxExpr|ctxType)
521515
l := n.Left
522516
t := l.Type
523517
if t == nil {
@@ -527,13 +521,9 @@ func typecheck1(n *Node, top int) (res *Node) {
527521
if l.Op == OTYPE {
528522
ok |= ctxType
529523
setTypeNode(n, types.NewPtr(l.Type))
530-
// Ensure l.Type gets dowidth'd for the backend. Issue 20174.
531-
// Don't checkwidth [...] arrays, though, since they
532-
// will be replaced by concrete-sized arrays. Issue 20333.
533-
if !l.Type.IsDDDArray() {
534-
checkwidth(l.Type)
535-
}
536524
n.Left = nil
525+
// Ensure l.Type gets dowidth'd for the backend. Issue 20174.
526+
checkwidth(l.Type)
537527
break
538528
}
539529

@@ -1257,7 +1247,7 @@ func typecheck1(n *Node, top int) (res *Node) {
12571247
n.Left = defaultlit(n.Left, nil)
12581248
l = n.Left
12591249
if l.Op == OTYPE {
1260-
if n.IsDDD() || l.Type.IsDDDArray() {
1250+
if n.IsDDD() {
12611251
if !l.Type.Broke() {
12621252
yyerror("invalid use of ... in type conversion to %v", l.Type)
12631253
}
@@ -2777,17 +2767,33 @@ func typecheckcomplit(n *Node) (res *Node) {
27772767
}
27782768

27792769
// Save original node (including n.Right)
2780-
norig := n.copy()
2770+
n.Orig = n.copy()
27812771

27822772
setlineno(n.Right)
2783-
n.Right = typecheck(n.Right, ctxType|ctxCompLit)
2784-
l := n.Right // sic
2785-
t := l.Type
2773+
2774+
// Need to handle [...]T arrays specially.
2775+
if n.Right.Op == OTARRAY && n.Right.Left != nil && n.Right.Left.Op == ODDD {
2776+
n.Right.Right = typecheck(n.Right.Right, ctxType)
2777+
if n.Right.Right.Type == nil {
2778+
n.Type = nil
2779+
return n
2780+
}
2781+
elemType := n.Right.Right.Type
2782+
2783+
length := typecheckarraylit(elemType, -1, n.List.Slice())
2784+
2785+
n.Op = OARRAYLIT
2786+
n.Type = types.NewArray(elemType, length)
2787+
n.Right = nil
2788+
return n
2789+
}
2790+
2791+
n.Right = typecheck(n.Right, ctxType)
2792+
t := n.Right.Type
27862793
if t == nil {
27872794
n.Type = nil
27882795
return n
27892796
}
2790-
nerr := nerrors
27912797
n.Type = t
27922798

27932799
switch t.Etype {
@@ -2796,12 +2802,7 @@ func typecheckcomplit(n *Node) (res *Node) {
27962802
n.Type = nil
27972803

27982804
case TARRAY:
2799-
if t.IsDDDArray() {
2800-
length := typecheckarraylit(t.Elem(), -1, n.List.Slice())
2801-
t.SetNumElem(length)
2802-
} else {
2803-
typecheckarraylit(t.Elem(), t.NumElem(), n.List.Slice())
2804-
}
2805+
typecheckarraylit(t.Elem(), t.NumElem(), n.List.Slice())
28052806
n.Op = OARRAYLIT
28062807
n.Right = nil
28072808

@@ -2954,11 +2955,6 @@ func typecheckcomplit(n *Node) (res *Node) {
29542955
n.Right = nil
29552956
}
29562957

2957-
if nerr != nerrors {
2958-
return n
2959-
}
2960-
2961-
n.Orig = norig
29622958
return n
29632959
}
29642960

src/cmd/compile/internal/types/type.go

Lines changed: 1 addition & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -495,14 +495,6 @@ func NewSlice(elem *Type) *Type {
495495
return t
496496
}
497497

498-
// NewDDDArray returns a new [...]T array Type.
499-
func NewDDDArray(elem *Type) *Type {
500-
t := New(TARRAY)
501-
t.Extra = &Array{Elem: elem, Bound: -1}
502-
t.SetNotInHeap(elem.NotInHeap())
503-
return t
504-
}
505-
506498
// NewChan returns a new chan Type with direction dir.
507499
func NewChan(elem *Type, dir ChanDir) *Type {
508500
t := New(TCHAN)
@@ -882,13 +874,6 @@ func (t *Type) SetInterface(methods []*Field) {
882874
t.Methods().Set(methods)
883875
}
884876

885-
func (t *Type) IsDDDArray() bool {
886-
if t.Etype != TARRAY {
887-
return false
888-
}
889-
return t.Extra.(*Array).Bound < 0
890-
}
891-
892877
func (t *Type) WidthCalculated() bool {
893878
return t.Align > 0
894879
}
@@ -1325,23 +1310,7 @@ func (t *Type) FieldName(i int) string {
13251310

13261311
func (t *Type) NumElem() int64 {
13271312
t.wantEtype(TARRAY)
1328-
at := t.Extra.(*Array)
1329-
if at.Bound < 0 {
1330-
Fatalf("NumElem array %v does not have bound yet", t)
1331-
}
1332-
return at.Bound
1333-
}
1334-
1335-
// SetNumElem sets the number of elements in an array type.
1336-
// The only allowed use is on array types created with NewDDDArray.
1337-
// For other uses, create a new array with NewArray instead.
1338-
func (t *Type) SetNumElem(n int64) {
1339-
t.wantEtype(TARRAY)
1340-
at := t.Extra.(*Array)
1341-
if at.Bound >= 0 {
1342-
Fatalf("SetNumElem array %v already has bound %d", t, at.Bound)
1343-
}
1344-
at.Bound = n
1313+
return t.Extra.(*Array).Bound
13451314
}
13461315

13471316
type componentsIncludeBlankFields bool

0 commit comments

Comments
 (0)