Skip to content

Commit

Permalink
Address exhaustiveness warnings when matching on Trees.
Browse files Browse the repository at this point in the history
 - Introduce a marker trait for Tree[Nothing] nodes,
   and use this in TreeAccumulator.
 - seal GenericApply
 - Make the match demo plugin transformer @unchecked
 - Add tree checking for Try
 - Match on EmptyTree() rather than tpd.EmptyTree
  • Loading branch information
retronym committed Feb 23, 2013
1 parent 717f690 commit 4598e8c
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 9 deletions.
2 changes: 1 addition & 1 deletion src/dotty/tools/dotc/core/PluggableTransformers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ object PluggableTransformers {
case _ => postProcess(tree, old, c, plugins)
}

protected def postProcess(tree: Tree[T], old: Tree[T], c: Context, plugins: Plugins): Tree[T] = tree match {
protected def postProcess(tree: Tree[T], old: Tree[T], c: Context, plugins: Plugins): Tree[T] = (tree: @unchecked) match {
case tree: Ident[_] => finishIdent(tree, old, c, plugins)
case tree: Select[_] => finishSelect(tree, old, c, plugins)
}
Expand Down
23 changes: 16 additions & 7 deletions src/dotty/tools/dotc/core/Trees.scala
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ object Trees {
def forwardTo = qual
}

abstract class GenericApply[T] extends ProxyTree[T] with TermTree[T] {
sealed abstract class GenericApply[T] extends ProxyTree[T] with TermTree[T] {
type ThisTree[T] <: GenericApply[T]
val fun: Tree[T]
val args: List[Tree[T]]
Expand Down Expand Up @@ -485,7 +485,7 @@ object Trees {
}

/** A missing tree */
abstract case class EmptyTree[T]()
sealed abstract case class EmptyTree[T]()
extends Tree[T] with AlwaysEmpty[T] {
type ThisTree[T] = EmptyTree[T]
}
Expand All @@ -496,7 +496,7 @@ object Trees {
def apply[T]: EmptyTree[T] = theEmptyTree.asInstanceOf
}

abstract class EmptyValDef[T] extends ValDef[T](
sealed abstract class EmptyValDef[T] extends ValDef[T](
Modifiers[T](Private), nme.WILDCARD, EmptyTree[T], EmptyTree[T])(NoPosition) with AlwaysEmpty[T]

private object theEmptyValDef extends EmptyValDef[Nothing]
Expand All @@ -506,7 +506,7 @@ object Trees {
}

/** A tree that can be shared without its position
* polluting containing trees. Accumulators and tranformers
* polluting containing trees. Accumulators and transformers
* memoize results of shared subtrees
*/
final case class Shared[T](shared: Tree[T]) extends Tree[T] {
Expand All @@ -518,20 +518,25 @@ object Trees {

// ----- Tree cases that exist in untyped form only ------------------

/** A marker trait for all Tree[Nothing] descendants. Useful for exhaustively pattern matching over Tree[U] */
sealed trait UntypedTreeMarker {
self: UntypedTree =>
}

/** A typed subtree of an untyped tree needs to be wrapped in a TypedSlice */
final class TypedSplice(tree: TypedTree) extends UntypedTree {
final class TypedSplice(tree: TypedTree) extends UntypedTree with UntypedTreeMarker {
val pos = tree.pos
}

/** mods object name impl */
final case class ModuleDef(mods: Modifiers[Nothing], name: TermName, impl: Template[Nothing])(implicit cpos: Position)
extends DefTree[Nothing] {
extends DefTree[Nothing] with UntypedTreeMarker {
val pos = cpos union impl.pos
}

/** (vparams) => body */
final case class Function(vparams: List[ValDef[Nothing]], body: Tree[Nothing])(implicit cpos: Position)
extends TermTree[Nothing] {
extends TermTree[Nothing] with UntypedTreeMarker {
val pos = unionPos(cpos union body.pos, vparams)
}

Expand Down Expand Up @@ -800,6 +805,8 @@ object Trees {
tree1
},
tree, c, plugins)
case _: UntypedTreeMarker =>
tree // TODO should this abort?
}
def transform(trees: List[Tree[T]], c: C): List[Tree[T]] =
trees mapConserve (transform(_, c))
Expand Down Expand Up @@ -948,6 +955,8 @@ object Trees {
sharedMemo = sharedMemo.updated(tree, x1)
x1
}
case _: UntypedTreeMarker =>
x
}
}
}
8 changes: 7 additions & 1 deletion src/dotty/tools/dotc/core/TypedTrees.scala
Original file line number Diff line number Diff line change
Expand Up @@ -573,9 +573,15 @@ object TypedTrees {
check(annot.symbol.isClassConstructor)
check(annot.symbol.owner.isSubClass(defn.AnnotationClass))
check(arg.isType || arg.isValue)
case tpd.EmptyTree =>
case Shared(shared) =>
check(shared.isType || shared.isTerm)
case Try(block, catches, finalizer) =>
check(block.isTerm)
check(finalizer.isTerm)
def checkType(t: Tree[Type]) = check(t.tpe <:< tree.tpe)
checkType(block)
catches foreach checkType
case EmptyTree() =>
}

implicit class TreeInfo(val tree: tpd.Tree) extends AnyVal {
Expand Down

0 comments on commit 4598e8c

Please sign in to comment.