diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala index 04c3d399eb7e..74b00c27fdf0 100644 --- a/compiler/src/dotty/tools/dotc/typer/Applications.scala +++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala @@ -181,7 +181,12 @@ object Applications { ((_, _) => None) private def getUnapplySelectors(tp: Type)(using Context): List[Type] = - if args.length > 1 && !(tp.derivesFrom(defn.SeqClass)) then + // We treat patterns as product elements if + // they are named, or there is more than one pattern + val isProduct = args match + case x :: xs => x.isInstanceOf[untpd.NamedArg] || xs.nonEmpty + case _ => false + if isProduct && !tp.derivesFrom(defn.SeqClass) then productUnapplySelectors(tp).getOrElse: // There are unapplys with return types which have `get` and `_1, ..., _n` // as members, but which are not subtypes of Product. So `productUnapplySelectors` diff --git a/tests/run/named-patterns.check b/tests/run/named-patterns.check index 0b9f3661b7ba..9ccc08d67069 100644 --- a/tests/run/named-patterns.check +++ b/tests/run/named-patterns.check @@ -4,8 +4,8 @@ age 22 age 22, name Bob Bob, 22 name Bob, age 22 -name (Bob,22) -age (Bob,22) +name Bob +age 22 age 22, name Bob Bob, 22 1003 Lausanne, Rue de la Gare 44 @@ -13,3 +13,8 @@ Bob, 22 Rue de la Gare in Lausanne 1003 Lausanne, Rue de la Gare 44 1003 Lausanne, Rue de la Gare 44 +Bob, aged 22, in 1003 Lausanne, Rue de la Gare 44 +Bob in 1003 Lausanne +aged 22 in Rue de la Gare in Lausanne +Bob, aged 22 in 1003 Lausanne, Rue de la Gare 44 +Bob, aged 22 in 1003 Lausanne, Rue de la Gare 44 diff --git a/tests/run/named-patterns.scala b/tests/run/named-patterns.scala index 73753c855073..7c24dc8d683a 100644 --- a/tests/run/named-patterns.scala +++ b/tests/run/named-patterns.scala @@ -53,3 +53,22 @@ object Test1: addr match case Address(c, z, s, number) => println(s"$z $c, $s $number") + + type Person3 = (p: Person2, addr: Address) + + val p3 = (p = bob2, addr = addr) + p3 match + case (addr = Address(city = c, zip = z, street = s, number = n), p = Person2(name = nn, age = a)) => + println(s"$nn, aged $a, in $z $c, $s $n") + p3 match + case (p = Person2(name = nn), addr = Address(zip = z, city = c)) => + println(s"$nn in $z $c") + p3 match + case (p = Person2(age = a), addr = Address(city = c, street = s)) => + println(s"aged $a in $s in $c") + p3 match + case (Person2(age = a, name = nn), Address(number = n, street = s, zip = z, city = c)) => + println(s"$nn, aged $a in $z $c, $s $n") + p3 match + case (Person2(nn, a), Address(c, z, s, number)) => + println(s"$nn, aged $a in $z $c, $s $number")