Skip to content

Commit f39943d

Browse files
Merge pull request #4887 from dotty-staging/add-tasty-reflect-subtype-check
Add <:< and =:= to testy reflect Type
2 parents 48a4daa + 5e742fa commit f39943d

File tree

5 files changed

+101
-0
lines changed

5 files changed

+101
-0
lines changed

compiler/src/dotty/tools/dotc/tastyreflect/TastyImpl.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -769,6 +769,12 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty { s
769769
// ----- Types ----------------------------------------------------
770770

771771
type Type = Types.Type
772+
773+
def TypeDeco(tpe: Type): TypeAPI = new TypeAPI {
774+
def =:=(other: Type)(implicit ctx: Context): Boolean = tpe =:= other
775+
def <:<(other: Type)(implicit ctx: Context): Boolean = tpe <:< other
776+
}
777+
772778
type RecursiveType = Types.RecType
773779
type LambdaType[ParamInfo <: TypeOrBounds] = Types.LambdaType { type PInfo = ParamInfo }
774780
type MethodType = Types.MethodType

library/src/scala/tasty/Tasty.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,12 @@ abstract class Tasty { tasty =>
591591

592592
type Type <: TypeOrBounds
593593

594+
trait TypeAPI {
595+
def =:=(other: Type)(implicit ctx: Context): Boolean
596+
def <:<(other: Type)(implicit ctx: Context): Boolean
597+
}
598+
implicit def TypeDeco(tpe: Type): TypeAPI
599+
594600
type RecursiveType <: Type
595601

596602
type LambdaType[ParamInfo <: TypeOrBounds] <: Type

tests/run/tasty-subtyping.check

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
true
2+
true
3+
true
4+
true
5+
true
6+
7+
false
8+
false
9+
false
10+
false
11+
false
12+
13+
true
14+
true
15+
true
16+
true
17+
true
18+
true
19+
20+
false
21+
false
22+
false
23+
false
24+
false
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import scala.quoted._
2+
3+
import scala.tasty._
4+
5+
object Macros {
6+
7+
transparent def isTypeEqual[T, U]: Boolean =
8+
~isTypeEqualImpl('[T], '[U])(TopLevelSplice.tastyContext) // FIXME infer TopLevelSplice.tastyContext within top level ~
9+
10+
transparent def isSubTypeOf[T, U]: Boolean =
11+
~isSubTypeOfImpl('[T], '[U])(TopLevelSplice.tastyContext) // FIXME infer TopLevelSplice.tastyContext within top level ~
12+
13+
def isTypeEqualImpl[T, U](t: Type[T], u: Type[U])(implicit tasty: Tasty): Expr[Boolean] = {
14+
import tasty._
15+
val isTypeEqual = t.toTasty.tpe =:= u.toTasty.tpe
16+
isTypeEqual.toExpr
17+
}
18+
19+
def isSubTypeOfImpl[T, U](t: Type[T], u: Type[U])(implicit tasty: Tasty): Expr[Boolean] = {
20+
import tasty._
21+
val isTypeEqual = t.toTasty.tpe <:< u.toTasty.tpe
22+
isTypeEqual.toExpr
23+
}
24+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
2+
import Macros._
3+
4+
object Test {
5+
type A
6+
type B <: A
7+
8+
def main(args: Array[String]): Unit = {
9+
// true
10+
println(isTypeEqual[Int, Int])
11+
println(isTypeEqual[String, String])
12+
println(isTypeEqual[Test.type, Test.type])
13+
println(isTypeEqual[2, 2])
14+
println(isTypeEqual[A, A])
15+
println()
16+
17+
// false
18+
println(isTypeEqual[Int, Double])
19+
println(isTypeEqual[String, Int])
20+
println(isTypeEqual[Test.type, Macros.type])
21+
println(isTypeEqual[2, 1])
22+
println(isTypeEqual[A, B])
23+
println()
24+
25+
// true
26+
println(isSubTypeOf[Int, Int])
27+
println(isSubTypeOf[String, Object])
28+
println(isSubTypeOf[Int, AnyVal])
29+
println(isSubTypeOf[AnyRef, Any])
30+
println(isSubTypeOf[AnyVal, Any])
31+
println(isSubTypeOf[B, A])
32+
println()
33+
34+
// false
35+
println(isSubTypeOf[Object, Int])
36+
println(isSubTypeOf[AnyVal, Int])
37+
println(isSubTypeOf[Any, AnyRef])
38+
println(isSubTypeOf[Any, AnyVal])
39+
println(isSubTypeOf[A, B])
40+
}
41+
}

0 commit comments

Comments
 (0)