30
30
#include " swift/AST/ForeignErrorConvention.h"
31
31
#include " swift/AST/GenericEnvironment.h"
32
32
#include " swift/AST/GenericSignatureBuilder.h"
33
+ #include " swift/AST/Initializer.h"
33
34
#include " swift/AST/NameLookup.h"
34
35
#include " swift/AST/PrettyStackTrace.h"
35
36
#include " swift/AST/ProtocolConformance.h"
@@ -2120,14 +2121,17 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
2120
2121
}
2121
2122
2122
2123
void visitBoundVariable (VarDecl *VD) {
2124
+ // WARNING: Anything you put in this function will only be run when the
2125
+ // VarDecl is fully type-checked within its own file. It will NOT be run
2126
+ // when the VarDecl is merely used from another file.
2123
2127
TC.validateDecl (VD);
2124
2128
2125
- // Set up accessors.
2129
+ // Set up accessors, also lowering lazy and @NSManaged properties .
2126
2130
maybeAddAccessorsToStorage (VD);
2127
2131
2128
- // WARNING: Anything you put in this function will only be run when the
2129
- // VarDecl is fully type-checked within its own file. It will NOT be run
2130
- // when the VarDecl is merely used from another file.
2132
+ // Add the '@_hasStorage' attribute if this property is stored.
2133
+ if (VD-> hasStorage () && !VD-> getAttrs (). hasAttribute <HasStorageAttr>())
2134
+ VD-> getAttrs (). add ( new (TC. Context ) HasStorageAttr ( /* isImplicit= */ true ));
2131
2135
2132
2136
// Reject cases where this is a variable that has storage but it isn't
2133
2137
// allowed.
@@ -2223,16 +2227,17 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
2223
2227
.fixItRemove (attr->getRange ());
2224
2228
}
2225
2229
}
2226
- }
2227
2230
2231
+ if (VD->getAttrs ().hasAttribute <DynamicReplacementAttr>())
2232
+ TC.checkDynamicReplacementAttribute (VD);
2233
+ }
2228
2234
2229
2235
void visitBoundVars (Pattern *P) {
2230
2236
P->forEachVariable ([&] (VarDecl *VD) { this ->visitBoundVariable (VD); });
2231
2237
}
2232
2238
2233
2239
void visitPatternBindingDecl (PatternBindingDecl *PBD) {
2234
- if (PBD->isBeingValidated ())
2235
- return ;
2240
+ DeclContext *DC = PBD->getDeclContext ();
2236
2241
2237
2242
// Check all the pattern/init pairs in the PBD.
2238
2243
validatePatternBindingEntries (TC, PBD);
@@ -2250,10 +2255,6 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
2250
2255
PBD->getPattern (i)->hasStorage () &&
2251
2256
!PBD->getPattern (i)->getType ()->hasError ()) {
2252
2257
2253
- // If we have a type-adjusting attribute (like ownership), apply it now.
2254
- if (auto var = PBD->getSingleVar ())
2255
- TC.checkTypeModifyingDeclAttributes (var);
2256
-
2257
2258
// Decide whether we should suppress default initialization.
2258
2259
//
2259
2260
// Note: Swift 4 had a bug where properties with a desugared optional
@@ -2280,15 +2281,27 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
2280
2281
// If we got a default initializer, install it and re-type-check it
2281
2282
// to make sure it is properly coerced to the pattern type.
2282
2283
PBD->setInit (i, defaultInit);
2283
- TC.typeCheckPatternBinding (PBD, i);
2284
2284
}
2285
2285
}
2286
+
2287
+ if (PBD->getInit (i)) {
2288
+ // Add the attribute that preserves the "has an initializer" value across
2289
+ // module generation, as required for TBDGen.
2290
+ PBD->getPattern (i)->forEachVariable ([&](VarDecl *VD) {
2291
+ if (VD->hasStorage () &&
2292
+ !VD->getAttrs ().hasAttribute <HasInitialValueAttr>()) {
2293
+ auto *attr = new (TC.Context ) HasInitialValueAttr (
2294
+ /* IsImplicit=*/ true );
2295
+ VD->getAttrs ().add (attr);
2296
+ }
2297
+ });
2298
+ }
2286
2299
}
2287
2300
2288
2301
bool isInSILMode = false ;
2289
- if (auto sourceFile = PBD-> getDeclContext () ->getParentSourceFile ())
2302
+ if (auto sourceFile = DC ->getParentSourceFile ())
2290
2303
isInSILMode = sourceFile->Kind == SourceFileKind::SIL;
2291
- bool isTypeContext = PBD-> getDeclContext () ->isTypeContext ();
2304
+ bool isTypeContext = DC ->isTypeContext ();
2292
2305
2293
2306
// If this is a declaration without an initializer, reject code if
2294
2307
// uninitialized vars are not allowed.
@@ -2305,8 +2318,6 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
2305
2318
if (var->isInvalid () || PBD->isInvalid ())
2306
2319
return ;
2307
2320
2308
- auto *varDC = var->getDeclContext ();
2309
-
2310
2321
auto markVarAndPBDInvalid = [PBD, var] {
2311
2322
PBD->setInvalid ();
2312
2323
var->setInvalid ();
@@ -2324,9 +2335,9 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
2324
2335
2325
2336
// Static/class declarations require an initializer unless in a
2326
2337
// protocol.
2327
- if (var->isStatic () && !isa<ProtocolDecl>(varDC )) {
2338
+ if (var->isStatic () && !isa<ProtocolDecl>(DC )) {
2328
2339
// ...but don't enforce this for SIL or parseable interface files.
2329
- switch (varDC ->getParentSourceFile ()->Kind ) {
2340
+ switch (DC ->getParentSourceFile ()->Kind ) {
2330
2341
case SourceFileKind::Interface:
2331
2342
case SourceFileKind::SIL:
2332
2343
return ;
@@ -2343,8 +2354,8 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
2343
2354
}
2344
2355
2345
2356
// Global variables require an initializer in normal source files.
2346
- if (varDC ->isModuleScopeContext ()) {
2347
- switch (varDC ->getParentSourceFile ()->Kind ) {
2357
+ if (DC ->isModuleScopeContext ()) {
2358
+ switch (DC ->getParentSourceFile ()->Kind ) {
2348
2359
case SourceFileKind::Main:
2349
2360
case SourceFileKind::REPL:
2350
2361
case SourceFileKind::Interface:
@@ -2368,8 +2379,35 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
2368
2379
2369
2380
// If the initializers in the PBD aren't checked yet, do so now.
2370
2381
for (unsigned i = 0 , e = PBD->getNumPatternEntries (); i != e; ++i) {
2371
- if (!PBD->isInitializerChecked (i) && PBD->getInit (i))
2382
+ if (!PBD->getInit (i))
2383
+ continue ;
2384
+
2385
+ if (!PBD->isInitializerChecked (i))
2372
2386
TC.typeCheckPatternBinding (PBD, i);
2387
+
2388
+ if (!PBD->isInvalid ()) {
2389
+ auto &entry = PBD->getPatternList ()[i];
2390
+ auto *init = PBD->getInit (i);
2391
+
2392
+ // If we're performing an binding to a weak or unowned variable from a
2393
+ // constructor call, emit a warning that the instance will be immediately
2394
+ // deallocated.
2395
+ diagnoseUnownedImmediateDeallocation (TC, PBD->getPattern (i),
2396
+ entry.getEqualLoc (),
2397
+ init);
2398
+
2399
+ // If we entered an initializer context, contextualize any
2400
+ // auto-closures we might have created.
2401
+ if (!DC->isLocalContext ()) {
2402
+ auto *initContext = cast_or_null<PatternBindingInitializer>(
2403
+ entry.getInitContext ());
2404
+ if (initContext) {
2405
+ // Check safety of error-handling in the declaration, too.
2406
+ TC.checkInitializerErrorHandling (initContext, init);
2407
+ (void ) TC.contextualizeInitializer (initContext, init);
2408
+ }
2409
+ }
2410
+ }
2373
2411
}
2374
2412
}
2375
2413
@@ -2845,12 +2883,6 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
2845
2883
void visitVarDecl (VarDecl *VD) {
2846
2884
// Delay type-checking on VarDecls until we see the corresponding
2847
2885
// PatternBindingDecl.
2848
-
2849
- // Except if there is a dynamic replacement attribute.
2850
- if (VD->getAttrs ().hasAttribute <DynamicReplacementAttr>()) {
2851
- TC.validateDecl (VD);
2852
- TC.checkDynamicReplacementAttribute (VD);
2853
- }
2854
2886
}
2855
2887
2856
2888
// / Determine whether the given declaration requires a definition.
@@ -3699,10 +3731,6 @@ void TypeChecker::validateDecl(ValueDecl *D) {
3699
3731
auto *VD = cast<VarDecl>(D);
3700
3732
auto *PBD = VD->getParentPatternBinding ();
3701
3733
3702
- // Add the '@_hasStorage' attribute if this property is stored.
3703
- if (VD->hasStorage () && !VD->getAttrs ().hasAttribute <HasStorageAttr>())
3704
- VD->getAttrs ().add (new (Context) HasStorageAttr (/* isImplicit=*/ true ));
3705
-
3706
3734
// Note that we need to handle the fact that some VarDecls don't
3707
3735
// have a PatternBindingDecl, for example the iterator in a
3708
3736
// 'for ... in ...' loop.
0 commit comments