Skip to content

Commit 9599228

Browse files
committed
[5.1] Diagnostic: dynamic replacement and replaced function's @objc attribute must match
rdar://48259565
1 parent 3307685 commit 9599228

File tree

3 files changed

+43
-1
lines changed

3 files changed

+43
-1
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3924,6 +3924,10 @@ ERROR(dynamic_replacement_not_in_extension, none,
39243924
"dynamicReplacement(for:) of %0 is not defined in an extension or at the file level", (DeclName))
39253925
ERROR(dynamic_replacement_must_not_be_dynamic, none,
39263926
"dynamicReplacement(for:) of %0 must not be dynamic itself", (DeclName))
3927+
ERROR(dynamic_replacement_replaced_not_objc_dynamic, none,
3928+
"%0 is not marked @objc dynamic", (DeclName))
3929+
ERROR(dynamic_replacement_replacement_not_objc_dynamic, none,
3930+
"%0 is marked @objc dynamic", (DeclName))
39273931

39283932
//------------------------------------------------------------------------------
39293933
// MARK: @available

lib/Sema/TypeCheckAttr.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2288,7 +2288,23 @@ void TypeChecker::checkDynamicReplacementAttribute(ValueDecl *D) {
22882288
if (auto *attr = replacements[index]
22892289
->getAttrs()
22902290
.getAttribute<DynamicReplacementAttr>()) {
2291-
attr->setReplacedFunction(origs[index]);
2291+
auto *replacedFun = origs[index];
2292+
auto *replacement = replacements[index];
2293+
if (replacedFun->isObjC() && !replacement->isObjC()) {
2294+
diagnose(attr->getLocation(),
2295+
diag::dynamic_replacement_replacement_not_objc_dynamic,
2296+
attr->getReplacedFunctionName());
2297+
attr->setInvalid();
2298+
return;
2299+
}
2300+
if (!replacedFun->isObjC() && replacement->isObjC()) {
2301+
diagnose(attr->getLocation(),
2302+
diag::dynamic_replacement_replaced_not_objc_dynamic,
2303+
attr->getReplacedFunctionName());
2304+
attr->setInvalid();
2305+
return;
2306+
}
2307+
attr->setReplacedFunction(replacedFun);
22922308
continue;
22932309
}
22942310
auto *newAttr = DynamicReplacementAttr::create(
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// RUN: %target-typecheck-verify-swift -swift-version 5
2+
//
3+
// REQUIRES: objc_interop
4+
5+
class Object {
6+
@objc dynamic func method(){
7+
}
8+
9+
dynamic func nativeMethod() {
10+
}
11+
}
12+
13+
extension Object {
14+
@_dynamicReplacement(for: method()) // expected-error{{'method()' is marked @objc dynamic}}
15+
func replacement() {
16+
}
17+
18+
@_dynamicReplacement(for: nativeMethod()) // expected-error{{'nativeMethod()' is not marked @objc dynamic}}
19+
@objc dynamic func replacement2() {
20+
}
21+
22+
}

0 commit comments

Comments
 (0)