From 62c0c8d86b85af082a9fe695d4a8fd95a133e059 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sat, 14 Nov 2020 11:51:58 +0100 Subject: [PATCH] Fix #10016: Bypass normalize for context function closure arguments Do not widen to their result type if expected type is again a context function --- compiler/src/dotty/tools/dotc/typer/Applications.scala | 4 +++- compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala | 3 ++- tests/run/i10016.scala | 5 +++++ 3 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 tests/run/i10016.scala diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala index 639e04e25415..47626459f90a 100644 --- a/compiler/src/dotty/tools/dotc/typer/Applications.scala +++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala @@ -677,7 +677,9 @@ trait Applications extends Compatibility { */ class ApplicableToTrees(methRef: TermRef, args: List[Tree], resultType: Type)(using Context) extends TestApplication(methRef, methRef.widen, args, resultType) { - def argType(arg: Tree, formal: Type): Type = normalize(arg.tpe, formal) + def argType(arg: Tree, formal: Type): Type = + if untpd.isContextualClosure(arg) && defn.isContextFunctionType(formal) then arg.tpe + else normalize(arg.tpe, formal) def treeToArg(arg: Tree): Tree = arg def isVarArg(arg: Tree): Boolean = tpd.isWildcardStarArg(arg) def typeOfArg(arg: Tree): Type = arg.tpe diff --git a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala index 71d99a210f7d..b4bd727d7063 100644 --- a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala +++ b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala @@ -630,7 +630,8 @@ object ProtoTypes { normalize(et.resultType, pt) case wtp => val iftp = defn.asContextFunctionType(wtp) - if (iftp.exists) normalize(iftp.dropDependentRefinement.argInfos.last, pt) else tp + if iftp.exists then normalize(iftp.dropDependentRefinement.argInfos.last, pt) + else tp } } diff --git a/tests/run/i10016.scala b/tests/run/i10016.scala new file mode 100644 index 000000000000..0b64e1eebb49 --- /dev/null +++ b/tests/run/i10016.scala @@ -0,0 +1,5 @@ +def f(init: Int ?=> Int) : Int = 1 +def f(s: String)(init: Int ?=> Int) : Int = 2 + +@main def Test() = + assert(f((using x:Int) => x) == 1)