Skip to content

Commit fa82965

Browse files
theblixguyCodaFi
authored andcommitted
[CSApply] Fix an issue with the @objc selector fix-it incorrectly being applied (#20949)
Special-case the diagnostic for members of non-@objc protocols that are referenced in #selector expressions.
1 parent b29e192 commit fa82965

File tree

3 files changed

+31
-0
lines changed

3 files changed

+31
-0
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,9 @@ ERROR(expr_selector_property_not_settable,none,
550550
(DescriptiveDeclKind, DeclName))
551551
ERROR(expr_selector_property_setter_inaccessible,none,
552552
"setter of %0 %1 is inaccessible", (DescriptiveDeclKind, DeclName))
553+
ERROR(expr_selector_cannot_be_used,none,
554+
"cannot use %0 as a selector because protocol %1 is not exposed to Objective-C",
555+
(DeclBaseName, DeclName))
553556
ERROR(expr_selector_not_objc,none,
554557
"argument of '#selector' refers to %0 %1 that is not exposed to "
555558
"Objective-C",

lib/Sema/CSApply.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4178,6 +4178,17 @@ namespace {
41784178
// The declaration we found must be exposed to Objective-C.
41794179
tc.validateDecl(method);
41804180
if (!method->isObjC()) {
4181+
// If the method declaration lies in a protocol and we're providing
4182+
// a default implementation of the method through a protocol extension
4183+
// and using it as a selector, then bail out as adding @objc to the
4184+
// protocol might not be the right thing to do and could lead to
4185+
// problems.
4186+
if (auto protocolDecl = dyn_cast<ProtocolDecl>(foundDecl->getDeclContext())) {
4187+
tc.diagnose(E->getLoc(), diag::expr_selector_cannot_be_used,
4188+
foundDecl->getBaseName(), protocolDecl->getFullName());
4189+
return E;
4190+
}
4191+
41814192
tc.diagnose(E->getLoc(), diag::expr_selector_not_objc,
41824193
foundDecl->getDescriptiveKind(), foundDecl->getFullName())
41834194
.highlight(subExpr->getSourceRange());

test/expr/primary/selector/selector.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,3 +144,20 @@ case #selector(SR1827.bar)?:
144144
default:
145145
break
146146
}
147+
148+
// SR-9391
149+
150+
protocol SomeProtocol {
151+
func someFunction()
152+
func anotherFunction()
153+
}
154+
155+
extension SomeProtocol {
156+
func someFunction() {
157+
let _ = #selector(anotherFunction) // expected-error {{cannot use 'anotherFunction' as a selector because protocol 'SomeProtocol' is not exposed to Objective-C}} {{none}}
158+
}
159+
160+
func anotherFunction() {
161+
print("Hello world!")
162+
}
163+
}

0 commit comments

Comments
 (0)