diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala index 4f87d0741be3..2d30b925a7eb 100644 --- a/compiler/src/dotty/tools/dotc/typer/Applications.scala +++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala @@ -2101,7 +2101,11 @@ trait Applications extends Compatibility { else defn.FunctionOf(commonParamTypes, WildcardType) overload.println(i"pretype arg $arg with expected type $commonFormal") if (commonParamTypes.forall(isFullyDefined(_, ForceDegree.flipBottom))) - withMode(Mode.ImplicitsEnabled)(pt.typedArg(arg, commonFormal)) + withMode(Mode.ImplicitsEnabled) { + // We can cache the adapted argument here because the expected type + // is a common type shared by all overloading candidates. + pt.cacheArg(arg, pt.typedArg(arg, commonFormal)) + } } recur(altFormals.map(_.tail), args1) case _ => diff --git a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala index 0d2c60c677b0..bc479b51b052 100644 --- a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala +++ b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala @@ -424,6 +424,10 @@ object ProtoTypes { if (t == null) NoType else t.tpe } + /** Cache the typed argument */ + def cacheArg(arg: untpd.Tree, targ: Tree) = + state.typedArg = state.typedArg.updated(arg, targ) + /** The same proto-type but with all arguments combined in a single tuple */ def tupledDual: FunProto = state.tupledDual match { case pt: FunProto => diff --git a/tests/pos/i11185.scala b/tests/pos/i11185.scala new file mode 100644 index 000000000000..3b4a308bbc9e --- /dev/null +++ b/tests/pos/i11185.scala @@ -0,0 +1,14 @@ +class Test: + def foo(a: Int, b: Int) = a + b + + Map(1 -> 2).map(foo _) + Map(1 -> 2).map(foo) + +class Test2: + def foo(a: Int, b: Int) = a + b + + def bar(f: ((Int, Int)) => Int) = "ok" + def bar(f: ((Int, Int)) => String)(using Int) = "ok" + + bar(foo) + bar(foo _)