Skip to content

Commit 2202356

Browse files
committed
[5.1] Disallow dynamic on native Swift declarations under library-evolution mode
The current ABI of dynamic is not what we want for certain declarations. e.g dynamic var x : Int { willset { } } Is exposed in the .swiftinterface file as dynamic var x : Int { get {} set {} } However, the actual implementation is marking the willSet only dynamic. var x : Int { dynamic willSet() {} get {} set {} } To be able to rely on `dynamic` in the future we disable dynamic (for non-@objc) under library-evolution for now until we have made sure that the ABI is proper. rdar://51678074
1 parent c596a26 commit 2202356

File tree

4 files changed

+43
-1
lines changed

4 files changed

+43
-1
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3963,6 +3963,11 @@ ERROR(dynamic_with_transparent,none,
39633963
"a declaration cannot be both '@_tranparent' and 'dynamic'",
39643964
())
39653965

3966+
ERROR(dynamic_and_library_evolution_not_supported,none,
3967+
"marking non-'@objc' Swift declaration 'dynamic' in library evolution mode is not supported",
3968+
())
3969+
3970+
39663971
//------------------------------------------------------------------------------
39673972
// MARK: @_dynamicReplacement(for:)
39683973
//------------------------------------------------------------------------------

lib/Sema/TypeCheckAttr.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,9 +337,12 @@ void AttributeEarlyChecker::visitDynamicAttr(DynamicAttr *attr) {
337337
// Members cannot be both dynamic and @_transparent.
338338
if (D->getAttrs().hasAttribute<TransparentAttr>())
339339
diagnoseAndRemoveAttr(attr, diag::dynamic_with_transparent);
340+
if (!D->getAttrs().hasAttribute<ObjCAttr>() &&
341+
D->getModuleContext()->isResilient())
342+
diagnoseAndRemoveAttr(attr,
343+
diag::dynamic_and_library_evolution_not_supported);
340344
}
341345

342-
343346
void AttributeEarlyChecker::visitIBActionAttr(IBActionAttr *attr) {
344347
// Only instance methods can be IBActions.
345348
const FuncDecl *FD = cast<FuncDecl>(D);
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-typecheck-verify-swift -swift-version 5 -enable-objc-interop -enable-library-evolution -I %t
3+
4+
struct Container {
5+
dynamic var property: Int { return 1 } // expected-error{{marking non-'@objc' Swift declaration 'dynamic' in library evolution mode is not supported}}
6+
dynamic func foo() {} // expected-error{{marking non-'@objc' Swift declaration 'dynamic' in library evolution mode is not supported}}
7+
}
8+
9+
class AClass {
10+
dynamic var property: Int { return 1 } // expected-error{{marking non-'@objc' Swift declaration 'dynamic' in library evolution mode is not supported}}
11+
dynamic func foo() {} // expected-error{{marking non-'@objc' Swift declaration 'dynamic' in library evolution mode is not supported}}
12+
13+
@objc dynamic func allowed() {}
14+
15+
16+
@objc dynamic var allowedProperty : Int { return 1}
17+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-typecheck-verify-swift -swift-version 5 -enable-objc-interop -enable-library-evolution -enable-implicit-dynamic -I %t
3+
4+
struct Container {
5+
var property: Int { return 1 }
6+
func foo() {}
7+
}
8+
9+
class AClass {
10+
var property: Int { return 1 }
11+
func foo() {}
12+
13+
@objc dynamic func allowed() {}
14+
15+
16+
@objc dynamic var allowedProperty : Int { return 1}
17+
}

0 commit comments

Comments
 (0)