@@ -198,20 +198,24 @@ class Verifier : public ASTWalker {
198198 using ScopeLike = llvm::PointerUnion<DeclContext *, BraceStmt *>;
199199 SmallVector<ScopeLike, 4 > Scopes;
200200
201- // / The stack of generic contexts.
202- using GenericLike = llvm::PointerUnion<DeclContext *, GenericEnvironment *>;
203- SmallVector<GenericLike, 2 > Generics;
201+ // / The stack of declaration contexts we're visiting. The primary
202+ // / archetypes from the innermost generic environment are in scope.
203+ SmallVector<DeclContext *, 2 > Generics;
204+
205+ // / The set of all opened existential and opened pack element generic
206+ // / environments that are currently in scope.
207+ llvm::DenseSet<GenericEnvironment *> LocalGenerics;
208+
209+ // / We track the pack expansion expressions in ForEachStmts, because
210+ // / their local generics remain in scope until the end of the statement.
211+ llvm::DenseSet<PackExpansionExpr *> ForEachPatternSequences;
204212
205213 // / The stack of optional evaluations active at this point.
206214 SmallVector<OptionalEvaluationExpr *, 4 > OptionalEvaluations;
207215
208216 // / The set of opaque value expressions active at this point.
209217 llvm::DenseMap<OpaqueValueExpr *, unsigned > OpaqueValues;
210218
211- // / The set of opened existential archetypes that are currently
212- // / active.
213- llvm::DenseSet<OpenedArchetypeType *> OpenedExistentialArchetypes;
214-
215219 // / The set of inout to pointer expr that match the following pattern:
216220 // /
217221 // / (call-expr
@@ -632,11 +636,10 @@ class Verifier : public ASTWalker {
632636
633637 bool foundError = type->getCanonicalType ().findIf ([&](Type type) -> bool {
634638 if (auto archetype = type->getAs <ArchetypeType>()) {
635- auto root = archetype->getRoot ();
636639
637640 // Opaque archetypes are globally available. We don't need to check
638641 // them here.
639- if (isa<OpaqueTypeArchetypeType>(root ))
642+ if (isa<OpaqueTypeArchetypeType>(archetype ))
640643 return false ;
641644
642645 // Only visit each archetype once.
@@ -645,11 +648,10 @@ class Verifier : public ASTWalker {
645648
646649 // We should know about archetypes corresponding to opened
647650 // existential archetypes.
648- if (auto opened = dyn_cast<OpenedArchetypeType>(root)) {
649- if (OpenedExistentialArchetypes.count (opened) == 0 ) {
650- Out << " Found opened existential archetype "
651- << root->getString ()
652- << " outside enclosing OpenExistentialExpr\n " ;
651+ if (isa<LocalArchetypeType>(archetype)) {
652+ if (LocalGenerics.count (archetype->getGenericEnvironment ()) == 0 ) {
653+ Out << " Found local archetype " << archetype
654+ << " outside its defining scope\n " ;
653655 return true ;
654656 }
655657
@@ -659,34 +661,19 @@ class Verifier : public ASTWalker {
659661 // Otherwise, the archetype needs to be from this scope.
660662 if (Generics.empty () || !Generics.back ()) {
661663 Out << " AST verification error: archetype outside of generic "
662- " context: " << root-> getString () << " \n " ;
664+ " context: " << archetype << " \n " ;
663665 return true ;
664666 }
665667
666668 // Get the archetype's generic signature.
667- GenericEnvironment *archetypeEnv = root ->getGenericEnvironment ();
669+ GenericEnvironment *archetypeEnv = archetype ->getGenericEnvironment ();
668670 auto archetypeSig = archetypeEnv->getGenericSignature ();
669671
670672 auto genericCtx = Generics.back ();
671- GenericSignature genericSig;
672- if (auto *genericDC = genericCtx.dyn_cast <DeclContext *>()) {
673- genericSig = genericDC->getGenericSignatureOfContext ();
674- } else {
675- auto *genericEnv = genericCtx.get <GenericEnvironment *>();
676- genericSig = genericEnv->getGenericSignature ();
677-
678- // Check whether this archetype is a substitution from the
679- // outer generic context of an opened element environment.
680- if (genericEnv->getKind () == GenericEnvironment::Kind::OpenedElement) {
681- auto contextSubs = genericEnv->getPackElementContextSubstitutions ();
682- QuerySubstitutionMap isInContext{contextSubs};
683- if (isInContext (root->getInterfaceType ()->castTo <GenericTypeParamType>()))
684- return false ;
685- }
686- }
673+ GenericSignature genericSig = genericCtx->getGenericSignatureOfContext ();
687674
688675 if (genericSig.getPointer () != archetypeSig.getPointer ()) {
689- Out << " Archetype " << root ->getString () << " not allowed "
676+ Out << " Archetype " << archetype ->getString () << " not allowed "
690677 << " in this context\n " ;
691678 Out << " Archetype generic signature: "
692679 << archetypeSig->getAsString () << " \n " ;
@@ -735,7 +722,7 @@ class Verifier : public ASTWalker {
735722 }
736723 void popScope (DeclContext *scope) {
737724 assert (Scopes.back ().get <DeclContext*>() == scope);
738- assert (Generics.back (). get <DeclContext*>() == scope);
725+ assert (Generics.back () == scope);
739726 Scopes.pop_back ();
740727 Generics.pop_back ();
741728 }
@@ -808,6 +795,9 @@ class Verifier : public ASTWalker {
808795 if (!shouldVerify (expansion)) {
809796 return false ;
810797 }
798+
799+ assert (ForEachPatternSequences.count (expansion) == 0 );
800+ ForEachPatternSequences.insert (expansion);
811801 }
812802
813803 if (!S->getElementExpr ())
@@ -821,6 +811,10 @@ class Verifier : public ASTWalker {
821811 void cleanup (ForEachStmt *S) {
822812 if (auto *expansion =
823813 dyn_cast<PackExpansionExpr>(S->getParsedSequence ())) {
814+ assert (ForEachPatternSequences.count (expansion) != 0 );
815+ ForEachPatternSequences.erase (expansion);
816+
817+ // Clean up for real.
824818 cleanup (expansion);
825819 }
826820
@@ -851,6 +845,16 @@ class Verifier : public ASTWalker {
851845 OpaqueValues.erase (expr->getInterpolationExpr ());
852846 }
853847
848+ void pushLocalGenerics (GenericEnvironment *env) {
849+ assert (LocalGenerics.count (env)==0 );
850+ LocalGenerics.insert (env);
851+ }
852+
853+ void popLocalGenerics (GenericEnvironment *env) {
854+ assert (LocalGenerics.count (env)==1 );
855+ LocalGenerics.erase (env);
856+ }
857+
854858 bool shouldVerify (OpenExistentialExpr *expr) {
855859 if (!shouldVerify (cast<Expr>(expr)))
856860 return false ;
@@ -862,8 +866,8 @@ class Verifier : public ASTWalker {
862866
863867 assert (!OpaqueValues.count (expr->getOpaqueValue ()));
864868 OpaqueValues[expr->getOpaqueValue ()] = 0 ;
865- assert (OpenedExistentialArchetypes. count (expr-> getOpenedArchetype ())== 0 );
866- OpenedExistentialArchetypes. insert (expr->getOpenedArchetype ());
869+
870+ pushLocalGenerics (expr->getOpenedArchetype ()-> getGenericEnvironment ());
867871 return true ;
868872 }
869873
@@ -875,22 +879,28 @@ class Verifier : public ASTWalker {
875879
876880 assert (OpaqueValues.count (expr->getOpaqueValue ()));
877881 OpaqueValues.erase (expr->getOpaqueValue ());
878- assert (OpenedExistentialArchetypes. count (expr-> getOpenedArchetype ())== 1 );
879- OpenedExistentialArchetypes. erase (expr->getOpenedArchetype ());
882+
883+ popLocalGenerics (expr->getOpenedArchetype ()-> getGenericEnvironment ());
880884 }
881885
882886 bool shouldVerify (PackExpansionExpr *expr) {
883887 if (!shouldVerify (cast<Expr>(expr)))
884888 return false ;
885889
886- Generics.push_back (expr->getGenericEnvironment ());
890+ // Don't push local generics again when we visit the expr inside
891+ // the ForEachStmt.
892+ if (auto *genericEnv = expr->getGenericEnvironment ())
893+ if (ForEachPatternSequences.count (expr) == 0 )
894+ pushLocalGenerics (genericEnv);
887895 return true ;
888896 }
889897
890- void cleanup (PackExpansionExpr *E) {
891- assert (Generics.back ().get <GenericEnvironment *>() ==
892- E->getGenericEnvironment ());
893- Generics.pop_back ();
898+ void cleanup (PackExpansionExpr *expr) {
899+ // If this is a pack iteration pattern, don't pop local generics
900+ // until we exit the ForEachStmt.
901+ if (auto *genericEnv = expr->getGenericEnvironment ())
902+ if (ForEachPatternSequences.count (expr) == 0 )
903+ popLocalGenerics (genericEnv);
894904 }
895905
896906 bool shouldVerify (MakeTemporarilyEscapableExpr *expr) {
0 commit comments