aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-08-23 16:15:46 +0200
committerMartin Odersky <odersky@gmail.com>2013-08-23 16:16:14 +0200
commit7b8000914abe73883052b1d8af356f91cc133806 (patch)
treeeca9fd3178e13c65c61dd9ff19f7953c11814a21 /src/dotty/tools
parent66a176bea94205469851fdb4fab46c2589fba407 (diff)
downloaddotty-7b8000914abe73883052b1d8af356f91cc133806.tar.gz
dotty-7b8000914abe73883052b1d8af356f91cc133806.tar.bz2
dotty-7b8000914abe73883052b1d8af356f91cc133806.zip
Fixes expansion and general handling of pattern defs.
Diffstat (limited to 'src/dotty/tools')
-rw-r--r--src/dotty/tools/dotc/ast/Desugar.scala103
-rw-r--r--src/dotty/tools/dotc/ast/UntypedTrees.scala2
-rw-r--r--src/dotty/tools/dotc/core/Types.scala4
-rw-r--r--src/dotty/tools/dotc/typer/Namer.scala12
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala4
5 files changed, 66 insertions, 59 deletions
diff --git a/src/dotty/tools/dotc/ast/Desugar.scala b/src/dotty/tools/dotc/ast/Desugar.scala
index 047a60814..ccb99290a 100644
--- a/src/dotty/tools/dotc/ast/Desugar.scala
+++ b/src/dotty/tools/dotc/ast/Desugar.scala
@@ -232,11 +232,53 @@ object desugar {
Thicket(modul, cls)
}
- def memberDef(tree: Tree)(implicit ctx: Context): Tree = tree match {
+ def patDef(pdef: PatDef)(implicit ctx: Context): Tree = {
+ val PatDef(mods, pats, tpt, rhs) = pdef
+ val pats1 = if (tpt.isEmpty) pats else pats map (Typed(_, tpt))
+ flatTree(pats1 map (makePatDef(mods, _, rhs)))
+ }
+
+ def defTree(tree: Tree)(implicit ctx: Context): Tree = tree match {
case tree: ValDef => valDef(tree)
case tree: TypeDef => if (tree.isClassDef) classDef(tree) else typeDef(tree)
case tree: DefDef => defDef(tree)
case tree: ModuleDef => moduleDef(tree)
+ case tree: PatDef => patDef(tree)
+ }
+
+ /** In case there is exactly one variable x_1 in pattern
+ * val/var p = e ==> val/var x_1 = (e: @unchecked) match (case p => (x_1))
+ *
+ * in case there are zero or more than one variables in pattern
+ * val/var p = e ==> private synthetic val t$ = (e: @unchecked) match (case p => (x_1, ..., x_N))
+ * val/var x_1 = t$._1
+ * ...
+ * val/var x_N = t$._N
+ * If the original pattern variable carries a type annotation, so does the corresponding
+ * ValDef.
+ */
+ def makePatDef(mods: Modifiers, pat: Tree, rhs: Tree)(implicit ctx: Context): Tree = pat match {
+ case VarPattern(named, tpt) =>
+ derivedValDef(mods, named, tpt, rhs)
+ case _ =>
+ val rhsUnchecked = makeAnnotated(defn.UncheckedAnnot, rhs)
+ val vars = getVariables(pat)
+ val ids = for ((named, _) <- vars) yield Ident(named.name)
+ val caseDef = CaseDef(pat, EmptyTree, makeTuple(ids))
+ val matchExpr = Match(rhsUnchecked, caseDef :: Nil)
+ vars match {
+ case (named, tpt) :: Nil =>
+ derivedValDef(mods, named, tpt, matchExpr)
+ case _ =>
+ val tmpName = ctx.freshName().toTermName
+ val patMods = Modifiers(PrivateLocal | Synthetic | (mods.flags & Lazy))
+ val firstDef = ValDef(patMods, tmpName, TypeTree(), matchExpr)
+ def selector(n: Int) = Select(Ident(tmpName), ("_" + n).toTermName)
+ val restDefs =
+ for (((named, tpt), n) <- vars.zipWithIndex)
+ yield derivedValDef(mods, named, tpt, selector(n))
+ flatTree(firstDef :: restDefs)
+ }
}
/** Make closure corresponding to function params => body */
@@ -251,6 +293,12 @@ object desugar {
Function(param :: Nil, Match(Ident(param.name), cases))
}
+ def makeAnnotated(cls: Symbol, tree: Tree)(implicit ctx: Context) =
+ Annotated(TypedSplice(tpd.New(cls.typeConstructor)), tree)
+
+ private def derivedValDef(mods: Modifiers, named: NameTree, tpt: Tree, rhs: Tree) =
+ ValDef(mods, named.name.asTermName, tpt, rhs).withPos(named.pos)
+
def apply(tree: Tree)(implicit ctx: Context): Tree = {
def labelDefAndCall(lname: TermName, rhs: Tree, call: Tree) = {
@@ -258,9 +306,6 @@ object desugar {
Block(ldef, call)
}
- def derivedValDef(mods: Modifiers, named: NameTree, tpt: Tree, rhs: Tree) =
- ValDef(mods, named.name.asTermName, tpt, rhs).withPos(named.pos)
-
/** Translate infix operation expression left op right
*/
def makeBinop(left: Tree, op: Name, right: Tree): Tree = {
@@ -418,50 +463,6 @@ object desugar {
}
}
- def makeAnnotated(cls: Symbol, tree: Tree) =
- Annotated(TypedSplice(tpd.New(cls.typeConstructor)), tree)
-
- /** Returns list of all pattern variables, possibly with their types,
- * without duplicates
- */
- def getVariables(tree: Tree): List[VarInfo] =
- getVars(new ListBuffer[VarInfo], tree).toList
-
- /** In case there is exactly one variable x_1 in pattern
- * val/var p = e ==> val/var x_1 = (e: @unchecked) match (case p => (x_1))
- *
- * in case there are zero or more than one variables in pattern
- * val/var p = e ==> private synthetic val t$ = (e: @unchecked) match (case p => (x_1, ..., x_N))
- * val/var x_1 = t$._1
- * ...
- * val/var x_N = t$._N
- * If the original pattern variable carries a type annotation, so does the corresponding
- * ValDef.
- */
- def makePatDef(mods: Modifiers, pat: Tree, rhs: Tree): Tree = pat match {
- case VarPattern(named, tpt) =>
- derivedValDef(mods, named, tpt, rhs)
- case _ =>
- val rhsUnchecked = makeAnnotated(defn.UncheckedAnnot, rhs)
- val vars = getVariables(pat)
- val ids = for ((named, _) <- vars) yield Ident(named.name)
- val caseDef = CaseDef(pat, EmptyTree, makeTuple(ids))
- val matchExpr = Match(rhsUnchecked, caseDef :: Nil)
- vars match {
- case (named, tpt) :: Nil =>
- derivedValDef(mods, named, tpt, matchExpr)
- case _ =>
- val tmpName = ctx.freshName().toTermName
- val patMods = Modifiers(PrivateLocal | Synthetic | (mods.flags & Lazy))
- val firstDef = ValDef(patMods, tmpName, TypeTree(), matchExpr)
- def selector(n: Int) = Select(Ident(tmpName), ("_" + n).toTermName)
- val restDefs =
- for (((named, tpt), n) <- vars.zipWithIndex)
- yield derivedValDef(mods, named, tpt, selector(n))
- flatTree(firstDef :: restDefs)
- }
- }
-
// begin desugar
tree match {
case SymbolLit(str) =>
@@ -555,4 +556,10 @@ object desugar {
}
}
}
+
+ /** Returns list of all pattern variables, possibly with their types,
+ * without duplicates
+ */
+ private def getVariables(tree: Tree): List[VarInfo] =
+ getVars(new ListBuffer[VarInfo], tree).toList
}
diff --git a/src/dotty/tools/dotc/ast/UntypedTrees.scala b/src/dotty/tools/dotc/ast/UntypedTrees.scala
index d7e0a7b3d..6ad547dc9 100644
--- a/src/dotty/tools/dotc/ast/UntypedTrees.scala
+++ b/src/dotty/tools/dotc/ast/UntypedTrees.scala
@@ -38,7 +38,7 @@ object untpd extends Trees.Instance[Untyped] with TreeInfo[Untyped] {
case class GenFrom(pat: Tree, expr: Tree) extends Tree
case class GenAlias(pat: Tree, expr: Tree) extends Tree
case class ContextBounds(bounds: TypeBoundsTree, cxBounds: List[Tree]) extends TypTree
- case class PatDef(mods: Modifiers, pats: List[Tree], tpt: Tree, rhs: Tree) extends Tree
+ case class PatDef(mods: Modifiers, pats: List[Tree], tpt: Tree, rhs: Tree) extends DefTree
class PolyTypeDef(mods: Modifiers, name: TypeName, override val tparams: List[TypeDef], rhs: Tree)
extends TypeDef(mods, name, rhs) {
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index b9d079a20..8f10816e9 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -2105,8 +2105,8 @@ object Types {
def apply(tp: Type) = tp
}
- /** Approximate occurrences of paremter types and uninstantiated typevars
- * by wildcard types
+ /** Approximate occurrences of parameter types and uninstantiated typevars
+ * by wildcard types.
*/
class WildApprox(implicit ctx: Context) extends TypeMap {
override def apply(tp: Type) = tp match {
diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala
index 3b1fb4810..5f6a6528f 100644
--- a/src/dotty/tools/dotc/typer/Namer.scala
+++ b/src/dotty/tools/dotc/typer/Namer.scala
@@ -59,12 +59,12 @@ class Namer { typer: Typer =>
import untpd._
- /** A partial map from unexpanded member defs to their expansions.
+ /** A partial map from unexpanded member and pattern defs and to their expansions.
* Populated during enterSyms, emptied during typer.
*/
- lazy val expandedTree = new mutable.HashMap[MemberDef, Tree]
+ lazy val expandedTree = new mutable.HashMap[DefTree, Tree]
- /** A map from expanded MemberDef or Import trees to their symbols.
+ /** A map from expanded MemberDef, PatDef or Import trees to their symbols.
* Populated during enterSyms, emptied at the point a typed tree
* with the same symbol is created (this can be when the symbol is completed
* or at the latest when the tree is typechecked.
@@ -187,8 +187,8 @@ class Namer { typer: Typer =>
}
/** The expansion of a member def */
- def expansion(mdef: MemberDef)(implicit ctx: Context): Tree = {
- val expanded = desugar.memberDef(mdef)
+ def expansion(mdef: DefTree)(implicit ctx: Context): Tree = {
+ val expanded = desugar.defTree(mdef)
if (expanded ne mdef) expandedTree(mdef) = expanded
expanded
}
@@ -215,7 +215,7 @@ class Namer { typer: Typer =>
ctx
case imp: Import =>
importContext(createSymbol(imp), imp.selectors)
- case mdef: MemberDef =>
+ case mdef: DefTree =>
expansion(mdef).toList foreach (tree => enterSymbol(createSymbol(tree)))
ctx
case _ =>
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index c693209f4..8bd5c6975 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -754,7 +754,7 @@ class Typer extends Namer with Applications with Implicits {
cpy.Typed(tree, arg1, TypeTree(ownType)) withType ownType
}
- def typedPackageDef(tree: untpd.PackageDef)(implicit ctx: Context): Tree = {
+ def typedPackageDef(tree: untpd.PackageDef)(implicit ctx: Context): Tree = {
val pid1 = typedExpr(tree.pid, AnySelectionProto)
val pkg = pid1.symbol
val packageContext =
@@ -845,7 +845,7 @@ class Typer extends Namer with Applications with Implicits {
val imp1 = typed(imp)
buf += imp1
traverse(rest)(importContext(imp1.symbol, imp.selectors))
- case (mdef: untpd.MemberDef) :: rest =>
+ case (mdef: untpd.DefTree) :: rest =>
expandedTree remove mdef match {
case Some(xtree) =>
traverse(xtree :: rest)