@@ -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`,
@@ -3699,6 +3702,16 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
3699
3702
|| Feature .warnOnMigration(MissingEmptyArgumentList (sym.show), tree.srcPos, version = `3.0`)
3700
3703
&& { patch(tree.span.endPos, " ()" ); true }
3701
3704
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
+
3702
3715
// Reasons NOT to eta expand:
3703
3716
// - we reference a constructor
3704
3717
// - we reference a typelevel method
@@ -3710,13 +3723,18 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
3710
3723
&& ! ctx.mode.is(Mode .Pattern )
3711
3724
&& ! (isSyntheticApply(tree) && ! functionExpected)
3712
3725
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)
3720
3738
else if (wtp.paramInfos.isEmpty && isAutoApplied(tree.symbol))
3721
3739
readaptSimplified(tpd.Apply (tree, Nil ))
3722
3740
else if (wtp.isImplicitMethod)
@@ -3825,11 +3843,9 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
3825
3843
def adaptNoArgs (wtp : Type ): Tree = {
3826
3844
val ptNorm = underlyingApplied(pt)
3827
3845
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
3831
3848
case _ => true
3832
- }
3833
3849
var resMatch : Boolean = false
3834
3850
wtp match {
3835
3851
case wtp : ExprType =>
@@ -3846,17 +3862,16 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
3846
3862
case wtp : MethodType if needsEta =>
3847
3863
val funExpected = functionExpected
3848
3864
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
3851
3867
// if method type is fully defined, but expected type is not,
3852
3868
// prioritize method parameter types as parameter types of the eta-expanded closure
3853
3869
0
3854
3870
else defn.functionArity(ptNorm)
3855
- else {
3871
+ else
3856
3872
val nparams = wtp.paramInfos.length
3857
- if ( nparams > 0 || pt.eq(AnyFunctionProto )) nparams
3873
+ if nparams > 0 || pt.eq(AnyFunctionProto ) then nparams
3858
3874
else - 1 // no eta expansion in this case
3859
- }
3860
3875
adaptNoArgsUnappliedMethod(wtp, funExpected, arity)
3861
3876
case _ =>
3862
3877
adaptNoArgsOther(wtp, functionExpected)
0 commit comments