Skip to content

Commit 272b2b4

Browse files
committed
AST: Accept AvailabilityDomains as diagnostic arguments.
This simplifies the code to emit availabilty diagnostics and ensures that they display domain names consistently. While updating existing diagnostics, improve consistency along other dimensions as well.
1 parent aaa0e0a commit 272b2b4

13 files changed

+55
-43
lines changed

include/swift/AST/DiagnosticEngine.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#define SWIFT_BASIC_DIAGNOSTICENGINE_H
2020

2121
#include "swift/AST/ActorIsolation.h"
22+
#include "swift/AST/AvailabilityDomain.h"
2223
#include "swift/AST/DeclNameLoc.h"
2324
#include "swift/AST/DiagnosticConsumer.h"
2425
#include "swift/AST/TypeLoc.h"
@@ -143,6 +144,7 @@ namespace swift {
143144
DescriptiveDeclKind,
144145
DescriptiveStmtKind,
145146
DeclAttribute,
147+
AvailabilityDomain,
146148
VersionTuple,
147149
LayoutConstraint,
148150
ActorIsolation,
@@ -179,6 +181,7 @@ namespace swift {
179181
DescriptiveDeclKind DescriptiveDeclKindVal;
180182
StmtKind DescriptiveStmtKindVal;
181183
const DeclAttribute *DeclAttributeVal;
184+
AvailabilityDomain AvailabilityDomainVal;
182185
llvm::VersionTuple VersionVal;
183186
LayoutConstraint LayoutConstraintVal;
184187
ActorIsolation ActorIsolationVal;
@@ -278,6 +281,10 @@ namespace swift {
278281
: Kind(DiagnosticArgumentKind::DeclAttribute),
279282
DeclAttributeVal(attr) {}
280283

284+
DiagnosticArgument(const AvailabilityDomain domain)
285+
: Kind(DiagnosticArgumentKind::AvailabilityDomain),
286+
AvailabilityDomainVal(domain) {}
287+
281288
DiagnosticArgument(llvm::VersionTuple version)
282289
: Kind(DiagnosticArgumentKind::VersionTuple),
283290
VersionVal(version) { }
@@ -400,6 +407,11 @@ namespace swift {
400407
return DeclAttributeVal;
401408
}
402409

410+
const AvailabilityDomain getAsAvailabilityDomain() const {
411+
assert(Kind == DiagnosticArgumentKind::AvailabilityDomain);
412+
return AvailabilityDomainVal;
413+
}
414+
403415
llvm::VersionTuple getAsVersionTuple() const {
404416
assert(Kind == DiagnosticArgumentKind::VersionTuple);
405417
return VersionVal;

include/swift/AST/DiagnosticsSema.def

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6755,9 +6755,9 @@ NOTE(type_eraser_init_spi,none,
67556755

67566756
ERROR(availability_must_occur_alone, none,
67576757
"%0 %select{|version }1availability must be specified alone",
6758-
(StringRef, bool))
6758+
(AvailabilityDomain, bool))
67596759
ERROR(availability_unexpected_version, none,
6760-
"unexpected version number for %0", (StringRef))
6760+
"unexpected version number for %0", (AvailabilityDomain))
67616761
WARNING(availability_unrecognized_platform_name,
67626762
PointsToFirstBadToken, "unrecognized platform name %0", (Identifier))
67636763
WARNING(availability_suggest_platform_name,
@@ -6766,17 +6766,17 @@ WARNING(availability_suggest_platform_name,
67666766
(Identifier, StringRef))
67676767

67686768
WARNING(attr_availability_expected_deprecated_version, none,
6769-
"expected version number with 'deprecated' in '%0' attribute for "
6770-
"platform '%1'", (StringRef, StringRef))
6769+
"expected version number with 'deprecated' in '%0' attribute for %1",
6770+
(const DeclAttribute, AvailabilityDomain))
67716771
WARNING(attr_availability_cannot_be_used_for_domain, none,
6772-
"'%0' cannot be used in '%1' attribute for platform '%2'",
6773-
(StringRef, StringRef, StringRef))
6772+
"'%0' cannot be used in '%1' attribute for %2",
6773+
(StringRef, const DeclAttribute, AvailabilityDomain))
67746774
WARNING(attr_availability_expected_version_spec, none,
67756775
"expected 'introduced', 'deprecated', or 'obsoleted' in '%0' attribute "
6776-
"for platform '%1'", (StringRef, StringRef))
6776+
"for %1", (const DeclAttribute, AvailabilityDomain))
67776777
ERROR(attr_availability_requires_custom_availability, none,
67786778
"%0 requires '-enable-experimental-feature CustomAvailability'",
6779-
(StringRef))
6779+
(AvailabilityDomain))
67806780

67816781
ERROR(availability_decl_unavailable, none,
67826782
"%0 is unavailable%select{ in %2|}1%select{|: %3}3",
@@ -7003,10 +7003,11 @@ ERROR(conformance_availability_only_version_newer, none,
70037003

70047004
ERROR(availability_query_not_allowed, none,
70057005
"%0 %select{|version }1checks not allowed in %2(...)",
7006-
(StringRef, bool, StringRef))
7006+
(AvailabilityDomain, bool, StringRef))
70077007

70087008
ERROR(availability_query_already_specified, none,
7009-
"%select{|version for }0'%1' already specified", (bool, StringRef))
7009+
"%select{|version for }0%1 already specified",
7010+
(bool, AvailabilityDomain))
70107011

70117012
ERROR(availability_query_wildcard_required, none,
70127013
"must handle potential future platforms with '*'", ())

lib/AST/Availability.cpp

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -807,7 +807,6 @@ SemanticAvailableAttrRequest::evaluate(swift::Evaluator &evaluator,
807807
auto &ctx = decl->getASTContext();
808808
auto &diags = ctx.Diags;
809809
auto attrLoc = attr->getLocation();
810-
auto attrName = attr->getAttrName();
811810
auto domainLoc = attr->getDomainLoc();
812811
auto declContext = decl->getInnermostDeclContext();
813812
auto mutableAttr = const_cast<AvailableAttr *>(attr);
@@ -817,7 +816,6 @@ SemanticAvailableAttrRequest::evaluate(swift::Evaluator &evaluator,
817816
if (!domain)
818817
return std::nullopt;
819818

820-
auto domainName = domain->getNameForAttributePrinting();
821819
auto semanticAttr = SemanticAvailableAttr(attr);
822820

823821
bool hasIntroduced = attr->getRawIntroduced().has_value();
@@ -834,9 +832,7 @@ SemanticAvailableAttrRequest::evaluate(swift::Evaluator &evaluator,
834832
else if (hasObsoleted)
835833
versionSourceRange = semanticAttr.getObsoletedSourceRange();
836834

837-
diags
838-
.diagnose(attrLoc, diag::availability_unexpected_version,
839-
domain->getNameForDiagnostics())
835+
diags.diagnose(attrLoc, diag::availability_unexpected_version, *domain)
840836
.limitBehaviorIf(domain->isUniversal(), DiagnosticBehavior::Warning)
841837
.highlight(versionSourceRange);
842838
return std::nullopt;
@@ -846,18 +842,18 @@ SemanticAvailableAttrRequest::evaluate(swift::Evaluator &evaluator,
846842
switch (attr->getKind()) {
847843
case AvailableAttr::Kind::Deprecated:
848844
diags.diagnose(attrLoc,
849-
diag::attr_availability_expected_deprecated_version,
850-
attrName, domainName);
845+
diag::attr_availability_expected_deprecated_version, attr,
846+
*domain);
851847
return std::nullopt;
852848

853849
case AvailableAttr::Kind::Unavailable:
854850
diags.diagnose(attrLoc, diag::attr_availability_cannot_be_used_for_domain,
855-
"unavailable", attrName, domainName);
851+
"unavailable", attr, *domain);
856852
return std::nullopt;
857853

858854
case AvailableAttr::Kind::NoAsync:
859855
diags.diagnose(attrLoc, diag::attr_availability_cannot_be_used_for_domain,
860-
"noasync", attrName, domainName);
856+
"noasync", attr, *domain);
861857
return std::nullopt;
862858

863859
case AvailableAttr::Kind::Default:
@@ -869,7 +865,7 @@ SemanticAvailableAttrRequest::evaluate(swift::Evaluator &evaluator,
869865
switch (attr->getKind()) {
870866
case AvailableAttr::Kind::Default:
871867
diags.diagnose(domainLoc, diag::attr_availability_expected_version_spec,
872-
attrName, domainName);
868+
attr, *domain);
873869
return std::nullopt;
874870
case AvailableAttr::Kind::Deprecated:
875871
case AvailableAttr::Kind::Unavailable:

lib/AST/AvailabilityDomain.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ AvailabilityDomainOrIdentifier::lookUpInDeclContext(
260260
!ctx.LangOpts.hasFeature(Feature::CustomAvailability) &&
261261
!declContext->isInSwiftinterface()) {
262262
diags.diagnose(loc, diag::attr_availability_requires_custom_availability,
263-
domain->getNameForDiagnostics());
263+
*domain);
264264
return std::nullopt;
265265
}
266266

lib/AST/DiagnosticEngine.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,6 +1051,11 @@ static void formatDiagnosticArgument(StringRef Modifier,
10511051
Out << '@' << Arg.getAsDeclAttribute()->getAttrName();
10521052
break;
10531053

1054+
case DiagnosticArgumentKind::AvailabilityDomain:
1055+
assert(Modifier.empty() &&
1056+
"Improper modifier for AvailabilityDomain argument");
1057+
Out << Arg.getAsAvailabilityDomain().getNameForDiagnostics();
1058+
break;
10541059
case DiagnosticArgumentKind::VersionTuple:
10551060
assert(Modifier.empty() &&
10561061
"Improper modifier for VersionTuple argument");

lib/Sema/MiscDiagnostics.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5147,14 +5147,14 @@ static bool diagnoseAvailabilityCondition(PoundAvailableInfo *info,
51475147
bool hasVersion = !spec.getVersion().empty();
51485148

51495149
if (!domain.supportsQueries()) {
5150-
diags.diagnose(loc, diag::availability_query_not_allowed,
5151-
domain.getNameForDiagnostics(), hasVersion, queryName);
5150+
diags.diagnose(loc, diag::availability_query_not_allowed, domain,
5151+
hasVersion, queryName);
51525152
return true;
51535153
}
51545154

51555155
if (!domain.isPlatform() && info->getQueries().size() > 1) {
5156-
diags.diagnose(loc, diag::availability_must_occur_alone,
5157-
domain.getNameForDiagnostics(), hasVersion);
5156+
diags.diagnose(loc, diag::availability_must_occur_alone, domain,
5157+
hasVersion);
51585158
return true;
51595159
}
51605160

@@ -5164,17 +5164,15 @@ static bool diagnoseAvailabilityCondition(PoundAvailableInfo *info,
51645164
return true;
51655165
}
51665166
} else if (hasVersion) {
5167-
diags
5168-
.diagnose(loc, diag::availability_unexpected_version,
5169-
domain.getNameForDiagnostics())
5167+
diags.diagnose(loc, diag::availability_unexpected_version, domain)
51705168
.highlight(parsedSpec->getVersionSrcRange());
51715169
return true;
51725170
}
51735171

51745172
// Diagnose duplicate domains.
51755173
if (!seenDomains.insert(domain).second) {
51765174
diags.diagnose(loc, diag::availability_query_already_specified,
5177-
domain.isVersioned(), domain.getNameForDiagnostics());
5175+
domain.isVersioned(), domain);
51785176
return true;
51795177
}
51805178

lib/Sema/TypeCheckAttr.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5006,16 +5006,16 @@ void AttributeChecker::checkAvailableAttrs(ArrayRef<AvailableAttr *> attrs) {
50065006
// Only platform availability is allowed to be written groups with more
50075007
// than one member.
50085008
if (!domain.isPlatform()) {
5009-
diagnose(loc, diag::availability_must_occur_alone,
5010-
domain.getNameForDiagnostics(), domain.isVersioned());
5009+
diagnose(loc, diag::availability_must_occur_alone, domain,
5010+
domain.isVersioned());
50115011
continue;
50125012
}
50135013
}
50145014

50155015
// Diagnose duplicate platforms.
50165016
if (!seenDomains.insert(domain).second) {
50175017
diagnose(loc, diag::availability_query_already_specified,
5018-
domain.isVersioned(), domain.getNameForAttributePrinting());
5018+
domain.isVersioned(), domain);
50195019
continue;
50205020
}
50215021

test/Parse/availability_query.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ if #available(macoss 51, *) { // expected-warning {{unrecognized platform name '
6464
if #available(mac 51, *) { // expected-warning {{unrecognized platform name 'mac'; did you mean 'macOS'?}} {{15-18=macOS}}
6565
}
6666

67-
if #available(OSX 51, OSX 52, *) { // expected-error {{version for 'macOS' already specified}}
67+
if #available(OSX 51, OSX 52, *) { // expected-error {{version for macOS already specified}}
6868
}
6969

7070
if #available(OSX 52) { } // expected-error {{must handle potential future platforms with '*'}} {{21-21=, *}}

test/Parse/availability_query_unavailability.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ if #unavailable(macoss 51) { // expected-warning {{unrecognized platform name 'm
5555
if #unavailable(mac 51) { // expected-warning {{unrecognized platform name 'mac'; did you mean 'macOS'?}} {{17-20=macOS}}
5656
}
5757

58-
if #unavailable(OSX 51, OSX 52) { // expected-error {{version for 'macOS' already specified}}
58+
if #unavailable(OSX 51, OSX 52) { // expected-error {{version for macOS already specified}}
5959
}
6060

6161
if #unavailable(OSX 51, iOS 8.0, *) { } // expected-error {{platform wildcard '*' is always implicit in #unavailable}} {{34-35=}}

test/Parse/diagnose_availability.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,23 +45,23 @@ func allPlatformsDeprecatedAndObsoleted() {}
4545
func allPlatformsDeprecatedAndObsoleted2() {}
4646

4747
@available(swift, unavailable)
48-
// expected-warning@-1 {{'unavailable' cannot be used in 'available' attribute for platform 'swift'}}
48+
// expected-warning@-1 {{'unavailable' cannot be used in '@available' attribute for Swift}}
4949
func swiftUnavailable() {}
5050

5151
@available(swift, unavailable, introduced: 4.2)
52-
// expected-warning@-1 {{'unavailable' cannot be used in 'available' attribute for platform 'swift'}}
52+
// expected-warning@-1 {{'unavailable' cannot be used in '@available' attribute for Swift}}
5353
func swiftUnavailableIntroduced() {}
5454

5555
@available(swift, deprecated)
56-
// expected-warning@-1 {{expected version number with 'deprecated' in 'available' attribute for platform 'swift'}}
56+
// expected-warning@-1 {{expected version number with 'deprecated' in '@available' attribute for Swift}}
5757
func swiftDeprecated() {}
5858

5959
@available(swift, deprecated, obsoleted: 4.2)
60-
// expected-warning@-1 {{expected version number with 'deprecated' in 'available' attribute for platform 'swift'}}
60+
// expected-warning@-1 {{expected version number with 'deprecated' in '@available' attribute for Swift}}
6161
func swiftDeprecatedObsoleted() {}
6262

6363
@available(swift, message: "missing valid option")
64-
// expected-warning@-1 {{expected 'introduced', 'deprecated', or 'obsoleted' in 'available' attribute for platform 'swift'}}
64+
// expected-warning@-1 {{expected 'introduced', 'deprecated', or 'obsoleted' in '@available' attribute for Swift}}
6565
func swiftMessage() {}
6666

6767
@available(swift 5, deprecated: 6)

0 commit comments

Comments
 (0)