Skip to content

Generic number literals miss overloaded method #11509

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
rjolly opened this issue Feb 23, 2021 · 4 comments
Closed

Generic number literals miss overloaded method #11509

rjolly opened this issue Feb 23, 2021 · 4 comments

Comments

@rjolly
Copy link
Contributor

rjolly commented Feb 23, 2021

Note: this time we are using BigInt, not java.math.BigInteger

Compiler version

3.0.0-RC1

Minimized code and output

import scala.language.experimental.genericNumberLiterals
class B
object B {
  def apply(x: BigInt): B = ???
  def apply(x: String): B = ???
}
object Test {
  val x = B(18446744073709551616)
//          ^^^^^^^^^^^^^^^^^^^^
//          number too large
}

Expectation

Should work as when there's no overload:

object B {
  def apply(x: BigInt): B = ???
}
object Test {
  val x = B(18446744073709551616) // works
}
@rjolly
Copy link
Contributor Author

rjolly commented Feb 23, 2021

This is a follow-up to #11482.

@odersky
Copy link
Contributor

odersky commented Feb 23, 2021

I don't think it can, really. That's not how it's specced.

Here's what it says:

If the expected type is a fully defined type T that has a given instance of type scala.util.FromDigits[T], the literal is converted to a value of type T by passing it as an argument to the fromDigits method of that instance (more details below).

The expected type of the literal here is "?" since the method is overloaded. There's nothing to be done here. If you think we need a different spec and algorithm, it's fine to propose and implement one.

@odersky odersky closed this as completed Feb 23, 2021
@som-snytt
Copy link
Contributor

TIL synthetic case class apply is retracted only if user-supplied apply signature conflicts. (Just supplying an apply is not sufficient.)

So if B is a case class, the workaround would be to make the constructor private. That inspires the following example, which fails unexpectedly:

class B
object B {
  private[this] def apply(y: String): B = ???
  def apply(x: BigInt): B = ???
}
object Test {
  val x = B(18446744073709551616)
  val f = B.apply _
  def main(args: Array[String]): Unit = println(x)
}

I see that the Scala 2 spec doesn't address accessibility with respect to overloading. B.apply is overloaded even if only one alternative is accessible. There is no rule to improve inference in this case. The spec could say, "Normally args are typed without an expected type, but ...". Well, if accessibility were part of the shape test ("potentially applicable"), then if only one candidate remains, the expected parameter types are determined.

@rjolly
Copy link
Contributor Author

rjolly commented Feb 25, 2021

Yes, and implicit conversion too needs an expected type, and it works despite overloading.

class B
object B {
  def apply(x: BigInt): B = ???
  def apply(x: String): B = ???
}
object Test {
  val x = B(1)
}

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

No branches or pull requests

3 participants