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

Compilation error invoking overloaded function with explicit type parameter #10074

Open
scabug opened this Issue Nov 21, 2016 · 7 comments

Comments

Projects
None yet
1 participant
@scabug
Copy link

scabug commented Nov 21, 2016

Trying to compile specified file results an error:
[error] The argument types of an anonymous function must be fully known. (SLS 8.5)
[error] Expected type was: ?
[error] a.overloadedF[Int]{

If you omit type parameter in method invocation or remove second overloaded function, everything works fine.

@scabug

This comment has been minimized.

Copy link

scabug commented Nov 21, 2016

Imported From: https://issues.scala-lang.org/browse/SI-10074?orig=1
Reporter: Kirill Yankov (manonthegithub)
Affected Versions: 2.11.8, 2.12.0
See #9386
Attachments:

@scabug

This comment has been minimized.

Copy link

scabug commented Nov 21, 2016

@SethTisue said:
minimized:

object A {
  f[Int]{case _ => 1}
  def f[T](f: Any => T) = ()
  def f[T](f: Any => T, v: Int) = ()
}
@scabug

This comment has been minimized.

Copy link

scabug commented Nov 21, 2016

@SethTisue said:
If there's a bug here, is it that the version with the explicit type does compile, or is it that the version without the explicit type doesn't compile? I'd need to go over SLS 6.26 with a fine-tooth comb (along with SLS 8.5 which is mentioned in the error).

@scabug

This comment has been minimized.

Copy link

scabug commented Nov 21, 2016

@som-snytt said:
I expected the shape test to allow arg typed with expected type, as if not overloaded.

But the behavior has history on its side.

$ scala29
Welcome to Scala version 2.9.3 (OpenJDK 64-Bit Server VM, Java 1.6.0_38).
Type in expressions to have them evaluated.
Type :help for more information.

scala> object Y {
     |   def f[A](g: PartialFunction[Any, A]): A = g(42)
     |   def f[A](i: Int, g: PartialFunction[Any, A]): A = g(i)
     | }
defined module Y

scala> Y.f { case _ => 17 }
res0: Int = 17

scala> Y.f[Int] { case _ => 17 }
<console>:9: error: missing parameter type for expanded function
The argument types of an anonymous function must be fully known. (SLS 8.5)
Expected type was: ?
              Y.f[Int] { case _ => 17 }
                       ^
<console>:9: error: overloaded method value f with alternatives:
  (i: Int,g: PartialFunction[Any,Int])Int <and>
  (g: PartialFunction[Any,Int])Int
 cannot be applied to (<error> => Int)
              Y.f[Int] { case _ => 17 }
                 ^

@scabug

This comment has been minimized.

Copy link

scabug commented Nov 21, 2016

@som-snytt said:
Maybe too much typechecking happens during shape test. Linking another example of mechanics of overload resolution affecting the result.

@scabug

This comment has been minimized.

Copy link

scabug commented Nov 22, 2016

@retronym said (edited on Nov 22, 2016 12:15:23 AM UTC):
Looks like an oversight in the implementation to me. Typer::preSelectOverloaded is responsible for filtering out alternatives based on arity (also based on the "shape type" of function literal arguments), but this is bypassed in this case.

      def preSelectOverloaded(fun: Tree): Tree = {
        if (fun.hasSymbolField && fun.symbol.isOverloaded) {

We have:

fun = A.this.f[Int] / TypeApply(Select(...., f), TypeTree(Int))
fun.hasSymbolField = false
fun.tpe = OverloadedType((f: Any => Int, v: Int)Unit <and> (f: Any => Int)Unit)
fun.fun.symbol.info = [T](f: Any => T, v: Int)Unit <and> (f: Any => T)Unit

After filtering, we can end up with a new symbol: either a single method symbol, or a new overloaded symbol with fewer alternatives. This needs to be assigned back to the tree fun. We can't just assign

The fix is conceptually easy enough ("generalize that code a little!") but there are a lot of details to line up. I took a hacky attempt at it : https://github.com/scala/scala/compare/2.12.x...retronym:ticket/10074?expand=1

but I'm not planning to pursue this right now.

@scabug

This comment has been minimized.

Copy link

scabug commented Nov 22, 2016

Kirill Yankov (manonthegithub) said (edited on Nov 22, 2016 4:20:34 PM UTC):
I don't know the specifics if this is the same place in code or not, but overloading with curried params results the same problem, regardless of using or omitting type parameter...

object A{

  fun[Int]{
    case _ => 1
  }

  def fun[T](f: PartialFunction[Any, T]): T = {
    f(1)
  }

  def fun[T](v: Int)(f: PartialFunction[Any, T]) = {
    f(v)
  }

}

@scabug scabug added this to the Backlog milestone Apr 7, 2017

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