Skip to content

Commit 56985d7

Browse files
committed
Fix #6190: eta-expand companion object if functions are expected
1 parent 121ced4 commit 56985d7

File tree

2 files changed

+9
-31
lines changed

2 files changed

+9
-31
lines changed

compiler/src/dotty/tools/dotc/ast/Desugar.scala

Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -676,28 +676,8 @@ object desugar {
676676
mods.is(Private) || (!mods.is(Protected) && mods.hasPrivateWithin)
677677
}
678678

679-
/** Does one of the parameter's types (in the first param clause)
680-
* mention a preceding parameter?
681-
*/
682-
def isParamDependent = constrVparamss match
683-
case vparams :: _ =>
684-
val paramNames = vparams.map(_.name).toSet
685-
vparams.exists(_.tpt.existsSubTree {
686-
case Ident(name: TermName) => paramNames.contains(name)
687-
case _ => false
688-
})
689-
case _ => false
690-
691-
val companionParent =
692-
if constrTparams.nonEmpty
693-
|| constrVparamss.length > 1
694-
|| mods.is(Abstract)
695-
|| restrictedAccess
696-
|| isParamDependent
697-
|| isEnumCase
698-
then anyRef
699-
else
700-
constrVparamss.foldRight(classTypeRef)((vparams, restpe) => Function(vparams map (_.tpt), restpe))
679+
def widenedCreatorExpr =
680+
widenDefs.foldLeft(creatorExpr)((rhs, meth) => Apply(Ident(meth.name), rhs :: Nil))
701681
val applyMeths =
702682
if (mods.is(Abstract)) Nil
703683
else {
@@ -727,7 +707,7 @@ object desugar {
727707
val toStringMeth =
728708
DefDef(nme.toString_, Nil, Nil, TypeTree(), Literal(Constant(className.toString))).withMods(Modifiers(Override | Synthetic))
729709

730-
companionDefs(companionParent, applyMeths ::: unapplyMeth :: toStringMeth :: companionMembers)
710+
companionDefs(anyRef, applyMeths ::: unapplyMeth :: toStringMeth :: companionMembers)
731711
}
732712
else if (companionMembers.nonEmpty || companionDerived.nonEmpty || isEnum)
733713
companionDefs(anyRef, companionMembers)

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3222,9 +3222,6 @@ class Typer extends Namer
32223222
* Examples for these cases are found in run/implicitFuns.scala and neg/i2006.scala.
32233223
*/
32243224
def adaptNoArgsUnappliedMethod(wtp: MethodType, functionExpected: Boolean, arity: Int): Tree = {
3225-
def isExpandableApply =
3226-
defn.isContextFunctionClass(tree.symbol.maybeOwner) && functionExpected
3227-
32283225
/** Is reference to this symbol `f` automatically expanded to `f()`? */
32293226
def isAutoApplied(sym: Symbol): Boolean =
32303227
sym.isConstructor
@@ -3241,7 +3238,7 @@ class Typer extends Namer
32413238
!tree.symbol.isConstructor &&
32423239
!tree.symbol.isAllOf(InlineMethod) &&
32433240
!ctx.mode.is(Mode.Pattern) &&
3244-
!(isSyntheticApply(tree) && !isExpandableApply)) {
3241+
!(isSyntheticApply(tree) && !functionExpected)) {
32453242
if (!defn.isFunctionType(pt))
32463243
pt match {
32473244
case SAMType(_) if !pt.classSymbol.hasAnnotation(defn.FunctionalInterfaceAnnot) =>
@@ -3266,9 +3263,10 @@ class Typer extends Namer
32663263
defn.isContextFunctionClass(underlying.classSymbol)
32673264
}
32683265

3269-
def adaptNoArgsOther(wtp: Type): Tree = {
3270-
if (isContextFunctionRef(wtp) &&
3271-
!untpd.isContextualClosure(tree) &&
3266+
def adaptNoArgsOther(wtp: Type, functionExpected: Boolean): Tree = {
3267+
val implicitFun = isImplicitFunctionRef(wtp) && !untpd.isContextualClosure(tree)
3268+
def caseCompanion = functionExpected && tree.symbol.is(Module) && tree.symbol.companionClass.is(Case)
3269+
if ((implicitFun || caseCompanion) &&
32723270
!isApplyProto(pt) &&
32733271
pt != AssignProto &&
32743272
!ctx.mode.is(Mode.Pattern) &&
@@ -3390,7 +3388,7 @@ class Typer extends Namer
33903388
}
33913389
adaptNoArgsUnappliedMethod(wtp, funExpected, arity)
33923390
case _ =>
3393-
adaptNoArgsOther(wtp)
3391+
adaptNoArgsOther(wtp, functionExpected)
33943392
}
33953393
}
33963394

0 commit comments

Comments
 (0)