Skip to content

Commit e50af98

Browse files
Merge pull request #23790 from aschwaighofer/dynamic_replacement_final
Allow final on dynamic members
2 parents d36a739 + 90fe435 commit e50af98

File tree

7 files changed

+20
-10
lines changed

7 files changed

+20
-10
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3874,9 +3874,6 @@ ERROR(borrowed_on_objc_protocol_requirement,none,
38743874

38753875
ERROR(dynamic_not_in_class,none,
38763876
"only members of classes may be dynamic", ())
3877-
ERROR(dynamic_with_final,none,
3878-
"a declaration cannot be both 'final' and 'dynamic'",
3879-
())
38803877
ERROR(dynamic_with_nonobjc,none,
38813878
"a declaration cannot be both '@nonobjc' and 'dynamic'",
38823879
())

lib/Sema/TypeCheckAttr.cpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -323,10 +323,6 @@ void AttributeEarlyChecker::visitMutationAttr(DeclAttribute *attr) {
323323
}
324324

325325
void AttributeEarlyChecker::visitDynamicAttr(DynamicAttr *attr) {
326-
// Members cannot be both dynamic and final.
327-
if (D->getAttrs().hasAttribute<FinalAttr>())
328-
diagnoseAndRemoveAttr(attr, diag::dynamic_with_final);
329-
330326
// Members cannot be both dynamic and @nonobjc.
331327
if (D->getAttrs().hasAttribute<NonObjCAttr>())
332328
diagnoseAndRemoveAttr(attr, diag::dynamic_with_nonobjc);
@@ -2632,8 +2628,7 @@ void TypeChecker::addImplicitDynamicAttribute(Decl *D) {
26322628
isa<AccessorDecl>(D))
26332629
return;
26342630

2635-
if (D->getAttrs().hasAttribute<FinalAttr>() ||
2636-
D->getAttrs().hasAttribute<NonObjCAttr>() ||
2631+
if (D->getAttrs().hasAttribute<NonObjCAttr>() ||
26372632
D->getAttrs().hasAttribute<TransparentAttr>() ||
26382633
D->getAttrs().hasAttribute<InlinableAttr>())
26392634
return;

test/Interpreter/Inputs/dynamic_replacement_module.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ public class PublicClass {
1717
public dynamic func function() -> String {
1818
return "public_class_func"
1919
}
20+
public dynamic final func finalFunction() -> String {
21+
return "public_class_final_func"
22+
}
2023
public dynamic func genericFunction<T>(_ t: T.Type) -> String {
2124
return "public_class_generic_func"
2225
}
@@ -84,6 +87,11 @@ public class PublicClass {
8487
public func function() -> String {
8588
return "public_class_func"
8689
}
90+
91+
public final func finalFunction() -> String {
92+
return "public_class_final_func"
93+
}
94+
8795
public func genericFunction<T>(_ t: T.Type) -> String {
8896
return "public_class_generic_func"
8997
}
@@ -163,6 +171,10 @@ extension PublicClass {
163171
public func replacement_function() -> String {
164172
return "replacement of " + function()
165173
}
174+
@_dynamicReplacement(for: finalFunction())
175+
public func replacement_finalFunction() -> String {
176+
return "replacement of " + finalFunction()
177+
}
166178
@_dynamicReplacement(for: genericFunction(_:))
167179
public func replacement_genericFunction<T>(_ t: T.Type) -> String {
168180
return "replacement of " + genericFunction(t)

test/Interpreter/dynamic_replacement.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ func checkExpectedResults(forOriginalLibrary useOrig: Bool) {
8484

8585
expectTrue(PublicClass().function() ==
8686
expectedResult(useOrig, "public_class_func"))
87+
expectTrue(PublicClass().finalFunction() ==
88+
expectedResult(useOrig, "public_class_final_func"))
8789
expectTrue(PublicClass().genericFunction(Int.self) ==
8890
expectedResult(useOrig, "public_class_generic_func"))
8991

test/attr/Inputs/dynamicReplacementC.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@ public extension TheReplaceables {
1111
public class K {
1212
public init(i: Int) {}
1313
public convenience init(c : Int) { self.init(i : c) }
14+
public final func finalFunction() {}
1415
}

test/attr/attr_dynamic.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class Foo {
3434

3535
func notDynamic() {}
3636

37-
@objc final dynamic func indecisive() {} // expected-error{{a declaration cannot be both 'final' and 'dynamic'}} {{15-23=}}
37+
@objc final dynamic func indecisive() {}
3838
}
3939

4040
struct Bar {

test/attr/dynamicReplacement.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ extension K {
4545

4646
@_dynamicReplacement(for: init(c:)) // expected-error{{replaced constructor 'init(c:)' is marked as convenience}})
4747
init(rc: Int) { }
48+
49+
@_dynamicReplacement(for:finalFunction())
50+
func replacement_finalFunction() {}
4851
}
4952

5053
extension undeclared { // expected-error{{use of undeclared type 'undeclared'}}

0 commit comments

Comments
 (0)