Skip to content

Commit 919cf8e

Browse files
authored
Merge pull request #65926 from slavapestov/availability-and-backdeploy-variadics-5.9
Availability and backward deployment for variadic generics [5.9]
2 parents 49b7e0d + c3e3b01 commit 919cf8e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+358
-151
lines changed

include/swift/AST/ASTContext.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -918,6 +918,10 @@ class ASTContext final {
918918
/// needed to place array buffers into constant data sections.
919919
AvailabilityContext getImmortalRefCountSymbolsAvailability();
920920

921+
/// Get the runtime availability of runtime functions for
922+
/// variadic generic types.
923+
AvailabilityContext getVariadicGenericTypeAvailability();
924+
921925
/// Get the runtime availability of features introduced in the Swift 5.2
922926
/// compiler for the target platform.
923927
AvailabilityContext getSwift52Availability();

include/swift/AST/DiagnosticsSema.def

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2160,10 +2160,10 @@ NOTE(decl_import_via_here,none,
21602160

21612161
// Opaque return types
21622162
ERROR(opaque_type_invalid_constraint,none,
2163-
"an 'opaque' type must specify only 'Any', 'AnyObject', protocols, "
2163+
"a 'some' type must specify only 'Any', 'AnyObject', protocols, "
21642164
"and/or a base class", ())
21652165
NOTE(opaque_of_optional_rewrite,none,
2166-
"did you mean to write an optional of an 'opaque' type?", ())
2166+
"did you mean to write an optional of an 'some' type?", ())
21672167
ERROR(inferred_opaque_type,none,
21682168
"property definition has inferred type %0, involving the 'some' "
21692169
"return type of another declaration", (Type))
@@ -6146,6 +6146,10 @@ ERROR(availability_parameterized_protocol_only_version_newer, none,
61466146
"%0 %1 or newer",
61476147
(StringRef, llvm::VersionTuple))
61486148

6149+
ERROR(availability_variadic_type_only_version_newer, none,
6150+
"parameter packs in generic types are only available in %0 %1 or newer",
6151+
(StringRef, llvm::VersionTuple))
6152+
61496153
NOTE(availability_guard_with_version_check, none,
61506154
"add 'if #available' version check", ())
61516155

include/swift/Frontend/BackDeploymentLibs.def

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,14 @@
2121
//===----------------------------------------------------------------------===//
2222

2323
#ifndef BACK_DEPLOYMENT_LIB
24-
# error "Must define BACK_DEPLOYMENT_LIB(Version, Filter, Library)"
24+
# error "Must define BACK_DEPLOYMENT_LIB(Version, Filter, Library, ForceLoad)"
2525
#endif
2626

27-
BACK_DEPLOYMENT_LIB((5, 0), all, "swiftCompatibility50")
28-
BACK_DEPLOYMENT_LIB((5, 1), all, "swiftCompatibility51")
29-
BACK_DEPLOYMENT_LIB((5, 0), executable, "swiftCompatibilityDynamicReplacements")
30-
BACK_DEPLOYMENT_LIB((5, 4), all, "swiftCompatibilityConcurrency")
31-
BACK_DEPLOYMENT_LIB((5, 6), all, "swiftCompatibility56")
27+
BACK_DEPLOYMENT_LIB((5, 0), all, "swiftCompatibility50", true)
28+
BACK_DEPLOYMENT_LIB((5, 1), all, "swiftCompatibility51", true)
29+
BACK_DEPLOYMENT_LIB((5, 0), executable, "swiftCompatibilityDynamicReplacements", true)
30+
BACK_DEPLOYMENT_LIB((5, 4), all, "swiftCompatibilityConcurrency", true)
31+
BACK_DEPLOYMENT_LIB((5, 6), all, "swiftCompatibility56", true)
32+
BACK_DEPLOYMENT_LIB((5, 8), all, "swiftCompatibilityPacks", false)
3233

3334
#undef BACK_DEPLOYMENT_LIB

lib/AST/Availability.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,11 @@ ASTContext::getImmortalRefCountSymbolsAvailability() {
517517
return getSwiftFutureAvailability();
518518
}
519519

520+
AvailabilityContext
521+
ASTContext::getVariadicGenericTypeAvailability() {
522+
return getSwift59Availability();
523+
}
524+
520525
AvailabilityContext ASTContext::getSwift52Availability() {
521526
auto target = LangOpts.Target;
522527

lib/Basic/TargetInfo.cpp

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ using namespace swift;
2323
/// Print information about a
2424
static void printCompatibilityLibrary(
2525
llvm::VersionTuple runtimeVersion, llvm::VersionTuple maxVersion,
26-
StringRef filter, StringRef libraryName, bool &printedAny,
27-
llvm::raw_ostream &out) {
26+
StringRef filter, StringRef libraryName, bool forceLoad,
27+
bool &printedAny, llvm::raw_ostream &out) {
2828
if (runtimeVersion > maxVersion)
2929
return;
3030

@@ -33,16 +33,21 @@ static void printCompatibilityLibrary(
3333
}
3434

3535
out << "\n";
36-
out << " {\n";
36+
out << " {";
3737

38-
out << " \"libraryName\": \"";
38+
out << "\n \"libraryName\": \"";
3939
swift::writeEscaped(libraryName, out);
40-
out << "\",\n";
40+
out << "\",";
4141

42-
out << " \"filter\": \"";
42+
out << "\n \"filter\": \"";
4343
swift::writeEscaped(filter, out);
44-
out << "\"\n";
45-
out << " }";
44+
out << "\"";
45+
46+
if (!forceLoad) {
47+
out << ",\n \"forceLoad\": false";
48+
}
49+
50+
out << "\n }";
4651

4752
printedAny = true;
4853
}
@@ -132,10 +137,10 @@ void targetinfo::printTripleInfo(const llvm::Triple &triple,
132137
// Compatibility libraries that need to be linked.
133138
out << " \"compatibilityLibraries\": [";
134139
bool printedAnyCompatibilityLibrary = false;
135-
#define BACK_DEPLOYMENT_LIB(Version, Filter, LibraryName) \
136-
printCompatibilityLibrary( \
140+
#define BACK_DEPLOYMENT_LIB(Version, Filter, LibraryName, ForceLoad) \
141+
printCompatibilityLibrary( \
137142
*runtimeVersion, llvm::VersionTuple Version, #Filter, LibraryName, \
138-
printedAnyCompatibilityLibrary, out);
143+
ForceLoad, printedAnyCompatibilityLibrary, out);
139144
#include "swift/Frontend/BackDeploymentLibs.def"
140145

141146
if (printedAnyCompatibilityLibrary) {

lib/Driver/DarwinToolChains.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,8 @@ toolchains::Darwin::addArgsToLinkStdlib(ArgStringList &Arguments,
406406
runtimeCompatibilityVersion = llvm::VersionTuple(5, 5);
407407
} else if (value.equals("5.6")) {
408408
runtimeCompatibilityVersion = llvm::VersionTuple(5, 6);
409+
} else if (value.equals("5.8")) {
410+
runtimeCompatibilityVersion = llvm::VersionTuple(5, 8);
409411
} else if (value.equals("none")) {
410412
runtimeCompatibilityVersion = None;
411413
} else {
@@ -419,7 +421,8 @@ toolchains::Darwin::addArgsToLinkStdlib(ArgStringList &Arguments,
419421
if (runtimeCompatibilityVersion) {
420422
auto addBackDeployLib = [&](llvm::VersionTuple version,
421423
BackDeployLibFilter filter,
422-
StringRef libraryName) {
424+
StringRef libraryName,
425+
bool forceLoad) {
423426
if (*runtimeCompatibilityVersion > version)
424427
return;
425428

@@ -431,14 +434,16 @@ toolchains::Darwin::addArgsToLinkStdlib(ArgStringList &Arguments,
431434
llvm::sys::path::append(BackDeployLib, "lib" + libraryName + ".a");
432435

433436
if (llvm::sys::fs::exists(BackDeployLib)) {
434-
Arguments.push_back("-force_load");
437+
if (forceLoad)
438+
Arguments.push_back("-force_load");
435439
Arguments.push_back(context.Args.MakeArgString(BackDeployLib));
436440
}
437441
};
438442

439-
#define BACK_DEPLOYMENT_LIB(Version, Filter, LibraryName) \
440-
addBackDeployLib( \
441-
llvm::VersionTuple Version, BackDeployLibFilter::Filter, LibraryName);
443+
#define BACK_DEPLOYMENT_LIB(Version, Filter, LibraryName, ForceLoad) \
444+
addBackDeployLib( \
445+
llvm::VersionTuple Version, BackDeployLibFilter::Filter, \
446+
LibraryName, ForceLoad);
442447
#include "swift/Frontend/BackDeploymentLibs.def"
443448
}
444449

lib/Frontend/CompilerInvocation.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2563,6 +2563,8 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
25632563
runtimeCompatibilityVersion = llvm::VersionTuple(5, 5);
25642564
} else if (version.equals("5.6")) {
25652565
runtimeCompatibilityVersion = llvm::VersionTuple(5, 6);
2566+
} else if (version.equals("5.8")) {
2567+
runtimeCompatibilityVersion = llvm::VersionTuple(5, 8);
25662568
} else {
25672569
Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value,
25682570
versionArg->getAsString(Args), version);

lib/IRGen/GenDecl.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,8 @@ void IRGenModule::emitSourceFile(SourceFile &SF) {
511511
// harmless aside from code size.
512512
if (!IRGen.Opts.UseJIT) {
513513
auto addBackDeployLib = [&](llvm::VersionTuple version,
514-
StringRef libraryName) {
514+
StringRef libraryName,
515+
bool forceLoad) {
515516
Optional<llvm::VersionTuple> compatibilityVersion;
516517
if (libraryName == "swiftCompatibilityDynamicReplacements") {
517518
compatibilityVersion = IRGen.Opts.
@@ -532,11 +533,11 @@ void IRGenModule::emitSourceFile(SourceFile &SF) {
532533

533534
this->addLinkLibrary(LinkLibrary(libraryName,
534535
LibraryKind::Library,
535-
/*forceLoad*/ true));
536+
forceLoad));
536537
};
537538

538-
#define BACK_DEPLOYMENT_LIB(Version, Filter, LibraryName) \
539-
addBackDeployLib(llvm::VersionTuple Version, LibraryName);
539+
#define BACK_DEPLOYMENT_LIB(Version, Filter, LibraryName, ForceLoad) \
540+
addBackDeployLib(llvm::VersionTuple Version, LibraryName, ForceLoad);
540541
#include "swift/Frontend/BackDeploymentLibs.def"
541542
}
542543
}

lib/Sema/TypeCheckAvailability.cpp

Lines changed: 33 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -2011,70 +2011,59 @@ static void fixAvailability(SourceRange ReferenceRange,
20112011
}
20122012
}
20132013

2014-
void TypeChecker::diagnosePotentialOpaqueTypeUnavailability(
2015-
SourceRange ReferenceRange, const DeclContext *ReferenceDC,
2014+
void TypeChecker::diagnosePotentialUnavailability(
2015+
SourceRange ReferenceRange, Diag<StringRef, llvm::VersionTuple> Diag,
2016+
const DeclContext *ReferenceDC,
20162017
const UnavailabilityReason &Reason) {
20172018
ASTContext &Context = ReferenceDC->getASTContext();
20182019

20192020
auto RequiredRange = Reason.getRequiredOSVersionRange();
20202021
{
20212022
auto Err =
20222023
Context.Diags.diagnose(
2023-
ReferenceRange.Start, diag::availability_opaque_types_only_version_newer,
2024+
ReferenceRange.Start, Diag,
20242025
prettyPlatformString(targetPlatform(Context.LangOpts)),
20252026
Reason.getRequiredOSVersionRange().getLowerEndpoint());
20262027

20272028
// Direct a fixit to the error if an existing guard is nearly-correct
2028-
if (fixAvailabilityByNarrowingNearbyVersionCheck(ReferenceRange,
2029-
ReferenceDC,
2030-
RequiredRange, Context, Err))
2031-
return;
2032-
}
2033-
fixAvailability(ReferenceRange, ReferenceDC, RequiredRange, Context);
2034-
}
2035-
2036-
static void diagnosePotentialConcurrencyUnavailability(
2037-
SourceRange ReferenceRange, const DeclContext *ReferenceDC,
2038-
const UnavailabilityReason &Reason) {
2039-
ASTContext &Context = ReferenceDC->getASTContext();
2040-
2041-
auto RequiredRange = Reason.getRequiredOSVersionRange();
2042-
{
2043-
auto Err =
2044-
Context.Diags.diagnose(
2045-
ReferenceRange.Start,
2046-
diag::availability_concurrency_only_version_newer,
2047-
prettyPlatformString(targetPlatform(Context.LangOpts)),
2048-
Reason.getRequiredOSVersionRange().getLowerEndpoint());
2049-
2050-
// Direct a fixit to the error if an existing guard is nearly-correct
2051-
if (fixAvailabilityByNarrowingNearbyVersionCheck(ReferenceRange,
2052-
ReferenceDC,
2053-
RequiredRange, Context, Err))
2029+
if (fixAvailabilityByNarrowingNearbyVersionCheck(
2030+
ReferenceRange, ReferenceDC, RequiredRange, Context, Err))
20542031
return;
20552032
}
20562033
fixAvailability(ReferenceRange, ReferenceDC, RequiredRange, Context);
20572034
}
20582035

2059-
void TypeChecker::checkConcurrencyAvailability(SourceRange ReferenceRange,
2060-
const DeclContext *ReferenceDC) {
2061-
// Check the availability of concurrency runtime support.
2036+
bool TypeChecker::checkAvailability(SourceRange ReferenceRange,
2037+
AvailabilityContext Availability,
2038+
Diag<StringRef, llvm::VersionTuple> Diag,
2039+
const DeclContext *ReferenceDC) {
20622040
ASTContext &ctx = ReferenceDC->getASTContext();
20632041
if (ctx.LangOpts.DisableAvailabilityChecking)
2064-
return;
2042+
return false;
20652043

20662044
if (!shouldCheckAvailability(ReferenceDC->getAsDecl()))
2067-
return;
2045+
return false;
20682046

20692047
auto runningOS =
20702048
TypeChecker::overApproximateAvailabilityAtLocation(
20712049
ReferenceRange.Start, ReferenceDC);
2072-
auto availability = ctx.getBackDeployedConcurrencyAvailability();
2073-
if (!runningOS.isContainedIn(availability)) {
2074-
diagnosePotentialConcurrencyUnavailability(
2075-
ReferenceRange, ReferenceDC,
2076-
UnavailabilityReason::requiresVersionRange(availability.getOSVersion()));
2050+
if (!runningOS.isContainedIn(Availability)) {
2051+
diagnosePotentialUnavailability(
2052+
ReferenceRange, Diag, ReferenceDC,
2053+
UnavailabilityReason::requiresVersionRange(Availability.getOSVersion()));
2054+
return true;
20772055
}
2056+
2057+
return false;
2058+
}
2059+
2060+
void TypeChecker::checkConcurrencyAvailability(SourceRange ReferenceRange,
2061+
const DeclContext *ReferenceDC) {
2062+
checkAvailability(
2063+
ReferenceRange,
2064+
ReferenceDC->getASTContext().getBackDeployedConcurrencyAvailability(),
2065+
diag::availability_concurrency_only_version_newer,
2066+
ReferenceDC);
20782067
}
20792068

20802069
/// Returns the diagnostic to emit for the potentially unavailable decl and sets
@@ -3005,48 +2994,13 @@ bool isSubscriptReturningString(const ValueDecl *D, ASTContext &Context) {
30052994
return resultTy->isString();
30062995
}
30072996

3008-
static bool diagnosePotentialParameterizedProtocolUnavailability(
3009-
SourceRange ReferenceRange, const DeclContext *ReferenceDC,
3010-
const UnavailabilityReason &Reason) {
3011-
ASTContext &Context = ReferenceDC->getASTContext();
3012-
3013-
auto RequiredRange = Reason.getRequiredOSVersionRange();
3014-
{
3015-
auto Err = Context.Diags.diagnose(
3016-
ReferenceRange.Start,
3017-
diag::availability_parameterized_protocol_only_version_newer,
3018-
prettyPlatformString(targetPlatform(Context.LangOpts)),
3019-
Reason.getRequiredOSVersionRange().getLowerEndpoint());
3020-
3021-
// Direct a fixit to the error if an existing guard is nearly-correct
3022-
if (fixAvailabilityByNarrowingNearbyVersionCheck(
3023-
ReferenceRange, ReferenceDC, RequiredRange, Context, Err))
3024-
return true;
3025-
}
3026-
fixAvailability(ReferenceRange, ReferenceDC, RequiredRange, Context);
3027-
return true;
3028-
}
3029-
30302997
bool swift::diagnoseParameterizedProtocolAvailability(
30312998
SourceRange ReferenceRange, const DeclContext *ReferenceDC) {
3032-
// Check the availability of parameterized existential runtime support.
3033-
ASTContext &ctx = ReferenceDC->getASTContext();
3034-
if (ctx.LangOpts.DisableAvailabilityChecking)
3035-
return false;
3036-
3037-
if (!shouldCheckAvailability(ReferenceDC->getAsDecl()))
3038-
return false;
3039-
3040-
auto runningOS = TypeChecker::overApproximateAvailabilityAtLocation(
3041-
ReferenceRange.Start, ReferenceDC);
3042-
auto availability = ctx.getParameterizedExistentialRuntimeAvailability();
3043-
if (!runningOS.isContainedIn(availability)) {
3044-
return diagnosePotentialParameterizedProtocolUnavailability(
3045-
ReferenceRange, ReferenceDC,
3046-
UnavailabilityReason::requiresVersionRange(
3047-
availability.getOSVersion()));
3048-
}
3049-
return false;
2999+
return TypeChecker::checkAvailability(
3000+
ReferenceRange,
3001+
ReferenceDC->getASTContext().getParameterizedExistentialRuntimeAvailability(),
3002+
diag::availability_parameterized_protocol_only_version_newer,
3003+
ReferenceDC);
30503004
}
30513005

30523006
static void

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,12 @@ static void checkGenericParams(GenericContext *ownerCtx) {
484484
decl->diagnose(diag::experimental_type_with_parameter_pack);
485485
}
486486

487+
TypeChecker::checkAvailability(
488+
gp->getSourceRange(),
489+
ownerCtx->getASTContext().getVariadicGenericTypeAvailability(),
490+
diag::availability_variadic_type_only_version_newer,
491+
ownerCtx);
492+
487493
if (hasPack) {
488494
gp->diagnose(diag::more_than_one_pack_in_type);
489495
}

lib/Sema/TypeCheckGeneric.cpp

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -85,19 +85,11 @@ OpaqueResultTypeRequest::evaluate(Evaluator &evaluator,
8585
}
8686

8787
// Check the availability of the opaque type runtime support.
88-
if (!ctx.LangOpts.DisableAvailabilityChecking) {
89-
auto runningOS =
90-
TypeChecker::overApproximateAvailabilityAtLocation(
91-
repr->getLoc(),
92-
originatingDecl->getInnermostDeclContext());
93-
auto availability = ctx.getOpaqueTypeAvailability();
94-
if (!runningOS.isContainedIn(availability)) {
95-
TypeChecker::diagnosePotentialOpaqueTypeUnavailability(
96-
repr->getSourceRange(),
97-
originatingDecl->getInnermostDeclContext(),
98-
UnavailabilityReason::requiresVersionRange(availability.getOSVersion()));
99-
}
100-
}
88+
TypeChecker::checkAvailability(
89+
repr->getSourceRange(),
90+
ctx.getOpaqueTypeAvailability(),
91+
diag::availability_opaque_types_only_version_newer,
92+
originatingDecl->getInnermostDeclContext());
10193

10294
// Create a generic signature for the opaque environment. This is the outer
10395
// generic signature with an added generic parameters representing the opaque

0 commit comments

Comments
 (0)