question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Java unrecognized trait mixin method override

See original GitHub issue

Compiler version: 3.0.1

Problem

Java cannot extend or implement an abstract class which has an abstract method overridden by a mixin trait.

trait A {
  def foo: Int
}
trait B { self: A =>
  override final def foo: Int = 1
}
abstract class JavaAWithB extends A with B
class Foo extends JavaAWithB { } // Foo must be abstract since it doesn't define `foo`

Issue Analytics

  • State:open
  • Created 2 years ago
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
smartercommented, Jul 20, 2021

It cannot make [foo] non-final, and it should not add the overrides automatically, since the JVM does not require them and it would just lead to unnecessary code bloat.

In fact, we do emit foo as non-final in B (default methods cannot be final), and we also emit an override of foo in JavaAWithB even though it’s not required at runtime (for performance reasons: https://github.com/lampepfl/dotty/commit/6c6443086071774431dae93709b4102ce3c4d15e), but unlike Scala 2 we emit this override with the ACC_SYNTHETIC flag to hide it from Java, this is done because it avoids/fixes a lot of issues with Java generic signatures (cf https://github.com/lampepfl/dotty/commit/6d0f9ca3ae4c7130c1ee18e0e21f283ff6cb21f3) but it does indeed mean that when Java consumes a Scala class, it can incorrectly conclude that an override is missing.

In fact, I first implemented this scheme in Scala 2 where it ended up being reverted because of this issue, I suggested a possible way forward at the time at https://github.com/scala/bug/issues/11512#issuecomment-489424170 but haven’t followed up since then, and I likely won’t have the time to do so anytime soon (but maybe @lrytz would be interested? 😃).

Note that while reverting https://github.com/lampepfl/dotty/commit/6d0f9ca3ae4c7130c1ee18e0e21f283ff6cb21f3 would fix this issue, it would also break a bunch of the tests in that commit, to keep these tests working some careful work on generic signature generation will be necessary.

0reactions
smartercommented, Jul 21, 2021

do you remember if we emit incorrect generic signatures for the forwarder

Scala 2 does, yes: https://github.com/scala/scala/blob/0c011547b1ccf961ca427c3d3459955e618e93d5/src/compiler/scala/tools/nsc/transform/Mixin.scala#L176-L204 and the issues with that are recorded in https://github.com/scala/bug/issues/8905 and all the tests that had to be changed/removed in https://github.com/scala/scala/pull/8037.

Scala 3 doesn’t since the forwarders are always ACC_SYNTHETIC, and in https://github.com/scala/bug/issues/11512#issuecomment-489424170 I suggested we only make the forwarders that are required to please javac non-synthetic, that way even if our generic signatures are sometimes lacking, less code would be affected.

Read more comments on GitHub >

github_iconTop Results From Across the Web

scala - Trait mixin with conflicting members: Why my code can ...
Since TA.play and TB.play are declared with override , it's clear that they intend to override the method play(): Unit that is in...
Read more >
Compilation error when subclassing a class with methods ...
A mixin forwarder added to a class can fall into three categories: The forwarder is required to get the correct runtime semantics (e.g....
Read more >
Simulating mixins in Kotlin - LinkedIn
The main inspiration for me to write this article is an approach to modeling common parts of Actions in Android applications - I...
Read more >
A few notes about using Scala traits as mixins (construction ...
The order in which overridden trait methods are called when multiple traits are mixed in. Lesson: When multiple traits are mixed into a...
Read more >
Documentation - Mixins - TypeScript
The pattern relies on using generics with class inheritance to extend a base class. TypeScript's best mixin support is done via the class...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found