Merge pull request #85098 from artemcm/DefaultIgnoreDiagnosticGroups

[Diagnostics] Replace diagnostics' `DefaultIgnore` option with a corresponding option on diagnostic groups
This commit is contained in:
Artem Chikin
2025-10-29 18:10:32 -04:00
committed by GitHub
12 changed files with 217 additions and 141 deletions

View File

@@ -28,10 +28,11 @@
// Declares a diagnostic group.
// Parameters:
// Name - group name as it appears in DiagGroupID enum and DiagGroupInfo.name
// Option - attribute applying to members of this diagnostic group
// DocsFile - file with a human readable description for the group located in
// userdocs/diagnostic_groups
#ifndef GROUP
#define GROUP(Name, DocsFile)
#define GROUP(Name, Option, DocsFile)
#endif
// GROUP_LINK macro:

View File

@@ -57,7 +57,7 @@ namespace swift {
/// this enumeration type that uniquely identifies it.
enum class DiagID : uint32_t;
enum class DiagGroupID : uint16_t;
enum class DiagGroupID : uint32_t;
/// Describes a diagnostic along with its argument types.
///
@@ -633,6 +633,14 @@ namespace swift {
/// escalated to errors.
llvm::BitVector warningsAsErrors;
/// Track which diagnostic group (`DiagGroupID`) warnings should be ignored.
llvm::BitVector ignoredDiagnosticGroups;
/// For compiler-internal purposes only, track which diagnostics should
/// be ignored completely. For example, this is used by LLDB to
/// suppress certain errors in expression evaluation.
llvm::BitVector compilerIgnoredDiagnostics;
/// Whether a fatal error has occurred
bool fatalErrorOccurred = false;
@@ -642,9 +650,6 @@ namespace swift {
/// Track the previous emitted Behavior, useful for notes
DiagnosticBehavior previousBehavior = DiagnosticBehavior::Unspecified;
/// Track which diagnostics should be ignored.
llvm::BitVector ignoredDiagnostics;
friend class DiagnosticStateRAII;
public:
@@ -708,17 +713,28 @@ namespace swift {
fatalErrorOccurred = false;
}
/// Set whether a diagnostic should be ignored.
void setIgnoredDiagnostic(DiagID id, bool ignored) {
ignoredDiagnostics[(unsigned)id] = ignored;
/// Set whether a diagnostic group should be ignored.
void setIgnoredDiagnosticGroup(DiagGroupID id, bool ignored) {
ignoredDiagnosticGroups[(unsigned)id] = ignored;
}
bool isIgnoredDiagnostic(DiagID id) const {
return ignoredDiagnostics[(unsigned)id];
/// Query whether a specific diagnostic group is ignored.
bool isIgnoredDiagnosticGroup(DiagGroupID id) const {
return ignoredDiagnosticGroups[(unsigned)id];
}
/// Set a specific diagnostic to be ignored by the compiler.
void compilerInternalIgnoreDiagnostic(DiagID id) {
compilerIgnoredDiagnostics[(unsigned)id] = true;
}
/// Query whether a specific diagnostic group and *all*
/// of its subgroups are ignored.
bool isIgnoredDiagnosticGroupTree(DiagGroupID id) const;
void swap(DiagnosticState &other) {
std::swap(showDiagnosticsAfterFatalError, other.showDiagnosticsAfterFatalError);
std::swap(showDiagnosticsAfterFatalError,
other.showDiagnosticsAfterFatalError);
std::swap(suppressWarnings, other.suppressWarnings);
std::swap(suppressNotes, other.suppressNotes);
std::swap(suppressRemarks, other.suppressRemarks);
@@ -726,7 +742,7 @@ namespace swift {
std::swap(fatalErrorOccurred, other.fatalErrorOccurred);
std::swap(anyErrorOccurred, other.anyErrorOccurred);
std::swap(previousBehavior, other.previousBehavior);
std::swap(ignoredDiagnostics, other.ignoredDiagnostics);
std::swap(ignoredDiagnosticGroups, other.ignoredDiagnosticGroups);
}
private:
@@ -966,12 +982,16 @@ namespace swift {
localization = diag::LocalizationProducer::producerFor(locale, path);
}
void ignoreDiagnostic(DiagID id) {
state.setIgnoredDiagnostic(id, true);
bool isIgnoredDiagnosticGroup(DiagGroupID id) const {
return state.isIgnoredDiagnosticGroup(id);
}
bool isIgnoredDiagnosticGroupTree(DiagGroupID id) const {
return state.isIgnoredDiagnosticGroupTree(id);
}
bool isIgnoredDiagnostic(DiagID id) const {
return state.isIgnoredDiagnostic(id);
void ignoreDiagnostic(DiagID id) {
state.compilerInternalIgnoreDiagnostic(id);
}
void resetHadAnyError() {

View File

@@ -35,63 +35,66 @@
#define DEFINE_DIAGNOSTIC_GROUPS_MACROS
#include "swift/AST/DefineDiagnosticGroupsMacros.h"
// GROUP(Name, DocsFile)
// GROUP_LINK(Parent, Child)
// GROUP(Name,Option,DocsFile)
// GROUP_LINK(Parent,Child)
GROUP(no_group, "")
GROUP(no_group,none,"")
GROUP(ActorIsolatedCall, "actor-isolated-call")
GROUP(AlwaysAvailableDomain, "always-available-domain")
GROUP(AvailabilityUnrecognizedName, "availability-unrecognized-name")
GROUP(ClangDeclarationImport, "clang-declaration-import")
GROUP(CompilationCaching, "compilation-caching")
GROUP(ConformanceIsolation, "conformance-isolation")
GROUP(ForeignReferenceType, "foreign-reference-type")
GROUP(DeprecatedDeclaration, "deprecated-declaration")
GROUP(DynamicCallable, "dynamic-callable-requirements")
GROUP(DynamicExclusivity, "dynamic-exclusivity")
GROUP(EmbeddedRestrictions, "embedded-restrictions")
GROUP(ErrorInFutureSwiftVersion, "error-in-future-swift-version")
GROUP(ExclusivityViolation, "exclusivity-violation")
GROUP(ExistentialAny, "existential-any")
GROUP(ExistentialMemberAccess, "existential-member-access-limitations")
GROUP(ExistentialType, "existential-type")
GROUP(ImplementationOnlyDeprecated, "implementation-only-deprecated")
GROUP(IsolatedConformances, "isolated-conformances")
GROUP(MemberImportVisibility, "member-import-visibility")
GROUP(MissingModuleOnKnownPaths, "missing-module-on-known-paths")
GROUP(ModuleNotTestable, "module-not-testable")
GROUP(ModuleVersionMissing, "module-version-missing")
GROUP(MultipleInheritance, "multiple-inheritance")
GROUP(MutableGlobalVariable, "mutable-global-variable")
GROUP(NominalTypes, "nominal-types")
GROUP(NonisolatedNonsendingByDefault, "nonisolated-nonsending-by-default")
GROUP(OpaqueTypeInference, "opaque-type-inference")
GROUP(PerformanceHints, "performance-hints")
GROUP(PreconcurrencyImport, "preconcurrency-import")
GROUP(PropertyWrappers, "property-wrapper-requirements")
GROUP(ProtocolTypeNonConformance, "protocol-type-non-conformance")
GROUP(RegionIsolation, "region-isolation")
GROUP(ResultBuilderMethods, "result-builder-methods")
GROUP(ReturnTypeImplicitCopy, "return-type-implicit-copy")
GROUP(SemanticCopies, "semantic-copies")
GROUP(SendableClosureCaptures, "sendable-closure-captures")
GROUP(SendableMetatypes, "sendable-metatypes")
GROUP(SendingClosureRisksDataRace, "sending-closure-risks-data-race")
GROUP(SendingRisksDataRace, "sending-risks-data-race")
GROUP(StrictLanguageFeatures, "strict-language-features")
GROUP(StrictMemorySafety, "strict-memory-safety")
GROUP(StringInterpolationConformance, "string-interpolation-conformance")
GROUP(TemporaryPointers, "temporary-pointers")
GROUP(TrailingClosureMatching, "trailing-closure-matching")
GROUP(UnknownWarningGroup, "unknown-warning-group")
GROUP(WeakMutability, "weak-mutability")
GROUP(ActorIsolatedCall,none,"actor-isolated-call")
GROUP(AlwaysAvailableDomain,none,"always-available-domain")
GROUP(AvailabilityUnrecognizedName,none,"availability-unrecognized-name")
GROUP(ClangDeclarationImport,none,"clang-declaration-import")
GROUP(CompilationCaching,none,"compilation-caching")
GROUP(ConformanceIsolation,none,"conformance-isolation")
GROUP(ForeignReferenceType,none,"foreign-reference-type")
GROUP(DeprecatedDeclaration,none,"deprecated-declaration")
GROUP(DynamicExclusivity,DefaultIgnoreWarnings,"dynamic-exclusivity")
GROUP(DynamicCallable,none,"dynamic-callable-requirements")
GROUP(EmbeddedRestrictions,DefaultIgnoreWarnings,"embedded-restrictions")
GROUP(ErrorInFutureSwiftVersion,none,"error-in-future-swift-version")
GROUP(ExclusivityViolation,none,"exclusivity-violation")
GROUP(ExistentialAny,none,"existential-any")
GROUP(ExistentialMemberAccess,none,"existential-member-access-limitations")
GROUP(ExistentialType,none,"existential-type")
GROUP(ImplementationOnlyDeprecated,none,"implementation-only-deprecated")
GROUP(IsolatedConformances,none,"isolated-conformances")
GROUP(MemberImportVisibility,none,"member-import-visibility")
GROUP(MissingModuleOnKnownPaths,none,"missing-module-on-known-paths")
GROUP(ModuleNotTestable,none,"module-not-testable")
GROUP(ModuleVersionMissing,none,"module-version-missing")
GROUP(MultipleInheritance,none,"multiple-inheritance")
GROUP(MutableGlobalVariable,none,"mutable-global-variable")
GROUP(NominalTypes,none,"nominal-types")
GROUP(NonisolatedNonsendingByDefault,none,"nonisolated-nonsending-by-default")
GROUP(OpaqueTypeInference,none,"opaque-type-inference")
GROUP(PerformanceHints,DefaultIgnoreWarnings,"performance-hints")
GROUP(PreconcurrencyImport,DefaultIgnoreWarnings,"preconcurrency-import")
GROUP(PropertyWrappers,none,"property-wrapper-requirements")
GROUP(ProtocolTypeNonConformance,none,"protocol-type-non-conformance")
GROUP(RegionIsolation,none,"region-isolation")
GROUP(ResultBuilderMethods,none,"result-builder-methods")
GROUP(ReturnTypeImplicitCopy,none,"return-type-implicit-copy")
GROUP(SendableClosureCaptures,none,"sendable-closure-captures")
GROUP(SendableMetatypes,none,"sendable-metatypes")
GROUP(SemanticCopies,DefaultIgnoreWarnings,"semantic-copies")
GROUP(SendingClosureRisksDataRace,none,"sending-closure-risks-data-race")
GROUP(SendingRisksDataRace,none,"sending-risks-data-race")
GROUP(StrictLanguageFeatures,none,"strict-language-features")
GROUP(UnrecognizedStrictLanguageFeatures,DefaultIgnoreWarnings,"strict-language-features")
GROUP(StrictMemorySafety,none,"strict-memory-safety")
GROUP(StringInterpolationConformance,none,"string-interpolation-conformance")
GROUP(TemporaryPointers,none,"temporary-pointers")
GROUP(TrailingClosureMatching,none,"trailing-closure-matching")
GROUP(UnknownWarningGroup,none,"unknown-warning-group")
GROUP(WeakMutability,none,"weak-mutability")
GROUP_LINK(PerformanceHints, ExistentialType)
GROUP_LINK(PerformanceHints, ReturnTypeImplicitCopy)
GROUP_LINK(PerformanceHints,ExistentialType)
GROUP_LINK(PerformanceHints,ReturnTypeImplicitCopy)
GROUP_LINK(RegionIsolation, SendingClosureRisksDataRace)
GROUP_LINK(RegionIsolation, SendingRisksDataRace)
GROUP_LINK(RegionIsolation,SendingClosureRisksDataRace)
GROUP_LINK(RegionIsolation,SendingRisksDataRace)
GROUP_LINK(StrictLanguageFeatures, UnrecognizedStrictLanguageFeatures)
#define UNDEFINE_DIAGNOSTIC_GROUPS_MACROS
#include "swift/AST/DefineDiagnosticGroupsMacros.h"

View File

@@ -24,16 +24,25 @@
#include <unordered_map>
namespace swift {
enum class DiagnosticGroupOptions {
/// No options.
none,
/// The diagnostic warnings belonging to this group should be ignored by default,
/// but will be re-enabled by various warning options (-Wwarning, -Werror).
DefaultIgnoreWarnings,
};
enum class DiagID : uint32_t;
enum class DiagGroupID : uint16_t {
#define GROUP(Name, Version) Name,
enum class DiagGroupID : uint32_t {
#define GROUP(Name, Option, DocsFile) Name,
#include "swift/AST/DiagnosticGroups.def"
};
constexpr const auto DiagGroupsCount = [] {
size_t count = 0;
#define GROUP(Name, Version) ++count;
#define GROUP(Name, Option, DocsFile) ++count;
#include "DiagnosticGroups.def"
return count;
}();
@@ -45,9 +54,30 @@ struct DiagGroupInfo {
llvm::ArrayRef<DiagGroupID> supergroups;
llvm::ArrayRef<DiagGroupID> subgroups;
llvm::ArrayRef<DiagID> diagnostics;
bool defaultIgnoreWarnings : 1;
constexpr DiagGroupInfo(DiagGroupID groupID, std::string_view name,
std::string_view documentationFile,
llvm::ArrayRef<DiagGroupID> supergroups,
llvm::ArrayRef<DiagGroupID> subgroups,
llvm::ArrayRef<DiagID> diagnostics,
bool defaultIgnoreWarnings)
: id(groupID), name(name), documentationFile(documentationFile),
supergroups(supergroups), subgroups(subgroups), diagnostics(diagnostics),
defaultIgnoreWarnings(defaultIgnoreWarnings) {}
constexpr DiagGroupInfo(DiagGroupID groupID, std::string_view name,
std::string_view documentationFile,
DiagnosticGroupOptions opts,
llvm::ArrayRef<DiagGroupID> supergroups,
llvm::ArrayRef<DiagGroupID> subgroups,
llvm::ArrayRef<DiagID> diagnostics)
: DiagGroupInfo(groupID, name, documentationFile, supergroups,
subgroups, diagnostics,
opts == DiagnosticGroupOptions::DefaultIgnoreWarnings) {}
void traverseDepthFirst(
llvm::function_ref<void(const DiagGroupInfo &)> func) const;
llvm::function_ref<void(const DiagGroupInfo &)> func) const;
};
extern const std::array<DiagGroupInfo, DiagGroupsCount> diagnosticGroupsInfo;

View File

@@ -40,12 +40,12 @@ WARNING(warning_upcoming_feature_on_by_default, none,
"upcoming feature '%0' is already enabled as of Swift version %1",
(StringRef, unsigned))
GROUPED_WARNING(unrecognized_feature, StrictLanguageFeatures, DefaultIgnore,
GROUPED_WARNING(unrecognized_feature, UnrecognizedStrictLanguageFeatures, none,
"'%0' is not a recognized "
"%select{experimental|upcoming}1 feature",
(StringRef, bool))
GROUPED_WARNING(feature_not_experimental, StrictLanguageFeatures, DefaultIgnore,
GROUPED_WARNING(feature_not_experimental, UnrecognizedStrictLanguageFeatures, none,
"'%0' is not an experimental feature, "
"use -%select{disable|enable}1-upcoming-feature instead",
(StringRef, bool))

View File

@@ -435,18 +435,18 @@ NOTE(performance_called_from,none,
"called from here", ())
// ManualOwnership diagnostics
GROUPED_WARNING(manualownership_copy,SemanticCopies,DefaultIgnore,
GROUPED_WARNING(manualownership_copy,SemanticCopies,none,
"implicit 'copy' happens here; please report this vague diagnostic as a bug", ())
GROUPED_WARNING(manualownership_copy_happened,SemanticCopies,DefaultIgnore,
GROUPED_WARNING(manualownership_copy_happened,SemanticCopies,none,
"accessing %0 may produce a copy; write 'copy' to acknowledge or 'consume' to elide", (Identifier))
GROUPED_WARNING(manualownership_copy_demanded,SemanticCopies,DefaultIgnore,
GROUPED_WARNING(manualownership_copy_demanded,SemanticCopies,none,
"independent copy of %0 is required here; write 'copy' to acknowledge or 'consume' to elide", (Identifier))
GROUPED_WARNING(manualownership_copy_captured,SemanticCopies,DefaultIgnore,
GROUPED_WARNING(manualownership_copy_captured,SemanticCopies,none,
"closure capture of '%0' requires independent copy of it; write [%0 = copy %0] in the closure's capture list to acknowledge", (StringRef))
GROUPED_WARNING(manualownership_exclusivity,DynamicExclusivity,DefaultIgnore,
GROUPED_WARNING(manualownership_exclusivity,DynamicExclusivity,none,
"exclusive access here will be checked at runtime; please report this vague diagnostic as a bug", ())
GROUPED_WARNING(manualownership_exclusivity_named,DynamicExclusivity,DefaultIgnore,
GROUPED_WARNING(manualownership_exclusivity_named,DynamicExclusivity,none,
"accessing %0 here may incur runtime exclusivity check%1", (Identifier, StringRef))
// 'transparent' diagnostics

View File

@@ -2859,7 +2859,7 @@ WARNING(add_predates_concurrency_import,none,
"'Sendable'-related %select{warnings|errors}0 from module %1"
"%select{| as warnings}0", (bool, Identifier))
GROUPED_WARNING(remove_predates_concurrency_import,PreconcurrencyImport,
DefaultIgnore,
none,
"'@preconcurrency' on module %0 has no effect", (Identifier))
WARNING(remove_public_import,none,
"public import of %0 was not used in public declarations or inlinable code",
@@ -8662,18 +8662,18 @@ GROUPED_ERROR(weak_unowned_in_embedded_swift, EmbeddedRestrictions, none,
(ReferenceOwnership))
GROUPED_WARNING(untyped_throws_in_embedded_swift, EmbeddedRestrictions,
DefaultIgnore,
none,
"untyped throws is not available in Embedded Swift; add a thrown error type with '(type)'", ())
GROUPED_WARNING(generic_nonfinal_in_embedded_swift, EmbeddedRestrictions,
DefaultIgnore,
none,
"generic %kind0 in a class %select{must be 'final'|cannot be 'required'}1 in Embedded Swift",
(const Decl *, bool))
GROUPED_WARNING(use_generic_member_of_existential_in_embedded_swift,
EmbeddedRestrictions, DefaultIgnore,
EmbeddedRestrictions, none,
"cannot use generic %kind0 on a value of type %1 in Embedded Swift",
(const Decl *, Type))
GROUPED_WARNING(dynamic_cast_involving_protocol_in_embedded_swift,
EmbeddedRestrictions, DefaultIgnore,
EmbeddedRestrictions, none,
"cannot perform a dynamic cast to a type involving %kind0 in Embedded Swift",
(const Decl *))
@@ -8992,33 +8992,33 @@ ERROR(conformance_repression_only_on_struct_class_enum,none,
// MARK: Swift Performance hints
//===----------------------------------------------------------------------===//
GROUPED_WARNING(perf_hint_function_returns_array,ReturnTypeImplicitCopy,DefaultIgnore,
GROUPED_WARNING(perf_hint_function_returns_array,ReturnTypeImplicitCopy,none,
"Performance: %0 returns a%select{ dictionary|n array}1, leading to implicit copies. "
"Consider using an 'inout' parameter instead.", (const FuncDecl *, bool))
GROUPED_WARNING(perf_hint_closure_returns_array,ReturnTypeImplicitCopy,DefaultIgnore,
GROUPED_WARNING(perf_hint_closure_returns_array,ReturnTypeImplicitCopy,none,
"Performance: closure returns a%select{ dictionary|n array}0, leading to implicit copies. "
"Consider using an 'inout' parameter instead.", (bool))
GROUPED_WARNING(perf_hint_param_expects_existential,ExistentialType,DefaultIgnore,
GROUPED_WARNING(perf_hint_param_expects_existential,ExistentialType,none,
"Performance: %0 expects an existential, leading to heap allocation, reference counting, "
"and dynamic dispatch. Consider using generic constraints or concrete types instead.",
(const ParamDecl*))
GROUPED_WARNING(perf_hint_func_returns_existential,ExistentialType,DefaultIgnore,
GROUPED_WARNING(perf_hint_func_returns_existential,ExistentialType,none,
"Performance: %0 returns an existential, leading to heap allocation, reference counting, "
"and dynamic dispatch. Consider using generic constraints or concrete types instead.",
(const FuncDecl*))
GROUPED_WARNING(perf_hint_closure_returns_existential,ExistentialType,DefaultIgnore,
GROUPED_WARNING(perf_hint_closure_returns_existential,ExistentialType,none,
"Performance: closure returns an existential, leading to heap allocation, reference counting, "
"and dynamic dispatch. Consider using generic constraints or concrete types instead.", ())
GROUPED_WARNING(perf_hint_var_uses_existential,ExistentialType,DefaultIgnore,
GROUPED_WARNING(perf_hint_var_uses_existential,ExistentialType,none,
"Performance: %0 uses an existential, leading to heap allocation, reference counting, "
"and dynamic dispatch. Consider using generic constraints or concrete types instead.",
(const VarDecl *))
GROUPED_WARNING(perf_hint_any_pattern_uses_existential,ExistentialType,DefaultIgnore,
GROUPED_WARNING(perf_hint_any_pattern_uses_existential,ExistentialType,none,
"Performance: declaration uses an existential, leading to heap allocation, reference counting, "
"and dynamic dispatch. Consider using generic constraints or concrete types instead.",
())
GROUPED_WARNING(perf_hint_typealias_uses_existential,ExistentialType,DefaultIgnore,
GROUPED_WARNING(perf_hint_typealias_uses_existential,ExistentialType,none,
"Performance: %0 aliases an existential type, leading to heap allocation, reference counting, "
"and dynamic dispatch. Consider using generic constraints or concrete types instead.",
(const TypeAliasDecl *))

View File

@@ -77,11 +77,6 @@ enum class DiagnosticOptions {
/// A diagnostic warning about an unused element.
NoUsage,
/// The diagnostic should be ignored by default, but will be re-enabled
/// by various warning options (-Wwarning, -Werror). This only makes sense
/// for warnings.
DefaultIgnore,
};
struct StoredDiagnosticInfo {
DiagnosticKind kind : 2;
@@ -90,17 +85,16 @@ struct StoredDiagnosticInfo {
bool isAPIDigesterBreakage : 1;
bool isDeprecation : 1;
bool isNoUsage : 1;
bool defaultIgnore : 1;
DiagGroupID groupID;
constexpr StoredDiagnosticInfo(DiagnosticKind k, bool firstBadToken,
bool fatal, bool isAPIDigesterBreakage,
bool deprecation, bool noUsage,
bool defaultIgnore, DiagGroupID groupID)
DiagGroupID groupID)
: kind(k), pointsToFirstBadToken(firstBadToken), isFatal(fatal),
isAPIDigesterBreakage(isAPIDigesterBreakage),
isDeprecation(deprecation), isNoUsage(noUsage),
defaultIgnore(defaultIgnore), groupID(groupID) {}
groupID(groupID) {}
constexpr StoredDiagnosticInfo(DiagnosticKind k, DiagnosticOptions opts,
DiagGroupID groupID)
: StoredDiagnosticInfo(k,
@@ -109,7 +103,6 @@ struct StoredDiagnosticInfo {
opts == DiagnosticOptions::APIDigesterBreakage,
opts == DiagnosticOptions::Deprecation,
opts == DiagnosticOptions::NoUsage,
opts == DiagnosticOptions::DefaultIgnore,
groupID) {}
};
} // end anonymous namespace
@@ -154,14 +147,29 @@ static constexpr const char *const fixItStrings[] = {
};
DiagnosticState::DiagnosticState() {
// Initialize our ignored diagnostics to defaults
ignoredDiagnostics.reserve(NumDiagIDs);
for (const auto &info : storedDiagnosticInfos) {
ignoredDiagnostics.push_back(info.defaultIgnore);
}
// Initialize ignored diagnostic groups to defaults
ignoredDiagnosticGroups.resize(DiagGroupsCount);
// Ensure that for each `DefaultIgnoreWarnings` group,
// we propagate this behavior to its child groups.
for (const auto &groupInfo : diagnosticGroupsInfo)
if (groupInfo.defaultIgnoreWarnings)
getDiagGroupInfoByID(groupInfo.id).traverseDepthFirst([&](auto group) {
ignoredDiagnosticGroups[(unsigned)group.id] = true;
});
// Initialize warningsAsErrors to default
warningsAsErrors.resize(DiagGroupsCount);
// Initialize compilerIgnoredDiagnostics
compilerIgnoredDiagnostics.resize(NumDiagIDs);
}
bool DiagnosticState::isIgnoredDiagnosticGroupTree(DiagGroupID id) const {
bool anyEnabled = false;
getDiagGroupInfoByID(id).traverseDepthFirst([&](auto group) {
anyEnabled |= !isIgnoredDiagnosticGroup(group.id);
});
return !anyEnabled;
}
Diagnostic::Diagnostic(DiagID ID)
@@ -597,10 +605,8 @@ void DiagnosticEngine::setWarningsAsErrorsRules(
if (auto groupID = getDiagGroupIDByName(name);
groupID && *groupID != DiagGroupID::no_group) {
getDiagGroupInfoByID(*groupID).traverseDepthFirst([&](auto group) {
state.setWarningsAsErrorsForDiagGroupID(*groupID, isEnabled);
for (DiagID diagID : group.diagnostics) {
state.setIgnoredDiagnostic(diagID, false);
}
state.setWarningsAsErrorsForDiagGroupID(group.id, isEnabled);
state.setIgnoredDiagnosticGroup(group.id, false);
});
} else {
unknownGroups.push_back(std::string(name));
@@ -1343,14 +1349,16 @@ DiagnosticState::determineBehavior(const Diagnostic &diag) const {
if (!showDiagnosticsAfterFatalError && lvl != DiagnosticBehavior::Note)
lvl = DiagnosticBehavior::Ignore;
// 3) If the user ignored this specific diagnostic, follow that
if (ignoredDiagnostics[(unsigned)diag.getID()])
lvl = DiagnosticBehavior::Ignore;
// Handle compiler-internal ignored diagnostics
if (compilerIgnoredDiagnostics[(unsigned)diag.getID()])
lvl = DiagnosticBehavior::Ignore;
// 4) If the user substituted a different behavior for this behavior, apply
// 3) If the user substituted a different behavior for this warning, apply
// that change
if (lvl == DiagnosticBehavior::Warning) {
if (getWarningsAsErrorsForDiagGroupID(diag.getGroupID()))
if (isIgnoredDiagnosticGroup(diag.getGroupID()))
lvl = DiagnosticBehavior::Ignore;
else if (getWarningsAsErrorsForDiagGroupID(diag.getGroupID()))
lvl = DiagnosticBehavior::Error;
if (suppressWarnings)
lvl = DiagnosticBehavior::Ignore;

View File

@@ -68,7 +68,7 @@ constexpr const auto diagnosticGroupConnections = [] {
constexpr auto diagnosticsCount = std::get<2>(sizes);
// Declare all edges
#define GROUP(Name, DocsFile) \
#define GROUP(Name, Option, DocsFile) \
std::array<DiagGroupID, supergroupsCount[(size_t)DiagGroupID::Name]> \
Name##_supergroups{}; \
std::array<DiagGroupID, subgroupsCount[(size_t)DiagGroupID::Name]> \
@@ -92,7 +92,7 @@ constexpr const auto diagnosticGroupConnections = [] {
#include "swift/AST/DiagnosticsAll.def"
// Produce the resulting structure with all the edges
#define GROUP(Name, DocsFile) \
#define GROUP(Name, Option, DocsFile) \
GroupConnections(Name##_supergroups, Name##_subgroups, Name##_diagnostics),
return std::tuple{
#include "swift/AST/DiagnosticGroups.def"
@@ -100,7 +100,7 @@ constexpr const auto diagnosticGroupConnections = [] {
}();
std::unordered_map<std::string_view, DiagGroupID> nameToIDMap{
#define GROUP(Name, DocsFile) {#Name, DiagGroupID::Name},
#define GROUP(Name, Option, DocsFile) {#Name, DiagGroupID::Name},
#include "swift/AST/DiagnosticGroups.def"
};
@@ -119,11 +119,12 @@ void traverseDepthFirst(DiagGroupID id,
} // end anonymous namespace
constexpr const std::array<DiagGroupInfo, DiagGroupsCount> diagnosticGroupsInfo{
#define GROUP(Name, DocsFile) \
#define GROUP(Name, Option, DocsFile) \
DiagGroupInfo{ \
DiagGroupID::Name, \
#Name, \
DocsFile, \
DiagnosticGroupOptions::Option, \
llvm::ArrayRef<DiagGroupID>( \
std::get<(size_t)DiagGroupID::Name>(diagnosticGroupConnections) \
.supergroups), \

View File

@@ -21,6 +21,7 @@
#include "swift/AST/ASTWalker.h"
#include "swift/AST/Decl.h"
#include "swift/AST/DiagnosticsFrontend.h"
#include "swift/AST/DiagnosticGroups.h"
#include "swift/AST/DiagnosticsSema.h"
#include "swift/AST/Evaluator.h"
#include "swift/AST/Expr.h"
@@ -30,22 +31,7 @@
using namespace swift;
bool swift::performanceHintDiagnosticsEnabled(ASTContext &ctx) {
return !ctx.Diags.isIgnoredDiagnostic(
diag::perf_hint_closure_returns_array.ID) ||
!ctx.Diags.isIgnoredDiagnostic(
diag::perf_hint_function_returns_array.ID) ||
!ctx.Diags.isIgnoredDiagnostic(
diag::perf_hint_param_expects_existential.ID) ||
!ctx.Diags.isIgnoredDiagnostic(
diag::perf_hint_func_returns_existential.ID) ||
!ctx.Diags.isIgnoredDiagnostic(
diag::perf_hint_closure_returns_existential.ID) ||
!ctx.Diags.isIgnoredDiagnostic(
diag::perf_hint_var_uses_existential.ID) ||
!ctx.Diags.isIgnoredDiagnostic(
diag::perf_hint_any_pattern_uses_existential.ID) ||
!ctx.Diags.isIgnoredDiagnostic(
diag::perf_hint_typealias_uses_existential.ID);
return !ctx.Diags.isIgnoredDiagnosticGroupTree(DiagGroupID::PerformanceHints);
}
namespace {

View File

@@ -17,6 +17,7 @@
#include "TypeCheckEmbedded.h"
#include "swift/AST/ASTContext.h"
#include "swift/AST/Decl.h"
#include "swift/AST/DiagnosticGroups.h"
#include "swift/AST/DiagnosticsSema.h"
#include "swift/AST/Effects.h"
#include "swift/AST/Expr.h"
@@ -46,11 +47,11 @@ swift::shouldDiagnoseEmbeddedLimitations(const DeclContext *dc, SourceLoc loc,
return defaultEmbeddedLimitationForError(dc, loc);
}
// Check one of the Embedded restriction diagnostics that is ignored by
// default. If it's still ignored, we won't diagnose anything.
// limitations.
// Check if the Embedded restriction diagnostics, which are ignored by
// default, have been enabled. If it's still ignored, we won't diagnose
// anything. limitations.
auto &diags = dc->getASTContext().Diags;
if (diags.isIgnoredDiagnostic(diag::untyped_throws_in_embedded_swift.ID))
if (diags.isIgnoredDiagnosticGroup(DiagGroupID::EmbeddedRestrictions))
return std::nullopt;
#if SWIFT_BUILD_SWIFT_SYNTAX

View File

@@ -0,0 +1,26 @@
// RUN: %empty-directory(%t)
// Ignore `ReturnTypeImplicitCopy` warnings by-default, because its parent group (`PerformanceHints`) is marked `DefaultIgnoreWarnings`
// RUN: %target-swift-frontend -typecheck %s -diagnostic-style llvm -verify
// Ensure enabled with `-Wwarning`
// RUN: %target-swift-frontend -typecheck %s -diagnostic-style llvm -Wwarning ReturnTypeImplicitCopy -verify -verify-additional-prefix warnonly-
// Ensure enabled with `-Wwarning` on the parent group
// RUN: %target-swift-frontend -typecheck %s -diagnostic-style llvm -Wwarning PerformanceHints -verify -verify-additional-prefix warnonly-
// Ensure enabled with `-Werror`
// RUN: %target-swift-frontend -typecheck %s -diagnostic-style llvm -Werror ReturnTypeImplicitCopy -verify -verify-additional-prefix erronly-
// Ensure enabled with `-Werror` on the parent group
// RUN: %target-swift-frontend -typecheck %s -diagnostic-style llvm -Werror PerformanceHints -verify -verify-additional-prefix erronly-
// Ensure enabling sibling group does not enable this group
// RUN: %target-swift-frontend -typecheck %s -diagnostic-style llvm -verify -Werror ExistentialType
func foo() -> [Int] {
// expected-erronly-error@-1 {{Performance: 'foo()' returns an array, leading to implicit copies. Consider using an 'inout' parameter instead}}
// expected-warnonly-warning@-2 {{Performance: 'foo()' returns an array, leading to implicit copies. Consider using an 'inout' parameter instead}}
return [1,2,3,4,5,6]
}