@@ -282,7 +282,7 @@ LayoutConstraint AbstractionPattern::getLayoutConstraint() const {
282
282
}
283
283
}
284
284
285
- bool AbstractionPattern::matchesTuple (CanTupleType substType) {
285
+ bool AbstractionPattern::matchesTuple (CanTupleType substType) const {
286
286
switch (getKind ()) {
287
287
case Kind::Invalid:
288
288
llvm_unreachable (" querying invalid abstraction pattern!" );
@@ -311,26 +311,25 @@ bool AbstractionPattern::matchesTuple(CanTupleType substType) {
311
311
LLVM_FALLTHROUGH;
312
312
case Kind::Tuple: {
313
313
size_t nextSubstIndex = 0 ;
314
- auto nextComponentIsAcceptable =
315
- [&](AbstractionPattern origComponentType) -> bool {
314
+ auto nextComponentIsAcceptable = [&](bool isPackExpansion) -> bool {
316
315
if (nextSubstIndex == substType->getNumElements ())
317
316
return false ;
318
317
auto substComponentType = substType.getElementType (nextSubstIndex++);
319
- return (origComponentType.isPackExpansion () ==
320
- isa<PackExpansionType>(substComponentType));
318
+ return (isPackExpansion == isa<PackExpansionType>(substComponentType));
321
319
};
322
- for (size_t i = 0 , n = getNumTupleElements (); i != n; ++i) {
323
- auto elt = getTupleElementType (i);
324
- if (elt.isPackExpansion ()) {
325
- bool fail = false ;
326
- elt.forEachPackExpandedComponent ([&](AbstractionPattern component) {
327
- if (!nextComponentIsAcceptable (component))
328
- fail = true ;
329
- });
330
- if (fail) return false ;
331
- } else {
332
- if (!nextComponentIsAcceptable (elt))
333
- return false ;
320
+ for (auto elt : getTupleElementTypes ()) {
321
+ bool isPackExpansion = elt.isPackExpansion ();
322
+ if (isPackExpansion && elt.GenericSubs ) {
323
+ auto origExpansion = cast<PackExpansionType>(elt.getType ());
324
+ auto substShape = cast<PackType>(
325
+ origExpansion.getCountType ().subst (elt.GenericSubs )
326
+ ->getCanonicalType ());
327
+ for (auto shapeElt : substShape.getElementTypes ()) {
328
+ if (!nextComponentIsAcceptable (isa<PackExpansionType>(shapeElt)))
329
+ return false ;
330
+ }
331
+ } else if (!nextComponentIsAcceptable (isPackExpansion)) {
332
+ return false ;
334
333
}
335
334
}
336
335
return nextSubstIndex == substType->getNumElements ();
@@ -469,6 +468,87 @@ bool AbstractionPattern::doesTupleContainPackExpansionType() const {
469
468
llvm_unreachable (" bad kind" );
470
469
}
471
470
471
+ void AbstractionPattern::forEachTupleElement (CanTupleType substType,
472
+ llvm::function_ref<void (unsigned origEltIndex,
473
+ unsigned substEltIndex,
474
+ AbstractionPattern origEltType,
475
+ CanType substEltType)>
476
+ handleScalar,
477
+ llvm::function_ref<void(unsigned origEltIndex,
478
+ unsigned substEltIndex,
479
+ AbstractionPattern origExpansionType,
480
+ CanTupleEltTypeArrayRef substEltTypes)>
481
+ handleExpansion) const {
482
+ assert (isTuple () && " can only call on a tuple expansion" );
483
+ assert (matchesTuple (substType));
484
+
485
+ size_t substEltIndex = 0 ;
486
+ auto substEltTypes = substType.getElementTypes ();
487
+ for (size_t origEltIndex : range (getNumTupleElements ())) {
488
+ auto origEltType = getTupleElementType (origEltIndex);
489
+ if (!origEltType.isPackExpansion ()) {
490
+ handleScalar (origEltIndex, substEltIndex,
491
+ origEltType, substEltTypes[substEltIndex]);
492
+ substEltIndex++;
493
+ } else {
494
+ auto numComponents = origEltType.getNumPackExpandedComponents ();
495
+ handleExpansion (origEltIndex, substEltIndex, origEltType,
496
+ substEltTypes.slice (substEltIndex, numComponents));
497
+ substEltIndex += numComponents;
498
+ }
499
+ }
500
+ assert (substEltIndex == substEltTypes.size ());
501
+ }
502
+
503
+ void AbstractionPattern::forEachExpandedTupleElement (CanTupleType substType,
504
+ llvm::function_ref<void (AbstractionPattern origEltType,
505
+ CanType substEltType,
506
+ const TupleTypeElt &elt)>
507
+ handleElement) const {
508
+ assert (matchesTuple (substType));
509
+
510
+ auto substEltTypes = substType.getElementTypes ();
511
+
512
+ // Handle opaque patterns by just iterating the substituted components.
513
+ if (!isTuple ()) {
514
+ for (auto i : indices (substEltTypes)) {
515
+ handleElement (getTupleElementType (i), substEltTypes[i],
516
+ substType->getElement (i));
517
+ }
518
+ return ;
519
+ }
520
+
521
+ // For non-opaque patterns, we have to iterate the original components
522
+ // in order to match things up properly, but we'll still end up calling
523
+ // once per substituted element.
524
+ size_t substEltIndex = 0 ;
525
+ for (size_t origEltIndex : range (getNumTupleElements ())) {
526
+ auto origEltType = getTupleElementType (origEltIndex);
527
+ if (!origEltType.isPackExpansion ()) {
528
+ handleElement (origEltType, substEltTypes[substEltIndex],
529
+ substType->getElement (substEltIndex));
530
+ substEltIndex++;
531
+ } else {
532
+ auto origPatternType = origEltType.getPackExpansionPatternType ();
533
+ for (auto i : range (origEltType.getNumPackExpandedComponents ())) {
534
+ (void ) i;
535
+ auto substEltType = substEltTypes[substEltIndex];
536
+ // When the substituted type is a pack expansion, pass down
537
+ // the original element type so that it's *also* a pack expansion.
538
+ // Clients expect to look through this structure in parallel on
539
+ // both types. The count is misleading, but normal usage won't
540
+ // access it, and there's nothing we could provide that *wouldn't*
541
+ // be misleading in one way or another.
542
+ handleElement (isa<PackExpansionType>(substEltType)
543
+ ? origEltType : origPatternType,
544
+ substEltType, substType->getElement (substEltIndex));
545
+ substEltIndex++;
546
+ }
547
+ }
548
+ }
549
+ assert (substEltIndex == substEltTypes.size ());
550
+ }
551
+
472
552
static CanType getCanPackElementType (CanType type, unsigned index) {
473
553
return cast<PackType>(type).getElementType (index);
474
554
}
@@ -541,6 +621,17 @@ bool AbstractionPattern::matchesPack(CanPackType substType) {
541
621
llvm_unreachable (" bad kind" );
542
622
}
543
623
624
+ AbstractionPattern
625
+ AbstractionPattern::getPackExpansionComponentType (CanType substType) const {
626
+ return getPackExpansionComponentType (isa<PackExpansionType>(substType));
627
+ }
628
+
629
+ AbstractionPattern
630
+ AbstractionPattern::getPackExpansionComponentType (bool isExpansion) const {
631
+ assert (isPackExpansion ());
632
+ return isExpansion ? *this : getPackExpansionPatternType ();
633
+ }
634
+
544
635
static CanType getPackExpansionPatternType (CanType type) {
545
636
return cast<PackExpansionType>(type).getPatternType ();
546
637
}
@@ -584,49 +675,6 @@ AbstractionPattern AbstractionPattern::getPackExpansionPatternType() const {
584
675
llvm_unreachable (" bad kind" );
585
676
}
586
677
587
- static CanType getPackExpansionCountType (CanType type) {
588
- return cast<PackExpansionType>(type).getCountType ();
589
- }
590
-
591
- AbstractionPattern AbstractionPattern::getPackExpansionCountType () const {
592
- switch (getKind ()) {
593
- case Kind::Invalid:
594
- llvm_unreachable (" querying invalid abstraction pattern!" );
595
- case Kind::ObjCMethodType:
596
- case Kind::CurriedObjCMethodType:
597
- case Kind::PartialCurriedObjCMethodType:
598
- case Kind::CFunctionAsMethodType:
599
- case Kind::CurriedCFunctionAsMethodType:
600
- case Kind::PartialCurriedCFunctionAsMethodType:
601
- case Kind::CXXMethodType:
602
- case Kind::CurriedCXXMethodType:
603
- case Kind::PartialCurriedCXXMethodType:
604
- case Kind::Tuple:
605
- case Kind::OpaqueFunction:
606
- case Kind::OpaqueDerivativeFunction:
607
- case Kind::ObjCCompletionHandlerArgumentsType:
608
- case Kind::ClangType:
609
- llvm_unreachable (" pattern for function or tuple cannot be for "
610
- " pack expansion type" );
611
-
612
- case Kind::Opaque:
613
- return *this ;
614
-
615
- case Kind::Type:
616
- if (isTypeParameterOrOpaqueArchetype ())
617
- return AbstractionPattern::getOpaque ();
618
- return AbstractionPattern (getGenericSubstitutions (),
619
- getGenericSignature (),
620
- ::getPackExpansionCountType (getType()));
621
-
622
- case Kind::Discard:
623
- return AbstractionPattern::getDiscard (
624
- getGenericSubstitutions (), getGenericSignature (),
625
- ::getPackExpansionCountType (getType()));
626
- }
627
- llvm_unreachable (" bad kind" );
628
- }
629
-
630
678
SmallVector<AbstractionPattern, 4 >
631
679
AbstractionPattern::getPackExpandedComponents () const {
632
680
SmallVector<AbstractionPattern, 4 > result;
@@ -636,6 +684,21 @@ AbstractionPattern::getPackExpandedComponents() const {
636
684
return result;
637
685
}
638
686
687
+ size_t AbstractionPattern::getNumPackExpandedComponents () const {
688
+ assert (isPackExpansion ());
689
+ assert (getKind () == Kind::Type || getKind () == Kind::Discard);
690
+
691
+ // If we don't have substitutions, we should be walking parallel
692
+ // structure; take a single element.
693
+ if (!GenericSubs) return 1 ;
694
+
695
+ // Otherwise, substitute the expansion shape.
696
+ auto origExpansion = cast<PackExpansionType>(getType ());
697
+ auto substShape = cast<PackType>(
698
+ origExpansion.getCountType ().subst (GenericSubs)->getCanonicalType ());
699
+ return substShape->getNumElements ();
700
+ }
701
+
639
702
void AbstractionPattern::forEachPackExpandedComponent (
640
703
llvm::function_ref<void (AbstractionPattern)> fn) const {
641
704
assert (isPackExpansion ());
@@ -665,7 +728,7 @@ void AbstractionPattern::forEachPackExpandedComponent(
665
728
}
666
729
667
730
default :
668
- return fn (* this );
731
+ llvm_unreachable ( " not a pack expansion " );
669
732
}
670
733
llvm_unreachable (" bad kind" );
671
734
}
@@ -692,8 +755,9 @@ AbstractionPattern AbstractionPattern::removingMoveOnlyWrapper() const {
692
755
llvm_unreachable (" not handled yet" );
693
756
case Kind::Discard:
694
757
llvm_unreachable (" operation not needed on discarded abstractions yet" );
695
- case Kind::Opaque:
696
758
case Kind::Tuple:
759
+ llvm_unreachable (" cannot apply move-only wrappers to open-coded patterns" );
760
+ case Kind::Opaque:
697
761
case Kind::Type:
698
762
if (auto mvi = dyn_cast<SILMoveOnlyWrappedType>(getType ())) {
699
763
return AbstractionPattern (getGenericSubstitutions (),
@@ -727,8 +791,9 @@ AbstractionPattern AbstractionPattern::addingMoveOnlyWrapper() const {
727
791
llvm_unreachable (" not handled yet" );
728
792
case Kind::Discard:
729
793
llvm_unreachable (" operation not needed on discarded abstractions yet" );
730
- case Kind::Opaque:
731
794
case Kind::Tuple:
795
+ llvm_unreachable (" cannot add move only wrapper to open-coded pattern" );
796
+ case Kind::Opaque:
732
797
case Kind::Type:
733
798
if (isa<SILMoveOnlyWrappedType>(getType ()))
734
799
return *this ;
@@ -1686,7 +1751,7 @@ AbstractionPattern::operator==(const AbstractionPattern &other) const {
1686
1751
}
1687
1752
}
1688
1753
return true ;
1689
-
1754
+
1690
1755
case Kind::Type:
1691
1756
case Kind::Discard:
1692
1757
return OrigType == other.OrigType
@@ -1996,7 +2061,7 @@ class SubstFunctionTypePatternVisitor
1996
2061
auto substPatternType = visit (pack->getPatternType (),
1997
2062
pattern.getPackExpansionPatternType ());
1998
2063
auto substCountType = visit (pack->getCountType (),
1999
- pattern. getPackExpansionCountType ());
2064
+ AbstractionPattern::getOpaque ());
2000
2065
2001
2066
SmallVector<Type> rootParameterPacks;
2002
2067
substPatternType->getTypeParameterPacks (rootParameterPacks);
0 commit comments