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

Type inference (with -Ypartial-unification) doesn't work for default arguments #366

Closed
TomasMikula opened this issue Apr 7, 2017 · 3 comments

Comments

@TomasMikula
Copy link

TomasMikula commented Apr 7, 2017

Try to compile the following code with scalac 2.12.1 with -language:higherKinds -Ypartial-unification

case class Foo[F[_]]()

class Bar[A, B]

object Test {

  // OK. For a local variable, type inference works.
  def test1[A]: Unit = {
    val m: Foo[({ type Out[α] = Bar[A, α] })#Out] = Foo()
  }

  // ERROR. Type inference doesn't work so well for default arguments.
  def test2[A](
    m: Foo[({ type Out[α] = Bar[A, α] })#Out] = Foo()
  ): Unit = ()

}

It gives the following error:

test.scala:14: error: no type parameters for method apply: ()Foo[F] in object Foo exist so that it can be applied to arguments ()
 --- because ---
undetermined type
    m: Foo[({ type Out[α] = Bar[A, α] })#Out] = Foo()
                                                ^
test.scala:14: error: type mismatch;
 found   : Foo[F]
 required: Foo[[α]Bar[?,α]]
    m: Foo[({ type Out[α] = Bar[A, α] })#Out] = Foo()
                                                   ^
two errors found

My expectation would be that type inference works the same in these two cases.

@lrytz
Copy link
Member

lrytz commented Apr 7, 2017

This is the consequence of a special-case in type-checking defaults. The idea is to enable this:

scala> def f[T](x: T = 1) = x
f: [T](x: T)T

scala> f()
res3: Int = 1

http://www.scala-lang.org/files/archive/spec/2.12/04-basic-declarations-and-definitions.html#default-arguments says

The default argument expression e is type-checked with an expected type T' obtained by replacing all occurrences of the function's type parameters in T by the undefined type

So the following still gives an error:

scala> def f[T](x: Option[T] = 1) = x
<console>:11: error: type mismatch;
 found   : Int(1)
 required: Option[?]
       def f[T](x: Option[T] = 1) = x
                               ^

Maybe that feature is questionable, it's a bit of a hack that hasn't been discussed in very much detail. Another example that might be surprising:

scala> case class C[T]()
defined class C

scala> def f[T](x: C[T] = C()) = 0
f: [T](x: C[T])Int

scala> f[String]()
<console>:13: error: type mismatch;
 found   : C[Nothing]
 required: C[String]
Note: Nothing <: String, but class C is invariant in type T.
You may wish to define T as +T instead. (SLS 4.5)
Error occurred in an application involving default arguments.
       f[String]()
        ^

@TomasMikula
Copy link
Author

Thanks for the explanation. The feature seems a little odd. I wonder if it has a good use (the example from the spec is not very useful).

@SethTisue
Copy link
Member

if (in 2.13.0-M5 or 2.13.x HEAD) there's still an issue here that deserves a ticket, please open one in scala/bug

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

3 participants