Open nafg opened 1 year ago
If there is a workaround for the case of override def method() = super.method()
I'd appreciate knowing it. I'd like to be able to turn a library-protected method into a subclass-public method.
I don't think it should compile at all, at least it would be consistent with how it works in general. In general, you can't provide a value class as a type parameter to a super class if that type is either returned from a method (directly, not wrapped), or used as a method argument. You get the annoying error of 'bridge method generated for
@nafg, if you'd like the same effect, you can go with 'poor man's opaque types` for Scala 2:
class Inner
type Outer //left abstract
def Outer(inner :Inner) :Outer = inner.asInstanceOf[Outer]
implicit class OuterExtension(val self :Outer) extends AnyVal {
def inner :Inner = self.asInstanceOf[Inner]
//any methods which would go in a value class Outer go here.
}
This trick is very useful exactly because it avoids both your problem and the problem of bridge method clashing with specialized override in a subclass.
Are you suggesting to rewrite scalajs-react that way?
Reproduction steps
Scala version: Scala 2, including 2.13.11, but going way back too
Tested on JVM and JS. Confirmed it works on Scala 3 (both)
Code is at https://github.com/nafg/reproduce-anyval-cce
This is a minimized version of a real world problem. I discussed it at https://discord.com/channels/632150470000902164/635668814956068864/1119201503937302610
Translation:
Inner
japgolly.scalajs.react.callback.Trampoline
Outer
japgolly.scalajs.react.callback.CallbackTo
Abstract
japgolly.scalajs.react.extra.BroadcasterF
Abstract#helper
japgolly.scalajs.react.util.Effect.UnsafeSync#traverse_
Abstract#method
japgolly.scalajs.react.extra.BroadcasterF#broadcast
Concrete
japgolly.scalajs.react.extra.Broadcaster
Concrete#helper
japgolly.scalajs.react.util.EffectCallback.callback#traverse_
Public
io.github.nafg.scalajs.react.util.PublicBroadcaster
Problem
It crashes at runtime with
Exception in thread "main" java.lang.ClassCastException: class Outer cannot be cast to class Inner
Note that removing
super.
inmethod2
fixes it. Originally I was overriding the same method just to make it public.