Skip to content

ClassCastException when attempting to use structural refinement that returns a value class #19833

Open
@steinybot

Description

@steinybot

Compiler version

3.4.0 Next, 3.3.2 LTS, 2.13.12

Minimized code

//import scala.language.reflectiveCalls
import scala.reflect.Selectable.reflectiveSelectable

class FunctionalComponent[P](val component: P => String) extends AnyVal

object View {
  val component = new FunctionalComponent[String]({ s => "Hello " + s })
}

type FunctionalComponentObject[P] = {
  val component: FunctionalComponent[P]
}

val obj: FunctionalComponentObject[String] = View
val component: FunctionalComponent[String] = obj.component

https://scastie.scala-lang.org/nHksLLQJR8GiiOws7Pt2rA

Output

java.lang.ClassCastException: class Playground$View$$$Lambda$12376/0x00007ff68d5a4208 cannot be cast to class Playground$FunctionalComponent 

Expectation

Ideally this should compile and run without any errors.

Does it need to cast? I would have thought that the compiler has already checked that View conforms to the refinement and so component is already known to be a FunctionalComponent.

If it does need to cast then is there any way for there to be a runtime check to tell whether it is boxed or unboxed? I'm guessing it is assuming that it is boxed when in fact it is not which is why there is a ClassCastException.

I found a lot of old Scala 2 issues such as scala/bug#6336 which seemed to restrict how value classes were used with refinements which seems less than ideal but if that is indeed the only answer it would be better to not compile than compile and fail at runtime.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions