@@ -659,6 +659,10 @@ Type GenericEnvironment::mapTypeIntoContext(GenericTypeParamType *type) const {
659659 return result;
660660}
661661
662+ // / So this expects a type written with the archetypes of the original generic
663+ // / environment, not 'this', the opened element environment, because it is the
664+ // / original PackArchetypes that become ElementArchetypes. Also this function
665+ // / does not apply outer substitutions, which might not be what you expect.
662666Type
663667GenericEnvironment::mapContextualPackTypeIntoElementContext (Type type) const {
664668 assert (getKind () == Kind::OpenedElement);
@@ -672,77 +676,40 @@ GenericEnvironment::mapContextualPackTypeIntoElementContext(Type type) const {
672676 FindElementArchetypeForOpenedPackParam
673677 findElementArchetype (this , getOpenedPackParams ());
674678
675- return type.transformRec ([&](TypeBase *ty) -> llvm::Optional<Type> {
676- // We're only directly substituting pack archetypes.
677- auto archetype = ty-> getAs <PackArchetypeType>();
678- if (!archetype) {
679- // Don't recurse into nested pack expansions.
680- if (ty-> is <PackExpansionType>())
681- return Type (ty);
679+ return type.transformTypeParameterPacks (
680+ [&](SubstitutableType *ty) -> llvm::Optional<Type> {
681+ if ( auto *packArchetype = dyn_cast <PackArchetypeType>(ty)) {
682+ auto interfaceType = packArchetype-> getInterfaceType ();
683+ if (sig-> haveSameShape (interfaceType, shapeClass))
684+ return Type ( findElementArchetype (interfaceType));
685+ }
682686
683- // Recurse into any other type.
684- return llvm::None;
685- }
686-
687- auto rootArchetype = cast<PackArchetypeType>(archetype->getRoot ());
688-
689- // TODO: assert that the generic environment of the pack archetype
690- // matches the signature that was originally opened to make this
691- // environment. Unfortunately, that isn't a trivial check because of
692- // the extra opened-element parameters.
693-
694- // If the archetype isn't the shape that was opened by this
695- // environment, ignore it.
696- auto rootParam = cast<GenericTypeParamType>(
697- rootArchetype->getInterfaceType ().getPointer ());
698- assert (rootParam->isParameterPack ());
699- if (!sig->haveSameShape (rootParam, shapeClass))
700- return Type (ty);
701-
702- return Type (findElementArchetype (archetype->getInterfaceType ()));
703- });
687+ return llvm::None;
688+ });
704689}
705690
706691CanType
707692GenericEnvironment::mapContextualPackTypeIntoElementContext (CanType type) const {
708693 return CanType (mapContextualPackTypeIntoElementContext (Type (type)));
709694}
710695
696+ // / Unlike mapContextualPackTypeIntoElementContext(), this also applies outer
697+ // / substitutions, so it behaves like mapTypeIntoContext() in that respect.
711698Type
712699GenericEnvironment::mapPackTypeIntoElementContext (Type type) const {
713700 assert (getKind () == Kind::OpenedElement);
714701 assert (!type->hasArchetype ());
715702
716- auto sig = getGenericSignature ();
717- auto shapeClass = getOpenedElementShapeClass ();
718-
719- FindElementArchetypeForOpenedPackParam
720- findElementArchetype (this , getOpenedPackParams ());
703+ if (!type->hasTypeParameter ()) return type;
721704
722- // Map the interface type to the element type by stripping
723- // away the isParameterPack bit before mapping type parameters
724- // to archetypes.
725- return type.transformRec ([&](TypeBase *ty) -> llvm::Optional<Type> {
726- // We're only directly substituting pack parameters.
727- if (!ty->isTypeParameter ()) {
728- // Don't recurse into nested pack expansions; just map it into
729- // context.
730- if (ty->is <PackExpansionType>())
731- return mapTypeIntoContext (ty);
732-
733- // Recurse into any other type.
734- return llvm::None;
735- }
736-
737- // Just do normal mapping for types that are not rooted in
738- // opened type parameters.
739- auto rootParam = ty->getRootGenericParam ();
740- if (!rootParam->isParameterPack () ||
741- !sig->haveSameShape (rootParam, shapeClass))
742- return mapTypeIntoContext (ty);
705+ // Get a contextual type in the original generic environment, not the
706+ // substituted one, which is what mapContextualPackTypeIntoElementContext()
707+ // expects.
708+ auto contextualType = getPackElementContextSubstitutions ()
709+ .getGenericSignature ().getGenericEnvironment ()->mapTypeIntoContext (type);
743710
744- return Type ( findElementArchetype (ty) );
745- } );
711+ contextualType = mapContextualPackTypeIntoElementContext (contextualType );
712+ return maybeApplyOuterContextSubstitutions (contextualType );
746713}
747714
748715Type
0 commit comments