@@ -55,17 +55,19 @@ 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,
68
- llvm::function_ref<void (InFlightDiagnostic &)> attachRenameFixIts);
67
+ const ValueDecl *D, SourceRange R, const AvailabilityConstraint &constraint,
68
+ const ExportContext &Where, DeclAvailabilityFlags Flags,
69
+ llvm::function_ref<void (InFlightDiagnostic &, StringRef)>
70
+ attachRenameFixIts);
69
71
70
72
static bool diagnoseSubstitutionMapAvailability (
71
73
SourceLoc loc, SubstitutionMap subs, const ExportContext &where,
@@ -2950,11 +2952,19 @@ void swift::diagnoseOverrideOfUnavailableDecl(ValueDecl *override,
2950
2952
return ;
2951
2953
}
2952
2954
2955
+ // FIXME: [availability] Take an unsatisfied constraint as input instead of
2956
+ // recomputing it.
2953
2957
ExportContext where = ExportContext::forDeclSignature (override , nullptr );
2958
+ auto constraint =
2959
+ getUnsatisfiedAvailabilityConstraint (base, where.getAvailability ());
2960
+ if (!constraint)
2961
+ return ;
2962
+
2954
2963
diagnoseExplicitUnavailability (
2955
- base, override ->getLoc (), where,
2956
- /* Flags*/ std::nullopt, [&](InFlightDiagnostic &diag) {
2957
- ParsedDeclName parsedName = parseDeclName (attr.getRename ());
2964
+ base, override ->getLoc (), *constraint, where,
2965
+ /* Flags*/ std::nullopt,
2966
+ [&override , &ctx](InFlightDiagnostic &diag, StringRef rename) {
2967
+ ParsedDeclName parsedName = parseDeclName (rename);
2958
2968
if (!parsedName || parsedName.isPropertyAccessor () ||
2959
2969
parsedName.isMember () || parsedName.isOperator ()) {
2960
2970
return ;
@@ -2981,127 +2991,63 @@ void swift::diagnoseOverrideOfUnavailableDecl(ValueDecl *override,
2981
2991
2982
2992
// / Emit a diagnostic for references to declarations that have been
2983
2993
// / marked as unavailable, either through "unavailable" or "obsoleted:".
2984
- static bool diagnoseExplicitUnavailability (const ValueDecl *D, SourceRange R,
2985
- const ExportContext &Where,
2986
- const Expr *call,
2987
- DeclAvailabilityFlags Flags) {
2994
+ static bool diagnoseExplicitUnavailability (
2995
+ const ValueDecl *D, SourceRange R, const AvailabilityConstraint &constraint,
2996
+ const ExportContext &Where, const Expr *call, DeclAvailabilityFlags Flags) {
2988
2997
return diagnoseExplicitUnavailability (
2989
- D, R, Where, Flags, [=](InFlightDiagnostic &diag) {
2990
- auto attr = D->getUnavailableAttr ();
2991
- assert (attr);
2992
- fixItAvailableAttrRename (diag, R, D, attr->getRename (), call);
2998
+ D, R, constraint, Where, Flags,
2999
+ [=](InFlightDiagnostic &diag, StringRef rename) {
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,14 +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,
3515
- llvm::function_ref<void (InFlightDiagnostic &)> attachRenameFixIts) {
3516
- auto diagnosticInfo = getExplicitUnavailabilityDiagnosticInfo (D, Where);
3517
- if (!diagnosticInfo )
3461
+ const ValueDecl *D, SourceRange R, const AvailabilityConstraint &constraint ,
3462
+ const ExportContext &Where, DeclAvailabilityFlags Flags,
3463
+ llvm::function_ref<void (InFlightDiagnostic &, StringRef)>
3464
+ attachRenameFixIts) {
3465
+ if (constraint. isConditionallySatisfiable () )
3518
3466
return false ;
3519
3467
3520
- auto Attr = diagnosticInfo-> getAttr ();
3468
+ auto Attr = constraint. getAttr ();
3521
3469
if (Attr.getDomain ().isSwiftLanguage () && !Attr.isVersionSpecific ()) {
3522
3470
if (shouldAllowReferenceToUnavailableInSwiftDeclaration (D, Where))
3523
3471
return false ;
@@ -3526,11 +3474,11 @@ bool diagnoseExplicitUnavailability(
3526
3474
SourceLoc Loc = R.Start ;
3527
3475
ASTContext &ctx = D->getASTContext ();
3528
3476
auto &diags = ctx.Diags ;
3529
- StringRef versionedPlatform = diagnosticInfo-> getDomainName ();
3530
- StringRef platform =
3531
- diagnosticInfo-> shouldHideDomainNameInUnversionedDiagnostics ( )
3532
- ? " "
3533
- : versionedPlatform;
3477
+ auto domain = constraint. getDomain ();
3478
+ StringRef versionedPlatform = domain. getNameForDiagnostics ();
3479
+ StringRef platform = shouldHideDomainNameForConstraintDiagnostic (constraint )
3480
+ ? " "
3481
+ : versionedPlatform;
3534
3482
3535
3483
// TODO: Consider removing this.
3536
3484
// ObjC keypaths components weren't checked previously, so errors are demoted
@@ -3556,7 +3504,7 @@ bool diagnoseExplicitUnavailability(
3556
3504
D, replaceKind.has_value (), rawReplaceKind,
3557
3505
newName, EncodedMessage.Message );
3558
3506
diag.limitBehavior (limit);
3559
- attachRenameFixIts (diag);
3507
+ attachRenameFixIts (diag, rename );
3560
3508
} else if (isSubscriptReturningString (D, ctx)) {
3561
3509
diags.diagnose (Loc, diag::availability_string_subscript_migration)
3562
3510
.highlight (R)
@@ -3578,23 +3526,26 @@ bool diagnoseExplicitUnavailability(
3578
3526
}
3579
3527
3580
3528
auto sourceRange = Attr.getParsedAttr ()->getRange ();
3581
- switch (diagnosticInfo-> getStatus ()) {
3582
- case UnavailabilityDiagnosticInfo::Status ::AlwaysUnavailable:
3529
+ switch (constraint. getKind ()) {
3530
+ case AvailabilityConstraint::Kind ::AlwaysUnavailable:
3583
3531
diags.diagnose (D, diag::availability_marked_unavailable, D)
3584
3532
.highlight (sourceRange);
3585
3533
break ;
3586
- case UnavailabilityDiagnosticInfo::Status::IntroducedInVersion :
3534
+ case AvailabilityConstraint::Kind::RequiresVersion :
3587
3535
diags
3588
3536
.diagnose (D, diag::availability_introduced_in_version, D,
3589
3537
versionedPlatform, *Attr.getIntroduced ())
3590
3538
.highlight (sourceRange);
3591
3539
break ;
3592
- case UnavailabilityDiagnosticInfo::Status ::Obsoleted:
3540
+ case AvailabilityConstraint::Kind ::Obsoleted:
3593
3541
diags
3594
3542
.diagnose (D, diag::availability_obsoleted, D, versionedPlatform,
3595
3543
*Attr.getObsoleted ())
3596
3544
.highlight (sourceRange);
3597
3545
break ;
3546
+ case AvailabilityConstraint::Kind::IntroducedInNewerVersion:
3547
+ llvm_unreachable (" unexpected constraint" );
3548
+ break ;
3598
3549
}
3599
3550
return true ;
3600
3551
}
@@ -4216,9 +4167,8 @@ bool swift::diagnoseDeclAvailability(const ValueDecl *D, SourceRange R,
4216
4167
auto constraint =
4217
4168
getUnsatisfiedAvailabilityConstraint (D, Where.getAvailability ());
4218
4169
4219
- if (constraint && !constraint->isConditionallySatisfiable ()) {
4220
- // FIXME: diagnoseExplicitUnavailability should take an unmet requirement
4221
- if (diagnoseExplicitUnavailability (D, R, Where, call, Flags))
4170
+ if (constraint) {
4171
+ if (diagnoseExplicitUnavailability (D, R, *constraint, Where, call, Flags))
4222
4172
return true ;
4223
4173
}
4224
4174
@@ -4738,11 +4688,9 @@ swift::diagnoseConformanceAvailability(SourceLoc loc,
4738
4688
auto constraint =
4739
4689
getUnsatisfiedAvailabilityConstraint (ext, where.getAvailability ());
4740
4690
if (constraint) {
4741
- // FIXME: diagnoseExplicitUnavailability() should take unmet requirement
4742
- if (diagnoseExplicitUnavailability (
4743
- loc, rootConf, ext, where,
4744
- warnIfConformanceUnavailablePreSwift6,
4745
- preconcurrency)) {
4691
+ if (diagnoseExplicitUnavailability (loc, *constraint, rootConf, ext, where,
4692
+ warnIfConformanceUnavailablePreSwift6,
4693
+ preconcurrency)) {
4746
4694
maybeEmitAssociatedTypeNote ();
4747
4695
return true ;
4748
4696
}
0 commit comments