-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Change "recursive/cyclic definitions needs type" errors to Message #2049
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
ce333b1
e1e13e9
34e3508
c3ec6df
98465f9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,6 +18,7 @@ import dotc.parsing.Tokens | |
import printing.Highlighting._ | ||
import printing.Formatting | ||
import ErrorMessageID._ | ||
import dotty.tools.dotc.core.SymDenotations.SymDenotation | ||
|
||
object messages { | ||
|
||
|
@@ -1147,7 +1148,7 @@ object messages { | |
} | ||
|
||
case class AnnotatedPrimaryConstructorRequiresModifierOrThis(cls: Name)(implicit ctx: Context) | ||
extends Message(AnnotatedPrimaryConstructorRequiresModifierOrThisID) { | ||
extends Message(AnnotatedPrimaryConstructorRequiresModifierOrThisID) { | ||
val kind = "Syntax" | ||
val msg = hl"""${"private"}, ${"protected"}, or ${"this"} expected for annotated primary constructor""" | ||
val explanation = | ||
|
@@ -1160,4 +1161,53 @@ object messages { | |
| ^^^^ | ||
|""".stripMargin | ||
} | ||
|
||
case class OverloadedMethodNeedsResultType(tree: Names.TermName)(implicit ctx: Context) | ||
extends Message(OverloadedMethodNeedsResultTypeID) { | ||
val kind = "Syntax" | ||
val msg = hl"""overloaded method ${tree} needs result type""" | ||
val explanation = | ||
hl"""|${tree} is overloaded and at least one definition of it calls another. | ||
|You need to specify the calling method's return type. | ||
""".stripMargin | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In this case the method might be overloaded but it could also be simply recursive. So claiming that it is overloaded is false. We might try to find out whether it is overloaded to improve the error message. Essentially, it's overloaded if its owner is a class and taking the member of the name in the owner gives several alternatives. |
||
} | ||
|
||
case class RecursiveMethodNeedsResultType(tree: Names.TermName)(implicit ctx: Context) | ||
extends Message(RecursiveMethodNeedsResultTypeID) { | ||
val kind = "Syntax" | ||
val msg = hl"""recursive method ${tree} needs result type""" | ||
val explanation = | ||
hl"""|The definition of `${tree.name}` is recursive and you need to specify its type. | ||
""".stripMargin | ||
} | ||
|
||
case class RecursiveValueNeedsResultType(tree: Names.TermName)(implicit ctx: Context) | ||
extends Message(RecursiveValueNeedsResultTypeID) { | ||
val kind = "Syntax" | ||
val msg = hl"""recursive value ${tree.name} needs type""" | ||
val explanation = | ||
hl"""|The definition of `${tree.name}` is recursive and you need to specify its type. | ||
""".stripMargin | ||
} | ||
|
||
case class CyclicReferenceInvolving(denot: SymDenotation)(implicit ctx: Context) | ||
extends Message(CyclicReferenceInvolvingID) { | ||
val kind = "Syntax" | ||
val msg = hl"""cyclic reference involving $denot""" | ||
val explanation = | ||
hl"""|$denot is declared as part of a cycle which makes it impossible for the | ||
|compiler to decide upon ${denot.name}'s type. | ||
|""".stripMargin | ||
} | ||
|
||
case class CyclicReferenceInvolvingImplicit(cycleSym: Symbol)(implicit ctx: Context) | ||
extends Message(CyclicReferenceInvolvingImplicitID) { | ||
val kind = "Syntax" | ||
val msg = hl"""cyclic reference involving implicit $cycleSym""" | ||
val explanation = | ||
hl"""|This happens when the right hand-side of $cycleSym's definition involves an implicit search. | ||
|To avoid this error, give `${cycleSym.name}` an explicit type. | ||
|""".stripMargin | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,24 +28,25 @@ object ErrorReporting { | |
|
||
def cyclicErrorMsg(ex: CyclicReference)(implicit ctx: Context) = { | ||
val cycleSym = ex.denot.symbol | ||
def errorMsg(msg: String, cx: Context): String = | ||
def errorMsg(msg: Message, cx: Context): Message = | ||
if (cx.mode is Mode.InferringReturnType) { | ||
cx.tree match { | ||
case tree: untpd.DefDef if !tree.tpt.typeOpt.exists => | ||
em"overloaded or recursive method ${tree.name} needs result type" | ||
// TODO: analysis if tree is an overloaded method (or directly recursive) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this will do the trick:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In that direction was what I tried, but There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do you need There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That is what I get upon calling [error] Test dotty.tools.dotc.reporting.ErrorMessagesTests.recursiveMethodNeedsReturnType failed: java.lang.AssertionError: assertion failed, took 0.01 sec There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It complains that we assign an error type into a tree, yet not errors were reported. Is that stacktrace reached from the call
? If yes, can you show me the full stacktrace up to the call? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here you go: stacktrace.txt There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. According to that stacktrace the error is not caused by the call
That one shows up nowhere. So it most likely happens later. Could it be that an error message is not reported? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The error is triggered by using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the |
||
val overloaded = true | ||
if (overloaded) OverloadedMethodNeedsResultType(tree.name) | ||
else RecursiveMethodNeedsResultType(tree.name) | ||
case tree: untpd.ValDef if !tree.tpt.typeOpt.exists => | ||
em"recursive value ${tree.name} needs type" | ||
RecursiveValueNeedsResultType(tree.name) | ||
case _ => | ||
errorMsg(msg, cx.outer) | ||
} | ||
} else msg | ||
|
||
if (cycleSym.is(Implicit, butNot = Method) && cycleSym.owner.isTerm) | ||
em"""cyclic reference involving implicit $cycleSym | ||
|This happens when the right hand-side of $cycleSym's definition involves an implicit search. | ||
|To avoid the error, give $cycleSym an explicit type.""" | ||
CyclicReferenceInvolvingImplicit(cycleSym) | ||
else | ||
errorMsg(ex.show, ctx) | ||
errorMsg(ex.toMessage, ctx) | ||
} | ||
|
||
def wrongNumberOfTypeArgs(fntpe: Type, expectedArgs: List[TypeParamInfo], actual: List[untpd.Tree], pos: Position)(implicit ctx: Context) = | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a more general question: Why are we using a Java enumeration for this? Would it not be easier to use a
scala.Enumeration
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@felixmulder recently changed from directly specified int constants to this Java enum.