@@ -16,6 +16,14 @@ class CheckPhantomCast extends MiniPhaseTransform { thisTransformer =>
16
16
17
17
override def phaseName = " checkPhantomCast"
18
18
19
+ override def checkPostCondition (tree : tpd.Tree )(implicit ctx : Context ): Unit = {
20
+ tree match {
21
+ case TypeApply (fun, targs) if fun.symbol eq defn.Any_asInstanceOf => assert(! containsPhantom(targs.head.tpe))
22
+ case Bind (_, Typed (_, tpt)) => assert(! containsPhantom(tpt.tpe))
23
+ case _ =>
24
+ }
25
+ }
26
+
19
27
override def transformTypeApply (tree : tpd.TypeApply )(implicit ctx : Context , info : TransformerInfo ): tpd.Tree = {
20
28
if (tree.fun.symbol eq defn.Any_asInstanceOf )
21
29
checkNoPhantoms(tree.args.head)
@@ -31,13 +39,12 @@ class CheckPhantomCast extends MiniPhaseTransform { thisTransformer =>
31
39
}
32
40
33
41
private def checkNoPhantoms (tpTree : tpd.Tree )(implicit ctx : Context ): Unit = {
34
- val checker = new TypeTraverser () {
35
- override def traverse (tp : Type ): Unit = {
36
- if (tp.isPhantom) ctx.error(" Cannot cast type containing a phantom type" , tpTree.pos)
37
- else traverseChildren(tp)
38
- }
39
- }
40
- checker.traverse(tpTree.tpe)
42
+ if (containsPhantom(tpTree.tpe))
43
+ ctx.error(" Cannot cast type containing a phantom type" , tpTree.pos)
41
44
}
42
45
46
+ private def containsPhantom (tp : Type )(implicit ctx : Context ): Boolean = new TypeAccumulator [Boolean ] {
47
+ override def apply (x : Boolean , tp : Type ): Boolean = x || tp.isPhantom || foldOver(false , tp)
48
+ }.apply(x = false , tp)
49
+
43
50
}
0 commit comments