Skip to content

Make stableNull public in the stdlib#25886

Draft
noti0na1 wants to merge 1 commit intoscala:mainfrom
dotty-staging:stable-null-public
Draft

Make stableNull public in the stdlib#25886
noti0na1 wants to merge 1 commit intoscala:mainfrom
dotty-staging:stable-null-public

Conversation

@noti0na1
Copy link
Copy Markdown
Member

The PR removes private[scala] from stableNull definition.

It was first introduced by #23528 for 3.8 stdlib migration. We want to make it public as part of explicit nulls.

How much have you relied on LLM-based tools in this contribution?

Minimally for document polishing

How was the solution tested?

It was already tested by #23528

Note

Need a minor release

@noti0na1 noti0na1 added needs-minor-release This PR cannot be merged until the next minor release area:nullability labels Apr 21, 2026
@noti0na1 noti0na1 requested a review from olhotak April 21, 2026 00:55
@noti0na1 noti0na1 self-assigned this Apr 21, 2026
Copy link
Copy Markdown
Contributor

@olhotak olhotak left a comment

Choose a reason for hiding this comment

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

LGTM

@SolalPirelli
Copy link
Copy Markdown
Contributor

If we're making stuff public for explicit nulls, should nullForGC also be public? Not strictly needed but convenient (Seb's PR removing unsafe nulls in the compiler could use it in a few places, for instance) https://github.com/scala/scala3/blob/main/library/src/scala/runtime/ScalaRunTime.scala#L324

@sjrd
Copy link
Copy Markdown
Member

sjrd commented Apr 21, 2026

I wouldn't make nullForGC public, no. That makes it less safe, contrary to @stableNull, which is safer than the alternative.

@bishabosha
Copy link
Copy Markdown
Member

so this is i guess just as safe as compiletime.uninitialized, i.e. not at all, but can there be hope for actual static analysis for checking "set-once"

@sjrd
Copy link
Copy Markdown
Member

sjrd commented Apr 22, 2026

It's not "not at all". Both require you to provide the reasoning/guarantee for one property. Then they do the rest of the job.

  • uninitialized: you need to guarantee that you will not read it before setting it the first time.
  • @stableNull: you need to guarantee that only one thread accesses it.

If you provide those guarantees, then they guarantee the rest of the safety.

nullForGC however gives you nothing besides local documentation.

@olhotak
Copy link
Copy Markdown
Contributor

olhotak commented Apr 22, 2026

For @stableNull, the required guarantee is stronger than just only one thread accessing it. You also need to guarantee that the mutable var will not be mutated in other methods or through aliases, even in the same thread.

@noti0na1
Copy link
Copy Markdown
Member Author

but can there be hope for actual static analysis for checking "set-once"

  1. A special "nullable" type, and Null is not its subtype;
  2. A runtime check it disallowing assigning null after initiallization.

Then, we can guarantee: if a field/variable has been initialized, it will never become null again.

@noti0na1
Copy link
Copy Markdown
Member Author

For question about Kotlin's behaviour: no, they don't track mutable fields for smart cast.

class A(var s: String?)

fun main() {
    val a = A("a")
    if (a.s != null) {
        println(a.s.length) // rejected by smart cast: 's' is a mutable property that could be mutated concurrently
    }
}

cc @odersky

@SethTisue
Copy link
Copy Markdown
Member

Core agreed today that this can become public, modulo a possible name change.

@noti0na1 noti0na1 added this to the 3.10.0 milestone Apr 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:nullability needs-minor-release This PR cannot be merged until the next minor release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants