Skip to content

Commit fa4e4be

Browse files
authored
Merge pull request swiftlang#9204 from jckarter/opened-type-subst
SILCloner: Map opened types using Type::subst instead of transform.
2 parents 75a1dca + 6764072 commit fa4e4be

File tree

3 files changed

+37
-21
lines changed

3 files changed

+37
-21
lines changed

include/swift/AST/Type.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,15 @@ struct QueryTypeSubstitutionMap {
7272
Type operator()(SubstitutableType *type) const;
7373
};
7474

75+
/// A function object suitable for use as a \c TypeSubstitutionFn that
76+
/// queries an underlying \c TypeSubstitutionMap, or returns the original type
77+
/// if no match was found.
78+
struct QueryTypeSubstitutionMapOrIdentity {
79+
const TypeSubstitutionMap &substitutions;
80+
81+
Type operator()(SubstitutableType *type) const;
82+
};
83+
7584
/// A function object suitable for use as a \c TypeSubstitutionFn that
7685
/// queries an underlying \c SubstitutionMap.
7786
struct QuerySubstitutionMap {

include/swift/SIL/SILCloner.h

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -118,10 +118,21 @@ class SILCloner : protected SILVisitor<ImplClass> {
118118
}
119119

120120
SILType getTypeInClonedContext(SILType Ty) {
121+
auto objectTy = Ty.getSwiftRValueType();
122+
// Do not substitute opened existential types, if we do not have any.
123+
if (!objectTy->hasOpenedExistential())
124+
return Ty;
125+
// Do not substitute opened existential types, if it is not required.
126+
// This is often the case when cloning basic blocks inside the same
127+
// function.
128+
if (OpenedExistentialSubs.empty())
129+
return Ty;
130+
121131
// Substitute opened existential types, if we have any.
122-
return SILType::getPrimitiveObjectType(
123-
getASTTypeInClonedContext(Ty.getSwiftRValueType()))
124-
.copyCategory(Ty);
132+
return Ty.subst(
133+
Builder.getModule(),
134+
QueryTypeSubstitutionMapOrIdentity{OpenedExistentialSubs},
135+
MakeAbstractConformanceForGenericType());
125136
}
126137
SILType getOpType(SILType Ty) {
127138
Ty = getTypeInClonedContext(Ty);
@@ -138,24 +149,10 @@ class SILCloner : protected SILVisitor<ImplClass> {
138149
if (OpenedExistentialSubs.empty())
139150
return ty->getCanonicalType();
140151

141-
return ty.transform(
142-
[&](Type t) -> Type {
143-
if (t->isOpenedExistential()) {
144-
auto found = OpenedExistentialSubs.find(
145-
t->castTo<ArchetypeType>());
146-
// If an opened existential is supposed to be
147-
// remapped, it is guaranteed by construction
148-
// to be in the OpenedExistentialSubs, because
149-
// a cloner always processes definitions of
150-
// opened existentials before their uses and
151-
// adds found opened existentials definitions
152-
// to the map.
153-
if (found != OpenedExistentialSubs.end())
154-
return found->second;
155-
return t;
156-
}
157-
return t;
158-
})->getCanonicalType();
152+
return ty.subst(
153+
QueryTypeSubstitutionMapOrIdentity{OpenedExistentialSubs},
154+
MakeAbstractConformanceForGenericType()
155+
)->getCanonicalType();
159156
}
160157

161158
CanType getOpASTType(CanType ty) {

lib/AST/Type.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,16 @@ Type QueryTypeSubstitutionMap::operator()(SubstitutableType *type) const {
5050
return Type();
5151
}
5252

53+
Type
54+
QueryTypeSubstitutionMapOrIdentity::operator()(SubstitutableType *type) const {
55+
auto key = type->getCanonicalType()->castTo<SubstitutableType>();
56+
auto known = substitutions.find(key);
57+
if (known != substitutions.end() && known->second)
58+
return known->second;
59+
60+
return type;
61+
}
62+
5363
Type QuerySubstitutionMap::operator()(SubstitutableType *type) const {
5464
auto key = cast<SubstitutableType>(type->getCanonicalType());
5565
return subMap.lookupSubstitution(key);

0 commit comments

Comments
 (0)