diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala index 2618f5178939..4af8c328e87b 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala @@ -324,21 +324,31 @@ trait MatchTreeMaking extends MatchCodeGen with Debugging { } object IrrefutableExtractorTreeMaker { + def isIrrefutablyIsEmptyFalse(sym: Symbol): Boolean = + sym.isMethod && sym.name == TermName("isEmpty") && (sym.asMethod.returnType 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,...) def irrefutableExtractorType(tp: Type): Boolean = tp.resultType.dealias match { + //Some(x) is always irrefutable case TypeRef(_, SomeClass, _) => true + //name based pattern matching checks for constant false `isEmpty`. + //TODO: align with dotty and spec -- constant true `isDefined` or `value: A` + //could also make sense, but when those don't align, we have to pick + //one "leading" one. + case TypeRef(_, res, _) => res.tpe.members.exists(isIrrefutablyIsEmptyFalse) // probably not useful since this type won't be inferred nor can it be written down (yet) case ConstantTrue => true - case _ => false + case x => false } def unapply(xtm: ExtractorTreeMaker): Option[(Tree, Symbol)] = xtm match { - case ExtractorTreeMaker(extractor, None, nextBinder) if irrefutableExtractorType(extractor.tpe) => + case ExtractorTreeMaker(extractor, None, nextBinder) if irrefutableExtractorType(extractor.tpe) => Some((extractor, nextBinder)) - case _ => - None + case _ => None } } 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/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