Skip to content

Commit 6b57a9f

Browse files
authored
Merge pull request #76511 from slavapestov/fix-issue-62061
SIL: Handle ProtocolCompositionType in SubstFunctionTypePatternVisitor
2 parents 6c92f3f + 5147adc commit 6b57a9f

File tree

3 files changed

+57
-3
lines changed

3 files changed

+57
-3
lines changed

include/swift/SIL/AbstractionPattern.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1516,6 +1516,10 @@ class AbstractionPattern {
15161516
/// the abstraction pattern for its self type.
15171517
AbstractionPattern getDynamicSelfSelfType() const;
15181518

1519+
/// Given that the value being abstracted is a protocol composition
1520+
/// type, return the abstraction pattern for one of its member types.
1521+
AbstractionPattern getProtocolCompositionMemberType(unsigned i) const;
1522+
15191523
/// Given that the value being abstracted is a parameterized protocol
15201524
/// type, return the abstraction pattern for one of its argument types.
15211525
AbstractionPattern getParameterizedProtocolArgType(unsigned i) const;

lib/SIL/IR/AbstractionPattern.cpp

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,6 +1022,14 @@ AbstractionPattern AbstractionPattern::getDynamicSelfSelfType() const {
10221022
cast<DynamicSelfType>(getType()).getSelfType());
10231023
}
10241024

1025+
AbstractionPattern
1026+
AbstractionPattern::getProtocolCompositionMemberType(unsigned argIndex) const {
1027+
assert(getKind() == Kind::Type);
1028+
return AbstractionPattern(getGenericSubstitutions(),
1029+
getGenericSignature(),
1030+
cast<ProtocolCompositionType>(getType()).getMembers()[argIndex]);
1031+
}
1032+
10251033
AbstractionPattern
10261034
AbstractionPattern::getParameterizedProtocolArgType(unsigned argIndex) const {
10271035
assert(getKind() == Kind::Type);
@@ -2699,22 +2707,44 @@ class SubstFunctionTypePatternVisitor
26992707
CanType visitParameterizedProtocolType(CanParameterizedProtocolType ppt,
27002708
AbstractionPattern pattern) {
27012709
// Recurse into the arguments of the parameterized protocol.
2702-
SmallVector<Type, 4> substArgs;
27032710
auto origPPT = pattern.getAs<ParameterizedProtocolType>();
27042711
if (!origPPT)
27052712
return ppt;
27062713

2714+
SmallVector<Type, 4> substArgs;
27072715
for (unsigned i = 0; i < ppt->getArgs().size(); ++i) {
27082716
auto argTy = ppt.getArgs()[i];
27092717
auto origArgTy = pattern.getParameterizedProtocolArgType(i);
2710-
auto substEltTy = visit(argTy, origArgTy);
2711-
substArgs.push_back(substEltTy);
2718+
auto substArgTy = visit(argTy, origArgTy);
2719+
substArgs.push_back(substArgTy);
27122720
}
27132721

27142722
return CanType(ParameterizedProtocolType::get(
27152723
TC.Context, ppt->getBaseType(), substArgs));
27162724
}
27172725

2726+
CanType visitProtocolCompositionType(CanProtocolCompositionType pct,
2727+
AbstractionPattern pattern) {
2728+
// Recurse into the arguments of the protocol composition.
2729+
auto origPCT = pattern.getAs<ProtocolCompositionType>();
2730+
if (!origPCT)
2731+
return pct;
2732+
2733+
SmallVector<Type, 4> substMembers;
2734+
for (unsigned i = 0; i < pct->getMembers().size(); ++i) {
2735+
auto memberTy = CanType(pct->getMembers()[i]);
2736+
auto origMemberTy = pattern.getProtocolCompositionMemberType(i);
2737+
auto substMemberTy = visit(memberTy, origMemberTy);
2738+
substMembers.push_back(substMemberTy);
2739+
}
2740+
2741+
return CanType(ProtocolCompositionType::get(
2742+
TC.Context,
2743+
substMembers,
2744+
pct->getInverses(),
2745+
pct->hasExplicitAnyObject()));
2746+
}
2747+
27182748
/// Visit a tuple pattern. Note that, because of vanishing tuples,
27192749
/// we can't handle this case by matching a tuple type in the
27202750
/// substituted type; we have to check for a tuple pattern in the
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// RUN: %target-swift-emit-silgen %s
2+
3+
// https://github.com/swiftlang/swift/issues/62061
4+
5+
protocol P {}
6+
7+
class C<T> {}
8+
9+
protocol Q {
10+
associatedtype A
11+
}
12+
13+
func foo1<T>(t: T) {
14+
let _: (any P & C<T>) -> T = { x in t }
15+
}
16+
17+
func foo2<T: Q>(t: T) {
18+
let _: (any P & C<(T.A) -> ()>) -> T = { x in t }
19+
}
20+

0 commit comments

Comments
 (0)