Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions include/swift/SIL/AbstractionPattern.h
Original file line number Diff line number Diff line change
Expand Up @@ -1516,6 +1516,10 @@ class AbstractionPattern {
/// the abstraction pattern for its self type.
AbstractionPattern getDynamicSelfSelfType() const;

/// Given that the value being abstracted is a protocol composition
/// type, return the abstraction pattern for one of its member types.
AbstractionPattern getProtocolCompositionMemberType(unsigned i) const;

/// Given that the value being abstracted is a parameterized protocol
/// type, return the abstraction pattern for one of its argument types.
AbstractionPattern getParameterizedProtocolArgType(unsigned i) const;
Expand Down
36 changes: 33 additions & 3 deletions lib/SIL/IR/AbstractionPattern.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1022,6 +1022,14 @@ AbstractionPattern AbstractionPattern::getDynamicSelfSelfType() const {
cast<DynamicSelfType>(getType()).getSelfType());
}

AbstractionPattern
AbstractionPattern::getProtocolCompositionMemberType(unsigned argIndex) const {
assert(getKind() == Kind::Type);
return AbstractionPattern(getGenericSubstitutions(),
getGenericSignature(),
cast<ProtocolCompositionType>(getType()).getMembers()[argIndex]);
}

AbstractionPattern
AbstractionPattern::getParameterizedProtocolArgType(unsigned argIndex) const {
assert(getKind() == Kind::Type);
Expand Down Expand Up @@ -2699,22 +2707,44 @@ class SubstFunctionTypePatternVisitor
CanType visitParameterizedProtocolType(CanParameterizedProtocolType ppt,
AbstractionPattern pattern) {
// Recurse into the arguments of the parameterized protocol.
SmallVector<Type, 4> substArgs;
auto origPPT = pattern.getAs<ParameterizedProtocolType>();
if (!origPPT)
return ppt;

SmallVector<Type, 4> substArgs;
for (unsigned i = 0; i < ppt->getArgs().size(); ++i) {
auto argTy = ppt.getArgs()[i];
auto origArgTy = pattern.getParameterizedProtocolArgType(i);
auto substEltTy = visit(argTy, origArgTy);
substArgs.push_back(substEltTy);
auto substArgTy = visit(argTy, origArgTy);
substArgs.push_back(substArgTy);
}

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

CanType visitProtocolCompositionType(CanProtocolCompositionType pct,
AbstractionPattern pattern) {
// Recurse into the arguments of the protocol composition.
auto origPCT = pattern.getAs<ProtocolCompositionType>();
if (!origPCT)
return pct;

SmallVector<Type, 4> substMembers;
for (unsigned i = 0; i < pct->getMembers().size(); ++i) {
auto memberTy = CanType(pct->getMembers()[i]);
auto origMemberTy = pattern.getProtocolCompositionMemberType(i);
auto substMemberTy = visit(memberTy, origMemberTy);
substMembers.push_back(substMemberTy);
}

return CanType(ProtocolCompositionType::get(
TC.Context,
substMembers,
pct->getInverses(),
pct->hasExplicitAnyObject()));
}

/// Visit a tuple pattern. Note that, because of vanishing tuples,
/// we can't handle this case by matching a tuple type in the
/// substituted type; we have to check for a tuple pattern in the
Expand Down
20 changes: 20 additions & 0 deletions test/SILGen/subst_function_type_existential.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// RUN: %target-swift-emit-silgen %s

// https://github.com/swiftlang/swift/issues/62061

protocol P {}

class C<T> {}

protocol Q {
associatedtype A
}

func foo1<T>(t: T) {
let _: (any P & C<T>) -> T = { x in t }
}

func foo2<T: Q>(t: T) {
let _: (any P & C<(T.A) -> ()>) -> T = { x in t }
}