Only warn about self capture in nested closures until Swift 6.

Swift has diagnosed implicit uses of class-reference `self` in
escaping closures for a long time as potentially leading to reference
cycles.  PR #35898 fixed a bug where we failed to diagnose this
condition in nested closures.  Unfortunately, treating this as an
error has proven problematic because there's a lot of code doing
it.  Requiring that code to be thoroughly stamped out before we
ship a compiler is just too much to ask.  Stage the fix in by
treating it as a warning in Swift versions prior to 6.

As with the non-nested case, this warning can be suppressed by
explicitly either capturing `self` or spelling out `self.` in the
access.

Fixes rdar://80847025.
This commit is contained in:
John McCall
2021-08-18 21:34:02 -04:00
parent 89847acd7a
commit 5eecc6ac07
5 changed files with 95 additions and 10 deletions

View File

@@ -1639,7 +1639,8 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
memberLoc = MRE->getLoc();
Diags.diagnose(memberLoc,
diag::property_use_in_closure_without_explicit_self,
baseName.getIdentifier());
baseName.getIdentifier())
.warnUntilSwiftVersionIf(Closures.size() > 1, 6);
}
// Handle method calls with a specific diagnostic + fixit.
@@ -1650,7 +1651,8 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
memberLoc = DSCE->getLoc();
Diags.diagnose(DSCE->getLoc(),
diag::method_call_in_closure_without_explicit_self,
MethodExpr->getDecl()->getBaseIdentifier());
MethodExpr->getDecl()->getBaseIdentifier())
.warnUntilSwiftVersionIf(Closures.size() > 1, 6);
}
if (memberLoc.isValid()) {
@@ -1660,7 +1662,8 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
// Catch any other implicit uses of self with a generic diagnostic.
if (isImplicitSelfParamUseLikelyToCauseCycle(E, ACE))
Diags.diagnose(E->getLoc(), diag::implicit_use_of_self_in_closure);
Diags.diagnose(E->getLoc(), diag::implicit_use_of_self_in_closure)
.warnUntilSwiftVersionIf(Closures.size() > 1, 6);
return { true, E };
}