Skip to content
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

Fail to resolve overloaded method when type inference is required #10046

Open
scabug opened this issue Nov 12, 2016 · 8 comments
Open

Fail to resolve overloaded method when type inference is required #10046

scabug opened this issue Nov 12, 2016 · 8 comments
Labels
fixed in Scala 3 This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/) infer overloading
Milestone

Comments

@scabug
Copy link

scabug commented Nov 12, 2016

Here is a snippet to illustrate the problem:

class Foo[A] {
  def compose(a: Foo[A]): Foo[A] = new Foo[A]
  def compose(b: Bar[A]): Bar[A] = new Bar[A]

  // non overloaded method
  def composeBar(b: Bar[A]): Bar[A] = new Bar[A]
}

class Bar[A] {
  def compose(a: Foo[A]): Bar[A] = new Bar[A]
  def compose(b: Bar[A]): Bar[A] = new Bar[A]
}

object Test {
  val fooS = new Foo[String]
  val barS = new Bar[String]
  def barA[A] = new Bar[A]

  // foos and bars compose together
  fooS compose fooS
  barS compose barS
  fooS compose barS
  barS compose fooS

  // here it fails with the following error
  // error: overloaded method value compose with alternatives:
  // (b: Bar[String])Bar[String] <and>
  // (a: Foo[String])Foo[String]
  // cannot be applied to (Bar[Nothing])
  fooS compose barA
  
  // but it works if you add a type annotation or a non overloaded method
  fooS compose barA[String]
  fooS composeBar barA
}

This issue is particularly important for monocle because all optics (Iso, Lens, Prism, ...) compose together which means we need to define 8 different compose methods instead of a single method overloaded 8 times.

@scabug
Copy link
Author

scabug commented Nov 12, 2016

Imported From: https://issues.scala-lang.org/browse/SI-10046?orig=1
Reporter: Julien Truffaut (julien-truffaut)
Affected Versions: 2.11.8, 2.12.0

@scabug
Copy link
Author

scabug commented Nov 12, 2016

Jean-Baptiste Giraudeau (jbgi) said:
In case this could be an incentive to fix this issue, the test case compile just fine in java:

class Test {
  static class Foo<A> {
    Foo<A> compose(Foo<A> a) {
       return new Foo<>();
    }
    Bar<A> compose(Bar<A> b) {
      return new Bar<>();
    }
  }

  static class Bar<A> {
    Bar<A> compose(Foo<A> a) {
      return new Bar<>();
    }

    Bar<A> compose(Bar<A> b) {
      return new Bar<>();
    }
  }

  static <A> Bar<A> barA() {
    return new Bar<>();
  }

  public static void main(String[] args) {
    Foo<String> fooS = new Foo<>();

    // Compile just fine:
    fooS.compose(barA());
  }
}

This kind of limitations means that the scala user-experience (of java 8 libraries in particular) can be inferior to the java user-experience. Resolving regressions vs Java 8 should, imo, be given major priority (at least from a marketing pov ;-)).

@scabug
Copy link
Author

scabug commented Nov 19, 2016

@som-snytt said:
Maybe the missing param type exception for function literals can be extended to this case, so that a single missing type param is inferred from the type args of the candidate expected types.

Problem statement:

scala> class D[A] ; class C[A] { def f(x: C[A]): C[A] = new C[A] ; def f(x: D[A]): D[A] = new D[A] }
defined class D
defined class C

scala> def d[A]: D[A] = new D[A]
d: [A]=> D[A]

scala> new C[String]().f(d)
<console>:14: error: overloaded method value f with alternatives:
  (x: D[String])D[String] <and>
  (x: C[String])C[String]
 cannot be applied to (D[Nothing])
       new C[String]().f(d)
                       ^

This is not a workaround.

scala> class D[A] ; class C[A] { def f(x: A => C[A]): C[A] = new C[A] ; def f(x: A => D[A]): D[A] = new D[A] }
defined class D
defined class C

scala> def d[A]: D[A] = new D[A]
d: [A]=> D[A]

scala> new C[String]().f(x => d)
<console>:14: error: overloaded method value f with alternatives:
  (x: String => D[String])D[String] <and>
  (x: String => C[String])C[String]
 cannot be applied to (String => D[Nothing])
       new C[String]().f(x => d)
                       ^

scala> new C[String]().f(x => d[x.type])
<console>:14: error: overloaded method value f with alternatives:
  (x: String => D[String])D[String] <and>
  (x: String => C[String])C[String]
 cannot be applied to (String => D[_ <: String with Singleton])
       new C[String]().f(x => d[x.type])
                       ^

@scabug
Copy link
Author

scabug commented Dec 10, 2016

Julien Truffaut (julien-truffaut) said:
At the moment, I can see one way to fix the issue but I am very unfamiliar with the internal API. Here is what I found so far:

In Typers -> preSelectOverloaded, we could try to remove overloaded candidates that cannot match, e.g. there is no way that a Bar[A] can be a Foo[String]. If we can do that then the issue would be resolved because there would be only one alternative. However, it seems that the Tree barA hasn't been type checked in preSelectOverloaded, so I don't know how to access type information.

@scabug
Copy link
Author

scabug commented Dec 11, 2016

@som-snytt said:
I think it's a spec issue and not just a matter of implementation. It takes two cuts at which alternatives apply, first by shape and second after type checking the args (without an expected type).

@scabug
Copy link
Author

scabug commented Dec 11, 2016

Julien Truffaut (julien-truffaut) said:
Would you mind to point me at the part of the spec you mentioned?

@scabug
Copy link
Author

scabug commented Dec 11, 2016

@som-snytt said:
http://www.scala-lang.org/files/archive/spec/2.12/06-expressions.html#overloading-resolution

That is 6.26.3. (The table of contents is temporarily pointing to a phantom 2.13 version.)

@SethTisue
Copy link
Member

#10542 seems similar?

@som-snytt som-snytt added the fixed in Scala 3 This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/) label Sep 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
fixed in Scala 3 This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/) infer overloading
Projects
None yet
Development

No branches or pull requests

3 participants