Skip to content

Compiler: Generic method overloading via implicit class #11810

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
REASY opened this issue Nov 26, 2019 · 3 comments
Closed

Compiler: Generic method overloading via implicit class #11810

REASY opened this issue Nov 26, 2019 · 3 comments

Comments

@REASY
Copy link

REASY commented Nov 26, 2019

When I try to create an extension for the class via implicit class and overload existing generic method, it fails with compilation error:

error: overloaded method value getAs with alternatives:
  (fieldName: String)String <and>
  (i: Int)String
 cannot be applied to (FooField.type)
       r.getAs[String](FooField)

While overloading normal (non-generic) method via implicit works fine. Tried on Scala 2.12.10. Link to scastie. What am I missing? Code:

trait Row {
    // Two overloads for `getAs[T]`
    def getAs[T](i: Int): T
    def getAs[T](fieldName: String): T

    // Two overloads for `get`
    def get(i: Int): String
    def get(fieldName: String): String
}

trait Field {
    def columnName: String
    def columnDescription: String
}
case object FooField extends Field {
    def columnName: String = "Foo"
  def columnDescription: String = "Foo desc"
}

object Implicits {
  implicit class RowEx(val r: Row) extends AnyVal {
    def getAs[T](field: Field): T = r.getAs[T](field.columnName)
    def get(field: Field): String = {
      println(s"RowEx.get: field")
      r.get(field.columnName)
    }
  }
}

object Main {
  import Implicits._
  // Create some instance of `Row`
  val r = new Row {
    def getAs[T](i: Int): T = i.toString.asInstanceOf[T]
    def getAs[T](fieldName: String): T = fieldName.toString.asInstanceOf[T]
    def get(i: Int): String = i.toString
    def get(fieldName: String): String = fieldName
  }

  def main(args: Array[String]): Unit = {
    // Call extension method => `RowEx.get`
    println(r.get(FooField))

    // Call extension method => `RowEx.get`
    // Won't compile with compilation error:
    /*
    overloaded method value getAs with alternatives:
      (fieldName: String)String 
      (i: Int)String
     cannot be applied to (FooField.type)
    */
    println(r.getAs[String](FooField))
  }
}

Originally I created a question in StackOverflow

@Jasper-M
Copy link

I think this is a duplicate of #9523.

@hrhino
Copy link

hrhino commented Nov 26, 2019

And would be fixed by scala/scala#7396...

@som-snytt
Copy link

Just verified that the linked PR compiles it.

Maybe we can enlist Jimmy G. to get it over the goal line! Go '49ers!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants