@@ -2848,7 +2848,8 @@ bool swift::diagnoseExplicitUnavailability(SourceLoc loc,
28482848 const RootProtocolConformance *rootConf,
28492849 const ExtensionDecl *ext,
28502850 const ExportContext &where,
2851- bool warnIfConformanceUnavailablePreSwift6) {
2851+ bool warnIfConformanceUnavailablePreSwift6,
2852+ bool preconcurrency) {
28522853 auto *attr = AvailableAttr::isUnavailable (ext);
28532854 if (!attr)
28542855 return false ;
@@ -2909,7 +2910,7 @@ bool swift::diagnoseExplicitUnavailability(SourceLoc loc,
29092910 diags.diagnose (loc, diag::conformance_availability_unavailable,
29102911 type, proto,
29112912 platform.empty (), platform, EncodedMessage.Message )
2912- .limitBehaviorUntilSwiftVersion (behavior, 6 )
2913+ .limitBehaviorWithPreconcurrency (behavior, preconcurrency )
29132914 .warnUntilSwiftVersionIf (warnIfConformanceUnavailablePreSwift6, 6 );
29142915
29152916 switch (attr->getVersionAvailability (ctx)) {
@@ -3442,6 +3443,7 @@ class ExprAvailabilityWalker : public ASTWalker {
34423443 ASTContext &Context;
34433444 MemberAccessContext AccessContext = MemberAccessContext::Default;
34443445 SmallVector<const Expr *, 16 > ExprStack;
3446+ SmallVector<bool , 4 > PreconcurrencyCalleeStack;
34453447 const ExportContext &Where;
34463448
34473449public:
@@ -3469,6 +3471,19 @@ class ExprAvailabilityWalker : public ASTWalker {
34693471
34703472 ExprStack.push_back (E);
34713473
3474+ if (auto *apply = dyn_cast<ApplyExpr>(E)) {
3475+ bool preconcurrency = false ;
3476+ auto *fn = apply->getFn ();
3477+ if (auto *selfApply = dyn_cast<SelfApplyExpr>(fn)) {
3478+ fn = selfApply->getFn ();
3479+ }
3480+ auto declRef = fn->getReferencedDecl ();
3481+ if (auto *decl = declRef.getDecl ()) {
3482+ preconcurrency = decl->preconcurrency ();
3483+ }
3484+ PreconcurrencyCalleeStack.push_back (preconcurrency);
3485+ }
3486+
34723487 if (auto DR = dyn_cast<DeclRefExpr>(E)) {
34733488 diagnoseDeclRefAvailability (DR->getDeclRef (), DR->getSourceRange (),
34743489 getEnclosingApplyExpr (), std::nullopt );
@@ -3573,9 +3588,15 @@ class ExprAvailabilityWalker : public ASTWalker {
35733588 EE->getLoc (),
35743589 Where.getDeclContext ());
35753590
3591+ bool preconcurrency = false ;
3592+ if (!PreconcurrencyCalleeStack.empty ()) {
3593+ preconcurrency = PreconcurrencyCalleeStack.back ();
3594+ }
3595+
35763596 for (ProtocolConformanceRef C : EE->getConformances ()) {
35773597 diagnoseConformanceAvailability (E->getLoc (), C, Where, Type (), Type (),
3578- /* useConformanceAvailabilityErrorsOpt=*/ true );
3598+ /* useConformanceAvailabilityErrorsOpt=*/ true ,
3599+ /* preconcurrency=*/ preconcurrency);
35793600 }
35803601 }
35813602
@@ -3601,6 +3622,10 @@ class ExprAvailabilityWalker : public ASTWalker {
36013622 assert (ExprStack.back () == E);
36023623 ExprStack.pop_back ();
36033624
3625+ if (auto *apply = dyn_cast<ApplyExpr>(E)) {
3626+ PreconcurrencyCalleeStack.pop_back ();
3627+ }
3628+
36043629 return Action::Continue (E);
36053630 }
36063631
@@ -3875,8 +3900,12 @@ bool ExprAvailabilityWalker::diagnoseDeclRefAvailability(
38753900 return true ;
38763901
38773902 if (R.isValid ()) {
3878- if (diagnoseSubstitutionMapAvailability (R.Start , declRef.getSubstitutions (),
3879- Where)) {
3903+ if (diagnoseSubstitutionMapAvailability (
3904+ R.Start , declRef.getSubstitutions (), Where,
3905+ Type (), Type (),
3906+ /* warnIfConformanceUnavailablePreSwift6*/ false ,
3907+ /* suppressParameterizationCheckForOptional*/ false ,
3908+ /* preconcurrency*/ D->preconcurrency ())) {
38803909 return true ;
38813910 }
38823911 }
@@ -4348,7 +4377,8 @@ class ProblematicTypeFinder : public TypeDeclFinder {
43484377 /* depTy=*/ Type (),
43494378 /* replacementTy=*/ Type (),
43504379 /* warnIfConformanceUnavailablePreSwift6=*/ false ,
4351- /* suppressParameterizationCheckForOptional=*/ ty->isOptional ());
4380+ /* suppressParameterizationCheckForOptional=*/ ty->isOptional (),
4381+ /* preconcurrency*/ ty->getAnyNominal ()->preconcurrency ());
43524382 return Action::Continue;
43534383 }
43544384
@@ -4403,17 +4433,19 @@ void swift::diagnoseTypeAvailability(const TypeRepr *TR, Type T, SourceLoc loc,
44034433}
44044434
44054435static void diagnoseMissingConformance (
4406- SourceLoc loc, Type type, ProtocolDecl *proto, const DeclContext *fromDC) {
4436+ SourceLoc loc, Type type, ProtocolDecl *proto, const DeclContext *fromDC,
4437+ bool preconcurrency) {
44074438 assert (proto->isSpecificProtocol (KnownProtocolKind::Sendable));
4408- diagnoseMissingSendableConformance (loc, type, fromDC);
4439+ diagnoseMissingSendableConformance (loc, type, fromDC, preconcurrency );
44094440}
44104441
44114442bool
44124443swift::diagnoseConformanceAvailability (SourceLoc loc,
44134444 ProtocolConformanceRef conformance,
44144445 const ExportContext &where,
44154446 Type depTy, Type replacementTy,
4416- bool warnIfConformanceUnavailablePreSwift6) {
4447+ bool warnIfConformanceUnavailablePreSwift6,
4448+ bool preconcurrency) {
44174449 assert (!where.isImplicit ());
44184450
44194451 if (conformance.isInvalid () || conformance.isAbstract ())
@@ -4425,7 +4457,8 @@ swift::diagnoseConformanceAvailability(SourceLoc loc,
44254457 for (auto patternConf : pack->getPatternConformances ()) {
44264458 diagnosed |= diagnoseConformanceAvailability (
44274459 loc, patternConf, where, depTy, replacementTy,
4428- warnIfConformanceUnavailablePreSwift6);
4460+ warnIfConformanceUnavailablePreSwift6,
4461+ preconcurrency);
44294462 }
44304463 return diagnosed;
44314464 }
@@ -4444,7 +4477,8 @@ swift::diagnoseConformanceAvailability(SourceLoc loc,
44444477 if (auto builtinConformance = dyn_cast<BuiltinProtocolConformance>(rootConf)){
44454478 if (builtinConformance->isMissing ()) {
44464479 diagnoseMissingConformance (loc, builtinConformance->getType (),
4447- builtinConformance->getProtocol (), DC);
4480+ builtinConformance->getProtocol (), DC,
4481+ preconcurrency);
44484482 }
44494483 }
44504484
@@ -4470,7 +4504,8 @@ swift::diagnoseConformanceAvailability(SourceLoc loc,
44704504 }
44714505
44724506 if (diagnoseExplicitUnavailability (loc, rootConf, ext, where,
4473- warnIfConformanceUnavailablePreSwift6)) {
4507+ warnIfConformanceUnavailablePreSwift6,
4508+ preconcurrency)) {
44744509 maybeEmitAssociatedTypeNote ();
44754510 return true ;
44764511 }
@@ -4498,7 +4533,8 @@ swift::diagnoseConformanceAvailability(SourceLoc loc,
44984533 SubstitutionMap subConformanceSubs = concreteConf->getSubstitutionMap ();
44994534 if (diagnoseSubstitutionMapAvailability (loc, subConformanceSubs, where,
45004535 depTy, replacementTy,
4501- warnIfConformanceUnavailablePreSwift6))
4536+ warnIfConformanceUnavailablePreSwift6,
4537+ preconcurrency))
45024538 return true ;
45034539
45044540 return false ;
@@ -4510,12 +4546,14 @@ swift::diagnoseSubstitutionMapAvailability(SourceLoc loc,
45104546 const ExportContext &where,
45114547 Type depTy, Type replacementTy,
45124548 bool warnIfConformanceUnavailablePreSwift6,
4513- bool suppressParameterizationCheckForOptional) {
4549+ bool suppressParameterizationCheckForOptional,
4550+ bool preconcurrency) {
45144551 bool hadAnyIssues = false ;
45154552 for (ProtocolConformanceRef conformance : subs.getConformances ()) {
45164553 if (diagnoseConformanceAvailability (loc, conformance, where,
45174554 depTy, replacementTy,
4518- warnIfConformanceUnavailablePreSwift6))
4555+ warnIfConformanceUnavailablePreSwift6,
4556+ preconcurrency))
45194557 hadAnyIssues = true ;
45204558 }
45214559
0 commit comments