Skip to content

Commit 315f47d

Browse files
committed
Diagnostic: dynamic replacement and replaced function's @objc attribute must match
rdar://48259565
1 parent 82c33dc commit 315f47d

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
@@ -3921,6 +3921,10 @@ ERROR(dynamic_replacement_not_in_extension, none,
39213921
"dynamicReplacement(for:) of %0 is not defined in an extension or at the file level", (DeclName))
39223922
ERROR(dynamic_replacement_must_not_be_dynamic, none,
39233923
"dynamicReplacement(for:) of %0 must not be dynamic itself", (DeclName))
3924+
ERROR(dynamic_replacement_replaced_not_objc_dynamic, none,
3925+
"%0 is not marked @objc dynamic", (DeclName))
3926+
ERROR(dynamic_replacement_replacement_not_objc_dynamic, none,
3927+
"%0 is marked @objc dynamic", (DeclName))
39243928

39253929
//------------------------------------------------------------------------------
39263930
// MARK: @available

lib/Sema/TypeCheckAttr.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2229,7 +2229,23 @@ void TypeChecker::checkDynamicReplacementAttribute(ValueDecl *D) {
22292229
if (auto *attr = replacements[index]
22302230
->getAttrs()
22312231
.getAttribute<DynamicReplacementAttr>()) {
2232-
attr->setReplacedFunction(origs[index]);
2232+
auto *replacedFun = origs[index];
2233+
auto *replacement = replacements[index];
2234+
if (replacedFun->isObjC() && !replacement->isObjC()) {
2235+
diagnose(attr->getLocation(),
2236+
diag::dynamic_replacement_replacement_not_objc_dynamic,
2237+
attr->getReplacedFunctionName());
2238+
attr->setInvalid();
2239+
return;
2240+
}
2241+
if (!replacedFun->isObjC() && replacement->isObjC()) {
2242+
diagnose(attr->getLocation(),
2243+
diag::dynamic_replacement_replaced_not_objc_dynamic,
2244+
attr->getReplacedFunctionName());
2245+
attr->setInvalid();
2246+
return;
2247+
}
2248+
attr->setReplacedFunction(replacedFun);
22332249
continue;
22342250
}
22352251
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)