Skip to content

Commit a467674

Browse files
committed
Sema: Always emit materializeForSelf for resilient structs
This gives us consistent behavior between stored and computed properties.
1 parent c3dd77a commit a467674

File tree

2 files changed

+35
-40
lines changed

2 files changed

+35
-40
lines changed

lib/Sema/CodeSynthesis.cpp

Lines changed: 27 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -699,7 +699,9 @@ static void maybeMarkTransparent(FuncDecl *accessor,
699699
->isNominalTypeOrNominalTypeExtensionContext();
700700

701701
// FIXME: resilient global variables
702-
if (!NTD || NTD->hasFixedLayout())
702+
if (!NTD ||
703+
NTD->hasFixedLayout() ||
704+
(isa<ClassDecl>(NTD) && NTD->getClangDecl()))
703705
accessor->getAttrs().add(new (TC.Context) TransparentAttr(IsImplicit));
704706
}
705707

@@ -793,14 +795,6 @@ static void synthesizeStoredMaterializeForSet(FuncDecl *materializeForSet,
793795

794796
SourceLoc loc = storage->getLoc();
795797
materializeForSet->setBody(BraceStmt::create(ctx, loc, returnStmt, loc,true));
796-
797-
maybeMarkTransparent(materializeForSet, storage, TC);
798-
799-
TC.typeCheckDecl(materializeForSet, true);
800-
801-
// Register the accessor as an external decl if the storage was imported.
802-
if (needsToBeRegisteredAsExternalDecl(storage))
803-
TC.Context.addExternalDecl(materializeForSet);
804798
}
805799

806800
/// Does a storage decl currently lacking accessor functions require a
@@ -896,7 +890,6 @@ void swift::addTrivialAccessorsToStorage(AbstractStorageDecl *storage,
896890
if (setter) {
897891
FuncDecl *materializeForSet = addMaterializeForSet(storage, TC);
898892
synthesizeMaterializeForSet(materializeForSet, storage, TC);
899-
TC.typeCheckDecl(materializeForSet, true);
900893
TC.typeCheckDecl(materializeForSet, false);
901894
}
902895
}
@@ -941,7 +934,6 @@ void TypeChecker::synthesizeWitnessAccessorsForStorage(
941934
requirement->getSetter() && !storage->getMaterializeForSetFunc()) {
942935
FuncDecl *materializeForSet = addMaterializeForSet(storage, *this);
943936
synthesizeMaterializeForSet(materializeForSet, storage, *this);
944-
typeCheckDecl(materializeForSet, true);
945937
typeCheckDecl(materializeForSet, false);
946938
}
947939
return;
@@ -1153,15 +1145,6 @@ static void synthesizeComputedMaterializeForSet(FuncDecl *materializeForSet,
11531145

11541146
SourceLoc loc = storage->getLoc();
11551147
materializeForSet->setBody(BraceStmt::create(ctx, loc, body, loc, true));
1156-
1157-
// Mark it transparent, there is no user benefit to this actually existing.
1158-
materializeForSet->getAttrs().add(new (ctx) TransparentAttr(IsImplicit));
1159-
1160-
TC.typeCheckDecl(materializeForSet, true);
1161-
1162-
// Register the accessor as an external decl if the storage was imported.
1163-
if (needsToBeRegisteredAsExternalDecl(storage))
1164-
TC.Context.addExternalDecl(materializeForSet);
11651148
}
11661149

11671150
/// Build a direct call to an addressor from within a
@@ -1333,15 +1316,6 @@ static void synthesizeAddressedMaterializeForSet(FuncDecl *materializeForSet,
13331316

13341317
SourceLoc loc = storage->getLoc();
13351318
materializeForSet->setBody(BraceStmt::create(ctx, loc, body, loc));
1336-
1337-
// Mark it transparent, there is no user benefit to this actually existing.
1338-
materializeForSet->getAttrs().add(new (ctx) TransparentAttr(IsImplicit));
1339-
1340-
TC.typeCheckDecl(materializeForSet, true);
1341-
1342-
// Register the accessor as an external decl if the storage was imported.
1343-
if (needsToBeRegisteredAsExternalDecl(storage))
1344-
TC.Context.addExternalDecl(materializeForSet);
13451319
}
13461320

13471321
void swift::synthesizeMaterializeForSet(FuncDecl *materializeForSet,
@@ -1363,20 +1337,19 @@ void swift::synthesizeMaterializeForSet(FuncDecl *materializeForSet,
13631337
|| needsDynamicMaterializeForSet(var)) {
13641338
synthesizeComputedMaterializeForSet(materializeForSet, storage,
13651339
bufferDecl, TC);
1366-
return;
1340+
} else {
1341+
synthesizeStoredMaterializeForSet(materializeForSet, storage,
1342+
bufferDecl, TC);
13671343
}
1368-
1369-
synthesizeStoredMaterializeForSet(materializeForSet, storage,
1370-
bufferDecl, TC);
1371-
return;
1344+
break;
13721345
}
13731346

13741347
// We should access these by calling mutableAddress.
13751348
case AbstractStorageDecl::AddressedWithTrivialAccessors:
13761349
case AbstractStorageDecl::ComputedWithMutableAddress:
13771350
synthesizeAddressedMaterializeForSet(materializeForSet, storage,
13781351
bufferDecl, TC);
1379-
return;
1352+
break;
13801353

13811354
// These must be accessed with a getter/setter pair.
13821355
// TODO: StoredWithObservers and AddressedWithObservers could be
@@ -1387,9 +1360,16 @@ void swift::synthesizeMaterializeForSet(FuncDecl *materializeForSet,
13871360
case AbstractStorageDecl::Computed:
13881361
synthesizeComputedMaterializeForSet(materializeForSet, storage,
13891362
bufferDecl, TC);
1390-
return;
1363+
break;
13911364
}
1392-
llvm_unreachable("bad abstract storage kind");
1365+
1366+
maybeMarkTransparent(materializeForSet, storage, TC);
1367+
1368+
TC.typeCheckDecl(materializeForSet, true);
1369+
1370+
// Register the accessor as an external decl if the storage was imported.
1371+
if (needsToBeRegisteredAsExternalDecl(storage))
1372+
TC.Context.addExternalDecl(materializeForSet);
13931373
}
13941374

13951375
/// Given a VarDecl with a willSet: and/or didSet: specifier, synthesize the
@@ -1761,10 +1741,17 @@ void swift::maybeAddMaterializeForSet(AbstractStorageDecl *storage,
17611741
return;
17621742
}
17631743

1764-
// Structs and enums don't need this.
1765-
} else {
1766-
assert(isa<StructDecl>(container) || isa<EnumDecl>(container));
1744+
// Enums don't need this.
1745+
} else if (isa<EnumDecl>(container)) {
17671746
return;
1747+
1748+
// Computed properties of @_fixed_layout structs don't need this, but
1749+
// resilient structs do, since stored properties can resiliently become
1750+
// computed or vice versa.
1751+
} else {
1752+
auto *structDecl = cast<StructDecl>(container);
1753+
if (structDecl->hasFixedLayout())
1754+
return;
17681755
}
17691756

17701757
addMaterializeForSet(storage, TC);

test/SILGen/struct_resilience.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,14 @@ func functionWithFixedLayoutOfResilientTypes(r: Rectangle, f: Rectangle -> Recta
6767

6868
public struct MySize {
6969

70+
// CHECK-LABEL: sil @_TFV17struct_resilience6MySizeg1dSi : $@convention(method) (@in_guaranteed MySize) -> Int
71+
// CHECK-LABEL: sil @_TFV17struct_resilience6MySizes1dSi : $@convention(method) (Int, @inout MySize) -> ()
72+
// CHECK-LABEL: sil @_TFV17struct_resilience6MySizem1dSi : $@convention(method) (Builtin.RawPointer, @inout Builtin.UnsafeValueBuffer, @inout MySize) -> (Builtin.RawPointer, Optional<@convention(thin) (Builtin.RawPointer, inout Builtin.UnsafeValueBuffer, inout MySize, @thick MySize.Type) -> ()>)
73+
public var d: Int {
74+
get { return 0 }
75+
set { }
76+
}
77+
7078
// CHECK-LABEL: sil @_TFV17struct_resilience6MySizeg1wSi : $@convention(method) (@in_guaranteed MySize) -> Int
7179
// CHECK-LABEL: sil @_TFV17struct_resilience6MySizes1wSi : $@convention(method) (Int, @inout MySize) -> ()
7280
// CHECK-LABEL: sil @_TFV17struct_resilience6MySizem1wSi : $@convention(method) (Builtin.RawPointer, @inout Builtin.UnsafeValueBuffer, @inout MySize) -> (Builtin.RawPointer, Optional<@convention(thin) (Builtin.RawPointer, inout Builtin.UnsafeValueBuffer, inout MySize, @thick MySize.Type) -> ()>)

0 commit comments

Comments
 (0)