From 0d89ab1fe4adfe7165a2e3812d76dbb586c79798 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Thu, 4 Feb 2016 15:26:57 -0800 Subject: SI-9449 sam expansion for explicitly eta-expanded method --- src/compiler/scala/tools/nsc/typechecker/Typers.scala | 12 ++++++++++-- test/files/pos/t9449.scala | 19 +++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 test/files/pos/t9449.scala 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 : (() => )}) + // 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 -- cgit v1.2.3