@@ -614,6 +614,9 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
614614 if selName.isTypeName then checkStable(qual.tpe, qual.srcPos, " type prefix" )
615615 checkLegalValue(select, pt)
616616 ConstFold (select)
617+ else if selName == nme.apply && qual.tpe.widen.isInstanceOf [MethodType ] then
618+ // Simplify `m.apply(...)` to `m(...)`
619+ qual
617620 else if couldInstantiateTypeVar(qual.tpe.widen) then
618621 // there's a simply visible type variable in the result; try again with a more defined qualifier type
619622 // There's a second trial where we try to instantiate all type variables in `qual.tpe.widen`,
@@ -3699,6 +3702,16 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
36993702 || Feature .warnOnMigration(MissingEmptyArgumentList (sym.show), tree.srcPos, version = `3.0`)
37003703 && { patch(tree.span.endPos, " ()" ); true }
37013704
3705+ /** If this is a selection prototype of the form `.apply(...): R`, return the nested
3706+ * function prototype `(...)R`. Otherwise `pt`.
3707+ */
3708+ def ptWithoutRedundantApply : Type = pt.revealIgnored match
3709+ case SelectionProto (nme.apply, mpt, _, _) =>
3710+ mpt.revealIgnored match
3711+ case fpt : FunProto => fpt
3712+ case _ => pt
3713+ case _ => pt
3714+
37023715 // Reasons NOT to eta expand:
37033716 // - we reference a constructor
37043717 // - we reference a typelevel method
@@ -3710,13 +3723,18 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
37103723 && ! ctx.mode.is(Mode .Pattern )
37113724 && ! (isSyntheticApply(tree) && ! functionExpected)
37123725 then
3713- if (! defn.isFunctionType(pt))
3714- pt match {
3715- case SAMType (_) if ! pt.classSymbol.hasAnnotation(defn.FunctionalInterfaceAnnot ) =>
3716- report.warning(ex " ${tree.symbol} is eta-expanded even though $pt does not have the @FunctionalInterface annotation. " , tree.srcPos)
3717- case _ =>
3718- }
3719- simplify(typed(etaExpand(tree, wtp, arity), pt), pt, locked)
3726+ val pt1 = ptWithoutRedundantApply
3727+ if pt1 ne pt then
3728+ // Ignore `.apply` in `m.apply(...)`; it will later be simplified in typedSelect to `m(...)`
3729+ adapt1(tree, pt1, locked)
3730+ else
3731+ if (! defn.isFunctionType(pt))
3732+ pt match {
3733+ case SAMType (_) if ! pt.classSymbol.hasAnnotation(defn.FunctionalInterfaceAnnot ) =>
3734+ report.warning(ex " ${tree.symbol} is eta-expanded even though $pt does not have the @FunctionalInterface annotation. " , tree.srcPos)
3735+ case _ =>
3736+ }
3737+ simplify(typed(etaExpand(tree, wtp, arity), pt), pt, locked)
37203738 else if (wtp.paramInfos.isEmpty && isAutoApplied(tree.symbol))
37213739 readaptSimplified(tpd.Apply (tree, Nil ))
37223740 else if (wtp.isImplicitMethod)
@@ -3825,11 +3843,9 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
38253843 def adaptNoArgs (wtp : Type ): Tree = {
38263844 val ptNorm = underlyingApplied(pt)
38273845 def functionExpected = defn.isFunctionType(ptNorm)
3828- def needsEta = pt match {
3829- case _ : SingletonType => false
3830- case IgnoredProto (_ : FunOrPolyProto ) => false
3846+ def needsEta = pt.revealIgnored match
3847+ case _ : SingletonType | _ : FunOrPolyProto => false
38313848 case _ => true
3832- }
38333849 var resMatch : Boolean = false
38343850 wtp match {
38353851 case wtp : ExprType =>
@@ -3846,17 +3862,16 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
38463862 case wtp : MethodType if needsEta =>
38473863 val funExpected = functionExpected
38483864 val arity =
3849- if ( funExpected)
3850- if ( ! isFullyDefined(pt, ForceDegree .none) && isFullyDefined(wtp, ForceDegree .none))
3865+ if funExpected then
3866+ if ! isFullyDefined(pt, ForceDegree .none) && isFullyDefined(wtp, ForceDegree .none) then
38513867 // if method type is fully defined, but expected type is not,
38523868 // prioritize method parameter types as parameter types of the eta-expanded closure
38533869 0
38543870 else defn.functionArity(ptNorm)
3855- else {
3871+ else
38563872 val nparams = wtp.paramInfos.length
3857- if ( nparams > 0 || pt.eq(AnyFunctionProto )) nparams
3873+ if nparams > 0 || pt.eq(AnyFunctionProto ) then nparams
38583874 else - 1 // no eta expansion in this case
3859- }
38603875 adaptNoArgsUnappliedMethod(wtp, funExpected, arity)
38613876 case _ =>
38623877 adaptNoArgsOther(wtp, functionExpected)
0 commit comments