0

I want to determine whether expressions represented by syntax trees tree1 and tree2 are of the same type. I tried to do so using type checking method from scala.tools.reflect.ToolBox, but it seems to be inconsistent with the actual Scala types.

Here I create the toolbox:

scala> val tb = runtimeMirror(getClass.getClassLoader).mkToolBox()
tb: scala.tools.reflect.ToolBox[reflect.runtime.universe.type] 
              = scala.tools.reflect.ToolBoxFactory$ToolBoxImpl@1ad29bfd

It reports type inequality:

scala> tb.typecheck(tree1).tpe =:= tb.typecheck(tree2).tpe
res81: Boolean = false

I ask for the types' representation:

scala> tb.typecheck(tree1).tpe
res82: tb.u.Type = st1 with st2{val x: X; val y: Y}

scala> tb.typecheck(tree2).tpe
res83: tb.u.Type = scala.AnyRef{val x: X; val y: Y}

Now these types successfully unified:

scala> implicitly[st1 with st2{val x: X; val y: Y} =:= scala.AnyRef{val x: X; val y: Y}]
res84: =:=[st1 with st2{val x: X; val y: Y},AnyRef{val x: X; val y: Y}] = <function1>

Can I somehow check if tree1 and tree2 represent expressions of similar types as it is done in the last snippet?

Edit: minimal definitions

trait X 
trait Y 

type st1 = { val x: X } 
type st2 = { val y: Y } 
val s1: st1 = new { val x: X = new X {} } 
val s2: st2 = new { val y: Y = new Y {} } 

def foo(s1: st1, s2: st2): st1 with st2 { val x: X; val y: Y } = ??? 
val pure = new { val x: X = new X {}; val y: Y = new Y {}} 

val tree1 = reify { foo(s1, s2) }.tree 
val tree2 = reify { pure }.tree
oquechy
  • 51
  • 4

1 Answers1

0

Try

val typ1 = tb.typecheck(tree1).tpe
val typ2 = tb.typecheck(tree2).tpe

tb.typecheck(q"implicitly[$typ1 =:= $typ2]")

or, which is the same,

tb.typecheck(q"_root_.scala.Predef.implicitly[_root_.scala.Predef.=:=[$typ1, $typ2]]")

Or try

tb.inferImplicitValue(tb.typecheck(tq"$typ1 =:= $typ2", mode = tb.TYPEmode).tpe, silent = false)

Or try

implicit class TypeOps(tp1: Type) {
  def =::= (tp2: Type): Boolean = tp1 <:< tp2 && tp2 <:< tp1
}

typ1 =::= typ2 // true
Dmytro Mitin
  • 48,194
  • 3
  • 28
  • 66