Skip to content

Commit 6b4710e

Browse files
authored
Merge pull request #81142 from slavapestov/more-type-subst-cleanup
Clean up duplicated opened existential archetype handling in SIL and more
2 parents 7b5b5e9 + 2fa49b0 commit 6b4710e

28 files changed

+150
-174
lines changed

SwiftCompilerSources/Sources/AST/Type.swift

-8
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,6 @@ public struct Type: TypeProperties, CustomStringConvertible, NoReflectionChildre
6464
public func subst(with substitutionMap: SubstitutionMap) -> Type {
6565
return Type(bridged: bridged.subst(substitutionMap.bridged))
6666
}
67-
68-
public func subst(type: Type, with targetType: Type) -> Type {
69-
return Type(bridged: bridged.subst(type.bridged, targetType.bridged))
70-
}
7167
}
7268

7369
/// A Type that is statically known to be canonical.
@@ -88,10 +84,6 @@ public struct CanonicalType: TypeProperties, CustomStringConvertible, NoReflecti
8884
public func subst(with substitutionMap: SubstitutionMap) -> CanonicalType {
8985
return rawType.subst(with: substitutionMap).canonical
9086
}
91-
92-
public func subst(type: CanonicalType, with targetType: CanonicalType) -> CanonicalType {
93-
return self.rawType.subst(type: type.rawType, with: targetType.rawType).canonical
94-
}
9587
}
9688

9789
/// Implements the common members of `AST.Type`, `AST.CanonicalType` and `SIL.Type`.

include/swift/AST/ASTBridging.h

-1
Original file line numberDiff line numberDiff line change
@@ -3115,7 +3115,6 @@ struct BridgedASTType {
31153115
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedSubstitutionMap getContextSubstitutionMap() const;
31163116
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedGenericSignature getInvocationGenericSignatureOfFunctionType() const;
31173117
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedASTType subst(BridgedSubstitutionMap substMap) const;
3118-
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedASTType subst(BridgedASTType fromType, BridgedASTType toType) const;
31193118
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedConformance checkConformance(BridgedDeclObj proto) const;
31203119
};
31213120

include/swift/AST/ASTBridgingImpl.h

-11
Original file line numberDiff line numberDiff line change
@@ -596,17 +596,6 @@ BridgedASTType BridgedASTType::subst(BridgedSubstitutionMap substMap) const {
596596
return {unbridged().subst(substMap.unbridged()).getPointer()};
597597
}
598598

599-
600-
BridgedASTType BridgedASTType::subst(BridgedASTType fromType, BridgedASTType toType) const {
601-
auto *fromTy = fromType.unbridged()->castTo<swift::SubstitutableType>();
602-
swift::Type toTy = toType.unbridged();
603-
return {unbridged().subst([fromTy, toTy](swift::SubstitutableType *t) -> swift::Type {
604-
if (t == fromTy)
605-
return toTy;
606-
return t;
607-
}, swift::LookUpConformanceInModule(), swift::SubstFlags::SubstituteLocalArchetypes).getPointer()};
608-
}
609-
610599
BridgedConformance BridgedASTType::checkConformance(BridgedDeclObj proto) const {
611600
return swift::checkConformance(unbridged(), proto.getAs<swift::ProtocolDecl>(), /*allowMissing=*/ false);
612601
}

include/swift/AST/ASTContext.h

+3
Original file line numberDiff line numberDiff line change
@@ -1051,6 +1051,9 @@ class ASTContext final {
10511051
const CanType TheUnconstrainedAnyType; /// This is 'any ~Copyable & ~Escapable',
10521052
/// the empty protocol composition
10531053
/// without any implicit constraints.
1054+
const CanGenericTypeParamType TheSelfType; /// The protocol 'Self' type;
1055+
/// a generic parameter with
1056+
/// depth 0 index 0
10541057
#define SINGLETON_TYPE(SHORT_ID, ID) \
10551058
const CanType The##SHORT_ID##Type;
10561059
#include "swift/AST/TypeNodes.def"

include/swift/AST/InFlightSubstitution.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,7 @@ class InFlightSubstitution {
5252
Type substType(SubstitutableType *origType, unsigned level);
5353

5454
/// Perform primitive conformance lookup on the given type.
55-
ProtocolConformanceRef lookupConformance(CanType dependentType,
56-
Type conformingReplacementType,
55+
ProtocolConformanceRef lookupConformance(Type dependentType,
5756
ProtocolDecl *conformedProtocol,
5857
unsigned level);
5958

include/swift/AST/SubstitutionMap.h

-6
Original file line numberDiff line numberDiff line change
@@ -181,12 +181,6 @@ class SubstitutionMap {
181181
/// subsystem.
182182
SubstitutionMap subst(InFlightSubstitution &subs) const;
183183

184-
/// Apply type expansion lowering to all types in the substitution map. Opaque
185-
/// archetypes will be lowered to their underlying types if the type expansion
186-
/// context allows.
187-
SubstitutionMap mapIntoTypeExpansionContext(
188-
TypeExpansionContext context) const;
189-
190184
/// Create a substitution map for a protocol conformance.
191185
static SubstitutionMap
192186
getProtocolSubstitutions(ProtocolConformanceRef conformance);

include/swift/AST/Types.h

+32
Original file line numberDiff line numberDiff line change
@@ -5032,9 +5032,15 @@ Type substOpaqueTypesWithUnderlyingTypes(Type type,
50325032

50335033
CanType substOpaqueTypesWithUnderlyingTypes(CanType type,
50345034
TypeExpansionContext context);
5035+
50355036
ProtocolConformanceRef
50365037
substOpaqueTypesWithUnderlyingTypes(ProtocolConformanceRef ref,
50375038
TypeExpansionContext context);
5039+
5040+
SubstitutionMap
5041+
substOpaqueTypesWithUnderlyingTypes(SubstitutionMap subs,
5042+
TypeExpansionContext context);
5043+
50385044
namespace Lowering {
50395045
class TypeConverter;
50405046
}
@@ -7082,6 +7088,32 @@ class ReplaceOpaqueTypesWithUnderlyingTypes {
70827088
bool isWholeModule() const { return inContextAndIsWholeModule.getInt(); }
70837089
};
70847090

7091+
/// A function object that can be used as a \c TypeSubstitutionFn and
7092+
/// \c LookupConformanceFn for \c Type::subst style APIs to map existential
7093+
/// archetypes in the given generic environment to known concrete types from
7094+
/// the given substitution map.
7095+
class ReplaceExistentialArchetypesWithConcreteTypes {
7096+
private:
7097+
GenericEnvironment *env;
7098+
SubstitutionMap subs;
7099+
7100+
Type getInterfaceType(ExistentialArchetypeType *type) const;
7101+
7102+
public:
7103+
ReplaceExistentialArchetypesWithConcreteTypes(GenericEnvironment *env,
7104+
SubstitutionMap subs)
7105+
: env(env), subs(subs) {}
7106+
7107+
/// TypeSubstitutionFn
7108+
Type operator()(SubstitutableType *type) const;
7109+
7110+
/// LookupConformanceFn
7111+
ProtocolConformanceRef operator()(CanType origType,
7112+
Type substType,
7113+
ProtocolDecl *protocol) const;
7114+
7115+
};
7116+
70857117
/// An archetype that's only valid in a portion of a local context.
70867118
class LocalArchetypeType : public ArchetypeType {
70877119
protected:

include/swift/SIL/SILCloner.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -590,7 +590,7 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
590590
!context.shouldLookThroughOpaqueTypeArchetypes())
591591
return Subs;
592592

593-
return Subs.mapIntoTypeExpansionContext(context);
593+
return substOpaqueTypesWithUnderlyingTypes(Subs, context);
594594
}
595595

596596
return Subs;

lib/AST/ASTContext.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -817,6 +817,8 @@ ASTContext::ASTContext(
817817
TheAnyType(ProtocolCompositionType::theAnyType(*this)),
818818
TheUnconstrainedAnyType(
819819
ProtocolCompositionType::theUnconstrainedAnyType(*this)),
820+
TheSelfType(CanGenericTypeParamType(
821+
GenericTypeParamType::getType(0, 0, *this))),
820822
#define SINGLETON_TYPE(SHORT_ID, ID) \
821823
The##SHORT_ID##Type(new (*this, AllocationArena::Permanent) \
822824
ID##Type(*this)),
@@ -6646,8 +6648,7 @@ CanGenericSignature ASTContext::getSingleGenericParameterSignature() const {
66466648
if (auto theSig = getImpl().SingleGenericParameterSignature)
66476649
return theSig;
66486650

6649-
auto param = GenericTypeParamType::getType(/*depth*/ 0, /*index*/ 0, *this);
6650-
auto sig = GenericSignature::get(param, { });
6651+
auto sig = GenericSignature::get({TheSelfType}, { });
66516652
auto canonicalSig = CanGenericSignature(sig);
66526653
getImpl().SingleGenericParameterSignature = canonicalSig;
66536654
return canonicalSig;

lib/AST/ASTMangler.cpp

+3-7
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ std::string ASTMangler::mangleKeyPathGetterThunkHelper(
395395
sub = sub.transformRec([](Type t) -> std::optional<Type> {
396396
if (auto *openedExistential = t->getAs<ExistentialArchetypeType>()) {
397397
auto &ctx = openedExistential->getASTContext();
398-
return GenericTypeParamType::getType(0, 0, ctx);
398+
return ctx.TheSelfType;
399399
}
400400
return std::nullopt;
401401
});
@@ -431,7 +431,7 @@ std::string ASTMangler::mangleKeyPathSetterThunkHelper(
431431
sub = sub.transformRec([](Type t) -> std::optional<Type> {
432432
if (auto *openedExistential = t->getAs<ExistentialArchetypeType>()) {
433433
auto &ctx = openedExistential->getASTContext();
434-
return GenericTypeParamType::getType(0, 0, ctx);
434+
return ctx.TheSelfType;
435435
}
436436
return std::nullopt;
437437
});
@@ -5274,15 +5274,11 @@ static void extractExistentialInverseRequirements(
52745274

52755275
auto &ctx = PCT->getASTContext();
52765276

5277-
// Form a parameter referring to the existential's Self.
5278-
auto existentialSelf =
5279-
GenericTypeParamType::getType(/*depth=*/0, /*index=*/0, ctx);
5280-
52815277
for (auto ip : PCT->getInverses()) {
52825278
auto *proto = ctx.getProtocol(getKnownProtocolKind(ip));
52835279
assert(proto);
52845280
ASSERT(!getABIDecl(proto) && "can't use @abi on inverse protocols");
5285-
inverses.push_back({existentialSelf, proto, SourceLoc()});
5281+
inverses.push_back({ctx.TheSelfType, proto, SourceLoc()});
52865282
}
52875283
}
52885284

lib/AST/ASTPrinter.cpp

+7-6
Original file line numberDiff line numberDiff line change
@@ -4334,13 +4334,14 @@ void PrintAST::visitFuncDecl(FuncDecl *decl) {
43344334
if (proto && Options.TransformContext) {
43354335
auto BaseType = Options.TransformContext->getBaseType();
43364336
if (BaseType->getClassOrBoundGenericClass()) {
4337-
ResultTy = ResultTy.subst(
4338-
[&](Type t) -> Type {
4339-
if (t->isEqual(proto->getSelfInterfaceType()))
4337+
ResultTy = ResultTy.transformRec(
4338+
[&](TypeBase *t) -> std::optional<Type> {
4339+
if (isa<DependentMemberType>(t))
4340+
return t;
4341+
else if (t->isEqual(proto->getSelfInterfaceType()))
43404342
return DynamicSelfType::get(t, Ctx);
4341-
return t;
4342-
},
4343-
MakeAbstractConformanceForGenericType());
4343+
return std::nullopt;
4344+
});
43444345
ResultTyLoc = TypeLoc::withoutLoc(ResultTy);
43454346
}
43464347
}

lib/AST/ProtocolConformanceRef.cpp

+1-3
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,7 @@ ProtocolConformanceRef::subst(InFlightSubstitution &IFS) const {
111111

112112
// Local conformance lookup into the substitution map.
113113
// FIXME: Pack element level?
114-
return IFS.lookupConformance(origType->getCanonicalType(),
115-
origType.subst(IFS), proto,
116-
/*level=*/0);
114+
return IFS.lookupConformance(origType, proto, /*level=*/0);
117115
}
118116

119117
ProtocolConformanceRef ProtocolConformanceRef::mapConformanceOutOfContext() const {

lib/AST/RequirementEnvironment.cpp

+3-5
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ RequirementEnvironment::RequirementEnvironment(
9696
// type.
9797
if (type->isEqual(selfType)) {
9898
if (covariantSelf)
99-
return GenericTypeParamType::getType(/*depth=*/0, /*index=*/0, ctx);
99+
return ctx.TheSelfType;
100100
return substConcreteType;
101101
}
102102
// Other requirement generic parameters map 1:1 with their depth
@@ -169,8 +169,7 @@ RequirementEnvironment::RequirementEnvironment(
169169
// If the conforming type is a class, add a class-constrained 'Self'
170170
// parameter.
171171
if (covariantSelf) {
172-
auto paramTy = GenericTypeParamType::getType(/*depth=*/0, /*index=*/0, ctx);
173-
genericParamTypes.push_back(paramTy);
172+
genericParamTypes.push_back(ctx.TheSelfType);
174173
}
175174

176175
// Now, add all generic parameters from the conforming type.
@@ -184,8 +183,7 @@ RequirementEnvironment::RequirementEnvironment(
184183
// Next, add requirements.
185184
SmallVector<Requirement, 2> requirements;
186185
if (covariantSelf) {
187-
auto paramTy = GenericTypeParamType::getType(/*depth=*/0, /*index=*/0, ctx);
188-
Requirement reqt(RequirementKind::Superclass, paramTy, substConcreteType);
186+
Requirement reqt(RequirementKind::Superclass, ctx.TheSelfType, substConcreteType);
189187
requirements.push_back(reqt);
190188
}
191189

lib/AST/RequirementMachine/InterfaceType.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -281,11 +281,11 @@ getTypeForSymbolRange(const Symbol *begin, const Symbol *end,
281281
continue;
282282

283283
case Symbol::Kind::Protocol:
284-
handleRoot(GenericTypeParamType::getType(0, 0, ctx.getASTContext()));
284+
handleRoot(ctx.getASTContext().TheSelfType);
285285
continue;
286286

287287
case Symbol::Kind::AssociatedType:
288-
handleRoot(GenericTypeParamType::getType(0, 0, ctx.getASTContext()));
288+
handleRoot(ctx.getASTContext().TheSelfType);
289289

290290
// An associated type symbol at the root means we have a dependent
291291
// member type rooted at Self; handle the associated type below.

lib/AST/SubstitutionMap.cpp

+11-13
Original file line numberDiff line numberDiff line change
@@ -174,14 +174,12 @@ SubstitutionMap SubstitutionMap::get(GenericSignature genericSig,
174174
// Form the stored conformances.
175175
SmallVector<ProtocolConformanceRef, 4> conformances;
176176
for (const auto &req : genericSig.getRequirements()) {
177-
if (req.getKind() != RequirementKind::Conformance) continue;
178-
179-
Type depTy = req.getFirstType();
180-
auto replacement = depTy.subst(IFS);
181-
auto *proto = req.getProtocolDecl();
182-
auto conformance = IFS.lookupConformance(
183-
depTy->getCanonicalType(), replacement, proto, /*level=*/0);
184-
conformances.push_back(conformance);
177+
if (req.getKind() != RequirementKind::Conformance)
178+
continue;
179+
180+
conformances.push_back(
181+
IFS.lookupConformance(
182+
req.getFirstType(), req.getProtocolDecl(), /*level=*/0));
185183
}
186184

187185
return SubstitutionMap(genericSig, types, conformances);
@@ -649,14 +647,14 @@ bool SubstitutionMap::isIdentity() const {
649647
return !hasNonIdentityReplacement;
650648
}
651649

652-
SubstitutionMap SubstitutionMap::mapIntoTypeExpansionContext(
653-
TypeExpansionContext context) const {
650+
SubstitutionMap swift::substOpaqueTypesWithUnderlyingTypes(
651+
SubstitutionMap subs, TypeExpansionContext context) {
654652
ReplaceOpaqueTypesWithUnderlyingTypes replacer(
655653
context.getContext(), context.getResilienceExpansion(),
656654
context.isWholeModuleContext());
657-
return this->subst(replacer, replacer,
658-
SubstFlags::SubstituteOpaqueArchetypes |
659-
SubstFlags::PreservePackExpansionLevel);
655+
return subs.subst(replacer, replacer,
656+
SubstFlags::SubstituteOpaqueArchetypes |
657+
SubstFlags::PreservePackExpansionLevel);
660658
}
661659

662660
bool OuterSubstitutions::isUnsubstitutedTypeParameter(Type type) const {

0 commit comments

Comments
 (0)