From 73223682853e0526fb35d8bbd6db8daff94b390d Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Tue, 26 May 2020 17:48:03 +0200 Subject: [PATCH 1/3] Fix whitebox macro syntax in CB --- community-build/community-projects/xml-interpolator | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/community-build/community-projects/xml-interpolator b/community-build/community-projects/xml-interpolator index 73ad802d216a..c386be6fef90 160000 --- a/community-build/community-projects/xml-interpolator +++ b/community-build/community-projects/xml-interpolator @@ -1 +1 @@ -Subproject commit 73ad802d216a7377ab6dfe62febdc02a7da95261 +Subproject commit c386be6fef90fede6cbccf2a6a5d1a6d5f594f5e From 44a7b027c6d74a7f7e08f78a43516e2d11cd2998 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Tue, 26 May 2020 21:15:54 +0200 Subject: [PATCH 2/3] Drop old whitebox macro syntax Standardize on transparent --- .../dotty/tools/dotc/parsing/Parsers.scala | 59 +++++++------------ docs/docs/internals/syntax.md | 16 ++--- tests/invalid/run/typelevel-patmat.scala | 4 +- ...d-machine-state-encoding-with-inline.scala | 4 +- tests/neg/i7078.scala | 3 +- ...e-state-encoding-with-implicit-match.scala | 4 +- .../tasty-constant-type/Macro_1.scala | 2 +- tests/pos/i5572.scala | 2 +- tests/pos/implicit-match-nested.scala | 2 +- tests/pos/inline-match-specialize.scala | 2 +- tests/pos/inline-named-typeargs.scala | 2 +- tests/pos/reference/compile-time.scala | 2 +- tests/pos/reference/delegate-match.scala | 2 +- .../typeclass-derivation2c.scala | 4 +- .../xml-interpolation-5/Macros_1.scala | 2 +- tests/run/typeclass-derivation2b.scala | 2 +- 16 files changed, 46 insertions(+), 66 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index 546288ed3481..677ba880de8d 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -36,8 +36,6 @@ object Parsers { import ast.untpd._ - val AllowOldWhiteboxSyntax = true - case class OpInfo(operand: Tree, operator: Ident, offset: Offset) class ParensCounters { @@ -1822,16 +1820,9 @@ object Parsers { Nil } - def typedOpt(): Tree = { - if (in.token == COLONEOL) in.token = COLON - // a hack to allow - // - // def f(): - // T - // + def typedOpt(): Tree = if (in.token == COLON) { in.nextToken(); toplevelTyp() } else TypeTree().withSpan(Span(in.lastOffset)) - } def typeDependingOn(location: Location): Tree = if location.inParens then typ() @@ -3266,7 +3257,7 @@ object Parsers { } } - /** DefDef ::= DefSig [(‘:’ | ‘<:’) Type] ‘=’ Expr + /** DefDef ::= DefSig [‘:’ Type] ‘=’ Expr * | this ParamClause ParamClauses `=' ConstrExpr * DefDcl ::= DefSig `:' Type * DefSig ::= id [DefTypeParamClause] DefParamClauses @@ -3342,12 +3333,13 @@ object Parsers { case rparamss => leadingVparamss ::: rparamss var tpt = fromWithinReturnType { - if in.token == SUBTYPE && mods.is(Inline) && AllowOldWhiteboxSyntax then - deprecationWarning("`<:` return type will no longer be supported. Use transparent modifier instead.") - in.nextToken() - mods1 = addMod(mods1, Mod.Transparent()) - toplevelTyp() - else typedOpt() + if in.token == COLONEOL then in.token = COLON + // a hack to allow + // + // def f(): + // T + // + typedOpt() } if (migrateTo3) newLineOptWhenFollowedBy(LBRACE) val rhs = @@ -3581,7 +3573,7 @@ object Parsers { syntaxError(i"extension clause can only define methods", stat.span) } - /** GivenDef ::= [GivenSig] [‘_’ ‘<:’] Type ‘=’ Expr + /** GivenDef ::= [GivenSig] Type ‘=’ Expr * | [GivenSig] ConstrApps [TemplateBody] * GivenSig ::= [id] [DefTypeParamClause] {UsingParamClauses} ‘as’ */ @@ -3601,30 +3593,19 @@ object Parsers { newLinesOpt() if isIdent(nme.as) || !name.isEmpty || !tparams.isEmpty || !vparamss.isEmpty then accept(nme.as) - def givenAlias(tpt: Tree) = + val parents = constrApps(commaOK = true, templateCanFollow = true) + if in.token == EQUALS && parents.length == 1 && parents.head.isType then accept(EQUALS) mods1 |= Final - DefDef(name, tparams, vparamss, tpt, subExpr()) - if in.token == USCORE && AllowOldWhiteboxSyntax then - deprecationWarning("`<:` return type will no longer be supported. Use transparent modifier instead.") - if !mods.is(Inline) then - syntaxError("`_ <:` is only allowed for given with `inline` modifier") - in.nextToken() - accept(SUBTYPE) - mods1 = addMod(mods1, Mod.Transparent()) - givenAlias(toplevelTyp()) + DefDef(name, tparams, vparamss, parents.head, subExpr()) else - val parents = constrApps(commaOK = true, templateCanFollow = true) - if in.token == EQUALS && parents.length == 1 && parents.head.isType then - givenAlias(parents.head) - else - possibleTemplateStart() - val tparams1 = tparams.map(tparam => tparam.withMods(tparam.mods | PrivateLocal)) - val vparamss1 = vparamss.map(_.map(vparam => - vparam.withMods(vparam.mods &~ Param | ParamAccessor | Protected))) - val templ = templateBodyOpt(makeConstructor(tparams1, vparamss1), parents, Nil) - if tparams.isEmpty && vparamss.isEmpty then ModuleDef(name, templ) - else TypeDef(name.toTypeName, templ) + possibleTemplateStart() + val tparams1 = tparams.map(tparam => tparam.withMods(tparam.mods | PrivateLocal)) + val vparamss1 = vparamss.map(_.map(vparam => + vparam.withMods(vparam.mods &~ Param | ParamAccessor | Protected))) + val templ = templateBodyOpt(makeConstructor(tparams1, vparamss1), parents, Nil) + if tparams.isEmpty && vparamss.isEmpty then ModuleDef(name, templ) + else TypeDef(name.toTypeName, templ) end gdef finalizeDef(gdef, mods1, start) } diff --git a/docs/docs/internals/syntax.md b/docs/docs/internals/syntax.md index 52ca07e9f0fe..8d6b93efe691 100644 --- a/docs/docs/internals/syntax.md +++ b/docs/docs/internals/syntax.md @@ -156,7 +156,7 @@ WithType ::= AnnotType {‘with’ AnnotType} AnnotType ::= SimpleType {Annotation} Annotated(t, annot) SimpleType ::= SimpleLiteral SingletonTypeTree(l) - | ‘?’ SubtypeBounds + | ‘?’ TypeBounds | SimpleType1 { ‘(’ Singletons ‘)’ } SimpleType1 ::= id Ident(name) | Singleton ‘.’ id Select(t, name) @@ -181,8 +181,8 @@ TypeArgs ::= ‘[’ ArgTypes ‘]’ NamedTypeArg ::= id ‘=’ Type NamedArg(id, t) NamedTypeArgs ::= ‘[’ NamedTypeArg {‘,’ NamedTypeArg} ‘]’ nts Refinement ::= ‘{’ [RefineDcl] {semi [RefineDcl]} ‘}’ ds -SubtypeBounds ::= [‘>:’ Type] [‘<:’ Type] | INT TypeBoundsTree(lo, hi) -TypeParamBounds ::= SubtypeBounds {‘:’ Type} ContextBounds(typeBounds, tps) +TypeBounds ::= [‘>:’ Type] [‘<:’ Type] TypeBoundsTree(lo, hi) +TypeParamBounds ::= TypeBounds {‘:’ Type} ContextBounds(typeBounds, tps) Types ::= Type {‘,’ Type} ``` @@ -299,11 +299,11 @@ DefTypeParamClause::= ‘[’ DefTypeParam {‘,’ DefTypeParam} ‘]’ DefTypeParam ::= {Annotation} id [HkTypeParamClause] TypeParamBounds TypTypeParamClause::= ‘[’ TypTypeParam {‘,’ TypTypeParam} ‘]’ -TypTypeParam ::= {Annotation} id [HkTypeParamClause] SubtypeBounds +TypTypeParam ::= {Annotation} id [HkTypeParamClause] TypeBounds HkTypeParamClause ::= ‘[’ HkTypeParam {‘,’ HkTypeParam} ‘]’ HkTypeParam ::= {Annotation} [‘+’ | ‘-’] (id [HkTypeParamClause] | ‘_’) - SubtypeBounds + TypeBounds ClsParamClauses ::= {ClsParamClause} [[nl] ‘(’ [‘implicit’] ClsParams ‘)’] ClsParamClause ::= [nl] ‘(’ ClsParams ‘)’ @@ -372,7 +372,7 @@ VarDcl ::= ids ‘:’ Type DefDcl ::= DefSig ‘:’ Type DefDef(_, name, tparams, vparamss, tpe, EmptyTree) DefSig ::= id [DefTypeParamClause] DefParamClauses | ExtParamClause {nl} [‘.’] id DefParamClauses -TypeDcl ::= id [TypeParamClause] {FunParamClause} SubtypeBounds TypeDefTree(_, name, tparams, bound +TypeDcl ::= id [TypeParamClause] {FunParamClause} TypeBounds TypeDefTree(_, name, tparams, bound [‘=’ Type] Def ::= ‘val’ PatDef @@ -385,7 +385,7 @@ PatDef ::= ids [‘:’ Type] ‘=’ Expr | Pattern2 [‘:’ Type | Ascription] ‘=’ Expr PatDef(_, pats, tpe?, expr) VarDef ::= PatDef | ids ‘:’ Type ‘=’ ‘_’ -DefDef ::= DefSig [(‘:’ | ‘<:’) Type] ‘=’ Expr DefDef(_, name, tparams, vparamss, tpe, expr) +DefDef ::= DefSig [‘:’ Type] ‘=’ Expr DefDef(_, name, tparams, vparamss, tpe, expr) | ‘this’ DefParamClause DefParamClauses ‘=’ ConstrExpr DefDef(_, , Nil, vparamss, EmptyTree, expr | Block) TmplDef ::= ([‘case’] ‘class’ | ‘trait’) ClassDef @@ -398,7 +398,7 @@ 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 +GivenDef ::= [GivenSig] Type ‘=’ Expr | [GivenSig] ConstrApps [TemplateBody] GivenSig ::= [id] [DefTypeParamClause] {UsingParamClause} ‘as’ ExtensionDef ::= [id] [‘on’ ExtParamClause {UsingParamClause}] diff --git a/tests/invalid/run/typelevel-patmat.scala b/tests/invalid/run/typelevel-patmat.scala index 6d85692955c2..7b110c97c42c 100644 --- a/tests/invalid/run/typelevel-patmat.scala +++ b/tests/invalid/run/typelevel-patmat.scala @@ -78,12 +78,12 @@ object Test extends App { val e1 = nth(r2, 1) val ce1: String = e1 - inline def concatTyped(xs: HList, ys: HList) <: Typed[_ <: HList] = inline xs match { + transparent inline def concatTyped(xs: HList, ys: HList): Typed[_ <: HList] = inline xs match { case HNil => Typed(ys) case HCons(x, xs1) => Typed(HCons(x, concatTyped(xs1, ys).value)) } - def concatImpl(xs: HList, ys: HList) <: HList = xs match { + transparent def concatImpl(xs: HList, ys: HList): HList = xs match { case HNil => ys case HCons(x, xs1) => HCons(x, concatImpl(xs1, ys)) } diff --git a/tests/neg-custom-args/erased/erased-machine-state-encoding-with-inline.scala b/tests/neg-custom-args/erased/erased-machine-state-encoding-with-inline.scala index d076705abc3a..0961ca4fbbee 100644 --- a/tests/neg-custom-args/erased/erased-machine-state-encoding-with-inline.scala +++ b/tests/neg-custom-args/erased/erased-machine-state-encoding-with-inline.scala @@ -5,11 +5,11 @@ final class On extends State final class Off extends State class Machine[S <: State] { - inline def turnOn() <: Machine[On] = inline erasedValue[S] match { + transparent inline def turnOn(): Machine[On] = inline erasedValue[S] match { case _: Off => new Machine[On] case _: On => error("Turning on an already turned on machine") } - inline def turnOff() <: Machine[Off] = inline erasedValue[S] match { + transparent inline def turnOff(): Machine[Off] = inline erasedValue[S] match { case _: On => new Machine[Off] case _: Off => error("Turning off an already turned off machine") } diff --git a/tests/neg/i7078.scala b/tests/neg/i7078.scala index 9ca3a007c191..387faafc745d 100644 --- a/tests/neg/i7078.scala +++ b/tests/neg/i7078.scala @@ -1,8 +1,7 @@ trait A class B extends A -given g1 as _ <: A = B() // error: `_ <:' is only allowed for given with `inline' modifier +transparent given g1 as A = B() // error: `transparent` can only be used in conjunction with `inline` inline given g2 as _ <: A: // error: `=' expected def foo = 2 -// error \ No newline at end of file diff --git a/tests/neg/machine-state-encoding-with-implicit-match.scala b/tests/neg/machine-state-encoding-with-implicit-match.scala index 9aaae7d1cf4f..f7e0a6ff536b 100644 --- a/tests/neg/machine-state-encoding-with-implicit-match.scala +++ b/tests/neg/machine-state-encoding-with-implicit-match.scala @@ -18,10 +18,10 @@ object IsOn { } class Machine[S <: State] { - inline def turnOn()(using s: IsOff[S]) <: Machine[On] = summonFrom { + transparent inline def turnOn()(using s: IsOff[S]): Machine[On] = summonFrom { case _: IsOff[Off] => new Machine[On] } - inline def turnOff()(using s: IsOn[S]) <: Machine[Off] = summonFrom { + transparent inline def turnOff()(using s: IsOn[S]): Machine[Off] = summonFrom { case _: IsOn[On] => new Machine[Off] } } diff --git a/tests/pos-macros/tasty-constant-type/Macro_1.scala b/tests/pos-macros/tasty-constant-type/Macro_1.scala index effb2252a56b..ba80aeac793c 100644 --- a/tests/pos-macros/tasty-constant-type/Macro_1.scala +++ b/tests/pos-macros/tasty-constant-type/Macro_1.scala @@ -4,7 +4,7 @@ object Macro { trait AddInt[A <: Int, B <: Int] { type Out <: Int } - inline def ff[A <: Int, B <: Int]() <: AddInt[A, B] = ${ impl('[A], '[B]) } + transparent inline def ff[A <: Int, B <: Int](): AddInt[A, B] = ${ impl('[A], '[B]) } def impl[A <: Int : Type, B <: Int : Type](a: Type[A], b: Type[B])(using qctx: QuoteContext) : Expr[AddInt[A, B]] = { import qctx.tasty._ diff --git a/tests/pos/i5572.scala b/tests/pos/i5572.scala index a6f4ab79397f..1db3ca53c7e5 100644 --- a/tests/pos/i5572.scala +++ b/tests/pos/i5572.scala @@ -1,6 +1,6 @@ trait Foo { type Id[t] = t - inline def foo[T](t: T) <: Id[T] = + transparent inline def foo[T](t: T): Id[T] = inline t match { case i: Int => (i+1).asInstanceOf[Id[T]] case _ => t diff --git a/tests/pos/implicit-match-nested.scala b/tests/pos/implicit-match-nested.scala index 62cfc7ac2180..d54f610d60b9 100644 --- a/tests/pos/implicit-match-nested.scala +++ b/tests/pos/implicit-match-nested.scala @@ -8,7 +8,7 @@ object `implicit-match-nested` { implicit val b1: B[Int] = B[Int]() implicit val b2: B[String] = B[String]() - inline def locateB <: B[_] = + transparent inline def locateB: B[_] = summonFrom { case _: A[t] => summonFrom { diff --git a/tests/pos/inline-match-specialize.scala b/tests/pos/inline-match-specialize.scala index 10377a3cc079..c5112eeeb1e1 100644 --- a/tests/pos/inline-match-specialize.scala +++ b/tests/pos/inline-match-specialize.scala @@ -1,6 +1,6 @@ object `inline-match-specialize` { case class Box[+T](value: T) - inline def specialize[T](box: Box[T]) <: Box[T] = inline box match { + transparent inline def specialize[T](box: Box[T]): Box[T] = inline box match { case box: Box[t] => box } diff --git a/tests/pos/inline-named-typeargs.scala b/tests/pos/inline-named-typeargs.scala index 16ec48610b8f..c839ff9550dd 100644 --- a/tests/pos/inline-named-typeargs.scala +++ b/tests/pos/inline-named-typeargs.scala @@ -1,4 +1,4 @@ // Working version of inline-named-typedargs, the original is currently disabled object t1 { - inline def construct[Elem, Coll[_]](xs: List[Elem]) <: Coll[Elem] = ??? + transparent inline def construct[Elem, Coll[_]](xs: List[Elem]): Coll[Elem] = ??? } diff --git a/tests/pos/reference/compile-time.scala b/tests/pos/reference/compile-time.scala index ff400133ad01..32ea7660c898 100644 --- a/tests/pos/reference/compile-time.scala +++ b/tests/pos/reference/compile-time.scala @@ -14,7 +14,7 @@ class Test: final val ctwo = toIntC[2] - inline def defaultValue[T] <: Option[Any] = inline erasedValue[T] match + transparent inline def defaultValue[T]: Option[Any] = inline erasedValue[T] match case _: Byte => Some(0: Byte) case _: Char => Some(0: Char) case _: Short => Some(0: Short) diff --git a/tests/pos/reference/delegate-match.scala b/tests/pos/reference/delegate-match.scala index 511ef597bd39..2f1e1379ecc6 100644 --- a/tests/pos/reference/delegate-match.scala +++ b/tests/pos/reference/delegate-match.scala @@ -4,7 +4,7 @@ class Test extends App: import scala.collection.immutable.{TreeSet, HashSet} import scala.compiletime.summonFrom - inline def setFor[T] <: Set[T] = summonFrom { + transparent inline def setFor[T]: Set[T] = summonFrom { case given ord: Ordering[T] => new TreeSet[T] case _ => new HashSet[T] } diff --git a/tests/run-custom-args/typeclass-derivation2c.scala b/tests/run-custom-args/typeclass-derivation2c.scala index 782da7b9239d..ba9dc9c49d30 100644 --- a/tests/run-custom-args/typeclass-derivation2c.scala +++ b/tests/run-custom-args/typeclass-derivation2c.scala @@ -88,7 +88,7 @@ object Lst { case Nil => 1 } inline override def numberOfCases = 2 - inline override def alternative(n: Int) <: Generic[_ <: Lst[T]] = + transparent inline override def alternative(n: Int): Generic[_ <: Lst[T]] = inline n match { case 0 => Cons.GenericCons[T] case 1 => Nil.GenericNil @@ -153,7 +153,7 @@ object Either { case x: Right[_] => 1 } inline override def numberOfCases = 2 - inline override def alternative(n: Int) <: Generic[_ <: Either[L, R]] = + inline override def alternative(n: Int): _ <: Generic[_ <: Either[L, R]] = inline n match { case 0 => Left.GenericLeft[L] case 1 => Right.GenericRight[R] diff --git a/tests/run-macros/xml-interpolation-5/Macros_1.scala b/tests/run-macros/xml-interpolation-5/Macros_1.scala index df83b4f18839..887ec2007f82 100644 --- a/tests/run-macros/xml-interpolation-5/Macros_1.scala +++ b/tests/run-macros/xml-interpolation-5/Macros_1.scala @@ -19,7 +19,7 @@ object XmlQuote { opaque type StringContext = scala.StringContext def apply(sc: scala.StringContext): StringContext = sc } - inline def (inline ctx: StringContext).xml <: SCOps.StringContext = SCOps(ctx) + transparent inline def (inline ctx: StringContext).xml: SCOps.StringContext = SCOps(ctx) inline def (inline ctx: SCOps.StringContext).apply(inline args: Any*): Xml = ${XmlQuote.impl('ctx, 'args)} // inline def (inline ctx: SCOps.StringContext).unapplySeq(...): Xml = ... diff --git a/tests/run/typeclass-derivation2b.scala b/tests/run/typeclass-derivation2b.scala index ed3d9eb1d864..caa7207f4c58 100644 --- a/tests/run/typeclass-derivation2b.scala +++ b/tests/run/typeclass-derivation2b.scala @@ -49,7 +49,7 @@ object Lst { case x: Cons[_] => 0 case Nil => 1 } - inline def alternative(inline n: Int) <: GenericProduct[_ <: Lst[T]] = + transparent inline def alternative(inline n: Int): GenericProduct[_ <: Lst[T]] = inline n match { case 0 => Cons.GenericCons[T] case 1 => Nil.GenericNil From 677830fe1adb20046ad340c14bbf68272dd75d78 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 29 May 2020 17:41:16 +0200 Subject: [PATCH 3/3] Another fix in xml interpolator --- community-build/community-projects/xml-interpolator | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/community-build/community-projects/xml-interpolator b/community-build/community-projects/xml-interpolator index c386be6fef90..fad00a33a5fd 160000 --- a/community-build/community-projects/xml-interpolator +++ b/community-build/community-projects/xml-interpolator @@ -1 +1 @@ -Subproject commit c386be6fef90fede6cbccf2a6a5d1a6d5f594f5e +Subproject commit fad00a33a5fdbf3d939ff53c4a89f01624c24245