Skip to content

Commit 4b5bd1f

Browse files
committed
Add post-condidtion to CheckPhantomCast
1 parent 9c15214 commit 4b5bd1f

File tree

1 file changed

+14
-7
lines changed

1 file changed

+14
-7
lines changed

compiler/src/dotty/tools/dotc/transform/CheckPhantomCast.scala

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)