@@ -37,6 +37,7 @@ import dotty.tools.dotc.config.MigrationVersion
37
37
import dotty .tools .dotc .util .chaining .*
38
38
import dotty .tools .dotc .config .Feature .ccEnabled
39
39
import dotty .tools .dotc .core .Types .AndType .make
40
+ import dotty .tools .dotc .config .Printers .capt
40
41
41
42
object Parsers {
42
43
@@ -2109,7 +2110,7 @@ object Parsers {
2109
2110
case HASH => simpleTypeRest(typeProjection(t))
2110
2111
case LBRACKET => simpleTypeRest(atSpan(startOffset(t)) {
2111
2112
val applied = rejectWildcardType(t)
2112
- val args = typeArgs(namedOK = false , wildOK = true )
2113
+ val args = if isCapKwNext then captureArgs(namedOK = false , wildOK = false ) else typeArgs(namedOK = false , wildOK = true )
2113
2114
2114
2115
if (! ctx.settings.XkindProjector .isDefault) {
2115
2116
def fail (): Tree = {
@@ -2197,6 +2198,31 @@ object Parsers {
2197
2198
commaSeparated(() => argType())
2198
2199
end argTypes
2199
2200
2201
+ def argCaps (namedOK : Boolean , wildOK : Boolean , tupleOK : Boolean ): List [Tree ] = // TODO grammar doc
2202
+ def argType () =
2203
+ val t = concreteCapsType(captureSetOrRef())
2204
+ if wildOK then t else rejectWildcardType(t) // TODO needed?
2205
+
2206
+ def namedArgType () =
2207
+ atSpan(in.offset):
2208
+ val name = ident()
2209
+ accept(EQUALS )
2210
+ NamedArg (name.toTypeName, argType())
2211
+
2212
+ def namedElem () =
2213
+ atSpan(in.offset):
2214
+ val name = ident()
2215
+ acceptColon()
2216
+ NamedArg (name, argType())
2217
+
2218
+ if namedOK && isIdent && in.lookahead.token == EQUALS then
2219
+ commaSeparated(() => namedArgType())
2220
+ else if tupleOK && isIdent && in.lookahead.isColon && sourceVersion.enablesNamedTuples then
2221
+ commaSeparated(() => namedElem())
2222
+ else
2223
+ commaSeparated(() => argType())
2224
+ end argCaps
2225
+
2200
2226
def paramTypeOf (core : () => Tree ): Tree =
2201
2227
if in.token == ARROW || isPureArrow(nme.PUREARROW ) then
2202
2228
val isImpure = in.token == ARROW
@@ -2244,6 +2270,11 @@ object Parsers {
2244
2270
def typeArgs (namedOK : Boolean , wildOK : Boolean ): List [Tree ] =
2245
2271
inBracketsWithCommas(argTypes(namedOK, wildOK, tupleOK = false ))
2246
2272
2273
+ def captureArgs (namedOK : Boolean , wildOK : Boolean ): List [Tree ] = inBracketsWithCommas {
2274
+ in.nextToken() // assumes we are the `cap` soft keyword
2275
+ argCaps(namedOK, wildOK, tupleOK = false ) // TODO grammar doc
2276
+ }
2277
+
2247
2278
/** Refinement ::= `{' RefineStatSeq `}'
2248
2279
*/
2249
2280
def refinement (indentOK : Boolean ): List [Tree ] =
@@ -2823,7 +2854,10 @@ object Parsers {
2823
2854
in.nextToken()
2824
2855
simpleExprRest(selectorOrMatch(t), location, canApply = true )
2825
2856
case LBRACKET =>
2826
- val tapp = atSpan(startOffset(t), in.offset) { TypeApply (t, typeArgs(namedOK = true , wildOK = false )) }
2857
+ val tapp = atSpan(startOffset(t), in.offset) {
2858
+ val args = if isCapKwNext then captureArgs(namedOK = true , wildOK = false ) else typeArgs(namedOK = true , wildOK = false )
2859
+ TypeApply (t, args)
2860
+ }
2827
2861
simpleExprRest(tapp, location, canApply = true )
2828
2862
case LPAREN | LBRACE | INDENT if canApply =>
2829
2863
val app = atSpan(startOffset(t), in.offset) { mkApply(t, argumentExprs()) }
0 commit comments