Skip to content

Commit f3c6d91

Browse files
committed
Only add () to calls of nullary methods if they come from Java or Scala2
Follows the scheme outlined in #2570. The reason not to flag bad calls to methods compiled from Scala 2 is that some Scala 2 libraries are not yet in a form where the parentheses are as they should be. For instance def isWhole() in some of the numeric libraries should not have the ().
1 parent 244257b commit f3c6d91

File tree

1 file changed

+30
-12
lines changed

1 file changed

+30
-12
lines changed

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

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1202,7 +1202,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
12021202
// necessary to force annotation trees to be computed.
12031203
sym.annotations.foreach(_.ensureCompleted)
12041204
lazy val annotCtx = {
1205-
val c = ctx.outersIterator.dropWhile(_.owner == sym).next
1205+
val c = ctx.outersIterator.dropWhile(_.owner == sym).next()
12061206
c.property(ExprOwner) match {
12071207
case Some(exprOwner) if c.owner.isClass =>
12081208
// We need to evaluate annotation arguments in an expression context, since
@@ -1737,7 +1737,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
17371737
def tryAlternatively[T](op1: Context => T)(op2: Context => T)(implicit ctx: Context): T =
17381738
tryEither(op1) { (failedVal, failedState) =>
17391739
tryEither(op2) { (_, _) =>
1740-
failedState.commit
1740+
failedState.commit()
17411741
failedVal
17421742
}
17431743
}
@@ -1858,9 +1858,10 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
18581858

18591859
def methodStr = err.refStr(methPart(tree).tpe)
18601860

1861-
def missingArgs = errorTree(tree,
1862-
em"""missing arguments for $methodStr
1863-
|follow this method with `_' if you want to treat it as a partially applied function""")
1861+
def missingArgs(mt: MethodType) = {
1862+
ctx.error(em"missing arguments for $methodStr", tree.pos)
1863+
tree.withType(mt.resultType)
1864+
}
18641865

18651866
def adaptOverloaded(ref: TermRef) = {
18661867
val altDenots = ref.denot.alternatives
@@ -2040,6 +2041,22 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
20402041
def isExpandableApply =
20412042
defn.isImplicitFunctionClass(tree.symbol.maybeOwner) && defn.isFunctionType(ptNorm)
20422043

2044+
/** Is reference to this symbol `f` automatically expanded to `f()`? */
2045+
def isAutoApplied(sym: Symbol): Boolean = {
2046+
def test(sym1: Symbol) =
2047+
sym1.is(JavaDefined) ||
2048+
sym1.owner == defn.AnyClass ||
2049+
sym1 == defn.Object_clone
2050+
sym.isConstructor ||
2051+
test(sym) ||
2052+
sym.allOverriddenSymbols.exists(test) ||
2053+
sym.owner.is(Scala2x) || // need to exclude Scala-2 compiled symbols for now, since the
2054+
// Scala library does not always follow the right conventions.
2055+
// Examples are: isWhole(), toInt(), toDouble() in BigDecimal, Numeric, RichInt, ScalaNumberProxy.
2056+
ctx.testScala2Mode(em"${sym.showLocated} requires () argument", tree.pos,
2057+
patch(tree.pos.endPos, "()"))
2058+
}
2059+
20432060
// Reasons NOT to eta expand:
20442061
// - we reference a constructor
20452062
// - we are in a patterm
@@ -2049,12 +2066,12 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
20492066
!ctx.mode.is(Mode.Pattern) &&
20502067
!(isSyntheticApply(tree) && !isExpandableApply))
20512068
typed(etaExpand(tree, wtp, arity), pt)
2052-
else if (wtp.paramInfos.isEmpty)
2069+
else if (wtp.paramInfos.isEmpty && isAutoApplied(tree.symbol))
20532070
adaptInterpolated(tpd.Apply(tree, Nil), pt, EmptyTree)
20542071
else if (wtp.isImplicit)
20552072
err.typeMismatch(tree, pt)
20562073
else
2057-
missingArgs
2074+
missingArgs(wtp)
20582075
case _ =>
20592076
ctx.typeComparer.GADTused = false
20602077
if (defn.isImplicitFunctionClass(wtp.underlyingClassRef(refinementOK = false).classSymbol) &&
@@ -2093,11 +2110,12 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
20932110
else
20942111
tree
20952112
}
2096-
else if (wtp.isInstanceOf[MethodType]) missingArgs
2097-
else {
2098-
typr.println(i"adapt to subtype ${tree.tpe} !<:< $pt")
2099-
//typr.println(TypeComparer.explained(implicit ctx => tree.tpe <:< pt))
2100-
adaptToSubType(wtp)
2113+
else wtp match {
2114+
case wtp: MethodType => missingArgs(wtp)
2115+
case _ =>
2116+
typr.println(i"adapt to subtype ${tree.tpe} !<:< $pt")
2117+
//typr.println(TypeComparer.explained(implicit ctx => tree.tpe <:< pt))
2118+
adaptToSubType(wtp)
21012119
}
21022120
}
21032121
/** Adapt an expression of constant type to a different constant type `tpe`. */

0 commit comments

Comments
 (0)