Skip to content

Extension methods with the same name failing #18744

Closed
@JD557

Description

@JD557

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).

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions