@@ -872,7 +872,7 @@ func (p *parser) parseParamDecl(name *ast.Ident, typeSetsOK bool) (f field) {
872
872
return
873
873
}
874
874
875
- func (p * parser ) parseParameterList (name0 * ast.Ident , typ0 ast.Expr , closing token.Token ) (params []* ast.Field ) {
875
+ func (p * parser ) parseParameterList (name0 * ast.Ident , typ0 ast.Expr , closing token.Token , dddok bool ) (params []* ast.Field ) {
876
876
if p .trace {
877
877
defer un (trace (p , "ParameterList" ))
878
878
}
@@ -1006,6 +1006,26 @@ func (p *parser) parseParameterList(name0 *ast.Ident, typ0 ast.Expr, closing tok
1006
1006
}
1007
1007
}
1008
1008
1009
+ // check use of ...
1010
+ first := true // only report first occurrence
1011
+ for i , _ := range list {
1012
+ f := & list [i ]
1013
+ if t , _ := f .typ .(* ast.Ellipsis ); t != nil && (! dddok || i + 1 < len (list )) {
1014
+ if first {
1015
+ first = false
1016
+ if dddok {
1017
+ p .error (t .Ellipsis , "can only use ... with final parameter" )
1018
+ } else {
1019
+ p .error (t .Ellipsis , "invalid use of ..." )
1020
+ }
1021
+ }
1022
+ // use T instead of invalid ...T
1023
+ // TODO(gri) would like to use `f.typ = t.Elt` but that causes problems
1024
+ // with the resolver in cases of reuse of the same identifier
1025
+ f .typ = & ast.BadExpr {From : t .Pos (), To : t .End ()}
1026
+ }
1027
+ }
1028
+
1009
1029
// Convert list to []*ast.Field.
1010
1030
// If list contains types only, each type gets its own ast.Field.
1011
1031
if named == 0 {
@@ -1050,7 +1070,7 @@ func (p *parser) parseTypeParameters() *ast.FieldList {
1050
1070
lbrack := p .expect (token .LBRACK )
1051
1071
var list []* ast.Field
1052
1072
if p .tok != token .RBRACK {
1053
- list = p .parseParameterList (nil , nil , token .RBRACK )
1073
+ list = p .parseParameterList (nil , nil , token .RBRACK , false )
1054
1074
}
1055
1075
rbrack := p .expect (token .RBRACK )
1056
1076
@@ -1062,32 +1082,22 @@ func (p *parser) parseTypeParameters() *ast.FieldList {
1062
1082
return & ast.FieldList {Opening : lbrack , List : list , Closing : rbrack }
1063
1083
}
1064
1084
1065
- func (p * parser ) parseParameters () * ast.FieldList {
1085
+ func (p * parser ) parseParameters (result bool ) * ast.FieldList {
1066
1086
if p .trace {
1067
1087
defer un (trace (p , "Parameters" ))
1068
1088
}
1069
1089
1070
- lparen := p .expect (token .LPAREN )
1071
- var list []* ast.Field
1072
- if p .tok != token .RPAREN {
1073
- list = p .parseParameterList (nil , nil , token .RPAREN )
1074
- }
1075
- rparen := p .expect (token .RPAREN )
1076
-
1077
- return & ast.FieldList {Opening : lparen , List : list , Closing : rparen }
1078
- }
1079
-
1080
- func (p * parser ) parseResult () * ast.FieldList {
1081
- if p .trace {
1082
- defer un (trace (p , "Result" ))
1083
- }
1084
-
1085
- if p .tok == token .LPAREN {
1086
- return p .parseParameters ()
1090
+ if ! result || p .tok == token .LPAREN {
1091
+ lparen := p .expect (token .LPAREN )
1092
+ var list []* ast.Field
1093
+ if p .tok != token .RPAREN {
1094
+ list = p .parseParameterList (nil , nil , token .RPAREN , ! result )
1095
+ }
1096
+ rparen := p .expect (token .RPAREN )
1097
+ return & ast.FieldList {Opening : lparen , List : list , Closing : rparen }
1087
1098
}
1088
1099
1089
- typ := p .tryIdentOrType ()
1090
- if typ != nil {
1100
+ if typ := p .tryIdentOrType (); typ != nil {
1091
1101
list := make ([]* ast.Field , 1 )
1092
1102
list [0 ] = & ast.Field {Type : typ }
1093
1103
return & ast.FieldList {List : list }
@@ -1109,8 +1119,8 @@ func (p *parser) parseFuncType() *ast.FuncType {
1109
1119
p .error (tparams .Opening , "function type must have no type parameters" )
1110
1120
}
1111
1121
}
1112
- params := p .parseParameters ()
1113
- results := p .parseResult ( )
1122
+ params := p .parseParameters (false )
1123
+ results := p .parseParameters ( true )
1114
1124
1115
1125
return & ast.FuncType {Func : pos , Params : params , Results : results }
1116
1126
}
@@ -1138,13 +1148,13 @@ func (p *parser) parseMethodSpec() *ast.Field {
1138
1148
//
1139
1149
// Interface methods do not have type parameters. We parse them for a
1140
1150
// better error message and improved error recovery.
1141
- _ = p .parseParameterList (name0 , nil , token .RBRACK )
1151
+ _ = p .parseParameterList (name0 , nil , token .RBRACK , false )
1142
1152
_ = p .expect (token .RBRACK )
1143
1153
p .error (lbrack , "interface method must have no type parameters" )
1144
1154
1145
1155
// TODO(rfindley) refactor to share code with parseFuncType.
1146
- params := p .parseParameters ()
1147
- results := p .parseResult ( )
1156
+ params := p .parseParameters (false )
1157
+ results := p .parseParameters ( true )
1148
1158
idents = []* ast.Ident {ident }
1149
1159
typ = & ast.FuncType {
1150
1160
Func : token .NoPos ,
@@ -1173,8 +1183,8 @@ func (p *parser) parseMethodSpec() *ast.Field {
1173
1183
case p .tok == token .LPAREN :
1174
1184
// ordinary method
1175
1185
// TODO(rfindley) refactor to share code with parseFuncType.
1176
- params := p .parseParameters ()
1177
- results := p .parseResult ( )
1186
+ params := p .parseParameters (false )
1187
+ results := p .parseParameters ( true )
1178
1188
idents = []* ast.Ident {ident }
1179
1189
typ = & ast.FuncType {Func : token .NoPos , Params : params , Results : results }
1180
1190
default :
@@ -2578,7 +2588,7 @@ func (p *parser) parseGenericType(spec *ast.TypeSpec, openPos token.Pos, name0 *
2578
2588
defer un (trace (p , "parseGenericType" ))
2579
2589
}
2580
2590
2581
- list := p .parseParameterList (name0 , typ0 , token .RBRACK )
2591
+ list := p .parseParameterList (name0 , typ0 , token .RBRACK , false )
2582
2592
closePos := p .expect (token .RBRACK )
2583
2593
spec .TypeParams = & ast.FieldList {Opening : openPos , List : list , Closing : closePos }
2584
2594
if p .tok == token .ASSIGN {
@@ -2775,7 +2785,7 @@ func (p *parser) parseFuncDecl() *ast.FuncDecl {
2775
2785
2776
2786
var recv * ast.FieldList
2777
2787
if p .tok == token .LPAREN {
2778
- recv = p .parseParameters ()
2788
+ recv = p .parseParameters (false )
2779
2789
}
2780
2790
2781
2791
ident := p .parseIdent ()
@@ -2790,8 +2800,8 @@ func (p *parser) parseFuncDecl() *ast.FuncDecl {
2790
2800
tparams = nil
2791
2801
}
2792
2802
}
2793
- params := p .parseParameters ()
2794
- results := p .parseResult ( )
2803
+ params := p .parseParameters (false )
2804
+ results := p .parseParameters ( true )
2795
2805
2796
2806
var body * ast.BlockStmt
2797
2807
switch p .tok {
0 commit comments