estatico / scala-newtype

NewTypes for Scala with no runtime overhead
Apache License 2.0
540 stars 31 forks source link

How to avoid abstract type pattern is unchecked error? #72

Closed steinybot closed 2 years ago

steinybot commented 2 years ago

Given this reproduction:

import io.estatico.newtype.macros.newsubtype

import scala.scalajs.js.|

object Main extends App {

  @newsubtype final case class Foo[A](unwrap: A)

  @newsubtype final case class Bar[A](unwrap: A)

  def which[A, B](fooOrBar: Foo[A] | Bar[B]) = fooOrBar match {
    case _: Foo[_] => "foo"
    case _: Bar[_] => "bar"
  }
}

How can I avoid this error?

[error] /Users/jason/src/bug-reports/src/main/scala/Main.scala:12:13: abstract type pattern Main.Foo.Type[_] (the underlying of Main.Foo[_]) is unchecked since it is eliminated by erasure
[error]     case _: Foo[_] => "foo"
[error]             ^

Normally in Scala.js we would have to ascribe it as Any to do the match but that doesn't seem necessary here for whatever reason. IntelliJ at least still thinks that this is a fruitless type test so the Any ascription could be cleaner.

I was thinking maybe it has something to do with this comment in #18 although I'm not quite seeing the implications:

Note that when matching on Any compiler warnings will be emitted, so I think that should be enough to clue in users that they're being unsafe.

Is there a workaround, even if it is unsafe?

steinybot commented 2 years ago

Oh I see. This is essentially the same as:

  def which2[A, B](aOrB: A | B) = aOrB match {
    case _: A => "a"
    case _: B => "b"
  }