Skip to content

Make Capability types have implied capture sets for new#25346

Merged
odersky merged 11 commits into
scala:mainfrom
dotty-staging:change-new-capability
Mar 24, 2026
Merged

Make Capability types have implied capture sets for new#25346
odersky merged 11 commits into
scala:mainfrom
dotty-staging:change-new-capability

Conversation

@odersky

@odersky odersky commented Feb 25, 2026

Copy link
Copy Markdown
Contributor

If a class extends a Capability, it will now get a LocalCap on creation. This
solves the problem that

  class C extends Capability
  val a = C()
  val b: C = C()

did two different things: a was pure but b was impure. Now they are both impure.

Based on #25278

Also, several other new rules around capture sets of new, outlined on the doc page.

@odersky odersky force-pushed the change-new-capability branch from da5b735 to f843a47 Compare February 25, 2026 14:34
@odersky odersky requested a review from a team as a code owner February 26, 2026 15:22
@odersky odersky force-pushed the change-new-capability branch from 0a317d8 to f8fc07a Compare February 26, 2026 17:11
@odersky odersky requested a review from natsukagami February 27, 2026 19:01
@odersky odersky force-pushed the change-new-capability branch from e200270 to c7e41e9 Compare March 19, 2026 14:36
it must extend `Capability`. This makes sure we add the proper capture set to `new C`
under separate compilation without having to scan its fields.

## Captures of

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Empty section

@natsukagami natsukagami left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code looks good, I haven't looked at the tests closely.

Why are we dropping Separate?

* type arguments. Charge deep capture sets of type arguments to non-reserved typevars
* to the environment. Other generic parents are represented as TypeApplys, where the
* same check is already done in the TypeApply.
* 6. Check that capture sets of fields are compatibe with declared extensions of

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
* 6. Check that capture sets of fields are compatibe with declared extensions of
* 6. Check that capture sets of fields are compatible with declared extensions of

@odersky odersky force-pushed the change-new-capability branch 2 times, most recently from 2569407 to 7474a82 Compare March 22, 2026 17:59
odersky added 10 commits March 22, 2026 21:36
If a class extends a Capability, it will now get a LocalCap on creation. This
solves the problem that
```scala
  class C extends Capability
  val a = C()
  val b: C = C()
```
did two different things: `a` was pure but `b` was impure. Now they are both impure.
... where we had use capturesImpliedByFields before.
Since we now always add `any` when creating a capability class, Stateful
should no longer be a capability class. Otherwise, we could not create
an Iterator (which extends Stateful) with capture set such as `{Iterator.this, f}`.
Also:

 - Do allow mixing an ExclusiveCapability class with stateful as long as it does not have exclusive fields
   or retains exclusive capabilities otherwise
 - Drop restriction that a class may not extend both Stateful and SharedCapability
 - Update doc pages to reflect changes to Stateful and Separate
@odersky odersky force-pushed the change-new-capability branch 3 times, most recently from 8ea695c to a57609c Compare March 22, 2026 22:16
@odersky

odersky commented Mar 22, 2026

Copy link
Copy Markdown
Contributor Author

Why are we dropping Separate?

We don't need it anymore since we add any to the capset of C() anyway if C is a capability class.

@odersky odersky force-pushed the change-new-capability branch from a57609c to d86a7e4 Compare March 23, 2026 10:47
If C extends Stateful, C means C^{}
If C extends Stateful and SharedCapability, C means C^{any}
If C extends Stateful and ExclusiveCapability, C means C^{any.rd}
@odersky odersky force-pushed the change-new-capability branch from d86a7e4 to b56e2e3 Compare March 23, 2026 11:38
@odersky odersky merged commit 4a31256 into scala:main Mar 24, 2026
64 checks passed
@odersky odersky deleted the change-new-capability branch March 24, 2026 17:30
@WojciechMazur WojciechMazur added this to the 3.8.4 milestone Mar 31, 2026
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.

4 participants