@@ -404,28 +404,24 @@ GenericEnvironment::maybeApplyOuterContextSubstitutions(Type type) const {
404
404
405
405
Type GenericEnvironment::mapTypeIntoContext (GenericEnvironment *env,
406
406
Type type) {
407
- assert ((!type->hasArchetype () || type->hasLocalArchetype ()) &&
408
- " already have a contextual type" );
409
- assert ((env || !type->hasTypeParameter ()) &&
410
- " no generic environment provided for type with type parameters" );
407
+ assert (!type->hasPrimaryArchetype () && " already have a contextual type" );
411
408
412
409
if (!env) {
410
+ assert (!type->hasTypeParameter () &&
411
+ " no generic environment provided for type with type parameters" );
413
412
return type;
414
413
}
415
414
416
415
return env->mapTypeIntoContext (type);
417
416
}
418
417
419
418
Type MapTypeOutOfContext::operator ()(SubstitutableType *type) const {
420
- auto archetype = cast<ArchetypeType>(type);
421
- if (isa<OpaqueTypeArchetypeType>(archetype->getRoot ()))
422
- return Type ();
423
-
424
- // Leave opened archetypes alone; they're handled contextually.
425
- if (isa<OpenedArchetypeType>(archetype))
426
- return Type (type);
419
+ if (isa<PrimaryArchetypeType>(type) ||
420
+ isa<PackArchetypeType>(type)) {
421
+ return cast<ArchetypeType>(type)->getInterfaceType ();
422
+ }
427
423
428
- return archetype-> getInterfaceType () ;
424
+ return type ;
429
425
}
430
426
431
427
Type TypeBase::mapTypeOutOfContext () {
@@ -632,8 +628,7 @@ Type QueryInterfaceTypeSubstitutions::operator()(SubstitutableType *type) const{
632
628
Type GenericEnvironment::mapTypeIntoContext (
633
629
Type type,
634
630
LookupConformanceFn lookupConformance) const {
635
- assert ((!type->hasArchetype () || type->hasLocalArchetype ()) &&
636
- " already have a contextual type" );
631
+ assert (!type->hasPrimaryArchetype () && " already have a contextual type" );
637
632
638
633
Type result = type.subst (QueryInterfaceTypeSubstitutions (this ),
639
634
lookupConformance,
@@ -668,7 +663,7 @@ GenericEnvironment::mapContextualPackTypeIntoElementContext(Type type) const {
668
663
assert (getKind () == Kind::OpenedElement);
669
664
assert (!type->hasTypeParameter () && " expected contextual type" );
670
665
671
- if (!type->hasArchetype ()) return type;
666
+ if (!type->hasPackArchetype ()) return type;
672
667
673
668
auto sig = getGenericSignature ();
674
669
auto shapeClass = getOpenedElementShapeClass ();
@@ -698,9 +693,9 @@ GenericEnvironment::mapContextualPackTypeIntoElementContext(CanType type) const
698
693
Type
699
694
GenericEnvironment::mapPackTypeIntoElementContext (Type type) const {
700
695
assert (getKind () == Kind::OpenedElement);
701
- assert (!type->hasArchetype ());
696
+ assert (!type->hasPackArchetype ());
702
697
703
- if (!type->hasTypeParameter ()) return type;
698
+ if (!type->hasParameterPack ()) return type;
704
699
705
700
// Get a contextual type in the original generic environment, not the
706
701
// substituted one, which is what mapContextualPackTypeIntoElementContext()
@@ -720,52 +715,58 @@ GenericEnvironment::mapElementTypeIntoPackContext(Type type) const {
720
715
// generic environment.
721
716
assert (type->hasElementArchetype ());
722
717
723
- ElementArchetypeType *element = nullptr ;
724
- type.visit ([&](Type type) {
725
- auto archetype = type->getAs <ElementArchetypeType>();
726
- if (!element && archetype)
727
- element = archetype;
728
- });
718
+ GenericEnvironment *elementEnv = nullptr ;
729
719
730
- auto sig = getGenericSignature ();
731
- auto *elementEnv = element->getGenericEnvironment ();
732
- auto shapeClass = elementEnv->getOpenedElementShapeClass ();
733
- QueryInterfaceTypeSubstitutions substitutions (this );
720
+ // Map element archetypes to interface types in the element generic
721
+ // environment's signature.
722
+ type = type.subst (
723
+ [&](SubstitutableType *type) -> Type {
724
+ auto *archetype = cast<ArchetypeType>(type);
734
725
735
- type = type->mapTypeOutOfContext ();
726
+ if (isa<OpenedArchetypeType>(archetype))
727
+ return archetype;
736
728
737
- auto interfaceType = element->getInterfaceType ();
729
+ if (isa<ElementArchetypeType>(archetype)) {
730
+ assert (!elementEnv ||
731
+ elementEnv == archetype->getGenericEnvironment ());
732
+ elementEnv = archetype->getGenericEnvironment ();
733
+ }
738
734
739
- llvm::SmallDenseMap<GenericParamKey, GenericTypeParamType *>
740
- packParamForElement;
741
- auto elementDepth = interfaceType->getRootGenericParam ()->getDepth ();
735
+ return archetype->getInterfaceType ();
736
+ },
737
+ MakeAbstractConformanceForGenericType (),
738
+ SubstFlags::AllowLoweredTypes |
739
+ SubstFlags::PreservePackExpansionLevel);
740
+
741
+ auto shapeClass = elementEnv->getOpenedElementShapeClass ();
742
+
743
+ llvm::SmallVector<GenericTypeParamType *, 2 > members;
744
+ auto elementDepth = elementEnv->getGenericSignature ()->getMaxDepth ();
742
745
746
+ auto sig = getGenericSignature ();
743
747
for (auto *genericParam : sig.getGenericParams ()) {
744
748
if (!genericParam->isParameterPack ())
745
749
continue ;
746
750
747
751
if (!sig->haveSameShape (genericParam, shapeClass))
748
752
continue ;
749
753
750
- GenericParamKey elementKey (/* isParameterPack*/ false ,
751
- /* depth*/ elementDepth,
752
- /* index*/ packParamForElement.size ());
753
- packParamForElement[elementKey] = genericParam;
754
+ members.push_back (genericParam);
754
755
}
755
756
756
- // Map element archetypes to the pack archetypes by converting
757
- // element types to interface types and adding the isParameterPack
758
- // bit. Then, map type parameters to archetypes.
757
+ // Map element interface types to pack archetypes.
758
+ QueryInterfaceTypeSubstitutions mapIntoContext (this );
759
759
return type.subst (
760
760
[&](SubstitutableType *type) {
761
761
auto *genericParam = type->getAs <GenericTypeParamType>();
762
762
if (!genericParam)
763
763
return Type ();
764
764
765
- if (auto *packParam = packParamForElement[{genericParam}])
766
- return substitutions (packParam);
767
-
768
- return substitutions (genericParam);
765
+ if (genericParam->getDepth () == elementDepth) {
766
+ genericParam = members[genericParam->getIndex ()];
767
+ assert (genericParam->isParameterPack ());
768
+ }
769
+ return mapIntoContext (genericParam);
769
770
},
770
771
LookUpConformanceInSignature (sig.getPointer ()),
771
772
SubstFlags::PreservePackExpansionLevel);
0 commit comments