Skip to content

Commit 31fa5fc

Browse files
committed
Sema: Replace UnavailabilityDiagnosticInfo with AvailabilityConstraint.
AvailabilityConstraint models a superset of UnavailabilityDiagnosticInfo and will become the currency type for unsatisfied availability everywhere. NFC.
1 parent fdb182b commit 31fa5fc

File tree

3 files changed

+82
-131
lines changed

3 files changed

+82
-131
lines changed

include/swift/AST/AvailabilityConstraint.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#ifndef SWIFT_AST_AVAILABILITY_CONSTRAINT_H
1818
#define SWIFT_AST_AVAILABILITY_CONSTRAINT_H
1919

20+
#include "swift/AST/AvailabilityDomain.h"
2021
#include "swift/AST/AvailabilityRange.h"
2122
#include "swift/AST/PlatformKind.h"
2223
#include "swift/Basic/LLVM.h"
@@ -88,6 +89,9 @@ class AvailabilityConstraint {
8889
return static_cast<SemanticAvailableAttr>(attrAndKind.getPointer());
8990
}
9091

92+
/// Returns the domain that the constraint applies to.
93+
AvailabilityDomain getDomain() const { return getAttr().getDomain(); }
94+
9195
/// Returns the platform that this constraint applies to, or
9296
/// `PlatformKind::none` if it is not platform specific.
9397
PlatformKind getPlatform() const;

lib/Sema/TypeCheckAvailability.cpp

Lines changed: 77 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -55,16 +55,17 @@ concreteSyntaxDeclForAvailableAttribute(const Decl *AbstractSyntaxDecl);
5555
/// Emit a diagnostic for references to declarations that have been
5656
/// marked as unavailable, either through "unavailable" or "obsoleted:".
5757
static bool diagnoseExplicitUnavailability(
58-
SourceLoc loc, const RootProtocolConformance *rootConf,
59-
const ExtensionDecl *ext, const ExportContext &where,
58+
SourceLoc loc, const AvailabilityConstraint &constraint,
59+
const RootProtocolConformance *rootConf, const ExtensionDecl *ext,
60+
const ExportContext &where,
6061
bool warnIfConformanceUnavailablePreSwift6 = false,
6162
bool preconcurrency = false);
6263

6364
/// Emit a diagnostic for references to declarations that have been
6465
/// marked as unavailable, either through "unavailable" or "obsoleted:".
6566
static bool diagnoseExplicitUnavailability(
66-
const ValueDecl *D, SourceRange R, const ExportContext &Where,
67-
DeclAvailabilityFlags Flags,
67+
const ValueDecl *D, SourceRange R, const AvailabilityConstraint &constraint,
68+
const ExportContext &Where, DeclAvailabilityFlags Flags,
6869
llvm::function_ref<void(InFlightDiagnostic &, StringRef)>
6970
attachRenameFixIts);
7071

@@ -2951,9 +2952,16 @@ void swift::diagnoseOverrideOfUnavailableDecl(ValueDecl *override,
29512952
return;
29522953
}
29532954

2955+
// FIXME: [availability] Take an unsatisfied constraint as input instead of
2956+
// recomputing it.
29542957
ExportContext where = ExportContext::forDeclSignature(override, nullptr);
2958+
auto constraint =
2959+
getUnsatisfiedAvailabilityConstraint(base, where.getAvailability());
2960+
if (!constraint)
2961+
return;
2962+
29552963
diagnoseExplicitUnavailability(
2956-
base, override->getLoc(), where,
2964+
base, override->getLoc(), *constraint, where,
29572965
/*Flags*/ std::nullopt,
29582966
[&override, &ctx](InFlightDiagnostic &diag, StringRef rename) {
29592967
ParsedDeclName parsedName = parseDeclName(rename);
@@ -2983,125 +2991,63 @@ void swift::diagnoseOverrideOfUnavailableDecl(ValueDecl *override,
29832991

29842992
/// Emit a diagnostic for references to declarations that have been
29852993
/// marked as unavailable, either through "unavailable" or "obsoleted:".
2986-
static bool diagnoseExplicitUnavailability(const ValueDecl *D, SourceRange R,
2987-
const ExportContext &Where,
2988-
const Expr *call,
2989-
DeclAvailabilityFlags Flags) {
2994+
static bool diagnoseExplicitUnavailability(
2995+
const ValueDecl *D, SourceRange R, const AvailabilityConstraint &constraint,
2996+
const ExportContext &Where, const Expr *call, DeclAvailabilityFlags Flags) {
29902997
return diagnoseExplicitUnavailability(
2991-
D, R, Where, Flags, [=](InFlightDiagnostic &diag, StringRef rename) {
2998+
D, R, constraint, Where, Flags,
2999+
[=](InFlightDiagnostic &diag, StringRef rename) {
29923000
fixItAvailableAttrRename(diag, R, D, rename, call);
29933001
});
29943002
}
29953003

2996-
/// Represents common information needed to emit diagnostics about explicitly
2997-
/// unavailable declarations.
2998-
class UnavailabilityDiagnosticInfo {
2999-
public:
3000-
enum class Status {
3001-
/// The declaration is marked `unavailable`, potentially on a specific
3002-
/// platform.
3003-
AlwaysUnavailable,
3004-
3005-
/// The declaration is not available until, for example, a later Swift
3006-
/// language mode.
3007-
IntroducedInVersion,
3008-
3009-
/// The declaration was obsoleted in a previous version.
3010-
Obsoleted,
3011-
};
3012-
3013-
private:
3014-
Status DiagnosticStatus;
3015-
SemanticAvailableAttr Attr;
3016-
3017-
public:
3018-
UnavailabilityDiagnosticInfo(Status status, const SemanticAvailableAttr &attr)
3019-
: DiagnosticStatus(status), Attr(attr) {};
3020-
3021-
Status getStatus() const { return DiagnosticStatus; }
3022-
SemanticAvailableAttr getAttr() const { return Attr; }
3023-
AvailabilityDomain getDomain() const { return Attr.getDomain(); }
3024-
StringRef getDomainName() const {
3025-
return getDomain().getNameForDiagnostics();
3026-
}
3004+
bool shouldHideDomainNameForConstraintDiagnostic(
3005+
const AvailabilityConstraint &constraint) {
3006+
switch (constraint.getDomain().getKind()) {
3007+
case AvailabilityDomain::Kind::Universal:
3008+
case AvailabilityDomain::Kind::Embedded:
3009+
return true;
3010+
case AvailabilityDomain::Kind::Platform:
3011+
return false;
30273012

3028-
bool shouldHideDomainNameInUnversionedDiagnostics() const {
3029-
switch (getDomain().getKind()) {
3030-
case AvailabilityDomain::Kind::Universal:
3031-
case AvailabilityDomain::Kind::Embedded:
3032-
return true;
3033-
case AvailabilityDomain::Kind::Platform:
3013+
case AvailabilityDomain::Kind::PackageDescription:
3014+
case AvailabilityDomain::Kind::SwiftLanguage:
3015+
switch (constraint.getKind()) {
3016+
case AvailabilityConstraint::Kind::AlwaysUnavailable:
3017+
case AvailabilityConstraint::Kind::IntroducedInNewerVersion:
30343018
return false;
3035-
3036-
case AvailabilityDomain::Kind::PackageDescription:
3037-
case AvailabilityDomain::Kind::SwiftLanguage:
3038-
switch (DiagnosticStatus) {
3039-
case Status::AlwaysUnavailable:
3040-
return false;
3041-
case Status::IntroducedInVersion:
3042-
case Status::Obsoleted:
3043-
return true;
3044-
}
3045-
}
3046-
}
3047-
};
3048-
3049-
static std::optional<UnavailabilityDiagnosticInfo>
3050-
getExplicitUnavailabilityDiagnosticInfo(const Decl *decl,
3051-
const ExportContext &where) {
3052-
auto attr = where.shouldDiagnoseDeclAsUnavailable(decl);
3053-
if (!attr)
3054-
return std::nullopt;
3055-
3056-
ASTContext &ctx = decl->getASTContext();
3057-
3058-
switch (attr->getVersionAvailability(ctx)) {
3059-
case AvailableVersionComparison::Available:
3060-
case AvailableVersionComparison::PotentiallyUnavailable:
3061-
llvm_unreachable("These aren't considered unavailable");
3062-
3063-
case AvailableVersionComparison::Unavailable:
3064-
if ((attr->isSwiftLanguageModeSpecific() ||
3065-
attr->isPackageDescriptionVersionSpecific()) &&
3066-
attr->getIntroduced()) {
3067-
return UnavailabilityDiagnosticInfo(
3068-
UnavailabilityDiagnosticInfo::Status::IntroducedInVersion, *attr);
3069-
} else {
3070-
return UnavailabilityDiagnosticInfo(
3071-
UnavailabilityDiagnosticInfo::Status::AlwaysUnavailable, *attr);
3019+
case AvailabilityConstraint::Kind::RequiresVersion:
3020+
case AvailabilityConstraint::Kind::Obsoleted:
3021+
return true;
30723022
}
3073-
break;
3074-
3075-
case AvailableVersionComparison::Obsoleted:
3076-
return UnavailabilityDiagnosticInfo(
3077-
UnavailabilityDiagnosticInfo::Status::Obsoleted, *attr);
30783023
}
30793024
}
30803025

3081-
bool diagnoseExplicitUnavailability(
3082-
SourceLoc loc, const RootProtocolConformance *rootConf,
3083-
const ExtensionDecl *ext, const ExportContext &where,
3084-
bool warnIfConformanceUnavailablePreSwift6,
3085-
bool preconcurrency) {
3086-
// Invertible protocols are never unavailable.
3087-
if (rootConf->getProtocol()->getInvertibleProtocolKind())
3026+
bool diagnoseExplicitUnavailability(SourceLoc loc,
3027+
const AvailabilityConstraint &constraint,
3028+
const RootProtocolConformance *rootConf,
3029+
const ExtensionDecl *ext,
3030+
const ExportContext &where,
3031+
bool warnIfConformanceUnavailablePreSwift6,
3032+
bool preconcurrency) {
3033+
if (constraint.isConditionallySatisfiable())
30883034
return false;
30893035

3090-
auto diagnosticInfo = getExplicitUnavailabilityDiagnosticInfo(ext, where);
3091-
if (!diagnosticInfo)
3036+
// Invertible protocols are never unavailable.
3037+
if (rootConf->getProtocol()->getInvertibleProtocolKind())
30923038
return false;
30933039

30943040
ASTContext &ctx = ext->getASTContext();
30953041
auto &diags = ctx.Diags;
30963042

30973043
auto type = rootConf->getType();
30983044
auto proto = rootConf->getProtocol()->getDeclaredInterfaceType();
3099-
StringRef versionedPlatform = diagnosticInfo->getDomainName();
3100-
StringRef platform =
3101-
diagnosticInfo->shouldHideDomainNameInUnversionedDiagnostics()
3102-
? ""
3103-
: versionedPlatform;
3104-
auto attr = diagnosticInfo->getAttr();
3045+
auto domain = constraint.getDomain();
3046+
StringRef versionedPlatform = domain.getNameForDiagnostics();
3047+
StringRef platform = shouldHideDomainNameForConstraintDiagnostic(constraint)
3048+
? ""
3049+
: versionedPlatform;
3050+
auto attr = constraint.getAttr();
31053051

31063052
// Downgrade unavailable Sendable conformance diagnostics where
31073053
// appropriate.
@@ -3115,23 +3061,25 @@ bool diagnoseExplicitUnavailability(
31153061
.limitBehaviorWithPreconcurrency(behavior, preconcurrency)
31163062
.warnUntilSwiftVersionIf(warnIfConformanceUnavailablePreSwift6, 6);
31173063

3118-
switch (diagnosticInfo->getStatus()) {
3119-
case UnavailabilityDiagnosticInfo::Status::AlwaysUnavailable:
3064+
switch (constraint.getKind()) {
3065+
case AvailabilityConstraint::Kind::AlwaysUnavailable:
31203066
diags
31213067
.diagnose(ext, diag::conformance_availability_marked_unavailable, type,
31223068
proto)
31233069
.highlight(attr.getParsedAttr()->getRange());
31243070
break;
3125-
case UnavailabilityDiagnosticInfo::Status::IntroducedInVersion:
3071+
case AvailabilityConstraint::Kind::RequiresVersion:
31263072
diags.diagnose(ext, diag::conformance_availability_introduced_in_version,
31273073
type, proto, versionedPlatform, *attr.getIntroduced());
31283074
break;
3129-
case UnavailabilityDiagnosticInfo::Status::Obsoleted:
3075+
case AvailabilityConstraint::Kind::Obsoleted:
31303076
diags
31313077
.diagnose(ext, diag::conformance_availability_obsoleted, type, proto,
31323078
versionedPlatform, *attr.getObsoleted())
31333079
.highlight(attr.getParsedAttr()->getRange());
31343080
break;
3081+
case AvailabilityConstraint::Kind::IntroducedInNewerVersion:
3082+
llvm_unreachable("unexpected constraint");
31353083
}
31363084
return true;
31373085
}
@@ -3510,15 +3458,14 @@ static void checkFunctionConversionAvailability(Type srcType, Type destType,
35103458
}
35113459

35123460
bool diagnoseExplicitUnavailability(
3513-
const ValueDecl *D, SourceRange R, const ExportContext &Where,
3514-
DeclAvailabilityFlags Flags,
3461+
const ValueDecl *D, SourceRange R, const AvailabilityConstraint &constraint,
3462+
const ExportContext &Where, DeclAvailabilityFlags Flags,
35153463
llvm::function_ref<void(InFlightDiagnostic &, StringRef)>
35163464
attachRenameFixIts) {
3517-
auto diagnosticInfo = getExplicitUnavailabilityDiagnosticInfo(D, Where);
3518-
if (!diagnosticInfo)
3465+
if (constraint.isConditionallySatisfiable())
35193466
return false;
35203467

3521-
auto Attr = diagnosticInfo->getAttr();
3468+
auto Attr = constraint.getAttr();
35223469
if (Attr.getDomain().isSwiftLanguage() && !Attr.isVersionSpecific()) {
35233470
if (shouldAllowReferenceToUnavailableInSwiftDeclaration(D, Where))
35243471
return false;
@@ -3527,11 +3474,11 @@ bool diagnoseExplicitUnavailability(
35273474
SourceLoc Loc = R.Start;
35283475
ASTContext &ctx = D->getASTContext();
35293476
auto &diags = ctx.Diags;
3530-
StringRef versionedPlatform = diagnosticInfo->getDomainName();
3531-
StringRef platform =
3532-
diagnosticInfo->shouldHideDomainNameInUnversionedDiagnostics()
3533-
? ""
3534-
: versionedPlatform;
3477+
auto domain = constraint.getDomain();
3478+
StringRef versionedPlatform = domain.getNameForDiagnostics();
3479+
StringRef platform = shouldHideDomainNameForConstraintDiagnostic(constraint)
3480+
? ""
3481+
: versionedPlatform;
35353482

35363483
// TODO: Consider removing this.
35373484
// ObjC keypaths components weren't checked previously, so errors are demoted
@@ -3579,23 +3526,26 @@ bool diagnoseExplicitUnavailability(
35793526
}
35803527

35813528
auto sourceRange = Attr.getParsedAttr()->getRange();
3582-
switch (diagnosticInfo->getStatus()) {
3583-
case UnavailabilityDiagnosticInfo::Status::AlwaysUnavailable:
3529+
switch (constraint.getKind()) {
3530+
case AvailabilityConstraint::Kind::AlwaysUnavailable:
35843531
diags.diagnose(D, diag::availability_marked_unavailable, D)
35853532
.highlight(sourceRange);
35863533
break;
3587-
case UnavailabilityDiagnosticInfo::Status::IntroducedInVersion:
3534+
case AvailabilityConstraint::Kind::RequiresVersion:
35883535
diags
35893536
.diagnose(D, diag::availability_introduced_in_version, D,
35903537
versionedPlatform, *Attr.getIntroduced())
35913538
.highlight(sourceRange);
35923539
break;
3593-
case UnavailabilityDiagnosticInfo::Status::Obsoleted:
3540+
case AvailabilityConstraint::Kind::Obsoleted:
35943541
diags
35953542
.diagnose(D, diag::availability_obsoleted, D, versionedPlatform,
35963543
*Attr.getObsoleted())
35973544
.highlight(sourceRange);
35983545
break;
3546+
case AvailabilityConstraint::Kind::IntroducedInNewerVersion:
3547+
llvm_unreachable("unexpected constraint");
3548+
break;
35993549
}
36003550
return true;
36013551
}
@@ -4217,9 +4167,8 @@ bool swift::diagnoseDeclAvailability(const ValueDecl *D, SourceRange R,
42174167
auto constraint =
42184168
getUnsatisfiedAvailabilityConstraint(D, Where.getAvailability());
42194169

4220-
if (constraint && !constraint->isConditionallySatisfiable()) {
4221-
// FIXME: diagnoseExplicitUnavailability should take an unmet requirement
4222-
if (diagnoseExplicitUnavailability(D, R, Where, call, Flags))
4170+
if (constraint) {
4171+
if (diagnoseExplicitUnavailability(D, R, *constraint, Where, call, Flags))
42234172
return true;
42244173
}
42254174

@@ -4739,11 +4688,9 @@ swift::diagnoseConformanceAvailability(SourceLoc loc,
47394688
auto constraint =
47404689
getUnsatisfiedAvailabilityConstraint(ext, where.getAvailability());
47414690
if (constraint) {
4742-
// FIXME: diagnoseExplicitUnavailability() should take unmet requirement
4743-
if (diagnoseExplicitUnavailability(
4744-
loc, rootConf, ext, where,
4745-
warnIfConformanceUnavailablePreSwift6,
4746-
preconcurrency)) {
4691+
if (diagnoseExplicitUnavailability(loc, *constraint, rootConf, ext, where,
4692+
warnIfConformanceUnavailablePreSwift6,
4693+
preconcurrency)) {
47474694
maybeEmitAssociatedTypeNote();
47484695
return true;
47494696
}

lib/Sema/TypeCheckDeclOverride.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2222,7 +2222,7 @@ static bool checkSingleOverride(ValueDecl *override, ValueDecl *base) {
22222222
return true;
22232223
}
22242224

2225-
// FIXME: Possibly should extend to more availability checking.
2225+
// FIXME: [availability] Possibly should extend to more availability checking.
22262226
auto unavailabilityStatusAndAttr =
22272227
checkOverrideUnavailability(override, base);
22282228
auto unavailableAttr = unavailabilityStatusAndAttr.second;

0 commit comments

Comments
 (0)