Skip to content

Commit 3b3e53e

Browse files
committed
[NFC] Use InFlightSubstitution in the SIL type substituter
1 parent 1042955 commit 3b3e53e

File tree

3 files changed

+87
-74
lines changed

3 files changed

+87
-74
lines changed

include/swift/AST/Types.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5168,6 +5168,9 @@ class SILFunctionType final
51685168
TypeSubstitutionFn subs,
51695169
LookupConformanceFn conformances,
51705170
TypeExpansionContext context);
5171+
CanSILFunctionType substGenericArgs(SILModule &silModule,
5172+
InFlightSubstitution &IFS,
5173+
TypeExpansionContext context);
51715174
CanSILFunctionType substituteOpaqueArchetypes(Lowering::TypeConverter &TC,
51725175
TypeExpansionContext context);
51735176

include/swift/SIL/SILType.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,10 @@ class SILType {
651651
CanGenericSignature genericSig = CanGenericSignature(),
652652
bool shouldSubstituteOpaqueArchetypes = false) const;
653653

654+
SILType subst(Lowering::TypeConverter &tc,
655+
InFlightSubstitution &IFS,
656+
CanGenericSignature genericSig) const;
657+
654658
SILType subst(Lowering::TypeConverter &tc, SubstitutionMap subs) const;
655659

656660
SILType subst(SILModule &M, SubstitutionMap subs) const;

lib/SIL/IR/SILTypeSubstitution.cpp

Lines changed: 80 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ namespace {
3434
class SILTypeSubstituter :
3535
public CanTypeVisitor<SILTypeSubstituter, CanType> {
3636
TypeConverter &TC;
37-
TypeSubstitutionFn Subst;
38-
LookupConformanceFn Conformances;
37+
InFlightSubstitution &IFS;
38+
3939
// The signature for the original type.
4040
//
4141
// Replacement types are lowered with respect to the current
@@ -65,21 +65,15 @@ class SILTypeSubstituter :
6565

6666
TypeExpansionContext typeExpansionContext;
6767

68-
bool shouldSubstituteOpaqueArchetypes;
69-
7068
public:
7169
SILTypeSubstituter(TypeConverter &TC,
7270
TypeExpansionContext context,
73-
TypeSubstitutionFn Subst,
74-
LookupConformanceFn Conformances,
75-
CanGenericSignature Sig,
76-
bool shouldSubstituteOpaqueArchetypes)
71+
InFlightSubstitution &IFS,
72+
CanGenericSignature Sig)
7773
: TC(TC),
78-
Subst(Subst),
79-
Conformances(Conformances),
74+
IFS(IFS),
8075
Sig(Sig),
81-
typeExpansionContext(context),
82-
shouldSubstituteOpaqueArchetypes(shouldSubstituteOpaqueArchetypes)
76+
typeExpansionContext(context)
8377
{}
8478

8579
// SIL type lowering only does special things to tuples and functions.
@@ -113,7 +107,7 @@ class SILTypeSubstituter :
113107
assert((!isGenericApplication || origType->isPolymorphic()) &&
114108
"generic application without invocation signature or with "
115109
"existing arguments");
116-
assert((!isGenericApplication || !shouldSubstituteOpaqueArchetypes) &&
110+
assert((!isGenericApplication || !IFS.shouldSubstituteOpaqueArchetypes()) &&
117111
"generic application while substituting opaque archetypes");
118112

119113
// The general substitution rule is that we should only substitute
@@ -194,7 +188,7 @@ class SILTypeSubstituter :
194188
if (patternSubs) {
195189
subs = substSubstitutions(patternSubs);
196190
} else {
197-
subs = SubstitutionMap::get(sig, Subst, Conformances);
191+
subs = SubstitutionMap::get(sig, IFS);
198192
}
199193
auto witnessConformance = substWitnessConformance(origType);
200194
substType = substType->withPatternSpecialization(nullptr, subs,
@@ -211,7 +205,7 @@ class SILTypeSubstituter :
211205
// substitutions present, just substitute those and preserve the
212206
// basic structure in the component types. Otherwise, fall through
213207
// to substitute the component types.
214-
} else if (shouldSubstituteOpaqueArchetypes) {
208+
} else if (IFS.shouldSubstituteOpaqueArchetypes()) {
215209
if (patternSubs) {
216210
patternSubs = substOpaqueTypes(patternSubs);
217211
auto witnessConformance = substWitnessConformance(origType);
@@ -271,10 +265,10 @@ class SILTypeSubstituter :
271265
// The substituted type is no longer generic, so it'd never be
272266
// pseudogeneric.
273267
auto extInfo = origType->getExtInfo();
274-
if (!shouldSubstituteOpaqueArchetypes)
268+
if (!IFS.shouldSubstituteOpaqueArchetypes())
275269
extInfo = extInfo.intoBuilder().withIsPseudogeneric(false).build();
276270

277-
auto genericSig = shouldSubstituteOpaqueArchetypes
271+
auto genericSig = IFS.shouldSubstituteOpaqueArchetypes()
278272
? origType->getInvocationGenericSignature()
279273
: nullptr;
280274

@@ -301,15 +295,14 @@ class SILTypeSubstituter :
301295
selfType = next;
302296
}
303297

304-
auto substConformance =
305-
conformance.subst(selfType, Subst, Conformances);
298+
auto substConformance = conformance.subst(selfType, IFS);
306299

307300
// Substitute the underlying conformance of opaque type archetypes if we
308301
// should look through opaque archetypes.
309302
if (typeExpansionContext.shouldLookThroughOpaqueTypeArchetypes()) {
310-
SubstOptions substOptions(None);
311-
auto substType = selfType.subst(Subst, Conformances, substOptions)
312-
->getCanonicalType();
303+
auto substType = IFS.withNewOptions(None, [&] {
304+
return selfType.subst(IFS)->getCanonicalType();
305+
});
313306
if (substType->hasOpaqueArchetype()) {
314307
substConformance = substOpaqueTypesWithUnderlyingTypes(
315308
substConformance, substType, typeExpansionContext);
@@ -523,7 +516,7 @@ class SILTypeSubstituter :
523516
SubstRespectingExpansions(SILTypeSubstituter *_this) : _this(_this) {}
524517

525518
Type operator()(SubstitutableType *origType) const {
526-
auto substType = _this->Subst(origType);
519+
auto substType = _this->IFS.substType(origType);
527520
if (!substType) return substType;
528521
auto substPackType = dyn_cast<PackType>(substType->getCanonicalType());
529522
if (!substPackType) return substType;
@@ -551,9 +544,10 @@ class SILTypeSubstituter :
551544
ProtocolConformanceRef operator()(CanType dependentType,
552545
Type conformingReplacementType,
553546
ProtocolDecl *conformingProtocol) const {
554-
auto conformance = _this->Conformances(dependentType,
555-
conformingReplacementType,
556-
conformingProtocol);
547+
auto conformance =
548+
_this->IFS.lookupConformance(dependentType,
549+
conformingReplacementType,
550+
conformingProtocol);
557551
if (!conformance || !conformance.isPack()) return conformance;
558552
auto activeExpansion = _this->getActivePackExpansion(dependentType);
559553
if (!activeExpansion) return conformance;
@@ -567,35 +561,23 @@ class SILTypeSubstituter :
567561
};
568562

569563
CanType substASTType(CanType origType) {
570-
SubstOptions substOptions(None);
571-
if (shouldSubstituteOpaqueArchetypes)
572-
substOptions = SubstFlags::SubstituteOpaqueArchetypes |
573-
SubstFlags::AllowLoweredTypes;
574-
575564
if (ActivePackExpansions.empty())
576-
return origType.subst(Subst, Conformances, substOptions)
577-
->getCanonicalType();
565+
return origType.subst(IFS)->getCanonicalType();
578566

579567
return origType.subst(SubstRespectingExpansions(this),
580568
SubstConformanceRespectingExpansions(this),
581-
substOptions)->getCanonicalType();
569+
IFS.getOptions())->getCanonicalType();
582570
}
583571

584572
SubstitutionMap substSubstitutions(SubstitutionMap subs) {
585-
// Substitute the substitutions.
586-
SubstOptions options = None;
587-
if (shouldSubstituteOpaqueArchetypes)
588-
options |= SubstFlags::SubstituteOpaqueArchetypes;
589-
590-
// Expand substituted type according to the expansion context.
591573
SubstitutionMap newSubs;
592574

593575
if (ActivePackExpansions.empty())
594-
newSubs = subs.subst(Subst, Conformances, options);
576+
newSubs = subs.subst(IFS);
595577
else
596578
newSubs = subs.subst(SubstRespectingExpansions(this),
597579
SubstConformanceRespectingExpansions(this),
598-
options);
580+
IFS.getOptions());
599581

600582
// If we need to look through opaque types in this context, re-substitute
601583
// according to the expansion context.
@@ -629,18 +611,39 @@ class SILTypeSubstituter :
629611

630612
} // end anonymous namespace
631613

614+
static bool isSubstitutionInvariant(SILType ty,
615+
bool shouldSubstituteOpaqueArchetypes) {
616+
return (!ty.hasArchetype() &&
617+
!ty.hasTypeParameter() &&
618+
(!shouldSubstituteOpaqueArchetypes ||
619+
!ty.getRawASTType()->hasOpaqueArchetype()));
620+
}
621+
632622
SILType SILType::subst(TypeConverter &tc, TypeSubstitutionFn subs,
633623
LookupConformanceFn conformances,
634624
CanGenericSignature genericSig,
635625
bool shouldSubstituteOpaqueArchetypes) const {
636-
if (!hasArchetype() && !hasTypeParameter() &&
637-
(!shouldSubstituteOpaqueArchetypes ||
638-
!getASTType()->hasOpaqueArchetype()))
626+
if (isSubstitutionInvariant(*this, shouldSubstituteOpaqueArchetypes))
639627
return *this;
640628

641-
SILTypeSubstituter STST(tc, TypeExpansionContext::minimal(), subs,
642-
conformances, genericSig,
643-
shouldSubstituteOpaqueArchetypes);
629+
auto substOptions =
630+
(shouldSubstituteOpaqueArchetypes
631+
? SubstOptions(SubstFlags::SubstituteOpaqueArchetypes)
632+
: SubstOptions(None));
633+
InFlightSubstitution IFS(subs, conformances, substOptions);
634+
635+
SILTypeSubstituter STST(tc, TypeExpansionContext::minimal(), IFS,
636+
genericSig);
637+
return STST.subst(*this);
638+
}
639+
640+
SILType SILType::subst(TypeConverter &tc, InFlightSubstitution &IFS,
641+
CanGenericSignature genericSig) const {
642+
if (isSubstitutionInvariant(*this, IFS.shouldSubstituteOpaqueArchetypes()))
643+
return *this;
644+
645+
SILTypeSubstituter STST(tc, TypeExpansionContext::minimal(), IFS,
646+
genericSig);
644647
return STST.subst(*this);
645648
}
646649

@@ -654,31 +657,24 @@ SILType SILType::subst(SILModule &M, TypeSubstitutionFn subs,
654657

655658
SILType SILType::subst(TypeConverter &tc, SubstitutionMap subs) const {
656659
auto sig = subs.getGenericSignature();
657-
return subst(tc, QuerySubstitutionMap{subs},
658-
LookUpConformanceInSubstitutionMap(subs),
659-
sig.getCanonicalSignature());
660+
661+
InFlightSubstitutionViaSubMap IFS(subs, None);
662+
return subst(tc, IFS, sig.getCanonicalSignature());
660663
}
661664
SILType SILType::subst(SILModule &M, SubstitutionMap subs) const{
662665
return subst(M.Types, subs);
663666
}
664667

665668
SILType SILType::subst(SILModule &M, SubstitutionMap subs,
666669
TypeExpansionContext context) const {
667-
if (!hasArchetype() && !hasTypeParameter() &&
668-
!getASTType()->hasOpaqueArchetype())
670+
if (isSubstitutionInvariant(*this, false))
669671
return *this;
670672

671-
// Pass the TypeSubstitutionFn and LookupConformanceFn as arguments so that
672-
// the llvm::function_ref value's scope spans the STST.subst call since
673-
// SILTypeSubstituter captures these functions.
674-
auto result = [&](TypeSubstitutionFn subsFn,
675-
LookupConformanceFn conformancesFn) -> SILType {
676-
SILTypeSubstituter STST(M.Types, context, subsFn, conformancesFn,
677-
subs.getGenericSignature().getCanonicalSignature(),
678-
false);
679-
return STST.subst(*this);
680-
}(QuerySubstitutionMap{subs}, LookUpConformanceInSubstitutionMap(subs));
681-
return result;
673+
InFlightSubstitutionViaSubMap IFS(subs, None);
674+
675+
SILTypeSubstituter STST(M.Types, context, IFS,
676+
subs.getGenericSignature().getCanonicalSignature());
677+
return STST.subst(*this);
682678
}
683679

684680
/// Apply a substitution to this polymorphic SILFunctionType so that
@@ -695,10 +691,9 @@ SILFunctionType::substGenericArgs(SILModule &silModule, SubstitutionMap subs,
695691
return CanSILFunctionType(this);
696692
}
697693

698-
return substGenericArgs(silModule,
699-
QuerySubstitutionMap{subs},
700-
LookUpConformanceInSubstitutionMap(subs),
701-
context);
694+
InFlightSubstitutionViaSubMap IFS(subs, None);
695+
696+
return substGenericArgs(silModule, IFS, context);
702697
}
703698

704699
CanSILFunctionType
@@ -707,9 +702,19 @@ SILFunctionType::substGenericArgs(SILModule &silModule,
707702
LookupConformanceFn conformances,
708703
TypeExpansionContext context) {
709704
if (!isPolymorphic()) return CanSILFunctionType(this);
710-
SILTypeSubstituter substituter(silModule.Types, context, subs, conformances,
711-
getSubstGenericSignature(),
712-
/*shouldSubstituteOpaqueTypes*/ false);
705+
706+
InFlightSubstitution IFS(subs, conformances, None);
707+
return substGenericArgs(silModule, IFS, context);
708+
}
709+
710+
CanSILFunctionType
711+
SILFunctionType::substGenericArgs(SILModule &silModule,
712+
InFlightSubstitution &IFS,
713+
TypeExpansionContext context) {
714+
if (!isPolymorphic()) return CanSILFunctionType(this);
715+
716+
SILTypeSubstituter substituter(silModule.Types, context, IFS,
717+
getSubstGenericSignature());
713718
return substituter.substSILFunctionType(CanSILFunctionType(this), true);
714719
}
715720

@@ -724,9 +729,10 @@ SILFunctionType::substituteOpaqueArchetypes(TypeConverter &TC,
724729
context.getContext(), context.getResilienceExpansion(),
725730
context.isWholeModuleContext());
726731

727-
SILTypeSubstituter substituter(TC, context, replacer, replacer,
728-
getSubstGenericSignature(),
729-
/*shouldSubstituteOpaqueTypes*/ true);
732+
InFlightSubstitution IFS(replacer, replacer,
733+
SubstFlags::SubstituteOpaqueArchetypes);
734+
735+
SILTypeSubstituter substituter(TC, context, IFS, getSubstGenericSignature());
730736
auto resTy =
731737
substituter.substSILFunctionType(CanSILFunctionType(this), false);
732738

0 commit comments

Comments
 (0)