Skip to content

Commit edfc820

Browse files
committed
Disallow normal method names starting with extension_
1 parent 4c1c4d3 commit edfc820

File tree

4 files changed

+27
-0
lines changed

4 files changed

+27
-0
lines changed

compiler/src/dotty/tools/dotc/typer/Typer.scala

+4
Original file line numberDiff line numberDiff line change
@@ -1953,7 +1953,11 @@ class Typer extends Namer
19531953
}
19541954

19551955
val ddef2 = assignType(cpy.DefDef(ddef)(name, tparams1, vparamss1, tpt1, rhs1), sym)
1956+
19561957
checkSignatureRepeatedParam(sym)
1958+
if name.isExtensionName then
1959+
ctx.error(em"illegal method name: $name may not start with `extension_`",
1960+
ddef.source.atSpan(ddef.nameSpan))
19571961
ddef2.setDefTree
19581962
//todo: make sure dependent method types do not depend on implicits or by-name params
19591963
}

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

+15
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,22 @@ def extension_position(s: String)(ch: Char, n: Int): Int =
229229
if n < s.length && s(n) != ch then extension_position(s)(ch, n + 1)
230230
else n
231231
```
232+
### More Details
232233

234+
1. To avoid confusion, names of normal methods are not allowed to start with `extension_`.
235+
236+
2. A named import such as `import a.m` of an extension method in `a` will make `m`
237+
only available as an extension method. To access it under
238+
`extension_m` that name as to be imported separately. Example:
239+
```scala
240+
object DoubleOps:
241+
extension (x: Double) def ** (exponent: Int): Double =
242+
require(exponent > 0)
243+
if exponent == 0 then 1 else x * (x ** (exponent - 1))
244+
245+
import DoubleOps.{**, extension_**}
246+
assert(2.0 ** 3 == extension_**(2.0)(3))
247+
```
233248

234249
### Syntax
235250

tests/neg/override-extension_normal-methods.scala

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ trait AAA extends A {
88

99
trait B {
1010
def m[T](x: T): String = "normal method"
11+
def extension_n: String = "illegal method" // error: illegal method name: extension_n may not start with `extension_`
1112
}
1213

1314
trait BBB extends B {

tests/pos/reference/extension-methods.scala

+7
Original file line numberDiff line numberDiff line change
@@ -92,4 +92,11 @@ object ExtMethods:
9292
xs.sorted.takeRight(n)
9393
}
9494

95+
object DoubleOps:
96+
extension (x: Double) def ** (exponent: Int): Double =
97+
require(exponent > 0)
98+
if exponent == 0 then 1 else x * (x ** (exponent - 1))
99+
100+
import DoubleOps.{**, extension_**}
101+
assert(2.0 ** 3 == extension_**(2.0)(3))
95102
end ExtMethods

0 commit comments

Comments
 (0)