22
22
#include " swift/AST/Expr.h"
23
23
#include " swift/AST/ForeignErrorConvention.h"
24
24
#include " swift/AST/GenericEnvironment.h"
25
+ #include " swift/AST/GenericSignature.h"
25
26
#include " swift/AST/Initializer.h"
26
27
#include " swift/AST/Module.h"
27
28
#include " swift/AST/ParameterList.h"
@@ -165,46 +166,6 @@ std::pair<bool, Expr *> dispatchVisitPreExprHelper(
165
166
return {false , node};
166
167
}
167
168
168
- // / Describes a generic environment that might be lazily deserialized.
169
- // /
170
- // / This class abstracts over a declaration context that may have a generic
171
- // / environment, ensuring that we don't deserialize the environment.
172
- struct LazyGenericEnvironment {
173
- llvm::PointerUnion<DeclContext *, GenericEnvironment *> storage;
174
-
175
- explicit operator bool () const {
176
- if (storage.dyn_cast <GenericEnvironment *>())
177
- return true ;
178
-
179
- if (auto dc = storage.dyn_cast <DeclContext *>())
180
- return dc->getGenericSignatureOfContext ();
181
-
182
- return false ;
183
- }
184
-
185
- bool isLazy () const {
186
- if (auto dc = storage.dyn_cast <DeclContext *>())
187
- return dc->contextHasLazyGenericEnvironment ();
188
-
189
- return false ;
190
- }
191
-
192
- bool containsPrimaryArchetype (PrimaryArchetypeType *archetype) const {
193
- // Assume true so we don't deserialize.
194
- if (isLazy ()) return true ;
195
-
196
- if (auto genericEnv = storage.dyn_cast <GenericEnvironment *>())
197
- return archetype->getGenericEnvironment () == genericEnv;
198
-
199
- if (auto dc = storage.dyn_cast <DeclContext *>()) {
200
- if (auto genericEnv = dc->getGenericEnvironmentOfContext ())
201
- return archetype->getGenericEnvironment () == genericEnv;
202
- }
203
-
204
- return false ;
205
- }
206
- };
207
-
208
169
namespace {
209
170
// / Retrieve the "overridden" declaration of this declaration, but only if
210
171
// it's already been computed.
@@ -229,8 +190,8 @@ class Verifier : public ASTWalker {
229
190
using ScopeLike = llvm::PointerUnion<DeclContext *, BraceStmt *>;
230
191
SmallVector<ScopeLike, 4 > Scopes;
231
192
232
- // / The stack of generic environments .
233
- SmallVector<LazyGenericEnvironment , 2 > GenericEnv ;
193
+ // / The stack of context generic signatures .
194
+ SmallVector<GenericSignature * , 2 > GenericSig ;
234
195
235
196
// / The stack of optional evaluations active at this point.
236
197
SmallVector<OptionalEvaluationExpr *, 4 > OptionalEvaluations;
@@ -270,8 +231,7 @@ class Verifier : public ASTWalker {
270
231
Ctx (M.is<ModuleDecl *>() ? M.get<ModuleDecl *>()->getASTContext()
271
232
: M.get<SourceFile *>()->getASTContext()),
272
233
Out(llvm::errs()), HadError(Ctx.hadError()) {
273
- Scopes.push_back (DC);
274
- GenericEnv.push_back ({DC});
234
+ pushScope (DC);
275
235
}
276
236
277
237
public:
@@ -654,18 +614,38 @@ class Verifier : public ASTWalker {
654
614
}
655
615
656
616
// Otherwise, the archetype needs to be from this scope.
657
- if (GenericEnv .empty () || !GenericEnv .back ()) {
617
+ if (GenericSig .empty () || !GenericSig .back ()) {
658
618
Out << " AST verification error: archetype outside of generic "
659
619
" context: " << root->getString () << " \n " ;
660
620
return true ;
661
621
}
662
622
663
- // Get the primary archetype.
623
+ // Get the archetype's generic signature .
664
624
auto rootPrimary = cast<PrimaryArchetypeType>(root);
625
+ auto *archetypeEnv = rootPrimary->getGenericEnvironment ();
626
+ auto *archetypeSig = archetypeEnv->getGenericSignature ();
665
627
666
- if (!GenericEnv.back ().containsPrimaryArchetype (rootPrimary)) {
667
- Out << " AST verification error: archetype "
668
- << root->getString () << " not allowed in this context\n " ;
628
+ if (GenericSig.back () != archetypeSig) {
629
+ Out << " Archetype " << root->getString () << " not allowed "
630
+ << " in this context\n " ;
631
+ Out << " Archetype generic signature: "
632
+ << archetypeSig->getAsString () << " \n " ;
633
+ Out << " Context generic signature: "
634
+ << GenericSig.back ()->getAsString () << " \n " ;
635
+
636
+ return true ;
637
+ }
638
+
639
+ // Mapping the archetype out and back in should produce the
640
+ // same archetype.
641
+ auto interfaceType = archetype->getInterfaceType ();
642
+ auto contextType = archetypeEnv->mapTypeIntoContext (interfaceType);
643
+
644
+ if (contextType.getPointer () != archetype) {
645
+ Out << " Archetype " << archetype->getString () << " does not appear"
646
+ << " inside its own generic environment\n " ;
647
+ Out << " Interface type: " << interfaceType.getString () << " \n " ;
648
+ Out << " Contextual type: " << contextType.getString () << " \n " ;
669
649
670
650
return true ;
671
651
}
@@ -706,16 +686,16 @@ class Verifier : public ASTWalker {
706
686
707
687
void pushScope (DeclContext *scope) {
708
688
Scopes.push_back (scope);
709
- GenericEnv .push_back ({ scope} );
689
+ GenericSig .push_back (scope-> getGenericSignatureOfContext () );
710
690
}
711
691
void pushScope (BraceStmt *scope) {
712
692
Scopes.push_back (scope);
713
693
}
714
694
void popScope (DeclContext *scope) {
715
695
assert (Scopes.back ().get <DeclContext*>() == scope);
716
- assert (GenericEnv .back (). storage . get <DeclContext *>() == scope);
696
+ assert (GenericSig .back () == scope-> getGenericSignatureOfContext () );
717
697
Scopes.pop_back ();
718
- GenericEnv .pop_back ();
698
+ GenericSig .pop_back ();
719
699
}
720
700
void popScope (BraceStmt *scope) {
721
701
assert (Scopes.back ().get <BraceStmt*>() == scope);
@@ -2689,15 +2669,14 @@ class Verifier : public ASTWalker {
2689
2669
const auto &witness = normal->getWitness (req);
2690
2670
2691
2671
if (auto *genericEnv = witness.getSyntheticEnvironment ())
2692
- GenericEnv .push_back ({ genericEnv} );
2672
+ GenericSig .push_back (genericEnv-> getGenericSignature () );
2693
2673
2694
2674
verifyChecked (witness.getRequirementToSyntheticSubs ());
2695
2675
verifyChecked (witness.getSubstitutions ());
2696
2676
2697
2677
if (auto *genericEnv = witness.getSyntheticEnvironment ()) {
2698
- assert (GenericEnv.back ().storage .dyn_cast <GenericEnvironment *>()
2699
- == genericEnv);
2700
- GenericEnv.pop_back ();
2678
+ assert (GenericSig.back () == genericEnv->getGenericSignature ());
2679
+ GenericSig.pop_back ();
2701
2680
}
2702
2681
2703
2682
continue ;
@@ -2739,32 +2718,7 @@ class Verifier : public ASTWalker {
2739
2718
}
2740
2719
}
2741
2720
2742
- void verifyGenericEnvironment (Decl *D,
2743
- GenericSignature *sig,
2744
- GenericEnvironment *env) {
2745
- if (!sig && !env)
2746
- return ;
2747
-
2748
- if (sig && env) {
2749
- for (auto *paramTy : sig->getGenericParams ()) {
2750
- (void )env->mapTypeIntoContext (paramTy);
2751
- }
2752
-
2753
- return ;
2754
- }
2755
-
2756
- Out << " Decl must have both signature and environment, or neither\n " ;
2757
- D->dump (Out);
2758
- abort ();
2759
- }
2760
-
2761
2721
void verifyChecked (GenericTypeDecl *generic) {
2762
- if (!generic->hasLazyGenericEnvironment ()) {
2763
- verifyGenericEnvironment (generic,
2764
- generic->getGenericSignature (),
2765
- generic->getGenericEnvironment ());
2766
- }
2767
-
2768
2722
verifyCheckedBase (generic);
2769
2723
}
2770
2724
@@ -3031,12 +2985,6 @@ class Verifier : public ASTWalker {
3031
2985
abort ();
3032
2986
}
3033
2987
3034
- if (!AFD->hasLazyGenericEnvironment ()) {
3035
- verifyGenericEnvironment (AFD,
3036
- AFD->getGenericSignature (),
3037
- AFD->getGenericEnvironment ());
3038
- }
3039
-
3040
2988
// If there is an interface type, it shouldn't have any unresolved
3041
2989
// dependent member types.
3042
2990
// FIXME: This is a general property of the type system.
0 commit comments