Skip to content

Unreachable case in TypeTest #18052

Open
Open
@bblfish

Description

@bblfish

Compiler version

Following the fix to issue 16408 I tried to use
Scala 3.3.2-RC1-bin-20230623-171849f-NIGHTLY
in the scala3 version of banana-rdf.

Minimized code

I adapted the longer code from 16408 in the unreachableCase branch RDF.scala and was able to duplicate the warning.
The difference as seen in this commit is just the addition of

  • a BNode type
  • a type Subject[R <: RDF] = URI[R] | BNode[R]
  • a given subjToURITT: TypeTest[RDF.Subject[R], RDF.URI[R]]

(the implementations are in terms of traits rather than a class, but that makes no difference anymore).

import scala.util.Try
import scala.reflect.TypeTest

trait RDF:
  rdf =>

  type R = rdf.type
  type Node <: Matchable
  type URI <: Node 
  type BNode <: Node 

  given rops: ROps[R]
end RDF

object RDF:
  type Node[R <: RDF] = R match
    case GetNode[n] => Matchable //n & rNode[R]

  type URI[R <: RDF] <: Node[R] = R match
    case GetURI[u] => u & Node[R] 

  type BNode[R <: RDF] <: Node[R] = R match
    case GetBNode[b] => b & Node[R] 

  type Subject[R <: RDF] = URI[R] | BNode[R]  

  private type GetNode[N] = RDF { type Node = N }
  private type GetURI[U] = RDF { type URI = U }
  private type GetBNode[B] = RDF { type BNode = B }
end RDF

trait ROps[R <: RDF]:
  def mkUri(str: String): Try[RDF.URI[R]]
  def auth(uri: RDF.URI[R]): Try[String]
  given subjToURITT: TypeTest[RDF.Subject[R], RDF.URI[R]]

object TraitTypes:
  trait Node:
    def value: String

  trait Uri extends Node
  trait BNode extends Node
  
  def mkUri(u: String): Uri =
    new Uri { def value = u }

object TraitRDF extends RDF:
  import TraitTypes as tz

  override opaque type Node <: Matchable = tz.Node
  override opaque type URI <: Node = tz.Uri

  given rops: ROps[R] with
    override def mkUri(str: String): Try[RDF.URI[R]] = Try(tz.mkUri(str))
    override def auth(uri: RDF.URI[R]): Try[String] =
      Try(java.net.URI.create(uri.value).getAuthority())

    given subjToURITT: TypeTest[RDF.Subject[R], RDF.URI[R]] with
       override def unapply(s: RDF.Subject[R]): Option[s.type & URI] =
         s match
           case x: (s.type & RDF.URI[R]) => Some(x)
           case _                        => None
  
end TraitRDF

class Test[R <: RDF](using rops: ROps[R]):
  import rops.given
  lazy val uriT: Try[RDF.URI[R]] = rops.mkUri("https://bblfish.net/#i")
  lazy val x: String = "uri authority=" + uriT.map(u => rops.auth(u))

@main def run =
  val test = Test[TraitRDF.type]
  println(test.x)

Output

$ scala-cli compile -j 17 -S 3.nightly scala
Compiling project (Scala 3.3.2-RC1-bin-20230623-171849f-NIGHTLY, JVM)
[warn] ./scala/RDF.scala:62:17
[warn] Unreachable case except for null (if this is intentional, consider writing case null => instead).
[warn]            case _                        => None
[warn]                 ^
Compiled project (Scala 3.3.2-RC1-bin-20230623-171849f-NIGHTLY, JVM)

Expectation

There should be no warning on unreachable case there as clearly the BNode case is possible.

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