6

I have the following scenario:

case class B(v: String)
case class A(bs: Seq[B])

extension(a: A)
  def doit() = a.bs.map(_.doit()) // here is the exception

extension(b: B)
  def doit() = println("OK: ${b.v}")

This gives me the following exception on compilation:

value doit is not a member of B.
An extension method was tried, but could not be fully constructed:

    _$1

Are there restrictions in the naming of extension methods in Scala 3?

See the example here on Scastie

stefanobaghino
  • 11,253
  • 4
  • 35
  • 63
pme
  • 14,156
  • 3
  • 52
  • 95
  • 3
    If I put methods into some object the errror message changes to `method extension_doit needs result type because its right-hand side attempts implicit search`. If I specify return type e.g. `Unit` for both methods the code compiles (both inside an object and top-level). Tested in 0.28.0-bin-20200920-e99793e-NIGHTLY. – Dmytro Mitin Sep 22 '20 at 19:09
  • 2
    Thanks @DmytroMitin - so it seems if the names are equals it needs the return type. – pme Sep 22 '20 at 19:14
  • 1
    @DmytroMitin that's a new rule for implicit resolution? – SwiftMango Sep 22 '20 at 21:11

1 Answers1

1

Turning the comment into an answer, the spec says both extensions are translated to def extension_doit.

Calling the extension method explicitly:

-- [E044] Cyclic Error: so.scala:7:45 -----------------------
7 |  extension(a: A) def doit() = a.bs.map(b => extension_doit(b)())
  |                                             ^
  |           Overloaded or recursive method extension_doit needs return type

This is the same error seen with debug of the original example:

>>>> StoredError: Overloaded or recursive method extension_doit needs return type
[snip]
-- [E008] Not Found Error: so.scala:7:42 --------------------
7 |  extension(a: A) def doit() = a.bs.map(_.doit())
  |                                        ^^^^^^
  |        value doit is not a member of B.
  |        An extension method was tried, but could not be fully constructed:
  |
  |            _$1

Overload resolution was explicitly improved or extended to handle this normal case of overloads which may be differentiated only in later parameter lists. So apparently we are supposed to be aware that the desugared form is overloaded.

Scala 2 also complains:

scala> object X { def f(i: Int) = f("") ; def f(s: String) = f(42) }
                                                              ^
       error: overloaded method f needs result type
                                   ^
       error: overloaded method f needs result type
som-snytt
  • 39,429
  • 2
  • 47
  • 129