1919
2020#include " swift/AST/ConformanceLookup.h"
2121#include " swift/AST/GenericEnvironment.h"
22+ #include " swift/AST/LocalArchetypeRequirementCollector.h"
2223#include " swift/AST/ProtocolConformance.h"
2324#include " swift/SIL/BasicBlockUtils.h"
2425#include " swift/SIL/DebugUtils.h"
@@ -32,14 +33,47 @@ namespace swift {
3233
3334struct SubstitutionMapWithLocalArchetypes {
3435 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+ }
3643
3744 SubstitutionMapWithLocalArchetypes () {}
3845 SubstitutionMapWithLocalArchetypes (SubstitutionMap subs) : SubsMap(subs) {}
3946
4047 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+ }
4377
4478 if (SubsMap)
4579 return Type (type).subst (*SubsMap);
@@ -210,10 +244,12 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
210244 }
211245
212246 // / 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));
217253 assert (result.second );
218254 (void )result;
219255 }
@@ -344,13 +380,17 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
344380 }
345381
346382 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 ()
350387 ->getCanonicalType ();
388+
351389 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);
354394 }
355395
356396 // / SILCloner will take care of debug scope on the instruction
@@ -469,7 +509,7 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
469509 SILType remapType (SILType Ty) {
470510 if (Functor.SubsMap || Ty.hasLocalArchetype ()) {
471511 SubstOptions options (std::nullopt );
472- if (! Functor.LocalArchetypeSubs . empty ())
512+ if (Functor.hasLocalArchetypes ())
473513 options |= SubstFlags::SubstituteLocalArchetypes;
474514
475515 Ty = Ty.subst (Builder.getModule (), Functor, Functor,
@@ -494,7 +534,7 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
494534 CanType remapASTType (CanType ty) {
495535 if (Functor.SubsMap || ty->hasLocalArchetype ()) {
496536 SubstOptions options (std::nullopt );
497- if (! Functor.LocalArchetypeSubs . empty ())
537+ if (Functor.hasLocalArchetypes ())
498538 options |= SubstFlags::SubstituteLocalArchetypes;
499539
500540 ty = ty.subst (Functor, Functor, options)->getCanonicalType ();
@@ -518,7 +558,7 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
518558 ProtocolConformanceRef remapConformance (Type Ty, ProtocolConformanceRef C) {
519559 if (Functor.SubsMap || Ty->hasLocalArchetype ()) {
520560 SubstOptions options (std::nullopt );
521- if (! Functor.LocalArchetypeSubs . empty ())
561+ if (Functor.hasLocalArchetypes ())
522562 options |= SubstFlags::SubstituteLocalArchetypes;
523563
524564 C = C.subst (Ty, Functor, Functor, options);
@@ -541,9 +581,9 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
541581
542582 SubstitutionMap remapSubstitutionMap (SubstitutionMap Subs) {
543583 // If we have local archetypes to substitute, do so now.
544- if (Subs.getRecursiveProperties ().hasLocalArchetype () || Functor. SubsMap ) {
584+ if (Functor. SubsMap || Subs.getRecursiveProperties ().hasLocalArchetype ()) {
545585 SubstOptions options (std::nullopt );
546- if (! Functor.LocalArchetypeSubs . empty ())
586+ if (Functor.hasLocalArchetypes ())
547587 options |= SubstFlags::SubstituteLocalArchetypes;
548588
549589 Subs = Subs.subst (Functor, Functor, options);
@@ -2909,20 +2949,7 @@ void SILCloner<ImplClass>::visitOpenPackElementInst(
29092949 openedShapeClass,
29102950 newContextSubs);
29112951
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);
29262953
29272954 recordClonedInstruction (
29282955 Inst, getBuilder ().createOpenPackElement (loc, newIndexValue, newEnv));
0 commit comments