@@ -229,8 +229,14 @@ object Parsers {
229229 if Feature .ccEnabled then
230230 val lookahead = in.LookaheadScanner ()
231231 lookahead.nextToken()
232- val res = lookahead.isIdent(nme.cap) && lookahead.lookahead.token == TYPE
233- res
232+ lookahead.isIdent(nme.cap) && lookahead.lookahead.token == TYPE
233+ else false
234+ }
235+ def isCapAssignmentNext = {
236+ if isCapKw then
237+ val lookahead = in.LookaheadScanner ()
238+ lookahead.nextToken()
239+ lookahead.isIdent && lookahead.lookahead.token == EQUALS
234240 else false
235241 }
236242 def isSimpleLiteral =
@@ -1614,7 +1620,7 @@ object Parsers {
16141620 case _ => None
16151621 }
16161622
1617- /** CaptureRef ::= { SimpleRef `.` } SimpleRef [`*`]
1623+ /** CaptureRef ::= { SimpleRef `.` } SimpleRef [`*`] [`.` rd]
16181624 * | [ { SimpleRef `.` } SimpleRef `.` ] id
16191625 */
16201626 def captureRef (): Tree =
@@ -1894,7 +1900,7 @@ object Parsers {
18941900 if in.token == LPAREN then funParamClause() :: funParamClauses() else Nil
18951901
18961902 /** InfixType ::= RefinedType {id [nl] RefinedType}
1897- * | RefinedType `^` // under capture checking
1903+ * | RefinedType `^` -- under captureChecking
18981904 */
18991905 def infixType (inContextBound : Boolean = false ): Tree = infixTypeRest(inContextBound)(refinedType())
19001906
@@ -2182,44 +2188,47 @@ object Parsers {
21822188 atSpan(startOffset(t), startOffset(id)) { Select (t, id.name) }
21832189 }
21842190
2185- /** ArgTypes ::= Type {`,' Type}
2186- * | NamedTypeArg {`,' NamedTypeArg}
2187- * NamedTypeArg ::= id `=' Type
2191+ /** ArgTypes ::= TypeArg {‘,’ TypeArg}
2192+ * | NamedTypeArg {‘,’ NamedTypeArg}
2193+ * TypeArg ::= Type
2194+ * | CaptureSet -- under captureChecking
2195+ * NamedTypeArg ::= id ‘=’ Type
2196+ * | ‘cap’ id ‘=’ CaptureSet -- under captureChecking
21882197 * NamesAndTypes ::= NameAndType {‘,’ NameAndType}
2189- * NameAndType ::= id ':' Type
2198+ * NameAndType ::= id ‘:’ Type
21902199 */
2191- def argTypes (namedOK : Boolean , wildOK : Boolean , tupleOK : Boolean ): List [Tree ] = // TODO grammar doc
2200+ def argTypes (namedOK : Boolean , wildOK : Boolean , tupleOK : Boolean ): List [Tree ] =
21922201 inline def wildCardCheck (inline gen : Tree ): Tree =
21932202 val t = gen
21942203 if wildOK then t else rejectWildcardType(t)
21952204
2196- def argType () = wildCardCheck :
2197- typ()
2205+ def argType () = wildCardCheck(typ())
21982206
2199- def argOrCapType () = wildCardCheck :
2207+ def typeArg () = wildCardCheck :
22002208 if Feature .ccEnabled && in.token == LBRACE && ! isDclIntroNext && ! isCapTypeKwNext then // is this a capture set and not a refinement type?
22012209 // This case is ambiguous w.r.t. an Object literal {}. But since CC is enabled, we probably expect it to designate the empty set
22022210 concreteCapsType(captureSet())
22032211 else typ()
22042212
2205- def namedArgType () =
2213+ def namedTypeArg () =
22062214 atSpan(in.offset):
2215+ val isCap = if isCapKw then { in.nextToken(); true } else false
22072216 val name = ident()
22082217 accept(EQUALS )
2209- NamedArg (name.toTypeName, argType())
2218+ NamedArg (name.toTypeName, if isCap then concreteCapsType(captureSet()) else argType())
22102219
2211- def namedElem () =
2220+ def nameAndType () =
22122221 atSpan(in.offset):
22132222 val name = ident()
22142223 acceptColon()
2215- NamedArg (name, argType()) // TODO allow capsets here?
2224+ NamedArg (name, argType())
22162225
2217- if namedOK && isIdent && in.lookahead.token == EQUALS then // TOOD support for named cap args
2218- commaSeparated(() => namedArgType ())
2226+ if namedOK && ( isIdent && in.lookahead.token == EQUALS || isCapAssignmentNext) then
2227+ commaSeparated(() => namedTypeArg ())
22192228 else if tupleOK && isIdent && in.lookahead.isColon && sourceVersion.enablesNamedTuples then
2220- commaSeparated(() => namedElem ())
2229+ commaSeparated(() => nameAndType ())
22212230 else
2222- commaSeparated(() => argOrCapType ())
2231+ commaSeparated(() => typeArg ())
22232232 end argTypes
22242233
22252234 def paramTypeOf (core : () => Tree ): Tree =
@@ -3439,7 +3448,7 @@ object Parsers {
34393448 * | opaque
34403449 * LocalModifier ::= abstract | final | sealed | open | implicit | lazy | erased |
34413450 * inline | transparent | infix |
3442- * mut | cap -- under cc
3451+ * mut | cap -- under captureChecking
34433452 */
34443453 def modifiers (allowed : BitSet = modifierTokens, start : Modifiers = Modifiers ()): Modifiers = {
34453454 @ tailrec
@@ -3529,20 +3538,24 @@ object Parsers {
35293538 end typeOrTermParamClauses
35303539
35313540 /** ClsTypeParamClause::= ‘[’ ClsTypeParam {‘,’ ClsTypeParam} ‘]’
3532- * ClsTypeParam ::= {Annotation} [‘+’ | ‘-’]
3533- * id [HkTypeParamClause] TypeAndCtxBounds
3541+ * ClsTypeParam ::= {Annotation} [‘+’ | ‘-’]
3542+ * id [HkTypeParamClause] TypeAndCtxBounds
3543+ * | {Annotation} ‘cap’ id CaptureSetAndCtxBounds -- under captureChecking
35343544 *
35353545 * DefTypeParamClause::= ‘[’ DefTypeParam {‘,’ DefTypeParam} ‘]’
3536- * DefTypeParam ::= {Annotation}
3537- * id [HkTypeParamClause] TypeAndCtxBounds
3546+ * DefTypeParam ::= {Annotation}
3547+ * id [HkTypeParamClause] TypeAndCtxBounds
3548+ * | {Annotation} ‘cap’ id CaptureSetAndCtxBounds -- under captureChecking
35383549 *
35393550 * TypTypeParamClause::= ‘[’ TypTypeParam {‘,’ TypTypeParam} ‘]’
3540- * TypTypeParam ::= {Annotation}
3541- * (id | ‘_’) [HkTypeParamClause] TypeAndCtxBounds
3551+ * TypTypeParam ::= {Annotation}
3552+ * (id | ‘_’) [HkTypeParamClause] TypeAndCtxBounds
3553+ * | {Annotation} ‘cap’ (id | ‘_’) CaptureSetAndCtxBounds -- under captureChecking
35423554 *
35433555 * HkTypeParamClause ::= ‘[’ HkTypeParam {‘,’ HkTypeParam} ‘]’
3544- * HkTypeParam ::= {Annotation} [‘+’ | ‘-’]
3545- * (id | ‘_’) [HkTypePamClause] TypeBounds
3556+ * HkTypeParam ::= {Annotation} [‘+’ | ‘-’]
3557+ * (id | ‘_’) [HkTypePamClause] TypeBounds
3558+ * | {Annotation} ‘cap’ (id | ‘_’) CaptureSetBounds -- under captureChecking
35463559 */
35473560 def typeParamClause (paramOwner : ParamOwner ): List [TypeDef ] = inBracketsWithCommas {
35483561
@@ -3571,7 +3584,7 @@ object Parsers {
35713584 capParam(start, mods)
35723585 else typeParam(start, mods)
35733586
3574- def capParam (startOffset : Int , mods0 : Modifiers ): TypeDef = { // TODO grammar doc
3587+ def capParam (startOffset : Int , mods0 : Modifiers ): TypeDef = {
35753588 val start = startOffset
35763589 var mods = mods0
35773590 if paramOwner.isClass then
@@ -3964,7 +3977,7 @@ object Parsers {
39643977 * | var VarDef
39653978 * | def DefDef
39663979 * | type {nl} TypeDef
3967- * | cap type {nl} CapDef -- under capture checking
3980+ * | cap type {nl} CapDef -- under captureChecking
39683981 * | TmplDef
39693982 * EnumCase ::= `case' (id ClassConstr [`extends' ConstrApps]] | ids)
39703983 */
@@ -4198,7 +4211,7 @@ object Parsers {
41984211 private def concreteCapsType (refs : List [Tree ]): Tree =
41994212 makeRetaining(Select (scalaDot(nme.caps), tpnme.CapSet ), refs, tpnme.retains)
42004213
4201- /** CapDef ::= id CaptureSetAndCtxBounds [‘=’ CaptureSetOrRef] -- under capture checking
4214+ /** CapDef ::= id CaptureSetAndCtxBounds [‘=’ CaptureSetOrRef] -- under captureChecking
42024215 */
42034216 def capDefOrDcl (start : Offset , mods : Modifiers ): Tree =
42044217 newLinesOpt()
@@ -4825,7 +4838,7 @@ object Parsers {
48254838 * | ‘var’ VarDef
48264839 * | ‘def’ DefDef
48274840 * | ‘type’ {nl} TypeDef
4828- * | ‘cap’ ‘type’ {nl} CapDef -- under capture checking
4841+ * | ‘cap’ ‘type’ {nl} CapDef -- under captureChecking
48294842 * (in reality we admit class defs and vars and filter them out afterwards in `checkLegal`)
48304843 */
48314844 def refineStatSeq (): List [Tree ] = {
0 commit comments