Skip to content

CC Language Reference: Rename cap to any/fresh#25057

Merged
bracevac merged 10 commits intoscala:mainfrom
dotty-staging:ob-cc-docs-rename
Feb 15, 2026
Merged

CC Language Reference: Rename cap to any/fresh#25057
bracevac merged 10 commits intoscala:mainfrom
dotty-staging:ob-cc-docs-rename

Conversation

@bracevac
Copy link
Contributor

This reflects the recent CC changes in the docs.

```

## Parameter and Result Caps in Function Types
## Parameter and Result `any`s in Function Types
Copy link
Member

@bishabosha bishabosha Jan 26, 2026

Choose a reason for hiding this comment

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

should Fresh be mentioned here? (it looks like Fresh is used in function type results)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, I still need to do a reading pass with a fine comb (most of the changes were Clauded).

@bracevac bracevac force-pushed the ob-cc-docs-rename branch 2 times, most recently from 2b20c25 to 880abc6 Compare February 1, 2026 22:30
@bracevac
Copy link
Contributor Author

@odersky your input, particularly on the separation checking chapter is appreciated.

nested, but not outward to enclosing scopes (which would mean a capability lives longer than its
lexical lifetime). The compiler computes a capability's level by walking up the ownership chain
until reaching a symbol that represents a level boundary. Level boundaries are:
- **Classes** (but not inner non-static module classes)
Copy link
Contributor

Choose a reason for hiding this comment

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

"module classes" is used only in the implementation. I would probably say:

classes
static objects
methods

the smallest visible super capture set:

```scala
def test(fs: FileSystem^/*{any₁}*/): Logger^/*{any₂}*/ =
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not declare test to have result Logger^{fs}? That's more natural and easier to explain, I think.

### Checking Return Types

When a `cap` appears in the return type of a function it means a "fresh" top capability, different from what is known at the call site. Separation checking makes sure this is the case. For instance, the following is OK:
When a `fresh` appears in the return type of a function it means a "fresh" top capability, different from what is known at the call site. Separation checking makes sure this is the case. For instance, the following is OK:
Copy link
Contributor

Choose a reason for hiding this comment

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

No, this is any (everywhere) not fresh. fresh only appears in the return types of function types, not in the return types of methods.

We should do a scan of the code to verify this (or, better, make sure everything typechecks).

### Consume Parameters

Returning parameters in fresh result caps is safe if the actual argument to the parameter is not used afterwards. We can signal and enforce this pattern by adding a `consume` modifier to a parameter. With that new soft modifier, the following variant of `incr` is legal:
Returning `fresh` parameters is safe if the actual argument to the parameter is not used afterwards. We can signal and enforce this pattern by adding a `consume` modifier to a parameter. With that new soft modifier, the following variant of `incr` is legal:
Copy link
Contributor

Choose a reason for hiding this comment

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

Should be "returning parameters is result any's".

```scala
class Buffer[T] extends Mutable:
consume def +=(x: T): Buffer[T]^ = this // ok
consume def +=(x: T): Buffer[T]^{fresh} = this // ok
Copy link
Contributor

Choose a reason for hiding this comment

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

same here: it's any, not fresh.

layout: doc-page
title: "Scoped Capabilities"
nightlyOf: https://docs.scala-lang.org/scala3/reference/experimental/capture-checking/scoped-capabilities.html
---
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder whether it's not better to say from the start here that each any (and each fresh) is a different capability. Each any can subsume capabilities of the same or outer level, including other anys. Then we don't need to make fine distinctions which anys are different and which are unified. Also, we prepare the ground for separation checking, where each any gets a hidden set.

bracevac and others added 10 commits February 14, 2026 20:27
This reflects the recent [CC changes](scala#24923)
in the docs.
Co-authored-by: Jamie Thompson <bishbashboshjt@gmail.com>
- Intro: introduce `fresh` with its import path before first use
- Result `fresh`s: clarify applies only to function types, not methods
- separation-checking: add section on `fresh` in function type results
@bracevac bracevac merged commit 77941ad into scala:main Feb 15, 2026
59 checks passed
@bracevac bracevac deleted the ob-cc-docs-rename branch February 15, 2026 13:20
bracevac added a commit that referenced this pull request Feb 16, 2026
This should catch rendering issues while evolving the capture checker.

Fixes #24783

Based on #25057
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