Skip to content

Add restricted capabilities x.only[C] #23485

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

Open
wants to merge 16 commits into
base: main
Choose a base branch
from

Conversation

odersky
Copy link
Contributor

@odersky odersky commented Jul 7, 2025

Implementation along the lines of #23463

  • Syntax and parsing rules for only-capabilities.
  • A Classifier base trait.
  • Enforce restriction that a class cannot inherit two unrelated classified capability classes.
  • A new capability class for only-capabilities.
  • Implement captureSetOfInfo for only capabilities.
  • The empty capability is x.only[Nothing]. It should have empty captureSetOfInfo.
  • Well-formedness rules: only must refer to a classified capability class.
  • Normalization rules:
    - it's *, then .only, then .rd,
    - multiple .only normalize to the smallest one if the classes are related,
    - multiple .only normalize to the empty capability if the classes are not related.
  • define transitive capture set and cache it in a capability. The tcs does not exist if a capture set in the hierarchy is still an unsolved capture set variable.
  • Add a classifier field to FreshCap and ResultCap.
  • Modify capToFresh and toResultInResults so that the classifier field is correctly set.
  • Using tcs, define when a capability is classified by a classifier class.
  • A FreshCap with a classifier C can subsume only capabilities that are classified as C.
  • Implement subsumption rules:
    - c.as[C] <: d if c <: d or c.as[D] <: empty
    - c.as[C] <: d.as[D] if c <: d and C derives from D
    - c <: d.as[D] if c <: d and c is classified as D
    - c.as[D] <: empty if tcs(c) consists of capabilities that all derive from classifier classes unrelated to D.

@@ -597,7 +597,7 @@ class SepCheck(checker: CheckCaptures.CheckerAPI) extends tpd.TreeTraverser:
* - If the reference is to a this type of the enclosing class, the
* access must be in a @consume method.
*
* References that extend SharedCapability are excluded from checking.
* References that extend cpas.Sharable are excluded from checking.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
* References that extend cpas.Sharable are excluded from checking.
* References that extend caps.Sharable are excluded from checking.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍

@odersky odersky marked this pull request as ready for review July 17, 2025 11:58
@odersky odersky requested a review from a team as a code owner July 17, 2025 11:58
@odersky odersky requested a review from bracevac July 17, 2025 12:35
Copy link
Contributor

@bracevac bracevac left a comment

Choose a reason for hiding this comment

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

Can we also have the example from the github discussion?

@bracevac
Copy link
Contributor

bracevac commented Jul 21, 2025

Can we also have the example from the github discussion?

Short answer: No! Not until we unify .rd and the Read classifier, then we could make File a Mutable and set up the example so that the closure permits only non-update methods.

I also realized that it's not clear how a design pattern like in 2nd-class values would work in our system, i.e., have objects/classes enclosing implicit members that granularly model different access tokens/capabilities on that object (them) vs. the enclosing objects/classes are themselves capabilities (us). The difference is that due to the whole-part relationship, it seems we need to track the enclosing object alongside its capability members.

That's rubbish, we can just box the capability members and brand the effectful methods with a reach capability to the box contents. Then we also do not need to pass them as explicit or implicit parameters.

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.

3 participants