Open
Description
While reviewing my thesis, Oleg Kiselyov pointed out a subtlety in the interaction of GADTs with staging in MetaOCaml: GADT constraints should be marked by stage to prevent the use of future-stage constraints in the current stage, which would be unsound. He gave the following example, which is a test in the MetaOCaml distribution:
type _ t = T : string t
let f : type a. a t option code -> a -> unit code =
fun c x -> .< match .~c with
| None -> ()
| Some T -> .~(print_endline x; .<()>.) >.
let _ = f .< None >. 0
(As an answer to the problem, MetaOCaml rejects pattern-matches of GADTs within quotes, so that does not compile.)
Sure enough, we can reproduce something similar in Scala, without even having to use a GADT, since Scala has first-class support for subtype evidence:
scala> import scala.quoted.staging._
scala> given Toolbox = Toolbox.make(getClass.getClassLoader)
def given_Toolbox: quoted.staging.Toolbox
scala> trait T { type A >: Any <: Nothing }
// defined trait T
scala> withQuoteContext { '{ (x: T) => ${ 42: x.A } } }
java.lang.ClassCastException: java.base/java.lang.Integer cannot be cast to scala.runtime.Nothing$