Skip to content

Inline Traits & Specialized Traits#78

Closed
starswap wants to merge 649 commits into
dotty-staging:mainfrom
starswap:specialized-inline-traits
Closed

Inline Traits & Specialized Traits#78
starswap wants to merge 649 commits into
dotty-staging:mainfrom
starswap:specialized-inline-traits

Conversation

@starswap
Copy link
Copy Markdown

@starswap starswap commented May 11, 2026

Still DRAFT - running CI now

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

How was the solution tested?

Additional notes

starswap and others added 30 commits May 5, 2026 18:29
…a#25908)

When a transitive dependency is missing from the classpath, the TASTy
reader for a TYPEREF can produce a TypeRef whose symbol cannot be
resolved. Downstream code in `computeBaseData` then hits an internal
`non-class parent` assertion and crashes the compiler.

Replace such unresolvable `TypeRef`s with a stub class symbol (similar
to what Scala2Unpickler does), so the user sees a `BadSymbolicReference`
error on first use instead of a compiler crash. The substitution is
limited to references whose prefix is a package or a module, where
member lookup is deterministic, to avoid converting transient lookup
failures into spurious stubs during incremental completion.

Adds an sbt scripted regression test (`sbt-test/tasty-compat/i20010`)
that mirrors the original minimisation: three modules, `a`/`b`/`c`,
where compiling `c` must not crash when `a` is absent from its
classpath.

Fixes scala#20010

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

Extensively, but its a small fix.

## How was the solution tested?

New automated tests (including the issue's reproducer, if applicable)
…a#25980)

`assumedCanEqual` lifts the scrutinee type by mapping non-opaque
abstract types to their upper bound. When a GADT pattern object is
matched against an invariant parameterized scrutinee (e.g. matching
`object Bar extends Foo[Int]` against `Foo[A]`), this lifting raises
`Foo[A]` to `Foo[Any]`, against which `Foo.Bar.type` is not a subtype
because `Foo` is invariant — so the check fails even though GADT
reasoning would correctly constrain `A := Int`.

Try the unlifted subtype check first so GADT reasoning gets a chance,
falling back to the existing lifted check.

Fixes scala#25979
## How much have you relied on LLM-based tools in this contribution?

Extensively, but it's a simple fix.

## How was the solution tested?

New automated tests (including the issue's reproducer, if applicable)

---------

Co-authored-by: Claude <noreply@anthropic.com>
<!-- Fixes #XYZ (where XYZ is the issue number from the issue tracker)
-->
Implementation of scala#22298: Short description  

[JEP 409](https://openjdk.org/jeps/409) introduced sealed classes which
in concept are similar to sealed trait, so in this PR we added a
possibility to do exhaustiveness check in pattern matching for sealed
abstract java classes.

<!-- Ideally should have a title like "Fix #XYZ: Short fix description"
-->

<!--
  TODO first sign the CLA
  https://contribute.akka.io/cla/scala
-->

<!-- if the PR is still a WIP, create it as a draft PR (or convert it
into one) -->

## How much have you relied on LLM-based tools in this contribution?
minimally
<!-- 
  State clearly in the pull request description, 
  whether LLM-based tools were used and to what extent 

  (extensively/moderately/minimally/not at all)
-->

<!--
Refer to our [LLM usage
policy](https://github.com/scala/scala3/blob/main/LLM_POLICY.md) for
rules and guidelines
  regarding usage of LLM-based tools in contributions.
-->

## How was the solution tested?

<!-- Tick exactly one of these boxes. Exceptions must have a very good
reason. -->

- [ ] Non-code change, no tests needed
- [ ] Covered by existing tests (e.g., for refactorings)
- [x] New automated tests (including the issue's reproducer, if
applicable)
- [ ] Manual tests described below (in enough detail that someone
unfamiliar with this can still follow)

Added automated test for getting a warn message if pattern matching is
not exhaustive
## Additional notes

<!-- Placeholder for any extra context regarding this contribution. -->

<!--
When in doubt, and for support regarding contributions to a particular
component of the compiler,
refer to [our contribution
guide](https://github.com/scala/scala3/blob/main/CONTRIBUTING.md),
and feel free to tag the maintainers listed there for the area(s) you
are modifying.
-->

---------

Co-authored-by: z.akhatuly <z.akhatuly@tbank.ru>
## Summary

Fix REPL silently exiting after the first user input.

The recent JLine refactor in scala#25925 added `reader.close()` to the
`finally` block of `withMonitoringCtrlC`, called after every
`interpret()`. But `terminal.reader()` returns the terminal's shared
`NonBlockingReader`, so that close propagates to the terminal's input
side. The next `readLine()` then gets immediate EOF and the REPL exits
silently — typically right after the user's first command.

## Fix

Drop the `reader.close()` call. The monitor thread's `reader.read(100L)`
already returns within 100ms, and `userInput.signalClosed()` flips the
loop condition so the monitor thread exits on its own. The
`thread.join()` afterwards now waits up to ~100ms instead of returning
immediately, which is negligible per command.

This was fully Clauded.

## Test plan

- [x] All 172 existing REPL tests pass (`sbt scala3-repl/test`)
- [x] Manual: `bin/replQ` then multiple `val` definitions in sequence —
REPL stays alive
- [x] Manual: `import language.experimental.captureChecking` followed by
`val x = new Object` — REPL stays alive and shows `val x: Object^{} = …`
(capture checking active)
Previously, compiling

```scala
import scala.language.experimental.erasedDefinitions
class Ev
trait Svc[A]:
  def run(using erased Ev)(a: A): String
class ISvc extends Svc[Int]:
  def run(using erased Ev)(a: Int): String = a.toString
```

crashed in erasure with `bad adapt for this.run(): (x$0: Int): String`.

The bridge body is `Apply(this.run, [a])`.
However, previously, `Erasure.Typer.typedApply` filters
erased arguments using the function's *pre-erasure* type, and zip
arguments against `paramErasureStatuses` positionally (`(erased Ev)(a: Int)`).

Hence, `a` is mistaken for the erased slot and dropped, that leads to bad adaption.

This commit fixes the issue, by just skipping the filter when the Apply is inside a
bridge body.

Fixes scala#25726.
When a class has a self-type that refines a member, the symbol of a TypeDef
in its body can resolve through the self-type prefix to a different symbol
than the one being defined. This caused two problems:

- During TASTy unpickling, `tree.ensureHasSym(sym)` for a TypeDef tried to
  call `sym.asTerm.name`, which crashes with "asTerm called on not-a-Term"
  when sym is a type symbol.
- During typer, the TypeDef tree's symbol was never reconciled with the
  intended sym, so `-Ycheck:all` would report the trait body as missing
  the type member.

Use `sym.name` in `ensureHasSym` so the produced `NamedType` correctly
selects between `TypeRef` and `TermRef` based on the name kind, and call
`ensureHasSym` from `typedTypeDef` so the typed tree carries the right
symbol before pickling.

https://claude.ai/code/session_01Gu4rX4Ywk7zkf8yPqvvwNG
sjrd and others added 28 commits May 31, 2026 22:42
…#26192)

Previously, they erroneously erased to `BoxedUnit`.

Fixes #34653.

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

Not at all

## How was the solution tested?

New automated tests (including the issue's reproducer, if applicable)

Note that this can break binary compatibility of libraries recompiled
with a newer compiler. The issue contains a workaround:
scala#24653 (comment)

@WojciechMazur We had decided to include this in 3.9.0, but I was
completely underwater until now. So this should be backported to 3.9.0,
please. :)
Commit 9c971be made the Java parser
consume annotations before array dimensions.

That also permits annotations before a varargs ellipsis, since varargs
parameters pass through the same type parsing path. Add a regression
test for that syntax:
```java
void varargs(String @lib.Valid ... values) {}
```

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

Minimally, for analysing the code.

## How was the solution tested?

New test
Java permits type-use annotations before wildcard type arguments, for
example
```java
Function<@nullable ? super String, @nullable ? extends Object>
```

## Reproduce

You can use this repo's test files:
```
$ cd tests/pos/java-annotated-wildcards/

$ scala -version
Scala code runner version: 1.12.4
Scala version (default): 3.8.3

$ scalac -usejavacp Nullable.java Test.java 
-- Error: Test.java:4:21 ---------------------------------------------------------------------------------------------------------------------------
4 |  Function<@nullable ? super String, @nullable ? extends Object> mappingFunction();
  |                     ^^^^^^^^
  |                     illegal start of type
-- Error: Test.java:4:82 ---------------------------------------------------------------------------------------------------------------------------
4 |  Function<@nullable ? super String, @nullable ? extends Object> mappingFunction();
  |                                                                                  ^
  |                                                                                  null expected but ';' found.
  |
5 |}
2 errors found
```

Java however can compile it:
```
$ java -version
openjdk version "1.8.0_492"
OpenJDK Runtime Environment (Temurin)(build 1.8.0_492-b09)
OpenJDK 64-Bit Server VM (Temurin)(build 25.492-b09, mixed mode)

$ javac Nullable.java Test.java 
$ ls -1 *.class
Nullable.class
Test.class
```

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

<!-- Pick one; refer to
https://github.com/scala/scala3/blob/main/LLM_POLICY.md for details -->

Not at all (update: after the GitHub actions jobs failed I used codex
for analysing the code and find out what broke, that lead to force push)

## How was the solution tested?

New automated tests (including the issue's reproducer)
Plus Manual tests

## See also

- scala#22391
  - basically same kind of fix
…6191)

Fixes scala#26190.

Copies erased flag into inline trait access proxies if the underlying
field is erased.

## How much have you relied on LLM-based tools in this contribution?
Minimally to search for things in the codebase.

## How was the solution tested?
New automated tests.
_This PR applies 5/5 suggestions from code quality [AI
findings](https://github.com/scala/scala3/security/quality/ai-findings)._

---------

Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
_This PR applies 1/1 suggestions from code quality [AI
findings](https://github.com/scala/scala3/security/quality/ai-findings)._

Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Fixes scala#25723

This seems to have been fixed in the meantime.

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

Not at all

## How was the solution tested?

New automated tests
Add multiple param packs test
@starswap
Copy link
Copy Markdown
Author

starswap commented Jun 2, 2026

Moved to scala#26156

@starswap starswap closed this Jun 2, 2026
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.