Skip to content

Commit 30ac9e2

Browse files
committed
Partial fix for #1731 by fixing error message for overloaded method without return type
1 parent 3bfe849 commit 30ac9e2

File tree

6 files changed

+49
-19
lines changed

6 files changed

+49
-19
lines changed

compiler/src/dotty/tools/dotc/core/Contexts.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ object Contexts {
126126
protected def sstate_=(sstate: SettingsState) = _sstate = sstate
127127
def sstate: SettingsState = _sstate
128128

129-
/** The current tree */
129+
/** The current compilation unit */
130130
private[this] var _compilationUnit: CompilationUnit = _
131131
protected def compilationUnit_=(compilationUnit: CompilationUnit) = _compilationUnit = compilationUnit
132132
def compilationUnit: CompilationUnit = _compilationUnit

compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1209,20 +1209,29 @@ object messages {
12091209
|""".stripMargin
12101210
}
12111211

1212-
case class OverloadedOrRecursiveMethodNeedsResultType(tree: Names.TermName)(implicit ctx: Context)
1212+
case class OverloadedOrRecursiveMethodNeedsResultType private (termName: String)(implicit ctx: Context)
12131213
extends Message(OverloadedOrRecursiveMethodNeedsResultTypeID) {
12141214
val kind = "Syntax"
1215-
val msg = hl"""overloaded or recursive method ${tree} needs return type"""
1215+
val msg = hl"""overloaded or recursive method $termName needs return type"""
12161216
val explanation =
1217-
hl"""Case 1: ${tree} is overloaded
1218-
|If there are multiple methods named `${tree.name}` and at least one definition of
1217+
hl"""Case 1: $termName is overloaded
1218+
|If there are multiple methods named `$termName` and at least one definition of
12191219
|it calls another, you need to specify the calling method's return type.
12201220
|
1221-
|Case 2: ${tree} is recursive
1222-
|If `${tree.name}` calls itself on any path, you need to specify its return type.
1221+
|Case 2: $termName is recursive
1222+
|If `$termName` calls itself on any path, you need to specify its return type.
12231223
|""".stripMargin
12241224
}
12251225

1226+
object OverloadedOrRecursiveMethodNeedsResultType {
1227+
@specialized def apply[T >: Trees.Untyped](tree: NameTree[T])(implicit ctx: Context)
1228+
: OverloadedOrRecursiveMethodNeedsResultType =
1229+
OverloadedOrRecursiveMethodNeedsResultType(tree.name.toString)(ctx)
1230+
def apply(symbol: Symbol)(implicit ctx: Context)
1231+
: OverloadedOrRecursiveMethodNeedsResultType =
1232+
OverloadedOrRecursiveMethodNeedsResultType(symbol.name.toString)(ctx)
1233+
}
1234+
12261235
case class RecursiveValueNeedsResultType(tree: Names.TermName)(implicit ctx: Context)
12271236
extends Message(RecursiveValueNeedsResultTypeID) {
12281237
val kind = "Syntax"
@@ -1320,7 +1329,8 @@ object messages {
13201329
|"""
13211330
}
13221331

1323-
case class MethodDoesNotTakeParameters(tree: tpd.Tree, methPartType: Types.Type)(err: typer.ErrorReporting.Errors)(implicit ctx: Context)
1332+
case class MethodDoesNotTakeParameters(tree: tpd.Tree, methPartType: Types.Type)
1333+
(err: typer.ErrorReporting.Errors)(implicit ctx: Context)
13241334
extends Message(MethodDoesNotTakeParametersId) {
13251335
private val more = tree match {
13261336
case Apply(_, _) => " more"

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ object ErrorReporting {
3232
if (cx.mode is Mode.InferringReturnType) {
3333
cx.tree match {
3434
case tree: untpd.DefDef if !tree.tpt.typeOpt.exists =>
35-
OverloadedOrRecursiveMethodNeedsResultType(tree.name)
35+
OverloadedOrRecursiveMethodNeedsResultType(tree)
3636
case tree: untpd.ValDef if !tree.tpt.typeOpt.exists =>
3737
RecursiveValueNeedsResultType(tree.name)
3838
case _ =>

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ object ProtoTypes {
4848

4949
private def disregardProto(pt: Type)(implicit ctx: Context): Boolean = pt.dealias match {
5050
case _: OrType => true
51-
case pt => pt.isRef(defn.UnitClass)
51+
case ptd => ptd.isRef(defn.UnitClass)
5252
}
5353

5454
/** Check that the result type of the current method

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1872,8 +1872,6 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
18721872
*/
18731873
def adaptInterpolated(tree: Tree, pt: Type, original: untpd.Tree)(implicit ctx: Context): Tree = {
18741874

1875-
assert(pt.exists)
1876-
18771875
def methodStr = err.refStr(methPart(tree).tpe)
18781876

18791877
def missingArgs(mt: MethodType) = {
@@ -1929,7 +1927,13 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
19291927
else
19301928
tree
19311929
case _ => tryInsertApplyOrImplicit(tree, pt) {
1932-
errorTree(tree, MethodDoesNotTakeParameters(tree, methPart(tree).tpe)(err))
1930+
pt.resType match {
1931+
case IgnoredProto(WildcardType(optBounds))
1932+
if (optBounds == NoType) && (pt.args.size == tree.productArity) =>
1933+
errorTree(tree, OverloadedOrRecursiveMethodNeedsResultType(tree.symbol))
1934+
case resType =>
1935+
errorTree(tree, MethodDoesNotTakeParameters(tree, methPart(tree).tpe)(err))
1936+
}
19331937
}
19341938
}
19351939

compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ class ErrorMessagesTests extends ErrorMessagesTest {
200200
assertTrue("expected trait", isTrait)
201201
}
202202

203-
@Test def overloadedMethodNeedsReturnType =
203+
@Test def overloadedMethodNeedsReturnType = {
204204
checkMessagesAfter("frontend") {
205205
"""
206206
|class Scope() {
@@ -214,9 +214,25 @@ class ErrorMessagesTests extends ErrorMessagesTest {
214214
val defn = ictx.definitions
215215

216216
assertMessageCount(1, messages)
217-
val OverloadedOrRecursiveMethodNeedsResultType(tree) :: Nil = messages
218-
assertEquals("foo", tree.show)
219-
}
217+
val OverloadedOrRecursiveMethodNeedsResultType(treeName) :: Nil = messages
218+
assertEquals("foo", treeName)
219+
}
220+
221+
//The following test is disabled (may be running in an unsupported phase)
222+
//
223+
// checkMessagesAfter("frontend") {
224+
// """
225+
// |case class Foo[T](x: T)
226+
// |object Foo { def apply[T]() = Foo(null.asInstanceOf[T]) }
227+
// """.stripMargin
228+
// }.expect { (ictx, messages) =>
229+
// implicit val ctx: Context = ictx
230+
//
231+
// assertMessageCount(1, messages)
232+
// val OverloadedOrRecursiveMethodNeedsResultType(treeName2) :: Nil = messages
233+
// assertEquals("Foo", treeName2)
234+
// }
235+
}
220236

221237
@Test def recursiveMethodNeedsReturnType =
222238
checkMessagesAfter("frontend") {
@@ -231,8 +247,8 @@ class ErrorMessagesTests extends ErrorMessagesTest {
231247
val defn = ictx.definitions
232248

233249
assertMessageCount(1, messages)
234-
val OverloadedOrRecursiveMethodNeedsResultType(tree) :: Nil = messages
235-
assertEquals("i", tree.show)
250+
val OverloadedOrRecursiveMethodNeedsResultType(treeName) :: Nil = messages
251+
assertEquals("i", treeName)
236252
}
237253

238254
@Test def recursiveValueNeedsReturnType =

0 commit comments

Comments
 (0)