Skip to content

Commit 45cc74e

Browse files
committed
Only add () to calls of nullary methods if they come from Java or Scala2
Follows the scheme outlined in scala#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 675d35e commit 45cc74e

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
@@ -1201,7 +1201,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
12011201
// necessary to force annotation trees to be computed.
12021202
sym.annotations.foreach(_.ensureCompleted)
12031203
lazy val annotCtx = {
1204-
val c = ctx.outersIterator.dropWhile(_.owner == sym).next
1204+
val c = ctx.outersIterator.dropWhile(_.owner == sym).next()
12051205
c.property(ExprOwner) match {
12061206
case Some(exprOwner) if c.owner.isClass =>
12071207
// We need to evaluate annotation arguments in an expression context, since
@@ -1736,7 +1736,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
17361736
def tryAlternatively[T](op1: Context => T)(op2: Context => T)(implicit ctx: Context): T =
17371737
tryEither(op1) { (failedVal, failedState) =>
17381738
tryEither(op2) { (_, _) =>
1739-
failedState.commit
1739+
failedState.commit()
17401740
failedVal
17411741
}
17421742
}
@@ -1857,9 +1857,10 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
18571857

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

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

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

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

0 commit comments

Comments
 (0)