diff --git a/CHANGELOG.md b/CHANGELOG.md index 699a37a3941f6..62ddd4a071cac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,83 @@ _**Note:** This is in reverse chronological order, so newer entries are added to ## Swift 5.7 +* [SE-0338][]: + + Non-isolated async functions now always execute on the global concurrent pool, + so calling a non-isolated async function from actor-isolated code will leave + the actor. For example: + + ```swift + class C { } + + func f(_: C) async { /* always executes on the global concurrent pool */ } + + actor A { + func g(c: C) async { + /* always executes on the actor */ + print("on the actor") + + await f(c) + } + } + ``` + + Prior to this change, the call from `f` to `g` might have started execution of + `g` on the actor, which could lead to actors being busy longer than strictly + necessary. Now, the non-isolated async function will always hop to the global + cooperative pool, not run on the actor. This can result in a behavior change + for programs that assumed that a non-isolated async function called from a + `@MainActor` context will be executed on the main actor, although such + programs were already technically incorrect. + + Additionally, when leaving an actor to execution on the global cooperative + pool, `Sendable` checking will be performed, so the compiler will emit a + diagnostic in the call to `f` if `c` is not of `Sendable` type. + +* [SE-0350][]: + + The standard library has a new `Regex` type. + + This type represents an _extended regular expression_, allowing more fluent + string processing operations. A `Regex` may be created by + [initialization from a string][SE-0355]: + ``` + let pattern = "a[bc]+" // matches "a" followed by one or more instances + // of either "b" or "c" + let regex = try! Regex(pattern) + ``` + Or via a [regex literal][SE-0354]: + ``` + let regex = #/a[bc]+/# + ``` + In Swift 6, `/` will also be supported as a delimiter for `Regex` literals. + You can enable this mode in Swift 5.7 with the `-enable-bare-slash-regex` + flag. Doing so will cause some existing expressions that use `/` as an + operator to no longer compile; you can add parentheses or line breaks as a + workaround. + + There are [new string-processing algorithms][SE-0357] that support + `String`, `Regex` and arbitrary `Collection` types. + +* [SE-0329][]: + New types representing time and clocks were introduced. This includes a protocol `Clock` defining clocks which allow for defining a concept of now and a way to wake up after a given instant. Additionally a new protocol `InstantProtocol` for defining instants in time was added. Furthermore a new protocol `DurationProtocol` was added to define an elapsed duration between two given `InstantProtocol` types. Most commonly the `Clock` types for general use are the `SuspendingClock` and `ContinuousClock` which represent the most fundamental clocks for the system. The `SuspendingClock` type does not progress while the machine is suspended whereas the `ContinuousClock` progresses no matter the state of the machine. + + ```swift + func delayedHello() async throws { + try await Task.sleep(until: .now + .milliseconds(123), clock: .continuous) + print("hello delayed world") + } + ``` + + `Clock` also has methods to measure the elapsed duration of the execution of work. In the case of the `SuspendingClock` and `ContinuousClock` this measures with high resolution and is suitable for benchmarks. + + ```swift + let clock = ContinuousClock() + let elapsed = clock.measure { + someLongRunningWork() + } + ``` + * [SE-0309][]: Protocols with associated types and `Self` requirements can now be used as the @@ -72,10 +149,26 @@ _**Note:** This is in reverse chronological order, so newer entries are added to * [SE-0353][]: - Further generalizing the above, protocol-constrained types can also be used with `any`: + Protocols with primary associated types can now be used in existential types, + enabling same-type constraints on those associated types. + + ``` + let strings: any Collection = [ "Hello" ] + ``` + + Note that language features requiring runtime support like dynamic casts + (`is`, `as?`, `as!`), as well as generic usages of parameterized existentials + in generic types (e.g. `Array>`) involve additional + availability checks to use. Back-deploying usages in generic position can be + worked around with a generic type-erasing wrapper struct, which is now much + simpler to implement: ```swift - func findBestGraph(_: [any Graph]) -> any Graph {...} + struct AnyCollection { + var wrapped: any Collection + } + + let arrayOfCollections: [AnyCollection] = [ /**/ ] ``` * [SE-0358][]: @@ -9354,12 +9447,14 @@ Swift 1.0 [SE-0326]: [SE-0327]: [SE-0328]: +[SE-0329]: [SE-0331]: [SE-0333]: [SE-0334]: [SE-0335]: [SE-0336]: [SE-0337]: +[SE-0338]: [SE-0340]: [SE-0341]: [SE-0343]: @@ -9367,8 +9462,12 @@ Swift 1.0 [SE-0346]: [SE-0347]: [SE-0349]: +[SE-0350]: [SE-0352]: [SE-0353]: +[SE-0354]: +[SE-0355]: +[SE-0357]: [SE-0358]: [SR-75]: diff --git a/include/swift/AST/Availability.h b/include/swift/AST/Availability.h index 1639f899ca272..fd3cb83ea341e 100644 --- a/include/swift/AST/Availability.h +++ b/include/swift/AST/Availability.h @@ -93,6 +93,18 @@ class VersionRange { return getLowerEndpoint() >= Other.getLowerEndpoint(); } + // Returns true if all the versions in the Other range are versions in this + // range and the ranges are not equal. + bool isSupersetOf(const VersionRange &Other) const { + if (isEmpty() || Other.isAll()) + return false; + + if (isAll() || Other.isEmpty()) + return true; + + return getLowerEndpoint() < Other.getLowerEndpoint(); + } + /// Mutates this range to be a best-effort underapproximation of /// the intersection of itself and Other. This is the /// meet operation (greatest lower bound) in the version range lattice. @@ -244,10 +256,17 @@ class AvailabilityContext { /// Returns true if \p other makes stronger guarantees than this context. /// /// That is, `a.isContainedIn(b)` implies `a.union(b) == b`. - bool isContainedIn(AvailabilityContext other) const { + bool isContainedIn(const AvailabilityContext &other) const { return OSVersion.isContainedIn(other.OSVersion); } + /// Returns true if \p other is a strict subset of this context. + /// + /// That is, `a.isSupersetOf(b)` implies `a != b` and `a.union(b) == a`. + bool isSupersetOf(const AvailabilityContext &other) const { + return OSVersion.isSupersetOf(other.OSVersion); + } + /// Returns true if this context has constraints that make it impossible to /// actually occur. /// @@ -272,7 +291,7 @@ class AvailabilityContext { /// /// As an example, this is used when figuring out the required availability /// for a type that references multiple nominal decls. - void intersectWith(AvailabilityContext other) { + void intersectWith(const AvailabilityContext &other) { OSVersion.intersectWith(other.getOSVersion()); } @@ -283,7 +302,7 @@ class AvailabilityContext { /// treating some invalid deployment environments as available. /// /// As an example, this is used for the true branch of `#available`. - void constrainWith(AvailabilityContext other) { + void constrainWith(const AvailabilityContext &other) { OSVersion.constrainWith(other.getOSVersion()); } @@ -295,7 +314,7 @@ class AvailabilityContext { /// /// As an example, this is used for the else branch of a conditional with /// multiple `#available` checks. - void unionWith(AvailabilityContext other) { + void unionWith(const AvailabilityContext &other) { OSVersion.unionWith(other.getOSVersion()); } diff --git a/include/swift/AST/DiagnosticsParse.def b/include/swift/AST/DiagnosticsParse.def index c1b0879aec041..67fd180b23552 100644 --- a/include/swift/AST/DiagnosticsParse.def +++ b/include/swift/AST/DiagnosticsParse.def @@ -1816,7 +1816,10 @@ ERROR(version_component_not_number,none, ERROR(compiler_version_too_many_components,none, "compiler version must not have more than five components", ()) WARNING(unused_compiler_version_component,NoUsage, - "the second version component is not used for comparison", ()) + "the second version component is not used for comparison in legacy " + "compiler versions%select{|; are you trying to encode a new Swift " + "compiler version for compatibility with legacy compilers?}0", + (bool)) ERROR(empty_version_component,none, "found empty version component", ()) ERROR(compiler_version_component_out_of_range,none, diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index 2100ac8db0c01..c51f41f9ef8be 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -1965,6 +1965,9 @@ NOTE(non_sendable_nominal,none, NOTE(add_nominal_sendable_conformance,none, "consider making %0 %1 conform to the 'Sendable' protocol", (DescriptiveDeclKind, DeclName)) +NOTE(add_generic_parameter_sendable_conformance,none, + "consider making generic parameter %0 conform to the 'Sendable' protocol", + (Type)) REMARK(add_predates_concurrency_import,none, "add '@preconcurrency' to %select{suppress|treat}0 " "'Sendable'-related %select{warnings|errors}0 from module %1" @@ -4570,6 +4573,12 @@ ERROR(concurrent_access_of_inout_param,none, ERROR(non_sendable_capture,none, "capture of %1 with non-sendable type %0 in a `@Sendable` closure", (Type, DeclName)) +ERROR(implicit_async_let_non_sendable_capture,none, + "capture of %1 with non-sendable type %0 in 'async let' binding", + (Type, DeclName)) +ERROR(implicit_non_sendable_capture,none, + "implicit capture of %1 requires that %0 conforms to `Sendable`", + (Type, DeclName)) NOTE(actor_isolated_sync_func,none, "calls to %0 %1 from outside of its actor context are " @@ -4648,9 +4657,10 @@ ERROR(isolated_parameter_not_actor,none, WARNING(non_sendable_param_type,none, "non-sendable type %0 %select{passed in call to %4 %2 %3|" + "exiting %4 context in call to non-isolated %2 %3|" "passed in implicitly asynchronous call to %4 %2 %3|" - "in parameter of %4 %2 %3 satisfying non-isolated protocol " - "requirement|" + "in parameter of %4 %2 %3 satisfying protocol requirement|" + "in parameter of %4 overriding %2 %3|" "in parameter of %4 '@objc' %2 %3}1 cannot cross actor boundary", (Type, unsigned, DescriptiveDeclKind, DeclName, ActorIsolation)) WARNING(non_sendable_call_param_type,none, @@ -4659,8 +4669,10 @@ WARNING(non_sendable_call_param_type,none, (Type, bool, ActorIsolation)) WARNING(non_sendable_result_type,none, "non-sendable type %0 returned by %select{call to %4 %2 %3|" + "call from %4 context to non-isolated %2 %3|" "implicitly asynchronous call to %4 %2 %3|" - "%4 %2 %3 satisfying non-isolated protocol requirement|" + "%4 %2 %3 satisfying protocol requirement|" + "%4 overriding %2 %3|" "%4 '@objc' %2 %3}1 cannot cross actor boundary", (Type, unsigned, DescriptiveDeclKind, DeclName, ActorIsolation)) WARNING(non_sendable_call_result_type,none, @@ -4670,8 +4682,10 @@ WARNING(non_sendable_call_result_type,none, WARNING(non_sendable_property_type,none, "non-sendable type %0 in %select{" "%select{asynchronous access to %5 %1 %2|" + "asynchronous access from %5 context to non-isolated %1 %2|" "implicitly asynchronous access to %5 %1 %2|" - "conformance of %5 %1 %2 to non-isolated protocol requirement|" + "conformance of %5 %1 %2 to protocol requirement|" + "%5 overriding %1 %2|" "%5 '@objc' %1 %2}4|captured local %1 %2}3 cannot " "cross %select{actor|task}3 boundary", (Type, DescriptiveDeclKind, DeclName, bool, unsigned, ActorIsolation)) diff --git a/include/swift/AST/PrintOptions.h b/include/swift/AST/PrintOptions.h index de095ed34659a..e24d5c4f12f6d 100644 --- a/include/swift/AST/PrintOptions.h +++ b/include/swift/AST/PrintOptions.h @@ -285,6 +285,9 @@ struct PrintOptions { /// types. bool PrintExplicitAny = false; + /// Whether to desugar the constraint for an existential type. + bool DesugarExistentialConstraint = false; + /// Whether to skip keywords with a prefix of underscore such as __consuming. bool SkipUnderscoredKeywords = false; diff --git a/include/swift/AST/TypeRefinementContext.h b/include/swift/AST/TypeRefinementContext.h index 6b42ed83c429c..dbe492476b8b7 100644 --- a/include/swift/AST/TypeRefinementContext.h +++ b/include/swift/AST/TypeRefinementContext.h @@ -54,15 +54,19 @@ class TypeRefinementContext : public ASTAllocated { /// The root refinement context. Root, - /// The context was introduced by a declaration (e.g., the body of a - /// function declaration or the contents of a class declaration). + /// The context was introduced by a declaration with an explicit + /// availability attribute. The context contains both the signature and the + /// body of the declaration. Decl, - /// The context was introduced by an API boundary; that is, we are in - /// a module with library evolution enabled and the parent context's - /// contents can be visible to the module's clients, but this context's - /// contents are not. - APIBoundary, + /// The context was introduced implicitly by a declaration. The context may + /// cover the entire declaration or it may cover a subset of it. For + /// example, a public, non-inlinable function declaration in an API module + /// will have at least two associated contexts: one for the entire + /// declaration at the declared availability of the API and a nested + /// implicit context for the body of the function, which will always run at + /// the deployment target of the library. + DeclImplicit, /// The context was introduced for the Then branch of an IfStmt. IfStmtThenBranch, @@ -131,7 +135,8 @@ class TypeRefinementContext : public ASTAllocated { } Decl *getAsDecl() const { - assert(IntroReason == Reason::Decl || IntroReason == Reason::APIBoundary); + assert(IntroReason == Reason::Decl || + IntroReason == Reason::DeclImplicit); return D; } @@ -163,8 +168,8 @@ class TypeRefinementContext : public ASTAllocated { SourceRange SrcRange; - /// A canonical availability info for this context, computed top-down from the root - /// context (compilation deployment target). + /// A canonical availability info for this context, computed top-down from the + /// root context. AvailabilityContext AvailabilityInfo; /// If this context was annotated with an availability attribute, this property captures that. @@ -194,8 +199,8 @@ class TypeRefinementContext : public ASTAllocated { /// Create a refinement context for the given declaration. static TypeRefinementContext * - createForAPIBoundary(ASTContext &Ctx, Decl *D, TypeRefinementContext *Parent, - const AvailabilityContext &Info, SourceRange SrcRange); + createForDeclImplicit(ASTContext &Ctx, Decl *D, TypeRefinementContext *Parent, + const AvailabilityContext &Info, SourceRange SrcRange); /// Create a refinement context for the Then branch of the given IfStmt. static TypeRefinementContext * diff --git a/include/swift/Basic/LangOptions.h b/include/swift/Basic/LangOptions.h index d4525251bbc6f..279fc24b5d599 100644 --- a/include/swift/Basic/LangOptions.h +++ b/include/swift/Basic/LangOptions.h @@ -326,10 +326,6 @@ namespace swift { /// in calls to generic functions. bool EnableOpenedExistentialTypes = false; - /// Enable support for parameterized protocol types in existential - /// position. - bool EnableParameterizedExistentialTypes = false; - /// Enable experimental flow-sensitive concurrent captures. bool EnableExperimentalFlowSensitiveConcurrentCaptures = false; diff --git a/include/swift/Basic/Version.h b/include/swift/Basic/Version.h index 57ff8d90712de..d5437ba941066 100644 --- a/include/swift/Basic/Version.h +++ b/include/swift/Basic/Version.h @@ -129,7 +129,12 @@ class Version { /// Return this Version struct as the appropriate version string for APINotes. std::string asAPINotesVersionString() const; - /// Parse a version in the form used by the _compiler_version \#if condition. + /// Parse a version in the form used by the _compiler_version(string-literal) + /// \#if condition. + /// + /// \note This is \em only used for the string literal version, so it includes + /// backwards-compatibility logic to convert it to something that can be + /// compared with a modern SWIFT_COMPILER_VERSION. static Optional parseCompilerVersionString(StringRef VersionString, SourceLoc Loc, DiagnosticEngine *Diags); diff --git a/include/swift/Option/FrontendOptions.td b/include/swift/Option/FrontendOptions.td index 8266445f281aa..d13464e850cf1 100644 --- a/include/swift/Option/FrontendOptions.td +++ b/include/swift/Option/FrontendOptions.td @@ -543,10 +543,6 @@ def enable_explicit_existential_types : Flag<["-"], "enable-explicit-existential-types">, HelpText<"Enable experimental support for explicit existential types">; -def enable_parameterized_existential_types : - Flag<["-"], "enable-parameterized-existential-types">, - HelpText<"Enable experimental support for parameterized existential types">; - def enable_experimental_opened_existential_types : Flag<["-"], "enable-experimental-opened-existential-types">, HelpText<"Enable experimental support for implicitly opened existentials">; diff --git a/include/swift/SILOptimizer/Analysis/Reachability.h b/include/swift/SILOptimizer/Analysis/Reachability.h index e98f9d2901123..1eef74d1d83c3 100644 --- a/include/swift/SILOptimizer/Analysis/Reachability.h +++ b/include/swift/SILOptimizer/Analysis/Reachability.h @@ -149,7 +149,7 @@ class BackwardReachability { /// Effect effectForPhi(SILBasicBlock *); /// /// /// The uses from which reachability will begin. -/// ArrayRef gens(); +/// iterable gens(); /// } template class IterativeBackwardReachability final { diff --git a/include/swift/Sema/Constraint.h b/include/swift/Sema/Constraint.h index 7e63e3f6fae49..2f4dc15bc2b78 100644 --- a/include/swift/Sema/Constraint.h +++ b/include/swift/Sema/Constraint.h @@ -263,6 +263,8 @@ enum class ConversionRestrictionKind { ProtocolMetatypeToProtocolClass, /// Inout-to-pointer conversion. InoutToPointer, + /// Converting from `inout` to a C pointer has `PointerToCPointer` semantics. + InoutToCPointer, /// Array-to-pointer conversion. ArrayToPointer, /// String-to-pointer conversion. @@ -302,8 +304,8 @@ enum class ConversionRestrictionKind { /// via an implicit Double initializer call passing a CGFloat value. CGFloatToDouble, /// Implicit conversion between Swift and C pointers: - // - Unsafe[Mutable]RawPointer -> Unsafe[Mutable]Pointer<[U]Int> - // - Unsafe[Mutable]Pointer <-> Unsafe[Mutable]Pointer + /// - Unsafe[Mutable]RawPointer -> Unsafe[Mutable]Pointer<[U]Int> + /// - Unsafe[Mutable]Pointer <-> Unsafe[Mutable]Pointer PointerToCPointer, // Convert a pack into a type with an equivalent arity. // - If the arity of the pack is 1, drops the pack structure => T diff --git a/include/swift/SymbolGraphGen/SymbolGraphOptions.h b/include/swift/SymbolGraphGen/SymbolGraphOptions.h index 371a7a6b5e3c0..a973a60f0cf51 100644 --- a/include/swift/SymbolGraphGen/SymbolGraphOptions.h +++ b/include/swift/SymbolGraphGen/SymbolGraphOptions.h @@ -21,33 +21,33 @@ namespace symbolgraphgen { struct SymbolGraphOptions { /// The directory to output the symbol graph JSON files. - StringRef OutputDir; + StringRef OutputDir = {}; /// The target of the module. - llvm::Triple Target; + llvm::Triple Target = {}; /// Pretty-print the JSON with newlines and indentation. - bool PrettyPrint; + bool PrettyPrint = false; /// The minimum access level that symbols must have in order to be /// included in the graph. - AccessLevel MinimumAccessLevel; + AccessLevel MinimumAccessLevel = AccessLevel::Public; /// Emit members gotten through class inheritance or protocol default /// implementations with compound, "SYNTHESIZED" USRs. - bool EmitSynthesizedMembers; + bool EmitSynthesizedMembers = false; /// Whether to print informational messages when rendering /// a symbol graph. - bool PrintMessages; + bool PrintMessages = false; /// Whether to skip docs for symbols with compound, "SYNTHESIZED" USRs. - bool SkipInheritedDocs; + bool SkipInheritedDocs = false; /// Whether to emit symbols with SPI information. - bool IncludeSPISymbols; + bool IncludeSPISymbols = false; /// Whether to include documentation for clang nodes or not. - bool IncludeClangDocs; + bool IncludeClangDocs = false; }; } // end namespace symbolgraphgen diff --git a/lib/AST/ASTMangler.cpp b/lib/AST/ASTMangler.cpp index 18aa4ecb44d87..64460d9979d10 100644 --- a/lib/AST/ASTMangler.cpp +++ b/lib/AST/ASTMangler.cpp @@ -1637,6 +1637,10 @@ static bool isRetroactiveConformance(const RootProtocolConformance *root) { return false; // self-conformances are never retroactive. nor are builtin. } + // Don't consider marker protocols at all. + if (conformance->getProtocol()->isMarkerProtocol()) + return false; + return conformance->isRetroactive(); } @@ -1682,6 +1686,12 @@ void ASTMangler::appendRetroactiveConformances(SubstitutionMap subMap, unsigned numProtocolRequirements = 0; for (auto conformance : subMap.getConformances()) { + if (conformance.isInvalid()) + continue; + + if (conformance.getRequirement()->isMarkerProtocol()) + continue; + SWIFT_DEFER { ++numProtocolRequirements; }; diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp index 67600e3bc2262..1a99e633e1f0a 100644 --- a/lib/AST/ASTPrinter.cpp +++ b/lib/AST/ASTPrinter.cpp @@ -57,6 +57,7 @@ #include "clang/AST/DeclObjC.h" #include "clang/Basic/Module.h" #include "clang/Basic/SourceManager.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ConvertUTF.h" @@ -156,6 +157,7 @@ PrintOptions PrintOptions::printSwiftInterfaceFile(ModuleDecl *ModuleToPrint, result.AlwaysTryPrintParameterLabels = true; result.PrintSPIs = printSPIs; result.PrintExplicitAny = true; + result.DesugarExistentialConstraint = true; // We should print __consuming, __owned, etc for the module interface file. result.SkipUnderscoredKeywords = false; @@ -6211,7 +6213,16 @@ class TypePrinter : public TypeVisitor { if (Options.PrintExplicitAny) Printer << "any "; - visit(T->getConstraintType()); + // FIXME: The desugared type is used here only to support + // existential types with protocol typealiases in Swift + // interfaces. Verifying that the underlying type of a + // protocol typealias is a constriant type is fundamentally + // circular, so the desugared type should be written in source. + if (Options.DesugarExistentialConstraint) { + visit(T->getConstraintType()->getDesugaredType()); + } else { + visit(T->getConstraintType()); + } } void visitLValueType(LValueType *T) { @@ -6387,10 +6398,16 @@ class TypePrinter : public TypeVisitor { // Print based on the type. Printer << "some "; - if (auto inheritedType = decl->getInherited().front().getType()) - inheritedType->print(Printer, Options); - else + if (!decl->getConformingProtocols().empty()) { + llvm::interleave(decl->getConformingProtocols(), Printer, [&](ProtocolDecl *proto){ + if (auto printType = proto->getDeclaredType()) + printType->print(Printer, Options); + else + Printer << proto->getNameStr(); + }, " & "); + } else { Printer << "Any"; + } return; } diff --git a/lib/AST/TypeRefinementContext.cpp b/lib/AST/TypeRefinementContext.cpp index d0ab3efb043ba..08c21dfee9910 100644 --- a/lib/AST/TypeRefinementContext.cpp +++ b/lib/AST/TypeRefinementContext.cpp @@ -64,13 +64,13 @@ TypeRefinementContext::createForDecl(ASTContext &Ctx, Decl *D, TypeRefinementContext(Ctx, D, Parent, SrcRange, Info, ExplicitInfo); } -TypeRefinementContext *TypeRefinementContext::createForAPIBoundary( +TypeRefinementContext *TypeRefinementContext::createForDeclImplicit( ASTContext &Ctx, Decl *D, TypeRefinementContext *Parent, const AvailabilityContext &Info, SourceRange SrcRange) { assert(D); assert(Parent); return new (Ctx) TypeRefinementContext( - Ctx, IntroNode(D, Reason::APIBoundary), Parent, SrcRange, Info, + Ctx, IntroNode(D, Reason::DeclImplicit), Parent, SrcRange, Info, AvailabilityContext::alwaysAvailable()); } @@ -180,7 +180,7 @@ void TypeRefinementContext::dump(raw_ostream &OS, SourceManager &SrcMgr) const { SourceLoc TypeRefinementContext::getIntroductionLoc() const { switch (getReason()) { case Reason::Decl: - case Reason::APIBoundary: + case Reason::DeclImplicit: return Node.getAsDecl()->getLoc(); case Reason::IfStmtThenBranch: @@ -294,7 +294,7 @@ TypeRefinementContext::getAvailabilityConditionVersionSourceRange( Node.getAsWhileStmt()->getCond(), Platform, Version); case Reason::Root: - case Reason::APIBoundary: + case Reason::DeclImplicit: return SourceRange(); } @@ -308,7 +308,7 @@ void TypeRefinementContext::print(raw_ostream &OS, SourceManager &SrcMgr, OS << " versions=" << AvailabilityInfo.getOSVersion().getAsString(); - if (getReason() == Reason::Decl || getReason() == Reason::APIBoundary) { + if (getReason() == Reason::Decl || getReason() == Reason::DeclImplicit) { Decl *D = Node.getAsDecl(); OS << " decl="; if (auto VD = dyn_cast(D)) { @@ -350,8 +350,8 @@ StringRef TypeRefinementContext::getReasonName(Reason R) { case Reason::Decl: return "decl"; - case Reason::APIBoundary: - return "api_boundary"; + case Reason::DeclImplicit: + return "decl_implicit"; case Reason::IfStmtThenBranch: return "if_then"; diff --git a/lib/Basic/Version.cpp b/lib/Basic/Version.cpp index 78593fff1f5a3..17026f79b5322 100644 --- a/lib/Basic/Version.cpp +++ b/lib/Basic/Version.cpp @@ -16,6 +16,7 @@ #include "clang/Basic/CharInfo.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Support/FormatVariadic.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" #include "swift/AST/DiagnosticsParse.h" @@ -132,9 +133,29 @@ Optional Version::parseCompilerVersionString( // The second version component isn't used for comparison. if (i == 1) { if (!SplitComponent.equals("*")) { - if (Diags) - Diags->diagnose(Range.Start, diag::unused_compiler_version_component) - .fixItReplaceChars(Range.Start, Range.End, "*"); + if (Diags) { + // Majors 600-1300 were used for Swift 1.0-5.5 (based on clang + // versions), but then we reset the numbering based on Swift versions, + // so 5.6 had major 5. We assume that majors below 600 use the new + // scheme and equal/above it use the old scheme. + bool firstComponentLooksNew = CV.Components[0] < 600; + + auto diag = Diags->diagnose(Range.Start, + diag::unused_compiler_version_component, + firstComponentLooksNew); + + if (firstComponentLooksNew && + !SplitComponent.getAsInteger(10, ComponentNumber)) { + // Fix-it version like "5.7.1.2.3" to "5007.*.1.2.3". + auto newDigits = llvm::formatv("{0}{1,0+3}.*", CV.Components[0], + ComponentNumber).str(); + diag.fixItReplaceChars(SplitComponents[0].second.Start, + Range.End, newDigits); + } + else { + diag.fixItReplaceChars(Range.Start, Range.End, "*"); + } + } } CV.Components.push_back(0); @@ -159,6 +180,38 @@ Optional Version::parseCompilerVersionString( isValidVersion = false; } + // In the beginning, '_compiler_version(string-literal)' was designed for a + // different version scheme where the major was fairly large and the minor + // was ignored; now we use one where the minor is significant and major and + // minor match the Swift language version. See the comment above on + // `firstComponentLooksNew` for details. + // + // However, we want the string literal variant of '_compiler_version' to + // maintain source compatibility with old checks; that means checks for new + // versions have to be written so that old compilers will think they represent + // newer versions, while new compilers have to interpret old version number + // strings in a way that will compare correctly to the new versions compiled + // into them. + // + // To achieve this, modern compilers divide the major by 1000 and overwrite + // the wildcard component with the remainder, effectively shifting the last + // three digits of the major into the minor, before comparing it to the + // compiler version: + // + // _compiler_version("5007.*.1.2.3") -> 5.7.1.2.3 + // _compiler_version("1300.*.1.2.3") -> 1.300.1.2.3 (smaller than 5.6) + // _compiler_version( "600.*.1.2.3") -> 0.600.1.2.3 (smaller than 5.6) + // + // So if you want to specify a 5.7.z.a.b version, we ask users to either write + // it as 5007.*.z.a.b, or to use the new '_compiler_version(>= version)' + // syntax instead, which does not perform this conversion. + if (!CV.Components.empty()) { + if (CV.Components.size() == 1) + CV.Components.push_back(0); + CV.Components[1] = CV.Components[0] % 1000; + CV.Components[0] = CV.Components[0] / 1000; + } + return isValidVersion ? Optional(CV) : None; } diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp index 5267532c8b358..8dd8c7ba1f2cb 100644 --- a/lib/ClangImporter/ClangImporter.cpp +++ b/lib/ClangImporter/ClangImporter.cpp @@ -687,9 +687,15 @@ importer::getNormalInvocationArguments( // declarations. auto V = version::Version::getCurrentCompilerVersion(); if (!V.empty()) { + // Note: Prior to Swift 5.7, the "Y" version component was omitted and the + // "X" component resided in its digits. invocationArgStrs.insert(invocationArgStrs.end(), { V.preprocessorDefinition("__SWIFT_COMPILER_VERSION", - {1000000000, /*ignored*/ 0, 1000000, 1000, 1}), + {1000000000000, // X + 1000000000, // Y + 1000000, // Z + 1000, // a + 1}), // b }); } } else { diff --git a/lib/ClangImporter/SwiftLookupTable.h b/lib/ClangImporter/SwiftLookupTable.h index e132b135cd0fa..99f81be41834b 100644 --- a/lib/ClangImporter/SwiftLookupTable.h +++ b/lib/ClangImporter/SwiftLookupTable.h @@ -21,6 +21,7 @@ #include "swift/Basic/LLVM.h" #include "swift/AST/Identifier.h" #include "clang/AST/Decl.h" +#include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" #include "clang/Serialization/ASTBitCodes.h" #include "clang/Serialization/ModuleFileExtension.h" @@ -197,6 +198,8 @@ class EffectiveClangContext { DC = omDecl->getCanonicalDecl(); } else if (auto fDecl = dyn_cast(dc)) { DC = fDecl->getCanonicalDecl(); + } else if (auto externCDecl = dyn_cast(dc)) { + DC = externCDecl->getLexicalDeclContext(); } else { assert(isa(dc) || isa(dc) || diff --git a/lib/DriverTool/autolink_extract_main.cpp b/lib/DriverTool/autolink_extract_main.cpp index 52487901422e4..4e12df23080ab 100644 --- a/lib/DriverTool/autolink_extract_main.cpp +++ b/lib/DriverTool/autolink_extract_main.cpp @@ -113,6 +113,7 @@ class AutolinkExtractInvocation { static bool extractLinkerFlagsFromObjectFile(const llvm::object::ObjectFile *ObjectFile, std::vector &LinkerFlags, + std::unordered_map &SwiftRuntimeLibraries, CompilerInstance &Instance) { // Search for the section we hold autolink entries in for (auto &Section : ObjectFile->sections()) { @@ -140,8 +141,13 @@ extractLinkerFlagsFromObjectFile(const llvm::object::ObjectFile *ObjectFile, llvm::SmallVector SplitFlags; SectionData->split(SplitFlags, llvm::StringRef("\0", 1), -1, /*KeepEmpty=*/false); - for (const auto &Flag : SplitFlags) - LinkerFlags.push_back(Flag.str()); + for (const auto &Flag : SplitFlags) { + auto RuntimeLibEntry = SwiftRuntimeLibraries.find(Flag.str()); + if (RuntimeLibEntry == SwiftRuntimeLibraries.end()) + LinkerFlags.emplace_back(Flag.str()); + else + RuntimeLibEntry->second = true; + } } } return false; @@ -154,12 +160,13 @@ extractLinkerFlagsFromObjectFile(const llvm::object::ObjectFile *ObjectFile, static bool extractLinkerFlags(const llvm::object::Binary *Bin, CompilerInstance &Instance, StringRef BinaryFileName, - std::vector &LinkerFlags) { + std::vector &LinkerFlags, + std::unordered_map &SwiftRuntimeLibraries) { if (auto *ObjectFile = llvm::dyn_cast(Bin)) { - return extractLinkerFlagsFromObjectFile(ObjectFile, LinkerFlags, Instance); + return extractLinkerFlagsFromObjectFile(ObjectFile, LinkerFlags, SwiftRuntimeLibraries, Instance); } else if (auto *ObjectFile = llvm::dyn_cast(Bin)) { - return extractLinkerFlagsFromObjectFile(ObjectFile, LinkerFlags, Instance); + return extractLinkerFlagsFromObjectFile(ObjectFile, LinkerFlags, SwiftRuntimeLibraries, Instance); } else if (auto *Archive = llvm::dyn_cast(Bin)) { llvm::Error Error = llvm::Error::success(); for (const auto &Child : Archive->children(Error)) { @@ -173,7 +180,7 @@ static bool extractLinkerFlags(const llvm::object::Binary *Bin, return true; } if (extractLinkerFlags(ChildBinary->get(), Instance, BinaryFileName, - LinkerFlags)) { + LinkerFlags, SwiftRuntimeLibraries)) { return true; } } @@ -205,6 +212,15 @@ int autolink_extract_main(ArrayRef Args, const char *Argv0, std::vector LinkerFlags; + // Keep track of whether we've already added the common + // Swift libraries that ususally have autolink directives + // in most object fiels + std::unordered_map SwiftRuntimeLibraries = { + {"-lswiftSwiftOnoneSupport", false}, + {"-lswiftCore", false}, + {"-lswift_Concurrency", false}, + }; + // Extract the linker flags from the objects. for (const auto &BinaryFileName : Invocation.getInputFilenames()) { auto BinaryOwner = llvm::object::createBinary(BinaryFileName); @@ -221,7 +237,7 @@ int autolink_extract_main(ArrayRef Args, const char *Argv0, } if (extractLinkerFlags(BinaryOwner->getBinary(), Instance, BinaryFileName, - LinkerFlags)) { + LinkerFlags, SwiftRuntimeLibraries)) { return 1; } } @@ -240,5 +256,11 @@ int autolink_extract_main(ArrayRef Args, const char *Argv0, OutOS << Flag << '\n'; } + for (const auto &RuntimeLib : SwiftRuntimeLibraries) { + if (RuntimeLib.second) + OutOS << RuntimeLib.first << '\n'; + } + + return 0; } diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 47abf96b9be15..724e26ccb042d 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -456,9 +456,6 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args, Opts.EnableExperimentalNamedOpaqueTypes |= Args.hasArg(OPT_enable_experimental_named_opaque_types); - Opts.EnableParameterizedExistentialTypes |= - Args.hasArg(OPT_enable_parameterized_existential_types); - Opts.EnableOpenedExistentialTypes = Args.hasFlag(OPT_enable_experimental_opened_existential_types, OPT_disable_experimental_opened_existential_types, @@ -1260,6 +1257,7 @@ static void ParseSymbolGraphArgs(symbolgraphgen::SymbolGraphOptions &Opts, Opts.PrettyPrint = false; Opts.EmitSynthesizedMembers = true; Opts.PrintMessages = false; + Opts.IncludeClangDocs = false; } static bool ParseSearchPathArgs(SearchPathOptions &Opts, diff --git a/lib/IRGen/SwiftTargetInfo.cpp b/lib/IRGen/SwiftTargetInfo.cpp index 9ed07c4a20bb7..a09f66209f7d8 100644 --- a/lib/IRGen/SwiftTargetInfo.cpp +++ b/lib/IRGen/SwiftTargetInfo.cpp @@ -257,6 +257,7 @@ SwiftTargetInfo SwiftTargetInfo::get(IRGenModule &IGM) { case llvm::Triple::wasm32: configureWasm32(IGM, triple, target); break; + default: // FIXME: Complain here? Default target info is unlikely to be correct. break; diff --git a/lib/Parse/ParseIfConfig.cpp b/lib/Parse/ParseIfConfig.cpp index b78a4bd92af64..5b000ea78de33 100644 --- a/lib/Parse/ParseIfConfig.cpp +++ b/lib/Parse/ParseIfConfig.cpp @@ -283,30 +283,26 @@ class ValidateIfConfigCondition : } // '_compiler_version' '(' string-literal ')' if (*KindName == "_compiler_version") { - auto SLE = dyn_cast(Arg); - if (!SLE) { - D.diagnose(Arg->getLoc(), - diag::unsupported_platform_condition_argument, - "string literal"); - return nullptr; - } - - auto ValStr = SLE->getValue(); - if (ValStr.empty()) { - D.diagnose(SLE->getLoc(), diag::empty_version_string); - return nullptr; + if (auto SLE = dyn_cast(Arg)) { + auto ValStr = SLE->getValue(); + if (ValStr.empty()) { + D.diagnose(SLE->getLoc(), diag::empty_version_string); + return nullptr; + } + + auto Val = version::Version::parseCompilerVersionString( + SLE->getValue(), SLE->getLoc(), &D); + if (!Val.hasValue()) + return nullptr; + return E; } - - auto Val = version::Version::parseCompilerVersionString( - SLE->getValue(), SLE->getLoc(), &D); - if (!Val.hasValue()) - return nullptr; - return E; } // 'swift' '(' ('>=' | '<') float-literal ( '.' integer-literal )* ')' // 'compiler' '(' ('>=' | '<') float-literal ( '.' integer-literal )* ')' - if (*KindName == "swift" || *KindName == "compiler") { + // '_compiler_version' '(' ('>=' | '<') float-literal ( '.' integer-literal )* ')' + if (*KindName == "swift" || *KindName == "compiler" || + *KindName == "_compiler_version") { auto PUE = dyn_cast(Arg); Optional PrefixName = PUE ? getDeclRefStr(PUE->getFn(), DeclRefKind::PrefixOperator) : None; @@ -500,28 +496,30 @@ class EvaluateIfConfigCondition : bool visitCallExpr(CallExpr *E) { auto KindName = getDeclRefStr(E->getFn()); auto *Arg = getSingleSubExp(E->getArgs(), KindName, nullptr); - if (KindName == "_compiler_version") { + if (KindName == "_compiler_version" && isa(Arg)) { auto Str = cast(Arg)->getValue(); auto Val = version::Version::parseCompilerVersionString( Str, SourceLoc(), nullptr).getValue(); auto thisVersion = version::Version::getCurrentCompilerVersion(); return thisVersion >= Val; - } else if ((KindName == "swift") || (KindName == "compiler")) { + } else if ((KindName == "swift") || (KindName == "compiler") || + (KindName == "_compiler_version")) { auto PUE = cast(Arg); auto PrefixName = getDeclRefStr(PUE->getFn()); auto Str = extractExprSource(Ctx.SourceMgr, PUE->getOperand()); auto Val = version::Version::parseVersionString( Str, SourceLoc(), nullptr).getValue(); + version::Version thisVersion; if (KindName == "swift") { - return isValidVersion(Ctx.LangOpts.EffectiveLanguageVersion, Val, - PrefixName); + thisVersion = Ctx.LangOpts.EffectiveLanguageVersion; } else if (KindName == "compiler") { - auto currentLanguageVersion = - version::Version::getCurrentLanguageVersion(); - return isValidVersion(currentLanguageVersion, Val, PrefixName); + thisVersion = version::Version::getCurrentLanguageVersion(); + } else if (KindName == "_compiler_version") { + thisVersion = version::Version::getCurrentCompilerVersion(); } else { llvm_unreachable("unsupported version conditional"); } + return isValidVersion(thisVersion, Val, PrefixName); } else if (KindName == "canImport") { auto Str = extractExprSource(Ctx.SourceMgr, Arg); bool underlyingModule = false; diff --git a/lib/Parse/ParseType.cpp b/lib/Parse/ParseType.cpp index f69ccf2cb7a8c..ee25cb2f8c7d0 100644 --- a/lib/Parse/ParseType.cpp +++ b/lib/Parse/ParseType.cpp @@ -881,13 +881,20 @@ Parser::parseTypeSimpleOrComposition(Diag<> MessageID, ParseTypeReason reason) { Tok.isContextualKeyword("any")) { auto keyword = Tok.getText(); auto badLoc = consumeToken(); + + // Suggest moving `some` or `any` in front of the first type unless + // the first type is an opaque or existential type. + if (opaqueLoc.isValid() || anyLoc.isValid()) { + diagnose(badLoc, diag::opaque_mid_composition, keyword) + .fixItRemove(badLoc); + } else { + diagnose(badLoc, diag::opaque_mid_composition, keyword) + .fixItRemove(badLoc) + .fixItInsert(FirstTypeLoc, keyword.str() + " "); + } const bool isAnyKeyword = keyword.equals("any"); - diagnose(badLoc, diag::opaque_mid_composition, keyword) - .fixItRemove(badLoc) - .fixItInsert(FirstTypeLoc, keyword.str() + " "); - if (isAnyKeyword) { if (anyLoc.isInvalid()) { anyLoc = badLoc; diff --git a/lib/Parse/SyntaxRegexFallbackLexing.cpp b/lib/Parse/SyntaxRegexFallbackLexing.cpp index 49da5deb8addf..7a0077665fddf 100644 --- a/lib/Parse/SyntaxRegexFallbackLexing.cpp +++ b/lib/Parse/SyntaxRegexFallbackLexing.cpp @@ -114,7 +114,7 @@ bool syntaxparse_lexRegexLiteral( case '\0': { if (Ptr - 1 == BufferEnd) { // Reached to EOF. - diagnose(BridgedDiagEngine, Ptr, diag::lex_regex_literal_unterminated); + diagnose(BridgedDiagEngine, Ptr - 1, diag::lex_regex_literal_unterminated); // In multi-line mode, we don't want to skip over what is likely // otherwise valid Swift code, so resume from the first newline. *InputPtr = firstNewline ? firstNewline : (Ptr - 1); diff --git a/lib/PrintAsClang/CMakeLists.txt b/lib/PrintAsClang/CMakeLists.txt index 7cde5669e33b1..7c283683e1b16 100644 --- a/lib/PrintAsClang/CMakeLists.txt +++ b/lib/PrintAsClang/CMakeLists.txt @@ -5,7 +5,8 @@ add_swift_host_library(swiftPrintAsClang STATIC ModuleContentsWriter.cpp PrimitiveTypeMapping.cpp PrintAsClang.cpp - PrintClangFunction.cpp) + PrintClangFunction.cpp + PrintClangValueType.cpp) target_link_libraries(swiftPrintAsClang PRIVATE swiftAST swiftClangImporter diff --git a/lib/PrintAsClang/DeclAndTypePrinter.cpp b/lib/PrintAsClang/DeclAndTypePrinter.cpp index 598cfe2ba9be1..68fe29479a5ca 100644 --- a/lib/PrintAsClang/DeclAndTypePrinter.cpp +++ b/lib/PrintAsClang/DeclAndTypePrinter.cpp @@ -14,6 +14,7 @@ #include "ClangSyntaxPrinter.h" #include "PrimitiveTypeMapping.h" #include "PrintClangFunction.h" +#include "PrintClangValueType.h" #include "swift/AST/ASTContext.h" #include "swift/AST/ASTMangler.h" @@ -327,6 +328,14 @@ class DeclAndTypePrinter::Implementation os << "@end\n"; } + void visitStructDecl(StructDecl *SD) { + if (outputLang != OutputLanguageMode::Cxx) + return; + // FIXME: Print struct's availability. + ClangValueTypePrinter printer(os); + printer.printStructDecl(SD); + } + void visitExtensionDecl(ExtensionDecl *ED) { if (isEmptyExtensionDecl(ED)) return; diff --git a/lib/PrintAsClang/ModuleContentsWriter.cpp b/lib/PrintAsClang/ModuleContentsWriter.cpp index fea9e0338367f..9424afb5bc0e8 100644 --- a/lib/PrintAsClang/ModuleContentsWriter.cpp +++ b/lib/PrintAsClang/ModuleContentsWriter.cpp @@ -409,6 +409,13 @@ class ModuleWriter { return true; } + bool writeStruct(const StructDecl *SD) { + if (addImport(SD)) + return true; + printer.print(SD); + return true; + } + bool writeProtocol(const ProtocolDecl *PD) { if (addImport(PD)) return true; @@ -584,6 +591,8 @@ class ModuleWriter { if (outputLangMode == OutputLanguageMode::Cxx) { if (auto FD = dyn_cast(D)) success = writeFunc(FD); + if (auto SD = dyn_cast(D)) + success = writeStruct(SD); // FIXME: Warn on unsupported exported decl. } else if (isa(D)) { if (auto CD = dyn_cast(D)) diff --git a/lib/PrintAsClang/PrintClangValueType.cpp b/lib/PrintAsClang/PrintClangValueType.cpp new file mode 100644 index 0000000000000..c52ebe70d2cbc --- /dev/null +++ b/lib/PrintAsClang/PrintClangValueType.cpp @@ -0,0 +1,33 @@ +//===--- PrintClangValueType.cpp - Printer for C/C++ value types *- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#include "PrintClangValueType.h" +#include "ClangSyntaxPrinter.h" +#include "DeclAndTypePrinter.h" +#include "OutputLanguageMode.h" +#include "PrimitiveTypeMapping.h" +#include "swift/AST/Decl.h" +#include "swift/AST/ParameterList.h" +#include "swift/AST/Type.h" +#include "swift/AST/TypeVisitor.h" +#include "swift/ClangImporter/ClangImporter.h" +#include "llvm/ADT/STLExtras.h" + +using namespace swift; + +void ClangValueTypePrinter::printStructDecl(const StructDecl *SD) { + os << "class "; + ClangSyntaxPrinter(os).printIdentifier(SD->getName().str()); + os << " final {\n"; + // FIXME: Print the members of the struct. + os << "};\n"; +} diff --git a/lib/PrintAsClang/PrintClangValueType.h b/lib/PrintAsClang/PrintClangValueType.h new file mode 100644 index 0000000000000..eeb267608b552 --- /dev/null +++ b/lib/PrintAsClang/PrintClangValueType.h @@ -0,0 +1,39 @@ +//===--- PrintClangValueType.h - Printer for C/C++ value types --*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#ifndef SWIFT_PRINTASCLANG_PRINTCLANGVALUETYPE_H +#define SWIFT_PRINTASCLANG_PRINTCLANGVALUETYPE_H + +#include "swift/Basic/LLVM.h" +#include "llvm/Support/raw_ostream.h" + +namespace swift { + +class StructDecl; + +/// Responsible for printing a Swift struct or enum decl or in C or C++ mode, to +/// be included in a Swift module's generated clang header. +class ClangValueTypePrinter { +public: + ClangValueTypePrinter(raw_ostream &os) : os(os) {} + + /// Print the C struct thunk or the C++ class definition that + /// corresponds to the given structure declaration. + void printStructDecl(const StructDecl *SD); + +private: + raw_ostream &os; +}; + +} // end namespace swift + +#endif diff --git a/lib/SILOptimizer/Transforms/SSADestroyHoisting.cpp b/lib/SILOptimizer/Transforms/SSADestroyHoisting.cpp index df81319a3d424..8e02d310f56c3 100644 --- a/lib/SILOptimizer/Transforms/SSADestroyHoisting.cpp +++ b/lib/SILOptimizer/Transforms/SSADestroyHoisting.cpp @@ -111,7 +111,7 @@ struct KnownStorageUses : UniqueStorageUseVisitor { bool preserveDebugInfo; SmallPtrSet storageUsers; - SmallVector originalDestroys; + SmallSetVector originalDestroys; SmallPtrSet debugInsts; KnownStorageUses(AccessStorage storage, SILFunction *function) @@ -158,7 +158,7 @@ struct KnownStorageUses : UniqueStorageUseVisitor { bool visitStore(Operand *use) override { return recordUser(use->getUser()); } bool visitDestroy(Operand *use) override { - originalDestroys.push_back(use->getUser()); + originalDestroys.insert(use->getUser()); return true; } @@ -283,9 +283,7 @@ class DeinitBarriers final { /// IterativeBackwardReachability::Effects /// VisitBarrierAccessScopes::Effects - ArrayRef gens() { - return result.knownUses.originalDestroys; - } + auto gens() { return result.knownUses.originalDestroys; } Effect effectForInstruction(SILInstruction *instruction); @@ -366,8 +364,7 @@ bool DeinitBarriers::classificationIsBarrier(Classification classification) { DeinitBarriers::DestroyReachability::Effect DeinitBarriers::DestroyReachability::effectForInstruction( SILInstruction *instruction) { - if (llvm::find(result.knownUses.originalDestroys, instruction) != - result.knownUses.originalDestroys.end()) + if (result.knownUses.originalDestroys.contains(instruction)) return Effect::Gen(); auto classification = result.classifyInstruction(instruction); if (recordDeadUsers && classification == Classification::DeadUser) diff --git a/lib/SILOptimizer/Utils/LexicalDestroyHoisting.cpp b/lib/SILOptimizer/Utils/LexicalDestroyHoisting.cpp index 2467b54ccb268..91a1374b245a2 100644 --- a/lib/SILOptimizer/Utils/LexicalDestroyHoisting.cpp +++ b/lib/SILOptimizer/Utils/LexicalDestroyHoisting.cpp @@ -20,6 +20,7 @@ #include "swift/SIL/SILInstruction.h" #include "swift/SIL/SILValue.h" #include "swift/SILOptimizer/Analysis/Reachability.h" +#include "swift/SILOptimizer/Analysis/VisitBarrierAccessScopes.h" #include "swift/SILOptimizer/Utils/CanonicalizeBorrowScope.h" #include "swift/SILOptimizer/Utils/InstOptUtils.h" #include "swift/SILOptimizer/Utils/InstructionDeleter.h" @@ -43,6 +44,8 @@ struct Context final { /// value->getDefiningInstruction() SILInstruction *const definition; + SILBasicBlock *defBlock; + SILFunction &function; InstructionDeleter &deleter; @@ -50,7 +53,8 @@ struct Context final { Context(SILValue const &value, SILFunction &function, InstructionDeleter &deleter) : value(value), definition(value->getDefiningInstruction()), - function(function), deleter(deleter) { + defBlock(value->getParentBlock()), function(function), + deleter(deleter) { assert(value->isLexical()); assert(value->getOwnershipKind() == OwnershipKind::Owned); } @@ -95,95 +99,108 @@ bool findUsage(Context const &context, Usage &usage) { /// How destroy_value hoisting is obstructed. struct DeinitBarriers final { - /// Blocks up to "before the beginning" of which hoisting was able to proceed. - BasicBlockSetVector hoistingReachesBeginBlocks; - - /// Blocks to "after the end" of which hoisting was able to proceed. - BasicBlockSet hoistingReachesEndBlocks; - /// Instructions above which destroy_values cannot be hoisted. - SmallVector barriers; + SmallVector instructions; /// Blocks one of whose phis is a barrier and consequently out of which /// destroy_values cannot be hoisted. - SmallVector phiBarriers; + SmallVector phis; - DeinitBarriers(Context &context) - : hoistingReachesBeginBlocks(&context.function), - hoistingReachesEndBlocks(&context.function) {} + SmallVector blocks; + + DeinitBarriers(Context &context) {} DeinitBarriers(DeinitBarriers const &) = delete; DeinitBarriers &operator=(DeinitBarriers const &) = delete; }; +class BarrierAccessScopeFinder; + /// Works backwards from the current location of destroy_values to the earliest /// place they can be hoisted to. /// -/// Implements BackwardReachability::BlockReachability. -class DataFlow final { +/// Implements IterativeBackwardReachability::Effects +/// Implements IterativeBackwardReachability::bindBarriers::Visitor +/// Implements VisitBarrierAccessScopes::Effects +class Dataflow final { + using Reachability = IterativeBackwardReachability; + using Effect = Reachability::Effect; Context const &context; Usage const &uses; - DeinitBarriers &result; + DeinitBarriers &barriers; + Reachability::Result result; + Reachability reachability; + SmallPtrSet barrierAccessScopes; enum class Classification { Barrier, Other }; - BackwardReachability reachability; - public: - DataFlow(Context const &context, Usage const &uses, DeinitBarriers &result) - : context(context), uses(uses), result(result), - reachability(&context.function, *this) { - // Seed reachability with the scope ending uses from which the backwards - // data flow will begin. - for (auto *end : uses.ends) { - reachability.initLastUse(end); - } - } - DataFlow(DataFlow const &) = delete; - DataFlow &operator=(DataFlow const &) = delete; + Dataflow(Context const &context, Usage const &uses, DeinitBarriers &barriers) + : context(context), uses(uses), barriers(barriers), + result(&context.function), + reachability(&context.function, context.defBlock, *this, result) {} + Dataflow(Dataflow const &) = delete; + Dataflow &operator=(Dataflow const &) = delete; - void run() { reachability.solveBackward(); } + void run(); private: - friend class BackwardReachability; + friend Reachability; + friend class BarrierAccessScopeFinder; + friend class VisitBarrierAccessScopes; - bool hasReachableBegin(SILBasicBlock *block) { - return result.hoistingReachesBeginBlocks.contains(block); - } + Classification classifyInstruction(SILInstruction *); - void markReachableBegin(SILBasicBlock *block) { - result.hoistingReachesBeginBlocks.insert(block); - } + bool classificationIsBarrier(Classification); - void markReachableEnd(SILBasicBlock *block) { - result.hoistingReachesEndBlocks.insert(block); - } + /// IterativeBackwardReachability::Effects + /// VisitBarrierAccessScopes::Effects - Classification classifyInstruction(SILInstruction *); + auto gens() { return uses.ends; } - bool classificationIsBarrier(Classification); + Effect effectForInstruction(SILInstruction *); + Effect effectForPhi(SILBasicBlock *); + + /// VisitBarrierAccessScopes::Effects + + auto localGens() { return result.localGens; } - void visitedInstruction(SILInstruction *, Classification); + bool isLocalGen(SILInstruction *instruction) { + return result.localGens.contains(instruction); + } + + /// IterativeBackwardReachability::bindBarriers::Visitor + + void visitBarrierInstruction(SILInstruction *instruction) { + barriers.instructions.push_back(instruction); + } - bool checkReachableBarrier(SILInstruction *); + void visitBarrierPhi(SILBasicBlock *block) { barriers.phis.push_back(block); } - bool checkReachablePhiBarrier(SILBasicBlock *); + void visitBarrierBlock(SILBasicBlock *block) { + barriers.blocks.push_back(block); + } }; -DataFlow::Classification -DataFlow::classifyInstruction(SILInstruction *instruction) { +Dataflow::Classification +Dataflow::classifyInstruction(SILInstruction *instruction) { if (instruction == context.definition) { return Classification::Barrier; } if (uses.users.contains(instruction)) { return Classification::Barrier; } + if (auto *eai = dyn_cast(instruction)) { + return barrierAccessScopes.contains(eai->getBeginAccess()) + ? Classification::Barrier + : Classification::Other; + } if (isDeinitBarrier(instruction)) { return Classification::Barrier; } return Classification::Other; } -bool DataFlow::classificationIsBarrier(Classification classification) { +bool Dataflow::classificationIsBarrier(Classification classification) { switch (classification) { case Classification::Barrier: return true; @@ -193,26 +210,15 @@ bool DataFlow::classificationIsBarrier(Classification classification) { llvm_unreachable("exhaustive switch not exhaustive?!"); } -void DataFlow::visitedInstruction(SILInstruction *instruction, - Classification classification) { - assert(classifyInstruction(instruction) == classification); - switch (classification) { - case Classification::Barrier: - result.barriers.push_back(instruction); - return; - case Classification::Other: - return; - } - llvm_unreachable("exhaustive switch not exhaustive?!"); -} - -bool DataFlow::checkReachableBarrier(SILInstruction *instruction) { +Dataflow::Effect Dataflow::effectForInstruction(SILInstruction *instruction) { + if (uses.ends.contains(instruction)) + return Effect::Gen(); auto classification = classifyInstruction(instruction); - visitedInstruction(instruction, classification); - return classificationIsBarrier(classification); + return classificationIsBarrier(classification) ? Effect::Kill() + : Effect::NoEffect(); } -bool DataFlow::checkReachablePhiBarrier(SILBasicBlock *block) { +Dataflow::Effect Dataflow::effectForPhi(SILBasicBlock *block) { assert(llvm::all_of(block->getArguments(), [&](auto argument) { return PhiValue(argument); })); @@ -221,10 +227,46 @@ bool DataFlow::checkReachablePhiBarrier(SILBasicBlock *block) { return classificationIsBarrier( classifyInstruction(predecessor->getTerminator())); }); - if (isBarrier) { - result.phiBarriers.push_back(block); + return isBarrier ? Effect::Kill() : Effect::NoEffect(); +} + +/// Finds end_access instructions which are barriers to hoisting because the +/// access scopes they contain barriers to hoisting. Hoisting destroy_values +/// into such access scopes could introduce exclusivity violations. +/// +/// Implements BarrierAccessScopeFinder::Visitor +class BarrierAccessScopeFinder final { + using Impl = VisitBarrierAccessScopes; + Impl impl; + Dataflow &dataflow; + +public: + BarrierAccessScopeFinder(Context const &context, Dataflow &dataflow) + : impl(&context.function, dataflow, *this), dataflow(dataflow) {} + + void find() { impl.visit(); } + +private: + friend Impl; + + bool isInRegion(SILBasicBlock *block) { + return dataflow.result.discoveredBlocks.contains(block); + } + + void visitBarrierAccessScope(BeginAccessInst *bai) { + dataflow.barrierAccessScopes.insert(bai); + for (auto *eai : bai->getEndAccesses()) { + dataflow.reachability.addKill(eai); + } } - return isBarrier; +}; + +void Dataflow::run() { + reachability.initialize(); + BarrierAccessScopeFinder finder(context, *this); + finder.find(); + reachability.solve(); + reachability.findBarriers(*this); } /// Hoist the destroy_values of %value. @@ -256,7 +298,7 @@ bool Rewriter::run() { // // A block is a phi barrier iff any of its predecessors' terminators get // classified as barriers. - for (auto *block : barriers.phiBarriers) { + for (auto *block : barriers.phis) { madeChange |= createDestroyValue(&block->front()); } @@ -271,13 +313,9 @@ bool Rewriter::run() { // have returned true for P, so none of its instructions would ever have been // classified (except for via checkReachablePhiBarrier, which doesn't record // terminator barriers). - for (auto instruction : barriers.barriers) { + for (auto instruction : barriers.instructions) { if (auto *terminator = dyn_cast(instruction)) { auto successors = terminator->getParentBlock()->getSuccessorBlocks(); - // In order for the instruction to have been classified as a barrier, - // reachability would have had to reach the block containing it. - assert(barriers.hoistingReachesEndBlocks.contains( - terminator->getParentBlock())); for (auto *successor : successors) { madeChange |= createDestroyValue(&successor->front()); } @@ -301,12 +339,8 @@ bool Rewriter::run() { // P not having a reachable end--see BackwardReachability::meetOverSuccessors. // // control-flow-boundary(B) := beginning-reachable(B) && !end-reachable(P) - for (auto *block : barriers.hoistingReachesBeginBlocks) { - if (auto *predecessor = block->getSinglePredecessorBlock()) { - if (!barriers.hoistingReachesEndBlocks.contains(predecessor)) { - madeChange |= createDestroyValue(&block->front()); - } - } + for (auto *block : barriers.blocks) { + madeChange |= createDestroyValue(&block->front()); } if (madeChange) { @@ -324,7 +358,7 @@ bool Rewriter::run() { bool Rewriter::createDestroyValue(SILInstruction *insertionPoint) { if (auto *ebi = dyn_cast(insertionPoint)) { - if (uses.ends.contains(insertionPoint)) { + if (llvm::find(uses.ends, insertionPoint) != uses.ends.end()) { reusedDestroyValueInsts.insert(insertionPoint); return false; } @@ -342,7 +376,7 @@ bool run(Context &context) { return false; DeinitBarriers barriers(context); - DataFlow flow(context, usage, barriers); + Dataflow flow(context, usage, barriers); flow.run(); Rewriter rewriter(context, usage, barriers); diff --git a/lib/SILOptimizer/Utils/ShrinkBorrowScope.cpp b/lib/SILOptimizer/Utils/ShrinkBorrowScope.cpp index a37d7c36d933f..da994b085e4c0 100644 --- a/lib/SILOptimizer/Utils/ShrinkBorrowScope.cpp +++ b/lib/SILOptimizer/Utils/ShrinkBorrowScope.cpp @@ -21,6 +21,7 @@ #include "swift/SIL/SILBasicBlock.h" #include "swift/SIL/SILInstruction.h" #include "swift/SILOptimizer/Analysis/Reachability.h" +#include "swift/SILOptimizer/Analysis/VisitBarrierAccessScopes.h" #include "swift/SILOptimizer/Utils/CanonicalizeBorrowScope.h" #include "swift/SILOptimizer/Utils/InstOptUtils.h" #include "swift/SILOptimizer/Utils/InstructionDeleter.h" @@ -49,6 +50,8 @@ struct Context final { /// introducer->getOperand() SILValue const borrowee; + SILBasicBlock *defBlock; + SILFunction &function; /// The copy_value instructions that the utility creates or changes. @@ -62,7 +65,8 @@ struct Context final { SmallVectorImpl &modifiedCopyValueInsts, InstructionDeleter &deleter) : introducer(introducer), borrowedValue(BorrowedValue(&introducer)), - borrowee(introducer.getOperand()), function(*introducer.getFunction()), + borrowee(introducer.getOperand()), defBlock(introducer.getParent()), + function(*introducer.getFunction()), modifiedCopyValueInsts(modifiedCopyValueInsts), deleter(deleter) {} Context(Context const &) = delete; Context &operator=(Context const &) = delete; @@ -112,81 +116,96 @@ bool findUsage(Context const &context, Usage &usage) { /// How end_borrow hoisting is obstructed. struct DeinitBarriers final { - /// Blocks up to "before the beginning" of which hoisting was able to proceed. - BasicBlockSetVector hoistingReachesBeginBlocks; - - /// Blocks to "after the end" of which hoisting was able to proceed. - BasicBlockSet hoistingReachesEndBlocks; - /// Copies to be rewritten as copies of %borrowee. SmallVector copies; /// Instructions above which end_borrows cannot be hoisted. - SmallVector barriers; + SmallVector instructions; /// Blocks one of whose phis is a barrier and consequently out of which /// end_borrows cannot be hoisted. - SmallVector phiBarriers; + SmallVector phis; - DeinitBarriers(Context &context) - : hoistingReachesBeginBlocks(&context.function), - hoistingReachesEndBlocks(&context.function) {} + /// Blocks whose single predecessors has another successor to the top of which + /// end_borrows cannot be hoisted. + SmallVector blocks; + + DeinitBarriers(Context &context) {} DeinitBarriers(DeinitBarriers const &) = delete; DeinitBarriers &operator=(DeinitBarriers const &) = delete; }; +class BarrierAccessScopeFinder; + /// Works backwards from the current location of end_borrows to the earliest /// place they can be hoisted to. /// -/// Implements BackwardReachability::BlockReachability. -class DataFlow final { +/// Implements IterativeBackwardReachability::Effects. +/// Implements IterativeBackwardReachability::findBarrier::Visitor. +/// Implements VisitBarrierAccessScopes::Effects +class Dataflow final { +public: + using Reachability = IterativeBackwardReachability; + using Effect = Reachability::Effect; + +private: Context const &context; Usage const &uses; - DeinitBarriers &result; + DeinitBarriers &barriers; + Reachability::Result result; + Reachability reachability; + SmallPtrSet barrierAccessScopes; + bool recordCopies = false; enum class Classification { Barrier, Copy, Other }; - BackwardReachability reachability; - public: - DataFlow(Context const &context, Usage const &uses, DeinitBarriers &result) - : context(context), uses(uses), result(result), - reachability(&context.function, *this) { - // Seed reachability with the scope ending uses from which the backwards - // data flow will begin. - for (auto *end : uses.ends) { - reachability.initLastUse(end); - } - } - DataFlow(DataFlow const &) = delete; - DataFlow &operator=(DataFlow const &) = delete; + Dataflow(Context const &context, Usage const &uses, DeinitBarriers &barriers) + : context(context), uses(uses), barriers(barriers), + result(&context.function), + reachability(&context.function, context.defBlock, *this, result) {} + Dataflow(Dataflow const &) = delete; + Dataflow &operator=(Dataflow const &) = delete; - void run() { reachability.solveBackward(); } + void run(); private: - friend class BackwardReachability; + friend Reachability; + friend class BarrierAccessScopeFinder; + friend class VisitBarrierAccessScopes; - bool hasReachableBegin(SILBasicBlock *block) { - return result.hoistingReachesBeginBlocks.contains(block); - } + Classification classifyInstruction(SILInstruction *); - void markReachableBegin(SILBasicBlock *block) { - result.hoistingReachesBeginBlocks.insert(block); - } + bool classificationIsBarrier(Classification); - void markReachableEnd(SILBasicBlock *block) { - result.hoistingReachesEndBlocks.insert(block); - } + /// IterativeBackwardReachability::Effects + /// VisitBarrierAccessScopes::Effects - Classification classifyInstruction(SILInstruction *); + auto gens() { return uses.ends; } - bool classificationIsBarrier(Classification); + Effect effectForInstruction(SILInstruction *); + + Effect effectForPhi(SILBasicBlock *); - void visitedInstruction(SILInstruction *, Classification); + /// VisitBarrierAccessScopes::Effects - bool checkReachableBarrier(SILInstruction *); + auto localGens() { return result.localGens; } - bool checkReachablePhiBarrier(SILBasicBlock *); + bool isLocalGen(SILInstruction *instruction) { + return result.localGens.contains(instruction); + } + + /// IterativeBackwardReachability::findBarrier::Visitor. + + void visitBarrierInstruction(SILInstruction *instruction) { + barriers.instructions.push_back(instruction); + } + + void visitBarrierPhi(SILBasicBlock *block) { barriers.phis.push_back(block); } + + void visitBarrierBlock(SILBasicBlock *block) { + barriers.blocks.push_back(block); + } }; /// Whether the specified value is %lifetime or its iterated copy_value. @@ -207,8 +226,8 @@ bool isSimpleExtendedIntroducerDef(Context const &context, SILValue value) { } } -DataFlow::Classification -DataFlow::classifyInstruction(SILInstruction *instruction) { +Dataflow::Classification +Dataflow::classifyInstruction(SILInstruction *instruction) { if (instruction == &context.introducer) { return Classification::Barrier; } @@ -220,13 +239,18 @@ DataFlow::classifyInstruction(SILInstruction *instruction) { if (uses.users.contains(instruction)) { return Classification::Barrier; } + if (auto *eai = dyn_cast(instruction)) { + return barrierAccessScopes.contains(eai->getBeginAccess()) + ? Classification::Barrier + : Classification::Other; + } if (isDeinitBarrier(instruction)) { return Classification::Barrier; } return Classification::Other; } -bool DataFlow::classificationIsBarrier(Classification classification) { +bool Dataflow::classificationIsBarrier(Classification classification) { switch (classification) { case Classification::Barrier: return true; @@ -237,29 +261,17 @@ bool DataFlow::classificationIsBarrier(Classification classification) { llvm_unreachable("exhaustive switch not exhaustive?!"); } -void DataFlow::visitedInstruction(SILInstruction *instruction, - Classification classification) { - assert(classifyInstruction(instruction) == classification); - switch (classification) { - case Classification::Barrier: - result.barriers.push_back(instruction); - return; - case Classification::Copy: - result.copies.push_back(cast(instruction)); - return; - case Classification::Other: - return; - } - llvm_unreachable("exhaustive switch not exhaustive?!"); -} - -bool DataFlow::checkReachableBarrier(SILInstruction *instruction) { +Dataflow::Effect Dataflow::effectForInstruction(SILInstruction *instruction) { + if (uses.ends.contains(instruction)) + return Effect::Gen(); auto classification = classifyInstruction(instruction); - visitedInstruction(instruction, classification); - return classificationIsBarrier(classification); + if (recordCopies && classification == Classification::Copy) + barriers.copies.push_back(cast(instruction)); + return classificationIsBarrier(classification) ? Effect::Kill() + : Effect::NoEffect(); } -bool DataFlow::checkReachablePhiBarrier(SILBasicBlock *block) { +Dataflow::Effect Dataflow::effectForPhi(SILBasicBlock *block) { assert(llvm::all_of(block->getArguments(), [&](auto argument) { return PhiValue(argument); })); @@ -268,10 +280,49 @@ bool DataFlow::checkReachablePhiBarrier(SILBasicBlock *block) { return classificationIsBarrier( classifyInstruction(predecessor->getTerminator())); }); - if (isBarrier) { - result.phiBarriers.push_back(block); + return isBarrier ? Effect::Kill() : Effect::NoEffect(); +} + +/// Finds end_access instructions which are barriers to hoisting because the +/// access scopes they contain barriers to hoisting. Hoisting end_borrows into +/// such access scopes could introduce exclusivity violations. +/// +/// Implements BarrierAccessScopeFinder::Visitor +class BarrierAccessScopeFinder final { + using Impl = VisitBarrierAccessScopes; + Context const &context; + Impl impl; + Dataflow &dataflow; + +public: + BarrierAccessScopeFinder(Context const &context, Dataflow &dataflow) + : context(context), impl(&context.function, dataflow, *this), + dataflow(dataflow) {} + + void find() { impl.visit(); } + +private: + friend Impl; + + bool isInRegion(SILBasicBlock *block) { + return dataflow.result.discoveredBlocks.contains(block); } - return isBarrier; + + void visitBarrierAccessScope(BeginAccessInst *bai) { + dataflow.barrierAccessScopes.insert(bai); + for (auto *eai : bai->getEndAccesses()) { + dataflow.reachability.addKill(eai); + } + } +}; + +void Dataflow::run() { + reachability.initialize(); + BarrierAccessScopeFinder finder(context, *this); + finder.find(); + reachability.solve(); + recordCopies = true; + reachability.findBarriers(*this); } /// Hoist the scope ends of %lifetime, rewriting copies and borrows along the @@ -311,7 +362,7 @@ bool Rewriter::run() { // A block is a phi barrier iff any of its predecessors' terminators get // classified as barriers. That happens when a copy of %lifetime is passed // to a phi. - for (auto *block : barriers.phiBarriers) { + for (auto *block : barriers.phis) { madeChange |= createEndBorrow(&block->front()); } @@ -324,15 +375,11 @@ bool Rewriter::run() { // of a block P's successors B had reachable beginnings. If any of them // didn't, then BackwardReachability::meetOverSuccessors would never have // returned true for P, so none of its instructions would ever have been - // classified (except for via checkReachablePhiBarrier, which doesn't record - // terminator barriers). - for (auto instruction : barriers.barriers) { + // classified (except for via effectForPhi, which doesn't record terminator + // barriers). + for (auto instruction : barriers.instructions) { if (auto *terminator = dyn_cast(instruction)) { auto successors = terminator->getParentBlock()->getSuccessorBlocks(); - // In order for the instruction to have been classified as a barrier, - // reachability would have had to reach the block containing it. - assert(barriers.hoistingReachesEndBlocks.contains( - terminator->getParentBlock())); for (auto *successor : successors) { madeChange |= createEndBorrow(&successor->front()); } @@ -356,12 +403,8 @@ bool Rewriter::run() { // P not having a reachable end--see BackwardReachability::meetOverSuccessors. // // control-flow-boundary(B) := beginning-reachable(B) && !end-reachable(P) - for (auto *block : barriers.hoistingReachesBeginBlocks) { - if (auto *predecessor = block->getSinglePredecessorBlock()) { - if (!barriers.hoistingReachesEndBlocks.contains(predecessor)) { - madeChange |= createEndBorrow(&block->front()); - } - } + for (auto *block : barriers.blocks) { + madeChange |= createEndBorrow(&block->front()); } if (madeChange) { @@ -379,7 +422,7 @@ bool Rewriter::run() { bool Rewriter::createEndBorrow(SILInstruction *insertionPoint) { if (auto *ebi = dyn_cast(insertionPoint)) { - if (uses.ends.contains(insertionPoint)) { + if (llvm::find(uses.ends, insertionPoint) != uses.ends.end()) { reusedEndBorrowInsts.insert(insertionPoint); return false; } @@ -397,7 +440,7 @@ bool run(Context &context) { return false; DeinitBarriers barriers(context); - DataFlow flow(context, usage, barriers); + Dataflow flow(context, usage, barriers); flow.run(); Rewriter rewriter(context, usage, barriers); diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp index c7e16f4b3a5bc..1e8a9224d8619 100644 --- a/lib/Sema/CSApply.cpp +++ b/lib/Sema/CSApply.cpp @@ -6611,7 +6611,8 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType, return buildCollectionUpcastExpr(expr, toType, /*bridged=*/false, locator); } - case ConversionRestrictionKind::InoutToPointer: { + case ConversionRestrictionKind::InoutToPointer: + case ConversionRestrictionKind::InoutToCPointer: { bool isOptional = false; Type unwrappedTy = toType; if (Type unwrapped = toType->getOptionalObjectType()) { @@ -6629,7 +6630,7 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType, result = cs.cacheType(new (ctx) InjectIntoOptionalExpr(result, toType)); return result; } - + case ConversionRestrictionKind::ArrayToPointer: { bool isOptional = false; Type unwrappedTy = toType; diff --git a/lib/Sema/CSClosure.cpp b/lib/Sema/CSClosure.cpp index 42373fffe9d8f..6e1a3035a0c08 100644 --- a/lib/Sema/CSClosure.cpp +++ b/lib/Sema/CSClosure.cpp @@ -1409,7 +1409,15 @@ class SyntacticElementSolutionApplication } auto caseStmt = cast(rawCase.get()); - visitCaseStmt(caseStmt); + // Body of the `case` statement can contain a `fallthrough` + // statement that requires both source and destination + // `case` preambles to be type-checked, so bodies of `case` + // statements should be visited after preambles. + visitCaseStmtPreamble(caseStmt); + } + + for (auto *caseStmt : switchStmt->getCases()) { + visitCaseStmtBody(caseStmt); // Check restrictions on '@unknown'. if (caseStmt->hasUnknownAttr()) { @@ -1436,7 +1444,7 @@ class SyntacticElementSolutionApplication return doStmt; } - ASTNode visitCaseStmt(CaseStmt *caseStmt) { + void visitCaseStmtPreamble(CaseStmt *caseStmt) { // Translate the patterns and guard expressions for each case label item. for (auto &caseItem : caseStmt->getMutableCaseLabelItems()) { SolutionApplicationTarget caseTarget(&caseItem, @@ -1453,11 +1461,16 @@ class SyntacticElementSolutionApplication solution.getType(prev)->mapTypeOutOfContext()); expected->setInterfaceType(type); } + } - // Translate the body. + void visitCaseStmtBody(CaseStmt *caseStmt) { auto *newBody = visit(caseStmt->getBody()).get(); caseStmt->setBody(cast(newBody)); + } + ASTNode visitCaseStmt(CaseStmt *caseStmt) { + visitCaseStmtPreamble(caseStmt); + visitCaseStmtBody(caseStmt); return caseStmt; } diff --git a/lib/Sema/CSDiagnostics.cpp b/lib/Sema/CSDiagnostics.cpp index 142baee43af40..a2e54e4e99c3d 100644 --- a/lib/Sema/CSDiagnostics.cpp +++ b/lib/Sema/CSDiagnostics.cpp @@ -6895,6 +6895,7 @@ void NonEphemeralConversionFailure::emitSuggestionNotes() const { break; } case ConversionRestrictionKind::InoutToPointer: + case ConversionRestrictionKind::InoutToCPointer: // For an arbitrary inout-to-pointer, we can suggest // withUnsafe[Mutable][Bytes/Pointer]. if (auto alternative = getAlternativeKind()) diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp index d416cd065fd3f..c4a79478c1727 100644 --- a/lib/Sema/CSSimplify.cpp +++ b/lib/Sema/CSSimplify.cpp @@ -4896,9 +4896,13 @@ bool ConstraintSystem::repairFailures( if (!(overload && overload->choice.isDecl())) return true; - if (!getParameterList(overload->choice.getDecl()) - ->get(applyLoc->getParamIdx()) - ->getTypeOfDefaultExpr()) + // Ignore decls that don't have meaningful parameter lists - this + // matches variables and parameters with function types. + auto *paramList = getParameterList(overload->choice.getDecl()); + if (!paramList) + return true; + + if (!paramList->get(applyLoc->getParamIdx())->getTypeOfDefaultExpr()) return true; } } @@ -6589,9 +6593,18 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind, // Only try an inout-to-pointer conversion if we know it's not // an array being converted to a raw pointer type. Such // conversions can only use array-to-pointer. - if (!baseIsArray || !isRawPointerKind(pointerKind)) + if (!baseIsArray || !isRawPointerKind(pointerKind)) { conversionsOrFixes.push_back( ConversionRestrictionKind::InoutToPointer); + + // If regular inout-to-pointer conversion doesn't work, + // let's try C pointer conversion that has special semantics + // for imported declarations. + if (isArgumentOfImportedDecl(locator)) { + conversionsOrFixes.push_back( + ConversionRestrictionKind::InoutToCPointer); + } + } } } @@ -11404,6 +11417,7 @@ ConstraintSystem::simplifyApplicableFnConstraint( FunctionType::get(trailingClosureTypes, callAsFunctionResultTy, FunctionType::ExtInfo()); + increaseScore(SK_DisfavoredOverload); // Form an unsolved constraint to apply trailing closures to a // callable type produced by `.init`. This constraint would become // active when `callableType` is bound. @@ -12222,6 +12236,35 @@ ConstraintSystem::simplifyRestrictedConstraintImpl( case ConversionRestrictionKind::PointerToCPointer: return simplifyPointerToCPointerRestriction(type1, type2, flags, locator); + case ConversionRestrictionKind::InoutToCPointer: { + SmallVector optionals; + + auto ptr2 = + type2->getDesugaredType()->lookThroughAllOptionalTypes(optionals); + + increaseScore(SK_ValueToOptional, optionals.size()); + + PointerTypeKind pointerKind; + (void)ptr2->getAnyPointerElementType(pointerKind); + + auto baseType1 = type1->getInOutObjectType(); + + Type ptr1; + // The right-hand size is a raw pointer, so let's use `UnsafeMutablePointer` + // for the `inout` type. + if (pointerKind == PTK_UnsafeRawPointer || + pointerKind == PTK_UnsafeMutableRawPointer) { + ptr1 = BoundGenericType::get(Context.getUnsafeMutablePointerDecl(), + /*parent=*/nullptr, {baseType1}); + } else { + ptr1 = baseType1->wrapInPointer(pointerKind); + } + + assert(ptr1); + + return simplifyPointerToCPointerRestriction(ptr1, ptr2, flags, locator); + } + // T < U or T is bridged to V where V < U ===> Array case ConversionRestrictionKind::ArrayUpcast: { Type baseType1 = *isArrayType(type1); diff --git a/lib/Sema/Constraint.cpp b/lib/Sema/Constraint.cpp index 6dddb57ae5213..d56143b63e256 100644 --- a/lib/Sema/Constraint.cpp +++ b/lib/Sema/Constraint.cpp @@ -612,6 +612,8 @@ StringRef swift::constraints::getName(ConversionRestrictionKind kind) { return "[string-to-pointer]"; case ConversionRestrictionKind::InoutToPointer: return "[inout-to-pointer]"; + case ConversionRestrictionKind::InoutToCPointer: + return "[inout-to-c-pointer]"; case ConversionRestrictionKind::PointerToPointer: return "[pointer-to-pointer]"; case ConversionRestrictionKind::PointerToCPointer: diff --git a/lib/Sema/ConstraintSystem.cpp b/lib/Sema/ConstraintSystem.cpp index aa4872bc76b35..1344cb71cdc51 100644 --- a/lib/Sema/ConstraintSystem.cpp +++ b/lib/Sema/ConstraintSystem.cpp @@ -5719,7 +5719,8 @@ ConstraintSystem::isConversionEphemeral(ConversionRestrictionKind conversion, case ConversionRestrictionKind::StringToPointer: // Always ephemeral. return ConversionEphemeralness::Ephemeral; - case ConversionRestrictionKind::InoutToPointer: { + case ConversionRestrictionKind::InoutToPointer: + case ConversionRestrictionKind::InoutToCPointer: { // Ephemeral, except if the expression is a reference to a global or // static stored variable, or a directly accessed stored property on such a diff --git a/lib/Sema/TypeCheckAccess.cpp b/lib/Sema/TypeCheckAccess.cpp index 437db59565502..64e537f3b4056 100644 --- a/lib/Sema/TypeCheckAccess.cpp +++ b/lib/Sema/TypeCheckAccess.cpp @@ -1746,10 +1746,22 @@ class DeclAvailabilityChecker : public DeclVisitor { void visitNominalTypeDecl(const NominalTypeDecl *nominal) { checkGenericParams(nominal, nominal); + DeclAvailabilityFlags flags = + DeclAvailabilityFlag::AllowPotentiallyUnavailableProtocol; + + // As a concession to source compatibility for API libraries, downgrade + // diagnostics about inheritance from a less available type when the + // following conditions are met: + // 1. The inherited type is only potentially unavailable before the + // deployment target. + // 2. The inheriting type is `@usableFromInline`. + if (nominal->getAttrs().hasAttribute()) + flags |= DeclAvailabilityFlag:: + WarnForPotentialUnavailabilityBeforeDeploymentTarget; + llvm::for_each(nominal->getInherited(), [&](TypeLoc inherited) { checkType(inherited.getType(), inherited.getTypeRepr(), nominal, - ExportabilityReason::General, - DeclAvailabilityFlag::AllowPotentiallyUnavailableProtocol); + ExportabilityReason::General, flags); }); } @@ -1850,21 +1862,8 @@ class DeclAvailabilityChecker : public DeclVisitor { }); Where = wasWhere.withExported(hasExportedMembers); - - // When diagnosing potential unavailability of the extended type, downgrade - // the diagnostics to warnings when the extension decl has no declared - // availability and the required availability is more than the deployment - // target. - DeclAvailabilityFlags extendedTypeFlags = None; - auto annotatedRange = - AvailabilityInference::annotatedAvailableRange(ED, ED->getASTContext()); - if (!annotatedRange.hasValue()) - extendedTypeFlags |= DeclAvailabilityFlag:: - WarnForPotentialUnavailabilityBeforeDeploymentTarget; - checkType(ED->getExtendedType(), ED->getExtendedTypeRepr(), ED, - ExportabilityReason::ExtensionWithPublicMembers, - extendedTypeFlags); + ExportabilityReason::ExtensionWithPublicMembers); // 3) If the extension contains exported members or defines conformances, // the 'where' clause must only name exported types. diff --git a/lib/Sema/TypeCheckAvailability.cpp b/lib/Sema/TypeCheckAvailability.cpp index 377a29ae2381c..8734085287d10 100644 --- a/lib/Sema/TypeCheckAvailability.cpp +++ b/lib/Sema/TypeCheckAvailability.cpp @@ -460,6 +460,9 @@ class TypeRefinementContextBuilder : private ASTWalker { // Adds in a TRC that covers the entire declaration. if (auto DeclTRC = getNewContextForSignatureOfDecl(D)) { pushContext(DeclTRC, D); + + // Possibly use this as an effective parent context later. + recordEffectiveParentContext(D, DeclTRC); } // Create TRCs that cover only the body of the declaration. @@ -542,46 +545,63 @@ class TypeRefinementContextBuilder : private ASTWalker { return nullptr; } - // A decl only introduces a new context when it either has explicit - // availability or requires the deployment target. - bool HasExplicitAvailability = hasActiveAvailableAttribute(D, Context); - bool ConstrainToDeploymentTarget = - shouldConstrainSignatureToDeploymentTarget(D); - if (!HasExplicitAvailability && !ConstrainToDeploymentTarget) - return nullptr; + // Declarations with an explicit availability attribute always get a TRC. + if (hasActiveAvailableAttribute(D, Context)) { + AvailabilityContext DeclaredAvailability = + swift::AvailabilityInference::availableRange(D, Context); - // We require a valid range in order to be able to query for the TRC - // corresponding to a given SourceLoc. - // If this assert fires, it means we have probably synthesized an implicit - // declaration without location information. The appropriate fix is - // probably to gin up a source range for the declaration when synthesizing - // it. - assert(D->getSourceRange().isValid()); + return TypeRefinementContext::createForDecl( + Context, D, getCurrentTRC(), + getEffectiveAvailabilityForDeclSignature(D, DeclaredAvailability), + DeclaredAvailability, refinementSourceRangeForDecl(D)); + } - // The potential versions in the declaration are constrained by both - // the declared availability of the declaration and the potential versions - // of its lexical context. - AvailabilityContext ExplicitDeclInfo = - swift::AvailabilityInference::availableRange(D, Context); - AvailabilityContext DeclInfo = ExplicitDeclInfo; - DeclInfo.intersectWith(getCurrentTRC()->getAvailabilityInfo()); - - if (ConstrainToDeploymentTarget) - DeclInfo.intersectWith(AvailabilityContext::forDeploymentTarget(Context)); - - SourceRange Range = refinementSourceRangeForDecl(D); - TypeRefinementContext *NewTRC; - if (HasExplicitAvailability) - NewTRC = TypeRefinementContext::createForDecl( - Context, D, getCurrentTRC(), DeclInfo, ExplicitDeclInfo, Range); - else - NewTRC = TypeRefinementContext::createForAPIBoundary( - Context, D, getCurrentTRC(), DeclInfo, Range); + // Declarations without explicit availability get a TRC if they are + // effectively less available than the surrounding context. For example, an + // internal property in a public struct can be effectively less available + // than the containing struct decl because the internal property will only + // be accessed by code running at the deployment target or later. + AvailabilityContext CurrentAvailability = + getCurrentTRC()->getAvailabilityInfo(); + AvailabilityContext EffectiveAvailability = + getEffectiveAvailabilityForDeclSignature(D, CurrentAvailability); + if (CurrentAvailability.isSupersetOf(EffectiveAvailability)) + return TypeRefinementContext::createForDeclImplicit( + Context, D, getCurrentTRC(), EffectiveAvailability, + refinementSourceRangeForDecl(D)); + + return nullptr; + } - // Possibly use this as an effective parent context later. - recordEffectiveParentContext(D, NewTRC); + AvailabilityContext getEffectiveAvailabilityForDeclSignature( + Decl *D, const AvailabilityContext BaseAvailability) { + AvailabilityContext EffectiveAvailability = BaseAvailability; + + // As a special case, extension decls are treated as effectively as + // available as the nominal type they extend, up to the deployment target. + // This rule is a convenience for library authors who have written + // extensions without specifying availabilty on the extension itself. + if (auto *ED = dyn_cast(D)) { + auto *Nominal = ED->getExtendedNominal(); + if (Nominal && !hasActiveAvailableAttribute(D, Context)) { + EffectiveAvailability.intersectWith( + swift::AvailabilityInference::availableRange(Nominal, Context)); + + // We want to require availability to be specified on extensions of + // types that would be potentially unavailable to the module containing + // the extension, so limit the effective availability to the deployment + // target. + EffectiveAvailability.unionWith( + AvailabilityContext::forDeploymentTarget(Context)); + } + } - return NewTRC; + EffectiveAvailability.intersectWith(getCurrentTRC()->getAvailabilityInfo()); + if (shouldConstrainSignatureToDeploymentTarget(D)) + EffectiveAvailability.intersectWith( + AvailabilityContext::forDeploymentTarget(Context)); + + return EffectiveAvailability; } /// Checks whether the entire declaration, including its signature, should be @@ -607,6 +627,14 @@ class TypeRefinementContextBuilder : private ASTWalker { /// provides a convenient place to specify the refined range when it is /// different than the declaration's source range. SourceRange refinementSourceRangeForDecl(Decl *D) { + // We require a valid range in order to be able to query for the TRC + // corresponding to a given SourceLoc. + // If this assert fires, it means we have probably synthesized an implicit + // declaration without location information. The appropriate fix is + // probably to gin up a source range for the declaration when synthesizing + // it. + assert(D->getSourceRange().isValid()); + if (auto *storageDecl = dyn_cast(D)) { // Use the declaration's availability for the context when checking // the bodies of its accessors. @@ -642,25 +670,26 @@ class TypeRefinementContextBuilder : private ASTWalker { return D->getSourceRange(); } - TypeRefinementContext *createAPIBoundaryContext(Decl *D, SourceRange range) { - AvailabilityContext DeploymentTargetInfo = - AvailabilityContext::forDeploymentTarget(Context); - DeploymentTargetInfo.intersectWith(getCurrentTRC()->getAvailabilityInfo()); - - return TypeRefinementContext::createForAPIBoundary( - Context, D, getCurrentTRC(), DeploymentTargetInfo, range); - } - void buildContextsForBodyOfDecl(Decl *D) { // Are we already constrained by the deployment target? If not, adding // new contexts won't change availability. if (isCurrentTRCContainedByDeploymentTarget()) return; + // A lambda that creates an implicit decl TRC specifying the deployment + // target for `range` in decl `D`. + auto createContext = [this](Decl *D, SourceRange range) { + AvailabilityContext Availability = + AvailabilityContext::forDeploymentTarget(Context); + Availability.intersectWith(getCurrentTRC()->getAvailabilityInfo()); + + return TypeRefinementContext::createForDeclImplicit( + Context, D, getCurrentTRC(), Availability, range); + }; + // Top level code always uses the deployment target. if (auto tlcd = dyn_cast(D)) { - auto *topLevelTRC = - createAPIBoundaryContext(tlcd, tlcd->getSourceRange()); + auto *topLevelTRC = createContext(tlcd, tlcd->getSourceRange()); pushContext(topLevelTRC, D); return; } @@ -670,8 +699,7 @@ class TypeRefinementContextBuilder : private ASTWalker { if (auto afd = dyn_cast(D)) { if (!afd->isImplicit() && afd->getBodySourceRange().isValid() && afd->getResilienceExpansion() != ResilienceExpansion::Minimal) { - auto *functionBodyTRC = - createAPIBoundaryContext(afd, afd->getBodySourceRange()); + auto *functionBodyTRC = createContext(afd, afd->getBodySourceRange()); pushContext(functionBodyTRC, D); } return; @@ -693,8 +721,7 @@ class TypeRefinementContextBuilder : private ASTWalker { // Create a TRC for the init written in the source. The ASTWalker // won't visit these expressions so instead of pushing these onto the // stack we build them directly. - auto *initTRC = - createAPIBoundaryContext(vd, initExpr->getSourceRange()); + auto *initTRC = createContext(vd, initExpr->getSourceRange()); TypeRefinementContextBuilder(initTRC, Context).build(initExpr); } @@ -710,7 +737,7 @@ class TypeRefinementContextBuilder : private ASTWalker { // example, property wrapper initializers that takes block arguments // are not handled correctly because of this (rdar://77841331). for (auto *wrapper : vd->getAttachedPropertyWrappers()) { - createAPIBoundaryContext(vd, wrapper->getRange()); + createContext(vd, wrapper->getRange()); } } diff --git a/lib/Sema/TypeCheckConcurrency.cpp b/lib/Sema/TypeCheckConcurrency.cpp index ea8de940caf68..7fb6ff24173e5 100644 --- a/lib/Sema/TypeCheckConcurrency.cpp +++ b/lib/Sema/TypeCheckConcurrency.cpp @@ -569,18 +569,27 @@ static void addSendableFixIt( const NominalTypeDecl *nominal, InFlightDiagnostic &diag, bool unchecked) { if (nominal->getInherited().empty()) { SourceLoc fixItLoc = nominal->getBraces().Start; - if (unchecked) - diag.fixItInsert(fixItLoc, ": @unchecked Sendable"); - else - diag.fixItInsert(fixItLoc, ": Sendable"); + diag.fixItInsert(fixItLoc, + unchecked ? ": @unchecked Sendable" : ": Sendable"); } else { - ASTContext &ctx = nominal->getASTContext(); - SourceLoc fixItLoc = nominal->getInherited().back().getSourceRange().End; - fixItLoc = Lexer::getLocForEndOfToken(ctx.SourceMgr, fixItLoc); - if (unchecked) - diag.fixItInsert(fixItLoc, ", @unchecked Sendable"); - else - diag.fixItInsert(fixItLoc, ", Sendable"); + auto fixItLoc = nominal->getInherited().back().getLoc(); + diag.fixItInsertAfter(fixItLoc, + unchecked ? ", @unchecked Sendable" : ", Sendable"); + } +} + +/// Add Fix-It text for the given generic param declaration type to adopt +/// Sendable. +static void addSendableFixIt(const GenericTypeParamDecl *genericArgument, + InFlightDiagnostic &diag, bool unchecked) { + if (genericArgument->getInherited().empty()) { + auto fixItLoc = genericArgument->getLoc(); + diag.fixItInsertAfter(fixItLoc, + unchecked ? ": @unchecked Sendable" : ": Sendable"); + } else { + auto fixItLoc = genericArgument->getInherited().back().getLoc(); + diag.fixItInsertAfter(fixItLoc, + unchecked ? ", @unchecked Sendable" : ", Sendable"); } } @@ -874,6 +883,18 @@ static bool diagnoseSingleNonSendableType( nominal->diagnose( diag::non_sendable_nominal, nominal->getDescriptiveKind(), nominal->getName()); + } else if (auto genericArchetype = type->getAs()) { + auto interfaceType = genericArchetype->getInterfaceType(); + if (auto genericParamType = + interfaceType->getAs()) { + auto *genericParamTypeDecl = genericParamType->getDecl(); + if (genericParamTypeDecl && + genericParamTypeDecl->getModuleContext() == module) { + auto diag = genericParamTypeDecl->diagnose( + diag::add_generic_parameter_sendable_conformance, type); + addSendableFixIt(genericParamTypeDecl, diag, /*unchecked=*/false); + } + } } return false; @@ -913,7 +934,16 @@ bool swift::diagnoseNonSendableTypes( bool swift::diagnoseNonSendableTypesInReference( ConcreteDeclRef declRef, const DeclContext *fromDC, SourceLoc loc, - SendableCheckReason reason) { + SendableCheckReason reason, Optional knownIsolation) { + + // Retrieve the actor isolation to use in diagnostics. + auto getActorIsolation = [&] { + if (knownIsolation) + return *knownIsolation; + + return swift::getActorIsolation(declRef.getDecl()); + }; + // For functions, check the parameter and result types. SubstitutionMap subs = declRef.getSubstitutions(); if (auto function = dyn_cast(declRef.getDecl())) { @@ -922,7 +952,7 @@ bool swift::diagnoseNonSendableTypesInReference( if (diagnoseNonSendableTypes( paramType, fromDC, loc, diag::non_sendable_param_type, (unsigned)reason, function->getDescriptiveKind(), - function->getName(), getActorIsolation(function))) + function->getName(), getActorIsolation())) return true; } @@ -932,7 +962,7 @@ bool swift::diagnoseNonSendableTypesInReference( if (diagnoseNonSendableTypes( resultType, fromDC, loc, diag::non_sendable_result_type, (unsigned)reason, func->getDescriptiveKind(), func->getName(), - getActorIsolation(func))) + getActorIsolation())) return true; } @@ -949,7 +979,7 @@ bool swift::diagnoseNonSendableTypesInReference( var->getDescriptiveKind(), var->getName(), var->isLocalCapture(), (unsigned)reason, - getActorIsolation(var))) + getActorIsolation())) return true; } @@ -959,7 +989,7 @@ bool swift::diagnoseNonSendableTypesInReference( if (diagnoseNonSendableTypes( paramType, fromDC, loc, diag::non_sendable_param_type, (unsigned)reason, subscript->getDescriptiveKind(), - subscript->getName(), getActorIsolation(subscript))) + subscript->getName(), getActorIsolation())) return true; } @@ -968,7 +998,7 @@ bool swift::diagnoseNonSendableTypesInReference( if (diagnoseNonSendableTypes( resultType, fromDC, loc, diag::non_sendable_result_type, (unsigned)reason, subscript->getDescriptiveKind(), - subscript->getName(), getActorIsolation(subscript))) + subscript->getName(), getActorIsolation())) return true; return false; @@ -1527,6 +1557,7 @@ namespace { SmallVector contextStack; SmallVector applyStack; SmallVector, 4> opaqueValues; + SmallVector patternBindingStack; /// Keeps track of the capture context of variables that have been /// explicitly captured in closures. @@ -1539,6 +1570,10 @@ namespace { using MutableVarParent = llvm::PointerUnion; + const PatternBindingDecl *getTopPatternBindingDecl() const { + return patternBindingStack.empty() ? nullptr : patternBindingStack.back(); + } + /// Mapping from mutable variable reference exprs, or inout expressions, /// to the parent expression, when that parent is either a load or /// an inout expr. @@ -1694,9 +1729,24 @@ namespace { Type type = getDeclContext() ->mapTypeIntoContext(decl->getInterfaceType()) ->getReferenceStorageReferent(); - diagnoseNonSendableTypes( - type, getDeclContext(), capture.getLoc(), - diag::non_sendable_capture, decl->getName()); + + if (closure->isImplicit()) { + auto *patternBindingDecl = getTopPatternBindingDecl(); + if (patternBindingDecl && patternBindingDecl->isAsyncLet()) { + diagnoseNonSendableTypes( + type, getDeclContext(), capture.getLoc(), + diag::implicit_async_let_non_sendable_capture, decl->getName()); + } else { + // Fallback to a generic implicit capture missing sendable + // conformance diagnostic. + diagnoseNonSendableTypes(type, getDeclContext(), capture.getLoc(), + diag::implicit_non_sendable_capture, + decl->getName()); + } + } else { + diagnoseNonSendableTypes(type, getDeclContext(), capture.getLoc(), + diag::non_sendable_capture, decl->getName()); + } } } @@ -1759,6 +1809,10 @@ namespace { contextStack.push_back(func); } + if (auto *PBD = dyn_cast(decl)) { + patternBindingStack.push_back(PBD); + } + return true; } @@ -1768,6 +1822,11 @@ namespace { contextStack.pop_back(); } + if (auto *PBD = dyn_cast(decl)) { + assert(patternBindingStack.back() == PBD); + patternBindingStack.pop_back(); + } + return true; } @@ -2722,8 +2781,10 @@ namespace { if (diagnoseReferenceToUnsafeGlobal(decl, loc)) return true; - // FIXME: SE-0338 would trigger Sendable checks here. - return false; + return diagnoseNonSendableTypesInReference( + declRef, getDeclContext(), loc, + SendableCheckReason::ExitingActor, + result.isolation); case ActorReferenceResult::EntersActor: // Handle all of the checking below. @@ -3489,6 +3550,16 @@ static ActorIsolation getOverriddenIsolationFor(ValueDecl *value) { return isolation.subst(subs); } +static ConcreteDeclRef getDeclRefInContext(ValueDecl *value) { + auto declContext = value->getInnermostDeclContext(); + if (auto genericEnv = declContext->getGenericEnvironmentOfContext()) { + return ConcreteDeclRef( + value, genericEnv->getForwardingSubstitutionMap()); + } + + return ConcreteDeclRef(value); +} + /// Generally speaking, the isolation of the decl that overrides /// must match the overridden decl. But there are a number of exceptions, /// e.g., the decl that overrides can be nonisolated. @@ -3496,12 +3567,8 @@ static ActorIsolation getOverriddenIsolationFor(ValueDecl *value) { static OverrideIsolationResult validOverrideIsolation( ValueDecl *value, ActorIsolation isolation, ValueDecl *overridden, ActorIsolation overriddenIsolation) { - ConcreteDeclRef valueRef(value); + ConcreteDeclRef valueRef = getDeclRefInContext(value); auto declContext = value->getInnermostDeclContext(); - if (auto genericEnv = declContext->getGenericEnvironmentOfContext()) { - valueRef = ConcreteDeclRef( - value, genericEnv->getForwardingSubstitutionMap()); - } auto refResult = ActorReferenceResult::forReference( valueRef, SourceLoc(), declContext, None, None, @@ -3520,9 +3587,7 @@ static OverrideIsolationResult validOverrideIsolation( if (isAsyncDecl(overridden) || isAccessibleAcrossActors( overridden, refResult.isolation, declContext)) { - // FIXME: Perform Sendable checking here because we're entering an - // actor. - return OverrideIsolationResult::Allowed; + return OverrideIsolationResult::Sendable; } // If the overridden declaration is from Objective-C with no actor @@ -3898,7 +3963,9 @@ void swift::checkOverrideActorIsolation(ValueDecl *value) { return; case OverrideIsolationResult::Sendable: - // FIXME: Do the Sendable check. + diagnoseNonSendableTypesInReference( + getDeclRefInContext(value), value->getInnermostDeclContext(), + value->getLoc(), SendableCheckReason::Override); return; case OverrideIsolationResult::Disallowed: @@ -4836,9 +4903,8 @@ bool swift::isThrowsDecl(ConcreteDeclRef declRef) { return false; } -bool swift::isAccessibleAcrossActors( - ValueDecl *value, const ActorIsolation &isolation, - const DeclContext *fromDC, Optional actorInstance) { +/// Determine whether a reference to this value isn't actually a value. +static bool isNonValueReference(const ValueDecl *value) { switch (value->getKind()) { case DeclKind::AssociatedType: case DeclKind::Class: @@ -4849,13 +4915,7 @@ bool swift::isAccessibleAcrossActors( case DeclKind::Protocol: case DeclKind::Struct: case DeclKind::TypeAlias: - return true; - case DeclKind::EnumCase: - case DeclKind::EnumElement: - // Type-level entities are always accessible across actors. - return true; - case DeclKind::IfConfig: case DeclKind::Import: case DeclKind::InfixOperator: @@ -4867,16 +4927,26 @@ bool swift::isAccessibleAcrossActors( case DeclKind::PrecedenceGroup: case DeclKind::PrefixOperator: case DeclKind::TopLevelCode: - // Non-value entities are always accessible across actors. - return true; - case DeclKind::Destructor: - // Destructors are always accessible across actors. return true; + case DeclKind::EnumElement: case DeclKind::Constructor: - // Initializers are accessible across actors unless they are global-actor - // qualified. + case DeclKind::Param: + case DeclKind::Var: + case DeclKind::Accessor: + case DeclKind::Func: + case DeclKind::Subscript: + return false; + } +} + +bool swift::isAccessibleAcrossActors( + ValueDecl *value, const ActorIsolation &isolation, + const DeclContext *fromDC, Optional actorInstance) { + // Initializers and enum elements are accessible across actors unless they + // are global-actor qualified. + if (isa(value) || isa(value)) { switch (isolation) { case ActorIsolation::ActorInstance: case ActorIsolation::Independent: @@ -4887,19 +4957,15 @@ bool swift::isAccessibleAcrossActors( case ActorIsolation::GlobalActor: return false; } + } - case DeclKind::Param: - case DeclKind::Var: - // 'let' declarations are immutable, so some of them can be accessed across - // actors. - return varIsSafeAcrossActors( - fromDC->getParentModule(), cast(value), isolation); - - case DeclKind::Accessor: - case DeclKind::Func: - case DeclKind::Subscript: - return false; + // 'let' declarations are immutable, so some of them can be accessed across + // actors. + if (auto var = dyn_cast(value)) { + return varIsSafeAcrossActors(fromDC->getParentModule(), var, isolation); } + + return false; } ActorReferenceResult ActorReferenceResult::forSameConcurrencyDomain( @@ -4948,6 +5014,11 @@ ActorReferenceResult ActorReferenceResult::forReference( declIsolation = declIsolation.subst(declRef.getSubstitutions()); } + // If the entity we are referencing is not a value, we're in thesame + // concurrency domain. + if (isNonValueReference(declRef.getDecl())) + return forSameConcurrencyDomain(declIsolation); + // Compute the isolation of the context, if not provided. ActorIsolation contextIsolation = ActorIsolation::forUnspecified(); if (knownContextIsolation) { diff --git a/lib/Sema/TypeCheckConcurrency.h b/lib/Sema/TypeCheckConcurrency.h index 413998f976dad..0c0a6da141100 100644 --- a/lib/Sema/TypeCheckConcurrency.h +++ b/lib/Sema/TypeCheckConcurrency.h @@ -75,6 +75,9 @@ enum class SendableCheckReason { /// A reference to an actor from outside that actor. CrossActor, + /// Exiting an actor to non-isolated async code. + ExitingActor, + /// A synchronous operation that was "promoted" to an asynchronous one /// because it was out of the actor's domain. SynchronousAsAsync, @@ -83,6 +86,9 @@ enum class SendableCheckReason { /// actor isolation. Conformance, + /// An override of a function. + Override, + /// The declaration is being exposed to Objective-C. ObjC, }; @@ -268,7 +274,8 @@ struct ActorReferenceResult { /// \returns true if an problem was detected, false otherwise. bool diagnoseNonSendableTypesInReference( ConcreteDeclRef declRef, const DeclContext *fromDC, SourceLoc loc, - SendableCheckReason refKind); + SendableCheckReason refKind, + Optional knownIsolation = None); /// Produce a diagnostic for a missing conformance to Sendable. void diagnoseMissingSendableConformance( diff --git a/lib/Sema/TypeCheckGeneric.cpp b/lib/Sema/TypeCheckGeneric.cpp index 0b3ab22a79bd1..07ec072ff3c5f 100644 --- a/lib/Sema/TypeCheckGeneric.cpp +++ b/lib/Sema/TypeCheckGeneric.cpp @@ -468,15 +468,11 @@ void TypeChecker::checkReferencedGenericParams(GenericContext *dc) { /// Generic types /// -/// Form the interface type of an extension from the raw type and the -/// extension's list of generic parameters. -static Type formExtensionInterfaceType( - ExtensionDecl *ext, Type type, - const GenericParamList *genericParams, - SmallVectorImpl &sameTypeReqs, - bool &mustInferRequirements) { +/// Collect additional requirements into \p sameTypeReqs. +static void collectAdditionalExtensionRequirements( + Type type, SmallVectorImpl &sameTypeReqs) { if (type->is()) - return type; + return; // Find the nominal type declaration and its parent type. if (type->is()) @@ -484,7 +480,7 @@ static Type formExtensionInterfaceType( // A parameterized protocol type is not a nominal. Unwrap it to get // the underlying nominal, and record a same-type requirement for - // the primary associated type. + // the primary associated types. if (auto *paramProtoTy = type->getAs()) { auto *protoTy = paramProtoTy->getBaseType(); type = protoTy; @@ -497,15 +493,9 @@ static Type formExtensionInterfaceType( Type parentType = type->getNominalParent(); GenericTypeDecl *genericDecl = type->getAnyGeneric(); - // Reconstruct the parent, if there is one. + // Visit the parent type, if there is one. if (parentType) { - // Build the nested extension type. - auto parentGenericParams = genericDecl->getGenericParams() - ? genericParams->getOuterParameters() - : genericParams; - parentType = - formExtensionInterfaceType(ext, parentType, parentGenericParams, - sameTypeReqs, mustInferRequirements); + collectAdditionalExtensionRequirements(parentType, sameTypeReqs); } // Find the nominal type. @@ -516,59 +506,26 @@ static Type formExtensionInterfaceType( nominal = type->getNominalOrBoundGenericNominal(); } - // Form the result. - Type resultType; - SmallVector genericArgs; - if (!nominal->isGeneric() || isa(nominal)) { - resultType = NominalType::get(nominal, parentType, - nominal->getASTContext()); - } else if (genericParams) { - auto currentBoundType = type->getAs(); - - // Form the bound generic type with the type parameters provided. - unsigned gpIndex = 0; - for (auto gp : *genericParams) { - SWIFT_DEFER { ++gpIndex; }; - + // If we have a bound generic type, add same-type requirements for each of + // its generic arguments. + if (auto currentBoundType = type->getAs()) { + auto *genericParams = currentBoundType->getDecl()->getGenericParams(); + for (unsigned gpIndex : indices(genericParams->getParams())) { + auto *gp = genericParams->getParams()[gpIndex]; auto gpType = gp->getDeclaredInterfaceType(); - genericArgs.push_back(gpType); - if (currentBoundType) { - sameTypeReqs.emplace_back(RequirementKind::SameType, gpType, - currentBoundType->getGenericArgs()[gpIndex]); - } + sameTypeReqs.emplace_back(RequirementKind::SameType, gpType, + currentBoundType->getGenericArgs()[gpIndex]); } - - resultType = BoundGenericType::get(nominal, parentType, genericArgs); } - // If we have a typealias, try to form type sugar. + // If we have a passthrough typealias, add the requirements from its + // generic signature. if (typealias && TypeChecker::isPassThroughTypealias( typealias, typealias->getUnderlyingType(), nominal)) { - auto typealiasSig = typealias->getGenericSignature(); - SubstitutionMap subMap; - if (typealiasSig) { - subMap = typealiasSig->getIdentitySubstitutionMap(); - - mustInferRequirements = true; - } - - resultType = TypeAliasType::get(typealias, parentType, subMap, resultType); + for (auto req : typealias->getGenericSignature().getRequirements()) + sameTypeReqs.push_back(req); } - - - return resultType; -} - -/// Retrieve the generic parameter depth of the extended type. -static unsigned getExtendedTypeGenericDepth(ExtensionDecl *ext) { - auto nominal = ext->getSelfNominalTypeDecl(); - if (!nominal) return static_cast(-1); - - auto sig = nominal->getGenericSignatureOfContext(); - if (!sig) return static_cast(-1); - - return sig.getGenericParams().back()->getDepth(); } GenericSignature @@ -605,7 +562,7 @@ GenericSignatureRequest::evaluate(Evaluator &evaluator, } bool allowConcreteGenericParams = false; - const auto *genericParams = GC->getGenericParams(); + auto *genericParams = GC->getGenericParams(); const auto *where = GC->getTrailingWhereClause(); if (genericParams) { @@ -650,10 +607,12 @@ GenericSignatureRequest::evaluate(Evaluator &evaluator, return GC->getParentForLookup()->getGenericSignatureOfContext(); } - auto parentSig = GC->getParentForLookup()->getGenericSignatureOfContext(); + GenericSignature parentSig; SmallVector inferenceSources; SmallVector sameTypeReqs; if (auto VD = dyn_cast_or_null(GC->getAsDecl())) { + parentSig = GC->getParentForLookup()->getGenericSignatureOfContext(); + auto func = dyn_cast(VD); auto subscr = dyn_cast(VD); @@ -708,38 +667,23 @@ GenericSignatureRequest::evaluate(Evaluator &evaluator, } } } else if (auto *ext = dyn_cast(GC)) { - // Form the interface type of the extension so we can use it as an inference - // source. - // - // FIXME: Push this into the "get interface type" request. - bool mustInferRequirements = false; - Type extInterfaceType = - formExtensionInterfaceType(ext, ext->getExtendedType(), - genericParams, sameTypeReqs, - mustInferRequirements); - - auto cannotReuseNominalSignature = [&]() -> bool { - const auto finalDepth = genericParams->getParams().back()->getDepth(); - return mustInferRequirements - || !sameTypeReqs.empty() - || ext->getTrailingWhereClause() - || (getExtendedTypeGenericDepth(ext) != finalDepth); - }; + parentSig = ext->getExtendedNominal()->getGenericSignatureOfContext(); + genericParams = nullptr; + + collectAdditionalExtensionRequirements(ext->getExtendedType(), sameTypeReqs); - // Re-use the signature of the type being extended by default. - if (!cannotReuseNominalSignature()) { - return ext->getSelfNominalTypeDecl()->getGenericSignatureOfContext(); + // Re-use the signature of the type being extended by default. + if (sameTypeReqs.empty() && !ext->getTrailingWhereClause()) { + return parentSig; } // Allow parameters to be equated with concrete types. allowConcreteGenericParams = true; - - inferenceSources.emplace_back(nullptr, extInterfaceType); } auto request = InferredGenericSignatureRequest{ parentSig.getPointer(), - GC->getGenericParams(), WhereClauseOwner(GC), + genericParams, WhereClauseOwner(GC), sameTypeReqs, inferenceSources, allowConcreteGenericParams}; auto sig = evaluateOrDefault(ctx.evaluator, request, diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp index 2d37c9b919048..d29c31d3c4aa5 100644 --- a/lib/Sema/TypeCheckProtocol.cpp +++ b/lib/Sema/TypeCheckProtocol.cpp @@ -2955,6 +2955,10 @@ bool ConformanceChecker::checkActorIsolation( requirementIsolation = requirementIsolation.subst(subs); } + SourceLoc loc = witness->getLoc(); + if (loc.isInvalid()) + loc = Conformance->getLoc(); + auto refResult = ActorReferenceResult::forReference( getConcreteWitness(), witness->getLoc(), DC, None, None, None, requirementIsolation); @@ -2972,7 +2976,8 @@ bool ConformanceChecker::checkActorIsolation( return false; case ActorReferenceResult::ExitsActorToNonisolated: - // FIXME: SE-0338 would diagnose this. + diagnoseNonSendableTypesInReference( + getConcreteWitness(), DC, loc, SendableCheckReason::Conformance); return false; case ActorReferenceResult::EntersActor: @@ -3016,10 +3021,6 @@ bool ConformanceChecker::checkActorIsolation( // If we aren't missing anything, do a Sendable check and move on. if (!missingOptions) { - SourceLoc loc = witness->getLoc(); - if (loc.isInvalid()) - loc = Conformance->getLoc(); - // FIXME: Disable Sendable checking when the witness is an initializer // that is explicitly marked nonisolated. if (isa(witness) && diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp index d769f9747288f..26fa0748611ea 100644 --- a/lib/Sema/TypeCheckType.cpp +++ b/lib/Sema/TypeCheckType.cpp @@ -632,7 +632,7 @@ static Type applyGenericArguments(Type type, TypeResolution resolution, // Build ParameterizedProtocolType if the protocol has a primary associated // type and we're in a supported context (for now just generic requirements, // inheritance clause, extension binding). - if (!resolution.getOptions().isParameterizedProtocolSupported(ctx.LangOpts)) { + if (!resolution.getOptions().isParameterizedProtocolSupported()) { diags.diagnose(loc, diag::parameterized_protocol_not_supported); return ErrorType::get(ctx); } diff --git a/lib/Sema/TypeCheckType.h b/lib/Sema/TypeCheckType.h index 334d6f1f77f5e..376fd56ab6053 100644 --- a/lib/Sema/TypeCheckType.h +++ b/lib/Sema/TypeCheckType.h @@ -284,18 +284,14 @@ class TypeResolutionOptions { } /// Whether parameterized protocol types are supported in this context. - /// - /// FIXME: Remove LangOptions parameter once EnableParameterizedExistentialTypes - /// staging flag is gone. - bool isParameterizedProtocolSupported(const LangOptions &opts) const { + bool isParameterizedProtocolSupported() const { switch (context) { case Context::Inherited: case Context::ExtensionBinding: case Context::GenericRequirement: - return true; case Context::ExistentialConstraint: case Context::MetatypeBase: - return opts.EnableParameterizedExistentialTypes; + return true; case Context::None: case Context::TypeAliasDecl: case Context::GenericTypeAliasDecl: diff --git a/lib/SymbolGraphGen/Symbol.cpp b/lib/SymbolGraphGen/Symbol.cpp index f411b6b60ac7a..44fa9f2a25883 100644 --- a/lib/SymbolGraphGen/Symbol.cpp +++ b/lib/SymbolGraphGen/Symbol.cpp @@ -197,6 +197,37 @@ const ValueDecl *Symbol::getDeclInheritingDocs() const { } } +namespace { + +StringRef getFileNameForDecl(const ValueDecl *VD) { + if (!VD) return StringRef{}; + + SourceLoc Loc = VD->getLoc(/*SerializedOK=*/true); + if (Loc.isInvalid()) return StringRef{}; + + SourceManager &SourceM = VD->getASTContext().SourceMgr; + return SourceM.getDisplayNameForLoc(Loc); +} + +StringRef getFileNameForDecl(const clang::Decl *ClangD) { + if (!ClangD) return StringRef{}; + + const clang::SourceManager &ClangSourceMgr = ClangD->getASTContext().getSourceManager(); + clang::PresumedLoc Loc = ClangSourceMgr.getPresumedLoc(ClangD->getLocation()); + if (Loc.isInvalid()) return StringRef{}; + + return StringRef(Loc.getFilename()); +} + +void serializeFileURI(llvm::json::OStream &OS, StringRef FileName) { + // FIXME: This can emit invalid URIs if the file name has a space in it (rdar://69242070) + SmallString<1024> FileURI("file://"); + FileURI.append(FileName); + OS.attribute("uri", FileURI.str()); +} + +} + void Symbol::serializeDocComment(llvm::json::OStream &OS) const { if (ClangNode ClangN = VD->getClangNode()) { if (!Graph->Walker.Options.IncludeClangDocs) @@ -221,6 +252,12 @@ void Symbol::serializeDocComment(llvm::json::OStream &OS) const { splitIntoLines(Text, Lines); OS.attributeObject("docComment", [&]() { + StringRef FileName = getFileNameForDecl(ClangD); + if (!FileName.empty()) + serializeFileURI(OS, FileName); + if (const auto *ModuleD = VD->getModuleContext()) { + OS.attribute("module", ModuleD->getNameStr()); + } OS.attributeArray("lines", [&]() { for (StringRef Line : Lines) { OS.object([&](){ @@ -247,6 +284,12 @@ void Symbol::serializeDocComment(llvm::json::OStream &OS) const { } OS.attributeObject("docComment", [&](){ + StringRef FileName = getFileNameForDecl(DocCommentProvidingDecl); + if (!FileName.empty()) + serializeFileURI(OS, FileName); + if (const auto *ModuleD = DocCommentProvidingDecl->getModuleContext()) { + OS.attribute("module", ModuleD->getNameStr()); + } auto LL = Graph->Ctx.getLineList(RC); StringRef FirstNonBlankLine; for (const auto &Line : LL.getLines()) { @@ -415,18 +458,13 @@ void Symbol::serializeLocationMixin(llvm::json::OStream &OS) const { return; if (auto *ClangD = ClangN.getAsDecl()) { - clang::SourceManager &ClangSM = - ClangD->getASTContext().getSourceManager(); - - clang::PresumedLoc Loc = ClangSM.getPresumedLoc(ClangD->getLocation()); - if (Loc.isValid()) { - // TODO: We should use a common function to fill in the location - // information for both cursor info and symbol graph gen, then also - // include position here. + StringRef FileName = getFileNameForDecl(ClangD); + if (!FileName.empty()) { OS.attributeObject("location", [&](){ - SmallString<1024> FileURI("file://"); - FileURI.append(Loc.getFilename()); - OS.attribute("uri", FileURI.str()); + // TODO: We should use a common function to fill in the location + // information for both cursor info and symbol graph gen, then also + // include position here. + serializeFileURI(OS, FileName); }); } } @@ -434,18 +472,17 @@ void Symbol::serializeLocationMixin(llvm::json::OStream &OS) const { return; } - auto Loc = VD->getLoc(/*SerializedOK=*/true); - if (Loc.isInvalid()) { + auto FileName = getFileNameForDecl(VD); + if (FileName.empty()) { return; } - auto FileName = VD->getASTContext().SourceMgr.getDisplayNameForLoc(Loc); - if (FileName.empty()) { + // TODO: Fold serializePosition into serializeFileURI so we don't need to load Loc twice? + auto Loc = VD->getLoc(/*SerializedOK=*/true); + if (Loc.isInvalid()) { return; } OS.attributeObject("location", [&](){ - SmallString<1024> FileURI("file://"); - FileURI.append(FileName); - OS.attribute("uri", FileURI.str()); + serializeFileURI(OS, FileName); serializePosition("position", Loc, Graph->M.getASTContext().SourceMgr, OS); }); } diff --git a/stdlib/public/Differentiation/FloatingPointDifferentiation.swift.gyb b/stdlib/public/Differentiation/FloatingPointDifferentiation.swift.gyb index 627dbd07863bb..3414fd8a51004 100644 --- a/stdlib/public/Differentiation/FloatingPointDifferentiation.swift.gyb +++ b/stdlib/public/Differentiation/FloatingPointDifferentiation.swift.gyb @@ -268,7 +268,7 @@ where func _vjpAddingProduct( _ lhs: Self, _ rhs: Self ) -> (value: Self, pullback: (Self) -> (Self, Self, Self)) { - return (addingProduct(lhs, rhs), { _ in (1, rhs, lhs) }) + return (addingProduct(lhs, rhs), { v in (v, v * rhs, v * lhs) }) } @inlinable // FIXME(sil-serialize-all) diff --git a/stdlib/public/SwiftShims/HeapObject.h b/stdlib/public/SwiftShims/HeapObject.h index c58c4767cdb4f..56440cdb5e8a9 100644 --- a/stdlib/public/SwiftShims/HeapObject.h +++ b/stdlib/public/SwiftShims/HeapObject.h @@ -209,7 +209,7 @@ static_assert(alignof(HeapObject) == alignof(void*), (__swift_uintptr_t) SWIFT_ABI_DEFAULT_BRIDGEOBJECT_TAG_64 #elif defined(__wasm32__) -extern unsigned char __global_base; + #define _swift_abi_LeastValidPointerValue \ (__swift_uintptr_t) SWIFT_ABI_WASM32_LEAST_VALID_POINTER diff --git a/stdlib/public/SwiftShims/System.h b/stdlib/public/SwiftShims/System.h index ab117efc9f1fd..53afedf3eff97 100644 --- a/stdlib/public/SwiftShims/System.h +++ b/stdlib/public/SwiftShims/System.h @@ -218,10 +218,10 @@ /*********************************** wasm32 ************************************/ -// WebAssembly doesn't reserve low addresses But without "extra inhabitants" of +// WebAssembly doesn't reserve low addresses. But without "extra inhabitants" of // the pointer representation, runtime performance and memory footprint are // worse. So assume that compiler driver uses wasm-ld and --global-base=1024 to // reserve low 1KB. -#define SWIFT_ABI_WASM32_LEAST_VALID_POINTER 1024 +#define SWIFT_ABI_WASM32_LEAST_VALID_POINTER 4096 #endif // SWIFT_STDLIB_SHIMS_ABI_SYSTEM_H diff --git a/stdlib/public/runtime/Heap.cpp b/stdlib/public/runtime/Heap.cpp index 989a7bd1118a5..adbd90c655bb2 100644 --- a/stdlib/public/runtime/Heap.cpp +++ b/stdlib/public/runtime/Heap.cpp @@ -134,30 +134,3 @@ static void swift_slowDeallocImpl(void *ptr, size_t alignMask) { void swift::swift_slowDealloc(void *ptr, size_t bytes, size_t alignMask) { swift_slowDeallocImpl(ptr, alignMask); } - -#if defined(__APPLE__) && defined(__MACH__) && SWIFT_STDLIB_HAS_DARWIN_LIBMALLOC -// On Darwin, define our own, hidden operator new/delete implementations. We -// don't want to pick up any overrides that come from other code, but we also -// don't want to expose our overrides to any other code. We can't do this -// directly in C++, as the compiler has an implicit prototype with default -// visibility. However, if we implement them as C functions using the C++ -// mangled names, the compiler accepts them without complaint, and the linker -// still links all internal uses with these overrides. - -__attribute__((visibility(("hidden")))) extern "C" void *_Znwm(size_t size) { - return swift_slowAlloc(size, MALLOC_ALIGN_MASK); -} - -__attribute__((visibility(("hidden")))) extern "C" void _ZdlPv(void *ptr) { - swift_slowDeallocImpl(ptr, MALLOC_ALIGN_MASK); -} - -__attribute__((visibility(("hidden")))) extern "C" void *_Znam(size_t size) { - return swift_slowAlloc(size, MALLOC_ALIGN_MASK); -} - -__attribute__((visibility(("hidden")))) extern "C" void _ZdaPv(void *ptr) { - swift_slowDeallocImpl(ptr, MALLOC_ALIGN_MASK); -} - -#endif diff --git a/stdlib/public/runtime/MetadataLookup.cpp b/stdlib/public/runtime/MetadataLookup.cpp index 25b3069502784..aab427dc0bc58 100644 --- a/stdlib/public/runtime/MetadataLookup.cpp +++ b/stdlib/public/runtime/MetadataLookup.cpp @@ -1930,7 +1930,7 @@ swift_stdlib_getTypeByMangledNameUntrusted(const char *typeNameStart, if (c >= '\x01' && c <= '\x1F') return nullptr; } - + return swift_getTypeByMangledName(MetadataState::Complete, typeName, nullptr, {}, {}).getType().getMetadata(); } @@ -2197,6 +2197,23 @@ swift_getOpaqueTypeConformance(const void * const *arguments, // Return the ObjC class for the given type name. // This gets installed as a callback from libobjc. +static bool validateObjCMangledName(const char *_Nonnull typeName) { + // Accept names with a mangling prefix. + if (getManglingPrefixLength(typeName)) + return true; + + // Accept names that start with a digit (unprefixed mangled names). + if (isdigit(typeName[0])) + return true; + + // Accept names that contain a dot. + if (strchr(typeName, '.')) + return true; + + // Reject anything else. + return false; +} + // FIXME: delete this #if and dlsym once we don't // need to build with older libobjc headers #if !OBJC_GETCLASSHOOK_DEFINED @@ -2232,8 +2249,9 @@ getObjCClassByMangledName(const char * _Nonnull typeName, [&](const Metadata *type, unsigned index) { return nullptr; } ).getType().getMetadata(); } else { - metadata = swift_stdlib_getTypeByMangledNameUntrusted(typeStr.data(), - typeStr.size()); + if (validateObjCMangledName(typeName)) + metadata = swift_stdlib_getTypeByMangledNameUntrusted(typeStr.data(), + typeStr.size()); } if (metadata) { auto objcClass = diff --git a/test/AutoDiff/compiler_crashers_fixed/rdar71191415-nested-differentiation-of-extension-method-optimized.swift b/test/AutoDiff/compiler_crashers_fixed/rdar71191415-nested-differentiation-of-extension-method-optimized.swift index 7a8a5f5ce8fc2..2aac3e1a58adc 100644 --- a/test/AutoDiff/compiler_crashers_fixed/rdar71191415-nested-differentiation-of-extension-method-optimized.swift +++ b/test/AutoDiff/compiler_crashers_fixed/rdar71191415-nested-differentiation-of-extension-method-optimized.swift @@ -1,7 +1,7 @@ // RUN: %target-build-swift -O %s // FIXME(rdar://89055298) -// UNSUPPORTED: linux +// UNSUPPORTED: OS=linux-gnu // rdar://71191415 diff --git a/test/AutoDiff/stdlib/floating_point.swift.gyb b/test/AutoDiff/stdlib/floating_point.swift.gyb index de94184c4f62f..d9e398bb0f0ab 100644 --- a/test/AutoDiff/stdlib/floating_point.swift.gyb +++ b/test/AutoDiff/stdlib/floating_point.swift.gyb @@ -81,6 +81,7 @@ FloatingPointDerivativeTests.test("${Self}.squareRoot") { FloatingPointDerivativeTests.test("${Self}.addingProduct") { expectEqual((1, 2, 3), gradient(at: ${Self}(10), 3, 2, of: { $0.addingProduct($1, $2) })) + expectEqual((2, 4, 6), pullback(at: ${Self}(10), 3, 2, of: { $0.addingProduct($1, $2) })(2)) } FloatingPointDerivativeTests.test("${Self}.minimum") { diff --git a/test/AutolinkExtract/import.swift b/test/AutolinkExtract/import.swift index 0d3a09a8eecf0..dce6df6a3b2b0 100644 --- a/test/AutolinkExtract/import.swift +++ b/test/AutolinkExtract/import.swift @@ -2,9 +2,14 @@ // RUN: %target-swiftc_driver -emit-module -emit-module-path %t/empty.swiftmodule -module-name empty -module-link-name empty %S/empty.swift // RUN: %target-swiftc_driver -c %s -I %t -o %t/import_experimental.o // RUN: %target-swift-autolink-extract %t/import_experimental.o -o - | %FileCheck --check-prefix CHECK-%target-object-format %s +// RUN: %target-swiftc_driver -c %s -I %t -o %t/import_experimental_again.o +// RUN: %target-swift-autolink-extract %t/import_experimental.o %t/import_experimental_again.o -o - | %FileCheck --check-prefix CHECK-%target-object-format %s +// RUN: %target-swift-autolink-extract %t/import_experimental.o %t/import_experimental_again.o -o - | %FileCheck --check-prefix UNIQUE %s // REQUIRES: autolink-extract +// UNIQUE-COUNT-1: -lswiftCore + // CHECK-elf-DAG: -lswiftCore // CHECK-elf-DAG: -lempty diff --git a/test/Concurrency/Reflection/reflect_task.swift b/test/Concurrency/Reflection/reflect_task.swift index 97267593888ea..9101fe70a174b 100644 --- a/test/Concurrency/Reflection/reflect_task.swift +++ b/test/Concurrency/Reflection/reflect_task.swift @@ -10,7 +10,7 @@ // UNSUPPORTED: use_os_stdlib // UNSUPPORTED: back_deployment_runtime // -// UNSUPPORTED: OS=macosx,ios,watchos,tvos +// UNSUPPORTED: OS=macosx, OS=ios, OS=watchos, OS=tvos import Swift import _Concurrency diff --git a/test/Concurrency/Runtime/async_taskgroup_asynciterator_semantics.swift b/test/Concurrency/Runtime/async_taskgroup_asynciterator_semantics.swift index c12695aa359cd..a2961f5da8394 100644 --- a/test/Concurrency/Runtime/async_taskgroup_asynciterator_semantics.swift +++ b/test/Concurrency/Runtime/async_taskgroup_asynciterator_semantics.swift @@ -3,7 +3,7 @@ // REQUIRES: concurrency // REQUIRES: concurrency_runtime // UNSUPPORTED: back_deployment_runtime -// UNSUPPORTED: linux +// UNSUPPORTED: OS=linux-gnu // REQUIRES: rdar86028226 diff --git a/test/Concurrency/Runtime/async_taskgroup_is_asyncsequence.swift b/test/Concurrency/Runtime/async_taskgroup_is_asyncsequence.swift index 8f036a0023a82..5ec0e92fc874f 100644 --- a/test/Concurrency/Runtime/async_taskgroup_is_asyncsequence.swift +++ b/test/Concurrency/Runtime/async_taskgroup_is_asyncsequence.swift @@ -7,7 +7,7 @@ // REQUIRES: concurrency_runtime // UNSUPPORTED: back_deployment_runtime -// UNSUPPORTED: linux +// UNSUPPORTED: OS=linux-gnu @available(SwiftStdlib 5.1, *) func test_taskGroup_is_asyncSequence() async { diff --git a/test/Concurrency/Runtime/executor_deinit1.swift b/test/Concurrency/Runtime/executor_deinit1.swift index a5f04ec1db5e7..904defa6bbea8 100644 --- a/test/Concurrency/Runtime/executor_deinit1.swift +++ b/test/Concurrency/Runtime/executor_deinit1.swift @@ -7,7 +7,7 @@ // UNSUPPORTED: back_deployment_runtime // https://bugs.swift.org/browse/SR-14461 -// UNSUPPORTED: linux +// UNSUPPORTED: OS=linux-gnu // REQUIRES: rdar78325660 diff --git a/test/Concurrency/concurrent_value_checking.swift b/test/Concurrency/concurrent_value_checking.swift index b59358496b1aa..fab8179829e3c 100644 --- a/test/Concurrency/concurrent_value_checking.swift +++ b/test/Concurrency/concurrent_value_checking.swift @@ -223,7 +223,7 @@ protocol AsyncProto { } extension A1: AsyncProto { - func asyncMethod(_: NotConcurrent) async { } // expected-warning{{non-sendable type 'NotConcurrent' in parameter of actor-isolated instance method 'asyncMethod' satisfying non-isolated protocol requirement cannot cross actor boundary}} + func asyncMethod(_: NotConcurrent) async { } // expected-warning{{non-sendable type 'NotConcurrent' in parameter of actor-isolated instance method 'asyncMethod' satisfying protocol requirement cannot cross actor boundary}} } protocol MainActorProto { @@ -232,7 +232,7 @@ protocol MainActorProto { class SomeClass: MainActorProto { @SomeGlobalActor - func asyncMainMethod(_: NotConcurrent) async { } // expected-warning{{non-sendable type 'NotConcurrent' in parameter of global actor 'SomeGlobalActor'-isolated instance method 'asyncMainMethod' satisfying non-isolated protocol requirement cannot cross actor boundary}} + func asyncMainMethod(_: NotConcurrent) async { } // expected-warning{{non-sendable type 'NotConcurrent' in parameter of global actor 'SomeGlobalActor'-isolated instance method 'asyncMainMethod' satisfying protocol requirement cannot cross actor boundary}} } // ---------------------------------------------------------------------- @@ -255,7 +255,7 @@ var concurrentFuncVar: (@Sendable (NotConcurrent) -> Void)? = nil // ---------------------------------------------------------------------- func acceptConcurrentUnary(_: @Sendable (T) -> T) { } -func concurrentClosures(_: T) { +func concurrentClosures(_: T) { // expected-note{{consider making generic parameter 'T' conform to the 'Sendable' protocol}} {{26-26=: Sendable}} acceptConcurrentUnary { (x: T) in _ = x // ok acceptConcurrentUnary { _ in x } // expected-warning{{capture of 'x' with non-sendable type 'T' in a `@Sendable` closure}} @@ -269,7 +269,7 @@ struct S1: Sendable { var nc: NotConcurrent // expected-warning{{stored property 'nc' of 'Sendable'-conforming struct 'S1' has non-sendable type 'NotConcurrent'}} } -struct S2: Sendable { +struct S2: Sendable { // expected-note{{consider making generic parameter 'T' conform to the 'Sendable' protocol}} {{12-12=: Sendable}} var nc: T // expected-warning{{stored property 'nc' of 'Sendable'-conforming generic struct 'S2' has non-sendable type 'T'}} } diff --git a/test/Concurrency/sendable_checking.swift b/test/Concurrency/sendable_checking.swift index 269ecd597a212..c2714efa40edc 100644 --- a/test/Concurrency/sendable_checking.swift +++ b/test/Concurrency/sendable_checking.swift @@ -4,6 +4,7 @@ @available(SwiftStdlib 5.1, *) struct NS1 { } +// expected-note@-1 2{{consider making struct 'NS1' conform to the 'Sendable' protocol}} @available(SwiftStdlib 5.1, *) @available(*, unavailable) @@ -68,10 +69,21 @@ public protocol MyProto { func foo(aFoo: F) async where F: Sendable } +@available(SwiftStdlib 5.1, *) +func nonisolatedAsyncFunc1(_: NS1) async { } + +@available(SwiftStdlib 5.1, *) +func nonisolatedAsyncFunc2() async -> NS1 { NS1() } + @available(SwiftStdlib 5.1, *) public actor MyActor: MyProto { public func foo(aFoo: F) async where F: Sendable { } public func bar(aBar: B) async where B: Sendable { } + + func g(ns1: NS1) async { + await nonisolatedAsyncFunc1(ns1) // expected-warning{{non-sendable type 'NS1' exiting actor-isolated context in call to non-isolated global function 'nonisolatedAsyncFunc1' cannot cross actor boundary}} + _ = await nonisolatedAsyncFunc2() // expected-warning{{non-sendable type 'NS1' returned by call from actor-isolated context to non-isolated global function 'nonisolatedAsyncFunc2()' cannot cross actor boundary}} + } } // rdar://82452688 - make sure sendable checking doesn't fire for a capture diff --git a/test/Concurrency/sendable_conformance_checking.swift b/test/Concurrency/sendable_conformance_checking.swift index 51041332ab284..08a602aaa1a34 100644 --- a/test/Concurrency/sendable_conformance_checking.swift +++ b/test/Concurrency/sendable_conformance_checking.swift @@ -2,7 +2,7 @@ // REQUIRES: concurrency @available(SwiftStdlib 5.1, *) -class NotSendable { // expected-note 8{{class 'NotSendable' does not conform to the 'Sendable' protocol}} +class NotSendable { // expected-note 9{{class 'NotSendable' does not conform to the 'Sendable' protocol}} } @available(SwiftStdlib 5.1, *) @@ -13,6 +13,8 @@ extension NotSendable: Sendable { } protocol IsolatedWithNotSendableRequirements: Actor { func f() -> NotSendable var prop: NotSendable { get } + + func fAsync() async -> NotSendable } // Okay, everything is isolated the same way @@ -20,6 +22,7 @@ protocol IsolatedWithNotSendableRequirements: Actor { actor A1: IsolatedWithNotSendableRequirements { func f() -> NotSendable { NotSendable() } var prop: NotSendable { NotSendable() } + func fAsync() async -> NotSendable { NotSendable() } } // Okay, sendable checking occurs when calling through the protocol @@ -28,6 +31,9 @@ actor A1: IsolatedWithNotSendableRequirements { actor A2: IsolatedWithNotSendableRequirements { nonisolated func f() -> NotSendable { NotSendable() } nonisolated var prop: NotSendable { NotSendable() } + + nonisolated func fAsync() async -> NotSendable { NotSendable() } + // expected-warning@-1{{non-sendable type 'NotSendable' returned by nonisolated instance method 'fAsync()' satisfying protocol requirement cannot cross actor boundary}} } @available(SwiftStdlib 5.1, *) @@ -40,9 +46,9 @@ protocol AsyncProtocolWithNotSendable { // actor's domain. @available(SwiftStdlib 5.1, *) actor A3: AsyncProtocolWithNotSendable { - func f() async -> NotSendable { NotSendable() } // expected-warning{{non-sendable type 'NotSendable' returned by actor-isolated instance method 'f()' satisfying non-isolated protocol requirement cannot cross actor boundary}} + func f() async -> NotSendable { NotSendable() } // expected-warning{{non-sendable type 'NotSendable' returned by actor-isolated instance method 'f()' satisfying protocol requirement cannot cross actor boundary}} - var prop: NotSendable { // expected-warning{{non-sendable type 'NotSendable' in conformance of actor-isolated property 'prop' to non-isolated protocol requirement cannot cross actor boundary}} + var prop: NotSendable { // expected-warning{{non-sendable type 'NotSendable' in conformance of actor-isolated property 'prop' to protocol requirement cannot cross actor boundary}} get async { NotSendable() } @@ -53,9 +59,9 @@ actor A3: AsyncProtocolWithNotSendable { // actor's domain. @available(SwiftStdlib 5.1, *) actor A4: AsyncProtocolWithNotSendable { - func f() -> NotSendable { NotSendable() } // expected-warning{{non-sendable type 'NotSendable' returned by actor-isolated instance method 'f()' satisfying non-isolated protocol requirement cannot cross actor boundary}} + func f() -> NotSendable { NotSendable() } // expected-warning{{non-sendable type 'NotSendable' returned by actor-isolated instance method 'f()' satisfying protocol requirement cannot cross actor boundary}} - var prop: NotSendable { // expected-warning{{non-sendable type 'NotSendable' in conformance of actor-isolated property 'prop' to non-isolated protocol requirement cannot cross actor boundary}} + var prop: NotSendable { // expected-warning{{non-sendable type 'NotSendable' in conformance of actor-isolated property 'prop' to protocol requirement cannot cross actor boundary}} get { NotSendable() } @@ -98,9 +104,9 @@ protocol AsyncThrowingProtocolWithNotSendable { // actor's domain. @available(SwiftStdlib 5.1, *) actor A7: AsyncThrowingProtocolWithNotSendable { - func f() async -> NotSendable { NotSendable() } // expected-warning{{non-sendable type 'NotSendable' returned by actor-isolated instance method 'f()' satisfying non-isolated protocol requirement cannot cross actor boundary}} + func f() async -> NotSendable { NotSendable() } // expected-warning{{non-sendable type 'NotSendable' returned by actor-isolated instance method 'f()' satisfying protocol requirement cannot cross actor boundary}} - var prop: NotSendable { // expected-warning{{non-sendable type 'NotSendable' in conformance of actor-isolated property 'prop' to non-isolated protocol requirement cannot cross actor boundary}} + var prop: NotSendable { // expected-warning{{non-sendable type 'NotSendable' in conformance of actor-isolated property 'prop' to protocol requirement cannot cross actor boundary}} get async { NotSendable() } @@ -111,9 +117,9 @@ actor A7: AsyncThrowingProtocolWithNotSendable { // actor's domain. @available(SwiftStdlib 5.1, *) actor A8: AsyncThrowingProtocolWithNotSendable { - func f() -> NotSendable { NotSendable() } // expected-warning{{non-sendable type 'NotSendable' returned by actor-isolated instance method 'f()' satisfying non-isolated protocol requirement cannot cross actor boundary}} + func f() -> NotSendable { NotSendable() } // expected-warning{{non-sendable type 'NotSendable' returned by actor-isolated instance method 'f()' satisfying protocol requirement cannot cross actor boundary}} - var prop: NotSendable { // expected-warning{{non-sendable type 'NotSendable' in conformance of actor-isolated property 'prop' to non-isolated protocol requirement cannot cross actor boundary}} + var prop: NotSendable { // expected-warning{{non-sendable type 'NotSendable' in conformance of actor-isolated property 'prop' to protocol requirement cannot cross actor boundary}} get { NotSendable() } diff --git a/test/Concurrency/sendable_override_checking.swift b/test/Concurrency/sendable_override_checking.swift new file mode 100644 index 0000000000000..b3e4c2b02f751 --- /dev/null +++ b/test/Concurrency/sendable_override_checking.swift @@ -0,0 +1,28 @@ +// RUN: %target-typecheck-verify-swift +// REQUIRES: concurrency + +@available(SwiftStdlib 5.1, *) +class NotSendable { // expected-note 2{{class 'NotSendable' does not conform to the 'Sendable' protocol}} +} + +@available(SwiftStdlib 5.1, *) +@available(*, unavailable) +extension NotSendable: Sendable { } + +@available(SwiftStdlib 5.1, *) +class Super { + func f(_: NotSendable) async { } + @MainActor func g1(_: NotSendable) { } + @MainActor func g2(_: NotSendable) async { } +} + +@available(SwiftStdlib 5.1, *) +class Sub: Super { + @MainActor override func f(_: NotSendable) async { } + // expected-warning@-1{{non-sendable type 'NotSendable' in parameter of main actor-isolated overriding instance method 'f' cannot cross actor boundary}} + + nonisolated override func g1(_: NotSendable) { } // okay, synchronous + + nonisolated override func g2(_: NotSendable) async { } + // expected-warning@-1{{non-sendable type 'NotSendable' in parameter of nonisolated overriding instance method 'g2' cannot cross actor boundary}} +} diff --git a/test/Concurrency/sr15049.swift b/test/Concurrency/sr15049.swift index aa1fe89afe9ee..2092d86e94fd4 100644 --- a/test/Concurrency/sr15049.swift +++ b/test/Concurrency/sr15049.swift @@ -19,26 +19,33 @@ func testAsyncSequence1Sendable(_ seq: Seq) async throws whe async let _ = seq.reduce(0) { $0 + $1 } // OK } -// TODO(diagnostics) [SR-16092]: Add a tailored wording for implicit autoclosure captures in sendable warnings, because -// from user perspective there is no closure capture, so diagnostic can be confusing. -func testAsyncSequenceTypedPattern(_ seq: Seq) async throws where Seq.Element == Int { +func testAsyncSequenceTypedPattern(_ seq: Seq) async throws where Seq.Element == Int { // expected-note{{consider making generic parameter 'Seq' conform to the 'Sendable' protocol}} {{54-54=, Sendable}} async let result: Int = seq.reduce(0) { $0 + $1 } // OK // expected-warning@-1{{immutable value 'result' was never used; consider replacing with '_' or removing it}} - // expected-warning@-2{{capture of 'seq' with non-sendable type 'Seq' in a `@Sendable` closure}} + // expected-warning@-2{{capture of 'seq' with non-sendable type 'Seq' in 'async let' binding}} } -func testAsyncSequenceTypedPattern1(_ seq: Seq) async throws where Seq.Element == Int { +func testAsyncSequenceTypedPattern1(_ seq: Seq) async throws where Seq.Element == Int { // expected-note{{consider making generic parameter 'Seq' conform to the 'Sendable' protocol}} {{55-55=, Sendable}} async let _: Int = seq.reduce(0) { $0 + $1 } // OK - // expected-warning@-1{{capture of 'seq' with non-sendable type 'Seq' in a `@Sendable` closure}} + // expected-warning@-1{{capture of 'seq' with non-sendable type 'Seq' in 'async let' binding}} } -func testAsyncSequence(_ seq: Seq) async throws where Seq.Element == Int { +func testAsyncSequence(_ seq: Seq) async throws where Seq.Element == Int { // expected-note{{consider making generic parameter 'Seq' conform to the 'Sendable' protocol}} {{42-42=, Sendable}} async let result = seq.reduce(0) { $0 + $1 } // OK // expected-warning@-1{{initialization of immutable value 'result' was never used; consider replacing with assignment to '_' or removing it}} - // expected-warning@-2{{capture of 'seq' with non-sendable type 'Seq' in a `@Sendable` closure}} + // expected-warning@-2{{capture of 'seq' with non-sendable type 'Seq' in 'async let' binding}} } -func testAsyncSequence1(_ seq: Seq) async throws where Seq.Element == Int { +func testAsyncSequence1(_ seq: Seq) async throws where Seq.Element == Int { // expected-note{{consider making generic parameter 'Seq' conform to the 'Sendable' protocol}} {{43-43=, Sendable}} async let _ = seq.reduce(0) { $0 + $1 } // OK - // expected-warning@-1{{capture of 'seq' with non-sendable type 'Seq' in a `@Sendable` closure}} + // expected-warning@-1{{capture of 'seq' with non-sendable type 'Seq' in 'async let' binding}} +} + +func testAsyncSequence3(_ seq: Seq) async throws where Seq: AsyncSequence, Seq.Element == Int { // expected-note{{consider making generic parameter 'Seq' conform to the 'Sendable' protocol}} {{28-28=: Sendable}} + async let result = seq // expected-warning{{capture of 'seq' with non-sendable type 'Seq' in 'async let' binding}} + //expected-warning@-1{{initialization of immutable value 'result' was never used; consider replacing with assignment to '_' or removing it}} +} + +func testAsyncSequence4(_ seq: Seq) async throws where Seq: AsyncSequence, Seq.Element == Int { // expected-note{{consider making generic parameter 'Seq' conform to the 'Sendable' protocol}} {{28-28=: Sendable}} + async let _ = seq // expected-warning{{capture of 'seq' with non-sendable type 'Seq' in 'async let' binding}} } diff --git a/test/Concurrency/unsafe_inherit_executor.swift b/test/Concurrency/unsafe_inherit_executor.swift index f14c88deb92ad..8512232491f89 100644 --- a/test/Concurrency/unsafe_inherit_executor.swift +++ b/test/Concurrency/unsafe_inherit_executor.swift @@ -21,7 +21,7 @@ struct A { } -class NonSendableObject { +class NonSendableObject { // expected-note{{class 'NonSendableObject' does not conform to the 'Sendable' protocol}} var property = 0 } @@ -31,7 +31,7 @@ func useNonSendable(object: NonSendableObject) async {} actor MyActor { var object = NonSendableObject() func foo() async { - // This should not be diagnosed when we implement SE-0338 checking. + // expected-warning@+1{{non-sendable type 'NonSendableObject' exiting actor-isolated context in call to non-isolated global function 'useNonSendable(object:)' cannot cross actor boundary}} await useNonSendable(object: self.object) } } diff --git a/test/Constraints/Inputs/c_pointer_conversions.h b/test/Constraints/Inputs/c_pointer_conversions.h index 52a0d2bd83b36..c0f4cabd21c19 100644 --- a/test/Constraints/Inputs/c_pointer_conversions.h +++ b/test/Constraints/Inputs/c_pointer_conversions.h @@ -2,6 +2,11 @@ #include "stdint.h" +void void_ptr_func(void * _Nonnull buffer); +void const_void_ptr_func(const void * _Nonnull buffer); +void opt_void_ptr_func(void * _Nullable buffer); +void const_opt_void_ptr_func(const void * _Nullable buffer); + void char_ptr_func(char * _Nonnull buffer); void const_char_ptr_func(const char * _Nonnull buffer); diff --git a/test/Constraints/argument_matching.swift b/test/Constraints/argument_matching.swift index 291d2cd95ca9a..c3ff7d144c50b 100644 --- a/test/Constraints/argument_matching.swift +++ b/test/Constraints/argument_matching.swift @@ -1782,3 +1782,10 @@ func testExtraTrailingClosure() { func qux(x: () -> Void, y: () -> Void, z: () -> Void) {} // expected-note {{'qux(x:y:z:)' declared here}} qux() {} m: {} y: {} n: {} z: {} o: {} // expected-error@:6 {{extra trailing closures at positions #2, #4, #6 in call}} } + +// rdar://93922410 - argument-to-parameter doesn't handle applies of ParamDecls +func rdar93922410(_ completion: (Int?) -> Void) { // expected-note {{'completion' declared here}} + _ = { + return completion() // expected-error {{missing argument for parameter #1 in call}} + } +} diff --git a/test/Constraints/existential_metatypes.swift b/test/Constraints/existential_metatypes.swift index 962fcd30d5eb2..45bb7365f2f4a 100644 --- a/test/Constraints/existential_metatypes.swift +++ b/test/Constraints/existential_metatypes.swift @@ -90,3 +90,33 @@ func testP3(_ p: P3, something: Something) { func testIUOToAny(_ t: AnyObject.Type!) { let _: Any = t } + +protocol P4 { + associatedtype T +} + +protocol Q4 { + associatedtype T +} + +protocol PP4: P4 { + associatedtype U: P4 +} + +func parameterizedExistentials() { + var qp: (any Q4).Type + var pp: (any P4).Type = qp // expected-error{{cannot convert value of type '(any Q4).Type' to specified type '(any P4).Type'}} + + var qt: any Q4.Type + qt = qp // expected-error{{cannot assign value of type '(any Q4).Type' to type 'any Q4.Type'}} + qp = qt // expected-error{{cannot assign value of type 'any Q4.Type' to type '(any Q4).Type'}} + var pt: any P4.Type = qt // expected-error{{cannot convert value of type 'any Q4.Type' to specified type 'any P4.Type'}} + pt = pp // expected-error{{cannot assign value of type '(any P4).Type' to type 'any P4.Type'}} + pp = pt // expected-error{{cannot assign value of type 'any P4.Type' to type '(any P4).Type'}} + + var ppp: (any PP4).Type + pp = ppp // expected-error{{cannot assign value of type '(any PP4).Type' to type '(any P4).Type'}} + + var ppt: any PP4.Type + pt = ppt +} diff --git a/test/Constraints/parameterized_existential_metatypes.swift b/test/Constraints/parameterized_existential_metatypes.swift deleted file mode 100644 index be2e6d092b015..0000000000000 --- a/test/Constraints/parameterized_existential_metatypes.swift +++ /dev/null @@ -1,31 +0,0 @@ -// RUN: %target-typecheck-verify-swift -enable-parameterized-existential-types -disable-availability-checking -// -// FIXME: Merge this file with existential_metatypes.swift once -enable-parameterized-existential-types becomes the default - -protocol P { - associatedtype T -} - -protocol Q { - associatedtype T -} - -protocol PP: P { - associatedtype U: P -} - -var qp: (any Q).Type -var pp: (any P).Type = qp // expected-error{{cannot convert value of type '(any Q).Type' to specified type '(any P).Type'}} - -var qt: any Q.Type -qt = qp // expected-error{{cannot assign value of type '(any Q).Type' to type 'any Q.Type'}} -qp = qt // expected-error{{cannot assign value of type 'any Q.Type' to type '(any Q).Type'}} -var pt: any P.Type = qt // expected-error{{cannot convert value of type 'any Q.Type' to specified type 'any P.Type'}} -pt = pp // expected-error{{cannot assign value of type '(any P).Type' to type 'any P.Type'}} -pp = pt // expected-error{{cannot assign value of type 'any P.Type' to type '(any P).Type'}} - -var ppp: (any PP).Type -pp = ppp // expected-error{{cannot assign value of type '(any PP).Type' to type '(any P).Type'}} - -var ppt: any PP.Type -pt = ppt diff --git a/test/Constraints/result_builder_callAsFunction.swift b/test/Constraints/result_builder_callAsFunction.swift new file mode 100644 index 0000000000000..a1546345b94d9 --- /dev/null +++ b/test/Constraints/result_builder_callAsFunction.swift @@ -0,0 +1,36 @@ +// RUN: %target-typecheck-verify-swift -target %target-cpu-apple-macosx10.15 -swift-version 5 -debug-constraints > %t.log 2>&1 +// RUN: %FileCheck %s < %t.log + +// REQUIRES: objc_interop +// REQUIRES: OS=macosx + +protocol View {} +protocol Callable {} + +struct EmptyView : View {} + +@resultBuilder struct ViewBuilder { + static func buildBlock(_ content: Content) -> Content where Content : View { fatalError() } +} + +extension Callable { + func callAsFunction(@ViewBuilder _: () -> T) -> some View { EmptyView() } +} + +struct MyView : View { + init(v: Int, @ViewBuilder _: () -> Content) {} +} + +extension MyView : Callable where Content == EmptyView { + init(v: Int) {} +} + +// CHECK: (overload set choice binding $T6 := (Int) -> MyView<{{.*}}>) +// CHECK-NEXT: (increasing score due to disfavored overload) +// CHECK-NEXT: (solution is worse than the best solution) + +func test() -> some View { + return MyView(v: 42) { + return EmptyView() + } +} diff --git a/test/Constraints/swift_to_c_pointer_conversions.swift.gyb b/test/Constraints/swift_to_c_pointer_conversions.swift.gyb index d70a6497a86ab..b57cdbf364304 100644 --- a/test/Constraints/swift_to_c_pointer_conversions.swift.gyb +++ b/test/Constraints/swift_to_c_pointer_conversions.swift.gyb @@ -269,3 +269,30 @@ func test_tailored_diagnostic(ptr: UnsafeRawPointer, tptr: UnsafePointer) opt_arg_func(optrU8) // expected-error@-1 {{cannot convert value of type 'UnsafePointer?' to expected argument type 'UnsafePointer?' because local function 'opt_arg_func' was not imported from C header}} } + +func test_inout_to_pointer_conversion() { +% for Size in ['16', '32', '64']: + var x${Size}: Int${Size} = 0 + + void_ptr_func(&x${Size}) // Ok + const_void_ptr_func(&x${Size}) // Ok + opt_void_ptr_func(&x${Size}) // Ok + + char_ptr_func(&x${Size}) // Ok + opt_char_ptr_func(&x${Size}) // Ok + + const_char_ptr_func(&x${Size}) // Ok + const_opt_char_ptr_func(&x${Size}) // Ok + + int_${Size}_ptr_func(&x${Size}) // Ok + uint_${Size}_ptr_func(&x${Size}) // Ok + + opt_int_${Size}_ptr_func(&x${Size}) // Ok + opt_uint_${Size}_ptr_func(&x${Size}) // Ok + + const_int_${Size}_ptr_func(&x${Size}) // OK + const_uint_${Size}_ptr_func(&x${Size}) // OK + const_opt_int_${Size}_ptr_func(&x${Size}) // OK + const_opt_uint_${Size}_ptr_func(&x${Size}) // OK +% end +} diff --git a/test/DebugInfo/local-vars.swift.gyb b/test/DebugInfo/local-vars.swift.gyb index 082d967215109..c13f46fa0a451 100644 --- a/test/DebugInfo/local-vars.swift.gyb +++ b/test/DebugInfo/local-vars.swift.gyb @@ -3,7 +3,7 @@ // all. There are other tests testing liveness and representation. // rdar://problem/57611302 -// XFAIL: windows +// XFAIL: OS=windows-msvc // RUN: %gyb %s -o %t.swift // RUN: %target-swift-frontend %t.swift -g -emit-ir -o - | %FileCheck %t.swift diff --git a/test/DebugInfo/move_function_dbginfo_async.swift b/test/DebugInfo/move_function_dbginfo_async.swift index ffa9982fad269..f7ecd82141e25 100644 --- a/test/DebugInfo/move_function_dbginfo_async.swift +++ b/test/DebugInfo/move_function_dbginfo_async.swift @@ -342,6 +342,45 @@ public func varSimpleTestVar() async { // This is the continuation block // CHECK-LABEL: define internal swifttailcc void @"$s27move_function_dbginfo_async20letArgCCFlowTrueTestyyxnYalFTQ4_"( // CHECK: call void @llvm.dbg.value(metadata %swift.opaque* undef, metadata !{{.*}}, metadata !DIExpression(DW_OP_deref)), + +// DWARF: DW_TAG_subprogram +// DWARF: DW_AT_linkage_name ("$s3out20letArgCCFlowTrueTestyyxnYalF") +// DWARF: DW_AT_name ("letArgCCFlowTrueTest") + +// DWARF: DW_TAG_formal_parameter +// DWARF-NEXT: DW_AT_location (DW_OP_entry_value([[ASYNC_REG]]), DW_OP_plus_uconst 0x10, DW_OP_plus_uconst 0x8, DW_OP_deref) +// DWARF-NEXT: DW_AT_name ("msg") +// +// DWARF: DW_AT_linkage_name ("$s3out20letArgCCFlowTrueTestyyxnYalFTQ0_") +// DWARF-NEXT: DW_AT_name ("letArgCCFlowTrueTest") +// DWARF: DW_TAG_formal_parameter +// DWARF-NEXT: DW_AT_location (DW_OP_entry_value([[ASYNC_REG]]), DW_OP_deref, DW_OP_plus_uconst 0x10, DW_OP_plus_uconst 0x8, DW_OP_deref) +// DWARF-NEXT: DW_AT_name ("msg") +// +// DWARF: DW_AT_linkage_name ("$s3out20letArgCCFlowTrueTestyyxnYalFTY1_") +// DWARF-NEXT: DW_AT_name ("letArgCCFlowTrueTest") +// DWARF: DW_TAG_formal_parameter +// DWARF-NEXT: DW_AT_location (0x{{[a-f0-9]+}}: +// DWARF-NEXT: [0x{{[a-f0-9]+}}, 0x{{[a-f0-9]+}}): DW_OP_entry_value([[ASYNC_REG]]), DW_OP_plus_uconst 0x10, DW_OP_plus_uconst 0x8, DW_OP_deref +// DWARF-NEXT: [0x{{[a-f0-9]+}}, 0x{{[a-f0-9]+}}): DW_OP_entry_value([[ASYNC_REG]]), DW_OP_plus_uconst 0x10, DW_OP_plus_uconst 0x8, DW_OP_deref) +// DWARF-NEXT: DW_AT_name ("msg") +// +// DWARF: DW_AT_linkage_name ("$s3out20letArgCCFlowTrueTestyyxnYalFTQ2_") +// DWARF-NEXT: DW_AT_name ("letArgCCFlowTrueTest") +// DWARF: DW_TAG_formal_parameter +// DWARF-NEXT: DW_AT_name ("msg") +// +// DWARF: DW_AT_linkage_name ("$s3out20letArgCCFlowTrueTestyyxnYalFTQ3_") +// DWARF-NEXT: DW_AT_name ("letArgCCFlowTrueTest") +// DWARF: DW_TAG_formal_parameter +// DWARF-NEXT: DW_AT_location (0x{{[a-f0-9]+}}: +// DWARF-NEXT: [0x{{[a-f0-9]+}}, 0x{{[a-f0-9]+}}): DW_OP_entry_value([[ASYNC_REG]]), DW_OP_deref, DW_OP_plus_uconst 0x10, DW_OP_plus_uconst 0x8, DW_OP_deref) +// DWARF-NEXT: DW_AT_name ("msg") +// +// DWARF: DW_AT_linkage_name ("$s3out20letArgCCFlowTrueTestyyxnYalFTQ4_") +// DWARF-NEXT: DW_AT_name ("letArgCCFlowTrueTest") +// DWARF: DW_TAG_formal_parameter +// DWARF-NEXT: DW_AT_name ("msg") public func letArgCCFlowTrueTest(_ msg: __owned T) async { await forceSplit1() if trueValue { @@ -441,6 +480,58 @@ public func letArgCCFlowTrueTest(_ msg: __owned T) async { // CHECK: musttail call swifttailcc void %{{[0-9]+}}(%swift.context* swiftasync // CHECK-NEXT: ret void, // CHECK-NEXT: } + +// DWARF: DW_AT_linkage_name ("$s3out20varArgCCFlowTrueTestyyxzYaAA1PRzlF") +// DWARF: DW_AT_name ("varArgCCFlowTrueTest") +// DWARF: DW_TAG_formal_parameter +// DWARF-NEXT: DW_AT_location (DW_OP_entry_value([[ASYNC_REG]]), DW_OP_plus_uconst 0x10, DW_OP_plus_uconst 0x30, DW_OP_deref) +// DWARF-NEXT: DW_AT_name ("msg") +// +// DWARF: DW_AT_linkage_name ("$s3out20varArgCCFlowTrueTestyyxzYaAA1PRzlFTQ0_") +// DWARF-NEXT: DW_AT_name ("varArgCCFlowTrueTest") +// DWARF: DW_TAG_formal_parameter +// DWARF-NEXT: DW_AT_location (DW_OP_entry_value([[ASYNC_REG]]), DW_OP_deref, DW_OP_plus_uconst 0x10, DW_OP_plus_uconst 0x30, DW_OP_deref) +// DWARF-NEXT: DW_AT_name ("msg") +// +// DWARF: DW_AT_linkage_name ("$s3out20varArgCCFlowTrueTestyyxzYaAA1PRzlFTY1_") +// DWARF-NEXT: DW_AT_name ("varArgCCFlowTrueTest") +// DWARF: DW_TAG_formal_parameter +// DWARF-NEXT: DW_AT_location (0x{{[a-f0-9]+}}: +// DWARF-NEXT: [0x{{[a-f0-9]+}}, 0x{{[a-f0-9]+}}): DW_OP_entry_value([[ASYNC_REG]]), DW_OP_plus_uconst 0x10, DW_OP_plus_uconst 0x30, DW_OP_deref +// DWARF-NEXT: [0x{{[a-f0-9]+}}, 0x{{[a-f0-9]+}}): DW_OP_entry_value([[ASYNC_REG]]), DW_OP_plus_uconst 0x10, DW_OP_plus_uconst 0x30, DW_OP_deref) +// DWARF-NEXT: DW_AT_name ("msg") +// +// DWARF: DW_AT_linkage_name ("$s3out20varArgCCFlowTrueTestyyxzYaAA1PRzlFTQ2_") +// DWARF-NEXT: DW_AT_name ("varArgCCFlowTrueTest") +// DWARF: DW_TAG_formal_parameter +// DWARF-NEXT: DW_AT_name ("msg") +// +// DWARF: DW_AT_linkage_name ("$s3out20varArgCCFlowTrueTestyyxzYaAA1PRzlFTY3_") +// DWARF-NEXT: DW_AT_name ("varArgCCFlowTrueTest") +// DWARF: DW_TAG_formal_parameter +// DWARF-NEXT: DW_AT_location (0x{{[a-f0-9]+}}: +// DWARF-NEXT: [0x{{[a-f0-9]+}}, 0x{{[a-f0-9]+}}): DW_OP_entry_value([[ASYNC_REG]]), DW_OP_plus_uconst 0x10, DW_OP_plus_uconst 0x30, DW_OP_deref) +// DWARF-NEXT: DW_AT_name ("msg") +// +// DWARF: DW_AT_linkage_name ("$s3out20varArgCCFlowTrueTestyyxzYaAA1PRzlFTQ4_") +// DWARF-NEXT: DW_AT_name ("varArgCCFlowTrueTest") +// DWARF: DW_TAG_formal_parameter +// DWARF-NEXT: DW_AT_location (0x{{[a-f0-9]+}}: +// DWARF-NEXT: [0x{{[a-f0-9]+}}, 0x{{[a-f0-9]+}}): DW_OP_entry_value([[ASYNC_REG]]), DW_OP_deref, DW_OP_plus_uconst 0x10, DW_OP_plus_uconst 0x30, DW_OP_deref) +// DWARF-NEXT: DW_AT_name ("msg") +// +// DWARF: DW_AT_linkage_name ("$s3out20varArgCCFlowTrueTestyyxzYaAA1PRzlFTY5_") +// DWARF-NEXT: DW_AT_name ("varArgCCFlowTrueTest") +// DWARF: DW_TAG_formal_parameter +// DWARF-NEXT: DW_AT_location (0x{{[a-f0-9]+}}: +// DWARF-NEXT: [0x{{[a-f0-9]+}}, 0x{{[a-f0-9]+}}): DW_OP_entry_value([[ASYNC_REG]]), DW_OP_plus_uconst 0x10, DW_OP_plus_uconst 0x30, DW_OP_deref) +// DWARF-NEXT: DW_AT_name ("msg") +// +// DWARF: DW_AT_linkage_name ("$s3out20varArgCCFlowTrueTestyyxzYaAA1PRzlFTQ6_") +// DWARF-NEXT: DW_AT_name ("varArgCCFlowTrueTest") +// DWARF: DW_TAG_formal_parameter +// DWARF-NEXT: DW_AT_location (DW_OP_entry_value([[ASYNC_REG]]), DW_OP_deref, DW_OP_plus_uconst 0x10, DW_OP_plus_uconst 0x30, DW_OP_deref) +// DWARF-NEXT: DW_AT_name ("msg") public func varArgCCFlowTrueTest(_ msg: inout T) async { await forceSplit1() if trueValue { diff --git a/test/Distributed/Runtime/distributed_actor_cross_module_final_class_adhoc_requirement_not_optimized_away.swift b/test/Distributed/Runtime/distributed_actor_cross_module_final_class_adhoc_requirement_not_optimized_away.swift index 03767a199b30d..e685e70719453 100644 --- a/test/Distributed/Runtime/distributed_actor_cross_module_final_class_adhoc_requirement_not_optimized_away.swift +++ b/test/Distributed/Runtime/distributed_actor_cross_module_final_class_adhoc_requirement_not_optimized_away.swift @@ -13,7 +13,7 @@ // UNSUPPORTED: back_deployment_runtime // FIXME(distributed): Distributed actors currently have some issues on windows, isRemote always returns false. rdar://82593574 -// UNSUPPORTED: windows +// UNSUPPORTED: OS=windows-msvc import Distributed import FakeDistributedActorSystems diff --git a/test/Distributed/Runtime/distributed_actor_deinit.swift b/test/Distributed/Runtime/distributed_actor_deinit.swift index 5a4d79f53ced8..e781c5e0a80fe 100644 --- a/test/Distributed/Runtime/distributed_actor_deinit.swift +++ b/test/Distributed/Runtime/distributed_actor_deinit.swift @@ -8,7 +8,7 @@ // UNSUPPORTED: back_deployment_runtime // FIXME(distributed): Distributed actors currently have some issues on windows, isRemote always returns false. rdar://82593574 -// UNSUPPORTED: windows +// UNSUPPORTED: OS=windows-msvc import Distributed diff --git a/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_echo.swift b/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_echo.swift index 8b26af2a09be3..bbcad0d4740d7 100644 --- a/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_echo.swift +++ b/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_echo.swift @@ -12,7 +12,7 @@ // UNSUPPORTED: back_deployment_runtime // FIXME(distributed): Distributed actors currently have some issues on windows, isRemote always returns false. rdar://82593574 -// UNSUPPORTED: windows +// UNSUPPORTED: OS=windows-msvc import Distributed import FakeDistributedActorSystems diff --git a/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_empty.swift b/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_empty.swift index b3cf476d23876..11e6de63d7141 100644 --- a/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_empty.swift +++ b/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_empty.swift @@ -12,7 +12,7 @@ // UNSUPPORTED: back_deployment_runtime // FIXME(distributed): Distributed actors currently have some issues on windows, isRemote always returns false. rdar://82593574 -// UNSUPPORTED: windows +// UNSUPPORTED: OS=windows-msvc import Distributed import FakeDistributedActorSystems diff --git a/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_genericFunc.swift b/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_genericFunc.swift index 23c778ca5524e..7ff6dcb0e9b02 100644 --- a/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_genericFunc.swift +++ b/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_genericFunc.swift @@ -12,7 +12,7 @@ // UNSUPPORTED: back_deployment_runtime // FIXME(distributed): Distributed actors currently have some issues on windows, isRemote always returns false. rdar://82593574 -// UNSUPPORTED: windows +// UNSUPPORTED: OS=windows-msvc import Distributed import FakeDistributedActorSystems diff --git a/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_hello.swift b/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_hello.swift index e3be138706354..c3bf701bc94b3 100644 --- a/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_hello.swift +++ b/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_hello.swift @@ -12,7 +12,7 @@ // UNSUPPORTED: back_deployment_runtime // FIXME(distributed): Distributed actors currently have some issues on windows, isRemote always returns false. rdar://82593574 -// UNSUPPORTED: windows +// UNSUPPORTED: OS=windows-msvc import Distributed import FakeDistributedActorSystems diff --git a/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_take.swift b/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_take.swift index 2857b2dbe605f..e8d9c58600d05 100644 --- a/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_take.swift +++ b/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_take.swift @@ -12,7 +12,7 @@ // UNSUPPORTED: back_deployment_runtime // FIXME(distributed): Distributed actors currently have some issues on windows, isRemote always returns false. rdar://82593574 -// UNSUPPORTED: windows +// UNSUPPORTED: OS=windows-msvc import Distributed import FakeDistributedActorSystems diff --git a/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_takeThrowReturn.swift b/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_takeThrowReturn.swift index 271ed8c2c65b2..1073ba2a84d41 100644 --- a/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_takeThrowReturn.swift +++ b/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_takeThrowReturn.swift @@ -12,7 +12,7 @@ // UNSUPPORTED: back_deployment_runtime // FIXME(distributed): Distributed actors currently have some issues on windows, isRemote always returns false. rdar://82593574 -// UNSUPPORTED: windows +// UNSUPPORTED: OS=windows-msvc import Distributed import FakeDistributedActorSystems diff --git a/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_take_two.swift b/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_take_two.swift index 201d2794ea812..435582b86f4d9 100644 --- a/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_take_two.swift +++ b/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_take_two.swift @@ -12,7 +12,7 @@ // UNSUPPORTED: back_deployment_runtime // FIXME(distributed): Distributed actors currently have some issues on windows, isRemote always returns false. rdar://82593574 -// UNSUPPORTED: windows +// UNSUPPORTED: OS=windows-msvc import Distributed import FakeDistributedActorSystems diff --git a/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_throw.swift b/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_throw.swift index c051b3e28f95e..a2664a6970a5d 100644 --- a/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_throw.swift +++ b/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_throw.swift @@ -12,7 +12,7 @@ // UNSUPPORTED: back_deployment_runtime // FIXME(distributed): Distributed actors currently have some issues on windows, isRemote always returns false. rdar://82593574 -// UNSUPPORTED: windows +// UNSUPPORTED: OS=windows-msvc import Distributed import FakeDistributedActorSystems diff --git a/test/Distributed/Runtime/distributed_actor_hop_to.swift b/test/Distributed/Runtime/distributed_actor_hop_to.swift index 4d977f274ea2c..54186c8828011 100644 --- a/test/Distributed/Runtime/distributed_actor_hop_to.swift +++ b/test/Distributed/Runtime/distributed_actor_hop_to.swift @@ -12,7 +12,7 @@ // UNSUPPORTED: back_deployment_runtime // FIXME(distributed): Distributed actors currently have some issues on windows, isRemote always returns false. rdar://82593574 -// UNSUPPORTED: windows +// UNSUPPORTED: OS=windows-msvc import Distributed diff --git a/test/Distributed/Runtime/distributed_actor_in_other_module.swift b/test/Distributed/Runtime/distributed_actor_in_other_module.swift index 21c545caccf2a..785b6d8d9285f 100644 --- a/test/Distributed/Runtime/distributed_actor_in_other_module.swift +++ b/test/Distributed/Runtime/distributed_actor_in_other_module.swift @@ -12,7 +12,7 @@ // UNSUPPORTED: back_deployment_runtime // FIXME(distributed): Distributed actors currently have some issues on windows, isRemote always returns false. rdar://82593574 -// UNSUPPORTED: windows +// UNSUPPORTED: OS=windows-msvc // REQUIRES: rdar92277324 diff --git a/test/Distributed/Runtime/distributed_actor_remoteCall.swift b/test/Distributed/Runtime/distributed_actor_remoteCall.swift index d339aa6ad29e9..3f6dbeb06fd74 100644 --- a/test/Distributed/Runtime/distributed_actor_remoteCall.swift +++ b/test/Distributed/Runtime/distributed_actor_remoteCall.swift @@ -12,7 +12,7 @@ // UNSUPPORTED: back_deployment_runtime // FIXME(distributed): Distributed actors currently have some issues on windows, isRemote always returns false. rdar://82593574 -// UNSUPPORTED: windows +// UNSUPPORTED: OS=windows-msvc import Distributed diff --git a/test/Distributed/Runtime/distributed_actor_remoteCallTarget_demanglingTargetNames.swift b/test/Distributed/Runtime/distributed_actor_remoteCallTarget_demanglingTargetNames.swift index 26f626d44d527..7f705dae84100 100644 --- a/test/Distributed/Runtime/distributed_actor_remoteCallTarget_demanglingTargetNames.swift +++ b/test/Distributed/Runtime/distributed_actor_remoteCallTarget_demanglingTargetNames.swift @@ -12,7 +12,7 @@ // UNSUPPORTED: back_deployment_runtime // FIXME(distributed): Distributed actors currently have some issues on windows, isRemote always returns false. rdar://82593574 -// UNSUPPORTED: windows +// UNSUPPORTED: OS=windows-msvc import Distributed import FakeDistributedActorSystems diff --git a/test/Distributed/Runtime/distributed_actor_remoteCall_roundtrip.swift b/test/Distributed/Runtime/distributed_actor_remoteCall_roundtrip.swift index 8302d69a152da..cd3b03c60ee8b 100644 --- a/test/Distributed/Runtime/distributed_actor_remoteCall_roundtrip.swift +++ b/test/Distributed/Runtime/distributed_actor_remoteCall_roundtrip.swift @@ -14,7 +14,7 @@ // UNSUPPORTED: back_deployment_runtime // FIXME(distributed): Distributed actors currently have some issues on windows, isRemote always returns false. rdar://82593574 -// UNSUPPORTED: windows +// UNSUPPORTED: OS=windows-msvc import Distributed import FakeDistributedActorSystems diff --git a/test/Distributed/Runtime/distributed_actor_whenLocal.swift b/test/Distributed/Runtime/distributed_actor_whenLocal.swift index f474ed9b1e353..67c09e85af7f4 100644 --- a/test/Distributed/Runtime/distributed_actor_whenLocal.swift +++ b/test/Distributed/Runtime/distributed_actor_whenLocal.swift @@ -12,7 +12,7 @@ // UNSUPPORTED: back_deployment_runtime // FIXME(distributed): Distributed actors currently have some issues on windows, isRemote always returns false. rdar://82593574 -// UNSUPPORTED: windows +// UNSUPPORTED: OS=windows-msvc import Distributed diff --git a/test/Distributed/distributed_protocol_isolation.swift b/test/Distributed/distributed_protocol_isolation.swift index c1075f76bd812..3c07421c265c1 100644 --- a/test/Distributed/distributed_protocol_isolation.swift +++ b/test/Distributed/distributed_protocol_isolation.swift @@ -127,7 +127,8 @@ protocol Server { func send(message: Message) async throws -> String } actor MyServer : Server { - func send(message: Message) throws -> String { "" } // expected-warning{{non-sendable type 'Message' in parameter of actor-isolated instance method 'send(message:)' satisfying non-isolated protocol requirement cannot cross actor boundary}} + // expected-note@+1{{consider making generic parameter 'Message' conform to the 'Sendable' protocol}} {{29-29=, Sendable}} + func send(message: Message) throws -> String { "" } // expected-warning{{non-sendable type 'Message' in parameter of actor-isolated instance method 'send(message:)' satisfying protocol requirement cannot cross actor boundary}} } protocol AsyncThrowsAll { diff --git a/test/Driver/Dependencies/embed-bitcode-parallel-fine.swift b/test/Driver/Dependencies/embed-bitcode-parallel-fine.swift index 8de4fb11423cb..4f61676a7e854 100644 --- a/test/Driver/Dependencies/embed-bitcode-parallel-fine.swift +++ b/test/Driver/Dependencies/embed-bitcode-parallel-fine.swift @@ -1,5 +1,5 @@ // Windows doesn't support parallel execution yet -// XFAIL: windows +// XFAIL: OS=windows-msvc // RUN: %empty-directory(%t) // RUN: cp -r %S/Inputs/one-way-fine/* %t // RUN: touch -t 201401240005 %t/* diff --git a/test/Driver/Dependencies/one-way-parallel-fine.swift b/test/Driver/Dependencies/one-way-parallel-fine.swift index 5f30a6377af69..a6a47f1a14328 100644 --- a/test/Driver/Dependencies/one-way-parallel-fine.swift +++ b/test/Driver/Dependencies/one-way-parallel-fine.swift @@ -1,5 +1,5 @@ // Windows doesn't support parallel execution yet -// XFAIL: windows +// XFAIL: OS=windows-msvc // RUN: %empty-directory(%t) // RUN: cp -r %S/Inputs/one-way-fine/* %t // RUN: touch -t 201401240005 %t/* diff --git a/test/Driver/Dependencies/only-skip-once.swift b/test/Driver/Dependencies/only-skip-once.swift index 314c29f752b14..a710f20bfa3eb 100644 --- a/test/Driver/Dependencies/only-skip-once.swift +++ b/test/Driver/Dependencies/only-skip-once.swift @@ -1,4 +1,4 @@ -// XFAIL: linux, openbsd, windows +// XFAIL: OS=linux-gnu, OS=openbsd, OS=windows-msvc // RUN: %empty-directory(%t) // RUN: cp -r %S/Inputs/only-skip-once/* %t diff --git a/test/Driver/batch_mode_bridging_pch.swift b/test/Driver/batch_mode_bridging_pch.swift index 4100a01ffb7c1..f55c4eac2c7b8 100644 --- a/test/Driver/batch_mode_bridging_pch.swift +++ b/test/Driver/batch_mode_bridging_pch.swift @@ -1,4 +1,3 @@ -// XFAIL: win32 // RUN: %empty-directory(%t) // RUN: touch %t/file-01.swift %t/file-02.swift %t/file-03.swift // RUN: echo 'public func main() {}' >%t/main.swift diff --git a/test/Driver/environment.swift b/test/Driver/environment.swift index e8ec6d1cbfd2d..62d625ab30496 100644 --- a/test/Driver/environment.swift +++ b/test/Driver/environment.swift @@ -1,5 +1,5 @@ // UNSUPPORTED: objc_interop -// UNSUPPORTED: windows +// UNSUPPORTED: OS=windows-msvc // Apple's "System Integrity Protection" makes this test fail on OS X. // RUN: %swift_driver_plain -sdk "" -target x86_64-unknown-gnu-linux -L/foo/ -driver-use-frontend-path %S/Inputs/print-var.sh %s LD_LIBRARY_PATH | %FileCheck -check-prefix=CHECK${LD_LIBRARY_PATH+_LAX} %s diff --git a/test/Driver/filelists.swift b/test/Driver/filelists.swift index 732f4914e580b..7b52089623f48 100644 --- a/test/Driver/filelists.swift +++ b/test/Driver/filelists.swift @@ -1,4 +1,4 @@ -// UNSUPPORTED: windows +// UNSUPPORTED: OS=windows-msvc // RUN: %empty-directory(%t) // RUN: touch %t/a.swift %t/b.swift %t/c.swift diff --git a/test/Driver/frontend.swift b/test/Driver/frontend.swift index f0ee617810814..b34eb00876f34 100644 --- a/test/Driver/frontend.swift +++ b/test/Driver/frontend.swift @@ -1,5 +1,5 @@ // RUN: %swiftc_driver %s -### 2>&1 | %FileCheck %s -// UNSUPPORTED: windows +// UNSUPPORTED: OS=windows-msvc // CHECK: swift-frontend diff --git a/test/Driver/fuzzer.swift b/test/Driver/fuzzer.swift index 308ba01f4374a..92536e81e58f9 100644 --- a/test/Driver/fuzzer.swift +++ b/test/Driver/fuzzer.swift @@ -1,4 +1,4 @@ -// UNSUPPORTED: windows +// UNSUPPORTED: OS=windows-msvc // UNSUPPORTED: CPU=powerpc64le // RUN: %swiftc_driver -driver-print-jobs -sanitize=fuzzer,address -target x86_64-apple-macosx10.9 -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ %s | %FileCheck -check-prefix=LIBFUZZER_OSX %s // RUN: %swiftc_driver -driver-print-jobs -sanitize=fuzzer,address -target x86_64-unknown-linux-gnu -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ %s | %FileCheck -check-prefix=LIBFUZZER_LINUX %s diff --git a/test/Driver/loaded_module_trace_nocrash.swift b/test/Driver/loaded_module_trace_nocrash.swift index 70960b5bbcdcb..b3b995071573e 100644 --- a/test/Driver/loaded_module_trace_nocrash.swift +++ b/test/Driver/loaded_module_trace_nocrash.swift @@ -1,4 +1,4 @@ -// UNSUPPORTED: -windows-msvc +// UNSUPPORTED: OS=windows-msvc // RUN: %empty-directory(%t) // RUN: mkdir -p %t/Mods/Foo.swiftmodule diff --git a/test/Driver/loaded_module_trace_swiftinterface.swift b/test/Driver/loaded_module_trace_swiftinterface.swift index 140215561e1b7..6289a02a0d120 100644 --- a/test/Driver/loaded_module_trace_swiftinterface.swift +++ b/test/Driver/loaded_module_trace_swiftinterface.swift @@ -1,4 +1,4 @@ -// UNSUPPORTED: -windows-msvc +// UNSUPPORTED: OS=windows-msvc // REQUIRES: SR13034 // 1) If there is no swiftmodule, use the swiftinterface diff --git a/test/Driver/macabi-environment.swift b/test/Driver/macabi-environment.swift index 928e31456a9d8..a55b43104be88 100644 --- a/test/Driver/macabi-environment.swift +++ b/test/Driver/macabi-environment.swift @@ -1,6 +1,6 @@ // Tests to check that the driver finds standard library in the macabi environment. -// UNSUPPORTED: windows +// UNSUPPORTED: OS=windows-msvc // RUN: %swiftc_driver -sdk "" -sdk "" -driver-print-jobs -target x86_64-apple-ios13.1-macabi -sdk %S/../Inputs/clang-importer-sdk %s | %FileCheck -check-prefix=IOS13-MACABI %s // IOS13-MACABI: bin/swift diff --git a/test/Driver/parseable_output.swift b/test/Driver/parseable_output.swift index 46458c013c404..fda873a44d5ac 100644 --- a/test/Driver/parseable_output.swift +++ b/test/Driver/parseable_output.swift @@ -1,6 +1,6 @@ // RUN: %swiftc_driver_plain -emit-executable %s -o %t.out -emit-module -emit-module-path %t.swiftmodule -emit-objc-header-path %t.h -serialize-diagnostics -emit-dependencies -parseable-output -driver-skip-execution 2>&1 | %FileCheck %s -// XFAIL: freebsd, openbsd, linux +// XFAIL: OS=freebsd, OS=openbsd, OS=linux-gnu // CHECK: {{[1-9][0-9]*}} // CHECK-NEXT: { diff --git a/test/Driver/parseable_output_unicode.swift b/test/Driver/parseable_output_unicode.swift index f8e8925cfe430..462fd6318a210 100644 --- a/test/Driver/parseable_output_unicode.swift +++ b/test/Driver/parseable_output_unicode.swift @@ -2,7 +2,7 @@ // RUN: cat "%S/Inputs/unicode.txt" >> %t.rsp // RUN: %swiftc_driver_plain -emit-executable @%t.rsp -o %t.out -emit-module -emit-module-path %t.swiftmodule -emit-objc-header-path %t.h -serialize-diagnostics -emit-dependencies -parseable-output -driver-skip-execution 2>&1 | %FileCheck %s -// XFAIL: freebsd, openbsd, linux +// XFAIL: OS=freebsd, OS=openbsd, OS=linux-gnu // CHECK: {{[1-9][0-9]*}} // CHECK-NEXT: { diff --git a/test/Driver/pipe_round_robin.swift.gyb b/test/Driver/pipe_round_robin.swift.gyb index fcdc4211a9df5..343a34fd0038f 100644 --- a/test/Driver/pipe_round_robin.swift.gyb +++ b/test/Driver/pipe_round_robin.swift.gyb @@ -1,5 +1,5 @@ // Windows doesn't track/use read() and poll() -// UNSUPPORTED: windows +// UNSUPPORTED: OS=windows-msvc // This test is unreliable on busy machines. // ALLOW_RETRIES: 5 // RUN: %empty-directory(%t/manyfuncs) diff --git a/test/Driver/sdk-apple.swift b/test/Driver/sdk-apple.swift index 228657231d4ea..481ebadcac64b 100644 --- a/test/Driver/sdk-apple.swift +++ b/test/Driver/sdk-apple.swift @@ -1,4 +1,4 @@ -// XFAIL: freebsd, openbsd, linux, windows +// XFAIL: OS=freebsd, OS=openbsd, OS=linux-gnu, OS=windows-msvc // Test SDK detection for immediate mode. // RUN: %empty-directory(%t) diff --git a/test/Generics/conditional_conformances.swift b/test/Generics/conditional_conformances.swift index 196065c308cc4..dc7fe35f96866 100644 --- a/test/Generics/conditional_conformances.swift +++ b/test/Generics/conditional_conformances.swift @@ -49,6 +49,7 @@ struct RedundantSame {} // CHECK-LABEL: ExtensionDecl line={{.*}} base=RedundantSame // CHECK-NEXT: (normal_conformance type=RedundantSame protocol=P2) extension RedundantSame: P2 where T: P1 {} +// expected-warning@-1 {{redundant conformance constraint 'T' : 'P1'}} struct RedundantSuper {} // CHECK-LABEL: ExtensionDecl line={{.*}} base=RedundantSuper @@ -334,6 +335,8 @@ struct RedundancyOrderDependenceGood {} // CHECK-NEXT: (normal_conformance type=RedundancyOrderDependenceGood protocol=P2 // CHECK-NEXT: same_type: T U) extension RedundancyOrderDependenceGood: P2 where U: P1, T == U {} +// expected-warning@-1 {{redundant conformance constraint 'U' : 'P1'}} + struct RedundancyOrderDependenceBad {} // CHECK-LABEL: ExtensionDecl line={{.*}} base=RedundancyOrderDependenceBad // CHECK-LABEL: ExtensionDecl line={{.*}} base=RedundancyOrderDependenceBad diff --git a/test/IDE/print_clang_header_i386.swift b/test/IDE/print_clang_header_i386.swift index d78436f712305..4a5e6d78ea37a 100644 --- a/test/IDE/print_clang_header_i386.swift +++ b/test/IDE/print_clang_header_i386.swift @@ -1,7 +1,7 @@ // REQUIRES: OS=macosx // REQUIRES: CPU=x86_64 // FIXME: rdar://problem/19648117 Needs splitting objc parts out -// XFAIL: linux, freebsd +// XFAIL: OS=linux-gnu, OS=freebsd // RUN: echo '#include "header-to-print.h"' > %t.i386.m // RUN: %empty-directory(%t) diff --git a/test/IRGen/abitypes.swift b/test/IRGen/abitypes.swift index 1b6e28275fdaa..4be683f963b8f 100644 --- a/test/IRGen/abitypes.swift +++ b/test/IRGen/abitypes.swift @@ -1,7 +1,7 @@ // RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -I %S/Inputs/abi %s -emit-ir -enable-objc-interop | %FileCheck -check-prefix=%target-cpu-%target-os-abi %s // FIXME: rdar://problem/19648117 Needs splitting objc parts out -// XFAIL: linux, windows, openbsd +// XFAIL: OS=linux-gnu, OS=windows-msvc, OS=openbsd import gadget import Foundation diff --git a/test/IRGen/existential_shape_metadata.swift b/test/IRGen/existential_shape_metadata.swift index cbf602e661e54..694bc8d679761 100644 --- a/test/IRGen/existential_shape_metadata.swift +++ b/test/IRGen/existential_shape_metadata.swift @@ -1,4 +1,4 @@ -// RUN: %target-swift-frontend -emit-ir %s -swift-version 5 -disable-availability-checking -enable-parameterized-existential-types | %IRGenFileCheck %s +// RUN: %target-swift-frontend -emit-ir %s -swift-version 5 -disable-availability-checking | %IRGenFileCheck %s // CHECK-LABEL: @"$sl26existential_shape_metadata2Q0_pyxXPXGMq" = linkonce_odr hidden constant // CHECK-SAME: { i32 {{.*}}sub ([[INT]] ptrtoint (i8** @{{[0-9]+}} to [[INT]]) diff --git a/test/IRGen/marker_protocol.swift b/test/IRGen/marker_protocol.swift index ce2cecae693d3..4e1fda242a66e 100644 --- a/test/IRGen/marker_protocol.swift +++ b/test/IRGen/marker_protocol.swift @@ -57,9 +57,14 @@ public func markerInDictionary() -> Any { // CHECK: swiftcc void @"$s15marker_protocol7genericyyxAA1PRzlF"(%swift.opaque* noalias nocapture %0, %swift.type* %T) public func generic(_: T) { } +public struct GenericType { } + +// CHECK-LABEL: @"$s15marker_protocol11testGeneric1i5arrayySi_SaySiGtF"( public func testGeneric(i: Int, array: [Int]) { generic(i) generic(array) + // CHECK: __swift_instantiateConcreteTypeFromMangledName{{.*}}$s15marker_protocol11GenericTypeVySaySiGGmMD + print(GenericType<[Int]>.self) } // Forming an existential involving a marker protocol would crash the compiler diff --git a/test/Index/skip-loaded-internal.swift b/test/Index/skip-loaded-internal.swift index 2e9211f968e96..4538def8360a9 100644 --- a/test/Index/skip-loaded-internal.swift +++ b/test/Index/skip-loaded-internal.swift @@ -3,10 +3,10 @@ // RUN: mkdir -p %t/Frameworks/lib2.framework/Modules/lib2.swiftmodule // RUN: split-file %s %t -// RUN: %target-swift-frontend -emit-module -emit-module-source-info -module-name lib2 -o %t/Frameworks/lib2.framework/Modules/lib2.swiftmodule/%module-target-triple.swiftmodule %t/lib2.swift -// RUN: %target-swift-frontend -emit-module -emit-module-source-info -module-name lib -o %t/Frameworks/lib.framework/Modules/lib.swiftmodule/%module-target-triple.swiftmodule %t/lib.swift -Fsystem %t/Frameworks +// RUN: %target-swift-frontend -emit-module -emit-module-source-info -module-name lib2 -o %t/Frameworks/lib2.framework/Modules/lib2.swiftmodule/%module-target-triple.swiftmodule %t/lib2.swift -disable-experimental-string-processing +// RUN: %target-swift-frontend -emit-module -emit-module-source-info -module-name lib -o %t/Frameworks/lib.framework/Modules/lib.swiftmodule/%module-target-triple.swiftmodule %t/lib.swift -Fsystem %t/Frameworks -disable-experimental-string-processing -// RUN: %target-swift-frontend -typecheck -index-system-modules -index-ignore-stdlib -index-store-path %t/idx -Fsystem %t/Frameworks %t/main.swift -disable-deserialization-recovery +// RUN: %target-swift-frontend -typecheck -index-system-modules -index-ignore-stdlib -index-store-path %t/idx -Fsystem %t/Frameworks %t/main.swift -disable-deserialization-recovery -disable-experimental-string-processing //--- main.swift import lib diff --git a/test/Interop/Cxx/enum/Inputs/c-enums-NS_OPTIONS.h b/test/Interop/Cxx/enum/Inputs/c-enums-NS_OPTIONS.h new file mode 100644 index 0000000000000..252bc96627b16 --- /dev/null +++ b/test/Interop/Cxx/enum/Inputs/c-enums-NS_OPTIONS.h @@ -0,0 +1,29 @@ +// Enum usage that is bitwise-able and assignable in C++, aka how CF_OPTIONS +// does things. + +#if __has_attribute(enum_extensibility) +#define __CF_ENUM_ATTRIBUTES __attribute__((enum_extensibility(open))) +#define __CF_CLOSED_ENUM_ATTRIBUTES __attribute__((enum_extensibility(closed))) +#define __CF_OPTIONS_ATTRIBUTES __attribute__((flag_enum,enum_extensibility(open))) +#else +#define __CF_ENUM_ATTRIBUTES +#define __CF_CLOSED_ENUM_ATTRIBUTES +#define __CF_OPTIONS_ATTRIBUTES +#endif + +// explicitly use extern "C" rather than setting it in the modulemap file as +// would be the case with Foundation's modulemap. +extern "C" { + +#define CF_OPTIONS(_type, _name) _type __attribute__((availability(swift, unavailable))) _name; enum __CF_OPTIONS_ATTRIBUTES : _name +#define NS_OPTIONS(_type, _name) CF_OPTIONS(_type, _name) + +typedef unsigned long NSUInteger; + +typedef NS_OPTIONS(NSUInteger, NSBinarySearchingOptions) { + NSBinarySearchingFirstEqual = (1UL << 8), + NSBinarySearchingLastEqual = (1UL << 9), + NSBinarySearchingInsertionIndex = (1UL << 10), +}; + +} \ No newline at end of file diff --git a/test/Interop/Cxx/enum/Inputs/module.modulemap b/test/Interop/Cxx/enum/Inputs/module.modulemap index 5bbdebe622303..ef4d86f2bfef8 100644 --- a/test/Interop/Cxx/enum/Inputs/module.modulemap +++ b/test/Interop/Cxx/enum/Inputs/module.modulemap @@ -17,3 +17,8 @@ module CenumsWithOptionsOmit { header "c-enums-withOptions-omit.h" requires cplusplus } + +module CenumsNSOptions { + header "c-enums-NS_OPTIONS.h" + requires cplusplus +} \ No newline at end of file diff --git a/test/Interop/Cxx/enum/c-enums-NS_OPTIONS.swift b/test/Interop/Cxx/enum/c-enums-NS_OPTIONS.swift new file mode 100644 index 0000000000000..6b7efc355ceef --- /dev/null +++ b/test/Interop/Cxx/enum/c-enums-NS_OPTIONS.swift @@ -0,0 +1,22 @@ +// RUN: %target-swift-ide-test -print-module -module-to-print=CenumsNSOptions -I %S/Inputs -source-filename=x -enable-experimental-cxx-interop | %FileCheck %s +// REQUIRES: objc_interop + +import CenumsNSOptions + +// CHECK: typealias NSBinarySearchingOptions = UInt +// CHECK-NEXT: struct NSBinarySearchingOptions : OptionSet, @unchecked Sendable { +// CHECK-NEXT: init(rawValue: UInt) +// CHECK-NEXT: let rawValue: UInt +// CHECK-NEXT: typealias RawValue = UInt +// CHECK-NEXT: typealias Element = NSBinarySearchingOptions +// CHECK-NEXT: typealias ArrayLiteralElement = NSBinarySearchingOptions +// CHECK-NEXT: static var firstEqual: NSBinarySearchingOptions { get } +// CHECK-NEXT: @available(swift, obsoleted: 3, renamed: "firstEqual") +// CHECK-NEXT: static var FirstEqual: NSBinarySearchingOptions { get } +// CHECK-NEXT: static var lastEqual: NSBinarySearchingOptions { get } +// CHECK-NEXT: @available(swift, obsoleted: 3, renamed: "lastEqual") +// CHECK-NEXT: static var LastEqual: NSBinarySearchingOptions { get } +// CHECK-NEXT: static var insertionIndex: NSBinarySearchingOptions { get } +// CHECK-NEXT: @available(swift, obsoleted: 3, renamed: "insertionIndex") +// CHECK-NEXT: static var InsertionIndex: NSBinarySearchingOptions { get } +// CHECK-NEXT: } diff --git a/test/Interop/SwiftToCxx/structs/swift-struct-in-cxx.swift b/test/Interop/SwiftToCxx/structs/swift-struct-in-cxx.swift new file mode 100644 index 0000000000000..78f279e6d9669 --- /dev/null +++ b/test/Interop/SwiftToCxx/structs/swift-struct-in-cxx.swift @@ -0,0 +1,20 @@ +// RUN: %empty-directory(%t) +// RUN: %target-swift-frontend %s -typecheck -module-name Structs -clang-header-expose-public-decls -emit-clang-header-path %t/structs.h +// RUN: %FileCheck %s < %t/structs.h + +// RUN: %check-interop-cxx-header-in-clang(%t/structs.h) + +// CHECK: namespace Structs { + +// CHECK: class StructWithIntField final { +// CHECK-NEXT: }; +struct StructWithIntField { + let field: Int +} + +// Special name gets renamed in C++. +// CHECK: class register_ final { +struct register { +} + +// CHECK: } // namespace Structs diff --git a/test/Interpreter/parameterized_existentials.swift b/test/Interpreter/parameterized_existentials.swift index 01fd712328cd2..d8039fc2d9462 100644 --- a/test/Interpreter/parameterized_existentials.swift +++ b/test/Interpreter/parameterized_existentials.swift @@ -1,4 +1,4 @@ -// RUN: %target-run-simple-swift(-Xfrontend -enable-parameterized-existential-types -Xfrontend -disable-availability-checking) +// RUN: %target-run-simple-swift(-Xfrontend -disable-availability-checking) // REQUIRES: executable_test // This test requires the new existential shape metadata accessors which are diff --git a/test/Interpreter/shebang-direct.swift b/test/Interpreter/shebang-direct.swift index cec0bb21344eb..ca6d376ad55e9 100644 --- a/test/Interpreter/shebang-direct.swift +++ b/test/Interpreter/shebang-direct.swift @@ -6,4 +6,4 @@ // RUN: %t.shebang.swift a b c | %FileCheck -check-prefix=THREE-ARGS %S/shebang-env.swift // REQUIRES: swift_interpreter -// UNSUPPORTED: linux +// UNSUPPORTED: OS=linux-gnu diff --git a/test/ModuleInterface/BadStdlib.swiftinterface b/test/ModuleInterface/BadStdlib.swiftinterface index f5375dabdfccb..54edbeda2e31d 100644 --- a/test/ModuleInterface/BadStdlib.swiftinterface +++ b/test/ModuleInterface/BadStdlib.swiftinterface @@ -16,4 +16,4 @@ import ClangMod public func useHasPointer(_: HasPointer) // FIXME: SR-14489 -// UNSUPPORTED: windows +// UNSUPPORTED: OS=windows-msvc diff --git a/test/ModuleInterface/existential-any.swift b/test/ModuleInterface/existential-any.swift index 69c49a3cd7e6a..8b475e58f570b 100644 --- a/test/ModuleInterface/existential-any.swift +++ b/test/ModuleInterface/existential-any.swift @@ -38,3 +38,11 @@ public struct S { // CHECK: public var q: any main.Q public var q: any Q } + + +public protocol ProtocolTypealias { + typealias A = P +} + +// CHECK: public func dependentExistential(value: (T) -> any main.P) where T : main.ProtocolTypealias +public func dependentExistential(value: (T) -> T.A) {} diff --git a/test/ModuleInterface/swift_build_sdk_interfaces/compiler-crash.test-sh b/test/ModuleInterface/swift_build_sdk_interfaces/compiler-crash.test-sh index 73b53dcc6ab27..e17a48e34f491 100644 --- a/test/ModuleInterface/swift_build_sdk_interfaces/compiler-crash.test-sh +++ b/test/ModuleInterface/swift_build_sdk_interfaces/compiler-crash.test-sh @@ -1,5 +1,5 @@ # For its Windows counterpart, see compiler-crash-windows.test-sh -UNSUPPORTED: windows +UNSUPPORTED: OS=windows-msvc RUN: not %swift_build_sdk_interfaces -sdk %S/Inputs/mock-sdk/ -o %t/output -debug-crash-compiler 2>&1 | %FileCheck %s diff --git a/test/Parse/ConditionalCompilation/compiler_version.swift b/test/Parse/ConditionalCompilation/compiler_version.swift index 690364c1df764..0dad441005ed3 100644 --- a/test/Parse/ConditionalCompilation/compiler_version.swift +++ b/test/Parse/ConditionalCompilation/compiler_version.swift @@ -7,7 +7,7 @@ asdf asdf asdf asdf #endif -#if _compiler_version("10.*.10.10") +#if _compiler_version("600.*.10.10") #if os(iOS) let z = 1 @@ -48,7 +48,10 @@ let thisWillStillParseBecauseConfigIsError = 1 #endif -#if _compiler_version("700.0.100") // expected-warning {{the second version component is not used for comparison}} +#if _compiler_version("700.0.100") // expected-warning {{the second version component is not used for comparison in legacy compiler versions}} {{28-29=*}} +#endif + +#if _compiler_version("5.7.100") // expected-warning {{the second version component is not used for comparison in legacy compiler versions; are you trying to encode a new Swift compiler version for compatibility with legacy compilers?}} {{24-27=5007.*}} #endif #if _compiler_version("700.*.1.1.1.1") // expected-error {{version must not have more than five components}} @@ -65,3 +68,14 @@ #if _compiler_version("700.*.1.1.1000") // expected-error {{version component out of range: must be in [0, 999]}} #endif + +// New style _compiler_version() +#if _compiler_version(<4.0) + // This shouldn't emit any diagnostics. + asdf asdf asdf asdf +#endif + +#if !_compiler_version(>=4.3.2.1.0) + // This shouldn't emit any diagnostics. + asdf asdf asdf asdf +#endif diff --git a/test/Prototypes/CollectionTransformers.swift b/test/Prototypes/CollectionTransformers.swift index 84dcafe4c04c6..e3a405c78486b 100644 --- a/test/Prototypes/CollectionTransformers.swift +++ b/test/Prototypes/CollectionTransformers.swift @@ -200,7 +200,7 @@ import Darwin import Dispatch // FIXME: port to Linux. -// XFAIL: linux, windows, openbsd +// XFAIL: OS=linux-gnu, OS=windows-msvc, OS=openbsd // A wrapper for pthread_t with platform-independent interface. public struct _stdlib_pthread_t : Equatable, Hashable { diff --git a/test/Reflection/box_descriptors.sil b/test/Reflection/box_descriptors.sil index 1c0392b6972dc..641eab38e4178 100644 --- a/test/Reflection/box_descriptors.sil +++ b/test/Reflection/box_descriptors.sil @@ -3,10 +3,10 @@ // RUN: %target-swift-reflection-dump -binary-filename %t/capture_descriptors%{target-shared-library-suffix} | %FileCheck %s // SR-10758 -// UNSUPPORTED: linux +// UNSUPPORTED: OS=linux-gnu // SR-12893 -// XFAIL: openbsd +// XFAIL: OS=openbsd sil_stage canonical diff --git a/test/Reflection/capture_descriptors.sil b/test/Reflection/capture_descriptors.sil index ef71fc31dc682..75d99f22138ea 100644 --- a/test/Reflection/capture_descriptors.sil +++ b/test/Reflection/capture_descriptors.sil @@ -2,7 +2,7 @@ // REQUIRES: no_asan // SR-12893 -// XFAIL: openbsd +// XFAIL: OS=openbsd // UNSUPPORTED: OS=linux-android, OS=linux-androideabi // RUN: %empty-directory(%t) diff --git a/test/Reflection/conformance_descriptors.swift b/test/Reflection/conformance_descriptors.swift index 91caa8cc2351a..f6d6fc65aad34 100644 --- a/test/Reflection/conformance_descriptors.swift +++ b/test/Reflection/conformance_descriptors.swift @@ -1,4 +1,4 @@ -// UNSUPPORTED: windows +// UNSUPPORTED: OS=windows-msvc // Temporarily disable on AArch64 Linux (rdar://88451721) // UNSUPPORTED: OS=linux-gnu && CPU=aarch64 diff --git a/test/Reflection/typeref_decoding_imported.swift b/test/Reflection/typeref_decoding_imported.swift index 4d2c7bcc8a75b..de550812f7ba3 100644 --- a/test/Reflection/typeref_decoding_imported.swift +++ b/test/Reflection/typeref_decoding_imported.swift @@ -1,7 +1,7 @@ // XFAIL: OS=windows-msvc // SR-12893 -// XFAIL: openbsd +// XFAIL: OS=openbsd // RUN: %empty-directory(%t) diff --git a/test/RemoteAST/parameterized_existentials.swift b/test/RemoteAST/parameterized_existentials.swift index 89973c9146ff9..ef1b558c66b28 100644 --- a/test/RemoteAST/parameterized_existentials.swift +++ b/test/RemoteAST/parameterized_existentials.swift @@ -1,4 +1,4 @@ -// RUN: %target-swift-remoteast-test -enable-parameterized-existential-types -disable-availability-checking %s | %FileCheck %s +// RUN: %target-swift-remoteast-test -disable-availability-checking %s | %FileCheck %s // REQUIRES: swift-remoteast-test diff --git a/test/SILGen/parameterized_existentials.swift b/test/SILGen/parameterized_existentials.swift index b6b3db9a02292..c36dc22695537 100644 --- a/test/SILGen/parameterized_existentials.swift +++ b/test/SILGen/parameterized_existentials.swift @@ -1,4 +1,4 @@ -// RUN: %target-swift-emit-silgen -module-name parameterized -enable-parameterized-existential-types -disable-availability-checking %s | %FileCheck %s +// RUN: %target-swift-emit-silgen -module-name parameterized -disable-availability-checking %s | %FileCheck %s protocol P { associatedtype T diff --git a/test/SILOptimizer/addr_escape_info.sil b/test/SILOptimizer/addr_escape_info.sil index 2bc43557ec89e..0f6c069cec95a 100644 --- a/test/SILOptimizer/addr_escape_info.sil +++ b/test/SILOptimizer/addr_escape_info.sil @@ -3,7 +3,7 @@ // REQUIRES: swift_in_compiler // rdar92963081 -// UNSUPPORTED: linux +// UNSUPPORTED: OS=linux-gnu sil_stage canonical diff --git a/test/SILOptimizer/cast_folding_parameterized_protocol.swift b/test/SILOptimizer/cast_folding_parameterized_protocol.swift index 1d8cfe92d141a..aab2fa9b18497 100644 --- a/test/SILOptimizer/cast_folding_parameterized_protocol.swift +++ b/test/SILOptimizer/cast_folding_parameterized_protocol.swift @@ -1,4 +1,4 @@ -// RUN: %target-swift-frontend %s -emit-sil -enable-parameterized-existential-types -disable-availability-checking -O -o - | %FileCheck %s +// RUN: %target-swift-frontend %s -emit-sil -disable-availability-checking -O -o - | %FileCheck %s public protocol P { associatedtype T diff --git a/test/SILOptimizer/escape_info.sil b/test/SILOptimizer/escape_info.sil index f51e6022f0d46..8503be891ce3f 100644 --- a/test/SILOptimizer/escape_info.sil +++ b/test/SILOptimizer/escape_info.sil @@ -3,7 +3,7 @@ // REQUIRES: swift_in_compiler // rdar92963081 -// UNSUPPORTED: linux +// UNSUPPORTED: OS=linux-gnu sil_stage canonical diff --git a/test/SILOptimizer/lexical_destroy_hoisting.sil b/test/SILOptimizer/lexical_destroy_hoisting.sil index 16e29693cc602..8cff942dcdc00 100644 --- a/test/SILOptimizer/lexical_destroy_hoisting.sil +++ b/test/SILOptimizer/lexical_destroy_hoisting.sil @@ -237,11 +237,11 @@ exit(%thing : @owned $C): // Don't hoist over loop without uses. // -// TODO: Eventually, we should hoist over such loops. // CHECK-LABEL: sil [ossa] @hoist_over_loop_1 : {{.*}} { // CHECK: {{bb[0-9]+}}([[INSTANCE:%[^,]+]] : @owned $C): // CHECK: [[CALLEE_GUARANTEED:%[^,]+]] = function_ref @callee_guaranteed // CHECK: apply [[CALLEE_GUARANTEED]]([[INSTANCE]]) +// CHECK: destroy_value [[INSTANCE]] // CHECK: br [[LOOP_HEADER:bb[0-9]+]] // CHECK: [[LOOP_HEADER]]: // CHECK: br [[LOOP_BODY:bb[0-9]+]] @@ -252,7 +252,6 @@ exit(%thing : @owned $C): // CHECK: [[LOOP_BACKEDGE]]: // CHECK: br [[LOOP_HEADER]] // CHECK: [[EXIT]]: -// CHECK: destroy_value [[INSTANCE]] // CHECK-LABEL: } // end sil function 'hoist_over_loop_1' sil [ossa] @hoist_over_loop_1 : $@convention(thin) (@owned C) -> () { entry(%instance: @owned $C): @@ -461,3 +460,67 @@ entry(%instance : @owned $C, %input : $S): // instruction tests }} // ============================================================================= +// ============================================================================= +// access scope tests {{ +// ============================================================================= + +// Don't hoist into an access scope that contains a barrier. +// +// CHECK-LABEL: sil [ossa] @nofold_scoped_load_barrier : {{.*}} { +// CHECK: end_access +// CHECK: end_access +// CHECK: destroy_value +// CHECK-LABEL: // end sil function 'nofold_scoped_load_barrier' +sil [ossa] @nofold_scoped_load_barrier : $@convention(thin) (@owned C, @owned C) -> (@owned C) { +entry(%instance : @owned $C, %other : @owned $C): + %addr = alloc_stack $C + %store_scope = begin_access [modify] [static] %addr : $*C + store %other to [init] %store_scope : $*C + end_access %store_scope : $*C + %load_scope = begin_access [read] [static] %addr : $*C + %value = load [copy] %load_scope : $*C + %barrier = function_ref @barrier : $@convention(thin) () -> () + apply %barrier() : $@convention(thin) () -> () + end_access %load_scope : $*C + destroy_addr %addr : $*C + dealloc_stack %addr : $*C + destroy_value %instance : $C + return %value : $C +} + +// Access scopes that are open at barrier blocks are barriers. Otherwise, we +// would hoist destroy_values into the scopes when the destroy_values are +// hoisted up to the begin of blocks whose predecessor is the barrier block. +// +// CHECK-LABEL: sil [ossa] @nohoist_into_access_scope_barred_by_barrier_block : {{.*}} { +// CHECK: {{bb[0-9]+}}([[INSTANCE:%[^,]+]] : @owned $C, [[INOUT:%[^,]+]] : $*C): +// CHECK: [[SCOPE:%[^,]+]] = begin_access [modify] [static] [[INOUT]] : $*C +// CHECK: cond_br undef, [[LEFT:bb[0-9]+]], +// CHECK: [[LEFT]]: +// CHECK: end_access [[SCOPE]] : $*C +// CHECK-NEXT: destroy_value [[INSTANCE]] : $C +// CHECK-LABEL: } // end sil function 'nohoist_into_access_scope_barred_by_barrier_block' +sil [ossa] @nohoist_into_access_scope_barred_by_barrier_block : $@convention(thin) (@owned C, @inout C) -> () { +entry(%instance : @owned $C, %second : $*C): + %scope = begin_access [modify] [static] %second : $*C + cond_br undef, left, right + +left: + end_access %scope : $*C + %ignore = tuple () + destroy_value %instance : $C + br exit + +right: + end_access %scope : $*C + apply undef(%instance) : $@convention(thin) (@owned C) -> () + br exit + +exit: + %retval = tuple () + return %retval : $() +} + +// ============================================================================= +// access scope tests }} +// ============================================================================= diff --git a/test/SILOptimizer/no-external-defs-onone.sil b/test/SILOptimizer/no-external-defs-onone.sil index 046df6f55074f..a7230a8105811 100644 --- a/test/SILOptimizer/no-external-defs-onone.sil +++ b/test/SILOptimizer/no-external-defs-onone.sil @@ -7,7 +7,7 @@ // CHECK-NOT: public_external_unused_test // TODO: update check line for the hidden_external_test for Windows. -// UNSUPPORTED: windows +// UNSUPPORTED: OS=windows-msvc sil public_external [serialized] @public_external_test : $@convention(thin) () -> () { %0 = tuple() diff --git a/test/SILOptimizer/ranges.sil b/test/SILOptimizer/ranges.sil index f28e4a5d2c896..ee34a648f64e3 100644 --- a/test/SILOptimizer/ranges.sil +++ b/test/SILOptimizer/ranges.sil @@ -3,7 +3,7 @@ // REQUIRES: swift_in_compiler // rdar92963081 -// UNSUPPORTED: linux +// UNSUPPORTED: OS=linux-gnu sil_stage canonical diff --git a/test/SILOptimizer/shrink_borrow_scope.sil b/test/SILOptimizer/shrink_borrow_scope.sil index 42821d9535e60..59e0f28b9986d 100644 --- a/test/SILOptimizer/shrink_borrow_scope.sil +++ b/test/SILOptimizer/shrink_borrow_scope.sil @@ -457,13 +457,14 @@ exit: // loop tests {{ // ============================================================================= -// Don't hoist over loop without uses. -// TODO: Eventually, we should hoist over such loops. +// Hoist over loop without uses. +// // CHECK-LABEL: sil [ossa] @hoist_over_loop_1 : {{.*}} { // CHECK: {{bb[0-9]+}}([[INSTANCE:%[^,]+]] : @owned $C): // CHECK: [[LIFETIME:%[^,]+]] = begin_borrow [[INSTANCE]] // CHECK: [[CALLEE_GUARANTEED:%[^,]+]] = function_ref @callee_guaranteed // CHECK: {{%[^,]+}} = apply [[CALLEE_GUARANTEED]]([[LIFETIME]]) +// CHECK: end_borrow [[LIFETIME]] // CHECK: br [[LOOP_HEADER:bb[0-9]+]] // CHECK: [[LOOP_HEADER]]: // CHECK: br [[LOOP_BODY:bb[0-9]+]] @@ -474,7 +475,6 @@ exit: // CHECK: [[LOOP_BACKEDGE]]: // CHECK: br [[LOOP_HEADER]] // CHECK: [[EXIT]]: -// CHECK: end_borrow [[LIFETIME]] // CHECK: return [[INSTANCE]] // CHECK-LABEL: } // end sil function 'hoist_over_loop_1' sil [ossa] @hoist_over_loop_1 : $@convention(thin) (@owned C) -> @owned C { @@ -1097,3 +1097,76 @@ bb0(%0 : $*ClassWrapper): // ============================================================================= // instruction tests }} // ============================================================================= + +// ============================================================================= +// access scope tests {{ +// ============================================================================= + +// Don't hoist into an access scope that contains a barrier. +// +// CHECK-LABEL: sil [ossa] @nofold_scoped_load_barrier : {{.*}} { +// CHECK: end_access +// CHECK: end_access +// CHECK: end_borrow +// CHECK-LABEL: // end sil function 'nofold_scoped_load_barrier' +sil [ossa] @nofold_scoped_load_barrier : $@convention(thin) (@owned C, @owned C) -> (@owned C) { +entry(%instance : @owned $C, %other : @owned $C): + %lifetime = begin_borrow [lexical] %instance : $C + apply undef(%lifetime) : $@convention(thin) (@guaranteed C) -> () + %addr = alloc_stack $C + %store_scope = begin_access [modify] [static] %addr : $*C + store %other to [init] %store_scope : $*C + end_access %store_scope : $*C + %load_scope = begin_access [read] [static] %addr : $*C + %value = load [copy] %load_scope : $*C + %barrier = function_ref @barrier : $@convention(thin) () -> () + apply %barrier() : $@convention(thin) () -> () + end_access %load_scope : $*C + destroy_addr %addr : $*C + dealloc_stack %addr : $*C + end_borrow %lifetime : $C + destroy_value %instance : $C + return %value : $C +} + +// Access scopes that are open at barrier blocks are barriers. Otherwise, we +// would hoist end_borrows into the scopes when the end_borrows are hoisted up +// to the begin of blocks whose predecessor is the barrier block. +// +// CHECK-LABEL: sil [ossa] @nohoist_into_access_scope_barred_by_barrier_block : {{.*}} { +// CHECK: {{bb[0-9]+}}([[INSTANCE:%[^,]+]] : @owned $C, [[INOUT:%[^,]+]] : $*C): +// CHECK: [[LIFETIME:%[^,]+]] = begin_borrow [lexical] [[INSTANCE]] +// CHECK: [[SCOPE:%[^,]+]] = begin_access [modify] [static] [[INOUT]] : $*C +// CHECK: cond_br undef, [[LEFT:bb[0-9]+]], +// CHECK: [[LEFT]]: +// CHECK: end_access [[SCOPE]] : $*C +// CHECK-NEXT: end_borrow [[LIFETIME]] : $C +// CHECK-LABEL: } // end sil function 'nohoist_into_access_scope_barred_by_barrier_block' +sil [ossa] @nohoist_into_access_scope_barred_by_barrier_block : $@convention(thin) (@owned C, @inout C) -> () { +entry(%instance : @owned $C, %second : $*C): + %lifetime = begin_borrow [lexical] %instance : $C + %scope = begin_access [modify] [static] %second : $*C + cond_br undef, left, right + +left: + end_access %scope : $*C + %ignore = tuple () + end_borrow %lifetime : $C + destroy_value %instance : $C + br exit + +right: + end_access %scope : $*C + apply undef(%lifetime) : $@convention(thin) (@guaranteed C) -> () + end_borrow %lifetime : $C + destroy_value %instance : $C + br exit + +exit: + %retval = tuple () + return %retval : $() +} + +// ============================================================================= +// access scope tests }} +// ============================================================================= diff --git a/test/Sanitizers/asan/recover.swift b/test/Sanitizers/asan/recover.swift index ee879e0f7dee5..d858c333f4298 100644 --- a/test/Sanitizers/asan/recover.swift +++ b/test/Sanitizers/asan/recover.swift @@ -1,6 +1,6 @@ // REQUIRES: executable_test // REQUIRES: asan_runtime -// UNSUPPORTED: windows +// UNSUPPORTED: OS=windows-msvc // Check with recovery instrumentation and the runtime option to continue execution. // RUN: %target-swiftc_driver %s -target %sanitizers-target-triple -g -sanitize=address -sanitize-recover=address -import-objc-header %S/asan_interface.h -emit-ir -o %t.asan_recover.ll diff --git a/test/Sanitizers/tsan/actor_counters.swift b/test/Sanitizers/tsan/actor_counters.swift index 9cf11f4a98964..4fd7d86140daa 100644 --- a/test/Sanitizers/tsan/actor_counters.swift +++ b/test/Sanitizers/tsan/actor_counters.swift @@ -5,8 +5,8 @@ // REQUIRES: libdispatch // REQUIRES: tsan_runtime // UNSUPPORTED: use_os_stdlib -// UNSUPPORTED: linux -// UNSUPPORTED: windows +// UNSUPPORTED: OS=linux-gnu +// UNSUPPORTED: OS=windows-msvc // REQUIRES: rdar83246843 diff --git a/test/Sanitizers/tsan/objc_async.swift b/test/Sanitizers/tsan/objc_async.swift index 50ee8ce60b5b4..1e5e58696c3ec 100644 --- a/test/Sanitizers/tsan/objc_async.swift +++ b/test/Sanitizers/tsan/objc_async.swift @@ -7,8 +7,8 @@ // REQUIRES: concurrency // REQUIRES: objc_interop // REQUIRES: tsan_runtime -// UNSUPPORTED: linux -// UNSUPPORTED: windows +// UNSUPPORTED: OS=linux-gnu +// UNSUPPORTED: OS=windows-msvc // rdar://76038845 // UNSUPPORTED: use_os_stdlib diff --git a/test/Sema/availability_parameterized_existential.swift b/test/Sema/availability_parameterized_existential.swift index 23b63c65f6fcb..ab5318522140b 100644 --- a/test/Sema/availability_parameterized_existential.swift +++ b/test/Sema/availability_parameterized_existential.swift @@ -1,8 +1,8 @@ -// RUN: %target-typecheck-verify-swift -target %target-cpu-apple-macosx10.50 -disable-objc-attr-requires-foundation-module -enable-parameterized-existential-types -// RUN: not %target-swift-frontend -target %target-cpu-apple-macosx10.50 -disable-objc-attr-requires-foundation-module -enable-parameterized-existential-types -typecheck %s 2>&1 | %FileCheck %s '--implicit-check-not=:0' +// RUN: %target-typecheck-verify-swift -target %target-cpu-apple-macosx10.50 -disable-objc-attr-requires-foundation-module +// RUN: not %target-swift-frontend -target %target-cpu-apple-macosx10.50 -disable-objc-attr-requires-foundation-module -typecheck %s 2>&1 | %FileCheck %s '--implicit-check-not=:0' // Make sure we do not emit availability errors or warnings when -disable-availability-checking is passed -// RUN: not %target-swift-frontend -target %target-cpu-apple-macosx10.50 -typecheck -disable-objc-attr-requires-foundation-module -enable-parameterized-existential-types -disable-availability-checking %s 2>&1 | %FileCheck %s '--implicit-check-not=error:' +// RUN: not %target-swift-frontend -target %target-cpu-apple-macosx10.50 -typecheck -disable-objc-attr-requires-foundation-module -disable-availability-checking %s 2>&1 | %FileCheck %s '--implicit-check-not=error:' // REQUIRES: OS=macosx diff --git a/test/Sema/availability_refinement_contexts_target_min_inlining.swift b/test/Sema/availability_refinement_contexts_target_min_inlining.swift index 321386501ed1b..e07c00057f5d7 100644 --- a/test/Sema/availability_refinement_contexts_target_min_inlining.swift +++ b/test/Sema/availability_refinement_contexts_target_min_inlining.swift @@ -11,8 +11,8 @@ // CHECK-tvos: {{^}}(root versions=[9.0,+Inf) // CHECK-watchos: {{^}}(root versions=[2.0,+Inf) -// CHECK-macosx-NEXT: {{^}} (api_boundary versions=[10.15.0,+Inf) decl=foo() -// CHECK-ios-NEXT: {{^}} (api_boundary versions=[13.0.0,+Inf) decl=foo() -// CHECK-tvos-NEXT: {{^}} (api_boundary versions=[13.0.0,+Inf) decl=foo() -// CHECK-watchos-NEXT: {{^}} (api_boundary versions=[6.0.0,+Inf) decl=foo() +// CHECK-macosx-NEXT: {{^}} (decl_implicit versions=[10.15.0,+Inf) decl=foo() +// CHECK-ios-NEXT: {{^}} (decl_implicit versions=[13.0.0,+Inf) decl=foo() +// CHECK-tvos-NEXT: {{^}} (decl_implicit versions=[13.0.0,+Inf) decl=foo() +// CHECK-watchos-NEXT: {{^}} (decl_implicit versions=[6.0.0,+Inf) decl=foo() func foo() {} diff --git a/test/Sema/availability_refinement_contexts_target_min_inlining_maccatalyst.swift b/test/Sema/availability_refinement_contexts_target_min_inlining_maccatalyst.swift index 3b11368547d13..a3e41616fe962 100644 --- a/test/Sema/availability_refinement_contexts_target_min_inlining_maccatalyst.swift +++ b/test/Sema/availability_refinement_contexts_target_min_inlining_maccatalyst.swift @@ -11,5 +11,5 @@ // Verify that -target-min-inlining-version min implies 13.1 on macCatalyst. // CHECK: {{^}}(root versions=[13.1,+Inf) -// CHECK-NEXT: {{^}} (api_boundary versions=[14.4.0,+Inf) decl=foo() +// CHECK-NEXT: {{^}} (decl_implicit versions=[14.4.0,+Inf) decl=foo() func foo() {} diff --git a/test/Serialization/parameterized_protocol.swift b/test/Serialization/parameterized_protocol.swift index a7212a272a787..1b352a417641e 100644 --- a/test/Serialization/parameterized_protocol.swift +++ b/test/Serialization/parameterized_protocol.swift @@ -1,6 +1,6 @@ // RUN: %empty-directory(%t) -// RUN: %target-swift-frontend -enable-parameterized-existential-types -emit-module %S/Inputs/parameterized_protocol_other.swift -emit-module-path %t/parameterized_protocol_other.swiftmodule -// RUN: %target-typecheck-verify-swift -enable-parameterized-existential-types -I%t +// RUN: %target-swift-frontend -emit-module %S/Inputs/parameterized_protocol_other.swift -emit-module-path %t/parameterized_protocol_other.swiftmodule +// RUN: %target-typecheck-verify-swift -I%t import parameterized_protocol_other diff --git a/test/SourceKit/CursorInfo/cursor_info_multi_module.swift b/test/SourceKit/CursorInfo/cursor_info_multi_module.swift index 262bf4b24f3f3..9d4014f65eb48 100644 --- a/test/SourceKit/CursorInfo/cursor_info_multi_module.swift +++ b/test/SourceKit/CursorInfo/cursor_info_multi_module.swift @@ -58,7 +58,9 @@ func test() { // CHECK-NORMAL-NEXT: }, // CHECK-NORMAL-NEXT: "text": "Comment from A" // CHECK-NORMAL-NEXT: } -// CHECK-NORMAL-NEXT: ] +// CHECK-NORMAL-NEXT: ], +// CHECK-NORMAL-NEXT: "module": "somemod", +// CHECK-NORMAL-NEXT: "uri": "file://{{.*}}cursor_info_multi_module.swift" // CHECK-NORMAL-NEXT: }, // CHECK-NORMAL: "location": { // CHECK-NORMAL-NEXT: "position": { @@ -87,7 +89,9 @@ func test() { // CHECK-BEFORE-NEXT: }, // CHECK-BEFORE-NEXT: "text": "Comment from B" // CHECK-BEFORE-NEXT: } -// CHECK-BEFORE-NEXT: ] +// CHECK-BEFORE-NEXT: ], +// CHECK-BEFORE-NEXT: "module": "somemod", +// CHECK-BEFORE-NEXT: "uri": "file://{{.*}}cursor_info_multi_module.swift" // CHECK-BEFORE-NEXT: }, // CHECK-BEFORE: "location": { // CHECK-BEFORE-NEXT: "position": { @@ -117,7 +121,9 @@ func test() { // CHECK-IN-NEXT: }, // CHECK-IN-NEXT: "text": "Comment from #sourceLocation" // CHECK-IN-NEXT: } -// CHECK-IN-NEXT: ] +// CHECK-IN-NEXT: ], +// CHECK-IN-NEXT: "module": "somemod", +// CHECK-IN-NEXT: "uri": "file://doesnotexist.swift" // CHECK-IN-NEXT: }, // CHECK-IN: "location": { // CHECK-IN-NEXT: "position": { @@ -146,7 +152,9 @@ func test() { // CHECK-AFTER-NEXT: }, // CHECK-AFTER-NEXT: "text": "Comment from B" // CHECK-AFTER-NEXT: } -// CHECK-AFTER-NEXT: ] +// CHECK-AFTER-NEXT: ], +// CHECK-AFTER-NEXT: "module": "somemod", +// CHECK-AFTER-NEXT: "uri": "file://{{.*}}cursor_info_multi_module.swift" // CHECK-AFTER-NEXT: }, // CHECK-AFTER: "location": { // CHECK-AFTER-NEXT: "position": { diff --git a/test/SourceKit/CursorInfo/cursor_symbol_graph_objc.swift b/test/SourceKit/CursorInfo/cursor_symbol_graph_objc.swift index ca4a974a6d494..4c9055106bb67 100644 --- a/test/SourceKit/CursorInfo/cursor_symbol_graph_objc.swift +++ b/test/SourceKit/CursorInfo/cursor_symbol_graph_objc.swift @@ -89,7 +89,9 @@ func test(s: ObjCStruct) { // CHECK-FUNC: { // CHECK-FUNC: "text": "someFunc doc" // CHECK-FUNC: } -// CHECK-FUNC: ] +// CHECK-FUNC: ], +// CHECK-FUNC: "module": "MyMod", +// CHECK-FUNC: "uri": "file://{{.*}}mod{{\\\\|/}}M.h" // CHECK-FUNC: }, // CHECK-FUNC: "functionSignature": { // CHECK-FUNC: "returns": [ @@ -164,7 +166,9 @@ struct ObjCStruct { // CHECK-SINGLE1-NEXT: { // CHECK-SINGLE1-NEXT: "text": "single line doc" // CHECK-SINGLE1-NEXT: } - // CHECK-SINGLE1-NEXT: ] + // CHECK-SINGLE1-NEXT: ], + // CHECK-SINGLE1-NEXT: "module": "MyMod", + // CHECK-SINGLE1-NEXT: "uri": "file://{{.*}}mod{{\\\\|/}}M.h" // CHECK-SINGLE1-NEXT: } //! single line doc @@ -174,7 +178,9 @@ struct ObjCStruct { // CHECK-SINGLE2-NEXT: { // CHECK-SINGLE2-NEXT: "text": "single line doc" // CHECK-SINGLE2-NEXT: } - // CHECK-SINGLE2-NEXT: ] + // CHECK-SINGLE2-NEXT: ], + // CHECK-SINGLE2-NEXT: "module": "MyMod", + // CHECK-SINGLE2-NEXT: "uri": "file://{{.*}}mod{{\\\\|/}}M.h" // CHECK-SINGLE2-NEXT: } /** single line block doc */ @@ -184,7 +190,9 @@ struct ObjCStruct { // CHECK-BLOCK1-NEXT: { // CHECK-BLOCK1-NEXT: "text": "single line block doc " // CHECK-BLOCK1-NEXT: } - // CHECK-BLOCK1-NEXT: ] + // CHECK-BLOCK1-NEXT: ], + // CHECK-BLOCK1-NEXT: "module": "MyMod", + // CHECK-BLOCK1-NEXT: "uri": "file://{{.*}}mod{{\\\\|/}}M.h" // CHECK-BLOCK1-NEXT: } /*! single line block doc */ @@ -194,7 +202,9 @@ struct ObjCStruct { // CHECK-BLOCK2-NEXT: { // CHECK-BLOCK2-NEXT: "text": "single line block doc " // CHECK-BLOCK2-NEXT: } - // CHECK-BLOCK2-NEXT: ] + // CHECK-BLOCK2-NEXT: ], + // CHECK-BLOCK2-NEXT: "module": "MyMod", + // CHECK-BLOCK2-NEXT: "uri": "file://{{.*}}mod{{\\\\|/}}M.h" // CHECK-BLOCK2-NEXT: } /** @@ -220,7 +230,9 @@ struct ObjCStruct { // DISABLED-CHECK-ART-NEXT: { // DISABLED-CHECK-ART-NEXT: "text": " " // DISABLED-CHECK-ART-NEXT: } - // DISABLED-CHECK-ART-NEXT: ] + // DISABLED-CHECK-ART-NEXT: ], + // DISABLED-CHECK-ART-NEXT: "module": "MyMod", + // DISABLED-CHECK-ART-NEXT: "uri": "file://{{.*}}mod{{\\\\|/}}M.h" // DISABLED-CHECK-ART-NEXT: } /// doc1 @@ -237,7 +249,9 @@ struct ObjCStruct { // CHECK-MIXED-TYPE-NEXT: { // CHECK-MIXED-TYPE-NEXT: "text": "doc2 last" // CHECK-MIXED-TYPE-NEXT: } - // CHECK-MIXED-TYPE-NEXT: ] + // CHECK-MIXED-TYPE-NEXT: ], + // CHECK-MIXED-TYPE-NEXT: "module": "MyMod", + // CHECK-MIXED-TYPE-NEXT: "uri": "file://{{.*}}mod{{\\\\|/}}M.h" // CHECK-MIXED-TYPE-NEXT: } /// doc1 @@ -274,7 +288,9 @@ struct ObjCStruct { // DISABLED-CHECK-MIXED-DOC-NEXT: { // DISABLED-CHECK-MIXED-DOC-NEXT: "text": "doc3" // DISABLED-CHECK-MIXED-DOC-NEXT: } - // DISABLED-CHECK-MIXED-DOC-NEXT: ] + // DISABLED-CHECK-MIXED-DOC-NEXT: ], + // DISABLED-CHECK-MIXED-DOC-NEXT: "module": "MyMod", + // DISABLED-CHECK-MIXED-DOC-NEXT: "uri": "file://{{.*}}mod{{\\\\|/}}M.h" // DISABLED-CHECK-MIXED-DOC-NEXT: } }; diff --git a/test/SourceKit/DocSupport/doc_swift_module.swift.response b/test/SourceKit/DocSupport/doc_swift_module.swift.response index f1fc0a593b5d3..15e86fbbbff16 100644 --- a/test/SourceKit/DocSupport/doc_swift_module.swift.response +++ b/test/SourceKit/DocSupport/doc_swift_module.swift.response @@ -1301,7 +1301,7 @@ func shouldPrintAnyAsKeyword(x x: Any) { key.kind: source.lang.swift.ref.generic_type_param, key.name: "Self", - key.usr: "s:4cake4ProtPAASi7ElementRtzrlE4Selfxmfp", + key.usr: "s:4cake4ProtP4Selfxmfp", key.offset: 1595, key.length: 4 }, @@ -1649,7 +1649,7 @@ func shouldPrintAnyAsKeyword(x x: Any) { key.kind: source.lang.swift.ref.generic_type_param, key.name: "Wrapped", - key.usr: "s:4cake2S3VA2A2P6RzrlE7Wrappedxmfp", + key.usr: "s:4cake2S3V7Wrappedxmfp", key.offset: 2041, key.length: 7 }, @@ -2557,7 +2557,7 @@ func shouldPrintAnyAsKeyword(x x: Any) ], key.offset: 1574, key.length: 63, - key.fully_annotated_decl: "extension Prot where Self.Element == Int", + key.fully_annotated_decl: "extension Prot where Self.Element == Int", key.extends: { key.kind: source.lang.swift.ref.protocol, key.name: "Prot", @@ -2758,6 +2758,11 @@ func shouldPrintAnyAsKeyword(x x: Any) }, { key.kind: source.lang.swift.decl.extension.struct, + key.generic_params: [ + { + key.name: "Wrapped" + } + ], key.generic_requirements: [ { key.description: "Wrapped : P6" @@ -2765,7 +2770,7 @@ func shouldPrintAnyAsKeyword(x x: Any) ], key.offset: 2022, key.length: 80, - key.fully_annotated_decl: "extension S3 where Wrapped : P6", + key.fully_annotated_decl: "extension S3 where Wrapped : P6", key.extends: { key.kind: source.lang.swift.ref.struct, key.name: "S3", diff --git a/test/SourceKit/DocSupport/doc_swift_module1.swift.response b/test/SourceKit/DocSupport/doc_swift_module1.swift.response index 662df987b140b..1cae78fc9741d 100644 --- a/test/SourceKit/DocSupport/doc_swift_module1.swift.response +++ b/test/SourceKit/DocSupport/doc_swift_module1.swift.response @@ -569,7 +569,7 @@ extension Dictionary.Keys where Key : cake1.P1 { { key.kind: source.lang.swift.ref.generic_type_param, key.name: "Self", - key.usr: "s:5cake12P2PA2A2P3RzrlE4Selfxmfp", + key.usr: "s:5cake12P2P4Selfxmfp", key.offset: 670, key.length: 4 }, @@ -671,7 +671,7 @@ extension Dictionary.Keys where Key : cake1.P1 { { key.kind: source.lang.swift.ref.generic_type_param, key.name: "Key", - key.usr: "s:SD4KeysV5cake1AC2P1RzrlE3Keyxmfp", + key.usr: "s:SD3Keyxmfp", key.offset: 836, key.length: 3 }, @@ -1038,7 +1038,7 @@ extension Dictionary.Keys where Key : cake1.P1 { ], key.offset: 651, key.length: 64, - key.fully_annotated_decl: "extension P2 where Self : P3", + key.fully_annotated_decl: "extension P2 where Self : P3", key.extends: { key.kind: source.lang.swift.ref.protocol, key.name: "P2", @@ -1110,6 +1110,14 @@ extension Dictionary.Keys where Key : cake1.P1 { }, { key.kind: source.lang.swift.decl.extension.struct, + key.generic_params: [ + { + key.name: "Key" + }, + { + key.name: "Value" + } + ], key.generic_requirements: [ { key.description: "Key : Hashable" @@ -1120,7 +1128,7 @@ extension Dictionary.Keys where Key : cake1.P1 { ], key.offset: 804, key.length: 66, - key.fully_annotated_decl: "extension Dictionary.Keys where Key : P1", + key.fully_annotated_decl: "extension Dictionary.Keys where Key : P1", key.extends: { key.kind: source.lang.swift.ref.struct, key.name: "Keys", diff --git a/test/SourceKit/DocSupport/doc_swift_module_class_extension.swift.response b/test/SourceKit/DocSupport/doc_swift_module_class_extension.swift.response index 7af1a0c5b29bb..87befec96d775 100644 --- a/test/SourceKit/DocSupport/doc_swift_module_class_extension.swift.response +++ b/test/SourceKit/DocSupport/doc_swift_module_class_extension.swift.response @@ -129,7 +129,7 @@ extension P8 where Self.T : module_with_class_extension.E { { key.kind: source.lang.swift.ref.generic_type_param, key.name: "T", - key.usr: "s:27module_with_class_extension1CCA2A1DCRbzlE1Txmfp", + key.usr: "s:27module_with_class_extension1CC1Txmfp", key.offset: 130, key.length: 1 }, @@ -344,7 +344,7 @@ extension P8 where Self.T : module_with_class_extension.E { { key.kind: source.lang.swift.ref.generic_type_param, key.name: "Self", - key.usr: "s:27module_with_class_extension2P8PA2A1DC1TRczrlE4Selfxmfp", + key.usr: "s:27module_with_class_extension2P8P4Selfxmfp", key.offset: 480, key.length: 4 }, @@ -397,7 +397,7 @@ extension P8 where Self.T : module_with_class_extension.E { { key.kind: source.lang.swift.ref.generic_type_param, key.name: "Self", - key.usr: "s:27module_with_class_extension2P8PA2A1EC1TRczrlE4Selfxmfp", + key.usr: "s:27module_with_class_extension2P8P4Selfxmfp", key.offset: 559, key.length: 4 }, @@ -470,6 +470,11 @@ extension P8 where Self.T : module_with_class_extension.E { }, { key.kind: source.lang.swift.decl.extension.class, + key.generic_params: [ + { + key.name: "T" + } + ], key.generic_requirements: [ { key.description: "T : D" @@ -477,7 +482,7 @@ extension P8 where Self.T : module_with_class_extension.E { ], key.offset: 112, key.length: 87, - key.fully_annotated_decl: "extension C where T : D", + key.fully_annotated_decl: "extension C where T : D", key.extends: { key.kind: source.lang.swift.ref.class, key.name: "C", @@ -630,7 +635,7 @@ extension P8 where Self.T : module_with_class_extension.E { ], key.offset: 461, key.length: 77, - key.fully_annotated_decl: "extension P8 where Self.T : D", + key.fully_annotated_decl: "extension P8 where Self.T : D", key.extends: { key.kind: source.lang.swift.ref.protocol, key.name: "P8", @@ -656,7 +661,7 @@ extension P8 where Self.T : module_with_class_extension.E { ], key.offset: 540, key.length: 77, - key.fully_annotated_decl: "extension P8 where Self.T : E", + key.fully_annotated_decl: "extension P8 where Self.T : E", key.extends: { key.kind: source.lang.swift.ref.protocol, key.name: "P8", diff --git a/test/SourceKit/DocSupport/doc_system_module_underscored.swift.response b/test/SourceKit/DocSupport/doc_system_module_underscored.swift.response index 69b177d042cbb..f9293f870ddd7 100644 --- a/test/SourceKit/DocSupport/doc_system_module_underscored.swift.response +++ b/test/SourceKit/DocSupport/doc_system_module_underscored.swift.response @@ -219,7 +219,7 @@ protocol Other1 { { key.kind: source.lang.swift.ref.generic_type_param, key.name: "T", - key.usr: "s:16UnderscoredProto1AVAASSRszlE1Txmfp", + key.usr: "s:16UnderscoredProto1AV1Txmfp", key.offset: 227, key.length: 1 }, @@ -849,7 +849,7 @@ protocol Other1 { { key.kind: source.lang.swift.ref.generic_type_param, key.name: "T", - key.usr: "s:16UnderscoredProto1DVAASQRzrlE1Txmfp", + key.usr: "s:16UnderscoredProto1DV1Txmfp", key.offset: 1411, key.length: 1 }, @@ -911,7 +911,7 @@ protocol Other1 { { key.kind: source.lang.swift.ref.generic_type_param, key.name: "T", - key.usr: "s:16UnderscoredProto1DVAASQRzrlE1Txmfp", + key.usr: "s:16UnderscoredProto1DV1Txmfp", key.offset: 1484, key.length: 1 }, @@ -1050,6 +1050,11 @@ protocol Other1 { }, { key.kind: source.lang.swift.decl.extension.struct, + key.generic_params: [ + { + key.name: "T" + } + ], key.generic_requirements: [ { key.description: "T == String" @@ -1057,7 +1062,7 @@ protocol Other1 { ], key.offset: 209, key.length: 185, - key.fully_annotated_decl: "extension A : _UnderscoredProto2 where T == String", + key.fully_annotated_decl: "extension A : _UnderscoredProto2 where T == String", key.conforms: [ { key.kind: source.lang.swift.ref.protocol, @@ -1520,6 +1525,14 @@ protocol Other1 { }, { key.kind: source.lang.swift.decl.extension.struct, + key.generic_params: [ + { + key.name: "T" + }, + { + key.name: "U" + } + ], key.generic_requirements: [ { key.description: "T : Equatable" @@ -1527,7 +1540,7 @@ protocol Other1 { ], key.offset: 1393, key.length: 59, - key.fully_annotated_decl: "extension D : _SomeProto where T : Equatable", + key.fully_annotated_decl: "extension D : _SomeProto where T : Equatable", key.conforms: [ { key.kind: source.lang.swift.ref.protocol, @@ -1560,6 +1573,14 @@ protocol Other1 { }, { key.kind: source.lang.swift.decl.extension.struct, + key.generic_params: [ + { + key.name: "T" + }, + { + key.name: "U" + } + ], key.generic_requirements: [ { key.description: "T : Other1" @@ -1570,7 +1591,7 @@ protocol Other1 { ], key.offset: 1454, key.length: 135, - key.fully_annotated_decl: "extension D where T : Other1, T : Equatable", + key.fully_annotated_decl: "extension D where T : Other1, T : Equatable", key.extends: { key.kind: source.lang.swift.ref.struct, key.name: "D", diff --git a/test/SymbolGraph/ClangImporter/EmitWhileBuilding.swift b/test/SymbolGraph/ClangImporter/EmitWhileBuilding.swift index 7c39f50551537..4d084851d6d94 100644 --- a/test/SymbolGraph/ClangImporter/EmitWhileBuilding.swift +++ b/test/SymbolGraph/ClangImporter/EmitWhileBuilding.swift @@ -4,6 +4,7 @@ // RUN: %{python} -m json.tool %t/EmitWhileBuilding.symbols.json %t/EmitWhileBuilding.formatted.symbols.json // RUN: %FileCheck %s --input-file %t/EmitWhileBuilding.formatted.symbols.json // RUN: %FileCheck %s --input-file %t/EmitWhileBuilding.formatted.symbols.json --check-prefix HEADER +// RUN: %FileCheck %s --input-file %t/EmitWhileBuilding.formatted.symbols.json --check-prefix LOCATION // REQUIRES: objc_interop @@ -28,3 +29,6 @@ public enum SwiftEnum {} // CHECK-NEXT: "spelling": "SwiftEnum" // CHECK-NEXT: } // CHECK-NEXT: ], + +// ensure that the only nodes with a "location" field are the ones that came from Swift +// LOCATION-COUNT-2: "location": diff --git a/test/SymbolGraph/Symbols/Mixins/DeclarationFragments/Full/SomeProtocol.swift b/test/SymbolGraph/Symbols/Mixins/DeclarationFragments/Full/SomeProtocol.swift new file mode 100644 index 0000000000000..60462d57867a4 --- /dev/null +++ b/test/SymbolGraph/Symbols/Mixins/DeclarationFragments/Full/SomeProtocol.swift @@ -0,0 +1,131 @@ +// RUN: %empty-directory(%t) +// RUN: %target-build-swift %s -module-name SomeProtocol -emit-module -emit-module-path %t/ +// RUN: %target-swift-symbolgraph-extract -module-name SomeProtocol -I %t -pretty-print -output-dir %t +// RUN: %FileCheck %s --input-file %t/SomeProtocol.symbols.json +// RUN: %FileCheck %s --input-file %t/SomeProtocol.symbols.json --check-prefix MULTI + +// RUN: %empty-directory(%t) +// RUN: %target-build-swift %s -module-name SomeProtocol -emit-module -emit-module-path %t/SomeProtocol.swiftmodule -emit-symbol-graph -emit-symbol-graph-dir %t/ +// RUN: %{python} -m json.tool %t/SomeProtocol.symbols.json %t/SomeProtocol.formatted.symbols.json +// RUN: %FileCheck %s --input-file %t/SomeProtocol.formatted.symbols.json +// RUN: %FileCheck %s --input-file %t/SomeProtocol.formatted.symbols.json --check-prefix MULTI + +// Make sure that `some MyProtocol` parameters don't crash swift-symbolgraph-extract, and that it +// properly renders `some MyProtocol & OtherProtocol` parameters with multiple protocols listed. + +public protocol SomeProtocol {} + +public func doSomething(with param: some SomeProtocol) {} + +public protocol OtherProtocol {} + +public func doSomethingElse(with param: some SomeProtocol & OtherProtocol) {} + +// CHECK-LABEL: "precise": "s:12SomeProtocol11doSomething4withyx_tA2ARzlF", + +// the functionSignature fragments come before the full fragments, so skip those +// CHECK: "functionSignature": { +// CHECK: "declarationFragments": [ + +// CHECK: "declarationFragments": [ +// CHECK-NEXT: { +// CHECK-NEXT: "kind": "keyword", +// CHECK-NEXT: "spelling": "func" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "kind": "text", +// CHECK-NEXT: "spelling": " " +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "kind": "identifier", +// CHECK-NEXT: "spelling": "doSomething" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "kind": "text", +// CHECK-NEXT: "spelling": "(" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "kind": "externalParam", +// CHECK-NEXT: "spelling": "with" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "kind": "text", +// CHECK-NEXT: "spelling": " " +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "kind": "internalParam", +// CHECK-NEXT: "spelling": "param" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "kind": "text", +// CHECK-NEXT: "spelling": ": some " +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "kind": "typeIdentifier", +// CHECK-NEXT: "spelling": "SomeProtocol", +// CHECK-NEXT: "preciseIdentifier": "s:12SomeProtocolAAP" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "kind": "text", +// CHECK-NEXT: "spelling": ")" +// CHECK-NEXT: } +// CHECK-NEXT: ], + +// MULTI-LABEL: "precise": "s:12SomeProtocol15doSomethingElse4withyx_tAA05OtherB0RzA2ARzlF", + +// the functionSignature fragments come before the full fragments, so skip those +// MULTI: "functionSignature": { +// MULTI: "declarationFragments": [ + +// MULTI: "declarationFragments": [ +// MULTI-NEXT: { +// MULTI-NEXT: "kind": "keyword", +// MULTI-NEXT: "spelling": "func" +// MULTI-NEXT: }, +// MULTI-NEXT: { +// MULTI-NEXT: "kind": "text", +// MULTI-NEXT: "spelling": " " +// MULTI-NEXT: }, +// MULTI-NEXT: { +// MULTI-NEXT: "kind": "identifier", +// MULTI-NEXT: "spelling": "doSomethingElse" +// MULTI-NEXT: }, +// MULTI-NEXT: { +// MULTI-NEXT: "kind": "text", +// MULTI-NEXT: "spelling": "(" +// MULTI-NEXT: }, +// MULTI-NEXT: { +// MULTI-NEXT: "kind": "externalParam", +// MULTI-NEXT: "spelling": "with" +// MULTI-NEXT: }, +// MULTI-NEXT: { +// MULTI-NEXT: "kind": "text", +// MULTI-NEXT: "spelling": " " +// MULTI-NEXT: }, +// MULTI-NEXT: { +// MULTI-NEXT: "kind": "internalParam", +// MULTI-NEXT: "spelling": "param" +// MULTI-NEXT: }, +// MULTI-NEXT: { +// MULTI-NEXT: "kind": "text", +// MULTI-NEXT: "spelling": ": some " +// MULTI-NEXT: }, +// MULTI-NEXT: { +// MULTI-NEXT: "kind": "typeIdentifier", +// MULTI-NEXT: "spelling": "OtherProtocol", +// MULTI-NEXT: "preciseIdentifier": "s:12SomeProtocol05OtherB0P" +// MULTI-NEXT: }, +// MULTI-NEXT: { +// MULTI-NEXT: "kind": "text", +// MULTI-NEXT: "spelling": " & " +// MULTI-NEXT: }, +// MULTI-NEXT: { +// MULTI-NEXT: "kind": "typeIdentifier", +// MULTI-NEXT: "spelling": "SomeProtocol", +// MULTI-NEXT: "preciseIdentifier": "s:12SomeProtocolAAP" +// MULTI-NEXT: }, +// MULTI-NEXT: { +// MULTI-NEXT: "kind": "text", +// MULTI-NEXT: "spelling": ")" +// MULTI-NEXT: } +// MULTI-NEXT: ], diff --git a/test/SymbolGraph/Symbols/Mixins/DocComment/BlockStyle.swift b/test/SymbolGraph/Symbols/Mixins/DocComment/BlockStyle.swift index e3b31f62ebd28..030c7f64bfe66 100644 --- a/test/SymbolGraph/Symbols/Mixins/DocComment/BlockStyle.swift +++ b/test/SymbolGraph/Symbols/Mixins/DocComment/BlockStyle.swift @@ -2,17 +2,94 @@ // Only add text to the bottom of this file // or you are going to have a bad time. +/** Single Same Line */ +public struct SingleSameLine {} + +/***/ +public struct Empty {} + +/** + */ +public struct EmptyWithNewLine {} + +/** + Single line. + */ +public struct SingleLine {} + +/** + * Single line with art. + */ +public struct SingleLineWithArt {} + +/** + Two + lines. + */ +public struct TwoLines {} + +/** + Large Indent + */ +public struct LargeIndent {} + +/** + Two lines + + Between Blank + */ +public struct TwoLinesBetweenBlank {} + +/** + + Leading Blank + */ +public struct LeadingBlank {} + +/** + Trailing Blank + + */ +public struct TrailingBlank {} + +/** + + Bound Blank + + */ +public struct BoundBlank {} + + /** + All indented. + */ + public struct AllIndented {} + +// RUN: %empty-directory(%t) +// RUN: %target-build-swift %s -module-name BlockStyle -emit-module-path %t/BlockStyle.swiftmodule +// RUN: %target-swift-symbolgraph-extract -module-name BlockStyle -I %t -pretty-print -output-dir %t +// RUN: %FileCheck %s --input-file %t/BlockStyle.symbols.json --check-prefix=SINGLESAMELINE +// RUN: %FileCheck %s --input-file %t/BlockStyle.symbols.json --check-prefix=EMPTY +// RUN: %FileCheck %s --input-file %t/BlockStyle.symbols.json --check-prefix=EMPTYWITHNEWLINE +// RUN: %FileCheck %s --input-file %t/BlockStyle.symbols.json --check-prefix=SINGLELINE +// RUN: %FileCheck %s --input-file %t/BlockStyle.symbols.json --check-prefix=SINGLELINEWITHART +// RUN: %FileCheck %s --input-file %t/BlockStyle.symbols.json --check-prefix=LARGEINDENT +// RUN: %FileCheck %s --input-file %t/BlockStyle.symbols.json --check-prefix=TWOLINESBETWEENBLANK +// RUN: %FileCheck %s --input-file %t/BlockStyle.symbols.json --check-prefix=LEADINGBLANK +// RUN: %FileCheck %s --input-file %t/BlockStyle.symbols.json --check-prefix=TRAILINGBLANK + // SINGLESAMELINE-LABEL: "precise": "s:10BlockStyle14SingleSameLineV" // SINGLESAMELINE: "docComment": { +// SINGLESAMELINE-NEXT: "uri": "file://{{.*}}BlockStyle.swift", +// SINGLESAMELINE-NEXT: "module": "BlockStyle", // SINGLESAMELINE-NEXT: "lines": [ // SINGLESAMELINE-NEXT: { // SINGLESAMELINE-NEXT: "range": { // SINGLESAMELINE-NEXT: "start": { -// SINGLESAMELINE-NEXT: "line": 23, +// SINGLESAMELINE-NEXT: "line": 4, // SINGLESAMELINE-NEXT: "character": 4 // SINGLESAMELINE-NEXT: }, // SINGLESAMELINE-NEXT: "end": { -// SINGLESAMELINE-NEXT: "line": 23, +// SINGLESAMELINE-NEXT: "line": 4, // SINGLESAMELINE-NEXT: "character": 21 // SINGLESAMELINE-NEXT: } // SINGLESAMELINE-NEXT: }, @@ -21,51 +98,47 @@ // SINGLESAMELINE-NEXT: ] // SINGLESAMELINE-NEXT: }, -/** Single Same Line */ -public struct SingleSameLine {} - // EMPTY-LABEL: "precise": "s:10BlockStyle5EmptyV" // EMPTY: "docComment": { +// EMPTY-NEXT: "uri": "file://{{.*}}BlockStyle.swift", +// EMPTY-NEXT: "module": "BlockStyle", // EMPTY-NEXT: "lines": [] // EMPTY-NEXT: }, -/***/ -public struct Empty {} - // EMPTYWITHNEWLINE-LABEL: "precise": "s:10BlockStyle16EmptyWithNewLineV" -// EMPTHWITHNEWLINE: "docComment": { -// EMPTHWITHNEWLINE-NEXT: "lines": [ -// EMPTHWITHNEWLINE-NEXT: { -// EMPTHWITHNEWLINE-NEXT: "range": { -// EMPTHWITHNEWLINE-NEXT: "start": { -// EMPTHWITHNEWLINE-NEXT: "line": 54, -// EMPTHWITHNEWLINE-NEXT: "character": 1 -// EMPTHWITHNEWLINE-NEXT: }, -// EMPTHWITHNEWLINE-NEXT: "end": { -// EMPTHWITHNEWLINE-NEXT: "line": 54, -// EMPTHWITHNEWLINE-NEXT: "character": 1 -// EMPTHWITHNEWLINE-NEXT: } -// EMPTHWITHNEWLINE-NEXT: }, -// EMPTHWITHNEWLINE-NEXT: "text": "" -// EMPTHWITHNEWLINE-NEXT: } -// EMPTHWITHNEWLINE-NEXT: ] -// EMPTHWITHNEWLINE-NEXT: }, - -/** - */ -public struct EmptyWithNewLine {} +// EMPTYWITHNEWLINE: "docComment": { +// EMPTYWITHNEWLINE-NEXT: "uri": "file://{{.*}}BlockStyle.swift", +// EMPTYWITHNEWLINE-NEXT: "module": "BlockStyle", +// EMPTYWITHNEWLINE-NEXT: "lines": [ +// EMPTYWITHNEWLINE-NEXT: { +// EMPTYWITHNEWLINE-NEXT: "range": { +// EMPTYWITHNEWLINE-NEXT: "start": { +// EMPTYWITHNEWLINE-NEXT: "line": 11, +// EMPTYWITHNEWLINE-NEXT: "character": 1 +// EMPTYWITHNEWLINE-NEXT: }, +// EMPTYWITHNEWLINE-NEXT: "end": { +// EMPTYWITHNEWLINE-NEXT: "line": 11, +// EMPTYWITHNEWLINE-NEXT: "character": 1 +// EMPTYWITHNEWLINE-NEXT: } +// EMPTYWITHNEWLINE-NEXT: }, +// EMPTYWITHNEWLINE-NEXT: "text": "" +// EMPTYWITHNEWLINE-NEXT: } +// EMPTYWITHNEWLINE-NEXT: ] +// EMPTYWITHNEWLINE-NEXT: }, // SINGLELINE-LABEL: "precise": "s:10BlockStyle10SingleLineV" // SINGLELINE: "docComment": { +// SINGLELINE-NEXT: "uri": "file://{{.*}}BlockStyle.swift", +// SINGLELINE-NEXT: "module": "BlockStyle", // SINGLELINE-NEXT: "lines": [ // SINGLELINE-NEXT: { // SINGLELINE-NEXT: "range": { // SINGLELINE-NEXT: "start": { -// SINGLELINE-NEXT: "line": 90, +// SINGLELINE-NEXT: "line": 15, // SINGLELINE-NEXT: "character": 1 // SINGLELINE-NEXT: }, // SINGLELINE-NEXT: "end": { -// SINGLELINE-NEXT: "line": 90, +// SINGLELINE-NEXT: "line": 15, // SINGLELINE-NEXT: "character": 13 // SINGLELINE-NEXT: } // SINGLELINE-NEXT: }, @@ -74,11 +147,11 @@ public struct EmptyWithNewLine {} // SINGLELINE-NEXT: { // SINGLELINE-NEXT: "range": { // SINGLELINE-NEXT: "start": { -// SINGLELINE-NEXT: "line": 91, +// SINGLELINE-NEXT: "line": 16, // SINGLELINE-NEXT: "character": 1 // SINGLELINE-NEXT: }, // SINGLELINE-NEXT: "end": { -// SINGLELINE-NEXT: "line": 91, +// SINGLELINE-NEXT: "line": 16, // SINGLELINE-NEXT: "character": 1 // SINGLELINE-NEXT: } // SINGLELINE-NEXT: }, @@ -87,22 +160,19 @@ public struct EmptyWithNewLine {} // SINGLELINE-NEXT: ] // SINGLELINE-NEXT: }, -/** - Single line. - */ -public struct SingleLine {} - // SINGLELINEWITHART-LABEL: "precise": "s:10BlockStyle17SingleLineWithArtV" // SINGLELINEWITHART: "docComment": { +// SINGLELINEWITHART-NEXT: "uri": "file://{{.*}}BlockStyle.swift", +// SINGLELINEWITHART-NEXT: "module": "BlockStyle", // SINGLELINEWITHART-NEXT: "lines": [ // SINGLELINEWITHART-NEXT: { // SINGLELINEWITHART-NEXT: "range": { // SINGLELINEWITHART-NEXT: "start": { -// SINGLELINEWITHART-NEXT: "line": 127, +// SINGLELINEWITHART-NEXT: "line": 20, // SINGLELINEWITHART-NEXT: "character": 3 // SINGLELINEWITHART-NEXT: }, // SINGLELINEWITHART-NEXT: "end": { -// SINGLELINEWITHART-NEXT: "line": 127, +// SINGLELINEWITHART-NEXT: "line": 20, // SINGLELINEWITHART-NEXT: "character": 24 // SINGLELINEWITHART-NEXT: } // SINGLELINEWITHART-NEXT: }, @@ -111,11 +181,11 @@ public struct SingleLine {} // SINGLELINEWITHART-NEXT: { // SINGLELINEWITHART-NEXT: "range": { // SINGLELINEWITHART-NEXT: "start": { -// SINGLELINEWITHART-NEXT: "line": 128, +// SINGLELINEWITHART-NEXT: "line": 21, // SINGLELINEWITHART-NEXT: "character": 0 // SINGLELINEWITHART-NEXT: }, // SINGLELINEWITHART-NEXT: "end": { -// SINGLELINEWITHART-NEXT: "line": 128, +// SINGLELINEWITHART-NEXT: "line": 21, // SINGLELINEWITHART-NEXT: "character": 1 // SINGLELINEWITHART-NEXT: } // SINGLELINEWITHART-NEXT: }, @@ -124,22 +194,19 @@ public struct SingleLine {} // SINGLELINEWITHART-NEXT: ] // SINGLELINEWITHART-NEXT: }, -/** - * Single line with art. - */ -public struct SingleLineWithArt {} - // TWOLINES-LABEL: "precise": "s:10BlockStyle8TwoLinesV" // TWOLINES: "docComment": { +// TWOLINES-NEXT: "uri": "file://{{.*}}BlockStyle.swift", +// TWOLINES-NEXT: "module": "BlockStyle", // TWOLINES-NEXT: "lines": [ // TWOLINES-NEXT: { // TWOLINES-NEXT: "range": { // TWOLINES-NEXT: "start": { -// TWOLINES-NEXT: "line": 177, +// TWOLINES-NEXT: "line": 25, // TWOLINES-NEXT: "character": 1 // TWOLINES-NEXT: }, // TWOLINES-NEXT: "end": { -// TWOLINES-NEXT: "line": 177, +// TWOLINES-NEXT: "line": 25, // TWOLINES-NEXT: "character": 4 // TWOLINES-NEXT: } // TWOLINES-NEXT: }, @@ -148,11 +215,11 @@ public struct SingleLineWithArt {} // TWOLINES-NEXT: { // TWOLINES-NEXT: "range": { // TWOLINES-NEXT: "start": { -// TWOLINES-NEXT: "line": 178, +// TWOLINES-NEXT: "line": 26, // TWOLINES-NEXT: "character": 1 // TWOLINES-NEXT: }, // TWOLINES-NEXT: "end": { -// TWOLINES-NEXT: "line": 178, +// TWOLINES-NEXT: "line": 26, // TWOLINES-NEXT: "character": 7 // TWOLINES-NEXT: } // TWOLINES-NEXT: }, @@ -161,11 +228,11 @@ public struct SingleLineWithArt {} // TWOLINES-NEXT: { // TWOLINES-NEXT: "range": { // TWOLINES-NEXT: "start": { -// TWOLINES-NEXT: "line": 179, +// TWOLINES-NEXT: "line": 27, // TWOLINES-NEXT: "character": 1 // TWOLINES-NEXT: }, // TWOLINES-NEXT: "end": { -// TWOLINES-NEXT: "line": 179, +// TWOLINES-NEXT: "line": 27, // TWOLINES-NEXT: "character": 1 // TWOLINES-NEXT: } // TWOLINES-NEXT: }, @@ -174,23 +241,19 @@ public struct SingleLineWithArt {} // TWOLINES-NEXT: ] // TWOLINES-NEXT: }, -/** - Two - lines. - */ -public struct TwoLines {} - // LARGEINDENT-LABEL: "precise": "s:10BlockStyle11LargeIndentV" // LARGEINDENT: "docComment": { +// LARGEINDENT-NEXT: "uri": "file://{{.*}}BlockStyle.swift", +// LARGEINDENT-NEXT: "module": "BlockStyle", // LARGEINDENT-NEXT: "lines": [ // LARGEINDENT-NEXT: { // LARGEINDENT-NEXT: "range": { // LARGEINDENT-NEXT: "start": { -// LARGEINDENT-NEXT: "line": 215, +// LARGEINDENT-NEXT: "line": 31, // LARGEINDENT-NEXT: "character": 5 // LARGEINDENT-NEXT: }, // LARGEINDENT-NEXT: "end": { -// LARGEINDENT-NEXT: "line": 215, +// LARGEINDENT-NEXT: "line": 31, // LARGEINDENT-NEXT: "character": 17 // LARGEINDENT-NEXT: } // LARGEINDENT-NEXT: }, @@ -199,11 +262,11 @@ public struct TwoLines {} // LARGEINDENT-NEXT: { // LARGEINDENT-NEXT: "range": { // LARGEINDENT-NEXT: "start": { -// LARGEINDENT-NEXT: "line": 216, +// LARGEINDENT-NEXT: "line": 32, // LARGEINDENT-NEXT: "character": 1 // LARGEINDENT-NEXT: }, // LARGEINDENT-NEXT: "end": { -// LARGEINDENT-NEXT: "line": 216, +// LARGEINDENT-NEXT: "line": 32, // LARGEINDENT-NEXT: "character": 1 // LARGEINDENT-NEXT: } // LARGEINDENT-NEXT: }, @@ -212,22 +275,19 @@ public struct TwoLines {} // LARGEINDENT-NEXT: ] // LARGEINDENT-NEXT: } -/** - Large Indent - */ -public struct LargeIndent {} - // TWOLINESBETWEENBLANK-LABEL: "precise": "s:10BlockStyle20TwoLinesBetweenBlankV" // TWOLINESBETWEENBLANK: "docComment": { +// TWOLINESBETWEENBLANK-NEXT: "uri": "file://{{.*}}BlockStyle.swift", +// TWOLINESBETWEENBLANK-NEXT: "module": "BlockStyle", // TWOLINESBETWEENBLANK-NEXT: "lines": [ // TWOLINESBETWEENBLANK-NEXT: { // TWOLINESBETWEENBLANK-NEXT: "range": { // TWOLINESBETWEENBLANK-NEXT: "start": { -// TWOLINESBETWEENBLANK-NEXT: "line": 278, +// TWOLINESBETWEENBLANK-NEXT: "line": 36, // TWOLINESBETWEENBLANK-NEXT: "character": 1 // TWOLINESBETWEENBLANK-NEXT: }, // TWOLINESBETWEENBLANK-NEXT: "end": { -// TWOLINESBETWEENBLANK-NEXT: "line": 278, +// TWOLINESBETWEENBLANK-NEXT: "line": 36, // TWOLINESBETWEENBLANK-NEXT: "character": 10 // TWOLINESBETWEENBLANK-NEXT: } // TWOLINESBETWEENBLANK-NEXT: }, @@ -236,11 +296,11 @@ public struct LargeIndent {} // TWOLINESBETWEENBLANK-NEXT: { // TWOLINESBETWEENBLANK-NEXT: "range": { // TWOLINESBETWEENBLANK-NEXT: "start": { -// TWOLINESBETWEENBLANK-NEXT: "line": 279, +// TWOLINESBETWEENBLANK-NEXT: "line": 37, // TWOLINESBETWEENBLANK-NEXT: "character": 0 // TWOLINESBETWEENBLANK-NEXT: }, // TWOLINESBETWEENBLANK-NEXT: "end": { -// TWOLINESBETWEENBLANK-NEXT: "line": 279, +// TWOLINESBETWEENBLANK-NEXT: "line": 37, // TWOLINESBETWEENBLANK-NEXT: "character": 0 // TWOLINESBETWEENBLANK-NEXT: } // TWOLINESBETWEENBLANK-NEXT: }, @@ -249,11 +309,11 @@ public struct LargeIndent {} // TWOLINESBETWEENBLANK-NEXT: { // TWOLINESBETWEENBLANK-NEXT: "range": { // TWOLINESBETWEENBLANK-NEXT: "start": { -// TWOLINESBETWEENBLANK-NEXT: "line": 280, +// TWOLINESBETWEENBLANK-NEXT: "line": 38, // TWOLINESBETWEENBLANK-NEXT: "character": 1 // TWOLINESBETWEENBLANK-NEXT: }, // TWOLINESBETWEENBLANK-NEXT: "end": { -// TWOLINESBETWEENBLANK-NEXT: "line": 280, +// TWOLINESBETWEENBLANK-NEXT: "line": 38, // TWOLINESBETWEENBLANK-NEXT: "character": 14 // TWOLINESBETWEENBLANK-NEXT: } // TWOLINESBETWEENBLANK-NEXT: }, @@ -262,11 +322,11 @@ public struct LargeIndent {} // TWOLINESBETWEENBLANK-NEXT: { // TWOLINESBETWEENBLANK-NEXT: "range": { // TWOLINESBETWEENBLANK-NEXT: "start": { -// TWOLINESBETWEENBLANK-NEXT: "line": 281, +// TWOLINESBETWEENBLANK-NEXT: "line": 39, // TWOLINESBETWEENBLANK-NEXT: "character": 1 // TWOLINESBETWEENBLANK-NEXT: }, // TWOLINESBETWEENBLANK-NEXT: "end": { -// TWOLINESBETWEENBLANK-NEXT: "line": 281, +// TWOLINESBETWEENBLANK-NEXT: "line": 39, // TWOLINESBETWEENBLANK-NEXT: "character": 1 // TWOLINESBETWEENBLANK-NEXT: } // TWOLINESBETWEENBLANK-NEXT: }, @@ -275,24 +335,19 @@ public struct LargeIndent {} // TWOLINESBETWEENBLANK-NEXT: ] // TWOLINESBETWEENBLANK-NEXT: }, -/** - Two lines - - Between Blank - */ -public struct TwoLinesBetweenBlank {} - // LEADINGBLANK-LABEL: "precise": "s:10BlockStyle12LeadingBlankV" // LEADINGBLANK: "docComment": { +// LEADINGBLANK-NEXT: "uri": "file://{{.*}}BlockStyle.swift", +// LEADINGBLANK-NEXT: "module": "BlockStyle", // LEADINGBLANK-NEXT: "lines": [ // LEADINGBLANK-NEXT: { // LEADINGBLANK-NEXT: "range": { // LEADINGBLANK-NEXT: "start": { -// LEADINGBLANK-NEXT: "line": 330, +// LEADINGBLANK-NEXT: "line": 43, // LEADINGBLANK-NEXT: "character": 0 // LEADINGBLANK-NEXT: }, // LEADINGBLANK-NEXT: "end": { -// LEADINGBLANK-NEXT: "line": 330, +// LEADINGBLANK-NEXT: "line": 43, // LEADINGBLANK-NEXT: "character": 0 // LEADINGBLANK-NEXT: } // LEADINGBLANK-NEXT: }, @@ -301,11 +356,11 @@ public struct TwoLinesBetweenBlank {} // LEADINGBLANK-NEXT: { // LEADINGBLANK-NEXT: "range": { // LEADINGBLANK-NEXT: "start": { -// LEADINGBLANK-NEXT: "line": 331, +// LEADINGBLANK-NEXT: "line": 44, // LEADINGBLANK-NEXT: "character": 1 // LEADINGBLANK-NEXT: }, // LEADINGBLANK-NEXT: "end": { -// LEADINGBLANK-NEXT: "line": 331, +// LEADINGBLANK-NEXT: "line": 44, // LEADINGBLANK-NEXT: "character": 14 // LEADINGBLANK-NEXT: } // LEADINGBLANK-NEXT: }, @@ -314,11 +369,11 @@ public struct TwoLinesBetweenBlank {} // LEADINGBLANK-NEXT: { // LEADINGBLANK-NEXT: "range": { // LEADINGBLANK-NEXT: "start": { -// LEADINGBLANK-NEXT: "line": 332, +// LEADINGBLANK-NEXT: "line": 45, // LEADINGBLANK-NEXT: "character": 1 // LEADINGBLANK-NEXT: }, // LEADINGBLANK-NEXT: "end": { -// LEADINGBLANK-NEXT: "line": 332, +// LEADINGBLANK-NEXT: "line": 45, // LEADINGBLANK-NEXT: "character": 1 // LEADINGBLANK-NEXT: } // LEADINGBLANK-NEXT: }, @@ -327,23 +382,19 @@ public struct TwoLinesBetweenBlank {} // LEADINGBLANK-NEXT: ] // LEADINGBLANK-NEXT: }, -/** - - Leading Blank - */ -public struct LeadingBlank {} - // TRAILINGBLANK-LABEL: "precise": "s:10BlockStyle13TrailingBlankV" // TRAILINGBLANK: "docComment": { +// TRAILINGBLANK-NEXT: "uri": "file://{{.*}}BlockStyle.swift", +// TRAILINGBLANK-NEXT: "module": "BlockStyle", // TRAILINGBLANK-NEXT: "lines": [ // TRAILINGBLANK-NEXT: { // TRAILINGBLANK-NEXT: "range": { // TRAILINGBLANK-NEXT: "start": { -// TRAILINGBLANK-NEXT: "line": 381, +// TRAILINGBLANK-NEXT: "line": 49, // TRAILINGBLANK-NEXT: "character": 1 // TRAILINGBLANK-NEXT: }, // TRAILINGBLANK-NEXT: "end": { -// TRAILINGBLANK-NEXT: "line": 381, +// TRAILINGBLANK-NEXT: "line": 49, // TRAILINGBLANK-NEXT: "character": 15 // TRAILINGBLANK-NEXT: } // TRAILINGBLANK-NEXT: }, @@ -352,11 +403,11 @@ public struct LeadingBlank {} // TRAILINGBLANK-NEXT: { // TRAILINGBLANK-NEXT: "range": { // TRAILINGBLANK-NEXT: "start": { -// TRAILINGBLANK-NEXT: "line": 382, +// TRAILINGBLANK-NEXT: "line": 50, // TRAILINGBLANK-NEXT: "character": 0 // TRAILINGBLANK-NEXT: }, // TRAILINGBLANK-NEXT: "end": { -// TRAILINGBLANK-NEXT: "line": 382, +// TRAILINGBLANK-NEXT: "line": 50, // TRAILINGBLANK-NEXT: "character": 0 // TRAILINGBLANK-NEXT: } // TRAILINGBLANK-NEXT: }, @@ -365,11 +416,11 @@ public struct LeadingBlank {} // TRAILINGBLANK-NEXT: { // TRAILINGBLANK-NEXT: "range": { // TRAILINGBLANK-NEXT: "start": { -// TRAILINGBLANK-NEXT: "line": 383, +// TRAILINGBLANK-NEXT: "line": 51, // TRAILINGBLANK-NEXT: "character": 1 // TRAILINGBLANK-NEXT: }, // TRAILINGBLANK-NEXT: "end": { -// TRAILINGBLANK-NEXT: "line": 383, +// TRAILINGBLANK-NEXT: "line": 51, // TRAILINGBLANK-NEXT: "character": 1 // TRAILINGBLANK-NEXT: } // TRAILINGBLANK-NEXT: }, @@ -378,23 +429,19 @@ public struct LeadingBlank {} // TRAILINGBLANK-NEXT: ] // TRAILINGBLANK-NEXT: }, -/** - Trailing Blank - - */ -public struct TrailingBlank {} - // BOUNDBLANK-LABEL: "precise": "s:10BlockStyle10BoundBlankV" // BOUNDBLANK: "docComment": { +// BOUNDBLANK-NEXT: "uri": "file://{{.*}}BlockStyle.swift", +// BOUNDBLANK-NEXT: "module": "BlockStyle", // BOUNDBLANK-NEXT: "lines": [ // BOUNDBLANK-NEXT: { // BOUNDBLANK-NEXT: "range": { // BOUNDBLANK-NEXT: "start": { -// BOUNDBLANK-NEXT: "line": 445, +// BOUNDBLANK-NEXT: "line": 55, // BOUNDBLANK-NEXT: "character": 0 // BOUNDBLANK-NEXT: }, // BOUNDBLANK-NEXT: "end": { -// BOUNDBLANK-NEXT: "line": 445, +// BOUNDBLANK-NEXT: "line": 55, // BOUNDBLANK-NEXT: "character": 0 // BOUNDBLANK-NEXT: } // BOUNDBLANK-NEXT: }, @@ -403,11 +450,11 @@ public struct TrailingBlank {} // BOUNDBLANK-NEXT: { // BOUNDBLANK-NEXT: "range": { // BOUNDBLANK-NEXT: "start": { -// BOUNDBLANK-NEXT: "line": 446, +// BOUNDBLANK-NEXT: "line": 56, // BOUNDBLANK-NEXT: "character": 1 // BOUNDBLANK-NEXT: }, // BOUNDBLANK-NEXT: "end": { -// BOUNDBLANK-NEXT: "line": 446, +// BOUNDBLANK-NEXT: "line": 56, // BOUNDBLANK-NEXT: "character": 12 // BOUNDBLANK-NEXT: } // BOUNDBLANK-NEXT: }, @@ -416,11 +463,11 @@ public struct TrailingBlank {} // BOUNDBLANK-NEXT: { // BOUNDBLANK-NEXT: "range": { // BOUNDBLANK-NEXT: "start": { -// BOUNDBLANK-NEXT: "line": 447, +// BOUNDBLANK-NEXT: "line": 57, // BOUNDBLANK-NEXT: "character": 0 // BOUNDBLANK-NEXT: }, // BOUNDBLANK-NEXT: "end": { -// BOUNDBLANK-NEXT: "line": 447, +// BOUNDBLANK-NEXT: "line": 57, // BOUNDBLANK-NEXT: "character": 0 // BOUNDBLANK-NEXT: } // BOUNDBLANK-NEXT: }, @@ -429,11 +476,11 @@ public struct TrailingBlank {} // BOUNDBLANK-NEXT: { // BOUNDBLANK-NEXT: "range": { // BOUNDBLANK-NEXT: "start": { -// BOUNDBLANK-NEXT: "line": 448, +// BOUNDBLANK-NEXT: "line": 58, // BOUNDBLANK-NEXT: "character": 1 // BOUNDBLANK-NEXT: }, // BOUNDBLANK-NEXT: "end": { -// BOUNDBLANK-NEXT: "line": 448, +// BOUNDBLANK-NEXT: "line": 58, // BOUNDBLANK-NEXT: "character": 1 // BOUNDBLANK-NEXT: } // BOUNDBLANK-NEXT: }, @@ -442,24 +489,19 @@ public struct TrailingBlank {} // BOUNDBLANK-NEXT: ] // BOUNDBLANK-NEXT: }, -/** - - Bound Blank - - */ -public struct BoundBlank {} - // ALLINDENTED-LABEL: "precise": "s:10BlockStyle11AllIndentedV" // ALLINDENTED: "docComment": { +// ALLINDENTED-NEXT: "uri": "file://{{.*}}BlockStyle.swift", +// ALLINDENTED-NEXT: "module": "BlockStyle", // ALLINDENTED-NEXT: "lines": [ // ALLINDENTED-NEXT: { // ALLINDENTED-NEXT: "range": { // ALLINDENTED-NEXT: "start": { -// ALLINDENTED-NEXT: "line": 484, +// ALLINDENTED-NEXT: "line": 62, // ALLINDENTED-NEXT: "character": 5 // ALLINDENTED-NEXT: }, // ALLINDENTED-NEXT: "end": { -// ALLINDENTED-NEXT: "line": 484, +// ALLINDENTED-NEXT: "line": 62, // ALLINDENTED-NEXT: "character": 18 // ALLINDENTED-NEXT: } // ALLINDENTED-NEXT: }, @@ -468,11 +510,11 @@ public struct BoundBlank {} // ALLINDENTED-NEXT: { // ALLINDENTED-NEXT: "range": { // ALLINDENTED-NEXT: "start": { -// ALLINDENTED-NEXT: "line": 485, +// ALLINDENTED-NEXT: "line": 63, // ALLINDENTED-NEXT: "character": 5 // ALLINDENTED-NEXT: }, // ALLINDENTED-NEXT: "end": { -// ALLINDENTED-NEXT: "line": 485, +// ALLINDENTED-NEXT: "line": 63, // ALLINDENTED-NEXT: "character": 5 // ALLINDENTED-NEXT: } // ALLINDENTED-NEXT: }, @@ -480,21 +522,3 @@ public struct BoundBlank {} // ALLINDENTED-NEXT: } // ALLINDENTED-NEXT: ] // ALLINDENTED-NEXT: }, - - /** - All indented. - */ - public struct AllIndented {} - -// RUN: %empty-directory(%t) -// RUN: %target-build-swift %s -module-name BlockStyle -emit-module-path %t/BlockStyle.swiftmodule -// RUN: %target-swift-symbolgraph-extract -module-name BlockStyle -I %t -pretty-print -output-dir %t -// RUN: %FileCheck %s --input-file %t/BlockStyle.symbols.json --check-prefix=SINGLESAMELINE -// RUN: %FileCheck %s --input-file %t/BlockStyle.symbols.json --check-prefix=EMPTY -// RUN: %FileCheck %s --input-file %t/BlockStyle.symbols.json --check-prefix=EMPTYWITHNEWLINE -// RUN: %FileCheck %s --input-file %t/BlockStyle.symbols.json --check-prefix=SINGLELINE -// RUN: %FileCheck %s --input-file %t/BlockStyle.symbols.json --check-prefix=SINGLELINEWITHART -// RUN: %FileCheck %s --input-file %t/BlockStyle.symbols.json --check-prefix=LARGEINDENT -// RUN: %FileCheck %s --input-file %t/BlockStyle.symbols.json --check-prefix=TWOLINESBETWEENBLANK -// RUN: %FileCheck %s --input-file %t/BlockStyle.symbols.json --check-prefix=LEADINGBLANK -// RUN: %FileCheck %s --input-file %t/BlockStyle.symbols.json --check-prefix=TRAILINGBLANK diff --git a/test/SymbolGraph/Symbols/Mixins/DocComment/LineStyle.swift b/test/SymbolGraph/Symbols/Mixins/DocComment/LineStyle.swift index e1ff66989f3aa..9b64e854f51d3 100644 --- a/test/SymbolGraph/Symbols/Mixins/DocComment/LineStyle.swift +++ b/test/SymbolGraph/Symbols/Mixins/DocComment/LineStyle.swift @@ -1,3 +1,39 @@ +// ATTN: The RUN lines and associated tests are at the bottom of the file, to +// keep the source locations stable. + +/// Single line. +public struct SingleLine {} + +/// Two +/// lines. +public struct TwoLines {} + +/// Two lines +/// +/// Around Blank +public struct TwoLinesAroundBlank {} + +/// +public struct Empty {} + +/// +/// +/// +public struct MultiEmpty {} + +/// +/// Leading Blank +public struct LeadingBlank {} + +/// Trailing Blank +/// +public struct TrailingBlank {} + +/// +/// Bound Blank +/// +public struct BoundBlank {} + // RUN: %empty-directory(%t) // RUN: %target-build-swift %s -module-name LineStyle -emit-module-path %t/LineStyle.swiftmodule // RUN: %target-swift-symbolgraph-extract -module-name LineStyle -I %t -pretty-print -output-dir %t @@ -11,15 +47,17 @@ // SINGLELINE-LABEL: "precise": "s:9LineStyle06SingleA0V" // SINGLELINE: "docComment": { +// SINGLELINE-NEXT: "uri": "file://{{.*}}LineStyle.swift", +// SINGLELINE-NEXT: "module": "LineStyle", // SINGLELINE-NEXT: "lines": [ // SINGLELINE-NEXT: { // SINGLELINE-NEXT: "range": { // SINGLELINE-NEXT: "start": { -// SINGLELINE-NEXT: "line": 30, +// SINGLELINE-NEXT: "line": 3, // SINGLELINE-NEXT: "character": 4 // SINGLELINE-NEXT: }, // SINGLELINE-NEXT: "end": { -// SINGLELINE-NEXT: "line": 30, +// SINGLELINE-NEXT: "line": 3, // SINGLELINE-NEXT: "character": 16 // SINGLELINE-NEXT: } // SINGLELINE-NEXT: }, @@ -28,20 +66,19 @@ // SINGLELINE-NEXT: ] // SINGLELINE-NEXT: } -/// Single line. -public struct SingleLine {} - // TWOLINES-LABEL: "precise": "s:9LineStyle8TwoLinesV" // TWOLINES: "docComment": { +// TWOLINES-NEXT: "uri": "file://{{.*}}LineStyle.swift", +// TWOLINES-NEXT: "module": "LineStyle", // TWOLINES-NEXT: "lines": [ // TWOLINES-NEXT: { // TWOLINES-NEXT: "range": { // TWOLINES-NEXT: "start": { -// TWOLINES-NEXT: "line": 65, +// TWOLINES-NEXT: "line": 6, // TWOLINES-NEXT: "character": 4 // TWOLINES-NEXT: }, // TWOLINES-NEXT: "end": { -// TWOLINES-NEXT: "line": 65, +// TWOLINES-NEXT: "line": 6, // TWOLINES-NEXT: "character": 7 // TWOLINES-NEXT: } // TWOLINES-NEXT: }, @@ -50,11 +87,11 @@ public struct SingleLine {} // TWOLINES-NEXT: { // TWOLINES-NEXT: "range": { // TWOLINES-NEXT: "start": { -// TWOLINES-NEXT: "line": 66, +// TWOLINES-NEXT: "line": 7, // TWOLINES-NEXT: "character": 4 // TWOLINES-NEXT: }, // TWOLINES-NEXT: "end": { -// TWOLINES-NEXT: "line": 66, +// TWOLINES-NEXT: "line": 7, // TWOLINES-NEXT: "character": 10 // TWOLINES-NEXT: } // TWOLINES-NEXT: }, @@ -63,21 +100,19 @@ public struct SingleLine {} // TWOLINES-NEXT: ] // TWOLINES-NEXT: }, -/// Two -/// lines. -public struct TwoLines {} - // TWOLINESAROUNDBLANK-LABEL: "precise": "s:9LineStyle19TwoLinesAroundBlankV" // TWOLINESAROUNDBLANK: "docComment": { +// TWOLINESAROUNDBLANK-NEXT: "uri": "file://{{.*}}LineStyle.swift", +// TWOLINESAROUNDBLANK-NEXT: "module": "LineStyle", // TWOLINESAROUNDBLANK-NEXT: "lines": [ // TWOLINESAROUNDBLANK-NEXT: { // TWOLINESAROUNDBLANK-NEXT: "range": { // TWOLINESAROUNDBLANK-NEXT: "start": { -// TWOLINESAROUNDBLANK-NEXT: "line": 114, +// TWOLINESAROUNDBLANK-NEXT: "line": 10, // TWOLINESAROUNDBLANK-NEXT: "character": 4 // TWOLINESAROUNDBLANK-NEXT: }, // TWOLINESAROUNDBLANK-NEXT: "end": { -// TWOLINESAROUNDBLANK-NEXT: "line": 114, +// TWOLINESAROUNDBLANK-NEXT: "line": 10, // TWOLINESAROUNDBLANK-NEXT: "character": 13 // TWOLINESAROUNDBLANK-NEXT: } // TWOLINESAROUNDBLANK-NEXT: }, @@ -86,11 +121,11 @@ public struct TwoLines {} // TWOLINESAROUNDBLANK-NEXT: { // TWOLINESAROUNDBLANK-NEXT: "range": { // TWOLINESAROUNDBLANK-NEXT: "start": { -// TWOLINESAROUNDBLANK-NEXT: "line": 115, +// TWOLINESAROUNDBLANK-NEXT: "line": 11, // TWOLINESAROUNDBLANK-NEXT: "character": 3 // TWOLINESAROUNDBLANK-NEXT: }, // TWOLINESAROUNDBLANK-NEXT: "end": { -// TWOLINESAROUNDBLANK-NEXT: "line": 115, +// TWOLINESAROUNDBLANK-NEXT: "line": 11, // TWOLINESAROUNDBLANK-NEXT: "character": 3 // TWOLINESAROUNDBLANK-NEXT: } // TWOLINESAROUNDBLANK-NEXT: }, @@ -99,11 +134,11 @@ public struct TwoLines {} // TWOLINESAROUNDBLANK-NEXT: { // TWOLINESAROUNDBLANK-NEXT: "range": { // TWOLINESAROUNDBLANK-NEXT: "start": { -// TWOLINESAROUNDBLANK-NEXT: "line": 116, +// TWOLINESAROUNDBLANK-NEXT: "line": 12, // TWOLINESAROUNDBLANK-NEXT: "character": 4 // TWOLINESAROUNDBLANK-NEXT: }, // TWOLINESAROUNDBLANK-NEXT: "end": { -// TWOLINESAROUNDBLANK-NEXT: "line": 116, +// TWOLINESAROUNDBLANK-NEXT: "line": 12, // TWOLINESAROUNDBLANK-NEXT: "character": 16 // TWOLINESAROUNDBLANK-NEXT: } // TWOLINESAROUNDBLANK-NEXT: }, @@ -112,22 +147,19 @@ public struct TwoLines {} // TWOLINESAROUNDBLANK-NEXT: ] // TWOLINESAROUNDBLANK-NEXT: } -/// Two lines -/// -/// Around Blank -public struct TwoLinesAroundBlank {} - // EMPTY-LABEL: "precise": "s:9LineStyle5EmptyV" // EMPTY: "docComment": { +// EMPTY-NEXT: "uri": "file://{{.*}}LineStyle.swift", +// EMPTY-NEXT: "module": "LineStyle", // EMPTY-NEXT: "lines": [ // EMPTY-NEXT: { // EMPTY-NEXT: "range": { // EMPTY-NEXT: "start": { -// EMPTY-NEXT: "line": 138, +// EMPTY-NEXT: "line": 15, // EMPTY-NEXT: "character": 3 // EMPTY-NEXT: }, // EMPTY-NEXT: "end": { -// EMPTY-NEXT: "line": 138, +// EMPTY-NEXT: "line": 15, // EMPTY-NEXT: "character": 3 // EMPTY-NEXT: } // EMPTY-NEXT: }, @@ -136,20 +168,19 @@ public struct TwoLinesAroundBlank {} // EMPTY-NEXT: ] // EMPTY-NEXT: }, -/// -public struct Empty {} - // MULTIEMPTY-LABEL: "precise": "s:9LineStyle10MultiEmptyV" // MULTIEMPTY: "docComment": { +// MULTIEMPTY-NEXT: "uri": "file://{{.*}}LineStyle.swift", +// MULTIEMPTY-NEXT: "module": "LineStyle", // MULTIEMPTY-NEXT: "lines": [ // MULTIEMPTY-NEXT: { // MULTIEMPTY-NEXT: "range": { // MULTIEMPTY-NEXT: "start": { -// MULTIEMPTY-NEXT: "line": 186, +// MULTIEMPTY-NEXT: "line": 18, // MULTIEMPTY-NEXT: "character": 3 // MULTIEMPTY-NEXT: }, // MULTIEMPTY-NEXT: "end": { -// MULTIEMPTY-NEXT: "line": 186, +// MULTIEMPTY-NEXT: "line": 18, // MULTIEMPTY-NEXT: "character": 3 // MULTIEMPTY-NEXT: } // MULTIEMPTY-NEXT: }, @@ -158,11 +189,11 @@ public struct Empty {} // MULTIEMPTY-NEXT: { // MULTIEMPTY-NEXT: "range": { // MULTIEMPTY-NEXT: "start": { -// MULTIEMPTY-NEXT: "line": 187, +// MULTIEMPTY-NEXT: "line": 19, // MULTIEMPTY-NEXT: "character": 3 // MULTIEMPTY-NEXT: }, // MULTIEMPTY-NEXT: "end": { -// MULTIEMPTY-NEXT: "line": 187, +// MULTIEMPTY-NEXT: "line": 19, // MULTIEMPTY-NEXT: "character": 3 // MULTIEMPTY-NEXT: } // MULTIEMPTY-NEXT: }, @@ -171,11 +202,11 @@ public struct Empty {} // MULTIEMPTY-NEXT: { // MULTIEMPTY-NEXT: "range": { // MULTIEMPTY-NEXT: "start": { -// MULTIEMPTY-NEXT: "line": 188, +// MULTIEMPTY-NEXT: "line": 20, // MULTIEMPTY-NEXT: "character": 3 // MULTIEMPTY-NEXT: }, // MULTIEMPTY-NEXT: "end": { -// MULTIEMPTY-NEXT: "line": 188, +// MULTIEMPTY-NEXT: "line": 20, // MULTIEMPTY-NEXT: "character": 3 // MULTIEMPTY-NEXT: } // MULTIEMPTY-NEXT: }, @@ -184,22 +215,19 @@ public struct Empty {} // MULTIEMPTY-NEXT: ] // MULTIEMPTY-NEXT: }, -/// -/// -/// -public struct MultiEmpty {} - // LEADINGBLANK-LABEL: "precise": "s:9LineStyle12LeadingBlankV", // LEADINGBLANK: "docComment": { +// LEADINGBLANK-NEXT: "uri": "file://{{.*}}LineStyle.swift", +// LEADINGBLANK-NEXT: "module": "LineStyle", // LEADINGBLANK-NEXT: "lines": [ // LEADINGBLANK-NEXT: { // LEADINGBLANK-NEXT: "range": { // LEADINGBLANK-NEXT: "start": { -// LEADINGBLANK-NEXT: "line": 223, +// LEADINGBLANK-NEXT: "line": 23, // LEADINGBLANK-NEXT: "character": 3 // LEADINGBLANK-NEXT: }, // LEADINGBLANK-NEXT: "end": { -// LEADINGBLANK-NEXT: "line": 223, +// LEADINGBLANK-NEXT: "line": 23, // LEADINGBLANK-NEXT: "character": 3 // LEADINGBLANK-NEXT: } // LEADINGBLANK-NEXT: }, @@ -208,11 +236,11 @@ public struct MultiEmpty {} // LEADINGBLANK-NEXT: { // LEADINGBLANK-NEXT: "range": { // LEADINGBLANK-NEXT: "start": { -// LEADINGBLANK-NEXT: "line": 224, +// LEADINGBLANK-NEXT: "line": 24, // LEADINGBLANK-NEXT: "character": 4 // LEADINGBLANK-NEXT: }, // LEADINGBLANK-NEXT: "end": { -// LEADINGBLANK-NEXT: "line": 224, +// LEADINGBLANK-NEXT: "line": 24, // LEADINGBLANK-NEXT: "character": 17 // LEADINGBLANK-NEXT: } // LEADINGBLANK-NEXT: }, @@ -221,21 +249,19 @@ public struct MultiEmpty {} // LEADINGBLANK-NEXT: ] // LEADINGBLANK-NEXT: } -/// -/// Leading Blank -public struct LeadingBlank {} - // TRAILINGBLANK-LABEL: "precise": "s:9LineStyle13TrailingBlankV" // TRAILINGBLANK: "docComment": { +// TRAILINGBLANK-NEXT: "uri": "file://{{.*}}LineStyle.swift", +// TRAILINGBLANK-NEXT: "module": "LineStyle", // TRAILINGBLANK-NEXT: "lines": [ // TRAILINGBLANK-NEXT: { // TRAILINGBLANK-NEXT: "range": { // TRAILINGBLANK-NEXT: "start": { -// TRAILINGBLANK-NEXT: "line": 259, +// TRAILINGBLANK-NEXT: "line": 27, // TRAILINGBLANK-NEXT: "character": 4 // TRAILINGBLANK-NEXT: }, // TRAILINGBLANK-NEXT: "end": { -// TRAILINGBLANK-NEXT: "line": 259, +// TRAILINGBLANK-NEXT: "line": 27, // TRAILINGBLANK-NEXT: "character": 18 // TRAILINGBLANK-NEXT: } // TRAILINGBLANK-NEXT: }, @@ -244,11 +270,11 @@ public struct LeadingBlank {} // TRAILINGBLANK-NEXT: { // TRAILINGBLANK-NEXT: "range": { // TRAILINGBLANK-NEXT: "start": { -// TRAILINGBLANK-NEXT: "line": 260, +// TRAILINGBLANK-NEXT: "line": 28, // TRAILINGBLANK-NEXT: "character": 3 // TRAILINGBLANK-NEXT: }, // TRAILINGBLANK-NEXT: "end": { -// TRAILINGBLANK-NEXT: "line": 260, +// TRAILINGBLANK-NEXT: "line": 28, // TRAILINGBLANK-NEXT: "character": 3 // TRAILINGBLANK-NEXT: } // TRAILINGBLANK-NEXT: }, @@ -257,21 +283,19 @@ public struct LeadingBlank {} // TRAILINGBLANK-NEXT: ] // TRAILINGBLANK-NEXT: }, -/// Trailing Blank -/// -public struct TrailingBlank {} - // BOUNDBLANK-LABEL: "precise": "s:9LineStyle10BoundBlankV" // BOUNDBLANK: "docComment": { +// BOUNDBLANK-NEXT: "uri": "file://{{.*}}LineStyle.swift", +// BOUNDBLANK-NEXT: "module": "LineStyle", // BOUNDBLANK-NEXT: "lines": [ // BOUNDBLANK-NEXT: { // BOUNDBLANK-NEXT: "range": { // BOUNDBLANK-NEXT: "start": { -// BOUNDBLANK-NEXT: "line": 308, +// BOUNDBLANK-NEXT: "line": 31, // BOUNDBLANK-NEXT: "character": 3 // BOUNDBLANK-NEXT: }, // BOUNDBLANK-NEXT: "end": { -// BOUNDBLANK-NEXT: "line": 308, +// BOUNDBLANK-NEXT: "line": 31, // BOUNDBLANK-NEXT: "character": 3 // BOUNDBLANK-NEXT: } // BOUNDBLANK-NEXT: }, @@ -280,11 +304,11 @@ public struct TrailingBlank {} // BOUNDBLANK-NEXT: { // BOUNDBLANK-NEXT: "range": { // BOUNDBLANK-NEXT: "start": { -// BOUNDBLANK-NEXT: "line": 309, +// BOUNDBLANK-NEXT: "line": 32, // BOUNDBLANK-NEXT: "character": 3 // BOUNDBLANK-NEXT: }, // BOUNDBLANK-NEXT: "end": { -// BOUNDBLANK-NEXT: "line": 309, +// BOUNDBLANK-NEXT: "line": 32, // BOUNDBLANK-NEXT: "character": 15 // BOUNDBLANK-NEXT: } // BOUNDBLANK-NEXT: }, @@ -293,11 +317,11 @@ public struct TrailingBlank {} // BOUNDBLANK-NEXT: { // BOUNDBLANK-NEXT: "range": { // BOUNDBLANK-NEXT: "start": { -// BOUNDBLANK-NEXT: "line": 310, +// BOUNDBLANK-NEXT: "line": 33, // BOUNDBLANK-NEXT: "character": 3 // BOUNDBLANK-NEXT: }, // BOUNDBLANK-NEXT: "end": { -// BOUNDBLANK-NEXT: "line": 310, +// BOUNDBLANK-NEXT: "line": 33, // BOUNDBLANK-NEXT: "character": 3 // BOUNDBLANK-NEXT: } // BOUNDBLANK-NEXT: }, @@ -305,8 +329,3 @@ public struct TrailingBlank {} // BOUNDBLANK-NEXT: } // BOUNDBLANK-NEXT: ] // BOUNDBLANK-NEXT: }, - -/// -/// Bound Blank -/// -public struct BoundBlank {} diff --git a/test/SymbolGraph/Symbols/Mixins/DocComment/SourceModule.swift b/test/SymbolGraph/Symbols/Mixins/DocComment/SourceModule.swift new file mode 100644 index 0000000000000..a0833dc807219 --- /dev/null +++ b/test/SymbolGraph/Symbols/Mixins/DocComment/SourceModule.swift @@ -0,0 +1,96 @@ +// FYI: The lit commands and FileCheck statements are at the bottom of the file, to be resilient +// against changes to the doc comment format. + +public protocol P { + /// same module doc + func something() +} + +public struct NoDocOverride: Hashable, P { + public func hash(into: inout Hasher) {} + public func something() {} +} + +public struct Override: Hashable, P { + /// override of doc from Swift + public func hash(into: inout Hasher) {} + /// override of doc from same module symbol + public func something() {} +} + +// RUN: %empty-directory(%t) +// RUN: %target-build-swift %s -module-name SourceModule -emit-module-path %t/SourceModule.swiftmodule +// RUN: %target-swift-symbolgraph-extract -module-name SourceModule -I %t -pretty-print -output-dir %t +// RUN: %FileCheck %s --input-file %t/SourceModule.symbols.json --check-prefix=NO-OVERRIDE-SAME +// RUN: %FileCheck %s --input-file %t/SourceModule.symbols.json --check-prefix=NO-OVERRIDE-OTHER +// RUN: %FileCheck %s --input-file %t/SourceModule.symbols.json --check-prefix=OVERRIDE-SAME +// RUN: %FileCheck %s --input-file %t/SourceModule.symbols.json --check-prefix=OVERRIDE-OTHER + +// NO-OVERRIDE-SAME-LABEL: "precise": "s:12SourceModule13NoDocOverrideV9somethingyyF" +// NO-OVERRIDE-SAME: "docComment": { +// NO-OVERRIDE-SAME-NEXT: "uri": "file://{{.*}}SourceModule.swift", +// NO-OVERRIDE-SAME-NEXT: "module": "SourceModule", +// NO-OVERRIDE-SAME-NEXT: "lines": [ +// NO-OVERRIDE-SAME-NEXT: { +// NO-OVERRIDE-SAME-NEXT: "range": { +// NO-OVERRIDE-SAME-NEXT: "start": { +// NO-OVERRIDE-SAME-NEXT: "line": 4, +// NO-OVERRIDE-SAME-NEXT: "character": 7 +// NO-OVERRIDE-SAME-NEXT: }, +// NO-OVERRIDE-SAME-NEXT: "end": { +// NO-OVERRIDE-SAME-NEXT: "line": 4, +// NO-OVERRIDE-SAME-NEXT: "character": 22 +// NO-OVERRIDE-SAME-NEXT: } +// NO-OVERRIDE-SAME-NEXT: }, +// NO-OVERRIDE-SAME-NEXT: "text": "same module doc" +// NO-OVERRIDE-SAME-NEXT: } +// NO-OVERRIDE-SAME-NEXT: ] +// NO-OVERRIDE-SAME-NEXT: } + +// NO-OVERRIDE-OTHER-LABEL: "precise": "s:12SourceModule13NoDocOverrideV4hash4intoys6HasherVz_tF" +// NO-OVERRIDE-OTHER: "docComment": { +// NO-OVERRIDE-OTHER-NEXT: "module": "Swift", +// NO-OVERRIDE-OTHER-NEXT: "lines": [ +// actual doc comment lines skipped because they're from the stdlib + +// OVERRIDE-SAME-LABEL: "precise": "s:12SourceModule8OverrideV9somethingyyF", +// OVERRIDE-SAME: "docComment": { +// OVERRIDE-SAME-NEXT: "uri": "file://{{.*}}SourceModule.swift", +// OVERRIDE-SAME-NEXT: "module": "SourceModule", +// OVERRIDE-SAME-NEXT: "lines": [ +// OVERRIDE-SAME-NEXT: { +// OVERRIDE-SAME-NEXT: "range": { +// OVERRIDE-SAME-NEXT: "start": { +// OVERRIDE-SAME-NEXT: "line": 16, +// OVERRIDE-SAME-NEXT: "character": 7 +// OVERRIDE-SAME-NEXT: }, +// OVERRIDE-SAME-NEXT: "end": { +// OVERRIDE-SAME-NEXT: "line": 16, +// OVERRIDE-SAME-NEXT: "character": 46 +// OVERRIDE-SAME-NEXT: } +// OVERRIDE-SAME-NEXT: }, +// OVERRIDE-SAME-NEXT: "text": "override of doc from same module symbol" +// OVERRIDE-SAME-NEXT: } +// OVERRIDE-SAME-NEXT: ] +// OVERRIDE-SAME-NEXT: } + +// OVERRIDE-OTHER-LABEL: "precise": "s:12SourceModule8OverrideV4hash4intoys6HasherVz_tF", +// OVERRIDE-OTHER: "docComment": { +// OVERRIDE-OTHER-NEXT: "uri": "file://{{.*}}SourceModule.swift", +// OVERRIDE-OTHER-NEXT: "module": "SourceModule", +// OVERRIDE-OTHER-NEXT: "lines": [ +// OVERRIDE-OTHER-NEXT: { +// OVERRIDE-OTHER-NEXT: "range": { +// OVERRIDE-OTHER-NEXT: "start": { +// OVERRIDE-OTHER-NEXT: "line": 14, +// OVERRIDE-OTHER-NEXT: "character": 7 +// OVERRIDE-OTHER-NEXT: }, +// OVERRIDE-OTHER-NEXT: "end": { +// OVERRIDE-OTHER-NEXT: "line": 14, +// OVERRIDE-OTHER-NEXT: "character": 33 +// OVERRIDE-OTHER-NEXT: } +// OVERRIDE-OTHER-NEXT: }, +// OVERRIDE-OTHER-NEXT: "text": "override of doc from Swift" +// OVERRIDE-OTHER-NEXT: } +// OVERRIDE-OTHER-NEXT: ] +// OVERRIDE-OTHER-NEXT: }, diff --git a/test/Syntax/Parser/unterminated_multiline_regex.swift b/test/Syntax/Parser/unterminated_multiline_regex.swift new file mode 100644 index 0000000000000..b083f28d64c55 --- /dev/null +++ b/test/Syntax/Parser/unterminated_multiline_regex.swift @@ -0,0 +1,6 @@ +// RUN: %swift-syntax-parser-test -dump-diags %s | %FileCheck %s +// CHECK: 7:1 Error: unterminated regex literal +// CHECK: 1 error(s) 0 warnings(s) 0 note(s) + +#/ +unterminatedLiteral diff --git a/test/Syntax/Parser/unterminated_regex.swift b/test/Syntax/Parser/unterminated_regex.swift new file mode 100644 index 0000000000000..041ac86bc08d8 --- /dev/null +++ b/test/Syntax/Parser/unterminated_regex.swift @@ -0,0 +1,6 @@ +// RUN: %swift-syntax-parser-test -dump-diags %s | %FileCheck %s +// CHECK: 6:21 Error: unterminated regex literal +// CHECK: 1 error(s) 0 warnings(s) 0 note(s) + +// IMPORTANT: This file must not contain a trailing newline +/unterminatedLiteral \ No newline at end of file diff --git a/test/attr/attr_inlinable_available.swift b/test/attr/attr_inlinable_available.swift index fa4fdcd4cbc1d..19250fad6cca9 100644 --- a/test/attr/attr_inlinable_available.swift +++ b/test/attr/attr_inlinable_available.swift @@ -929,120 +929,209 @@ internal struct InternalStruct { // expected-note 2 {{add @available attribute}} // // Extensions are externally visible if they extend a public type and (1) have -// public members or (2) declare a conformance to a public protocol. Externally -// visible extensions should be typechecked with the inlining target. +// public members or (2) declare a conformance to a public protocol. +// +// Extensions without explicit availability that are externally visible use an +// implied floor of either the availability of the extended type or the +// deployment target, whichever is more available. This is a special rule +// designed as a convenience to library authors who have written quite a bit of +// code without annotating availability on their extensions and getting away +// with it because previously the deployment target was always used as the +// floor. +// +// Extensions without explicit availability that are not visible externally are +// checked using an implied floor of the deployment target. // -// OK, NoAvailable is always available, both internally and externally. -extension NoAvailable {} -extension NoAvailable { - public func publicFunc1() {} -} -// OK, no public members and BetweenTargets is always available internally. -extension BetweenTargets {} +// MARK: Extensions on NoAvailable -// OK, no public members and BetweenTargets is always available internally. -extension BetweenTargets { - internal func internalFunc1() {} - private func privateFunc1() {} - fileprivate func fileprivateFunc1() {} -} +extension NoAvailable {} -// expected-warning@+1 {{'BetweenTargets' is only available in macOS 10.14.5 or newer; clients of 'Test' may have a lower deployment target}} expected-note@+1 {{add @available attribute to enclosing extension}} -extension BetweenTargets { - public func publicFunc1() {} +extension NoAvailable { // expected-note {{add @available attribute to enclosing extension}} + func internalFuncInExtension( // expected-note {{add @available attribute to enclosing instance method}} + _: NoAvailable, + _: BeforeInliningTarget, + _: AtInliningTarget, + _: BetweenTargets, + _: AtDeploymentTarget, + _: AfterDeploymentTarget // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} + ) {} } -// expected-warning@+1 {{'BetweenTargets' is only available in macOS 10.14.5 or newer; clients of 'Test' may have a lower deployment target}} expected-note@+1 {{add @available attribute to enclosing extension}} -extension BetweenTargets { - @usableFromInline - internal func usableFromInlineFunc1() {} +extension NoAvailable { // expected-note 3 {{add @available attribute to enclosing extension}} + public func publicFuncInExtension( // expected-note 3 {{add @available attribute to enclosing instance method}} + _: NoAvailable, + _: BeforeInliningTarget, + _: AtInliningTarget, + _: BetweenTargets, // expected-error {{'BetweenTargets' is only available in macOS 10.14.5 or newer; clients of 'Test' may have a lower deployment target}} + _: AtDeploymentTarget, // expected-error {{'AtDeploymentTarget' is only available in macOS 10.15 or newer; clients of 'Test' may have a lower deployment target}} + _: AfterDeploymentTarget // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} + ) {} } -// expected-warning@+1 {{'BetweenTargets' is only available in macOS 10.14.5 or newer; clients of 'Test' may have a lower deployment target}} expected-note@+1 {{add @available attribute to enclosing extension}} -extension BetweenTargets { - internal func internalFunc2() {} - private func privateFunc2() {} - fileprivate func fileprivateFunc2() {} - public func publicFunc2() {} -} +// MARK: Extensions on BetweenTargets -// An extension with more availability than BetweenTargets. -// expected-error@+2 {{'BetweenTargets' is only available in macOS 10.14.5 or newer; clients of 'Test' may have a lower deployment target}} -@available(macOS 10.10, *) -extension BetweenTargets { - public func publicFunc3() {} +extension BetweenTargets {} + +extension BetweenTargets { // expected-note {{add @available attribute to enclosing extension}} + func internalFuncInExtension( // expected-note {{add @available attribute to enclosing instance method}} + _: NoAvailable, + _: BeforeInliningTarget, + _: AtInliningTarget, + _: BetweenTargets, + _: AtDeploymentTarget, + _: AfterDeploymentTarget // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} + ) {} } -// FIXME: Can we prevent this warning when SPI members are the reason the extension is exported? -// expected-warning@+1 {{'BetweenTargets' is only available in macOS 10.14.5 or newer; clients of 'Test' may have a lower deployment target}} expected-note@+1 {{add @available attribute to enclosing extension}} -extension BetweenTargets { - @_spi(Private) - public func spiFunc1() {} +extension BetweenTargets { // expected-note 2 {{add @available attribute to enclosing extension}} + public func publicFuncInExtension( // expected-note 2 {{add @available attribute to enclosing instance method}} + _: NoAvailable, + _: BeforeInliningTarget, + _: AtInliningTarget, + _: BetweenTargets, + _: AtDeploymentTarget, // expected-error {{'AtDeploymentTarget' is only available in macOS 10.15 or newer; clients of 'Test' may have a lower deployment target}} + _: AfterDeploymentTarget // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} + ) {} } -@_spi(Private) +@available(macOS 10.15, *) extension BetweenTargets { - internal func internalFunc3() {} - private func privateFunc3() {} - fileprivate func fileprivateFunc3() {} - public func spiFunc2() {} + public func publicFuncInExtensionWithExplicitAvailability( // expected-note {{add @available attribute to enclosing instance method}} + _: NoAvailable, + _: BeforeInliningTarget, + _: AtInliningTarget, + _: BetweenTargets, + _: AtDeploymentTarget, + _: AfterDeploymentTarget // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} + ) {} } -@available(macOS, unavailable) -extension BetweenTargets { - public func inheritsUnavailable( +extension BetweenTargets { // expected-note {{add @available attribute to enclosing extension}} + @available(macOS 10.15, *) + public func publicFuncWithExplicitAvailabilityInExtension( _: NoAvailable, _: BeforeInliningTarget, _: AtInliningTarget, _: BetweenTargets, _: AtDeploymentTarget, - _: AfterDeploymentTarget, - _: Unavailable - ) { } + _: AfterDeploymentTarget // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} + ) {} } @_spi(Private) -extension BetweenTargets { // expected-note 1 {{add @available attribute to enclosing extension}} - public func inheritsSPINoAvailable( // expected-note 1 {{add @available attribute to enclosing instance method}} +extension BetweenTargets { // expected-note {{add @available attribute to enclosing extension}} + public func inheritedSPIFuncInExtension( // expected-note {{add @available attribute to enclosing instance method}} _: NoAvailable, _: BeforeInliningTarget, _: AtInliningTarget, _: BetweenTargets, _: AtDeploymentTarget, _: AfterDeploymentTarget // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} - ) { } + ) {} } +@available(macOS, unavailable) +extension BetweenTargets { + public func inheritsUnavailableFuncInExtension( + _: NoAvailable, + _: BeforeInliningTarget, + _: AtInliningTarget, + _: BetweenTargets, + _: AtDeploymentTarget, + _: AfterDeploymentTarget, + _: Unavailable + ) {} +} + +// This extension is explicitly more available than BetweenTargets but because +// it only contains internal members, the availability floor is still the +// deployment target. +@available(macOS 10.10, *) +extension BetweenTargets { + func internalFuncInExcessivelyAvailableExtension() {} +} + +extension BetweenTargets { + @available(macOS 10.10, *) + func excessivelyAvailableInternalFuncInExtension() {} +} + +@available(macOS 10.10, *) +extension BetweenTargets { // expected-error {{'BetweenTargets' is only available in macOS 10.14.5 or newer; clients of 'Test' may have a lower deployment target}} + public func publicFuncInExcessivelyAvailableExtension() {} +} + +// MARK: Extensions on BetweenTargetsInternal + // Same availability as BetweenTargets but internal instead of public. @available(macOS 10.14.5, *) internal struct BetweenTargetsInternal {} -// OK, extensions on internal types are never visible externally. extension BetweenTargetsInternal {} -extension BetweenTargetsInternal { - public func publicFunc() {} + +extension BetweenTargetsInternal { // expected-note {{add @available attribute to enclosing extension}} + func internalFuncInExtension( // expected-note {{add @available attribute to enclosing instance method}} + _: NoAvailable, + _: BeforeInliningTarget, + _: AtInliningTarget, + _: BetweenTargets, + _: AtDeploymentTarget, + _: AfterDeploymentTarget // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} + ) {} } -// expected-warning@+1 {{'AtDeploymentTarget' is only available in macOS 10.15 or newer; clients of 'Test' may have a lower deployment target}} expected-note@+1 {{add @available attribute to enclosing extension}} -extension AtDeploymentTarget { - public func publicFunc() {} +extension BetweenTargetsInternal { // expected-note {{add @available attribute to enclosing extension}} + public func publicFuncInExtension( // expected-note {{add @available attribute to enclosing instance method}} + _: NoAvailable, + _: BeforeInliningTarget, + _: AtInliningTarget, + _: BetweenTargets, + _: AtDeploymentTarget, + _: AfterDeploymentTarget // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} + ) {} } +// MARK: Extensions on AfterDeploymentTarget + // expected-error@+1 {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} expected-note@+1 {{add @available attribute to enclosing extension}} extension AfterDeploymentTarget {} -// expected-error@+1 {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} expected-note@+1 {{add @available attribute to enclosing extension}} -extension AfterDeploymentTarget { - internal func internalFunc1() {} - private func privateFunc1() {} - fileprivate func fileprivateFunc1() {} +// expected-error@+1 {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} +extension AfterDeploymentTarget { // expected-note 2 {{add @available attribute to enclosing extension}} + func internalFuncInExtension( // expected-note {{add @available attribute to enclosing instance method}} + _: NoAvailable, + _: BeforeInliningTarget, + _: AtInliningTarget, + _: BetweenTargets, + _: AtDeploymentTarget, + _: AfterDeploymentTarget // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} + ) {} } -// expected-error@+1 {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} expected-note@+1 {{add @available attribute to enclosing extension}} +// expected-error@+1 {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} +extension AfterDeploymentTarget { // expected-note 2 {{add @available attribute to enclosing extension}} + public func publicFuncInExtension( // expected-note {{add @available attribute to enclosing instance method}} + _: NoAvailable, + _: BeforeInliningTarget, + _: AtInliningTarget, + _: BetweenTargets, + _: AtDeploymentTarget, + _: AfterDeploymentTarget // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} + ) {} +} + +@available(macOS 11, *) extension AfterDeploymentTarget { - public func publicFunc1() {} + public func publicFuncInExtensionWithExplicitAvailability( + _: NoAvailable, + _: BeforeInliningTarget, + _: AtInliningTarget, + _: BetweenTargets, + _: AtDeploymentTarget, + _: AfterDeploymentTarget + ) {} } @@ -1062,8 +1151,8 @@ public protocol PublicProto {} extension NoAvailable: PublicProto {} extension BeforeInliningTarget: PublicProto {} extension AtInliningTarget: PublicProto {} -extension BetweenTargets: PublicProto {} // expected-warning {{'BetweenTargets' is only available in macOS 10.14.5 or newer; clients of 'Test' may have a lower deployment target}} expected-note {{add @available attribute to enclosing extension}} -extension AtDeploymentTarget: PublicProto {} // expected-warning {{'AtDeploymentTarget' is only available in macOS 10.15 or newer; clients of 'Test' may have a lower deployment target}} expected-note {{add @available attribute to enclosing extension}} +extension BetweenTargets: PublicProto {} +extension AtDeploymentTarget: PublicProto {} extension AfterDeploymentTarget: PublicProto {} // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} expected-note {{add @available attribute to enclosing extension}} @@ -1201,6 +1290,11 @@ public enum NoAvailableEnumWithClasses { public class InheritsBetweenTargets: BetweenTargetsClass {} // expected-error {{'BetweenTargetsClass' is only available in macOS 10.14.5 or newer; clients of 'Test' may have a lower deployment target}} expected-note 2 {{add @available attribute to enclosing class}} public class InheritsAtDeploymentTarget: AtDeploymentTargetClass {} // expected-error {{'AtDeploymentTargetClass' is only available in macOS 10.15 or newer; clients of 'Test' may have a lower deployment target}} expected-note 2 {{add @available attribute to enclosing class}} public class InheritsAfterDeploymentTarget: AfterDeploymentTargetClass {} // expected-error {{'AfterDeploymentTargetClass' is only available in macOS 11 or newer}} expected-note 2 {{add @available attribute to enclosing class}} + + // As a special case, downgrade the less available superclasses diagnostic for + // `@usableFromInline` classes. + @usableFromInline + class UFIInheritsBetweenTargets: BetweenTargetsClass {} // expected-warning {{'BetweenTargetsClass' is only available in macOS 10.14.5 or newer; clients of 'Test' may have a lower deployment target}} expected-note 2 {{add @available attribute to enclosing class}} } @_spi(Private) diff --git a/test/decl/result_builder_fixits.swift b/test/decl/result_builder_fixits.swift index 9c49ff29d6d3d..2a1584e4c3d57 100644 --- a/test/decl/result_builder_fixits.swift +++ b/test/decl/result_builder_fixits.swift @@ -1,5 +1,5 @@ // RUN: %target-typecheck-verify-swift -disable-availability-checking -// UNSUPPORTED: windows +// UNSUPPORTED: OS=windows-msvc // Line-feeds in Fix-Its fail to check on Windows. @resultBuilder diff --git a/test/expr/closure/multi_statement.swift b/test/expr/closure/multi_statement.swift index 1b9f25761c68e..90bf7b58bce65 100644 --- a/test/expr/closure/multi_statement.swift +++ b/test/expr/closure/multi_statement.swift @@ -404,3 +404,23 @@ func test_type_finder_doesnt_walk_into_inner_closures() { return x } } + +// rdar://93796211 (issue#59035) - crash during solution application to fallthrough statement +func test_fallthrough_stmt() { + { + var collector: [Void] = [] + for _: Void in [] { + switch (() as Void?, ()) { + case (let a?, let b): + // expected-warning@-1 {{constant 'b' inferred to have type '()', which may be unexpected}} + // expected-note@-2 {{add an explicit type annotation to silence this warning}} + collector.append(a) + fallthrough + case (nil, let b): + // expected-warning@-1 {{constant 'b' inferred to have type '()', which may be unexpected}} + // expected-note@-2 {{add an explicit type annotation to silence this warning}} + collector.append(b) + } + } + }() +} diff --git a/test/multifile/protocol-conformance-redundant.swift b/test/multifile/protocol-conformance-redundant.swift index 05f87440cde59..f27a8a346b5d6 100644 --- a/test/multifile/protocol-conformance-redundant.swift +++ b/test/multifile/protocol-conformance-redundant.swift @@ -6,7 +6,7 @@ // RUN: %target-run %t/main %t/%target-library-name(Def) %t/%target-library-name(Ext) 2>&1 | %FileCheck %s // REQUIRES: executable_test -// XFAIL: windows +// XFAIL: OS=windows-msvc // CHECK: Warning: 'main.Sub' conforms to protocol 'Hello', but it also inherits conformance from 'Def.Super'. Relying on a particular conformance is undefined behaviour. // CHECK: Hello diff --git a/test/stdlib/simd_diagnostics.swift b/test/stdlib/simd_diagnostics.swift index 44fa7da18625e..03f7ce260f214 100644 --- a/test/stdlib/simd_diagnostics.swift +++ b/test/stdlib/simd_diagnostics.swift @@ -1,7 +1,7 @@ // RUN: %target-typecheck-verify-swift // FIXME: No simd module on linux rdar://problem/20795411 -// XFAIL: linux, windows, openbsd +// XFAIL: OS=linux-gnu, OS=windows-msvc, OS=openbsd // XFAIL: OS=wasi import simd diff --git a/test/type/explicit_existential.swift b/test/type/explicit_existential.swift index 45dd419ce07b0..0d66d986d0870 100644 --- a/test/type/explicit_existential.swift +++ b/test/type/explicit_existential.swift @@ -156,15 +156,17 @@ func anyAny() { protocol P1 {} protocol P2 {} +protocol P3 {} do { // Test that we don't accidentally misparse an 'any' type as a 'some' type // and vice versa. - let _: P1 & any P2 // expected-error {{'any' should appear at the beginning of a composition}} - let _: any P1 & any P2 // expected-error {{'any' should appear at the beginning of a composition}} - let _: any P1 & some P2 // expected-error {{'some' should appear at the beginning of a composition}} + let _: P1 & any P2 // expected-error {{'any' should appear at the beginning of a composition}} {{15-19=}} {{10-10=any }} + let _: any P1 & any P2 // expected-error {{'any' should appear at the beginning of a composition}} {{19-23=}} + let _: any P1 & P2 & any P3 // expected-error {{'any' should appear at the beginning of a composition}} {{24-28=}} + let _: any P1 & some P2 // expected-error {{'some' should appear at the beginning of a composition}} {{19-24=}} let _: some P1 & any P2 // expected-error@-1 {{'some' type can only be declared on a single property declaration}} - // expected-error@-2 {{'any' should appear at the beginning of a composition}} + // expected-error@-2 {{'any' should appear at the beginning of a composition}} {{20-24=}} } struct ConcreteComposition: P1, P2 {} diff --git a/test/type/opaque.swift b/test/type/opaque.swift index b07882b922bd0..dc4fe826214ab 100644 --- a/test/type/opaque.swift +++ b/test/type/opaque.swift @@ -488,8 +488,11 @@ func foo_repl(_ s: S) -> some Proto { protocol SomeProtocolA {} protocol SomeProtocolB {} -struct SomeStructC: SomeProtocolA, SomeProtocolB {} +protocol SomeProtocolC {} +struct SomeStructC: SomeProtocolA, SomeProtocolB, SomeProtocolC {} let someProperty: SomeProtocolA & some SomeProtocolB = SomeStructC() // expected-error {{'some' should appear at the beginning of a composition}}{{35-40=}}{{19-19=some }} +let someOtherProperty: some SomeProtocolA & some SomeProtocolB = SomeStructC() // expected-error {{'some' should appear at the beginning of a composition}}{{45-50=}} +let someThirdProperty: some SomeProtocolA & SomeProtocolB & some SomeProtocolC = SomeStructC() // expected-error {{'some' should appear at the beginning of a composition}}{{61-66=}} // An opaque result type on a protocol extension member effectively // contains an invariant reference to 'Self', and therefore cannot diff --git a/test/type/opaque_parameterized_existential.swift b/test/type/opaque_parameterized_existential.swift index 6714cc5dce09d..ced21b9029ac3 100644 --- a/test/type/opaque_parameterized_existential.swift +++ b/test/type/opaque_parameterized_existential.swift @@ -1,4 +1,4 @@ -// RUN: %target-swift-frontend -enable-parameterized-existential-types -disable-availability-checking -typecheck -verify %s +// RUN: %target-swift-frontend -disable-availability-checking -typecheck -verify %s // I do not like nested some type params, // I do not like them Σam-i-am diff --git a/test/type/parameterized_existential.swift b/test/type/parameterized_existential.swift index 345774b31f5d2..51152068060d4 100644 --- a/test/type/parameterized_existential.swift +++ b/test/type/parameterized_existential.swift @@ -1,4 +1,4 @@ -// RUN: %target-typecheck-verify-swift -disable-availability-checking -enable-parameterized-existential-types +// RUN: %target-typecheck-verify-swift -disable-availability-checking protocol Sequence { associatedtype Element diff --git a/test/type/parameterized_protocol.swift b/test/type/parameterized_protocol.swift index 24e39ce8398fa..947ce3cd697c6 100644 --- a/test/type/parameterized_protocol.swift +++ b/test/type/parameterized_protocol.swift @@ -29,7 +29,7 @@ protocol Invalid5 { /// Test semantics -protocol Sequence { +protocol Sequence { // expected-note {{'Sequence' declared here}} associatedtype Element // expected-note@-1 {{protocol requires nested type 'Element'; do you want to add it?}} } @@ -189,17 +189,17 @@ func returnsSequenceOfInt1() -> Sequence {} // expected-error@-1 {{protocol type with type arguments can only be used as a generic constraint}} func takesSequenceOfInt2(_: any Sequence) {} -// expected-error@-1 {{protocol type with type arguments can only be used as a generic constraint}} func returnsSequenceOfInt2() -> any Sequence {} -// expected-error@-1 {{protocol type with type arguments can only be used as a generic constraint}} func typeExpr() { _ = Sequence.self // expected-error@-1 {{protocol type with type arguments can only be used as a generic constraint}} _ = any Sequence.self - // expected-error@-1 {{protocol type with type arguments can only be used as a generic constraint}} + // expected-error@-1 {{'self' is not a member type of protocol 'parameterized_protocol.Sequence'}} + + _ = (any Sequence).self } /// Not supported as a protocol composition term for now diff --git a/unittests/Parse/BuildConfigTests.cpp b/unittests/Parse/BuildConfigTests.cpp index 639e6527e9899..db526296e9d0f 100644 --- a/unittests/Parse/BuildConfigTests.cpp +++ b/unittests/Parse/BuildConfigTests.cpp @@ -8,6 +8,7 @@ using namespace llvm; class CompilerVersionTest : public ::testing::Test {}; class VersionTest : public ::testing::Test{}; +class CompilerVersionUnpackingTest : public ::testing::Test {}; Optional CV(const char *VersionString) { return version::Version::parseCompilerVersionString(VersionString, @@ -52,3 +53,31 @@ TEST_F(VersionTest, VersionComparison) { EXPECT_FALSE(V(".1").hasValue()); } + +TEST_F(CompilerVersionUnpackingTest, VersionComparison) { + EXPECT_EQ(CV("700").getValue(), V("0.700").getValue()); + EXPECT_EQ(CV("700.*").getValue(), V("0.700").getValue()); + EXPECT_EQ(CV("700.*.1").getValue(), V("0.700.1").getValue()); + EXPECT_EQ(CV("700.*.23").getValue(), V("0.700.23").getValue()); + EXPECT_EQ(CV("700.*.1.1").getValue(), V("0.700.1.1").getValue()); + + EXPECT_EQ(CV("1300").getValue(), V("1.300").getValue()); + EXPECT_EQ(CV("1300.*").getValue(), V("1.300").getValue()); + EXPECT_EQ(CV("1300.*.1").getValue(), V("1.300.1").getValue()); + EXPECT_EQ(CV("1300.*.23").getValue(), V("1.300.23").getValue()); + EXPECT_EQ(CV("1300.*.1.1").getValue(), V("1.300.1.1").getValue()); + + EXPECT_EQ(CV("5007").getValue(), V("5.7").getValue()); + EXPECT_EQ(CV("5007.*").getValue(), V("5.7").getValue()); + EXPECT_EQ(CV("5007.*.1").getValue(), V("5.7.1").getValue()); + EXPECT_EQ(CV("5007.*.23").getValue(), V("5.7.23").getValue()); + EXPECT_EQ(CV("5007.*.1.1").getValue(), V("5.7.1.1").getValue()); + + // Since this test was added during 5.7, we expect all of these comparisons to + // be GE, either because we are comparing to the empty version or because we + // are comparing to a version >= 5.7.0.0.0. + auto currentVersion = version::Version::getCurrentCompilerVersion(); + EXPECT_GE(CV("700"), currentVersion); + EXPECT_GE(CV("1300"), currentVersion); + EXPECT_GE(CV("5007"), currentVersion); +} diff --git a/utils/build-script-impl b/utils/build-script-impl index 7a0400531fd6b..fde67d8ddd74f 100755 --- a/utils/build-script-impl +++ b/utils/build-script-impl @@ -1847,21 +1847,9 @@ for host in "${ALL_HOSTS[@]}"; do llvm_enable_projects+=("clang-tools-extra") fi - # On non-Darwin platforms, build lld so we can always have a - # linker that is compatible with the swift we are using to - # compile the stdlib. - # - # This makes it easier to build target stdlibs on systems that - # have old toolchains without more modern linker features. - - # wasm: lld should be built when cross building for wasm - # After enabling stdlib cross compile, add if statement - # to build only when cross compiling for wasm - # if [[ "$(uname -s)" != "Darwin" ]] ; then - if [[ ! "${SKIP_BUILD_LLD}" ]]; then - llvm_enable_projects+=("lld") - fi - # fi + if [[ ! "${SKIP_BUILD_LLD}" ]]; then + llvm_enable_projects+=("lld") + fi cmake_options+=( -DLLVM_ENABLE_PROJECTS="$(join ";" ${llvm_enable_projects[@]})" diff --git a/utils/build-windows-toolchain.bat b/utils/build-windows-toolchain.bat index 09d239499b5a0..0dad9819aa645 100644 --- a/utils/build-windows-toolchain.bat +++ b/utils/build-windows-toolchain.bat @@ -45,13 +45,29 @@ call :CloneRepositories || (exit /b) md "%BuildRoot%\Library" -:: TODO(compnerd) build ICU from source -curl.exe -sOL "https://github.com/unicode-org/icu/releases/download/release-67-1/icu4c-67_1-Win64-MSVC2017.zip" || (exit /b) -"%SystemDrive%\Program Files\Git\usr\bin\unzip.exe" -o icu4c-67_1-Win64-MSVC2017.zip -d %BuildRoot%\Library\icu-67.1 -md %BuildRoot%\Library\icu-67.1\usr\bin -copy %BuildRoot%\Library\icu-67.1\bin64\icudt67.dll %BuildRoot%\Library\icu-67.1\usr\bin || (exit /b) -copy %BuildRoot%\Library\icu-67.1\bin64\icuin67.dll %BuildRoot%\Library\icu-67.1\usr\bin || (exit /b) -copy %BuildRoot%\Library\icu-67.1\bin64\icuuc67.dll %BuildRoot%\Library\icu-67.1\usr\bin || (exit /b) +:: Build ICU +copy %SourceRoot%\swift-installer-scripts\shared\ICU\CMakeLists.txt %SourceRoot%\icu\icu4c\ || (exit /b) +cmake ^ + -B %BuildRoot%\icu ^ + + -D BUILD_SHARED_LIBS=NO ^ + -D CMAKE_BUILD_TYPE=%CMAKE_BUILD_TYPE% ^ + -D CMAKE_C_COMPILER=cl ^ + -D CMAKE_C_FLAGS="/GS- /Oy /Gw /Gy" ^ + -D CMAKE_CXX_COMPILER=cl ^ + -D CMAKE_CXX_FLAGS="/GS- /Oy /Gw /Gy" ^ + -D CMAKE_MT=mt ^ + -D CMAKE_EXE_LINKER_FLAGS="/INCREMENTAL:NO" ^ + -D CMAKE_SHARED_LINKER_FLAGS="/INCREMENTAL:NO" ^ + + -D CMAKE_INSTALL_PREFIX=%BuildRoot%\Library\icu-69.1\usr ^ + + -D BUILD_TOOLS=YES ^ + + -G Ninja ^ + -S %SourceRoot%\icu\icu4c || (exit /b) +cmake --build "%BuildRoot%\icu" || (exit /b) +cmake --build "%BuildRoot%\icu" --target install || (exit /b) :: FIXME(compnerd) is there a way to build the sources without downloading the amalgamation? curl.exe -sOL "https://sqlite.org/2021/sqlite-amalgamation-3360000.zip" || (exit /b) @@ -280,9 +296,10 @@ cmake ^ -D CMAKE_INSTALL_PREFIX=%SDKInstallRoot%\usr ^ -D CURL_DIR=%BuildRoot%\Library\curl-7.77.0\usr\lib\cmake\CURL ^ - -D ICU_ROOT=%BuildRoot%\Library\icu-67.1 ^ - -D ICU_UC_LIBRARY=%BuildRoot%\Library\icu-67.1\lib64\icuuc67.lib ^ - -D ICU_I18N_LIBRARY=%BuildRoot%\Library\icu-67.1\lib64\icuin67.lib ^ + -D ICU_ROOT=%BuildRoot%\Library\icu-69.1\usr ^ + -D ICU_DATA_LIBRARY_RELEASE=%BuildRoot%\Library\icu-69.1\usr\lib\sicudt69.lib ^ + -D ICU_UC_LIBRARY_RELEASE=%BuildRoot%\Library\icu-69.1\usr\lib\sicuuc69.lib ^ + -D ICU_I18N_LIBRARY_RELEASE=%BuildRoot%\Library\icu-69.1\usr\lib\sicuin69.lib ^ -D LIBXML2_LIBRARY=%BuildRoot%\Library\libxml2-2.9.12\usr\lib\libxml2s.lib ^ -D LIBXML2_INCLUDE_DIR=%BuildRoot%\Library\libxml2-2.9.12\usr\include\libxml2 ^ -D LIBXML2_DEFINITIONS="/DLIBXML_STATIC" ^ @@ -655,17 +672,6 @@ msbuild %SourceRoot%\swift-installer-scripts\platforms\Windows\runtime.wixproj ^ :: TODO(compnerd) actually perform the code-signing :: signtool sign /f Apple_CodeSign.pfx /p Apple_CodeSign_Password /tr http://timestamp.digicert.com /fd sha256 %PackageRoot%\runtime\runtime.msi -:: Package icu.msi -msbuild %SourceRoot%\swift-installer-scripts\platforms\Windows\icu.wixproj ^ - -p:RunWixToolsOutOfProc=true ^ - -p:OutputPath=%PackageRoot%\icu\ ^ - -p:IntermediateOutputPath=%PackageRoot%\icu\ ^ - -p:ProductVersion=67.1 ^ - -p:ProductVersionMajor=67 ^ - -p:ICU_ROOT=%BuildRoot% -:: TODO(compnerd) actually perform the code-signing -:: signtool sign /f Apple_CodeSign.pfx /p Apple_CodeSign_Password /tr http://timestamp.digicert.com /fd sha256 %PackageRoot%\icu\icu.msi - :: Package devtools.msi msbuild %SourceRoot%\swift-installer-scripts\platforms\Windows\devtools.wixproj ^ -p:RunWixToolsOutOfProc=true ^ @@ -679,7 +685,6 @@ msbuild %SourceRoot%\swift-installer-scripts\platforms\Windows\devtools.wixproj move %PackageRoot%\toolchain\toolchain.msi %PackageRoot% || (exit /b) move %PackageRoot%\sdk\sdk.msi %PackageRoot% || (exit /b) move %PackageRoot%\runtime\runtime.msi %PackageRoot% || (exit /b) -move %PackageRoot%\icu\icu.msi %PackageRoot% || (exit /b) move %PackageRoot%\devtools\devtools.msi %PackageRoot% || (exit /b) :: Build Installer @@ -693,8 +698,6 @@ msbuild %SourceRoot%\swift-installer-scripts\platforms\Windows\installer.wixproj :: Stage Artifacts md %BuildRoot%\artifacts -:: ICU Dependency for runtime libraries -move %PackageRoot%\icu.msi %BuildRoot%\artifacts || (exit /b) :: Redistributable libraries for developers move %PackageRoot%\runtime.msi %BuildRoot%\artifacts || (exit /b) :: Toolchain @@ -706,17 +709,99 @@ move %PackageRoot%\installer\installer.exe %BuildRoot%\artifacts || (exit /b) :: TODO(compnerd) test LLVM +SET SKIP_TEST=0 +FOR %%T IN (%SKIP_TESTS%) DO (IF /I %%T==swift SET SKIP_TEST=1) +IF "%SKIP_TEST%"=="0" call :TestSwift + +SET SKIP_TEST=0 +FOR %%T IN (%SKIP_TESTS%) DO (IF /I %T==dispatch SET SKIP_TEST=1) +IF "%SKIP_TEST%"=="0" call :TestDispatch + +SET SKIP_TEST=0 +FOR %%T IN (%SKIP_TESTS%) DO (IF /I %T==foundation SET SKIP_TEST=1) +IF "%SKIP_TEST%"=="0" call :TestFoundation + +SET SKIP_TEST=0 +FOR %%T IN (%SKIP_TESTS%) DO (IF /I %T==xctest SET SKIP_TEST=1) +IF "%SKIP_TEST%"=="0" call :TestXCTest + +:: Clean up the module cache +rd /s /q %LocalAppData%\clang\ModuleCache + +goto :end +endlocal + +:CloneRepositories +setlocal enableextensions enabledelayedexpansion + +if defined SKIP_UPDATE_CHECKOUT goto :eof + +if defined REPO_SCHEME set "args=--scheme %REPO_SCHEME%" + +:: Always enable symbolic links +git config --global core.symlink true + +:: Ensure that we have the files in the original line endings, the swift tests +:: depend on this being the case. +git -C "%SourceRoot%\swift" config --local core.autocrlf input +git -C "%SourceRoot%\swift" checkout-index --force --all + +set "args=%args% --skip-repository swift" +set "args=%args% --skip-repository ninja" +set "args=%args% --skip-repository icu" +set "args=%args% --skip-repository swift-integration-tests" +set "args=%args% --skip-repository swift-stress-tester" +set "args=%args% --skip-repository swift-xcode-playground-support" + +call "%SourceRoot%\swift\utils\update-checkout.cmd" %args% --clone --skip-history --github-comment "%ghprbCommentBody%" + +goto :eof +endlocal + +:CloneDependencies +setlocal enableextensions enabledelayedexpansion + +:: Always enable symbolic links +git config --global core.symlink true + +:: FIXME(compnerd) avoid the fresh clone +rd /s /q zlib libxml2 sqlite icu curl + +git clone --quiet --no-tags --depth 1 --branch v1.2.11 https://github.com/madler/zlib +git clone --quiet --no-tags --depth 1 --branch v2.9.12 https://github.com/gnome/libxml2 +git clone --quiet --no-tags --depth 1 --branch version-3.36.0 https://github.com/sqlite/sqlite +git clone --quiet --no-tags --depth 1 --branch maint/maint-69 https://github.com/unicode-org/icu +git clone --quiet --no-tags --depth 1 --branch curl-7_77_0 https://github.com/curl/curl + +goto :eof +endlocal + +:TestSwift +setlocal enableextensions enabledelayedexpansion + :: Test Swift :: TODO(compnerd) make lit adjust the path properly -path %BuildRoot%\3;%BuildRoot%\1\bin;%BuildRoot%\Library\icu-67.1\usr\bin;%PATH%;%SystemDrive%\Program Files\Git\usr\bin +path %BuildRoot%\3;%BuildRoot%\1\bin;%PATH%;%SystemDrive%\Program Files\Git\usr\bin cmake --build %BuildRoot%\1 --target check-swift || (exit /b) +goto :eof +endlocal + +:TestDispatch +setlocal enableextensions enabledelayedexpansion + :: Test dispatch cmake --build %BuildRoot%\3 --target ExperimentalTest || (exit /b) +goto :eof +endlocal + +:TestFoundation +setlocal enableextensions enabledelayedexpansion + :: NOTE(compnerd) update the path *before* the build because the tests are :: executed to shard the test suite. -path %BuildRoot%\5;%BuildRoot%\4\bin;%PATH% +path %BuildRoot%\5;%BuildRoot%\4\bin;%BuildRoot%\3;%BuildRoot%\1\bin;%PATH%;%SystemDrive%\Program Files\Git\usr\bin :: Rebuild Foundation (w/ testing) cmake ^ @@ -735,9 +820,10 @@ cmake ^ -D CMAKE_INSTALL_PREFIX=%SDKInstallRoot%\usr ^ -D CURL_DIR=%BuildRoot%\Library\curl-7.77.0\usr\lib\cmake\CURL ^ - -D ICU_ROOT=%BuildRoot%\Library\icu-67.1 ^ - -D ICU_UC_LIBRARY=%BuildRoot%\Library\icu-67.1\lib64\icuuc67.lib ^ - -D ICU_I18N_LIBRARY=%BuildRoot%\Library\icu-67.1\lib64\icuin67.lib ^ + -D ICU_ROOT=%BuildRoot%\Library\icu-69.1\usr ^ + -D ICU_DATA_LIBRARY_RELEASE=%BuildRoot%\Library\icu-69.1\usr\lib\sicudt69.lib ^ + -D ICU_I18N_LIBRARY_RELEASE=%BuildRoot%\Library\icu-69.1\usr\lib\sicuin69.lib ^ + -D ICU_UC_LIBRARY_RELEASE=%BuildRoot%\Library\icu-69.1\usr\lib\sicuuc69.lib ^ -D LIBXML2_LIBRARY=%BuildRoot%\Library\libxml2-2.9.12\usr\lib\libxml2s.lib ^ -D LIBXML2_INCLUDE_DIR=%BuildRoot%\Library\libxml2-2.9.12\usr\include\libxml2 ^ -D LIBXML2_DEFINITIONS="/DLIBXML_STATIC" ^ @@ -756,6 +842,16 @@ cmake --build %BuildRoot%\4 || (exit /b) set CTEST_OUTPUT_ON_FAILURE=1 cmake --build %BuildRoot%\4 --target test || (exit /b) +goto :eof +endlocal + +:TestXCTest +setlocal enableextensions enabledelayedexpansion + +:: NOTE(compnerd) update the path *before* the build because the tests are +:: executed to shard the test suite. +path %BuildRoot%\5;%BuildRoot%\4\bin;%BuildRoot%\3;%BuildRoot%\1\bin;%PATH%;%SystemDrive%\Program Files\Git\usr\bin + :: Rebuild XCTest (w/ testing) cmake ^ -B %BuildRoot%\5 ^ @@ -787,54 +883,6 @@ cmake --build %BuildRoot%\5 || (exit /b) :: Test XCTest cmake --build %BuildRoot%\5 --target check-xctest || (exit /b) -:: Clean up the module cache -rd /s /q %LocalAppData%\clang\ModuleCache - -goto :end -endlocal - -:CloneRepositories -setlocal enableextensions enabledelayedexpansion - -if defined SKIP_UPDATE_CHECKOUT goto :eof - -if defined REPO_SCHEME set "args=--scheme %REPO_SCHEME%" - -:: Always enable symbolic links -git config --global core.symlink true - -:: Ensure that we have the files in the original line endings, the swift tests -:: depend on this being the case. -git -C "%SourceRoot%\swift" config --local core.autocrlf input -git -C "%SourceRoot%\swift" checkout-index --force --all - -set "args=%args% --skip-repository swift" -set "args=%args% --skip-repository ninja" -set "args=%args% --skip-repository icu" -set "args=%args% --skip-repository swift-integration-tests" -set "args=%args% --skip-repository swift-stress-tester" -set "args=%args% --skip-repository swift-xcode-playground-support" - -call "%SourceRoot%\swift\utils\update-checkout.cmd" %args% --clone --skip-history --github-comment "%ghprbCommentBody%" - -goto :eof -endlocal - -:CloneDependencies -setlocal enableextensions enabledelayedexpansion - -:: Always enable symbolic links -git config --global core.symlink true - -:: FIXME(compnerd) avoid the fresh clone -rd /s /q zlib libxml2 sqlite icu curl - -git clone --quiet --no-tags --depth 1 --branch v1.2.11 https://github.com/madler/zlib -git clone --quiet --no-tags --depth 1 --branch v2.9.12 https://github.com/gnome/libxml2 -git clone --quiet --no-tags --depth 1 --branch version-3.36.0 https://github.com/sqlite/sqlite -git clone --quiet --no-tags --depth 1 --branch maint/maint-67 https://github.com/unicode-org/icu -git clone --quiet --no-tags --depth 1 --branch curl-7_77_0 https://github.com/curl/curl - goto :eof endlocal diff --git a/utils/build_swift/build_swift/driver_arguments.py b/utils/build_swift/build_swift/driver_arguments.py index 114352c9586c1..ed6fbb9812024 100644 --- a/utils/build_swift/build_swift/driver_arguments.py +++ b/utils/build_swift/build_swift/driver_arguments.py @@ -736,6 +736,9 @@ def create_argument_parser(): option(['--build-libparser-only'], toggle_true('build_libparser_only'), help='build only libParser for SwiftSyntax') + option(['--build-lld'], toggle_true('build_lld'), + help='build lld as part of llvm') + option('--skip-build-clang-tools-extra', toggle_false('build_clang_tools_extra'), default=True, diff --git a/utils/build_swift/tests/expected_options.py b/utils/build_swift/tests/expected_options.py index f49df29d34898..376bc07d8ef92 100644 --- a/utils/build_swift/tests/expected_options.py +++ b/utils/build_swift/tests/expected_options.py @@ -72,6 +72,7 @@ 'build_lldb': False, 'build_libcxx': False, 'build_ninja': False, + 'build_lld': False, 'build_osx': True, 'build_playgroundsupport': False, 'build_runtime_with_host_compiler': False, @@ -538,6 +539,7 @@ class BuildScriptImplOption(_BaseOption): EnableOption('--android'), EnableOption('--build-external-benchmarks'), EnableOption('--build-ninja'), + EnableOption('--build-lld'), EnableOption('--build-runtime-with-host-compiler'), EnableOption('--build-swift-dynamic-sdk-overlay'), EnableOption('--build-swift-dynamic-stdlib'), diff --git a/utils/swift_build_support/swift_build_support/build_script_invocation.py b/utils/swift_build_support/swift_build_support/build_script_invocation.py index a59b2ab8f69b9..58bfaecc043d5 100644 --- a/utils/swift_build_support/swift_build_support/build_script_invocation.py +++ b/utils/swift_build_support/swift_build_support/build_script_invocation.py @@ -430,6 +430,20 @@ def convert_to_impl_arguments(self): "--llvm-install-components=%s" % args.llvm_install_components ] + # On non-Darwin platforms, build lld so we can always have a + # linker that is compatible with the swift we are using to + # compile the stdlib. + # + # This makes it easier to build target stdlibs on systems that + # have old toolchains without more modern linker features. + # + # On Darwin, only build lld if explicitly requested using --build-lld. + should_build_lld = (platform.system() != 'Darwin' or args.build_lld) + if not should_build_lld: + impl_args += [ + "--skip-build-lld" + ] + if not args.clean_libdispatch: impl_args += [ "--skip-clean-libdispatch" diff --git a/utils/swift_build_support/swift_build_support/products/indexstoredb.py b/utils/swift_build_support/swift_build_support/products/indexstoredb.py index af187e9e612ce..cd6fedcbb0334 100644 --- a/utils/swift_build_support/swift_build_support/products/indexstoredb.py +++ b/utils/swift_build_support/swift_build_support/products/indexstoredb.py @@ -76,7 +76,7 @@ def get_dependencies(cls): def run_build_script_helper(action, host_target, product, args, - sanitize_all=False): + sanitize_all=False, clean=True): script_path = os.path.join( product.source_dir, 'Utilities', 'build-script-helper.py') @@ -105,6 +105,9 @@ def run_build_script_helper(action, host_target, product, args, elif args.enable_tsan: helper_cmd.extend(['--sanitize', 'thread']) + if not clean: + helper_cmd.append('--no-clean') + if not product.is_darwin_host( host_target) and product.is_cross_compile_target(host_target): helper_cmd.extend(['--cross-compile-host', host_target]) diff --git a/utils/swift_build_support/swift_build_support/products/sourcekitlsp.py b/utils/swift_build_support/swift_build_support/products/sourcekitlsp.py index c7349ab7e60de..eae0165927069 100644 --- a/utils/swift_build_support/swift_build_support/products/sourcekitlsp.py +++ b/utils/swift_build_support/swift_build_support/products/sourcekitlsp.py @@ -50,14 +50,14 @@ def should_test(self, host_target): def test(self, host_target): indexstoredb.run_build_script_helper( 'test', host_target, self, self.args, - self.args.test_sourcekitlsp_sanitize_all) + self.args.test_sourcekitlsp_sanitize_all, clean=False) def should_install(self, host_target): return self.args.install_sourcekitlsp def install(self, host_target): indexstoredb.run_build_script_helper( - 'install', host_target, self, self.args) + 'install', host_target, self, self.args, clean=False) @classmethod def get_dependencies(cls): diff --git a/utils/webassembly/build-presets.ini b/utils/webassembly/build-presets.ini index a92292bedbf8f..2cf2fc31c69f6 100644 --- a/utils/webassembly/build-presets.ini +++ b/utils/webassembly/build-presets.ini @@ -41,6 +41,7 @@ swiftpm indexstore-db sourcekit-lsp libcxx +build-lld install-llvm install-swift diff --git a/validation-test/BuildSystem/build_lld.test b/validation-test/BuildSystem/build_lld.test new file mode 100644 index 0000000000000..4df80311c6f58 --- /dev/null +++ b/validation-test/BuildSystem/build_lld.test @@ -0,0 +1,9 @@ +# RUN: %empty-directory(%t) +# RUN: mkdir -p %t +# RUN: SKIP_XCODE_VERSION_CHECK=1 SWIFT_BUILD_ROOT=%t %swift_src_root/utils/build-script --dry-run --build-lld 2>&1 | %FileCheck %s + +# REQUIRES: standalone_build + +# Check that lld is in LLVM_ENABLE_PROJECTS of the llvm-project/llvm build + +# CHECK: '-DLLVM_ENABLE_PROJECTS={{[^']*}}lld{{[^']*}}'{{.*}}llvm-project/llvm{{$}} diff --git a/validation-test/SILOptimizer/hoist_destroy_addr.sil b/validation-test/SILOptimizer/hoist_destroy_addr.sil index 25158a97fac9a..fe5912e4d007a 100644 --- a/validation-test/SILOptimizer/hoist_destroy_addr.sil +++ b/validation-test/SILOptimizer/hoist_destroy_addr.sil @@ -3,6 +3,8 @@ // REQUIRES: long_test // REQUIRES: objc_interop +// SIL includes assumption of 64-bit wordsize +// REQUIRES: PTRSIZE=64 import Builtin import Swift diff --git a/validation-test/SILOptimizer/large_string_array.swift.gyb b/validation-test/SILOptimizer/large_string_array.swift.gyb index 360790a651285..b86e6201391bb 100644 --- a/validation-test/SILOptimizer/large_string_array.swift.gyb +++ b/validation-test/SILOptimizer/large_string_array.swift.gyb @@ -2,7 +2,7 @@ // RUN: %gyb %s > %t/main.swift // https://bugs.swift.org/browse/SR-14460 -// UNSUPPORTED: linux +// UNSUPPORTED: OS=linux-gnu // The compiler should finish in less than 1 minute. To give some slack, // specify a timeout of 5 minutes. diff --git a/validation-test/Sema/type_checker_perf/fast/rdar23620262.swift b/validation-test/Sema/type_checker_perf/fast/rdar23620262.swift index 3f503115680aa..fdd04f1b2b283 100644 --- a/validation-test/Sema/type_checker_perf/fast/rdar23620262.swift +++ b/validation-test/Sema/type_checker_perf/fast/rdar23620262.swift @@ -1,7 +1,7 @@ // RUN: %target-typecheck-verify-swift -solver-expression-time-threshold=1 // REQUIRES: tools-release,no_asan -// UNSUPPORTED: linux +// UNSUPPORTED: OS=linux-gnu // expected-no-diagnostics diff --git a/validation-test/Sema/type_checker_perf/fast/rdar54580427.swift b/validation-test/Sema/type_checker_perf/fast/rdar54580427.swift index faac1e377ff9b..a53909ab0ec96 100644 --- a/validation-test/Sema/type_checker_perf/fast/rdar54580427.swift +++ b/validation-test/Sema/type_checker_perf/fast/rdar54580427.swift @@ -1,7 +1,7 @@ // RUN: %scale-test --begin 1 --end 20 --step 1 --select NumLeafScopes %s -Xfrontend=-solver-expression-time-threshold=1 // REQUIRES: asserts,no_asan -// UNSUPPORTED: linux +// UNSUPPORTED: OS=linux-gnu enum Val { case d([String: Val]) diff --git a/validation-test/compiler_crashers_2_fixed/unsupported_recursive_opaque_conformance.swift b/validation-test/compiler_crashers_2_fixed/unsupported_recursive_opaque_conformance.swift index 9660050fca9c3..2aa6f773a3984 100644 --- a/validation-test/compiler_crashers_2_fixed/unsupported_recursive_opaque_conformance.swift +++ b/validation-test/compiler_crashers_2_fixed/unsupported_recursive_opaque_conformance.swift @@ -1,4 +1,4 @@ -// RUN: not %target-swift-frontend -disable-availability-checking -emit-ir -enable-parameterized-existential-types %s +// RUN: not %target-swift-frontend -disable-availability-checking -emit-ir %s protocol P { associatedtype X : P diff --git a/validation-test/execution/dsohandle-multi-module.swift b/validation-test/execution/dsohandle-multi-module.swift index 3a7f98c2b2c5a..bda5819b0102f 100644 --- a/validation-test/execution/dsohandle-multi-module.swift +++ b/validation-test/execution/dsohandle-multi-module.swift @@ -8,7 +8,7 @@ // REQUIRES: executable_test -// UNSUPPORTED: linux +// UNSUPPORTED: OS=linux-gnu import first import second diff --git a/validation-test/stdlib/SIMDParameterPassing.swift.gyb b/validation-test/stdlib/SIMDParameterPassing.swift.gyb index 5cf58db6c77e6..d2ed07df5ca00 100644 --- a/validation-test/stdlib/SIMDParameterPassing.swift.gyb +++ b/validation-test/stdlib/SIMDParameterPassing.swift.gyb @@ -18,7 +18,7 @@ // REQUIRES: executable_test // REQUIRES: long_test -// XFAIL: linux +// XFAIL: OS=linux-gnu import StdlibUnittest import simd