From 326ba1b8764094c58619b084c81affcba1c74aad Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 25 Nov 2020 14:19:34 +0100 Subject: [PATCH 01/14] Parser refactorings --- .../dotty/tools/dotc/parsing/Parsers.scala | 128 +++++++++--------- 1 file changed, 66 insertions(+), 62 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index fe6c8b7ba9dd..d280ca4910fb 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -1360,8 +1360,8 @@ object Parsers { */ def typ(): Tree = { val start = in.offset - var imods = Modifiers() - def functionRest(params: List[Tree]): Tree = + def functionRest(params: List[Tree], mods: Modifiers): Tree = + var imods = mods atSpan(start, in.offset) { if in.token == TLARROW then if !imods.flags.isEmpty || params.isEmpty then @@ -1389,61 +1389,11 @@ object Parsers { Function(params, t) } } - def funArgTypesRest(first: Tree, following: () => Tree) = { - val buf = new ListBuffer[Tree] += first - while (in.token == COMMA) { - in.nextToken() - buf += following() - } - buf.toList - } - var isValParamList = false val t = - if (in.token == LPAREN) { - in.nextToken() - if (in.token == RPAREN) { - in.nextToken() - functionRest(Nil) - } - else { - openParens.change(LPAREN, 1) - imods = modifiers(funTypeArgMods) - val paramStart = in.offset - val ts = funArgType() match { - case Ident(name) if name != tpnme.WILDCARD && in.token == COLON => - isValParamList = true - funArgTypesRest( - typedFunParam(paramStart, name.toTermName, imods), - () => typedFunParam(in.offset, ident(), imods)) - case t => - funArgTypesRest(t, funArgType) - } - openParens.change(LPAREN, -1) - accept(RPAREN) - if isValParamList || in.token == ARROW || in.token == CTXARROW then - functionRest(ts) - else { - val ts1 = - for (t <- ts) yield - t match { - case t@ByNameTypeTree(t1) => - syntaxError(ByNameParameterNotSupported(t), t.span) - t1 - case _ => - t - } - val tuple = atSpan(start) { makeTupleOrParens(ts1) } - infixTypeRest( - refinedTypeRest( - withTypeRest( - annotTypeRest( - simpleTypeRest(tuple))))) - } - } - } + if in.token == LPAREN then + typAfterParens(functionRest) else if (in.token == LBRACKET) { - val start = in.offset val tparams = typeParamClause(ParamOwner.TypeParam) if (in.token == TLARROW) atSpan(start, in.skipToken())(LambdaTypeTree(tparams, toplevelTyp())) @@ -1465,16 +1415,64 @@ object Parsers { else infixType() in.token match { - case ARROW | CTXARROW => functionRest(t :: Nil) + case ARROW | CTXARROW => functionRest(t :: Nil, Modifiers()) case MATCH => matchType(t) case FORSOME => syntaxError(ExistentialTypesNoLongerSupported()); t case _ => - if (imods.is(Erased) && !t.isInstanceOf[FunctionWithMods]) - syntaxError(ErasedTypesCanOnlyBeFunctionTypes(), implicitKwPos(start)) + //if (imods.is(Erased) && !t.isInstanceOf[FunctionWithMods]) + // syntaxError(ErasedTypesCanOnlyBeFunctionTypes(), implicitKwPos(start)) t } } + def funArgTypesRest(first: Tree, following: () => Tree): List[Tree] = + val buf = new ListBuffer[Tree] += first + while in.token == COMMA do + in.nextToken() + buf += following() + buf.toList + + def typAfterParens(parseRest: (List[Tree], Modifiers) => Tree) = + val start = in.offset + in.nextToken() + var imods = Modifiers() + var isValParamList = false + if in.token == RPAREN then + in.nextToken() + parseRest(Nil, imods) + else + openParens.change(LPAREN, 1) + imods = modifiers(funTypeArgMods) + val paramStart = in.offset + val ts = funArgType() match + case Ident(name) if name != tpnme.WILDCARD && in.token == COLON => + isValParamList = true + funArgTypesRest( + typedFunParam(paramStart, name.toTermName, imods), + () => typedFunParam(in.offset, ident(), imods)) + case t => + funArgTypesRest(t, funArgType) + openParens.change(LPAREN, -1) + accept(RPAREN) + if isValParamList || in.token == ARROW || in.token == CTXARROW then + parseRest(ts, imods) + else + val ts1 = + for t <- ts yield + t match + case t@ByNameTypeTree(t1) => + syntaxError(ByNameParameterNotSupported(t), t.span) + t1 + case _ => + t + val tuple = atSpan(start) { makeTupleOrParens(ts1) } + infixTypeRest( + refinedTypeRest( + withTypeRest( + annotTypeRest( + simpleTypeRest(tuple))))) + end typAfterParens + private def makeKindProjectorTypeDef(name: TypeName): TypeDef = TypeDef(name, WildcardTypeBoundsTree()).withFlags(Param) @@ -3607,24 +3605,30 @@ object Parsers { /* -------- TEMPLATES ------------------------------------------- */ + def constrOrSimpleType() = + rejectWildcardType( + annotTypeRest(simpleType1()), + fallbackTree = Ident(tpnme.ERROR)) + // Using Ident(tpnme.ERROR) to avoid causing cascade errors on non-user-written code + /** ConstrApp ::= SimpleType1 {Annotation} {ParArgumentExprs} */ val constrApp: () => Tree = () => - val t = rejectWildcardType(annotTypeRest(simpleType1()), - fallbackTree = Ident(tpnme.ERROR)) - // Using Ident(tpnme.ERROR) to avoid causing cascade errors on non-user-written code + val t = constrOrSimpleType() if in.token == LPAREN then parArgumentExprss(wrapNew(t)) else t /** ConstrApps ::= ConstrApp {(‘,’ | ‘with’) ConstrApp} */ def constrApps(commaOK: Boolean): List[Tree] = - val t = constrApp() + constrAppsRest(constrApp(), commaOK) + + def constrAppsRest(app: Tree, commaOK: Boolean): List[Tree] = val ts = if in.token == WITH || commaOK && in.token == COMMA then in.nextToken() constrApps(commaOK) else Nil - t :: ts + app :: ts /** Template ::= InheritClauses [TemplateBody] * InheritClauses ::= [‘extends’ ConstrApps] [‘derives’ QualId {‘,’ QualId}] From 4c9002bd3d3210d1d42a9a65151e732937d28f34 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 25 Nov 2020 17:36:58 +0100 Subject: [PATCH 02/14] Refine followingIsGivenSig to not get confused by postfix `as` --- .../dotty/tools/dotc/parsing/Parsers.scala | 60 +++++++++++++++++-- .../dotty/tools/dotc/parsing/Scanners.scala | 3 + tests/disabled/pos/i7851.scala | 6 +- tests/pos/i5915.scala | 4 +- tests/pos/i5978.scala | 6 +- tests/run/extmethod-overload.scala | 4 +- 6 files changed, 67 insertions(+), 16 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index d280ca4910fb..6e1157ba35ed 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -80,6 +80,9 @@ object Parsers { private val InCase: Region => Region = Scanners.InCase private val InCond: Region => Region = Scanners.InBraces + // TRANSITION + val knownTypeNames: Set[TypeName] = Set(tpnme.AnyRef, tpnme.Object) + abstract class ParserCommon(val source: SourceFile)(using Context) { val in: ScannerCommon @@ -897,23 +900,68 @@ object Parsers { followedByToken(LARROW) // `<-` comes before possible statement starts } - /** Are the next token the "GivenSig" part of a given definition, + /** Are the next token the "GivenSig" part of an old-style given definition, * i.e. an identifier followed by type and value parameters, followed by `:`? - * @pre The current token is an identifier */ - def followingIsGivenSig() = + def followingIsGivenSig() = // TRANSITION val lookahead = in.LookaheadScanner() + var prefixName = EmptyTermName if lookahead.isIdent then + prefixName = lookahead.name lookahead.nextToken() + var isOldStyle: Boolean = false + def isParamStart = lookahead.token == LPAREN || lookahead.token == LBRACKET def skipParams(): Unit = - if lookahead.token == LPAREN || lookahead.token == LBRACKET then - lookahead.skipParens() + if isParamStart then + val opening = lookahead.token + lookahead.nextToken() + if prefixName.isEmpty + && (opening == LBRACKET || lookahead.isIdent(nme.using)) + then isOldStyle = true + lookahead.skipParensRest(opening) skipParams() else if lookahead.isNewLine then lookahead.nextToken() skipParams() + val prefixHasParams = isParamStart skipParams() - lookahead.isIdent(nme.as) + if !lookahead.isIdent(nme.as) then false + else + lookahead.nextToken() + if isOldStyle || !lookahead.isIdent then + true + else + val suffixName = lookahead.name + lookahead.nextToken() + if isParamStart || lookahead.token == DOT then + true + else if prefixName.isEmpty then + // we have `given (...) as bar with no `using`; it must be new style + false + else if !prefixHasParams && prefixName == suffixName then + // we have `given foo as foo`, so it does not matter how we interpret it + true + else if knownTypeNames.contains(suffixName.toTypeName) then + true + else if knownTypeNames.contains(prefixName.toTypeName) then + true + else + // we have one of the following + // + // 1. given foo as bar + // 2. given foo[...]... as bar + // 3. given foo(...)... as bar + // + // Decide on the case of the names; lowercase means bound name + + val prefixIsUpper = Character.isUpperCase(prefixName.head) + val suffixIsUpper = Character.isUpperCase(suffixName.head) + if prefixIsUpper && !suffixIsUpper then false + else if !prefixIsUpper && suffixIsUpper then true + else syntaxError( + em"ambiguous syntax for given definition; make sure exactly one of $prefixName, $suffixName is capitalized") + true + end followingIsGivenSig def followingIsExtension() = val next = in.lookahead.token diff --git a/compiler/src/dotty/tools/dotc/parsing/Scanners.scala b/compiler/src/dotty/tools/dotc/parsing/Scanners.scala index 4e769c037ba1..8abf8ae3f96e 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Scanners.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Scanners.scala @@ -890,6 +890,9 @@ object Scanners { final def skipParens(multiple: Boolean = true): Unit = val opening = token nextToken() + skipParensRest(opening, multiple) // TRANSITION + + final def skipParensRest(opening: Token, multiple: Boolean = true): Unit = while token != EOF && token != opening + 1 do if token == opening && multiple then skipParens() else nextToken() nextToken() diff --git a/tests/disabled/pos/i7851.scala b/tests/disabled/pos/i7851.scala index 095de26cf0eb..89cc95cb39d0 100644 --- a/tests/disabled/pos/i7851.scala +++ b/tests/disabled/pos/i7851.scala @@ -8,11 +8,11 @@ object Wrapper { type Aux[T <: Tuple, WrappedT0 <: Tuple] = Wrapper[T] { type Wr given Wrapper[EmptyTuple] { type WrappedT = EmptyTuple } -given [T: Wrappable] as Wrapper[T] { type WrappedT = Wrapped[T] } +given [T: Wrappable] => Wrapper[T] { type WrappedT = Wrapped[T] } given [H: Wrappable, T <: Tuple, WrappedT0 <: Tuple] - (using Wrapper.Aux[T, WrappedT0]) - as Wrapper[H *: T]: + => Wrapper.Aux[T, WrappedT0] + => Wrapper[H *: T]: type WrappedT = Wrapped[H] *: WrappedT0 def wrappedFunction[F, FArgs <: Tuple, WrapperFArgs <: Tuple, R: Wrappable]( diff --git a/tests/pos/i5915.scala b/tests/pos/i5915.scala index 9822f4b93d76..ccd78df4a38c 100644 --- a/tests/pos/i5915.scala +++ b/tests/pos/i5915.scala @@ -2,8 +2,8 @@ trait RunDSL val rdsl = new RunDSL {} -given RunNNFExpr[B] as RunDSL = rdsl +given runNNFExpr[B] as RunDSL = rdsl -given RunNNFImpl[B] as RunDSL { +given runNNFImpl[B] as RunDSL { //override def runDSL(b: NNF[B]): B = b.terminal } \ No newline at end of file diff --git a/tests/pos/i5978.scala b/tests/pos/i5978.scala index 75573f775312..a453545433ff 100644 --- a/tests/pos/i5978.scala +++ b/tests/pos/i5978.scala @@ -84,9 +84,9 @@ package p3 { package p4 { class TC - given A as TC + given a as TC - given B[X[_], Y] as TC + given b[X[_], Y] as TC - given C(using TC) as TC + given c(using TC) as TC } \ No newline at end of file diff --git a/tests/run/extmethod-overload.scala b/tests/run/extmethod-overload.scala index c3d0ddbf2c20..783e243da1b3 100644 --- a/tests/run/extmethod-overload.scala +++ b/tests/run/extmethod-overload.scala @@ -61,7 +61,7 @@ object Test extends App { extension [T](xs: List[T]) def +++ (ys: List[T]): List[T] = xs ++ ys ++ ys extension [T](xs: List[T]) def +++ (ys: Iterator[T]): List[T] = xs ++ ys ++ ys } - given Bar as Foo + given bar as Foo assert((1 |+| 2) == 3) assert((1 |+| "2") == 2) @@ -74,7 +74,7 @@ object Test extends App { // Test with extension methods coming from given alias object test4 { - given test3.Foo = test3.Bar + given test3.Foo = test3.bar assert((1 |+| 2) == 3) assert((1 |+| "2") == 2) From 553c8818b981885c690e0e0c66f796a6cd3db5ed Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 25 Nov 2020 18:05:20 +0100 Subject: [PATCH 03/14] Factor out parsing that's only relevant if there is a given sig --- .../src/dotty/tools/dotc/parsing/Parsers.scala | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index 6e1157ba35ed..55b0a18b0cf1 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -3568,11 +3568,9 @@ object Parsers { */ def givenDef(start: Offset, mods: Modifiers, givenMod: Mod) = atSpan(start, nameStart) { var mods1 = addMod(mods, givenMod) - val hasGivenSig = followingIsGivenSig() val nameStart = in.offset - val name = if isIdent && hasGivenSig then ident() else EmptyTermName - - val gdef = + val (name, tparams, vparamss, parents) = if followingIsGivenSig() then + val name = if isIdent then ident() else EmptyTermName val tparams = typeParamClauseOpt(ParamOwner.Def) newLineOpt() val vparamss = @@ -3580,14 +3578,16 @@ object Parsers { then paramClauses(givenOnly = true) else Nil newLinesOpt() - val noParams = tparams.isEmpty && vparamss.isEmpty - if !(name.isEmpty && noParams) then - accept(nme.as) + accept(nme.as) val parents = constrApps(commaOK = true) + (name, tparams, vparamss, parents) + else + (EmptyTermName, Nil, Nil, constrApps(commaOK = true)) + val gdef = if in.token == EQUALS && parents.length == 1 && parents.head.isType then accept(EQUALS) mods1 |= Final - if noParams && !mods.is(Inline) then + if tparams.isEmpty && vparamss.isEmpty && !mods.is(Inline) then mods1 |= Lazy ValDef(name, parents.head, subExpr()) else From 3ad77e395386afcd0f4a3d220276705ba0e1428f Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 25 Nov 2020 19:50:37 +0100 Subject: [PATCH 04/14] Enable suffix as in given defs --- .../dotty/tools/dotc/parsing/Parsers.scala | 63 ++++++++++++++----- 1 file changed, 46 insertions(+), 17 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index 55b0a18b0cf1..694aca6fc655 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -958,8 +958,9 @@ object Parsers { val suffixIsUpper = Character.isUpperCase(suffixName.head) if prefixIsUpper && !suffixIsUpper then false else if !prefixIsUpper && suffixIsUpper then true - else syntaxError( - em"ambiguous syntax for given definition; make sure exactly one of $prefixName, $suffixName is capitalized") + else + syntaxError( + em"ambiguous syntax for given definition; make sure exactly one of $prefixName, $suffixName is capitalized") true end followingIsGivenSig @@ -1440,7 +1441,7 @@ object Parsers { val t = if in.token == LPAREN then - typAfterParens(functionRest) + afterArguments(x => infixTypeRest(refinedTypeRest(withTypeRest(x))), functionRest) else if (in.token == LBRACKET) { val tparams = typeParamClause(ParamOwner.TypeParam) if (in.token == TLARROW) @@ -1480,14 +1481,14 @@ object Parsers { buf += following() buf.toList - def typAfterParens(parseRest: (List[Tree], Modifiers) => Tree) = + def afterArguments[T](parseSimple: Tree => T, parseFn: (List[Tree], Modifiers) => T): T = val start = in.offset in.nextToken() var imods = Modifiers() var isValParamList = false if in.token == RPAREN then in.nextToken() - parseRest(Nil, imods) + parseFn(Nil, imods) else openParens.change(LPAREN, 1) imods = modifiers(funTypeArgMods) @@ -1503,7 +1504,7 @@ object Parsers { openParens.change(LPAREN, -1) accept(RPAREN) if isValParamList || in.token == ARROW || in.token == CTXARROW then - parseRest(ts, imods) + parseFn(ts, imods) else val ts1 = for t <- ts yield @@ -1514,12 +1515,8 @@ object Parsers { case _ => t val tuple = atSpan(start) { makeTupleOrParens(ts1) } - infixTypeRest( - refinedTypeRest( - withTypeRest( - annotTypeRest( - simpleTypeRest(tuple))))) - end typAfterParens + parseSimple(annotTypeRest(simpleTypeRest(tuple))) + end afterArguments private def makeKindProjectorTypeDef(name: TypeName): TypeDef = TypeDef(name, WildcardTypeBoundsTree()).withFlags(Param) @@ -3562,13 +3559,13 @@ object Parsers { syntaxError(i"extension clause can only define methods", stat.span) } - /** GivenDef ::= [GivenSig] Type ‘=’ Expr - * | [GivenSig] ConstrApps [TemplateBody] - * GivenSig ::= [id] [DefTypeParamClause] {UsingParamClauses} ‘as’ + /** GivenDef ::= [GivenParams] Type ['as' id] ‘=’ Expr + * | [GivenParams] ConstrApps ['as' id] [TemplateBody] + * GivenParams ::= [DefTypeParamClause '=>'] {FunArgTypes '=>'} */ def givenDef(start: Offset, mods: Modifiers, givenMod: Mod) = atSpan(start, nameStart) { var mods1 = addMod(mods, givenMod) - val nameStart = in.offset + val start = in.offset val (name, tparams, vparamss, parents) = if followingIsGivenSig() then val name = if isIdent then ident() else EmptyTermName val tparams = typeParamClauseOpt(ParamOwner.Def) @@ -3581,6 +3578,36 @@ object Parsers { accept(nme.as) val parents = constrApps(commaOK = true) (name, tparams, vparamss, parents) + else if true then + val tparams = typeParamClauseOpt(ParamOwner.Def) + if tparams.nonEmpty then accept(ARROW) + var counter = 0 + def nextIdx = { counter += 1; counter } + def givenHeadRest(params: List[Tree], mods: Modifiers): (List[List[ValDef]], List[Tree]) = + accept(ARROW) + val vparams = params match + case (_: ValDef) :: _ => + params.asInstanceOf[List[ValDef]].map(_.withFlags(Given)) + case _ => + params.map(makeSyntheticParameter(nextIdx, _, Param | Synthetic | Given)) + val (vparamss1, parents) = givenHead() + (vparams :: vparamss1, parents) + def givenHeadFinish(t: Tree): (List[List[ValDef]], List[Tree]) = + (Nil, constrAppsRest(constrAppRest(t), commaOK = true)) + def givenHead(): (List[List[ValDef]], List[Tree]) = + if in.token == LPAREN then + afterArguments(givenHeadFinish, givenHeadRest) + else + val constr = constrOrSimpleType() + if in.token == ARROW then givenHeadRest(constr :: Nil, EmptyModifiers) + else givenHeadFinish(constr) + val (vparamss, parents) = givenHead() + val name = + if in.isIdent(nme.as) then + in.nextToken() + ident() + else EmptyTermName + (name, tparams, vparamss, parents) else (EmptyTermName, Nil, Nil, constrApps(commaOK = true)) val gdef = @@ -3662,7 +3689,9 @@ object Parsers { /** ConstrApp ::= SimpleType1 {Annotation} {ParArgumentExprs} */ val constrApp: () => Tree = () => - val t = constrOrSimpleType() + constrAppRest(constrOrSimpleType()) + + def constrAppRest(t: Tree): Tree = if in.token == LPAREN then parArgumentExprss(wrapNew(t)) else t /** ConstrApps ::= ConstrApp {(‘,’ | ‘with’) ConstrApp} From b3a989f71861276ebebd032fc490d23aff284eea Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 25 Nov 2020 21:37:42 +0100 Subject: [PATCH 05/14] Switch tests to postfix as --- scala3doc-testcases/src/tests/FilterTest.scala | 8 ++++---- scala3doc-testcases/src/tests/givenDRI.scala | 4 ++-- scala3doc-testcases/src/tests/givenSignatures.scala | 4 ++-- tests/disabled/pos-macros/i7853/JsonEncoder_1.scala | 4 ++-- tests/disabled/pos/i8311.scala | 2 +- tests/init/crash/i7821.scala | 4 ++-- tests/neg-custom-args/fatal-warnings/i7821.scala | 4 ++-- tests/neg-custom-args/impl-conv/A.scala | 2 +- tests/neg-macros/i4044b.scala | 4 ++-- tests/neg/extmethod-overload.scala | 4 ++-- tests/neg/i5978.scala | 6 +++--- tests/neg/i7078.scala | 2 +- tests/neg/i7526.scala | 2 +- tests/neg/i7980.scala | 2 +- tests/neg/i8623a.scala | 2 +- tests/neg/i9185.scala | 4 ++-- .../machine-state-encoding-with-implicit-match.scala | 4 ++-- tests/neg/missing-implicit1.scala | 4 ++-- tests/neg/missing-implicit2.scala | 2 +- tests/neg/missing-implicit4.scala | 4 ++-- tests/neg/missing-implicit5.scala | 4 ++-- tests/neg/multi-param-derives.scala | 4 ++-- tests/patmat/i6088.scala | 2 +- tests/pos-custom-args/erased/i7878.scala | 2 +- tests/pos-macros/i6803b/Macro_1.scala | 2 +- tests/pos-macros/nil-liftable.scala | 2 +- tests/pos/i5966.scala | 2 +- tests/pos/i5978.scala | 10 +++++----- tests/pos/i6373.scala | 2 +- tests/pos/i7078.scala | 2 +- tests/pos/i7413.scala | 2 +- tests/pos/i8284.scala | 4 ++-- tests/pos/i8825.scala | 2 +- tests/pos/multi-given.scala | 2 +- tests/pos/reference/delegates.scala | 12 ++++++------ tests/pos/the.scala | 2 +- tests/run-macros/i6988/FirstArg_1.scala | 2 +- tests/run-macros/i9812b/Macro_1.scala | 12 ++++++------ .../quote-matcher-symantics-3/quoted_1.scala | 2 +- tests/run-staging/i6281.scala | 2 +- tests/run-with-compiler/intmaptest.scala | 6 +++--- tests/run-with-compiler/maptest.scala | 4 ++-- tests/run-with-compiler/settest.scala | 6 +++--- tests/run/Signals.scala | 2 +- tests/run/Signals1.scala | 2 +- tests/run/Typeable.scala | 2 +- tests/run/cochis-example.scala | 2 +- tests/run/implicit-alias.scala | 6 +++--- tests/run/implicit-disambiguation.scala | 2 +- tests/run/implicit-specifity.scala | 4 ++-- tests/run/instances.scala | 4 ++-- tests/run/poly-kinded-derives.scala | 4 ++-- tests/run/tagless.scala | 2 +- tests/semanticdb/expect/Givens.scala | 2 +- 54 files changed, 97 insertions(+), 97 deletions(-) diff --git a/scala3doc-testcases/src/tests/FilterTest.scala b/scala3doc-testcases/src/tests/FilterTest.scala index 2183a66a90cf..8b203dd20e14 100644 --- a/scala3doc-testcases/src/tests/FilterTest.scala +++ b/scala3doc-testcases/src/tests/FilterTest.scala @@ -65,9 +65,9 @@ class FilterTestBase: given Map[String, Double] = Map.empty /** doc */ - protected given namedSet as Set[String | Int] = Set(1, "ala") + protected given Set[String | Int] as namedSet = Set(1, "ala") /** doc */ - given namedMap as Map[String, Double] = Map.empty + given Map[String, Double] as namedMap = Map.empty class FilterTest extends FilterTestBase with FilterTestBaseTrait: /** doc */ @@ -116,9 +116,9 @@ class FilterTest extends FilterTestBase with FilterTestBaseTrait: given List[String] = "ula" :: Nil /** doc */ - given namedList as List[String] = "ula" :: Nil + given List[String] as namedList = "ula" :: Nil /** doc */ - protected given namedSeq as Seq[String | Int | Double] = List(1) + protected given Seq[String | Int | Double] as namedSeq = List(1) extension (e: FilterTest): def extensionMethod(name: FilterTest): FilterTest = ??? diff --git a/scala3doc-testcases/src/tests/givenDRI.scala b/scala3doc-testcases/src/tests/givenDRI.scala index 2fb16fa49f42..16f35adc71e2 100644 --- a/scala3doc-testcases/src/tests/givenDRI.scala +++ b/scala3doc-testcases/src/tests/givenDRI.scala @@ -23,12 +23,12 @@ given [S <: C] as A[S] class R: def a = 1 -given R as A[Int]: +given A[Int] as r: def a = 2 class S: class R: def a = 3 - given R as A[Int]: + given A[Int] as r: def a = 5 \ No newline at end of file diff --git a/scala3doc-testcases/src/tests/givenSignatures.scala b/scala3doc-testcases/src/tests/givenSignatures.scala index 4364a7e4c0a8..aa4ec3f219eb 100644 --- a/scala3doc-testcases/src/tests/givenSignatures.scala +++ b/scala3doc-testcases/src/tests/givenSignatures.scala @@ -15,7 +15,7 @@ class GivenClass { extension (x: T) def < (y: T) = compare(x, y) < 0 extension (x: T) def > (y: T) = compare(x, y) > 0 } - given intOrd as Ord[Int] { + given Ord[Int] as intOrd { def compare(x: Int, y: Int) = if (x < y) -1 else if (x > y) +1 else 0 } @@ -35,7 +35,7 @@ class GivenClass { if (fst != 0) fst else compare(xs1, ys1) } - given IntOps as Int.type = Int + given Int.type as IntOps = Int given GivenType = GivenType() diff --git a/tests/disabled/pos-macros/i7853/JsonEncoder_1.scala b/tests/disabled/pos-macros/i7853/JsonEncoder_1.scala index d37c84b861ad..d6c6f8be1a5e 100644 --- a/tests/disabled/pos-macros/i7853/JsonEncoder_1.scala +++ b/tests/disabled/pos-macros/i7853/JsonEncoder_1.scala @@ -39,11 +39,11 @@ object JsonEncoder { def encode(list: List[T]) = s"[${ list.map(v => encoder.encode(v)).mkString(", ") }]" } - given intEncoder as JsonEncoder[Int] { + given JsonEncoder[Int] as intEncoder { def encode(value: Int) = value + "" } - given stringEncoder as JsonEncoder[String] { + given JsonEncoder[String] as stringEncoder { def encode(value: String) = value } } diff --git a/tests/disabled/pos/i8311.scala b/tests/disabled/pos/i8311.scala index 93649a06154d..f898612d8f91 100644 --- a/tests/disabled/pos/i8311.scala +++ b/tests/disabled/pos/i8311.scala @@ -9,7 +9,7 @@ class Foo object test: given box[A](using Show[A]) as Show[Box[A]] = _.toString - given foo as Show[Foo] = _.toString + given Show[Foo] as foo = _.toString def run(s: Box[Box[Foo]]): Unit = val x = summon[Show[Box[Box[Foo]]]] diff --git a/tests/init/crash/i7821.scala b/tests/init/crash/i7821.scala index 523fa1e7306c..d9ac320c705d 100644 --- a/tests/init/crash/i7821.scala +++ b/tests/init/crash/i7821.scala @@ -3,7 +3,7 @@ object XObject { def anX: X = 5 - given ops as Object { + given Object as ops { extension (x: X) def + (y: X): X = x + y } } @@ -13,7 +13,7 @@ object MyXObject { def anX: MyX = XObject.anX - given ops as Object { + given Object as ops { extension (x: MyX) def + (y: MyX): MyX = x + y // error: warring: Infinite recursive call } } diff --git a/tests/neg-custom-args/fatal-warnings/i7821.scala b/tests/neg-custom-args/fatal-warnings/i7821.scala index 523fa1e7306c..d9ac320c705d 100644 --- a/tests/neg-custom-args/fatal-warnings/i7821.scala +++ b/tests/neg-custom-args/fatal-warnings/i7821.scala @@ -3,7 +3,7 @@ object XObject { def anX: X = 5 - given ops as Object { + given Object as ops { extension (x: X) def + (y: X): X = x + y } } @@ -13,7 +13,7 @@ object MyXObject { def anX: MyX = XObject.anX - given ops as Object { + given Object as ops { extension (x: MyX) def + (y: MyX): MyX = x + y // error: warring: Infinite recursive call } } diff --git a/tests/neg-custom-args/impl-conv/A.scala b/tests/neg-custom-args/impl-conv/A.scala index 4598172fd18a..f17716ca441c 100644 --- a/tests/neg-custom-args/impl-conv/A.scala +++ b/tests/neg-custom-args/impl-conv/A.scala @@ -3,7 +3,7 @@ package implConv object A { implicit def s2i(x: String): Int = Integer.parseInt(x) // error: feature - given i2s as Conversion[Int, String] = _.toString // ok + given Conversion[Int, String] as i2s = _.toString // ok implicit class Foo(x: String) { def foo = x.length diff --git a/tests/neg-macros/i4044b.scala b/tests/neg-macros/i4044b.scala index f8ebf884bbe2..ca727de5bb7d 100644 --- a/tests/neg-macros/i4044b.scala +++ b/tests/neg-macros/i4044b.scala @@ -4,13 +4,13 @@ def test(using Quotes) = { '{ val qctx: Quotes = ??? - given x1 as qctx.type = qctx + given qctx.type as x1 = qctx val b = '{3} '{ val qctx: Quotes = ??? - given x2 as qctx.type = qctx + given qctx.type as x2 = qctx b // error ${b} diff --git a/tests/neg/extmethod-overload.scala b/tests/neg/extmethod-overload.scala index c680acda9144..e3a59fd94800 100644 --- a/tests/neg/extmethod-overload.scala +++ b/tests/neg/extmethod-overload.scala @@ -1,9 +1,9 @@ object Test { - given a as AnyRef: + given AnyRef as a: extension (x: Int) { def |+| (y: Int) = x + y } - given b as AnyRef: + given AnyRef as b: extension (x: Int) { def |+| (y: String) = x + y.length } diff --git a/tests/neg/i5978.scala b/tests/neg/i5978.scala index 47dee9c9fdd3..9d30952cd158 100644 --- a/tests/neg/i5978.scala +++ b/tests/neg/i5978.scala @@ -5,7 +5,7 @@ opaque type Position[Buffer] = Int trait TokenParser[Token, R] object TextParser { - given TP as TokenParser[Char, Position[CharSequence]] {} + given TokenParser[Char, Position[CharSequence]] as tp {} given FromCharToken(using T: TokenParser[Char, Position[CharSequence]]) as Conversion[Char, Position[CharSequence]] = ??? @@ -15,13 +15,13 @@ object Testcase { def main(args: Array[String]): Unit = { import TextParser._ - val tp_v: TokenParser[Char, Position[CharSequence]] = TextParser.TP + val tp_v: TokenParser[Char, Position[CharSequence]] = TextParser.tp val tp_i = summon[TokenParser[Char, Position[CharSequence]]] // error val co_i = summon[Conversion[Char, Position[CharSequence]]] // error val co_x : Position[CharSequence] = 'x' // error { - given XXX as Conversion[Char, Position[CharSequence]] = co_i + given Conversion[Char, Position[CharSequence]] as xxx = co_i val co_y : Position[CharSequence] = 'x' } } diff --git a/tests/neg/i7078.scala b/tests/neg/i7078.scala index 387faafc745d..7a10a7c1d16d 100644 --- a/tests/neg/i7078.scala +++ b/tests/neg/i7078.scala @@ -1,7 +1,7 @@ trait A class B extends A -transparent given g1 as A = B() // error: `transparent` can only be used in conjunction with `inline` +transparent given A as g1 = B() // error: `transparent` can only be used in conjunction with `inline` inline given g2 as _ <: A: // error: `=' expected def foo = 2 diff --git a/tests/neg/i7526.scala b/tests/neg/i7526.scala index e85fc552d3a4..1c97f520985a 100644 --- a/tests/neg/i7526.scala +++ b/tests/neg/i7526.scala @@ -13,6 +13,6 @@ def compQ(name: => String) object net extends NetDB with NetHelper import net._ -given n as NetApi = net +given NetApi as n = net val q: Tr[Nothing, Comp, Comp] = compQ("???") // error Found: Tr[Nothing, ?1.Comp, ?1.Comp] Required: Tr[Nothing, net.Comp, net.Comp] \ No newline at end of file diff --git a/tests/neg/i7980.scala b/tests/neg/i7980.scala index 73c17b0fd687..49d54df59808 100644 --- a/tests/neg/i7980.scala +++ b/tests/neg/i7980.scala @@ -3,5 +3,5 @@ trait Evidence[X] trait Trait[X : Evidence]: def method(x : X) : X -given ev as Evidence[Int] = new Evidence[Int]{} +given Evidence[Int] as ev = new Evidence[Int]{} val crash : Trait[Int] = (x: Int) => x // error diff --git a/tests/neg/i8623a.scala b/tests/neg/i8623a.scala index 909dce706015..df2dad997b9e 100644 --- a/tests/neg/i8623a.scala +++ b/tests/neg/i8623a.scala @@ -7,7 +7,7 @@ object Test { } def foo: A & B = o - given o as (A & B) = foo + given (A & B) as o = foo def xToString(x: o.X): String = x // error diff --git a/tests/neg/i9185.scala b/tests/neg/i9185.scala index d4558e28bbbd..59c0b8bc6e07 100644 --- a/tests/neg/i9185.scala +++ b/tests/neg/i9185.scala @@ -1,8 +1,8 @@ trait M[F[_]] { def pure[A](x: A): F[A] } object M { extension [A, F[A]](x: A) def pure(using m: M[F]): F[A] = m.pure(x) - given listMonad as M[List] { def pure[A](x: A): List[A] = List(x) } - given optionMonad as M[Option] { def pure[A](x: A): Option[A] = Some(x) } + given M[List] as listMonad { def pure[A](x: A): List[A] = List(x) } + given M[Option] as optionMonad { def pure[A](x: A): Option[A] = Some(x) } val value1: List[String] = "ola".pure val value2 = "ola".pure // error val value3 = M.pure("ola") // error diff --git a/tests/neg/machine-state-encoding-with-implicit-match.scala b/tests/neg/machine-state-encoding-with-implicit-match.scala index f7e0a6ff536b..da756fb6cd2f 100644 --- a/tests/neg/machine-state-encoding-with-implicit-match.scala +++ b/tests/neg/machine-state-encoding-with-implicit-match.scala @@ -8,13 +8,13 @@ final class Off extends State @implicitNotFound("State must be Off") class IsOff[S <: State] object IsOff { - given isOff as IsOff[Off] = new IsOff[Off] + given IsOff[Off] as isOff = new IsOff[Off] } @implicitNotFound("State must be On") class IsOn[S <: State] object IsOn { - given isOn as IsOn[On] = new IsOn[On] + given IsOn[On] as isOn = new IsOn[On] } class Machine[S <: State] { diff --git a/tests/neg/missing-implicit1.scala b/tests/neg/missing-implicit1.scala index c94d78099068..fb3617584979 100644 --- a/tests/neg/missing-implicit1.scala +++ b/tests/neg/missing-implicit1.scala @@ -5,8 +5,8 @@ object testObjectInstance: } object instances { - given zipOption as Zip[Option] = ??? - given traverseList as Traverse[List] = ??? + given Zip[Option] as zipOption = ??? + given Traverse[List] as traverseList = ??? extension [T](xs: List[T]) def second: T = xs.tail.head extension [T](xs: List[T]) def first: T = xs.head diff --git a/tests/neg/missing-implicit2.scala b/tests/neg/missing-implicit2.scala index 7edcd1d37b0e..21a23887a067 100644 --- a/tests/neg/missing-implicit2.scala +++ b/tests/neg/missing-implicit2.scala @@ -3,7 +3,7 @@ trait Y object test: def f(using x: X) = ??? object instances { - given y as Y = ??? + given Y as y = ??? } locally { given xFromY(using y: Y) as X = ??? diff --git a/tests/neg/missing-implicit4.scala b/tests/neg/missing-implicit4.scala index a02d543c12f8..27a8423b8e33 100644 --- a/tests/neg/missing-implicit4.scala +++ b/tests/neg/missing-implicit4.scala @@ -5,8 +5,8 @@ def testLocalInstance = } object instances { - given zipOption as Zip[Option] = ??? - given traverseList as Traverse[List] = ??? + given Zip[Option] as zipOption = ??? + given Traverse[List] as traverseList = ??? } def ff(using xs: Zip[Option]) = ??? diff --git a/tests/neg/missing-implicit5.scala b/tests/neg/missing-implicit5.scala index a2a0fd55315c..a5590899ccf8 100644 --- a/tests/neg/missing-implicit5.scala +++ b/tests/neg/missing-implicit5.scala @@ -5,8 +5,8 @@ object testObjectInstance: } object instances { - given zipOption as Zip[Option] = ??? - given traverseList as Traverse[List] = ??? + given Zip[Option] as zipOption = ??? + given Traverse[List] as traverseList = ??? extension [T](xs: List[T]) def second: T = xs.tail.head extension [T](xs: List[T]) def first: T = xs.head diff --git a/tests/neg/multi-param-derives.scala b/tests/neg/multi-param-derives.scala index 98b7a3272f1e..5c1ab411ed83 100644 --- a/tests/neg/multi-param-derives.scala +++ b/tests/neg/multi-param-derives.scala @@ -56,9 +56,9 @@ object Test extends App { { trait Bifunctor[F[_, _]] object Bifunctor { - given [C] as Bifunctor[[T, U] =>> C] {} + given [C] => Bifunctor[[T, U] =>> C] {} given Bifunctor[[T, U] =>> Tuple1[U]] {} - given t2 as Bifunctor[[T, U] =>> (T, U)] {} + given Bifunctor[[T, U] =>> (T, U)] as t2 {} given t3 [T] as Bifunctor[[U, V] =>> (T, U, V)] {} def derived[F[_, _]](using m: Mirror { type MirroredType[X, Y] = F[X, Y] ; type MirroredElemTypes[_, _] }, r: Bifunctor[m.MirroredElemTypes]): Bifunctor[F] = ??? diff --git a/tests/patmat/i6088.scala b/tests/patmat/i6088.scala index 9c532a608bb4..061770ea9e4c 100644 --- a/tests/patmat/i6088.scala +++ b/tests/patmat/i6088.scala @@ -17,7 +17,7 @@ enum ExprF[R[_],I] { /** Companion. */ object ExprF { - given hfunctor as HFunctor[ExprF] { + given HFunctor[ExprF] as hfunctor { def hmap[A[_], B[_]](nt: A ~> B): ([x] =>> ExprF[A,x]) ~> ([x] =>> ExprF[B,x]) = { new ~>[[x] =>> ExprF[A,x], [x] =>> ExprF[B,x]] { def apply[I](fa: ExprF[A,I]): ExprF[B,I] = fa match { diff --git a/tests/pos-custom-args/erased/i7878.scala b/tests/pos-custom-args/erased/i7878.scala index 4fea0c095561..73a6e60251cd 100644 --- a/tests/pos-custom-args/erased/i7878.scala +++ b/tests/pos-custom-args/erased/i7878.scala @@ -9,7 +9,7 @@ object Boom { } val a: Int = 1 - given ev1 as Fail[a.type, 2] = null + given Fail[a.type, 2] as ev1 = null summon[Fail[a.type, 3]] } \ No newline at end of file diff --git a/tests/pos-macros/i6803b/Macro_1.scala b/tests/pos-macros/i6803b/Macro_1.scala index 17e0fede7597..8310fa7b4339 100644 --- a/tests/pos-macros/i6803b/Macro_1.scala +++ b/tests/pos-macros/i6803b/Macro_1.scala @@ -7,7 +7,7 @@ object AsObject { final class LineNo(val lineNo: Int) object LineNo { def unsafe(i: Int): LineNo = new LineNo(i) - inline given x as LineNo = ${impl} + inline given LineNo as x = ${impl} private def impl(using Quotes) : Expr[LineNo] = { import quotes.reflect._ '{unsafe(${Expr(Position.ofMacroExpansion.startLine)})} diff --git a/tests/pos-macros/nil-liftable.scala b/tests/pos-macros/nil-liftable.scala index a8ac5bbd6240..2cc034705e7b 100644 --- a/tests/pos-macros/nil-liftable.scala +++ b/tests/pos-macros/nil-liftable.scala @@ -1,7 +1,7 @@ import scala.quoted._ class Test: - given NilIsLiftable as Liftable[Nil.type] = new Liftable[Nil.type] { + given Liftable[Nil.type] as nilIsLiftable = new Liftable[Nil.type] { def toExpr(xs: Nil.type): Quotes ?=> Expr[Nil.type] = '{ Nil } } diff --git a/tests/pos/i5966.scala b/tests/pos/i5966.scala index 88a0c9a9beb5..9d62862866bd 100644 --- a/tests/pos/i5966.scala +++ b/tests/pos/i5966.scala @@ -1,6 +1,6 @@ object Test { def foo = (v: Int) ?=> (x: Int) => v + x - given myInt as Int = 4 + given Int as myInt = 4 foo.apply(1) foo(using 2) diff --git a/tests/pos/i5978.scala b/tests/pos/i5978.scala index a453545433ff..7b6319978220 100644 --- a/tests/pos/i5978.scala +++ b/tests/pos/i5978.scala @@ -7,7 +7,7 @@ trait TokenParser[Token, R] package p1 { object TextParser { - given TP as TokenParser[Char, Position[CharSequence]] {} + given TokenParser[Char, Position[CharSequence]] as tp {} def f (using TokenParser[Char, Position[CharSequence]]) = ??? @@ -23,13 +23,13 @@ package p1 { def main(args: Array[String]): Unit = { import TextParser.{given, _} - val tp_v: TokenParser[Char, Position[CharSequence]] = TextParser.TP + val tp_v: TokenParser[Char, Position[CharSequence]] = TextParser.tp val tp_i = summon[TokenParser[Char, Position[CharSequence]]] val co_i = summon[Conversion[Char, Position[CharSequence]]] val co_x : Position[CharSequence] = 'x' { - given XXX as Conversion[Char, Position[CharSequence]] = co_i + given Conversion[Char, Position[CharSequence]] as xxx = co_i val co_y : Position[CharSequence] = 'x' } } @@ -74,7 +74,7 @@ package p3 { val co_x : Position[CharSequence] = 'x' { - given XXX as Conversion[Char, Position[CharSequence]] = co_i + given Conversion[Char, Position[CharSequence]] as xxx = co_i val co_y : Position[CharSequence] = 'x' } } @@ -84,7 +84,7 @@ package p3 { package p4 { class TC - given a as TC + given TC as a given b[X[_], Y] as TC diff --git a/tests/pos/i6373.scala b/tests/pos/i6373.scala index 3b30388798bf..d68dfbafb8ca 100644 --- a/tests/pos/i6373.scala +++ b/tests/pos/i6373.scala @@ -6,7 +6,7 @@ object Test { inline def f(): Contextual[Boolean] = summon[Context].t - given ctx as Context = new Context(true) + given Context as ctx = new Context(true) f() } diff --git a/tests/pos/i7078.scala b/tests/pos/i7078.scala index ab49673b3ca6..23ecb03b7cc9 100644 --- a/tests/pos/i7078.scala +++ b/tests/pos/i7078.scala @@ -1,7 +1,7 @@ trait A class B extends A -transparent inline given tc as A = B() +transparent inline given A as tc = B() val x: B = summon[A] diff --git a/tests/pos/i7413.scala b/tests/pos/i7413.scala index 1e90ca7e8d74..153e0e556f77 100644 --- a/tests/pos/i7413.scala +++ b/tests/pos/i7413.scala @@ -11,7 +11,7 @@ trait Greeter: case class MyFixture(name: String, greeter: Greeter) object Test1: - given conv as Conversion[0, Greeter]: + given Conversion[0, Greeter] as conv: def apply(x: 0): Greeter = ??? val g: Greeter = 0 diff --git a/tests/pos/i8284.scala b/tests/pos/i8284.scala index 148ef81c67b6..80e12eceb33f 100644 --- a/tests/pos/i8284.scala +++ b/tests/pos/i8284.scala @@ -1,5 +1,5 @@ type Foo -given myFoo1 as (Foo { type X = Int }) = ??? +given (Foo { type X = Int }) as myFoo1 = ??? type Bar = Foo { type X = Int } -given myFoo2 as Bar = ??? \ No newline at end of file +given Bar as myFoo2 = ??? \ No newline at end of file diff --git a/tests/pos/i8825.scala b/tests/pos/i8825.scala index 49c85434ce98..1cdc25d851d1 100644 --- a/tests/pos/i8825.scala +++ b/tests/pos/i8825.scala @@ -16,7 +16,7 @@ object Length { type Aux[L <: HList, Out0 <: Nat] = Length[L] { type Out = Out0 } def instance[L <: HList, Out0 <: Nat]: Aux[L, Out0] = new Length[L] { type Out = Out0 } - given hnilLength as Aux[HNil, Zero] = instance + given Aux[HNil, Zero] as hnilLength = instance given hconsLength[H, T <: HList] (using length: Length[T]) as Aux[HCons[H, T], Succ[length.Out]] = instance // (*) //given hconsLength[H, T <: HList, N <: Nat] (using length: Aux[T, N]) as Aux[HCons[H, T], Succ[N]] = instance // (**) } diff --git a/tests/pos/multi-given.scala b/tests/pos/multi-given.scala index eb1c40718b01..b433d290e6ae 100644 --- a/tests/pos/multi-given.scala +++ b/tests/pos/multi-given.scala @@ -7,4 +7,4 @@ def foo(implicit a: A, b: B, c: C) = "foo" given A, B {} -given ops as A with B {} \ No newline at end of file +given A with B as ops {} \ No newline at end of file diff --git a/tests/pos/reference/delegates.scala b/tests/pos/reference/delegates.scala index 56b29c008924..65ec665705ec 100644 --- a/tests/pos/reference/delegates.scala +++ b/tests/pos/reference/delegates.scala @@ -26,7 +26,7 @@ end Common object Instances extends Common: - given intOrd as Ord[Int]: + given Ord[Int] as intOrd: extension (x: Int) def compareTo(y: Int) = if (x < y) -1 else if (x > y) +1 else 0 @@ -49,7 +49,7 @@ object Instances extends Common: def second = xs.tail.head def third = xs.tail.tail.head - given listMonad as Monad[List]: + given Monad[List] as listMonad: extension [A, B](xs: List[A]) def flatMap (f: A => List[B]): List[B] = xs.flatMap(f) def pure[A](x: A): List[A] = @@ -123,7 +123,7 @@ object Instances extends Common: class Token(str: String) object Token: - given StringToToken as Conversion[String, Token]: + given Conversion[String, Token] as stringToToken: def apply(str: String): Token = new Token(str) val x: Token = "if" @@ -231,9 +231,9 @@ object Completions: // // CompletionArg.from(statusCode) - given fromString as Conversion[String, CompletionArg] = Error(_) - given fromFuture as Conversion[Future[HttpResponse], CompletionArg] = Response(_) - given fromStatusCode as Conversion[Future[StatusCode], CompletionArg] = Status(_) + given Conversion[String, CompletionArg] as fromString = Error(_) + given Conversion[Future[HttpResponse], CompletionArg] as fromFuture = Response(_) + given Conversion[Future[StatusCode], CompletionArg] as fromStatusCode = Status(_) import CompletionArg._ def complete[T](arg: CompletionArg) = arg match diff --git a/tests/pos/the.scala b/tests/pos/the.scala index f8559450be23..3f3133aa74cb 100644 --- a/tests/pos/the.scala +++ b/tests/pos/the.scala @@ -2,7 +2,7 @@ object Test { trait Foo { type T; val x: T } - given intFoo as Foo { + given Foo as intFoo { type T = Int val x = 3 } diff --git a/tests/run-macros/i6988/FirstArg_1.scala b/tests/run-macros/i6988/FirstArg_1.scala index 09e096927332..5d1cb45ed416 100644 --- a/tests/run-macros/i6988/FirstArg_1.scala +++ b/tests/run-macros/i6988/FirstArg_1.scala @@ -2,7 +2,7 @@ package foo case class FirstArg(value: Any, source: String) object FirstArg { - inline given create as FirstArg = ${Macros.argsImpl} + inline given FirstArg as create = ${Macros.argsImpl} } object Macros { diff --git a/tests/run-macros/i9812b/Macro_1.scala b/tests/run-macros/i9812b/Macro_1.scala index b9ba7b6acbad..e71ee1c56409 100644 --- a/tests/run-macros/i9812b/Macro_1.scala +++ b/tests/run-macros/i9812b/Macro_1.scala @@ -16,31 +16,31 @@ object SomeEnum: object Bar: def apply[S <: SomeEnum](s: S): SomeEnum = new Bar(s) -given LiftFoo as Liftable[Foo.type]: +given Liftable[Foo.type] as liftFoo: def toExpr(x: Foo.type): Quotes ?=> Expr[Foo.type] = '{Foo} -given LiftBar[S <: SomeEnum: Type: Liftable] as Liftable[Bar[S]]: +given liftBar[S <: SomeEnum: Type: Liftable] as Liftable[Bar[S]]: def toExpr(x: Bar[S]): Quotes ?=> Expr[Bar[S]] = '{new Bar(${Lift(x.s)})} sealed abstract class Lst[+T] final case class CONS[+T](head: T, tail: Lst[T]) extends Lst[T] case object NIL extends Lst[Nothing] -given IntLiftable[T <: Int] as Liftable[T]: +given intLiftable[T <: Int] as Liftable[T]: def toExpr(x: T): Quotes ?=> Expr[T] = qctx ?=> { import quotes.reflect._ Literal(Constant.Int(x)).asExpr.asInstanceOf[Expr[T]] } -given LiftLst[T: Type: Liftable](using ev1: => Liftable[CONS[T]], ev2: => Liftable[NIL.type]) as Liftable[Lst[T]]: +given liftLst[T: Type: Liftable](using ev1: => Liftable[CONS[T]], ev2: => Liftable[NIL.type]) as Liftable[Lst[T]]: def toExpr(xs: Lst[T]): Quotes ?=> Expr[Lst[T]] = xs match case NIL => ev2.toExpr(NIL) case cons @ CONS(_, _) => ev1.toExpr(cons) -given LiftCONS[T: Type: Liftable](using Liftable[Lst[T]]) as Liftable[CONS[T]]: +given liftCONS[T: Type: Liftable](using Liftable[Lst[T]]) as Liftable[CONS[T]]: def toExpr(x: CONS[T]): Quotes ?=> Expr[CONS[T]] = '{CONS(${Lift(x.head)}, ${Lift(x.tail)})} -given LiftNIL as Liftable[NIL.type]: +given Liftable[NIL.type] as liftNIL: def toExpr(x: NIL.type): Quotes ?=> Expr[NIL.type] = '{NIL} def mkLst[T](ts: T*) = ts.foldRight(NIL: Lst[T])(CONS(_,_)) diff --git a/tests/run-macros/quote-matcher-symantics-3/quoted_1.scala b/tests/run-macros/quote-matcher-symantics-3/quoted_1.scala index 38915b73c66e..68d0fc440196 100644 --- a/tests/run-macros/quote-matcher-symantics-3/quoted_1.scala +++ b/tests/run-macros/quote-matcher-symantics-3/quoted_1.scala @@ -10,7 +10,7 @@ object Macros { type Env = Map[Int, Any] - given ev0 as Env = Map.empty + given Env as ev0 = Map.empty def envWith[T](id: Int, ref: Expr[R[T]])(using env: Env): Env = env.updated(id, ref) diff --git a/tests/run-staging/i6281.scala b/tests/run-staging/i6281.scala index 2f19bc641d1b..49087ba75f90 100644 --- a/tests/run-staging/i6281.scala +++ b/tests/run-staging/i6281.scala @@ -21,7 +21,7 @@ object Test extends App { def reify[A](using Type[A]): STM[A, L] => Expr[Stm[A, L]] def reflect[A](using Type[A]): Expr[Stm[A, L]] => STM[A, L] } - given empty as Effects[HNil] { + given Effects[HNil] as empty { def reify[A](using Type[A]) = m => m def reflect[A](using Type[A]) = m => m } diff --git a/tests/run-with-compiler/intmaptest.scala b/tests/run-with-compiler/intmaptest.scala index 90154290a310..542db120d15f 100644 --- a/tests/run-with-compiler/intmaptest.scala +++ b/tests/run-with-compiler/intmaptest.scala @@ -10,11 +10,11 @@ object Generator: val NumLimit = 300 val Iterations = 10000 - given integers as Generator[Int]: + given Generator[Int] as integers: val rand = new java.util.Random def generate = rand.nextInt() - given booleans as Generator[Boolean] = + given Generator[Boolean] as booleans = integers.map(x => x > 0) def range(end: Int): Generator[Int] = @@ -24,7 +24,7 @@ object Generator: case Lookup, Update, Remove export Op._ - given ops as Generator[Op] = + given Generator[Op] as ops = range(10).map { case 0 | 1 | 2 | 3 => Lookup case 4 | 5 | 6 | 7 => Update diff --git a/tests/run-with-compiler/maptest.scala b/tests/run-with-compiler/maptest.scala index 41f2da34551b..243216251c36 100644 --- a/tests/run-with-compiler/maptest.scala +++ b/tests/run-with-compiler/maptest.scala @@ -14,7 +14,7 @@ object Generator: val rand = new java.util.Random def generate = rand.nextInt() - given booleans as Generator[Boolean] = + given Generator[Boolean] as booleans = integers.map(x => x > 0) def range(end: Int): Generator[Int] = @@ -24,7 +24,7 @@ object Generator: case Lookup, Update, Remove export Op._ - given ops as Generator[Op] = + given Generator[Op] as ops = range(10).map { case 0 | 1 | 2 | 3 => Lookup case 4 | 5 | 6 | 7 => Update diff --git a/tests/run-with-compiler/settest.scala b/tests/run-with-compiler/settest.scala index 2d930ca3fdf9..d614079c8345 100644 --- a/tests/run-with-compiler/settest.scala +++ b/tests/run-with-compiler/settest.scala @@ -10,11 +10,11 @@ object Generator: val NumLimit = 300 val Iterations = 10000 - given integers as Generator[Int]: + given Generator[Int] as integers: val rand = new java.util.Random def generate = rand.nextInt() - given booleans as Generator[Boolean] = + given Generator[Boolean] as booleans = integers.map(x => x > 0) def range(end: Int): Generator[Int] = @@ -24,7 +24,7 @@ object Generator: case Lookup, Update, Remove export Op._ - given ops as Generator[Op] = + given Generator[Op] as ops = range(10).map { case 0 | 1 | 2 | 3 => Lookup case 4 | 5 | 6 | 7 => Update diff --git a/tests/run/Signals.scala b/tests/run/Signals.scala index 4125c804b855..12f1981269b9 100644 --- a/tests/run/Signals.scala +++ b/tests/run/Signals.scala @@ -28,7 +28,7 @@ package frp: object Signal: type Caller = Signal[?] - given noCaller as Caller(???): + given Caller(???) as noCaller: override def computeValue() = () end Signal diff --git a/tests/run/Signals1.scala b/tests/run/Signals1.scala index 4ef86d0603d4..a62fb5408478 100644 --- a/tests/run/Signals1.scala +++ b/tests/run/Signals1.scala @@ -43,7 +43,7 @@ package frp: end Var opaque type Caller = AbstractSignal[?] - given noCaller as Caller = new AbstractSignal[Nothing]: + given Caller as noCaller = new AbstractSignal[Nothing]: override def eval = ??? override def computeValue() = () diff --git a/tests/run/Typeable.scala b/tests/run/Typeable.scala index a3fdb6b26c57..b539fe185895 100644 --- a/tests/run/Typeable.scala +++ b/tests/run/Typeable.scala @@ -27,7 +27,7 @@ object Typeable: class instanceOf[T: Typeable]: def unapply(x: Any): Option[T] = Typeable[T].cast(x) - given int as Typeable[Int]: + given Typeable[Int] as int: def cast(x: Any): Option[Int] = x match case x: Int => Some(x) case _ => None diff --git a/tests/run/cochis-example.scala b/tests/run/cochis-example.scala index 4f32b00b6ddb..586ed6b0f585 100644 --- a/tests/run/cochis-example.scala +++ b/tests/run/cochis-example.scala @@ -5,7 +5,7 @@ trait A { def trans[X](x: X)(using f: X => X) = f(x) // (2) } object Test extends A with App{ - given succ as (Int => Int) = x => x + 1 // (3) + given (Int => Int) as succ = x => x + 1 // (3) def bad[X](x: X): X = trans[X](x) // (4) unstable definition ! val v1 = bad [Int] (3) // (5) evaluates to 3 assert(v1 == 3) diff --git a/tests/run/implicit-alias.scala b/tests/run/implicit-alias.scala index f10f85603175..9c9e3fb3d051 100644 --- a/tests/run/implicit-alias.scala +++ b/tests/run/implicit-alias.scala @@ -22,7 +22,7 @@ object Test extends App { locally{ println("= new") - given t as TC = new TC + given TC as t = new TC summon[TC] summon[TC] } @@ -34,7 +34,7 @@ object Test extends App { locally{ println("= new VC") - given t as TV = new TV(new TC) + given TV as t = new TV(new TC) summon[TV] summon[TV] } @@ -46,7 +46,7 @@ object Test extends App { val tcc = new TCC locally { println("= x.y") - given t as TC = tcc.tc + given TC as t = tcc.tc summon[TC] summon[TC] } diff --git a/tests/run/implicit-disambiguation.scala b/tests/run/implicit-disambiguation.scala index 881e4ec8083f..a8a903749afc 100644 --- a/tests/run/implicit-disambiguation.scala +++ b/tests/run/implicit-disambiguation.scala @@ -9,7 +9,7 @@ class C extends A { } object M { def f(using B, C): String = { - given a as A = summon[B] + given A as a = summon[B] summon[A].show } } diff --git a/tests/run/implicit-specifity.scala b/tests/run/implicit-specifity.scala index bfde7b414824..84203189bc15 100644 --- a/tests/run/implicit-specifity.scala +++ b/tests/run/implicit-specifity.scala @@ -2,13 +2,13 @@ case class Show[T](val i: Int) object Show { def apply[T](implicit st: Show[T]): Int = st.i - given showInt as Show[Int] = new Show[Int](0) + given Show[Int] as showInt = new Show[Int](0) given fallback[T] as Show[T] = new Show[T](1) } class Generic object Generic { - given gen as Generic = new Generic + given Generic as gen = new Generic given showGen[T](using Generic) as Show[T] = new Show[T](2) } diff --git a/tests/run/instances.scala b/tests/run/instances.scala index 6c3ea675ff5c..ebe7cd731070 100644 --- a/tests/run/instances.scala +++ b/tests/run/instances.scala @@ -46,7 +46,7 @@ object Test extends App { trait Monoid[T] extends SemiGroup[T]: def unit: T - given StringMonoid as Monoid[String]: + given Monoid[String] as stringMonoid: extension (x: String) def combine(y: String): String = x.concat(y) def unit: String = "" @@ -99,7 +99,7 @@ object Test extends App { def pure[A](x: A): F[A] end Monad - given listMonad as Monad[List]: + given Monad[List] as listMonad: extension [A, B](xs: List[A]) def flatMap (f: A => List[B]): List[B] = xs.flatMap(f) def pure[A](x: A): List[A] = diff --git a/tests/run/poly-kinded-derives.scala b/tests/run/poly-kinded-derives.scala index c98dcb9541e1..40a96280ba4a 100644 --- a/tests/run/poly-kinded-derives.scala +++ b/tests/run/poly-kinded-derives.scala @@ -58,8 +58,8 @@ object Test extends App { object Bifunctor { given [C] as Bifunctor[[T, U] =>> C] {} given Bifunctor[[T, U] =>> Tuple1[U]] {} - given t2 as Bifunctor[[T, U] =>> (T, U)] {} - given t3 [T] as Bifunctor[[U, V] =>> (T, U, V)] {} + given Bifunctor[[T, U] =>> (T, U)] as t2 {} + given [T] => Bifunctor[[U, V] =>> (T, U, V)] as t3 {} def derived[F[_, _]](using m: Mirror { type MirroredType[X, Y] = F[X, Y] ; type MirroredElemTypes[_, _] }, r: Bifunctor[m.MirroredElemTypes]): Bifunctor[F] = ??? } diff --git a/tests/run/tagless.scala b/tests/run/tagless.scala index 334a5a692e40..6c1e9ab68818 100644 --- a/tests/run/tagless.scala +++ b/tests/run/tagless.scala @@ -230,7 +230,7 @@ object Test extends App { import IExp._ // Going from type class encoding to ADT encoding - given initialize as Exp[IExp] { + given Exp[IExp] as initialize { def lit(i: Int): IExp = Lit(i) def neg(t: IExp): IExp = Neg(t) def add(l: IExp, r: IExp): IExp = Add(l, r) diff --git a/tests/semanticdb/expect/Givens.scala b/tests/semanticdb/expect/Givens.scala index be219b361924..15ccd76a6841 100644 --- a/tests/semanticdb/expect/Givens.scala +++ b/tests/semanticdb/expect/Givens.scala @@ -22,6 +22,6 @@ object Givens: def empty = "" extension (x: String) def combine(y: String) = x + y - inline given int2String as Conversion[Int, String] = _.toString + inline given Conversion[Int, String] as int2String = _.toString def foo[A](using A: Monoid[A]): A = A.combine(A.empty)(A.empty) From 924672b590ceb3bc535e0f69ce3d0e63ebe5f968 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 25 Nov 2020 21:49:22 +0100 Subject: [PATCH 06/14] Fix followingIsGivenSig --- compiler/src/dotty/tools/dotc/parsing/Parsers.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index 694aca6fc655..949b69cb4542 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -944,7 +944,7 @@ object Parsers { else if knownTypeNames.contains(suffixName.toTypeName) then true else if knownTypeNames.contains(prefixName.toTypeName) then - true + false else // we have one of the following // @@ -3587,7 +3587,7 @@ object Parsers { accept(ARROW) val vparams = params match case (_: ValDef) :: _ => - params.asInstanceOf[List[ValDef]].map(_.withFlags(Given)) + params.asInstanceOf[List[ValDef]].map(_.withFlags(Param | Given)) case _ => params.map(makeSyntheticParameter(nextIdx, _, Param | Synthetic | Given)) val (vparamss1, parents) = givenHead() From b9e39c5eee6b9f7bd5f23987893ca949f786d1fb Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 25 Nov 2020 22:22:35 +0100 Subject: [PATCH 07/14] Switch more tests to postfix as --- scala3doc-testcases/src/tests/givenDRI.scala | 8 ++++---- tests/neg/i8623.scala | 2 +- tests/neg/multi-param-derives.scala | 8 ++++---- tests/pos-custom-args/erased/i7868.scala | 2 +- tests/pos-macros/macro-docs.scala | 2 +- tests/pos/X.scala | 4 ++-- tests/pos/combine.scala | 2 +- tests/pos/givenFallback.scala | 2 +- tests/pos/i6864.scala | 2 +- tests/pos/i6900.scala | 2 +- tests/pos/i6938.scala | 6 +++--- tests/pos/i8344-1.scala | 2 +- tests/pos/i8397.scala | 4 ++-- tests/pos/i9342b.scala | 2 +- tests/pos/multiversal.scala | 2 +- tests/pos/reference/delegates.scala | 4 ++-- tests/run-macros/i7048/Lib_1.scala | 2 +- tests/run/fragables-extension.scala | 4 ++-- tests/run/i7788.scala | 2 +- tests/run/instances-anonymous.scala | 4 ++-- tests/run/poly-kinded-derives.scala | 10 +++++----- .../run/string-context-implicits-with-conversion.scala | 2 +- tests/run/tagless.scala | 4 ++-- tests/semanticdb/expect/Enums.expect.scala | 2 +- tests/semanticdb/expect/Enums.scala | 2 +- 25 files changed, 43 insertions(+), 43 deletions(-) diff --git a/scala3doc-testcases/src/tests/givenDRI.scala b/scala3doc-testcases/src/tests/givenDRI.scala index 16f35adc71e2..3258d3d05e94 100644 --- a/scala3doc-testcases/src/tests/givenDRI.scala +++ b/scala3doc-testcases/src/tests/givenDRI.scala @@ -10,15 +10,15 @@ given A[String] given A[Seq[String]] -given [T: A] as A[Option[T]] +given [T: A] => A[Option[T]] -given [T: B] as A[T] +given [T: B] => A[T] -given [C] as A[C] +given [C] => A[C] given A[C] -given [S <: C] as A[S] +given [S <: C] => A[S] class R: def a = 1 diff --git a/tests/neg/i8623.scala b/tests/neg/i8623.scala index 1cd01e598e93..4f9dc336fb61 100644 --- a/tests/neg/i8623.scala +++ b/tests/neg/i8623.scala @@ -6,7 +6,7 @@ trait QC: def pos: Tree = ??? def test = - given [T] as QC = ??? + given [T] => QC = ??? def unseal(using qctx: QC): qctx.tasty.Tree = ??? unseal.pos // error diff --git a/tests/neg/multi-param-derives.scala b/tests/neg/multi-param-derives.scala index 5c1ab411ed83..1cc99a1f7cbc 100644 --- a/tests/neg/multi-param-derives.scala +++ b/tests/neg/multi-param-derives.scala @@ -5,7 +5,7 @@ object Test extends App { trait Show[T] object Show { given Show[Int] {} - given [T](using st: Show[T]) as Show[Tuple1[T]] {} + given [T] => (st: Show[T]) => Show[Tuple1[T]] {} given t2[T, U](using st: Show[T], su: Show[U]) as Show[(T, U)] {} given t3[T, U, V](using st: Show[T], su: Show[U], sv: Show[V]) as Show[(T, U, V)] {} @@ -22,7 +22,7 @@ object Test extends App { { trait Functor[F[_]] object Functor { - given [C] as Functor[[T] =>> C] {} + given [C] => Functor[[T] =>> C] {} given Functor[[T] =>> Tuple1[T]] {} given t2 [T] as Functor[[U] =>> (T, U)] {} given t3 [T, U] as Functor[[V] =>> (T, U, V)] {} @@ -40,8 +40,8 @@ object Test extends App { { trait FunctorK[F[_[_]]] object FunctorK { - given [C] as FunctorK[[F[_]] =>> C] {} - given [T] as FunctorK[[F[_]] =>> Tuple1[F[T]]] + given [C] => FunctorK[[F[_]] =>> C] {} + given [T] => FunctorK[[F[_]] =>> Tuple1[F[T]]] def derived[F[_[_]]](using m: Mirror { type MirroredType[X[_]] = F[X] ; type MirroredElemTypes[_[_]] }, r: FunctorK[m.MirroredElemTypes]): FunctorK[F] = new FunctorK[F] {} } diff --git a/tests/pos-custom-args/erased/i7868.scala b/tests/pos-custom-args/erased/i7868.scala index 21d5f79ad93b..cc90a33d5896 100644 --- a/tests/pos-custom-args/erased/i7868.scala +++ b/tests/pos-custom-args/erased/i7868.scala @@ -21,7 +21,7 @@ object Coproduct { as At[Head +: Tail, Value, S[NextIndex]]: val cast: Value <:< Head +: Tail = atNext.cast - given [A](using A) as (() => A)= { () => summon[A]} + given [A] => (A) => (() => A)= { () => summon[A]} } def upCast[A, B](a: A)(using erased evidence: (A <:< B) ): B = a.asInstanceOf[B] diff --git a/tests/pos-macros/macro-docs.scala b/tests/pos-macros/macro-docs.scala index b1f7d4933934..c06feeb14daf 100644 --- a/tests/pos-macros/macro-docs.scala +++ b/tests/pos-macros/macro-docs.scala @@ -17,7 +17,7 @@ object MacrosMD_Liftable { } } - given [T: Liftable : Type] as Liftable[List[T]] { + given [T: Liftable : Type] => Liftable[List[T]] { def toExpr(xs: List[T]) = xs match { case head :: tail => '{ ${ Expr(head) } :: ${ toExpr(tail) } } case Nil => '{ Nil: List[T] } diff --git a/tests/pos/X.scala b/tests/pos/X.scala index 119aef885cac..9c72d564e537 100644 --- a/tests/pos/X.scala +++ b/tests/pos/X.scala @@ -2,8 +2,8 @@ import scala.deriving._ trait FunctorK[F[_[_]]] object FunctorK { - given [C] as FunctorK[[F[_]] =>> C] {} - given [T] as FunctorK[[F[_]] =>> Tuple1[F[T]]] + given [C] => FunctorK[[F[_]] =>> C] {} + given [T] => FunctorK[[F[_]] =>> Tuple1[F[T]]] def derived[F[_[_]]](using m: Mirror { type MirroredType[X[_]] = F[X] ; type MirroredElemTypes[_[_]] }, r: FunctorK[m.MirroredElemTypes]): FunctorK[F] = new FunctorK[F] {} } diff --git a/tests/pos/combine.scala b/tests/pos/combine.scala index fd7715b2ac19..c9217e593dc8 100644 --- a/tests/pos/combine.scala +++ b/tests/pos/combine.scala @@ -2,7 +2,7 @@ trait Semigroup[A] { extension (x: A) def combine(y: A): A } given Semigroup[Int] = ??? -given [A, B](using Semigroup[A], Semigroup[B]) as Semigroup[(A, B)] = ??? +given [A, B] => (Semigroup[A], Semigroup[B]) => Semigroup[(A, B)] = ??? object Test extends App { ((1, 1)) combine ((2, 2)) // doesn't compile ((1, 1): (Int, Int)) combine (2, 2) // compiles diff --git a/tests/pos/givenFallback.scala b/tests/pos/givenFallback.scala index 8581194291b5..768777d45dc0 100644 --- a/tests/pos/givenFallback.scala +++ b/tests/pos/givenFallback.scala @@ -1,6 +1,6 @@ trait TC[T] { def x: Int; def y: Int = 0 } -given [T] as TC[T] { +given [T] => TC[T] { inline val x = 1 } diff --git a/tests/pos/i6864.scala b/tests/pos/i6864.scala index 60ce1238f164..fc724a2aedad 100644 --- a/tests/pos/i6864.scala +++ b/tests/pos/i6864.scala @@ -14,4 +14,4 @@ trait C trait Baz[A] given C -given [A] as Baz[A] \ No newline at end of file +given [A] => Baz[A] \ No newline at end of file diff --git a/tests/pos/i6900.scala b/tests/pos/i6900.scala index 45313c21921e..8523f94c283d 100644 --- a/tests/pos/i6900.scala +++ b/tests/pos/i6900.scala @@ -8,7 +8,7 @@ object Test1 { // But not with newstyle /* - given [A] as Conversion[A, Foo[A]]: + given [A] => Conversion[A, Foo[A]]: def apply(a: A) = new Foo[A]: def foo[C]: C => A = _ => a */ diff --git a/tests/pos/i6938.scala b/tests/pos/i6938.scala index f4955e115ba3..b89a103400e3 100644 --- a/tests/pos/i6938.scala +++ b/tests/pos/i6938.scala @@ -1,5 +1,5 @@ trait Foo[T] object Foo: - given [T] as Foo[Tuple1[T]] - given [T, U] as Foo[(T, U)] - given [T, U, V] as Foo[(T, U, V)] \ No newline at end of file + given [T] => Foo[Tuple1[T]] + given [T, U] => Foo[(T, U)] + given [T, U, V] => Foo[(T, U, V)] \ No newline at end of file diff --git a/tests/pos/i8344-1.scala b/tests/pos/i8344-1.scala index 48aae05e38b2..bd931d15cd9e 100644 --- a/tests/pos/i8344-1.scala +++ b/tests/pos/i8344-1.scala @@ -5,7 +5,7 @@ enum Datatype[T] { } object Datatype { - given [H, T <: STuple](using ht: Datatype[H], tt: Datatype[T]) as Datatype[H *: T] = tt match { + given [H, T <: STuple] => (ht: Datatype[H], tt: Datatype[T]) => Datatype[H *: T] = tt match { case Datatype.Tuple(elems) => Datatype.Tuple(ht *: elems) } } diff --git a/tests/pos/i8397.scala b/tests/pos/i8397.scala index dd1a00c27fa1..ec3bd2bda3e9 100644 --- a/tests/pos/i8397.scala +++ b/tests/pos/i8397.scala @@ -6,13 +6,13 @@ given foo(using x: Int) as AnyRef: trait Lub2[A, B]: type Output -given [A <: C, B <: C, C] as Lub2[A, B]: +given [A <: C, B <: C, C] => Lub2[A, B]: type Output = C trait Lub[Union]: type Output -given [A] as Lub[A]: +given [A] => Lub[A]: type Output = A given [Left, Right]( diff --git a/tests/pos/i9342b.scala b/tests/pos/i9342b.scala index c6712c00236f..36093876e989 100644 --- a/tests/pos/i9342b.scala +++ b/tests/pos/i9342b.scala @@ -1,7 +1,7 @@ trait Label[A]: def apply(v: A): String -given [A] as Label[A] = _.toString +given [A] => Label[A] = _.toString extension [A](x: A) inline def label(using inline l: Label[A]): String = l(x) diff --git a/tests/pos/multiversal.scala b/tests/pos/multiversal.scala index 89364910281b..d019f0d1b6c8 100644 --- a/tests/pos/multiversal.scala +++ b/tests/pos/multiversal.scala @@ -1,7 +1,7 @@ object Test { import scala.CanEqual - given [X, Y](using CanEqual[X, Y]) as CanEqual[List[X], List[Y]] = CanEqual.derived + given [X, Y] => (CanEqual[X, Y]) => CanEqual[List[X], List[Y]] = CanEqual.derived val b: Byte = 1 val c: Char = 2 diff --git a/tests/pos/reference/delegates.scala b/tests/pos/reference/delegates.scala index 65ec665705ec..9c205db52212 100644 --- a/tests/pos/reference/delegates.scala +++ b/tests/pos/reference/delegates.scala @@ -145,7 +145,7 @@ object AnonymousInstances extends Common: extension (x: Int) def compareTo(y: Int) = if (x < y) -1 else if (x > y) +1 else 0 - given [T: Ord] as Ord[List[T]]: + given [T: Ord] => Ord[List[T]]: extension (xs: List[T]) def compareTo(ys: List[T]): Int = (xs, ys).match case (Nil, Nil) => 0 case (Nil, _) => -1 @@ -162,7 +162,7 @@ object AnonymousInstances extends Common: extension [T](xs: List[T]) def second = xs.tail.head - given [From, To](using c: Convertible[From, To]) as Convertible[List[From], List[To]]: + given [From, To] => (c: Convertible[From, To]) => Convertible[List[From], List[To]]: extension (x: List[From]) def convert: List[To] = x.map(c.convert) given Monoid[String]: diff --git a/tests/run-macros/i7048/Lib_1.scala b/tests/run-macros/i7048/Lib_1.scala index 1cb1c0465342..7595bec5a997 100644 --- a/tests/run-macros/i7048/Lib_1.scala +++ b/tests/run-macros/i7048/Lib_1.scala @@ -5,7 +5,7 @@ trait IsExpr[T] { def toExpr(x: T): Expr[Underlying] } -given [U] as IsExpr[Expr[U]] = new IsExpr[Expr[U]] { +given [U] => IsExpr[Expr[U]] = new IsExpr[Expr[U]] { type Underlying = U def toExpr(x: Expr[U]): Expr[U] = x } diff --git a/tests/run/fragables-extension.scala b/tests/run/fragables-extension.scala index 9476d1efd191..1fc738af25d8 100644 --- a/tests/run/fragables-extension.scala +++ b/tests/run/fragables-extension.scala @@ -11,11 +11,11 @@ given Fragable[Int] = x => List(IntFrag(x)) given Fragable[String] = x => List(StringFrag(x)) -given [A: Fragable] as Fragable[List[A]] = +given [A: Fragable] => Fragable[List[A]] = x => x.flatMap(_.toFrags) given Fragable[EmptyTuple] = x => Nil -given [A: Fragable, B <: Tuple: Fragable] as Fragable[A *: B] = +given [A: Fragable, B <: Tuple: Fragable] => Fragable[A *: B] = x => x.head.toFrags ++ x.tail.toFrags def f[T: Fragable](x: T) = diff --git a/tests/run/i7788.scala b/tests/run/i7788.scala index e20287e5b936..edcc0b1b46e3 100644 --- a/tests/run/i7788.scala +++ b/tests/run/i7788.scala @@ -6,7 +6,7 @@ given Show[Int] = _.toString given showEither[A,B](using sA: Show[A])(using Show[B]) as Show[Either[A,B]] = _.fold(a => s"Left(${summon[Show[A]].show(a)})", b => s"Right(${summon[Show[B]].show(b)})") -given [A,B](using sA: Show[A])(using sB: Show[B]) as Show[(A,B)] = (a,b) => s"(${sA.show(a)}), ${sB.show(b)})" +given [A,B] => (sA: Show[A]) => (sB: Show[B]) => Show[(A,B)] = (a,b) => s"(${sA.show(a)}), ${sB.show(b)})" @main def Test = diff --git a/tests/run/instances-anonymous.scala b/tests/run/instances-anonymous.scala index 6df12e5d52e7..c317e824016f 100644 --- a/tests/run/instances-anonymous.scala +++ b/tests/run/instances-anonymous.scala @@ -69,7 +69,7 @@ object Test extends App { val minimum = Int.MinValue } - given [T: Ord] as Ord[List[T]] { + given [T: Ord] => Ord[List[T]] { extension (xs: List[T]) def compareTo(ys: List[T]): Int = (xs, ys).match { case (Nil, Nil) => 0 case (Nil, _) => -1 @@ -108,7 +108,7 @@ object Test extends App { List(x) } - given [Ctx] as Monad[[X] =>> Ctx => X] { + given [Ctx] => Monad[[X] =>> Ctx => X] { extension [A, B](r: Ctx => A) def flatMap (f: A => Ctx => B): Ctx => B = ctx => f(r(ctx))(ctx) def pure[A](x: A): Ctx => A = diff --git a/tests/run/poly-kinded-derives.scala b/tests/run/poly-kinded-derives.scala index 40a96280ba4a..45508da8be8a 100644 --- a/tests/run/poly-kinded-derives.scala +++ b/tests/run/poly-kinded-derives.scala @@ -5,7 +5,7 @@ object Test extends App { trait Show[T] object Show { given Show[Int] {} - given [T](using st: Show[T]) as Show[Tuple1[T]] + given [T] => (st: Show[T]) => Show[Tuple1[T]] given t2[T, U](using st: Show[T], su: Show[U]) as Show[(T, U)] given t3 [T, U, V](using st: Show[T], su: Show[U], sv: Show[V]) as Show[(T, U, V)] @@ -22,7 +22,7 @@ object Test extends App { { trait Functor[F[_]] object Functor { - given [C] as Functor[[T] =>> C] {} + given [C] => Functor[[T] =>> C] {} given Functor[[T] =>> Tuple1[T]] {} given t2 [T] as Functor[[U] =>> (T, U)] {} given t3 [T, U] as Functor[[V] =>> (T, U, V)] {} @@ -40,8 +40,8 @@ object Test extends App { { trait FunctorK[F[_[_]]] object FunctorK { - given [C] as FunctorK[[F[_]] =>> C] {} - given [T] as FunctorK[[F[_]] =>> Tuple1[F[T]]] + given [C] => FunctorK[[F[_]] =>> C] {} + given [T] => FunctorK[[F[_]] =>> Tuple1[F[T]]] def derived[F[_[_]]](using m: Mirror { type MirroredType[X[_]] = F[X] ; type MirroredElemTypes[_[_]] }, r: FunctorK[m.MirroredElemTypes]): FunctorK[F] = new FunctorK[F] {} } @@ -56,7 +56,7 @@ object Test extends App { { trait Bifunctor[F[_, _]] object Bifunctor { - given [C] as Bifunctor[[T, U] =>> C] {} + given [C] => Bifunctor[[T, U] =>> C] {} given Bifunctor[[T, U] =>> Tuple1[U]] {} given Bifunctor[[T, U] =>> (T, U)] as t2 {} given [T] => Bifunctor[[U, V] =>> (T, U, V)] as t3 {} diff --git a/tests/run/string-context-implicits-with-conversion.scala b/tests/run/string-context-implicits-with-conversion.scala index 54e52ebdda8d..41e4c3170181 100644 --- a/tests/run/string-context-implicits-with-conversion.scala +++ b/tests/run/string-context-implicits-with-conversion.scala @@ -4,7 +4,7 @@ object Lib { opaque type Showed = String - given [T](using show: Show[T]) as Conversion[T, Showed] = x => show(x) + given [T] => (show: Show[T]) => Conversion[T, Showed] = x => show(x) trait Show[T] { def apply(x: T): String diff --git a/tests/run/tagless.scala b/tests/run/tagless.scala index 6c1e9ab68818..c68c1a5e5947 100644 --- a/tests/run/tagless.scala +++ b/tests/run/tagless.scala @@ -196,7 +196,7 @@ object Test extends App { // Added operation: negation pushdown enum NCtx { case Pos, Neg } - given [T](using e: Exp[T]) as Exp[NCtx => T] { + given [T] => (e: Exp[T]) => Exp[NCtx => T] { import NCtx._ def lit(i: Int) = { case Pos => e.lit(i) @@ -216,7 +216,7 @@ object Test extends App { println(pushNeg(tf1[NCtx => String])) println(pushNeg(pushNeg(pushNeg(tf1))): String) - given [T](using e: Mult[T]) as Mult[NCtx => T] { + given [T] => (e: Mult[T]) => Mult[NCtx => T] { import NCtx._ def mul(l: NCtx => T, r: NCtx => T): NCtx => T = { case Pos => e.mul(l(Pos), r(Pos)) diff --git a/tests/semanticdb/expect/Enums.expect.scala b/tests/semanticdb/expect/Enums.expect.scala index 1fc2256cee59..5d3e10ece49b 100644 --- a/tests/semanticdb/expect/Enums.expect.scala +++ b/tests/semanticdb/expect/Enums.expect.scala @@ -47,7 +47,7 @@ object Enums/*<-_empty_::Enums.*/: case Refl/*<-_empty_::Enums.`<:<`.Refl#*/[C/*<-_empty_::Enums.`<:<`.Refl#[C]*/]() extends (C/*->_empty_::Enums.`<:<`.Refl#[C]*/ <:_empty_::Enums.`<:<`#*/ C/*->_empty_::Enums.`<:<`.Refl#[C]*/) object <:_empty_::Enums.`<:<`.given_T().[T]*/ <:_empty_::Enums.`<:<`#*/ T/*->_empty_::Enums.`<:<`.given_T().[T]*/) = Refl/*->_empty_::Enums.`<:<`.Refl.*//*->_empty_::Enums.`<:<`.Refl.apply().*/() + given [T] => /*<-_empty_::Enums.`<:<`.given_T().*//*<-_empty_::Enums.`<:<`.given_T().[T]*/(T/*->_empty_::Enums.`<:<`.given_T().[T]*/ <:_empty_::Enums.`<:<`#*/ T/*->_empty_::Enums.`<:<`.given_T().[T]*/) = Refl/*->_empty_::Enums.`<:<`.Refl.*//*->_empty_::Enums.`<:<`.Refl.apply().*/() extension [A/*<-_empty_::Enums.unwrap().[A]*/, B/*<-_empty_::Enums.unwrap().[B]*/](opt/*<-_empty_::Enums.unwrap().(opt)*/: Option/*->scala::Option#*/[A/*->_empty_::Enums.unwrap().[A]*/]) def unwrap/*<-_empty_::Enums.unwrap().*/(using ev/*<-_empty_::Enums.unwrap().(ev)*/: A/*->_empty_::Enums.unwrap().[A]*/ <:_empty_::Enums.`<:<`#*/ Option/*->scala::Option#*/[B/*->_empty_::Enums.unwrap().[B]*/]): Option/*->scala::Option#*/[B/*->_empty_::Enums.unwrap().[B]*/] = ev/*->_empty_::Enums.unwrap().(ev)*/ match case Refl/*->_empty_::Enums.`<:<`.Refl.*//*->_empty_::Enums.`<:<`.Refl.unapply().*/() => opt/*->_empty_::Enums.unwrap().(opt)*/.flatMap/*->scala::Option#flatMap().*/(identity/*->scala::Predef.identity().*//*->local0*/[Option/*->scala::Option#*/[B/*->_empty_::Enums.unwrap().[B]*/]]) diff --git a/tests/semanticdb/expect/Enums.scala b/tests/semanticdb/expect/Enums.scala index 56ed483b2d76..d96a1b4c4c08 100644 --- a/tests/semanticdb/expect/Enums.scala +++ b/tests/semanticdb/expect/Enums.scala @@ -47,7 +47,7 @@ object Enums: case Refl[C]() extends (C <:< C) object <:< : - given [T] as (T <:< T) = Refl() + given [T] => (T <:< T) = Refl() extension [A, B](opt: Option[A]) def unwrap(using ev: A <:< Option[B]): Option[B] = ev match case Refl() => opt.flatMap(identity[Option[B]]) From 4901185e981f1e50e60c0a3f73f10eeb2c85162e Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 25 Nov 2020 22:26:07 +0100 Subject: [PATCH 08/14] Update semanticdb expect files --- tests/semanticdb/expect/Givens.expect.scala | 2 +- tests/semanticdb/metac.expect | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/semanticdb/expect/Givens.expect.scala b/tests/semanticdb/expect/Givens.expect.scala index b037af9da2ca..06baa732eaa9 100644 --- a/tests/semanticdb/expect/Givens.expect.scala +++ b/tests/semanticdb/expect/Givens.expect.scala @@ -22,6 +22,6 @@ object Givens/*<-a::b::Givens.*/: /*<-a::b::Givens.given_Monoid_String.*//*->a::b::Givens.Monoid#*//*->scala::Predef.String#*/ def empty/*<-a::b::Givens.given_Monoid_String.empty().*/ = "" extension (x/*<-a::b::Givens.given_Monoid_String.combine().(x)*/: String/*->scala::Predef.String#*/) def combine/*<-a::b::Givens.given_Monoid_String.combine().*/(y/*<-a::b::Givens.given_Monoid_String.combine().(y)*/: String/*->scala::Predef.String#*/) = x/*->a::b::Givens.given_Monoid_String.combine().(x)*/ +/*->java::lang::String#`+`().*/ y/*->a::b::Givens.given_Monoid_String.combine().(y)*/ - inline given int2String/*<-a::b::Givens.int2String().*/ as Conversion/*->scala::Conversion#*/[Int/*->scala::Int#*/, String/*->scala::Predef.String#*/] = _.toString/*->scala::Any#toString().*/ + inline given Conversion/*<-a::b::Givens.int2String().*//*->scala::Conversion#*/[Int/*->scala::Int#*/, String/*->scala::Predef.String#*/] as int2String = _.toString/*->scala::Any#toString().*/ def foo/*<-a::b::Givens.foo().*/[A/*<-a::b::Givens.foo().[A]*/](using A/*<-a::b::Givens.foo().(A)*/: Monoid/*->a::b::Givens.Monoid#*/[A/*->a::b::Givens.foo().[A]*/]): A/*->a::b::Givens.foo().[A]*/ = A/*->a::b::Givens.foo().(A)*/.combine/*->a::b::Givens.Monoid#combine().*/(A/*->a::b::Givens.foo().(A)*/.empty/*->a::b::Givens.Monoid#empty().*/)(A/*->a::b::Givens.foo().(A)*/.empty/*->a::b::Givens.Monoid#empty().*/) diff --git a/tests/semanticdb/metac.expect b/tests/semanticdb/metac.expect index 521c8773312d..bb5f05c680a3 100644 --- a/tests/semanticdb/metac.expect +++ b/tests/semanticdb/metac.expect @@ -936,7 +936,7 @@ Occurrences: [46:34..46:35): C -> _empty_/Enums.`<:<`.Refl#[C] [46:35..46:35): -> _empty_/Enums.`<:<`#``(). [48:9..48:12): <:< <- _empty_/Enums.`<:<`. -[49:10..49:17): [T] as <- _empty_/Enums.`<:<`.given_T(). +[49:10..49:17): [T] => <- _empty_/Enums.`<:<`.given_T(). [49:11..49:12): T <- _empty_/Enums.`<:<`.given_T().[T] [49:18..49:19): T -> _empty_/Enums.`<:<`.given_T().[T] [49:20..49:23): <:< -> _empty_/Enums.`<:<`# @@ -1316,10 +1316,10 @@ Occurrences: [22:51..22:52): x -> a/b/Givens.given_Monoid_String.combine().(x) [22:53..22:54): + -> java/lang/String#`+`(). [22:55..22:56): y -> a/b/Givens.given_Monoid_String.combine().(y) -[24:15..24:25): int2String <- a/b/Givens.int2String(). -[24:29..24:39): Conversion -> scala/Conversion# -[24:40..24:43): Int -> scala/Int# -[24:45..24:51): String -> scala/Predef.String# +[24:15..24:25): Conversion <- a/b/Givens.int2String(). +[24:15..24:25): Conversion -> scala/Conversion# +[24:26..24:29): Int -> scala/Int# +[24:31..24:37): String -> scala/Predef.String# [24:57..24:65): toString -> scala/Any#toString(). [26:6..26:9): foo <- a/b/Givens.foo(). [26:10..26:11): A <- a/b/Givens.foo().[A] From 1cf5c4da9c6e28b823467bf47db5ef6ea127743b Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 26 Nov 2020 11:31:23 +0100 Subject: [PATCH 09/14] Refactorings: maybeParams Niw is parameterized to also accept regular param clauses with default parameters. --- .../dotty/tools/dotc/parsing/Parsers.scala | 137 ++++++++++-------- docs/docs/internals/syntax.md | 2 +- tests/neg/functiontypes.scala | 4 + tests/run/implied-priority.scala | 2 +- 4 files changed, 79 insertions(+), 66 deletions(-) create mode 100644 tests/neg/functiontypes.scala diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index 949b69cb4542..b3e33360ce78 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -968,6 +968,10 @@ object Parsers { val next = in.lookahead.token next == LBRACKET || next == LPAREN + def followingIsParam(): Boolean = + startParamTokens.contains(in.token) + || isIdent && (in.name == nme.inline || in.lookahead.token == COLON) + /* --------- OPERAND/OPERATOR STACK --------------------------------------- */ var opStack: List[OpInfo] = Nil @@ -1441,7 +1445,8 @@ object Parsers { val t = if in.token == LPAREN then - afterArguments(x => infixTypeRest(refinedTypeRest(withTypeRest(x))), functionRest) + def normalTypeRest(t: Tree) = infixTypeRest(refinedTypeRest(withTypeRest(t))) + maybeParams(typedFunParams, normalTypeRest, functionRest) else if (in.token == LBRACKET) { val tparams = typeParamClause(ParamOwner.TypeParam) if (in.token == TLARROW) @@ -1474,14 +1479,18 @@ object Parsers { } } - def funArgTypesRest(first: Tree, following: () => Tree): List[Tree] = - val buf = new ListBuffer[Tree] += first - while in.token == COMMA do - in.nextToken() - buf += following() - buf.toList - - def afterArguments[T](parseSimple: Tree => T, parseFn: (List[Tree], Modifiers) => T): T = + /** Either a parameter list, which then needs to be followed by `=>` or + * a type or constructor application. + * + * @param parseParams The parsing method for the parameters inside `(...)` + * @param parseSimple The parsing continuation if the prefix is not a parameter list + * or the prefix is not followed by `=>` or `?=>` + * @param parseFn The parsing continuation to follow otherwise. + */ + def maybeParams[T]( + parseParams: Modifiers => List[ValDef], + parseSimple: Tree => T, + parseFn: (List[Tree], Modifiers) => T): T = val start = in.offset in.nextToken() var imods = Modifiers() @@ -1493,17 +1502,11 @@ object Parsers { openParens.change(LPAREN, 1) imods = modifiers(funTypeArgMods) val paramStart = in.offset - val ts = funArgType() match - case Ident(name) if name != tpnme.WILDCARD && in.token == COLON => - isValParamList = true - funArgTypesRest( - typedFunParam(paramStart, name.toTermName, imods), - () => typedFunParam(in.offset, ident(), imods)) - case t => - funArgTypesRest(t, funArgType) + val isParams = followingIsParam() + val ts = if isParams then parseParams(imods) else funArgTypes() openParens.change(LPAREN, -1) accept(RPAREN) - if isValParamList || in.token == ARROW || in.token == CTXARROW then + if isParams || in.token == ARROW || in.token == CTXARROW then parseFn(ts, imods) else val ts1 = @@ -1516,7 +1519,7 @@ object Parsers { t val tuple = atSpan(start) { makeTupleOrParens(ts1) } parseSimple(annotTypeRest(simpleTypeRest(tuple))) - end afterArguments + end maybeParams private def makeKindProjectorTypeDef(name: TypeName): TypeDef = TypeDef(name, WildcardTypeBoundsTree()).withFlags(Param) @@ -1548,10 +1551,12 @@ object Parsers { makeParameter(name, typ(), mods) } + def typedFunParams(mods: Modifiers = EmptyModifiers): List[ValDef] = + commaSeparated(() => typedFunParam(in.offset, ident(), mods)) + /** FunParamClause ::= ‘(’ TypedFunParam {‘,’ TypedFunParam } ‘)’ */ - def funParamClause(): List[ValDef] = - inParens(commaSeparated(() => typedFunParam(in.offset, ident()))) + def funParamClause(): List[ValDef] = inParens(typedFunParams()) def funParamClauses(): List[List[ValDef]] = if in.token == LPAREN then funParamClause() :: funParamClauses() else Nil @@ -1796,6 +1801,10 @@ object Parsers { if (in.token == ARROW) atSpan(in.skipToken()) { ByNameTypeTree(typ()) } else typ() + /** FunArgTypes ::= FunArgType { `,` FunArgType} + */ + def funArgTypes(): List[Tree] = commaSeparated(funArgType) + /** ParamType ::= [`=>'] ParamValueType */ def paramType(): Tree = @@ -2965,28 +2974,23 @@ object Parsers { * * Param ::= id `:' ParamType [`=' Expr] * + * The method here does not parse the outer `(...)` or any "head" modifiers + * in `erased`, `using`, `given`; this has to be done in the caller. * @return the list of parameter definitions */ - def paramClause(nparams: Int, // number of parameters preceding this clause + def paramClause(hmods: Modifiers, // parsed modifiers at start of clause + nparams: Int = 0, // number of parameters preceding this clause ofClass: Boolean = false, // owner is a class ofCaseClass: Boolean = false, // owner is a case class prefix: Boolean = false, // clause precedes name of an extension method givenOnly: Boolean = false, // only given parameters allowed firstClause: Boolean = false // clause is the first in regular list of clauses - ): List[ValDef] = { - var impliedMods: Modifiers = EmptyModifiers - - def addParamMod(mod: () => Mod) = impliedMods = addMod(impliedMods, atSpan(in.skipToken()) { mod() }) - - def paramMods() = - if in.token == IMPLICIT then addParamMod(() => Mod.Implicit()) - else - if isIdent(nme.using) then addParamMod(() => Mod.Given()) - if in.token == ERASED then addParamMod(() => Mod.Erased()) + ): List[ValDef] = + var headMods: Modifiers = hmods def param(): ValDef = { val start = in.offset - var mods = impliedMods.withAnnotations(annotations()) + var mods = headMods.withAnnotations(annotations()) if (ofClass) { mods = addFlag(modifiers(start = mods), ParamAccessor) mods = @@ -2997,7 +3001,7 @@ object Parsers { val mod = atSpan(in.skipToken()) { Mod.Var() } addMod(mods, mod) else - if (!(mods.flags &~ (ParamAccessor | Inline | impliedMods.flags)).isEmpty) + if (!(mods.flags &~ (ParamAccessor | Inline | headMods.flags)).isEmpty) syntaxError("`val` or `var` expected") if (firstClause && ofCaseClass) mods else mods | PrivateLocal @@ -3016,8 +3020,8 @@ object Parsers { val default = if (in.token == EQUALS) { in.nextToken(); subExpr() } else EmptyTree - if (impliedMods.mods.nonEmpty) - impliedMods = impliedMods.withMods(Nil) // keep only flags, so that parameter positions don't overlap + if (headMods.mods.nonEmpty) + headMods = headMods.withMods(Nil) // keep only flags, so that parameter positions don't overlap ValDef(name, tpt, default).withMods(mods) } } @@ -3034,26 +3038,21 @@ object Parsers { checkVarArgsRules(rest) } - // begin paramClause - inParens { - if in.token == RPAREN && !prefix && !impliedMods.is(Given) then Nil - else - val clause = - if prefix then param() :: Nil + if in.token == RPAREN && !prefix && headMods.flags.isEmpty then + Nil + else + val clause = + if prefix then param() :: Nil + else + if givenOnly && !headMods.is(Given) then + syntaxError("`using` expected") + if !headMods.is(Given) || followingIsParam() then + commaSeparated(param) else - paramMods() - if givenOnly && !impliedMods.is(Given) then - syntaxError("`using` expected") - val isParams = - !impliedMods.is(Given) - || startParamTokens.contains(in.token) - || isIdent && (in.name == nme.inline || in.lookahead.token == COLON) - if isParams then commaSeparated(() => param()) - else contextTypes(ofClass, nparams) - checkVarArgsRules(clause) - clause - } - } + contextTypes(ofClass, nparams) + checkVarArgsRules(clause) + clause + end paramClause /** ClsParamClauses ::= {ClsParamClause} [[nl] ‘(’ [‘implicit’] ClsParams ‘)’] * DefParamClauses ::= {DefParamClause} [[nl] ‘(’ [‘implicit’] DefParams ‘)’] @@ -3067,13 +3066,22 @@ object Parsers { def recur(firstClause: Boolean, nparams: Int): List[List[ValDef]] = newLineOptWhenFollowedBy(LPAREN) if in.token == LPAREN then - val paramsStart = in.offset - val params = paramClause( - nparams, - ofClass = ofClass, - ofCaseClass = ofCaseClass, - givenOnly = givenOnly, - firstClause = firstClause) + val params = inParens { + var headMods: Modifiers = EmptyModifiers + def addParamMod(mod: () => Mod) = + headMods = addMod(headMods, atSpan(in.skipToken()) { mod() }) + if in.token == IMPLICIT then addParamMod(() => Mod.Implicit()) + else + if isIdent(nme.using) then addParamMod(() => Mod.Given()) + if in.token == ERASED then addParamMod(() => Mod.Erased()) + paramClause( + headMods, + nparams, + ofClass = ofClass, + ofCaseClass = ofCaseClass, + givenOnly = givenOnly, + firstClause = firstClause) + } val lastClause = params.nonEmpty && params.head.mods.flags.is(Implicit) params :: ( if lastClause then Nil @@ -3596,12 +3604,13 @@ object Parsers { (Nil, constrAppsRest(constrAppRest(t), commaOK = true)) def givenHead(): (List[List[ValDef]], List[Tree]) = if in.token == LPAREN then - afterArguments(givenHeadFinish, givenHeadRest) + maybeParams(paramClause(_), givenHeadFinish, givenHeadRest) else val constr = constrOrSimpleType() if in.token == ARROW then givenHeadRest(constr :: Nil, EmptyModifiers) else givenHeadFinish(constr) val (vparamss, parents) = givenHead() + newLinesOptWhenFollowedBy(nme.as) val name = if in.isIdent(nme.as) then in.nextToken() @@ -3637,7 +3646,7 @@ object Parsers { def extension(): ExtMethods = val start = in.skipToken() val tparams = typeParamClauseOpt(ParamOwner.Def) - val extParams = paramClause(0, prefix = true) + val extParams = inParens(paramClause(EmptyModifiers, prefix = true)) val givenParamss = paramClauses(givenOnly = true) in.observeColonEOL() if (in.token == COLONEOL) in.nextToken() diff --git a/docs/docs/internals/syntax.md b/docs/docs/internals/syntax.md index 7d2f3d18ef4e..3cf7345eeaa8 100644 --- a/docs/docs/internals/syntax.md +++ b/docs/docs/internals/syntax.md @@ -176,7 +176,7 @@ FunArgType ::= Type | ‘=>’ Type PrefixOp(=>, t) ParamType ::= [‘=>’] ParamValueType ParamValueType ::= Type [‘*’] PostfixOp(t, "*") -TypeArgs ::= ‘[’ Types ‘]’ ts +TypeArgs ::= ‘[’ Types ‘]’ ts Refinement ::= ‘{’ [RefineDcl] {semi [RefineDcl]} ‘}’ ds TypeBounds ::= [‘>:’ Type] [‘<:’ Type] TypeBoundsTree(lo, hi) TypeParamBounds ::= TypeBounds {‘:’ Type} ContextBounds(typeBounds, tps) diff --git a/tests/neg/functiontypes.scala b/tests/neg/functiontypes.scala new file mode 100644 index 000000000000..e101287c6412 --- /dev/null +++ b/tests/neg/functiontypes.scala @@ -0,0 +1,4 @@ +type T = (=> Int) => Int +type U = (x: => Int) => Int // error, named parameter cannot be cbn since cbn dependent function types are not allowed. +type V = _ => Int +type W = (_) => Boolean diff --git a/tests/run/implied-priority.scala b/tests/run/implied-priority.scala index 5f3a514bcc03..3ec5bde9e76c 100644 --- a/tests/run/implied-priority.scala +++ b/tests/run/implied-priority.scala @@ -134,7 +134,7 @@ object HigherPriority { } object fallback5 { - given [T](using ev: E[T] = new E[T]("fallback")) as (E[T] & HigherPriority.Type) = HigherPriority.inject(ev) + given [T] => (ev: E[T] = new E[T]("fallback")) => (E[T] & HigherPriority.Type) = HigherPriority.inject(ev) } def test5 = { From 5f52f0cc6f51044442022e7f47b9d3336ea0b8e4 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 26 Nov 2020 12:37:32 +0100 Subject: [PATCH 10/14] Convert more tests to postfix as --- .../src/tests/givenSignatures.scala | 6 ++--- .../pos-macros/i7853/JsonEncoder_1.scala | 2 +- tests/disabled/pos/i8311.scala | 2 +- tests/init/crash/i6914.scala | 4 ++-- tests/neg/eql.scala | 2 +- tests/neg/i5978.scala | 5 ++-- tests/neg/i7248.scala | 2 +- tests/neg/i7249.scala | 2 +- tests/neg/i7294-a.scala | 2 +- tests/neg/i7294-b.scala | 2 +- tests/neg/i7459.scala | 2 +- tests/neg/missing-implicit2.scala | 4 ++-- tests/neg/missing-implicit3.scala | 2 +- tests/neg/multi-param-derives.scala | 4 ++-- tests/pending/pos/i10161.scala | 4 ++-- tests/pos-custom-args/erased/i7868.scala | 2 +- tests/pos-custom-args/erased/i7878.scala | 2 +- tests/pos/i5915.scala | 4 ++-- tests/pos/i5978.scala | 12 ++++++---- tests/pos/i6914.scala | 4 ++-- tests/pos/i8198.scala | 2 +- tests/pos/i8397.scala | 2 +- tests/pos/i8825.scala | 4 ++-- tests/pos/inlined-the.scala | 4 ++-- tests/pos/reference/delegates.scala | 8 +++---- tests/pos/reference/extension-methods.scala | 2 +- tests/run-macros/i8007/Macro_3.scala | 2 +- tests/run-macros/i9812b/Macro_1.scala | 8 +++---- tests/run/Typeable.scala | 2 +- tests/run/cochis-example.scala | 2 +- tests/run/extmethods2.scala | 2 +- tests/run/i7788.scala | 2 +- tests/run/i9011.scala | 2 +- tests/run/i9473.scala | 2 +- tests/run/implicit-alias.scala | 4 ++-- tests/run/implicit-specifity.scala | 12 +++++----- tests/run/implied-divergence.scala | 2 +- tests/run/implied-for.scala | 2 +- tests/run/implied-priority.scala | 16 ++++++------- tests/run/implied-specifity-2.scala | 24 +++++++++---------- tests/run/instances.scala | 4 ++-- tests/run/poly-kinded-derives.scala | 4 ++-- .../typeclass-derivation-doc-example.scala | 2 +- 43 files changed, 94 insertions(+), 89 deletions(-) diff --git a/scala3doc-testcases/src/tests/givenSignatures.scala b/scala3doc-testcases/src/tests/givenSignatures.scala index aa4ec3f219eb..dbbd89209d3c 100644 --- a/scala3doc-testcases/src/tests/givenSignatures.scala +++ b/scala3doc-testcases/src/tests/givenSignatures.scala @@ -20,11 +20,11 @@ class GivenClass { if (x < y) -1 else if (x > y) +1 else 0 } - given asd(using int: Int) as B + given (int: Int) => B as asd - given asd2[T] as C[T] + given [T] => C[T] as asd2 - given listOrd[T](using ord: Ord[T]) as Ord[List[T]] { + given [T] => (ord: Ord[T]) => Ord[List[T]] as listOrd { def compare(xs: List[T], ys: List[T]): Int = (xs, ys) match case (Nil, Nil) => 0 diff --git a/tests/disabled/pos-macros/i7853/JsonEncoder_1.scala b/tests/disabled/pos-macros/i7853/JsonEncoder_1.scala index d6c6f8be1a5e..a9fe96f0fc9d 100644 --- a/tests/disabled/pos-macros/i7853/JsonEncoder_1.scala +++ b/tests/disabled/pos-macros/i7853/JsonEncoder_1.scala @@ -35,7 +35,7 @@ object JsonEncoder { } } - given listEncoder[T](using encoder: JsonEncoder[T]) as JsonEncoder[List[T]] { + given [T] => (encoder: JsonEncoder[T]) => JsonEncoder[List[T]] as listEncoder { def encode(list: List[T]) = s"[${ list.map(v => encoder.encode(v)).mkString(", ") }]" } diff --git a/tests/disabled/pos/i8311.scala b/tests/disabled/pos/i8311.scala index f898612d8f91..d44eb69b96ce 100644 --- a/tests/disabled/pos/i8311.scala +++ b/tests/disabled/pos/i8311.scala @@ -8,7 +8,7 @@ class Foo object test: - given box[A](using Show[A]) as Show[Box[A]] = _.toString + given [A] => Show[A] => Show[Box[A]] as box = _.toString given Show[Foo] as foo = _.toString def run(s: Box[Box[Foo]]): Unit = diff --git a/tests/init/crash/i6914.scala b/tests/init/crash/i6914.scala index aa2cd26def6d..22571fc9c700 100644 --- a/tests/init/crash/i6914.scala +++ b/tests/init/crash/i6914.scala @@ -5,7 +5,7 @@ object test1 { class ToExpr[T](using Liftable[T]) extends Conversion[T, Expr[T]] { def apply(x: T): Expr[T] = ??? } - given toExprFun[T](using Liftable[T]) as ToExpr[T] + given [T] => (Liftable[T]) => ToExpr[T] as toExprFun given Liftable[Int] = ??? given Liftable[String] = ??? @@ -18,7 +18,7 @@ object test1 { object test2 { - given autoToExpr[T](using Liftable[T]) as Conversion[T, Expr[T]] { + given [T] => (Liftable[T]) => Conversion[T, Expr[T]] as autoToExpr { def apply(x: T): Expr[T] = ??? } diff --git a/tests/neg/eql.scala b/tests/neg/eql.scala index 78e7434160c9..701f538780bd 100644 --- a/tests/neg/eql.scala +++ b/tests/neg/eql.scala @@ -1,7 +1,7 @@ object lst: opaque type Lst[+T] = Any object Lst: - given lstCanEqual[T, U] as CanEqual[Lst[T], Lst[U]] = CanEqual.derived + given [T, U] => CanEqual[Lst[T], Lst[U]] as lstCanEqual = CanEqual.derived val Empty: Lst[Nothing] = ??? end lst diff --git a/tests/neg/i5978.scala b/tests/neg/i5978.scala index 9d30952cd158..cbc9cdeb1991 100644 --- a/tests/neg/i5978.scala +++ b/tests/neg/i5978.scala @@ -7,8 +7,9 @@ trait TokenParser[Token, R] object TextParser { given TokenParser[Char, Position[CharSequence]] as tp {} - given FromCharToken(using T: TokenParser[Char, Position[CharSequence]]) - as Conversion[Char, Position[CharSequence]] = ??? + given (T: TokenParser[Char, Position[CharSequence]]) + => Conversion[Char, Position[CharSequence]] + as FromCharToken = ??? } object Testcase { diff --git a/tests/neg/i7248.scala b/tests/neg/i7248.scala index e3d8f3115333..a5df7b54a57f 100644 --- a/tests/neg/i7248.scala +++ b/tests/neg/i7248.scala @@ -1,4 +1,4 @@ object Test extends App { - given f[H](using h: H) as H = h + given [H] => (h: H) => H as f = h summon[Int] // error } \ No newline at end of file diff --git a/tests/neg/i7249.scala b/tests/neg/i7249.scala index 472918278354..40216686d347 100644 --- a/tests/neg/i7249.scala +++ b/tests/neg/i7249.scala @@ -4,6 +4,6 @@ trait F[H, T] object Test extends App { - given f[H, T](using h: H, t: T) as F[H, T] = ??? + given [H, T] => (h: H, t: T) => F[H, T] as f = ??? summon[F[Int, Unit]] // error } \ No newline at end of file diff --git a/tests/neg/i7294-a.scala b/tests/neg/i7294-a.scala index f5fc2588fb0d..96d1381e9233 100644 --- a/tests/neg/i7294-a.scala +++ b/tests/neg/i7294-a.scala @@ -2,7 +2,7 @@ package foo trait Foo { def g(x: Int): Any } -inline given f[T <: Foo] as T = ??? match { +inline given [T <: Foo] => T as f = ??? match { case x: T => x.g(10) // error } diff --git a/tests/neg/i7294-b.scala b/tests/neg/i7294-b.scala index 027a3c154fbc..c6892d1aa204 100644 --- a/tests/neg/i7294-b.scala +++ b/tests/neg/i7294-b.scala @@ -2,7 +2,7 @@ package foo trait Foo { def g(x: Any): Any } -inline given f[T <: Foo] as T = ??? match { +inline given [T <: Foo] => T as f = ??? match { case x: T => x.g(10) // error } diff --git a/tests/neg/i7459.scala b/tests/neg/i7459.scala index 09b8156ca442..dfc884cb5802 100644 --- a/tests/neg/i7459.scala +++ b/tests/neg/i7459.scala @@ -47,7 +47,7 @@ object Eq { } } - inline given derived[T](using m: Mirror.Of[T]) as Eq[T] = { + inline given [T] => (m: Mirror.Of[T]) => Eq[T] as derived = { val elemInstances = summonAll[m.MirroredElemTypes] inline m match { case s: Mirror.SumOf[T] => eqSum(s, elemInstances) diff --git a/tests/neg/missing-implicit2.scala b/tests/neg/missing-implicit2.scala index 21a23887a067..9b57cbed460c 100644 --- a/tests/neg/missing-implicit2.scala +++ b/tests/neg/missing-implicit2.scala @@ -6,12 +6,12 @@ object test: given Y as y = ??? } locally { - given xFromY(using y: Y) as X = ??? + given (y: Y) => X as xFromY = ??? f(using xFromY) // error } locally { object instances2 { - given xFromY(using Y) as X = ??? + given (Y) => X as xFromY = ??? } f // error } diff --git a/tests/neg/missing-implicit3.scala b/tests/neg/missing-implicit3.scala index 7affe234bbab..7e589ef13928 100644 --- a/tests/neg/missing-implicit3.scala +++ b/tests/neg/missing-implicit3.scala @@ -3,7 +3,7 @@ package ord trait Ord[A] object Ord { - given ordered[A](using A => java.lang.Comparable[? >: A]) as Ord[A] = ??? + given [A] => (A => java.lang.Comparable[? >: A]) => Ord[A] as ordered = ??? } def sort[A: Ord](as: List[A]): List[A] = ??? diff --git a/tests/neg/multi-param-derives.scala b/tests/neg/multi-param-derives.scala index 1cc99a1f7cbc..8b1969c92691 100644 --- a/tests/neg/multi-param-derives.scala +++ b/tests/neg/multi-param-derives.scala @@ -6,8 +6,8 @@ object Test extends App { object Show { given Show[Int] {} given [T] => (st: Show[T]) => Show[Tuple1[T]] {} - given t2[T, U](using st: Show[T], su: Show[U]) as Show[(T, U)] {} - given t3[T, U, V](using st: Show[T], su: Show[U], sv: Show[V]) as Show[(T, U, V)] {} + given [T, U] => (st: Show[T], su: Show[U]) => Show[(T, U)] as t2 {} + given [T, U, V] => (st: Show[T], su: Show[U], sv: Show[V]) => Show[(T, U, V)] as t3 {} def derived[T](using m: Mirror.Of[T], r: Show[m.MirroredElemTypes]): Show[T] = new Show[T] {} } diff --git a/tests/pending/pos/i10161.scala b/tests/pending/pos/i10161.scala index 0bbc78b1b354..87c5783b80f7 100644 --- a/tests/pending/pos/i10161.scala +++ b/tests/pending/pos/i10161.scala @@ -11,8 +11,8 @@ object Incompat3 { trait Context { type Out } object Context { - given foo(using ctx: Context) as Option[ctx.Out] = ??? + given (ctx: Context) => Option[ctx.Out] as foo = ??? - given bar(using ctx: Context) as (Option[ctx.Out], String) = (foo, "foo") + given (ctx: Context) => (Option[ctx.Out], String) as bar = (foo, "foo") } } \ No newline at end of file diff --git a/tests/pos-custom-args/erased/i7868.scala b/tests/pos-custom-args/erased/i7868.scala index cc90a33d5896..f9a7249d29b0 100644 --- a/tests/pos-custom-args/erased/i7868.scala +++ b/tests/pos-custom-args/erased/i7868.scala @@ -12,7 +12,7 @@ object Coproduct { object At { - given atHead[Head, Tail] as At[Head +: Tail, Head, 0] { + given [Head, Tail] => At[Head +: Tail, Head, 0] as atHead { def cast: Head <:< Head +: Tail = summon[Head <:< Head +: Tail] } diff --git a/tests/pos-custom-args/erased/i7878.scala b/tests/pos-custom-args/erased/i7878.scala index 73a6e60251cd..735261a5ef49 100644 --- a/tests/pos-custom-args/erased/i7878.scala +++ b/tests/pos-custom-args/erased/i7878.scala @@ -2,7 +2,7 @@ object Boom { import scala.compiletime._ trait Fail[A <: Int, B <: Int] - erased inline given fail[X <: Int, Y <: Int] as Fail[X, Y] = { + erased inline given [X <: Int, Y <: Int] => Fail[X, Y] as fail = { scala.compiletime.summonFrom { case t: Fail[X, y] if constValue[y] < constValue[Y] => ??? } diff --git a/tests/pos/i5915.scala b/tests/pos/i5915.scala index ccd78df4a38c..7729a08ee5cb 100644 --- a/tests/pos/i5915.scala +++ b/tests/pos/i5915.scala @@ -2,8 +2,8 @@ trait RunDSL val rdsl = new RunDSL {} -given runNNFExpr[B] as RunDSL = rdsl +given [B] => RunDSL as runNNFExpr = rdsl -given runNNFImpl[B] as RunDSL { +given [B] => RunDSL as runNNFImpl { //override def runDSL(b: NNF[B]): B = b.terminal } \ No newline at end of file diff --git a/tests/pos/i5978.scala b/tests/pos/i5978.scala index 7b6319978220..e264ed2b689e 100644 --- a/tests/pos/i5978.scala +++ b/tests/pos/i5978.scala @@ -12,11 +12,15 @@ package p1 { def f (using TokenParser[Char, Position[CharSequence]]) = ??? - given FromCharToken(using T: TokenParser[Char, Position[CharSequence]]) + given (T: TokenParser[Char, Position[CharSequence]]) // skipping newlines is OK here - as Conversion[Char, Position[CharSequence]] = ??? + => Conversion[Char, Position[CharSequence]] + + // skipping newlines is OK here as well + + as FromCharToken = ??? } object Testcase { @@ -86,7 +90,7 @@ package p4 { given TC as a - given b[X[_], Y] as TC + given [X[_], Y] => TC as b - given c(using TC) as TC + given (TC) => TC as c } \ No newline at end of file diff --git a/tests/pos/i6914.scala b/tests/pos/i6914.scala index 14ee61dc5c4a..c0e6c0f3b487 100644 --- a/tests/pos/i6914.scala +++ b/tests/pos/i6914.scala @@ -5,7 +5,7 @@ object test1 { class ToExpr[T](using Liftable[T]) extends Conversion[T, Expr[T]] { def apply(x: T): Expr[T] = ??? } - given toExpr[T](using Liftable[T]) as ToExpr[T] + given [T] => (Liftable[T]) => ToExpr[T] as toExpr given Liftable[Int] = ??? given Liftable[String] = ??? @@ -18,7 +18,7 @@ object test1 { object test2 { - given autoToExpr[T](using Liftable[T]) as Conversion[T, Expr[T]] { + given [T] => (Liftable[T]) => Conversion[T, Expr[T]] as autoToExpr { def apply(x: T): Expr[T] = ??? } diff --git a/tests/pos/i8198.scala b/tests/pos/i8198.scala index 3946624acd83..d3154eb9b352 100644 --- a/tests/pos/i8198.scala +++ b/tests/pos/i8198.scala @@ -6,6 +6,6 @@ trait Eq[A] { case class Id[T](id: T) -given idEq[A](using eqA: Eq[A]) as Eq[Id[A]] = new { +given [A] => (eqA: Eq[A]) => Eq[Id[A]] as idEq = new { extension (i1: Id[A]) def === (i2: Id[A]) = !(i1.id /== i2.id) } diff --git a/tests/pos/i8397.scala b/tests/pos/i8397.scala index ec3bd2bda3e9..dc83e14c2797 100644 --- a/tests/pos/i8397.scala +++ b/tests/pos/i8397.scala @@ -1,4 +1,4 @@ -given foo(using x: Int) as AnyRef: +given (x: Int) => AnyRef as foo: type T = x.type // #7859 diff --git a/tests/pos/i8825.scala b/tests/pos/i8825.scala index 1cdc25d851d1..1b0597de4844 100644 --- a/tests/pos/i8825.scala +++ b/tests/pos/i8825.scala @@ -17,8 +17,8 @@ object Length { def instance[L <: HList, Out0 <: Nat]: Aux[L, Out0] = new Length[L] { type Out = Out0 } given Aux[HNil, Zero] as hnilLength = instance - given hconsLength[H, T <: HList] (using length: Length[T]) as Aux[HCons[H, T], Succ[length.Out]] = instance // (*) - //given hconsLength[H, T <: HList, N <: Nat] (using length: Aux[T, N]) as Aux[HCons[H, T], Succ[N]] = instance // (**) + given [H, T <: HList] => (length: Length[T]) => Aux[HCons[H, T], Succ[length.Out]] as hconsLength = instance // (*) + //given [H, T <: HList, N <: Nat] (using length: Aux[T, N]) => Aux[HCons[H, T], Succ[N]] as hconsLength = instance // (**) } val test = summon[Length.Aux[HCons[Int, HNil], One]] \ No newline at end of file diff --git a/tests/pos/inlined-the.scala b/tests/pos/inlined-the.scala index 290c39670355..3d84cb94242b 100644 --- a/tests/pos/inlined-the.scala +++ b/tests/pos/inlined-the.scala @@ -5,7 +5,7 @@ object Instances { class C { def f() = { locally { - given d[T] as D[T] + given [T] => D[T] as d summon[D[Int]] implicit val s: 3 = ??? val a: 3 = summon[3] @@ -14,7 +14,7 @@ object Instances { } locally { - given d[T] as D[T] + given [T] => D[T] as d the2[D[Int]] implicit val s: 3 = ??? val a: 3 = the2[3] diff --git a/tests/pos/reference/delegates.scala b/tests/pos/reference/delegates.scala index 9c205db52212..a54e14ad7fd6 100644 --- a/tests/pos/reference/delegates.scala +++ b/tests/pos/reference/delegates.scala @@ -30,7 +30,7 @@ object Instances extends Common: extension (x: Int) def compareTo(y: Int) = if (x < y) -1 else if (x > y) +1 else 0 - given listOrd[T](using Ord[T]) as Ord[List[T]]: + given [T] => Ord[T] => Ord[List[T]] as listOrd: extension (xs: List[T]) def compareTo(ys: List[T]): Int = (xs, ys) match case (Nil, Nil) => 0 case (Nil, _) => -1 @@ -55,7 +55,7 @@ object Instances extends Common: def pure[A](x: A): List[A] = List(x) - given readerMonad[Ctx] as Monad[[X] =>> Ctx => X]: + given [Ctx] => Monad[[X] =>> Ctx => X] as readerMonad: extension [A, B](r: Ctx => A) def flatMap (f: A => Ctx => B): Ctx => B = ctx => f(r(ctx))(ctx) def pure[A](x: A): Ctx => A = @@ -111,11 +111,11 @@ object Instances extends Common: println(summon[Context].value) } locally { - given d[T] as D[T] + given [T] => D[T] as d println(summon[D[Int]]) } locally { - given (using Context) as D[Int] + given Context => D[Int] println(summon[D[Int]]) } end C diff --git a/tests/pos/reference/extension-methods.scala b/tests/pos/reference/extension-methods.scala index 5d063997f210..2cd09f9c9411 100644 --- a/tests/pos/reference/extension-methods.scala +++ b/tests/pos/reference/extension-methods.scala @@ -90,7 +90,7 @@ object ExtMethods: extension [T](xs: Lst[Lst[T]]) def flatten: Lst[T] = xs.foldLeft(Lst())(_ ++ _) - given ord[T: Ord] as Ord[Lst[T]]: + given [T: Ord] => Ord[Lst[T]] as ord: extension (xs: Lst[T]) def less (ys: Lst[T]): Boolean = ??? end Lst diff --git a/tests/run-macros/i8007/Macro_3.scala b/tests/run-macros/i8007/Macro_3.scala index 7eb0fd2baebc..33d8003b2dda 100644 --- a/tests/run-macros/i8007/Macro_3.scala +++ b/tests/run-macros/i8007/Macro_3.scala @@ -32,7 +32,7 @@ object Eq { case '[EmptyTuple] => Nil } - given derived[T: Type](using q: Quotes) as Expr[Eq[T]] = { + given [T: Type] => (q: Quotes) => Expr[Eq[T]] as derived = { import quotes.reflect._ val ev: Expr[Mirror.Of[T]] = Expr.summon(using Type.of[Mirror.Of[T]]).get diff --git a/tests/run-macros/i9812b/Macro_1.scala b/tests/run-macros/i9812b/Macro_1.scala index e71ee1c56409..37d86152b086 100644 --- a/tests/run-macros/i9812b/Macro_1.scala +++ b/tests/run-macros/i9812b/Macro_1.scala @@ -19,25 +19,25 @@ object SomeEnum: given Liftable[Foo.type] as liftFoo: def toExpr(x: Foo.type): Quotes ?=> Expr[Foo.type] = '{Foo} -given liftBar[S <: SomeEnum: Type: Liftable] as Liftable[Bar[S]]: +given [S <: SomeEnum: Type: Liftable] => Liftable[Bar[S]] as liftBar: def toExpr(x: Bar[S]): Quotes ?=> Expr[Bar[S]] = '{new Bar(${Lift(x.s)})} sealed abstract class Lst[+T] final case class CONS[+T](head: T, tail: Lst[T]) extends Lst[T] case object NIL extends Lst[Nothing] -given intLiftable[T <: Int] as Liftable[T]: +given [T <: Int] => Liftable[T] as intLiftable: def toExpr(x: T): Quotes ?=> Expr[T] = qctx ?=> { import quotes.reflect._ Literal(Constant.Int(x)).asExpr.asInstanceOf[Expr[T]] } -given liftLst[T: Type: Liftable](using ev1: => Liftable[CONS[T]], ev2: => Liftable[NIL.type]) as Liftable[Lst[T]]: +given [T: Type: Liftable] => (ev1: => Liftable[CONS[T]], ev2: => Liftable[NIL.type]) => Liftable[Lst[T]] as liftLst: def toExpr(xs: Lst[T]): Quotes ?=> Expr[Lst[T]] = xs match case NIL => ev2.toExpr(NIL) case cons @ CONS(_, _) => ev1.toExpr(cons) -given liftCONS[T: Type: Liftable](using Liftable[Lst[T]]) as Liftable[CONS[T]]: +given [T: Type: Liftable] => (Liftable[Lst[T]]) => Liftable[CONS[T]] as liftCONS: def toExpr(x: CONS[T]): Quotes ?=> Expr[CONS[T]] = '{CONS(${Lift(x.head)}, ${Lift(x.tail)})} given Liftable[NIL.type] as liftNIL: diff --git a/tests/run/Typeable.scala b/tests/run/Typeable.scala index b539fe185895..ded4acdde7c8 100644 --- a/tests/run/Typeable.scala +++ b/tests/run/Typeable.scala @@ -33,7 +33,7 @@ object Typeable: case _ => None def describe = "Int" - given list[T: Typeable] as Typeable[List[T]]: + given [T: Typeable] => Typeable[List[T]] as list: def cast(x: Any): Option[List[T]] = x match case x: List[_] if x.forall(Typeable[T].cast(_).isDefined) => Some(x.asInstanceOf[List[T]]) case _ => None diff --git a/tests/run/cochis-example.scala b/tests/run/cochis-example.scala index 586ed6b0f585..4b0bf27f2a3c 100644 --- a/tests/run/cochis-example.scala +++ b/tests/run/cochis-example.scala @@ -1,7 +1,7 @@ import Predef.{assert, $conforms => _} trait A { - given id[X] as (X => X) = x => x + given [X] => (X => X) as id = x => x def trans[X](x: X)(using f: X => X) = f(x) // (2) } object Test extends A with App{ diff --git a/tests/run/extmethods2.scala b/tests/run/extmethods2.scala index f1369d37d306..2e457dc3abbd 100644 --- a/tests/run/extmethods2.scala +++ b/tests/run/extmethods2.scala @@ -2,7 +2,7 @@ object Test extends App { class TC - given stringListOps(using TC) as Object { + given TC => Object as stringListOps { type T = List[String] extension (x: T) def foo(y: T) = (x ++ y, summon[TC]) extension (x: T) def bar(y: Int) = (x(0)(y), summon[TC]) diff --git a/tests/run/i7788.scala b/tests/run/i7788.scala index edcc0b1b46e3..361128cf446c 100644 --- a/tests/run/i7788.scala +++ b/tests/run/i7788.scala @@ -4,7 +4,7 @@ trait Show[-A]: given Show[String] = x => x given Show[Int] = _.toString -given showEither[A,B](using sA: Show[A])(using Show[B]) as Show[Either[A,B]] = +given [A,B] => Show[A] => Show[B] => Show[Either[A,B]] as showEither = _.fold(a => s"Left(${summon[Show[A]].show(a)})", b => s"Right(${summon[Show[B]].show(b)})") given [A,B] => (sA: Show[A]) => (sB: Show[B]) => Show[(A,B)] = (a,b) => s"(${sA.show(a)}), ${sB.show(b)})" diff --git a/tests/run/i9011.scala b/tests/run/i9011.scala index e76f0b522409..cc45a5256fdd 100644 --- a/tests/run/i9011.scala +++ b/tests/run/i9011.scala @@ -40,7 +40,7 @@ object Eq { } } - inline given derived[T](using m: Mirror.Of[T]) as Eq[T] = { + inline given [T] => (m: Mirror.Of[T]) => Eq[T] as derived = { val elemInstances = summonAll[m.MirroredElemTypes] inline m match { case s: Mirror.SumOf[T] => eqSum(s, elemInstances) diff --git a/tests/run/i9473.scala b/tests/run/i9473.scala index f65f0f6df9e7..4695b3d15c01 100644 --- a/tests/run/i9473.scala +++ b/tests/run/i9473.scala @@ -36,7 +36,7 @@ object Eq { } } - inline given derived[T](using m: Mirror.Of[T]) as Eq[T] = { + inline given [T] => (m: Mirror.Of[T]) => Eq[T] as derived = { lazy val elemInstances = summonAll[m.MirroredElemTypes] inline m match { case s: Mirror.SumOf[T] => eqSum(s, elemInstances) diff --git a/tests/run/implicit-alias.scala b/tests/run/implicit-alias.scala index 9c9e3fb3d051..a1aa5638afa1 100644 --- a/tests/run/implicit-alias.scala +++ b/tests/run/implicit-alias.scala @@ -53,14 +53,14 @@ object Test extends App { locally { println("with given") - given t(using TC1) as TC = new TC + given TC1 => TC as t = new TC summon[TC] summon[TC] } locally { println("with type params") - given t[X] as TC = new TC + given [X] => TC as t = new TC summon[TC] summon[TC] } diff --git a/tests/run/implicit-specifity.scala b/tests/run/implicit-specifity.scala index 84203189bc15..a9d259c653e0 100644 --- a/tests/run/implicit-specifity.scala +++ b/tests/run/implicit-specifity.scala @@ -3,19 +3,19 @@ object Show { def apply[T](implicit st: Show[T]): Int = st.i given Show[Int] as showInt = new Show[Int](0) - given fallback[T] as Show[T] = new Show[T](1) + given [T] => Show[T] as fallback = new Show[T](1) } class Generic object Generic { given Generic as gen = new Generic - given showGen[T](using Generic) as Show[T] = new Show[T](2) + given [T] => Generic => Show[T] as showGen = new Show[T](2) } class Generic2 object Generic2 { opaque type HiPriority = AnyRef - given showGen[T] as (Show[T] & HiPriority) = new Show[T](2).asInstanceOf + given [T] => (Show[T] & HiPriority) as showGen = new Show[T](2).asInstanceOf } class SubGen extends Generic @@ -27,11 +27,11 @@ object Contextual { given ctx as Context - given showGen[T](using Generic) as Show[T] = new Show[T](2) + given [T] => Generic => Show[T] as showGen = new Show[T](2) - given showGen[T](using Generic, Context) as Show[T] = new Show[T](3) + given [T] => (Generic, Context) => Show[T] as showGen = new Show[T](3) - given showGen[T](using SubGen) as Show[T] = new Show[T](4) + given [T] => SubGen => Show[T] as showGen = new Show[T](4) } object Test extends App { diff --git a/tests/run/implied-divergence.scala b/tests/run/implied-divergence.scala index dc431bb87288..5808c94b552d 100644 --- a/tests/run/implied-divergence.scala +++ b/tests/run/implied-divergence.scala @@ -6,7 +6,7 @@ given e as E(null) object Test extends App { - given f(using e: E) as E(e) + given (e: E) => E(e) as f assert(summon[E].toString == "E(E(null))") diff --git a/tests/run/implied-for.scala b/tests/run/implied-for.scala index ead431a67372..b4c486f25af4 100644 --- a/tests/run/implied-for.scala +++ b/tests/run/implied-for.scala @@ -31,7 +31,7 @@ class Monoid[T] object Instances { given intOrd as Ordering[Int] - given listOrd[T](using Ordering[T]) as Ordering[List[T]] + given [T] => Ordering[T] => Ordering[List[T]] as listOrd given ec as ExecutionContext given im as Monoid[Int] } diff --git a/tests/run/implied-priority.scala b/tests/run/implied-priority.scala index 3ec5bde9e76c..e68e243bdead 100644 --- a/tests/run/implied-priority.scala +++ b/tests/run/implied-priority.scala @@ -11,11 +11,11 @@ class Arg[T] // An argument that we use as a given for some given instances bel * Traditional scheme: prioritize with location in class hierarchy */ class LowPriorityImplicits { - given t1[T] as E[T]("low") + given [T] => E[T]("low") as t1 } object NormalImplicits extends LowPriorityImplicits { - given t2[T](using Arg[T]) as E[T]("norm") + given [T] => Arg[T] => E[T]("norm") as t2 } def test1 = { @@ -38,8 +38,8 @@ object Priority { } object Impl2 { - given t1[T](using Priority.Low) as E[T]("low") - given t2[T](using Priority.High)(using Arg[T]) as E[T]("norm") + given [T] => Priority.Low => E[T]("low") as t1 + given [T] => Priority.High => Arg[T] => E[T]("norm") as t2 } def test2 = { @@ -60,7 +60,7 @@ def test2 = { * an alternative without implicit arguments would override all of them. */ object Impl2a { - given t3[T] as E[T]("hi") + given [T] => E[T]("hi") as t3 } def test2a = { @@ -75,13 +75,13 @@ def test2a = { * result type of the given instance, e.g. like this: */ object Impl3 { - given t1[T] as E[T]("low") + given [T] => E[T]("low") as t1 } object Override { trait HighestPriority // A marker trait to indicate a higher priority - given over[T] as E[T]("hi"), HighestPriority + given [T] => E[T]("hi"), HighestPriority as over } def test3 = { @@ -103,7 +103,7 @@ def test3 = { object Impl4 { given t1 as E[String]("string") - given t2[T](using Arg[T]) as E[T]("generic") + given [T] => Arg[T] => E[T]("generic") as t2 } object fallback4 { diff --git a/tests/run/implied-specifity-2.scala b/tests/run/implied-specifity-2.scala index 51c213c47a1e..acfaef01ce03 100644 --- a/tests/run/implied-specifity-2.scala +++ b/tests/run/implied-specifity-2.scala @@ -15,18 +15,18 @@ class Foo[T](val i: Int) object Foo { def apply[T](using fooT: Foo[T]): Int = fooT.i - given foo[T](using Low) as Foo[T](0) - given foobar[T](using Low) as Foo[Bar[T]](1) - given foobarbaz(using Low) as Foo[Bar[Baz]](2) + given [T] => Low => Foo[T](0) as foo + given [T] => Low => Foo[Bar[T]](1) as foobar + given Low => Foo[Bar[Baz]](2) as foobarbaz } class Bar[T] object Bar { - given foobar[T](using Medium) as Foo[Bar[T]](3) - given foobarbaz(using Medium) as Foo[Bar[Baz]](4) + given [T] => Medium => Foo[Bar[T]](3) as foobar + given Medium => Foo[Bar[Baz]](4) as foobarbaz } class Baz object Baz { - given baz(using High) as Foo[Bar[Baz]](5) + given High => Foo[Bar[Baz]](5) as baz } class Arg @@ -35,24 +35,24 @@ given Arg class Bam(val str: String) -given lo(using Low) as Bam("lo") +given Low => Bam("lo") as lo -given hi(using High)(using Arg) as Bam("hi") +given High => Arg => Bam("hi") as hi class Bam2(val str: String) -given lo2(using Low) as Bam2("lo") +given Low => Bam2("lo") as lo2 -given mid2(using High)(using Arg) as Bam2("mid") +given High => (Arg) => Bam2("mid") as mid2 given hi2 as Bam2("hi") class Arg2 class Red(val str: String) -given normal(using Arg2) as Red("normal") +given Arg2 => Red("normal") as normal -given reduced(using ev: Arg2 | Low) as Red("reduced") +given (ev: Arg2 | Low) => Red("reduced") as reduced object Test extends App { assert(Foo[Int] == 0) diff --git a/tests/run/instances.scala b/tests/run/instances.scala index ebe7cd731070..6ec5c4f6f282 100644 --- a/tests/run/instances.scala +++ b/tests/run/instances.scala @@ -68,7 +68,7 @@ object Test extends App { if (x < y) -1 else if (x > y) +1 else 0 val minimum = Int.MinValue - given listOrd[T: Ord] as Ord[List[T]]: + given [T: Ord] => Ord[List[T]] as listOrd: extension (xs: List[T]) def compareTo(ys: List[T]): Int = (xs, ys).match case (Nil, Nil) => 0 case (Nil, _) => -1 @@ -105,7 +105,7 @@ object Test extends App { def pure[A](x: A): List[A] = List(x) - given readerMonad[Ctx] as Monad[[X] =>> Ctx => X]: + given [Ctx] => Monad[[X] =>> Ctx => X] as readerMonad: extension [A, B](r: Ctx => A) def flatMap (f: A => Ctx => B): Ctx => B = ctx => f(r(ctx))(ctx) def pure[A](x: A): Ctx => A = diff --git a/tests/run/poly-kinded-derives.scala b/tests/run/poly-kinded-derives.scala index 45508da8be8a..a48ce2443d09 100644 --- a/tests/run/poly-kinded-derives.scala +++ b/tests/run/poly-kinded-derives.scala @@ -6,8 +6,8 @@ object Test extends App { object Show { given Show[Int] {} given [T] => (st: Show[T]) => Show[Tuple1[T]] - given t2[T, U](using st: Show[T], su: Show[U]) as Show[(T, U)] - given t3 [T, U, V](using st: Show[T], su: Show[U], sv: Show[V]) as Show[(T, U, V)] + given [T, U] => (st: Show[T], su: Show[U]) => Show[(T, U)] as t2 + given [T, U, V] => (Show[T], Show[U], Show[V]) => Show[(T, U, V)] as t3 def derived[T](using m: Mirror.Of[T], r: Show[m.MirroredElemTypes]): Show[T] = new Show[T] {} } diff --git a/tests/run/typeclass-derivation-doc-example.scala b/tests/run/typeclass-derivation-doc-example.scala index c70b1bac5c50..5654d2a39085 100644 --- a/tests/run/typeclass-derivation-doc-example.scala +++ b/tests/run/typeclass-derivation-doc-example.scala @@ -36,7 +36,7 @@ object Eq { } } - inline given derived[T](using m: Mirror.Of[T]) as Eq[T] = { + inline given [T] => (m: Mirror.Of[T]) => Eq[T] as derived = { val elemInstances = summonAll[m.MirroredElemTypes] inline m match { case s: Mirror.SumOf[T] => eqSum(s, elemInstances) From b8294e6807bd4c77d3ef676557b1ad011513b81b Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 26 Nov 2020 15:57:45 +0100 Subject: [PATCH 11/14] Switch to postfix as in CB --- community-build/community-projects/PPrint | 2 +- community-build/community-projects/dotty-cps-async | 2 +- community-build/community-projects/intent | 2 +- community-build/community-projects/scodec | 2 +- community-build/community-projects/shapeless | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/community-build/community-projects/PPrint b/community-build/community-projects/PPrint index 05aae07eb487..d9bdda54155b 160000 --- a/community-build/community-projects/PPrint +++ b/community-build/community-projects/PPrint @@ -1 +1 @@ -Subproject commit 05aae07eb487b8f21216faf1d9557b24c560d6d5 +Subproject commit d9bdda54155bbcfb83237c0a94e2f091f6eb0973 diff --git a/community-build/community-projects/dotty-cps-async b/community-build/community-projects/dotty-cps-async index c436717f1812..1d4685d5aa24 160000 --- a/community-build/community-projects/dotty-cps-async +++ b/community-build/community-projects/dotty-cps-async @@ -1 +1 @@ -Subproject commit c436717f18122ef5300ee6846e8560733cffe867 +Subproject commit 1d4685d5aa24525ec4364f00661ae71d0d5b7921 diff --git a/community-build/community-projects/intent b/community-build/community-projects/intent index 20774fb03b11..8fd58a3ffd75 160000 --- a/community-build/community-projects/intent +++ b/community-build/community-projects/intent @@ -1 +1 @@ -Subproject commit 20774fb03b11c8e3f1d4fda4c731f308183fd4c9 +Subproject commit 8fd58a3ffd75150ef6dd6a8fd347a843e3124297 diff --git a/community-build/community-projects/scodec b/community-build/community-projects/scodec index 620880b81bff..2869417edaa3 160000 --- a/community-build/community-projects/scodec +++ b/community-build/community-projects/scodec @@ -1 +1 @@ -Subproject commit 620880b81bff1cb365f28ff4cbf93e799265bf4d +Subproject commit 2869417edaa3161a924aef030b874dec7f30133d diff --git a/community-build/community-projects/shapeless b/community-build/community-projects/shapeless index 8b53f19a41ef..19f483fc82fd 160000 --- a/community-build/community-projects/shapeless +++ b/community-build/community-projects/shapeless @@ -1 +1 @@ -Subproject commit 8b53f19a41efbedbc00c8b062e66dec896bc92c0 +Subproject commit 19f483fc82fdc2d029e14adfd2f3487a4bd90987 From 25bc9609045a0b670243b46776af95f3e6feb85f Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 26 Nov 2020 18:53:48 +0100 Subject: [PATCH 12/14] Support `given => T` syntax for uncached givens --- .../dotty/tools/dotc/parsing/Parsers.scala | 61 +++++++++++-------- docs/docs/internals/syntax.md | 7 ++- tests/run/given-mutable.scala | 7 +++ 3 files changed, 47 insertions(+), 28 deletions(-) create mode 100644 tests/run/given-mutable.scala diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index b3e33360ce78..c2a1e6d50571 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -3567,13 +3567,15 @@ object Parsers { syntaxError(i"extension clause can only define methods", stat.span) } - /** GivenDef ::= [GivenParams] Type ['as' id] ‘=’ Expr + /** GivenDef ::= [GivenParams | `=>`] Type ['as' id] ‘=’ Expr * | [GivenParams] ConstrApps ['as' id] [TemplateBody] - * GivenParams ::= [DefTypeParamClause '=>'] {FunArgTypes '=>'} + * GivenParams ::= [DefTypeParamClause '=>'] {GivenParamClause '=>'} + * GivenParamClause ::= `(` DefParams `)` | FunArgTypes */ def givenDef(start: Offset, mods: Modifiers, givenMod: Mod) = atSpan(start, nameStart) { var mods1 = addMod(mods, givenMod) val start = in.offset + var defOnly = false val (name, tparams, vparamss, parents) = if followingIsGivenSig() then val name = if isIdent then ident() else EmptyTermName val tparams = typeParamClauseOpt(ParamOwner.Def) @@ -3588,28 +3590,35 @@ object Parsers { (name, tparams, vparamss, parents) else if true then val tparams = typeParamClauseOpt(ParamOwner.Def) - if tparams.nonEmpty then accept(ARROW) - var counter = 0 - def nextIdx = { counter += 1; counter } - def givenHeadRest(params: List[Tree], mods: Modifiers): (List[List[ValDef]], List[Tree]) = - accept(ARROW) - val vparams = params match - case (_: ValDef) :: _ => - params.asInstanceOf[List[ValDef]].map(_.withFlags(Param | Given)) - case _ => - params.map(makeSyntheticParameter(nextIdx, _, Param | Synthetic | Given)) - val (vparamss1, parents) = givenHead() - (vparams :: vparamss1, parents) - def givenHeadFinish(t: Tree): (List[List[ValDef]], List[Tree]) = - (Nil, constrAppsRest(constrAppRest(t), commaOK = true)) - def givenHead(): (List[List[ValDef]], List[Tree]) = - if in.token == LPAREN then - maybeParams(paramClause(_), givenHeadFinish, givenHeadRest) + val (vparamss, parents) = + if tparams.isEmpty && in.token == ARROW then + defOnly = true + in.nextToken() + (Nil, constrApps(commaOK = true)) else - val constr = constrOrSimpleType() - if in.token == ARROW then givenHeadRest(constr :: Nil, EmptyModifiers) - else givenHeadFinish(constr) - val (vparamss, parents) = givenHead() + if tparams.nonEmpty then accept(ARROW) + var counter = 0 + def nextIdx = { counter += 1; counter } + def givenHeadRest(params: List[Tree], mods: Modifiers): (List[List[ValDef]], List[Tree]) = + accept(ARROW) + val vparams = params match + case (_: ValDef) :: _ => + params.asInstanceOf[List[ValDef]].map(_.withFlags(Param | Given)) + case _ => + params.map(makeSyntheticParameter(nextIdx, _, Param | Synthetic | Given)) + val (vparamss1, parents) = givenHead() + (vparams :: vparamss1, parents) + def givenHeadFinish(t: Tree): (List[List[ValDef]], List[Tree]) = + (Nil, constrAppsRest(constrAppRest(t), commaOK = true)) + def givenHead(): (List[List[ValDef]], List[Tree]) = + if in.token == LPAREN then + maybeParams(paramClause(_), givenHeadFinish, givenHeadRest) + else + val constr = constrOrSimpleType() + if in.token == ARROW then givenHeadRest(constr :: Nil, EmptyModifiers) + else givenHeadFinish(constr) + givenHead() + end if newLinesOptWhenFollowedBy(nme.as) val name = if in.isIdent(nme.as) then @@ -3620,10 +3629,12 @@ object Parsers { else (EmptyTermName, Nil, Nil, constrApps(commaOK = true)) val gdef = - if in.token == EQUALS && parents.length == 1 && parents.head.isType then + if defOnly || in.token == EQUALS then + if parents.length != 1 || !parents.head.isType then + syntaxError(em"Given parent is not a type. It cannot be defined with an alias") accept(EQUALS) mods1 |= Final - if tparams.isEmpty && vparamss.isEmpty && !mods.is(Inline) then + if tparams.isEmpty && vparamss.isEmpty && !mods.is(Inline) && !defOnly then mods1 |= Lazy ValDef(name, parents.head, subExpr()) else diff --git a/docs/docs/internals/syntax.md b/docs/docs/internals/syntax.md index 3cf7345eeaa8..dbb27f7f2b87 100644 --- a/docs/docs/internals/syntax.md +++ b/docs/docs/internals/syntax.md @@ -396,9 +396,10 @@ ClassConstr ::= [ClsTypeParamClause] [ConstrMods] ClsParamClauses ConstrMods ::= {Annotation} [AccessModifier] ObjectDef ::= id [Template] ModuleDef(mods, name, template) // no constructor EnumDef ::= id ClassConstr InheritClauses EnumBody EnumDef(mods, name, tparams, template) -GivenDef ::= [GivenSig] Type ‘=’ Expr - | [GivenSig] ConstrApps [TemplateBody] -GivenSig ::= [id] [DefTypeParamClause] {UsingParamClause} ‘as’ -- one of `id`, `DefParamClause`, `UsingParamClause` must appear +GivenDef ::= [GivenParams | `=>`] Type ['as' id] ‘=’ Expr + | [GivenParams] ConstrApps ['as' id] [TemplateBody] +GivenParams ::= [DefTypeParamClause '=>'] {GivenParamClause '=>'} +GivenParamClause ::= `(` DefParams `)` | FunArgTypes Extension ::= ‘extension’ [DefTypeParamClause] ‘(’ DefParam ‘)’ {UsingParamClause}] ExtMethods ExtMethods ::= ExtMethod | [nl] ‘{’ ExtMethod {semi ExtMethod ‘}’ diff --git a/tests/run/given-mutable.scala b/tests/run/given-mutable.scala new file mode 100644 index 000000000000..1acb2732a18d --- /dev/null +++ b/tests/run/given-mutable.scala @@ -0,0 +1,7 @@ +var x = 0 +given => Int = + x += 1 + x +@main def Test = + assert(summon[Int] == 1) + assert(summon[Int] == 2) From 943fc3574e754f727e414b61e59e4f46a644b45a Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 26 Nov 2020 21:18:13 +0100 Subject: [PATCH 13/14] Update docs --- .../community-projects/dotty-cps-async | 2 +- .../contextual/by-name-context-parameters.md | 8 +-- .../reference/contextual/context-functions.md | 6 +-- docs/docs/reference/contextual/conversions.md | 8 +-- .../reference/contextual/derivation-macro.md | 6 +-- docs/docs/reference/contextual/derivation.md | 20 +++---- .../reference/contextual/extension-methods.md | 4 +- .../reference/contextual/given-imports.md | 4 +- docs/docs/reference/contextual/givens.md | 52 ++++++++++--------- .../contextual/multiversal-equality.md | 2 +- .../contextual/relationship-implicits.md | 30 +++++++---- .../docs/reference/contextual/type-classes.md | 10 ++-- .../reference/contextual/using-clauses.md | 6 +-- 13 files changed, 86 insertions(+), 72 deletions(-) diff --git a/community-build/community-projects/dotty-cps-async b/community-build/community-projects/dotty-cps-async index 1d4685d5aa24..c436717f1812 160000 --- a/community-build/community-projects/dotty-cps-async +++ b/community-build/community-projects/dotty-cps-async @@ -1 +1 @@ -Subproject commit 1d4685d5aa24525ec4364f00661ae71d0d5b7921 +Subproject commit c436717f18122ef5300ee6846e8560733cffe867 diff --git a/docs/docs/reference/contextual/by-name-context-parameters.md b/docs/docs/reference/contextual/by-name-context-parameters.md index a259cea88ae5..46b1d3b20826 100644 --- a/docs/docs/reference/contextual/by-name-context-parameters.md +++ b/docs/docs/reference/contextual/by-name-context-parameters.md @@ -10,9 +10,9 @@ trait Codec[T] { def write(x: T): Unit } -given intCodec as Codec[Int] = ??? +given Codec[Int] as intCodec = ??? -given optionCodec[T](using ev: => Codec[T]) as Codec[Option[T]] { +given [T] => (ev: => Codec[T]) => Codec[Option[T]] as optionCodec { def write(xo: Option[T]) = xo match { case Some(x) => ev.write(x) case None => @@ -36,7 +36,7 @@ The precise steps for synthesizing an argument for a by-name context parameter o 1. Create a new given of type `T`: ```scala - given lv as T = ??? + given T as lv = ??? ``` where `lv` is an arbitrary fresh name. @@ -46,7 +46,7 @@ The precise steps for synthesizing an argument for a by-name context parameter o ```scala - { given lv as T = E; lv } + { given T as lv = E; lv } ``` Otherwise, return `E` unchanged. diff --git a/docs/docs/reference/contextual/context-functions.md b/docs/docs/reference/contextual/context-functions.md index 279d2ad13356..c662b75c995c 100644 --- a/docs/docs/reference/contextual/context-functions.md +++ b/docs/docs/reference/contextual/context-functions.md @@ -13,7 +13,7 @@ Context functions are written using `?=>` as the "arrow" sign. They are applied to synthesized arguments, in the same way methods with context parameters are applied. For instance: ```scala - given ec as ExecutionContext = ... + given ExecutionContext as ec = ... def f(x: Int): ExecutionContext ?=> Int = ... @@ -86,13 +86,13 @@ with context function types as parameters to avoid the plumbing boilerplate that would otherwise be necessary. ```scala def table(init: Table ?=> Unit) = { - given t as Table // note the use of a creator application; same as: given t as Table = new Table + given Table as t // note the use of a creator application; same as: given t as Table = new Table init t } def row(init: Row ?=> Unit)(using t: Table) = { - given r as Row + given Row as r init t.add(r) } diff --git a/docs/docs/reference/contextual/conversions.md b/docs/docs/reference/contextual/conversions.md index 7faeb3aac0d5..59dea7111e10 100644 --- a/docs/docs/reference/contextual/conversions.md +++ b/docs/docs/reference/contextual/conversions.md @@ -37,7 +37,7 @@ If such an instance `C` is found, the expression `e` is replaced by `C.apply(e)` primitive number types to subclasses of `java.lang.Number`. For instance, the conversion from `Int` to `java.lang.Integer` can be defined as follows: ```scala -given int2Integer as Conversion[Int, java.lang.Integer] = +given Conversion[Int, java.lang.Integer] as int2Integer = java.lang.Integer.valueOf(_) ``` @@ -59,9 +59,9 @@ object Completions { // // CompletionArg.fromStatusCode(statusCode) - given fromString as Conversion[String, CompletionArg] = Error(_) - given fromFuture as Conversion[Future[HttpResponse], CompletionArg] = Response(_) - given fromStatusCode as Conversion[Future[StatusCode], CompletionArg] = Status(_) + given Conversion[String, CompletionArg] as fromString = Error(_) + given Conversion[Future[HttpResponse], CompletionArg] as fromFuture = Response(_) + given Conversion[Future[StatusCode], CompletionArg] as fromStatusCode = Status(_) } import CompletionArg._ diff --git a/docs/docs/reference/contextual/derivation-macro.md b/docs/docs/reference/contextual/derivation-macro.md index 82b01e001f18..b3bdb41d14a8 100644 --- a/docs/docs/reference/contextual/derivation-macro.md +++ b/docs/docs/reference/contextual/derivation-macro.md @@ -25,13 +25,13 @@ we need to implement a method `Eq.derived` on the companion object of `Eq` that produces a quoted instance for `Eq[T]`. Here is a possible signature, ```scala -given derived[T: Type](using Quotes) as Expr[Eq[T]] +given [T: Type] => Quotes => Expr[Eq[T]] as derived ``` and for comparison reasons we give the same signature we had with `inline`: ```scala -inline given derived[T] as (m: Mirror.Of[T]) => Eq[T] = ??? +inline given [T] => (m: Mirror.Of[T]) => Eq[T] as derived = ??? ``` Note, that since a type is used in a subsequent stage it will need to be lifted @@ -176,7 +176,7 @@ object Eq { case '[EmptyTuple] => Nil } - given derived[T: Type](using q: Quotes) as Expr[Eq[T]] = { + given [T: Type] => (q: Quotes) => Expr[Eq[T]] as derived = { import quotes.reflect._ val ev: Expr[Mirror.Of[T]] = Expr.summon[Mirror.Of[T]].get diff --git a/docs/docs/reference/contextual/derivation.md b/docs/docs/reference/contextual/derivation.md index 53d8cb16acac..27da6a8f85d7 100644 --- a/docs/docs/reference/contextual/derivation.md +++ b/docs/docs/reference/contextual/derivation.md @@ -19,9 +19,9 @@ The `derives` clause generates the following given instances for the `Eq`, `Orde companion object of `Tree`, ```scala -given [T: Eq] as Eq[Tree[T]] = Eq.derived -given [T: Ordering] as Ordering[Tree] = Ordering.derived -given [T: Show] as Show[Tree] = Show.derived +given [T: Eq] => Eq[Tree[T]] = Eq.derived +given [T: Ordering] => Ordering[Tree] = Ordering.derived +given [T: Show] => Show[Tree] = Show.derived ``` We say that `Tree` is the _deriving type_ and that the `Eq`, `Ordering` and `Show` instances are _derived instances_. @@ -179,7 +179,7 @@ we need to implement a method `Eq.derived` on the companion object of `Eq` that a `Mirror[T]`. Here is a possible implementation, ```scala -inline given derived[T](using m: Mirror.Of[T]) as Eq[T] = { +inline given derived[T] => (m: Mirror.Of[T]) => Eq[T] = { val elemInstances = summonAll[m.MirroredElemTypes] // (1) inline m match { // (2) case s: Mirror.SumOf[T] => eqSum(s, elemInstances) @@ -278,7 +278,7 @@ object Eq { } } - inline given derived[T](using m: Mirror.Of[T]) as Eq[T] = { + inline given [T] => (m: Mirror.Of[T]) => Eq[T] as derived = { lazy val elemInstances = summonAll[m.MirroredElemTypes] inline m match { case s: Mirror.SumOf[T] => eqSum(s, elemInstances) @@ -309,7 +309,7 @@ In this case the code that is generated by the inline expansion for the derived following, after a little polishing, ```scala -given derived$Eq[T](using eqT: Eq[T]) as Eq[Opt[T]] = +given [T] => Eq[T] => Eq[Opt[T]] as derived$Eq = eqSum(summon[Mirror[Opt[T]]], List( eqProduct(summon[Mirror[Sm[T]]], List(summon[Eq[T]])) @@ -326,19 +326,19 @@ As a third example, using a higher level library such as shapeless the type clas `derived` method as, ```scala -given eqSum[A](using inst: => K0.CoproductInstances[Eq, A]) as Eq[A] { +given [A] => (inst: => K0.CoproductInstances[Eq, A]) => Eq[A] as eqSum { def eqv(x: A, y: A): Boolean = inst.fold2(x, y)(false)( [t] => (eqt: Eq[t], t0: t, t1: t) => eqt.eqv(t0, t1) ) } -given eqProduct[A](using inst: K0.ProductInstances[Eq, A]) as Eq[A] { +given [A] => (inst: K0.ProductInstances[Eq, A]) => Eq[A] as eqProduct { def eqv(x: A, y: A): Boolean = inst.foldLeft2(x, y)(true: Boolean)( [t] => (acc: Boolean, eqt: Eq[t], t0: t, t1: t) => Complete(!eqt.eqv(t0, t1))(false)(true) ) } -inline def derived[A](using gen: K0.Generic[A]) as Eq[A] = gen.derive(eqSum, eqProduct) +inline def derived[A](using gen: K0.Generic[A]): Eq[A] = gen.derive(eqSum, eqProduct) ``` The framework described here enables all three of these approaches without mandating any of them. @@ -354,7 +354,7 @@ change the code of the ADT itself. To do this, simply define an instance using as right-hand side. E.g, to implement `Ordering` for `Option` define, ```scala -given [T: Ordering] as Ordering[Option[T]] = Ordering.derived +given [T: Ordering] => Ordering[Option[T]] = Ordering.derived ``` Assuming the `Ordering.derived` method has a context parameter of type `Mirror[T]` it will be satisfied by the diff --git a/docs/docs/reference/contextual/extension-methods.md b/docs/docs/reference/contextual/extension-methods.md index 77e8eef90055..8757c935c184 100644 --- a/docs/docs/reference/contextual/extension-methods.md +++ b/docs/docs/reference/contextual/extension-methods.md @@ -194,7 +194,7 @@ trait SafeDiv: By the second rule, an extension method can be made available by defining a given instance containing it, like this: ```scala -given ops1 as IntOps // brings safeMod into scope +given IntOps as ops1 // brings safeMod into scope 1.safeMod(2) ``` @@ -209,7 +209,7 @@ object List: extension [T](xs: List[List[T]]) def flatten: List[T] = xs.foldLeft(Nil: List[T])(_ ++ _) - given [T: Ordering] as Ordering[List[T]]: + given [T: Ordering] => Ordering[List[T]]: extension (xs: List[T]) def < (ys: List[T]): Boolean = ... end List diff --git a/docs/docs/reference/contextual/given-imports.md b/docs/docs/reference/contextual/given-imports.md index c2e3a8e48f2a..c5ae20f6d565 100644 --- a/docs/docs/reference/contextual/given-imports.md +++ b/docs/docs/reference/contextual/given-imports.md @@ -8,7 +8,7 @@ A special form of import wildcard selector is used to import given instances. Ex ```scala object A { class TC - given tc as TC + given TC as tc def f(using TC) = ??? } @@ -60,7 +60,7 @@ For instance, assuming the object ```scala object Instances { - given intOrd as Ordering[Int] + given Ordering[Int] as intOrd given listOrd[T: Ordering] as Ordering[List[T]] given ec as ExecutionContext = ... given im as Monoid[Int] diff --git a/docs/docs/reference/contextual/givens.md b/docs/docs/reference/contextual/givens.md index 98f2f4504c18..7fda736b0f47 100644 --- a/docs/docs/reference/contextual/givens.md +++ b/docs/docs/reference/contextual/givens.md @@ -13,12 +13,12 @@ trait Ord[T] { extension (x: T) def > (y: T) = compare(x, y) > 0 } -given intOrd as Ord[Int] { +given Ord[Int] { def compare(x: Int, y: Int) = if (x < y) -1 else if (x > y) +1 else 0 } -given listOrd[T](using ord: Ord[T]) as Ord[List[T]] { +given [T] => Ord[T] => Ord[List[T]] { def compare(xs: List[T], ys: List[T]): Int = (xs, ys) match case (Nil, Nil) => 0 @@ -29,33 +29,34 @@ given listOrd[T](using ord: Ord[T]) as Ord[List[T]] { if (fst != 0) fst else compare(xs1, ys1) } ``` -This code defines a trait `Ord` with two given instances. `intOrd` defines -a given for the type `Ord[Int]` whereas `listOrd[T]` defines givens +This code defines a trait `Ord` with two given instances. The first instance defines +a given for the type `Ord[Int]`. The second instance defines givens for `Ord[List[T]]` for all types `T` that come with a given instance for `Ord[T]` -themselves. The `using` clause in `listOrd` defines a condition: There must be a -given of type `Ord[T]` for a given of type `List[Ord[T]]` to exist. -Such conditions are expanded by the compiler to [context -parameters](./using-clauses.html). +themselves. The parts left to the arrows `=>` are type parameters and conditions. +In the example above, there must be a given instance of type `Ord[T]` for a given +instance of type `List[Ord[T]]` to exist. Such conditions are expanded by the compiler +to [context parameters](./using-clauses.html). -## Anonymous Givens +## Named Givens -The name of a given can be left out. So the definitions -of the last section can also be expressed like this: +One can attach a name to a given instance by following its type with an `as`. +For instance, the definitions of the last section can be labelled like this: ```scala -given Ord[Int] { ... } -given [T](using Ord[T]) as Ord[List[T]] { ... } +given Ord[Int] as intOrd { ... } +given [T] => Ord[T] => Ord[List[T]] as listOrd { ... } ``` If the name of a given is missing, the compiler will synthesize a name from the implemented type(s). -**Note** The name synthesized by the compiler is chosen to be readable and reasonably concise. For instance, the two instances above would get the names: +**Note** The name synthesized by the compiler is chosen to be readable and +reasonably concise. For instance, the two instances in the previous section would get the names: ```scala given_Ord_Int given_Ord_List_T ``` -The precise rules for synthesizing names are found [here](./relationship-implicits.html#anonymous-given-instances). These rules do not guarantee absence of name conflicts between -given instances of types that are "too similar". To avoid conflicts one can -use named instances. +The precise rules for synthesizing names are found [here](./relationship-implicits.html#anonymous-given-instances). +These rules do not guarantee absence of name conflicts between given instances of types that +are "too similar". To avoid conflicts one needs to use named instances. **Note** To ensure robust binary compatibility, publicly available libraries should prefer named instances. @@ -63,7 +64,7 @@ use named instances. An alias can be used to define a given instance that is equal to some expression. E.g.: ```scala -given global as ExecutionContext = new ForkJoinPool() +given ExecutionContext as global = new ForkJoinPool() ``` This creates a given `global` of type `ExecutionContext` that resolves to the right hand side `new ForkJoinPool()`. @@ -73,7 +74,7 @@ returned for this and all subsequent accesses to `global`. This operation is thr Alias givens can be anonymous as well, e.g. ```scala given Position = enclosingTree.position -given (using config: Config) as Factory = MemoizingFactory(config) +given (config: Config) => Factory = MemoizingFactory(config) ``` An alias given can have type parameters and context parameters just like any other given, @@ -84,11 +85,11 @@ but it can only implement a single type. Given aliases can have the `inline` and `transparent` modifiers. Example: ```scala -transparent inline given mkAnnotations[A, T] as Annotations[A, T] = ${ +transparent inline given [A, T] => Annotations[A, T] = ${ // code producing a value of a subtype of Annotations } ``` -Since `mkAnnotations` is `transparent`, the type of an application is the type of its right hand side, which can be a proper subtype of the declared result type `Annotations[A, T]`. +Since the given instance is `transparent`, the type of an application is the type of its right hand side, which can be a proper subtype of the declared result type `Annotations[A, T]`. ## Pattern-Bound Given Instances @@ -98,7 +99,7 @@ Given instances can also appear as pattern bound-variables. Example: for given Context <- applicationContexts do pair match - case (ctx as given Context, y) => ... + case (given Context as ctx, y) => ... ``` In the first fragment above, anonymous given instances for class `Context` are established by enumerating over `applicationContexts`. In the second fragment, a given `Context` instance named `ctx` is established by matching against the first half of the `pair` selector. @@ -118,7 +119,8 @@ Here is the new syntax for given instances, seen as a delta from the [standard c ``` TmplDef ::= ... | ‘given’ GivenDef -GivenDef ::= [GivenSig] Type ‘=’ Expr - | [GivenSig] ConstrApps [TemplateBody] -GivenSig ::= [id] [DefTypeParamClause] {UsingParamClause} ‘as’ +GivenDef ::= [GivenParams | `=>`] Type ['as' id] ‘=’ Expr + | [GivenParams] ConstrApps ['as' id] [TemplateBody] +GivenParams ::= [DefTypeParamClause '=>'] {GivenParamClause '=>'} +GivenParamClause ::= `(` DefParams `)` | FunArgTypes ``` diff --git a/docs/docs/reference/contextual/multiversal-equality.md b/docs/docs/reference/contextual/multiversal-equality.md index c420884eda8d..0bcb992d7d0c 100644 --- a/docs/docs/reference/contextual/multiversal-equality.md +++ b/docs/docs/reference/contextual/multiversal-equality.md @@ -97,7 +97,7 @@ class Box[T](x: T) derives CanEqual By the usual rules of [type class derivation](./derivation.md), this generates the following `CanEqual` instance in the companion object of `Box`: ```scala -given [T, U](using CanEqual[T, U]) as CanEqual[Box[T], Box[U]] = CanEqual.derived +given [T, U] => CanEqual[T, U] => CanEqual[Box[T], Box[U]] = CanEqual.derived ``` That is, two boxes are comparable with `==` or `!=` if their elements are. Examples: ```scala diff --git a/docs/docs/reference/contextual/relationship-implicits.md b/docs/docs/reference/contextual/relationship-implicits.md index 53e28165a10f..3208e7454009 100644 --- a/docs/docs/reference/contextual/relationship-implicits.md +++ b/docs/docs/reference/contextual/relationship-implicits.md @@ -14,7 +14,7 @@ Given instances can be mapped to combinations of implicit objects, classes and i 1. Given instances without parameters are mapped to implicit objects. E.g., ```scala - given intOrd as Ord[Int] { ... } + given Ord[Int] as intOrd { ... } ``` maps to @@ -26,13 +26,13 @@ Given instances can be mapped to combinations of implicit objects, classes and i 2. Parameterized givens are mapped to combinations of classes and implicit methods. E.g., ```scala - given listOrd[T](using ord: Ord[T]) as Ord[List[T]] { ... } + given [T] => (ord: Ord[T]) => Ord[List[T]] as listOrd { ... } ``` maps to ```scala - class ListOrd[T](implicit ord: Ord[T]) extends Ord[List[T]] { ... } + class listOrd[T](implicit ord: Ord[T]) extends Ord[List[T]] { ... } final implicit def ListOrd[T](implicit ord: Ord[T]): ListOrd[T] = new ListOrd[T] ``` @@ -43,7 +43,7 @@ Given instances can be mapped to combinations of implicit objects, classes and i Examples: ```scala -given global as ExecutionContext = new ForkJoinContext() +given ExecutionContext as global = [new ForkJoinContext()] val ctx: Context given Context = ctx @@ -56,13 +56,25 @@ final implicit lazy val global: ExecutionContext = new ForkJoinContext() final implicit def given_Context = ctx ``` +Alias givens with that define a by-name type starting with `=>` are always kept as defs. +Example: + +```scala +given => ExecutionContext = + println("new execution context created") + new ForkJoinContext() +summon[ExecutionContext] +summon[ExecutionContext] +``` +In this code fragment, "new execution context created" is printed twice. + ### Anonymous Given Instances -Anonymous given instances get compiler synthesized names, which are generated in a reproducible way from the implemented type(s). For example, if the names of the `IntOrd` and `ListOrd` givens above were left out, the following names would be synthesized instead: +Anonymous given instances get compiler synthesized names, which are generated in a reproducible way from the implemented type(s). For example, if the names of the `IntOrd` and `listOrd` givens above were left out, the following names would be synthesized instead: ```scala -given given_Ord_Int as Ord[Int] { ... } -given given_Ord_List_T[T](using ord: Ord[T]) as Ord[List[T]] { ... } +given Ord[Int] as given_Ord_Int { ... } +given [T] => Ord[T] => Ord[List[T]] as given_Ord_List_T { ... } ``` The synthesized type names are formed from @@ -150,7 +162,7 @@ implicit def stringToToken(str: String): Token = new Keyword(str) one can write ```scala -given stringToToken as Conversion[String, Token] { +given Conversion[String, Token] as stringToToken { def apply(str: String): Token = KeyWord(str) } ``` @@ -158,7 +170,7 @@ given stringToToken as Conversion[String, Token] { or ```scala -given stringToToken as Conversion[String, Token] = KeyWord(_) +given Conversion[String, Token] as stringToToken = KeyWord(_) ``` ### Implicit Classes diff --git a/docs/docs/reference/contextual/type-classes.md b/docs/docs/reference/contextual/type-classes.md index 412ef7834103..37ddae9a6159 100644 --- a/docs/docs/reference/contextual/type-classes.md +++ b/docs/docs/reference/contextual/type-classes.md @@ -158,7 +158,7 @@ end Monad A `List` can be turned into a monad via this `given` instance: ```scala -given listMonad as Monad[List]: +given Monad[List]: def pure[A](x: A): List[A] = List(x) extension [A, B](xs: List[A]) @@ -175,7 +175,7 @@ it explicitly. `Option` is an other type having the same kind of behaviour: ```scala -given optionMonad as Monad[Option]: +given Monad[Option]: def pure[A](x: A): Option[A] = Option(x) extension [A, B](xo: Option[A]) @@ -222,7 +222,7 @@ type ConfigDependent[Result] = Config => Result The monad instance will look like this: ```scala -given configDependentMonad as Monad[ConfigDependent]: +given Monad[ConfigDependent] as configDependentMonad: def pure[A](x: A): ConfigDependent[A] = config => x @@ -243,7 +243,7 @@ type ConfigDependent = [Result] =>> Config => Result Using this syntax would turn the previous `configDependentMonad` into: ```scala -given configDependentMonad as Monad[[Result] =>> Config => Result] +given Monad[[Result] =>> Config => Result] as configDependentMonad def pure[A](x: A): Config => A = config => x @@ -258,7 +258,7 @@ end configDependentMonad It is likely that we would like to use this pattern with other kinds of environments than our `Config` trait. The Reader monad allows us to abstract away `Config` as a type _parameter_, named `Ctx` in the following definition: ```scala -given readerMonad[Ctx] as Monad[[X] =>> Ctx => X]: +given [Ctx] => Monad[[X] =>> Ctx => X] as readerMonad: def pure[A](x: A): Ctx => A = ctx => x diff --git a/docs/docs/reference/contextual/using-clauses.md b/docs/docs/reference/contextual/using-clauses.md index 7f494f7b5845..65bc0a85c661 100644 --- a/docs/docs/reference/contextual/using-clauses.md +++ b/docs/docs/reference/contextual/using-clauses.md @@ -69,9 +69,9 @@ def f(u: Universe)(using ctx: u.Context)(using s: ctx.Symbol, k: ctx.Kind) = ... Multiple using clauses are matched left-to-right in applications. Example: ```scala object global extends Universe { type Context = ... } -given ctx as global.Context { type Symbol = ...; type Kind = ... } -given sym as ctx.Symbol -given kind as ctx.Kind +given global.Context as ctx { type Symbol = ...; type Kind = ... } +given ctx.Symbol as sym +given ctx.Kind as kind ``` Then the following calls are all valid (and normalize to the last one) ```scala From 86101b10cf8a747e3131c1410e6f101bb177a7c1 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 27 Nov 2020 10:53:35 +0100 Subject: [PATCH 14/14] Switch to postfix `as` for patterns --- .../dotty/tools/dotc/core/TypeComparer.scala | 4 ++-- .../src/dotty/tools/dotc/core/TypeOps.scala | 2 +- .../dotty/tools/dotc/parsing/Parsers.scala | 24 +++++++++++++------ .../tools/dotc/printing/RefinedPrinter.scala | 2 +- .../tools/dotc/transform/patmat/Space.scala | 2 +- .../dotty/tools/dotc/typer/Applications.scala | 2 +- docs/docs/internals/syntax.md | 3 +-- .../reference/contextual/given-imports.md | 6 ++--- library/src/scala/quoted/ExprMap.scala | 2 +- .../src/tests/implicitConversions2.scala | 2 +- tests/init/crash/fors.scala | 4 ++-- tests/neg/Iter3.scala | 2 +- tests/neg/ensureReported.scala | 2 +- tests/neg/i1716.scala | 2 +- tests/neg/i3200.scala | 2 +- tests/neg/i3200b.scala | 8 +++---- tests/neg/i3332.scala | 2 +- tests/neg/i3812b.scala | 4 ++-- tests/neg/i8407.scala | 2 +- tests/neg/i8715.scala | 2 +- tests/neg/i9310.scala | 2 +- tests/neg/multi-patterns.scala | 2 +- tests/neg/patternUnsoundness.scala | 2 +- tests/patmat/i7186.scala | 2 +- tests/pos-macros/i6535/Macro_1.scala | 2 +- tests/pos-macros/quoted-pattern-type.scala | 14 +++++------ .../CollectionStrawMan1.scala | 2 +- .../CollectionStrawMan4.scala | 4 ++-- tests/pos-with-compiler/Patterns.scala | 4 ++-- tests/pos/Iter2.scala | 2 +- tests/pos/given-pattern.scala | 6 ++--- tests/pos/i10087.scala | 2 +- tests/pos/i1540.scala | 2 +- tests/pos/i1540b.scala | 2 +- tests/pos/i3412.scala | 2 +- tests/pos/i4177.scala | 2 +- tests/pos/i4564.scala | 2 +- tests/pos/i5402.scala | 2 +- tests/pos/reference/delegate-match.scala | 2 +- tests/pos/reference/delegates.scala | 2 +- tests/pos/simpleExtractors-2.scala | 4 ++-- tests/pos/t10533.scala | 2 +- tests/pos/t3136.scala | 2 +- tests/pos/t6675.scala | 2 +- tests/pos/trailingCommas/trailingCommas.scala | 2 +- tests/pos/virtpatmat_alts_subst.scala | 2 +- .../tasty-extractors-owners/quoted_1.scala | 4 ++-- .../interpreter/TreeInterpreter.scala | 6 ++--- .../typelevel-defaultValue.scala | 2 +- .../colltest4/CollectionStrawMan4_1.scala | 4 ++-- tests/run-macros/i5715/Macro_1.scala | 2 +- tests/run-macros/i6171/Macro_1.scala | 2 +- tests/run-macros/i8745/Macro_1.scala | 2 +- tests/run-macros/i8745b/Macro_1.scala | 2 +- tests/run-macros/i9812b/Macro_1.scala | 2 +- .../quoted-pattern-type/Macro_1.scala | 6 ++--- tests/run-macros/reflect-dsl/assert_1.scala | 2 +- .../run-macros/reflect-pos-fun/assert_1.scala | 2 +- .../reflect-select-constructor/assert_1.scala | 2 +- .../reflect-select-copy-2/assert_1.scala | 2 +- .../reflect-select-copy/assert_1.scala | 2 +- .../assert_1.scala | 2 +- .../reflect-select-value-class/assert_1.scala | 2 +- tests/run/3179.scala | 2 +- tests/run/enums-serialization-compat.scala | 6 ++--- tests/run/fors.scala | 4 ++-- tests/run/fully-abstract-interface.scala | 8 +++---- tests/run/fully-abstract-nat-1.scala | 2 +- tests/run/fully-abstract-nat-2.scala | 2 +- tests/run/fully-abstract-nat-3.scala | 4 ++-- tests/run/fully-abstract-nat-4.scala | 2 +- tests/run/fully-abstract-nat-5.scala | 2 +- tests/run/fully-abstract-nat-6.scala | 2 +- tests/run/fully-abstract-nat-7.scala | 2 +- tests/run/fully-abstract-nat.scala | 4 ++-- tests/run/i1099.scala | 2 +- tests/run/i1432.scala | 4 ++-- tests/run/i1463.scala | 2 +- tests/run/i1991.scala | 4 ++-- tests/run/i3200c.scala | 2 +- tests/run/patmat-bind-typed.scala | 2 +- tests/run/patmat-spec.scala | 2 +- tests/run/patmatch-classtag.scala | 2 +- tests/run/t6646.scala | 4 ++-- tests/run/t8395.scala | 2 +- tests/run/type-test-binding.scala | 2 +- tests/run/type-test-nat.scala | 2 +- tests/run/unchecked-patterns.scala | 2 +- tests/untried/neg/catch-all.scala | 4 ++-- tests/untried/neg/t7290.scala | 2 +- 90 files changed, 143 insertions(+), 134 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala index 93d715ca38ed..9b60fb63c409 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala @@ -630,7 +630,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling } } compareTypeLambda - case tp2 as OrType(tp21, tp22) => + case tp2 @ OrType(tp21, tp22) => compareAtoms(tp1, tp2) match case Some(b) => return b case _ => @@ -970,7 +970,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling * corresponding arguments are subtypes relative to their variance (see `isSubArgs`). */ def isMatchingApply(tp1: Type): Boolean = tp1 match { - case tp1 as AppliedType(tycon1, args1) => + case tp1 @ AppliedType(tycon1, args1) => // We intentionally do not automatically dealias `tycon1` or `tycon2` here. // `TypeApplications#appliedTo` already takes care of dealiasing type // constructors when this can be done without affecting type diff --git a/compiler/src/dotty/tools/dotc/core/TypeOps.scala b/compiler/src/dotty/tools/dotc/core/TypeOps.scala index a2dfffd74c99..cfe3b80a2422 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeOps.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeOps.scala @@ -150,7 +150,7 @@ object TypeOps: tp.derivedAlias(simplify(tp.alias, theMap)) case AndType(l, r) if !ctx.mode.is(Mode.Type) => simplify(l, theMap) & simplify(r, theMap) - case tp as OrType(l, r) + case tp @ OrType(l, r) if !ctx.mode.is(Mode.Type) && (tp.isSoft || l.isBottomType || r.isBottomType) => // Normalize A | Null and Null | A to A even if the union is hard (i.e. diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index c2a1e6d50571..0eb34aeea523 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -2657,12 +2657,12 @@ object Parsers { ascription(p, location) else p - /** Pattern2 ::= [id `as'] InfixPattern + /** Pattern2 ::= InfixPattern [`as' id] */ - val pattern2: () => Tree = () => infixPattern() match { - case p @ Ident(name) if in.token == AT || in.isIdent(nme.as) => - if in.token == AT && sourceVersion.isAtLeast(`3.1`) then - deprecationWarning(s"`@` bindings have been deprecated; use `as` instead", in.offset) + val pattern2: () => Tree = () => infixPattern() match + case p @ Ident(name) if in.token == AT => + if sourceVersion.isAtLeast(`3.1`) then + deprecationWarning(s"` @ ` bindings have been deprecated; use ` as ` instead", in.offset) val offset = in.skipToken() infixPattern() match { @@ -2678,8 +2678,18 @@ object Parsers { warnMigration(p) atSpan(startOffset(p)) { Typed(Ident(nme.WILDCARD), p) } case p => - p - } + if in.isIdent(nme.as) then + in.nextToken() + atSpan(startOffset(p), in.offset) { + p match + case p @ Bind(nme.WILDCARD, pt: Typed) if p.mods.is(Given) => + Bind(ident(), pt).withMods(p.mods) + case _ => + Bind(ident(), p) + } + else + p + end pattern2 private def warnMigration(p: Tree) = if sourceVersion.isAtLeast(`3.1`) then diff --git a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala index 9ec00ba3b642..dabc9d25acf1 100644 --- a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala +++ b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala @@ -214,7 +214,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { // of AndType and OrType to account for associativity case AndType(tp1, tp2) => toTextInfixType(tpnme.raw.AMP, tp1, tp2) { toText(tpnme.raw.AMP) } - case tp as OrType(tp1, tp2) => + case tp @ OrType(tp1, tp2) => toTextInfixType(tpnme.raw.BAR, tp1, tp2) { if tp.isSoft && printDebug then toText(tpnme.ZOR) else toText(tpnme.raw.BAR) } diff --git a/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala b/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala index 582429823fac..a231dfe8d955 100644 --- a/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala +++ b/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala @@ -480,7 +480,7 @@ class SpaceEngine(using Context) extends SpaceLogic { else args.map(arg => erase(arg, inArray = false)) tp.derivedAppliedType(erase(tycon, inArray), args2) - case tp as OrType(tp1, tp2) => + case tp @ OrType(tp1, tp2) => OrType(erase(tp1, inArray), erase(tp2, inArray), tp.isSoft) case AndType(tp1, tp2) => diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala index cf004a9134f8..f299b6bc37cf 100644 --- a/compiler/src/dotty/tools/dotc/typer/Applications.scala +++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala @@ -600,7 +600,7 @@ trait Applications extends Compatibility { args match { case arg :: Nil if isVarArg(arg) => addTyped(arg, formal) - case (arg as Typed(Literal(Constant(null)), _)) :: Nil if ctx.isAfterTyper => + case (arg @ Typed(Literal(Constant(null)), _)) :: Nil if ctx.isAfterTyper => addTyped(arg, formal) case _ => val elemFormal = formal.widenExpr.argTypesLo.head diff --git a/docs/docs/internals/syntax.md b/docs/docs/internals/syntax.md index dbb27f7f2b87..1b562c260a7f 100644 --- a/docs/docs/internals/syntax.md +++ b/docs/docs/internals/syntax.md @@ -268,8 +268,7 @@ TypeCaseClauses ::= TypeCaseClause { TypeCaseClause } TypeCaseClause ::= ‘case’ InfixType ‘=>’ Type [nl] Pattern ::= Pattern1 { ‘|’ Pattern1 } Alternative(pats) -Pattern1 ::= Pattern2 [‘:’ RefinedType] Bind(name, Typed(Ident(wildcard), tpe)) -Pattern2 ::= [id ‘as’] InfixPattern Bind(name, pat) +Pattern1 ::= InfixPattern [‘as’ id] [‘:’ RefinedType] Bind(name, pat), Bind(name, Typed(Ident(wildcard), tpe)) InfixPattern ::= SimplePattern { id [nl] SimplePattern } InfixOp(pat, op, pat) SimplePattern ::= PatVar Ident(wildcard) | Literal Bind(name, Ident(wildcard)) diff --git a/docs/docs/reference/contextual/given-imports.md b/docs/docs/reference/contextual/given-imports.md index c5ae20f6d565..c0fded3a2b1e 100644 --- a/docs/docs/reference/contextual/given-imports.md +++ b/docs/docs/reference/contextual/given-imports.md @@ -61,9 +61,9 @@ For instance, assuming the object ```scala object Instances { given Ordering[Int] as intOrd - given listOrd[T: Ordering] as Ordering[List[T]] - given ec as ExecutionContext = ... - given im as Monoid[Int] + given [T: Ordering] => Ordering[List[T]] as listOrd + given ExecutionContext as ec = ... + given Monoid[Int] as im } ``` diff --git a/library/src/scala/quoted/ExprMap.scala b/library/src/scala/quoted/ExprMap.scala index b6064f238a2e..4d7be33d7372 100644 --- a/library/src/scala/quoted/ExprMap.scala +++ b/library/src/scala/quoted/ExprMap.scala @@ -47,7 +47,7 @@ trait ExprMap: tree case Super(qual, mix) => tree - case tree as Apply(fun, args) => + case tree @ Apply(fun, args) => val MethodType(_, tpes, _) = fun.tpe.widen Apply.copy(tree)(transformTerm(fun, TypeRepr.of[Any])(owner), transformTerms(args, tpes)(owner)) case TypeApply(fun, args) => diff --git a/scala3doc-testcases/src/tests/implicitConversions2.scala b/scala3doc-testcases/src/tests/implicitConversions2.scala index 018164b0e5c0..3c1470d00919 100644 --- a/scala3doc-testcases/src/tests/implicitConversions2.scala +++ b/scala3doc-testcases/src/tests/implicitConversions2.scala @@ -29,7 +29,7 @@ class OuterClass //unexpected = ??? } - given conversionFromVal as Conversion[ClassWithConversionFromVal, Methods] //unexpected + given Conversion[ClassWithConversionFromVal, Methods] as conversionFromVal //unexpected { def apply(a: ClassWithConversionFromVal): Methods //unexpected = ??? diff --git a/tests/init/crash/fors.scala b/tests/init/crash/fors.scala index 50ed4bf69a38..9b156ab787b0 100644 --- a/tests/init/crash/fors.scala +++ b/tests/init/crash/fors.scala @@ -26,7 +26,7 @@ object Test extends App { var n = 0 for (_ <- xs) n += 1; println(n) for ((x, y) <- xs zip ys) print(x + " "); println() - for (p as (x, y) <- xs zip ys) print(p._1 + " "); println() + for ((x, y) as p <- xs zip ys) print(p._1 + " "); println() // iterators for (x <- it) print(x + " "); println() @@ -53,7 +53,7 @@ object Test extends App { var n = 0 for (_ <- xs) n += 1; println(n) for ((x, y) <- xs zip ys) print(x + " "); println() - for (p as (x, y) <- xs zip ys) print(p._1 + " "); println() + for ((x, y) as p <- xs zip ys) print(p._1 + " "); println() // iterators for (x <- it) print(x + " "); println() diff --git a/tests/neg/Iter3.scala b/tests/neg/Iter3.scala index db363432a021..ad1c74a9428b 100644 --- a/tests/neg/Iter3.scala +++ b/tests/neg/Iter3.scala @@ -147,7 +147,7 @@ object Iter2 { flatten(map(f(_).buildIterator)) override def ++[B >: A](that: IterableOnce[B]): ArrayIterator[B] = { - val thatIterator as ArrayIterator(elems2, len2) = fromIterator(that.iterator) + val ArrayIterator(elems2, len2) as thatIterator = fromIterator(that.iterator) if (len == 0) thatIterator else if (len2 == 0) this.asInstanceOf[ArrayIterator[B]] else { diff --git a/tests/neg/ensureReported.scala b/tests/neg/ensureReported.scala index 712c541f8e40..557985f5cd0c 100644 --- a/tests/neg/ensureReported.scala +++ b/tests/neg/ensureReported.scala @@ -1,6 +1,6 @@ object AnonymousF { val f = { - case l as List(1) => // error: missing parameter type + case List(1) as l => // error: missing parameter type Some(l) } } diff --git a/tests/neg/i1716.scala b/tests/neg/i1716.scala index b9994d3fd1cc..6160343bbb5c 100644 --- a/tests/neg/i1716.scala +++ b/tests/neg/i1716.scala @@ -1,7 +1,7 @@ object Fail { def f(m: Option[Int]): Unit = { m match { - case x as Some[_] => // error: unbound wildcard type + case Some[_] as x => // error: unbound wildcard type case _ => } } diff --git a/tests/neg/i3200.scala b/tests/neg/i3200.scala index 8e7da443a758..4f30b30dae25 100644 --- a/tests/neg/i3200.scala +++ b/tests/neg/i3200.scala @@ -1,6 +1,6 @@ object Test { case object Bob { override def equals(other: Any) = true } def main(args: Array[String]): Unit = { - val m : Bob.type = (5: Any) match { case x as Bob => x } // error + val m : Bob.type = (5: Any) match { case Bob as x => x } // error } } diff --git a/tests/neg/i3200b.scala b/tests/neg/i3200b.scala index 9b647838ba4a..bd01ce61ec18 100644 --- a/tests/neg/i3200b.scala +++ b/tests/neg/i3200b.scala @@ -1,8 +1,8 @@ object Test { def main(args: Array[String]): Unit = { - val a: Nil.type = (Vector(): Any) match { case n as Nil => n } // error - val b: Nil.type = (Vector(): Any) match { case n as (m as Nil) => n } // error - val c: Int = (1.0: Any) match { case n as 1 => n } // error - val d: Int = (1.0: Any) match { case n as (m as 1) => n } // error + val a: Nil.type = (Vector(): Any) match { case Nil as n => n } // error + val b: Nil.type = (Vector(): Any) match { case (Nil as m) as n => n } // error + val c: Int = (1.0: Any) match { case 1 as n => n } // error + val d: Int = (1.0: Any) match { case (1 as m) as n => n } // error } } diff --git a/tests/neg/i3332.scala b/tests/neg/i3332.scala index 64aad9c97777..28ab4470e4dc 100644 --- a/tests/neg/i3332.scala +++ b/tests/neg/i3332.scala @@ -16,6 +16,6 @@ object Test { case _ => println("nope") } def test(x: Any) = x match { - case _: String | _ as A() => 1 + case _: String | A() => 1 } } diff --git a/tests/neg/i3812b.scala b/tests/neg/i3812b.scala index 8a222a2e8ce3..8860b182cd61 100644 --- a/tests/neg/i3812b.scala +++ b/tests/neg/i3812b.scala @@ -19,9 +19,9 @@ object Test { Some(x) match { case Some(Z2.v) => () } // ok Some(x) match { case Some(4) | Some(Z1.v) => () } // error - Some(x) match { case a as Some(Z1.v) => () } // error + Some(x) match { case Some(Z1.v) as a => () } // error Some(x) match { case Some(4) | Some(Z2.v) => () } // ok - Some(x) match { case a as Some(Z2.v) => () } // ok + Some(x) match { case Some(Z2.v) as a => () } // ok } } diff --git a/tests/neg/i8407.scala b/tests/neg/i8407.scala index 744bb1487700..82f99fe4d224 100644 --- a/tests/neg/i8407.scala +++ b/tests/neg/i8407.scala @@ -1,6 +1,6 @@ object Test: val xs = List(1, 2, 3, 4, 5) xs match { - case List(1, 2, xs1 as xs2: _*) => println(xs2) // error // error + case List(1, 2, xs2 as xs1: _*) => println(xs2) // error // error case _ => () } \ No newline at end of file diff --git a/tests/neg/i8715.scala b/tests/neg/i8715.scala index f5607e39a615..0d4ac66e2ecb 100644 --- a/tests/neg/i8715.scala +++ b/tests/neg/i8715.scala @@ -1,2 +1,2 @@ @main -def Test = List(42) match { case List(xs as (ys: _*)) => xs } // error +def Test = List(42) match { case List((ys: _*) as xs) => xs } // error diff --git a/tests/neg/i9310.scala b/tests/neg/i9310.scala index 7d23e0b7a18e..93535049b528 100644 --- a/tests/neg/i9310.scala +++ b/tests/neg/i9310.scala @@ -1,5 +1,5 @@ //AE-d101cfe6d25117a51897609e673f6c8e74d31e6e -val foo as this = 0 +val this as foo = 0 class Foo { foo { } // error } \ No newline at end of file diff --git a/tests/neg/multi-patterns.scala b/tests/neg/multi-patterns.scala index 3cacb40e7bac..bb7d36eb271e 100644 --- a/tests/neg/multi-patterns.scala +++ b/tests/neg/multi-patterns.scala @@ -1,4 +1,4 @@ object Test { val (a :: as), bs = List(1, 2, 3) // error - val B as List(), C: List[Int] = List() // error + val List() as B, C: List[Int] = List() // error } \ No newline at end of file diff --git a/tests/neg/patternUnsoundness.scala b/tests/neg/patternUnsoundness.scala index 1db64979dd2d..cf7484f979e4 100644 --- a/tests/neg/patternUnsoundness.scala +++ b/tests/neg/patternUnsoundness.scala @@ -10,7 +10,7 @@ object patternUnsoundness extends App { val y: C[Object] = x y match { - case d as D(x) => d.s = new Integer(1) // error + case D(x) as d => d.s = new Integer(1) // error } val z: String = x.s // used to throw ClassCast exception diff --git a/tests/patmat/i7186.scala b/tests/patmat/i7186.scala index d34945bed756..13942217c824 100644 --- a/tests/patmat/i7186.scala +++ b/tests/patmat/i7186.scala @@ -118,7 +118,7 @@ object printMips { s"$indent.globl $id$endl" case Label(Scoped(Identifier(i),-1)) => s"$i:$endl" - case Label(s @ Scoped(Identifier(i), id)) => + case Label(Scoped(Identifier(i), id) as s) => s"${getScopedLabel(s)}: #debug: $i~$id$endl" case ControlLabel(id) => s"${evalLabels(id)}:$endl" diff --git a/tests/pos-macros/i6535/Macro_1.scala b/tests/pos-macros/i6535/Macro_1.scala index aaec24d82ba5..5016d2b2b124 100644 --- a/tests/pos-macros/i6535/Macro_1.scala +++ b/tests/pos-macros/i6535/Macro_1.scala @@ -10,7 +10,7 @@ object scalatest { import ValDef.let Term.of(cond).underlyingArgument match { - case t @ Apply(Select(lhs, op), rhs :: Nil) => + case Apply(Select(lhs, op), rhs :: Nil) as t => let(Symbol.spliceOwner, lhs) { left => let(Symbol.spliceOwner, rhs) { right => val app = Select.overloaded(left, op, Nil, right :: Nil) diff --git a/tests/pos-macros/quoted-pattern-type.scala b/tests/pos-macros/quoted-pattern-type.scala index 4cf7e0f43bab..bf44de08ebe8 100644 --- a/tests/pos-macros/quoted-pattern-type.scala +++ b/tests/pos-macros/quoted-pattern-type.scala @@ -4,39 +4,39 @@ object Lib { def impl[T: Type](arg: Expr[T])(using Quotes): Expr[T] = { arg match { - case e @ '{ $x: Boolean } => + case '{ $x: Boolean } as e => e: Expr[T & Boolean] x: Expr[T & Boolean] e - case e @ '{ println("hello"); $x } => + case '{ println("hello"); $x } as e => e: Expr[T] x: Expr[T] e - case e @ '{ println("hello"); $x: T } => + case '{ println("hello"); $x: T } as e => e: Expr[T] x: Expr[T] e - case e @ '{ Some($x: Int) } => + case '{ Some($x: Int) } as e => e: Expr[T & Some[Int]] x: Expr[Int] e - case e @ '{ if ($x) ($y: Boolean) else ($z: Int) } => + case '{ if ($x) ($y: Boolean) else ($z: Int) } as e => e: Expr[T & (Boolean | Int)] y: Expr[T & Boolean] z: Expr[T & Int] e - case e @ '{ if ($x) $y else $z } => + case '{ if ($x) $y else $z } as e => e: Expr[T] y: Expr[T] z: Expr[T] e - case e @ '{ if ($x) $y else ($z: Int) } => + case '{ if ($x) $y else ($z: Int) } as e => e: Expr[T & (T | Int)] y: Expr[T] z: Expr[T & Int] diff --git a/tests/pos-special/strawman-collections/CollectionStrawMan1.scala b/tests/pos-special/strawman-collections/CollectionStrawMan1.scala index c127757ad539..9023e5388a92 100644 --- a/tests/pos-special/strawman-collections/CollectionStrawMan1.scala +++ b/tests/pos-special/strawman-collections/CollectionStrawMan1.scala @@ -190,7 +190,7 @@ object CollectionStrawMan1 { Array.copy(fst.elems, fst.start, elems, 0, fst.remaining) Array.copy(snd.elems, snd.start, elems, fst.remaining, snd.remaining) new ArrayBuffer(elems, elems.length) - case it @ Iterator.Partition(underlying, _, buf, _) => + case Iterator.Partition(underlying, _, buf, _) as it => while (underlying.hasNext) it.distribute() buf.asInstanceOf[ArrayBuffer[B]] case it if it.remaining >= 0 => diff --git a/tests/pos-special/strawman-collections/CollectionStrawMan4.scala b/tests/pos-special/strawman-collections/CollectionStrawMan4.scala index a554c3e8c794..c2ce94876122 100644 --- a/tests/pos-special/strawman-collections/CollectionStrawMan4.scala +++ b/tests/pos-special/strawman-collections/CollectionStrawMan4.scala @@ -216,7 +216,7 @@ object CollectionStrawMan4 { object ListBuffer extends IterableFactory[ListBuffer] { def fromIterable[B](coll: Iterable[B]): ListBuffer[B] = coll match { - case pd @ View.Partitioned(partition: View.Partition[B] @unchecked) => + case View.Partitioned(partition: View.Partition[B] @unchecked) as pd => partition.distribute(new ListBuffer[B]()) new ListBuffer[B] ++= pd.forced.get case _ => @@ -267,7 +267,7 @@ object CollectionStrawMan4 { Array.copy(fst.elems, fst.start, elems, 0, fst.length) Array.copy(snd.elems, snd.start, elems, fst.length, snd.length) new ArrayBuffer(elems, elems.length) - case pd @ View.Partitioned(partition: View.Partition[B] @unchecked) => + case View.Partitioned(partition: View.Partition[B] @unchecked) as pd => partition.distribute(new ArrayBuffer[B]()) pd.forced.get.asInstanceOf[ArrayBuffer[B]] case c if c.knownLength >= 0 => diff --git a/tests/pos-with-compiler/Patterns.scala b/tests/pos-with-compiler/Patterns.scala index ecbde54df0b0..7b084adaf09b 100644 --- a/tests/pos-with-compiler/Patterns.scala +++ b/tests/pos-with-compiler/Patterns.scala @@ -13,7 +13,7 @@ object Patterns { } d match { case WildcardType(bounds: TypeBounds) => bounds.lo - case a @ Assign(Ident(id), rhs) => id + case Assign(Ident(id), rhs) as a => id case a: Object => a } @@ -42,7 +42,7 @@ object Patterns { case List(x, z) => x case List(x) => x case List() => "" - case x @ _ => "wildcard" + case _ as x => "wildcard" } val yy: String = y } diff --git a/tests/pos/Iter2.scala b/tests/pos/Iter2.scala index 193a715e388f..698060ed9f72 100644 --- a/tests/pos/Iter2.scala +++ b/tests/pos/Iter2.scala @@ -193,7 +193,7 @@ object Iter2 { flatten(map(f(_).buildIterator)) override def ++[B >: A](that: IterableOnce[B]): ArrayIterator[B] = { - val thatIterator as ArrayIterator(elems2, len2) = fromIterator(that.iterator) + val ArrayIterator(elems2, len2) as thatIterator = fromIterator(that.iterator) if (len == 0) thatIterator else if (len2 == 0) this else { diff --git a/tests/pos/given-pattern.scala b/tests/pos/given-pattern.scala index 6267e23193e4..2318cf3cef38 100644 --- a/tests/pos/given-pattern.scala +++ b/tests/pos/given-pattern.scala @@ -6,17 +6,17 @@ class Test { transparent inline def trySummon[S, T](f: PartialFunction[S, T]): T = ??? inline def setFor[T]: Set[T] = trySummon { - case ord as given Ordering[T] => new TreeSet[T] + case given Ordering[T] as ord => new TreeSet[T] case given Ordering[T] => new TreeSet[T] case _ => new HashSet[T] } def f1[T](x: Ordering[T]) = (x, x) match { - case (y as given Ordering[T], _) => new TreeSet[T] + case (given Ordering[T] as y, _) => new TreeSet[T] } def f2[T](x: Ordering[T]) = { val xs = List(x, x, x) - for y as given Ordering[T] <- xs + for given Ordering[T] as y <- xs yield new TreeSet[T] } def f3[T](x: Ordering[T]) = (x, x) match { diff --git a/tests/pos/i10087.scala b/tests/pos/i10087.scala index 7c9cd1ca24e3..8ace96b33c25 100644 --- a/tests/pos/i10087.scala +++ b/tests/pos/i10087.scala @@ -8,6 +8,6 @@ def f4[T](x: Ordering[T]) = { val xs = List(x, x, x) for given Ordering[T] <- xs yield new TreeSet[T] - for x as given Ordering[T] <- xs + for given Ordering[T] as x <- xs yield new TreeSet[T] } \ No newline at end of file diff --git a/tests/pos/i1540.scala b/tests/pos/i1540.scala index 096a19aee060..01b80b155792 100644 --- a/tests/pos/i1540.scala +++ b/tests/pos/i1540.scala @@ -8,7 +8,7 @@ object Casey1 { def unapply(a: Casey1) = a } object Test { def main(args: Array[String]): Unit = { - val c as Casey1(x) = new Casey1(0) + val Casey1(x) as c = new Casey1(0) assert(x == c.get) } } diff --git a/tests/pos/i1540b.scala b/tests/pos/i1540b.scala index 64a09a43061d..9ad0b5aa8543 100644 --- a/tests/pos/i1540b.scala +++ b/tests/pos/i1540b.scala @@ -8,7 +8,7 @@ object Casey1 { def unapply[T](a: Casey1[T]) = a } object Test { def main(args: Array[String]): Unit = { - val c as Casey1(x) = new Casey1(0) + val Casey1(x) as c = new Casey1(0) assert(x == c.get) } } diff --git a/tests/pos/i3412.scala b/tests/pos/i3412.scala index 071fcee9fb53..52a4cd08f310 100644 --- a/tests/pos/i3412.scala +++ b/tests/pos/i3412.scala @@ -1,3 +1,3 @@ class Test { - val A as List() = List() + val List() as A = List() } diff --git a/tests/pos/i4177.scala b/tests/pos/i4177.scala index 13dde628a77a..2fe2b0b201aa 100644 --- a/tests/pos/i4177.scala +++ b/tests/pos/i4177.scala @@ -6,7 +6,7 @@ class Test { val a: PartialFunction[Int, String] = { case Foo(x) => x } val b: PartialFunction[Int, String] = { case x => x.toString } - val e: PartialFunction[String, String] = { case x as "abc" => x } + val e: PartialFunction[String, String] = { case "abc" as x => x } val f: PartialFunction[String, String] = x => x match { case "abc" => x } val g: PartialFunction[String, String] = x => x match { case "abc" if x.isEmpty => x } diff --git a/tests/pos/i4564.scala b/tests/pos/i4564.scala index 66e97aabd795..bda512e0febd 100644 --- a/tests/pos/i4564.scala +++ b/tests/pos/i4564.scala @@ -10,7 +10,7 @@ object ClashNoSig { // ok def unapply(x: ClashNoSig) = x ClashNoSig(2) match { - case c as ClashNoSig(y) => c.copy(y + c._1) + case ClashNoSig(y) as c => c.copy(y + c._1) } } case class ClashNoSig private (x: Int) { diff --git a/tests/pos/i5402.scala b/tests/pos/i5402.scala index 647dd43afeb3..fff78ca6defb 100644 --- a/tests/pos/i5402.scala +++ b/tests/pos/i5402.scala @@ -9,7 +9,7 @@ object Main { case 1 => 1 case 0 | 0 => 0 case 2 | 2 | 2 | 3 | 2 | 3 => 0 - case 4 | (_ as 4) => 0 + case 4 | 4 => 0 case _ => -1 } diff --git a/tests/pos/reference/delegate-match.scala b/tests/pos/reference/delegate-match.scala index 4e81c63af37b..f3caf24dcaf8 100644 --- a/tests/pos/reference/delegate-match.scala +++ b/tests/pos/reference/delegate-match.scala @@ -5,7 +5,7 @@ class Test extends App: import scala.compiletime.summonFrom transparent inline def setFor[T]: Set[T] = summonFrom { - case ord as given Ordering[T] => new TreeSet[T] + case given Ordering[T] as ord => new TreeSet[T] case _ => new HashSet[T] } diff --git a/tests/pos/reference/delegates.scala b/tests/pos/reference/delegates.scala index a54e14ad7fd6..c50f038fe7c0 100644 --- a/tests/pos/reference/delegates.scala +++ b/tests/pos/reference/delegates.scala @@ -145,7 +145,7 @@ object AnonymousInstances extends Common: extension (x: Int) def compareTo(y: Int) = if (x < y) -1 else if (x > y) +1 else 0 - given [T: Ord] => Ord[List[T]]: + given [T] => Ord[T] => Ord[List[T]]: extension (xs: List[T]) def compareTo(ys: List[T]): Int = (xs, ys).match case (Nil, Nil) => 0 case (Nil, _) => -1 diff --git a/tests/pos/simpleExtractors-2.scala b/tests/pos/simpleExtractors-2.scala index ba0cecab5d78..722564e6a70b 100644 --- a/tests/pos/simpleExtractors-2.scala +++ b/tests/pos/simpleExtractors-2.scala @@ -1,7 +1,7 @@ class Foo { def bar(x: Any): Unit = x match { case Some(Some(i: Int)) => println(i) - case Some(s as Some(i)) => println(s) - case s as Some(r as Some(i)) => println(s) + case Some(Some(i) as s) => println(s) + case Some(Some(i) as r) as s => println(s) } } diff --git a/tests/pos/t10533.scala b/tests/pos/t10533.scala index 714ec72979c1..524cb6a62b6f 100644 --- a/tests/pos/t10533.scala +++ b/tests/pos/t10533.scala @@ -1,5 +1,5 @@ object Foo { - val b as Bar(_) = Bar(1)(2)(3) + val Bar(_) as b = Bar(1)(2)(3) } case class Bar(a: Int)(b: Int)(c: Int) diff --git a/tests/pos/t3136.scala b/tests/pos/t3136.scala index 86a2c81e3045..1bd215ac9d77 100644 --- a/tests/pos/t3136.scala +++ b/tests/pos/t3136.scala @@ -13,7 +13,7 @@ object NullaryMethodType { object Test { def TEST(tp: Type): String = tp match { - case PolyType(ps1, PolyType(ps2, res as PolyType(a, b))) => "1" + tp // couldn't find a simpler version that still crashes + case PolyType(ps1, PolyType(ps2, PolyType(a, b) as res)) => "1" + tp // couldn't find a simpler version that still crashes case NullaryMethodType(meh) => "2" + meh } } diff --git a/tests/pos/t6675.scala b/tests/pos/t6675.scala index 599ba89dbb14..ff74adb31244 100644 --- a/tests/pos/t6675.scala +++ b/tests/pos/t6675.scala @@ -7,7 +7,7 @@ object LeftOrRight { object Test { (Left((0, 0)): Either[(Int, Int), (Int, Int)]) match { - case LeftOrRight(pair as (a, b)) => a // false -Xlint warning: "extractor pattern binds a single value to a Product2 of type (Int, Int)" + case LeftOrRight((a, b) as pair) => a // false -Xlint warning: "extractor pattern binds a single value to a Product2 of type (Int, Int)" } (Left((0, 0)): Either[(Int, Int), (Int, Int)]) match { diff --git a/tests/pos/trailingCommas/trailingCommas.scala b/tests/pos/trailingCommas/trailingCommas.scala index f0423bc1e00f..5c1f0a947f12 100644 --- a/tests/pos/trailingCommas/trailingCommas.scala +++ b/tests/pos/trailingCommas/trailingCommas.scala @@ -114,7 +114,7 @@ trait SimplePattern { // test '@' syntax in patterns Some(1) match { - case Some(x as 1, + case Some(1 as x, ) => x } diff --git a/tests/pos/virtpatmat_alts_subst.scala b/tests/pos/virtpatmat_alts_subst.scala index 00bd897ea3b5..2e4ae000f6a3 100644 --- a/tests/pos/virtpatmat_alts_subst.scala +++ b/tests/pos/virtpatmat_alts_subst.scala @@ -1,6 +1,6 @@ case class Foo(s: String) { def appliedType(tycon: Any) = tycon match { - case Foo(sym as ("NothingClass" | "AnyClass")) => println(sym) + case Foo(("NothingClass" | "AnyClass") as sym) => println(sym) } } diff --git a/tests/run-custom-args/Yretain-trees/tasty-extractors-owners/quoted_1.scala b/tests/run-custom-args/Yretain-trees/tasty-extractors-owners/quoted_1.scala index 09054f8a5a5e..eecc546b0023 100644 --- a/tests/run-custom-args/Yretain-trees/tasty-extractors-owners/quoted_1.scala +++ b/tests/run-custom-args/Yretain-trees/tasty-extractors-owners/quoted_1.scala @@ -22,12 +22,12 @@ object Macros { import quotes.reflect._ override def traverseTree(tree: Tree)(owner: Symbol): Unit = { tree match { - case tree @ DefDef(name, _, _, _, _) => + case DefDef(name, _, _, _, _) as tree => buff.append(name) buff.append("\n") buff.append(tree.symbol.owner.tree.showExtractors) buff.append("\n\n") - case tree @ ValDef(name, _, _) => + case ValDef(name, _, _) as tree => buff.append(name) buff.append("\n") buff.append(tree.symbol.owner.tree.showExtractors) diff --git a/tests/run-custom-args/tasty-interpreter/interpreter/TreeInterpreter.scala b/tests/run-custom-args/tasty-interpreter/interpreter/TreeInterpreter.scala index f5b0a73ecc12..20fb47640e39 100644 --- a/tests/run-custom-args/tasty-interpreter/interpreter/TreeInterpreter.scala +++ b/tests/run-custom-args/tasty-interpreter/interpreter/TreeInterpreter.scala @@ -114,7 +114,7 @@ abstract class TreeInterpreter[Q <: Quotes & Singleton](using val q: Q) { case Select(prefix, "isInstanceOf") => log("interpretIsInstanceOf", tree)(interpretIsInstanceOf(eval(prefix), targs.head)) case Select(prefix, "asInstanceOf") => log("interpretAsInstanceOf", tree)(interpretAsInstanceOf(eval(prefix), targs.head)) case Select(prefix, "==") => log("interpretEqEq", tree)(interpretEqEq(eval(prefix), eval(argss.head.head))) - case Select(prefix, name @ ("+" | "-" | "*" | "<" | ">" | "<=" | "=>")) if isNumericPrimitive(prefix.tpe) => + case Select(prefix, ("+" | "-" | "*" | "<" | ">" | "<=" | "=>") as name) if isNumericPrimitive(prefix.tpe) => val lhs = eval(prefix) val rhs = eval(argss.head.head) name match { @@ -126,12 +126,12 @@ abstract class TreeInterpreter[Q <: Quotes & Singleton](using val q: Q) { case "<=" => log("interpretPrivitiveLtEq", tree)(interpretPrivitiveLtEq(lhs, rhs)) case ">=" => log("interpretPrivitiveGtEq", tree)(interpretPrivitiveGtEq(lhs, rhs)) } - case Select(prefix, name @ ("/" | "%")) if isIntegralPrimitive(prefix.tpe) => + case Select(prefix, ("/" | "%") as name) if isIntegralPrimitive(prefix.tpe) => def lhs = eval(prefix) def rhs = eval(argss.head.head) if (name == "/") log("interpretPrivitiveQuot", tree)(interpretPrivitiveQuot(lhs, rhs)) else log("interpretPrivitiveRem", tree)(interpretPrivitiveRem(lhs, rhs)) - case Select(prefix, name @ "/") if isFractionalPrimitive(prefix.tpe) => + case Select(prefix, "/" as name) if isFractionalPrimitive(prefix.tpe) => def lhs = eval(prefix) def rhs = eval(argss.head.head) log("interpretPrivitiveDiv", tree)(interpretPrivitiveDiv(lhs, rhs)) diff --git a/tests/run-custom-args/typelevel-defaultValue.scala b/tests/run-custom-args/typelevel-defaultValue.scala index 7c3b0af46d25..4727667c99f1 100644 --- a/tests/run-custom-args/typelevel-defaultValue.scala +++ b/tests/run-custom-args/typelevel-defaultValue.scala @@ -8,7 +8,7 @@ object Test extends App { inline def defaultValue[T] <: Option[Any] = inline compiletime.erasedValue[T] match { case _: Byte => Some(0: Byte) case c: Char => Some(0: Char) - case d @ (_: Short) => Some(0: Short) + case (_: Short) as d => Some(0: Short) case _: Int => Some(0) case _: Long => Some(0L) case _: Float => Some(0.0f) diff --git a/tests/run-deep-subtype/colltest4/CollectionStrawMan4_1.scala b/tests/run-deep-subtype/colltest4/CollectionStrawMan4_1.scala index 1284a00bc6fc..1ec43abff753 100644 --- a/tests/run-deep-subtype/colltest4/CollectionStrawMan4_1.scala +++ b/tests/run-deep-subtype/colltest4/CollectionStrawMan4_1.scala @@ -215,7 +215,7 @@ object CollectionStrawMan4 { object ListBuffer extends IterableFactory[ListBuffer] { def fromIterable[B](coll: Iterable[B]): ListBuffer[B] = coll match { - case pd @ View.Partitioned(partition: View.Partition[B]) => + case View.Partitioned(partition: View.Partition[B]) as pd => partition.distribute(new ListBuffer[B]()) new ListBuffer[B] ++= pd.forced.get case _ => @@ -266,7 +266,7 @@ object CollectionStrawMan4 { Array.copy(fst.elems, fst.start, elems, 0, fst.length) Array.copy(snd.elems, snd.start, elems, fst.length, snd.length) new ArrayBuffer(elems, elems.length) - case pd @ View.Partitioned(partition: View.Partition[B]) => + case View.Partitioned(partition: View.Partition[B]) as pd => partition.distribute(new ArrayBuffer[B]()) pd.forced.get.asInstanceOf[ArrayBuffer[B]] case c if c.knownLength >= 0 => diff --git a/tests/run-macros/i5715/Macro_1.scala b/tests/run-macros/i5715/Macro_1.scala index 199b00433500..b6abf19a7b71 100644 --- a/tests/run-macros/i5715/Macro_1.scala +++ b/tests/run-macros/i5715/Macro_1.scala @@ -8,7 +8,7 @@ object scalatest { import quotes.reflect._ Term.of(cond).underlyingArgument match { - case app @ Apply(select @ Select(lhs, op), rhs :: Nil) => + case Apply(Select(lhs, op) as select, rhs :: Nil) as app => val cond = Apply(Select.copy(select)(lhs, "exists"), rhs :: Nil).asExprOf[Boolean] '{ scala.Predef.assert($cond) } case _ => diff --git a/tests/run-macros/i6171/Macro_1.scala b/tests/run-macros/i6171/Macro_1.scala index 4e1cc1ba89b7..a420cd50a1ec 100644 --- a/tests/run-macros/i6171/Macro_1.scala +++ b/tests/run-macros/i6171/Macro_1.scala @@ -13,7 +13,7 @@ object scalatest { case _ => false Term.of(cond).underlyingArgument match { - case t @ Apply(Select(lhs, op), rhs :: Nil) => + case Apply(Select(lhs, op), rhs :: Nil) as t => ValDef.let(Symbol.spliceOwner, lhs) { left => ValDef.let(Symbol.spliceOwner, rhs) { right => val app = Select.overloaded(left, op, Nil, right :: Nil) diff --git a/tests/run-macros/i8745/Macro_1.scala b/tests/run-macros/i8745/Macro_1.scala index 23a44412789b..30e9f3b4adb7 100644 --- a/tests/run-macros/i8745/Macro_1.scala +++ b/tests/run-macros/i8745/Macro_1.scala @@ -9,7 +9,7 @@ object Macro { inline def mac(inline tree: String): String = ${ macImpl('tree) } def macImpl(tree: Expr[String])(using Quotes): Expr[String] = { tree match { - case vv @ '{ ($s: Trait).fun($arg) } => arg + case '{ ($s: Trait).fun($arg) } as vv => arg case _ => Expr("not matched") } } diff --git a/tests/run-macros/i8745b/Macro_1.scala b/tests/run-macros/i8745b/Macro_1.scala index bebb6cf6c382..596c5afdc3ca 100644 --- a/tests/run-macros/i8745b/Macro_1.scala +++ b/tests/run-macros/i8745b/Macro_1.scala @@ -8,7 +8,7 @@ object Macro { inline def mac(inline tree: String): String = ${ macImpl('tree) } def macImpl(tree: Expr[String])(using Quotes): Expr[String] = { tree match { - case vv @ '{ ($s: Companion.type).fun($arg) } => arg + case '{ ($s: Companion.type).fun($arg) } as vv => arg case _ => ??? } } diff --git a/tests/run-macros/i9812b/Macro_1.scala b/tests/run-macros/i9812b/Macro_1.scala index 37d86152b086..fadeb86f9e22 100644 --- a/tests/run-macros/i9812b/Macro_1.scala +++ b/tests/run-macros/i9812b/Macro_1.scala @@ -35,7 +35,7 @@ given [T <: Int] => Liftable[T] as intLiftable: given [T: Type: Liftable] => (ev1: => Liftable[CONS[T]], ev2: => Liftable[NIL.type]) => Liftable[Lst[T]] as liftLst: def toExpr(xs: Lst[T]): Quotes ?=> Expr[Lst[T]] = xs match case NIL => ev2.toExpr(NIL) - case cons @ CONS(_, _) => ev1.toExpr(cons) + case CONS(_, _) as cons => ev1.toExpr(cons) given [T: Type: Liftable] => (Liftable[Lst[T]]) => Liftable[CONS[T]] as liftCONS: def toExpr(x: CONS[T]): Quotes ?=> Expr[CONS[T]] = '{CONS(${Lift(x.head)}, ${Lift(x.tail)})} diff --git a/tests/run-macros/quoted-pattern-type/Macro_1.scala b/tests/run-macros/quoted-pattern-type/Macro_1.scala index 9406a6f4cd04..69f965f112f5 100644 --- a/tests/run-macros/quoted-pattern-type/Macro_1.scala +++ b/tests/run-macros/quoted-pattern-type/Macro_1.scala @@ -6,11 +6,11 @@ object Lib { private def impl[T: Type](arg: Expr[T])(using Quotes): Expr[T] = { arg match { - case e @ '{ $x: Boolean } => '{ println("Boolean: " + $e); $e } - case e @ '{ $x: Int } => '{ println("Int: " + $x); $x } + case '{ $x: Boolean } as e => '{ println("Boolean: " + $e); $e } + case '{ $x: Int } as e => '{ println("Int: " + $x); $x } case '{ println("hello"); $arg } => '{ println("Printed hello and returned " + $arg); $arg } case '{ println("world"); $arg: T } => '{ println("Printed world and returned " + $arg); $arg } - case e @ '{ Some($x: Int) } => '{ println("Some: " + $x); $e } + case '{ Some($x: Int) } as e => '{ println("Some: " + $x); $e } case arg => '{ ??? } } } diff --git a/tests/run-macros/reflect-dsl/assert_1.scala b/tests/run-macros/reflect-dsl/assert_1.scala index 2b1a6f7b29e4..07f836e5ca49 100644 --- a/tests/run-macros/reflect-dsl/assert_1.scala +++ b/tests/run-macros/reflect-dsl/assert_1.scala @@ -13,7 +13,7 @@ object scalatest { case _ => false Term.of(cond).underlyingArgument match { - case t @ Apply(sel @ Select(lhs, op), rhs :: Nil) => + case Apply(Select(lhs, op) as sel, rhs :: Nil) as t => ValDef.let(Symbol.spliceOwner, lhs) { left => ValDef.let(Symbol.spliceOwner, rhs) { right => val app = left.select(sel.symbol).appliedTo(right) diff --git a/tests/run-macros/reflect-pos-fun/assert_1.scala b/tests/run-macros/reflect-pos-fun/assert_1.scala index e8395b788fa5..d4e8777a5f17 100644 --- a/tests/run-macros/reflect-pos-fun/assert_1.scala +++ b/tests/run-macros/reflect-pos-fun/assert_1.scala @@ -9,7 +9,7 @@ object scalatest { import util._ Term.of(cond).underlyingArgument match { - case t @ Apply(TypeApply(Select(lhs, op), targs), rhs) => + case Apply(TypeApply(Select(lhs, op), targs), rhs) as t => ValDef.let(Symbol.spliceOwner, lhs) { left => ValDef.let(Symbol.spliceOwner, rhs) { rs => val app = Select.overloaded(left, op, targs.map(_.tpe), rs) diff --git a/tests/run-macros/reflect-select-constructor/assert_1.scala b/tests/run-macros/reflect-select-constructor/assert_1.scala index 01e85812e590..36db249da014 100644 --- a/tests/run-macros/reflect-select-constructor/assert_1.scala +++ b/tests/run-macros/reflect-select-constructor/assert_1.scala @@ -13,7 +13,7 @@ object scalatest { case _ => false Term.of(cond).underlyingArgument match { - case t @ Apply(Select(lhs, op), rhs :: Nil) => + case Apply(Select(lhs, op), rhs :: Nil) as t => ValDef.let(Symbol.spliceOwner, lhs) { left => ValDef.let(Symbol.spliceOwner, rhs) { right => val app = Select.overloaded(left, op, Nil, right :: Nil) diff --git a/tests/run-macros/reflect-select-copy-2/assert_1.scala b/tests/run-macros/reflect-select-copy-2/assert_1.scala index 502a6e9493bd..5a9c12ed2b3d 100644 --- a/tests/run-macros/reflect-select-copy-2/assert_1.scala +++ b/tests/run-macros/reflect-select-copy-2/assert_1.scala @@ -13,7 +13,7 @@ object scalatest { case _ => false Term.of(cond).underlyingArgument match { - case Apply(sel @ Select(lhs, op), rhs :: Nil) => + case Apply(Select(lhs, op) as sel, rhs :: Nil) => ValDef.let(Symbol.spliceOwner, lhs) { left => ValDef.let(Symbol.spliceOwner, rhs) { right => ValDef.let(Symbol.spliceOwner, Apply(Select.copy(sel)(left, op), right :: Nil)) { result => diff --git a/tests/run-macros/reflect-select-copy/assert_1.scala b/tests/run-macros/reflect-select-copy/assert_1.scala index cd489d08f364..050b7f18973e 100644 --- a/tests/run-macros/reflect-select-copy/assert_1.scala +++ b/tests/run-macros/reflect-select-copy/assert_1.scala @@ -8,7 +8,7 @@ object scalatest { import quotes.reflect._ Term.of(cond).underlyingArgument match { - case Apply(select @ Select(lhs, op), rhs :: Nil) => + case Apply(Select(lhs, op) as select, rhs :: Nil) => val cond = Apply(Select.copy(select)(lhs, ">"), rhs :: Nil).asExprOf[Boolean] '{ scala.Predef.assert($cond) } case _ => diff --git a/tests/run-macros/reflect-select-symbol-constructor/assert_1.scala b/tests/run-macros/reflect-select-symbol-constructor/assert_1.scala index 56d80b88f850..775eb77767b9 100644 --- a/tests/run-macros/reflect-select-symbol-constructor/assert_1.scala +++ b/tests/run-macros/reflect-select-symbol-constructor/assert_1.scala @@ -13,7 +13,7 @@ object scalatest { case _ => false Term.of(cond).underlyingArgument match { - case t @ Apply(sel @ Select(lhs, op), rhs :: Nil) => + case Apply(Select(lhs, op) as sel, rhs :: Nil) as t => ValDef.let(Symbol.spliceOwner, lhs) { left => ValDef.let(Symbol.spliceOwner, rhs) { right => val app = Apply(Select(left, sel.symbol), right :: Nil) diff --git a/tests/run-macros/reflect-select-value-class/assert_1.scala b/tests/run-macros/reflect-select-value-class/assert_1.scala index 01e85812e590..36db249da014 100644 --- a/tests/run-macros/reflect-select-value-class/assert_1.scala +++ b/tests/run-macros/reflect-select-value-class/assert_1.scala @@ -13,7 +13,7 @@ object scalatest { case _ => false Term.of(cond).underlyingArgument match { - case t @ Apply(Select(lhs, op), rhs :: Nil) => + case Apply(Select(lhs, op), rhs :: Nil) as t => ValDef.let(Symbol.spliceOwner, lhs) { left => ValDef.let(Symbol.spliceOwner, rhs) { right => val app = Select.overloaded(left, op, Nil, right :: Nil) diff --git a/tests/run/3179.scala b/tests/run/3179.scala index 0eb13bd54fef..fa78466e7e1f 100644 --- a/tests/run/3179.scala +++ b/tests/run/3179.scala @@ -1,7 +1,7 @@ object Test { def main(args: Array[String]): Unit = { ("": Any) match { - case a as Test => 1 + case Test as a => 1 case _ => 2 } } diff --git a/tests/run/enums-serialization-compat.scala b/tests/run/enums-serialization-compat.scala index 3dfb559429bb..19aa4dae6059 100644 --- a/tests/run/enums-serialization-compat.scala +++ b/tests/run/enums-serialization-compat.scala @@ -31,19 +31,19 @@ extension (ref: AnyRef) def aliases(compare: AnyRef) = assert(ref eq compare, co val read = use(ByteArrayInputStream(buf.toByteArray)) val in = use(ObjectInputStream(read)) - val Seq(Red as _, Green as _, Blue as _, Indigo as _) = (1 to 4).map(_ => in.readObject) + val Seq(_ as Red, _ as Green, _ as Blue, _ as Indigo) = (1 to 4).map(_ => in.readObject) Red aliases JColor.Red Green aliases SColor.Green Blue aliases SColorTagged.Blue Indigo aliases SColorTagged.Indigo - val Seq(A as _, C as _, G as _, T as _) = (1 to 4).map(_ => in.readObject) + val Seq(_ as A, _ as C, _ as G, _ as T) = (1 to 4).map(_ => in.readObject) A aliases Nucleobase.A C aliases Nucleobase.C G aliases Nucleobase.G T aliases Nucleobase.T - val Seq(IntTag as _, UnitTag as _) = (1 to 2).map(_ => in.readObject) + val Seq(_ as IntTag, _ as UnitTag) = (1 to 2).map(_ => in.readObject) IntTag aliases MyClassTag.IntTag UnitTag aliases MyClassTag.UnitTag diff --git a/tests/run/fors.scala b/tests/run/fors.scala index a7057d23ae1e..56ca7d335025 100644 --- a/tests/run/fors.scala +++ b/tests/run/fors.scala @@ -26,7 +26,7 @@ object Test extends App { var n = 0 for (_ <- xs) n += 1; println(n) for ((x, y) <- xs zip ys) print(x + " "); println() - for (p as (x, y) <- xs zip ys) print(p._1 + " "); println() + for ((x, y) as p <- xs zip ys) print(p._1 + " "); println() // iterators for (x <- it) print(x + " "); println() @@ -53,7 +53,7 @@ object Test extends App { var n = 0 for (_ <- xs) n += 1; println(n) for ((x, y) <- xs zip ys) print(x + " "); println() - for (p as (x, y) <- xs zip ys) print(p._1 + " "); println() + for ((x, y) as p <- xs zip ys) print(p._1 + " "); println() // iterators for (x <- it) print(x + " "); println() diff --git a/tests/run/fully-abstract-interface.scala b/tests/run/fully-abstract-interface.scala index 7d05b3dc342c..befed7239745 100644 --- a/tests/run/fully-abstract-interface.scala +++ b/tests/run/fully-abstract-interface.scala @@ -20,7 +20,7 @@ object Test { const1 match { case AppliedOp(_, _, _) => println("test1 fail") - case c as Constant(n) => + case Constant(n) as c => println("test1 OK") println(s"$n = ${c.eval}") } @@ -41,9 +41,9 @@ object Test { println(applied.eval) applied match { - case c as Constant(n) => + case Constant(n) as c => println("test3 fail") - case a as AppliedOp(op, x, y) => + case AppliedOp(op, x, y) as a => println("test3 OK") println(s"AppliedOp($op, $x, $y) = ${a.eval}") } @@ -304,7 +304,7 @@ object ListImplementation extends Arithmetic { def opClassTag: ClassTag[Op] = new ClassTag[Constant] { def runtimeClass: Class[_] = classOf[List[_]] override def unapply(x: Any): Option[List[Any]] = x match { - case op as (("+" | "*") :: Nil) => + case (("+" | "*") :: Nil) as op => // Test that it is: // type Op <: List[Any] // List(id: "+" | "*") Some(op) diff --git a/tests/run/fully-abstract-nat-1.scala b/tests/run/fully-abstract-nat-1.scala index 263437d33a0b..f2ef8a5933a4 100644 --- a/tests/run/fully-abstract-nat-1.scala +++ b/tests/run/fully-abstract-nat-1.scala @@ -32,7 +32,7 @@ object Test { } def divOpt(a: Nat, b: Nat): Option[(Nat, Nat)] = b match { - case s as Succ(_) => + case Succ(_) as s => // s is of type Nat though we know it is a Succ Some(safeDiv(a, s.asInstanceOf[Succ])) case _ => None diff --git a/tests/run/fully-abstract-nat-2.scala b/tests/run/fully-abstract-nat-2.scala index 305c7805e92f..a4ca7e45d618 100644 --- a/tests/run/fully-abstract-nat-2.scala +++ b/tests/run/fully-abstract-nat-2.scala @@ -34,7 +34,7 @@ object Test { } def divOpt(a: Nat, b: Nat): Option[(Nat, Nat)] = b match { - case s as Succ(_) => Some(safeDiv(a, s)) + case Succ(_) as s => Some(safeDiv(a, s)) case _ => None } diff --git a/tests/run/fully-abstract-nat-3.scala b/tests/run/fully-abstract-nat-3.scala index dfdf4edb4607..d3223540eed0 100644 --- a/tests/run/fully-abstract-nat-3.scala +++ b/tests/run/fully-abstract-nat-3.scala @@ -32,7 +32,7 @@ object Test { } def divOpt(a: Nat, b: Nat): Option[(Nat, Nat)] = b match { - case SuccRefine(s as Succ(_)) => Some(safeDiv(a, s)) + case SuccRefine(Succ(_) as s) => Some(safeDiv(a, s)) case _ => None } @@ -97,7 +97,7 @@ object CaseNums extends Numbers { object SuccRefine extends SuccRefineExtractor { def unapply(nat: Nat): Option[Succ] = nat match { - case succ as SuccClass(_) => Some(succ) + case SuccClass(_) as succ => Some(succ) case _ => None } } diff --git a/tests/run/fully-abstract-nat-4.scala b/tests/run/fully-abstract-nat-4.scala index 1063b41519a5..13d9661e7448 100644 --- a/tests/run/fully-abstract-nat-4.scala +++ b/tests/run/fully-abstract-nat-4.scala @@ -32,7 +32,7 @@ object Test { } def divOpt(a: Nat, b: Nat): Option[(Nat, Nat)] = b match { - case s as Succ(p) => + case Succ(p) as s => Some(safeDiv(a, s.asInstanceOf[b.type & SuccOpt#Refined])) // safe unchecked cast inserted by the language extension case _ => None } diff --git a/tests/run/fully-abstract-nat-5.scala b/tests/run/fully-abstract-nat-5.scala index f73f3fff6b88..beae3dd3ed90 100644 --- a/tests/run/fully-abstract-nat-5.scala +++ b/tests/run/fully-abstract-nat-5.scala @@ -32,7 +32,7 @@ object Test { } def divOpt(a: Nat, b: Nat): Option[(Nat, Nat)] = b match { - case s as Succ(p) => + case Succ(p) as s => Some(safeDiv(a, s.asInstanceOf[Succ])) // cast should not be needed with extension case _ => None } diff --git a/tests/run/fully-abstract-nat-6.scala b/tests/run/fully-abstract-nat-6.scala index ab51ff981b2f..3dd82ec3f680 100644 --- a/tests/run/fully-abstract-nat-6.scala +++ b/tests/run/fully-abstract-nat-6.scala @@ -32,7 +32,7 @@ object Test { } def divOpt(a: Nat, b: Nat): Option[(Nat, Nat)] = b match { - case s as Succ(p) => + case Succ(p) as s => Some(safeDiv(a, s.asInstanceOf[Succ])) // this case will not be needed case _ => None } diff --git a/tests/run/fully-abstract-nat-7.scala b/tests/run/fully-abstract-nat-7.scala index 1f6a6ee7c543..28125b579a49 100644 --- a/tests/run/fully-abstract-nat-7.scala +++ b/tests/run/fully-abstract-nat-7.scala @@ -32,7 +32,7 @@ object Test { } def divOpt(a: Nat, b: Nat): Option[(Nat, Nat)] = b match { - case s as Succ(p) => + case Succ(p) as s => Some(safeDiv(a, s.asInstanceOf[Succ])) // this case will not be needed case _ => None } diff --git a/tests/run/fully-abstract-nat.scala b/tests/run/fully-abstract-nat.scala index 7bd302caef3e..aea3b6ae8b27 100644 --- a/tests/run/fully-abstract-nat.scala +++ b/tests/run/fully-abstract-nat.scala @@ -22,7 +22,7 @@ object Test { val large = (BigInt(1) << 100).asInstanceOf[Succ] large match { case Zero() => println("test fail") - case s as Succ(pred) => + case Succ(pred) as s => println("test OK") println(s"Succ(${pred.pred}) = $s") } @@ -52,7 +52,7 @@ object Test { three match { case Zero() => println("test3 fail") - case s as Succ(pred) => + case Succ(pred) as s => println("test3 OK") println(s"Succ($pred) = ${s.value}") } diff --git a/tests/run/i1099.scala b/tests/run/i1099.scala index b25fbb5bc1bf..b072098eeb49 100644 --- a/tests/run/i1099.scala +++ b/tests/run/i1099.scala @@ -8,7 +8,7 @@ object Test { // This is what `foo` expands to def foo2[T](x: Any)(implicit ev: ClassTag[T]) = x match { - case t as ev(_) => true + case ev(_) as t => true case _ => false } def main(args: Array[String]): Unit = { diff --git a/tests/run/i1432.scala b/tests/run/i1432.scala index a76889957122..b35fe5c39194 100644 --- a/tests/run/i1432.scala +++ b/tests/run/i1432.scala @@ -2,8 +2,8 @@ object Test { def main(args: Array[String]): Unit = { val someFoo = Some("foo") - val _ as bar = someFoo - val _ as Some(baz) = someFoo + val bar = someFoo + val Some(baz) = someFoo println(bar) println(baz) } diff --git a/tests/run/i1463.scala b/tests/run/i1463.scala index aff09911d900..33ad1dd3ad97 100644 --- a/tests/run/i1463.scala +++ b/tests/run/i1463.scala @@ -8,7 +8,7 @@ object Test { def f0(x: Any) = x match { case Bob2 => Bob2 } def f1(x: Any) = x match { case Bob => Bob } - // def f2(x: Any): Bob.type = x match { case x as Bob => x } // should not type check + // def f2(x: Any): Bob.type = x match { case Bob as x => x } // should not type check def main(args: Array[String]): Unit = { assert(f0(Bob2) eq Bob2) diff --git a/tests/run/i1991.scala b/tests/run/i1991.scala index 54ef6819dfdc..622d93906a13 100644 --- a/tests/run/i1991.scala +++ b/tests/run/i1991.scala @@ -14,9 +14,9 @@ class A[Foo](implicit tag: ClassTag[Foo]) { def testBind(x: Any) = x match { case foo0: Foo => (foo0: Foo) - case foo1 as (_: Foo) => + case (_: Foo) as foo1 => (foo1: Foo) - case foo2 as ExtractFoo() => + case ExtractFoo() as foo2 => (foo2: Foo) } } diff --git a/tests/run/i3200c.scala b/tests/run/i3200c.scala index 88bfbb1d12ef..f89d42a38b9f 100644 --- a/tests/run/i3200c.scala +++ b/tests/run/i3200c.scala @@ -9,7 +9,7 @@ object Test { } def test2(x: X) = x match { - case y as (yy: Y.type) => + case (yy: Y.type) as y => yIs1(y) yIs1(yy) } diff --git a/tests/run/patmat-bind-typed.scala b/tests/run/patmat-bind-typed.scala index a8fb80d4f4e9..1cf911997488 100644 --- a/tests/run/patmat-bind-typed.scala +++ b/tests/run/patmat-bind-typed.scala @@ -1,5 +1,5 @@ object Test { - def f(xs: List[Any]) = for (key as (dummy: String) <- xs) yield key + def f(xs: List[Any]) = for ((dummy: String) as key <- xs) yield key def main(args: Array[String]): Unit = { f("abc" :: Nil) foreach println diff --git a/tests/run/patmat-spec.scala b/tests/run/patmat-spec.scala index 5d623c4dfb35..faaca9518163 100644 --- a/tests/run/patmat-spec.scala +++ b/tests/run/patmat-spec.scala @@ -6,7 +6,7 @@ object Test { } "even" match { - case s as Even() => println(s"$s has an even number of characters") + case Even() as s => println(s"$s has an even number of characters") case s => println(s"$s has an odd number of characters") } // even has an even number of characters diff --git a/tests/run/patmatch-classtag.scala b/tests/run/patmatch-classtag.scala index e2701e0fdadc..887334e321fe 100644 --- a/tests/run/patmatch-classtag.scala +++ b/tests/run/patmatch-classtag.scala @@ -38,7 +38,7 @@ object Test extends App { println(cdef) } x match { - case cdef as CaseDef(s) => + case CaseDef(s) as cdef => val x: CaseDef = cdef println(s) } diff --git a/tests/run/t6646.scala b/tests/run/t6646.scala index 327d32109a0a..755ac23b0c3b 100644 --- a/tests/run/t6646.scala +++ b/tests/run/t6646.scala @@ -8,8 +8,8 @@ object Test { val l = List(PrimaryKey, NoNull, lower) // withFilter must be generated in these - for (option as NoNull <- l) println("Found " + option) - for (option as `lower` <- l) println("Found " + option) + for (NoNull as option <- l) println("Found " + option) + for (`lower` as option <- l) println("Found " + option) for ((`lower`, i) <- l.zipWithIndex) println("Found " + i) // no withFilter diff --git a/tests/run/t8395.scala b/tests/run/t8395.scala index 77c5fff0634a..acd0ceb3cc5f 100644 --- a/tests/run/t8395.scala +++ b/tests/run/t8395.scala @@ -1,6 +1,6 @@ object Test { def baz(x: Object) = { - val s as (_s: String) = x + val (_s: String) as s = x x } def main(args: Array[String]): Unit = { diff --git a/tests/run/type-test-binding.scala b/tests/run/type-test-binding.scala index ad055a537f46..145ae54ecf6d 100644 --- a/tests/run/type-test-binding.scala +++ b/tests/run/type-test-binding.scala @@ -26,7 +26,7 @@ object Test { def test(foo: Foo): Unit = { foo.x match { - case x @ foo.Z(i) => // `x` is refined to type `foo.Y` + case foo.Z(i) as x => // `x` is refined to type `foo.Y` foo.f(x) println(i) } diff --git a/tests/run/type-test-nat.scala b/tests/run/type-test-nat.scala index a7f21ec33fce..4a832bb63569 100644 --- a/tests/run/type-test-nat.scala +++ b/tests/run/type-test-nat.scala @@ -11,7 +11,7 @@ object Test { def divOpt(m: Nat, n: Nat): Option[(Nat, Nat)] = { n match { case Zero => None - case s @ Succ(_) => Some(safeDiv(m, s)) + case Succ(_) as s => Some(safeDiv(m, s)) } } val two = Succ(Succ(Zero)) diff --git a/tests/run/unchecked-patterns.scala b/tests/run/unchecked-patterns.scala index 60f41ee03402..5c91d2d35cc3 100644 --- a/tests/run/unchecked-patterns.scala +++ b/tests/run/unchecked-patterns.scala @@ -3,7 +3,7 @@ object Test extends App { val (y1: Some[Int] @unchecked) = Some(1): Option[Int] val a :: as: @unchecked = List(1, 2, 3) - val lst as b :: bs: @unchecked = List(1, 2, 3) + val b :: bs as lst: @unchecked = List(1, 2, 3) val (1, c): @unchecked = (1, 2) object Positive { def unapply(i: Int): Option[Int] = Some(i).filter(_ > 0) } diff --git a/tests/untried/neg/catch-all.scala b/tests/untried/neg/catch-all.scala index c05be7704441..fe2a6a66d135 100644 --- a/tests/untried/neg/catch-all.scala +++ b/tests/untried/neg/catch-all.scala @@ -11,9 +11,9 @@ object CatchAll { try { "okay" } catch { case `t` => } - try { "okay" } catch { case x @ T => } + try { "okay" } catch { case T as x => } - try { "okay" } catch { case x @ `t` => } + try { "okay" } catch { case `t` as x => } try { "okay" } catch { case _: Throwable => } diff --git a/tests/untried/neg/t7290.scala b/tests/untried/neg/t7290.scala index b9db7f7e8a88..f7a0a8b69346 100644 --- a/tests/untried/neg/t7290.scala +++ b/tests/untried/neg/t7290.scala @@ -3,7 +3,7 @@ object Test extends App { case 1 => 1 case 0 | 0 => 0 case 2 | 2 | 2 | 3 | 2 | 3 => 0 - case 4 | (_ @ 4) => 0 + case 4 | (4 as x) => 0 case _ => -1 } assert(y == 0, y)