Skip to content

Commit 35da844

Browse files
committed
Drop extension keyword
1 parent 77fbcdb commit 35da844

File tree

19 files changed

+61
-51
lines changed

19 files changed

+61
-51
lines changed

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

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3322,6 +3322,22 @@ object Parsers {
33223322
Template(constr, parents, Nil, EmptyValDef, Nil)
33233323
}
33243324

3325+
/** Are the next tokens a prefix of a DefParam? */
3326+
def isDefParam() =
3327+
val lookahead = in.LookaheadScanner()
3328+
if lookahead.token == LPAREN then
3329+
lookahead.nextToken()
3330+
if lookahead.token == AT then true
3331+
else if lookahead.token == IDENTIFIER then
3332+
if lookahead.name == nme.inline then
3333+
lookahead.nextToken()
3334+
if lookahead.token == IDENTIFIER then
3335+
lookahead.nextToken()
3336+
lookahead.token == COLON
3337+
else false
3338+
else false
3339+
else false
3340+
33253341
/** OLD:
33263342
* GivenDef ::= [id] [DefTypeParamClause] GivenBody
33273343
* GivenBody ::= [‘as ConstrApp {‘,’ ConstrApp }] {GivenParamClause} [TemplateBody]
@@ -3338,11 +3354,7 @@ object Parsers {
33383354
var mods1 = addMod(mods, instanceMod)
33393355
var isExtension = false
33403356
val name =
3341-
if isIdent(nme.extension) then
3342-
in.nextToken()
3343-
isExtension = true
3344-
EmptyTermName
3345-
else if newStyle && allowOldGiven && isIdent(nme.as) then EmptyTermName
3357+
if newStyle && allowOldGiven && isIdent(nme.as) then EmptyTermName
33463358
else if isIdent then ident()
33473359
else EmptyTermName
33483360
indentRegion(name) {
@@ -3359,12 +3371,13 @@ object Parsers {
33593371
tokenSeparated(COMMA, constrApp)
33603372
else if in.token == COLON then
33613373
in.nextToken()
3362-
if isIdent(nme.extension) then
3374+
if in.token == LBRACE
3375+
|| in.token == LBRACKET
3376+
|| in.token == LPAREN && isDefParam() then
33633377
if tparams.nonEmpty then
3364-
syntaxError(i"no type parameters allowed before `extension`", tparams.head.span)
3378+
syntaxError(i"no type parameters allowed for extension", tparams.head.span)
33653379
if leadingParamss.nonEmpty then
3366-
syntaxError(i"no parameters allowed before `extension`", leadingParamss.head.head.span)
3367-
in.nextToken()
3380+
syntaxError(i"no parameters allowed for extension", leadingParamss.head.head.span)
33683381
parseParams()
33693382
Nil
33703383
else tokenSeparated(COMMA, constrApp)

docs/docs/internals/syntax.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ ObjectDef ::= id [Template]
389389
EnumDef ::= id ClassConstr InheritClauses EnumBody EnumDef(mods, name, tparams, template)
390390
GivenDef ::= [GivenSig (‘:’ | <:)] Type ‘=’ Expr
391391
| [GivenSig ‘:’] [ConstrApp {‘,’ ConstrApp }] [TemplateBody]
392-
| ‘extension’ [id ‘:’] [ExtParamClause] TemplateBody
392+
| [id ‘:’] [ExtParamClause] TemplateBody
393393
GivenSig ::= [id] [DefTypeParamClause] {GivenParamClause}
394394
ExtParamClause ::= [DefTypeParamClause] ‘(’ DefParam ‘)’ {GivenParamClause}
395395
Template ::= InheritClauses [TemplateBody] Template(constr, parents, self, stats)

docs/docs/reference/contextual/extension-methods.md

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -84,39 +84,36 @@ So `circle.circumference` translates to `CircleOps.circumference(circle)`, provi
8484

8585
### Given Instances Defining Only Extension Methods
8686

87-
Given instances that define extension methods can also be defined without a parent clause. In this case the `given` is followed by the special identifier
88-
`extension`. E.g.,
87+
Given instances that define extension methods can also be defined without a parent clause. E.g.,
8988

9089
```scala
91-
given stringOps: extension {
90+
given stringOps: {
9291
def (xs: Seq[String]) longestStrings: Seq[String] = {
9392
val maxLength = xs.map(_.length).max
9493
xs.filter(_.length == maxLength)
9594
}
9695
}
9796

98-
given extension {
97+
given {
9998
def (xs: List[T]) second[T] = xs.tail.head
10099
}
101100
```
102-
If given extensions are anonymous (as in the second clause), their name is synthesized from the name of the first defined extension method.
103-
104-
Note: `extension` is a soft keyword, it can be used elsewhere as a normal identifier.
101+
If an extensions is anonymous (as in the second clause), its name is synthesized from the name of the first defined extension method.
105102

106103
### Given Extensions with Collective Parameters
107104

108105
If a given extension defines several extension methods one can pull out the left parameter section
109106
as well as any type parameters of these extension methods into the given instance itself.
110107
For instance, here is a given instance with two extension methods.
111108
```scala
112-
given listOps: extension {
109+
given listOps: {
113110
def (xs: List[T]) second[T]: T = xs.tail.head
114111
def (xs: List[T]) third[T]: T = xs.tail.tail.head
115112
}
116113
```
117114
The repetition in the parameters can be avoided by moving the parameters in front of the opening brace. The following version is a shorthand for the code above.
118115
```scala
119-
given listOps: extension[T](xs: List[T]) {
116+
given listOps: [T](xs: List[T]) {
120117
def second: T = xs.tail.head
121118
def third: T = xs.tail.tail.head
122119
}
@@ -176,6 +173,6 @@ Here are the required syntax extensions compared to the
176173
DefSig ::= ...
177174
| ‘(’ DefParam ‘)’ [nl] id [DefTypeParamClause] DefParamClauses
178175
GivenDef ::= ...
179-
| [id ‘:’] ‘extension’ ExtParamClause TemplateBody
176+
| [id ‘:’] [ExtParamClause] TemplateBody
180177
ExtParamClause ::= [DefTypeParamClause] ‘(’ DefParam ‘)’ {GivenParamClause}
181178
```

docs/docs/reference/contextual/relationship-implicits.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ Anonymous given instances that define extension methods without also implementin
6868
get their name from the name of the first extension method and the toplevel type
6969
constructor of its first parameter. For example, the given extension
7070
```scala
71-
given extension {
71+
given {
7272
def (xs: List[T]) second[T] = ...
7373
}
7474
```

docs/docs/reference/metaprogramming/macros.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ The `toExpr` extension method is defined in package `quoted`:
251251
```scala
252252
package quoted
253253

254-
given extension {
254+
given {
255255
def (x: T) toExpr[T: Liftable] given QuoteContext: Expr[T] = summon[Liftable[T]].toExpr(x)
256256
...
257257
}

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: extension {
23+
given logarithmOps: {
2424
def (x: Logarithm) toDouble: Double = math.exp(x)
2525
def (x: Logarithm) + (y: Logarithm): Logarithm = Logarithm(math.exp(x) + math.exp(y))
2626
def (x: Logarithm) * (y: Logarithm): Logarithm = Logarithm(x + y)

library/src-bootstrapped/scala/IArray.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ object opaques {
88
opaque type IArray[+T] = Array[_ <: T]
99

1010
/** Defines extension methods for immutable arrays */
11-
given arrayOps: extension {
11+
given arrayOps: {
1212

1313
/** The selection operation on an immutable array.
1414
*

tests/neg/extmethod-overload.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
object Test {
2-
given A: extension {
2+
given A: {
33
def (x: Int) |+| (y: Int) = x + y
44
}
5-
given B: extension {
5+
given B: {
66
def (x: Int) |+| (y: String) = x + y.length
77
}
88
assert((1 |+| 2) == 3) // error ambiguous

tests/neg/i5455.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ object Library {
1111
def toInt(n: Nat): Int = n
1212

1313
}
14-
given extension {
14+
given {
1515
def (x: Nat) * (y: Nat): Nat = x * y
1616
def (x: Nat) toInt: Int = x
1717
}

tests/pos/i7084.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ object Test {
22

33
type Foo
44

5-
given extension {
5+
given {
66
def (y: Any) g given Foo: Any = ???
77
}
88

0 commit comments

Comments
 (0)