Skip to content

Commit 7f95284

Browse files
committed
Make check more precise for single named tuple selector in pattern match
1 parent 4e684dc commit 7f95284

File tree

1 file changed

+10
-10
lines changed

1 file changed

+10
-10
lines changed

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

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -343,8 +343,12 @@ object PatternMatcher {
343343
receiver.ensureConforms(defn.NonEmptyTupleTypeRef), // If scrutinee is a named tuple, cast to underlying tuple
344344
Literal(Constant(i)))
345345

346-
val wasNamedArg = args.length == 1 && args.head.removeAttachment(FirstTransform.WasNamedArg).isDefined
347-
if (isSyntheticScala2Unapply(unapp.symbol) && caseAccessors.length == args.length && !wasNamedArg)
346+
// Disable Scala2Unapply optimization if the argument is a named argument for a single-element named tuple to
347+
// enable selecting the field. See i23131.scala for test cases.
348+
val wasSingleNamedArgForNamedTuple =
349+
args.length == 1 && args.head.removeAttachment(FirstTransform.WasNamedArg).isDefined &&
350+
isGetMatch(unappType) && unapp.select(nme.get, _.info.isParameterless).tpe.widenDealias.isNamedTupleType
351+
if (isSyntheticScala2Unapply(unapp.symbol) && caseAccessors.length == args.length && !wasSingleNamedArgForNamedTuple)
348352
def tupleSel(sym: Symbol) =
349353
// If scrutinee is a named tuple, cast to underlying tuple, so that we can
350354
// continue to select with _1, _2, ...
@@ -387,20 +391,16 @@ object PatternMatcher {
387391
}
388392
else
389393
letAbstract(get) { getResult =>
390-
def isUnaryNamedTupleSelectArg(arg: Tree) =
391-
get.tpe.widenDealias.isNamedTupleType
392-
&& wasNamedArg
393394
// Special case: Normally, we pull out the argument wholesale if
394395
// there is only one. But if the argument is a named argument for
395396
// a single-element named tuple, we have to select the field instead.
396397
// NamedArg trees are eliminated in FirstTransform but for named arguments
397398
// of patterns we add a WasNamedArg attachment, which is used to guide the
398399
// logic here. See i22900.scala for test cases.
399-
val selectors = args match
400-
case arg :: Nil if !isUnaryNamedTupleSelectArg(arg) =>
401-
ref(getResult) :: Nil
402-
case _ =>
403-
productSelectors(getResult.info).map(ref(getResult).select(_))
400+
val selectors = if args.length == 1 && !wasSingleNamedArgForNamedTuple then
401+
ref(getResult) :: Nil
402+
else
403+
productSelectors(getResult.info).map(ref(getResult).select(_))
404404
matchArgsPlan(selectors, args, onSuccess)
405405
}
406406
}

0 commit comments

Comments
 (0)