@@ -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,8 +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
2360+ newLineOptWhenFollowedBy(LPAREN )
2361+ if (in.token == NEWLINE && in.next.token == GIVEN && ! followingIsInstanceDef)
2362+ in.nextToken()
23082363 if (in.token == GIVEN ) {
23092364 in.nextToken()
23102365 initialMods |= Given
@@ -2313,22 +2368,10 @@ object Parsers {
23132368 in.nextToken()
23142369 initialMods |= Erased
23152370 }
2316- val isContextual = initialMods.is(Given )
2371+ val isGiven = initialMods.is(Given )
23172372 newLineOptWhenFollowedBy(LPAREN )
2318- def isParamClause : Boolean =
2319- ! isContextual || {
2320- val lookahead = in.lookaheadScanner
2321- lookahead.nextToken()
2322- paramIntroTokens.contains(lookahead.token) && {
2323- lookahead.token != IDENTIFIER ||
2324- lookahead.name == nme.inline || {
2325- lookahead.nextToken()
2326- lookahead.token == COLON
2327- }
2328- }
2329- }
2330- if (in.token == LPAREN && isParamClause) {
2331- if (contextualOnly && ! isContextual)
2373+ if (in.token == LPAREN && (! isGiven || followingIsParamClause)) {
2374+ if (contextualOnly && ! isGiven)
23322375 if (ofInstance) syntaxError(em " parameters of instance definitions must come after `given' " )
23332376 else syntaxError(em " normal parameters cannot come after `given' clauses " )
23342377 val params = paramClause(
@@ -2337,15 +2380,15 @@ object Parsers {
23372380 firstClause = firstClause,
23382381 initialMods = initialMods)
23392382 val lastClause = params.nonEmpty && params.head.mods.flags.is(Implicit )
2340- 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 ))
23412384 }
2342- else if (isContextual ) {
2385+ else if (isGiven ) {
23432386 val tps = commaSeparated(() => annotType())
23442387 var counter = nparams
23452388 def nextIdx = { counter += 1 ; counter }
23462389 val paramFlags = if (ofClass) Private | Local | ParamAccessor else Param
23472390 val params = tps.map(makeSyntheticParameter(nextIdx, _, paramFlags | Synthetic | Given ))
2348- params :: recur(firstClause = false , nparams + params.length, isContextual )
2391+ params :: recur(firstClause = false , nparams + params.length, isGiven )
23492392 }
23502393 else Nil
23512394 }
@@ -2359,12 +2402,12 @@ object Parsers {
23592402
23602403 type ImportConstr = (Boolean , Tree , List [Tree ]) => Tree
23612404
2362- /** Import ::= import [delegate ] [ImportExpr {`,' ImportExpr}
2363- * Export ::= export [delegate ] [ImportExpr {`,' ImportExpr}
2405+ /** Import ::= ` import' [`given' ] [ImportExpr {`,' ImportExpr}
2406+ * Export ::= ` export' [`given' ] [ImportExpr {`,' ImportExpr}
23642407 */
23652408 def importClause (leading : Token , mkTree : ImportConstr ): List [Tree ] = {
23662409 val offset = accept(leading)
2367- val importDelegate = in.token == IMPLIED
2410+ val importDelegate = in.token == IMPLIED || in.token == GIVEN
23682411 if (importDelegate) in.nextToken()
23692412 commaSeparated(importExpr(importDelegate, mkTree)) match {
23702413 case t :: rest =>
@@ -2383,15 +2426,21 @@ object Parsers {
23832426
23842427 /** ImportSelectors ::= `{' {ImportSelector `,'} FinalSelector ‘}’
23852428 * FinalSelector ::= ImportSelector
2386- * | ‘_’
2387- * | ‘for’ InfixType {‘,’ InfixType}
2429+ * | ‘_’ [‘:’ Type]
23882430 */
23892431 def importSelectors (): List [Tree ] = in.token match {
23902432 case USCORE =>
2391- 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
23922441 case FOR =>
23932442 if (! importDelegate)
2394- syntaxError(em " `for` qualifier only allowed in `import delegate ` " )
2443+ syntaxError(em " `for` qualifier only allowed in `import given ` " )
23952444 atSpan(in.skipToken()) {
23962445 var t = infixType()
23972446 while (in.token == COMMA ) {
@@ -2695,7 +2744,7 @@ object Parsers {
26952744 /** TmplDef ::= ([‘case’] ‘class’ | ‘trait’) ClassDef
26962745 * | [‘case’] ‘object’ ObjectDef
26972746 * | ‘enum’ EnumDef
2698- * | ‘instance’ InstanceDef
2747+ * | ‘given’ GivenDef
26992748 */
27002749 def tmplDef (start : Int , mods : Modifiers ): Tree = {
27012750 in.token match {
@@ -2711,8 +2760,8 @@ object Parsers {
27112760 objectDef(start, posMods(start, mods | Case | Module ))
27122761 case ENUM =>
27132762 enumDef(start, posMods(start, mods | Enum ))
2714- case IMPLIED =>
2715- instanceDef(start, mods, atSpan(in.skipToken()) { Mod .Delegate () })
2763+ case IMPLIED | GIVEN =>
2764+ instanceDef(in.token == GIVEN , start, mods, atSpan(in.skipToken()) { Mod .Delegate () })
27162765 case _ =>
27172766 syntaxErrorOrIncomplete(ExpectedStartOfTopLevelDefinition ())
27182767 EmptyTree
@@ -2804,17 +2853,16 @@ object Parsers {
28042853 Template (constr, parents, Nil , EmptyValDef , Nil )
28052854 }
28062855
2807- /** InstanceDef ::= [id] [DefTypeParamClause] InstanceBody
2808- * InstanceParams ::= [DefTypeParamClause] {GivenParamClause}
2809- * InstanceBody ::= [‘for’ ConstrApp {‘,’ ConstrApp }] {GivenParamClause} [TemplateBody]
2810- * | ‘for’ Type {GivenParamClause} ‘=’ Expr
2856+ /** GivenDef ::= [id] [DefTypeParamClause] GivenBody
2857+ * GivenBody ::= [‘as ConstrApp {‘,’ ConstrApp }] {GivenParamClause} [TemplateBody]
2858+ * | ‘as’ Type {GivenParamClause} ‘=’ Expr
28112859 */
2812- 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) {
28132861 var mods1 = addMod(mods, instanceMod)
2814- val name = if (isIdent) ident() else EmptyTermName
2862+ val name = if (isIdent && ( ! newStyle || in.name != nme.as) ) ident() else EmptyTermName
28152863 val tparams = typeParamClauseOpt(ParamOwner .Def )
28162864 val parents =
2817- if (in.token == FOR ) {
2865+ if (! newStyle && in.token == FOR || isIdent(nme.as)) { // for the moment, accept both `given for` and `given as`
28182866 in.nextToken()
28192867 tokenSeparated(COMMA , constrApp)
28202868 }
@@ -3121,8 +3169,16 @@ object Parsers {
31213169 setLastStatOffset()
31223170 if (in.token == IMPORT )
31233171 stats ++= importClause(IMPORT , Import )
3124- else if (in.token == GIVEN )
3125- 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+ }
31263182 else if (isExprIntro)
31273183 stats += expr(Location .InBlock )
31283184 else if (isDefIntro(localModifierTokens, excludedSoftModifiers = Set (nme.`opaque`)))
0 commit comments