Skip to content

Commit f85cb50

Browse files
committed
[Sema] Add diagnostics handling for nested expressions
1 parent c3ab99a commit f85cb50

File tree

2 files changed

+51
-15
lines changed

2 files changed

+51
-15
lines changed

lib/Sema/MiscDiagnostics.cpp

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2888,21 +2888,27 @@ VarDeclUsageChecker::~VarDeclUsageChecker() {
28882888

28892889
// If the subexpr is an "as?" cast, we can rewrite it to
28902890
// be an "is" test.
2891-
bool isIsTest = false;
2892-
if (isa<ConditionalCheckedCastExpr>(initExpr) &&
2893-
!initExpr->isImplicit()) {
2894-
noParens = isIsTest = true;
2891+
ConditionalCheckedCastExpr *CCE = nullptr;
2892+
2893+
// initExpr can be wrapped inside parens or try expressions.
2894+
if (auto ccExpr = dyn_cast<ConditionalCheckedCastExpr>(
2895+
initExpr->getValueProvidingExpr())) {
2896+
if (!ccExpr->isImplicit()) {
2897+
CCE = ccExpr;
2898+
noParens = true;
2899+
}
28952900
}
2901+
28962902
// In cases where the value is optional, the cast expr is
28972903
// wrapped inside OptionalEvaluationExpr. Unwrap it to get
28982904
// ConditionalCheckedCastExpr.
2899-
if (auto oeExpr =
2900-
dyn_cast<OptionalEvaluationExpr>(initExpr)) {
2905+
if (auto oeExpr = dyn_cast<OptionalEvaluationExpr>(
2906+
initExpr->getValueProvidingExpr())) {
29012907
if (auto ccExpr = dyn_cast<ConditionalCheckedCastExpr>(
2902-
oeExpr->getSubExpr())) {
2908+
oeExpr->getSubExpr()->getValueProvidingExpr())) {
29032909
if (!ccExpr->isImplicit()) {
2904-
initExpr = ccExpr;
2905-
noParens = isIsTest = true;
2910+
CCE = ccExpr;
2911+
noParens = true;
29062912
}
29072913
}
29082914
}
@@ -2914,10 +2920,9 @@ VarDeclUsageChecker::~VarDeclUsageChecker() {
29142920
diagIF.fixItReplaceChars(introducerLoc,
29152921
initExpr->getStartLoc(),
29162922
&"("[noParens]);
2917-
2918-
if (isIsTest) {
2923+
2924+
if (CCE) {
29192925
// If this was an "x as? T" check, rewrite it to "x is T".
2920-
auto CCE = cast<ConditionalCheckedCastExpr>(initExpr);
29212926
diagIF.fixItReplace(SourceRange(CCE->getLoc(),
29222927
CCE->getQuestionLoc()),
29232928
"is");

test/decl/var/usage.swift

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -332,11 +332,42 @@ func test(_ a : Int?, b : Any) {
332332

333333
// SR-14646. Special case, turn this into an 'is' test with optional value.
334334
let bb: Any? = 3
335-
if let bbb = bb as? Int { // expected-warning {{value 'bbb' was defined but never used; consider replacing with boolean test}} {{6-16=}} {{19-22=is}}
336-
}
335+
if let bbb = bb as? Int {} // expected-warning {{value 'bbb' was defined but never used; consider replacing with boolean test}} {{6-16=}} {{19-22=is}}
336+
if let bbb = (bb) as? Int {} // expected-warning {{value 'bbb' was defined but never used; consider replacing with boolean test}} {{6-16=}} {{21-24=is}}
337+
338+
func aa() -> Any? { return 1 }
339+
if let aaa = aa() as? Int {} // expected-warning {{value 'aaa' was defined but never used; consider replacing with boolean test}} {{6-16=}} {{21-24=is}}
340+
if let aaa = (aa()) as? Int {} // expected-warning {{value 'aaa' was defined but never used; consider replacing with boolean test}} {{6-16=}} {{23-26=is}}
341+
342+
func bb() -> Any { return 1 }
343+
if let aaa = aa() as? Int {} // expected-warning {{value 'aaa' was defined but never used; consider replacing with boolean test}} {{6-16=}} {{21-24=is}}
344+
if let aaa = (aa()) as? Int {} // expected-warning {{value 'aaa' was defined but never used; consider replacing with boolean test}} {{6-16=}} {{23-26=is}}
337345

338-
// SR-1112
339346

347+
func throwingAA() throws -> Any? { return 1 }
348+
do {
349+
if let aaa = try! throwingAA() as? Int {} // expected-warning {{value 'aaa' was defined but never used; consider replacing with boolean test}} {{8-18=}} {{36-39=is}}
350+
if let aaa = (try! throwingAA()) as? Int {} // expected-warning {{value 'aaa' was defined but never used; consider replacing with boolean test}} {{8-18=}} {{38-41=is}}
351+
if let aaa = try throwingAA() as? Int {} // expected-warning {{value 'aaa' was defined but never used; consider replacing with boolean test}} {{8-18=}} {{35-38=is}}
352+
if let aaa = (try throwingAA()) as? Int {} // expected-warning {{value 'aaa' was defined but never used; consider replacing with boolean test}} {{8-18=}} {{37-40=is}}
353+
} catch { }
354+
if let aaa = try? throwingAA() as? Int {} // expected-warning {{value 'aaa' was defined but never used; consider replacing with boolean test}} {{6-16=(}} {{41-41=) != nil}}
355+
if let aaa = (try? throwingAA()) as? Int {} // expected-warning {{value 'aaa' was defined but never used; consider replacing with boolean test}} {{6-16=}} {{36-39=is}}
356+
357+
func throwingBB() throws -> Any { return 1 }
358+
do {
359+
if let bbb = try! throwingBB() as? Int {} // expected-warning {{value 'bbb' was defined but never used; consider replacing with boolean test}} {{8-18=}} {{36-39=is}}
360+
if let bbb = (try! throwingBB()) as? Int {} // expected-warning {{value 'bbb' was defined but never used; consider replacing with boolean test}} {{8-18=}} {{38-41=is}}
361+
if let bbb = try throwingBB() as? Int {} // expected-warning {{value 'bbb' was defined but never used; consider replacing with boolean test}} {{8-18=}} {{35-38=is}}
362+
if let bbb = (try throwingBB()) as? Int {} // expected-warning {{value 'bbb' was defined but never used; consider replacing with boolean test}} {{8-18=}} {{37-40=is}}
363+
} catch { }
364+
if let bbb = try? throwingBB() as? Int {} // expected-warning {{value 'bbb' was defined but never used; consider replacing with boolean test}} {{6-16=(}} {{41-41=) != nil}}
365+
if let bbb = (try? throwingBB()) as? Int {} // expected-warning {{value 'bbb' was defined but never used; consider replacing with boolean test}} {{6-16=}} {{36-39=is}}
366+
367+
let cc: (Any?, Any) = (1, 2)
368+
if let (cc1, cc2) = cc as? (Int, Int) {} // expected-warning {{immutable value 'cc1' was never used; consider replacing with '_' or removing it}} expected-warning {{immutable value 'cc2' was never used; consider replacing with '_' or removing it}}
369+
370+
// SR-1112
340371
let xxx: Int? = 0
341372

342373
if let yyy = xxx { } // expected-warning{{with boolean test}} {{6-16=}} {{19-19= != nil}}

0 commit comments

Comments
 (0)