In JVM, is 0-overhead type coercion/downcasting a possibility?

84 Views Asked by At

I'm evaluating the technical difficulty & runtime impact of implementing project Caprese in Scala (https://www.slideshare.net/Odersky/capabilities-for-resources-and-effects-252161040)

The scope of the project is to introduce a new substructural type system that can mix-in/evict new capabilities to a define term over its lifespan. Similar to the linear/affine type system of Rust, the compiler can now track its evolving usage/state and enable/disable its method at different part of the program.

I'm trying to mimic this capability using several terms that are different in types, but are identical in runtime, here is my code:

    trait Cap
    trait Cap1 extends Cap {

      final def canDo(): Unit = {
        println("canDo")
      }
    }
    trait Cap2 extends Cap {
      // ...some other capabilities
    }

    class HasNoCap extends Cap

//    class HasCap1 extends HasNoCap with Cap1

    val a = new HasNoCap
    val b = a.asInstanceOf[HasNoCap & Cap1]

    b.canDo()

Unfortunately, it can't be executed in JVM (haven't tried JavaScript or native compiler yet), despite the fact that HasNoCap and HasCap1 has identical data structure:

Exception in thread "main" java.lang.ExceptionInInitializerError
    at com.tribbloids.spike.dotty.CapabilityTracking$.main(CapabilityTracking.scala:27)
    at com.tribbloids.spike.dotty.CapabilityTracking.main(CapabilityTracking.scala)
Caused by: java.lang.ClassCastException: class com.tribbloids.spike.dotty.CapabilityTracking$ByDirectMixin$HasNoCap cannot be cast to class com.tribbloids.spike.dotty.CapabilityTracking$ByDirectMixin$Cap1 (com.tribbloids.spike.dotty.CapabilityTracking$ByDirectMixin$HasNoCap and com.tribbloids.spike.dotty.CapabilityTracking$ByDirectMixin$Cap1 are in unnamed module of loader 'app')
    at com.tribbloids.spike.dotty.CapabilityTracking$ByDirectMixin$.<clinit>(CapabilityTracking.scala:23)
    ... 2 more

As a result, it appears that the compiler will rely heavily on extension methods (https://www.baeldung.com/scala/extension-methods), which to my knowledge has high overhead and may not be compatible with method override

Is there a method that allows me to bypass this limitation? Or it is simply impossible under current architecture?

0

There are 0 best solutions below