summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@typesafe.com>2016-02-04 15:26:57 -0800
committerAdriaan Moors <adriaan.moors@typesafe.com>2016-03-26 09:32:44 -0700
commit0d89ab1fe4adfe7165a2e3812d76dbb586c79798 (patch)
tree5db2839738954b9d020676b788cfd8979b5b487f
parent236d0e0db8b4c53837bd580e2b2022d86afde456 (diff)
downloadscala-0d89ab1fe4adfe7165a2e3812d76dbb586c79798.tar.gz
scala-0d89ab1fe4adfe7165a2e3812d76dbb586c79798.tar.bz2
scala-0d89ab1fe4adfe7165a2e3812d76dbb586c79798.zip
SI-9449 sam expansion for explicitly eta-expanded method
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala12
-rw-r--r--test/files/pos/t9449.scala19
2 files changed, 29 insertions, 2 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 383953f27e..5a62c32d2e 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -2908,6 +2908,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
* (a => a): MyFun
*
* Note that the arity of the sam must correspond to the arity of the function.
+ * TODO: handle vararg sams?
*/
val ptNorm =
if (sam.exists && sameLength(sam.info.params, fun.vparams)) samToFunctionType(pt, sam)
@@ -4407,6 +4408,13 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
tp
}
+ def expectingFunctionMatchingFormals(formals: List[Symbol]) =
+ isFunctionType(pt) || {
+ val sam = samOf(pt)
+ // TODO: handle vararg sam here and in typedFunction
+ sam.exists && sameLength(sam.info.params, formals)
+ }
+
def typedEta(expr1: Tree): Tree = expr1.tpe match {
case TypeRef(_, ByNameParamClass, _) =>
val expr2 = Function(List(), expr1) setPos expr1.pos
@@ -4417,10 +4425,10 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
new ChangeOwnerTraverser(context.owner, expr2.symbol).traverse(expr2)
typed1(expr2, mode, pt)
case PolyType(_, MethodType(formals, _)) =>
- if (isFunctionType(pt)) expr1
+ if (expectingFunctionMatchingFormals(formals)) expr1
else adapt(expr1, mode, functionTypeWildcard(expr1, formals.length))
case MethodType(formals, _) =>
- if (isFunctionType(pt)) expr1
+ if (expectingFunctionMatchingFormals(formals)) expr1
else adapt(expr1, mode, functionTypeWildcard(expr1, formals.length))
case ErrorType =>
expr1
diff --git a/test/files/pos/t9449.scala b/test/files/pos/t9449.scala
new file mode 100644
index 0000000000..06653cca83
--- /dev/null
+++ b/test/files/pos/t9449.scala
@@ -0,0 +1,19 @@
+trait II {
+ def apply(x: Int): Int
+}
+
+object Test {
+ def ii(x: Int): Int = x
+ def test = {
+ val ii1: II = x => ii(x) // works
+ val ii2: II = ii // works (adapting `ii` to `II`)
+ val ii3: II = ii _ // fails -- should work
+ // typedTyped({ii : (() => <empty>)})
+ // typedEta(ii, pt = II)
+ // adapt(ii, pt = (? => ?))
+ // instantiatedToMethodType(ii, pt = (? => ?))
+ // val ii3: II = ii _ // error:
+ // found : Int => Int
+ // required: II
+ }
+} \ No newline at end of file