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

Method overload with mismatched type chosen over generic overload #16737

Closed
armanbilge opened this issue Jan 21, 2023 · 1 comment
Closed

Method overload with mismatched type chosen over generic overload #16737

armanbilge opened this issue Jan 21, 2023 · 1 comment

Comments

@armanbilge
Copy link
Contributor

Compiler version

3.3.0-RC1-bin-20230119-13b8d7d-NIGHTLY

Minimized code

//> using scala "3.3.0-RC1-bin-20230119-13b8d7d-NIGHTLY"

class Foo

object bar:
  def apply[M](m: M): Unit =
    ???

  def apply[M](f: Unit => M): Unit =
    ???

  def apply[M <: Tuple](f: Unit => M)(using DummyImplicit): Unit =
    ???

def main =
  bar(_ => new Foo)

Output

[error] ./test.scala:16:12: Found:    Foo
[error] Required: Tuple
[error]   bar(_ => new Foo)
[error]            ^^^^^^^

Expectation

The overload should resolve.

@odersky
Copy link
Contributor

odersky commented Jan 23, 2023

This was a very hard puzzler. First, Scala 2 and Scala 3 behave the same (different error messages but same outcome).
Second, the example is quite minimal -- you change the slightest detail and it works. So let's look at it in details:

The first definition

  def apply[M](m: M): Unit =
    ???

means that the argument cannot be pre-typed using preTypeArgs since not all expected types are functions.
If the first definition is missing, it compiles OK.

The argument _ => new Foo must have an undeclared parameter type. If you write (_: Unit) => new Foo instead, it compiles OK.

Since the argument has an undeclared parameter and it cannot be pre-typed from the outside, we assume the wildcard type <?> => <?>. That type matches both the second and the third versions of apply.

The third version of apply is more specific than the second, since it constrains its type parameter more. So that version is chosen.

The argument is now typed with expected type Unit => M where M <: Tuple, and that fails.

I think this is all as expected. Surprising? Sure. But the example is pushing it.

@odersky odersky added itype:invalid and removed itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels Jan 23, 2023
@odersky odersky closed this as completed Jan 23, 2023
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

2 participants