Skip to content

Cyclic Reference errors for recursive toplevel match types #9000

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

Closed
odersky opened this issue May 18, 2020 · 0 comments · Fixed by #9001
Closed

Cyclic Reference errors for recursive toplevel match types #9000

odersky opened this issue May 18, 2020 · 0 comments · Fixed by #9001

Comments

@odersky
Copy link
Contributor

odersky commented May 18, 2020

Minimized example

class A
class B

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

Output

Error: cyclic reference

Expectation

Should compile. The type A2B compiles OK if it is put inside an object test.

odersky added a commit to dotty-staging/dotty that referenced this issue 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 a commit to dotty-staging/dotty that referenced this issue May 19, 2020
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 added a commit to dotty-staging/dotty that referenced this issue May 19, 2020
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.
smarter added a commit that referenced this issue May 19, 2020
…yclic

Fix #9000: Avoid spurious cyclic errors for toplevel matches
rethab pushed a commit to rethab/dotty that referenced this issue May 25, 2020
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.
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 a pull request may close this issue.

1 participant