@@ -141,6 +141,46 @@ std::pair<bool, Expr *> dispatchVisitPreExprHelper(
141
141
return {false , node};
142
142
}
143
143
144
+ // / Describes a generic environment that might be lazily deserialized.
145
+ // /
146
+ // / This class abstracts over a declaration context that may have a generic
147
+ // / environment, ensuring that we don't deserialize the environment.
148
+ struct LazyGenericEnvironment {
149
+ llvm::PointerUnion<DeclContext *, GenericEnvironment *> storage;
150
+
151
+ explicit operator bool () const {
152
+ if (storage.dyn_cast <GenericEnvironment *>())
153
+ return true ;
154
+
155
+ if (auto dc = storage.dyn_cast <DeclContext *>())
156
+ return dc->getGenericSignatureOfContext ();
157
+
158
+ return false ;
159
+ }
160
+
161
+ bool isLazy () const {
162
+ if (auto dc = storage.dyn_cast <DeclContext *>())
163
+ return dc->contextHasLazyGenericEnvironment ();
164
+
165
+ return false ;
166
+ }
167
+
168
+ bool containsPrimaryArchetype (ArchetypeType *archetype) const {
169
+ // Assume true so we don't deserialize.
170
+ if (isLazy ()) return true ;
171
+
172
+ if (auto genericEnv = storage.dyn_cast <GenericEnvironment *>())
173
+ return genericEnv->containsPrimaryArchetype (archetype);
174
+
175
+ if (auto dc = storage.dyn_cast <DeclContext *>()) {
176
+ if (auto genericEnv = dc->getGenericEnvironmentOfContext ())
177
+ return genericEnv->containsPrimaryArchetype (archetype);
178
+ }
179
+
180
+ return false ;
181
+ }
182
+ };
183
+
144
184
class Verifier : public ASTWalker {
145
185
PointerUnion<ModuleDecl *, SourceFile *> M;
146
186
ASTContext &Ctx;
@@ -155,8 +195,8 @@ class Verifier : public ASTWalker {
155
195
using ScopeLike = llvm::PointerUnion<DeclContext *, BraceStmt *>;
156
196
SmallVector<ScopeLike, 4 > Scopes;
157
197
158
- // / The set of primary archetypes that are currently available .
159
- SmallVector<GenericEnvironment * , 2 > GenericEnv;
198
+ // / The stack of generic environments .
199
+ SmallVector<LazyGenericEnvironment , 2 > GenericEnv;
160
200
161
201
// / \brief The stack of optional evaluations active at this point.
162
202
SmallVector<OptionalEvaluationExpr *, 4 > OptionalEvaluations;
@@ -197,7 +237,7 @@ class Verifier : public ASTWalker {
197
237
: M.get<SourceFile *>()->getASTContext()),
198
238
Out(llvm::errs()), HadError(Ctx.hadError()) {
199
239
Scopes.push_back (DC);
200
- GenericEnv.push_back (DC-> getGenericEnvironmentOfContext () );
240
+ GenericEnv.push_back ({DC} );
201
241
}
202
242
203
243
public:
@@ -447,7 +487,7 @@ class Verifier : public ASTWalker {
447
487
}
448
488
void verifyCheckedAlways (Stmt *S) {}
449
489
void verifyCheckedAlways (Pattern *P) {
450
- if (P->hasType ())
490
+ if (P->hasType () && !P-> getDelayedInterfaceType () )
451
491
verifyChecked (P->getType ());
452
492
}
453
493
void verifyCheckedAlways (Decl *D) {
@@ -536,7 +576,7 @@ class Verifier : public ASTWalker {
536
576
// Get the primary archetype.
537
577
auto *parent = archetype->getPrimary ();
538
578
539
- if (!GenericEnv.back ()-> containsPrimaryArchetype (parent)) {
579
+ if (!GenericEnv.back (). containsPrimaryArchetype (parent)) {
540
580
Out << " AST verification error: archetype "
541
581
<< archetype->getString () << " not allowed in this context\n " ;
542
582
@@ -587,14 +627,14 @@ class Verifier : public ASTWalker {
587
627
588
628
void pushScope (DeclContext *scope) {
589
629
Scopes.push_back (scope);
590
- GenericEnv.push_back (scope-> getGenericEnvironmentOfContext () );
630
+ GenericEnv.push_back ({ scope} );
591
631
}
592
632
void pushScope (BraceStmt *scope) {
593
633
Scopes.push_back (scope);
594
634
}
595
635
void popScope (DeclContext *scope) {
596
636
assert (Scopes.back ().get <DeclContext*>() == scope);
597
- assert (GenericEnv.back () == scope-> getGenericEnvironmentOfContext () );
637
+ assert (GenericEnv.back (). storage . get <DeclContext *>() == scope);
598
638
Scopes.pop_back ();
599
639
GenericEnv.pop_back ();
600
640
}
@@ -2008,23 +2048,25 @@ class Verifier : public ASTWalker {
2008
2048
2009
2049
Type typeForAccessors =
2010
2050
var->getInterfaceType ()->getReferenceStorageReferent ();
2011
- typeForAccessors =
2012
- var->getDeclContext ()->mapTypeIntoContext (typeForAccessors);
2013
- if (const FuncDecl *getter = var->getGetter ()) {
2014
- if (getter->getParameterLists ().back ()->size () != 0 ) {
2015
- Out << " property getter has parameters\n " ;
2016
- abort ();
2017
- }
2018
- Type getterResultType = getter->getResultInterfaceType ();
2019
- getterResultType =
2020
- var->getDeclContext ()->mapTypeIntoContext (getterResultType);
2021
- if (!getterResultType->isEqual (typeForAccessors)) {
2022
- Out << " property and getter have mismatched types: '" ;
2023
- typeForAccessors.print (Out);
2024
- Out << " ' vs. '" ;
2025
- getterResultType.print (Out);
2026
- Out << " '\n " ;
2027
- abort ();
2051
+ if (!var->getDeclContext ()->contextHasLazyGenericEnvironment ()) {
2052
+ typeForAccessors =
2053
+ var->getDeclContext ()->mapTypeIntoContext (typeForAccessors);
2054
+ if (const FuncDecl *getter = var->getGetter ()) {
2055
+ if (getter->getParameterLists ().back ()->size () != 0 ) {
2056
+ Out << " property getter has parameters\n " ;
2057
+ abort ();
2058
+ }
2059
+ Type getterResultType = getter->getResultInterfaceType ();
2060
+ getterResultType =
2061
+ var->getDeclContext ()->mapTypeIntoContext (getterResultType);
2062
+ if (!getterResultType->isEqual (typeForAccessors)) {
2063
+ Out << " property and getter have mismatched types: '" ;
2064
+ typeForAccessors.print (Out);
2065
+ Out << " ' vs. '" ;
2066
+ getterResultType.print (Out);
2067
+ Out << " '\n " ;
2068
+ abort ();
2069
+ }
2028
2070
}
2029
2071
}
2030
2072
@@ -2043,14 +2085,16 @@ class Verifier : public ASTWalker {
2043
2085
}
2044
2086
const ParamDecl *param = setter->getParameterLists ().back ()->get (0 );
2045
2087
Type paramType = param->getInterfaceType ();
2046
- paramType = var->getDeclContext ()->mapTypeIntoContext (paramType);
2047
- if (!paramType->isEqual (typeForAccessors)) {
2048
- Out << " property and setter param have mismatched types: '" ;
2049
- typeForAccessors.print (Out);
2050
- Out << " ' vs. '" ;
2051
- paramType.print (Out);
2052
- Out << " '\n " ;
2053
- abort ();
2088
+ if (!var->getDeclContext ()->contextHasLazyGenericEnvironment ()) {
2089
+ paramType = var->getDeclContext ()->mapTypeIntoContext (paramType);
2090
+ if (!paramType->isEqual (typeForAccessors)) {
2091
+ Out << " property and setter param have mismatched types: '" ;
2092
+ typeForAccessors.print (Out);
2093
+ Out << " ' vs. '" ;
2094
+ paramType.print (Out);
2095
+ Out << " '\n " ;
2096
+ abort ();
2097
+ }
2054
2098
}
2055
2099
}
2056
2100
@@ -2226,11 +2270,12 @@ class Verifier : public ASTWalker {
2226
2270
const auto &witness = normal->getWitness (req, nullptr );
2227
2271
2228
2272
if (witness.requiresSubstitution ()) {
2229
- GenericEnv.push_back (witness.getSyntheticEnvironment ());
2273
+ GenericEnv.push_back ({ witness.getSyntheticEnvironment ()} );
2230
2274
for (const auto &sub : witness.getSubstitutions ()) {
2231
2275
verifyChecked (sub.getReplacement ());
2232
2276
}
2233
- assert (GenericEnv.back () == witness.getSyntheticEnvironment ());
2277
+ assert (GenericEnv.back ().storage .dyn_cast <GenericEnvironment *>()
2278
+ == witness.getSyntheticEnvironment ());
2234
2279
GenericEnv.pop_back ();
2235
2280
}
2236
2281
@@ -2293,9 +2338,12 @@ class Verifier : public ASTWalker {
2293
2338
}
2294
2339
2295
2340
void verifyChecked (GenericTypeDecl *generic) {
2296
- verifyGenericEnvironment (generic,
2297
- generic->getGenericSignature (),
2298
- generic->getGenericEnvironment ());
2341
+ if (!generic->hasLazyGenericEnvironment ()) {
2342
+ verifyGenericEnvironment (generic,
2343
+ generic->getGenericSignature (),
2344
+ generic->getGenericEnvironment ());
2345
+ }
2346
+
2299
2347
verifyCheckedBase (generic);
2300
2348
}
2301
2349
@@ -2472,15 +2520,17 @@ class Verifier : public ASTWalker {
2472
2520
// If the function has a generic interface type, it should also have a
2473
2521
// generic signature.
2474
2522
if (AFD->isGenericContext () !=
2475
- (AFD->getGenericEnvironment () != nullptr )) {
2523
+ (AFD->getGenericSignature () != nullptr )) {
2476
2524
Out << " Functions in generic context must have a generic signature\n " ;
2477
2525
AFD->dump (Out);
2478
2526
abort ();
2479
2527
}
2480
2528
2481
- verifyGenericEnvironment (AFD,
2482
- AFD->getGenericSignature (),
2483
- AFD->getGenericEnvironment ());
2529
+ if (!AFD->hasLazyGenericEnvironment ()) {
2530
+ verifyGenericEnvironment (AFD,
2531
+ AFD->getGenericSignature (),
2532
+ AFD->getGenericEnvironment ());
2533
+ }
2484
2534
2485
2535
// If there is an interface type, it shouldn't have any unresolved
2486
2536
// dependent member types.
0 commit comments