diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index dc3bfd62a5ce..a80c5dbf4d51 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -1016,11 +1016,20 @@ class Global(var currentSettings: Settings, reporter0: Reporter) && rootMirror.isMirrorInitialized ) override def isPastTyper = isPast(currentRun.typerPhase) + def isBeforeErasure = isBefore(currentRun.erasurePhase) def isPast(phase: Phase) = ( (curRun ne null) && isGlobalInitialized // defense against init order issues && (globalPhase.id > phase.id) ) + def isBefore(phase: Phase) = ( + (curRun ne null) + && isGlobalInitialized // defense against init order issues + && (phase match { + case NoPhase => true // if phase is NoPhase then that phase ain't comin', so we're "before it" + case _ => globalPhase.id < phase.id + }) + ) // TODO - trim these to the absolute minimum. @inline final def exitingErasure[T](op: => T): T = exitingPhase(currentRun.erasurePhase)(op) diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala index a531726fe395..077da54490d6 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala @@ -374,10 +374,42 @@ trait MatchApproximation extends TreeAndTypeAnalysis with ScalaLogic with MatchT def tru = True } + + private def isIrrefutabilityProof(sym: Symbol): Boolean = { + sym.isMethod && sym.name == nme.isEmpty && { + // ConstantFalse is foldable but in joint compilation (bug?) this will be a literal type + // with case using `==` rather than `=:=` we need to do this instead. neg/t12240.scala + sym.tpe.finalResultType match { + case c: ConstantType => c.value == Constant(false) + case _ => false + } + } + } + // will an extractor with unapply method of methodtype `tp` always succeed? + // note: this assumes the other side-conditions implied by the extractor are met + // (argument of the right type, length check succeeds for unapplySeq,...) + private def irrefutableExtractorType(tp: Type): Boolean = tp.resultType.dealias match { + //Some(x) is irrefutable + case TypeRef(_, SomeClass, _) => true + //name based pattern matching checks for constant false `isEmpty`. + case TypeRef(_, res, _) => res.tpe.members.exists(isIrrefutabilityProof) + //`true.type` is irrefutable for boolean extractors + case c: ConstantType => c.value == Constant(true) + case _ => false + } + private val irrefutableExtractor: PartialFunction[TreeMaker, Prop] = { - // the extra condition is None, the extractor's result indicates it always succeeds, + // if the extra condition is None, the extractor's result indicates it always succeeds, // (the potential type-test for the argument is represented by a separate TypeTestTreeMaker) - case IrrefutableExtractorTreeMaker(_, _) => True + case ExtractorTreeMaker(extractor, None, _) if irrefutableExtractorType(extractor.tpe) => True + // Otherwise, if we call the pattern irrefutable here, these conditions + // are no longer checked and considered true in exhaustiveness and + // reachability checking. + // Therefore, the below case alone would treat too much "irrefutable" + // that really isn't. Something similar is needed (perhaps elsewhere) + // to check whether a set of unapplySeq's with all arities is toegether + // exhaustive + //case p @ ExtractorTreeMaker(extractor, Some(conditions), _) if irrefutableExtractorType(extractor.tpe) => True } // special-case: interpret pattern `List()` as `Nil` @@ -446,11 +478,12 @@ trait MatchAnalysis extends MatchApproximation { // thus, the case is unreachable if there is no model for -(-P /\ C), // or, equivalently, P \/ -C, or C => P def unreachableCase(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type): Option[Int] = { + debug.patmat("reachability analysis") val start = if (StatisticsStatics.areSomeColdStatsEnabled) statistics.startTimer(statistics.patmatAnaReach) else null // use the same approximator so we share variables, // but need different conditions depending on whether we're conservatively looking for failure or success - // don't rewrite List-like patterns, as List() and Nil need to distinguished for unreachability + // don't rewrite List-like patterns, as List() and Nil need to be distinguished for unreachability val approx = new TreeMakersToProps(prevBinder) def approximate(default: Prop) = approx.approximateMatch(cases, approx.onUnknown { tm => approx.refutableRewrite.applyOrElse(tm, (_: TreeMaker) => default ) @@ -508,6 +541,7 @@ trait MatchAnalysis extends MatchApproximation { // exhaustivity def exhaustive(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type): List[String] = if (!settings.warnStrictUnsealedPatMat && uncheckableType(prevBinder.info)) Nil else { + debug.patmat("exhaustiveness analysis") // customize TreeMakersToProps (which turns a tree of tree makers into a more abstract DAG of tests) // - approximate the pattern `List()` (unapplySeq on List with empty length) as `Nil`, // otherwise the common (xs: List[Any]) match { case List() => case x :: xs => } is deemed unexhaustive diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala index e79171e6d211..64cde9496d45 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala @@ -314,7 +314,7 @@ trait MatchTranslation { * a function that will take care of binding and substitution of the next ast (to the right). * */ - def translateCase(scrutSym: Symbol, pt: Type)(caseDef: CaseDef) = { + def translateCase(scrutSym: Symbol, pt: Type)(caseDef: CaseDef): List[TreeMaker] = { val CaseDef(pattern, guard, body) = caseDef translatePattern(BoundTree(scrutSym, pattern)) ++ translateGuard(guard) :+ translateBody(body, pt) } diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala index 2618f5178939..a26b941a5aa0 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala @@ -323,25 +323,6 @@ trait MatchTreeMaking extends MatchCodeGen with Debugging { override def toString = "P"+((prevBinder.name, extraCond getOrElse "", localSubstitution)) } - object IrrefutableExtractorTreeMaker { - // will an extractor with unapply method of methodtype `tp` always succeed? - // note: this assumes the other side-conditions implied by the extractor are met - // (argument of the right type, length check succeeds for unapplySeq,...) - def irrefutableExtractorType(tp: Type): Boolean = tp.resultType.dealias match { - case TypeRef(_, SomeClass, _) => true - // probably not useful since this type won't be inferred nor can it be written down (yet) - case ConstantTrue => true - case _ => false - } - - def unapply(xtm: ExtractorTreeMaker): Option[(Tree, Symbol)] = xtm match { - case ExtractorTreeMaker(extractor, None, nextBinder) if irrefutableExtractorType(extractor.tpe) => - Some((extractor, nextBinder)) - case _ => - None - } - } - object TypeTestTreeMaker { // factored out so that we can consistently generate other representations of the tree that implements the test // (e.g. propositions for exhaustivity and friends, boolean for isPureTypeTest) diff --git a/src/compiler/scala/tools/nsc/transform/patmat/PatternExpansion.scala b/src/compiler/scala/tools/nsc/transform/patmat/PatternExpansion.scala index 1c8849a75637..58e35abbfd1d 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/PatternExpansion.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/PatternExpansion.scala @@ -127,7 +127,7 @@ trait PatternExpansion { // rest is private private val isUnapply = fun.symbol.name == nme.unapply private val isUnapplySeq = fun.symbol.name == nme.unapplySeq - private def isBooleanUnapply = isUnapply && unapplyResultType() =:= BooleanTpe + private def isBooleanUnapply = isUnapply && unapplyResultType().typeSymbol == definitions.BooleanClass private def isRepeatedCaseClass = caseCtorParamTypes.exists(tpes => tpes.nonEmpty && isScalaRepeatedParamType(tpes.last)) private def caseCtorParamTypes: Option[List[Type]] = @@ -248,7 +248,10 @@ trait PatternExpansion { // emit error/warning on mismatch if (isStar && !isSeq) err("Star pattern must correspond with varargs or unapplySeq") - else if (equivConstrParamTypes == List(NoType)) err(s"The result type of an ${fun.symbol.name} method must contain a member `get` to be used as an extractor pattern, no such member exists in ${unapplyResultType()}") + else if (equivConstrParamTypes == List(NoType) && unapplyResultType().isNothing) + err(s"${fun.symbol.owner} can't be used as an extractor: The result type of an ${fun.symbol.name} method may not be Nothing") + else if (equivConstrParamTypes == List(NoType)) + err(s"The result type of an ${fun.symbol.name} method must contain a member `get` to be used as an extractor pattern, no such member exists in ${unapplyResultType()}") else if (elementArity < 0) arityError("not enough") else if (elementArity > 0 && !isSeq) arityError("too many") else if (settings.warnStarsAlign && isSeq && productArity > 0 && elementArity > 0) warn( diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index b5538dfb2441..a862ca339ca1 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -1240,8 +1240,8 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper inferExprAlternative(tree, pt) adaptAfterOverloadResolution(tree, mode, pt, original) case NullaryMethodType(restpe) => // (2) - val resTpDeconst = - if (isPastTyper || (tree.symbol.isAccessor && tree.symbol.hasFlag(STABLE) && treeInfo.isExprSafeToInline(tree))) restpe + val resTpDeconst = // keep constant types when they are safe to fold. erasure eliminates constant types modulo some exceptions, so keep those. + if (isBeforeErasure && tree.symbol.isAccessor && tree.symbol.hasFlag(STABLE) && treeInfo.isExprSafeToInline(tree)) restpe else restpe.deconst adapt(tree setType resTpDeconst, mode, pt, original) case TypeRef(_, ByNameParamClass, arg :: Nil) if mode.inExprMode => // (2) diff --git a/src/library/scala/Array.scala b/src/library/scala/Array.scala index 18641bb1eeca..2c4e702c65a2 100644 --- a/src/library/scala/Array.scala +++ b/src/library/scala/Array.scala @@ -559,7 +559,7 @@ object Array { def unapplySeq[T](x: Array[T]): UnapplySeqWrapper[T] = new UnapplySeqWrapper(x) final class UnapplySeqWrapper[T](private val a: Array[T]) extends AnyVal { - def isEmpty: Boolean = false + def isEmpty: false = false def get: UnapplySeqWrapper[T] = this def lengthCompare(len: Int): Int = a.lengthCompare(len) def apply(i: Int): T = a(i) diff --git a/src/library/scala/collection/Factory.scala b/src/library/scala/collection/Factory.scala index 72a35f78040a..2b15f1cc15d1 100644 --- a/src/library/scala/collection/Factory.scala +++ b/src/library/scala/collection/Factory.scala @@ -308,7 +308,7 @@ object SeqFactory { } final class UnapplySeqWrapper[A](private val c: SeqOps[A, Seq, Seq[A]]) extends AnyVal { - def isEmpty: Boolean = false + def isEmpty: false = false def get: UnapplySeqWrapper[A] = this def lengthCompare(len: Int): Int = c.lengthCompare(len) def apply(i: Int): A = c(i) diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index ae234a13f29a..06ff7793bf43 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -3089,17 +3089,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => override def isVarargs: Boolean = definitions.isVarArgsList(paramss.flatten) - override def returnType: Type = { - @tailrec - def loop(tpe: Type): Type = - tpe match { - case NullaryMethodType(ret) => loop(ret) - case MethodType(_, ret) => loop(ret) - case PolyType(_, tpe) => loop(tpe) - case tpe => tpe - } - loop(info) - } + override def returnType: Type = definitions.finalResultType(info) override def exceptions = { rawInfo match { diff --git a/test/files/neg/t12240.check b/test/files/neg/t12240.check new file mode 100644 index 000000000000..fa290cc2aa88 --- /dev/null +++ b/test/files/neg/t12240.check @@ -0,0 +1,13 @@ +t12240.scala:21: warning: match may not be exhaustive. + def guardedNonExhaustive(x: Int) = x match { + ^ +t12240.scala:25: warning: match may not be exhaustive. + def guardedSeqNonExhaustive(x: Int) = x match { + ^ +t12240.scala:32: warning: match may not be exhaustive. +It would fail on the following input: Vector1() + def reported(v: Vector[String]) = v match { + ^ +error: No warnings can be incurred under -Werror. +3 warnings +1 error diff --git a/test/files/neg/t12240.scala b/test/files/neg/t12240.scala new file mode 100644 index 000000000000..c1a3b068c5f3 --- /dev/null +++ b/test/files/neg/t12240.scala @@ -0,0 +1,38 @@ +// scalac: -Xfatal-warnings -Xlint:strict-unsealed-patmat +// + +object Test { + + //see also pos/t12240.scala + + class IrrefutableNameBasedResult[Result](r: Result) { + def isEmpty: false = false + def get: Result = r + } + + object IrrefutableIdentityExtractor { + def unapply[A](a: A): IrrefutableNameBasedResult[A] = new IrrefutableNameBasedResult(a) + } + + object IrrefutableSeqExtractor { + def unapplySeq[A](a: A) = new IrrefutableNameBasedResult(List(a)) + } + + def guardedNonExhaustive(x: Int) = x match { + case IrrefutableIdentityExtractor(_) if false => "non-exhaustive" + } + + def guardedSeqNonExhaustive(x: Int) = x match { + case IrrefutableSeqExtractor(_*) if false => "non-exhaustive" + } + + //status quo: + //should be in pos/t12240.scala but isn't exhaustive per + //per https://github.com/scala/bug/issues/12252 + def reported(v: Vector[String]) = v match { + case Vector() => "empty" + case Vector(_) => "one" + case Vector(_, _, _*) => "scalac doesn't know that this is exhaustive" + } + +} \ No newline at end of file diff --git a/test/files/neg/t4425b.check b/test/files/neg/t4425b.check index baa526e92663..2fc9121ea6fb 100644 --- a/test/files/neg/t4425b.check +++ b/test/files/neg/t4425b.check @@ -22,22 +22,22 @@ t4425b.scala:10: error: object X is not a case class, nor does it have a valid u Note: def unapply(x: String)(y: String): Nothing exists in object X, but it cannot be used as an extractor due to its second non-implicit parameter list println((X: Any) match { case X(_, _) => "ok" ; case _ => "fail" }) ^ -t4425b.scala:18: error: The result type of an unapply method must contain a member `get` to be used as an extractor pattern, no such member exists in Nothing +t4425b.scala:18: error: object X can't be used as an extractor: The result type of an unapply method may not be Nothing println( "" match { case _ X _ => "ok" ; case _ => "fail" }) ^ -t4425b.scala:19: error: The result type of an unapply method must contain a member `get` to be used as an extractor pattern, no such member exists in Nothing +t4425b.scala:19: error: object X can't be used as an extractor: The result type of an unapply method may not be Nothing println((X: Any) match { case _ X _ => "ok" ; case _ => "fail" }) ^ -t4425b.scala:20: error: The result type of an unapply method must contain a member `get` to be used as an extractor pattern, no such member exists in Nothing +t4425b.scala:20: error: object X can't be used as an extractor: The result type of an unapply method may not be Nothing println( "" match { case X(_) => "ok" ; case _ => "fail" }) ^ -t4425b.scala:21: error: The result type of an unapply method must contain a member `get` to be used as an extractor pattern, no such member exists in Nothing +t4425b.scala:21: error: object X can't be used as an extractor: The result type of an unapply method may not be Nothing println((X: Any) match { case X(_) => "ok" ; case _ => "fail" }) ^ -t4425b.scala:22: error: The result type of an unapply method must contain a member `get` to be used as an extractor pattern, no such member exists in Nothing +t4425b.scala:22: error: object X can't be used as an extractor: The result type of an unapply method may not be Nothing println( "" match { case X(_, _) => "ok" ; case _ => "fail" }) ^ -t4425b.scala:23: error: The result type of an unapply method must contain a member `get` to be used as an extractor pattern, no such member exists in Nothing +t4425b.scala:23: error: object X can't be used as an extractor: The result type of an unapply method may not be Nothing println((X: Any) match { case X(_, _) => "ok" ; case _ => "fail" }) ^ t4425b.scala:31: error: too many patterns for object X offering Nothing: expected 1, found 2 diff --git a/test/files/pos/t12240.scala b/test/files/pos/t12240.scala new file mode 100644 index 000000000000..a04ef0e734cf --- /dev/null +++ b/test/files/pos/t12240.scala @@ -0,0 +1,65 @@ +// scalac: -Xfatal-warnings -Xlint:strict-unsealed-patmat +// + +object Test { + + //original reports + + def originalReported(v: Vector[String]) = v match { + case Vector() => "empty" + case Vector(_) => "one" + case Vector(_*) => "this pattern is irrefutable" + } + + def originalMinimized(v: Vector[String]) = v match { + case Vector(_*) => "this pattern is irrefutable" + } + + //broader applicability + + class IrrefutableNameBasedResult[Result](r: Result) { + def isEmpty: false = false + def get: Result = r + } + + object IrrefutableIdentityExtractor { + def unapply[A](a: A) = new IrrefutableNameBasedResult(a) + } + + object IrrefutableSeqExtractor { + def unapplySeq[A](a: A) = new IrrefutableNameBasedResult(List(a)) + } + + def nameBasedPatternIsExhaustive(x: Int) = x match { + case IrrefutableIdentityExtractor(_) => "exhaustive" + } + + def nameBasedSeqIsExhaustive(x: Int) = x match { + case IrrefutableSeqExtractor(_*) => "exhaustive" + } + + //status quo: + //should be in neg/t12240.scala but isn't exhaustive per + //per https://github.com/scala/bug/issues/12252 + + def reported(v: Vector[String]) = v match { + case Vector() => "empty" + case Vector(_) => "one" + case Vector(_, _, _*) => "this ought to be exhaustive" + case Vector(_*) => "scalac doesn't know was already exhaustive" + } + + //status quo: + //should be in neg/t12240.scala, but the unreachable code isn't reported + //per https://github.com/scala/bug/issues/12251 + def nameBasedPatternUnreachable(x: Int) = x match { + case IrrefutableIdentityExtractor(_) => "exhaustive" + case _ => "unreachable" + } + + def nameBasedSeqUnreachable(x: Int) = x match { + case IrrefutableSeqExtractor(_*) => "exhaustive" + case _ => "unreachable" + } + +} \ No newline at end of file diff --git a/test/files/pos/t12254.scala b/test/files/pos/t12254.scala new file mode 100644 index 000000000000..a44393063d60 --- /dev/null +++ b/test/files/pos/t12254.scala @@ -0,0 +1,15 @@ +// scalac: -Xfatal-warnings -Xlint:strict-unsealed-patmat +// + +object Test { + sealed trait Foo + final class Bar extends Foo + + object Bar { + def unapply(o: Bar): true = true + } + + def f(foo: Foo) = foo match { + case Bar() => println("Bar") + } +} \ No newline at end of file diff --git a/test/files/run/patmat-no-inline-isEmpty.check b/test/files/run/patmat-no-inline-isEmpty.check new file mode 100644 index 000000000000..60ed79c25c04 --- /dev/null +++ b/test/files/run/patmat-no-inline-isEmpty.check @@ -0,0 +1,36 @@ +[[syntax trees at end of patmat]] // newSource1.scala +package { + object A extends scala.AnyRef { + def (): A.type = { + A.super.(); + () + }; + def unapplySeq(a: Int): Wrap = new Wrap(a) + }; + class T extends scala.AnyRef { + def (): T = { + T.super.(); + () + }; + def t: Any = { + case val x1: Int(2) = 2; + case5(){ + val o7: Wrap = A.unapplySeq(x1); + if (o7.isEmpty.unary_!) + { + val xs: Seq[Int] = o7.get.toSeq; + matchEnd4(xs) + } + else + case6() + }; + case6(){ + matchEnd4("other") + }; + matchEnd4(x: Any){ + x + } + } + } +} + diff --git a/test/files/run/patmat-no-inline-isEmpty.scala b/test/files/run/patmat-no-inline-isEmpty.scala new file mode 100644 index 000000000000..3af510134c70 --- /dev/null +++ b/test/files/run/patmat-no-inline-isEmpty.scala @@ -0,0 +1,31 @@ +import scala.tools.partest._ + +object Test extends DirectTest { + def depCode = + """class Wrap(private val a: Int) extends AnyVal { + | def isEmpty: false = { println("confirm seq isEmpty method doesn't get elided"); false } + | def get = this + | def lengthCompare(len: Int) = Integer.compare(1, len) + | def apply(i: Int) = if (i == 0) a else Nil(i) + | def drop(n: Int): scala.Seq[Int] = if (n == 0) toSeq else Nil + | def toSeq: scala.Seq[Int] = List(a) + |} + """.stripMargin + + override def code = + """object A { + | def unapplySeq(a: Int) = new Wrap(a) + |} + |class T { + | def t: Any = 2 match { + | case A(xs @ _*) => xs + | case _ => "other" + | } + |} + """.stripMargin + + def show(): Unit = Console.withErr(System.out) { + compileString(newCompiler("-usejavacp"))(depCode) + compileString(newCompiler("-usejavacp", "-cp", testOutput.path, "-Vprint:patmat"))(code) + } +} diff --git a/test/files/run/patmat-no-inline-unapply.check b/test/files/run/patmat-no-inline-unapply.check new file mode 100644 index 000000000000..6b0b6eb2425b --- /dev/null +++ b/test/files/run/patmat-no-inline-unapply.check @@ -0,0 +1,25 @@ +[[syntax trees at end of patmat]] // newSource1.scala +package { + class T extends scala.AnyRef { + def (): T = { + T.super.(); + () + }; + def t: Any = { + case val x1: Int(2) = 2; + case5(){ + if (A.unapply(x1)) + matchEnd4("ok") + else + case6() + }; + case6(){ + matchEnd4("other") + }; + matchEnd4(x: Any){ + x + } + } + } +} + diff --git a/test/files/run/patmat-no-inline-unapply.scala b/test/files/run/patmat-no-inline-unapply.scala new file mode 100644 index 000000000000..bd6a5541cdd6 --- /dev/null +++ b/test/files/run/patmat-no-inline-unapply.scala @@ -0,0 +1,23 @@ +import scala.tools.partest._ + +object Test extends DirectTest { + def depCode = + """object A { + | def unapply(a: Int): true = true + |} + """.stripMargin + + override def code = + """class T { + | def t: Any = 2 match { + | case A() => "ok" + | case _ => "other" + | } + |} + """.stripMargin + + def show(): Unit = Console.withErr(System.out) { + compileString(newCompiler("-usejavacp"))(depCode) + compileString(newCompiler("-usejavacp", "-cp", testOutput.path, "-Vprint:patmat"))(code) + } +} diff --git a/test/files/run/patmat-seq.check b/test/files/run/patmat-seq.check index 1a95226a06fb..ffd4b8c20ac7 100644 --- a/test/files/run/patmat-seq.check +++ b/test/files/run/patmat-seq.check @@ -1,5 +1,5 @@ -newSource1.scala:35: warning: unreachable code - case B(x, y) => (x, y) +newSource1.scala:32: warning: unreachable code + case A(x, y) => (x, y) // wrapper.get.apply(0/1) ^ [[syntax trees at end of patmat]] // newSource1.scala package { diff --git a/test/files/run/patmatnew.check b/test/files/run/patmatnew.check index e27759138347..ff9eb4579d7e 100644 --- a/test/files/run/patmatnew.check +++ b/test/files/run/patmatnew.check @@ -16,10 +16,6 @@ patmatnew.scala:356: warning: multiline expressions might require enclosing pare patmatnew.scala:356: warning: a pure expression does nothing in statement position case 3 => assert(false); "KO" ^ -patmatnew.scala:175: warning: match may not be exhaustive. -It would fail on the following inputs: List(_), Nil - def doMatch(xs: List[String]): String = xs match { - ^ patmatnew.scala:178: warning: match may not be exhaustive. It would fail on the following inputs: List(_), Nil def doMatch2(xs: List[String]): List[String] = xs match { diff --git a/test/files/run/t3530.check b/test/files/run/t3530.check index 859d468b8b4f..1f906680e9ac 100644 --- a/test/files/run/t3530.check +++ b/test/files/run/t3530.check @@ -1,7 +1,3 @@ -t3530.scala:9: warning: match may not be exhaustive. -It would fail on the following inputs: List(_), Nil - def f2[T](x: List[T]) = println(x match { - ^ two three list: 4