Skip to content

Complete owners of type parameters before parameters themselves #10972

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 2 commits into from
Jan 6, 2021

Conversation

odersky
Copy link
Contributor

@odersky odersky commented Jan 2, 2021

Fixes #10967
Fixes #10638

I minimized #10967 further to:

trait SomeTrait

trait CollBase[CC1[A2 <: SomeTrait]] {
  val companion: CollCompanion[CC1]
}

trait CollCompanion[CC2[A <: SomeTrait]]

What happened was:

  1. the compiler tries to typecheck companion
  2. this means needs to check CollCompanion[CC1]
  3. this means it needs to complete the type parameter CC2 of CollCompanion in order to make sure the argument is CC1 is kind correct.
  4. this means we complete type parameter A of CC2
  5. checking the type parameter requires checking the owner class CollCompanion.
  6. And this leads back to CC2, hence the cycle.

Note that if the definitions of CollBase and CollCompanion appear in reverse order,
no cycle results, since then CollCompanion and its type parameters were completed before
completing companion.

To break the cycle, we can complete the owner of a type parameter before starting
completion of the parameter. Furthermore, we need to do this only in Namer, which is
where the complex checking patterns are. I have not tried to also treat symbols that
are not type definitions that way. It's not necessary to fix #10967 but it might help
for other cycles (or it might cause them, these things are tricky!). I did try to
make the behavior universal for all completers, not just Namers, but that caused
crashes immediately.

Fixes scala#10967

I minimized scala#10967 further to:
```scala
trait SomeTrait

trait CollBase[CC1[A2 <: SomeTrait]] {
  val companion: CollCompanion[CC1]
}

trait CollCompanion[CC2[A <: SomeTrait]]
```
What happened was:

 1. the compiler tries to typecheck `companion`
 2. this means needs to check `CollCompanion[CC1]`
 3. this means it needs to complete the type parameter `CC2` of CollCompanion in order to make sure the argument is CC1 is kind correct.
 4. this means we complete type parameter `A` of `CC2`
 4. checking the type parameter requires checking the owner class `CollCompanion`.
 5. And this leads back to `CC2`, hence the cycle.

Note that if the definitions of `CollBase` and `CollCompanion` appear in reverse order,
no cycle results, since then `CollCompanion` and its type parameters were completed before
completing `companion`.

To break the cycle, we can complete the owner of a type parameter before starting
completion of the parameter. Furthermore, we need to do this only in Namer, which is
where the complex checking patterns are. I have not tried to also treat symbols that
are not type definitions that way. It's not necessary to fix scala#10967 but it might help
for other cycles (or it might cause them, these things are tricky!). I did try to
make the behavior universal for all completers, not just Namers, but that caused
crashes immediately.
@odersky odersky requested a review from smarter January 2, 2021 13:03
@smarter
Copy link
Member

smarter commented Jan 5, 2021

test performance please

@dottybot
Copy link
Member

dottybot commented Jan 5, 2021

performance test scheduled: 10 job(s) in queue, 1 running.

@dottybot
Copy link
Member

dottybot commented Jan 5, 2021

Performance test finished successfully:

Visit http://dotty-bench.epfl.ch/10972/ to see the changes.

Benchmarks is based on merging with master (234cb00)

@smarter smarter merged commit cb153a0 into scala:master Jan 6, 2021
@smarter smarter deleted the fix-#10967 branch January 6, 2021 00:24
@Kordyjan Kordyjan added this to the 3.0.0 milestone Aug 2, 2023
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 involving type X F-bounded type cannot be used in type member - Cyclic reference
4 participants