Skip to content

Commit 765140c

Browse files
authored
Merge pull request #6933 from slavapestov/resilience-diagnostics-round-two
Resilience diagnostics round two
2 parents 4153928 + 022c283 commit 765140c

25 files changed

+292
-34
lines changed

include/swift/AST/Decl.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5385,9 +5385,6 @@ enum class CtorInitializerKind {
53855385
/// object by delegating to another initializer (eventually reaching a
53865386
/// designated initializer).
53875387
///
5388-
/// A convenience initializer is written with a return type of "Self" in
5389-
/// source code.
5390-
///
53915388
/// Convenience initializers are inherited into subclasses that override
53925389
/// all of their superclass's designated initializers.
53935390
Convenience,

include/swift/AST/DiagnosticsSema.def

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3327,11 +3327,20 @@ WARNING(discardable_result_on_void_never_function, none,
33273327
// Resilience diagnostics
33283328
//------------------------------------------------------------------------------
33293329

3330+
ERROR(fixed_layout_attr_on_internal_type,
3331+
none, "'@_fixed_layout' attribute can only be applied to '@_versioned' "
3332+
"or public declarations, but %0 is "
3333+
"%select{private|fileprivate|internal|%error|%error}1",
3334+
(Identifier, Accessibility))
3335+
33303336
ERROR(versioned_attr_with_explicit_accessibility,
33313337
none, "'@_versioned' attribute can only be applied to internal "
33323338
"declarations, but %0 is %select{private|fileprivate|%error|public|open}1",
33333339
(Identifier, Accessibility))
33343340

3341+
ERROR(versioned_attr_in_protocol,none,
3342+
"'@_versioned' attribute cannot be used in protocols", ())
3343+
33353344
#define FRAGILE_FUNC_KIND \
33363345
"%select{a '@_transparent' function|" \
33373346
"an '@inline(__always)' function|" \
@@ -3347,10 +3356,19 @@ ERROR(resilience_decl_unavailable,
33473356
"cannot be referenced from " FRAGILE_FUNC_KIND "3",
33483357
(DescriptiveDeclKind, DeclName, Accessibility, unsigned))
33493358

3359+
#undef FRAGILE_FUNC_KIND
3360+
33503361
NOTE(resilience_decl_declared_here,
33513362
none, "%0 %1 is not '@_versioned' or public", (DescriptiveDeclKind, DeclName))
33523363

3353-
#undef FRAGILE_FUNC_KIND
3364+
ERROR(designated_init_in_extension_resilient,none,
3365+
"initializer declared in an extension of "
3366+
"non-'@_fixed_layout' type %0 must delegate to another initializer", (Type))
3367+
3368+
ERROR(designated_init_inlineable_resilient,none,
3369+
"initializer of non-'@_fixed_layout' type %0 is "
3370+
"'%select{@_transparent|@inline(__always)|@_inlineable|%error}1' and must "
3371+
"delegate to another initializer", (Type, unsigned))
33543372

33553373
//------------------------------------------------------------------------------
33563374
// @_specialize diagnostics

lib/Sema/CSApply.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,11 @@ static bool shouldAccessStorageDirectly(Expr *base, VarDecl *member,
210210
member->getDeclContext()->getDeclaredInterfaceType()))
211211
return false;
212212

213+
// If the storage is resilient, we cannot access it directly at all.
214+
if (!member->hasFixedLayout(DC->getParentModule(),
215+
DC->getResilienceExpansion()))
216+
return false;
217+
213218
return true;
214219
}
215220

@@ -222,12 +227,6 @@ getImplicitMemberReferenceAccessSemantics(Expr *base, VarDecl *member,
222227
// accessors. However, in the init and destructor methods for the type
223228
// immediately containing the property, accesses are done direct.
224229
if (shouldAccessStorageDirectly(base, member, DC)) {
225-
// The storage better not be resilient.
226-
assert(member->hasFixedLayout(DC->getParentModule(),
227-
DC->getResilienceExpansion()) &&
228-
"Designated initializers and destructors of resilient types "
229-
"cannot be @_transparent or defined in extensions");
230-
231230
// Access this directly instead of going through (e.g.) observing or
232231
// trivial accessors.
233232
return AccessSemantics::DirectToStorage;

lib/Sema/ResilienceDiagnostics.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ bool TypeChecker::diagnoseInlineableDeclRef(SourceLoc loc,
7979
auto expansion = DC->getResilienceExpansion();
8080
if (expansion == ResilienceExpansion::Minimal) {
8181
if (!isa<GenericTypeParamDecl>(D) &&
82+
// Protocol requirements are not versioned because there's no
83+
// global entry point
84+
!(isa<ProtocolDecl>(D->getDeclContext()) && isRequirement(D)) &&
8285
// FIXME: Figure out what to do with typealiases
8386
!isa<TypeAliasDecl>(D) &&
8487
!D->getDeclContext()->isLocalContext() &&
@@ -96,3 +99,33 @@ bool TypeChecker::diagnoseInlineableDeclRef(SourceLoc loc,
9699

97100
return false;
98101
}
102+
103+
void TypeChecker::diagnoseResilientValueConstructor(ConstructorDecl *ctor) {
104+
auto nominalDecl = ctor->getDeclContext()
105+
->getAsNominalTypeOrNominalTypeExtensionContext();
106+
107+
bool isDelegating =
108+
(ctor->getDelegatingOrChainedInitKind(&Diags) ==
109+
ConstructorDecl::BodyInitKind::Delegating);
110+
111+
if (!isDelegating &&
112+
!nominalDecl->hasFixedLayout(ctor->getParentModule(),
113+
ctor->getResilienceExpansion())) {
114+
if (ctor->getResilienceExpansion() == ResilienceExpansion::Minimal) {
115+
// An @_inlineable designated initializer defined in a resilient type
116+
// cannot initialize stored properties directly, and must chain to
117+
// another initializer.
118+
diagnose(ctor->getLoc(),
119+
diag::designated_init_inlineable_resilient,
120+
ctor->getDeclContext()->getDeclaredInterfaceType(),
121+
getFragileFunctionKind(ctor));
122+
} else {
123+
// A designated initializer defined on an extension of a resilient
124+
// type from a different resilience domain cannot initialize stored
125+
// properties directly, and must chain to another initializer.
126+
diagnose(ctor->getLoc(),
127+
diag::designated_init_in_extension_resilient,
128+
ctor->getDeclContext()->getDeclaredInterfaceType());
129+
}
130+
}
131+
}

lib/Sema/TypeCheckAttr.cpp

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -697,7 +697,6 @@ class AttributeChecker : public AttributeVisitor<AttributeChecker> {
697697
IGNORED_ATTR(Dynamic)
698698
IGNORED_ATTR(Effects)
699699
IGNORED_ATTR(Exported)
700-
IGNORED_ATTR(FixedLayout)
701700
IGNORED_ATTR(GKInspectable)
702701
IGNORED_ATTR(IBDesignable)
703702
IGNORED_ATTR(IBInspectable)
@@ -764,6 +763,7 @@ class AttributeChecker : public AttributeVisitor<AttributeChecker> {
764763

765764
void visitSpecializeAttr(SpecializeAttr *attr);
766765

766+
void visitFixedLayoutAttr(FixedLayoutAttr *attr);
767767
void visitVersionedAttr(VersionedAttr *attr);
768768

769769
void visitDiscardableResultAttr(DiscardableResultAttr *attr);
@@ -1770,16 +1770,40 @@ void AttributeChecker::visitSpecializeAttr(SpecializeAttr *attr) {
17701770
attr->setRequirements(DC->getASTContext(), convertedRequirements);
17711771
}
17721772

1773+
void AttributeChecker::visitFixedLayoutAttr(FixedLayoutAttr *attr) {
1774+
auto *VD = cast<ValueDecl>(D);
1775+
1776+
if (VD->getEffectiveAccess() < Accessibility::Public) {
1777+
TC.diagnose(attr->getLocation(),
1778+
diag::fixed_layout_attr_on_internal_type,
1779+
VD->getName(),
1780+
VD->getFormalAccess())
1781+
.fixItRemove(attr->getRangeWithAt());
1782+
attr->setInvalid();
1783+
}
1784+
}
1785+
17731786
void AttributeChecker::visitVersionedAttr(VersionedAttr *attr) {
17741787
auto *VD = cast<ValueDecl>(D);
17751788

1789+
// FIXME: Once protocols can contain nominal types, do we want to allow
1790+
// these nominal types to have accessibility (and also @_versioned)?
1791+
if (isa<ProtocolDecl>(VD->getDeclContext())) {
1792+
TC.diagnose(attr->getLocation(),
1793+
diag::versioned_attr_in_protocol)
1794+
.fixItRemove(attr->getRangeWithAt());
1795+
attr->setInvalid();
1796+
return;
1797+
}
1798+
17761799
if (VD->getFormalAccess() != Accessibility::Internal) {
17771800
TC.diagnose(attr->getLocation(),
17781801
diag::versioned_attr_with_explicit_accessibility,
17791802
VD->getName(),
17801803
VD->getFormalAccess())
17811804
.fixItRemove(attr->getRangeWithAt());
17821805
attr->setInvalid();
1806+
return;
17831807
}
17841808
}
17851809

lib/Sema/TypeCheckDecl.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6416,6 +6416,13 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
64166416
} else if (auto extType = CD->getDeclContext()->getDeclaredInterfaceType()) {
64176417
// A designated initializer for a class must be written within the class
64186418
// itself.
6419+
//
6420+
// This is because designated initializers of classes get a vtable entry,
6421+
// and extensions cannot add vtable entries to the extended type.
6422+
//
6423+
// If we implement the ability for extensions defined in the same module
6424+
// (or the same file) to add vtable entries, we can re-evaluate this
6425+
// restriction.
64196426
if (extType->getClassOrBoundGenericClass() &&
64206427
isa<ExtensionDecl>(CD->getDeclContext())) {
64216428
TC.diagnose(CD->getLoc(), diag::designated_init_in_extension, extType)

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5649,7 +5649,7 @@ void DefaultWitnessChecker::recordWitness(
56495649
}
56505650

56515651
// Not all protocol members are requirements.
5652-
bool TypeChecker::isRequirement(ValueDecl *requirement) {
5652+
bool TypeChecker::isRequirement(const ValueDecl *requirement) {
56535653
if (auto *FD = dyn_cast<FuncDecl>(requirement))
56545654
if (FD->isAccessor())
56555655
return false;

lib/Sema/TypeCheckStmt.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1489,7 +1489,12 @@ bool TypeChecker::typeCheckConstructorBodyUntil(ConstructorDecl *ctor,
14891489
// Determine whether we need to introduce a super.init call.
14901490
auto nominalDecl = ctor->getDeclContext()
14911491
->getAsNominalTypeOrNominalTypeExtensionContext();
1492-
ClassDecl *ClassD = dyn_cast_or_null<ClassDecl>(nominalDecl);
1492+
1493+
// Error case.
1494+
if (nominalDecl == nullptr)
1495+
return HadError;
1496+
1497+
ClassDecl *ClassD = dyn_cast<ClassDecl>(nominalDecl);
14931498
bool wantSuperInitCall = false;
14941499
if (ClassD) {
14951500
bool isDelegating = false;
@@ -1521,18 +1526,22 @@ bool TypeChecker::typeCheckConstructorBodyUntil(ConstructorDecl *ctor,
15211526
}
15221527

15231528
// A class designated initializer must never be delegating.
1524-
if (ctor->isDesignatedInit() && ClassD && isDelegating) {
1529+
if (ctor->isDesignatedInit() && isDelegating) {
15251530
diagnose(ctor->getLoc(),
15261531
diag::delegating_designated_init,
15271532
ctor->getDeclContext()->getDeclaredInterfaceType())
15281533
.fixItInsert(ctor->getLoc(), "convenience ");
15291534
diagnose(initExpr->getLoc(), diag::delegation_here);
15301535
ctor->setInitKind(CtorInitializerKind::Convenience);
15311536
}
1537+
} else {
1538+
diagnoseResilientValueConstructor(ctor);
15321539
}
15331540

15341541
// If we want a super.init call...
15351542
if (wantSuperInitCall) {
1543+
assert(ClassD != nullptr);
1544+
15361545
// Find a default initializer in the superclass.
15371546
if (Expr *SuperInitCall = constructCallToSuperInit(ctor, ClassD)) {
15381547
// If the initializer we found is a designated initializer, we're okay.

lib/Sema/TypeChecker.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1095,7 +1095,7 @@ class TypeChecker final : public LazyResolver {
10951095
void introduceLazyVarAccessors(VarDecl *var) override;
10961096

10971097
// Not all protocol members are requirements.
1098-
bool isRequirement(ValueDecl *requirement);
1098+
bool isRequirement(const ValueDecl *requirement);
10991099

11001100
/// Infer default value witnesses for all requirements in the given protocol.
11011101
void inferDefaultWitnesses(ProtocolDecl *proto);
@@ -1943,6 +1943,8 @@ class TypeChecker final : public LazyResolver {
19431943
bool diagnoseInlineableDeclRef(SourceLoc loc, const ValueDecl *D,
19441944
const DeclContext *DC);
19451945

1946+
void diagnoseResilientValueConstructor(ConstructorDecl *ctor);
1947+
19461948
/// \name Availability checking
19471949
///
19481950
/// Routines that perform API availability checking and type checking of

stdlib/public/core/BridgeObjectiveC.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,6 @@ public func == <Pointee>(
527527
return Bool(Builtin.cmp_eq_RawPointer(lhs._rawValue, rhs._rawValue))
528528
}
529529

530-
@_fixed_layout
531530
internal struct _CocoaFastEnumerationStackBuf {
532531
// Clang uses 16 pointers. So do we.
533532
internal var _item0: UnsafeRawPointer?

test/IRGen/class_resilience.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1-
// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -I %S/../Inputs -enable-source-import -emit-ir -enable-resilience -enable-class-resilience %s | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-runtime
2-
// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -I %S/../Inputs -enable-source-import -emit-ir -enable-resilience -enable-class-resilience -O %s
1+
// RUN: rm -rf %t && mkdir %t
2+
// RUN: %target-swift-frontend -emit-module -enable-resilience -enable-class-resilience -emit-module-path=%t/resilient_struct.swiftmodule -module-name=resilient_struct %S/../Inputs/resilient_struct.swift
3+
// RUN: %target-swift-frontend -emit-module -enable-resilience -enable-class-resilience -emit-module-path=%t/resilient_enum.swiftmodule -module-name=resilient_enum -I %t %S/../Inputs/resilient_enum.swift
4+
// RUN: %target-swift-frontend -emit-module -enable-resilience -enable-class-resilience -emit-module-path=%t/resilient_class.swiftmodule -module-name=resilient_class -I %t %S/../Inputs/resilient_class.swift
5+
// RUN: %target-swift-frontend -I %t -emit-ir -enable-resilience -enable-class-resilience %s | %FileCheck %s
6+
// RUN: %target-swift-frontend -I %t -emit-ir -enable-resilience -enable-class-resilience -O %s
37

48
// CHECK: %swift.type = type { [[INT:i32|i64]] }
59

test/IRGen/class_resilience_objc.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -enable-source-import -emit-ir -o - -primary-file %s | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize
1+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-ir -o - -primary-file %s | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize
22

33
// REQUIRES: objc_interop
44
// XFAIL: CPU=armv7k

test/IRGen/class_resilience_objc_armv7k.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -enable-source-import -emit-ir -o - -primary-file %s | %FileCheck %s --check-prefix=CHECK
1+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-ir -o - -primary-file %s | %FileCheck %s --check-prefix=CHECK
22

33
// REQUIRES: objc_interop
44
// REQUIRES: CPU=armv7k

test/IRGen/enum_resilience.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1-
// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -I %S/../Inputs -enable-source-import -emit-ir -enable-resilience %s | %FileCheck %s
2-
// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -I %S/../Inputs -enable-source-import -emit-ir -enable-resilience -O %s
1+
// RUN: rm -rf %t && mkdir %t
2+
// RUN: %target-swift-frontend -emit-module -enable-resilience -emit-module-path=%t/resilient_struct.swiftmodule -module-name=resilient_struct %S/../Inputs/resilient_struct.swift
3+
// RUN: %target-swift-frontend -emit-module -enable-resilience -emit-module-path=%t/resilient_enum.swiftmodule -module-name=resilient_enum -I %t %S/../Inputs/resilient_enum.swift
4+
// RUN: %target-swift-frontend -I %t -emit-ir -enable-resilience %s | %FileCheck %s
5+
// RUN: %target-swift-frontend -I %t -emit-ir -enable-resilience -O %s
36

47
import resilient_enum
58
import resilient_struct

test/IRGen/protocol_resilience.sil

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -I %S/../Inputs -enable-source-import -emit-ir -enable-resilience %s | %FileCheck %s
2-
// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -I %S/../Inputs -enable-source-import -emit-ir -enable-resilience -O %s
1+
// RUN: rm -rf %t && mkdir %t
2+
// RUN: %target-swift-frontend -emit-module -enable-resilience -emit-module-path=%t/resilient_protocol.swiftmodule -module-name=resilient_protocol %S/../Inputs/resilient_protocol.swift
3+
// RUN: %target-swift-frontend -I %t -emit-ir -enable-resilience -assume-parsing-unqualified-ownership-sil %s | %FileCheck %s
4+
// RUN: %target-swift-frontend -I %t -emit-ir -enable-resilience -O -assume-parsing-unqualified-ownership-sil %s
35

46
sil_stage canonical
57

test/IRGen/struct_resilience.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1-
// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -I %S/../Inputs -enable-source-import -emit-ir -enable-resilience %s | %FileCheck %s
2-
// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -I %S/../Inputs -enable-source-import -emit-ir -enable-resilience -O %s
1+
// RUN: rm -rf %t && mkdir %t
2+
// RUN: %target-swift-frontend -emit-module -enable-resilience -emit-module-path=%t/resilient_struct.swiftmodule -module-name=resilient_struct %S/../Inputs/resilient_struct.swift
3+
// RUN: %target-swift-frontend -emit-module -enable-resilience -emit-module-path=%t/resilient_enum.swiftmodule -module-name=resilient_enum -I %t %S/../Inputs/resilient_enum.swift
4+
// RUN: %target-swift-frontend -I %t -emit-ir -enable-resilience %s | %FileCheck %s
5+
// RUN: %target-swift-frontend -I %t -emit-ir -enable-resilience -O %s
36

47
import resilient_struct
58
import resilient_enum

test/SILGen/class_resilience.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
// RUN: %target-swift-frontend -I %S/../Inputs -enable-source-import -emit-silgen -enable-resilience %s | %FileCheck %s
1+
// RUN: rm -rf %t && mkdir %t
2+
// RUN: %target-swift-frontend -emit-module -enable-resilience -emit-module-path=%t/resilient_struct.swiftmodule -module-name=resilient_struct %S/../Inputs/resilient_struct.swift
3+
// RUN: %target-swift-frontend -emit-module -enable-resilience -emit-module-path=%t/resilient_class.swiftmodule -module-name=resilient_class -I %t %S/../Inputs/resilient_class.swift
4+
// RUN: %target-swift-frontend -I %t -emit-silgen -enable-resilience %s | %FileCheck %s
25

36
import resilient_class
47

test/SILGen/enum_resilience.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
// RUN: %target-swift-frontend -I %S/../Inputs -enable-source-import -emit-silgen -enable-resilience %s | %FileCheck %s
1+
// RUN: rm -rf %t && mkdir %t
2+
// RUN: %target-swift-frontend -emit-module -enable-resilience -emit-module-path=%t/resilient_struct.swiftmodule -module-name=resilient_struct %S/../Inputs/resilient_struct.swift
3+
// RUN: %target-swift-frontend -emit-module -enable-resilience -emit-module-path=%t/resilient_enum.swiftmodule -module-name=resilient_enum -I %t %S/../Inputs/resilient_enum.swift
4+
// RUN: %target-swift-frontend -I %t -emit-silgen -enable-resilience %s | %FileCheck %s
25

36
import resilient_enum
47

test/SILGen/global_resilience.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
// RUN: %target-swift-frontend -I %S/../Inputs -emit-silgen -enable-source-import -parse-as-library -enable-resilience %s | %FileCheck %s
2-
// RUN: %target-swift-frontend -I %S/../Inputs -emit-sil -enable-source-import -parse-as-library -enable-resilience %s -O | %FileCheck --check-prefix=CHECK-OPT %s
1+
// RUN: rm -rf %t && mkdir %t
2+
// RUN: %target-swift-frontend -emit-module -enable-resilience -emit-module-path=%t/resilient_global.swiftmodule -module-name=resilient_global %S/../Inputs/resilient_global.swift
3+
// RUN: %target-swift-frontend -I %t -emit-silgen -enable-resilience -parse-as-library %s | %FileCheck %s
4+
// RUN: %target-swift-frontend -I %t -emit-sil -O -enable-resilience -parse-as-library %s | %FileCheck --check-prefix=CHECK-OPT %s
35

46
import resilient_global
57

test/SILGen/protocol_resilience.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
// RUN: %target-swift-frontend -I %S/../Inputs -enable-source-import -emit-silgen -enable-resilience %s | %FileCheck %s --check-prefix=CHECK
1+
// RUN: rm -rf %t && mkdir %t
2+
// RUN: %target-swift-frontend -emit-module -enable-resilience -emit-module-path=%t/resilient_protocol.swiftmodule -module-name=resilient_protocol %S/../Inputs/resilient_protocol.swift
3+
// RUN: %target-swift-frontend -I %t -emit-silgen -enable-resilience %s | %FileCheck %s
24

35
import resilient_protocol
46

test/SILGen/struct_resilience.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
// RUN: %target-swift-frontend -I %S/../Inputs -enable-source-import -emit-silgen -enable-resilience %s | %FileCheck %s
1+
// RUN: rm -rf %t && mkdir %t
2+
// RUN: %target-swift-frontend -emit-module -enable-resilience -emit-module-path=%t/resilient_struct.swiftmodule -module-name=resilient_struct %S/../Inputs/resilient_struct.swift
3+
// RUN: %target-swift-frontend -I %t -emit-silgen -enable-resilience %s | %FileCheck %s
24

35
import resilient_struct
46

test/attr/attr_fixed_layout.swift

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// RUN: %target-swift-frontend -typecheck -dump-ast -enable-resilience %s 2>&1 | %FileCheck --check-prefix=RESILIENCE-ON %s
2-
// RUN: %target-swift-frontend -typecheck -dump-ast %s 2>&1 | %FileCheck --check-prefix=RESILIENCE-OFF %s
1+
// RUN: %target-swift-frontend -typecheck -verify -dump-ast -enable-resilience %s 2>&1 | %FileCheck --check-prefix=RESILIENCE-ON %s
2+
// RUN: %target-swift-frontend -typecheck -verify -dump-ast %s 2>&1 | %FileCheck --check-prefix=RESILIENCE-OFF %s
33

44
//
55
// Public types with @_fixed_layout are always fixed layout
@@ -45,3 +45,16 @@ struct Rectangle {
4545
let topLeft: Point
4646
let bottomRight: Size
4747
}
48+
49+
//
50+
// Diagnostics
51+
//
52+
53+
@_fixed_layout struct InternalStruct {}
54+
// expected-error@-1 {{'@_fixed_layout' attribute can only be applied to '@_versioned' or public declarations, but 'InternalStruct' is internal}}
55+
56+
@_fixed_layout fileprivate struct FileprivateStruct {}
57+
// expected-error@-1 {{'@_fixed_layout' attribute can only be applied to '@_versioned' or public declarations, but 'FileprivateStruct' is fileprivate}}
58+
59+
@_fixed_layout private struct PrivateStruct {}
60+
// expected-error@-1 {{'@_fixed_layout' attribute can only be applied to '@_versioned' or public declarations, but 'PrivateStruct' is private}}

0 commit comments

Comments
 (0)