summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid MacIver <david.maciver@gmail.com>2008-10-29 00:30:23 +0000
committerDavid MacIver <david.maciver@gmail.com>2008-10-29 00:30:23 +0000
commit325e2ba1b1a1d2c05bd8f5981dbbfd00b2c7e2d8 (patch)
treef62edbdfd66b9347b74cf2395bcca0d4329f886c
parent8e4e97ad7882bc8eb8e8dbc13d74fcc1c47a1fa4 (diff)
downloadscala-325e2ba1b1a1d2c05bd8f5981dbbfd00b2c7e2d8.tar.gz
scala-325e2ba1b1a1d2c05bd8f5981dbbfd00b2c7e2d8.tar.bz2
scala-325e2ba1b1a1d2c05bd8f5981dbbfd00b2c7e2d8.zip
Modifications to pattern matching to allow the ...
Modifications to pattern matching to allow the threading of a Typer all the way through. This is in aid of fixing bug #1087. It doesn't actually fix it, but it makes the error message produces a little more enlightening. That's something. :) (It also seems this is a neccessary change for correctness with respect to the typechecker anyway).
-rw-r--r--src/compiler/scala/tools/nsc/matching/CodeFactory.scala36
-rw-r--r--src/compiler/scala/tools/nsc/matching/ParallelMatching.scala39
-rw-r--r--src/compiler/scala/tools/nsc/matching/TransMatcher.scala12
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala33
4 files changed, 53 insertions, 67 deletions
diff --git a/src/compiler/scala/tools/nsc/matching/CodeFactory.scala b/src/compiler/scala/tools/nsc/matching/CodeFactory.scala
index b599572fb8..ca44b5609e 100644
--- a/src/compiler/scala/tools/nsc/matching/CodeFactory.scala
+++ b/src/compiler/scala/tools/nsc/matching/CodeFactory.scala
@@ -15,18 +15,18 @@ import scala.tools.nsc.util.Position
trait CodeFactory {
self: transform.ExplicitOuter with PatternNodes =>
- import global._
+ import global.{typer => _, _}
+ import analyzer.Typer;
import definitions._ // standard classes and methods
- import typer.typed // methods to type trees
import posAssigner.atPos // for filling in tree positions
final def mkIdent(sym:Symbol) = Ident(sym) setType sym.tpe
- final def typedValDef(x:Symbol, rhs:Tree) = {
+ final def typedValDef(x:Symbol, rhs:Tree)(implicit typer : Typer) = {
x.tpe match {
- case WildcardType => rhs.setType(null); val rhs1 = typed(rhs); x setInfo rhs1.tpe; typed{ValDef(x, rhs)}
- case _ => typed{ValDef(x, typed(rhs, x.tpe))}
+ case WildcardType => rhs.setType(null); val rhs1 = typer.typed(rhs); x setInfo rhs1.tpe; typer.typed{ValDef(x, rhs)}
+ case _ => typer.typed{ValDef(x, typer.typed(rhs, x.tpe))}
}
}
@@ -35,9 +35,9 @@ trait CodeFactory {
/**
* Convert a pattern binding into a list of value definitions.
*/
- final def targetParams(subst:Binding):List[ValDef] = subst match {
+ final def targetParams(subst:Binding)(implicit typer : Typer):List[ValDef] = subst match {
case NoBinding => Nil;
- case Binding(v,t,n) => ValDef(v, typed(mkIdent(t)))::targetParams(n)
+ case Binding(v,t,n) => ValDef(v, typer.typed(mkIdent(t)))::targetParams(n)
}
/** returns A for T <: Sequence[ A ]
@@ -59,16 +59,16 @@ trait CodeFactory {
}
/** for tree of sequence type, returns tree that drops first i elements */
- final def seqDrop(sel:Tree, ix: Int) = if (ix == 0) sel else
- typed { Select(Apply(Select(sel, nme.drop), List(Literal(Constant(ix)))), nme.toSeq) }
+ final def seqDrop(sel:Tree, ix: Int)(implicit typer : Typer) = if (ix == 0) sel else
+ typer.typed { Select(Apply(Select(sel, nme.drop), List(Literal(Constant(ix)))), nme.toSeq) }
/** for tree of sequence type, returns tree that drops first i elements */
- final def seqElement(sel:Tree, ix: Int) =
- typed { Apply(Select(sel, sel.tpe.member(nme.apply)), List(Literal(Constant(ix)))) }
+ final def seqElement(sel:Tree, ix: Int)(implicit typer : Typer) =
+ typer.typed { Apply(Select(sel, sel.tpe.member(nme.apply)), List(Literal(Constant(ix)))) }
/** for tree of sequence type, returns boolean tree testing that the sequence has length i */
- final def seqHasLength(sel: Tree, ntpe: Type, i: Int) =
- typed(
+ final def seqHasLength(sel: Tree, ntpe: Type, i: Int)(implicit typer : Typer) =
+ typer.typed(
Equals(
Apply(Select(sel, ntpe.member(nme.lengthCompare)), List(Literal(Constant(i)))),
Literal(Constant(0))
@@ -77,10 +77,10 @@ trait CodeFactory {
/** for tree of sequence type sel, returns boolean tree testing that length >= i
*/
- final def seqLongerThan(sel:Tree, tpe:Type, i:Int) =
+ final def seqLongerThan(sel:Tree, tpe:Type, i:Int)(implicit typer : Typer) =
GreaterThanOrEquals(
- typed(Apply(Select(sel, tpe.member(nme.lengthCompare)), List(Literal(Constant(i))))),
- typed(Literal(Constant(0))))
+ typer.typed(Apply(Select(sel, tpe.member(nme.lengthCompare)), List(Literal(Constant(i))))),
+ typer.typed(Literal(Constant(0))))
//defs.Seq_length instead of tpe.member ?
final def Not(arg:Tree) = arg match {
@@ -119,8 +119,8 @@ trait CodeFactory {
))))
}
- final def NotNull(tree:Tree) =
- typed {
+ final def NotNull(tree:Tree)(implicit typer : Typer) =
+ typer.typed {
Apply(Select(tree, nme.ne), List(Literal(Constant(null))))
}
diff --git a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
index 856cc44e74..b21dd75c6d 100644
--- a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
+++ b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
@@ -28,8 +28,8 @@ import collection.immutable.IntMap
trait ParallelMatching {
self: transform.ExplicitOuter with PatternNodes with CodeFactory =>
- import global._
- import typer.typed
+ import global.{typer => _, _}
+ import analyzer.Typer;
import symtab.Flags
// used as argument to `EqualsPatternClass'
@@ -106,6 +106,7 @@ trait ParallelMatching {
sealed abstract class RuleApplication(rep: RepFactory) {
def scrutinee:Symbol
+ implicit def typer = rep.typer;
// used in MixEquals and MixSequence
final protected def repWithoutHead(col: List[Tree],rest: Rep)(implicit theOwner: Symbol): Rep = {
@@ -126,12 +127,12 @@ trait ParallelMatching {
case class VariableRule(subst:Binding, guard: Tree, guardedRest:Rep, bx: Int)(implicit rep:RepFactory) extends RuleApplication(rep) {
def scrutinee:Symbol = throw new RuntimeException("this never happens")
final def tree(implicit theOwner: Symbol, failTree: Tree): Tree = {
- val body = typed { rep.requestBody(bx, subst) }
+ val body = typer.typed { rep.requestBody(bx, subst) }
if (guard eq EmptyTree)
return body
val vdefs = targetParams(subst)
val typedElse = repToTree(guardedRest)
- val typedIf = typed { If(guard.duplicate, body, typedElse) }
+ val typedIf = typer.typed { If(guard.duplicate, body, typedElse) }
typer.typed { squeezedBlock(vdefs, typedIf) }
}
@@ -371,7 +372,7 @@ trait ParallelMatching {
for ((vtpe, i) <- ts.zip((1 to ts.size).toList)) yield {
val vchild = newVarCapture(ua.pos, vtpe)
val accSym = definitions.productProj(uresGet, i)
- val rhs = typed(Apply(Select(mkIdent(uresGet), accSym), Nil))
+ val rhs = typer.typed(Apply(Select(mkIdent(uresGet), accSym), Nil))
(typedValDef(vchild, rhs), vchild)
})
@@ -397,10 +398,10 @@ trait ParallelMatching {
val fail = if (frep.isEmpty) failTree else repToTree(frep.get)
val cond =
if (uacall.symbol.tpe.typeSymbol eq definitions.BooleanClass)
- typed{ mkIdent(uacall.symbol) }
+ typer.typed{ mkIdent(uacall.symbol) }
else
emptynessCheck(uacall.symbol)
- typed { squeezedBlock(List(rep.handleOuter(uacall)), If(cond,squeezedBlock(vdefs,succ),fail)) }
+ typer.typed { squeezedBlock(List(rep.handleOuter(uacall)), If(cond,squeezedBlock(vdefs,succ),fail)) }
}
}
@@ -437,7 +438,7 @@ trait ParallelMatching {
val treeAsSeq =
if (!isSubType(scrutinee.tpe, column.head.tpe))
- typed(gen.mkAsInstanceOf(mkIdent(scrutinee), column.head.tpe, true))
+ typer.typed(gen.mkAsInstanceOf(mkIdent(scrutinee), column.head.tpe, true))
else
mkIdent(scrutinee)
@@ -527,16 +528,16 @@ trait ParallelMatching {
// todo: optimize if no guard, and no further tests
val nsucc = rep.make(scrutinee :: rest.temp, nsuccRow)
val nfail = repWithoutHead(column, rest)
- return (typed{ Equals(mkIdent(scrutinee) setType scrutinee.tpe, vlue) }, nsucc, fLabel, nfail)
+ return (typer.typed{ Equals(mkIdent(scrutinee) setType scrutinee.tpe, vlue) }, nsucc, fLabel, nfail)
}
final def tree(implicit theOwner: Symbol, failTree: Tree) = {
val (cond, srep, fLabel, frep) = this.getTransition
- val cond2 = typed { rep.handleOuter(cond) }
- val fail = typed { repToTree(frep) }
+ val cond2 = typer.typed { rep.handleOuter(cond) }
+ val fail = typer.typed { repToTree(frep) }
fLabel setInfo (new MethodType(Nil, fail.tpe))
val succ = repToTree(srep)
- typed{ If(cond2, succ, LabelDef(fLabel, Nil, fail)) }
+ typer.typed{ If(cond2, succ, LabelDef(fLabel, Nil, fail)) }
}
}
@@ -682,7 +683,7 @@ trait ParallelMatching {
final def tree(implicit theOwner: Symbol, failTree: Tree): Tree = {
val (casted,srep,frep) = this.getTransition
val condUntyped = condition(casted.tpe, this.scrutinee)
- var cond = rep.handleOuter(typed { condUntyped })
+ var cond = rep.handleOuter(typer.typed { condUntyped })
if (needsOuterTest(casted.tpe, this.scrutinee.tpe, theOwner)) { // @todo merge into def condition
cond = addOuterCondition(cond, casted.tpe, mkIdent(this.scrutinee), rep.handleOuter)
}
@@ -699,14 +700,14 @@ trait ParallelMatching {
val tmp = p._1;
val accessorMethod = p._2
val untypedAccess = Apply(Select(mkIdent(casted), accessorMethod),List())
- val typedAccess = typed { untypedAccess }
+ val typedAccess = typer.typed { untypedAccess }
typedValDef(tmp, typedAccess)
}
if (casted ne this.scrutinee)
vdefs = ValDef(casted, gen.mkAsInstanceOf(mkIdent(this.scrutinee), casted.tpe)) :: vdefs
- return typed { If(cond, squeezedBlock(vdefs, succ), fail) }
+ return typer.typed { If(cond, squeezedBlock(vdefs, succ), fail) }
}
}
@@ -728,7 +729,7 @@ trait ParallelMatching {
final def unapply(x:Rep)(implicit rep:RepFactory):Option[RepType] =
if (x.isInstanceOf[rep.RepImpl]) Some(x.asInstanceOf[RepType]) else None
}
- class RepFactory(val handleOuter: Tree => Tree) {
+ class RepFactory(val handleOuter: Tree => Tree)(implicit val typer : Typer) {
case class RepImpl(val temp:List[Symbol], val row:List[Row]) extends Rep with Rep.RepType {
(row.find { case Row(pats, _, _, _) => temp.length != pats.length }) match {
case Some(row) => assert(false, "temp == "+temp+" row.pats == "+row.pat);
@@ -1183,12 +1184,12 @@ trait ParallelMatching {
/** returns the condition in "if (cond) k1 else k2"
*/
- final def condition(tpe: Type, scrut: Symbol): Tree = {
+ final def condition(tpe: Type, scrut: Symbol)(implicit typer : Typer): Tree = {
assert(scrut ne NoSymbol)
condition(tpe, mkIdent(scrut))
}
- final def condition(tpe: Type, scrutineeTree: Tree): Tree = {
+ final def condition(tpe: Type, scrutineeTree: Tree)(implicit typer : Typer): Tree = {
assert(tpe ne NoType)
assert(scrutineeTree.tpe ne NoType)
if (tpe.isInstanceOf[SingletonType] && !tpe.isInstanceOf[ConstantType]) {
@@ -1202,7 +1203,7 @@ trait ParallelMatching {
if (tpe.prefix ne NoPrefix) gen.mkIsInstanceOf(scrutineeTree, tpe)
else
Equals(gen.mkAttributedRef(tpe.termSymbol), scrutineeTree)
- typed { x }
+ typer.typed { x }
}
} else if (tpe.isInstanceOf[ConstantType]) {
val value = tpe.asInstanceOf[ConstantType].value
diff --git a/src/compiler/scala/tools/nsc/matching/TransMatcher.scala b/src/compiler/scala/tools/nsc/matching/TransMatcher.scala
index 10cd6cfdd4..924135c5ad 100644
--- a/src/compiler/scala/tools/nsc/matching/TransMatcher.scala
+++ b/src/compiler/scala/tools/nsc/matching/TransMatcher.scala
@@ -13,11 +13,11 @@ package scala.tools.nsc.matching
*/
trait TransMatcher { self: transform.ExplicitOuter with PatternNodes with ParallelMatching with CodeFactory =>
- import global._
+ import global.{typer => _, _}
+ import analyzer.Typer;
import definitions._
import posAssigner.atPos
import symtab.Flags
- import typer.typed
import collection.mutable.ListBuffer
@@ -44,7 +44,7 @@ trait TransMatcher { self: transform.ExplicitOuter with PatternNodes with Parall
/** handles all translation of pattern matching
*/
- def handlePattern(selector: Tree, cases: List[CaseDef], doCheckExhaustive: Boolean, owner: Symbol, handleOuter: Tree => Tree): Tree = {
+ def handlePattern(selector: Tree, cases: List[CaseDef], doCheckExhaustive: Boolean, owner: Symbol, handleOuter: Tree => Tree)(implicit typer : Typer): Tree = {
implicit val theOwner = owner
if (settings_debug) {
Console.println("****")
@@ -59,7 +59,7 @@ trait TransMatcher { self: transform.ExplicitOuter with PatternNodes with Parall
if (!doCheckExhaustive)
root.setFlag(Flags.TRANS_FLAG)
- var vdef:Tree = typed{ValDef(root, selector)}
+ var vdef:Tree = typer.typed{ValDef(root, selector)}
var theFailTree:Tree = ThrowMatchError(selector.pos, mkIdent(root))
if (definitions.isTupleType(selector.tpe)) selector match {
@@ -89,8 +89,8 @@ trait TransMatcher { self: transform.ExplicitOuter with PatternNodes with Parall
implicit val fail: Tree = theFailTree
- val mch = typed{ repToTree(irep)}
- var dfatree = typed{Block(vds.toList, mch)}
+ val mch = typer.typed{ repToTree(irep)}
+ var dfatree = typer.typed{Block(vds.toList, mch)}
// cannot use squeezedBlock because of side-effects, see t275
for ((cs, bx) <- cases.zipWithIndex){
if (!rep.isReached(bx)) {
diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
index 0451509a07..5c7480d0f4 100644
--- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
@@ -483,30 +483,15 @@ abstract class ExplicitOuter extends InfoTransform with TransMatcher with Patter
ExplicitOuter.this.resultType = tree.tpe
- //println("handle pattern = "+nselector+"/"+ncases.toList+"/"+currentOwner+"/"+tree.tpe)
- val t_untyped = handlePattern(nselector, ncases.toList, checkExhaustive, currentOwner, transform)
- //println("t_untyped = "+t_untyped)
- try {
- //Console.println("t_untyped "+t_untyped.toString())
- val t = atPos(tree.pos) { localTyper.typed(t_untyped, resultType) }
- //println("t_typed = "+t)
-
- //t = transform(t)
- //val t = atPos(tree.pos) { typed(t_untyped, resultType) }
- //val t = atPos(tree.pos) { typed(t_untyped) }
- //Console.println("t typed "+t.toString())
- if (settings.debug.value)
- Console.println("finished translation of " + tid)
-
- if(nguard.isEmpty) {t} else Block(nguard.toList, t) setType t.tpe
- } catch {
- case e =>
- e.printStackTrace()
- //treeBrowser.browse(Seq.single(unit).elements)
- Console.println("[died while typechecking the translated pattern match:]")
- Console.println(t_untyped)
- null
- }
+ val t = atPos(tree.pos) {
+ val t_untyped = handlePattern(nselector, ncases.toList, checkExhaustive, currentOwner, transform)(localTyper)
+ localTyper.typed(t_untyped, resultType)
+ }
+
+ if (settings.debug.value)
+ Console.println("finished translation of " + tid)
+
+ if(nguard.isEmpty) {t} else Block(nguard.toList, t) setType t.tpe
case _ =>
val x = super.transform(tree)