-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Ignore capture sets in certain cases of subtyping #22183
Conversation
@@ -12,8 +12,4 @@ def either[T1, T2, Cap^]( | |||
src2: Source[T2, Cap]^{Cap^}): Source[Either[T1, T2], Cap]^{Cap^} = | |||
val left = src1.transformValuesWith(Left(_)) | |||
val right = src2.transformValuesWith(Right(_)) | |||
race[Either[T1, T2], Cap](left, right) |
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.
The extension methods above can be tested as well. I remember they have similar issues.
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.
It causes an infinite regress now, looking into it.
We should have standalone file to test the subtyping: def test[C^] =
val a: C = ???
val b: CapSet^{C^} = a
val c: C = b
val d: CapSet^{C^, ...} = a
... We also want to test nested types are still working: def test[C^, D^] =
A[C] <:< A[CapSet^{C^}] // ok
A[C] <:< A[CapSet^{D^}] // error
A[C]^{D^} <:< A[CapSet^{D^}]^{D^} // error |
7acd730
to
7d8b439
Compare
val d: CapSet^{C^, c} = a | ||
|
||
// TODO: make "CapSet-ness" of type variables somehow contagious? | ||
// Then we don't have to spell out the bounds explicitly... |
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.
We should support that. Say we have def foo[C^, D <: C, E >: C]
, then we should automatically constraint both D
and E
to be capture set variables, i.e., D
is implicitly lower-bounded by CapSet
, and E
is implicitly upper-bounded by CapSet^
val d_e_f2: CapSet^{D^,E^,F^} = e1 | ||
val d_e_f3: CapSet^{D^,E^,F^} = f1 | ||
val f2: F = d_e_f1 | ||
val c3: C = d_e_f1 // error |
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.
This line and the three following lines are all not flagged as errors, but they should be. Investigating.
The continuation: #22299 |
Fixes #22103 Subtype problems where at least one side is a type variable representing a capture variable are canonicalized to capturing type comparisons on the special `CapSet` for the universe capture sets. For example, `C <: CapSet^{C^}` becomes `CapSet^{C^} <: CapSet^{C^}`, and `A <: B` becomes `CapSet^{A^} <: CapSet^{B^}` if both `A` and `B` are capture variables. Supersedes #22183 and #22289. This solution is overall cleaner and does not require adding a new bit to the TypeComparer's ApproxState. TODOs/Issues/Questions: - [x] Fix extension method in test [cc-poly-varargs.scala](https://github.com/dotty-staging/dotty/blob/capture-subtyping-canon/tests/pos-custom-args/captures/cc-poly-varargs.scala). Currently causes an infinite regress. - [x] Fix the aftermath * tests/neg-custom-args/captures/lazylists-exceptions.scala * tests/neg-custom-args/captures/exceptions.scala * tests/neg-custom-args/captures/real-try.scala * tests/run-custom-args/captures/colltest5 - [x] Some negative cases in test [capture-vars-subtyping.scala](https://github.com/dotty-staging/dotty/blob/capture-subtyping-canon/tests/neg-custom-args/captures/capture-vars-subtyping.scala) pass: `D <: E` fails, but its canonicalized form `CapSet^{D^} <: CapSet^{E^}` now succeeds. Potential problem in the subcapturing implementation. - [x] ~Extend to intersection/unions `def f[C^, D^, E <: C | D, F <: C & D](...) = ...` etc.~ Lacking good uses cases, not planned right now. - [X] ~If we have `C^` declared in the current context, should there be a difference between `C` vs. `C^` for subsequent mentions? We currently do, but seems a bit too subtle for users.~ Will be addressed by a new scheme for declaring capture variables using context bounds.
Fixes #22103
If
C
is a capture-set variable, then a comparisonC <: CapSet^{C^}
would previously fail in theTypeComparer
due to a level mismatch resulting in the testCapSet^ <: CapSet
.For such cases, we now ignore the LHS capture annotation. This is controlled by a new bit in the
ApproxState
of theTypeComparer
.