Skip to content

Extension methods with the same name failing #18744

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
JD557 opened this issue Oct 22, 2023 · 2 comments · Fixed by #18759
Closed

Extension methods with the same name failing #18744

JD557 opened this issue Oct 22, 2023 · 2 comments · Fixed by #18759

Comments

@JD557
Copy link
Contributor

JD557 commented Oct 22, 2023

Compiler version

3.3.1

Minimized code

import scala.annotation.targetName

object Types:
  opaque type Color = Int
  object Color:
    def apply(i: Int): Color = i

  trait Surface
  opaque type Plane = (Int, Int) => Color

  object Plane:
    def fromFunction(f: (Int, Int) => Color): Plane = f
    extension (plane: Plane)
      @targetName("zipWithP")
      def zipWith(that: Plane, f: (Color, Color) => Color): Plane = ???
      @targetName("zipWithS")
      def zipWith(that: Surface, f: (Color, Color) => Color): Surface = ???

      // Call the functions above, but renamed
      def zipWithPlane(that: Plane, f: (Color, Color) => Color): Plane =
        zipWith(that, f) // I can call zipWith fine here

      def zipWithSurface(
          that: Surface,
          f: (Color, Color) => Color
      ): Surface =
        zipWith(that, f) // I can call zipWith fine here as well

import Types.*

@main def hello =
  val p: Plane = Plane.fromFunction((i: Int, b: Int) => Color(i + b))
  p.zipWithPlane(p, (_: Color, _: Color) => Color(25)) // Works if I use the renamed version
  Plane.zipWith(p)(p, (_: Color, _: Color) => Color(25)) // Works if I use the curried version
  p.zipWith(p, (_: Color, _: Color) => Color(25)) // Does not work if I use the overloaded version

Output

[error] value zipWith is not a member of Types.Plane.
[error] An extension method was tried, but could not be fully constructed:
[error]
[error]     Types.Plane.zipWith(p)
[error]   p.zipWith(p, (_: Color, _: Color) => Color(25)) // Does not work if I use the overloaded version

Expectation

I would expect to be able to call zipWith on hello as well.

Notes

Some weird things I noticed: If I use Int instead of Color, the code compiles:

//> using option -explain

import scala.annotation.targetName

object Types:
  trait Surface
  opaque type Plane = (Int, Int) => Int

  object Plane:
    def fromFunction(f: (Int, Int) => Int): Plane = f
    extension (plane: Plane)
      @targetName("zipWithP")
      def zipWith(that: Plane, f: (Int, Int) => Int): Plane = ???
      @targetName("zipWithS")
      def zipWith(that: Surface, f: (Int, Int) => Int): Surface = ???

      // Call the functions above, but renamed
      def zipWithPlane(that: Plane, f: (Int, Int) => Int): Plane =
        zipWith(that, f)

      def zipWithSurface(
          that: Surface,
          f: (Int, Int) => Int
      ): Surface =
        zipWith(that, f)

import Types.*

@main def hello =
  val p: Plane = Plane.fromFunction((i: Int, b: Int) => i + b)
  p.zipWithPlane(p, (_: Int, _: Int) => 25) // Works
  Plane.zipWith(p)(p, (_: Int, _: Int) => 25) // Works
  p.zipWith(p, (_: Int, _: Int) => 25) // Works

However, if I just remove the opaque modifier from Color, the code still won't compile (even if I add inline to Color#apply).

@JD557 JD557 added itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels Oct 22, 2023
@soronpo
Copy link
Contributor

soronpo commented Oct 22, 2023

I was playing around with it and also discovered a crash. Submitted #18745

@nicolasstucki
Copy link
Contributor

nicolasstucki commented Oct 23, 2023

Minimization

object Color:
  def apply(): Int = ???

extension (u: Unit)
  def foo(that: String, f: Int => Int): Int = ???
  def foo(that: Long, f: Int => Int): Int = ???

def test =
  val c = Color()
  ().foo("", (_: Int) => c)
  ().foo("", (_: Int) => Color()) // fails

@nicolasstucki nicolasstucki added area:typer and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels Oct 23, 2023
odersky added a commit to dotty-staging/dotty that referenced this issue Oct 23, 2023
…ding resolution

The SynthesizeExtMethodReceiver mode is supposed to be turned on only for the
direct application of of a synthesized receiver to the qualifier of an
extension method selection. previously its lifetime was accidentally extended
when overloading resolution looking at subsequent parameter lists because the
first one was not enough to disambiguate.

Fixes scala#18745
Fixes scala#18744
WojciechMazur pushed a commit that referenced this issue Jun 22, 2024
…ding resolution

The SynthesizeExtMethodReceiver mode is supposed to be turned on only for the
direct application of of a synthesized receiver to the qualifier of an
extension method selection. previously its lifetime was accidentally extended
when overloading resolution looking at subsequent parameter lists because the
first one was not enough to disambiguate.

Fixes #18745
Fixes #18744

[Cherry-picked edc4bc8]
WojciechMazur pushed a commit that referenced this issue Jun 23, 2024
…ding resolution

The SynthesizeExtMethodReceiver mode is supposed to be turned on only for the
direct application of of a synthesized receiver to the qualifier of an
extension method selection. previously its lifetime was accidentally extended
when overloading resolution looking at subsequent parameter lists because the
first one was not enough to disambiguate.

Fixes #18745
Fixes #18744

[Cherry-picked edc4bc8]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants