From 1649b5ec45ef1f08fbdcdb923aa95ac831a99911 Mon Sep 17 00:00:00 2001 From: Pavel Yaskevich Date: Mon, 24 Feb 2025 18:03:35 -0800 Subject: [PATCH 1/2] [Concurrency] Avoid dowgrading diagnostics multiple times Unify `warn` + `limitBehavior` into a single call to make sure that diagnostic doesn't get downgraded multiple times because that could affect how diagnostics are tracked. --- lib/Sema/TypeCheckAvailability.cpp | 7 ++++-- lib/Sema/TypeCheckConcurrency.cpp | 39 +++++++++++++++++------------- 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/lib/Sema/TypeCheckAvailability.cpp b/lib/Sema/TypeCheckAvailability.cpp index d40670b627c4c..e58ae673d8afc 100644 --- a/lib/Sema/TypeCheckAvailability.cpp +++ b/lib/Sema/TypeCheckAvailability.cpp @@ -2337,8 +2337,11 @@ diagnosePotentialUnavailability(const RootProtocolConformance *rootConf, ctx.getTargetPlatformStringForDiagnostics(), availability.getRawMinimumVersion()); - err.warnUntilSwiftVersion(6); - err.limitBehavior(behaviorLimitForExplicitUnavailability(rootConf, dc)); + auto behaviorLimit = behaviorLimitForExplicitUnavailability(rootConf, dc); + if (behaviorLimit >= DiagnosticBehavior::Warning) + err.limitBehavior(behaviorLimit); + else + err.warnUntilSwiftVersion(6); // Direct a fixit to the error if an existing guard is nearly-correct if (fixAvailabilityByNarrowingNearbyVersionCheck(loc, dc, availability, ctx, diff --git a/lib/Sema/TypeCheckConcurrency.cpp b/lib/Sema/TypeCheckConcurrency.cpp index 084196654c246..b989ce887f1ce 100644 --- a/lib/Sema/TypeCheckConcurrency.cpp +++ b/lib/Sema/TypeCheckConcurrency.cpp @@ -4853,14 +4853,12 @@ getIsolationFromAttributes(const Decl *decl, bool shouldDiagnose = true, bool isUnsafe = attr->isArgUnsafe(); if (attr->hasArgs()) { if (isUnsafe) { - bool inSwiftinterface = decl->getDeclContext()->isInSwiftinterface(); - ctx.Diags.diagnose( - attr->getLocation(), - diag::unsafe_global_actor) - .fixItRemove(attr->getArgs()->getSourceRange()) - .fixItInsert(attr->getLocation(), "@preconcurrency ") - .warnUntilSwiftVersion(6) - .limitBehaviorIf(inSwiftinterface, DiagnosticBehavior::Ignore); + if (!decl->getDeclContext()->isInSwiftinterface()) { + ctx.Diags.diagnose(attr->getLocation(), diag::unsafe_global_actor) + .fixItRemove(attr->getArgs()->getSourceRange()) + .fixItInsert(attr->getLocation(), "@preconcurrency ") + .warnUntilSwiftVersion(6); + } } else { ctx.Diags.diagnose( attr->getLocation(), @@ -6490,11 +6488,14 @@ static bool checkSendableInstanceStorage( return true; } - property->diagnose(diag::non_concurrent_type_member, - propertyType, false, property->getName(), - nominal) - .limitBehaviorUntilSwiftVersion(behavior, 6) - .limitBehaviorIf(preconcurrency); + if (preconcurrency) + behavior = preconcurrency.value(); + + property + ->diagnose(diag::non_concurrent_type_member, propertyType, + false, property->getName(), nominal) + .limitBehaviorWithPreconcurrency(behavior, + preconcurrency.has_value()); return false; }); @@ -6532,10 +6533,14 @@ static bool checkSendableInstanceStorage( return true; } - element->diagnose(diag::non_concurrent_type_member, type, - true, element->getName(), nominal) - .limitBehaviorUntilSwiftVersion(behavior, 6) - .limitBehaviorIf(preconcurrency); + if (preconcurrency) + behavior = preconcurrency.value(); + + element + ->diagnose(diag::non_concurrent_type_member, type, true, + element->getName(), nominal) + .limitBehaviorWithPreconcurrency(behavior, + preconcurrency.has_value()); return false; }); From 664c119e3085ba6a13d90493e8d7b3452b564c0d Mon Sep 17 00:00:00 2001 From: Pavel Yaskevich Date: Mon, 24 Feb 2025 18:04:55 -0800 Subject: [PATCH 2/2] [DiagnosticEngine] Don't account ignored diagnostics in `Sema.NumSwift6Errors` statistic Since the diagnostic is not going to be emitted counting it in `Swift6Errors` statistics is going to be confusing to the users. Resolves: https://github.com/swiftlang/swift/issues/79291 Resolves: rdar://145341605 --- lib/AST/DiagnosticEngine.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/AST/DiagnosticEngine.cpp b/lib/AST/DiagnosticEngine.cpp index 599ff14369719..c6722f803f638 100644 --- a/lib/AST/DiagnosticEngine.cpp +++ b/lib/AST/DiagnosticEngine.cpp @@ -440,7 +440,8 @@ InFlightDiagnostic::limitBehaviorUntilSwiftVersion( limitBehavior(limit); } - if (majorVersion == 6) { + // Record all of the diagnostics that are going to be emitted. + if (majorVersion == 6 && limit != DiagnosticBehavior::Ignore) { if (auto stats = Engine->statsReporter) { ++stats->getFrontendCounters().NumSwift6Errors; }