summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/matching/CodeFactory.scala9
-rw-r--r--src/compiler/scala/tools/nsc/matching/ParallelMatching.scala40
-rw-r--r--src/compiler/scala/tools/nsc/matching/PatternMatchers.scala30
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala3
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala2
-rw-r--r--test/files/run/patmatnew.scala16
6 files changed, 55 insertions, 45 deletions
diff --git a/src/compiler/scala/tools/nsc/matching/CodeFactory.scala b/src/compiler/scala/tools/nsc/matching/CodeFactory.scala
index d2facaf2a9..c33e9f0e25 100644
--- a/src/compiler/scala/tools/nsc/matching/CodeFactory.scala
+++ b/src/compiler/scala/tools/nsc/matching/CodeFactory.scala
@@ -22,6 +22,7 @@ trait CodeFactory {
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) = {
//Console.println("1"+x.tpe)
@@ -39,12 +40,12 @@ trait CodeFactory {
final def targetParams(subst:Binding):List[ValDef] = if(subst eq NoBinding) Nil else subst match {
case Binding(v,t,n) => ValDef(v, {
//v.setFlag(symtab.Flags.TRANS_FLAG);
- if(t.tpe <:< v.tpe) typed{Ident(t)}
- else if(v.tpe <:< t.tpe) typed{gen.mkAsInstanceOf(Ident(t),v.tpe)} // refinement
+ if(t.tpe <:< v.tpe) mkIdent(t)
+ else if(v.tpe <:< t.tpe) typed{gen.mkAsInstanceOf(mkIdent(t),v.tpe)} // refinement
else {
//Console.println("internal error, types don't match: pattern variable "+v+":"+v.tpe+" temp "+t+":"+t.tpe)
error("internal error, types don't match: pattern variable "+v+":"+v.tpe+" temp "+t+":"+t.tpe)
- typed{gen.mkAsInstanceOf(Ident(t),v.tpe)} // refinement
+ typed{gen.mkAsInstanceOf(mkIdent(t), v.tpe)} // refinement
}
})::targetParams(n)
}
@@ -96,7 +97,7 @@ trait CodeFactory {
if (vsym.tpe.typeSymbol == definitions.SomeClass) // is Some[_]
Literal(Constant(true))
else // is Option[_]
- Not(Select(Ident(vsym), nme.isEmpty))
+ Not(Select(mkIdent(vsym), nme.isEmpty))
}
/** returns code `<seqObj>.elements' */
diff --git a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
index 9677fe9c1d..08bdfba340 100644
--- a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
+++ b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
@@ -291,7 +291,7 @@ trait ParallelMatching {
//cast
val vtmp = newVar(pat.pos, ptpe)
squeezedBlock(
- List(typedValDef(vtmp, gen.mkAsInstanceOf(Ident(this.scrutinee), ptpe))),
+ List(typedValDef(vtmp, gen.mkAsInstanceOf(mkIdent(this.scrutinee), ptpe))),
repToTree(rep.make(vtmp :: r.temp.tail, r.row),handleOuter,localTyper)
)
} else repToTree(r, handleOuter,localTyper)
@@ -309,9 +309,9 @@ trait ParallelMatching {
cases.length match {
case 0 => ndefault
case 1 => val CaseDef(lit,_,body) = cases.head
- If(Equals(Select(Ident(this.scrutinee),nme.tag),lit), body, ndefault)
+ If(Equals(Select(mkIdent(this.scrutinee),nme.tag),lit), body, ndefault)
case _ => val defCase = CaseDef(mk_(definitions.IntClass.tpe), EmptyTree, ndefault)
- Match(Select(Ident(this.scrutinee),nme.tag), cases ::: defCase :: Nil)
+ Match(Select(mkIdent(this.scrutinee),nme.tag), cases ::: defCase :: Nil)
}
} /* def tree(implicit handleOuter: HandleOuter, theOwner: Symbol, failTree: Tree) */
} /* MixCases */
@@ -392,7 +392,7 @@ trait ParallelMatching {
renamingBind(defaultV, this.scrutinee, ndefault) // each v in defaultV gets bound to scrutinee
if(cases.length == 1) {
val CaseDef(lit,_,body) = cases.head
- If(Equals(Ident(this.scrutinee),lit), body, ndefault)
+ If(Equals(mkIdent(this.scrutinee),lit), body, ndefault)
} else {
val defCase = CaseDef(mk_(definitions.IntClass.tpe), EmptyTree, ndefault)
@@ -403,11 +403,11 @@ trait ParallelMatching {
// where erasure forgets the char to int conversion and emits Int.unbox in the scrutinee position
// of the match. This then fails at runtime, because it encounters a boxed Character, not boxedq Int
return Block(
- List(typedValDef(zz, Ident(this.scrutinee))),
- Match(gen.mkAsInstanceOf(Ident(zz), definitions.IntClass.tpe), cases ::: defCase :: Nil)
+ List(typedValDef(zz, mkIdent(this.scrutinee))),
+ Match(gen.mkAsInstanceOf(mkIdent(zz), definitions.IntClass.tpe), cases ::: defCase :: Nil)
)
}
- return Match(Ident(this.scrutinee), cases ::: defCase :: Nil)
+ return Match(mkIdent(this.scrutinee), cases ::: defCase :: Nil)
}
} /* def tree(implicit handleOuter: HandleOuter, theOwner: Symbol, failTree: Tree) */
} /* MixLiterals */
@@ -424,7 +424,7 @@ trait ParallelMatching {
v
}
- private def bindToScrutinee(x:Symbol) = typedValDef(x,Ident(scrutinee))
+ private def bindToScrutinee(x:Symbol) = typedValDef(x,mkIdent(scrutinee))
val unapp = strip2(column.head)
/** returns the (un)apply and two continuations */
@@ -435,7 +435,7 @@ trait ParallelMatching {
case ua @ UnApply(app @ Apply(fn, appargs), args) =>
val ures = newVarCapture(ua.pos, app.tpe)
val n = args.length
- val uacall = ValDef(ures, Apply(fn, Ident(scrutinee) :: appargs.tail))
+ val uacall = ValDef(ures, Apply(fn, mkIdent(scrutinee) :: appargs.tail))
//Console.println("uacall:"+uacall)
val nrowsOther = column.tail.zip(rest.row.tail) flatMap { case (pat, Row(ps, subst, g, bx)) => strip2(pat) match {
@@ -467,11 +467,11 @@ trait ParallelMatching {
case _ =>
Row(EmptyTree :: pat :: ps, subst, g, bx)
}}
- (uacall, rootvdefs:::List( typedValDef(vsym, Select(Ident(ures), nme.get))), rep.make(ntemps, nrows), nrepFail)
+ (uacall, rootvdefs:::List( typedValDef(vsym, Select(mkIdent(ures), nme.get))), rep.make(ntemps, nrows), nrepFail)
case _ => // app.tpe is Option[? <: ProductN[T1,...,Tn]]
val uresGet = newVarCapture(ua.pos, app.tpe.typeArgs(0))
- var vdefs = typedValDef(uresGet, Select(Ident(ures), nme.get))::Nil
+ var vdefs = typedValDef(uresGet, Select(mkIdent(ures), nme.get))::Nil
var ts = definitions.getProductArgs(uresGet.tpe).get
var i = 1;
//Console.println("typeargs"+ts)
@@ -481,7 +481,7 @@ trait ParallelMatching {
val vtpe = ts.head
val vchild = newVarCapture(ua.pos, vtpe)
val accSym = definitions.productProj(uresGet, i)
- val rhs = typed(Apply(Select(Ident(uresGet), accSym), List())) // nsc !
+ val rhs = typed(Apply(Select(mkIdent(uresGet), accSym), List())) // nsc !
vdefs = typedValDef(vchild, rhs)::vdefs
vsyms = vchild :: vsyms
dummies = EmptyTree::dummies
@@ -508,7 +508,7 @@ trait ParallelMatching {
val fail = if(frep.isEmpty) failTree else repToTree(frep.get, handleOuter,localTyper)
val cond =
if(uacall.symbol.tpe.typeSymbol eq definitions.BooleanClass)
- typed{ Ident(uacall.symbol) }
+ typed{ mkIdent(uacall.symbol) }
else
emptynessCheck(uacall.symbol)
typed { squeezedBlock(List(handleOuter(uacall)), If(cond,squeezedBlock(vdefs,succ),fail)) }
@@ -600,7 +600,7 @@ trait ParallelMatching {
val nsuccRow = nsuccFst :: (column.tail.zip(rest.row.tail) map { case (p, Row(pats,bnd,g,b)) => Row(p::pats,bnd,g,b) })
val nsucc = rep.make(scrutinee :: rest.temp, nsuccRow)
val nfail = repWithoutHead(column,rest)
- return (typed{ Equals(Ident(scrutinee) setType scrutinee.tpe, vlue) }, nsucc, nfail)
+ return (typed{ Equals(mkIdent(scrutinee) setType scrutinee.tpe, vlue) }, nsucc, nfail)
}
final def tree(implicit handleOuter: HandleOuter, localTyper: LocalTyper, theOwner: Symbol, failTree: Tree) = {
@@ -805,7 +805,7 @@ trait ParallelMatching {
val condUntyped = condition(casted.tpe, this.scrutinee)
var cond = handleOuter(typed { condUntyped }) // <- throws exceptions in some situations?
if(needsOuterTest(casted.tpe, this.scrutinee.tpe)) // @todo merge into def condition
- cond = addOuterCondition(cond, casted.tpe, typed{Ident(this.scrutinee)}, handleOuter)
+ cond = addOuterCondition(cond, casted.tpe, mkIdent(this.scrutinee), handleOuter)
val succ = repToTree(srep, handleOuter, localTyper)
val fail = if(frep.isEmpty) failTree else repToTree(frep.get, handleOuter,localTyper)
@@ -823,14 +823,14 @@ trait ParallelMatching {
case (tmp,accessorMethod) =>
//Console.println("tmp: "+tmp+":"+tmp.tpe)
//Console.println("accessorMethod: "+accessorMethod+":"+accessorMethod.tpe)
- val untypedAccess = Apply(Select(typed{Ident(casted)}, accessorMethod),List())
+ val untypedAccess = Apply(Select(mkIdent(casted), accessorMethod),List())
val typedAccess = typed { untypedAccess }
//Console.println("ParallelMatching-- MixTypes "+typedAccess)
typedValDef(tmp, typedAccess)
}
if(casted ne this.scrutinee) {
- vdefs = ValDef(casted, gen.mkAsInstanceOf(typed{Ident(this.scrutinee)}, casted.tpe)) :: vdefs
+ vdefs = ValDef(casted, gen.mkAsInstanceOf(mkIdent(this.scrutinee), casted.tpe)) :: vdefs
}
typed { If(cond, squeezedBlock(vdefs,succ), fail) }
} catch {
@@ -970,7 +970,7 @@ trait ParallelMatching {
//Console.println("requestBody ("+bx+") gets shortcut "+(shortCuts.length-bx)+ " all:"+shortCuts);
val jlabel = shortCuts(-bx-1)
//Console.println("is "+jlabel);
- val jump = Apply(Ident(jlabel) setType jlabel.tpe, Nil)
+ val jump = Apply(mkIdent(jlabel), Nil)
//Console.println(jump)
//val jumpT = typed{ jump }
//Console.println(jumpT)
@@ -1043,7 +1043,7 @@ trait ParallelMatching {
}
- return Apply(Ident(label),args.toList)
+ return Apply(mkIdent(label),args.toList)
}
/** the injection here handles alternatives and unapply type tests */
@@ -1416,7 +1416,7 @@ trait ParallelMatching {
}
final def condition1(tpe: Type, scrut: Symbol): Tree = {
assert(scrut ne NoSymbol)
- condition(tpe, Ident(scrut) setType scrut.tpe setSymbol scrut)
+ condition(tpe, mkIdent(scrut))
}
final def condition(tpe: Type, scrutineeTree: Tree): Tree = {
diff --git a/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala b/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala
index 7602cee7d9..e4bf66674e 100644
--- a/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala
+++ b/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala
@@ -189,7 +189,7 @@ trait PatternMatchers { self: transform.ExplicitOuter with PatternNodes with Par
val irep = initRep(selector, cases, doCheckExhaustive, rep)
val root = irep.temp.head
- implicit val fail: Tree = ThrowMatchError(selector.pos, Ident(root))
+ implicit val fail: Tree = ThrowMatchError(selector.pos, mkIdent(root))
val vdef = typed{ValDef(root, selector)}
val mch = typed{repToTree(irep, handleOuter, localTyper)}
@@ -275,7 +275,7 @@ trait PatternMatchers { self: transform.ExplicitOuter with PatternNodes with Par
// List.unapply<...>(xs)
case Apply(TypeApply(sel @ Select(stor, nme.unapplySeq),_),_) if(stor.symbol eq definitions.ListModule) =>
(xs: @unchecked) match {
- case ArrayValue(_,ys)::Nil => isImplemented(ys, guard) //return {if(guard eq EmptyTree) isImplemented(ys, guard) else CantHandleSeq }
+ case ArrayValue(_,ys)::Nil => isImplemented(ys, guard) //return {if(guard eq EmptyTree) isImplemented(ys, guard) else CantHandleSeq }
}
// ignore other unapplySeq occurrences, since will run into ArrayValue
@@ -364,7 +364,7 @@ trait PatternMatchers { self: transform.ExplicitOuter with PatternNodes with Par
val tpe2test = tree.symbol.tpe
// @note: if (isSubType(header.tpe, tpe2test)) then this will be translated to isNull test
val node = pConstrPat(tree.pos, tpe2test)
- env.newBoundVar(tree.symbol, tpe2test, typed(Ident(node.casted)));
+ env.newBoundVar(tree.symbol, tpe2test, mkIdent(node.casted));
node
case Bind(name, Ident(nme.WILDCARD)) => // x @ _
@@ -378,7 +378,7 @@ trait PatternMatchers { self: transform.ExplicitOuter with PatternNodes with Par
if ((env ne null) && (tree.symbol != defs.PatternWildcard)) {
val theValue = node.symbol2bind match {
case NoSymbol => header.selector
- case x => Ident(x) setType x.tpe
+ case x => mkIdent(x)
}
env.newBoundVar(tree.symbol, tree.tpe, theValue)
}
@@ -433,7 +433,7 @@ trait PatternMatchers { self: transform.ExplicitOuter with PatternNodes with Par
case ConstrPat(casted) =>
env.newBoundVar(t.expr.symbol,
tpe.tpe,
- Ident( casted ).setType(casted.tpe));
+ mkIdent( casted ));
}
node
@@ -512,7 +512,7 @@ trait PatternMatchers { self: transform.ExplicitOuter with PatternNodes with Par
private def newHeader(pos: Position, casted: Symbol, index: Int): Header = {
//Console.println("newHeader(pos,"+casted+" (has CASE flag? "+casted.tpe.symbol.hasFlag(Flags.CASE)+") of type "+casted.tpe+" with pos "+casted.pos+"(equals FIRSTPOS? "+(casted.pos == Position.FIRSTPOS)+"),"+index+")");
- val ident = typed(Ident(casted))
+ val ident = mkIdent(casted)
if (casted.pos == NoPosition) { // load the result of casted(i)
//Console.println("FIRSTPOS");
val t = typed(
@@ -618,7 +618,7 @@ print()
case u @ UnapplyPat(_,_) if u.returnsOne =>
//Console.println("u.returnsOne!"+u+ " casted:"+casted+" u.casted"+u.casted)
assert(index==0)
- curHeader = pHeader(pat.pos, casted.tpe, Ident(casted) setType casted.tpe)
+ curHeader = pHeader(pat.pos, casted.tpe, mkIdent(casted))
target.and = curHeader
curHeader.or = patternNode(pat, curHeader, env)
enter(patArgs, curHeader.or, casted, env)
@@ -648,7 +648,7 @@ print()
patNode.casted match {
case NoSymbol => ;
case ocasted =>
- env.substitute(ocasted, typed(Ident(next.casted)));
+ env.substitute(ocasted, mkIdent(next.casted));
}
return enter(patArgs, next, casted, env);
} else if (next.isDefaultPat() || // default case reached, or
@@ -859,7 +859,7 @@ print()
case _ => ncases = ncases + 1
}
- val matchError = ThrowMatchError(selector.pos, Ident(root.casted))
+ val matchError = ThrowMatchError(selector.pos, mkIdent(root.casted))
// without a case, we return a match error if there is no default case
if (ncases == 0)
return defaultBody(root.and, matchError);
@@ -869,7 +869,7 @@ print()
case ConstantPat(value) =>
return squeezedBlock(
List(typedValDef(root.casted, selector)),
- If(Equals(Ident(root.casted), Literal(value)),
+ If(Equals(mkIdent(root.casted), Literal(value)),
(root.and.or.and).bodyToTree(),
defaultBody(root.and, matchError))
)
@@ -937,7 +937,7 @@ print()
// changed to
nCases = CaseDef(Ident(nme.WILDCARD),defaultBody1) :: nCases;
- squeezedBlock(List(typedValDef(root.casted, selector)),Match(Ident(root.casted), nCases))
+ squeezedBlock(List(typedValDef(root.casted, selector)),Match(mkIdent(root.casted), nCases))
}
@@ -952,8 +952,8 @@ print()
List(
typedValDef(root.casted, selector),
typed { toTree(root.and) },
- ThrowMatchError(selector.pos, Ident(root.casted))) ,
- LabelDef(exit, List(result), Ident(result)))
+ ThrowMatchError(selector.pos, mkIdent(root.casted))) ,
+ LabelDef(exit, List(result), mkIdent(result)))
}
@@ -1007,7 +1007,7 @@ print()
squeezedBlock(
List(
typedValDef(temp, body(i)),
- Apply(Ident(exit), List(Ident(temp).setType(temp.tpe)) )
+ Apply(mkIdent(exit), List(mkIdent(temp)) )
),
Literal(Constant(true))
); // forward jump
@@ -1176,7 +1176,7 @@ print()
}
val fntpe = fn.tpe
val v = newVar(fn.pos, fntpe)
- var __opt_get__ = typed(Select(Ident(v),nme.get))
+ var __opt_get__ = typed(Select(mkIdent(v),nme.get))
var __opt_nonemp__ = emptynessCheck(v)
Or(And(checkType,
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index 5efd37cf68..81ee95d45b 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -781,6 +781,9 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
if (fn.symbol == Any_asInstanceOf || fn.symbol == Any_asInstanceOfErased)
fn match {
case TypeApply(Select(qual, _), List(targ)) =>
+ //bq: if (qual.tpe eq null), it was surely an Ident constructed with Ident(sym)
+ //if((qual eq null) || (targ eq null) || (qual.tpe eq null) || (targ.tpe eq null))
+ // Console.println("qual: "+qual+" targ "+targ+" qual.tpe"+{if(qual eq null) "n.a. " else qual.tpe}+(if(qual.tpe eq null) "((but qual.symbol.tpe is "+qual.symbol.tpe+"))" else "")+ " targ.tpe "+{if(targ eq null) "n.a." else targ.tpe}+" Erasure: "+nodeToString(tree)) // DEBUG
if (qual.tpe <:< targ.tpe) {
atPos(tree.pos) { Typed(qual, TypeTree(targ.tpe)) }
} else if (isNumericValueClass(qual.tpe.typeSymbol) &&
diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
index 6c828b81a5..4aeb4c2cbb 100644
--- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
@@ -470,5 +470,3 @@ abstract class ExplicitOuter extends InfoTransform with TransMatcher with Patter
}
}
}
-
-
diff --git a/test/files/run/patmatnew.scala b/test/files/run/patmatnew.scala
index 36e52315a6..76395bd7e2 100644
--- a/test/files/run/patmatnew.scala
+++ b/test/files/run/patmatnew.scala
@@ -35,7 +35,8 @@ object Test extends TestConsoleMain {
new Test903,
new Test1093,
new Test1163_Order,
- new TestUnbox
+ new TestUnbox,
+ ClassDefInGuard
)
class Foo(j:Int) {
@@ -427,15 +428,22 @@ object Test extends TestConsoleMain {
println((new Buffer).jp.isDefinedAt(42))
}
- object lk { // compile only
+ object ClassDefInGuard extends TestCase("classdef in guard") { // compile-and-load only
val z:PartialFunction[Any,Any] = {
case x::xs if xs.forall { y => y.hashCode() > 0 } => 1
}
+ override def runTest {
val s:PartialFunction[Any,Any] = {
- case List(x) if List(x).forall { g => g.hashCode() > 0 } => 1
+ case List(4::xs) => 1
+ case List(5::xs) => 1
+ case _ if false =>
+ case List(3::xs) if List(3:Any).forall { g => g.hashCode() > 0 } => 1
+ }
+ z.isDefinedAt(42)
+ s.isDefinedAt(42)
+ // just load the thing, to see if the classes are found
}
-
}
}