Skip to content

Commit 1980c4a

Browse files
committed
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 d878aed commit 1980c4a

6 files changed

+51
-1
lines changed

Diff for: include/swift/AST/DiagnosticsSema.def

+5
Original file line numberDiff line numberDiff line change
@@ -3985,6 +3985,11 @@ ERROR(dynamic_with_transparent,none,
39853985
"a declaration cannot be both '@_tranparent' and 'dynamic'",
39863986
())
39873987

3988+
ERROR(dynamic_and_library_evolution_not_supported,none,
3989+
"a native Swift declaration cannot be marked 'dynamic' in library evolution mode",
3990+
())
3991+
3992+
39883993
//------------------------------------------------------------------------------
39893994
// MARK: @_dynamicReplacement(for:)
39903995
//------------------------------------------------------------------------------

Diff for: include/swift/Basic/LangOptions.h

+4
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,10 @@ namespace swift {
305305
/// set to true.
306306
bool ExperimentalDependenciesIncludeIntrafileOnes = false;
307307

308+
/// We disallow explicit dynamic on native swift declarations in
309+
/// library-evolution-mode for now because the ABI is not fully baked.
310+
bool DisallowDynamicOnNativeSwiftDeclarations = false;
311+
308312
/// Sets the target we are building for and updates platform conditions
309313
/// to match.
310314
///

Diff for: lib/Frontend/CompilerInvocation.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,10 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
261261
Opts.EnableOpaqueResultTypes |=
262262
Args.hasArg(OPT_enable_opaque_result_types);
263263

264+
// We don't allow dynamic on native swift declarations.
265+
Opts.DisallowDynamicOnNativeSwiftDeclarations |=
266+
Args.hasArg(OPT_enable_library_evolution);
267+
264268
// Always enable operator designated types for the standard library.
265269
Opts.EnableOperatorDesignatedTypes |= FrontendOpts.ParseStdlib;
266270

Diff for: lib/Sema/TypeCheckAttr.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -333,9 +333,12 @@ void AttributeEarlyChecker::visitDynamicAttr(DynamicAttr *attr) {
333333
// Members cannot be both dynamic and @_transparent.
334334
if (D->getAttrs().hasAttribute<TransparentAttr>())
335335
diagnoseAndRemoveAttr(attr, diag::dynamic_with_transparent);
336+
if (!D->getAttrs().hasAttribute<ObjCAttr>()&&
337+
TC.getLangOpts().DisallowDynamicOnNativeSwiftDeclarations)
338+
diagnoseAndRemoveAttr(attr,
339+
diag::dynamic_and_library_evolution_not_supported);
336340
}
337341

338-
339342
void AttributeEarlyChecker::visitIBActionAttr(IBActionAttr *attr) {
340343
// Only instance methods can be IBActions.
341344
const FuncDecl *FD = cast<FuncDecl>(D);

Diff for: test/attr/dynamicReplacement_library_evolution.swift

+17
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-library-evolution -I %t
3+
4+
struct Container {
5+
dynamic var property: Int { return 1 } // expected-error{{a native Swift declaration cannot be marked 'dynamic' in library evolution mode}}
6+
dynamic func foo() {} // expected-error{{a native Swift declaration cannot be marked 'dynamic' in library evolution mode}}
7+
}
8+
9+
class AClass {
10+
dynamic var property: Int { return 1 } // expected-error{{a native Swift declaration cannot be marked 'dynamic' in library evolution mode}}
11+
dynamic func foo() {} // expected-error{{a native Swift declaration cannot be marked 'dynamic' in library evolution mode}}
12+
13+
@objc dynamic func allowed() {}
14+
15+
16+
@objc dynamic var allowedProperty : Int { return 1}
17+
}
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-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)