Skip to content

Fix #9000: Avoid spurious cyclic errors for toplevel matches #9001

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 3 commits into from
May 19, 2020

Conversation

odersky
Copy link
Contributor

@odersky odersky commented May 18, 2020

I still don't know why the match type

type A2B[Xs <: Tuple] <: Tuple = Xs match
  case Unit => Unit
  case a *: as => B *: A2B[as]

compiled OK if it appeared in a user defined object, but failed with a cyclic
reference when written on the top level. But the logic for cyclic detection was
clearly very fragile, and unadapted to the case at hand. Essentially, it's a
type map that inserts LazyRefs when it detects legal cycles. The problem is that
these insertions cause recomputations of applied types in the TypeMap. And these
fail since the type constructor (A2B in this case) has not yet been completed.
So after a LazyRef was inserted, the cycle checker fails again in an unrecoverable
way because it tries to get the type parameters of an uncompleted type constructor.
So the question would be rather - why did this work if the match type appears in
a user-defined object? I could not answer that question, but I could fix the logic
to handle these cases.

odersky added 2 commits May 18, 2020 15:01
Sometimes, printing a cyclic error leads to another cyclic error. In this case
we should print the original error, not the error caused by the printing.
Previously cyclic references arising from cyclicity checking were not printed.
Now we print them as well if -Ydebug is on. This gives us better insight into
why a cyclic test fails.
@smarter
Copy link
Member

smarter commented May 18, 2020

So the question would be rather - why did this work if the match type appears in
a user-defined object?

Don't know exactly what's going on but: 1) in some situations we can complete type parameters without fully forcing the info using completerTypeParams and 2) appliedTo uses safeDealias to avoid forcing the type being applied, so there is some chance that an AppliedType can be mapped without causing a cycle I think.

@odersky odersky force-pushed the fix-toplevel-matchtypes-cyclic branch from de789c3 to df95ac4 Compare May 19, 2020 09:40
@odersky
Copy link
Contributor Author

odersky commented May 19, 2020

I found the root cause. Here's the commit message of the last commit:

Fix #9000: Change definition of isTrivial

The only difference between checking cyclicity of a match type
in an object O and on the toplevel is that the matchtype itself
has the prefix O.this in the first case, and TermRef(_, pkgObject)
in the second case (this is because the match type is actually looked
up in the package scope, not in the package object scope).
This made a difference in the isTrivial check when computing type parameters.
And this in turn caused spurious cycles to be reported. The fix is
to add the missing case to isTrivial.

The only difference between checking cyclicity of a match type
in an object O and on the toplevel is that the matchtype itself
has the prefix O.this in the first case, and TermRef(_, pkgObject)
in the second case (this is because the match type is actually looked
up in the package scope, not in the package object scope).
This made a difference in the isTrivial check when computing type parameters.
And this in turn caused spurious cycles to be reported. The fix is
to add the missing case to isTrivial.
@odersky odersky force-pushed the fix-toplevel-matchtypes-cyclic branch from df95ac4 to 1e30c39 Compare May 19, 2020 09:53
@nicolasstucki nicolasstucki linked an issue May 19, 2020 that may be closed by this pull request
@odersky odersky requested a review from smarter May 19, 2020 12:39
@smarter smarter merged commit 0e6aa7e into scala:master May 19, 2020
@smarter smarter deleted the fix-toplevel-matchtypes-cyclic branch May 19, 2020 13:12
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.

Cyclic Reference errors for recursive toplevel match types
2 participants