Skip to content

Commit d76aefe

Browse files
committed
Drop "extended with" syntax
1 parent 83ab6c7 commit d76aefe

File tree

5 files changed

+59
-73
lines changed

5 files changed

+59
-73
lines changed

compiler/src/dotty/tools/dotc/core/StdNames.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,6 @@ object StdNames {
457457
val eval: N = "eval"
458458
val eqlAny: N = "eqlAny"
459459
val ex: N = "ex"
460-
val extended: N = "extended"
461460
val extension: N = "extension"
462461
val experimental: N = "experimental"
463462
val f: N = "f"

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

Lines changed: 51 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -3458,78 +3458,63 @@ object Parsers {
34583458
if in.token == LPAREN && followingIsParamOrGivenType()
34593459
then paramClauses() // todo: ONLY admit a single paramClause
34603460
else Nil
3461-
val isExtension = isIdent(nme.extended)
34623461
def checkAllGivens(vparamss: List[List[ValDef]], what: String) =
34633462
vparamss.foreach(_.foreach(vparam =>
34643463
if !vparam.mods.is(Given) then syntaxError(em"$what must be `given`", vparam.span)))
3465-
if isExtension then
3466-
if !name.isEmpty && !hasLabel then
3467-
syntaxError(em"name $name of extension clause must be followed by `:`", nameStart)
3468-
vparamss match
3469-
case (vparam :: Nil) :: vparamss1 if !vparam.mods.is(Given) =>
3470-
checkAllGivens(vparamss1, "follow-on parameter in extension clause")
3471-
case _ =>
3472-
syntaxError("extension clause must start with a single regular parameter", paramsStart)
3473-
in.nextToken()
3474-
accept(WITH)
3475-
val (self, stats) = templateBody()
3476-
stats.foreach(checkExtensionMethod(tparams, _))
3477-
ModuleDef(name, Template(makeConstructor(tparams, vparamss), Nil, Nil, self, stats))
3478-
else
3479-
def makeGiven(params: List[ValDef]): List[ValDef] =
3480-
params.map(param => param.withMods(param.mods | Given))
3481-
def conditionalParents(): List[Tree] =
3482-
accept(ARROW)
3483-
if in.token == LPAREN && followingIsParam() then
3484-
vparamss = vparamss :+ makeGiven(paramClause(vparamss.flatten.length))
3485-
conditionalParents()
3486-
else
3487-
val constrs = constrApps(commaOK = true, templateCanFollow = true)
3488-
if in.token == ARROW && constrs.forall(_.isType) then
3489-
vparamss = vparamss
3490-
:+ typesToGivenParams(constrs, ofClass = false, vparamss.flatten.length)
3491-
conditionalParents()
3492-
else constrs
3493-
3494-
val isConditional =
3495-
in.token == ARROW
3496-
&& vparamss.length == 1
3497-
&& (hasLabel || name.isEmpty && tparams.isEmpty)
3498-
if !isConditional then checkAllGivens(vparamss, "parameter of given instance")
3499-
val parents =
3500-
if in.token == SUBTYPE && !hasLabel then
3501-
if !mods.is(Inline) then
3502-
syntaxError("`<:` is only allowed for given with `inline` modifier")
3503-
in.nextToken()
3504-
TypeBoundsTree(EmptyTree, annotType()) :: Nil
3505-
else if isConditional then
3506-
vparamss = vparamss.map(makeGiven)
3464+
def makeGiven(params: List[ValDef]): List[ValDef] =
3465+
params.map(param => param.withMods(param.mods | Given))
3466+
def conditionalParents(): List[Tree] =
3467+
accept(ARROW)
3468+
if in.token == LPAREN && followingIsParam() then
3469+
vparamss = vparamss :+ makeGiven(paramClause(vparamss.flatten.length))
3470+
conditionalParents()
3471+
else
3472+
val constrs = constrApps(commaOK = true, templateCanFollow = true)
3473+
if in.token == ARROW && constrs.forall(_.isType) then
3474+
vparamss = vparamss
3475+
:+ typesToGivenParams(constrs, ofClass = false, vparamss.flatten.length)
35073476
conditionalParents()
3508-
else
3509-
if !hasLabel && !(name.isEmpty && tparams.isEmpty && vparamss.isEmpty) then
3510-
accept(COLON)
3511-
val constrs = constrApps(commaOK = true, templateCanFollow = true)
3512-
if in.token == ARROW && vparamss.isEmpty && constrs.forall(_.isType) then
3513-
vparamss = typesToGivenParams(constrs, ofClass = false, 0) :: Nil
3514-
conditionalParents()
3515-
else
3516-
constrs
3517-
3518-
if in.token == EQUALS && parents.length == 1 && parents.head.isType then
3477+
else constrs
3478+
3479+
val isConditional =
3480+
in.token == ARROW
3481+
&& vparamss.length == 1
3482+
&& (hasLabel || name.isEmpty && tparams.isEmpty)
3483+
if !isConditional then checkAllGivens(vparamss, "parameter of given instance")
3484+
val parents =
3485+
if in.token == SUBTYPE && !hasLabel then
3486+
if !mods.is(Inline) then
3487+
syntaxError("`<:` is only allowed for given with `inline` modifier")
35193488
in.nextToken()
3520-
mods1 |= Final
3521-
DefDef(name, tparams, vparamss, parents.head, subExpr())
3489+
TypeBoundsTree(EmptyTree, annotType()) :: Nil
3490+
else if isConditional then
3491+
vparamss = vparamss.map(makeGiven)
3492+
conditionalParents()
35223493
else
3523-
parents match
3524-
case TypeBoundsTree(_, _) :: _ => syntaxError("`=` expected")
3525-
case _ =>
3526-
possibleTemplateStart()
3527-
val tparams1 = tparams.map(tparam => tparam.withMods(tparam.mods | PrivateLocal))
3528-
val vparamss1 = vparamss.map(_.map(vparam =>
3529-
vparam.withMods(vparam.mods &~ Param | ParamAccessor | PrivateLocal)))
3530-
val templ = templateBodyOpt(makeConstructor(tparams1, vparamss1), parents, Nil)
3531-
if tparams.isEmpty && vparamss.isEmpty then ModuleDef(name, templ)
3532-
else TypeDef(name.toTypeName, templ)
3494+
if !hasLabel && !(name.isEmpty && tparams.isEmpty && vparamss.isEmpty) then
3495+
accept(COLON)
3496+
val constrs = constrApps(commaOK = true, templateCanFollow = true)
3497+
if in.token == ARROW && vparamss.isEmpty && constrs.forall(_.isType) then
3498+
vparamss = typesToGivenParams(constrs, ofClass = false, 0) :: Nil
3499+
conditionalParents()
3500+
else
3501+
constrs
3502+
3503+
if in.token == EQUALS && parents.length == 1 && parents.head.isType then
3504+
in.nextToken()
3505+
mods1 |= Final
3506+
DefDef(name, tparams, vparamss, parents.head, subExpr())
3507+
else
3508+
parents match
3509+
case TypeBoundsTree(_, _) :: _ => syntaxError("`=` expected")
3510+
case _ =>
3511+
possibleTemplateStart()
3512+
val tparams1 = tparams.map(tparam => tparam.withMods(tparam.mods | PrivateLocal))
3513+
val vparamss1 = vparamss.map(_.map(vparam =>
3514+
vparam.withMods(vparam.mods &~ Param | ParamAccessor | PrivateLocal)))
3515+
val templ = templateBodyOpt(makeConstructor(tparams1, vparamss1), parents, Nil)
3516+
if tparams.isEmpty && vparamss.isEmpty then ModuleDef(name, templ)
3517+
else TypeDef(name.toTypeName, templ)
35333518
}
35343519
finalizeDef(gdef, mods1, start)
35353520
}

docs/docs/reference/other-new-features/opaques.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ object Logarithms {
2020
}
2121

2222
// Extension methods define opaque types' public APIs
23-
given logarithmOps: (x: Logarithm) extended with {
23+
extension logarithmOps on (x: Logarithm) {
2424
def toDouble: Double = math.exp(x)
2525
def + (y: Logarithm): Logarithm = Logarithm(math.exp(x) + math.exp(y))
2626
def * (y: Logarithm): Logarithm = x + y

tests/pos/i7401.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
object Test {
2-
given ops: (a: Int) extended with {
2+
extension ops on (a: Int) {
33
def foo(i: Int): Unit = ()
44
def foo: Unit = ()
55
}

tests/run/LazyLists.scala

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,7 @@ package xcollections with
5555
if it.hasNext then set(it.next, fromIterator (it))
5656
else empty
5757

58-
given [T, U >: T](xs: LazyList[T]) extended with
59-
58+
extension on [T, U >: T](xs: LazyList[T]) {
6059
def #::(x: U): LazyList[U] = new with
6160
protected def force(): LazyList[U] =
6261
set(x, xs)
@@ -65,8 +64,9 @@ package xcollections with
6564
protected def force() =
6665
if xs.isEmpty then ys.forced()
6766
else set(xs.head, xs.tail ++ ys)
67+
}
6868

69-
given [T, U](xs: LazyList[T]) extended with
69+
extension on [T, U](xs: LazyList[T]) {
7070
def map(f: T => U): LazyList[U] = new with
7171
protected def force() =
7272
if xs.isEmpty then empty
@@ -80,8 +80,9 @@ package xcollections with
8080
def foldLeft(z: U)(f: (U, T) => U): U =
8181
if xs.isEmpty then z
8282
else xs.tail.foldLeft(f(z, xs.head))(f)
83+
}
8384

84-
given [T](xs: LazyList[T]) extended with
85+
extension on [T](xs: LazyList[T]) {
8586
def filter(p: T => Boolean): LazyList[T] = new with
8687
protected def force(): LazyList[T] =
8788
if xs.isEmpty then empty
@@ -103,6 +104,7 @@ package xcollections with
103104
if n <= 0 || xs.isEmpty then xs
104105
else advance(xs.tail, n - 1)
105106
advance(xs, n)
107+
}
106108
end LazyList
107109
end xcollections
108110

0 commit comments

Comments
 (0)