Skip to content

Port Capture-checked Scala 2 collections#23769

Merged
natsukagami merged 87 commits intoscala:mainfrom
dotty-staging:port-scala2-cc
Aug 19, 2025
Merged

Port Capture-checked Scala 2 collections#23769
natsukagami merged 87 commits intoscala:mainfrom
dotty-staging:port-scala2-cc

Conversation

@natsukagami
Copy link
Copy Markdown
Contributor

@natsukagami natsukagami commented Aug 16, 2025

Changes:

  • New final class collection.immutable.LazyListIterable[A], implements Iterable and IterableOps. LazyList and Stream are not capture-checked. Note added to LazyList.
  • New trait collection.StrictSeqOps[A, CC[_] <: Pure, C], which extends SeqOps (which can now be impure) and requires the implementation to be pure. Seq and other data structures extend this. no longer needed

Suspicious changes:

  • Might be suspicious: MapOps.keySet changes implementation to be always strict, unless it is one of the library's known strict collections

Not capture-checked (yet?)

  • Generated functions and tuples files. I tried turning CC on for functions and it hung the compiler. Maybe not a problem.
  • collection.convert.impl a.k.a Steppers, due to some purity problems (maybe because we don't compile steppers and rely on Scala 2, for specialization?).
  • LazyList and Streams.

Copy link
Copy Markdown
Member

@hamzaremmal hamzaremmal left a comment

Choose a reason for hiding this comment

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

All good, Martin's upcoming PR should solve all the issues with the bound checker for caps.Pure. There is one added bounded that will not be covered by that check and needs to be (dropped ?) solved.

Copy link
Copy Markdown
Contributor

@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.

All OK from my side. Nice that we could get rid of the StrictSeqOps traits and related stuff.

@odersky
Copy link
Copy Markdown
Contributor

odersky commented Aug 19, 2025

PR for pure checking: #23784

@natsukagami natsukagami marked this pull request as ready for review August 19, 2025 21:53
@natsukagami natsukagami requested a review from a team as a code owner August 19, 2025 21:53
@odersky
Copy link
Copy Markdown
Contributor

odersky commented Aug 19, 2025

I'm going to bed now. If the tests are green we can merge.

@natsukagami natsukagami merged commit 1f13619 into scala:main Aug 19, 2025
49 checks passed
@natsukagami natsukagami deleted the port-scala2-cc branch August 19, 2025 23:26
@hamzaremmal hamzaremmal added the release-notes Should be mentioned in the release notes label Aug 22, 2025
@tgodzik tgodzik added the area:experimental:cc Capture checking related label Aug 25, 2025
hamzaremmal added a commit to hamzaremmal/scala3 that referenced this pull request Sep 11, 2025
hamzaremmal added a commit to hamzaremmal/scala3 that referenced this pull request Sep 12, 2025
hamzaremmal added a commit to hamzaremmal/scala3 that referenced this pull request Sep 13, 2025
hamzaremmal added a commit to hamzaremmal/scala3 that referenced this pull request Sep 13, 2025
hamzaremmal added a commit to hamzaremmal/scala3 that referenced this pull request Sep 15, 2025
@WojciechMazur WojciechMazur added this to the 3.8.0 milestone Oct 28, 2025
Gedochao pushed a commit that referenced this pull request Nov 17, 2025
HarrisL2 pushed a commit to HarrisL2/scala3 that referenced this pull request Nov 18, 2025
bracevac pushed a commit to dotty-staging/dotty that referenced this pull request Nov 19, 2025
WojciechMazur pushed a commit that referenced this pull request Jan 7, 2026
…trict/lazy KeySet implementations (#24767)

Fixes #24749.

The PR contains two parts, one tiny and the other more involved.

## `KeySet` performance issues

Previously we use a `List[K]` to hold keys inside the strict KeySet, in
order to
keep iteration order stable. However this degrades performance of KeySet
as a Set.
The fix is to simply use something that has both. Currently it means
`mutable.LinkedHashSet`,
so we use it, even though we don't intend to mutate the set at all.

## Deprecating `KeySet` as a whole and use our private implementations
instead

As part of #23769 we categorised most data structures to be strict/pure
(as in "not hiding any
computation as part of its structure"), which includes `Set`. **It turns
out that our change to `MapOps.GenKeySet` in
#23769 was never
backwards-compatible -- it creates abstract getters and setters for the
`allKeys` val.**

This however clashes with how `.keySet` method was implemented: it
returns a `Set[K]`, but
provides _no_ guarantee on whether it is a lazy view over the underlying
data structure
(which _can_ be lazy, e.g. when you call `.keySet` from a `MapView`) or
a strict set.
With API compatibility in mind, we now create strict key sets (with a
copy of the keys)
in the generic case, while trying to detect whether the `.keySet` method
was called from an
already strict data-structure (which is the majority case) - returning a
thin-wrapper `LazyKeySet`
in that case. As the LazyKeySet works like a view with no aggregation,
applying it over a strict
data structure doesn't violate strictness.

This left a few holes however, which was overlooked: some data
structures such as `mutable.HashSet`
overrides `.keySet` with their own (protected!) classes, extending from
the previously-ambiguous
KeySet classes (that is now made strict), and accidentally ending up
always using the strict version.

Unfortunately we cannot modify these extended classes (for TASTy
compatibility), so similar versions
extending the thin wrapper are added instead, and the old classes
deprecated.
To not shoot ourselves in the foot in the future, these classes are also
made `private[collection]`:
We don't expect classes like `HashMap` to be extended with a custom
`KeySet`, and in the cases that
it does, it is not a problem to reimplement the missing 4-5 methods in
the most efficient way for your
extended data structure.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:experimental:cc Capture checking related release-notes Should be mentioned in the release notes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants