From fc34bf23dc2a8726dcd0227a94f78a63141cfc75 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 28 Jan 2021 22:58:04 +0000 Subject: [PATCH] Teach typedConstructorPattern to ignore non-redefining unapplies In pos/t12250.scala Foo defines an unapply which doesn't redefine the synthetic one. Thus unapply is overloaded. In the pattern being typed, the synthetic one is indeed the one seeked, so despite being overloaded, we should convertToCaseConstructor. --- .../scala/tools/nsc/typechecker/PatternTypers.scala | 6 +++--- test/files/pos/t12250.scala | 11 +++++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 test/files/pos/t12250.scala diff --git a/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala b/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala index 74bfd0491a14..b858d37dae93 100644 --- a/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala @@ -97,9 +97,9 @@ trait PatternTypers { // Dueling test cases: pos/overloaded-unapply.scala, run/case-class-23.scala, pos/t5022.scala // A case class with 23+ params has no unapply method. // A case class constructor may be overloaded with unapply methods in the companion. - // A case class maybe have its own custom unapply (so non-synthetic) scala/bug#11252 - // Unapply methods aren't `isCaseApplyOrUnapply` in Scala 3 tasty/run/src-2/tastytest/TestColour.scala - else if (canElide && caseClass.isCase && !member.isOverloaded && (member == NoSymbol || member.isSynthetic)) + // A case class may have its own custom unapply (so non-synthetic) pos/t11252.scala + // A case class may have its own custom unapply unrelated to deconstructing pos/t12250.scala + else if (canElide && caseClass.isCase && (!member.isOverloaded && (member == NoSymbol || member.isSynthetic) || member.alternatives.exists(_.isSynthetic) && caseClass.tpe =:= pt)) logResult(s"convertToCaseConstructor($fun, $caseClass, pt=$pt)")(convertToCaseConstructor(fun, caseClass, pt)) else if (!reallyExists(member)) CaseClassConstructorError(fun, s"${fun.symbol} is not a case class, nor does it have a valid unapply/unapplySeq member") diff --git a/test/files/pos/t12250.scala b/test/files/pos/t12250.scala new file mode 100644 index 000000000000..ec5be8411860 --- /dev/null +++ b/test/files/pos/t12250.scala @@ -0,0 +1,11 @@ +// scalac: -Werror +final case class Foo(value: String) + +object Foo { + def unapply(str: String): Option[Foo] = Some(Foo(str)) + + def extract(id: Foo): String = + id match { + case Foo(a) => a + } +}