Skip to content

Commit c41113d

Browse files
committed
Support for cap arguments
1 parent 887799e commit c41113d

File tree

2 files changed

+45
-3
lines changed

2 files changed

+45
-3
lines changed

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

+36-2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import dotty.tools.dotc.config.MigrationVersion
3737
import dotty.tools.dotc.util.chaining.*
3838
import dotty.tools.dotc.config.Feature.ccEnabled
3939
import dotty.tools.dotc.core.Types.AndType.make
40+
import dotty.tools.dotc.config.Printers.capt
4041

4142
object Parsers {
4243

@@ -2109,7 +2110,7 @@ object Parsers {
21092110
case HASH => simpleTypeRest(typeProjection(t))
21102111
case LBRACKET => simpleTypeRest(atSpan(startOffset(t)) {
21112112
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)
21132114

21142115
if (!ctx.settings.XkindProjector.isDefault) {
21152116
def fail(): Tree = {
@@ -2197,6 +2198,31 @@ object Parsers {
21972198
commaSeparated(() => argType())
21982199
end argTypes
21992200

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+
22002226
def paramTypeOf(core: () => Tree): Tree =
22012227
if in.token == ARROW || isPureArrow(nme.PUREARROW) then
22022228
val isImpure = in.token == ARROW
@@ -2244,6 +2270,11 @@ object Parsers {
22442270
def typeArgs(namedOK: Boolean, wildOK: Boolean): List[Tree] =
22452271
inBracketsWithCommas(argTypes(namedOK, wildOK, tupleOK = false))
22462272

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+
22472278
/** Refinement ::= `{' RefineStatSeq `}'
22482279
*/
22492280
def refinement(indentOK: Boolean): List[Tree] =
@@ -2823,7 +2854,10 @@ object Parsers {
28232854
in.nextToken()
28242855
simpleExprRest(selectorOrMatch(t), location, canApply = true)
28252856
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+
}
28272861
simpleExprRest(tapp, location, canApply = true)
28282862
case LPAREN | LBRACE | INDENT if canApply =>
28292863
val app = atSpan(startOffset(t), in.offset) { mkApply(t, argumentExprs()) }

tests/pos-custom-args/captures/cap-paramlists.scala

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import language.experimental.captureChecking
2+
import language.experimental.namedTypeArguments
23

34
trait Ctx[T]
45

@@ -30,4 +31,11 @@ def test =
3031
trait Foo[cap U,V,W]:
3132
cap C = caps.cap
3233
cap D = {caps.cap}
33-
cap E >: {V,W} <: U
34+
cap E >: {V,W} <: U
35+
36+
def test2 =
37+
val x: Any^ = ???
38+
def foo[cap A, B >: A](x: Int) = 1
39+
foo[cap x, x](0)
40+
foo[cap A = x, B = {x}](0)
41+
foo[cap A = {x}](0)

0 commit comments

Comments
 (0)