@@ -34,8 +34,8 @@ namespace {
34
34
class SILTypeSubstituter :
35
35
public CanTypeVisitor<SILTypeSubstituter, CanType> {
36
36
TypeConverter &TC;
37
- TypeSubstitutionFn Subst ;
38
- LookupConformanceFn Conformances;
37
+ InFlightSubstitution &IFS ;
38
+
39
39
// The signature for the original type.
40
40
//
41
41
// Replacement types are lowered with respect to the current
@@ -65,21 +65,15 @@ class SILTypeSubstituter :
65
65
66
66
TypeExpansionContext typeExpansionContext;
67
67
68
- bool shouldSubstituteOpaqueArchetypes;
69
-
70
68
public:
71
69
SILTypeSubstituter (TypeConverter &TC,
72
70
TypeExpansionContext context,
73
- TypeSubstitutionFn Subst,
74
- LookupConformanceFn Conformances,
75
- CanGenericSignature Sig,
76
- bool shouldSubstituteOpaqueArchetypes)
71
+ InFlightSubstitution &IFS,
72
+ CanGenericSignature Sig)
77
73
: TC(TC),
78
- Subst (Subst),
79
- Conformances(Conformances),
74
+ IFS (IFS),
80
75
Sig(Sig),
81
- typeExpansionContext(context),
82
- shouldSubstituteOpaqueArchetypes(shouldSubstituteOpaqueArchetypes)
76
+ typeExpansionContext(context)
83
77
{}
84
78
85
79
// SIL type lowering only does special things to tuples and functions.
@@ -113,7 +107,7 @@ class SILTypeSubstituter :
113
107
assert ((!isGenericApplication || origType->isPolymorphic ()) &&
114
108
" generic application without invocation signature or with "
115
109
" existing arguments" );
116
- assert ((!isGenericApplication || !shouldSubstituteOpaqueArchetypes) &&
110
+ assert ((!isGenericApplication || !IFS. shouldSubstituteOpaqueArchetypes () ) &&
117
111
" generic application while substituting opaque archetypes" );
118
112
119
113
// The general substitution rule is that we should only substitute
@@ -194,7 +188,7 @@ class SILTypeSubstituter :
194
188
if (patternSubs) {
195
189
subs = substSubstitutions (patternSubs);
196
190
} else {
197
- subs = SubstitutionMap::get (sig, Subst, Conformances );
191
+ subs = SubstitutionMap::get (sig, IFS );
198
192
}
199
193
auto witnessConformance = substWitnessConformance (origType);
200
194
substType = substType->withPatternSpecialization (nullptr , subs,
@@ -211,7 +205,7 @@ class SILTypeSubstituter :
211
205
// substitutions present, just substitute those and preserve the
212
206
// basic structure in the component types. Otherwise, fall through
213
207
// to substitute the component types.
214
- } else if (shouldSubstituteOpaqueArchetypes) {
208
+ } else if (IFS. shouldSubstituteOpaqueArchetypes () ) {
215
209
if (patternSubs) {
216
210
patternSubs = substOpaqueTypes (patternSubs);
217
211
auto witnessConformance = substWitnessConformance (origType);
@@ -271,10 +265,10 @@ class SILTypeSubstituter :
271
265
// The substituted type is no longer generic, so it'd never be
272
266
// pseudogeneric.
273
267
auto extInfo = origType->getExtInfo ();
274
- if (!shouldSubstituteOpaqueArchetypes)
268
+ if (!IFS. shouldSubstituteOpaqueArchetypes () )
275
269
extInfo = extInfo.intoBuilder ().withIsPseudogeneric (false ).build ();
276
270
277
- auto genericSig = shouldSubstituteOpaqueArchetypes
271
+ auto genericSig = IFS. shouldSubstituteOpaqueArchetypes ()
278
272
? origType->getInvocationGenericSignature ()
279
273
: nullptr ;
280
274
@@ -301,15 +295,14 @@ class SILTypeSubstituter :
301
295
selfType = next;
302
296
}
303
297
304
- auto substConformance =
305
- conformance.subst (selfType, Subst, Conformances);
298
+ auto substConformance = conformance.subst (selfType, IFS);
306
299
307
300
// Substitute the underlying conformance of opaque type archetypes if we
308
301
// should look through opaque archetypes.
309
302
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
+ } );
313
306
if (substType->hasOpaqueArchetype ()) {
314
307
substConformance = substOpaqueTypesWithUnderlyingTypes (
315
308
substConformance, substType, typeExpansionContext);
@@ -523,7 +516,7 @@ class SILTypeSubstituter :
523
516
SubstRespectingExpansions (SILTypeSubstituter *_this) : _this(_this) {}
524
517
525
518
Type operator ()(SubstitutableType *origType) const {
526
- auto substType = _this->Subst (origType);
519
+ auto substType = _this->IFS . substType (origType);
527
520
if (!substType) return substType;
528
521
auto substPackType = dyn_cast<PackType>(substType->getCanonicalType ());
529
522
if (!substPackType) return substType;
@@ -551,9 +544,10 @@ class SILTypeSubstituter :
551
544
ProtocolConformanceRef operator ()(CanType dependentType,
552
545
Type conformingReplacementType,
553
546
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);
557
551
if (!conformance || !conformance.isPack ()) return conformance;
558
552
auto activeExpansion = _this->getActivePackExpansion (dependentType);
559
553
if (!activeExpansion) return conformance;
@@ -567,35 +561,23 @@ class SILTypeSubstituter :
567
561
};
568
562
569
563
CanType substASTType (CanType origType) {
570
- SubstOptions substOptions (None);
571
- if (shouldSubstituteOpaqueArchetypes)
572
- substOptions = SubstFlags::SubstituteOpaqueArchetypes |
573
- SubstFlags::AllowLoweredTypes;
574
-
575
564
if (ActivePackExpansions.empty ())
576
- return origType.subst (Subst, Conformances, substOptions)
577
- ->getCanonicalType ();
565
+ return origType.subst (IFS)->getCanonicalType ();
578
566
579
567
return origType.subst (SubstRespectingExpansions (this ),
580
568
SubstConformanceRespectingExpansions (this ),
581
- substOptions )->getCanonicalType ();
569
+ IFS. getOptions () )->getCanonicalType ();
582
570
}
583
571
584
572
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.
591
573
SubstitutionMap newSubs;
592
574
593
575
if (ActivePackExpansions.empty ())
594
- newSubs = subs.subst (Subst, Conformances, options );
576
+ newSubs = subs.subst (IFS );
595
577
else
596
578
newSubs = subs.subst (SubstRespectingExpansions (this ),
597
579
SubstConformanceRespectingExpansions (this ),
598
- options );
580
+ IFS. getOptions () );
599
581
600
582
// If we need to look through opaque types in this context, re-substitute
601
583
// according to the expansion context.
@@ -629,18 +611,39 @@ class SILTypeSubstituter :
629
611
630
612
} // end anonymous namespace
631
613
614
+ static bool isSubstitutionInvariant (SILType ty,
615
+ bool shouldSubstituteOpaqueArchetypes) {
616
+ return (!ty.hasArchetype () &&
617
+ !ty.hasTypeParameter () &&
618
+ (!shouldSubstituteOpaqueArchetypes ||
619
+ !ty.getRawASTType ()->hasOpaqueArchetype ()));
620
+ }
621
+
632
622
SILType SILType::subst (TypeConverter &tc, TypeSubstitutionFn subs,
633
623
LookupConformanceFn conformances,
634
624
CanGenericSignature genericSig,
635
625
bool shouldSubstituteOpaqueArchetypes) const {
636
- if (!hasArchetype () && !hasTypeParameter () &&
637
- (!shouldSubstituteOpaqueArchetypes ||
638
- !getASTType ()->hasOpaqueArchetype ()))
626
+ if (isSubstitutionInvariant (*this , shouldSubstituteOpaqueArchetypes))
639
627
return *this ;
640
628
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);
644
647
return STST.subst (*this );
645
648
}
646
649
@@ -654,31 +657,24 @@ SILType SILType::subst(SILModule &M, TypeSubstitutionFn subs,
654
657
655
658
SILType SILType::subst (TypeConverter &tc, SubstitutionMap subs) const {
656
659
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 ());
660
663
}
661
664
SILType SILType::subst (SILModule &M, SubstitutionMap subs) const {
662
665
return subst (M.Types , subs);
663
666
}
664
667
665
668
SILType SILType::subst (SILModule &M, SubstitutionMap subs,
666
669
TypeExpansionContext context) const {
667
- if (!hasArchetype () && !hasTypeParameter () &&
668
- !getASTType ()->hasOpaqueArchetype ())
670
+ if (isSubstitutionInvariant (*this , false ))
669
671
return *this ;
670
672
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 );
682
678
}
683
679
684
680
// / Apply a substitution to this polymorphic SILFunctionType so that
@@ -695,10 +691,9 @@ SILFunctionType::substGenericArgs(SILModule &silModule, SubstitutionMap subs,
695
691
return CanSILFunctionType (this );
696
692
}
697
693
698
- return substGenericArgs (silModule,
699
- QuerySubstitutionMap{subs},
700
- LookUpConformanceInSubstitutionMap (subs),
701
- context);
694
+ InFlightSubstitutionViaSubMap IFS (subs, None);
695
+
696
+ return substGenericArgs (silModule, IFS, context);
702
697
}
703
698
704
699
CanSILFunctionType
@@ -707,9 +702,19 @@ SILFunctionType::substGenericArgs(SILModule &silModule,
707
702
LookupConformanceFn conformances,
708
703
TypeExpansionContext context) {
709
704
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 ());
713
718
return substituter.substSILFunctionType (CanSILFunctionType (this ), true );
714
719
}
715
720
@@ -724,9 +729,10 @@ SILFunctionType::substituteOpaqueArchetypes(TypeConverter &TC,
724
729
context.getContext (), context.getResilienceExpansion (),
725
730
context.isWholeModuleContext ());
726
731
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 ());
730
736
auto resTy =
731
737
substituter.substSILFunctionType (CanSILFunctionType (this ), false );
732
738
0 commit comments