Skip to content

Ensure monotonicity of the types of closures#26193

Open
odersky wants to merge 7 commits into
scala:mainfrom
dotty-staging:change-unscoped-fresh
Open

Ensure monotonicity of the types of closures#26193
odersky wants to merge 7 commits into
scala:mainfrom
dotty-staging:change-unscoped-fresh

Conversation

@odersky
Copy link
Copy Markdown
Contributor

@odersky odersky commented May 31, 2026

Previously, a closure could return an unscoped type with any in it
(e.g., Ref^) but its type would be a pure function type. We now propagate
the any into the function type. This has to be done with care though, since
the ^ of a closure might come from the expected type, in which case we
should ignore it. The tricky bit is distinguishing one from the other.

@odersky odersky force-pushed the change-unscoped-fresh branch 2 times, most recently from 36a4c5d to 2412b6a Compare June 2, 2026 13:49
@odersky odersky requested a review from a team as a code owner June 2, 2026 13:49
@odersky
Copy link
Copy Markdown
Contributor Author

odersky commented Jun 2, 2026

@bracevac Can you take a look at the scaladoc test failure? It's hard to see what goes on here.

@odersky odersky requested a review from Linyxus June 2, 2026 15:17
@odersky odersky changed the title Handle unscoped fresh in closures differently Ensure monotonicity of the types of closures Jun 2, 2026
Previously, anonymous functions were excluded. lambda-fresh-2.scala shows why this is
unsound. We now drop the special treatment of anonymous functions, and at the same time
exclude LocalCaps that come from outside the function from checking.
@bracevac bracevac assigned odersky and unassigned bracevac Jun 3, 2026
odersky added 4 commits June 3, 2026 23:53
Previously, a closure could return an unscoped type with `any` in it
(e.g., `Ref^`) but its type would be a pure function type. We now propagate
the `any` into the function type. This has to be done with care though, since
the `^` of a closure might come from the expected type, in which case we
should ignore it. The tricky bit is distinguishing one from the other.
Drop two unused parameters.
@bracevac
Copy link
Copy Markdown
Contributor

bracevac commented Jun 3, 2026

@odersky I fixed the test in question. But tbh, this one was no different than a cc compilation test, so it's not unreasonable to expect someone working on cc to fix them.

Certain other tests for scaladoc and REPL I will absolutely insist on keeping them, as they affect user experience.

Copy link
Copy Markdown
Contributor Author

@odersky odersky left a comment

Choose a reason for hiding this comment

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

Yes, that's much better! I completely agree we need snippet tests for specific cc code. But we should be 100% dumb for generic functionality such as whether more than one expectation per line is checked.

@bracevac
Copy link
Copy Markdown
Contributor

bracevac commented Jun 3, 2026

We now see extra errors on already erroring lines in the scoped-capabilities.md chapter. Maybe we should also add magic comments for "at least one error" to avoid overdosing, e.g., // error+ or // error(s)

@bracevac
Copy link
Copy Markdown
Contributor

bracevac commented Jun 3, 2026

I ended up with a simpler change that lets error and warn match on one or more error/warning.


val _: () -> One^{fresh} = () => One() // ok
val _: () => One^{fresh} = () => One() // ok
val _: () => One^{fresh} = f2 // ok
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.

I wonder: does the notion of fresh here ever make sense without an ExclusiveCapability?
Which is to say, if One is already known to be exclusive, why can't One^ just mean fresh?

odersky added 2 commits June 4, 2026 11:10
Don't elide even if the capset belongs to a Capability class.
This replaces the special treatment of UnScoped in the ToResult map and
makes Unscoped capabilities more versatile.
@odersky odersky force-pushed the change-unscoped-fresh branch from 5ff528f to 4b737ca Compare June 4, 2026 17:27
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.

2 participants