Skip to content

Commit 9076944

Browse files
committed
Simplify tupleElementTypes unapply handling
1 parent 4ac1ff6 commit 9076944

File tree

4 files changed

+22
-28
lines changed

4 files changed

+22
-28
lines changed

compiler/src/dotty/tools/dotc/core/TypeUtils.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import Names.{Name, TermName}
88
import Constants.Constant
99

1010
class TypeUtils {
11+
1112
/** A decorator that provides methods on types
1213
* that are needed in the transformer pipeline.
1314
*/

compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,9 @@ object PatternMatcher {
371371
else if isUnapplySeq && unapplySeqTypeElemTp(unappType.finalResultType).exists then
372372
unapplySeqPlan(unappResult, args)
373373
else if unappResult.info <:< defn.NonEmptyTupleTypeRef then
374-
val components = (0 until foldApplyTupleType(unappResult.denot.info).length).toList.map(tupleApp(_, ref(unappResult)))
374+
val components =
375+
(0 until unappResult.denot.info.tupleElementTypes.getOrElse(Nil).length)
376+
.toList.map(tupleApp(_, ref(unappResult)))
375377
matchArgsPlan(components, args, onSuccess)
376378
else {
377379
assert(isGetMatch(unappType))

compiler/src/dotty/tools/dotc/typer/Applications.scala

Lines changed: 17 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ object Applications {
149149
(0 until argsNum).map(i => if (i < arity - 1) selTps(i) else elemTp).toList
150150
}
151151

152-
def unapplyArgs(unapplyResult: Type, unapplyFn: Tree, args: List[untpd.Tree], pos: SrcPos)(using Context): List[Type] = {
152+
def unapplyArgs(unapplyResult: Type, unapplyFn: Tree, args: List[untpd.Tree], pos: SrcPos)(using Context): List[Type] =
153153
def getName(fn: Tree): Name =
154154
fn match
155155
case TypeApply(fn, _) => getName(fn)
@@ -164,46 +164,36 @@ object Applications {
164164
Nil
165165
}
166166

167-
def unapplySeq(tp: Type)(fallback: => List[Type]): List[Type] = {
167+
def unapplySeq(tp: Type)(fallback: => List[Type]): List[Type] =
168168
val elemTp = unapplySeqTypeElemTp(tp)
169-
if (elemTp.exists) args.map(Function.const(elemTp))
170-
else if (isProductSeqMatch(tp, args.length, pos)) productSeqSelectors(tp, args.length, pos)
171-
else if tp.derivesFrom(defn.NonEmptyTupleClass) then foldApplyTupleType(tp)
169+
if elemTp.exists then
170+
args.map(Function.const(elemTp))
171+
else if isProductSeqMatch(tp, args.length, pos) then
172+
productSeqSelectors(tp, args.length, pos)
173+
else if tp.derivesFrom(defn.NonEmptyTupleClass) then
174+
tp.tupleElementTypes.getOrElse(Nil)
172175
else fallback
173-
}
174176

175-
if (unapplyName == nme.unapplySeq)
176-
unapplySeq(unapplyResult) {
177+
if unapplyName == nme.unapplySeq then
178+
unapplySeq(unapplyResult):
177179
if (isGetMatch(unapplyResult, pos)) unapplySeq(getTp)(fail)
178180
else fail
179-
}
180-
else {
181+
else
181182
assert(unapplyName == nme.unapply)
182-
if (isProductMatch(unapplyResult, args.length, pos))
183+
if isProductMatch(unapplyResult, args.length, pos) then
183184
productSelectorTypes(unapplyResult, pos)
184-
else if (isGetMatch(unapplyResult, pos))
185+
else if isGetMatch(unapplyResult, pos) then
185186
getUnapplySelectors(getTp, args, pos)
186-
else if (unapplyResult.widenSingleton isRef defn.BooleanClass)
187+
else if unapplyResult.derivesFrom(defn.BooleanClass) then
187188
Nil
188-
else if (defn.isProductSubType(unapplyResult) && productArity(unapplyResult, pos) != 0)
189+
else if defn.isProductSubType(unapplyResult) && productArity(unapplyResult, pos) != 0 then
189190
productSelectorTypes(unapplyResult, pos)
190191
// this will cause a "wrong number of arguments in pattern" error later on,
191192
// which is better than the message in `fail`.
192193
else if unapplyResult.derivesFrom(defn.NonEmptyTupleClass) then
193-
foldApplyTupleType(unapplyResult)
194+
unapplyResult.tupleElementTypes.getOrElse(Nil)
194195
else fail
195-
}
196-
}
197-
198-
def foldApplyTupleType(tp: Type)(using Context): List[Type] =
199-
object tupleFold extends TypeAccumulator[List[Type]]:
200-
override def apply(accum: List[Type], t: Type): List[Type] =
201-
t match
202-
case AppliedType(tycon, x :: x2 :: Nil) if tycon.typeSymbol == defn.PairClass =>
203-
apply(x :: accum, x2)
204-
case x => foldOver(accum, x)
205-
end tupleFold
206-
tupleFold(Nil, tp).reverse
196+
end unapplyArgs
207197

208198
def wrapDefs(defs: mutable.ListBuffer[Tree] | Null, tree: Tree)(using Context): Tree =
209199
if (defs != null && defs.nonEmpty) tpd.Block(defs.toList, tree) else tree

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2431,6 +2431,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
24312431
|| body1.isInstanceOf[Literal]
24322432
val symTp =
24332433
if isStableIdentifierOrLiteral || pt.isNamedTupleType then pt
2434+
// need to combine tuple element types with expected named type
24342435
else if isWildcardStarArg(body1)
24352436
|| pt == defn.ImplicitScrutineeTypeRef
24362437
|| body1.tpe <:< pt // There is some strange interaction with gadt matching.

0 commit comments

Comments
 (0)