diff options
author | Martin Odersky <odersky@gmail.com> | 2014-09-06 11:35:07 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2014-09-06 11:36:35 +0200 |
commit | b58b90683652e1b6e2c32412f0a03ba614b61b33 (patch) | |
tree | b86490f67c73d5d91bcc54f691469812f6b88a73 /src/dotty/tools/dotc/transform/Erasure.scala | |
parent | e1040935cbcc1d767933c38a141372538ef63ac2 (diff) | |
download | dotty-b58b90683652e1b6e2c32412f0a03ba614b61b33.tar.gz dotty-b58b90683652e1b6e2c32412f0a03ba614b61b33.tar.bz2 dotty-b58b90683652e1b6e2c32412f0a03ba614b61b33.zip |
Generalize phase postcondition checking.
Have a general way how a phase can establish a postcondition which will be
checked each time a later phase is tree-checked.
Moves erasure constraints from TreeChecker to Erasure's post condition.
Diffstat (limited to 'src/dotty/tools/dotc/transform/Erasure.scala')
-rw-r--r-- | src/dotty/tools/dotc/transform/Erasure.scala | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/src/dotty/tools/dotc/transform/Erasure.scala b/src/dotty/tools/dotc/transform/Erasure.scala index fe5e516bf..f9e48ac5d 100644 --- a/src/dotty/tools/dotc/transform/Erasure.scala +++ b/src/dotty/tools/dotc/transform/Erasure.scala @@ -71,6 +71,37 @@ class Erasure extends Phase with DenotTransformer { thisTransformer => val unit = ctx.compilationUnit unit.tpdTree = eraser.typedExpr(unit.tpdTree)(ctx.fresh.setPhase(this.next)) } + + override def checkPostCondition(tree: tpd.Tree)(implicit ctx: Context) = { + assertErased(tree) + tree match { + case res: tpd.This => + assert(!ExplicitOuter.referencesOuter(ctx.owner.enclosingClass, res), + i"Reference to $res from ${ctx.owner.showLocated}") + case _ => + } + } + + /** Assert that tree type and its widened underlying type are erased. + * Also assert that term refs have fixed symbols (so we are sure + * they need not be reloaded using member; this would likely fail as signatures + * may change after erasure). + */ + def assertErased(tree: tpd.Tree)(implicit ctx: Context): Unit = { + assertErased(tree.typeOpt, tree) + if (!(tree.symbol == defn.Any_isInstanceOf || tree.symbol == defn.Any_asInstanceOf)) + assertErased(tree.typeOpt.widen, tree) + if (ctx.mode.isExpr) + tree.tpe match { + case ref: TermRef => + assert(ref.denot.isInstanceOf[SymDenotation], + i"non-sym type $ref of class ${ref.getClass} with denot of class ${ref.denot.getClass} of $tree") + case _ => + } + } + + def assertErased(tp: Type, tree: tpd.Tree = tpd.EmptyTree)(implicit ctx: Context): Unit = + assert(isErasedType(tp), i"The type $tp - ${tp.toString} of class ${tp.getClass} of tree $tree / ${tree.getClass} is illegal after erasure, phase = ${ctx.phase}") } object Erasure { |