@@ -404,28 +404,24 @@ GenericEnvironment::maybeApplyOuterContextSubstitutions(Type type) const {
404404
405405Type GenericEnvironment::mapTypeIntoContext (GenericEnvironment *env,
406406 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" );
411408
412409 if (!env) {
410+ assert (!type->hasTypeParameter () &&
411+ " no generic environment provided for type with type parameters" );
413412 return type;
414413 }
415414
416415 return env->mapTypeIntoContext (type);
417416}
418417
419418Type 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+ }
427423
428- return archetype-> getInterfaceType () ;
424+ return type ;
429425}
430426
431427Type TypeBase::mapTypeOutOfContext () {
@@ -632,8 +628,7 @@ Type QueryInterfaceTypeSubstitutions::operator()(SubstitutableType *type) const{
632628Type GenericEnvironment::mapTypeIntoContext (
633629 Type type,
634630 LookupConformanceFn lookupConformance) const {
635- assert ((!type->hasArchetype () || type->hasLocalArchetype ()) &&
636- " already have a contextual type" );
631+ assert (!type->hasPrimaryArchetype () && " already have a contextual type" );
637632
638633 Type result = type.subst (QueryInterfaceTypeSubstitutions (this ),
639634 lookupConformance,
@@ -668,7 +663,7 @@ GenericEnvironment::mapContextualPackTypeIntoElementContext(Type type) const {
668663 assert (getKind () == Kind::OpenedElement);
669664 assert (!type->hasTypeParameter () && " expected contextual type" );
670665
671- if (!type->hasArchetype ()) return type;
666+ if (!type->hasPackArchetype ()) return type;
672667
673668 auto sig = getGenericSignature ();
674669 auto shapeClass = getOpenedElementShapeClass ();
@@ -698,9 +693,9 @@ GenericEnvironment::mapContextualPackTypeIntoElementContext(CanType type) const
698693Type
699694GenericEnvironment::mapPackTypeIntoElementContext (Type type) const {
700695 assert (getKind () == Kind::OpenedElement);
701- assert (!type->hasArchetype ());
696+ assert (!type->hasPackArchetype ());
702697
703- if (!type->hasTypeParameter ()) return type;
698+ if (!type->hasParameterPack ()) return type;
704699
705700 // Get a contextual type in the original generic environment, not the
706701 // substituted one, which is what mapContextualPackTypeIntoElementContext()
@@ -720,52 +715,58 @@ GenericEnvironment::mapElementTypeIntoPackContext(Type type) const {
720715 // generic environment.
721716 assert (type->hasElementArchetype ());
722717
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 ;
729719
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);
734725
735- type = type->mapTypeOutOfContext ();
726+ if (isa<OpenedArchetypeType>(archetype))
727+ return archetype;
736728
737- auto interfaceType = element->getInterfaceType ();
729+ if (isa<ElementArchetypeType>(archetype)) {
730+ assert (!elementEnv ||
731+ elementEnv == archetype->getGenericEnvironment ());
732+ elementEnv = archetype->getGenericEnvironment ();
733+ }
738734
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 ();
742745
746+ auto sig = getGenericSignature ();
743747 for (auto *genericParam : sig.getGenericParams ()) {
744748 if (!genericParam->isParameterPack ())
745749 continue ;
746750
747751 if (!sig->haveSameShape (genericParam, shapeClass))
748752 continue ;
749753
750- GenericParamKey elementKey (/* isParameterPack*/ false ,
751- /* depth*/ elementDepth,
752- /* index*/ packParamForElement.size ());
753- packParamForElement[elementKey] = genericParam;
754+ members.push_back (genericParam);
754755 }
755756
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 );
759759 return type.subst (
760760 [&](SubstitutableType *type) {
761761 auto *genericParam = type->getAs <GenericTypeParamType>();
762762 if (!genericParam)
763763 return Type ();
764764
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);
769770 },
770771 LookUpConformanceInSignature (sig.getPointer ()),
771772 SubstFlags::PreservePackExpansionLevel);
0 commit comments