Skip to content

Commit 59df509

Browse files
committed
[Sema] Improve diagnostics for #selector() expressions
When the `#selector()` expression refers to a parameter or variable, we don't want to call it a property. Fixes the rest of SR-880.
1 parent 502b159 commit 59df509

File tree

3 files changed

+24
-7
lines changed

3 files changed

+24
-7
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -367,8 +367,8 @@ ERROR(expr_selector_module_missing,none,
367367
"import the 'ObjectiveC' module to use '#selector'", ())
368368
ERROR(expr_selector_no_declaration,none,
369369
"argument of '#selector' does not refer to an initializer or method", ())
370-
ERROR(expr_selector_property,none,
371-
"argument of '#selector' cannot refer to a property", ())
370+
ERROR(expr_selector_var,none,
371+
"argument of '#selector' cannot refer to a %select{property|parameter|variable}0", (int))
372372
ERROR(expr_selector_not_method_or_init,none,
373373
"argument of '#selector' does not refer to a method or initializer", ())
374374
ERROR(expr_selector_not_objc,none,

lib/Sema/CSApply.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3342,11 +3342,20 @@ namespace {
33423342
// complain.
33433343
auto func = dyn_cast<AbstractFunctionDecl>(foundDecl);
33443344
if (!func) {
3345-
tc.diagnose(E->getLoc(),
3346-
isa<VarDecl>(foundDecl)
3347-
? diag::expr_selector_property
3348-
: diag::expr_selector_not_method_or_init)
3349-
.highlight(subExpr->getSourceRange());
3345+
Optional<InFlightDiagnostic> diag;
3346+
if (auto VD = dyn_cast<VarDecl>(foundDecl)) {
3347+
diag.emplace(tc.diagnose(E->getLoc(), diag::expr_selector_var,
3348+
isa<ParamDecl>(VD)
3349+
? 1
3350+
: VD->getDeclContext()->isTypeContext()
3351+
? 0
3352+
: 2));
3353+
} else {
3354+
diag.emplace(tc.diagnose(E->getLoc(),
3355+
diag::expr_selector_not_method_or_init));
3356+
}
3357+
diag->highlight(subExpr->getSourceRange());
3358+
diag.reset();
33503359
tc.diagnose(foundDecl, diag::decl_declared_here,
33513360
foundDecl->getFullName());
33523361
return E;

test/expr/unary/selector/selector.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ class C1 {
2626
_ = testUnqualifiedSelector // suppress unused warning
2727
}
2828

29+
@objc func testParam(testParam: A) { // expected-note{{'testParam' declared here}}
30+
_ = #selector(testParam) // expected-error{{argument of '#selector' cannot refer to a parameter}}
31+
}
32+
33+
@objc func testVariable() {
34+
let testVariable = 1 // expected-note{{'testVariable' declared here}}
35+
_ = #selector(testVariable) // expected-error{{argument of '#selector' cannot refer to a variable}}
36+
}
2937
}
3038

3139
@objc protocol P1 {

0 commit comments

Comments
 (0)