Skip to content

Commit

Permalink
Disallow normal method names starting with extension_
Browse files Browse the repository at this point in the history
  • Loading branch information
odersky committed Jun 30, 2020
1 parent 4c1c4d3 commit edfc820
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 0 deletions.
4 changes: 4 additions & 0 deletions compiler/src/dotty/tools/dotc/typer/Typer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1953,7 +1953,11 @@ class Typer extends Namer
}

val ddef2 = assignType(cpy.DefDef(ddef)(name, tparams1, vparamss1, tpt1, rhs1), sym)

checkSignatureRepeatedParam(sym)
if name.isExtensionName then
ctx.error(em"illegal method name: $name may not start with `extension_`",
ddef.source.atSpan(ddef.nameSpan))
ddef2.setDefTree
//todo: make sure dependent method types do not depend on implicits or by-name params
}
Expand Down
15 changes: 15 additions & 0 deletions docs/docs/reference/contextual/extension-methods.md
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,22 @@ def extension_position(s: String)(ch: Char, n: Int): Int =
if n < s.length && s(n) != ch then extension_position(s)(ch, n + 1)
else n
```
### More Details

1. To avoid confusion, names of normal methods are not allowed to start with `extension_`.

2. A named import such as `import a.m` of an extension method in `a` will make `m`
only available as an extension method. To access it under
`extension_m` that name as to be imported separately. Example:
```scala
object DoubleOps:
extension (x: Double) def ** (exponent: Int): Double =
require(exponent > 0)
if exponent == 0 then 1 else x * (x ** (exponent - 1))

import DoubleOps.{**, extension_**}
assert(2.0 ** 3 == extension_**(2.0)(3))
```

### Syntax

Expand Down
1 change: 1 addition & 0 deletions tests/neg/override-extension_normal-methods.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ trait AAA extends A {

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

trait BBB extends B {
Expand Down
7 changes: 7 additions & 0 deletions tests/pos/reference/extension-methods.scala
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,11 @@ object ExtMethods:
xs.sorted.takeRight(n)
}

object DoubleOps:
extension (x: Double) def ** (exponent: Int): Double =
require(exponent > 0)
if exponent == 0 then 1 else x * (x ** (exponent - 1))

import DoubleOps.{**, extension_**}
assert(2.0 ** 3 == extension_**(2.0)(3))
end ExtMethods

0 comments on commit edfc820

Please sign in to comment.