@@ -55,16 +55,17 @@ concreteSyntaxDeclForAvailableAttribute(const Decl *AbstractSyntaxDecl);
55
55
// / Emit a diagnostic for references to declarations that have been
56
56
// / marked as unavailable, either through "unavailable" or "obsoleted:".
57
57
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,
60
61
bool warnIfConformanceUnavailablePreSwift6 = false ,
61
62
bool preconcurrency = false );
62
63
63
64
// / Emit a diagnostic for references to declarations that have been
64
65
// / marked as unavailable, either through "unavailable" or "obsoleted:".
65
66
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,
68
69
llvm::function_ref<void (InFlightDiagnostic &, StringRef)>
69
70
attachRenameFixIts);
70
71
@@ -2951,9 +2952,16 @@ void swift::diagnoseOverrideOfUnavailableDecl(ValueDecl *override,
2951
2952
return ;
2952
2953
}
2953
2954
2955
+ // FIXME: [availability] Take an unsatisfied constraint as input instead of
2956
+ // recomputing it.
2954
2957
ExportContext where = ExportContext::forDeclSignature (override , nullptr );
2958
+ auto constraint =
2959
+ getUnsatisfiedAvailabilityConstraint (base, where.getAvailability ());
2960
+ if (!constraint)
2961
+ return ;
2962
+
2955
2963
diagnoseExplicitUnavailability (
2956
- base, override ->getLoc (), where,
2964
+ base, override ->getLoc (), *constraint, where,
2957
2965
/* Flags*/ std::nullopt,
2958
2966
[&override , &ctx](InFlightDiagnostic &diag, StringRef rename) {
2959
2967
ParsedDeclName parsedName = parseDeclName (rename);
@@ -2983,125 +2991,63 @@ void swift::diagnoseOverrideOfUnavailableDecl(ValueDecl *override,
2983
2991
2984
2992
// / Emit a diagnostic for references to declarations that have been
2985
2993
// / 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) {
2990
2997
return diagnoseExplicitUnavailability (
2991
- D, R, Where, Flags, [=](InFlightDiagnostic &diag, StringRef rename) {
2998
+ D, R, constraint, Where, Flags,
2999
+ [=](InFlightDiagnostic &diag, StringRef rename) {
2992
3000
fixItAvailableAttrRename (diag, R, D, rename, call);
2993
3001
});
2994
3002
}
2995
3003
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 ;
3027
3012
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:
3034
3018
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 ;
3072
3022
}
3073
- break ;
3074
-
3075
- case AvailableVersionComparison::Obsoleted:
3076
- return UnavailabilityDiagnosticInfo (
3077
- UnavailabilityDiagnosticInfo::Status::Obsoleted, *attr);
3078
3023
}
3079
3024
}
3080
3025
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 ())
3088
3034
return false ;
3089
3035
3090
- auto diagnosticInfo = getExplicitUnavailabilityDiagnosticInfo (ext, where);
3091
- if (!diagnosticInfo )
3036
+ // Invertible protocols are never unavailable.
3037
+ if (rootConf-> getProtocol ()-> getInvertibleProtocolKind () )
3092
3038
return false ;
3093
3039
3094
3040
ASTContext &ctx = ext->getASTContext ();
3095
3041
auto &diags = ctx.Diags ;
3096
3042
3097
3043
auto type = rootConf->getType ();
3098
3044
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 ();
3105
3051
3106
3052
// Downgrade unavailable Sendable conformance diagnostics where
3107
3053
// appropriate.
@@ -3115,23 +3061,25 @@ bool diagnoseExplicitUnavailability(
3115
3061
.limitBehaviorWithPreconcurrency (behavior, preconcurrency)
3116
3062
.warnUntilSwiftVersionIf (warnIfConformanceUnavailablePreSwift6, 6 );
3117
3063
3118
- switch (diagnosticInfo-> getStatus ()) {
3119
- case UnavailabilityDiagnosticInfo::Status ::AlwaysUnavailable:
3064
+ switch (constraint. getKind ()) {
3065
+ case AvailabilityConstraint::Kind ::AlwaysUnavailable:
3120
3066
diags
3121
3067
.diagnose (ext, diag::conformance_availability_marked_unavailable, type,
3122
3068
proto)
3123
3069
.highlight (attr.getParsedAttr ()->getRange ());
3124
3070
break ;
3125
- case UnavailabilityDiagnosticInfo::Status::IntroducedInVersion :
3071
+ case AvailabilityConstraint::Kind::RequiresVersion :
3126
3072
diags.diagnose (ext, diag::conformance_availability_introduced_in_version,
3127
3073
type, proto, versionedPlatform, *attr.getIntroduced ());
3128
3074
break ;
3129
- case UnavailabilityDiagnosticInfo::Status ::Obsoleted:
3075
+ case AvailabilityConstraint::Kind ::Obsoleted:
3130
3076
diags
3131
3077
.diagnose (ext, diag::conformance_availability_obsoleted, type, proto,
3132
3078
versionedPlatform, *attr.getObsoleted ())
3133
3079
.highlight (attr.getParsedAttr ()->getRange ());
3134
3080
break ;
3081
+ case AvailabilityConstraint::Kind::IntroducedInNewerVersion:
3082
+ llvm_unreachable (" unexpected constraint" );
3135
3083
}
3136
3084
return true ;
3137
3085
}
@@ -3510,15 +3458,14 @@ static void checkFunctionConversionAvailability(Type srcType, Type destType,
3510
3458
}
3511
3459
3512
3460
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,
3515
3463
llvm::function_ref<void (InFlightDiagnostic &, StringRef)>
3516
3464
attachRenameFixIts) {
3517
- auto diagnosticInfo = getExplicitUnavailabilityDiagnosticInfo (D, Where);
3518
- if (!diagnosticInfo)
3465
+ if (constraint.isConditionallySatisfiable ())
3519
3466
return false ;
3520
3467
3521
- auto Attr = diagnosticInfo-> getAttr ();
3468
+ auto Attr = constraint. getAttr ();
3522
3469
if (Attr.getDomain ().isSwiftLanguage () && !Attr.isVersionSpecific ()) {
3523
3470
if (shouldAllowReferenceToUnavailableInSwiftDeclaration (D, Where))
3524
3471
return false ;
@@ -3527,11 +3474,11 @@ bool diagnoseExplicitUnavailability(
3527
3474
SourceLoc Loc = R.Start ;
3528
3475
ASTContext &ctx = D->getASTContext ();
3529
3476
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;
3535
3482
3536
3483
// TODO: Consider removing this.
3537
3484
// ObjC keypaths components weren't checked previously, so errors are demoted
@@ -3579,23 +3526,26 @@ bool diagnoseExplicitUnavailability(
3579
3526
}
3580
3527
3581
3528
auto sourceRange = Attr.getParsedAttr ()->getRange ();
3582
- switch (diagnosticInfo-> getStatus ()) {
3583
- case UnavailabilityDiagnosticInfo::Status ::AlwaysUnavailable:
3529
+ switch (constraint. getKind ()) {
3530
+ case AvailabilityConstraint::Kind ::AlwaysUnavailable:
3584
3531
diags.diagnose (D, diag::availability_marked_unavailable, D)
3585
3532
.highlight (sourceRange);
3586
3533
break ;
3587
- case UnavailabilityDiagnosticInfo::Status::IntroducedInVersion :
3534
+ case AvailabilityConstraint::Kind::RequiresVersion :
3588
3535
diags
3589
3536
.diagnose (D, diag::availability_introduced_in_version, D,
3590
3537
versionedPlatform, *Attr.getIntroduced ())
3591
3538
.highlight (sourceRange);
3592
3539
break ;
3593
- case UnavailabilityDiagnosticInfo::Status ::Obsoleted:
3540
+ case AvailabilityConstraint::Kind ::Obsoleted:
3594
3541
diags
3595
3542
.diagnose (D, diag::availability_obsoleted, D, versionedPlatform,
3596
3543
*Attr.getObsoleted ())
3597
3544
.highlight (sourceRange);
3598
3545
break ;
3546
+ case AvailabilityConstraint::Kind::IntroducedInNewerVersion:
3547
+ llvm_unreachable (" unexpected constraint" );
3548
+ break ;
3599
3549
}
3600
3550
return true ;
3601
3551
}
@@ -4217,9 +4167,8 @@ bool swift::diagnoseDeclAvailability(const ValueDecl *D, SourceRange R,
4217
4167
auto constraint =
4218
4168
getUnsatisfiedAvailabilityConstraint (D, Where.getAvailability ());
4219
4169
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))
4223
4172
return true ;
4224
4173
}
4225
4174
@@ -4739,11 +4688,9 @@ swift::diagnoseConformanceAvailability(SourceLoc loc,
4739
4688
auto constraint =
4740
4689
getUnsatisfiedAvailabilityConstraint (ext, where.getAvailability ());
4741
4690
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)) {
4747
4694
maybeEmitAssociatedTypeNote ();
4748
4695
return true ;
4749
4696
}
0 commit comments