From fddd576b1183e394cdfb47f074fe7918a37644b6 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Thu, 24 May 2012 11:33:34 +0200 Subject: don't check exhaustivity involving user-defined unapplySeq --- .../scala/tools/nsc/typechecker/PatternMatching.scala | 1 + test/files/neg/patmatexhaust.check | 6 +----- test/files/pos/exhaustive_heuristics.scala | 12 +++++++++++- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala index 4d66fb5617..b9aa2c73fd 100644 --- a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala +++ b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala @@ -1973,6 +1973,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL case Some(0) if testedBinder.tpe.typeSymbol == ListClass => // extractor.symbol.owner == SeqFactory EqualityCond(binderToUniqueTree(p.prevBinder), unique(Ident(NilModule) setType NilModule.tpe)) case _ => + backoff = true super.treeMakerToCond(tm) } case ExtractorTreeMaker(_, _, _, _) => diff --git a/test/files/neg/patmatexhaust.check b/test/files/neg/patmatexhaust.check index 6172811e13..1168f36e11 100644 --- a/test/files/neg/patmatexhaust.check +++ b/test/files/neg/patmatexhaust.check @@ -18,10 +18,6 @@ patmatexhaust.scala:53: error: match may not be exhaustive. It would fail on the following input: Gp() def ma5(x:Deep) = x match { ^ -patmatexhaust.scala:59: error: match may not be exhaustive. -It would fail on the following input: Nil - def ma6() = List(1,2) match { // give up - ^ patmatexhaust.scala:75: error: match may not be exhaustive. It would fail on the following input: B() def ma9(x: B) = x match { @@ -38,4 +34,4 @@ patmatexhaust.scala:126: error: match may not be exhaustive. It would fail on the following input: C1() def ma10(x: C) = x match { // not exhaustive: C1 is not abstract. ^ -10 errors found +9 errors found diff --git a/test/files/pos/exhaustive_heuristics.scala b/test/files/pos/exhaustive_heuristics.scala index f6bea455a5..297900510b 100644 --- a/test/files/pos/exhaustive_heuristics.scala +++ b/test/files/pos/exhaustive_heuristics.scala @@ -12,5 +12,15 @@ object Test { case _ if turnOffChecks => } - // TODO: we back off when there are any user-defined extractors + // we back off when there are any user-defined extractors + // in fact this is exhaustive, but we pretend we don't know since List's unapplySeq is not special to the compiler + // to compensate our ignorance, we back off + // well, in truth, we do rewrite List() to Nil, but otherwise we do nothing + // the full rewrite List(a, b) to a :: b :: Nil, for example is planned (but not sure it's a good idea) + List(true, false) match { + case List(_, _, _*) => + case List(node, _*) => + case Nil => + } + } \ No newline at end of file -- cgit v1.2.3 From 7d0fdb37f4ae4555a51e13b17cca3e8ec94dd9d1 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Mon, 28 May 2012 11:07:28 +0200 Subject: handle approximating alternative of empty pattern --- src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala index b9aa2c73fd..b36a92a186 100644 --- a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala +++ b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala @@ -1457,6 +1457,9 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL def binderToUniqueTree(b: Symbol) = unique(accumSubst(normalize(CODE.REF(b))), b.tpe) + @inline def /\(conds: Iterable[Cond]) = if (conds.isEmpty) Top else conds.reduceLeft(AndCond(_, _)) + @inline def \/(conds: Iterable[Cond]) = if (conds.isEmpty) Havoc else conds.reduceLeft(OrCond(_, _)) + // note that the sequencing of operations is important: must visit in same order as match execution // binderToUniqueTree uses the type of the first symbol that was encountered as the type for all future binders def treeMakerToCond(tm: TreeMaker): Cond = { @@ -1475,7 +1478,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL } ttm.renderCondition(condStrategy) case EqualityTestTreeMaker(prevBinder, patTree, _) => EqualityCond(binderToUniqueTree(prevBinder), unique(patTree)) - case AlternativesTreeMaker(_, altss, _) => altss map (_ map treeMakerToCond reduceLeft AndCond) reduceLeft OrCond + case AlternativesTreeMaker(_, altss, _) => \/(altss map (alts => /\(alts map treeMakerToCond))) case ProductExtractorTreeMaker(testedBinder, None, subst) => NonNullCond(binderToUniqueTree(testedBinder)) case ExtractorTreeMaker(_, _, _, _) | GuardTreeMaker(_) -- cgit v1.2.3