19
19
20
20
#include " swift/AST/ConformanceLookup.h"
21
21
#include " swift/AST/GenericEnvironment.h"
22
+ #include " swift/AST/LocalArchetypeRequirementCollector.h"
22
23
#include " swift/AST/ProtocolConformance.h"
23
24
#include " swift/SIL/BasicBlockUtils.h"
24
25
#include " swift/SIL/DebugUtils.h"
@@ -32,14 +33,47 @@ namespace swift {
32
33
33
34
struct SubstitutionMapWithLocalArchetypes {
34
35
std::optional<SubstitutionMap> SubsMap;
35
- TypeSubstitutionMap LocalArchetypeSubs;
36
+ llvm::DenseMap<GenericEnvironment *, GenericEnvironment *> LocalArchetypeSubs;
37
+ GenericSignature BaseGenericSig;
38
+ llvm::ArrayRef<GenericEnvironment *> CapturedEnvs;
39
+
40
+ bool hasLocalArchetypes () const {
41
+ return !LocalArchetypeSubs.empty () || !CapturedEnvs.empty ();
42
+ }
36
43
37
44
SubstitutionMapWithLocalArchetypes () {}
38
45
SubstitutionMapWithLocalArchetypes (SubstitutionMap subs) : SubsMap(subs) {}
39
46
40
47
Type operator ()(SubstitutableType *type) {
41
- if (isa<LocalArchetypeType>(type))
42
- return QueryTypeSubstitutionMap{LocalArchetypeSubs}(type);
48
+ if (auto *local = dyn_cast<LocalArchetypeType>(type)) {
49
+ auto *origEnv = local->getGenericEnvironment ();
50
+
51
+ // Special handling of captured environments, which don't appear in
52
+ // LocalArchetypeSubs. This only happens with the LocalArchetypeTransform
53
+ // in SILGenLocalArchetype.cpp.
54
+ auto found = LocalArchetypeSubs.find (origEnv);
55
+ if (found == LocalArchetypeSubs.end ()) {
56
+ if (std::find (CapturedEnvs.begin (), CapturedEnvs.end (), origEnv)
57
+ == CapturedEnvs.end ()) {
58
+ return Type ();
59
+ }
60
+
61
+ // Map the local archetype to an interface type in the new generic
62
+ // signature.
63
+ MapLocalArchetypesOutOfContext mapOutOfContext (BaseGenericSig,
64
+ CapturedEnvs);
65
+ auto interfaceTy = mapOutOfContext (local);
66
+
67
+ // Map this interface type into the new generic environment to get
68
+ // a primary archetype.
69
+ return interfaceTy.subst (*SubsMap);
70
+ }
71
+
72
+ auto *newEnv = found->second ;
73
+
74
+ auto interfaceTy = local->getInterfaceType ();
75
+ return newEnv->mapTypeIntoContext (interfaceTy);
76
+ }
43
77
44
78
if (SubsMap)
45
79
return Type (type).subst (*SubsMap);
@@ -210,10 +244,12 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
210
244
}
211
245
212
246
// / Register a re-mapping for local archetypes such as opened existentials.
213
- void registerLocalArchetypeRemapping (ArchetypeType *From,
214
- ArchetypeType *To) {
215
- auto result = Functor.LocalArchetypeSubs .insert (
216
- std::make_pair (CanArchetypeType (From), CanType (To)));
247
+ void registerLocalArchetypeRemapping (GenericEnvironment *From,
248
+ GenericEnvironment *To) {
249
+ ASSERT (From->getGenericSignature ()->getMaxDepth ()
250
+ == To->getGenericSignature ()->getMaxDepth ());
251
+
252
+ auto result = Functor.LocalArchetypeSubs .insert (std::make_pair (From, To));
217
253
assert (result.second );
218
254
(void )result;
219
255
}
@@ -344,13 +380,17 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
344
380
}
345
381
346
382
void remapRootOpenedType (CanOpenedArchetypeType archetypeTy) {
347
- assert (archetypeTy->isRoot ());
348
-
349
- auto origExistentialTy = archetypeTy->getExistentialType ()
383
+ auto *origEnv = archetypeTy->getGenericEnvironment ();
384
+ auto subMap = origEnv->getOuterSubstitutions ();
385
+ ASSERT (!subMap && " Transform the substitution map!" );
386
+ auto origExistentialTy = origEnv->getOpenedExistentialType ()
350
387
->getCanonicalType ();
388
+
351
389
auto substExistentialTy = getOpASTType (origExistentialTy);
352
- auto replacementTy = OpenedArchetypeType::get (substExistentialTy);
353
- registerLocalArchetypeRemapping (archetypeTy, replacementTy);
390
+ auto *newEnv = GenericEnvironment::forOpenedExistential (
391
+ substExistentialTy, subMap, UUID::fromTime ());
392
+
393
+ registerLocalArchetypeRemapping (origEnv, newEnv);
354
394
}
355
395
356
396
// / SILCloner will take care of debug scope on the instruction
@@ -469,7 +509,7 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
469
509
SILType remapType (SILType Ty) {
470
510
if (Functor.SubsMap || Ty.hasLocalArchetype ()) {
471
511
SubstOptions options (std::nullopt);
472
- if (! Functor.LocalArchetypeSubs . empty ())
512
+ if (Functor.hasLocalArchetypes ())
473
513
options |= SubstFlags::SubstituteLocalArchetypes;
474
514
475
515
Ty = Ty.subst (Builder.getModule (), Functor, Functor,
@@ -494,7 +534,7 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
494
534
CanType remapASTType (CanType ty) {
495
535
if (Functor.SubsMap || ty->hasLocalArchetype ()) {
496
536
SubstOptions options (std::nullopt);
497
- if (! Functor.LocalArchetypeSubs . empty ())
537
+ if (Functor.hasLocalArchetypes ())
498
538
options |= SubstFlags::SubstituteLocalArchetypes;
499
539
500
540
ty = ty.subst (Functor, Functor, options)->getCanonicalType ();
@@ -518,7 +558,7 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
518
558
ProtocolConformanceRef remapConformance (Type Ty, ProtocolConformanceRef C) {
519
559
if (Functor.SubsMap || Ty->hasLocalArchetype ()) {
520
560
SubstOptions options (std::nullopt);
521
- if (! Functor.LocalArchetypeSubs . empty ())
561
+ if (Functor.hasLocalArchetypes ())
522
562
options |= SubstFlags::SubstituteLocalArchetypes;
523
563
524
564
C = C.subst (Ty, Functor, Functor, options);
@@ -541,9 +581,9 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
541
581
542
582
SubstitutionMap remapSubstitutionMap (SubstitutionMap Subs) {
543
583
// If we have local archetypes to substitute, do so now.
544
- if (Subs.getRecursiveProperties ().hasLocalArchetype () || Functor. SubsMap ) {
584
+ if (Functor. SubsMap || Subs.getRecursiveProperties ().hasLocalArchetype ()) {
545
585
SubstOptions options (std::nullopt);
546
- if (! Functor.LocalArchetypeSubs . empty ())
586
+ if (Functor.hasLocalArchetypes ())
547
587
options |= SubstFlags::SubstituteLocalArchetypes;
548
588
549
589
Subs = Subs.subst (Functor, Functor, options);
@@ -2909,20 +2949,7 @@ void SILCloner<ImplClass>::visitOpenPackElementInst(
2909
2949
openedShapeClass,
2910
2950
newContextSubs);
2911
2951
2912
- // Associate the old opened archetypes with the new ones.
2913
- SmallVector<ArchetypeType*, 4 > oldOpenedArchetypes;
2914
- origEnv->forEachPackElementArchetype ([&](ElementArchetypeType *oldType) {
2915
- oldOpenedArchetypes.push_back (oldType);
2916
- });
2917
- {
2918
- size_t nextOldIndex = 0 ;
2919
- newEnv->forEachPackElementArchetype ([&](ElementArchetypeType *newType) {
2920
- ArchetypeType *oldType = oldOpenedArchetypes[nextOldIndex++];
2921
- registerLocalArchetypeRemapping (oldType, newType);
2922
- });
2923
- assert (nextOldIndex == oldOpenedArchetypes.size () &&
2924
- " different opened archetype count" );
2925
- }
2952
+ registerLocalArchetypeRemapping (origEnv, newEnv);
2926
2953
2927
2954
recordClonedInstruction (
2928
2955
Inst, getBuilder ().createOpenPackElement (loc, newIndexValue, newEnv));
0 commit comments