@@ -588,44 +588,81 @@ func (p *parser) typeDecl(group *Group) Decl {
588
588
d .Name = p .name ()
589
589
if p .allowGenerics () && p .tok == _Lbrack {
590
590
// d.Name "[" ...
591
- // array/slice or type parameter list
591
+ // array/slice type or type parameter list
592
592
pos := p .pos ()
593
593
p .next ()
594
594
switch p .tok {
595
595
case _Name :
596
- // d.Name "[" name ...
597
- // array or type parameter list
598
- name := p .name ()
599
- // Index or slice expressions are never constant and thus invalid
600
- // array length expressions. Thus, if we see a "[" following name
601
- // we can safely assume that "[" name starts a type parameter list.
602
- var x Expr // x != nil means x is the array length expression
596
+ // We may have an array type or a type parameter list.
597
+ // In either case we expect an expression x (which may
598
+ // just be a name, or a more complex expression) which
599
+ // we can analyze further.
600
+ //
601
+ // A type parameter list may have a type bound starting
602
+ // with a "[" as in: P []E. In that case, simply parsing
603
+ // an expression would lead to an error: P[] is invalid.
604
+ // But since index or slice expressions are never constant
605
+ // and thus invalid array length expressions, if we see a
606
+ // "[" following a name it must be the start of an array
607
+ // or slice constraint. Only if we don't see a "[" do we
608
+ // need to parse a full expression.
609
+ var x Expr = p .name ()
603
610
if p .tok != _Lbrack {
604
- // d.Name "[" name ...
605
- // If we reach here, the next token is not a "[", and we need to
606
- // parse the expression starting with name. If that expression is
607
- // just that name, not followed by a "]" (in which case we might
608
- // have the array length "[" name "]"), we can also safely assume
609
- // a type parameter list.
611
+ // To parse the expression starting with name, expand
612
+ // the call sequence we would get by passing in name
613
+ // to parser.expr, and pass in name to parser.pexpr.
610
614
p .xnest ++
611
- // To parse the expression starting with name, expand the call
612
- // sequence we would get by passing in name to parser.expr, and
613
- // pass in name to parser.pexpr.
614
- x = p .binaryExpr (p .pexpr (name , false ), 0 )
615
+ x = p .binaryExpr (p .pexpr (x , false ), 0 )
615
616
p .xnest --
616
- if x == name && p .tok != _Rbrack {
617
- x = nil
617
+ }
618
+
619
+ // analyze the cases
620
+ var pname * Name // pname != nil means pname is the type parameter name
621
+ var ptype Expr // ptype != nil means ptype is the type parameter type; pname != nil in this case
622
+ switch t := x .(type ) {
623
+ case * Name :
624
+ // Unless we see a "]", we are at the start of a type parameter list.
625
+ if p .tok != _Rbrack {
626
+ // d.Name "[" name ...
627
+ pname = t
628
+ // no ptype
629
+ }
630
+ case * Operation :
631
+ // If we have an expression of the form name*T, and T is a (possibly
632
+ // parenthesized) type literal or the next token is a comma, we are
633
+ // at the start of a type parameter list.
634
+ if name , _ := t .X .(* Name ); name != nil {
635
+ if t .Op == Mul && (isTypeLit (t .Y ) || p .tok == _Comma ) {
636
+ // d.Name "[" name "*" t.Y
637
+ // d.Name "[" name "*" t.Y ","
638
+ t .X , t .Y = t .Y , nil // convert t into unary *t.Y
639
+ pname = name
640
+ ptype = t
641
+ }
642
+ }
643
+ case * CallExpr :
644
+ // If we have an expression of the form name(T), and T is a (possibly
645
+ // parenthesized) type literal or the next token is a comma, we are
646
+ // at the start of a type parameter list.
647
+ if name , _ := t .Fun .(* Name ); name != nil {
648
+ if len (t .ArgList ) == 1 && ! t .HasDots && (isTypeLit (t .ArgList [0 ]) || p .tok == _Comma ) {
649
+ // d.Name "[" name "(" t.ArgList[0] ")"
650
+ // d.Name "[" name "(" t.ArgList[0] ")" ","
651
+ pname = name
652
+ ptype = t .ArgList [0 ]
653
+ }
618
654
}
619
655
}
620
- if x == nil {
621
- // d.Name "[" name ...
622
- // type parameter list
623
- d .TParamList = p .paramList (name , _Rbrack , true )
656
+
657
+ if pname != nil {
658
+ // d.Name "[" pname ...
659
+ // d.Name "[" pname ptype ...
660
+ // d.Name "[" pname ptype "," ...
661
+ d .TParamList = p .paramList (pname , ptype , _Rbrack , true )
624
662
d .Alias = p .gotAssign ()
625
663
d .Type = p .typeOrNil ()
626
664
} else {
627
- // d.Name "[" x "]" ...
628
- // x is the array length expression
665
+ // d.Name "[" x ...
629
666
d .Type = p .arrayType (pos , x )
630
667
}
631
668
case _Rbrack :
@@ -650,6 +687,21 @@ func (p *parser) typeDecl(group *Group) Decl {
650
687
return d
651
688
}
652
689
690
+ // isTypeLit reports whether x is a (possibly parenthesized) type literal.
691
+ func isTypeLit (x Expr ) bool {
692
+ switch x := x .(type ) {
693
+ case * ArrayType , * StructType , * FuncType , * InterfaceType , * SliceType , * MapType , * ChanType :
694
+ return true
695
+ case * Operation :
696
+ // *T may be a pointer dereferenciation.
697
+ // Only consider *T as type literal if T is a type literal.
698
+ return x .Op == Mul && x .Y == nil && isTypeLit (x .X )
699
+ case * ParenExpr :
700
+ return isTypeLit (x .X )
701
+ }
702
+ return false
703
+ }
704
+
653
705
// VarSpec = IdentifierList ( Type [ "=" ExpressionList ] | "=" ExpressionList ) .
654
706
func (p * parser ) varDecl (group * Group ) Decl {
655
707
if trace {
@@ -689,7 +741,7 @@ func (p *parser) funcDeclOrNil() *FuncDecl {
689
741
f .Pragma = p .takePragma ()
690
742
691
743
if p .got (_Lparen ) {
692
- rcvr := p .paramList (nil , _Rparen , false )
744
+ rcvr := p .paramList (nil , nil , _Rparen , false )
693
745
switch len (rcvr ) {
694
746
case 0 :
695
747
p .error ("method has no receiver" )
@@ -1369,12 +1421,12 @@ func (p *parser) funcType(context string) ([]*Field, *FuncType) {
1369
1421
p .syntaxError ("empty type parameter list" )
1370
1422
p .next ()
1371
1423
} else {
1372
- tparamList = p .paramList (nil , _Rbrack , true )
1424
+ tparamList = p .paramList (nil , nil , _Rbrack , true )
1373
1425
}
1374
1426
}
1375
1427
1376
1428
p .want (_Lparen )
1377
- typ .ParamList = p .paramList (nil , _Rparen , false )
1429
+ typ .ParamList = p .paramList (nil , nil , _Rparen , false )
1378
1430
typ .ResultList = p .funcResult ()
1379
1431
1380
1432
return tparamList , typ
@@ -1392,6 +1444,13 @@ func (p *parser) arrayType(pos Pos, len Expr) Expr {
1392
1444
len = p .expr ()
1393
1445
p .xnest --
1394
1446
}
1447
+ if p .tok == _Comma {
1448
+ // Trailing commas are accepted in type parameter
1449
+ // lists but not in array type declarations.
1450
+ // Accept for better error handling but complain.
1451
+ p .syntaxError ("unexpected comma; expecting ]" )
1452
+ p .next ()
1453
+ }
1395
1454
p .want (_Rbrack )
1396
1455
t := new (ArrayType )
1397
1456
t .pos = pos
@@ -1516,7 +1575,7 @@ func (p *parser) funcResult() []*Field {
1516
1575
}
1517
1576
1518
1577
if p .got (_Lparen ) {
1519
- return p .paramList (nil , _Rparen , false )
1578
+ return p .paramList (nil , nil , _Rparen , false )
1520
1579
}
1521
1580
1522
1581
pos := p .pos ()
@@ -1742,7 +1801,7 @@ func (p *parser) methodDecl() *Field {
1742
1801
1743
1802
// A type argument list looks like a parameter list with only
1744
1803
// types. Parse a parameter list and decide afterwards.
1745
- list := p .paramList (nil , _Rbrack , false )
1804
+ list := p .paramList (nil , nil , _Rbrack , false )
1746
1805
if len (list ) == 0 {
1747
1806
// The type parameter list is not [] but we got nothing
1748
1807
// due to other errors (reported by paramList). Treat
@@ -1948,17 +2007,41 @@ func (p *parser) paramDeclOrNil(name *Name, follow token) *Field {
1948
2007
// ParameterList = ParameterDecl { "," ParameterDecl } .
1949
2008
// "(" or "[" has already been consumed.
1950
2009
// If name != nil, it is the first name after "(" or "[".
2010
+ // If typ != nil, name must be != nil, and (name, typ) is the first field in the list.
1951
2011
// In the result list, either all fields have a name, or no field has a name.
1952
- func (p * parser ) paramList (name * Name , close token , requireNames bool ) (list []* Field ) {
2012
+ func (p * parser ) paramList (name * Name , typ Expr , close token , requireNames bool ) (list []* Field ) {
1953
2013
if trace {
1954
2014
defer p .trace ("paramList" )()
1955
2015
}
1956
2016
2017
+ // p.list won't invoke its function argument if we're at the end of the
2018
+ // parameter list. If we have a complete field, handle this case here.
2019
+ if name != nil && typ != nil && p .tok == close {
2020
+ p .next ()
2021
+ par := new (Field )
2022
+ par .pos = name .pos
2023
+ par .Name = name
2024
+ par .Type = typ
2025
+ return []* Field {par }
2026
+ }
2027
+
1957
2028
var named int // number of parameters that have an explicit name and type
1958
2029
var typed int // number of parameters that have an explicit type
1959
2030
end := p .list (_Comma , close , func () bool {
1960
- par := p .paramDeclOrNil (name , close )
2031
+ var par * Field
2032
+ if typ != nil {
2033
+ if debug && name == nil {
2034
+ panic ("initial type provided without name" )
2035
+ }
2036
+ par = new (Field )
2037
+ par .pos = name .pos
2038
+ par .Name = name
2039
+ par .Type = typ
2040
+ } else {
2041
+ par = p .paramDeclOrNil (name , close )
2042
+ }
1961
2043
name = nil // 1st name was consumed if present
2044
+ typ = nil // 1st type was consumed if present
1962
2045
if par != nil {
1963
2046
if debug && par .Name == nil && par .Type == nil {
1964
2047
panic ("parameter without name or type" )
0 commit comments