@@ -194,12 +194,16 @@ object Parsers {
194194 /** Is current token a hard or soft modifier (in modifier position or not)? */
195195 def isModifier : Boolean = modifierTokens.contains(in.token) || in.isSoftModifier
196196
197- def isBindingIntro : Boolean =
198- canStartBindingTokens.contains(in.token) &&
199- ! in.isSoftModifierInModifierPosition
197+ def isBindingIntro : Boolean = {
198+ in.token match {
199+ case USCORE | LPAREN => true
200+ case IDENTIFIER | BACKQUOTED_IDENT => in.lookaheadIn(BitSet (COLON , ARROW ))
201+ case _ => false
202+ }
203+ } && ! in.isSoftModifierInModifierPosition
200204
201205 def isExprIntro : Boolean =
202- if (in.token == IMPLIED ) in.lookaheadIn(BitSet (MATCH ))
206+ if (in.token == IMPLIED || in.token == GIVEN ) in.lookaheadIn(BitSet (MATCH ))
203207 else (canStartExpressionTokens.contains(in.token) && ! in.isSoftModifierInModifierPosition)
204208
205209 def isDefIntro (allowedMods : BitSet , excludedSoftModifiers : Set [TermName ] = Set .empty): Boolean =
@@ -1274,7 +1278,7 @@ object Parsers {
12741278 * | SimpleExpr1 ArgumentExprs `=' Expr
12751279 * | Expr2
12761280 * | [‘inline’] Expr2 `match' `{' CaseClauses `}'
1277- * | `delegate ' `match' `{' ImplicitCaseClauses `}'
1281+ * | `given ' `match' `{' ImplicitCaseClauses `}'
12781282 * Bindings ::= `(' [Binding {`,' Binding}] `)'
12791283 * Binding ::= (id | `_') [`:' Type]
12801284 * Expr2 ::= PostfixExpr [Ascription]
@@ -1293,7 +1297,7 @@ object Parsers {
12931297 if (in.token == MATCH ) impliedMatch(start, imods)
12941298 else implicitClosure(start, location, imods)
12951299 }
1296- else if (in.token == IMPLIED ) {
1300+ else if (in.token == IMPLIED || in.token == GIVEN ) {
12971301 in.nextToken()
12981302 if (in.token == MATCH )
12991303 impliedMatch(start, EmptyModifiers )
@@ -1478,7 +1482,7 @@ object Parsers {
14781482 */
14791483 def impliedMatch (start : Int , imods : Modifiers ) = {
14801484 def markFirstIllegal (mods : List [Mod ]) = mods match {
1481- case mod :: _ => syntaxError(em " illegal modifier for delegate match " , mod.span)
1485+ case mod :: _ => syntaxError(em " illegal modifier for given match " , mod.span)
14821486 case _ =>
14831487 }
14841488 imods.mods match {
@@ -1493,7 +1497,7 @@ object Parsers {
14931497 case pat => isVarPattern(pat)
14941498 }
14951499 if (! isImplicitPattern(pat))
1496- syntaxError(em " not a legal pattern for a delegate match " , pat.span)
1500+ syntaxError(em " not a legal pattern for a given match " , pat.span)
14971501 }
14981502 result
14991503 }
@@ -2303,9 +2307,59 @@ object Parsers {
23032307 def paramClauses (ofClass : Boolean = false ,
23042308 ofCaseClass : Boolean = false ,
23052309 ofInstance : Boolean = false ): List [List [ValDef ]] = {
2310+
2311+ def followingIsParamClause : Boolean = {
2312+ val lookahead = in.lookaheadScanner
2313+ lookahead.nextToken()
2314+ paramIntroTokens.contains(lookahead.token) && {
2315+ lookahead.token != IDENTIFIER ||
2316+ lookahead.name == nme.inline || {
2317+ lookahead.nextToken()
2318+ lookahead.token == COLON
2319+ }
2320+ }
2321+ }
2322+
2323+ /** For given instance definitions we have a disambiguation problem:
2324+ * given A as B
2325+ * given C ...
2326+ * Is the second line a parameter `given C` for the first `given` definition, or is it
2327+ * a second `given` definition? We only know if we find a `for` or `as` in `...`
2328+ * The same problem arises for
2329+ * class A
2330+ * given C ...
2331+ * For method definitions we do not have this problem since a parameter clause
2332+ * in a method definition is always followed by something else. So in
2333+ * def m(...)
2334+ * given C ...
2335+ * we know that `given` must start a parameter list. It cannot be a new given` definition.
2336+ */
2337+ def followingIsInstanceDef =
2338+ (ofClass || ofInstance) && {
2339+ val lookahead = in.lookaheadScanner // skips newline on startup
2340+ lookahead.nextToken() // skip the `given`
2341+ if (lookahead.token == IDENTIFIER || lookahead.token == BACKQUOTED_IDENT ) {
2342+ lookahead.nextToken()
2343+ if (lookahead.token == LBRACKET ) {
2344+ lookahead.nextToken()
2345+ var openBrackets = 1
2346+ while (openBrackets > 0 && lookahead.token != EOF ) {
2347+ if (lookahead.token == LBRACKET ) openBrackets += 1
2348+ else if (lookahead.token == RBRACKET ) openBrackets -= 1
2349+ lookahead.nextToken()
2350+ }
2351+ }
2352+ }
2353+ lookahead.token == FOR ||
2354+ lookahead.token == IDENTIFIER && lookahead.name == nme.as
2355+ }
2356+
23062357 def recur (firstClause : Boolean , nparams : Int , contextualOnly : Boolean ): List [List [ValDef ]] = {
23072358 var initialMods = EmptyModifiers
2359+ val isNewLine = in.token == NEWLINE
23082360 newLineOptWhenFollowedBy(LPAREN )
2361+ if (in.token == NEWLINE && in.next.token == GIVEN && ! followingIsInstanceDef)
2362+ in.nextToken()
23092363 if (in.token == GIVEN ) {
23102364 in.nextToken()
23112365 initialMods |= Given
@@ -2314,22 +2368,10 @@ object Parsers {
23142368 in.nextToken()
23152369 initialMods |= Erased
23162370 }
2317- val isContextual = initialMods.is(Given )
2371+ val isGiven = initialMods.is(Given )
23182372 newLineOptWhenFollowedBy(LPAREN )
2319- def isParamClause : Boolean =
2320- ! isContextual || {
2321- val lookahead = in.lookaheadScanner
2322- lookahead.nextToken()
2323- paramIntroTokens.contains(lookahead.token) && {
2324- lookahead.token != IDENTIFIER ||
2325- lookahead.name == nme.inline || {
2326- lookahead.nextToken()
2327- lookahead.token == COLON
2328- }
2329- }
2330- }
2331- if (in.token == LPAREN && isParamClause) {
2332- if (contextualOnly && ! isContextual)
2373+ if (in.token == LPAREN && (! isGiven || followingIsParamClause)) {
2374+ if (contextualOnly && ! isGiven)
23332375 if (ofInstance) syntaxError(em " parameters of instance definitions must come after `given' " )
23342376 else syntaxError(em " normal parameters cannot come after `given' clauses " )
23352377 val params = paramClause(
@@ -2338,15 +2380,15 @@ object Parsers {
23382380 firstClause = firstClause,
23392381 initialMods = initialMods)
23402382 val lastClause = params.nonEmpty && params.head.mods.flags.is(Implicit )
2341- params :: (if (lastClause) Nil else recur(firstClause = false , nparams + params.length, isContextual ))
2383+ params :: (if (lastClause) Nil else recur(firstClause = false , nparams + params.length, isGiven ))
23422384 }
2343- else if (isContextual ) {
2385+ else if (isGiven ) {
23442386 val tps = commaSeparated(() => annotType())
23452387 var counter = nparams
23462388 def nextIdx = { counter += 1 ; counter }
23472389 val paramFlags = if (ofClass) Private | Local | ParamAccessor else Param
23482390 val params = tps.map(makeSyntheticParameter(nextIdx, _, paramFlags | Synthetic | Given ))
2349- params :: recur(firstClause = false , nparams + params.length, isContextual )
2391+ params :: recur(firstClause = false , nparams + params.length, isGiven )
23502392 }
23512393 else Nil
23522394 }
@@ -2360,12 +2402,12 @@ object Parsers {
23602402
23612403 type ImportConstr = (Boolean , Tree , List [Tree ]) => Tree
23622404
2363- /** Import ::= import [delegate ] [ImportExpr {`,' ImportExpr}
2364- * Export ::= export [delegate ] [ImportExpr {`,' ImportExpr}
2405+ /** Import ::= ` import' [`given' ] [ImportExpr {`,' ImportExpr}
2406+ * Export ::= ` export' [`given' ] [ImportExpr {`,' ImportExpr}
23652407 */
23662408 def importClause (leading : Token , mkTree : ImportConstr ): List [Tree ] = {
23672409 val offset = accept(leading)
2368- val importDelegate = in.token == IMPLIED
2410+ val importDelegate = in.token == IMPLIED || in.token == GIVEN
23692411 if (importDelegate) in.nextToken()
23702412 commaSeparated(importExpr(importDelegate, mkTree)) match {
23712413 case t :: rest =>
@@ -2384,15 +2426,21 @@ object Parsers {
23842426
23852427 /** ImportSelectors ::= `{' {ImportSelector `,'} FinalSelector ‘}’
23862428 * FinalSelector ::= ImportSelector
2387- * | ‘_’
2388- * | ‘for’ InfixType {‘,’ InfixType}
2429+ * | ‘_’ [‘:’ Type]
23892430 */
23902431 def importSelectors (): List [Tree ] = in.token match {
23912432 case USCORE =>
2392- wildcardIdent() :: Nil
2433+ atSpan(in.skipToken()) {
2434+ val id = Ident (nme.WILDCARD )
2435+ if (in.token == COLON ) {
2436+ in.nextToken()
2437+ TypeBoundsTree (EmptyTree , typ())
2438+ }
2439+ else id
2440+ } :: Nil
23932441 case FOR =>
23942442 if (! importDelegate)
2395- syntaxError(em " `for` qualifier only allowed in `import delegate ` " )
2443+ syntaxError(em " `for` qualifier only allowed in `import given ` " )
23962444 atSpan(in.skipToken()) {
23972445 var t = infixType()
23982446 while (in.token == COMMA ) {
@@ -2696,7 +2744,7 @@ object Parsers {
26962744 /** TmplDef ::= ([‘case’] ‘class’ | ‘trait’) ClassDef
26972745 * | [‘case’] ‘object’ ObjectDef
26982746 * | ‘enum’ EnumDef
2699- * | ‘instance’ InstanceDef
2747+ * | ‘given’ GivenDef
27002748 */
27012749 def tmplDef (start : Int , mods : Modifiers ): Tree = {
27022750 in.token match {
@@ -2712,8 +2760,8 @@ object Parsers {
27122760 objectDef(start, posMods(start, mods | Case | Module ))
27132761 case ENUM =>
27142762 enumDef(start, posMods(start, mods | Enum ))
2715- case IMPLIED =>
2716- instanceDef(start, mods, atSpan(in.skipToken()) { Mod .Delegate () })
2763+ case IMPLIED | GIVEN =>
2764+ instanceDef(in.token == GIVEN , start, mods, atSpan(in.skipToken()) { Mod .Delegate () })
27172765 case _ =>
27182766 syntaxErrorOrIncomplete(ExpectedStartOfTopLevelDefinition ())
27192767 EmptyTree
@@ -2805,17 +2853,16 @@ object Parsers {
28052853 Template (constr, parents, Nil , EmptyValDef , Nil )
28062854 }
28072855
2808- /** InstanceDef ::= [id] [DefTypeParamClause] InstanceBody
2809- * InstanceParams ::= [DefTypeParamClause] {GivenParamClause}
2810- * InstanceBody ::= [‘for’ ConstrApp {‘,’ ConstrApp }] {GivenParamClause} [TemplateBody]
2811- * | ‘for’ Type {GivenParamClause} ‘=’ Expr
2856+ /** GivenDef ::= [id] [DefTypeParamClause] GivenBody
2857+ * GivenBody ::= [‘as ConstrApp {‘,’ ConstrApp }] {GivenParamClause} [TemplateBody]
2858+ * | ‘as’ Type {GivenParamClause} ‘=’ Expr
28122859 */
2813- def instanceDef (start : Offset , mods : Modifiers , instanceMod : Mod ) = atSpan(start, nameStart) {
2860+ def instanceDef (newStyle : Boolean , start : Offset , mods : Modifiers , instanceMod : Mod ) = atSpan(start, nameStart) {
28142861 var mods1 = addMod(mods, instanceMod)
2815- val name = if (isIdent) ident() else EmptyTermName
2862+ val name = if (isIdent && ( ! newStyle || in.name != nme.as) ) ident() else EmptyTermName
28162863 val tparams = typeParamClauseOpt(ParamOwner .Def )
28172864 val parents =
2818- if (in.token == FOR ) {
2865+ if (! newStyle && in.token == FOR || isIdent(nme.as)) { // for the moment, accept both `given for` and `given as`
28192866 in.nextToken()
28202867 tokenSeparated(COMMA , constrApp)
28212868 }
@@ -3122,8 +3169,16 @@ object Parsers {
31223169 setLastStatOffset()
31233170 if (in.token == IMPORT )
31243171 stats ++= importClause(IMPORT , Import )
3125- else if (in.token == GIVEN )
3126- stats += implicitClosure(in.offset, Location .InBlock , modifiers(closureMods))
3172+ else if (in.token == GIVEN ) {
3173+ val start = in.offset
3174+ val mods = modifiers(closureMods)
3175+ mods.mods match {
3176+ case givenMod :: Nil if ! isBindingIntro =>
3177+ stats += instanceDef(true , start, EmptyModifiers , Mod .Delegate ().withSpan(givenMod.span))
3178+ case _ =>
3179+ stats += implicitClosure(in.offset, Location .InBlock , mods)
3180+ }
3181+ }
31273182 else if (isExprIntro)
31283183 stats += expr(Location .InBlock )
31293184 else if (isDefIntro(localModifierTokens, excludedSoftModifiers = Set (nme.`opaque`)))
0 commit comments