Skip to content

Commit a2d0d4a

Browse files
committed
Fix #1503: try select when encountering MethodType in simpleApply
1 parent 61ae7dc commit a2d0d4a

File tree

1 file changed

+23
-15
lines changed

1 file changed

+23
-15
lines changed

src/dotty/tools/dotc/typer/Applications.scala

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -574,11 +574,19 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
574574
new ApplyToUntyped(tree, fun1, funRef, proto, pt)(argCtx(tree))
575575
convertNewGenericArray(ConstFold(app.result))
576576
case mt: MethodType =>
577-
val applyVal = untpd.ValDef(ctx.freshName("applyVal").toTermName, untpd.TypeTree(), tree.fun)
578-
val valBlock =
579-
untpd.Block(applyVal :: Nil, untpd.Apply(untpd.Ident(applyVal.name), tree.args))
580-
581-
typed(valBlock, pt)
577+
/**
578+
* Fixes i1503:
579+
* {{{
580+
* (new Function0[Unit] {
581+
* def apply() = println("hello")
582+
* })()
583+
* }}}
584+
*
585+
* Will get a weird shape that results in a MethodType being
586+
* inferred instead of a TermRef, to solve this we'll try to type
587+
* it as an Apply with a Select.
588+
*/
589+
typedApply(untpd.Apply(untpd.Select(tree.fun, nme.apply), tree.args), pt)
582590
case _ =>
583591
handleUnexpectedFunType(tree, fun1)
584592
}
@@ -607,16 +615,16 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
607615
case _ =>
608616
tryEither {
609617
implicit ctx => simpleApply(fun1, proto)
610-
} {
611-
(failedVal, failedState) =>
612-
def fail = { failedState.commit(); failedVal }
613-
// Try once with original prototype and once (if different) with tupled one.
614-
// The reason we need to try both is that the decision whether to use tupled
615-
// or not was already taken but might have to be revised when an implicit
616-
// is inserted on the qualifier.
617-
tryWithImplicitOnQualifier(fun1, originalProto).getOrElse(
618-
if (proto eq originalProto) fail
619-
else tryWithImplicitOnQualifier(fun1, proto).getOrElse(fail))
618+
} { (failedVal, failedState) =>
619+
def fail = { failedState.commit(); failedVal }
620+
// Try once with original prototype and once (if different) with tupled one.
621+
// The reason we need to try both is that the decision whether to use tupled
622+
// or not was already taken but might have to be revised when an implicit
623+
// is inserted on the qualifier.
624+
tryWithImplicitOnQualifier(fun1, originalProto) getOrElse {
625+
if (proto eq originalProto) fail
626+
else tryWithImplicitOnQualifier(fun1, proto).getOrElse(fail)
627+
}
620628
}
621629
}
622630
}

0 commit comments

Comments
 (0)