Skip to content

Commit 594c9d6

Browse files
committed
Use with for context parameters
1 parent d95fd15 commit 594c9d6

File tree

3 files changed

+32
-22
lines changed

3 files changed

+32
-22
lines changed

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

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2797,12 +2797,12 @@ object Parsers {
27972797
tps.map(makeSyntheticParameter(nextIdx, _, paramFlags | Synthetic | Given))
27982798

27992799
/** ClsParamClause ::= ‘(’ [‘erased’] ClsParams ‘)’
2800-
* GivenClsParamClause::= ‘(’ ‘given’ [‘erased’] (ClsParams | GivenTypes) ‘)’
2800+
* GivenClsParamClause::= 'with' ‘(’ (ClsParams | GivenTypes) ‘)’
28012801
* ClsParams ::= ClsParam {‘,’ ClsParam}
28022802
* ClsParam ::= {Annotation}
28032803
*
28042804
* DefParamClause ::= ‘(’ [‘erased’] DefParams ‘)’
2805-
* GivenParamClause ::= ‘(’ ‘given’ [‘erased’] (DefParams | GivenTypes) ‘)’
2805+
* GivenParamClause ::= ‘with’ ‘(’ (DefParams | GivenTypes) ‘)’
28062806
* DefParams ::= DefParam {‘,’ DefParam}
28072807
* DefParam ::= {Annotation} [‘inline’] Param
28082808
*
@@ -2815,9 +2815,10 @@ object Parsers {
28152815
ofCaseClass: Boolean = false, // owner is a case class
28162816
prefix: Boolean = false, // clause precedes name of an extension method
28172817
givenOnly: Boolean = false, // only given parameters allowed
2818-
firstClause: Boolean = false // clause is the first in regular list of clauses
2818+
firstClause: Boolean = false, // clause is the first in regular list of clauses
2819+
prefixMods: Modifiers = EmptyModifiers // is `Given` if this is a with clause
28192820
): List[ValDef] = {
2820-
var impliedMods: Modifiers = EmptyModifiers
2821+
var impliedMods: Modifiers = prefixMods
28212822

28222823
def impliedModOpt(token: Token, mod: () => Mod): Boolean =
28232824
if in.token == token then
@@ -2900,9 +2901,10 @@ object Parsers {
29002901
}
29012902

29022903
/** ClsParamClauses ::= {ClsParamClause} [[nl] ‘(’ [‘implicit’] ClsParams ‘)’]
2903-
* | {ClsParamClause} {GivenClsParamClause}
2904+
* | {ClsParamClause | GivenClsParamClause} [‘with’ GivenTypes]
29042905
* DefParamClauses ::= {DefParamClause} [[nl] ‘(’ [‘implicit’] DefParams ‘)’]
2905-
* | {DefParamClause} {GivenParamClause}
2906+
* | {DefParamClause | GivenParamClause} [‘with’ GivenTypes]
2907+
* GivenParamClauses ::= {GivenParamClause} [‘with’ GivenTypes]
29062908
*
29072909
* @return The parameter definitions
29082910
*/
@@ -2912,18 +2914,27 @@ object Parsers {
29122914

29132915
def recur(firstClause: Boolean, nparams: Int): List[List[ValDef]] =
29142916
newLineOptWhenFollowedBy(LPAREN)
2917+
val prefixMods =
2918+
if in.token == WITH then
2919+
in.nextToken()
2920+
Modifiers(Given)
2921+
else
2922+
EmptyModifiers
29152923
if in.token == LPAREN then
29162924
val paramsStart = in.offset
29172925
val params = paramClause(
29182926
nparams,
29192927
ofClass = ofClass,
29202928
ofCaseClass = ofCaseClass,
29212929
givenOnly = givenOnly,
2922-
firstClause = firstClause)
2930+
firstClause = firstClause,
2931+
prefixMods = prefixMods)
29232932
val lastClause = params.nonEmpty && params.head.mods.flags.is(Implicit)
29242933
params :: (
29252934
if lastClause then Nil
29262935
else recur(firstClause = false, nparams + params.length))
2936+
else if prefixMods.is(Given) then
2937+
givenTypes(nparams, ofClass) :: Nil
29272938
else Nil
29282939
end recur
29292940

@@ -3421,7 +3432,7 @@ object Parsers {
34213432

34223433
/** GivenDef ::= [GivenSig] [‘_’ ‘<:’] Type ‘=’ Expr
34233434
* | [GivenSig] ConstrApps [TemplateBody]
3424-
* GivenSig ::= [id] [DefTypeParamClause] {GivenParamClause} ‘as’
3435+
* GivenSig ::= [id] [DefTypeParamClause] GivenParamClauses ‘as’
34253436
* ExtParamClause ::= [DefTypeParamClause] DefParamClause
34263437
* ExtMethods ::= [nl] ‘{’ ‘def’ DefDef {semi ‘def’ DefDef} ‘}’
34273438
*/
@@ -3453,7 +3464,7 @@ object Parsers {
34533464
val tparams = typeParamClauseOpt(ParamOwner.Def)
34543465
val paramsStart = in.offset
34553466
val vparamss =
3456-
if in.token == LPAREN && followingIsParamOrGivenType()
3467+
if in.token == WITH || in.token == LPAREN && followingIsParamOrGivenType()
34573468
then paramClauses()
34583469
else Nil
34593470
def checkAllGivens(vparamss: List[List[ValDef]], what: String) =
@@ -3496,7 +3507,7 @@ object Parsers {
34963507
finalizeDef(gdef, mods1, start)
34973508
}
34983509

3499-
/** ExtensionDef ::= [id] ‘on’ ExtParamClause {GivenParamClause} ExtMethods
3510+
/** ExtensionDef ::= [id] ‘on’ ExtParamClause GivenParamClauses ExtMethods
35003511
*/
35013512
def extensionDef(start: Offset, mods: Modifiers): ModuleDef =
35023513
in.nextToken()

docs/docs/internals/syntax.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -293,19 +293,20 @@ HkTypeParam ::= {Annotation} [‘+’ | ‘-’] (Id[HkTypeParamClause] |
293293
SubtypeBounds
294294
295295
ClsParamClauses ::= {ClsParamClause} [[nl] ‘(’ [‘implicit’] ClsParams ‘)’]
296-
| {ClsParamClause} {GivenClsParamClause}
296+
| {ClsParamClause | GivenClsParamClause} [‘with’ GivenTypes]
297297
ClsParamClause ::= [nl] ‘(’ ClsParams ‘)’
298-
GivenClsParamClause::= ‘(’ ‘given’ (ClsParams | GivenTypes) ‘)’
298+
GivenClsParamClause::= ‘with’ ‘(’ (ClsParams | GivenTypes) ‘)’
299299
ClsParams ::= ClsParam {‘,’ ClsParam}
300300
ClsParam ::= {Annotation} ValDef(mods, id, tpe, expr) -- point of mods on val/var
301301
[{Modifier} (‘val’ | ‘var’) | ‘inline’] Param
302302
Param ::= id ‘:’ ParamType [‘=’ Expr]
303303
| INT
304304
305305
DefParamClauses ::= {DefParamClause} [[nl] ‘(’ [‘implicit’] DefParams ‘)’]
306-
| {DefParamClause} {GivenParamClause}
306+
| {DefParamClause | GivenParamClause} [‘with’ GivenTypes]
307307
DefParamClause ::= [nl] ‘(’ DefParams ‘)’
308-
GivenParamClause ::= ‘(’ ‘given’ (DefParams | GivenTypes) ‘)’
308+
GivenParamClause ::= ‘with’ ‘(’ (DefParams | GivenTypes) ‘)’
309+
GivenParamClauses ::= {GivenParamClause} [‘with’ GivenTypes]
309310
DefParams ::= DefParam {‘,’ DefParam}
310311
DefParam ::= {Annotation} [‘inline’] Param ValDef(mods, id, tpe, expr) -- point of mods at id.
311312
GivenTypes ::= Type {‘,’ Type}
@@ -386,8 +387,8 @@ ObjectDef ::= id [Template]
386387
EnumDef ::= id ClassConstr InheritClauses EnumBody EnumDef(mods, name, tparams, template)
387388
GivenDef ::= [GivenSig] [‘_’ ‘<:’] Type ‘=’ Expr
388389
| [GivenSig] ConstrApps [TemplateBody]
389-
GivenSig ::= [id] [DefTypeParamClause] {GivenParamClause} ‘as’
390-
ExtensionDef ::= [id] ‘on’ ExtParamClause {GivenParamClause} ExtMethods
390+
GivenSig ::= [id] [DefTypeParamClause] GivenParamClauses ‘as’
391+
ExtensionDef ::= [id] ‘on’ ExtParamClause GivenParamClauses ExtMethods
391392
ExtMethods ::= [nl] ‘{’ ‘def’ DefDef {semi ‘def’ DefDef} ‘}’
392393
ExtParamClause ::= [DefTypeParamClause] ‘(’ DefParam ‘)’
393394
Template ::= InheritClauses [TemplateBody] Template(constr, parents, self, stats)

library/src/scala/internal/quoted/Matcher.scala

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -94,15 +94,13 @@ private[quoted] object Matcher {
9494
case _ => notMatched
9595
}
9696

97-
private given treeListOps: extension (scrutinees: List[Tree]) with
98-
97+
private given treeListOps: extension (scrutinees: List[Tree]) {
9998
/** Check that all trees match with =?= and concatenate the results with && */
10099
def =?= (patterns: List[Tree])(given Context, Env): Matching =
101100
matchLists(scrutinees, patterns)(_ =?= _)
101+
}
102102

103-
end treeListOps
104-
105-
private given treeOps: extension (scrutinee0: Tree) with
103+
private given treeOps: extension (scrutinee0: Tree) {
106104

107105
/** Check that the trees match and return the contents from the pattern holes.
108106
* Return None if the trees do not match otherwise return Some of a tuple containing all the contents in the holes.
@@ -307,7 +305,7 @@ private[quoted] object Matcher {
307305
notMatched
308306
}
309307
}
310-
end treeOps
308+
}
311309

312310
private object ClosedPatternTerm {
313311
/** Matches a term that does not contain free variables defined in the pattern (i.e. not defined in `Env`) */

0 commit comments

Comments
 (0)