@@ -16,6 +16,14 @@ class CheckPhantomCast extends MiniPhaseTransform { thisTransformer =>
1616
1717 override def phaseName = " checkPhantomCast"
1818
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+
1927 override def transformTypeApply (tree : tpd.TypeApply )(implicit ctx : Context , info : TransformerInfo ): tpd.Tree = {
2028 if (tree.fun.symbol eq defn.Any_asInstanceOf )
2129 checkNoPhantoms(tree.args.head)
@@ -31,13 +39,12 @@ class CheckPhantomCast extends MiniPhaseTransform { thisTransformer =>
3139 }
3240
3341 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)
4144 }
4245
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+
4350}
0 commit comments