@@ -659,15 +659,24 @@ static Expr *buildStorageReference(AccessorDecl *accessor,
659
659
// Otherwise do a self-reference, which is dynamically bogus but
660
660
// should be statically valid. This should only happen in invalid cases.
661
661
} else {
662
- assert (storage->isInvalid ());
663
662
semantics = AccessSemantics::Ordinary;
664
663
selfAccessKind = SelfAccessorKind::Peer;
665
664
}
666
665
break ;
667
666
668
667
case TargetImpl::Wrapper: {
669
668
auto var = cast<VarDecl>(accessor->getStorage ());
670
- storage = var->getPropertyWrapperBackingProperty ();
669
+ auto *backing = var->getPropertyWrapperBackingProperty ();
670
+
671
+ // Error recovery.
672
+ if (!backing) {
673
+ auto type = storage->getValueInterfaceType ();
674
+ if (isLValue)
675
+ type = LValueType::get (type);
676
+ return new (ctx) ErrorExpr (SourceRange (), type);
677
+ }
678
+
679
+ storage = backing;
671
680
672
681
// If the outermost property wrapper uses the enclosing self pattern,
673
682
// record that.
@@ -691,7 +700,18 @@ static Expr *buildStorageReference(AccessorDecl *accessor,
691
700
case TargetImpl::WrapperStorage: {
692
701
auto var =
693
702
cast<VarDecl>(accessor->getStorage ())->getOriginalWrappedProperty ();
694
- storage = var->getPropertyWrapperBackingProperty ();
703
+ auto *backing = var->getPropertyWrapperBackingProperty ();
704
+
705
+ // Error recovery.
706
+ if (!backing) {
707
+ auto type = storage->getValueInterfaceType ();
708
+ if (isLValue)
709
+ type = LValueType::get (type);
710
+ return new (ctx) ErrorExpr (SourceRange (), type);
711
+ }
712
+
713
+ storage = backing;
714
+
695
715
enclosingSelfAccess =
696
716
getEnclosingSelfPropertyWrapperAccess (var, /* forProjected=*/ true );
697
717
if (!enclosingSelfAccess) {
@@ -976,12 +996,21 @@ void createPropertyStoreOrCallSuperclassSetter(AccessorDecl *accessor,
976
996
value = synthesizeCopyWithZoneCall (value, property, ctx);
977
997
}
978
998
999
+ // Error recovery.
1000
+ if (value->getType ()->hasError ())
1001
+ return ;
1002
+
979
1003
Expr *dest = buildStorageReference (accessor, storage, target,
980
1004
/* isLValue=*/ true , ctx);
981
1005
982
1006
// A lazy property setter will store a value of type T into underlying storage
983
1007
// of type T?.
984
1008
auto destType = dest->getType ()->getWithoutSpecifierType ();
1009
+
1010
+ // Error recovery.
1011
+ if (destType->hasError ())
1012
+ return ;
1013
+
985
1014
if (!destType->isEqual (value->getType ())) {
986
1015
assert (destType->getOptionalObjectType ()->isEqual (value->getType ()));
987
1016
value = new (ctx) InjectIntoOptionalExpr (value, destType);
@@ -1172,17 +1201,25 @@ synthesizeLazyGetterBody(AccessorDecl *Get, VarDecl *VD, VarDecl *Storage,
1172
1201
// Take the initializer from the PatternBindingDecl for VD.
1173
1202
// TODO: This doesn't work with complicated patterns like:
1174
1203
// lazy var (a,b) = foo()
1175
- auto *InitValue = VD->getParentInitializer ();
1176
1204
auto PBD = VD->getParentPatternBinding ();
1177
1205
unsigned entryIndex = PBD->getPatternEntryIndexForVarDecl (VD);
1178
- PBD->setInitializerSubsumed (entryIndex);
1179
1206
1180
- if (!PBD->isInitializerChecked (entryIndex))
1181
- TC.typeCheckPatternBinding (PBD, entryIndex);
1207
+ Expr *InitValue;
1208
+ if (PBD->getPatternList ()[entryIndex].getInit ()) {
1209
+ PBD->setInitializerSubsumed (entryIndex);
1210
+
1211
+ if (!PBD->isInitializerChecked (entryIndex))
1212
+ TC.typeCheckPatternBinding (PBD, entryIndex);
1213
+
1214
+ InitValue = PBD->getPatternList ()[entryIndex].getInit ();
1215
+ } else {
1216
+ InitValue = new (Ctx) ErrorExpr (SourceRange (), Tmp2VD->getType ());
1217
+ }
1182
1218
1183
1219
// Recontextualize any closure declcontexts nested in the initializer to
1184
1220
// realize that they are in the getter function.
1185
1221
Get->getImplicitSelfDecl ()->setDeclContext (Get);
1222
+
1186
1223
InitValue->walk (RecontextualizeClosures (Get));
1187
1224
1188
1225
// Wrap the initializer in a LazyInitializerExpr to avoid walking it twice.
@@ -1226,6 +1263,12 @@ synthesizePropertyWrapperGetterBody(AccessorDecl *getter, ASTContext &ctx) {
1226
1263
return synthesizeTrivialGetterBody (getter, TargetImpl::Wrapper, ctx);
1227
1264
}
1228
1265
1266
+ static std::pair<BraceStmt *, bool >
1267
+ synthesizeInvalidAccessor (AccessorDecl *accessor, ASTContext &ctx) {
1268
+ auto loc = accessor->getLoc ();
1269
+ return { BraceStmt::create (ctx, loc, ArrayRef<ASTNode>(), loc, true ), true };
1270
+ }
1271
+
1229
1272
static std::pair<BraceStmt *, bool >
1230
1273
synthesizeGetterBody (AccessorDecl *getter, ASTContext &ctx) {
1231
1274
auto storage = getter->getStorage ();
@@ -1257,7 +1300,7 @@ synthesizeGetterBody(AccessorDecl *getter, ASTContext &ctx) {
1257
1300
return synthesizeTrivialGetterBody (getter, ctx);
1258
1301
1259
1302
case ReadImplKind::Get:
1260
- llvm_unreachable ( " synthesizing getter that already exists? " );
1303
+ return synthesizeInvalidAccessor ( getter, ctx );
1261
1304
1262
1305
case ReadImplKind::Inherited:
1263
1306
return synthesizeInheritedGetterBody (getter, ctx);
@@ -1490,7 +1533,7 @@ synthesizeSetterBody(AccessorDecl *setter, ASTContext &ctx) {
1490
1533
return synthesizeInheritedWithObserversSetterBody (setter, ctx);
1491
1534
1492
1535
case WriteImplKind::Set:
1493
- llvm_unreachable ( " synthesizing setter for unknown reason? " );
1536
+ return synthesizeInvalidAccessor ( setter, ctx);
1494
1537
1495
1538
case WriteImplKind::MutableAddress:
1496
1539
return synthesizeMutableAddressSetterBody (setter, ctx);
@@ -1547,17 +1590,14 @@ synthesizeModifyCoroutineBody(AccessorDecl *modify, ASTContext &ctx) {
1547
1590
return synthesizeCoroutineAccessorBody (modify, ctx);
1548
1591
}
1549
1592
1550
- std::pair<BraceStmt *, bool >
1593
+ static std::pair<BraceStmt *, bool >
1551
1594
synthesizeAccessorBody (AbstractFunctionDecl *fn, void *) {
1552
1595
auto *accessor = cast<AccessorDecl>(fn);
1553
1596
auto &ctx = accessor->getASTContext ();
1554
1597
1555
1598
if (ctx.Stats )
1556
1599
ctx.Stats ->getFrontendCounters ().NumAccessorBodiesSynthesized ++;
1557
1600
1558
- if (accessor->isInvalid () || ctx.hadError ())
1559
- return { nullptr , true };
1560
-
1561
1601
switch (accessor->getAccessorKind ()) {
1562
1602
case AccessorKind::Get:
1563
1603
return synthesizeGetterBody (accessor, ctx);
0 commit comments