diff options
author | Paul Phillips <paulp@improving.org> | 2011-04-30 20:01:25 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2011-04-30 20:01:25 +0000 |
commit | b4749d3b1afb1df236ec48fd3a773aab24a6f74d (patch) | |
tree | 81792bd4de8dfb8c2beb6ad1418880947fb6e371 /src | |
parent | 793796eee0769926a3162d69dd23c282ca2d8ba4 (diff) | |
download | scala-b4749d3b1afb1df236ec48fd3a773aab24a6f74d.tar.gz scala-b4749d3b1afb1df236ec48fd3a773aab24a6f74d.tar.bz2 scala-b4749d3b1afb1df236ec48fd3a773aab24a6f74d.zip |
Completely to my surprise, found that fixing al...
Completely to my surprise, found that fixing all those sequence issues
revealed that the pattern matcher can catch a lot more inexhaustive
cases than it has been catching. Fixed most of the inexhaustive matches
in the compiler, which had become a bit warnier. No review.
Diffstat (limited to 'src')
7 files changed, 23 insertions, 17 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/icode/ICodeCheckers.scala b/src/compiler/scala/tools/nsc/backend/icode/ICodeCheckers.scala index f29618c7cf..3d3097e497 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/ICodeCheckers.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/ICodeCheckers.scala @@ -321,9 +321,9 @@ abstract class ICodeCheckers { } } - def popStack = { checkStack(1) ; popStackN(1) match { case List(x) => x } } - def popStack2 = { checkStack(2) ; popStackN(2) match { case List(x, y) => (x, y) } } - def popStack3 = { checkStack(3) ; popStackN(3) match { case List(x, y, z) => (x, y, z) } } + def popStack = { checkStack(1) ; (popStackN(1): @unchecked) match { case List(x) => x } } + def popStack2 = { checkStack(2) ; (popStackN(2): @unchecked) match { case List(x, y) => (x, y) } } + def popStack3 = { checkStack(3) ; (popStackN(3): @unchecked) match { case List(x, y, z) => (x, y, z) } } /** Called by faux instruction LOAD_EXCEPTION to wipe out the stack. */ def clearStack() = { diff --git a/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala b/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala index e59d8c7858..c5c57938ca 100644 --- a/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala +++ b/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala @@ -136,7 +136,7 @@ trait MatrixAdditions extends ast.TreeDSL { /** Exhaustiveness checking requires looking for sealed classes * and if found, making sure all children are covered by a pattern. */ - class ExhaustivenessChecker(rep: Rep) { + class ExhaustivenessChecker(rep: Rep, matchPos: Position) { val Rep(tvars, rows) = rep import Flags.{ MUTABLE, ABSTRACT, SEALED } @@ -201,7 +201,7 @@ trait MatrixAdditions extends ast.TreeDSL { def check = { def errMsg = (inexhaustives map mkMissingStr).mkString if (inexhaustives.nonEmpty) - cunit.warning(tvars.head.lhs.pos, "match is not exhaustive!\n" + errMsg) + cunit.warning(matchPos, "match is not exhaustive!\n" + errMsg) rep } diff --git a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala index 89ca99de86..fb617908c7 100644 --- a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala +++ b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala @@ -70,7 +70,11 @@ trait ParallelMatching extends ast.TreeDSL val newRows = rows1 flatMap (_ expandAlternatives classifyPat) if (rows1.length != newRows.length) make(roots1, newRows) // recursive call if any change - else Rep(roots1, newRows).checkExhaustive + else { + val rep = Rep(roots1, newRows) + new ExhaustivenessChecker(rep, roots.head.sym.pos).check + rep + } } override def toString() = "MatchMatrix(%s) { %s }".format(matchResultType, indentAll(targets)) @@ -722,9 +726,6 @@ trait ParallelMatching extends ast.TreeDSL lazy val guardedRest = if (guard.isEmpty) Rep(Nil, Nil) else make(tvars, rows.tail) lazy val (defaults, others) = pats span (_.isDefault) - /** Sealed classes. */ - def checkExhaustive = new ExhaustivenessChecker(this).check - /** Cut out the column containing the non-default pattern. */ class Cut(index: Int) { /** The first two separate out the 'i'th pattern in each row from the remainder. */ diff --git a/src/compiler/scala/tools/nsc/matching/Patterns.scala b/src/compiler/scala/tools/nsc/matching/Patterns.scala index 750fdb3c3f..e0734e7f2e 100644 --- a/src/compiler/scala/tools/nsc/matching/Patterns.scala +++ b/src/compiler/scala/tools/nsc/matching/Patterns.scala @@ -173,9 +173,16 @@ trait Patterns extends ast.TreeDSL { // 8.1.7 / 8.1.8 (unapply and unapplySeq calls) case class ExtractorPattern(tree: UnApply) extends UnapplyPattern { - override def simplify(pv: PatternVar) = + override def simplify(pv: PatternVar) = { + if (pv.sym hasFlag NO_EXHAUSTIVE) () + else { + TRACE("Setting NO_EXHAUSTIVE on " + pv.sym + " due to extractor " + tree) + pv.sym setFlag NO_EXHAUSTIVE + } + if (pv.tpe <:< arg.tpe) this else this rebindTo uaTyped + } override def description = "Unapply(%s => %s)".format(necessaryType, resTypesString) } @@ -205,8 +212,6 @@ trait Patterns extends ast.TreeDSL { override def necessaryType = if (nonStarPatterns.nonEmpty) consRef else listRef override def simplify(pv: PatternVar) = { - pv.sym setFlag NO_EXHAUSTIVE - if (pv.tpe <:< necessaryType) foldedPatterns else diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index 36552894e5..007ab36e5e 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -458,7 +458,7 @@ abstract class Erasure extends AddInterfaces else if (sym.name == nme.apply) tp else if (sym.name == nme.update) - tp match { + (tp: @unchecked) match { case MethodType(List(index, tvar), restpe) => MethodType(List(index.cloneSymbol.setInfo(erasure(index.tpe)), tvar), erasedTypeRef(UnitClass)) @@ -987,7 +987,7 @@ abstract class Erasure extends AddInterfaces case Apply(fn, args) => if (fn.symbol == Any_asInstanceOf) - fn match { + (fn: @unchecked) match { case TypeApply(Select(qual, _), List(targ)) => if (qual.tpe <:< targ.tpe) { atPos(tree.pos) { Typed(qual, TypeTree(targ.tpe)) } diff --git a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala index e837af42fd..9cfd497c76 100644 --- a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala +++ b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala @@ -271,11 +271,11 @@ abstract class LambdaLift extends InfoTransform { case Some(ps) => val freeParams = ps map (p => ValDef(p) setPos tree.pos setType NoType) tree match { - case DefDef(mods, name, tparams, List(vparams), tpt, rhs) => + case DefDef(mods, name, tparams, vparamss, tpt, rhs) => val addParams = cloneSymbols(ps).map(_.setFlag(PARAM)) sym.updateInfo( lifted(MethodType(sym.info.params ::: addParams, sym.info.resultType))) - treeCopy.DefDef(tree, mods, name, tparams, List(vparams ::: freeParams), tpt, rhs) + treeCopy.DefDef(tree, mods, name, tparams, List(vparamss.head ++ freeParams), tpt, rhs) case ClassDef(mods, name, tparams, impl @ Template(parents, self, body)) => // Disabled attempt to to add getters to freeParams // this does not work yet. Problem is that local symbols need local names diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 2c89647c88..4a62c7c70d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -2740,7 +2740,7 @@ trait Typers extends Modes { fun1clazz, List(selfsym.info, annClass.tpe)) - typed(func, mode, funcType) match { + (typed(func, mode, funcType): @unchecked) match { case t @ Function(List(arg), rhs) => val subs = new TreeSymSubstituter(List(arg.symbol),List(selfsym)) |