Skip to content

Commit 0a51b8d

Browse files
authored
Merge pull request #67403 from slavapestov/sil-pattern-count-abstraction-5.9
SIL: Fix substituted function type visitor for PackExpansionType with concrete pattern type [5.9]
2 parents 428090f + e4cbba9 commit 0a51b8d

File tree

3 files changed

+72
-10
lines changed

3 files changed

+72
-10
lines changed

include/swift/SIL/AbstractionPattern.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1472,13 +1472,12 @@ class AbstractionPattern {
14721472

14731473
/// Given that the value being abstracted is a pack expansion type,
14741474
/// return the underlying pattern type.
1475-
///
1476-
/// If you're looking for getPackExpansionCountType(), it deliberately
1477-
/// does not exist. Count types are not lowered types, and the original
1478-
/// count types are not relevant to lowering. Only the substituted
1479-
/// components and expansion counts are significant.
14801475
AbstractionPattern getPackExpansionPatternType() const;
14811476

1477+
/// Given that the value being abstracted is a pack expansion type,
1478+
/// return the underlying count type.
1479+
AbstractionPattern getPackExpansionCountType() const;
1480+
14821481
/// Given that the value being abstracted is a pack expansion type,
14831482
/// return the appropriate pattern type for the given expansion
14841483
/// component.

lib/SIL/IR/AbstractionPattern.cpp

Lines changed: 60 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -795,6 +795,49 @@ AbstractionPattern AbstractionPattern::getPackExpansionPatternType() const {
795795
llvm_unreachable("bad kind");
796796
}
797797

798+
static CanType getPackExpansionCountType(CanType type) {
799+
return cast<PackExpansionType>(type).getCountType();
800+
}
801+
802+
AbstractionPattern AbstractionPattern::getPackExpansionCountType() const {
803+
switch (getKind()) {
804+
case Kind::Invalid:
805+
llvm_unreachable("querying invalid abstraction pattern!");
806+
case Kind::ObjCMethodType:
807+
case Kind::CurriedObjCMethodType:
808+
case Kind::PartialCurriedObjCMethodType:
809+
case Kind::CFunctionAsMethodType:
810+
case Kind::CurriedCFunctionAsMethodType:
811+
case Kind::PartialCurriedCFunctionAsMethodType:
812+
case Kind::CXXMethodType:
813+
case Kind::CurriedCXXMethodType:
814+
case Kind::PartialCurriedCXXMethodType:
815+
case Kind::Tuple:
816+
case Kind::OpaqueFunction:
817+
case Kind::OpaqueDerivativeFunction:
818+
case Kind::ObjCCompletionHandlerArgumentsType:
819+
case Kind::ClangType:
820+
llvm_unreachable("pattern for function or tuple cannot be for "
821+
"pack expansion type");
822+
823+
case Kind::Opaque:
824+
return *this;
825+
826+
case Kind::Type:
827+
if (isTypeParameterOrOpaqueArchetype())
828+
return AbstractionPattern::getOpaque();
829+
return AbstractionPattern(getGenericSubstitutions(),
830+
getGenericSignature(),
831+
::getPackExpansionCountType(getType()));
832+
833+
case Kind::Discard:
834+
return AbstractionPattern::getDiscard(
835+
getGenericSubstitutions(), getGenericSignature(),
836+
::getPackExpansionCountType(getType()));
837+
}
838+
llvm_unreachable("bad kind");
839+
}
840+
798841
size_t AbstractionPattern::getNumPackExpandedComponents() const {
799842
assert(isPackExpansion());
800843
assert(getKind() == Kind::Type || getKind() == Kind::Discard);
@@ -2268,7 +2311,7 @@ class SubstFunctionTypePatternVisitor
22682311
// Recursively visit the pattern type.
22692312
auto patternTy = visit(substPatternType, origPatternType);
22702313

2271-
// Find a pack parameter from the pattern to expand over.
2314+
// If the pattern contains a pack parameter, use that as the count type.
22722315
CanType countParam;
22732316
patternTy->walkPackReferences([&](Type t) {
22742317
if (t->isTypeParameter()) {
@@ -2282,10 +2325,22 @@ class SubstFunctionTypePatternVisitor
22822325
return false;
22832326
});
22842327

2285-
// If that didn't work, we should be able to find an expansion
2286-
// to use from either the substituted type or the subs. At worst,
2287-
// we can make one.
2288-
assert(countParam && "implementable but lazy");
2328+
// If the pattern was fully substituted, substitute the original
2329+
// count type and use that instead.
2330+
if (!countParam) {
2331+
auto origCountType = origExpansion.getPackExpansionCountType();
2332+
CanType substCountType;
2333+
if (origExpansion.getGenericSubstitutions()) {
2334+
substCountType = cast<PackExpansionType>(origExpansion.getType())
2335+
.getCountType();
2336+
} else {
2337+
assert(candidateSubstType);
2338+
substCountType =
2339+
cast<PackExpansionType>(candidateSubstType).getCountType();
2340+
}
2341+
2342+
countParam = visit(substCountType, origCountType);
2343+
}
22892344

22902345
return CanPackExpansionType::get(patternTy, countParam);
22912346
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// RUN: %target-swift-frontend -emit-ir %s
2+
3+
public func test<each T: BinaryInteger>(_ values: repeat each T) {
4+
var values = (repeat UInt32(truncatingIfNeeded: each values))
5+
withUnsafePointer(to: &values) { ptr in
6+
_ = ptr[0]
7+
}
8+
}

0 commit comments

Comments
 (0)