Skip to content

Commit 7fdc849

Browse files
committed
[Diagnostics] Improve warning suggestion for var in for loop
When iterator consists of tuple of variable and iteration only mutates the tuple partially, improve the warning message from "changing to 'let" to "changing to 'case let'"
1 parent db6bc98 commit 7fdc849

File tree

3 files changed

+20
-4
lines changed

3 files changed

+20
-4
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7030,8 +7030,8 @@ WARNING(immutable_value_never_used_but_assigned, NoUsage,
70307030
(Identifier))
70317031
WARNING(variable_never_mutated, none,
70327032
"variable %0 was never mutated; "
7033-
"consider %select{removing 'var' to make it|changing to 'let'}1 constant",
7034-
(Identifier, bool))
7033+
"consider %select{removing 'var' to make it|changing to '%2'}1 constant",
7034+
(Identifier, bool, StringRef))
70357035
WARNING(variable_never_read, none,
70367036
"variable %0 was written to, but never read",
70377037
(Identifier))

lib/Sema/MiscDiagnostics.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4102,8 +4102,16 @@ VarDeclUsageChecker::~VarDeclUsageChecker() {
41024102

41034103
// If this is a parameter explicitly marked 'var', remove it.
41044104
if (FixItLoc.isInvalid()) {
4105+
bool suggestCaseLet = false;
4106+
if (auto *stmt = var->getRecursiveParentPatternStmt()) {
4107+
// Suggest 'var' -> 'case let' conversion
4108+
// in case of 'for' loop and invalid because it's
4109+
// tuple variable.
4110+
suggestCaseLet = isa<ForEachStmt>(stmt);
4111+
}
4112+
41054113
Diags.diagnose(var->getLoc(), diag::variable_never_mutated,
4106-
var->getName(), true);
4114+
var->getName(), true, suggestCaseLet ? "case let": "let");
41074115
}
41084116
else {
41094117
bool suggestLet = true;
@@ -4115,7 +4123,7 @@ VarDeclUsageChecker::~VarDeclUsageChecker() {
41154123
}
41164124

41174125
auto diag = Diags.diagnose(var->getLoc(), diag::variable_never_mutated,
4118-
var->getName(), suggestLet);
4126+
var->getName(), suggestLet, "let");
41194127

41204128
if (suggestLet)
41214129
diag.fixItReplace(FixItLoc, "let");

test/decl/var/usage.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,3 +563,11 @@ func testUselessCastWithInvalidParam(foo: Any?) -> Int {
563563
if let bar = foo as? Foo { return 42 } // expected-warning {{value 'bar' was defined but never used; consider replacing with boolean test}} {{6-16=}} {{20-23=is}}
564564
else { return 54 }
565565
}
566+
567+
// https://github.com/swiftlang/swift/issues/72811
568+
func testEnumeratedForLoop(a: [Int]) {
569+
for var (b, c) in a.enumerated() { // expected-warning {{variable 'b' was never mutated; consider changing to 'case let' constant}}
570+
c = b
571+
let _ = c
572+
}
573+
}

0 commit comments

Comments
 (0)