From 0e6522a1badcf1febde02b618d4efe65839e5774 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 | 10 ++++++++++ 2 files changed, 13 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..cd3863108de9 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.alternatives.exists(_.isSynthetic) && caseClass.tpe =:= pt) && (member == NoSymbol || member.isSynthetic)) 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..b51a1e861a7a --- /dev/null +++ b/test/files/pos/t12250.scala @@ -0,0 +1,10 @@ +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 + } +}