@@ -614,6 +614,9 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
614
614
if selName.isTypeName then checkStable(qual.tpe, qual.srcPos, " type prefix" )
615
615
checkLegalValue(select, pt)
616
616
ConstFold (select)
617
+ else if selName == nme.apply && qual.tpe.widen.isInstanceOf [MethodType ] then
618
+ // Simplify `m.apply(...)` to `m(...)`
619
+ qual
617
620
else if couldInstantiateTypeVar(qual.tpe.widen) then
618
621
// there's a simply visible type variable in the result; try again with a more defined qualifier type
619
622
// There's a second trial where we try to instantiate all type variables in `qual.tpe.widen`,
@@ -3665,6 +3668,16 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
3665
3668
|| Feature .warnOnMigration(MissingEmptyArgumentList (sym.show), tree.srcPos, version = `3.0`)
3666
3669
&& { patch(tree.span.endPos, " ()" ); true }
3667
3670
3671
+ /** If this is a selection prototype of the form `.apply(...): R`, return the nested
3672
+ * function prototype `(...)R`. Otherwise `pt`.
3673
+ */
3674
+ def ptWithoutRedundantApply : Type = pt.revealIgnored match
3675
+ case SelectionProto (nme.apply, mpt, _, _) =>
3676
+ mpt.revealIgnored match
3677
+ case fpt : FunProto => fpt
3678
+ case _ => pt
3679
+ case _ => pt
3680
+
3668
3681
// Reasons NOT to eta expand:
3669
3682
// - we reference a constructor
3670
3683
// - we reference a typelevel method
@@ -3676,13 +3689,18 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
3676
3689
&& ! ctx.mode.is(Mode .Pattern )
3677
3690
&& ! (isSyntheticApply(tree) && ! functionExpected)
3678
3691
then
3679
- if (! defn.isFunctionType(pt))
3680
- pt match {
3681
- case SAMType (_) if ! pt.classSymbol.hasAnnotation(defn.FunctionalInterfaceAnnot ) =>
3682
- report.warning(ex " ${tree.symbol} is eta-expanded even though $pt does not have the @FunctionalInterface annotation. " , tree.srcPos)
3683
- case _ =>
3684
- }
3685
- simplify(typed(etaExpand(tree, wtp, arity), pt), pt, locked)
3692
+ val pt1 = ptWithoutRedundantApply
3693
+ if pt1 ne pt then
3694
+ // Ignore `.apply` in `m.apply(...)`; it will later be simplified in typedSelect to `m(...)`
3695
+ adapt1(tree, pt1, locked)
3696
+ else
3697
+ if (! defn.isFunctionType(pt))
3698
+ pt match {
3699
+ case SAMType (_) if ! pt.classSymbol.hasAnnotation(defn.FunctionalInterfaceAnnot ) =>
3700
+ report.warning(ex " ${tree.symbol} is eta-expanded even though $pt does not have the @FunctionalInterface annotation. " , tree.srcPos)
3701
+ case _ =>
3702
+ }
3703
+ simplify(typed(etaExpand(tree, wtp, arity), pt), pt, locked)
3686
3704
else if (wtp.paramInfos.isEmpty && isAutoApplied(tree.symbol))
3687
3705
readaptSimplified(tpd.Apply (tree, Nil ))
3688
3706
else if (wtp.isImplicitMethod)
@@ -3791,11 +3809,9 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
3791
3809
def adaptNoArgs (wtp : Type ): Tree = {
3792
3810
val ptNorm = underlyingApplied(pt)
3793
3811
def functionExpected = defn.isFunctionType(ptNorm)
3794
- def needsEta = pt match {
3795
- case _ : SingletonType => false
3796
- case IgnoredProto (_ : FunOrPolyProto ) => false
3812
+ def needsEta = pt.revealIgnored match
3813
+ case _ : SingletonType | _ : FunOrPolyProto => false
3797
3814
case _ => true
3798
- }
3799
3815
var resMatch : Boolean = false
3800
3816
wtp match {
3801
3817
case wtp : ExprType =>
@@ -3812,17 +3828,16 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
3812
3828
case wtp : MethodType if needsEta =>
3813
3829
val funExpected = functionExpected
3814
3830
val arity =
3815
- if ( funExpected)
3816
- if ( ! isFullyDefined(pt, ForceDegree .none) && isFullyDefined(wtp, ForceDegree .none))
3831
+ if funExpected then
3832
+ if ! isFullyDefined(pt, ForceDegree .none) && isFullyDefined(wtp, ForceDegree .none) then
3817
3833
// if method type is fully defined, but expected type is not,
3818
3834
// prioritize method parameter types as parameter types of the eta-expanded closure
3819
3835
0
3820
3836
else defn.functionArity(ptNorm)
3821
- else {
3837
+ else
3822
3838
val nparams = wtp.paramInfos.length
3823
- if ( nparams > 0 || pt.eq(AnyFunctionProto )) nparams
3839
+ if nparams > 0 || pt.eq(AnyFunctionProto ) then nparams
3824
3840
else - 1 // no eta expansion in this case
3825
- }
3826
3841
adaptNoArgsUnappliedMethod(wtp, funExpected, arity)
3827
3842
case _ =>
3828
3843
adaptNoArgsOther(wtp, functionExpected)
0 commit comments