From 22ec0813771cb36ae0bc7b25e6adf4ee665ce3bb Mon Sep 17 00:00:00 2001 From: Pavel Yaskevich Date: Tue, 4 Nov 2025 12:17:15 -0800 Subject: [PATCH] [AST/Sema] Add a diagnostic group `ExplicitSendable` to replace `-require-explicit-sendable` Always run explicit `Sendable` checks on public types and suppress warning printing by default instead of using a special compiler argument. Resolves: rdar://162394810 --- include/swift/AST/DiagnosticGroups.def | 1 + include/swift/AST/DiagnosticsSema.def | 6 ++-- lib/Sema/TypeCheckConcurrency.cpp | 3 +- .../objc_require_explicit_sendable.swift | 6 ++-- .../require-explicit-sendable.swift | 2 +- .../explicit-sendable-annotations.md | 30 +++++++++++++++++++ 6 files changed, 40 insertions(+), 8 deletions(-) create mode 100644 userdocs/diagnostics/explicit-sendable-annotations.md diff --git a/include/swift/AST/DiagnosticGroups.def b/include/swift/AST/DiagnosticGroups.def index 0eae2e01efe..2f0c3e31ca1 100644 --- a/include/swift/AST/DiagnosticGroups.def +++ b/include/swift/AST/DiagnosticGroups.def @@ -87,6 +87,7 @@ GROUP(TemporaryPointers,none,"temporary-pointers") GROUP(TrailingClosureMatching,none,"trailing-closure-matching") GROUP(UnknownWarningGroup,none,"unknown-warning-group") GROUP(WeakMutability,none,"weak-mutability") +GROUP(ExplicitSendable,DefaultIgnoreWarnings,"explicit-sendable-annotations") GROUP_LINK(PerformanceHints,ExistentialType) GROUP_LINK(PerformanceHints,ReturnTypeImplicitCopy) diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index e3326cf5a83..7b586db8d55 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -2857,9 +2857,9 @@ WARNING(remove_public_import,none, WARNING(remove_package_import,none, "package import of %0 was not used in package declarations", (Identifier)) -WARNING(public_decl_needs_sendable,none, - "public %kind0 does not specify whether it is 'Sendable' or not", - (const ValueDecl *)) +GROUPED_WARNING(public_decl_needs_sendable,ExplicitSendable,none, + "public %kind0 does not specify whether it is 'Sendable' or not", + (const ValueDecl *)) NOTE(explicit_disable_sendable,none, "make %kind0 explicitly non-Sendable to suppress this warning", (const ValueDecl *)) diff --git a/lib/Sema/TypeCheckConcurrency.cpp b/lib/Sema/TypeCheckConcurrency.cpp index 4da77c6ea22..27685d80a55 100644 --- a/lib/Sema/TypeCheckConcurrency.cpp +++ b/lib/Sema/TypeCheckConcurrency.cpp @@ -25,6 +25,7 @@ #include "swift/AST/ASTWalker.h" #include "swift/AST/Concurrency.h" #include "swift/AST/ConformanceLookup.h" +#include "swift/AST/DiagnosticGroups.h" #include "swift/AST/DistributedDecl.h" #include "swift/AST/ExistentialLayout.h" #include "swift/AST/GenericEnvironment.h" @@ -1376,7 +1377,7 @@ static bool checkSendableInstanceStorage( void swift::diagnoseMissingExplicitSendable(NominalTypeDecl *nominal) { // Only diagnose when explicitly requested. ASTContext &ctx = nominal->getASTContext(); - if (!ctx.LangOpts.RequireExplicitSendable) + if (ctx.Diags.isIgnoredDiagnosticGroupTree(DiagGroupID::ExplicitSendable)) return; if (nominal->getLoc().isInvalid()) diff --git a/test/Concurrency/objc_require_explicit_sendable.swift b/test/Concurrency/objc_require_explicit_sendable.swift index e0a47aac9d3..dc1df950eef 100644 --- a/test/Concurrency/objc_require_explicit_sendable.swift +++ b/test/Concurrency/objc_require_explicit_sendable.swift @@ -1,6 +1,6 @@ -// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-sil -o /dev/null -I %S/Inputs/custom-modules %s -verify -parse-as-library -require-explicit-sendable -// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-sil -o /dev/null -I %S/Inputs/custom-modules %s -verify -parse-as-library -require-explicit-sendable -strict-concurrency=targeted -// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-sil -o /dev/null -I %S/Inputs/custom-modules %s -verify -parse-as-library -require-explicit-sendable -strict-concurrency=complete +// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-sil -o /dev/null -I %S/Inputs/custom-modules %s -verify -parse-as-library -Wwarning ExplicitSendable +// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-sil -o /dev/null -I %S/Inputs/custom-modules %s -verify -parse-as-library -Wwarning ExplicitSendable -strict-concurrency=targeted +// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-sil -o /dev/null -I %S/Inputs/custom-modules %s -verify -parse-as-library -Wwarning ExplicitSendable -strict-concurrency=complete // REQUIRES: objc_interop // REQUIRES: concurrency diff --git a/test/Concurrency/require-explicit-sendable.swift b/test/Concurrency/require-explicit-sendable.swift index 4ddfd6c1f57..4dbf14e367f 100644 --- a/test/Concurrency/require-explicit-sendable.swift +++ b/test/Concurrency/require-explicit-sendable.swift @@ -1,4 +1,4 @@ -// RUN: %target-swift-frontend -require-explicit-sendable -strict-concurrency=complete %s -emit-sil -o /dev/null -verify +// RUN: %target-swift-frontend -Wwarning ExplicitSendable -strict-concurrency=complete %s -emit-sil -o /dev/null -verify public protocol P { } diff --git a/userdocs/diagnostics/explicit-sendable-annotations.md b/userdocs/diagnostics/explicit-sendable-annotations.md new file mode 100644 index 00000000000..6e46368c373 --- /dev/null +++ b/userdocs/diagnostics/explicit-sendable-annotations.md @@ -0,0 +1,30 @@ +# Explicit Sendable annotations on public type declarations + +If a public type doesn't have an explicit Sendable or non-Sendable annotation it is sometimes hard to discern whether that is intentional or not, especially if a type could be Sendable. + +## Overview + +The Swift compiler would emit a warning if a public type has none of the following: + + - A conformance to `Sendable` protocol; + - An unavailable conformance to `Sendable` protocol; + - `~Sendable` conformance to suppress the inference. + +Let's consider a simple public type without any Senable annotations: + +``` +public struct S { + let x: Int +} +``` + +When compiling with `-Wwarning ExplicitSendable` the following warning is going to be produced by the Swift compiler: + +``` +1 | public struct S { + | |- warning: public struct 'S' does not specify whether it is 'Sendable' or not [#ExplicitSendable] + | |- note: consider making struct 'S' conform to the 'Sendable' protocol + | `- note: make struct 'S' explicitly non-Sendable to suppress this warning +2 | let x: Int +3 | } +```