Skip to content

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

Merged
merged 5 commits into from
Mar 9, 2017

Conversation

ennru
Copy link
Contributor

@ennru ennru commented Mar 4, 2017

@odersky
Here are my changes to move the recursive/cyclic definition type required errors to Message.
I hope the explanations make sense.

@@ -52,6 +52,9 @@
MixedLeftAndRightAssociativeOpsID,
CantInstantiateAbstractClassOrTraitID,
AnnotatedPrimaryConstructorRequiresModifierOrThisID,
OverloadedOrRecursiveMethodNeedsResultTypeID,
RecursiveValueNeedsResultTypeID,
CyclicReferenceInvolvingImplicitID,
Copy link
Contributor

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?

Copy link
Contributor Author

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.

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
Copy link
Contributor

Choose a reason for hiding this comment

The 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.

@felixmulder
Copy link
Contributor

felixmulder commented Mar 5, 2017 via email

Split error messages for recursive method and overloaded method needs type into two (but
did not solve the analysis which to show).
Make CyclicReference type error construct corresponding error message.
@ennru
Copy link
Contributor Author

ennru commented Mar 5, 2017

@odersky
I made it two distinct errors "Overloaded method needs result type" and "Recursive method needs result type". But I did not find out how to dig into the owning class' members.

The "cyclic reference involving" from the CyclicReference type error is now a Message.

if (cx.mode is Mode.InferringReturnType) {
cx.tree match {
case tree: untpd.DefDef if !tree.tpt.typeOpt.exists =>
OverloadedOrRecursiveMethodNeedsResultType(tree.name)
// TODO: analysis if tree is an overloaded method (or directly recursive)
Copy link
Contributor

@odersky odersky Mar 5, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this will do the trick:

cycleSym.owner.isClass && cycleSym.owner.info.member(cycleSym.name).isOverloaded

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that direction was what I tried, but member fails in Tree.withType as it encounters an ErrorType.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need Tree.withtype?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is what I get upon calling member(cycleSym.name) - not sure how the code gets there.

[error] Test dotty.tools.dotc.reporting.ErrorMessagesTests.recursiveMethodNeedsReturnType failed: java.lang.AssertionError: assertion failed, took 0.01 sec
[error] at scala.Predef$.assert(Predef.scala:151)
[error] at dotty.tools.dotc.ast.Trees$Tree.withType(Trees.scala:116)
[error] at dotty.tools.dotc.typer.ErrorReporting$.errorTree(ErrorReporting.scala:22)
[error] at dotty.tools.dotc.typer.Typer$$anonfun$typed$2.apply(Typer.scala:1584)
[error] at dotty.tools.dotc.typer.Typer$$anonfun$typed$2.apply(Typer.scala:1582)
[error] at dotty.tools.dotc.reporting.Reporting$class.traceIndented(Reporter.scala:136)
[error] at dotty.tools.dotc.core.Contexts$Context.traceIndented(Contexts.scala:57)
[error] at dotty.tools.dotc.typer.Typer.typed(Typer.scala:1582)
...

Copy link
Contributor

Choose a reason for hiding this comment

The 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

cycleSym.owner.info.member(cycleSym.name).isOverloaded

? If yes, can you show me the full stacktrace up to the call?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here you go: stacktrace.txt

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to that stacktrace the error is not caused by the call

cycleSym.owner.info.member(cycleSym.name).isOverloaded

That one shows up nowhere. So it most likely happens later. Could it be that an error message is not reported?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error is triggered by using member, even though it is not on the stack. The error is reported correctly if I don't call it and it fails when I try to, at the time of calling the error is not reported yet.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the member call causes another CyclicReference exception. That's not easy to avoid. So I think we should give up. Don't try to distinguish the error message and just say "recursive or overloaded".

Fall-back to reporting "overloaded or recursive needs type".
@odersky
Copy link
Contributor

odersky commented Mar 7, 2017

Yes, that's indeed harder than expected. Thanks for hanging in there!

@odersky odersky merged commit 6abaa10 into scala:master Mar 9, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants