Skip to content

Commit a88a144

Browse files
committed
AST: Add handy new overload of SubstitutionMap::get()
1 parent cc3e9af commit a88a144

File tree

15 files changed

+116
-80
lines changed

15 files changed

+116
-80
lines changed

include/swift/AST/SubstitutionMap.h

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -101,26 +101,29 @@ class SubstitutionMap {
101101
/// Build an empty substitution map.
102102
SubstitutionMap() { }
103103

104-
/// Build an interface type substitution map for the given generic
105-
/// signature and a vector of Substitutions that correspond to the
106-
/// requirements of this generic signature.
104+
/// The primitive constructor.
107105
static SubstitutionMap get(GenericSignature genericSig,
108106
ArrayRef<Type> replacementTypes,
109107
ArrayRef<ProtocolConformanceRef> conformances) {
110108
return SubstitutionMap(genericSig, replacementTypes, conformances);
111109
}
112110

113-
/// Build an interface type substitution map for the given generic
114-
/// signature using the mapping in the given substitutions.
111+
/// Translate a substitution map from one generic signature to another
112+
/// "compatible" one. Think carefully before using this.
115113
static SubstitutionMap get(GenericSignature genericSig,
116114
SubstitutionMap substitutions);
117115

118-
/// Build an interface type substitution map for the given generic signature
119-
/// from a type substitution function and conformance lookup function.
116+
/// General form that takes two callbacks.
120117
static SubstitutionMap get(GenericSignature genericSig,
121118
TypeSubstitutionFn subs,
122119
LookupConformanceFn lookupConformance);
123120

121+
/// Takes an array of replacement types already in the correct form, together
122+
/// with a conformance lookup callback.
123+
static SubstitutionMap get(GenericSignature genericSig,
124+
ArrayRef<Type> replacementTypes,
125+
LookupConformanceFn lookupConformance);
126+
124127
/// Build a substitution map from the substitutions represented by
125128
/// the given in-flight substitution.
126129
///
@@ -306,6 +309,15 @@ inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
306309
return OS;
307310
}
308311

312+
/// A function object suitable for use as a \c TypeSubstitutionFn that
313+
/// queries an array of replacement types.
314+
struct QueryReplacementTypeArray {
315+
GenericSignature sig;
316+
ArrayRef<Type> types;
317+
318+
Type operator()(SubstitutableType *type) const;
319+
};
320+
309321
/// A function object suitable for use as a \c TypeSubstitutionFn that
310322
/// queries an underlying \c SubstitutionMap.
311323
struct QuerySubstitutionMap {

lib/AST/ASTDemangler.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -953,7 +953,8 @@ ASTBuilder::createGenericSignature(ArrayRef<BuiltType> builtParams,
953953
SubstitutionMap
954954
ASTBuilder::createSubstitutionMap(BuiltGenericSignature sig,
955955
ArrayRef<BuiltType> replacements) {
956-
return SubstitutionMap::get(sig, replacements, {});
956+
return SubstitutionMap::get(sig, replacements,
957+
LookUpConformanceInSignature(sig.getPointer()));
957958
}
958959

959960
Type ASTBuilder::subst(Type subject, const BuiltSubstitutionMap &Subs) const {

lib/AST/SubstitutionMap.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,15 +203,21 @@ SubstitutionMap SubstitutionMap::get(GenericSignature genericSig,
203203
LookUpConformanceInSubstitutionMap(substitutions));
204204
}
205205

206-
/// Build an interface type substitution map for the given generic signature
207-
/// from a type substitution function and conformance lookup function.
208206
SubstitutionMap SubstitutionMap::get(GenericSignature genericSig,
209207
TypeSubstitutionFn subs,
210208
LookupConformanceFn lookupConformance) {
211209
InFlightSubstitution IFS(subs, lookupConformance, llvm::None);
212210
return get(genericSig, IFS);
213211
}
214212

213+
SubstitutionMap SubstitutionMap::get(GenericSignature genericSig,
214+
ArrayRef<Type> types,
215+
LookupConformanceFn lookupConformance) {
216+
return get(genericSig,
217+
QueryReplacementTypeArray{genericSig, types},
218+
lookupConformance);
219+
}
220+
215221
SubstitutionMap SubstitutionMap::get(GenericSignature genericSig,
216222
InFlightSubstitution &IFS) {
217223
if (!genericSig) {

lib/AST/TypeSubstitution.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,14 @@ using namespace swift;
3232
// Type::subst() and friends
3333
//===----------------------------------------------------------------------===//
3434

35+
Type QueryReplacementTypeArray::operator()(SubstitutableType *type) const {
36+
auto *genericParam = cast<GenericTypeParamType>(type);
37+
auto genericParams = sig.getGenericParams();
38+
auto replacementIndex =
39+
GenericParamKey(genericParam).findIndexIn(genericParams);
40+
return types[replacementIndex];
41+
}
42+
3543
Type QueryTypeSubstitutionMap::operator()(SubstitutableType *type) const {
3644
auto key = type->getCanonicalType()->castTo<SubstitutableType>();
3745
auto known = substitutions.find(key);

lib/ClangImporter/ClangImporter.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4804,12 +4804,14 @@ MemberRefExpr *getSelfInteropStaticCast(FuncDecl *funcDecl,
48044804
return selfRef;
48054805
}(funcDecl);
48064806

4807+
auto *module = funcDecl->getParentModule();
4808+
48074809
auto createCallToBuiltin = [&](Identifier name, ArrayRef<Type> substTypes,
48084810
Argument arg) {
48094811
auto builtinFn = cast<FuncDecl>(getBuiltinValueDecl(ctx, name));
48104812
auto substMap =
48114813
SubstitutionMap::get(builtinFn->getGenericSignature(), substTypes,
4812-
ArrayRef<ProtocolConformanceRef>());
4814+
LookUpConformanceInModule(module));
48134815
ConcreteDeclRef builtinFnRef(builtinFn, substMap);
48144816
auto builtinFnRefExpr =
48154817
new (ctx) DeclRefExpr(builtinFnRef, DeclNameLoc(), /*implicit*/ true);
@@ -4852,7 +4854,8 @@ MemberRefExpr *getSelfInteropStaticCast(FuncDecl *funcDecl,
48524854

48534855
SubstitutionMap pointeeSubst = SubstitutionMap::get(
48544856
ctx.getUnsafeMutablePointerDecl()->getGenericSignature(),
4855-
{baseStruct->getSelfInterfaceType()}, {});
4857+
{baseStruct->getSelfInterfaceType()},
4858+
LookUpConformanceInModule(module));
48564859
VarDecl *pointeePropertyDecl =
48574860
ctx.getPointerPointeePropertyDecl(PTK_UnsafeMutablePointer);
48584861
auto pointeePropertyRefExpr = new (ctx) MemberRefExpr(

lib/ClangImporter/SwiftDeclSynthesizer.cpp

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,8 @@ synthesizeStructDefaultConstructorBody(AbstractFunctionDecl *afd,
440440
ASTContext &ctx = constructor->getASTContext();
441441
auto structDecl = static_cast<StructDecl *>(context);
442442

443+
auto *module = structDecl->getParentModule();
444+
443445
// Use a builtin to produce a zero initializer, and assign it to self.
444446

445447
// Construct the left-hand reference to self.
@@ -456,7 +458,8 @@ synthesizeStructDefaultConstructorBody(AbstractFunctionDecl *afd,
456458
cast<FuncDecl>(getBuiltinValueDecl(ctx, zeroInitID));
457459
SubstitutionMap subMap =
458460
SubstitutionMap::get(zeroInitializerFunc->getGenericSignature(),
459-
llvm::makeArrayRef(selfType), {});
461+
llvm::makeArrayRef(selfType),
462+
LookUpConformanceInModule(module));
460463
ConcreteDeclRef concreteDeclRef(zeroInitializerFunc, subMap);
461464
auto zeroInitializerRef =
462465
new (ctx) DeclRefExpr(concreteDeclRef, DeclNameLoc(), /*implicit*/ true);
@@ -822,6 +825,8 @@ synthesizeUnionFieldGetterBody(AbstractFunctionDecl *afd, void *context) {
822825
ASTContext &ctx = getterDecl->getASTContext();
823826
auto importedFieldDecl = static_cast<VarDecl *>(context);
824827

828+
auto *module = afd->getParentModule();
829+
825830
auto selfDecl = getterDecl->getImplicitSelfDecl();
826831

827832
auto selfRef = new (ctx) DeclRefExpr(selfDecl, DeclNameLoc(),
@@ -836,7 +841,7 @@ synthesizeUnionFieldGetterBody(AbstractFunctionDecl *afd, void *context) {
836841
SubstitutionMap::get(
837842
reinterpretCast->getGenericSignature(),
838843
{selfDecl->getInterfaceType(), importedFieldDecl->getInterfaceType()},
839-
ArrayRef<ProtocolConformanceRef>()));
844+
LookUpConformanceInModule(module)));
840845
auto reinterpretCastRefExpr =
841846
new (ctx) DeclRefExpr(reinterpretCastRef, DeclNameLoc(),
842847
/*implicit*/ true);
@@ -860,6 +865,8 @@ synthesizeUnionFieldGetterBody(AbstractFunctionDecl *afd, void *context) {
860865
/// Synthesizer for the body of a union field setter.
861866
static std::pair<BraceStmt *, bool>
862867
synthesizeUnionFieldSetterBody(AbstractFunctionDecl *afd, void *context) {
868+
auto *module = afd->getParentModule();
869+
863870
auto setterDecl = cast<AccessorDecl>(afd);
864871
ASTContext &ctx = setterDecl->getASTContext();
865872

@@ -880,7 +887,7 @@ synthesizeUnionFieldSetterBody(AbstractFunctionDecl *afd, void *context) {
880887
ConcreteDeclRef addressofFnRef(
881888
addressofFn, SubstitutionMap::get(addressofFn->getGenericSignature(),
882889
{inoutSelfDecl->getInterfaceType()},
883-
ArrayRef<ProtocolConformanceRef>()));
890+
LookUpConformanceInModule(module)));
884891
auto addressofFnRefExpr =
885892
new (ctx) DeclRefExpr(addressofFnRef, DeclNameLoc(), /*implicit*/ true);
886893
// FIXME: Verify ExtInfo state is correct, not working by accident.
@@ -902,7 +909,7 @@ synthesizeUnionFieldSetterBody(AbstractFunctionDecl *afd, void *context) {
902909
ConcreteDeclRef initializeFnRef(
903910
initializeFn, SubstitutionMap::get(initializeFn->getGenericSignature(),
904911
{newValueDecl->getInterfaceType()},
905-
ArrayRef<ProtocolConformanceRef>()));
912+
LookUpConformanceInModule(module)));
906913
auto initializeFnRefExpr =
907914
new (ctx) DeclRefExpr(initializeFnRef, DeclNameLoc(), /*implicit*/ true);
908915
// FIXME: Verify ExtInfo state is correct, not working by accident.
@@ -1205,6 +1212,8 @@ static std::pair<BraceStmt *, bool>
12051212
synthesizeEnumRawValueConstructorBody(AbstractFunctionDecl *afd,
12061213
void *context) {
12071214
ASTContext &ctx = afd->getASTContext();
1215+
auto *module = afd->getParentModule();
1216+
12081217
auto ctorDecl = cast<ConstructorDecl>(afd);
12091218
auto enumDecl = static_cast<EnumDecl *>(context);
12101219
auto selfDecl = ctorDecl->getImplicitSelfDecl();
@@ -1222,7 +1231,8 @@ synthesizeEnumRawValueConstructorBody(AbstractFunctionDecl *afd,
12221231
auto rawTy = enumDecl->getRawType();
12231232
auto enumTy = enumDecl->getDeclaredInterfaceType();
12241233
SubstitutionMap subMap = SubstitutionMap::get(
1225-
reinterpretCast->getGenericSignature(), {rawTy, enumTy}, {});
1234+
reinterpretCast->getGenericSignature(), {rawTy, enumTy},
1235+
LookUpConformanceInModule(module));
12261236
ConcreteDeclRef concreteDeclRef(reinterpretCast, subMap);
12271237
auto reinterpretCastRef =
12281238
new (ctx) DeclRefExpr(concreteDeclRef, DeclNameLoc(), /*implicit*/ true);
@@ -1290,10 +1300,13 @@ synthesizeEnumRawValueGetterBody(AbstractFunctionDecl *afd, void *context) {
12901300
/*implicit*/ true);
12911301
selfRef->setType(selfDecl->getTypeInContext());
12921302

1303+
auto *module = afd->getParentModule();
1304+
12931305
auto reinterpretCast = cast<FuncDecl>(
12941306
getBuiltinValueDecl(ctx, ctx.getIdentifier("reinterpretCast")));
12951307
SubstitutionMap subMap = SubstitutionMap::get(
1296-
reinterpretCast->getGenericSignature(), {enumTy, rawTy}, {});
1308+
reinterpretCast->getGenericSignature(), {enumTy, rawTy},
1309+
LookUpConformanceInModule(module));
12971310
ConcreteDeclRef concreteDeclRef(reinterpretCast, subMap);
12981311

12991312
auto reinterpretCastRef =
@@ -1495,8 +1508,11 @@ Expr *SwiftDeclSynthesizer::synthesizeReturnReinterpretCast(ASTContext &ctx,
14951508
Expr *baseExpr) {
14961509
auto reinterpretCast = cast<FuncDecl>(
14971510
getBuiltinValueDecl(ctx, ctx.getIdentifier("reinterpretCast")));
1511+
auto *module = reinterpretCast->getParentModule();
1512+
14981513
SubstitutionMap subMap = SubstitutionMap::get(
1499-
reinterpretCast->getGenericSignature(), {givenType, exprType}, {});
1514+
reinterpretCast->getGenericSignature(), {givenType, exprType},
1515+
LookUpConformanceInModule(module));
15001516
ConcreteDeclRef concreteDeclRef(reinterpretCast, subMap);
15011517
auto reinterpretCastRef =
15021518
new (ctx) DeclRefExpr(concreteDeclRef, DeclNameLoc(), /*implicit*/ true);
@@ -1519,6 +1535,8 @@ Expr *SwiftDeclSynthesizer::synthesizeReturnReinterpretCast(ASTContext &ctx,
15191535
static std::pair<BraceStmt *, bool>
15201536
synthesizeUnwrappingGetterOrAddressGetterBody(AbstractFunctionDecl *afd,
15211537
void *context, bool isAddress) {
1538+
auto *module = afd->getParentModule();
1539+
15221540
auto getterDecl = cast<AccessorDecl>(afd);
15231541
auto getterImpl = static_cast<FuncDecl *>(context);
15241542

@@ -1550,7 +1568,8 @@ synthesizeUnwrappingGetterOrAddressGetterBody(AbstractFunctionDecl *afd,
15501568

15511569
// Handle operator[] that returns a reference type.
15521570
SubstitutionMap subMap = SubstitutionMap::get(
1553-
ctx.getUnsafePointerDecl()->getGenericSignature(), {elementTy}, {});
1571+
ctx.getUnsafePointerDecl()->getGenericSignature(), {elementTy},
1572+
LookUpConformanceInModule(module));
15541573
auto pointeePropertyRefExpr = new (ctx) MemberRefExpr(
15551574
getterImplCallExpr, SourceLoc(),
15561575
ConcreteDeclRef(pointeePropertyDecl, subMap), DeclNameLoc(),
@@ -1593,6 +1612,8 @@ synthesizeUnwrappingSetterBody(AbstractFunctionDecl *afd, void *context) {
15931612

15941613
ASTContext &ctx = setterDecl->getASTContext();
15951614

1615+
auto *module = afd->getParentModule();
1616+
15961617
auto selfArg = createSelfArg(setterDecl);
15971618
DeclRefExpr *valueParamRefExpr = createParamRefExpr(setterDecl, 0);
15981619
// For a subscript this decl will have two parameters, for a pointee property
@@ -1611,7 +1632,7 @@ synthesizeUnwrappingSetterBody(AbstractFunctionDecl *afd, void *context) {
16111632

16121633
SubstitutionMap subMap = SubstitutionMap::get(
16131634
ctx.getUnsafeMutablePointerDecl()->getGenericSignature(), {elementTy},
1614-
{});
1635+
LookUpConformanceInModule(module));
16151636
auto pointeePropertyRefExpr = new (ctx)
16161637
MemberRefExpr(setterImplCallExpr, SourceLoc(),
16171638
ConcreteDeclRef(pointeePropertyDecl, subMap), DeclNameLoc(),

lib/IRGen/GenStruct.cpp

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -592,14 +592,7 @@ namespace {
592592
auto sig = ptrTypeDecl->getGenericSignature();
593593

594594
// Map the generic parameter to T
595-
auto params = sig.getGenericParams();
596-
assert(params.size() == 1);
597-
auto param = params[0]->getCanonicalType()->castTo<SubstitutableType>();
598-
TypeSubstitutionMap map;
599-
map[param] = T.getASTType();
600-
601-
auto subst = SubstitutionMap::get(sig,
602-
QueryTypeSubstitutionMap{map},
595+
auto subst = SubstitutionMap::get(sig, {T.getASTType()},
603596
LookUpConformanceInModule{IGF.getSwiftModule()});
604597
auto ptrType = ptrTypeDecl->getDeclaredInterfaceType().subst(subst);
605598
SILParameterInfo ptrParam(ptrType->getCanonicalType(),

lib/SIL/IR/AbstractionPattern.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2388,20 +2388,19 @@ class SubstFunctionTypePatternVisitor
23882388

23892389
auto nomGenericSig = decl->getGenericSignature();
23902390

2391-
TypeSubstitutionMap replacementTypes;
2391+
SmallVector<Type, 2> replacementTypes;
23922392
for (auto gp : nomGenericSig.getGenericParams()) {
23932393
auto origParamTy = Type(gp).subst(origSubMap)
23942394
->getCanonicalType();
23952395
auto substParamTy = Type(gp).subst(substSubMap)
23962396
->getCanonicalType();
23972397

2398-
replacementTypes[gp->getCanonicalType()->castTo<SubstitutableType>()]
2399-
= visit(substParamTy,
2400-
AbstractionPattern(origPatternSubs, origSig, origParamTy));
2398+
replacementTypes.push_back(
2399+
visit(substParamTy,
2400+
AbstractionPattern(origPatternSubs, origSig, origParamTy)));
24012401
}
24022402

2403-
auto newSubMap = SubstitutionMap::get(nomGenericSig,
2404-
QueryTypeSubstitutionMap{replacementTypes},
2403+
auto newSubMap = SubstitutionMap::get(nomGenericSig, replacementTypes,
24052404
LookUpConformanceInModule(moduleDecl));
24062405

24072406
for (auto reqt : nomGenericSig.getRequirements()) {

lib/SILGen/SILGenConstructor.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,8 @@ void SILGenFunction::emitValueConstructor(ConstructorDecl *ctor) {
740740
// lifetime checker doesn't seem to process trivial locations. But empty
741741
// move only structs are non-trivial, so we need to handle this here.
742742
if (nominal->getAttrs().hasAttribute<RawLayoutAttr>()) {
743+
auto *module = ctor->getParentModule();
744+
743745
// Raw memory is not directly decomposable, but we still want to mark
744746
// it as initialized. Use a zero initializer.
745747
auto &C = ctor->getASTContext();
@@ -749,7 +751,7 @@ void SILGenFunction::emitValueConstructor(ConstructorDecl *ctor) {
749751
SubstitutionMap::get(zeroInit->getInnermostDeclContext()
750752
->getGenericSignatureOfContext(),
751753
{selfDecl->getTypeInContext()},
752-
{}),
754+
LookUpConformanceInModule(module)),
753755
selfLV.getLValueAddress());
754756
} else if (isa<StructDecl>(nominal) && !nominal->canBeCopyable()
755757
&& nominal->getStoredProperties().empty()) {

lib/SILGen/SILGenLValue.cpp

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2321,40 +2321,35 @@ namespace {
23212321
auto keyPathValue = KeyPath;
23222322

23232323
GenericSignature sig;
2324-
TypeSubstitutionMap map;
2324+
SmallVector<Type, 2> replacementTypes;
23252325

23262326
if (TypeKind == KPTK_AnyKeyPath) {
23272327
projectFn = SGF.getASTContext().getGetAtAnyKeyPath();
2328+
sig = projectFn->getGenericSignature();
2329+
replacementTypes.push_back(BaseFormalType);
23282330
} else if (TypeKind == KPTK_PartialKeyPath) {
23292331
projectFn = SGF.getASTContext().getGetAtPartialKeyPath();
2332+
sig = projectFn->getGenericSignature();
2333+
replacementTypes.push_back(BaseFormalType);
23302334
} else if (TypeKind == KPTK_KeyPath ||
23312335
TypeKind == KPTK_WritableKeyPath ||
23322336
TypeKind == KPTK_ReferenceWritableKeyPath) {
23332337
projectFn = SGF.getASTContext().getGetAtKeyPath();
23342338
sig = projectFn->getGenericSignature();
2335-
auto genericParams = sig.getGenericParams();
23362339

23372340
auto keyPathTy = keyPathValue.getType().castTo<BoundGenericType>();
23382341
assert(keyPathTy->getGenericArgs().size() == 2);
23392342
assert(keyPathTy->getGenericArgs()[0]->getCanonicalType() ==
23402343
BaseFormalType->getCanonicalType());
2341-
assert(genericParams.size() == 2);
2342-
auto secondGenParam = genericParams[1]->getCanonicalType()
2343-
->castTo<SubstitutableType>();
2344-
map[secondGenParam] = keyPathTy->getGenericArgs()[1];
2344+
replacementTypes.push_back(keyPathTy->getGenericArgs()[0]);
2345+
replacementTypes.push_back(keyPathTy->getGenericArgs()[1]);
23452346

23462347
keyPathValue = emitUpcastToKeyPath(SGF, loc, TypeKind, keyPathValue);
23472348
} else {
23482349
llvm_unreachable("bad key path kind for this component");
23492350
}
23502351

2351-
sig = projectFn->getGenericSignature();
2352-
auto firstGenParam = sig.getGenericParams()[0]->getCanonicalType()
2353-
->castTo<SubstitutableType>();
2354-
map[firstGenParam] = BaseFormalType;
2355-
2356-
auto subs = SubstitutionMap::get(sig,
2357-
QueryTypeSubstitutionMap{map},
2352+
auto subs = SubstitutionMap::get(sig, replacementTypes,
23582353
LookUpConformanceInModule{SGF.getModule().getSwiftModule()});
23592354

23602355
base = makeBaseConsumableMaterializedRValue(SGF, loc, base);

0 commit comments

Comments
 (0)