diff --git a/include/swift/AST/ASTBridging.h b/include/swift/AST/ASTBridging.h index 56c66893d039d..e3ba7b44ac738 100644 --- a/include/swift/AST/ASTBridging.h +++ b/include/swift/AST/ASTBridging.h @@ -28,6 +28,10 @@ SWIFT_BEGIN_NULLABILITY_ANNOTATIONS +namespace llvm { +template class ArrayRef; +} + namespace swift { class Argument; class ASTContext; @@ -42,6 +46,8 @@ class Identifier; class IfConfigClauseRangeInfo; struct LabeledStmtInfo; class ProtocolConformanceRef; +class RegexLiteralPatternFeature; +class RegexLiteralPatternFeatureKind; class Type; class CanType; class TypeBase; @@ -1351,6 +1357,68 @@ BridgedPrefixUnaryExpr BridgedPrefixUnaryExpr_createParsed(BridgedASTContext cContext, BridgedExpr oper, BridgedExpr operand); +class BridgedRegexLiteralPatternFeatureKind final { + unsigned RawValue; + +public: + BRIDGED_INLINE + SWIFT_NAME("init(rawValue:)") + BridgedRegexLiteralPatternFeatureKind(SwiftInt rawValue); + + using UnbridgedTy = swift::RegexLiteralPatternFeatureKind; + + BRIDGED_INLINE + BridgedRegexLiteralPatternFeatureKind(UnbridgedTy kind); + + BRIDGED_INLINE + UnbridgedTy unbridged() const; +}; + +class BridgedRegexLiteralPatternFeature final { + BridgedCharSourceRange Range; + BridgedRegexLiteralPatternFeatureKind Kind; + +public: + SWIFT_NAME("init(kind:at:)") + BridgedRegexLiteralPatternFeature(BridgedRegexLiteralPatternFeatureKind kind, + BridgedCharSourceRange range) + : Range(range), Kind(kind) {} + + using UnbridgedTy = swift::RegexLiteralPatternFeature; + + BRIDGED_INLINE + BridgedRegexLiteralPatternFeature(UnbridgedTy feature); + + BRIDGED_INLINE + UnbridgedTy unbridged() const; +}; + +class BridgedRegexLiteralPatternFeatures final { + BridgedRegexLiteralPatternFeature *_Nullable Data; + SwiftInt Count; + +public: + BridgedRegexLiteralPatternFeatures() : Data(nullptr), Count(0) {} + + SWIFT_NAME("init(baseAddress:count:)") + BridgedRegexLiteralPatternFeatures( + BridgedRegexLiteralPatternFeature *_Nullable data, SwiftInt count) + : Data(data), Count(count) {} + + using UnbridgedTy = llvm::ArrayRef; + + BRIDGED_INLINE + UnbridgedTy unbridged() const; + + SWIFT_IMPORT_UNSAFE + BridgedRegexLiteralPatternFeature *_Nullable getData() const { + return Data; + } + SwiftInt getCount() const { + return Count; + } +}; + SWIFT_NAME("BridgedRegexLiteralExpr.createParsed(_:loc:regexText:)") BridgedRegexLiteralExpr BridgedRegexLiteralExpr_createParsed(BridgedASTContext cContext, diff --git a/include/swift/AST/ASTBridgingImpl.h b/include/swift/AST/ASTBridgingImpl.h index 35153dbd8a634..a982a4649d9a2 100644 --- a/include/swift/AST/ASTBridgingImpl.h +++ b/include/swift/AST/ASTBridgingImpl.h @@ -16,10 +16,12 @@ #include "swift/AST/ASTContext.h" #include "swift/AST/ArgumentList.h" #include "swift/AST/Decl.h" +#include "swift/AST/Expr.h" #include "swift/AST/IfConfigClauseRangeInfo.h" #include "swift/AST/Stmt.h" #include "swift/AST/ProtocolConformance.h" #include "swift/AST/ProtocolConformanceRef.h" +#include "swift/Basic/Assertions.h" SWIFT_BEGIN_NULLABILITY_ANNOTATIONS @@ -379,6 +381,40 @@ swift::IfConfigClauseRangeInfo BridgedIfConfigClauseRangeInfo::unbridged() const clauseKind); } +//===----------------------------------------------------------------------===// +// MARK: BridgedRegexLiteralPatternFeature +//===----------------------------------------------------------------------===// + +BridgedRegexLiteralPatternFeatureKind::BridgedRegexLiteralPatternFeatureKind( + SwiftInt rawValue) + : RawValue(rawValue) { + ASSERT(rawValue >= 0); + ASSERT(rawValue == RawValue); +} + +BridgedRegexLiteralPatternFeatureKind::BridgedRegexLiteralPatternFeatureKind( + UnbridgedTy kind) + : RawValue(kind.getRawValue()) {} + +BridgedRegexLiteralPatternFeatureKind::UnbridgedTy +BridgedRegexLiteralPatternFeatureKind::unbridged() const { + return UnbridgedTy(RawValue); +} + +BridgedRegexLiteralPatternFeature::BridgedRegexLiteralPatternFeature( + UnbridgedTy feature) + : Range(feature.getRange()), Kind(feature.getKind()) {} + +BridgedRegexLiteralPatternFeature::UnbridgedTy +BridgedRegexLiteralPatternFeature::unbridged() const { + return UnbridgedTy(Kind.unbridged(), Range.unbridged()); +} + +BridgedRegexLiteralPatternFeatures::UnbridgedTy +BridgedRegexLiteralPatternFeatures::unbridged() const { + return UnbridgedTy(Data, Count); +} + //===----------------------------------------------------------------------===// // MARK: BridgedStmtConditionElement //===----------------------------------------------------------------------===// diff --git a/include/swift/AST/DiagnosticEngine.h b/include/swift/AST/DiagnosticEngine.h index d092dc497090d..2c70e337b8e50 100644 --- a/include/swift/AST/DiagnosticEngine.h +++ b/include/swift/AST/DiagnosticEngine.h @@ -755,6 +755,9 @@ namespace swift { /// Add a character-based range to the currently-active diagnostic. InFlightDiagnostic &highlightChars(SourceLoc Start, SourceLoc End); + /// Add a character-based range to the currently-active diagnostic. + InFlightDiagnostic &highlightChars(CharSourceRange Range); + static const char *fixItStringFor(const FixItID id); /// Get the best location where an 'import' fixit might be offered. diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index 3bdf543dfafbe..29061595d68a3 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -5962,6 +5962,10 @@ ERROR(regex_capture_types_failed_to_decode,none, "failed to decode capture types for regular expression literal; this may " "be a compiler bug", ()) +ERROR(regex_feature_unavailable, none, + "%0 is only available in %1 %2 or newer", + (StringRef, StringRef, llvm::VersionTuple)) + ERROR(must_import_regex_builder_module,none, "regex builder requires the 'RegexBuilder' module be imported'", ()) diff --git a/include/swift/AST/Expr.h b/include/swift/AST/Expr.h index 88fbbc1ae3b0c..b2c657de055b1 100644 --- a/include/swift/AST/Expr.h +++ b/include/swift/AST/Expr.h @@ -992,6 +992,50 @@ class InterpolatedStringLiteralExpr : public LiteralExpr { } }; +/// The opaque kind of a RegexLiteralExpr feature, which should only be +/// interpreted by the compiler's regex parsing library. +class RegexLiteralPatternFeatureKind final { + unsigned RawValue; + +public: + RegexLiteralPatternFeatureKind(unsigned rawValue) : RawValue(rawValue) {} + + unsigned getRawValue() const { return RawValue; } + + AvailabilityRange getAvailability(ASTContext &ctx) const; + StringRef getDescription(ASTContext &ctx) const; + + friend llvm::hash_code + hash_value(const RegexLiteralPatternFeatureKind &kind) { + return llvm::hash_value(kind.getRawValue()); + } + + friend bool operator==(const RegexLiteralPatternFeatureKind &lhs, + const RegexLiteralPatternFeatureKind &rhs) { + return lhs.getRawValue() == rhs.getRawValue(); + } + + friend bool operator!=(const RegexLiteralPatternFeatureKind &lhs, + const RegexLiteralPatternFeatureKind &rhs) { + return !(lhs == rhs); + } +}; + +/// A specific feature used in a RegexLiteralExpr, needed for availability +/// diagnostics. +class RegexLiteralPatternFeature final { + RegexLiteralPatternFeatureKind Kind; + CharSourceRange Range; + +public: + RegexLiteralPatternFeature(RegexLiteralPatternFeatureKind kind, + CharSourceRange range) + : Kind(kind), Range(range) {} + + RegexLiteralPatternFeatureKind getKind() const { return Kind; } + CharSourceRange getRange() const { return Range; } +}; + /// A regular expression literal e.g '(a|c)*'. class RegexLiteralExpr : public LiteralExpr { ASTContext *Ctx; @@ -1021,6 +1065,9 @@ class RegexLiteralExpr : public LiteralExpr { /// Retrieve the version of the regex string. unsigned getVersion() const; + /// Retrieve any features used in the regex pattern. + ArrayRef getPatternFeatures() const; + SourceRange getSourceRange() const { return Loc; } static bool classof(const Expr *E) { diff --git a/include/swift/AST/TypeCheckRequests.h b/include/swift/AST/TypeCheckRequests.h index b876c842368f1..22c51b2997350 100644 --- a/include/swift/AST/TypeCheckRequests.h +++ b/include/swift/AST/TypeCheckRequests.h @@ -5110,6 +5110,7 @@ struct RegexLiteralPatternInfo { StringRef RegexToEmit; Type RegexType; size_t Version; + ArrayRef Features; }; /// Parses the regex pattern for a given regex literal using the @@ -5131,6 +5132,47 @@ class RegexLiteralPatternInfoRequest bool isCached() const { return true; } }; +/// The description for a given regex pattern feature. This is cached since +/// the resulting string is allocated in the ASTContext for ease of bridging. +class RegexLiteralFeatureDescriptionRequest + : public SimpleRequest { +public: + using SimpleRequest::SimpleRequest; + +private: + friend SimpleRequest; + + StringRef evaluate(Evaluator &evaluator, RegexLiteralPatternFeatureKind kind, + ASTContext *ctx) const; + +public: + bool isCached() const { return true; } +}; + +/// The availability range for a given regex pattern feature. +class RegexLiteralFeatureAvailabilityRequest + : public SimpleRequest { +public: + using SimpleRequest::SimpleRequest; + +private: + friend SimpleRequest; + + AvailabilityRange evaluate(Evaluator &evaluator, + RegexLiteralPatternFeatureKind kind, + ASTContext *ctx) const; +}; + +void simple_display(llvm::raw_ostream &out, + RegexLiteralPatternFeatureKind kind); +SourceLoc extractNearestSourceLoc(RegexLiteralPatternFeatureKind kind); + class IsUnsafeRequest : public SimpleRequest= 0 && minor >= 0); + ASSERT(major == Major && minor == Minor); +} + SWIFT_END_NULLABILITY_ANNOTATIONS #endif // SWIFT_BASIC_BASICBRIDGINGIMPL_H diff --git a/include/swift/Bridging/ASTGen.h b/include/swift/Bridging/ASTGen.h index 33b0d142c4ec4..20ace660c2e22 100644 --- a/include/swift/Bridging/ASTGen.h +++ b/include/swift/Bridging/ASTGen.h @@ -103,12 +103,22 @@ bool swift_ASTGen_lexRegexLiteral(const char *_Nonnull *_Nonnull curPtrPtr, bool mustBeRegex, BridgedNullableDiagnosticEngine diagEngine); -bool swift_ASTGen_parseRegexLiteral(BridgedStringRef inputPtr, - size_t *_Nonnull versionOut, - void *_Nonnull UnsafeMutableRawPointer, - size_t captureStructureSize, - BridgedSourceLoc diagLoc, - BridgedDiagnosticEngine diagEngine); +bool swift_ASTGen_parseRegexLiteral( + BridgedStringRef inputPtr, size_t *_Nonnull versionOut, + void *_Nonnull UnsafeMutableRawPointer, size_t captureStructureSize, + BridgedRegexLiteralPatternFeatures *_Nonnull featuresOut, + BridgedSourceLoc diagLoc, BridgedDiagnosticEngine diagEngine); + +void swift_ASTGen_freeBridgedRegexLiteralPatternFeatures( + BridgedRegexLiteralPatternFeatures features); + +void swift_ASTGen_getSwiftVersionForRegexPatternFeature( + BridgedRegexLiteralPatternFeatureKind kind, + BridgedSwiftVersion *_Nonnull versionOut); + +void swift_ASTGen_getDescriptionForRegexPatternFeature( + BridgedRegexLiteralPatternFeatureKind kind, BridgedASTContext astContext, + BridgedStringRef *_Nonnull descriptionOut); intptr_t swift_ASTGen_configuredRegions( BridgedASTContext astContext, diff --git a/lib/AST/DiagnosticEngine.cpp b/lib/AST/DiagnosticEngine.cpp index dbdb850ab9217..b2a5ef7f5793a 100644 --- a/lib/AST/DiagnosticEngine.cpp +++ b/lib/AST/DiagnosticEngine.cpp @@ -225,6 +225,13 @@ InFlightDiagnostic &InFlightDiagnostic::highlightChars(SourceLoc Start, return *this; } +InFlightDiagnostic &InFlightDiagnostic::highlightChars(CharSourceRange Range) { + assert(IsActive && "Cannot modify an inactive diagnostic"); + if (Engine && Range.getStart().isValid()) + Engine->getActiveDiagnostic().addRange(Range); + return *this; +} + /// Add an insertion fix-it to the currently-active diagnostic. The /// text is inserted immediately *after* the token specified. /// diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 1231cfecb20d8..62cdf97fbb8d5 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -2772,6 +2772,28 @@ unsigned RegexLiteralExpr::getVersion() const { .Version; } +ArrayRef +RegexLiteralExpr::getPatternFeatures() const { + auto &eval = getASTContext().evaluator; + return evaluateOrDefault(eval, RegexLiteralPatternInfoRequest{this}, {}) + .Features; +} + +StringRef +RegexLiteralPatternFeatureKind::getDescription(ASTContext &ctx) const { + auto &eval = ctx.evaluator; + return evaluateOrDefault( + eval, RegexLiteralFeatureDescriptionRequest{*this, &ctx}, {}); +} + +AvailabilityRange +RegexLiteralPatternFeatureKind::getAvailability(ASTContext &ctx) const { + auto &eval = ctx.evaluator; + return evaluateOrDefault(eval, + RegexLiteralFeatureAvailabilityRequest{*this, &ctx}, + AvailabilityRange::alwaysAvailable()); +} + TypeJoinExpr::TypeJoinExpr(llvm::PointerUnion result, ArrayRef elements, SingleValueStmtExpr *SVE) : Expr(ExprKind::TypeJoin, /*implicit=*/true, Type()), Var(nullptr), diff --git a/lib/AST/TypeCheckRequests.cpp b/lib/AST/TypeCheckRequests.cpp index d3e2981f6cb48..93d92a103d489 100644 --- a/lib/AST/TypeCheckRequests.cpp +++ b/lib/AST/TypeCheckRequests.cpp @@ -99,6 +99,15 @@ void swift::simple_display(llvm::raw_ostream &out, const TypeLoc source) { out << ")"; } +void swift::simple_display(llvm::raw_ostream &out, + RegexLiteralPatternFeatureKind kind) { + out << "regex pattern feature " << kind.getRawValue(); +} + +SourceLoc swift::extractNearestSourceLoc(RegexLiteralPatternFeatureKind kind) { + return SourceLoc(); +} + //----------------------------------------------------------------------------// // Inherited type computation. //----------------------------------------------------------------------------// diff --git a/lib/ASTGen/Sources/ASTGen/Regex.swift b/lib/ASTGen/Sources/ASTGen/Regex.swift index 860961887ecde..d814197f02052 100644 --- a/lib/ASTGen/Sources/ASTGen/Regex.swift +++ b/lib/ASTGen/Sources/ASTGen/Regex.swift @@ -98,6 +98,7 @@ public func _RegexLiteralParsingFn( _ versionOut: UnsafeMutablePointer, _ captureStructureOut: UnsafeMutableRawPointer, _ captureStructureSize: UInt, + _ patternFeaturesOut: UnsafeMutablePointer, _ bridgedDiagnosticBaseLoc: BridgedSourceLoc, _ bridgedDiagnosticEngine: BridgedDiagnosticEngine ) -> Bool { @@ -113,6 +114,8 @@ public func _RegexLiteralParsingFn( str, captureBufferOut: captureBuffer ) + // TODO: -> [Feature(opaque kind, (String.Index, length))] + patternFeaturesOut.pointee = .init(baseAddress: nil, count: 0) versionOut.pointee = UInt(version) return false } catch let error as CompilerParseError { @@ -136,6 +139,36 @@ public func _RegexLiteralParsingFn( } } +@_cdecl("swift_ASTGen_freeBridgedRegexLiteralPatternFeatures") +func freeBridgedRegexLiteralPatternFeatures( + _ features: BridgedRegexLiteralPatternFeatures +) { + let buffer = UnsafeMutableBufferPointer( + start: features.getData(), count: features.getCount() + ) + buffer.deinitialize() + buffer.deallocate() +} + +@_cdecl("swift_ASTGen_getSwiftVersionForRegexPatternFeature") +func getSwiftVersionForRegexPatternFeature( + _ featureKind: BridgedRegexLiteralPatternFeatureKind, + _ versionOut: UnsafeMutablePointer +) { + // TODO: FeatureKind(opaque kind) -> Version(major, minor) + fatalError("Unimplemented") +} + +@_cdecl("swift_ASTGen_getDescriptionForRegexPatternFeature") +func getDescriptionForRegexPatternFeature( + _ featureKind: BridgedRegexLiteralPatternFeatureKind, + _ context: BridgedASTContext, + _ descriptionOut: UnsafeMutablePointer +) { + // TODO: FeatureKind(opaque kind) -> String + fatalError("Unimplemented") +} + #else // canImport(_CompilerRegexParser) #warning("Regex parsing is disabled") diff --git a/lib/Sema/TypeCheckAvailability.cpp b/lib/Sema/TypeCheckAvailability.cpp index 9bcf3c83034e6..83568b3025196 100644 --- a/lib/Sema/TypeCheckAvailability.cpp +++ b/lib/Sema/TypeCheckAvailability.cpp @@ -2098,15 +2098,15 @@ static void fixAvailability(SourceRange ReferenceRange, } static void diagnosePotentialUnavailability( - SourceRange ReferenceRange, Diag Diag, + SourceRange ReferenceRange, + llvm::function_ref + Diagnose, const DeclContext *ReferenceDC, const AvailabilityRange &Availability) { ASTContext &Context = ReferenceDC->getASTContext(); { - auto Err = Context.Diags.diagnose( - ReferenceRange.Start, Diag, - Context.getTargetPlatformStringForDiagnostics(), - Availability.getRawMinimumVersion()); + auto Err = Diagnose(Context.getTargetPlatformStringForDiagnostics(), + Availability.getRawMinimumVersion()); // Direct a fixit to the error if an existing guard is nearly-correct if (fixAvailabilityByNarrowingNearbyVersionCheck( @@ -2116,10 +2116,11 @@ static void diagnosePotentialUnavailability( fixAvailability(ReferenceRange, ReferenceDC, Availability, Context); } -bool TypeChecker::checkAvailability(SourceRange ReferenceRange, - AvailabilityRange RequiredAvailability, - Diag Diag, - const DeclContext *ReferenceDC) { +bool TypeChecker::checkAvailability( + SourceRange ReferenceRange, AvailabilityRange RequiredAvailability, + const DeclContext *ReferenceDC, + llvm::function_ref + Diagnose) { ASTContext &ctx = ReferenceDC->getASTContext(); if (ctx.LangOpts.DisableAvailabilityChecking) return false; @@ -2128,7 +2129,7 @@ bool TypeChecker::checkAvailability(SourceRange ReferenceRange, TypeChecker::overApproximateAvailabilityAtLocation(ReferenceRange.Start, ReferenceDC); if (!availabilityAtLocation.isContainedIn(RequiredAvailability)) { - diagnosePotentialUnavailability(ReferenceRange, Diag, ReferenceDC, + diagnosePotentialUnavailability(ReferenceRange, Diagnose, ReferenceDC, RequiredAvailability); return true; } @@ -2136,6 +2137,19 @@ bool TypeChecker::checkAvailability(SourceRange ReferenceRange, return false; } +bool TypeChecker::checkAvailability(SourceRange ReferenceRange, + AvailabilityRange RequiredAvailability, + Diag Diag, + const DeclContext *ReferenceDC) { + auto &Diags = ReferenceDC->getASTContext().Diags; + return TypeChecker::checkAvailability( + ReferenceRange, RequiredAvailability, ReferenceDC, + [&](StringRef platformName, llvm::VersionTuple version) { + return Diags.diagnose(ReferenceRange.Start, Diag, platformName, + version); + }); +} + void TypeChecker::checkConcurrencyAvailability(SourceRange ReferenceRange, const DeclContext *ReferenceDC) { checkAvailability( @@ -3620,6 +3634,24 @@ class ExprAvailabilityWalker : public ASTWalker { diagnoseDeclRefAvailability(LE->getInitializer(), LE->getSourceRange()); } + // Diagnose availability for any features used in a regex literal. + if (auto *RE = dyn_cast(E)) { + for (auto &feature : RE->getPatternFeatures()) { + auto featureKind = feature.getKind(); + TypeChecker::checkAvailability( + RE->getSourceRange(), featureKind.getAvailability(Context), + Where.getDeclContext(), + [&](StringRef platformName, llvm::VersionTuple version) { + auto range = feature.getRange(); + auto diag = Context.Diags.diagnose( + range.getStart(), diag::regex_feature_unavailable, + featureKind.getDescription(Context), platformName, version); + diag.highlightChars(range); + return diag; + }); + } + } + if (auto *CE = dyn_cast(E)) { // Diagnose availability of implicit collection literal initializers. diagnoseDeclRefAvailability(CE->getInitializer(), CE->getSourceRange()); diff --git a/lib/Sema/TypeCheckRegex.cpp b/lib/Sema/TypeCheckRegex.cpp index 41ac56c76e7a8..d8731b2546276 100644 --- a/lib/Sema/TypeCheckRegex.cpp +++ b/lib/Sema/TypeCheckRegex.cpp @@ -18,6 +18,7 @@ #include "swift/AST/TypeCheckRequests.h" #include "swift/AST/Types.h" #include "swift/Basic/Assertions.h" +#include "swift/Basic/Defer.h" #include "swift/Bridging/ASTGen.h" using namespace swift; @@ -174,21 +175,59 @@ RegexLiteralPatternInfoRequest::evaluate(Evaluator &eval, auto capturesSize = getCaptureStructureSerializationAllocationSize(regexText.size()); std::vector capturesBuf(capturesSize); + + BridgedRegexLiteralPatternFeatures bridgedFeatures; + SWIFT_DEFER { + swift_ASTGen_freeBridgedRegexLiteralPatternFeatures(bridgedFeatures); + }; + bool hadError = swift_ASTGen_parseRegexLiteral( regexText, /*versionOut=*/&version, /*captureStructureOut=*/capturesBuf.data(), /*captureStructureSize=*/capturesBuf.size(), + /*patternFeaturesOut=*/&bridgedFeatures, /*diagBaseLoc=*/regex->getLoc(), &ctx.Diags); if (hadError) - return {regexText, Type(), /*version*/ 0}; + return {regexText, Type(), /*version*/ 0, /*features*/ {}}; + + SmallVector features; + for (auto &bridgedFeature : bridgedFeatures.unbridged()) + features.push_back(bridgedFeature.unbridged()); assert(version >= 1); auto regexTy = computeRegexLiteralType(regex, capturesBuf); // FIXME: We need to plumb through the 'regexToEmit' result to the caller. // For now, it is the same as the input. - return {/*regexToEmit*/ regexText, regexTy, version}; + return {/*regexToEmit*/ regexText, regexTy, version, + ctx.AllocateCopy(features)}; +#else + llvm_unreachable("Shouldn't have parsed a RegexLiteralExpr"); +#endif +} + +StringRef RegexLiteralFeatureDescriptionRequest::evaluate( + Evaluator &evaluator, RegexLiteralPatternFeatureKind kind, + ASTContext *ctx) const { +#if SWIFT_BUILD_REGEX_PARSER_IN_COMPILER + // The resulting string is allocated in the ASTContext, we can return the + // StringRef directly. + BridgedStringRef str; + swift_ASTGen_getDescriptionForRegexPatternFeature(kind, *ctx, &str); + return str.unbridged(); +#else + llvm_unreachable("Shouldn't have parsed a RegexLiteralExpr"); +#endif +} + +AvailabilityRange RegexLiteralFeatureAvailabilityRequest::evaluate( + Evaluator &evaluator, RegexLiteralPatternFeatureKind kind, + ASTContext *ctx) const { +#if SWIFT_BUILD_REGEX_PARSER_IN_COMPILER + BridgedSwiftVersion version; + swift_ASTGen_getSwiftVersionForRegexPatternFeature(kind, &version); + return ctx->getSwiftAvailability(version.getMajor(), version.getMinor()); #else llvm_unreachable("Shouldn't have parsed a RegexLiteralExpr"); #endif diff --git a/lib/Sema/TypeChecker.h b/lib/Sema/TypeChecker.h index b156fdd72edec..de724d973626f 100644 --- a/lib/Sema/TypeChecker.h +++ b/lib/Sema/TypeChecker.h @@ -1052,6 +1052,12 @@ checkConformanceAvailability(const RootProtocolConformance *Conf, const ExtensionDecl *Ext, const ExportContext &Where); +bool checkAvailability( + SourceRange ReferenceRange, AvailabilityRange RequiredAvailability, + const DeclContext *ReferenceDC, + llvm::function_ref + Diagnose); + bool checkAvailability(SourceRange ReferenceRange, AvailabilityRange RequiredAvailability, Diag Diag,