diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala index 69c8dba57ad8..9934ebb716a5 100644 --- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala +++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala @@ -789,7 +789,12 @@ object messages { |It would fail on: $uncovered""" - val explanation = "" + val explanation = + hl"""|There are several ways to make the match exhaustive: + | - Add missing cases as shown in the warning + | - If an extractor always return 'Some(...)', write 'Some[X]' for its return type + | - Add a 'case _ => ...' at the end to match all remaining cases + |""" } case class MatchCaseUnreachable()(implicit ctx: Context) diff --git a/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala b/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala index 96c1da50b62e..d37002094372 100644 --- a/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala +++ b/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala @@ -641,6 +641,14 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic { /** Display spaces */ def show(s: Space): String = { + + /** does the companion object of the given symbol have custom unapply */ + def hasCustomUnapply(sym: Symbol): Boolean = { + val companion = sym.companionModule + companion.findMember(nme.unapply, NoPrefix, excluded = Synthetic).exists || + companion.findMember(nme.unapplySeq, NoPrefix, excluded = Synthetic).exists + } + def doShow(s: Space, mergeList: Boolean = false): String = s match { case Empty => "" case Typ(c: ConstantType, _) => c.value.show @@ -654,11 +662,9 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic { if (mergeList) "_*" else "_: List" else if (scalaConsType.isRef(sym)) if (mergeList) "_" else "List(_)" - else if (tp.classSymbol.is(CaseClass)) + else if (tp.classSymbol.is(CaseClass) && !hasCustomUnapply(tp.classSymbol)) // use constructor syntax for case class showType(tp) + signature(tp).map(_ => "_").mkString("(", ", ", ")") - else if (signature(tp).nonEmpty) - tp.classSymbol.name + signature(tp).map(_ => "_").mkString("(", ", ", ")") else if (decomposed) "_: " + showType(tp) else "_" case Kon(tp, params) => diff --git a/tests/patmat/i2502.check b/tests/patmat/i2502.check new file mode 100644 index 000000000000..fe2194e650cf --- /dev/null +++ b/tests/patmat/i2502.check @@ -0,0 +1 @@ +5: Pattern Match Exhaustivity: _: BTypes.ClassBType \ No newline at end of file diff --git a/tests/patmat/i2502.scala b/tests/patmat/i2502.scala new file mode 100644 index 000000000000..2ccb20c135c5 --- /dev/null +++ b/tests/patmat/i2502.scala @@ -0,0 +1,17 @@ +abstract class BTypes { + trait BType + + sealed trait RefBType extends BType { + def classOrArrayType: String = this match { + case ClassBType(internalName) => internalName + case a: ArrayBType => "" + } + } + + final class ClassBType(val internalName: String) extends RefBType + class ArrayBType extends RefBType + + object ClassBType { + def unapply(x: ClassBType): Option[String] = None + } +} \ No newline at end of file diff --git a/tests/patmat/i2502b.check b/tests/patmat/i2502b.check new file mode 100644 index 000000000000..fe2194e650cf --- /dev/null +++ b/tests/patmat/i2502b.check @@ -0,0 +1 @@ +5: Pattern Match Exhaustivity: _: BTypes.ClassBType \ No newline at end of file diff --git a/tests/patmat/i2502b.scala b/tests/patmat/i2502b.scala new file mode 100644 index 000000000000..9550c84973d9 --- /dev/null +++ b/tests/patmat/i2502b.scala @@ -0,0 +1,17 @@ +abstract class BTypes { + trait BType + + sealed trait RefBType extends BType { + def classOrArrayType: String = this match { + case ClassBType(internalName) => internalName + case a: ArrayBType => "" + } + } + + final case class ClassBType(val internalName: String) extends RefBType + class ArrayBType extends RefBType + + object ClassBType { + def unapply(x: RefBType): Option[String] = None + } +} diff --git a/tests/patmat/t4691.check b/tests/patmat/t4691.check index 5fbcb267ab80..692dcd358f45 100644 --- a/tests/patmat/t4691.check +++ b/tests/patmat/t4691.check @@ -1 +1 @@ -15: Pattern Match Exhaustivity: NodeType2(_) +15: Pattern Match Exhaustivity: _: NodeType2