Skip to content

Commit 568dbec

Browse files
committed
Fix #7204: Use evidence based type testing for unapplies
1 parent 3cb93f3 commit 568dbec

File tree

15 files changed

+718
-568
lines changed

15 files changed

+718
-568
lines changed

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

Lines changed: 291 additions & 176 deletions
Large diffs are not rendered by default.

library/src-bootstrapped/scala/tasty/reflect/TreeUtils.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ trait TreeUtils
7171
foldTrees(foldTrees(foldTrees(foldTrees(foldTree(x, constr), parents), derived), self), body)
7272
case Import(expr, _) =>
7373
foldTree(x, expr)
74-
case IsPackageClause(clause @ PackageClause(pid, stats)) =>
74+
case clause @ PackageClause(pid, stats) =>
7575
foldTrees(foldTree(x, pid), stats)(given clause.symbol.localContext)
7676
case Inferred() => x
7777
case TypeIdent(_) => x

library/src/scala/tasty/reflect/CompilerInterface.scala

Lines changed: 54 additions & 54 deletions
Large diffs are not rendered by default.
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package scala.tasty
2+
package reflect
3+
/* FIXME Using class tags to type tests abstract type members in unsound
4+
5+
```
6+
trait R {
7+
type Nat
8+
type Succ <: Nat
9+
type Idx
10+
given ClassTag[Nat]
11+
given ClassTag[Succ]
12+
given ClassTag[Z]
13+
def n: Nat
14+
}
15+
object RI extens R {
16+
type Nat = Int
17+
type Succ = Int
18+
type Idx = Int
19+
given ClassTag[Nat] = classOf[Integer]
20+
given ClassTag[Succ] = new ClassTag[Integer] {
21+
def runtimeClass = classOf[Integer]
22+
def unapply(x: Any): Option[Succ] = x match
23+
case n: Int if n > 0 => Some(n)
24+
case _ => None
25+
}
26+
given ClassTag[Idx] = classOf[Integer]
27+
def n: Nat = 4
28+
}
29+
val r1: R = RI
30+
val r2: R = RI
31+
r1.x match {
32+
case x: r2.Nat => // Should not match or should have an unchecked waring
33+
case x: r1.Idx => // Should not match or should have an unchecked waring
34+
case x: r1.Succ => // Should match only if r1.x is an r1.Succ under the constraints set in r1
35+
}
36+
```
37+
*/
38+
/** Place holder until we implement a ClassTag like abstraction that is sound for all type tests */
39+
type IsInstanceOf[T] = scala.reflect.ClassTag[T]

0 commit comments

Comments
 (0)