diff --git a/.github/workflows/build-toolchain.yml b/.github/workflows/build-toolchain.yml index 730e365814209..0271efa509201 100644 --- a/.github/workflows/build-toolchain.yml +++ b/.github/workflows/build-toolchain.yml @@ -129,11 +129,12 @@ jobs: restore-keys: | ${{ matrix.target }}-sccache-v11- - - name: Clean stdlib build directory + - name: Clean build directory if: ${{ matrix.clean_build_dir }} run: | rm -rf ${{ github.workspace }}/target-build \ ${{ github.workspace }}/host-build \ + ${{ github.workspace }}/build-sdk \ ${{ github.workspace }}/host-toolchain-sdk \ ${{ github.workspace }}/dist-toolchain-sdk diff --git a/docs/ABI/Mangling.rst b/docs/ABI/Mangling.rst index 25f964624d276..5abbc6946838f 100644 --- a/docs/ABI/Mangling.rst +++ b/docs/ABI/Mangling.rst @@ -635,6 +635,7 @@ Types type ::= protocol-list 'p' // existential type type ::= protocol-list superclass 'Xc' // existential type with superclass type ::= protocol-list 'Xl' // existential type with AnyObject + type ::= protocol-list 'y' (type* '_')* type* retroactive-conformance* 'Xp' // parameterized protocol type type ::= type-list 't' // tuple type ::= type generic-signature 'u' // generic type type ::= 'x' // generic param, depth=0, idx=0 diff --git a/docs/CppInteropability/CppInteroperabilityManifesto.md b/docs/CppInteroperability/CppInteroperabilityManifesto.md similarity index 100% rename from docs/CppInteropability/CppInteroperabilityManifesto.md rename to docs/CppInteroperability/CppInteroperabilityManifesto.md diff --git a/docs/CppInteropability/GettingStartedWithC++Interop.md b/docs/CppInteroperability/GettingStartedWithC++Interop.md similarity index 98% rename from docs/CppInteropability/GettingStartedWithC++Interop.md rename to docs/CppInteroperability/GettingStartedWithC++Interop.md index 7e58a786ebbad..18fc47103f914 100644 --- a/docs/CppInteropability/GettingStartedWithC++Interop.md +++ b/docs/CppInteroperability/GettingStartedWithC++Interop.md @@ -59,24 +59,23 @@ struct ContentView: View { ``` ``` -//In Cxx.cpp +//In Cxx.hpp + +#ifndef Cxx_hpp +#define Cxx_hpp -#include "Cxx.hpp" int cxxFunction(int n) { return n; } - +#endif ``` ``` -//In Cxx.hpp - -#ifndef Cxx_hpp -#define Cxx_hpp +//In Cxx.cpp +#include "Cxx.hpp" int cxxFunction(int n); -#endif ``` @@ -198,7 +197,7 @@ CxxInterop.main() ``` -- In your projects direcetoy, run `cmake` to generate the systems build files +- In your project's directory, run `cmake` to generate the systems build files - To generate an Xcode project run `cmake -GXcode` - To generate with Ninja run `cmake -GNinja` diff --git a/docs/ReferenceGuides/UnderscoredAttributes.md b/docs/ReferenceGuides/UnderscoredAttributes.md index 8158e791dfe1c..8c7a5c668a02f 100644 --- a/docs/ReferenceGuides/UnderscoredAttributes.md +++ b/docs/ReferenceGuides/UnderscoredAttributes.md @@ -830,6 +830,7 @@ the compiler. This `async` function uses the pre-SE-0338 semantics of unsafely inheriting the caller's executor. This is an underscored feature because the right way of inheriting an executor is to pass in the required executor and switch to it. Unfortunately, there are functions in the standard library which need to inherit their caller's executor but cannot change their ABI because they were not defined as `@_alwaysEmitIntoClient` in the initial release. + ## `@_spi_available(platform, version)` Like `@available`, this attribute indicates a decl is available only as an SPI. @@ -837,3 +838,12 @@ This implies several behavioral changes comparing to regular `@available`: 1. Type checker diagnoses when a client accidently exposes such a symbol in library APIs. 2. When emitting public interfaces, `@_spi_available` is printed as `@available(platform, unavailable)`. 3. ClangImporter imports ObjC macros `SPI_AVAILABLE` and `__SPI_AVAILABLE` to this attribute. + + +## `_local` + +A distributed actor can be marked as "known to be local" which allows avoiding +the distributed actor isolation checks. This is used for things like `whenLocal` +where the actor passed to the closure is known-to-be-local, and similarly a +`self` of obtained from an _isolated_ function inside a distributed actor is +also guaranteed to be local by construction. diff --git a/include/swift/AST/ASTContext.h b/include/swift/AST/ASTContext.h index 173a3a43bb6e2..b97cf8e2fd9d1 100644 --- a/include/swift/AST/ASTContext.h +++ b/include/swift/AST/ASTContext.h @@ -658,12 +658,11 @@ class ASTContext final { /// Retrieve the declaration of DistributedActorSystem.make(). /// - /// \param actorOrSystem distributed actor or actor system to get the - /// remoteCall function for. Since the method we're looking for is an ad-hoc - /// requirement, a specific type MUST be passed here as it is not possible - /// to obtain the decl from just the `DistributedActorSystem` protocol type. + /// \param thunk the function from which we'll be invoking things on the obtained + /// actor system; This way we'll always get the right type, taking care of any + /// where clauses etc. FuncDecl *getMakeInvocationEncoderOnDistributedActorSystem( - NominalTypeDecl *actorOrSystem) const; + AbstractFunctionDecl *thunk) const; // Retrieve the declaration of // DistributedInvocationEncoder.recordGenericSubstitution(_:). diff --git a/include/swift/AST/ASTDemangler.h b/include/swift/AST/ASTDemangler.h index 8e4100d77396e..b425e745e6876 100644 --- a/include/swift/AST/ASTDemangler.h +++ b/include/swift/AST/ASTDemangler.h @@ -112,6 +112,8 @@ class ASTBuilder { bool isClassBound, bool forRequirement = true); + Type createParameterizedProtocolType(Type base, ArrayRef args); + Type createExistentialMetatypeType(Type instance, Optional repr=None); diff --git a/include/swift/AST/Attr.def b/include/swift/AST/Attr.def index dbfacd6aa395b..63fa9d87f7fe9 100644 --- a/include/swift/AST/Attr.def +++ b/include/swift/AST/Attr.def @@ -57,6 +57,7 @@ TYPE_ATTR(async) TYPE_ATTR(Sendable) TYPE_ATTR(unchecked) TYPE_ATTR(_typeSequence) +TYPE_ATTR(_local) // SIL-specific attributes TYPE_ATTR(block_storage) @@ -720,6 +721,13 @@ DECL_ATTR(_backDeploy, BackDeploy, ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIBreakingToRemove, 129) +CONTEXTUAL_SIMPLE_DECL_ATTR(_local, KnownToBeLocal, + DeclModifier | OnFunc | OnParam | OnVar | + DistributedOnly | + ABIBreakingToAdd | ABIBreakingToRemove | + APIBreakingToAdd | APIBreakingToRemove, + 130) + // If you're adding a new underscored attribute here, please document it in // docs/ReferenceGuides/UnderscoredAttributes.md. diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h index 61cb8e40322bb..edb74fa4eaa16 100644 --- a/include/swift/AST/Decl.h +++ b/include/swift/AST/Decl.h @@ -2693,8 +2693,7 @@ class ValueDecl : public Decl { /// property, or the uncurried result type of a method/subscript, e.g. /// '() -> () -> Self'. GenericParameterReferenceInfo findExistentialSelfReferences( - Type baseTy, const DeclContext *useDC, - bool treatNonResultCovariantSelfAsInvariant) const; + Type baseTy, bool treatNonResultCovariantSelfAsInvariant) const; }; /// This is a common base class for declarations which declare a type. @@ -4491,10 +4490,6 @@ class ProtocolDecl final : public NominalTypeDecl { /// semantics but has no corresponding witness table. bool isMarkerProtocol() const; - /// Is a protocol that can only be conformed by distributed actors. - /// Such protocols are allowed to contain distributed functions. - bool inheritsFromDistributedActor() const; - private: void computeKnownProtocolKind() const; @@ -5255,6 +5250,10 @@ class VarDecl : public AbstractStorageDecl { /// Does this have a 'distributed' modifier? bool isDistributed() const; + /// Is this var known to be a "local" distributed actor, + /// if so the implicit throwing ans some isolation checks can be skipped. + bool isKnownToBeLocal() const; + /// Is this a stored property that will _not_ trigger any user-defined code /// upon any kind of access? bool isOrdinaryStoredProperty() const; @@ -6309,6 +6308,13 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl { /// Returns 'true' if the function is distributed. bool isDistributed() const; + /// For a 'distributed' target (func or computed property), + /// get the 'thunk' responsible for performing the 'remoteCall'. + /// + /// \return the synthesized thunk, or null if the base of the call has + /// diagnosed errors during type checking. + FuncDecl *getDistributedThunk() const; + /// Returns 'true' if the function has the @c @_backDeploy attribute. bool isBackDeployed() const; @@ -6456,6 +6462,16 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl { /// 'DistributedActorSystem' protocol. bool isDistributedActorSystemRemoteCall(bool isVoidReturn) const; + /// Determines whether this function is a 'makeInvocationEncoder' function, + /// which is used as ad-hoc protocol requirement by the + /// 'DistributedActorSystem' protocol. + bool isDistributedActorSystemMakeInvocationEncoder() const; + + /// Determines if this function is a 'recordGenericSubstitution' function, + /// which is used as ad-hoc protocol requirement by the + /// 'DistributedTargetInvocationEncoder' protocol. + bool isDistributedTargetInvocationEncoderRecordGenericSubstitution() const; + /// Determines if this function is a 'recordArgument' function, /// which is used as ad-hoc protocol requirement by the /// 'DistributedTargetInvocationEncoder' protocol. diff --git a/include/swift/AST/DiagnosticsParse.def b/include/swift/AST/DiagnosticsParse.def index b39b9174816f5..e47e1abe1ec86 100644 --- a/include/swift/AST/DiagnosticsParse.def +++ b/include/swift/AST/DiagnosticsParse.def @@ -1561,18 +1561,9 @@ ERROR(attr_availability_duplicate,none, (StringRef, StringRef)) // originallyDefinedIn -// FIXME(backDeploy): Refactor to share with back deployment attr ERROR(originally_defined_in_missing_rparen,none, "expected ')' in @_originallyDefinedIn argument list", ()) -// FIXME(backDeploy): Refactor to share with back deployment attr -ERROR(originally_defined_in_unrecognized_platform,none, - "unrecognized platform name in @_originallyDefinedIn argument list", ()) - -// FIXME: This is unused and can be removed -ERROR(originally_defined_in_unrecognized_property,none, - "unrecognized property in @_originallyDefinedIn argument list", ()) - ERROR(originally_defined_in_need_original_module_name,none, "expected 'module: \"original\"' in the first argument to " "@_originallyDefinedIn", ()) @@ -1580,27 +1571,6 @@ ERROR(originally_defined_in_need_original_module_name,none, ERROR(originally_defined_in_need_nonempty_module_name,none, "original module name cannot be empty in @_originallyDefinedIn", ()) -// FIXME(backDeploy): Refactor to share with back deployment attr -ERROR(originally_defined_in_need_platform_version,none, - "expected at least one platform version in @_originallyDefinedIn", ()) - -// FIXME(backDeploy): Refactor to share with back deployment attr -WARNING(originally_defined_in_major_minor_only,none, - "@_originallyDefinedIn only uses major and minor version number", ()) - -// FIXME(backDeploy): Refactor to share with back deployment attr -WARNING(originally_defined_in_missing_platform_name,none, - "* as platform name has no effect", ()) - -// FIXME(backDeploy): Refactor to share with back deployment attr -WARNING(originally_defined_in_swift_version, none, - "Swift language version checks has no effect " - "in @_originallyDefinedIn", ()) - -WARNING(originally_defined_in_package_description, none, - "PackageDescription version checks has no effect " - "in @_originallyDefinedIn", ()) - // backDeploy ERROR(attr_back_deploy_missing_rparen,none, "expected ')' in '@_backDeploy' argument list", ()) diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index 96df9846f67b8..14e7a82efdb6f 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -1935,8 +1935,8 @@ WARNING(type_does_not_conform_swiftui_warning,none, ERROR(non_final_class_cannot_conform_to_self_same_type,none, "non-final class %0 cannot safely conform to protocol %1, " - "which requires that 'Self' is exactly equal to %2", - (Type, Type, Type)) + "which requires that %2 %select{is exactly equal to|inherit from}3 %4", + (Type, Type, Type, unsigned, Type)) ERROR(cannot_use_nil_with_this_type,none, "'nil' cannot be used in context expecting type %0", (Type)) @@ -4495,6 +4495,13 @@ ERROR(actor_inheritance,none, ERROR(actor_protocol_illegal_inheritance,none, "non-actor type %0 cannot conform to the 'Actor' protocol", (DeclName)) +ERROR(distributed_actor_conformance_missing_system_type,none, + "distributed actor %0 does not declare ActorSystem it can be used with.", + (DeclName)) +NOTE(note_distributed_actor_system_can_be_defined_using_defaultdistributedactorsystem,none, + "you can provide a module-wide default actor system by declaring:\n" + "typealias DefaultDistributedActorSystem = <#ConcreteActorSystem#>\n", + ()) ERROR(distributed_actor_protocol_illegal_inheritance,none, "non-distributed actor type %0 cannot conform to the 'DistributedActor' protocol", (DeclName)) @@ -4595,6 +4602,9 @@ NOTE(note_distributed_actor_isolated_method,none, ERROR(distributed_actor_isolated_method,none, "only 'distributed' instance methods can be called on a potentially remote distributed actor", ()) +ERROR(distributed_local_cannot_be_used,none, + "'local' cannot be used in user-defined code currently", + ()) ERROR(distributed_actor_func_param_not_codable,none, "parameter '%0' of type %1 in %2 does not conform to serialization requirement '%3'", (StringRef, Type, DescriptiveDeclKind, StringRef)) diff --git a/include/swift/AST/DistributedDecl.h b/include/swift/AST/DistributedDecl.h index 19405e5148965..60932af16a89b 100644 --- a/include/swift/AST/DistributedDecl.h +++ b/include/swift/AST/DistributedDecl.h @@ -31,6 +31,16 @@ class DeclContext; class FuncDecl; class NominalTypeDecl; +/// Determine the concrete type of 'ActorSystem' as seen from the member. +/// E.g. when in a protocol, and trying to determine what the actor system was +/// constrained to. +/// +/// \param member the member from which context the lookup should be performed, +/// e.g. a function or computed property. +/// \return the concrete type of the ActorSystem to be used by this member, +/// or null if no concrete actor system was found. +Type getConcreteReplacementForProtocolActorSystemType(ValueDecl *member); + /// Determine the `ActorSystem` type for the given actor. Type getDistributedActorSystemType(NominalTypeDecl *actor); @@ -43,14 +53,12 @@ Type getDistributedActorIDType(NominalTypeDecl *actor); Type getDistributedSerializationRequirementType( NominalTypeDecl *nominal, ProtocolDecl *protocol); -///// Determine the serialization requirement for the given actor, actor system -///// or other type that has the SerializationRequirement associated type. -//Type getDistributedSerializationRequirementType( -// NominalTypeDecl *nominal, ProtocolDecl *protocol); - -Type getDistributedActorSystemActorIDRequirementType( - NominalTypeDecl *system); +/// Get the specific 'InvocationEncoder' type of a specific distributed actor +/// system. +Type getDistributedActorSystemInvocationEncoderType(NominalTypeDecl *system); +/// Get the 'ActorID' type of a specific distributed actor system. +Type getDistributedActorSystemActorIDRequirementType(NominalTypeDecl *system); /// Get the specific protocols that the `SerializationRequirement` specifies, /// and all parameters / return types of distributed targets must conform to. diff --git a/include/swift/AST/Expr.h b/include/swift/AST/Expr.h index e9645cab3921b..6a57cb9d3679b 100644 --- a/include/swift/AST/Expr.h +++ b/include/swift/AST/Expr.h @@ -297,9 +297,10 @@ class alignas(8) Expr : public ASTAllocated { IsNonAccessing : 1 ); - SWIFT_INLINE_BITFIELD_FULL(ErasureExpr, ImplicitConversionExpr, 32, + SWIFT_INLINE_BITFIELD_FULL(ErasureExpr, ImplicitConversionExpr, 32+20, : NumPadBits, - NumConformances : 32 + NumConformances : 32, + NumArgumentConversions : 20 ); SWIFT_INLINE_BITFIELD_FULL(UnresolvedSpecializeExpr, Expr, 32, @@ -312,7 +313,7 @@ class alignas(8) Expr : public ASTAllocated { NumCaptures : 32 ); - SWIFT_INLINE_BITFIELD(ApplyExpr, Expr, 1+1+1+1+1+1, + SWIFT_INLINE_BITFIELD(ApplyExpr, Expr, 1+1+1+1+1+1+1, ThrowsIsSet : 1, Throws : 1, ImplicitlyAsync : 1, @@ -1907,6 +1908,11 @@ class TryExpr : public AnyTryExpr { static bool classof(const Expr *e) { return e->getKind() == ExprKind::Try; } + + static TryExpr *createImplicit(ASTContext &ctx, SourceLoc tryLoc, Expr *sub, + Type type = Type()) { + return new (ctx) TryExpr(tryLoc, sub, type, /*implicit=*/true); + } }; /// ForceTryExpr - A 'try!' surrounding an expression, marking that @@ -2065,7 +2071,11 @@ class AwaitExpr final : public IdentityExpr { bool implicit = false) : IdentityExpr(ExprKind::Await, sub, type, implicit), AwaitLoc(awaitLoc) { } - + + static AwaitExpr *createImplicit(ASTContext &ctx, SourceLoc awaitLoc, Expr *sub, Type type = Type()) { + return new (ctx) AwaitExpr(awaitLoc, sub, type, /*implicit=*/true); + } + SourceLoc getLoc() const { return AwaitLoc; } SourceLoc getAwaitLoc() const { return AwaitLoc; } @@ -3244,20 +3254,35 @@ class CollectionUpcastConversionExpr : public ImplicitConversionExpr { /// "Appropriate kind" means e.g. a concrete/existential metatype if the /// result is an existential metatype. class ErasureExpr final : public ImplicitConversionExpr, - private llvm::TrailingObjects { + private llvm::TrailingObjects { friend TrailingObjects; + using ConversionPair = CollectionUpcastConversionExpr::ConversionPair; ErasureExpr(Expr *subExpr, Type type, - ArrayRef conformances) + ArrayRef conformances, + ArrayRef argConversions) : ImplicitConversionExpr(ExprKind::Erasure, subExpr, type) { Bits.ErasureExpr.NumConformances = conformances.size(); std::uninitialized_copy(conformances.begin(), conformances.end(), getTrailingObjects()); + + Bits.ErasureExpr.NumArgumentConversions = argConversions.size(); + std::uninitialized_copy(argConversions.begin(), argConversions.end(), + getTrailingObjects()); } public: static ErasureExpr *create(ASTContext &ctx, Expr *subExpr, Type type, - ArrayRef conformances); + ArrayRef conformances, + ArrayRef argConversions); + + size_t numTrailingObjects(OverloadToken) const { + return Bits.ErasureExpr.NumConformances; + } + size_t numTrailingObjects(OverloadToken) const { + return Bits.ErasureExpr.NumArgumentConversions; + } /// Retrieve the mapping specifying how the type of the subexpression /// maps to the resulting existential type. If the resulting existential @@ -3274,6 +3299,30 @@ class ErasureExpr final : public ImplicitConversionExpr, Bits.ErasureExpr.NumConformances }; } + /// Retrieve the conversion expressions mapping requirements from any + /// parameterized existentials involved in this erasure. + /// + /// If the destination type is not a parameterized protocol type, + /// this array will be empty + ArrayRef getArgumentConversions() const { + return {getTrailingObjects(), + Bits.ErasureExpr.NumArgumentConversions }; + } + + /// Retrieve the conversion expressions mapping requirements from any + /// parameterized existentials involved in this erasure. + /// + /// If the destination type is not a parameterized protocol type, + /// this array will be empty + MutableArrayRef getArgumentConversions() { + return {getTrailingObjects(), + Bits.ErasureExpr.NumArgumentConversions }; + } + + void setArgumentConversion(unsigned i, const ConversionPair &p) { + getArgumentConversions()[i] = p; + } + static bool classof(const Expr *E) { return E->getKind() == ExprKind::Erasure; } @@ -4469,11 +4518,11 @@ class ApplyExpr : public Expr { } /// Is this application _implicitly_ required to be a throwing call? - /// This can happen if the function is actually a proxy function invocation, - /// which may throw, regardless of the target function throwing, e.g. - /// a distributed instance method call on a 'remote' actor, may throw due to network - /// issues reported by the transport, regardless if the actual target function - /// can throw. + /// This can happen if the function is actually a distributed thunk + /// invocation, which may throw, regardless of the target function throwing, + /// e.g. a distributed instance method call on a 'remote' actor, may throw due + /// to network issues reported by the transport, regardless if the actual + /// target function can throw. bool implicitlyThrows() const { return Bits.ApplyExpr.ImplicitlyThrows; } diff --git a/include/swift/AST/KnownIdentifiers.def b/include/swift/AST/KnownIdentifiers.def index 7ae9fb928ac24..519c0fa59a9d4 100644 --- a/include/swift/AST/KnownIdentifiers.def +++ b/include/swift/AST/KnownIdentifiers.def @@ -293,6 +293,7 @@ IDENTIFIER(target) IDENTIFIER(throwing) IDENTIFIER(using) IDENTIFIER(InvocationDecoder) +IDENTIFIER(InvocationEncoder) IDENTIFIER(whenLocal) IDENTIFIER(decodeNextArgument) IDENTIFIER(SerializationRequirement) diff --git a/include/swift/AST/KnownSDKTypes.def b/include/swift/AST/KnownSDKTypes.def index 449e4cecc3dc9..249fd18b07d82 100644 --- a/include/swift/AST/KnownSDKTypes.def +++ b/include/swift/AST/KnownSDKTypes.def @@ -45,6 +45,9 @@ KNOWN_SDK_TYPE_DECL(Concurrency, TaskLocal, ClassDecl, 1) // Distributed actors KNOWN_SDK_TYPE_DECL(Distributed, DistributedActor, ProtocolDecl, 0) +KNOWN_SDK_TYPE_DECL(Distributed, DistributedActorSystem, ProtocolDecl, 0) +KNOWN_SDK_TYPE_DECL(Distributed, DistributedTargetInvocationEncoder, ProtocolDecl, 0) +KNOWN_SDK_TYPE_DECL(Distributed, DistributedTargetInvocationDecoder, ProtocolDecl, 0) KNOWN_SDK_TYPE_DECL(Distributed, RemoteCallTarget, StructDecl, 0) // String processing diff --git a/include/swift/AST/TypeCheckRequests.h b/include/swift/AST/TypeCheckRequests.h index e2bff3d6020f2..e1c3f5c98f82a 100644 --- a/include/swift/AST/TypeCheckRequests.h +++ b/include/swift/AST/TypeCheckRequests.h @@ -1184,6 +1184,27 @@ class GetDistributedRemoteCallTargetInitFunctionRequest : bool isCached() const { return true; } }; +/// Obtain the 'distributed thunk' for the passed-in function. +/// +/// The thunk is responsible for invoking 'remoteCall' when invoked on a remote +/// 'distributed actor'. +class GetDistributedThunkRequest : + public SimpleRequest { +public: + using SimpleRequest::SimpleRequest; + +private: + friend SimpleRequest; + + FuncDecl *evaluate(Evaluator &evaluator, AbstractFunctionDecl *distributedFunc) const; + +public: + // Caching + bool isCached() const { return true; } +}; + /// Obtain the 'id' property of a 'distributed actor'. class GetDistributedActorIDPropertyRequest : public SimpleRequest(type) || - isa(type) || - isa(type)); + return isa(type) || + isa(type) || + isa(type) || + isa(type); } inline bool CanType::isAnyExistentialTypeImpl(CanType type) { @@ -6515,6 +6520,8 @@ inline NominalTypeDecl *CanType::getNominalOrBoundGenericNominal() const { return Ty->getDecl(); if (auto Ty = dyn_cast(*this)) return Ty->getConstraintType()->getNominalOrBoundGenericNominal(); + if (auto Ty = dyn_cast(*this)) + return Ty->getBaseType()->getNominalOrBoundGenericNominal(); return nullptr; } @@ -6525,7 +6532,8 @@ inline NominalTypeDecl *TypeBase::getAnyNominal() { inline Type TypeBase::getNominalParent() { if (auto existential = getAs()) return existential->getConstraintType()->getNominalParent(); - + if (auto ppt = getAs()) + return ppt->getBaseType()->getNominalParent(); return castTo()->getParent(); } diff --git a/include/swift/Basic/LangOptions.h b/include/swift/Basic/LangOptions.h index cde2912aaf244..7f094fc7cb11f 100644 --- a/include/swift/Basic/LangOptions.h +++ b/include/swift/Basic/LangOptions.h @@ -545,6 +545,10 @@ namespace swift { /// enabled. It can be disabled for debugging and testing. bool EnableRequirementMachineConcreteContraction = true; + /// Enable the stronger minimization algorithm. This is just for debugging; + /// if you have a testcase which requires this, please submit a bug report. + bool EnableRequirementMachineLoopNormalization = false; + /// Enables dumping type witness systems from associated type inference. bool DumpTypeWitnessSystems = false; diff --git a/include/swift/ClangImporter/ClangImporter.h b/include/swift/ClangImporter/ClangImporter.h index 3c081cde41662..d1cbbbc442721 100644 --- a/include/swift/ClangImporter/ClangImporter.h +++ b/include/swift/ClangImporter/ClangImporter.h @@ -441,9 +441,12 @@ class ClangImporter final : public ClangModuleLoader { std::string getClangModuleHash() const; - /// If we already imported a given decl, return the corresponding Swift decl. - /// Otherwise, return nullptr. - Decl *importDeclCached(const clang::NamedDecl *ClangDecl); + /// If we already imported a given decl successfully, return the corresponding + /// Swift decl as an Optional, but if we previously tried and failed + /// to import said decl then return nullptr. + /// Otherwise, if we have never encountered this decl previously then return + /// None. + Optional importDeclCached(const clang::NamedDecl *ClangDecl); // Returns true if it is expected that the macro is ignored. bool shouldIgnoreMacro(StringRef Name, const clang::MacroInfo *Macro); diff --git a/include/swift/Demangling/DemangleNodes.def b/include/swift/Demangling/DemangleNodes.def index 1a2d812a57951..50f92c7d73e7c 100644 --- a/include/swift/Demangling/DemangleNodes.def +++ b/include/swift/Demangling/DemangleNodes.def @@ -170,6 +170,7 @@ NODE(EscapingObjCBlock) CONTEXT_NODE(OtherNominalType) CONTEXT_NODE(OwningAddressor) CONTEXT_NODE(OwningMutableAddressor) +NODE(ParameterizedProtocol) NODE(PartialApplyForwarder) NODE(PartialApplyObjCForwarder) NODE(PostfixOperator) diff --git a/include/swift/Demangling/TypeDecoder.h b/include/swift/Demangling/TypeDecoder.h index 07b5e5161dc70..7361e0147b5b3 100644 --- a/include/swift/Demangling/TypeDecoder.h +++ b/include/swift/Demangling/TypeDecoder.h @@ -710,6 +710,34 @@ class TypeDecoder { forRequirement); } + case NodeKind::ParameterizedProtocol: { + if (Node->getNumChildren() < 2) + return MAKE_NODE_TYPE_ERROR(Node, + "fewer children (%zu) than required (2)", + Node->getNumChildren()); + + auto protocolType = decodeMangledType(Node->getChild(0), depth + 1); + if (protocolType.isError()) + return protocolType; + + llvm::SmallVector args; + + const auto &genericArgs = Node->getChild(1); + if (genericArgs->getKind() != NodeKind::TypeList) + return MAKE_NODE_TYPE_ERROR0(genericArgs, "is not TypeList"); + + for (auto genericArg : *genericArgs) { + auto paramType = decodeMangledType(genericArg, depth + 1, + /*forRequirement=*/false); + if (paramType.isError()) + return paramType; + args.push_back(paramType.getType()); + } + + return Builder.createParameterizedProtocolType(protocolType.getType(), + args); + } + case NodeKind::Protocol: case NodeKind::ProtocolSymbolicReference: { if (auto Proto = decodeMangledProtocolType(Node, depth + 1)) { diff --git a/include/swift/Option/FrontendOptions.td b/include/swift/Option/FrontendOptions.td index 60e83a773471d..86d99764ccc18 100644 --- a/include/swift/Option/FrontendOptions.td +++ b/include/swift/Option/FrontendOptions.td @@ -359,6 +359,9 @@ def disable_requirement_machine_concrete_contraction : Flag<["-"], "disable-requ HelpText<"Disable preprocessing pass to eliminate conformance requirements " "on generic parameters which are made concrete">; +def enable_requirement_machine_loop_normalization : Flag<["-"], "enable-requirement-machine-loop-normalization">, + HelpText<"Enable stronger minimization algorithm, for debugging only">; + def dump_type_witness_systems : Flag<["-"], "dump-type-witness-systems">, HelpText<"Enables dumping type witness systems from associated type inference">; diff --git a/include/swift/Reflection/TypeRef.h b/include/swift/Reflection/TypeRef.h index d0061b4de22ff..74c5035c1c512 100644 --- a/include/swift/Reflection/TypeRef.h +++ b/include/swift/Reflection/TypeRef.h @@ -563,6 +563,42 @@ class ProtocolCompositionTypeRef final : public TypeRef { } }; +class ParameterizedProtocolTypeRef final : public TypeRef { + const ProtocolCompositionTypeRef *Base; + std::vector Args; + + static TypeRefID Profile(const ProtocolCompositionTypeRef *Protocol, + std::vector Args) { + TypeRefID ID; + ID.addPointer(Protocol); + for (auto Arg : Args) { + ID.addPointer(Arg); + } + return ID; + } + +public: + ParameterizedProtocolTypeRef(const ProtocolCompositionTypeRef *Protocol, + std::vector Args) + : TypeRef(TypeRefKind::ParameterizedProtocol), Base(Protocol), + Args(Args) {} + + template + static const ParameterizedProtocolTypeRef * + create(Allocator &A, const ProtocolCompositionTypeRef *Protocol, + std::vector Args) { + FIND_OR_CREATE_TYPEREF(A, ParameterizedProtocolTypeRef, Protocol, Args); + } + + const ProtocolCompositionTypeRef *getBase() const { return Base; } + + const std::vector &getArgs() const { return Args; } + + static bool classof(const TypeRef *TR) { + return TR->getKind() == TypeRefKind::ParameterizedProtocol; + } +}; + class MetatypeTypeRef final : public TypeRef { const TypeRef *InstanceType; bool WasAbstract; diff --git a/include/swift/Reflection/TypeRefBuilder.h b/include/swift/Reflection/TypeRefBuilder.h index 8a82352edbc04..3847ec41926e5 100644 --- a/include/swift/Reflection/TypeRefBuilder.h +++ b/include/swift/Reflection/TypeRefBuilder.h @@ -614,6 +614,15 @@ class TypeRefBuilder { isClassBound); } + const ParameterizedProtocolTypeRef * + createParameterizedProtocolType(const TypeRef *base, + llvm::ArrayRef args) { + auto *baseProto = llvm::dyn_cast(base); + if (!baseProto) + return nullptr; + return ParameterizedProtocolTypeRef::create(*this, baseProto, args); + } + const ExistentialMetatypeTypeRef *createExistentialMetatypeType( const TypeRef *instance, llvm::Optional repr = None) { diff --git a/include/swift/Reflection/TypeRefs.def b/include/swift/Reflection/TypeRefs.def index 90e9dbd80e38a..61baf077fd505 100644 --- a/include/swift/Reflection/TypeRefs.def +++ b/include/swift/Reflection/TypeRefs.def @@ -22,6 +22,7 @@ TYPEREF(BoundGeneric, TypeRef) TYPEREF(Tuple, TypeRef) TYPEREF(Function, TypeRef) TYPEREF(ProtocolComposition, TypeRef) +TYPEREF(ParameterizedProtocol, TypeRef) TYPEREF(Metatype, TypeRef) TYPEREF(ExistentialMetatype, TypeRef) TYPEREF(GenericTypeParameter, TypeRef) diff --git a/include/swift/SIL/SILDeclRef.h b/include/swift/SIL/SILDeclRef.h index 4113b70998c6e..952f14665a747 100644 --- a/include/swift/SIL/SILDeclRef.h +++ b/include/swift/SIL/SILDeclRef.h @@ -105,6 +105,7 @@ struct SILDeclRef { /// entry point of a class ConstructorDecl or the constructor of a value /// ConstructorDecl. Allocator, + /// Initializer - this constant references the initializing constructor /// entry point of the class ConstructorDecl in loc. Initializer, @@ -185,6 +186,8 @@ struct SILDeclRef { unsigned isForeign : 1; /// True if this references a distributed function. unsigned isDistributed : 1; + /// True if this references a distributed function, but it is known to be local + unsigned isKnownToBeLocal : 1; /// The BackDeploymentKind of this SILDeclRef. BackDeploymentKind backDeploymentKind : 2; /// The default argument index for a default argument getter. @@ -221,7 +224,8 @@ struct SILDeclRef { /// Produces a null SILDeclRef. SILDeclRef() - : loc(), kind(Kind::Func), isForeign(0), isDistributed(0), + : loc(), kind(Kind::Func), isForeign(0), + isDistributed(0), isKnownToBeLocal(0), backDeploymentKind(BackDeploymentKind::None), defaultArgIndex(0) {} /// Produces a SILDeclRef of the given kind for the given decl. @@ -229,6 +233,7 @@ struct SILDeclRef { ValueDecl *decl, Kind kind, bool isForeign = false, bool isDistributed = false, + bool isDistributedKnownToBeLocal = false, BackDeploymentKind backDeploymentKind = BackDeploymentKind::None, AutoDiffDerivativeFunctionIdentifier *derivativeId = nullptr); @@ -246,7 +251,8 @@ struct SILDeclRef { explicit SILDeclRef( Loc loc, bool isForeign = false, - bool isDistributed = false); + bool isDistributed = false, + bool isDistributedLocal = false); /// See above put produces a prespecialization according to the signature. explicit SILDeclRef(Loc loc, GenericSignature prespecializationSig); @@ -401,6 +407,7 @@ struct SILDeclRef { return SILDeclRef(loc.getOpaqueValue(), kind, /*foreign=*/foreign, /*distributed=*/false, + /*knownToBeLocal=*/false, backDeploymentKind, defaultArgIndex, pointer.get()); @@ -411,15 +418,30 @@ struct SILDeclRef { return SILDeclRef(loc.getOpaqueValue(), kind, /*foreign=*/false, /*distributed=*/distributed, + /*knownToBeLocal=*/false, backDeploymentKind, defaultArgIndex, pointer.get()); } + + /// Returns the distributed known-to-be-local entry point corresponding to + /// the same decl. + SILDeclRef asDistributedKnownToBeLocal(bool isLocal = true) const { + return SILDeclRef(loc.getOpaqueValue(), kind, + /*foreign=*/false, + /*distributed=*/false, + /*distributedKnownToBeLocal=*/isLocal, + backDeploymentKind, + defaultArgIndex, + pointer.get()); + } + /// Returns a copy of the decl with the given back deployment kind. SILDeclRef asBackDeploymentKind(BackDeploymentKind backDeploymentKind) const { return SILDeclRef(loc.getOpaqueValue(), kind, isForeign, isDistributed, + isKnownToBeLocal, backDeploymentKind, defaultArgIndex, pointer.get()); @@ -550,11 +572,14 @@ struct SILDeclRef { explicit SILDeclRef(void *opaqueLoc, Kind kind, bool isForeign, bool isDistributed, + bool isKnownToBeLocal, BackDeploymentKind backDeploymentKind, unsigned defaultArgIndex, AutoDiffDerivativeFunctionIdentifier *derivativeId) : loc(Loc::getFromOpaqueValue(opaqueLoc)), kind(kind), - isForeign(isForeign), isDistributed(isDistributed), + isForeign(isForeign), + isDistributed(isDistributed), + isKnownToBeLocal(isKnownToBeLocal), backDeploymentKind(backDeploymentKind), defaultArgIndex(defaultArgIndex), pointer(derivativeId) {} @@ -580,11 +605,11 @@ template<> struct DenseMapInfo { static SILDeclRef getEmptyKey() { return SILDeclRef(PointerInfo::getEmptyKey(), Kind::Func, false, false, - BackDeploymentKind::None, 0, nullptr); + false, BackDeploymentKind::None, 0, nullptr); } static SILDeclRef getTombstoneKey() { return SILDeclRef(PointerInfo::getTombstoneKey(), Kind::Func, false, false, - BackDeploymentKind::None, 0, nullptr); + false, BackDeploymentKind::None, 0, nullptr); } static unsigned getHashValue(swift::SILDeclRef Val) { unsigned h1 = PointerInfo::getHashValue(Val.loc.getOpaqueValue()); @@ -596,8 +621,9 @@ template<> struct DenseMapInfo { unsigned h5 = PointerInfo::getHashValue(Val.pointer.getOpaqueValue()); unsigned h6 = UnsignedInfo::getHashValue(Val.isDistributed); unsigned h7 = UnsignedInfo::getHashValue(unsigned(Val.backDeploymentKind)); + unsigned h8 = UnsignedInfo::getHashValue(Val.isKnownToBeLocal); return h1 ^ (h2 << 4) ^ (h3 << 9) ^ (h4 << 7) ^ (h5 << 11) ^ (h6 << 8) ^ - (h7 << 10); + (h7 << 10) ^ (h8 << 13); } static bool isEqual(swift::SILDeclRef const &LHS, swift::SILDeclRef const &RHS) { diff --git a/include/swift/SIL/SILFunction.h b/include/swift/SIL/SILFunction.h index 07ec487377009..1f23676b657b7 100644 --- a/include/swift/SIL/SILFunction.h +++ b/include/swift/SIL/SILFunction.h @@ -262,7 +262,7 @@ class SILFunction unsigned Transparent : 1; /// The function's serialized attribute. - unsigned Serialized : 2; + bool Serialized : 1; /// Specifies if this function is a thunk or a reabstraction thunk. /// @@ -689,10 +689,7 @@ class SILFunction /// Returns true if this function can be inlined into a fragile function /// body. - bool hasValidLinkageForFragileInline() const { - return (isSerialized() == IsSerialized || - isSerialized() == IsSerializable); - } + bool hasValidLinkageForFragileInline() const { return isSerialized(); } /// Returns true if this function can be referenced from a fragile function /// body. @@ -914,7 +911,11 @@ class SILFunction /// Get this function's serialized attribute. IsSerialized_t isSerialized() const { return IsSerialized_t(Serialized); } - void setSerialized(IsSerialized_t isSerialized) { Serialized = isSerialized; } + void setSerialized(IsSerialized_t isSerialized) { + Serialized = isSerialized; + assert(this->isSerialized() == isSerialized && + "too few bits for Serialized storage"); + } /// Get this function's thunk attribute. IsThunk_t isThunk() const { return IsThunk_t(Thunk); } diff --git a/include/swift/SIL/SILLinkage.h b/include/swift/SIL/SILLinkage.h index 0791bcf1f35dc..ba286be451c0a 100644 --- a/include/swift/SIL/SILLinkage.h +++ b/include/swift/SIL/SILLinkage.h @@ -38,33 +38,51 @@ enum class SILLinkage : uint8_t { /// This object definition is visible to multiple Swift modules (and /// thus potentially across linkage-unit boundaries). There are no /// other object definitions with this name in the program. + /// + /// Public functions must be definitions, i.e. must have a body, except the + /// body is emitted by clang. Public, /// This is a special linkage used for symbols which are treated /// as public for the purposes of SIL serialization and optimization, /// but do not have public entry points in the generated binary. /// + /// This linkage is used for @_alwaysEmitIntoClient functions. + /// /// There is no external variant of this linkage, because from other /// translation units in the same module, this behaves identically /// to the HiddenExternal linkage. /// /// When deserialized, such declarations receive Shared linkage. + /// + /// PublicNonABI functions must be definitions. PublicNonABI, /// This object definition is visible only to the current Swift /// module (and thus should not be visible across linkage-unit /// boundaries). There are no other object definitions with this /// name in the module. + /// + /// Hidden functions must be definitions, i.e. must have a body, except the + /// body is emitted by clang. Hidden, /// This object definition is visible only within a single Swift /// module. There may be other object definitions with this name in /// the module; those definitions are all guaranteed to be /// semantically equivalent to this one. + /// + /// This linkage is used e.g. for thunks and for specialized functions. + /// + /// Public functions must be definitions, i.e. must have a body, except the + /// body is emitted by clang. Shared, /// This object definition is visible only within a single Swift /// file. + /// + /// Private functions must be definitions, i.e. must have a body, except the + /// body is emitted by clang. Private, /// A Public definition with the same name as this object will be @@ -74,17 +92,12 @@ enum class SILLinkage : uint8_t { PublicExternal, /// A Public or Hidden definition with the same name as this object - /// will be defined by the current Swift module at runtime. If this - /// object is a definition, it is semantically equivalent to that - /// definition. + /// will be defined by the current Swift module at runtime. + /// + /// This linkage is only used for non-whole-module compilations to refer to + /// functions in other files of the same module. HiddenExternal, - /// This Shared definition was imported from another module. It is not - /// necessary to serialize it since it can be deserialized from the original - /// module. Besides that caveat this should be treated exactly the same as - /// shared. - SharedExternal, - /// The default linkage for a definition. DefaultForDefinition = Public, @@ -97,14 +110,40 @@ enum { NumSILLinkageBits = 4 }; -/// Related to linkage: flag if a function or global variable is serialized, -/// either unconditionally, or if referenced from another serialized function. +/// Related to linkage: flag if a function, global variable, vtable or witness +/// table is serialized. +/// +/// Used, e.g. for @inlinable functions. +/// +/// This flag serves for two purposes: +/// * Imposes restrictions for optimizations. For example, non-serialized functions +/// cannot be inlined into serialized functions, because that could expose +/// internal types/functions to client modules. +/// * Tells the serializer which functions (and tables) need to be serialized: +/// - all public functions with the IsSerialized flag and +/// - all IsSerialized shared functions which are referenced from such functions. +/// +/// After the swiftmodule file is written, the IsSerialized flag is cleared from +/// all functions. This means that optimizations after the serialization point +/// are not limited anymore regarding serialized functions. enum IsSerialized_t : unsigned char { - // Never serialized. + + /// The function is not inlinable and will not be serialized. IsNotSerialized, - // Serialized if referenced from another serialized function. - IsSerializable, - // Always serialized. + + /// The function (or table) will be serialized. + /// + /// This flag is only valid for Public, PublicNonABI, PublicExternal, + /// HiddenExternal and Shared functions. + /// Functions with external linkage (PublicExternl, HiddenExternal) will not + /// be serialized, because they are available in a different module (from which + /// they were de-serialized). + /// + /// Functions with Shared linkage will only be serialized if they are referenced + /// from another serialized function (or table). + /// + /// This flag is removed from all functions after the serialization point in + /// the optimizer pipeline. IsSerialized }; @@ -131,8 +170,6 @@ inline SILLinkage stripExternalFromLinkage(SILLinkage linkage) { return SILLinkage::Public; if (linkage == SILLinkage::HiddenExternal) return SILLinkage::Hidden; - if (linkage == SILLinkage::SharedExternal) - return SILLinkage::Shared; return linkage; } @@ -146,13 +183,11 @@ inline SILLinkage addExternalToLinkage(SILLinkage linkage) { // if the function was emitted in another translation unit of the // same Swift module, so we treat it as hidden here. return SILLinkage::HiddenExternal; - case SILLinkage::Shared: - return SILLinkage::SharedExternal; case SILLinkage::Hidden: return SILLinkage::HiddenExternal; + case SILLinkage::Shared: case SILLinkage::Private: case SILLinkage::PublicExternal: - case SILLinkage::SharedExternal: case SILLinkage::HiddenExternal: return linkage; } @@ -186,7 +221,6 @@ inline bool hasPublicVisibility(SILLinkage linkage) { return true; case SILLinkage::Hidden: case SILLinkage::Shared: - case SILLinkage::SharedExternal: case SILLinkage::Private: case SILLinkage::HiddenExternal: return false; @@ -198,7 +232,6 @@ inline bool hasPublicVisibility(SILLinkage linkage) { inline bool hasSharedVisibility(SILLinkage linkage) { switch (linkage) { case SILLinkage::Shared: - case SILLinkage::SharedExternal: return true; case SILLinkage::Public: case SILLinkage::PublicExternal: @@ -222,7 +255,6 @@ inline bool hasPrivateVisibility(SILLinkage linkage) { case SILLinkage::Hidden: case SILLinkage::HiddenExternal: case SILLinkage::Shared: - case SILLinkage::SharedExternal: return false; } diff --git a/include/swift/SIL/SILModule.h b/include/swift/SIL/SILModule.h index f389e7b24e9ee..c522cb946b86e 100644 --- a/include/swift/SIL/SILModule.h +++ b/include/swift/SIL/SILModule.h @@ -167,7 +167,7 @@ class SILModule { llvm::DenseMap; enum class LinkingMode : uint8_t { - /// Link functions with non-public linkage. Used by the mandatory pipeline. + /// Link functions with shared linkage. Used by the mandatory pipeline. LinkNormal, /// Link all functions. Used by the performance pipeine. @@ -349,6 +349,8 @@ class SILModule { /// to ensure that the module is serialized only once. bool serialized; + bool parsedAsSerializedSIL; + /// Set if we have registered a deserialization notification handler for /// lowering ownership in non transparent functions. /// This gets set in NonTransparent OwnershipModelEliminator pass. @@ -455,6 +457,12 @@ class SILModule { void setSerialized() { serialized = true; } bool isSerialized() const { return serialized; } + void setParsedAsSerializedSIL() { + serialized = true; + parsedAsSerializedSIL = true; + } + bool isParsedAsSerializedSIL() const { return parsedAsSerializedSIL; } + void setBasicBlockName(const SILBasicBlock *block, StringRef name) { #ifndef NDEBUG basicBlockNames[block] = name.str(); @@ -688,9 +696,20 @@ class SILModule { /// \return null if this module has no such function SILFunction *lookUpFunction(SILDeclRef fnRef); - /// Attempt to deserialize the SILFunction. Returns true if deserialization - /// succeeded, false otherwise. - bool loadFunction(SILFunction *F); + /// Attempt to deserialize function \p F and all functions which are referenced + /// from \p F (according to the \p LinkMode). + /// + /// Returns true if deserialization succeeded, false otherwise. + bool loadFunction(SILFunction *F, LinkingMode LinkMode); + + /// Attempt to deserialize a function with \p name and all functions which are + /// referenced from that function (according to the \p LinkMode). + /// + /// If \p linkage is provided, the deserialized function is required to have + /// that linkage. Returns null, if this is not the case. + SILFunction *loadFunction(StringRef name, + LinkingMode LinkMode, + Optional linkage = None); /// Update the linkage of the SILFunction with the linkage of the serialized /// function. @@ -699,19 +718,10 @@ class SILModule { /// AST, e.g. cross-module-optimization can change the SIL linkages. void updateFunctionLinkage(SILFunction *F); - /// Attempt to link the SILFunction. Returns true if linking succeeded, false - /// otherwise. - /// - /// \return false if the linking failed. - bool linkFunction(SILFunction *F, - LinkingMode LinkMode = LinkingMode::LinkNormal); - - /// Check if a given function exists in any of the modules with a - /// required linkage, i.e. it can be linked by linkFunction. + /// Attempt to deserialize function \p F and all required referenced functions. /// - /// \return null if this module has no such function. Otherwise - /// the declaration of a function. - SILFunction *findFunction(StringRef Name, SILLinkage Linkage); + /// Returns true if linking succeeded, false otherwise. + bool linkFunction(SILFunction *F, LinkingMode LinkMode); /// Check if a given function exists in any of the modules. /// i.e. it can be linked by linkFunction. @@ -725,15 +735,15 @@ class SILModule { /// table. /// \arg deserializeLazily If we cannot find the witness table should we /// attempt to lazily deserialize it. - SILWitnessTable * - lookUpWitnessTable(ProtocolConformanceRef C, bool deserializeLazily=true); - SILWitnessTable * - lookUpWitnessTable(const ProtocolConformance *C, bool deserializeLazily=true); + SILWitnessTable *lookUpWitnessTable(const ProtocolConformance *C); /// Attempt to lookup \p Member in the witness table for \p C. + /// + /// Also, deserialize all referenced functions according to the \p linkgingMode. std::pair lookUpFunctionInWitnessTable(ProtocolConformanceRef C, - SILDeclRef Requirement); + SILDeclRef Requirement, + SILModule::LinkingMode linkingMode); /// Look up the SILDefaultWitnessTable representing the default witnesses /// of a resilient protocol, if any. diff --git a/include/swift/SIL/SILVTable.h b/include/swift/SIL/SILVTable.h index 8a5c5866f6f04..2a1b892029c6d 100644 --- a/include/swift/SIL/SILVTable.h +++ b/include/swift/SIL/SILVTable.h @@ -144,7 +144,6 @@ class SILVTable final : public SILAllocated, /// Sets the serialized flag. void setSerialized(IsSerialized_t serialized) { - assert(serialized != IsSerializable); Serialized = (serialized ? 1 : 0); } diff --git a/include/swift/SIL/SILWitnessTable.h b/include/swift/SIL/SILWitnessTable.h index bf1269a0c7687..92c0efbe5a065 100644 --- a/include/swift/SIL/SILWitnessTable.h +++ b/include/swift/SIL/SILWitnessTable.h @@ -260,7 +260,6 @@ class SILWitnessTable : public llvm::ilist_node, /// Sets the serialized flag. void setSerialized(IsSerialized_t serialized) { - assert(serialized != IsSerializable); Serialized = (serialized ? 1 : 0); } diff --git a/include/swift/Sema/ConstraintSystem.h b/include/swift/Sema/ConstraintSystem.h index a6a81edf918fe..e37baa80e0ad9 100644 --- a/include/swift/Sema/ConstraintSystem.h +++ b/include/swift/Sema/ConstraintSystem.h @@ -3939,12 +3939,6 @@ class ConstraintSystem { /// due to a change. ConstraintList &getActiveConstraints() { return ActiveConstraints; } - void findConstraints(SmallVectorImpl &found, - llvm::function_ref pred) { - filterConstraints(ActiveConstraints, pred, found); - filterConstraints(InactiveConstraints, pred, found); - } - /// Retrieve the representative of the equivalence class containing /// this type variable. TypeVariableType *getRepresentative(TypeVariableType *typeVar) const { @@ -4117,16 +4111,6 @@ class ConstraintSystem { /// into the worklist. void addTypeVariableConstraintsToWorkList(TypeVariableType *typeVar); - static void - filterConstraints(ConstraintList &constraints, - llvm::function_ref pred, - SmallVectorImpl &found) { - for (auto &constraint : constraints) { - if (pred(constraint)) - found.push_back(&constraint); - } - } - public: /// Coerce the given expression to an rvalue, if it isn't already. diff --git a/include/swift/Serialization/SerializedSILLoader.h b/include/swift/Serialization/SerializedSILLoader.h index 83d58649f31f8..8ae8b77ff1647 100644 --- a/include/swift/Serialization/SerializedSILLoader.h +++ b/include/swift/Serialization/SerializedSILLoader.h @@ -60,9 +60,7 @@ class SerializedSILLoader { ~SerializedSILLoader(); SILFunction *lookupSILFunction(SILFunction *Callee, bool onlyUpdateLinkage); - SILFunction * - lookupSILFunction(StringRef Name, bool declarationOnly = false, - Optional linkage = None); + SILFunction *lookupSILFunction(StringRef Name, Optional linkage); bool hasSILFunction(StringRef Name, Optional linkage = None); SILVTable *lookupVTable(const ClassDecl *C); SILWitnessTable *lookupWitnessTable(SILWitnessTable *C); diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 59f534d3418ac..61953985fd68e 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -22,6 +22,7 @@ #include "swift/AST/ConcreteDeclRef.h" #include "swift/AST/DiagnosticEngine.h" #include "swift/AST/DiagnosticsSema.h" +#include "swift/AST/DistributedDecl.h" #include "swift/AST/ExistentialLayout.h" #include "swift/AST/FileUnit.h" #include "swift/AST/ForeignAsyncConvention.h" @@ -1258,47 +1259,19 @@ FuncDecl *ASTContext::getEqualIntDecl() const { return getBinaryComparisonOperatorIntDecl(*this, "==", getImpl().EqualIntDecl); } -AbstractFunctionDecl *ASTContext::getRemoteCallOnDistributedActorSystem( - NominalTypeDecl *actorOrSystem, bool isVoidReturn) const { - assert(actorOrSystem && "distributed actor (or system) decl must be provided"); - const NominalTypeDecl *system = actorOrSystem; - if (actorOrSystem->isDistributedActor()) { - auto var = actorOrSystem->getDistributedActorSystemProperty(); - system = var->getInterfaceType()->getAnyNominal(); - } - - if (!system) - system = getProtocol(KnownProtocolKind::DistributedActorSystem); - - auto mutableSystem = const_cast(system); - return evaluateOrDefault( - system->getASTContext().evaluator, - GetDistributedActorSystemRemoteCallFunctionRequest{mutableSystem, /*isVoidReturn=*/isVoidReturn}, - nullptr); -} - FuncDecl *ASTContext::getMakeInvocationEncoderOnDistributedActorSystem( - NominalTypeDecl *actorOrSystem) const { - NominalTypeDecl *system = actorOrSystem; - assert(actorOrSystem && "distributed actor (or system) decl must be provided"); - if (actorOrSystem->isDistributedActor()) { - auto var = actorOrSystem->getDistributedActorSystemProperty(); - system = var->getInterfaceType()->getAnyNominal(); - } + AbstractFunctionDecl *thunk) const { + auto systemTy = getConcreteReplacementForProtocolActorSystemType(thunk); + assert(systemTy && "No specific ActorSystem type found!"); - for (auto result : system->lookupDirect(Id_makeInvocationEncoder)) { - auto *fd = dyn_cast(result); - if (!fd) - continue; - if (fd->getParameters()->size() != 0) - continue; - if (fd->hasAsync()) - continue; - if (fd->hasThrows()) - continue; - // TODO(distributed): more checks, return type etc + auto systemNominal = systemTy->getNominalOrBoundGenericNominal(); + assert(systemNominal && "No system nominal type found!"); - return fd; + for (auto result : systemNominal->lookupDirect(Id_makeInvocationEncoder)) { + auto *func = dyn_cast(result); + if (func && func->isDistributedActorSystemMakeInvocationEncoder()) { + return func; + } } return nullptr; @@ -1308,29 +1281,11 @@ FuncDecl * ASTContext::getRecordGenericSubstitutionOnDistributedInvocationEncoder( NominalTypeDecl *nominal) const { for (auto result : nominal->lookupDirect(Id_recordGenericSubstitution)) { - auto *fd = dyn_cast(result); - if (!fd) - continue; - if (fd->getParameters()->size() != 1) - continue; - if (fd->hasAsync()) - continue; - if (!fd->hasThrows()) - continue; - // TODO(distributed): more checks - - auto genericParamList = fd->getGenericParams(); - - // A single generic parameter. - if (genericParamList->size() != 1) - continue; - - // No requirements on the generic parameter - if (fd->getGenericRequirements().size() != 0) - continue; - - if (fd->getResultInterfaceType()->isVoid()) - return fd; + auto *func = dyn_cast(result); + if (func && + func->isDistributedTargetInvocationEncoderRecordGenericSubstitution()) { + return func; + } } return nullptr; @@ -4444,7 +4399,8 @@ CanTypeWrapper OpenedArchetypeType::get(CanType existential, GenericSignature parentSig, Optional knownID) { assert(existential->isExistentialType()); - auto interfaceType = OpenedArchetypeType::getSelfInterfaceTypeFromContext(parentSig, existential->getASTContext()); + auto interfaceType = OpenedArchetypeType::getSelfInterfaceTypeFromContext( + parentSig, existential->getASTContext()); return get(existential, interfaceType, parentSig, knownID); } @@ -4510,7 +4466,8 @@ CanType OpenedArchetypeType::getAny(CanType existential, Type interfaceType, CanType OpenedArchetypeType::getAny(CanType existential, GenericSignature parentSig) { - auto interfaceTy = OpenedArchetypeType::getSelfInterfaceTypeFromContext(parentSig, existential->getASTContext()); + auto interfaceTy = OpenedArchetypeType::getSelfInterfaceTypeFromContext( + parentSig, existential->getASTContext()); return getAny(existential, interfaceTy, parentSig); } @@ -5201,7 +5158,8 @@ ASTContext::getOpenedArchetypeSignature(Type type, GenericSignature parentSig) { type = existential->getConstraintType(); const CanType constraint = type->getCanonicalType(); - assert(!constraint->hasTypeParameter() && "This only works with archetypes"); + assert(parentSig || !constraint->hasTypeParameter() && + "Interface type here requires a parent signature"); // The opened archetype signature for a protocol type is identical // to the protocol's own canonical generic signature if there aren't any @@ -5216,11 +5174,13 @@ ASTContext::getOpenedArchetypeSignature(Type type, GenericSignature parentSig) { // generic parameters. This ensures that we keep e.g. generic superclass // existentials contained in a well-formed generic context. auto canParentSig = parentSig.getCanonicalSignature(); - auto found = getImpl().ExistentialSignatures.find({constraint, canParentSig.getPointer()}); + auto key = std::make_pair(constraint, canParentSig.getPointer()); + auto found = getImpl().ExistentialSignatures.find(key); if (found != getImpl().ExistentialSignatures.end()) return found->second; - auto genericParam = OpenedArchetypeType::getSelfInterfaceTypeFromContext(canParentSig, type->getASTContext()) + auto genericParam = OpenedArchetypeType::getSelfInterfaceTypeFromContext( + canParentSig, type->getASTContext()) ->castTo(); Requirement requirement(RequirementKind::Conformance, genericParam, constraint); @@ -5231,7 +5191,7 @@ ASTContext::getOpenedArchetypeSignature(Type type, GenericSignature parentSig) { CanGenericSignature canGenericSig(genericSig); auto result = getImpl().ExistentialSignatures.insert( - std::make_pair(std::make_pair(constraint, canParentSig.getPointer()), canGenericSig)); + std::make_pair(key, canGenericSig)); assert(result.second); (void) result; diff --git a/lib/AST/ASTDemangler.cpp b/lib/AST/ASTDemangler.cpp index 2ab79f1b6c618..0ae70a080434c 100644 --- a/lib/AST/ASTDemangler.cpp +++ b/lib/AST/ASTDemangler.cpp @@ -621,6 +621,14 @@ Type ASTBuilder::createExistentialMetatypeType(Type instance, getMetatypeRepresentation(*repr)); } +Type ASTBuilder::createParameterizedProtocolType(Type base, + ArrayRef args) { + if (!base->getAs()) + return Type(); + return ParameterizedProtocolType::get(base->getASTContext(), + base->castTo(), args); +} + Type ASTBuilder::createMetatypeType(Type instance, Optional repr) { if (!repr) diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp index a76d67bf3c594..0b61e905fc9dd 100644 --- a/lib/AST/ASTDumper.cpp +++ b/lib/AST/ASTDumper.cpp @@ -748,6 +748,9 @@ namespace { PrintWithColorRAII(OS, DeclModifierColor) << " lazy"; printStorageImpl(VD); printAccessors(VD); + if (VD->getAttrs().hasAttribute()) { + OS << " known-to-be-local"; + } PrintWithColorRAII(OS, ParenthesisColor) << ')'; } @@ -858,8 +861,11 @@ namespace { D->getCaptureInfo().print(OS); } + if (D->getAttrs().hasAttribute()) { + PrintWithColorRAII(OS, ExprModifierColor) << " nonisolated"; + } if (D->isDistributed()) { - OS << " distributed"; + PrintWithColorRAII(OS, ExprModifierColor) << " distributed"; } if (auto fac = D->getForeignAsyncConvention()) { @@ -893,6 +899,9 @@ namespace { OS.indent(Indent); PrintWithColorRAII(OS, ParenthesisColor) << '('; PrintWithColorRAII(OS, ParameterColor) << "parameter "; + if (P->getAttrs().hasAttribute()) { + OS << "known-to-be-local "; + } printDeclName(P); if (!P->getArgumentName().empty()) PrintWithColorRAII(OS, IdentifierColor) @@ -1317,6 +1326,10 @@ void ValueDecl::dumpRef(raw_ostream &os) const { os << moduleName; } + if (getAttrs().hasAttribute()) { + os << " known-to-be-local"; + } + // Print location. auto &srcMgr = getASTContext().SourceMgr; if (getLoc().isValid()) { diff --git a/lib/AST/ASTMangler.cpp b/lib/AST/ASTMangler.cpp index 78db761c4be1d..3e8dc0d0c9b36 100644 --- a/lib/AST/ASTMangler.cpp +++ b/lib/AST/ASTMangler.cpp @@ -1269,8 +1269,11 @@ void ASTMangler::appendType(Type type, GenericSignature sig, } case TypeKind::ParameterizedProtocol: { - llvm::errs() << "Not implemented\n"; - abort(); + auto layout = type->getExistentialLayout(); + appendExistentialLayout(layout, sig, forDecl); + bool isFirstArgList = true; + appendBoundGenericArgs(type, sig, isFirstArgList, forDecl); + return appendOperator("XP"); } case TypeKind::Existential: { @@ -1574,6 +1577,9 @@ void ASTMangler::appendBoundGenericArgs(Type type, GenericSignature sig, if (Type parent = nominalType->getParent()) appendBoundGenericArgs(parent->getDesugaredType(), sig, isFirstArgList, forDecl); + } else if (auto *ppt = dyn_cast(typePtr)) { + assert(!ppt->getBaseType()->getParent()); + genericArgs = ppt->getArgs(); } else { auto boundType = cast(typePtr); genericArgs = boundType->getGenericArgs(); diff --git a/lib/AST/ASTVerifier.cpp b/lib/AST/ASTVerifier.cpp index 7a30e871fc0ad..2da20ad72189b 100644 --- a/lib/AST/ASTVerifier.cpp +++ b/lib/AST/ASTVerifier.cpp @@ -1469,6 +1469,25 @@ class Verifier : public ASTWalker { verifyCheckedBase(E); } + bool shouldVerify(ErasureExpr *expr) { + if (!shouldVerify(cast(expr))) + return false; + + for (auto &elt : expr->getArgumentConversions()) { + assert(!OpaqueValues.count(elt.OrigValue)); + OpaqueValues[elt.OrigValue] = 0; + } + + return true; + } + + void cleanup(ErasureExpr *expr) { + for (auto &elt : expr->getArgumentConversions()) { + assert(OpaqueValues.count(elt.OrigValue)); + OpaqueValues.erase(elt.OrigValue); + } + } + void verifyChecked(ErasureExpr *E) { PrettyStackTraceExpr debugStack(Ctx, "verifying ErasureExpr", E); diff --git a/lib/AST/ASTWalker.cpp b/lib/AST/ASTWalker.cpp index b2f50f56b195e..926d6b8b414a1 100644 --- a/lib/AST/ASTWalker.cpp +++ b/lib/AST/ASTWalker.cpp @@ -695,7 +695,29 @@ class Traversal : public ASTVisitorgetSubExpr())) { + E->setSubExpr(E2); + } else { + return nullptr; + } + + for (unsigned i = 0; i < E->getArgumentConversions().size(); ++i) { + const auto &conv = E->getArgumentConversions()[i]; + auto kConv = conv.Conversion; + if (!kConv) { + return nullptr; + } else if (Expr *E2 = doIt(kConv)) { + E->setArgumentConversion(i, {conv.OrigValue, E2}); + } else { + return nullptr; + } + } + + return E; + } + Expr *visitCollectionUpcastConversionExpr(CollectionUpcastConversionExpr *E) { if (Expr *E2 = doIt(E->getSubExpr())) { E->setSubExpr(E2); diff --git a/lib/AST/CMakeLists.txt b/lib/AST/CMakeLists.txt index 618b361f6276b..ce74b7fe8baf2 100644 --- a/lib/AST/CMakeLists.txt +++ b/lib/AST/CMakeLists.txt @@ -83,6 +83,7 @@ add_swift_host_library(swiftAST STATIC RequirementMachine/InterfaceType.cpp RequirementMachine/KnuthBendix.cpp RequirementMachine/MinimalConformances.cpp + RequirementMachine/NormalizeRewritePath.cpp RequirementMachine/PropertyMap.cpp RequirementMachine/PropertyRelations.cpp RequirementMachine/PropertyUnification.cpp diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 85ab068772dd2..cb8ceaba71b6a 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -2926,7 +2926,7 @@ CanType ValueDecl::getOverloadSignatureType() const { /*topLevelFunction=*/true, isMethod, /*isInitializer=*/isa(afd), getNumCurryLevels()) - ->getCanonicalType(); + ->getMinimalCanonicalType(afd); } if (isa(this)) { @@ -2942,7 +2942,7 @@ CanType ValueDecl::getOverloadSignatureType() const { /*topLevelFunction=*/true, /*isMethod=*/false, /*isInitializer=*/false, getNumCurryLevels()) - ->getCanonicalType(); + ->getMinimalCanonicalType(cast(this)); } // We want to curry the default signature type with the 'self' type of the @@ -2957,7 +2957,7 @@ CanType ValueDecl::getOverloadSignatureType() const { auto mappedType = mapSignatureFunctionType( getASTContext(), getInterfaceType(), /*topLevelFunction=*/false, /*isMethod=*/false, /*isInitializer=*/false, getNumCurryLevels()); - return mappedType->getCanonicalType(); + return mappedType->getMinimalCanonicalType(getDeclContext()); } // Note: If you add more cases to this function, you should update the @@ -4085,9 +4085,9 @@ GenericParameterReferenceInfo swift::findGenericParameterReferences( } GenericParameterReferenceInfo ValueDecl::findExistentialSelfReferences( - Type baseTy, const DeclContext *useDC, - bool treatNonResultCovariantSelfAsInvariant) const { + Type baseTy, bool treatNonResultCovariantSelfAsInvariant) const { assert(baseTy->isExistentialType()); + assert(!baseTy->hasTypeParameter()); // Types never refer to 'Self'. if (isa(this)) @@ -4099,9 +4099,12 @@ GenericParameterReferenceInfo ValueDecl::findExistentialSelfReferences( if (type->hasError()) return GenericParameterReferenceInfo(); - const auto sig = - getASTContext().getOpenedArchetypeSignature(baseTy, - useDC->getGenericSignatureOfContext()); + // Note: a non-null GenericSignature would violate the invariant that + // the protocol 'Self' type referenced from the requirement's interface + // type is the same as the existential 'Self' type. + auto sig = getASTContext().getOpenedArchetypeSignature(baseTy, + GenericSignature()); + auto genericParam = sig.getGenericParams().front(); return findGenericParameterReferences( this, sig, genericParam, treatNonResultCovariantSelfAsInvariant, None); @@ -5310,11 +5313,6 @@ bool ProtocolDecl::isMarkerProtocol() const { return getAttrs().hasAttribute(); } -bool ProtocolDecl::inheritsFromDistributedActor() const { - auto &C = getASTContext(); - return inheritsFrom(C.getDistributedActorDecl()); -} - ArrayRef ProtocolDecl::getInheritedProtocols() const { auto *mutThis = const_cast(this); return evaluateOrDefault(getASTContext().evaluator, @@ -6377,6 +6375,10 @@ bool VarDecl::isDistributed() const { return getAttrs().hasAttribute(); } +bool VarDecl::isKnownToBeLocal() const { + return getAttrs().hasAttribute(); +} + bool VarDecl::isOrdinaryStoredProperty() const { // we assume if it hasAttachedPropertyWrapper, it has no storage. // @@ -7996,7 +7998,6 @@ ParamDecl *AbstractFunctionDecl::getImplicitSelfDecl(bool createIfNeeded) { *selfDecl = new (ctx) ParamDecl(SourceLoc(), SourceLoc(), Identifier(), getLoc(), ctx.Id_self, this); (*selfDecl)->setImplicit(); - return *selfDecl; } diff --git a/lib/AST/DistributedDecl.cpp b/lib/AST/DistributedDecl.cpp index 23fc23bf4b39b..bd88538af9fef 100644 --- a/lib/AST/DistributedDecl.cpp +++ b/lib/AST/DistributedDecl.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors +// 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 @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// // -// This file implements the Decl class and subclasses. +// This file handles lookups related to distributed actor decls. // //===----------------------------------------------------------------------===// @@ -65,19 +65,50 @@ using namespace swift; /************** Distributed Actor System Associated Types *********************/ /******************************************************************************/ +// TODO(distributed): make into a request +Type swift::getConcreteReplacementForProtocolActorSystemType(ValueDecl *member) { + auto &C = member->getASTContext(); + auto *DC = member->getDeclContext(); + auto DA = C.getDistributedActorDecl(); + + // === When declared inside an actor, we can get the type directly + if (auto classDecl = DC->getSelfClassDecl()) { + return getDistributedActorSystemType(classDecl); + } + + /// === Maybe the value is declared in a protocol? + if (auto protocol = DC->getSelfProtocolDecl()) { + GenericSignature signature; + if (auto *genericContext = member->getAsGenericContext()) { + signature = genericContext->getGenericSignature(); + } else { + signature = DC->getGenericSignatureOfContext(); + } + + auto ActorSystemAssocType = + DA->getAssociatedType(C.Id_ActorSystem)->getDeclaredInterfaceType(); + + // Note that this may be null, e.g. if we're a distributed func inside + // a protocol that did not declare a specific actor system requirement. + return signature->getConcreteType(ActorSystemAssocType); + } + + llvm_unreachable("Unable to fetch ActorSystem type!"); +} + Type swift::getDistributedActorSystemType(NominalTypeDecl *actor) { assert(actor->isDistributedActor()); - auto &ctx = actor->getASTContext(); + auto &C = actor->getASTContext(); - auto protocol = ctx.getProtocol(KnownProtocolKind::DistributedActor); - if (!protocol) - return ErrorType::get(ctx); + auto DA = C.getDistributedActorDecl(); + if (!DA) + return ErrorType::get(C); // Dig out the actor system type. auto module = actor->getParentModule(); Type selfType = actor->getSelfInterfaceType(); - auto conformance = module->lookupConformance(selfType, protocol); - return conformance.getTypeWitnessByName(selfType, ctx.Id_ActorSystem); + auto conformance = module->lookupConformance(selfType, DA); + return conformance.getTypeWitnessByName(selfType, C.Id_ActorSystem); } Type swift::getDistributedActorIDType(NominalTypeDecl *actor) { @@ -89,7 +120,7 @@ Type swift::getDistributedActorSystemActorIDRequirementType(NominalTypeDecl *sys assert(!system->isDistributedActor()); auto &ctx = system->getASTContext(); - auto protocol = ctx.getProtocol(KnownProtocolKind::DistributedActorSystem); + auto protocol = ctx.getDistributedActorSystemDecl(); if (!protocol) return Type(); @@ -100,8 +131,24 @@ Type swift::getDistributedActorSystemActorIDRequirementType(NominalTypeDecl *sys return conformance.getTypeWitnessByName(selfType, ctx.Id_ActorID); } +Type swift::getDistributedActorSystemInvocationEncoderType(NominalTypeDecl *system) { + assert(!system->isDistributedActor()); + auto &ctx = system->getASTContext(); + + auto protocol = ctx.getDistributedActorSystemDecl(); + if (!protocol) + return Type(); + + // Dig out the serialization requirement type. + auto module = system->getParentModule(); + Type selfType = system->getSelfInterfaceType(); + auto conformance = module->lookupConformance(selfType, protocol); + return conformance.getTypeWitnessByName(selfType, ctx.Id_InvocationEncoder); +} + Type swift::getDistributedSerializationRequirementType( NominalTypeDecl *nominal, ProtocolDecl *protocol) { + assert(nominal); assert(protocol); auto &ctx = nominal->getASTContext(); @@ -128,7 +175,7 @@ Type ASTContext::getAssociatedTypeOfDistributedSystemOfActor( if (!actorSystemDecl) return Type(); - auto actorSystemProtocol = ctx.getProtocol(KnownProtocolKind::DistributedActorSystem); + auto actorSystemProtocol = ctx.getDistributedActorSystemDecl(); if (!actorSystemProtocol) return Type(); @@ -148,11 +195,10 @@ Type ASTContext::getAssociatedTypeOfDistributedSystemOfActor( actorProtocol, selfType, conformance)); } -//Type ASTContext::getDistributedSerializationRequirementType( -// NominalTypeDecl *nominal) { -// return getAssociatedTypeOfDistributedSystemOfActor(nominal, -// Id_SerializationRequirement); -//} +/******************************************************************************/ +/******** Functions on DistributedActorSystem and friends *********************/ +/******************************************************************************/ + FuncDecl* ASTContext::getDistributedActorArgumentDecodingMethod(NominalTypeDecl *actor) { @@ -252,7 +298,7 @@ bool AbstractFunctionDecl::isDistributedActorSystemRemoteCall(bool isVoidReturn) // === Must be declared in a 'DistributedActorSystem' conforming type ProtocolDecl *systemProto = - C.getProtocol(KnownProtocolKind::DistributedActorSystem); + C.getDistributedActorSystemDecl(); auto systemNominal = getDeclContext()->getSelfNominalTypeDecl(); auto distSystemConformance = module->lookupConformance( @@ -457,6 +503,79 @@ bool AbstractFunctionDecl::isDistributedActorSystemRemoteCall(bool isVoidReturn) return true; } +bool +AbstractFunctionDecl::isDistributedActorSystemMakeInvocationEncoder() const { + auto &C = getASTContext(); + auto module = getParentModule(); + + if (getBaseIdentifier() != C.Id_makeInvocationEncoder) { + return false; + } + + auto *func = dyn_cast(this); + if (!func) { + return false; + } + if (func->getParameters()->size() != 0) { + return false; + } + if (func->hasAsync()) { + return false; + } + if (func->hasThrows()) { + return false; + } + + auto returnTy = func->getResultInterfaceType(); + auto conformance = module->lookupConformance( + returnTy, C.getDistributedTargetInvocationEncoderDecl()); + if (conformance.isInvalid()) { + return false; + } + + return true; +} + +bool +AbstractFunctionDecl::isDistributedTargetInvocationEncoderRecordGenericSubstitution() const { + auto &C = getASTContext(); + + if (getBaseIdentifier() != C.Id_recordGenericSubstitution) { + return false; + } + + auto *fd = dyn_cast(this); + if (!fd) { + return false; + } + if (fd->getParameters()->size() != 1) { + return false; + } + if (fd->hasAsync()) { + return false; + } + if (!fd->hasThrows()) { + return false; + } + // TODO(distributed): more checks + + // A single generic parameter. + auto genericParamList = fd->getGenericParams(); + if (genericParamList->size() != 1) { + return false; + } + + // No requirements on the generic parameter + if (fd->getGenericRequirements().size() != 0) { + return false; + } + + if (!fd->getResultInterfaceType()->isVoid()) + return false; + + return true; +} + bool AbstractFunctionDecl::isDistributedTargetInvocationEncoderRecordArgument() const { auto &C = getASTContext(); @@ -577,6 +696,11 @@ AbstractFunctionDecl::isDistributedTargetInvocationEncoderRecordReturnType() con auto &C = getASTContext(); auto module = getParentModule(); + auto func = dyn_cast(this); + if (!func) { + return false; + } + // === Check base name if (getBaseIdentifier() != C.Id_recordReturnType) { return false; @@ -605,14 +729,11 @@ AbstractFunctionDecl::isDistributedTargetInvocationEncoderRecordReturnType() con return false; } - // TODO(distributed): not sure how, but this fails Distributed/distributed_actor_accessor_section_macho.swift - // in the sense that it does not find the mutating on the declaration inside FakeDistributedActorSystems.swift - // even though it definitely is there on a source level hm... -// // --- must be mutating, if it is defined in a struct -// if (isa(getDeclContext()) && -// !getAttrs().hasAttribute()) { -// return false; -// } + // --- must be mutating, if it is defined in a struct + if (isa(getDeclContext()) && + !func->isMutating()) { + return false; + } // === Check generics if (!isGeneric()) { @@ -667,11 +788,6 @@ AbstractFunctionDecl::isDistributedTargetInvocationEncoderRecordReturnType() con // conforms_to: Argument Encodable // ... - auto func = dyn_cast(this); - if (!func) { - return false; - } - auto resultType = func->mapTypeIntoContext(argumentParam->getInterfaceType()) ->getMetatypeInstanceType() ->getDesugaredType(); @@ -704,6 +820,11 @@ AbstractFunctionDecl::isDistributedTargetInvocationEncoderRecordErrorType() cons auto &C = getASTContext(); auto module = getParentModule(); + auto func = dyn_cast(this); + if (!func) { + return false; + } + // === Check base name if (getBaseIdentifier() != C.Id_recordErrorType) { return false; @@ -734,7 +855,7 @@ AbstractFunctionDecl::isDistributedTargetInvocationEncoderRecordErrorType() cons // --- must be mutating, if it is defined in a struct if (isa(getDeclContext()) && - !getAttrs().hasAttribute()) { + !func->isMutating()) { return false; } @@ -793,11 +914,6 @@ AbstractFunctionDecl::isDistributedTargetInvocationEncoderRecordErrorType() cons } // === Check result type: Void - auto func = dyn_cast(this); - if (!func) { - return false; - } - if (!func->getResultInterfaceType()->isVoid()) { return false; } @@ -810,6 +926,11 @@ AbstractFunctionDecl::isDistributedTargetInvocationDecoderDecodeNextArgument() c auto &C = getASTContext(); auto module = getParentModule(); + auto func = dyn_cast(this); + if (!func) { + return false; + } + // === Check base name if (getBaseIdentifier() != C.Id_decodeNextArgument) { return false; @@ -840,7 +961,7 @@ AbstractFunctionDecl::isDistributedTargetInvocationDecoderDecodeNextArgument() c // --- must be mutating, if it is defined in a struct if (isa(getDeclContext()) && - !getAttrs().hasAttribute()) { + !func->isMutating()) { return false; } @@ -872,11 +993,6 @@ AbstractFunctionDecl::isDistributedTargetInvocationDecoderDecodeNextArgument() c } // === Check generic parameters in detail - auto func = dyn_cast(this); - if (!func) { - return false; - } - // --- Check: Argument: SerializationRequirement GenericTypeParamDecl *ArgumentParam = genericParams->getParams()[0]; auto resultType = func->mapTypeIntoContext(func->getResultInterfaceType()) @@ -968,7 +1084,7 @@ llvm::SmallPtrSet swift::extractDistributedSerializationRequirements( ASTContext &C, ArrayRef allRequirements) { llvm::SmallPtrSet serializationReqs; - auto systemProto = C.getProtocol(KnownProtocolKind::DistributedActorSystem); + auto systemProto = C.getDistributedActorSystemDecl(); auto serializationReqAssocType = systemProto->getAssociatedType(C.Id_SerializationRequirement); auto systemSerializationReqTy = serializationReqAssocType->getInterfaceType(); @@ -1024,10 +1140,44 @@ NominalTypeDecl::getDistributedRemoteCallTargetInitFunction() const { GetDistributedRemoteCallTargetInitFunctionRequest(mutableThis), nullptr); } +AbstractFunctionDecl *ASTContext::getRemoteCallOnDistributedActorSystem( + NominalTypeDecl *actorOrSystem, bool isVoidReturn) const { + assert(actorOrSystem && "distributed actor (or system) decl must be provided"); + const NominalTypeDecl *system = actorOrSystem; + if (actorOrSystem->isDistributedActor()) { + if (auto systemTy = + getConcreteReplacementForProtocolActorSystemType(actorOrSystem)) { + system = systemTy->getNominalOrBoundGenericNominal(); + } + } + + // If no concrete system was found, return the general protocol: + if (!system) + system = getProtocol(KnownProtocolKind::DistributedActorSystem); + + auto mutableSystem = const_cast(system); + return evaluateOrDefault( + system->getASTContext().evaluator, + GetDistributedActorSystemRemoteCallFunctionRequest{mutableSystem, /*isVoidReturn=*/isVoidReturn}, + nullptr); +} + /******************************************************************************/ /********************** Distributed Actor Properties **************************/ /******************************************************************************/ +FuncDecl* +AbstractFunctionDecl::getDistributedThunk() const { + if (!isDistributed()) + return nullptr; + + auto mutableThis = const_cast(this); + return evaluateOrDefault( + getASTContext().evaluator, + GetDistributedThunkRequest{mutableThis}, + nullptr); +} + VarDecl* NominalTypeDecl::getDistributedActorSystemProperty() const { if (!isDistributedActor()) diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 385889709f5a4..8c07e1169c5e8 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -1178,14 +1178,16 @@ SequenceExpr *SequenceExpr::create(ASTContext &ctx, ArrayRef elements) { assert(elements.size() & 1 && "even number of elements in sequence"); size_t bytes = totalSizeToAlloc(elements.size()); void *Buffer = ctx.Allocate(bytes, alignof(SequenceExpr)); - return ::new(Buffer) SequenceExpr(elements); + return ::new (Buffer) SequenceExpr(elements); } ErasureExpr *ErasureExpr::create(ASTContext &ctx, Expr *subExpr, Type type, - ArrayRef conformances){ - auto size = totalSizeToAlloc(conformances.size()); + ArrayRef conformances, + ArrayRef argConversions) { + auto size = totalSizeToAlloc(conformances.size(), + argConversions.size()); auto mem = ctx.Allocate(size, alignof(ErasureExpr)); - return ::new(mem) ErasureExpr(subExpr, type, conformances); + return ::new (mem) ErasureExpr(subExpr, type, conformances, argConversions); } UnresolvedSpecializeExpr *UnresolvedSpecializeExpr::create(ASTContext &ctx, @@ -1194,8 +1196,8 @@ UnresolvedSpecializeExpr *UnresolvedSpecializeExpr::create(ASTContext &ctx, SourceLoc RAngleLoc) { auto size = totalSizeToAlloc(UnresolvedParams.size()); auto mem = ctx.Allocate(size, alignof(UnresolvedSpecializeExpr)); - return ::new(mem) UnresolvedSpecializeExpr(SubExpr, LAngleLoc, - UnresolvedParams, RAngleLoc); + return ::new (mem) UnresolvedSpecializeExpr(SubExpr, LAngleLoc, + UnresolvedParams, RAngleLoc); } CaptureListEntry::CaptureListEntry(PatternBindingDecl *PBD) : PBD(PBD) { diff --git a/lib/AST/GenericSignature.cpp b/lib/AST/GenericSignature.cpp index 1837de0d74ebd..07b3dc946cd50 100644 --- a/lib/AST/GenericSignature.cpp +++ b/lib/AST/GenericSignature.cpp @@ -827,6 +827,9 @@ void GenericSignature::verify(ArrayRef reqts) const { // We collect conformance requirements to check that they're minimal. llvm::SmallDenseMap, 2> conformances; + // We collect same-type requirements to check that they're minimal. + llvm::SmallDenseMap, 2> sameTypeComponents; + // Check that the requirements satisfy certain invariants. for (unsigned idx : indices(reqts)) { const auto &reqt = reqts[idx].getCanonical(); @@ -873,6 +876,10 @@ void GenericSignature::verify(ArrayRef reqts) const { auto firstType = reqt.getFirstType(); auto secondType = reqt.getSecondType(); + + auto canType = canSig->getCanonicalTypeInContext(firstType); + auto &component = sameTypeComponents[canType]; + if (!hasCanonicalOrConcreteParent(firstType)) { llvm::errs() << "Left hand side does not have a canonical parent: "; reqt.dump(llvm::errs()); @@ -893,6 +900,18 @@ void GenericSignature::verify(ArrayRef reqts) const { llvm::errs() << "\n"; abort(); } + + if (component.empty()) { + component.push_back(firstType); + } else if (!component.back()->isEqual(firstType)) { + llvm::errs() << "Same-type requirement within an equiv. class " + << "is out-of-order: "; + reqt.dump(llvm::errs()); + llvm::errs() << "\n"; + abort(); + } + + component.push_back(secondType); } else { if (!canSig->isCanonicalTypeInContext(secondType)) { llvm::errs() << "Right hand side is not canonical: "; @@ -900,6 +919,15 @@ void GenericSignature::verify(ArrayRef reqts) const { llvm::errs() << "\n"; abort(); } + + if (component.empty()) { + component.push_back(secondType); + } else if (!component.back()->isEqual(secondType)) { + llvm::errs() << "Inconsistent concrete requirement in equiv. class: "; + reqt.dump(llvm::errs()); + llvm::errs() << "\n"; + abort(); + } } break; } @@ -925,33 +953,6 @@ void GenericSignature::verify(ArrayRef reqts) const { abort(); } - // If we have two same-type requirements where the left-hand sides differ - // but fall into the same equivalence class, we can check the form. - if (compareLHS < 0 && reqt.getKind() == RequirementKind::SameType && - prevReqt.getKind() == RequirementKind::SameType && - canSig->areSameTypeParameterInContext(prevReqt.getFirstType(), - reqt.getFirstType())) { - // If it's a it's a type parameter, make sure the equivalence class is - // wired together sanely. - if (prevReqt.getSecondType()->isTypeParameter()) { - if (!prevReqt.getSecondType()->isEqual(reqt.getFirstType())) { - llvm::errs() << "Same-type requirement within an equiv. class " - << "is out-of-order: "; - reqt.dump(llvm::errs()); - llvm::errs() << "\n"; - abort(); - } - } else { - // Otherwise, the concrete types must match up. - if (!prevReqt.getSecondType()->isEqual(reqt.getSecondType())) { - llvm::errs() << "Inconsistent concrete requirement in equiv. class: "; - reqt.dump(llvm::errs()); - llvm::errs() << "\n"; - abort(); - } - } - } - // If we have a concrete same-type requirement, we shouldn't have any // other requirements on the same type. if (reqt.getKind() == RequirementKind::SameType && @@ -974,7 +975,7 @@ void GenericSignature::verify(ArrayRef reqts) const { } // Make sure we don't have redundant protocol conformance requirements. - for (auto pair : conformances) { + for (const auto &pair : conformances) { const auto &protos = pair.second; auto canonicalProtos = protos; @@ -992,6 +993,18 @@ void GenericSignature::verify(ArrayRef reqts) const { abort(); } } + + // Check same-type components for consistency. + for (const auto &pair : sameTypeComponents) { + if (pair.second.front()->isTypeParameter() && + !canSig->isCanonicalTypeInContext(pair.second.front())) { + llvm::errs() << "Abstract same-type requirement involving concrete types\n"; + llvm::errs() << "Canonical type: " << pair.first << "\n"; + llvm::errs() << "Left hand side of first requirement: " + << pair.second.front() << "\n"; + abort(); + } + } } static Type stripBoundDependentMemberTypes(Type t) { diff --git a/lib/AST/Parameter.cpp b/lib/AST/Parameter.cpp index 32a66bd58ea34..b4918f0d5b95a 100644 --- a/lib/AST/Parameter.cpp +++ b/lib/AST/Parameter.cpp @@ -52,6 +52,7 @@ void ParameterList::setDeclContextOfParamDecls(DeclContext *DC) { /// the ParamDecls, so they can be reparented into a new DeclContext. ParameterList *ParameterList::clone(const ASTContext &C, OptionSet options) const { + // TODO(distributed): copy types thanks to flag in options // If this list is empty, don't actually bother with a copy. if (size() == 0) return const_cast(this); diff --git a/lib/AST/RequirementMachine/ConcreteTypeWitness.cpp b/lib/AST/RequirementMachine/ConcreteTypeWitness.cpp index 382537bc8c692..ffb31a03ba0bd 100644 --- a/lib/AST/RequirementMachine/ConcreteTypeWitness.cpp +++ b/lib/AST/RequirementMachine/ConcreteTypeWitness.cpp @@ -483,7 +483,7 @@ void PropertyMap::recordConcreteConformanceRule( auto protocolSymbol = *conformanceRule.isPropertyRule(); - // Now, transform T''.[concrete: C].[P] into T''.[concrete: C : P]. + // Now, transform T''.[concrete: C].[P] into T''.[concrete: C].[concrete: C : P]. unsigned relationID = System.recordConcreteConformanceRelation( concreteSymbol, protocolSymbol, concreteConformanceSymbol); @@ -491,6 +491,21 @@ void PropertyMap::recordConcreteConformanceRule( /*startOffset=*/rhs.size(), relationID, /*inverse=*/false)); + // If T' is a suffix of T, prepend the prefix to the concrete type's + // substitutions. + if (prefixLength > 0 && + !concreteConformanceSymbol.getSubstitutions().empty()) { + path.add(RewriteStep::forPrefixSubstitutions(prefixLength, /*endOffset=*/1, + /*inverse=*/true)); + } + + // Finally, apply the concrete type rule to obtain T''.[concrete: C : P]. + path.add(RewriteStep::forRewriteRule( + /*startOffset=*/rhs.size() - concreteRule.getRHS().size(), + /*endOffset=*/1, + /*ruleID=*/concreteRuleID, + /*inverse=*/false)); + MutableTerm lhs(rhs); lhs.add(concreteConformanceSymbol); diff --git a/lib/AST/RequirementMachine/HomotopyReduction.cpp b/lib/AST/RequirementMachine/HomotopyReduction.cpp index 0ce53065a382f..fc8c33d26504a 100644 --- a/lib/AST/RequirementMachine/HomotopyReduction.cpp +++ b/lib/AST/RequirementMachine/HomotopyReduction.cpp @@ -55,15 +55,18 @@ #include "swift/Basic/Range.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" #include +#include "RewriteContext.h" #include "RewriteSystem.h" using namespace swift; using namespace rewriting; -/// Recompute RulesInEmptyContext and DecomposeCount if needed. +/// Recompute Useful, RulesInEmptyContext, ProjectionCount and DecomposeCount +/// if needed. void RewriteLoop::recompute(const RewriteSystem &system) { if (!Dirty) return; @@ -109,6 +112,8 @@ void RewriteLoop::recompute(const RewriteSystem &system) { evaluator.apply(step, system); } + Useful = !rulesInEmptyContext.empty(); + RulesInEmptyContext.clear(); // Collect all rules that we saw exactly once in empty context. @@ -146,6 +151,14 @@ unsigned RewriteLoop::getDecomposeCount( return DecomposeCount; } +/// The number of Decompose steps, used by the elimination order to prioritize +/// loops that are not concrete simplifications. +bool RewriteLoop::isUseful( + const RewriteSystem &system) const { + const_cast(this)->recompute(system); + return Useful; +} + /// If a rewrite loop contains an explicit rule in empty context, propagate the /// explicit bit to all other rules appearing in empty context within the same /// loop. @@ -418,16 +431,22 @@ findRuleToDelete(llvm::function_ref isRedundantRuleFn) { if (loop.isDeleted()) continue; - bool foundAny = false; + // Delete loops that don't contain any rewrite rules in empty context, + // since such loops do not yield any elimination candidates. + if (!loop.isUseful(*this)) { + if (Debug.contains(DebugFlags::HomotopyReduction)) { + llvm::dbgs() << "** Deleting useless loop #" << loopID << ": "; + loop.dump(llvm::dbgs(), *this); + llvm::dbgs() << "\n"; + } + + loop.markDeleted(); + continue; + } + for (unsigned ruleID : loop.findRulesAppearingOnceInEmptyContext(*this)) { redundancyCandidates.emplace_back(loopID, ruleID); - foundAny = true; } - - // Delete loops that don't contain any rewrite rules in empty context, - // since such loops do not give us useful information. - if (!foundAny) - loop.markDeleted(); } Optional> found; @@ -609,6 +628,10 @@ void RewriteSystem::deleteRule(unsigned ruleID, if (!changed) continue; + if (Context.getASTContext().LangOpts.EnableRequirementMachineLoopNormalization) { + loop.computeNormalForm(*this); + } + // The loop's path has changed, so we must invalidate the cached // result of findRulesAppearingOnceInEmptyContext(). loop.markDirty(); @@ -658,6 +681,34 @@ void RewriteSystem::performHomotopyReduction( } } +void RewriteSystem::normalizeRedundantRules() { + for (auto &pair : RedundantRules) { + pair.second.computeNormalForm(*this); + } + + if (Debug.contains(DebugFlags::RedundantRules)) { + llvm::dbgs() << "\nRedundant rules:\n"; + for (const auto &pair : RedundantRules) { + const auto &rule = getRule(pair.first); + llvm::dbgs() << "- (" + << rule.getLHS() << " => " + << rule.getRHS() << ") ::== "; + + MutableTerm lhs(rule.getLHS()); + pair.second.dump(llvm::dbgs(), lhs, *this); + + llvm::dbgs() << "\n"; + + if (Debug.contains(DebugFlags::RedundantRulesDetail)) { + llvm::dbgs() << "\n"; + pair.second.dumpLong(llvm::dbgs(), lhs, *this); + + llvm::dbgs() << "\n\n"; + } + } + } +} + /// Use the loops to delete redundant rewrite rules via a series of Tietze /// transformations, updating and simplifying existing loops as each rule /// is deleted. @@ -677,6 +728,12 @@ void RewriteSystem::minimizeRewriteSystem() { propagateExplicitBits(); processConflicts(); + if (Context.getASTContext().LangOpts.EnableRequirementMachineLoopNormalization) { + for (auto &loop : Loops) { + loop.computeNormalForm(*this); + } + } + // First pass: // - Eliminate all LHS-simplified non-conformance rules. // - Eliminate all RHS-simplified and substitution-simplified rules. @@ -753,25 +810,7 @@ void RewriteSystem::minimizeRewriteSystem() { verifyRedundantConformances(redundantConformances); verifyMinimizedRules(redundantConformances); - if (Debug.contains(DebugFlags::RedundantRules)) { - llvm::dbgs() << "\nRedundant rules:\n"; - for (const auto &pair : RedundantRules) { - const auto &rule = getRule(pair.first); - llvm::dbgs() << "- " << rule << " ::== "; - - MutableTerm lhs(rule.getLHS()); - pair.second.dump(llvm::dbgs(), lhs, *this); - - llvm::dbgs() << "\n"; - - if (Debug.contains(DebugFlags::RedundantRulesDetail)) { - llvm::dbgs() << "\n"; - pair.second.dumpLong(llvm::dbgs(), lhs, *this); - - llvm::dbgs() << "\n\n"; - } - } - } + normalizeRedundantRules(); } /// In a conformance-valid rewrite system, any rule with unresolved symbols on diff --git a/lib/AST/RequirementMachine/NormalizeRewritePath.cpp b/lib/AST/RequirementMachine/NormalizeRewritePath.cpp new file mode 100644 index 0000000000000..4d369fe4620d0 --- /dev/null +++ b/lib/AST/RequirementMachine/NormalizeRewritePath.cpp @@ -0,0 +1,241 @@ +//===--- LeftCanonicalForm.cpp - Left canonical form of a rewrite path ----===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2021 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 +// +//===----------------------------------------------------------------------===// +// +// Algorithm for reducing a rewrite path to left-canonical form: +// +// - Adjacent steps that are inverses of each other cancel out. for example +// these two steps will be eliminated: +// +// (A => B) ⊗ (B => A) +// +// - Interchange law moves rewrites "to the left", for example +// +// X.(U => V) ⊗ (X => Y).V +// +// becomes +// +// (X => Y).U ⊗ Y.(U => V) +// +// These two transformations are iterated until fixed point to produce a +// equivalent rewrite path that is simpler. +// +// From "Homotopy reduction systems for monoid presentations", +// https://www.sciencedirect.com/science/article/pii/S0022404997000959 +// +//===----------------------------------------------------------------------===// + +#include "RewriteLoop.h" +#include "RewriteSystem.h" +#include "llvm/ADT/SmallVector.h" +#include + +using namespace swift; +using namespace rewriting; + +/// Returns true if this rewrite step is an inverse of \p other +/// (and vice versa). +bool RewriteStep::isInverseOf(const RewriteStep &other) const { + if (Kind != other.Kind) + return false; + + if (StartOffset != other.StartOffset) + return false; + + if (Inverse != !other.Inverse) + return false; + + switch (Kind) { + case RewriteStep::Rule: + return Arg == other.Arg; + + default: + return false; + } + + assert(EndOffset == other.EndOffset && "Bad whiskering?"); + return true; +} + +bool RewriteStep::maybeSwapRewriteSteps(RewriteStep &other, + const RewriteSystem &system) { + if (Kind != RewriteStep::Rule || + other.Kind != RewriteStep::Rule) + return false; + + // Two rewrite steps are _orthogonal_ if they rewrite disjoint subterms + // in context. Orthogonal rewrite steps commute, so we can canonicalize + // a path by placing the left-most step first. + // + // Eg, A.U.B.(X => Y).C ⊗ A.(U => V).B.Y == A.(U => V).B.X ⊗ A.V.B.(X => Y). + // + // Or, in diagram form. We want to turn this: + // + // ----- time -----> + // +---------+---------+ + // | A | A | + // +---------+---------+ + // | U | U ==> V | + // +---------+---------+ + // | B | B | + // +---------+---------+ + // | X ==> Y | Y | + // +---------+---------+ + // | C | C | + // +---------+---------+ + // + // Into this: + // + // +---------+---------+ + // | A | A | + // +---------+---------+ + // | U ==> V | V | + // +---------+---------+ + // | B | B | + // +---------+---------+ + // | X | X ==> Y | + // +---------+---------+ + // | C | C | + // +---------+---------+ + // + // Note that + // + // StartOffset == |A|+|U|+|B| + // EndOffset = |C| + // + // other.StartOffset = |A| + // other.EndOffset = |B|+|Y|+|C| + // + // After interchange, we adjust: + // + // StartOffset = |A| + // EndOffset = |B|+|X|+|C| + // + // other.StartOffset = |A|+|V|+|B| + // other.EndOffset = |C| + + const auto &rule = system.getRule(Arg); + auto lhs = (Inverse ? rule.getRHS() : rule.getLHS()); + auto rhs = (Inverse ? rule.getLHS() : rule.getRHS()); + + const auto &otherRule = system.getRule(other.Arg); + auto otherLHS = (other.Inverse ? otherRule.getRHS() : otherRule.getLHS()); + auto otherRHS = (other.Inverse ? otherRule.getLHS() : otherRule.getRHS()); + + if (StartOffset < other.StartOffset + otherLHS.size()) + return false; + + std::swap(*this, other); + EndOffset += (lhs.size() - rhs.size()); + other.StartOffset += (otherRHS.size() - otherLHS.size()); + + return true; +} + +/// Cancels out adjacent rewrite steps that are inverses of each other. +/// This does not change either endpoint of the path, and the path does +/// not necessarily need to be a loop. +bool RewritePath::computeFreelyReducedForm() { + SmallVector newSteps; + bool changed = false; + + for (const auto &step : Steps) { + if (!newSteps.empty() && + newSteps.back().isInverseOf(step)) { + changed = true; + newSteps.pop_back(); + continue; + } + + newSteps.push_back(step); + } + + if (!changed) + return false; + std::swap(newSteps, Steps); + return changed; +} + +/// Apply the interchange rule until fixed point (see maybeSwapRewriteSteps()). +bool RewritePath::computeLeftCanonicalForm(const RewriteSystem &system) { + bool changed = false; + + for (unsigned i = 1, e = Steps.size(); i < e; ++i) { + auto &prevStep = Steps[i - 1]; + auto &step = Steps[i]; + + if (prevStep.maybeSwapRewriteSteps(step, system)) + changed = true; + } + + return changed; +} + +/// Compute freely-reduced left-canonical normal form of a path. +void RewritePath::computeNormalForm(const RewriteSystem &system) { + // FIXME: This can be more efficient. + bool changed; + do { + changed = false; + changed |= computeFreelyReducedForm(); + changed |= computeLeftCanonicalForm(system); + } while (changed); +} + +/// Given a path that is a loop around the given basepoint, cancels out +/// pairs of terms from the ends that are inverses of each other, applying +/// the corresponding translation to the basepoint. +/// +/// For example, consider this loop with basepoint 'X': +/// +/// (X => Y.A) * (Y.A => Y.B) * Y.(B => A) * (Y.A => X) +/// +/// The first step is the inverse of the last step, so the cyclic +/// reduction is the loop (Y.A => Y.B) * Y.(B => A), with a new +/// basepoint 'Y.A'. +bool RewritePath::computeCyclicallyReducedForm(MutableTerm &basepoint, + const RewriteSystem &system) { + RewritePathEvaluator evaluator(basepoint); + unsigned count = 0; + + while (2 * count + 1 < size()) { + auto left = Steps[count]; + auto right = Steps[Steps.size() - count - 1]; + if (!left.isInverseOf(right)) + break; + + // Update the basepoint by applying the first step in the path. + evaluator.apply(left, system); + + ++count; + } + + std::rotate(Steps.begin(), Steps.begin() + count, Steps.end() - count); + Steps.erase(Steps.end() - 2 * count, Steps.end()); + + basepoint = evaluator.getCurrentTerm(); + return count > 0; +} + +/// Compute cyclically-reduced left-canonical normal form of a loop. +void RewriteLoop::computeNormalForm(const RewriteSystem &system) { + // FIXME: This can be more efficient. + bool changed; + do { + changed = false; + changed |= Path.computeFreelyReducedForm(); + changed |= Path.computeCyclicallyReducedForm(Basepoint, system); + changed |= Path.computeLeftCanonicalForm(system); + + if (changed) + markDirty(); + } while (changed); +} \ No newline at end of file diff --git a/lib/AST/RequirementMachine/PropertyRelations.cpp b/lib/AST/RequirementMachine/PropertyRelations.cpp index c796ba99ef07b..739687c4fafe9 100644 --- a/lib/AST/RequirementMachine/PropertyRelations.cpp +++ b/lib/AST/RequirementMachine/PropertyRelations.cpp @@ -65,9 +65,9 @@ unsigned RewriteSystem::recordRelation(Symbol lhsProperty, Term::get(rhsTerm, Context)); } -/// Record a relation ([concrete: C].[P] => [concrete: C : P]) -/// or ([superclass: C].[P] => [concrete: C : P]) which combines a -/// concrete type symbol (or a superclass symbol) with a protocol +/// Record a relation ([concrete: C].[P] => [concrete: C].[concrete: C : P]) +/// or ([superclass: C].[P] => [superclass: C].[concrete: C : P]) which combines +/// a concrete type symbol (or a superclass symbol) with a protocol /// symbol to form a single a concrete conformance symbol. unsigned RewriteSystem::recordConcreteConformanceRelation( Symbol concreteSymbol, Symbol protocolSymbol, @@ -83,6 +83,7 @@ unsigned RewriteSystem::recordConcreteConformanceRelation( lhsTerm.add(protocolSymbol); MutableTerm rhsTerm; + rhsTerm.add(concreteSymbol); rhsTerm.add(concreteConformanceSymbol); return recordRelation( diff --git a/lib/AST/RequirementMachine/RewriteLoop.h b/lib/AST/RequirementMachine/RewriteLoop.h index a5b22597d677e..9dc14602c949c 100644 --- a/lib/AST/RequirementMachine/RewriteLoop.h +++ b/lib/AST/RequirementMachine/RewriteLoop.h @@ -355,6 +355,11 @@ struct RewriteStep { RewritePathEvaluator &evaluator, const RewriteSystem &system) const; + bool isInverseOf(const RewriteStep &other) const; + + bool maybeSwapRewriteSteps(RewriteStep &other, + const RewriteSystem &system); + private: static unsigned getConcreteProjectionArg(unsigned differenceID, unsigned substitutionIndex) { @@ -406,6 +411,15 @@ class RewritePath { void invert(); + bool computeFreelyReducedForm(); + + bool computeCyclicallyReducedForm(MutableTerm &basepoint, + const RewriteSystem &system); + + bool computeLeftCanonicalForm(const RewriteSystem &system); + + void computeNormalForm(const RewriteSystem &system); + void dump(llvm::raw_ostream &out, MutableTerm term, const RewriteSystem &system) const; @@ -440,12 +454,18 @@ class RewriteLoop { /// Cached value for getDecomposeCount(). unsigned DecomposeCount : 15; - /// Loops are deleted once they no longer contain rules in empty context, - /// since at that point they don't participate in minimization and do not - /// need to be considered. + /// A useful loop contains at least one rule in empty context, even if that + /// rule appears multiple times or also in non-empty context. The only loops + /// that are elimination candidates contain a rule in empty context *exactly + /// once*. A useful loop can become an elimination candidate after + /// normalization. + unsigned Useful : 1; + + /// Loops are deleted once they are no longer useful, as defined above. unsigned Deleted : 1; - /// If true, RulesInEmptyContext should be recomputed. + /// If true, Useful, RulesInEmptyContext, ProjectionCount, and DecomposeCount + /// should be recomputed. unsigned Dirty : 1; void recompute(const RewriteSystem &system); @@ -455,11 +475,11 @@ class RewriteLoop { : Basepoint(basepoint), Path(path) { ProjectionCount = 0; DecomposeCount = 0; - + Useful = 0; Deleted = 0; - // Initially, RulesInEmptyContext and ProjectionCount are not valid because - // they have not been computed yet. + // Initially, cached values are not valid because they have not been + // computed yet. Dirty = 1; } @@ -477,7 +497,7 @@ class RewriteLoop { Dirty = 1; } - bool isInContext(const RewriteSystem &system) const; + bool isUseful(const RewriteSystem &system) const; ArrayRef findRulesAppearingOnceInEmptyContext(const RewriteSystem &system) const; @@ -491,6 +511,8 @@ class RewriteLoop { ProtocolConformanceRules, 2> &result, const RewriteSystem &system) const; + void computeNormalForm(const RewriteSystem &system); + void verify(const RewriteSystem &system) const; void dump(llvm::raw_ostream &out, const RewriteSystem &system) const; diff --git a/lib/AST/RequirementMachine/RewriteSystem.cpp b/lib/AST/RequirementMachine/RewriteSystem.cpp index 465c973ead667..00d5150b5291d 100644 --- a/lib/AST/RequirementMachine/RewriteSystem.cpp +++ b/lib/AST/RequirementMachine/RewriteSystem.cpp @@ -627,7 +627,7 @@ void RewriteSystem::recordRewriteLoop(MutableTerm basepoint, if (!RecordLoops) return; - // Ignore the rewrite rule if it is not part of our minimization domain. + // Ignore the rewrite loop if it is not part of our minimization domain. if (!isInMinimizationDomain(basepoint.getRootProtocol())) return; diff --git a/lib/AST/RequirementMachine/RewriteSystem.h b/lib/AST/RequirementMachine/RewriteSystem.h index 25514c3de6a3c..be5e1118056bf 100644 --- a/lib/AST/RequirementMachine/RewriteSystem.h +++ b/lib/AST/RequirementMachine/RewriteSystem.h @@ -486,6 +486,8 @@ class RewriteSystem final { void computeMinimalConformances( llvm::DenseSet &redundantConformances); + void normalizeRedundantRules(); + public: void recordRewriteLoop(MutableTerm basepoint, RewritePath path); diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 6b453fa087221..4dc1e9caec456 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -106,6 +106,8 @@ NominalTypeDecl *CanType::getAnyNominal() const { GenericTypeDecl *CanType::getAnyGeneric() const { if (auto existential = dyn_cast(*this)) return existential->getConstraintType()->getAnyGeneric(); + if (auto ppt = dyn_cast(*this)) + return ppt->getBaseType()->getDecl(); if (auto Ty = dyn_cast(*this)) return Ty->getDecl(); return nullptr; @@ -380,6 +382,20 @@ bool CanType::isTypeErasedGenericClassTypeImpl(CanType type) { return false; } +static bool archetypeConformsTo(ArchetypeType *archetype, KnownProtocolKind protocol) { + auto &ctx = archetype->getASTContext(); + auto expectedProto = ctx.getProtocol(protocol); + if (!expectedProto) + return false; + + for (auto proto : archetype->getConformsTo()) { + if (proto == expectedProto || proto->inheritsFrom(expectedProto)) + return true; + } + + return false; +} + bool TypeBase::isActorType() { // Nominal types: check whether the declaration is an actor. if (auto nominal = getAnyNominal()) @@ -387,16 +403,7 @@ bool TypeBase::isActorType() { // Archetypes check for conformance to Actor. if (auto archetype = getAs()) { - auto actorProto = getASTContext().getProtocol(KnownProtocolKind::Actor); - if (!actorProto) - return false; - - for (auto proto : archetype->getConformsTo()) { - if (proto == actorProto || proto->inheritsFrom(actorProto)) - return true; - } - - return false; + return archetypeConformsTo(archetype, KnownProtocolKind::Actor); } // Existential types: check for Actor protocol. @@ -422,6 +429,40 @@ bool TypeBase::isActorType() { return false; } +bool TypeBase::isDistributedActor() { + // Nominal types: check whether the declaration is an actor. + if (auto *nominal = getAnyNominal()) { + if (auto *classDecl = dyn_cast(nominal)) + return classDecl->isDistributedActor(); + + if (isa(nominal) || isa(nominal)) + return false; + } + + // Archetypes check for conformance to DistributedActor. + if (auto archetype = getAs()) { + return archetypeConformsTo(archetype, KnownProtocolKind::DistributedActor); + } + + // Existential types: check for DistributedActor protocol conformance. + if (isExistentialType()) { + auto actorProto = getASTContext().getDistributedActorDecl(); + if (!actorProto) + return false; + + // TODO(distributed): Inheritance is not yet supported. + + auto layout = getExistentialLayout(); + return llvm::any_of(layout.getProtocols(), + [&actorProto](ProtocolType *protocol) { + return protocol->getDecl() == actorProto || + protocol->isDistributedActor(); + }); + } + + return false; +} + bool TypeBase::isSpecialized() { Type t = getCanonicalType(); diff --git a/lib/AST/TypeRepr.cpp b/lib/AST/TypeRepr.cpp index d77e551b4fc63..b5910874c035f 100644 --- a/lib/AST/TypeRepr.cpp +++ b/lib/AST/TypeRepr.cpp @@ -211,6 +211,8 @@ void AttributedTypeRepr::printAttrs(ASTPrinter &Printer, Printer.printSimpleAttr("@autoclosure") << " "; if (hasAttr(TAK_escaping)) Printer.printSimpleAttr("@escaping") << " "; + if (hasAttr(TAK_Sendable)) + Printer.printSimpleAttr("@Sendable") << " "; if (hasAttr(TAK_noDerivative)) Printer.printSimpleAttr("@noDerivative") << " "; diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp index 941424d6e264f..227cd6ec6642a 100644 --- a/lib/ClangImporter/ClangImporter.cpp +++ b/lib/ClangImporter/ClangImporter.cpp @@ -3675,7 +3675,8 @@ std::string ClangImporter::getClangModuleHash() const { return Impl.Invocation->getModuleHash(Impl.Instance->getDiagnostics()); } -Decl *ClangImporter::importDeclCached(const clang::NamedDecl *ClangDecl) { +Optional +ClangImporter::importDeclCached(const clang::NamedDecl *ClangDecl) { return Impl.importDeclCached(ClangDecl, Impl.CurrentVersion); } diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp index 0b5737e2ae245..68efb9405a138 100644 --- a/lib/ClangImporter/ImportDecl.cpp +++ b/lib/ClangImporter/ImportDecl.cpp @@ -4841,8 +4841,9 @@ namespace { // While importing the DeclContext, we might have imported the decl // itself. - if (auto Known = Impl.importDeclCached(decl, getVersion())) - return Known; + auto Known = Impl.importDeclCached(decl, getVersion()); + if (Known.hasValue()) + return Known.getValue(); ImportedName importedName; std::tie(importedName, std::ignore) = importFullName(decl); @@ -4926,8 +4927,11 @@ namespace { } private: - static bool isAcceptableResult(Decl *fn, - Optional accessorInfo) { + static bool isAcceptableResultOrNull(Decl *fn, + Optional accessorInfo) { + if (nullptr == fn) + return true; + // We can't safely re-use the same declaration if it disagrees // in accessor-ness. auto accessor = dyn_cast(fn); @@ -5038,7 +5042,7 @@ namespace { getVersion()}); if (known != Impl.ImportedDecls.end()) { auto decl = known->second; - if (isAcceptableResult(decl, accessorInfo)) + if (isAcceptableResultOrNull(decl, accessorInfo)) return decl; } } @@ -5056,7 +5060,7 @@ namespace { if (isActiveSwiftVersion()) { if (isMethodAlreadyImported(selector, importedName, isInstance, dc, [&](AbstractFunctionDecl *fn) { - return isAcceptableResult(fn, accessorInfo); + return isAcceptableResultOrNull(fn, accessorInfo); })) { return nullptr; } @@ -5190,7 +5194,7 @@ namespace { getVersion()}); if (known != Impl.ImportedDecls.end()) { auto decl = known->second; - if (isAcceptableResult(decl, accessorInfo)) + if (isAcceptableResultOrNull(decl, accessorInfo)) return decl; } } @@ -5885,8 +5889,9 @@ namespace { // While importing the DeclContext, we might have imported the decl // itself. - if (auto Known = Impl.importDeclCached(decl, getVersion())) - return Known; + auto Known = Impl.importDeclCached(decl, getVersion()); + if (Known.hasValue()) + return Known.getValue(); return importObjCPropertyDecl(decl, dc); } @@ -8589,16 +8594,16 @@ void SwiftDeclConverter::importInheritedConstructors( } } -Decl *ClangImporter::Implementation::importDeclCached( +Optional ClangImporter::Implementation::importDeclCached( const clang::NamedDecl *ClangDecl, ImportNameVersion version, bool UseCanonical) { auto Known = ImportedDecls.find( { UseCanonical? ClangDecl->getCanonicalDecl(): ClangDecl, version }); - if (Known != ImportedDecls.end()) - return Known->second; + if (Known == ImportedDecls.end()) + return None; - return nullptr; + return Known->second; } /// Checks if we don't need to import the typedef itself. If the typedef @@ -9451,11 +9456,12 @@ Decl *ClangImporter::Implementation::importDeclAndCacheImpl( auto Canon = cast(UseCanonicalDecl? ClangDecl->getCanonicalDecl(): ClangDecl); - if (auto Known = importDeclCached(Canon, version, UseCanonicalDecl)) { + auto Known = importDeclCached(Canon, version, UseCanonicalDecl); + if (Known.hasValue()) { if (!SuperfluousTypedefsAreTransparent && SuperfluousTypedefs.count(Canon)) return nullptr; - return Known; + return Known.getValue(); } bool TypedefIsSuperfluous = false; @@ -9464,8 +9470,10 @@ Decl *ClangImporter::Implementation::importDeclAndCacheImpl( startedImportingEntity(); Decl *Result = importDeclImpl(ClangDecl, version, TypedefIsSuperfluous, HadForwardDeclaration); - if (!Result) + if (!Result) { + ImportedDecls[{Canon, version}] = nullptr; return nullptr; + } if (TypedefIsSuperfluous) { SuperfluousTypedefs.insert(Canon); @@ -9633,8 +9641,9 @@ ClangImporter::Implementation::importDeclForDeclContext( // There's a cycle. Is the declaration imported enough to break the cycle // gracefully? If so, we'll have it in the decl cache. - if (auto cached = importDeclCached(contextDecl, version, useCanonicalDecl)) - return cached; + auto cached = importDeclCached(contextDecl, version, useCanonicalDecl); + if (cached.hasValue()) + return cached.getValue(); // Can't break it? Warn and return nullptr, which is at least better than // stack overflow by recursion. diff --git a/lib/ClangImporter/ImporterImpl.h b/lib/ClangImporter/ImporterImpl.h index eb66e1e1df9a6..6829b37da7883 100644 --- a/lib/ClangImporter/ImporterImpl.h +++ b/lib/ClangImporter/ImporterImpl.h @@ -958,8 +958,9 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation /// If we already imported a given decl, return the corresponding Swift decl. /// Otherwise, return nullptr. - Decl *importDeclCached(const clang::NamedDecl *ClangDecl, Version version, - bool UseCanonicalDecl = true); + Optional importDeclCached(const clang::NamedDecl *ClangDecl, + Version version, + bool UseCanonicalDecl = true); Decl *importDeclImpl(const clang::NamedDecl *ClangDecl, Version version, bool &TypedefIsSuperfluous, bool &HadForwardDeclaration); diff --git a/lib/ClangImporter/Serializability.cpp b/lib/ClangImporter/Serializability.cpp index 05945dad0842a..c0d47c25ec70a 100644 --- a/lib/ClangImporter/Serializability.cpp +++ b/lib/ClangImporter/Serializability.cpp @@ -66,7 +66,10 @@ class SerializationPathFinder { StableSerializationPath findImportedPath(const clang::NamedDecl *decl) { // We've almost certainly imported this declaration, look for it. - if (auto swiftDecl = Impl.importDeclCached(decl, Impl.CurrentVersion)) { + Optional swiftDeclOpt = + Impl.importDeclCached(decl, Impl.CurrentVersion); + if (swiftDeclOpt.hasValue() && swiftDeclOpt.getValue()) { + auto swiftDecl = swiftDeclOpt.getValue(); // The serialization code doesn't allow us to cross-reference // typealias declarations directly. We could fix that, but it's // easier to just avoid doing so and fall into the external-path code. diff --git a/lib/Demangling/Demangler.cpp b/lib/Demangling/Demangler.cpp index 9c8b21ea89f82..9df7fdfcc9268 100644 --- a/lib/Demangling/Demangler.cpp +++ b/lib/Demangling/Demangler.cpp @@ -1815,6 +1815,12 @@ NodePointer Demangler::demangleBoundGenericArgs(NodePointer Nominal, case Node::Kind::Constructor: // Well, not really a nominal type. return createWithChildren(Node::Kind::BoundGenericFunction, Nominal, args); + case Node::Kind::Type: + if (!Nominal->hasChildren()) + return nullptr; + if (Nominal->getFirstChild()->getKind() != Node::Kind::ProtocolList) + return nullptr; + return createWithChildren(Node::Kind::ParameterizedProtocol, Nominal, args); default: return nullptr; } @@ -3253,6 +3259,22 @@ NodePointer Demangler::demangleSpecialType() { return createType(createWithChildren(Node::Kind::ExistentialMetatype, MTR, Type)); } + case 'P': { + NodePointer RetroactiveConformances; + Vector TypeListList(*this, 4); + + if (!demangleBoundGenerics(TypeListList, RetroactiveConformances)) + return nullptr; + + NodePointer Type = popNode(Node::Kind::Type); + if (!Type) + return nullptr; + + NodePointer BoundNode = demangleBoundGenericArgs(Type, TypeListList, 0); + NodePointer NTy = createType(BoundNode); + addSubstitution(NTy); + return NTy; + } case 'p': return createType(createWithChild(Node::Kind::ExistentialMetatype, popNode(Node::Kind::Type))); diff --git a/lib/Demangling/NodePrinter.cpp b/lib/Demangling/NodePrinter.cpp index 7a3dc8961a806..23320b552579c 100644 --- a/lib/Demangling/NodePrinter.cpp +++ b/lib/Demangling/NodePrinter.cpp @@ -306,6 +306,7 @@ class NodePrinter { case Node::Kind::MetatypeRepresentation: case Node::Kind::Module: case Node::Kind::Tuple: + case Node::Kind::ParameterizedProtocol: case Node::Kind::Protocol: case Node::Kind::ProtocolSymbolicReference: case Node::Kind::ReturnType: @@ -2024,7 +2025,7 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth, return nullptr; case Node::Kind::DistributedThunk: if (!Options.ShortenThunk) { - Printer << "distributed thunk for "; + Printer << "distributed thunk "; } return nullptr; case Node::Kind::DistributedAccessor: @@ -2270,6 +2271,10 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth, } return nullptr; } + case Node::Kind::ParameterizedProtocol: { + printBoundGeneric(Node, depth); + return nullptr; + } case Node::Kind::ExistentialMetatype: { unsigned Idx = 0; if (Node->getNumChildren() == 2) { diff --git a/lib/Demangling/OldRemangler.cpp b/lib/Demangling/OldRemangler.cpp index a667e220882fd..d295ace556f09 100644 --- a/lib/Demangling/OldRemangler.cpp +++ b/lib/Demangling/OldRemangler.cpp @@ -2714,7 +2714,10 @@ ManglingError Remangler::mangleObjCAsyncCompletionHandlerImpl(Node *node, unsigned depth) { return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node); } - +ManglingError Remangler::mangleParameterizedProtocol(Node *node, + unsigned int depth) { + return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node); +} ManglingError Remangler::mangleCanonicalSpecializedGenericMetaclass(Node *node, unsigned depth) { diff --git a/lib/Demangling/Remangler.cpp b/lib/Demangling/Remangler.cpp index 5b3bce92dda07..d1e0950df57c3 100644 --- a/lib/Demangling/Remangler.cpp +++ b/lib/Demangling/Remangler.cpp @@ -601,6 +601,13 @@ ManglingError Remangler::mangleGenericArgs(Node *node, char &Separator, break; } + case Node::Kind::ParameterizedProtocol: { + Buffer << Separator; + Separator = '_'; + RETURN_IF_ERROR(mangleChildNodes(node->getChild(1), depth + 1)); + break; + } + case Node::Kind::BoundGenericFunction: { fullSubstitutionMap = true; @@ -1218,6 +1225,15 @@ ManglingError Remangler::mangleErrorType(Node *node, unsigned depth) { return ManglingError::Success; } +ManglingError Remangler::mangleParameterizedProtocol(Node *node, + unsigned int depth) { + RETURN_IF_ERROR(mangleType(node->getChild(0), depth + 1)); + char separator = 'y'; + RETURN_IF_ERROR(mangleGenericArgs(node, separator, depth + 1)); + Buffer << "XP"; + return ManglingError::Success; +} + ManglingError Remangler::mangleExistentialMetatype(Node *node, unsigned depth) { if (node->getFirstChild()->getKind() == Node::Kind::MetatypeRepresentation) { RETURN_IF_ERROR(mangleChildNode(node, 1, depth + 1)); @@ -3475,6 +3491,7 @@ bool Demangle::isSpecialized(Node *node) { case Node::Kind::BoundGenericTypeAlias: case Node::Kind::BoundGenericProtocol: case Node::Kind::BoundGenericFunction: + case Node::Kind::ParameterizedProtocol: return true; case Node::Kind::Structure: @@ -3577,6 +3594,12 @@ ManglingErrorOr Demangle::getUnspecialized(Node *node, return nominalType; } + case Node::Kind::ParameterizedProtocol: { + NodePointer unboundType = node->getChild(0); + DEMANGLER_ASSERT(unboundType->getKind() == Node::Kind::Type, unboundType); + return unboundType; + } + case Node::Kind::BoundGenericFunction: { NodePointer unboundFunction = node->getChild(0); DEMANGLER_ASSERT(unboundFunction->getKind() == Node::Kind::Function || diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 5da1be92b2b0c..bf58496dc8a44 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -1005,6 +1005,9 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args, if (Args.hasArg(OPT_disable_requirement_machine_concrete_contraction)) Opts.EnableRequirementMachineConcreteContraction = false; + if (Args.hasArg(OPT_enable_requirement_machine_loop_normalization)) + Opts.EnableRequirementMachineLoopNormalization = true; + Opts.DumpTypeWitnessSystems = Args.hasArg(OPT_dump_type_witness_systems); return HadError || UnsupportedOS || UnsupportedArch; diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp index 9248f8d068608..fa193d4728746 100644 --- a/lib/IRGen/GenDecl.cpp +++ b/lib/IRGen/GenDecl.cpp @@ -2106,7 +2106,6 @@ getIRLinkage(const UniversalLinkageInfo &info, SILLinkage linkage, : RESULT(External, Hidden, Default); case SILLinkage::Shared: - case SILLinkage::SharedExternal: return isDefinition ? RESULT(LinkOnceODR, Hidden, Default) : RESULT(External, Hidden, Default); diff --git a/lib/IRGen/GenExistential.cpp b/lib/IRGen/GenExistential.cpp index d85bcbff44f85..6669b41130724 100644 --- a/lib/IRGen/GenExistential.cpp +++ b/lib/IRGen/GenExistential.cpp @@ -1445,7 +1445,7 @@ static const TypeInfo *createExistentialTypeInfo(IRGenModule &IGM, CanType T) { T = existential->getConstraintType()->getCanonicalType(); } llvm::StructType *type; - if (isa(T)) + if (isa(T) || isa(T)) type = IGM.createNominalType(T); else type = IGM.createNominalType(cast(T.getPointer())); diff --git a/lib/IRGen/GenMeta.cpp b/lib/IRGen/GenMeta.cpp index c675d55550519..eaa22e74c6bca 100644 --- a/lib/IRGen/GenMeta.cpp +++ b/lib/IRGen/GenMeta.cpp @@ -2080,7 +2080,6 @@ namespace { return true; case SILLinkage::Shared: - case SILLinkage::SharedExternal: case SILLinkage::PublicNonABI: return false; } diff --git a/lib/IRGen/IRGenModule.cpp b/lib/IRGen/IRGenModule.cpp index e52aa724c8579..cecce8192314f 100644 --- a/lib/IRGen/IRGenModule.cpp +++ b/lib/IRGen/IRGenModule.cpp @@ -1173,7 +1173,7 @@ bool IRGenerator::canEmitWitnessTableLazily(SILWitnessTable *wt) { } void IRGenerator::addLazyWitnessTable(const ProtocolConformance *Conf) { - if (auto *wt = SIL.lookUpWitnessTable(Conf, /*deserializeLazily=*/false)) { + if (auto *wt = SIL.lookUpWitnessTable(Conf)) { // Add it to the queue if it hasn't already been put there. if (canEmitWitnessTableLazily(wt) && LazilyEmittedWitnessTables.insert(wt).second) { diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 8f978e5d25a8e..8dd3be82e5a9b 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -1743,10 +1743,36 @@ void Parser::parseAllAvailabilityMacroArguments() { ParserStatus Parser::parsePlatformVersionInList(StringRef AttrName, llvm::SmallVector &PlatformAndVersions) { - // FIXME(backDeploy): Parse availability macros (e.g. SwiftStdlib: 5.1) SyntaxParsingContext argumentContext(SyntaxContext, SyntaxKind::AvailabilityVersionRestriction); + // Check for availability macros first. + if (peekAvailabilityMacroName()) { + SmallVector Specs; + ParserStatus MacroStatus = parseAvailabilityMacro(Specs); + if (MacroStatus.isError()) + return MacroStatus; + + for (auto *Spec : Specs) { + auto *PlatformVersionSpec = + dyn_cast(Spec); + // Since peekAvailabilityMacroName() only matches defined availability + // macros, we don't expect to get any other kind of spec here. + assert(PlatformVersionSpec && "Unexpected AvailabilitySpec kind"); + + auto Platform = PlatformVersionSpec->getPlatform(); + auto Version = PlatformVersionSpec->getVersion(); + if (Version.getSubminor().hasValue() || Version.getBuild().hasValue()) { + diagnose(PlatformVersionSpec->getVersionSrcRange().Start, + diag::attr_availability_platform_version_major_minor_only, + AttrName); + } + PlatformAndVersions.emplace_back(Platform, Version); + } + + return makeParserSuccess(); + } + // Expect a possible platform name (e.g. 'macOS' or '*'). if (!Tok.isAny(tok::identifier, tok::oper_binary_spaced)) { diagnose(Tok, diag::attr_availability_expected_platform, AttrName); @@ -1754,23 +1780,22 @@ ParserStatus Parser::parsePlatformVersionInList(StringRef AttrName, } // Parse the platform name. - auto MaybePlatform = platformFromString(Tok.getText()); + StringRef platformText = Tok.getText(); + auto MaybePlatform = platformFromString(platformText); SourceLoc PlatformLoc = Tok.getLoc(); - if (!MaybePlatform.hasValue()) { - diagnose(PlatformLoc, diag::attr_availability_unknown_platform, - Tok.getText(), AttrName); - return makeParserError(); - } consumeToken(); - PlatformKind Platform = *MaybePlatform; - // Wildcards ('*') aren't supported in this kind of list. If this list - // entry is just a wildcard, skip it. Wildcards with a version are - // diagnosed below. - if (Platform == PlatformKind::none && Tok.isAny(tok::comma, tok::r_paren)) { + if (!MaybePlatform.hasValue()) { + diagnose(PlatformLoc, diag::attr_availability_unknown_platform, + platformText, AttrName); + } else if (*MaybePlatform == PlatformKind::none) { + // Wildcards ('*') aren't supported in this kind of list. diagnose(PlatformLoc, diag::attr_availability_wildcard_ignored, AttrName); - return makeParserSuccess(); + + // If this list entry is just a wildcard, skip it. + if (Tok.isAny(tok::comma, tok::r_paren)) + return makeParserSuccess(); } // Parse version number. @@ -1789,13 +1814,13 @@ ParserStatus Parser::parsePlatformVersionInList(StringRef AttrName, AttrName); } - // Wildcards ('*') aren't supported in this kind of list. - if (Platform == PlatformKind::none) { - diagnose(PlatformLoc, diag::attr_availability_wildcard_ignored, - AttrName); - } else { - PlatformAndVersions.emplace_back(Platform, VerTuple); + if (MaybePlatform.hasValue()) { + auto Platform = *MaybePlatform; + if (Platform != PlatformKind::none) { + PlatformAndVersions.emplace_back(Platform, VerTuple); + } } + return makeParserSuccess(); } @@ -2448,91 +2473,11 @@ bool Parser::parseNewDeclAttribute(DeclAttributes &Attributes, SourceLoc AtLoc, } // Parse 'OSX 13.13'. case NextSegmentKind::PlatformVersion: { - SyntaxParsingContext argumentContext(SyntaxContext, - SyntaxKind::AvailabilityVersionRestriction); - if ((Tok.is(tok::identifier) || Tok.is(tok::oper_binary_spaced)) && - (peekToken().isAny(tok::integer_literal, tok::floating_literal) || - peekAvailabilityMacroName())) { - - PlatformKind Platform; - - if (peekAvailabilityMacroName()) { - // Handle availability macros first. - // - // The logic to search for macros and platform name could - // likely be handled by parseAvailabilitySpecList - // if we don't rely on parseList here. - SmallVector Specs; - ParserStatus MacroStatus = parseAvailabilityMacro(Specs); - if (MacroStatus.isError()) - return MacroStatus; - - for (auto *Spec : Specs) { - if (auto *PlatformVersionSpec = - dyn_cast(Spec)) { - auto Platform = PlatformVersionSpec->getPlatform(); - auto Version = PlatformVersionSpec->getVersion(); - if (Version.getSubminor().hasValue() || - Version.getBuild().hasValue()) { - diagnose(Tok.getLoc(), diag::originally_defined_in_major_minor_only); - } - PlatformAndVersions.emplace_back(Platform, Version); - - } else if (auto *PlatformAgnostic = - dyn_cast(Spec)) { - diagnose(PlatformAgnostic->getPlatformAgnosticNameLoc(), - PlatformAgnostic->isLanguageVersionSpecific() ? - diag::originally_defined_in_swift_version : - diag::originally_defined_in_package_description); - - } else if (auto *OtherPlatform = - dyn_cast(Spec)) { - diagnose(OtherPlatform->getStarLoc(), - diag::originally_defined_in_missing_platform_name); - - } else { - llvm_unreachable("Unexpected AvailabilitySpec kind."); - } - } - - return makeParserSuccess(); - } - - // Parse platform name. - auto Plat = platformFromString(Tok.getText()); - if (!Plat.hasValue()) { - diagnose(Tok.getLoc(), - diag::originally_defined_in_unrecognized_platform); - SuppressLaterDiags = true; - return makeParserError(); - } else { - consumeToken(); - Platform = *Plat; - } - // Parse version number - llvm::VersionTuple VerTuple; - SourceRange VersionRange; - if (parseVersionTuple(VerTuple, VersionRange, - Diagnostic(diag::attr_availability_expected_version, AttrName))) { - SuppressLaterDiags = true; - return makeParserError(); - } else { - if (VerTuple.getSubminor().hasValue() || - VerTuple.getBuild().hasValue()) { - diagnose(Tok.getLoc(), diag::originally_defined_in_major_minor_only); - } - // * as platform name isn't supported. - if (Platform == PlatformKind::none) { - diagnose(AtLoc, diag::originally_defined_in_missing_platform_name); - } else { - PlatformAndVersions.emplace_back(Platform, VerTuple); - } - return makeParserSuccess(); - } - } - diagnose(AtLoc, diag::originally_defined_in_need_platform_version); - SuppressLaterDiags = true; - return makeParserError(); + ParserStatus ListItemStatus = + parsePlatformVersionInList(AttrName, PlatformAndVersions); + if (ListItemStatus.isErrorOrHasCompletion()) + SuppressLaterDiags = true; + return ListItemStatus; } } llvm_unreachable("invalid next segment kind"); @@ -2544,7 +2489,7 @@ bool Parser::parseNewDeclAttribute(DeclAttributes &Attributes, SourceLoc AtLoc, return false; } if (PlatformAndVersions.empty()) { - diagnose(AtLoc, diag::originally_defined_in_need_platform_version); + diagnose(AtLoc, diag::attr_availability_need_platform_version, AttrName); return false; } diff --git a/lib/SIL/IR/AbstractionPattern.cpp b/lib/SIL/IR/AbstractionPattern.cpp index 204c4b0e3e549..aff14883d7559 100644 --- a/lib/SIL/IR/AbstractionPattern.cpp +++ b/lib/SIL/IR/AbstractionPattern.cpp @@ -1464,9 +1464,10 @@ class SubstFunctionTypePatternVisitor if (auto gp = handleTypeParameterInAbstractionPattern(pattern, t)) return gp; - assert(!pattern.getType()->hasTypeParameter() + assert(pattern.getType()->isExistentialType() || + (!pattern.getType()->hasTypeParameter() && !pattern.getType()->hasArchetype() - && !pattern.getType()->hasOpaqueArchetype()); + && !pattern.getType()->hasOpaqueArchetype())); return pattern.getType(); } diff --git a/lib/SIL/IR/Linker.cpp b/lib/SIL/IR/Linker.cpp index 8b2aa67a0fcf9..02e3ea8d4da4d 100644 --- a/lib/SIL/IR/Linker.cpp +++ b/lib/SIL/IR/Linker.cpp @@ -64,6 +64,7 @@ #include "swift/AST/SubstitutionMap.h" #include "swift/ClangImporter/ClangModule.h" #include "swift/SIL/FormalLinkage.h" +#include "swift/Serialization/SerializedSILLoader.h" #include using namespace swift; @@ -75,45 +76,69 @@ STATISTIC(NumFuncLinked, "Number of SIL functions linked"); // Linker Helpers //===----------------------------------------------------------------------===// -void SILLinkerVisitor::addFunctionToWorklist(SILFunction *F) { +void SILLinkerVisitor::deserializeAndPushToWorklist(SILFunction *F) { assert(F->isExternalDeclaration()); LLVM_DEBUG(llvm::dbgs() << "Imported function: " << F->getName() << "\n"); - if (Mod.loadFunction(F)) { - if (F->isExternalDeclaration()) - return; - - F->setBare(IsBare); - F->verify(); - Worklist.push_back(F); - Changed = true; - ++NumFuncLinked; + SILFunction *NewF = + Mod.getSILLoader()->lookupSILFunction(F, /*onlyUpdateLinkage*/ false); + assert(!NewF || NewF == F); + if (!NewF || F->isExternalDeclaration()) { + assert((!hasSharedVisibility(F->getLinkage()) || F->hasForeignBody()) && + "cannot deserialize shared function"); + return; } + + assert((bool)F->isSerialized() == !Mod.isSerialized() && + "the de-serializer did set the wrong serialized flag"); + + F->setBare(IsBare); + F->verify(); + Worklist.push_back(F); + Changed = true; + ++NumFuncLinked; } /// Deserialize a function and add it to the worklist for processing. -void SILLinkerVisitor::maybeAddFunctionToWorklist(SILFunction *F) { - // Don't need to do anything if the function already has a body. - if (!F->isExternalDeclaration()) +void SILLinkerVisitor::maybeAddFunctionToWorklist(SILFunction *F, + bool setToSerializable) { + SILLinkage linkage = F->getLinkage(); + assert((!setToSerializable || F->hasValidLinkageForFragileRef() || + hasSharedVisibility(linkage)) && + "called function has wrong linkage for serialized function"); + + if (!F->isExternalDeclaration()) { + // The function is already in the module, so no need to de-serialized it. + // But check if we need to set the IsSerialized flag. + // See the top-level comment for SILLinkerVisitor for details. + if (setToSerializable && !Mod.isSerialized() && + hasSharedVisibility(linkage) && !F->isSerialized()) { + F->setSerialized(IsSerialized); + + // Push the function to the worklist so that all referenced shared functions + // are also set to IsSerialized. + Worklist.push_back(F); + } return; + } // In the performance pipeline, we deserialize all reachable functions. if (isLinkAll()) - return addFunctionToWorklist(F); + return deserializeAndPushToWorklist(F); // Otherwise, make sure to deserialize shared functions; we need to // emit them into the client binary since they're not available // externally. - if (hasSharedVisibility(F->getLinkage())) - return addFunctionToWorklist(F); + if (hasSharedVisibility(linkage)) + return deserializeAndPushToWorklist(F); // Functions with PublicNonABI linkage are deserialized as having // HiddenExternal linkage when they are declarations, then they - // become SharedExternal after the body has been deserialized. + // become Shared after the body has been deserialized. // So try deserializing HiddenExternal functions too. - if (F->getLinkage() == SILLinkage::HiddenExternal) - return addFunctionToWorklist(F); + if (linkage == SILLinkage::HiddenExternal) + return deserializeAndPushToWorklist(F); // Update the linkage of the function in case it's different in the serialized // SIL than derived from the AST. This can be the case with cross-module- @@ -125,7 +150,7 @@ void SILLinkerVisitor::maybeAddFunctionToWorklist(SILFunction *F) { bool SILLinkerVisitor::processFunction(SILFunction *F) { // If F is a declaration, first deserialize it. if (F->isExternalDeclaration()) { - maybeAddFunctionToWorklist(F); + maybeAddFunctionToWorklist(F, /*setToSerializable*/ false); } else { Worklist.push_back(F); } @@ -134,6 +159,13 @@ bool SILLinkerVisitor::processFunction(SILFunction *F) { return Changed; } +bool SILLinkerVisitor::processConformance(ProtocolConformanceRef conformanceRef) { + visitProtocolConformance(conformanceRef); + process(); + return Changed; +} + + /// Deserialize the given VTable all SIL the VTable transitively references. void SILLinkerVisitor::linkInVTable(ClassDecl *D) { // Devirtualization already deserializes vtables as needed in both the @@ -151,10 +183,13 @@ void SILLinkerVisitor::linkInVTable(ClassDecl *D) { // Ok we found our VTable. Visit each function referenced by the VTable. If // any of the functions are external declarations, add them to the worklist // for processing. - for (auto P : Vtbl->getEntries()) { - // Deserialize and recursively walk any vtable entries that do not have - // bodies yet. - maybeAddFunctionToWorklist(P.getImplementation()); + for (auto &entry : Vtbl->getEntries()) { + SILFunction *impl = entry.getImplementation(); + if (!Vtbl->isSerialized() || impl->hasValidLinkageForFragileRef()) { + // Deserialize and recursively walk any vtable entries that do not have + // bodies yet. + maybeAddFunctionToWorklist(impl, Vtbl->isSerialized()); + } } } @@ -175,17 +210,20 @@ void SILLinkerVisitor::visitPartialApplyInst(PartialApplyInst *PAI) { } void SILLinkerVisitor::visitFunctionRefInst(FunctionRefInst *FRI) { - maybeAddFunctionToWorklist(FRI->getReferencedFunction()); + maybeAddFunctionToWorklist(FRI->getReferencedFunction(), + FRI->getFunction()->isSerialized()); } void SILLinkerVisitor::visitDynamicFunctionRefInst( DynamicFunctionRefInst *FRI) { - maybeAddFunctionToWorklist(FRI->getInitiallyReferencedFunction()); + maybeAddFunctionToWorklist(FRI->getInitiallyReferencedFunction(), + FRI->getFunction()->isSerialized()); } void SILLinkerVisitor::visitPreviousDynamicFunctionRefInst( PreviousDynamicFunctionRefInst *FRI) { - maybeAddFunctionToWorklist(FRI->getInitiallyReferencedFunction()); + maybeAddFunctionToWorklist(FRI->getInitiallyReferencedFunction(), + FRI->getFunction()->isSerialized()); } // Eagerly visiting all used conformances leads to a large blowup @@ -203,8 +241,7 @@ static bool mustDeserializeProtocolConformance(SILModule &M, ->getModuleScopeContext()); } -void SILLinkerVisitor::visitProtocolConformance( - ProtocolConformanceRef ref, const Optional &Member) { +void SILLinkerVisitor::visitProtocolConformance(ProtocolConformanceRef ref) { // If an abstract protocol conformance was passed in, do nothing. if (ref.isAbstract()) return; @@ -212,12 +249,29 @@ void SILLinkerVisitor::visitProtocolConformance( bool mustDeserialize = mustDeserializeProtocolConformance(Mod, ref); // Otherwise try and lookup a witness table for C. - auto C = ref.getConcrete(); + ProtocolConformance *C = ref.getConcrete(); if (!VisitedConformances.insert(C).second) return; - auto *WT = Mod.lookUpWitnessTable(C, mustDeserialize); + auto *WT = Mod.lookUpWitnessTable(C); + + if ((!WT || WT->isDeclaration()) && + (mustDeserialize || Mode == SILModule::LinkingMode::LinkAll)) { + if (!WT) { + RootProtocolConformance *rootC = C->getRootConformance(); + SILLinkage linkage = getLinkageForProtocolConformance(rootC, NotForDefinition); + WT = SILWitnessTable::create(Mod, linkage, + const_cast(rootC)); + } + // If the module is at or past the Lowered stage, then we can't do any + // further deserialization, since pre-IRGen SIL lowering changes the types + // of definitions to make them incompatible with canonical serialized SIL. + if (Mod.getStage() == SILStage::Lowered) + return; + + WT = Mod.getSILLoader()->lookupWitnessTable(WT); + } // If the looked up witness table is a declaration, there is nothing we can // do here. @@ -241,7 +295,7 @@ void SILLinkerVisitor::visitProtocolConformance( // However, we *must* pull in shared clang-importer-derived conformances // we potentially use, since we may not otherwise have a local definition. if (mustDeserializeProtocolConformance(Mod, c)) - visitProtocolConformance(c, None); + visitProtocolConformance(c); }; // For each entry in the witness table... @@ -249,18 +303,14 @@ void SILLinkerVisitor::visitProtocolConformance( switch (E.getKind()) { // If the entry is a witness method... case SILWitnessTable::WitnessKind::Method: { - // And we are only interested in deserializing a specific requirement - // and don't have that requirement, don't deserialize this method. - if (Member.hasValue() && E.getMethodWitness().Requirement != *Member) - continue; - // The witness could be removed by dead function elimination. if (!E.getMethodWitness().Witness) continue; // Otherwise, deserialize the witness if it has shared linkage, or if // we were asked to deserialize everything. - maybeAddFunctionToWorklist(E.getMethodWitness().Witness); + maybeAddFunctionToWorklist(E.getMethodWitness().Witness, + WT->isSerialized() || isAvailableExternally(WT->getLinkage())); break; } @@ -294,7 +344,7 @@ void SILLinkerVisitor::visitApplySubstitutions(SubstitutionMap subs) { // However, we *must* pull in shared clang-importer-derived conformances // we potentially use, since we may not otherwise have a local definition. if (mustDeserializeProtocolConformance(Mod, conformance)) { - visitProtocolConformance(conformance, None); + visitProtocolConformance(conformance); } } } @@ -310,7 +360,7 @@ void SILLinkerVisitor::visitInitExistentialAddrInst( // visiting the open_existential_addr/witness_method before the // init_existential_inst. for (ProtocolConformanceRef C : IEI->getConformances()) { - visitProtocolConformance(C, Optional()); + visitProtocolConformance(C); } } @@ -324,7 +374,7 @@ void SILLinkerVisitor::visitInitExistentialRefInst( // not going to be smart about this to enable avoiding any issues with // visiting the protocol_method before the init_existential_inst. for (ProtocolConformanceRef C : IERI->getConformances()) { - visitProtocolConformance(C, Optional()); + visitProtocolConformance(C); } } void SILLinkerVisitor::visitAllocRefDynamicInst(AllocRefDynamicInst *ARI) { diff --git a/lib/SIL/IR/Linker.h b/lib/SIL/IR/Linker.h index cf14fec651dc9..8e9b12af3888b 100644 --- a/lib/SIL/IR/Linker.h +++ b/lib/SIL/IR/Linker.h @@ -20,7 +20,57 @@ namespace swift { -/// Visitor that knows how to link in dependencies of SILInstructions. +/// Visits the call graph and makes sure that all required functions (according +/// to the linking `Mode`) are de-serialized and the `isSerialized` flag is set +/// correctly. +/// +/// If the Mode is LinkNormal, just de-serialize the bare minimum of what's +/// required for a non-optimized compilation. That are all referenced shared +/// functions, because shared functions must have a body. +/// +/// If the Mode is LinkAll, de-serialize the maximum amount of functions - for +/// optimized compilation. +/// +/// Also make sure that shared functions which are referenced from "IsSerialized" +/// functions also have the "IsSerialized" flag set. +/// Usually this already is enforced by SILGen and all passes which create new +/// functions. +/// Only in case a de-serialized function references a shared function which +/// already exists in the module as "IsNotSerialized", it's required to explicitly +/// set the "IsSerialized" flag. +/// +/// Example: +/// +/// Before de-serialization: +/// \code +/// sil @foo { +/// function_ref @publicFuncInOtherModule +/// function_ref @specializedFunction +/// } +/// sil shared @specializedFunction { // IsNotSerialized +/// function_ref @otherSpecializedFunction +/// } +/// sil shared @otherSpecializedFunction { // IsNotSerialized +/// } +/// \endcode +/// +/// After de-serialization: +/// \code +/// sil @foo { +/// function_ref @publicFuncInOtherModule +/// function_ref @specializedFunction +/// } +/// sil public_external [serialized] @publicFuncInOtherModule { +/// function_ref @specializedFunction +/// } +/// // Need to be changed to "IsSerialized" +/// sil shared [serialized] @specializedFunction { +/// function_ref @otherSpecializedFunction +/// } +/// sil shared [serialized] @otherSpecializedFunction { +/// } +/// \endcode +/// class SILLinkerVisitor : public SILInstructionVisitor { using LinkingMode = SILModule::LinkingMode; @@ -47,6 +97,10 @@ class SILLinkerVisitor : public SILInstructionVisitor { /// Returns true if any deserialization was performed. bool processFunction(SILFunction *F); + /// Process the witnesstable of \p conformanceRef. + /// Returns true if any deserialization was performed. + bool processConformance(ProtocolConformanceRef conformanceRef); + /// Deserialize the VTable mapped to C if it exists and all SIL the VTable /// transitively references. /// @@ -63,11 +117,10 @@ class SILLinkerVisitor : public SILInstructionVisitor { void visitFunctionRefInst(FunctionRefInst *FRI); void visitDynamicFunctionRefInst(DynamicFunctionRefInst *FRI); void visitPreviousDynamicFunctionRefInst(PreviousDynamicFunctionRefInst *FRI); - void visitProtocolConformance(ProtocolConformanceRef C, - const Optional &Member); + void visitProtocolConformance(ProtocolConformanceRef C); void visitApplySubstitutions(SubstitutionMap subs); void visitWitnessMethodInst(WitnessMethodInst *WMI) { - visitProtocolConformance(WMI->getConformance(), WMI->getMember()); + visitProtocolConformance(WMI->getConformance()); } void visitInitExistentialAddrInst(InitExistentialAddrInst *IEI); void visitInitExistentialRefInst(InitExistentialRefInst *IERI); @@ -78,11 +131,14 @@ class SILLinkerVisitor : public SILInstructionVisitor { private: /// Cause a function to be deserialized, and visit all other functions /// referenced from this function according to the linking mode. - void addFunctionToWorklist(SILFunction *F); + void deserializeAndPushToWorklist(SILFunction *F); /// Consider a function for deserialization if the current linking mode /// requires it. - void maybeAddFunctionToWorklist(SILFunction *F); + /// + /// If `setToSerializable` is true than all shared functions which are referenced + /// from `F` are set to + void maybeAddFunctionToWorklist(SILFunction *F, bool setToSerializable); /// Is the current mode link all? Link all implies we should try and link /// everything, not just transparent/shared functions. diff --git a/lib/SIL/IR/SIL.cpp b/lib/SIL/IR/SIL.cpp index 1a6d255548186..ba8387cc5f543 100644 --- a/lib/SIL/IR/SIL.cpp +++ b/lib/SIL/IR/SIL.cpp @@ -281,7 +281,6 @@ bool AbstractStorageDecl::exportsPropertyDescriptor() const { case SILLinkage::HiddenExternal: case SILLinkage::PublicExternal: - case SILLinkage::SharedExternal: llvm_unreachable("should be definition linkage?"); } diff --git a/lib/SIL/IR/SILDeclRef.cpp b/lib/SIL/IR/SILDeclRef.cpp index 5c224b072d39c..174f909c35419 100644 --- a/lib/SIL/IR/SILDeclRef.cpp +++ b/lib/SIL/IR/SILDeclRef.cpp @@ -122,15 +122,16 @@ bool swift::requiresForeignEntryPoint(ValueDecl *vd) { } SILDeclRef::SILDeclRef(ValueDecl *vd, SILDeclRef::Kind kind, bool isForeign, - bool isDistributed, + bool isDistributed, bool isKnownToBeLocal, SILDeclRef::BackDeploymentKind backDeploymentKind, AutoDiffDerivativeFunctionIdentifier *derivativeId) - : loc(vd), kind(kind), isForeign(isForeign), isDistributed(isDistributed), + : loc(vd), kind(kind), isForeign(isForeign), + isDistributed(isDistributed), isKnownToBeLocal(isKnownToBeLocal), backDeploymentKind(backDeploymentKind), defaultArgIndex(0), pointer(derivativeId) {} SILDeclRef::SILDeclRef(SILDeclRef::Loc baseLoc, bool asForeign, - bool asDistributed) + bool asDistributed, bool asDistributedKnownToBeLocal) : backDeploymentKind(SILDeclRef::BackDeploymentKind::None), defaultArgIndex(0), pointer((AutoDiffDerivativeFunctionIdentifier *)nullptr) { @@ -171,6 +172,7 @@ SILDeclRef::SILDeclRef(SILDeclRef::Loc baseLoc, bool asForeign, isForeign = asForeign; isDistributed = asDistributed; + isKnownToBeLocal = asDistributedKnownToBeLocal; } SILDeclRef::SILDeclRef(SILDeclRef::Loc baseLoc, @@ -572,9 +574,6 @@ IsSerialized_t SILDeclRef::isSerialized() const { if (auto closure = getAbstractClosureExpr()) { // Ask the AST if we're inside an @inlinable context. if (closure->getResilienceExpansion() == ResilienceExpansion::Minimal) { - if (isForeign) - return IsSerializable; - return IsSerialized; } @@ -638,7 +637,7 @@ IsSerialized_t SILDeclRef::isSerialized() const { // serializable. if (d->getDeclContext()->isLocalContext()) { if (dc->getResilienceExpansion() == ResilienceExpansion::Minimal) - return IsSerializable; + return IsSerialized; return IsNotSerialized; } @@ -650,7 +649,7 @@ IsSerialized_t SILDeclRef::isSerialized() const { // Enum element constructors are serializable if the enum is // @usableFromInline or public. if (isEnumElement()) - return IsSerializable; + return IsSerialized; // 'read' and 'modify' accessors synthesized on-demand are serialized if // visible outside the module. @@ -660,7 +659,7 @@ IsSerialized_t SILDeclRef::isSerialized() const { return IsSerialized; if (isForeignToNativeThunk()) - return IsSerializable; + return IsSerialized; // The allocating entry point for designated initializers are serialized // if the class is @usableFromInline or public. @@ -682,13 +681,13 @@ IsSerialized_t SILDeclRef::isSerialized() const { // @objc thunks for top-level functions are serializable since they're // referenced from @convention(c) conversions inside inlinable // functions. - return IsSerializable; + return IsSerialized; } // Declarations imported from Clang modules are serialized if // referenced from an inlinable context. if (isClangImported()) - return IsSerializable; + return IsSerialized; // Otherwise, ask the AST if we're inside an @inlinable context. if (dc->getResilienceExpansion() == ResilienceExpansion::Minimal) diff --git a/lib/SIL/IR/SILFunctionBuilder.cpp b/lib/SIL/IR/SILFunctionBuilder.cpp index b332513a2d889..84dd94b8a1b07 100644 --- a/lib/SIL/IR/SILFunctionBuilder.cpp +++ b/lib/SIL/IR/SILFunctionBuilder.cpp @@ -249,7 +249,7 @@ SILFunction *SILFunctionBuilder::getOrCreateFunction( (forDefinition == ForDefinition_t::NotForDefinition && (fnLinkage == linkageForDef || (linkageForDef == SILLinkage::PublicNonABI && - fnLinkage == SILLinkage::SharedExternal)))); + fnLinkage == SILLinkage::Shared)))); if (forDefinition) { // In all the cases where getConstantLinkage returns something // different for ForDefinition, it returns an available-externally diff --git a/lib/SIL/IR/SILGlobalVariable.cpp b/lib/SIL/IR/SILGlobalVariable.cpp index abcdfb731feee..e44a9938d089a 100644 --- a/lib/SIL/IR/SILGlobalVariable.cpp +++ b/lib/SIL/IR/SILGlobalVariable.cpp @@ -75,7 +75,6 @@ IsSerialized_t SILGlobalVariable::isSerialized() const { return Serialized ? IsSerialized : IsNotSerialized; } void SILGlobalVariable::setSerialized(IsSerialized_t isSerialized) { - assert(isSerialized != IsSerializable); Serialized = isSerialized ? 1 : 0; } diff --git a/lib/SIL/IR/SILModule.cpp b/lib/SIL/IR/SILModule.cpp index 2ccd751e9bbae..6f63f8c85ec08 100644 --- a/lib/SIL/IR/SILModule.cpp +++ b/lib/SIL/IR/SILModule.cpp @@ -67,22 +67,19 @@ class SILModule::SerializationCallback final decl->setLinkage(SILLinkage::PublicExternal); return; case SILLinkage::PublicNonABI: - // PublicNonABI functions receive SharedExternal linkage, so that + // PublicNonABI functions receive Shared linkage, so that // they have "link once" semantics when deserialized by multiple // translation units in the same Swift module. - decl->setLinkage(SILLinkage::SharedExternal); + decl->setLinkage(SILLinkage::Shared); return; case SILLinkage::Hidden: decl->setLinkage(SILLinkage::HiddenExternal); return; - case SILLinkage::Shared: - decl->setLinkage(SILLinkage::SharedExternal); - return; case SILLinkage::Private: llvm_unreachable("cannot make a private external symbol"); case SILLinkage::PublicExternal: case SILLinkage::HiddenExternal: - case SILLinkage::SharedExternal: + case SILLinkage::Shared: return; } } @@ -272,82 +269,16 @@ void SILModule::flushDeletedInsts() { } SILWitnessTable * -SILModule::lookUpWitnessTable(ProtocolConformanceRef C, - bool deserializeLazily) { - // If we have an abstract conformance passed in (a legal value), just return - // nullptr. - if (!C.isConcrete()) - return nullptr; - - return lookUpWitnessTable(C.getConcrete()); -} - -SILWitnessTable * -SILModule::lookUpWitnessTable(const ProtocolConformance *C, - bool deserializeLazily) { +SILModule::lookUpWitnessTable(const ProtocolConformance *C) { assert(C && "null conformance passed to lookUpWitnessTable"); - SILWitnessTable *wtable; - auto rootC = C->getRootConformance(); // Attempt to lookup the witness table from the table. auto found = WitnessTableMap.find(rootC); - if (found == WitnessTableMap.end()) { -#ifndef NDEBUG - // Make sure that all witness tables are in the witness table lookup - // cache. - // - // This code should not be hit normally since we add witness tables to the - // lookup cache when we create them. We don't just assert here since there - // is the potential for a conformance without a witness table to be passed - // to this function. - for (SILWitnessTable &WT : witnessTables) - assert(WT.getConformance() != rootC && - "Found witness table that is not" - " in the witness table lookup cache."); -#endif - - // If we don't have a witness table and we're not going to try - // deserializing it, do not create a declaration. - if (!deserializeLazily) - return nullptr; - - auto linkage = getLinkageForProtocolConformance(rootC, NotForDefinition); - wtable = SILWitnessTable::create(*this, linkage, - const_cast(rootC)); - } else { - wtable = found->second; - assert(wtable != nullptr && "Should never map a conformance to a null witness" - " table."); - - // If we have a definition, return it. - if (wtable->isDefinition()) - return wtable; - } - - // If the module is at or past the Lowered stage, then we can't do any - // further deserialization, since pre-IRGen SIL lowering changes the types - // of definitions to make them incompatible with canonical serialized SIL. - switch (getStage()) { - case SILStage::Canonical: - case SILStage::Raw: - break; - - case SILStage::Lowered: - return wtable; - } - - // Otherwise try to deserialize it. If we succeed return the deserialized - // function. - // - // *NOTE* In practice, wtable will be deserializedTable, but I do not want to rely - // on that behavior for now. - if (deserializeLazily) - if (auto deserialized = getSILLoader()->lookupWitnessTable(wtable)) - return deserialized; + if (found == WitnessTableMap.end()) + return nullptr; - // If we fail, just return the declaration. - return wtable; + return found->second; } SILDefaultWitnessTable * @@ -385,7 +316,7 @@ SILModule::createDefaultWitnessTableDeclaration(const ProtocolDecl *Protocol, void SILModule::deleteWitnessTable(SILWitnessTable *Wt) { auto Conf = Wt->getConformance(); - assert(lookUpWitnessTable(Conf, false) == Wt); + assert(lookUpWitnessTable(Conf) == Wt); getSILLoader()->invalidateWitnessTable(Wt); WitnessTableMap.erase(Conf); witnessTables.erase(Wt); @@ -453,16 +384,31 @@ SILFunction *SILModule::lookUpFunction(SILDeclRef fnRef) { return lookUpFunction(name); } -bool SILModule::loadFunction(SILFunction *F) { +bool SILModule::loadFunction(SILFunction *F, LinkingMode LinkMode) { SILFunction *NewF = getSILLoader()->lookupSILFunction(F, /*onlyUpdateLinkage*/ false); if (!NewF) return false; + linkFunction(NewF, LinkMode); + assert(F == NewF); return true; } +SILFunction *SILModule::loadFunction(StringRef name, + LinkingMode LinkMode, + Optional linkage) { + SILFunction *func = lookUpFunction(name); + if (!func) + func = getSILLoader()->lookupSILFunction(name, linkage); + if (!func) + return nullptr; + + linkFunction(func, LinkMode); + return func; +} + void SILModule::updateFunctionLinkage(SILFunction *F) { getSILLoader()->lookupSILFunction(F, /*onlyUpdateLinkage*/ true); } @@ -471,71 +417,6 @@ bool SILModule::linkFunction(SILFunction *F, SILModule::LinkingMode Mode) { return SILLinkerVisitor(*this, Mode).processFunction(F); } -SILFunction *SILModule::findFunction(StringRef Name, SILLinkage Linkage) { - assert((Linkage == SILLinkage::Public || - Linkage == SILLinkage::SharedExternal || - Linkage == SILLinkage::PublicExternal) && - "Only a lookup of public functions is supported currently"); - - SILFunction *F = nullptr; - - // First, check if there is a function with a required name in the - // current module. - SILFunction *CurF = lookUpFunction(Name); - - // Nothing to do if the current module has a required function - // with a proper linkage already. - if (CurF && CurF->getLinkage() == Linkage) { - F = CurF; - } else { - assert((!CurF || CurF->getLinkage() != Linkage) && - "hasFunction should be only called for functions that are not " - "contained in the SILModule yet or do not have a required linkage"); - } - - if (!F) { - if (CurF) { - // Perform this lookup only if a function with a given - // name is present in the current module. - // This is done to reduce the amount of IO from the - // swift module file. - if (!getSILLoader()->hasSILFunction(Name, Linkage)) - return nullptr; - // The function in the current module will be changed. - F = CurF; - } - - // If function with a given name wasn't seen anywhere yet - // or if it is known to exist, perform a lookup. - if (!F) { - // Try to load the function from other modules. - F = getSILLoader()->lookupSILFunction(Name, /*declarationOnly*/ true, - Linkage); - // Bail if nothing was found and we are not sure if - // this function exists elsewhere. - if (!F) - return nullptr; - assert(F && "SILFunction should be present in one of the modules"); - assert(F->getLinkage() == Linkage && "SILFunction has a wrong linkage"); - } - } - - // If a function exists already and it is a non-optimizing - // compilation, simply convert it into an external declaration, - // so that a compiled version from the shared library is used. - if (F->isDefinition() && - // Don't eliminate bodies of _alwaysEmitIntoClient functions - // (PublicNonABI linkage is de-serialized as SharedExternal) - F->getLinkage() != SILLinkage::SharedExternal && - !F->getModule().getOptions().shouldOptimize()) { - F->convertToDeclaration(); - } - if (F->isExternalDeclaration()) - F->setSerialized(IsSerialized_t::IsNotSerialized); - F->setLinkage(Linkage); - return F; -} - bool SILModule::hasFunction(StringRef Name) { if (lookUpFunction(Name)) return true; @@ -638,21 +519,26 @@ SerializedSILLoader *SILModule::getSILLoader() { /// for the requirement. std::pair SILModule::lookUpFunctionInWitnessTable(ProtocolConformanceRef C, - SILDeclRef Requirement) { - // Look up the witness table associated with our protocol conformance from the - // SILModule. - auto Ret = lookUpWitnessTable(C); + SILDeclRef Requirement, + SILModule::LinkingMode linkingMode) { + if (!C.isConcrete()) + return {nullptr, nullptr}; - // If no witness table was found, bail. - if (!Ret) { + if (getStage() != SILStage::Lowered) { + SILLinkerVisitor linker(*this, linkingMode); + linker.processConformance(C); + } + SILWitnessTable *wt = lookUpWitnessTable(C.getConcrete()); + + if (!wt) { LLVM_DEBUG(llvm::dbgs() << " Failed speculative lookup of " "witness for: "; C.dump(llvm::dbgs()); Requirement.dump()); - return std::make_pair(nullptr, nullptr); + return {nullptr, nullptr}; } // Okay, we found the correct witness table. Now look for the method. - for (auto &Entry : Ret->getEntries()) { + for (auto &Entry : wt->getEntries()) { // Look at method entries only. if (Entry.getKind() != SILWitnessTable::WitnessKind::Method) continue; @@ -662,10 +548,10 @@ SILModule::lookUpFunctionInWitnessTable(ProtocolConformanceRef C, if (MethodEntry.Requirement != Requirement) continue; - return std::make_pair(MethodEntry.Witness, Ret); + return {MethodEntry.Witness, wt}; } - return std::make_pair(nullptr, nullptr); + return {nullptr, nullptr}; } /// Given a protocol \p Protocol and a requirement \p Requirement, diff --git a/lib/SIL/IR/SILPrinter.cpp b/lib/SIL/IR/SILPrinter.cpp index dd86dafcb92d1..eab187d728645 100644 --- a/lib/SIL/IR/SILPrinter.cpp +++ b/lib/SIL/IR/SILPrinter.cpp @@ -2838,7 +2838,6 @@ static StringRef getLinkageString(SILLinkage linkage) { case SILLinkage::Private: return "private "; case SILLinkage::PublicExternal: return "public_external "; case SILLinkage::HiddenExternal: return "hidden_external "; - case SILLinkage::SharedExternal: return "shared_external "; } llvm_unreachable("bad linkage"); } @@ -2894,7 +2893,6 @@ void SILFunction::print(SILPrintContext &PrintCtx) const { switch (isSerialized()) { case IsNotSerialized: break; - case IsSerializable: OS << "[serializable] "; break; case IsSerialized: OS << "[serialized] "; break; } diff --git a/lib/SIL/IR/SILWitnessTable.cpp b/lib/SIL/IR/SILWitnessTable.cpp index 26e654f5faaea..8c6852f1c499b 100644 --- a/lib/SIL/IR/SILWitnessTable.cpp +++ b/lib/SIL/IR/SILWitnessTable.cpp @@ -143,7 +143,6 @@ void SILWitnessTable::convertToDefinition( IsSerialized_t isSerialized) { assert(isDeclaration() && "Definitions should never call this method."); IsDeclaration = false; - assert(isSerialized != IsSerializable); Serialized = (isSerialized == IsSerialized); Entries = Mod.allocateCopy(entries); diff --git a/lib/SIL/Parser/ParseSIL.cpp b/lib/SIL/Parser/ParseSIL.cpp index a693e316ba54b..d40a298744d37 100644 --- a/lib/SIL/Parser/ParseSIL.cpp +++ b/lib/SIL/Parser/ParseSIL.cpp @@ -38,11 +38,16 @@ #include "swift/Subsystems.h" #include "swift/Syntax/SyntaxKind.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/SaveAndRestore.h" using namespace swift; using namespace swift::syntax; +static llvm::cl::opt +ParseSerializedSIL("parse-serialized-sil", + llvm::cl::desc("Parse the output of a serialized module")); + //===----------------------------------------------------------------------===// // SILParserState implementation //===----------------------------------------------------------------------===// @@ -84,6 +89,10 @@ ParseSILModuleRequest::evaluate(Evaluator &evaluator, Parser parser(*bufferID, *SF, &parserState); PrettyStackTraceParser StackTrace(parser); + if (ParseSerializedSIL) { + silMod.get()->setParsedAsSerializedSIL(); + } + auto hadError = parser.parseTopLevelSIL(); if (hadError) { // The rest of the SIL pipeline expects well-formed SIL, so if we encounter @@ -798,7 +807,6 @@ static bool parseSILLinkage(Optional &Result, Parser &P) { .Case("shared", SILLinkage::Shared) .Case("public_external", SILLinkage::PublicExternal) .Case("hidden_external", SILLinkage::HiddenExternal) - .Case("shared_external", SILLinkage::SharedExternal) .Default(None); // If we succeed, consume the token. @@ -1000,8 +1008,6 @@ static bool parseDeclSILOptional(bool *isTransparent, *isDistributed = IsDistributed; else if (isExactSelfClass && SP.P.Tok.getText() == "exact_self_class") *isExactSelfClass = IsExactSelfClass; - else if (isSerialized && SP.P.Tok.getText() == "serializable") - *isSerialized = IsSerializable; else if (isCanonical && SP.P.Tok.getText() == "canonical") *isCanonical = true; else if (hasOwnershipSSA && SP.P.Tok.getText() == "ossa") @@ -1518,7 +1524,8 @@ bool SILParser::parseSILDeclRef(SILDeclRef &Result, if (!P.consumeIf(tok::sil_exclamation)) { // Construct SILDeclRef. - Result = SILDeclRef(VD, Kind, IsObjC, /*distributed=*/false, + Result = SILDeclRef(VD, Kind, IsObjC, + /*distributed=*/false, /*knownToBeLocal=*/false, SILDeclRef::BackDeploymentKind::None, DerivativeId); return false; } @@ -1639,7 +1646,8 @@ bool SILParser::parseSILDeclRef(SILDeclRef &Result, } while (P.consumeIf(tok::period)); // Construct SILDeclRef. - Result = SILDeclRef(VD, Kind, IsObjC, /*distributed=*/false, + Result = SILDeclRef(VD, Kind, IsObjC, + /*distributed=*/false, /*knownToBeLocal=*/false, SILDeclRef::BackDeploymentKind::None, DerivativeId); return false; } @@ -7256,7 +7264,7 @@ bool SILParserState::parseSILWitnessTable(Parser &P) { SILWitnessTable *wt = nullptr; if (theConformance) { - wt = M.lookUpWitnessTable(theConformance, false); + wt = M.lookUpWitnessTable(theConformance); assert((!wt || wt->isDeclaration()) && "Attempting to create duplicate witness table."); } diff --git a/lib/SIL/Utils/MemAccessUtils.cpp b/lib/SIL/Utils/MemAccessUtils.cpp index 8a762598963db..52265ba59d924 100644 --- a/lib/SIL/Utils/MemAccessUtils.cpp +++ b/lib/SIL/Utils/MemAccessUtils.cpp @@ -2025,8 +2025,7 @@ bool GatherUniqueStorageUses::visitUse(Operand *use, AccessUseType useTy) { case SILInstructionKind::StoreWeakInst: case SILInstructionKind::StoreUnownedInst: if (operIdx == CopyLikeInstruction::Dest) { - visitor.visitStore(use); - return true; + return visitor.visitStore(use); } break; diff --git a/lib/SIL/Verifier/SILVerifier.cpp b/lib/SIL/Verifier/SILVerifier.cpp index 15200c8bc2d70..51f1e635da8c4 100644 --- a/lib/SIL/Verifier/SILVerifier.cpp +++ b/lib/SIL/Verifier/SILVerifier.cpp @@ -2089,16 +2089,7 @@ class SILVerifier : public SILVerifierBase { // from a fragile function is an error. if (F.isSerialized()) { require((SingleFunction && RefF->isExternalDeclaration()) || - RefF->hasValidLinkageForFragileRef() || - - // A serialized specialized function can reference another - // specialized function. In case the other specialization is already - // generated by the optimizer before the de-serialization point, - // we can end up that a shared_external function references a - // shared function. This is okay. - (F.getLinkage() == SILLinkage::SharedExternal && - RefF->getLinkage() == SILLinkage::Shared), - + RefF->hasValidLinkageForFragileRef(), "function_ref inside fragile function cannot " "reference a private or hidden symbol"); } @@ -5811,6 +5802,41 @@ class SILVerifier : public SILVerifierBase { CanSILFunctionType FTy = F->getLoweredFunctionType(); verifySILFunctionType(FTy); + SILModule &mod = F->getModule(); + + require(!F->isSerialized() || !mod.isSerialized() || mod.isParsedAsSerializedSIL(), + "cannot have a serialized function after the module has been serialized"); + + switch (F->getLinkage()) { + case SILLinkage::Public: + case SILLinkage::Shared: + require(F->isDefinition() || F->hasForeignBody(), + "public/shared function must have a body"); + break; + case SILLinkage::PublicNonABI: + require(F->isDefinition(), + "alwaysEmitIntoClient function must have a body"); + require(F->isSerialized() || mod.isSerialized(), + "alwaysEmitIntoClient function must be serialized"); + break; + case SILLinkage::Hidden: + case SILLinkage::Private: + require(F->isDefinition() || F->hasForeignBody(), + "internal/private function must have a body"); + require(!F->isSerialized(), + "internal/private function cannot be serialized or serializable"); + break; + case SILLinkage::PublicExternal: + require(F->isExternalDeclaration() || F->isSerialized() || + mod.isSerialized(), + "public-external function definition must be serialized"); + break; + case SILLinkage::HiddenExternal: + require(F->isExternalDeclaration(), + "hidden-external function cannot have a body"); + break; + } + // Don't verify functions that were skipped. We are likely to see them in // FunctionBodySkipping::NonInlinableWithoutTypes mode. auto Ctx = F->getDeclContext(); @@ -5856,7 +5882,7 @@ class SILVerifier : public SILVerifierBase { visitSILBasicBlocks(F); if (F->hasOwnership() && F->shouldVerifyOwnership() && - !F->getModule().getASTContext().hadError()) { + !mod.getASTContext().hadError()) { F->verifyMemoryLifetime(); } } diff --git a/lib/SILGen/SILGen.cpp b/lib/SILGen/SILGen.cpp index 8a70a69cde651..fd9172e168c0c 100644 --- a/lib/SILGen/SILGen.cpp +++ b/lib/SILGen/SILGen.cpp @@ -798,7 +798,7 @@ void SILGenModule::emitFunctionDefinition(SILDeclRef constant, SILFunction *f) { if (constant.isForeignToNativeThunk()) { f->setThunk(IsThunk); if (constant.asForeign().isClangGenerated()) - f->setSerialized(IsSerializable); + f->setSerialized(IsSerialized); auto loc = constant.getAsRegularLocation(); loc.markAutoGenerated(); @@ -846,8 +846,11 @@ void SILGenModule::emitFunctionDefinition(SILDeclRef constant, SILFunction *f) { PrettyStackTraceSILFunction X("silgen emitDistributedThunk", f); f->setBare(IsBare); f->setThunk(IsThunk); + f->setIsDistributed(); - SILGenFunction(*this, *f, dc).emitDistributedThunk(constant); + assert(constant.isDistributedThunk()); + SILGenFunction(*this, *f, constant.getFuncDecl()) + .emitFunction(constant.getFuncDecl()); postEmitFunction(constant, f); return; @@ -1396,9 +1399,10 @@ void SILGenModule::emitAbstractFuncDecl(AbstractFunctionDecl *AFD) { emitNativeToForeignThunk(thunk); } - if (AFD->isDistributed()) { - auto thunk = SILDeclRef(AFD).asDistributed(); - emitDistributedThunk(thunk); + if (auto thunkDecl = AFD->getDistributedThunk()) { + auto thunk = SILDeclRef(thunkDecl).asDistributed(); + emitFunctionDefinition(SILDeclRef(thunkDecl).asDistributed(), + getFunction(thunk, ForDefinition)); } if (AFD->isBackDeployed()) { diff --git a/lib/SILGen/SILGenApply.cpp b/lib/SILGen/SILGenApply.cpp index a4a161b1cf136..f208cc1026b4b 100644 --- a/lib/SILGen/SILGenApply.cpp +++ b/lib/SILGen/SILGenApply.cpp @@ -1058,8 +1058,8 @@ class SILGenApply : public Lowering::ExprVisitor { } SILDeclRef constant = SILDeclRef(afd); - if (afd->isDistributed()) { - constant = constant.asDistributed(true); + if (auto distributedThunk = afd->getDistributedThunk()) { + constant = SILDeclRef(distributedThunk).asDistributed(); } else { constant = constant.asForeign(requiresForeignEntryPoint(afd)); } @@ -1119,9 +1119,13 @@ class SILGenApply : public Lowering::ExprVisitor { } // Otherwise, we have a statically-dispatched call. - auto constant = SILDeclRef(e->getDecl()); + SILDeclRef constant = SILDeclRef(e->getDecl()); + + /// Some special handling may be necessary for thunks: if (callSite && callSite->shouldApplyDistributedThunk()) { - constant = constant.asDistributed(true); + if (auto distributedThunk = cast(e->getDecl())->getDistributedThunk()) { + constant = SILDeclRef(distributedThunk).asDistributed(); + } } else if (afd->isBackDeployed()) { // If we're calling a back deployed function then we need to call a // thunk instead that will handle the fallback when the original @@ -5155,8 +5159,8 @@ RValue SILGenFunction::emitApplyMethod(SILLocation loc, ConcreteDeclRef declRef, auto callRef = SILDeclRef(call, SILDeclRef::Kind::Func) .asForeign(requiresForeignEntryPoint(declRef.getDecl())); - if (call->isDistributed()) { - callRef = callRef.asDistributed(true); + if (auto distributedThunk = call->getDistributedThunk()) { + callRef = SILDeclRef(distributedThunk).asDistributed(); } else if (call->isBackDeployed()) { callRef = callRef.asBackDeploymentKind(SILDeclRef::BackDeploymentKind::Thunk); diff --git a/lib/SILGen/SILGenDistributed.cpp b/lib/SILGen/SILGenDistributed.cpp index d244b5fa50417..c1778e38e077c 100644 --- a/lib/SILGen/SILGenDistributed.cpp +++ b/lib/SILGen/SILGenDistributed.cpp @@ -20,6 +20,7 @@ #include "SILGenFunctionBuilder.h" #include "Scope.h" #include "swift/AST/ASTMangler.h" +#include "swift/AST/DistributedDecl.h" #include "swift/AST/ForeignErrorConvention.h" #include "swift/AST/GenericEnvironment.h" #include "swift/AST/ParameterList.h" @@ -40,17 +41,25 @@ using namespace Lowering; /// Obtain a nominal type's member by name, as a VarDecl. /// \returns nullptr if the name lookup doesn't resolve to exactly one member, /// or the subsequent cast to VarDecl failed. -static VarDecl* lookupProperty(NominalTypeDecl *ty, DeclName name) { - auto refs = ty->lookupDirect(name); - if (refs.size() != 1) - return nullptr; - return dyn_cast(refs.front()); +static VarDecl* lookupProperty(NominalTypeDecl *decl, DeclName name) { + assert(decl && "decl was null"); + auto &C = decl->getASTContext(); + + if (auto clazz = dyn_cast(decl)) { + auto refs = decl->lookupDirect(name); + if (refs.size() != 1) + return nullptr; + return dyn_cast(refs.front()); + } + + return nullptr; } /// Emit a reference to a specific stored property of the actor. static SILValue emitActorPropertyReference( SILGenFunction &SGF, SILLocation loc, SILValue actorSelf, VarDecl *property) { + assert(property); Type formalType = SGF.F.mapTypeIntoContext(property->getInterfaceType()); SILType loweredType = SGF.getLoweredType(formalType).getAddressType(); return SGF.B.createRefElementAddr(loc, actorSelf, property, loweredType); @@ -87,79 +96,10 @@ static void initializeProperty(SILGenFunction &SGF, SILLocation loc, } } -/******************************************************************************/ -/********************* COMMON CONFORMANCE SIL PATTERNS ************************/ -/******************************************************************************/ - -/// Push `Type` and `ProtocolConformanceRef` for the `Error` protocol to -/// `subTypes` and `subConformances`. -static void pushErrorConformance( - SILGenFunction &SGF, ASTContext &ctx, - SmallVectorImpl &subTypes, - SmallVectorImpl &subConformances) { - auto &B = SGF.B; - auto module = B.getModule().getSwiftModule(); - - auto errorDecl = ctx.getErrorDecl(); - auto errorTy = errorDecl->getInterfaceType(); - auto thrownErrorConfRef = - module->lookupConformance(errorDecl->getDeclaredInterfaceType(), ctx.getErrorDecl()); - - assert(!thrownErrorConfRef.isInvalid() && "Missing conformance to `Error`"); - subTypes.push_back(errorTy); - subConformances.push_back(thrownErrorConfRef); -} - -static void pushNeverErrorConformance( - SILGenFunction &SGF, ASTContext &ctx, - SmallVectorImpl &subTypes, - SmallVectorImpl &subConformances) { - auto &B = SGF.B; - auto module = B.getModule().getSwiftModule(); - - auto neverDecl = ctx.getNeverDecl(); - auto neverTy = neverDecl->getDeclaredInterfaceType(); - auto thrownErrorConfRef = - module->lookupConformance(neverTy, ctx.getErrorDecl()); - -// assert(!thrownErrorConfRef.isInvalid() && "Missing conformance to `Error`"); // FIXME(distributed): how to deal with the `: Error` !!!! - subTypes.push_back(neverTy); - subConformances.push_back(thrownErrorConfRef); // FIXME(distributed): how to deal with the `: Error` !!!! -} - -/// Push `Type` and `ProtocolConformanceRef` for the `Self` of this distributed -/// actor to `subTypes` and `subConformances`. -static void pushDistributedActorConformance( - SILGenFunction &SGF, ASTContext &ctx, - SILType distributedActorSelfTy, - SmallVectorImpl &subTypes, - SmallVectorImpl &subConformances) { - auto &B = SGF.B; - auto module = B.getModule().getSwiftModule(); - - ProtocolDecl *distributedActorProto = - ctx.getProtocol(KnownProtocolKind::DistributedActor); - - auto confRef = - module->lookupConformance(distributedActorSelfTy.getASTType(), distributedActorProto); - assert(!confRef.isInvalid() && "Missing conformance to `DistributedActor`"); - - subTypes.push_back(distributedActorSelfTy.getASTType()); - subConformances.push_back(confRef); -} - - /******************************************************************************/ /******************* COMMON (DISTRIBUTED) SIL PATTERNS ************************/ /******************************************************************************/ -static void createVoidPhiArgument(SILGenFunction &SGF, - ASTContext &ctx, - SILBasicBlock *block) { - block->createPhiArgument( - SGF.getLoweredType(ctx.getVoidType()), OwnershipKind::Owned); -} - /// Emit the following branch SIL instruction: /// \verbatim /// if __isRemoteActor(self) { @@ -587,994 +527,3 @@ void SILGenFunction::emitDistributedActorClassMemberDestruction( B.createBranch(cleanupLoc, normalMemberDestroyBB); } } - -/******************************************************************************/ -/***************************** DISTRIBUTED THUNKS *****************************/ -/******************************************************************************/ - -/// Emit a basic block that accepts an error, emits pending cleanups -static void emitThrowWithCleanupBasicBlock(SILGenFunction &SGF, SILLocation loc, - SILDeclRef thunk, - SILBasicBlock *errorBB, - SILBasicBlock *throwBB, - ArrayRef endAccesses = {}, - ArrayRef endLifetimes = {}) { - if (!errorBB) - return; - - auto &B = SGF.B; - auto &SGM = SGF.SGM; - - B.emitBlock(errorBB); - - auto methodTy = - SGM.Types.getConstantOverrideType(SGF.getTypeExpansionContext(), thunk); - auto derivativeFnSILTy = SILType::getPrimitiveObjectType(methodTy); - auto silFnType = derivativeFnSILTy.castTo(); - SILFunctionConventions fnConv(silFnType, SGM.M); - - SILValue error = errorBB->createPhiArgument( - fnConv.getSILErrorType(SGF.getTypeExpansionContext()), - OwnershipKind::Owned); - - for (const auto &value : endAccesses) { - B.createEndAccess(loc, value, /*aborted=*/false); - } - for (const auto &value : endLifetimes) { // TODO(distributed): use enterCleanup for ending lifetimes - if (value->getType().isAddress()) - B.createEndLifetime(loc, value); - } - - SGF.Cleanups.emitCleanupsForReturn(CleanupLocation(loc), IsForUnwind); - - B.createBranch(loc, throwBB, {error}); -} - -void SILGenFunction::emitDistributedThunk(SILDeclRef thunk) { - // Check if actor is local or remote and call respective logic - // - // func X_distributedThunk(...) async throws -> T { - // if __isRemoteActor(self) { - // // ... prepare args ... - // return try await actorSystem.remoteCall() - // } else { - // return try await self.X(...) - // } - // } - // - - assert(thunk.isDistributed); - SILDeclRef native = thunk.asDistributed(false); - auto fd = cast(thunk.getDecl()); - - ASTContext &ctx = getASTContext(); - - // Use the same generic environment as the native entry point. - F.setGenericEnvironment(SGM.Types.getConstantGenericEnvironment(native)); - - auto loc = thunk.getAsRegularLocation(); - loc.markAutoGenerated(); - Scope scope(Cleanups, CleanupLocation(loc)); - - auto methodTy = SGM.Types.getConstantOverrideType(getTypeExpansionContext(), - thunk); - auto derivativeFnSILTy = SILType::getPrimitiveObjectType(methodTy); - auto silFnType = derivativeFnSILTy.castTo(); - SILFunctionConventions fnConv(silFnType, SGM.M); - auto resultType = fnConv.getSILResultType(getTypeExpansionContext()); - - auto shouldRecordGenericSubstitutions = fd->isGeneric(); // TODO: also handle if the outer actor is generic - auto shouldRecordArguments = fd->getParameters()->size() > 0; - auto shouldRecordErrorType = fd->hasThrows(); - auto shouldRecordReturnType = !resultType.isVoid(); - - auto errorBB = createBasicBlock("errorBB"); - auto returnBB = createBasicBlock("returnBB"); - - auto *selfVarDecl = fd->getImplicitSelfDecl(); - - SmallVector paramsForForwarding; - bindParametersForForwarding(fd->getParameters(), paramsForForwarding); - bindParameterForForwarding(selfVarDecl, paramsForForwarding); - - // === `Self` types - auto selfValue = ManagedValue::forUnmanaged(F.getSelfArgument()); - auto selfTy = selfVarDecl->getType(); - auto selfSILTy = getLoweredType(selfTy); - auto *selfTyDecl = FunctionDC->getParent()->getSelfNominalTypeDecl(); - assert(selfTyDecl && "distributed instance method declared outside of actor"); - - // === Thrown 'Err' type - auto errorTy = F.mapTypeIntoContext(ctx.getErrorDecl()->getInterfaceType()); - auto neverTy = F.mapTypeIntoContext(ctx.getNeverType()); - auto effectiveErrorTy = fd->hasThrows() ? errorTy : neverTy; - - // === `InvocationEncoder` types - AbstractFunctionDecl *makeInvocationEncoderFnDecl = - ctx.getMakeInvocationEncoderOnDistributedActorSystem(selfTyDecl); - assert(makeInvocationEncoderFnDecl && "no 'makeInvocationEncoder' func found!"); - auto makeInvocationEncoderFnRef = SILDeclRef(makeInvocationEncoderFnDecl); - - auto makeInvocationEncoderMethodTy = SGM.Types.getConstantOverrideType( - getTypeExpansionContext(), makeInvocationEncoderFnRef); - auto makeInvocationEncoderDerivativeFnSILTy = SILType::getPrimitiveObjectType(makeInvocationEncoderMethodTy); - auto makeInvocationEncoderSilFnType = makeInvocationEncoderDerivativeFnSILTy.castTo(); - - auto invocationEncoderResultInfo = - makeInvocationEncoderSilFnType->getResults().begin(); - auto invocationEncoderCanTy = invocationEncoderResultInfo->getInterfaceType(); - auto invocationEncoderTy = getLoweredType(invocationEncoderCanTy); - - NominalTypeDecl *invocationEncoderNominal = - invocationEncoderTy.getNominalOrBoundGenericNominal(); - - // ==== ---------------------------------------------------------------------- - - // if __isRemoteActor(self) { - // ... - // } else { - // ... - // } - auto isLocalBB = createBasicBlock("isLocalBB"); - auto isRemoteBB = createBasicBlock("isRemoteBB"); - { - FuncDecl* isRemoteFn = ctx.getIsRemoteDistributedActor(); - assert(isRemoteFn && - "Could not find 'is remote' function, is the '_Distributed' module available?"); - - ManagedValue selfAnyObject = B.createInitExistentialRef( - loc, getLoweredType(ctx.getAnyObjectType()), - CanType(selfTy), selfValue, {}); - auto result = emitApplyOfLibraryIntrinsic( - loc, isRemoteFn, SubstitutionMap(), - {selfAnyObject}, SGFContext()); - - SILValue isRemoteResult = std::move(result).forwardAsSingleValue(*this, loc); - SILValue isRemoteResultUnwrapped = emitUnwrapIntegerResult(loc, isRemoteResult); - - B.createCondBranch(loc, isRemoteResultUnwrapped, isRemoteBB, isLocalBB); - } - - // === Local Call ------------------------------------------------------------ - // { - // return (try)? (await)? self.X(...) - // } - SILBasicBlock *localReturnBB; - SILBasicBlock *localCallErrorBB; - { - B.emitBlock(isLocalBB); - - auto nativeMethodTy = SGM.Types.getConstantOverrideType(getTypeExpansionContext(), - native); - auto nativeFnSILTy = SILType::getPrimitiveObjectType(nativeMethodTy); - auto nativeSilFnType = nativeFnSILTy.castTo(); - - localReturnBB = createBasicBlock("localReturnBB"); - localCallErrorBB = nativeSilFnType->hasErrorResult() ? createBasicBlock() : nullptr; - - bool isClassMethod = false; - if (auto classDecl = dyn_cast(fd->getDeclContext())) { - if (!classDecl->isFinal() && !fd->isFinal() && - !fd->hasForcedStaticDispatch()) - isClassMethod = true; - } - - SILValue nativeFn; - if (isClassMethod) { - nativeFn = emitClassMethodRef( - loc, selfValue.getValue(), native, nativeMethodTy); - } else { - nativeFn = emitGlobalFunctionRef(loc, native); - } - auto subs = F.getForwardingSubstitutionMap(); - - if (localCallErrorBB) { - B.createTryApply(loc, nativeFn, subs, paramsForForwarding, localReturnBB, localCallErrorBB); - } else { - auto result = B.createApply(loc, nativeFn, subs, paramsForForwarding); - B.createBranch(loc, localReturnBB, {result}); - } - } - { - B.emitBlock(localReturnBB); - - SILValue result = localReturnBB->createPhiArgument( - resultType, OwnershipKind::Owned); - B.createBranch(loc, returnBB, {result}); - } - { // local error - emitThrowWithCleanupBasicBlock(*this, loc, thunk, localCallErrorBB, errorBB); - } - - - // === Remote Call ----------------------------------------------------------- - SILGenFunctionBuilder builder(SGM); - // { - // var invocation = try self.actorSystem.makeInvocationEncoder() - // // ... - // } - { - B.emitBlock(isRemoteBB); - - // We need to maintain a "next normal basic block" pointer because - // we cannot just emit a bunch of tryApply right after one another - // but each subsequent call must be in its own basic block on the - // 'normal' path. - SILBasicBlock *nextNormalBB = nullptr; - - // === ------------------------------------------------------------------- - // var encoder = actorSystem.makeInvocationEncoder() - SILValue invocationEncoderBuf; - ManagedValue invocationEncoder; - - SILValue actorSystemBuf; - ManagedValue actorSystem; - { - invocationEncoderBuf = emitTemporaryAllocation(loc, invocationEncoderTy); - invocationEncoder = emitManagedBufferWithCleanup(invocationEncoderBuf); - - // === get the actorSystem property - // %16 = ref_element_addr %2 : $MyDistActor, #MyDistActor.actorSystem // user: %17 - auto systemRef = emitActorPropertyReference( - *this, loc, selfValue.getValue(), - lookupProperty(selfTyDecl, ctx.Id_actorSystem)); - - auto actorSystemTy = systemRef->getType(); - - // FIXME: this is wrong for struct with values, and classes? - // %17 = load %16 : $*FakeActorSystem // users: %21, %20, %18 - SILValue systemLoaded; - if (actorSystemTy.isAddressOnly(F)) { - assert(false && "isAddressOnly"); - } else { - if (actorSystemTy.isAddress()) { - systemLoaded = B.createTrivialLoadOr( - loc, systemRef, LoadOwnershipQualifier::Copy); - } else { - assert(false); - } - } - -// if (!actorSystemTy.isAddressOnly(F) && -// !actorSystemTy.isTrivial(F)) { -// // retain_value %17 : $FakeActorSystem // id: %18 -// B.createRetainValue(loc, systemLoaded, -// RefCountingInst::Atomicity::Atomic); -// } - - // function_ref FakeActorSystem.makeInvocationEncoder() - // %19 = function_ref @$s27FakeDistributedActorSystems0aC6SystemV21makeInvocationEncoderAA0aG0VyF : $@convention(method) (@guaranteed FakeActorSystem) -> FakeInvocation // user: %20 - SILFunction *makeInvocationEncoderFnSIL = - builder.getOrCreateFunction(loc, makeInvocationEncoderFnRef, NotForDefinition); - SILValue makeInvocationEncoderFn = - B.createFunctionRefFor(loc, makeInvocationEncoderFnSIL); - - // %20 = apply %19(%17) : $@convention(method) (@guaranteed FakeActorSystem) -> FakeInvocation // user: %22 - ApplyInst *invocationEncoderValue = B.createApply( - loc, makeInvocationEncoderFn, - /*subs=*/SubstitutionMap(), - /*args=*/{systemLoaded}); - - if (!systemLoaded->getType().isTrivial(F)) - B.createDestroyValue(loc, systemLoaded); - // B.createEndLifetime(loc, systemLoaded); - - // FIXME(distributed): cannot deal with class yet - // TODO(distributed): make into "emit apropriate store" - if (invocationEncoderTy.isTrivial(F)) { - B.createTrivialStoreOr(loc, - /*src=*/invocationEncoderValue, - /*dest=*/invocationEncoder.getValue(), - StoreOwnershipQualifier::Init); - } else { - B.createStore(loc, - /*src=*/invocationEncoderValue, - /*dest=*/invocationEncoder.getValue(), - StoreOwnershipQualifier::Init); - } - } - - // === ------------------------------------------------------------------- - // populate the invocation: - - // The graph of basic blocks depends - // test() - // [...] -> [doneRecording] - // \-...ErrorBB - // - // test() throws - // [...] -> [recordErrorType] -> [doneRecordingBB] - // \-...ErrorBB \-...ErrorBB - // - // test() -> T - // [...] -> [recordReturnTypeBB] -> [doneRecordingBB] - // \-...ErrorBB \-...ErrorBB - // - // test() throws -> T - // [...] -> [recordErrorType] -> [recordReturnTypeBB] -> [doneRecordingBB] - // \-...ErrorBB \-...ErrorBB \-...ErrorBB - // - // test(p: P1) - // [...] -> [recordArgument] -> [doneRecordingBB] - // \-...ErrorBB \-...ErrorBB - // - // test(p: P1) throws - // [...] -> [recordArgument] -> [recordErrorTypeBB] -> [doneRecordingBB] - // \-...ErrorBB \-...ErrorBB \-...ErrorBB - // - // test(p: P1) throws -> P1 - // [...] -> [recordArgument] -> [recordErrorTypeBB] -> [recordReturnTypeBB] -> [doneRecordingBB] - // \-...ErrorBB \-...ErrorBB \-...ErrorBB \-...ErrorBB - // - // test(p: P1, p: P2, ...) - // [...] -> [recordArgument] (-> [recordArgumentNBB])* -> [doneRecordingBB] - // \-...ErrorBB \-...ErrorBB \-...ErrorBB - // - // test(p: P1, p: P2, ...) throws - // [...] -> [recordArgument] (-> [recordArgumentNBB])* -> [recordErrorType] -> [doneRecording] - // \-...ErrorBB \-...ErrorBB \-...ErrorBB \-...ErrorBB - // - // test(p: P1, p: P2, ...) throws -> T - // [...] -> [recordArgument] (-> [recordArgumentNBB])* -> [recordErrorType] -> [recordReturnType] -> [doneRecording] - // \-...ErrorBB \-...ErrorBB \-...ErrorBB \-...ErrorBB \-...ErrorBB - auto anyRecordBlocks = false; - if (shouldRecordGenericSubstitutions) { - anyRecordBlocks = true; - } - - SILBasicBlock *firstRecordArgumentBB = nullptr; - if (shouldRecordArguments) { - if (anyRecordBlocks) { - firstRecordArgumentBB = createBasicBlock("firstRecordArgumentBB"); - } - anyRecordBlocks = true; - } - - SILBasicBlock *recordErrorTypeBB = nullptr; - SILBasicBlock *recordErrorTypeErrorBB = nullptr; - if (shouldRecordErrorType) { - if (anyRecordBlocks) { - recordErrorTypeBB = createBasicBlock("recordErrorTypeBB"); - } - anyRecordBlocks = true; - recordErrorTypeErrorBB = createBasicBlock("recordErrorTypeErrorBB"); - } - - SILBasicBlock *recordReturnTypeBB = nullptr; - SILBasicBlock *recordReturnTypeErrorBB = nullptr; - if (shouldRecordReturnType) { - if (anyRecordBlocks) { - recordReturnTypeBB = createBasicBlock("recordReturnTypeBB"); - } - anyRecordBlocks = true; - recordReturnTypeErrorBB = createBasicBlock("recordReturnTypeErrorBB"); - } - - SILBasicBlock *recordingDoneBB = nullptr; - SILBasicBlock *recordingDoneErrorBB = - createBasicBlock("recordingDoneErrorBB"); - if (anyRecordBlocks) { - // If any previous record* calls have been made, we need a BB to jump to - // on the normal path to the recordingDone call: - recordingDoneBB = createBasicBlock("recordingDoneBB"); - } - - // === All calls on invocationEncoder need Access: - SILValue invocationEncoderAccess; - { - invocationEncoderAccess = B.createBeginAccess( - loc, invocationEncoder.getValue(), SILAccessKind::Modify, - SILAccessEnforcement::Static, false, false); - } - - // === encoder.recordGenericSubstitution() --------------------------------- - if (shouldRecordGenericSubstitutions) { - // === Prepare the func - FuncDecl *recordGenSubFnDecl = - ctx.getRecordGenericSubstitutionOnDistributedInvocationEncoder( - invocationEncoderNominal); - auto recordGenSubFnRef = SILDeclRef(recordGenSubFnDecl); - assert(recordGenSubFnRef && "no 'recordGenericSubstitution' func found!"); - - auto recordGenSubFnSIL = - builder.getOrCreateFunction(loc, recordGenSubFnRef, NotForDefinition); - SILValue recordGenSubFn = B.createFunctionRefFor(loc, recordGenSubFnSIL); - - unsigned long paramIdx = 0; - auto sig = fd->getGenericSignature(); - auto paramsNum = sig.getGenericParams().size(); - for (auto genericParamType : sig.getGenericParams()) { - auto isLastParam = ++paramIdx == paramsNum; - - if (nextNormalBB) { - // this will be `nextRecordArgumentNormalBB` from the previous - // iteration i.e. if we're the first parameter, we just emit directly; - // if we're the second (or later) parameter, we need to emit a basic - // block here. - B.emitBlock(nextNormalBB); - createVoidPhiArgument(*this, ctx, nextNormalBB); - } - - auto genericParamTypeDecl = genericParamType->getDecl(); - auto genericParamCanType = - genericParamTypeDecl->getInterfaceType()->getCanonicalType(); - auto metatypeType = fd->mapTypeIntoContext(genericParamCanType); - - SILType loweredMetatypeType = - getLoweredType(AbstractionPattern::getOpaque(), metatypeType); - auto metatypeValue = B.createMetatype(loc, loweredMetatypeType); - auto paramTy = metatypeType->getMetatypeInstanceType(); - - SILBasicBlock *recordErrorGenericSubstitutionBB = - createBasicBlock("recordErrorGenericSubstitutionBB"); - - // === Prepare generic signature - SubstitutionMap subs; - { - auto recordArgumentGenericSig = - recordGenSubFnDecl->getGenericSignature(); - SmallVector subTypes; - SmallVector subConformances; - - subTypes.push_back(paramTy); - - subs = SubstitutionMap::get(recordArgumentGenericSig, subTypes, - subConformances); - } - - // --- determine the next normal BB to jump to - if (!isLastParam) { - nextNormalBB = createBasicBlock("nextGenericSigNormalBB"); - } else if (shouldRecordArguments) { - assert(firstRecordArgumentBB); - nextNormalBB = firstRecordArgumentBB; - } else if (shouldRecordErrorType) { - assert(recordErrorTypeBB); - nextNormalBB = recordErrorTypeBB; - } else if (shouldRecordReturnType) { - assert(recordReturnTypeBB); - nextNormalBB = recordReturnTypeBB; - } else { - assert(recordingDoneBB); - nextNormalBB = recordingDoneBB; - } - - B.createTryApply(loc, recordGenSubFn, subs, - {metatypeValue, invocationEncoderAccess}, - /*normalBB=*/nextNormalBB, - /*errorBB=*/recordErrorGenericSubstitutionBB); - - emitThrowWithCleanupBasicBlock(*this, loc, thunk, - recordErrorGenericSubstitutionBB, - errorBB, {invocationEncoderAccess}); - } - } - - // === encoder.recordArgument() -------------------------------------------- - if (shouldRecordArguments) { - if (firstRecordArgumentBB) { - B.emitBlock(firstRecordArgumentBB); - createVoidPhiArgument(*this, ctx, firstRecordArgumentBB); - } - nextNormalBB = nullptr; - - AbstractFunctionDecl *recordArgumentFnDecl = - ctx.getRecordArgumentOnDistributedInvocationEncoder( - invocationEncoderNominal); - auto recordArgumentFnRef = SILDeclRef(recordArgumentFnDecl); - assert(recordArgumentFnRef && "no 'recordArgument' func found!"); - - auto recordArgumentFnSIL = - builder.getOrCreateFunction(loc, recordArgumentFnRef, NotForDefinition); - SILValue recordArgumentFn = - B.createFunctionRefFor(loc, recordArgumentFnSIL); - - // --- invoke recordArgument for every parameter - auto funcDeclParamsNum = fd->getParameters()->size(); - assert(funcDeclParamsNum > 0 && - "attempted recording arguments but no actual parameters declared " - "on distributed method"); - - assert(paramsForForwarding.size() == funcDeclParamsNum + 1); - assert(paramsForForwarding.back()->getType().getNominalOrBoundGenericNominal()->isDistributedActor()); - // the parameters for forwarding include `self`, but here we should not - // copy that self, so we just drop it. - paramsForForwarding.pop_back(); - - unsigned long paramIdx = 0; - Optional previousArgumentToDestroy; - for (SILValue paramValue : paramsForForwarding) { - auto isLastParam = ++paramIdx == funcDeclParamsNum; - - auto paramTy = paramValue->getType().getASTType(); - if (nextNormalBB) { - // this will be `nextRecordArgumentNormalBB` from the previous - // iteration i.e. if we're the first parameter, we just emit directly; - // if we're the second (or later) parameter, we need to emit a basic - // block here. - B.emitBlock(nextNormalBB); - createVoidPhiArgument(*this, ctx, nextNormalBB); - } - - if (previousArgumentToDestroy.hasValue()) { - B.createDestroyAddr(loc, previousArgumentToDestroy.getValue()); - } - - // Prepare the next normalBB we need to jump to on successful - // recordArgument call; If this is the last parameter we need to record - // though, then we always go to the following record* function type, - // which need to be the 'nextNormalBB'. - if (!isLastParam) { - nextNormalBB = createBasicBlock("recordNextArgumentBB"); - } else if (shouldRecordErrorType) { - assert(recordErrorTypeBB); - nextNormalBB = recordErrorTypeBB; - } else if (shouldRecordReturnType) { - assert(recordReturnTypeBB); - nextNormalBB = recordReturnTypeBB; - } else { - assert(recordingDoneBB); - nextNormalBB = recordingDoneBB; - } - auto recordArgumentErrorBB = createBasicBlock("recordArgumentErrorBB"); - - // === Prepare the argument - SILType argType = paramValue->getType(); - if (paramValue->getType().hasArchetype()) { - argType = paramValue->getType().mapTypeOutOfContext(); - } - - // FIXME(distributed): something is off here - llvm::Optional argValue; - { - auto argTemp = emitTemporaryAllocation(loc, paramValue->getType()); - argValue = emitManagedBufferWithCleanup(argTemp); - - if (paramValue->getType().isAddressOnly(F)) { - B.createCopyAddr(loc, paramValue, argTemp, IsNotTake, IsInitialization); - } else { - if (paramValue->getType().isAddress()) { - paramValue = B.createTrivialLoadOr(loc, paramValue, - LoadOwnershipQualifier::Take); - } else { - paramValue = B.emitCopyValueOperation(loc, paramValue); - } - - B.emitStoreValueOperation(loc, paramValue, argTemp, - StoreOwnershipQualifier::Init); - } - } - - // === Prepare generic signature - auto recordArgumentGenericSig = recordArgumentFnDecl->getGenericSignature(); - SmallVector subTypes; - SmallVector subConformances; - { - auto module = B.getModule().getSwiftModule(); - subTypes.push_back(paramTy); - - // --- Codable: Decodable - auto decodableRequirementTy = ctx.getProtocol( - KnownProtocolKind::Decodable); // FIXME(distributed): actually use - // SerializationRequirement - auto paramDecodableTypeConfRef = module->lookupConformance( - paramTy, decodableRequirementTy); - subConformances.push_back(paramDecodableTypeConfRef); - - // --- Codable: Encodable - auto encodableRequirementTy = ctx.getProtocol( - KnownProtocolKind::Encodable); // FIXME(distributed): actually use - // SerializationRequirement - auto paramEncodableTypeConfRef = module->lookupConformance( - paramTy, encodableRequirementTy); - subConformances.push_back(paramEncodableTypeConfRef); - - } - auto subs = SubstitutionMap::get( - recordArgumentGenericSig, - subTypes, subConformances); - - B.createTryApply( - loc, recordArgumentFn, - subs, - { - argValue.hasValue() ? argValue->getValue() : paramValue, - invocationEncoderAccess - }, - /*normalBB=*/nextNormalBB, - /*errorBB=*/recordArgumentErrorBB); - { - emitThrowWithCleanupBasicBlock( - *this, loc, thunk, recordArgumentErrorBB, errorBB, - /*endAccesses=*/{invocationEncoderAccess}); - } - } - } - - // === encoder.recordErrorType() ------------------------------------------- - if (shouldRecordErrorType) { - if (recordErrorTypeBB) { - B.emitBlock(recordErrorTypeBB); - createVoidPhiArgument(*this, ctx, recordErrorTypeBB); - } - - if (recordReturnTypeBB) { - nextNormalBB = recordReturnTypeBB; - } else { - nextNormalBB = recordingDoneBB; - } - - // Get the error type. - // If we ever did typed-throws we'd get the error type from fd here... - auto errorMetatype = getLoweredType(MetatypeType::get(errorTy, MetatypeRepresentation::Thick)); - auto errorMetatypeValue = B.createMetatype(loc, errorMetatype); - - // Get the function - AbstractFunctionDecl *recordErrorTypeFnDecl = - ctx.getRecordErrorTypeOnDistributedInvocationEncoder( - invocationEncoderNominal); - assert(recordErrorTypeFnDecl); - auto recordErrorTyFnRef = SILDeclRef(recordErrorTypeFnDecl); - auto recordErrorTypeFnSIL = - builder.getOrCreateFunction(loc, recordErrorTyFnRef, NotForDefinition); - SILValue recordErrorTyFn = B.createFunctionRefFor(loc, recordErrorTypeFnSIL); - - // Prepare the substitution, - // but just fill it with Error anyway. - auto recordErrorTypeGenericSig = recordErrorTypeFnDecl->getGenericSignature(); - SmallVector subTypes; - SmallVector subConformances; - { - // - pushErrorConformance(*this, ctx, subTypes, subConformances); - } - auto errorSubs = SubstitutionMap::get( - recordErrorTypeGenericSig, - subTypes, subConformances); - - B.createTryApply( - loc, recordErrorTyFn, - /*subs*/errorSubs, - /*args*/{ errorMetatypeValue, invocationEncoder.getValue() }, - /*normalBB*/nextNormalBB, - /*errorBB*/recordErrorTypeErrorBB); - } - if (shouldRecordErrorType) { - emitThrowWithCleanupBasicBlock( - *this, loc, thunk, recordErrorTypeErrorBB, errorBB, - /*endAccesses=*/{invocationEncoderAccess}); - } - - // === encoder.recordReturnType() ------------------------------------------ - if (shouldRecordReturnType) { - if (recordReturnTypeBB) { - B.emitBlock(recordReturnTypeBB); - createVoidPhiArgument(*this, ctx, recordReturnTypeBB); - } - - // Get the return meta type. - // If we ever did typed-throws we'd get the error type from fd here... - auto returnMetatype = getLoweredType(MetatypeType::get(resultType.getASTType(), MetatypeRepresentation::Thick)); - auto returnMetatypeValue = B.createMetatype(loc, returnMetatype); - - // Get the function - AbstractFunctionDecl *recordReturnTypeFnDecl = - ctx.getRecordReturnTypeOnDistributedInvocationEncoder( - invocationEncoderNominal); - assert(recordReturnTypeFnDecl); - auto recordErrorTyFnRef = SILDeclRef(recordReturnTypeFnDecl); - auto recordReturnTypeFnSIL = - builder.getOrCreateFunction(loc, recordErrorTyFnRef, NotForDefinition); - SILValue recordErrorTyFn = B.createFunctionRefFor(loc, recordReturnTypeFnSIL); - - // Prepare the substitution, - // but just fill it with Error anyway. - auto recordReturnTypeGenericSig = recordReturnTypeFnDecl->getGenericSignature(); - SmallVector subTypes; - SmallVector subConformances; - { - auto module = B.getModule().getSwiftModule(); - - // - subTypes.push_back(resultType.getASTType()); - - // pushSerializationRequirementConformance(*this, ctx, resultType, subTypes, subConformances); // FIXME(distributed): use this - - // FIXME: actually use SerializationRequirement - subConformances.push_back(module->lookupConformance( - resultType.getASTType(), - ctx.getProtocol(KnownProtocolKind::Decodable))); - - // FIXME: actually use SerializationRequirement - subConformances.push_back(module->lookupConformance( - resultType.getASTType(), - ctx.getProtocol(KnownProtocolKind::Encodable))); - } - auto errorSubs = SubstitutionMap::get( - recordReturnTypeGenericSig, - subTypes, subConformances); - - B.createTryApply( - loc, recordErrorTyFn, - /*subs*/errorSubs, - /*args*/{ returnMetatypeValue, invocationEncoder.getValue() }, - /*normalBB*/recordingDoneBB, - /*errorBB*/recordReturnTypeErrorBB); - } - if (shouldRecordReturnType) { - emitThrowWithCleanupBasicBlock( - *this, loc, thunk, recordReturnTypeErrorBB, errorBB, - /*endAccesses=*/{invocationEncoderAccess}); - } - - // === encoder.doneRecording() --------------------------------------------- - SILBasicBlock *makeRemoteCallTargetBB = - createBasicBlock("makeRemoteCallTargetBB"); - { - if (recordingDoneBB) { - B.emitBlock(recordingDoneBB); - - createVoidPhiArgument(*this, ctx, recordingDoneBB); - } - - assert(invocationEncoderNominal); - FuncDecl *doneRecordingFnDecl = - ctx.getDoneRecordingOnDistributedInvocationEncoder( - invocationEncoderNominal); - assert(doneRecordingFnDecl); - auto doneRecordingFnRef = SILDeclRef(doneRecordingFnDecl); - - auto doneRecordingFnSIL = - builder.getOrCreateFunction(loc, doneRecordingFnRef, NotForDefinition); - SILValue doneRecordingFn = B.createFunctionRefFor(loc, doneRecordingFnSIL); - - B.createTryApply( - loc, doneRecordingFn, - /*subs=*/SubstitutionMap(), - /*args=*/{invocationEncoderAccess}, - /*normalBB=*/makeRemoteCallTargetBB, - /*errorBB*/recordingDoneErrorBB); - } - { - emitThrowWithCleanupBasicBlock(*this, loc, thunk, recordingDoneErrorBB, - errorBB, /*endAccesses=*/{invocationEncoderAccess}); - } - - // === create the RemoteCallTarget ----------------------------------------- - auto remoteCallTargetDecl = ctx.getRemoteCallTargetDecl(); - auto remoteCallTargetTy = F.mapTypeIntoContext(remoteCallTargetDecl->getDeclaredInterfaceType()); - ManagedValue remoteCallTargetValue; - LoadInst *remoteCallSystemSelf = nullptr; - SILBasicBlock *remoteCallReturnBB = createBasicBlock("remoteCallReturnBB"); - SILBasicBlock *remoteCallErrorBB = createBasicBlock("remoteCallErrorBB"); - ManagedValue remoteCallReturnValue; - { - B.emitBlock(makeRemoteCallTargetBB); - createVoidPhiArgument(*this, ctx, makeRemoteCallTargetBB); - - // --- Get the `RemoteCallTarget` type - - // %28 = alloc_stack $RemoteCallTarget, let, name "target" // users: %58, %57, %50, %77, %76, %37 - auto remoteCallTargetBuf = emitTemporaryAllocation(loc, getLoweredType(remoteCallTargetTy)); - remoteCallTargetValue = emitManagedBufferWithCleanup(remoteCallTargetBuf); - - // %29 = metatype $@thin RemoteCallTarget.Type // user: %37 - auto remoteCallTargetMetatype = getLoweredType(MetatypeType::get(remoteCallTargetTy)); - auto remoteCallTargetMetatypeValue = B.createMetatype(loc, remoteCallTargetMetatype); - - auto mangledName = thunk.mangle(SILDeclRef::ManglingKind::Default); - auto mangledNameRef = llvm::StringRef(mangledName.c_str(), mangledName.size()); // FIXME(distributed): can just pass the mangledName? - - auto mangledNameString = emitStringLiteral(loc, mangledNameRef); // FIXME(distributed): trouble with the cleanups running in error BB too... - - // --- Create the RemoteCallTarget instance, passing the mangledNameString - // function_ref RemoteCallTarget.init(_mangledName:) - // %36 = function_ref @$s12_Distributed16RemoteCallTargetV12_mangledNameACSS_tcfC : $@convention(method) (@owned String, @thin RemoteCallTarget.Type) -> @out RemoteCallTarget // user: %37 - auto remoteCallTargetInitDecl = remoteCallTargetDecl->getDistributedRemoteCallTargetInitFunction(); - assert(remoteCallTargetInitDecl && "no 'RemoteCallTarget.init' found!"); - auto remoteCallTargetInitRef = SILDeclRef(remoteCallTargetInitDecl); - auto remoteCallTargetInitFnSIL = - builder.getOrCreateFunction(loc, remoteCallTargetInitRef, NotForDefinition); - SILValue remoteCallTargetInitFn = B.createFunctionRefFor(loc, remoteCallTargetInitFnSIL); - - // %37 = apply %36(%28, %35, %29) : $@convention(method) (@owned String, @thin RemoteCallTarget.Type) -> @out RemoteCallTarget - B.createApply( - loc, remoteCallTargetInitFn, {}, - {/*out*/ remoteCallTargetValue.getValue(), mangledNameString.forward(*this), - remoteCallTargetMetatypeValue}); - - // === Prepare `actorSystem.remoteCall()` -------------------------------- - // --- Prepare storage for the return value - // %38 = alloc_stack $String // users: %54, %56, %50, %75 - auto remoteCallReturnBuf = emitTemporaryAllocation(loc, resultType); - remoteCallReturnValue = emitManagedBufferWithCleanup(remoteCallReturnBuf); - - auto systemRef = emitActorPropertyReference( - *this, loc, selfValue.getValue(), - lookupProperty(selfTyDecl, ctx.Id_actorSystem)); - remoteCallSystemSelf = B.createTrivialLoadOr(loc, systemRef, LoadOwnershipQualifier::Copy); - - // --- Prepare 'throwing' type, Error or Never depending on throws of the target - auto effectiveErrorMetatype = getLoweredType( - MetatypeType::get(effectiveErrorTy, MetatypeRepresentation::Thick)); - SILValue thrownErrorMetatypeValue = - B.createMetatype(loc, effectiveErrorMetatype); - assert(thrownErrorMetatypeValue); - - // --- Prepare 'returning' type, can be 'Void' or specific type - SILValue returnMetatypeValue; - switch (methodTy->getNumResults()) { - case 0: { - auto voidTy = ctx.getVoidType(); - auto voidMetatype = - getLoweredType(MetatypeType::get(voidTy, MetatypeRepresentation::Thick)); - // %42 = metatype $@thin Never.Type - // %43 = metatype $@thick Never.Type /// we just have this one - returnMetatypeValue = B.createMetatype(loc, voidMetatype); - break; - } - case 1: { - CanType returnType = methodTy->getSingleResult().getInterfaceType(); - auto returnMetatype = getLoweredType(MetatypeType::get(returnType, MetatypeRepresentation::Thick)); - returnMetatypeValue = B.createMetatype(loc, returnMetatype); - break; - } - default: - llvm_unreachable("Can't support more results than one."); - } - assert(returnMetatypeValue); - - // function_ref FakeActorSystem.remoteCall(on:target:invocation:throwing:returning:) - // %49 = function_ref @$s27FakeDistributedActorSystems0aC6SystemV10remoteCall2on6target17invocationDecoder8throwing9returningq0_x_01_B006RemoteG6TargetVAA0A10InvocationVzq_mq0_mSgtYaKAJ0bC0RzSeR0_SER0_AA0C7AddressV2IDRtzr1_lF : $@convention(method) @async <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : DistributedActor, τ_0_2 : Decodable, τ_0_2 : Encodable, τ_0_0.ID == ActorAddress> (@guaranteed τ_0_0, @in_guaranteed RemoteCallTarget, @inout FakeInvocation, @thick τ_0_1.Type, Optional<@thick τ_0_2.Type>, @guaranteed FakeActorSystem) -> (@out τ_0_2, @error Error) // user: %50 - auto remoteCallFnDecl = - ctx.getRemoteCallOnDistributedActorSystem(selfTyDecl, /*isVoid=*/resultType.isVoid()); - assert(remoteCallFnDecl && "no remoteCall func found!"); - auto remoteCallFnRef = SILDeclRef(remoteCallFnDecl); - auto remoteCallFnSIL = - builder.getOrCreateFunction(loc, remoteCallFnRef, NotForDefinition); - SILValue remoteCallFn = B.createFunctionRefFor(loc, remoteCallFnSIL); - - // --- prepare subs for the 'remoteCall' - // - auto remoteCallGenericSig = remoteCallFnDecl->getGenericSignature(); - SmallVector subTypes; - SmallVector subConformances; - // <τ_0_0, - // τ_0_1, - // τ_0_2 // only if resultTy != Void - // where - // τ_0_0 : DistributedActor, - // τ_0_2 : Decodable, // only if resultTy != Void - // τ_0_2 : Encodable, // only if resultTy != Void - // τ_0_0.ID == ActorAddress - // > - // ( - // @guaranteed τ_0_0, - // @in_guaranteed RemoteCallTarget, - // @inout FakeInvocation, - // @thick τ_0_1.Type, - // @thick τ_0_2.Type, // only if resultTy != Void - // @guaranteed FakeActorSystem) - { - auto module = B.getModule().getSwiftModule(); - - // - pushDistributedActorConformance(*this, ctx, selfSILTy, subTypes, subConformances); - - // - if (fd->hasThrows()) { - pushErrorConformance(*this, ctx, subTypes, subConformances); - } else { - pushNeverErrorConformance(*this, ctx, subTypes, subConformances); - } - - if (!resultType.isVoid()) { - // - // pushSerializationRequirementConformance(*this, ctx, - // resultType, - // subTypes, subConformances); - subTypes.push_back(resultType.getASTType()); - - // FIXME(distributed): get the types from SerializationRequirement - subConformances.push_back(module->lookupConformance( - resultType.getASTType(), - ctx.getProtocol(KnownProtocolKind::Decodable))); - - subConformances.push_back(module->lookupConformance( - resultType.getASTType(), - ctx.getProtocol(KnownProtocolKind::Encodable))); - } - } - - SubstitutionMap remoteCallSubs = - SubstitutionMap::get(remoteCallGenericSig, - subTypes, subConformances); - - SmallVector remoteCallArgs; - // 'out' arguments: - if (!resultType.isVoid()) - remoteCallArgs.push_back(remoteCallReturnValue.forward(*this)); // return value buffer - // function arguments: - remoteCallArgs.push_back(selfValue.getValue()); // on actor - remoteCallArgs.push_back(remoteCallTargetValue.getValue()); // target - remoteCallArgs.push_back(invocationEncoderAccess); // invocation encoder - remoteCallArgs.push_back(thrownErrorMetatypeValue); // throwing type - if (!resultType.isVoid()) - remoteCallArgs.push_back(returnMetatypeValue); // returning type, only if non-void - // self: - remoteCallArgs.push_back(remoteCallSystemSelf); // ActorSystem - - // try_apply %49(%38, %2, %28, %48, %43, %46, %40) : $@convention(method) @async <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : DistributedActor, τ_0_2 : Decodable, τ_0_2 : Encodable, τ_0_0.ID == ActorAddress> (@guaranteed τ_0_0, @in_guaranteed RemoteCallTarget, @inout FakeInvocation, @thick τ_0_1.Type, Optional<@thick τ_0_2.Type>, @guaranteed FakeActorSystem) -> (@out τ_0_2, @error Error), normal bb5, error bb10 // id: %50 - B.createTryApply(loc, remoteCallFn, - remoteCallSubs, - remoteCallArgs, - /*normalBB=*/remoteCallReturnBB, - /*errorBB=*/remoteCallErrorBB); - } - - // === return -------------------------------------- - { - B.emitBlock(remoteCallReturnBB); - createVoidPhiArgument(*this, ctx, remoteCallReturnBB); - - auto result = remoteCallReturnValue.getValue(); - auto resultLoaded = B.createTrivialLoadOr(loc, result, LoadOwnershipQualifier::Copy, true); - - // FIXME(distributed): manual since I could not figure out how to NOT destroy_addr in the error path, where the memory is not initialized, so the destroy would fail SIL verification - B.createDestroyAddr(loc, result); -// B.createDeallocStack(loc, result); - - // FIXME: these are very hacky, how to do properly? - if (!remoteCallSystemSelf->getType().isTrivial(F)) - B.createDestroyValue(loc, remoteCallSystemSelf); - if (remoteCallSystemSelf->getType().isAddress()) - B.createEndLifetime(loc, remoteCallSystemSelf); - - B.createEndAccess(loc, invocationEncoderAccess, /*aborted=*/false); - Cleanups.emitCleanupsForReturn(CleanupLocation(loc), NotForUnwind); - B.createBranch(loc, returnBB, {resultLoaded}); - } - { - // FIXME(distributed): manual since I could not figure out how to NOT destroy_addr in the error path, where the memory is not initialized, so the destroy would fail SIL verification - // emitThrowWithCleanupBasicBlock(*this, loc, thunk, remoteCallErrorBB, errorBB, - // /*endAccesses*/{invocationEncoderAccess}, - // /*endLifetimes*/{remoteCallSystemSelf}); - B.emitBlock(remoteCallErrorBB); - SILValue error = remoteCallErrorBB->createPhiArgument( - fnConv.getSILErrorType(getTypeExpansionContext()), - OwnershipKind::Owned); - - // TODO(distributed): make those into cleanups - B.createEndAccess(loc, invocationEncoderAccess, /*aborted=*/false); - - // FIXME: these are very hacky, how to do properly? - if (!remoteCallSystemSelf->getType().isTrivial(F)) - B.createDestroyValue(loc, remoteCallSystemSelf); - if (remoteCallSystemSelf->getType().isAddress()) - B.createEndLifetime(loc, remoteCallSystemSelf); - - Cleanups.emitCleanupsForReturn(CleanupLocation(loc), IsForUnwind); - - B.createBranch(loc, errorBB, {error}); - } - } // end of `if isRemote { ... }` - - // Emit return logic - { - B.emitBlock(returnBB); - SILValue result = - returnBB->createPhiArgument(resultType, OwnershipKind::Owned); - - B.createReturn(loc, result); - } - - // Emit the rethrow logic. - { - B.emitBlock(errorBB); - SILValue error = errorBB->createPhiArgument( - fnConv.getSILErrorType(getTypeExpansionContext()), - OwnershipKind::Owned); - - B.createThrow(loc, error); - } -} diff --git a/lib/SILGen/SILGenExpr.cpp b/lib/SILGen/SILGenExpr.cpp index 8b19ad00e35ba..903297199e540 100644 --- a/lib/SILGen/SILGenExpr.cpp +++ b/lib/SILGen/SILGenExpr.cpp @@ -2801,7 +2801,7 @@ static SILFunction *getOrCreateKeyPathGetter(SILGenModule &SGM, auto thunk = builder.getOrCreateSharedFunction( loc, name, signature, IsBare, IsNotTransparent, (expansion == ResilienceExpansion::Minimal - ? IsSerializable + ? IsSerialized : IsNotSerialized), ProfileCounter(), IsThunk, IsNotDynamic, IsNotDistributed); if (!thunk->empty()) @@ -2960,7 +2960,7 @@ static SILFunction *getOrCreateKeyPathSetter(SILGenModule &SGM, auto thunk = builder.getOrCreateSharedFunction( loc, name, signature, IsBare, IsNotTransparent, (expansion == ResilienceExpansion::Minimal - ? IsSerializable + ? IsSerialized : IsNotSerialized), ProfileCounter(), IsThunk, IsNotDynamic, IsNotDistributed); if (!thunk->empty()) @@ -3148,7 +3148,7 @@ getOrCreateKeyPathEqualsAndHash(SILGenModule &SGM, equals = builder.getOrCreateSharedFunction( loc, name, signature, IsBare, IsNotTransparent, (expansion == ResilienceExpansion::Minimal - ? IsSerializable + ? IsSerialized : IsNotSerialized), ProfileCounter(), IsThunk, IsNotDynamic, IsNotDistributed); if (!equals->empty()) { @@ -3325,7 +3325,7 @@ getOrCreateKeyPathEqualsAndHash(SILGenModule &SGM, hash = builder.getOrCreateSharedFunction( loc, name, signature, IsBare, IsNotTransparent, (expansion == ResilienceExpansion::Minimal - ? IsSerializable + ? IsSerialized : IsNotSerialized), ProfileCounter(), IsThunk, IsNotDynamic, IsNotDistributed); if (!hash->empty()) { diff --git a/lib/SILGen/SILGenFunction.h b/lib/SILGen/SILGenFunction.h index 79703bf9f9f9d..4f513f4812e83 100644 --- a/lib/SILGen/SILGenFunction.h +++ b/lib/SILGen/SILGenFunction.h @@ -2055,9 +2055,6 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction /// corresponding SIL function for it. void emitDistributedActorFactory(FuncDecl *fd); - /// Generates a thunk from an actor function - void emitDistributedThunk(SILDeclRef thunk); - /// Notify transport that actor has initialized successfully, /// and is ready to receive messages. void emitDistributedActorReady( diff --git a/lib/SILGen/SILGenProlog.cpp b/lib/SILGen/SILGenProlog.cpp index a08891ce97c62..4168d7599fc3a 100644 --- a/lib/SILGen/SILGenProlog.cpp +++ b/lib/SILGen/SILGenProlog.cpp @@ -316,7 +316,7 @@ struct ArgumentInitHelper { assert(type->isMaterializable()); ++ArgNo; - if (PD->hasName()) { + if (PD->hasName() || PD->isIsolated()) { makeArgumentIntoBinding(type, &*f.begin(), PD); return; } diff --git a/lib/SILGen/SILGenThunk.cpp b/lib/SILGen/SILGenThunk.cpp index 2ddd40c854a6b..31b7e4398444a 100644 --- a/lib/SILGen/SILGenThunk.cpp +++ b/lib/SILGen/SILGenThunk.cpp @@ -60,7 +60,7 @@ SILFunction *SILGenModule::getDynamicThunk(SILDeclRef constant, SILGenFunctionBuilder builder(*this); auto F = builder.getOrCreateFunction( constant.getDecl(), name, SILLinkage::Shared, constantTy, IsBare, - IsTransparent, IsSerializable, IsNotDynamic, IsNotDistributed, + IsTransparent, IsSerialized, IsNotDynamic, IsNotDistributed, ProfileCounter(), IsThunk); if (F->empty()) { @@ -261,7 +261,7 @@ SILFunction *SILGenModule::getOrCreateForeignAsyncCompletionHandlerImplFunction( SILGenFunctionBuilder builder(*this); auto F = builder.getOrCreateSharedFunction(loc, name, implTy, - IsBare, IsTransparent, IsSerializable, + IsBare, IsTransparent, IsSerialized, ProfileCounter(), IsThunk, IsNotDynamic, @@ -514,11 +514,11 @@ getOrCreateReabstractionThunk(CanSILFunctionType thunkType, // The thunk that converts an actor-constrained, non-async function to an // async function is not serializable if the actor's visibility precludes it. - auto serializable = IsSerializable; + auto serializable = IsSerialized; if (fromGlobalActorBound) { auto globalActorLinkage = getTypeLinkage(fromGlobalActorBound); serializable = globalActorLinkage >= FormalLinkage::PublicNonUnique - ? IsSerializable : IsNotSerialized; + ? IsSerialized : IsNotSerialized; } SILGenFunctionBuilder builder(*this); diff --git a/lib/SILGen/SILGenType.cpp b/lib/SILGen/SILGenType.cpp index d7db58e39a54a..20dfe4bb206f4 100644 --- a/lib/SILGen/SILGenType.cpp +++ b/lib/SILGen/SILGenType.cpp @@ -533,7 +533,7 @@ class SILGenConformance : public SILGenWitnessTable { // Check if we already have a declaration or definition for this witness // table. - if (auto *wt = SGM.M.lookUpWitnessTable(Conformance, false)) { + if (auto *wt = SGM.M.lookUpWitnessTable(Conformance)) { // If we have a definition already, just return it. // // FIXME: I am not sure if this is possible, if it is not change this to an diff --git a/lib/SILOptimizer/Analysis/BasicCalleeAnalysis.cpp b/lib/SILOptimizer/Analysis/BasicCalleeAnalysis.cpp index 120327fb918d7..d2db31023ab02 100644 --- a/lib/SILOptimizer/Analysis/BasicCalleeAnalysis.cpp +++ b/lib/SILOptimizer/Analysis/BasicCalleeAnalysis.cpp @@ -57,8 +57,8 @@ bool CalleeList::allCalleesVisible() const { // TODO: exclude functions which are deserialized from modules in the same // resilience domain. if (Callee->isAvailableExternally() && - // shared_external functions are always emitted in the client. - Callee->getLinkage() != SILLinkage::SharedExternal) + // shared functions are always emitted in the client. + Callee->getLinkage() != SILLinkage::Shared) return false; } return true; @@ -214,7 +214,7 @@ CalleeCache::getSingleCalleeForWitnessMethod(WitnessMethodInst *WMI) const { // Attempt to find a specific callee for the given conformance and member. std::tie(CalleeFn, WT) = WMI->getModule().lookUpFunctionInWitnessTable( - WMI->getConformance(), WMI->getMember()); + WMI->getConformance(), WMI->getMember(), SILModule::LinkingMode::LinkNormal); return CalleeFn; } diff --git a/lib/SILOptimizer/IPO/CapturePropagation.cpp b/lib/SILOptimizer/IPO/CapturePropagation.cpp index 8a07d0b488272..0c97d7db19818 100644 --- a/lib/SILOptimizer/IPO/CapturePropagation.cpp +++ b/lib/SILOptimizer/IPO/CapturePropagation.cpp @@ -267,8 +267,8 @@ CanSILFunctionType getPartialApplyInterfaceResultType(PartialApplyInst *PAI) { SILFunction *CapturePropagation::specializeConstClosure(PartialApplyInst *PAI, SILFunction *OrigF) { IsSerialized_t Serialized = IsNotSerialized; - if (PAI->getFunction()->isSerialized() && OrigF->isSerialized()) - Serialized = IsSerializable; + if (PAI->getFunction()->isSerialized()) + Serialized = IsSerialized; std::string Name = getClonedName(PAI, Serialized, OrigF); diff --git a/lib/SILOptimizer/IPO/ClosureSpecializer.cpp b/lib/SILOptimizer/IPO/ClosureSpecializer.cpp index 74d767c907893..df518f954728d 100644 --- a/lib/SILOptimizer/IPO/ClosureSpecializer.cpp +++ b/lib/SILOptimizer/IPO/ClosureSpecializer.cpp @@ -489,9 +489,8 @@ static void rewriteApplyInst(const CallSiteDescriptor &CSDesc, } IsSerialized_t CallSiteDescriptor::isSerialized() const { - if (getClosure()->getFunction()->isSerialized() && - getApplyCallee()->isSerialized()) - return IsSerializable; + if (getClosure()->getFunction()->isSerialized()) + return IsSerialized; return IsNotSerialized; } diff --git a/lib/SILOptimizer/IPO/CrossModuleOptimization.cpp b/lib/SILOptimizer/IPO/CrossModuleOptimization.cpp index 84b9694a7c105..ddd1c3fb6160d 100644 --- a/lib/SILOptimizer/IPO/CrossModuleOptimization.cpp +++ b/lib/SILOptimizer/IPO/CrossModuleOptimization.cpp @@ -189,7 +189,7 @@ bool CrossModuleOptimization::canSerializeFunction( return false; } - if (function->isSerialized() == IsSerialized) + if (function->isSerialized()) return true; if (!function->isDefinition() || function->isAvailableExternally()) @@ -375,10 +375,9 @@ bool CrossModuleOptimization::canUseFromInline(SILFunction *function) { switch (function->getLinkage()) { case SILLinkage::PublicNonABI: - case SILLinkage::Shared: case SILLinkage::HiddenExternal: return false; - case SILLinkage::SharedExternal: + case SILLinkage::Shared: // static inline C functions if (!function->isDefinition() && function->hasClangNode()) return true; @@ -395,7 +394,7 @@ bool CrossModuleOptimization::canUseFromInline(SILFunction *function) { /// Decide whether to serialize a function. bool CrossModuleOptimization::shouldSerialize(SILFunction *function) { // Check if we already handled this function before. - if (function->isSerialized() == IsSerialized) + if (function->isSerialized()) return false; if (function->hasSemanticsAttr("optimize.no.crossmodule")) @@ -431,7 +430,7 @@ bool CrossModuleOptimization::shouldSerialize(SILFunction *function) { /// marked in \p canSerializeFlags. void CrossModuleOptimization::serializeFunction(SILFunction *function, const FunctionFlags &canSerializeFlags) { - if (function->isSerialized() == IsSerialized) + if (function->isSerialized()) return; if (!canSerializeFlags.lookup(function)) @@ -482,8 +481,7 @@ void CrossModuleOptimization::serializeInstruction(SILInstruction *inst, } } serializeFunction(callee, canSerializeFlags); - assert(callee->isSerialized() == IsSerialized || - callee->getLinkage() == SILLinkage::Public); + assert(callee->isSerialized() || callee->getLinkage() == SILLinkage::Public); return; } if (auto *GAI = dyn_cast(inst)) { diff --git a/lib/SILOptimizer/IPO/DeadFunctionElimination.cpp b/lib/SILOptimizer/IPO/DeadFunctionElimination.cpp index 7edf204c4eeef..3004339b6002e 100644 --- a/lib/SILOptimizer/IPO/DeadFunctionElimination.cpp +++ b/lib/SILOptimizer/IPO/DeadFunctionElimination.cpp @@ -253,8 +253,7 @@ class DeadFunctionAndGlobalElimination { /// Marks a witness table as alive if it is not alive yet. void ensureAliveConformance(const ProtocolConformance *C) { - SILWitnessTable *WT = Module->lookUpWitnessTable(C, - /*deserializeLazily*/ false); + SILWitnessTable *WT = Module->lookUpWitnessTable(C); if (!WT || isAlive(WT)) return; makeAlive(WT); @@ -312,9 +311,7 @@ class DeadFunctionAndGlobalElimination { mi->methodIsCalled = true; for (FuncImpl &FImpl : mi->implementingFunctions) { if (auto Conf = FImpl.Impl.dyn_cast()) { - SILWitnessTable *WT = - Module->lookUpWitnessTable(Conf, - /*deserializeLazily*/ false); + SILWitnessTable *WT = Module->lookUpWitnessTable(Conf); if (!WT || isAlive(WT)) makeAlive(FImpl.F); } else { diff --git a/lib/SILOptimizer/IPO/UsePrespecialized.cpp b/lib/SILOptimizer/IPO/UsePrespecialized.cpp index bdf9d6210c821..d85c927dd7793 100644 --- a/lib/SILOptimizer/IPO/UsePrespecialized.cpp +++ b/lib/SILOptimizer/IPO/UsePrespecialized.cpp @@ -115,12 +115,7 @@ bool UsePrespecialized::replaceByPrespecialized(SILFunction &F) { if (PrevF) { LLVM_DEBUG(llvm::dbgs() << "Found a specialization: " << ClonedName << "\n"); - if (PrevF->getLinkage() != SILLinkage::SharedExternal) - NewF = PrevF; - else { - LLVM_DEBUG(llvm::dbgs() << "Wrong linkage: " << (int)PrevF->getLinkage() - << "\n"); - } + NewF = PrevF; } if (!PrevF || !NewF) { diff --git a/lib/SILOptimizer/Mandatory/CapturePromotion.cpp b/lib/SILOptimizer/Mandatory/CapturePromotion.cpp index a6257b49263b7..b21b7d2b334a1 100644 --- a/lib/SILOptimizer/Mandatory/CapturePromotion.cpp +++ b/lib/SILOptimizer/Mandatory/CapturePromotion.cpp @@ -541,8 +541,8 @@ SILFunction *ClosureCloner::constructClonedFunction( SILFunction *origF = fri->getReferencedFunction(); IsSerialized_t isSerialized = IsNotSerialized; - if (f->isSerialized() && origF->isSerialized()) - isSerialized = IsSerialized_t::IsSerializable; + if (f->isSerialized()) + isSerialized = IsSerialized_t::IsSerialized; auto clonedName = getSpecializedName(origF, isSerialized, promotableIndices); diff --git a/lib/SILOptimizer/Mandatory/DiagnoseInfiniteRecursion.cpp b/lib/SILOptimizer/Mandatory/DiagnoseInfiniteRecursion.cpp index f6c77ff41f2d7..d1985258f5d44 100644 --- a/lib/SILOptimizer/Mandatory/DiagnoseInfiniteRecursion.cpp +++ b/lib/SILOptimizer/Mandatory/DiagnoseInfiniteRecursion.cpp @@ -100,7 +100,7 @@ static bool isRecursiveCall(FullApplySite applySite) { if (auto *WMI = dyn_cast(callee)) { auto funcAndTable = parentFunc->getModule().lookUpFunctionInWitnessTable( - WMI->getConformance(), WMI->getMember()); + WMI->getConformance(), WMI->getMember(), SILModule::LinkingMode::LinkNormal); return funcAndTable.first == parentFunc; } return false; diff --git a/lib/SILOptimizer/Mandatory/LowerHopToActor.cpp b/lib/SILOptimizer/Mandatory/LowerHopToActor.cpp index bc7cb999432b6..f5f3c674cccbd 100644 --- a/lib/SILOptimizer/Mandatory/LowerHopToActor.cpp +++ b/lib/SILOptimizer/Mandatory/LowerHopToActor.cpp @@ -178,7 +178,8 @@ SILValue LowerHopToActor::emitGetExecutor(SILLocation loc, SILValue actor, // If the actor type is a default actor, go ahead and devirtualize here. auto module = F->getModule().getSwiftModule(); SILValue unmarkedExecutor; - if (isDefaultActorType(actorType, module, F->getResilienceExpansion())) { + if (isDefaultActorType(actorType, module, F->getResilienceExpansion()) || + actorType->isDistributedActor()) { auto builtinName = ctx.getIdentifier( getBuiltinName(BuiltinValueKind::BuildDefaultActorExecutorRef)); auto builtinDecl = cast(getBuiltinValueDecl(ctx, builtinName)); diff --git a/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp b/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp index 398e84d0d6fc2..9be79987291d0 100644 --- a/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp +++ b/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp @@ -727,7 +727,7 @@ getCalleeFunction(SILFunction *F, FullApplySite AI, bool &IsThick, // If CalleeFunction is a declaration, see if we can load it. if (CalleeFunction->empty()) - AI.getModule().loadFunction(CalleeFunction); + AI.getModule().loadFunction(CalleeFunction, SILModule::LinkingMode::LinkNormal); // If we fail to load it, bail. if (CalleeFunction->empty()) diff --git a/lib/SILOptimizer/Mandatory/MoveKillsCopyableAddressesChecker.cpp b/lib/SILOptimizer/Mandatory/MoveKillsCopyableAddressesChecker.cpp index c33d1ef4a2560..112e8c45d1308 100644 --- a/lib/SILOptimizer/Mandatory/MoveKillsCopyableAddressesChecker.cpp +++ b/lib/SILOptimizer/Mandatory/MoveKillsCopyableAddressesChecker.cpp @@ -2338,6 +2338,7 @@ bool MoveKillsCopyableAddressesChecker::check(SILValue address) { // diagnostic. bool emittedSingleBBDiagnostic = false; for (auto *mvi : useState.markMoves) { + LLVM_DEBUG(llvm::dbgs() << "Performing single block analysis on: " << *mvi); emittedSingleBBDiagnostic |= performSingleBasicBlockAnalysis(address, mvi); } diff --git a/lib/SILOptimizer/Mandatory/OSLogOptimization.cpp b/lib/SILOptimizer/Mandatory/OSLogOptimization.cpp index dd1983b22013f..59cd78082d951 100644 --- a/lib/SILOptimizer/Mandatory/OSLogOptimization.cpp +++ b/lib/SILOptimizer/Mandatory/OSLogOptimization.cpp @@ -496,7 +496,8 @@ static SILValue emitCodeForConstantArray(ArrayRef elements, std::string allocatorMangledName = SILDeclRef(arrayAllocateDecl, SILDeclRef::Kind::Func).mangle(); SILFunction *arrayAllocateFun = - module.findFunction(allocatorMangledName, SILLinkage::PublicExternal); + module.loadFunction(allocatorMangledName, + SILModule::LinkingMode::LinkNormal); assert(arrayAllocateFun); SILFunction *arrayFinalizeFun = nullptr; @@ -505,9 +506,9 @@ static SILValue emitCodeForConstantArray(ArrayRef elements, std::string finalizeMangledName = SILDeclRef(arrayFinalizeDecl, SILDeclRef::Kind::Func).mangle(); arrayFinalizeFun = - module.findFunction(finalizeMangledName, SILLinkage::SharedExternal); + module.loadFunction(finalizeMangledName, + SILModule::LinkingMode::LinkNormal); assert(arrayFinalizeFun); - module.linkFunction(arrayFinalizeFun); } } diff --git a/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp index 2127117f770f4..2f4cc28b11afa 100644 --- a/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp +++ b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp @@ -433,8 +433,8 @@ bool SILCombiner::tryOptimizeKeypathKVCString(ApplyInst *AI, if (!init) return false; auto initRef = SILDeclRef(init.getDecl(), SILDeclRef::Kind::Allocator); - auto initFn = AI->getModule().findFunction(initRef.mangle(), - SILLinkage::PublicExternal); + auto initFn = AI->getModule().loadFunction(initRef.mangle(), + SILModule::LinkingMode::LinkAll); if (!initFn) return false; diff --git a/lib/SILOptimizer/Transforms/AllocBoxToStack.cpp b/lib/SILOptimizer/Transforms/AllocBoxToStack.cpp index 5a487d3e89f1a..098bc86388000 100644 --- a/lib/SILOptimizer/Transforms/AllocBoxToStack.cpp +++ b/lib/SILOptimizer/Transforms/AllocBoxToStack.cpp @@ -904,7 +904,7 @@ specializeApplySite(SILOptFunctionBuilder &FuncBuilder, ApplySite Apply, IsSerialized_t Serialized = IsNotSerialized; if (Apply.getFunction()->isSerialized()) - Serialized = IsSerializable; + Serialized = IsSerialized; std::string ClonedName = getClonedName(F, Serialized, PromotedCalleeArgIndices); diff --git a/lib/SILOptimizer/Transforms/ArrayElementValuePropagation.cpp b/lib/SILOptimizer/Transforms/ArrayElementValuePropagation.cpp index 8f84bde149b50..506e3accd994e 100644 --- a/lib/SILOptimizer/Transforms/ArrayElementValuePropagation.cpp +++ b/lib/SILOptimizer/Transforms/ArrayElementValuePropagation.cpp @@ -281,12 +281,14 @@ bool ArrayAllocation::replaceAppendContentOf() { return false; auto Mangled = SILDeclRef(AppendFnDecl, SILDeclRef::Kind::Func).mangle(); - SILFunction *AppendFn = M.findFunction(Mangled, SILLinkage::PublicExternal); + SILFunction *AppendFn = M.loadFunction(Mangled, + SILModule::LinkingMode::LinkAll); if (!AppendFn) return false; Mangled = SILDeclRef(ReserveFnDecl, SILDeclRef::Kind::Func).mangle(); - SILFunction *ReserveFn = M.findFunction(Mangled, SILLinkage::PublicExternal); + SILFunction *ReserveFn = M.loadFunction(Mangled, + SILModule::LinkingMode::LinkAll); if (!ReserveFn) return false; diff --git a/lib/SILOptimizer/Transforms/EagerSpecializer.cpp b/lib/SILOptimizer/Transforms/EagerSpecializer.cpp index 51045e3cb723a..1b6bb098efb68 100644 --- a/lib/SILOptimizer/Transforms/EagerSpecializer.cpp +++ b/lib/SILOptimizer/Transforms/EagerSpecializer.cpp @@ -309,8 +309,8 @@ class EagerDispatch { substConv(ReInfo.getSubstitutedType(), GenericFunc->getModule()), Builder(*GenericFunc), Loc(GenericFunc->getLocation()) { Builder.setCurrentDebugScope(GenericFunc->getDebugScope()); - IsClassF = Builder.getModule().findFunction( - "_swift_isClassOrObjCExistentialType", SILLinkage::PublicExternal); + IsClassF = Builder.getModule().loadFunction( + "_swift_isClassOrObjCExistentialType", SILModule::LinkingMode::LinkAll); assert(IsClassF); } @@ -848,9 +848,9 @@ void EagerSpecializerTransform::run() { targetFunc = SA->getTargetFunction(); if (!targetFunc->isDefinition()) { auto &module = FuncBuilder.getModule(); - bool success = module.loadFunction(targetFunc); + bool success = module.loadFunction(targetFunc, + SILModule::LinkingMode::LinkAll); assert(success); - module.linkFunction(targetFunc); } onlyCreatePrespecializations = true; } diff --git a/lib/SILOptimizer/Transforms/GenericSpecializer.cpp b/lib/SILOptimizer/Transforms/GenericSpecializer.cpp index 25a82281b0524..9da1a9d064900 100644 --- a/lib/SILOptimizer/Transforms/GenericSpecializer.cpp +++ b/lib/SILOptimizer/Transforms/GenericSpecializer.cpp @@ -254,7 +254,7 @@ optimizeInst(SILInstruction *inst, SILOptFunctionBuilder &funcBuilder, return true; if (callee->isExternalDeclaration()) - getModule()->loadFunction(callee); + getModule()->loadFunction(callee, SILModule::LinkingMode::LinkAll); if (callee->isExternalDeclaration()) return true; diff --git a/lib/SILOptimizer/Transforms/Outliner.cpp b/lib/SILOptimizer/Transforms/Outliner.cpp index daa8aa407f787..48228d5dd61f9 100644 --- a/lib/SILOptimizer/Transforms/Outliner.cpp +++ b/lib/SILOptimizer/Transforms/Outliner.cpp @@ -334,7 +334,7 @@ BridgedProperty::outline(SILModule &M) { auto *Fun = FuncBuilder.getOrCreateFunction( ObjCMethod->getLoc(), name, SILLinkage::Shared, FunctionType, IsNotBare, - IsNotTransparent, IsSerializable, IsNotDynamic, IsNotDistributed); + IsNotTransparent, IsSerialized, IsNotDynamic, IsNotDistributed); bool NeedsDefinition = Fun->empty(); if (Release) { @@ -1046,7 +1046,7 @@ ObjCMethodCall::outline(SILModule &M) { auto *Fun = FuncBuilder.getOrCreateFunction( ObjCMethod->getLoc(), name, SILLinkage::Shared, FunctionType, IsNotBare, - IsNotTransparent, IsSerializable, IsNotDynamic, IsNotDistributed); + IsNotTransparent, IsSerialized, IsNotDynamic, IsNotDistributed); bool NeedsDefinition = Fun->empty(); // Call the outlined function. diff --git a/lib/SILOptimizer/Transforms/SILMem2Reg.cpp b/lib/SILOptimizer/Transforms/SILMem2Reg.cpp index 7ad3d884bb223..edd2d8eaaefe0 100644 --- a/lib/SILOptimizer/Transforms/SILMem2Reg.cpp +++ b/lib/SILOptimizer/Transforms/SILMem2Reg.cpp @@ -1410,19 +1410,12 @@ class MemoryToRegisters { /// 1. (load %ASI) /// 2. (load (struct_element_addr/tuple_element_addr/unchecked_addr_cast %ASI)) static bool isAddressForLoad(SILInstruction *load, SILBasicBlock *&singleBlock, - bool &hasGuaranteedOwnership) { - - if (isa(load)) { - // SILMem2Reg is disabled when we find: - // (load [take] (struct_element_addr/tuple_element_addr %ASI)) - // struct_element_addr and tuple_element_addr are lowered into - // struct_extract and tuple_extract and these SIL instructions have a - // guaranteed ownership. For replacing load's users, we need an owned value. - // We will need a new copy and destroy of the running val placed after the - // last use. This is not implemented currently. - if (hasGuaranteedOwnership && - cast(load)->getOwnershipQualifier() == - LoadOwnershipQualifier::Take) { + bool &involvesUntakableProjection) { + if (auto *li = dyn_cast(load)) { + // SILMem2Reg is disabled when we find a load [take] of an untakable + // projection. See below for further discussion. + if (involvesUntakableProjection && + li->getOwnershipQualifier() == LoadOwnershipQualifier::Take) { return false; } return true; @@ -1432,17 +1425,40 @@ static bool isAddressForLoad(SILInstruction *load, SILBasicBlock *&singleBlock, !isa(load)) return false; - if (isa(load) || isa(load)) { - hasGuaranteedOwnership = true; - } + // None of the projections are lowered to owned values: + // + // struct_element_addr and tuple_element_addr instructions are lowered to + // struct_extract and tuple_extract instructions respectively. These both + // have guaranteed ownership (since they forward ownership and can only be + // used on a guaranteed value). + // + // unchecked_addr_cast instructions are lowered to unchecked_bitwise_cast + // instructions. These have unowned ownership. + // + // So in no case can a load [take] be lowered into the new projected value + // (some sequence of struct_extract, tuple_extract, and + // unchecked_bitwise_cast instructions) taking over ownership of the original + // value. Without additional changes. + // + // For example, for a sequence of element_addr projections could be + // transformed into a sequence of destructure instructions, followed by a + // sequence of structure instructions where all the original values are + // kept in place but the taken value is "knocked out" and replaced with + // undef. The running value would then be set to the newly structed + // "knockout" value. + // + // Alternatively, a new copy of the running value could be created and a new + // set of destroys placed after its last uses. + involvesUntakableProjection = true; // Recursively search for other (non-)loads in the instruction's uses. - for (auto *use : cast(load)->getUses()) { + auto *svi = cast(load); + for (auto *use : svi->getUses()) { SILInstruction *user = use->getUser(); if (user->getParent() != singleBlock) singleBlock = nullptr; - if (!isAddressForLoad(user, singleBlock, hasGuaranteedOwnership)) + if (!isAddressForLoad(user, singleBlock, involvesUntakableProjection)) return false; } return true; @@ -1476,8 +1492,8 @@ static bool isCaptured(AllocStackInst *asi, bool &inSingleBlock) { singleBlock = nullptr; // Loads are okay. - bool hasGuaranteedOwnership = false; - if (isAddressForLoad(user, singleBlock, hasGuaranteedOwnership)) + bool involvesUntakableProjection = false; + if (isAddressForLoad(user, singleBlock, involvesUntakableProjection)) continue; // We can store into an AllocStack (but not the pointer). @@ -1757,6 +1773,14 @@ bool MemoryToRegisters::promoteSingleAllocation(AllocStackInst *alloc) { b.createDeallocStack(next->getLoc(), alloc); } return true; + } else { + // For enums we require that all uses are in the same block. + // Otherwise there could be a switch_enum of an optional where the none-case + // does not have a destroy of the enum value. + // After transforming such an alloc_stack, the value would leak in the none- + // case block. + if (f.hasOwnership() && alloc->getType().isOrHasEnum()) + return false; } LLVM_DEBUG(llvm::dbgs() << "*** Need to insert BB arguments for " << *alloc); diff --git a/lib/SILOptimizer/Transforms/SSADestroyHoisting.cpp b/lib/SILOptimizer/Transforms/SSADestroyHoisting.cpp index 66b4042d5d2c1..471f58850cc96 100644 --- a/lib/SILOptimizer/Transforms/SSADestroyHoisting.cpp +++ b/lib/SILOptimizer/Transforms/SSADestroyHoisting.cpp @@ -173,13 +173,11 @@ struct KnownStorageUses : UniqueStorageUseVisitor { bool visitUnknownUse(Operand *use) override { auto *user = use->getUser(); - // Recognize any leaf users not already recognized by UniqueAddressUses. - // - // Destroy hoisting considers address_to_pointer to be a leaf use because - // any potential pointer access is already considered to be a - // deinitializtion barrier. - if (isa(user)) { - storageUsers.insert(use->getUser()); + if (isa(use->get()->getType().getASTType())) { + // Destroy hoisting considers address_to_pointer to be a leaf use because + // any potential pointer access is already considered to be a + // deinitializtion barrier. Consequently, any instruction that uses a + // value produced by address_to_pointer isn't regarded as a storage use. return true; } LLVM_DEBUG(llvm::dbgs() << "Unknown user " << *user); diff --git a/lib/SILOptimizer/Transforms/StringOptimization.cpp b/lib/SILOptimizer/Transforms/StringOptimization.cpp index bfc2fdc8611f5..ffe739efaea74 100644 --- a/lib/SILOptimizer/Transforms/StringOptimization.cpp +++ b/lib/SILOptimizer/Transforms/StringOptimization.cpp @@ -693,7 +693,7 @@ ApplyInst *StringOptimization::createStringInit(StringRef str, return nullptr; auto Mangled = SILDeclRef(makeUTF8Decl, SILDeclRef::Kind::Allocator).mangle(); - makeUTF8Func = module.findFunction(Mangled, SILLinkage::PublicExternal); + makeUTF8Func = module.loadFunction(Mangled, SILModule::LinkingMode::LinkAll); if (!makeUTF8Func) return nullptr; } diff --git a/lib/SILOptimizer/UtilityPasses/InstCount.cpp b/lib/SILOptimizer/UtilityPasses/InstCount.cpp index 8e7df92465103..d13b770879030 100644 --- a/lib/SILOptimizer/UtilityPasses/InstCount.cpp +++ b/lib/SILOptimizer/UtilityPasses/InstCount.cpp @@ -50,7 +50,6 @@ STATISTIC(TotalPrivateFuncs, "Number of private funcs"); STATISTIC(TotalSharedFuncs, "Number of shared funcs"); STATISTIC(TotalPublicExternalFuncs, "Number of public external funcs"); STATISTIC(TotalHiddenExternalFuncs, "Number of hidden external funcs"); -STATISTIC(TotalSharedExternalFuncs, "Number of shared external funcs"); // Individual instruction statistics #define INST(Id, Parent) \ @@ -135,9 +134,6 @@ class InstCount : public SILFunctionTransform { case SILLinkage::HiddenExternal: ++TotalHiddenExternalFuncs; break; - case SILLinkage::SharedExternal: - ++TotalSharedExternalFuncs; - break; } } }; diff --git a/lib/SILOptimizer/Utils/ConstExpr.cpp b/lib/SILOptimizer/Utils/ConstExpr.cpp index 565d18ea3e0ea..5f089dbcd32a6 100644 --- a/lib/SILOptimizer/Utils/ConstExpr.cpp +++ b/lib/SILOptimizer/Utils/ConstExpr.cpp @@ -430,7 +430,8 @@ SymbolicValue ConstExprFunctionState::computeConstantValue(SILValue value) { UnknownReason::UnknownWitnessMethodConformance); auto &module = wmi->getModule(); SILFunction *fn = - module.lookUpFunctionInWitnessTable(conf, wmi->getMember()).first; + module.lookUpFunctionInWitnessTable(conf, wmi->getMember(), + SILModule::LinkingMode::LinkAll).first; // If we were able to resolve it, then we can proceed. if (fn) return SymbolicValue::getFunction(fn); diff --git a/lib/SILOptimizer/Utils/Devirtualize.cpp b/lib/SILOptimizer/Utils/Devirtualize.cpp index 056dc78a7c95e..3ebb4495f19a7 100644 --- a/lib/SILOptimizer/Utils/Devirtualize.cpp +++ b/lib/SILOptimizer/Utils/Devirtualize.cpp @@ -1073,7 +1073,7 @@ static bool canDevirtualizeWitnessMethod(ApplySite applySite) { auto *wmi = cast(applySite.getCallee()); std::tie(f, wt) = applySite.getModule().lookUpFunctionInWitnessTable( - wmi->getConformance(), wmi->getMember()); + wmi->getConformance(), wmi->getMember(), SILModule::LinkingMode::LinkAll); if (!f) return false; @@ -1153,7 +1153,7 @@ swift::tryDevirtualizeWitnessMethod(ApplySite applySite, auto *wmi = cast(applySite.getCallee()); std::tie(f, wt) = applySite.getModule().lookUpFunctionInWitnessTable( - wmi->getConformance(), wmi->getMember()); + wmi->getConformance(), wmi->getMember(), SILModule::LinkingMode::LinkAll); return devirtualizeWitnessMethod(applySite, f, wmi->getConformance(), ore); } diff --git a/lib/SILOptimizer/Utils/DistributedActor.cpp b/lib/SILOptimizer/Utils/DistributedActor.cpp index 52c9fff6345ef..fd828d0468936 100644 --- a/lib/SILOptimizer/Utils/DistributedActor.cpp +++ b/lib/SILOptimizer/Utils/DistributedActor.cpp @@ -65,8 +65,8 @@ void emitDistributedActorSystemWitnessCall( auto &C = F.getASTContext(); // Dig out the conformance to DistributedActorSystem. - ProtocolDecl *systemProto = C.getProtocol(KnownProtocolKind::DistributedActorSystem); - assert(systemProto); + ProtocolDecl *DAS = C.getDistributedActorSystemDecl(); + assert(DAS); auto systemASTType = base->getType().getASTType(); auto *module = M.getSwiftModule(); ProtocolConformanceRef systemConfRef; @@ -83,16 +83,16 @@ void emitDistributedActorSystemWitnessCall( } if (systemASTType->isTypeParameter() || systemASTType->is()) { - systemConfRef = ProtocolConformanceRef(systemProto); + systemConfRef = ProtocolConformanceRef(DAS); } else { - systemConfRef = module->lookupConformance(systemASTType, systemProto); + systemConfRef = module->lookupConformance(systemASTType, DAS); } assert(!systemConfRef.isInvalid() && "Missing conformance to `DistributedActorSystem`"); // Dig out the method. - auto method = cast(systemProto->getSingleRequirement(methodName)); + auto method = cast(DAS->getSingleRequirement(methodName)); auto methodRef = SILDeclRef(method, SILDeclRef::Kind::Func); auto methodSILTy = M.Types.getConstantInfo(B.getTypeExpansionContext(), methodRef) @@ -147,7 +147,6 @@ void emitDistributedActorSystemWitnessCall( auto params = methodSILFnTy->getParameters(); for (size_t i = 0; i < args.size(); ++i) { auto arg = args[i]; - // FIXME(distributed): handle multiple ones (!!!!) if (params[i].isFormalIndirect() && !arg->getType().isAddress() && !dyn_cast(arg->getType().getASTType())) { diff --git a/lib/SILOptimizer/Utils/Generics.cpp b/lib/SILOptimizer/Utils/Generics.cpp index 9d17a52aa9217..7f4d0160fce49 100644 --- a/lib/SILOptimizer/Utils/Generics.cpp +++ b/lib/SILOptimizer/Utils/Generics.cpp @@ -1870,10 +1870,8 @@ SILFunction *GenericFuncSpecializer::lookupSpecialization() { // Otherwise we could end up that another de-serialized function from the // same module would reference the new (non-external) specialization we // would create here. - SpecializedF = M.findFunction(ClonedName, SILLinkage::SharedExternal); - if (SpecializedF) { - M.linkFunction(SpecializedF, SILModule::LinkingMode::LinkAll); - } + SpecializedF = M.loadFunction(ClonedName, SILModule::LinkingMode::LinkAll, + SILLinkage::Shared); } if (SpecializedF) { if (ReInfo.getSpecializedType() != SpecializedF->getLoweredFunctionType()) { @@ -2408,10 +2406,10 @@ static bool createPrespecialized(StringRef UnspecializedName, SILFunction *UnspecFunc = M.lookUpFunction(UnspecializedName); if (UnspecFunc) { if (!UnspecFunc->isDefinition()) - M.loadFunction(UnspecFunc); + M.loadFunction(UnspecFunc, SILModule::LinkingMode::LinkAll); } else { - UnspecFunc = M.getSILLoader()->lookupSILFunction(UnspecializedName, - /*declarationOnly*/ false); + UnspecFunc = M.loadFunction(UnspecializedName, + SILModule::LinkingMode::LinkAll); } if (!UnspecFunc || !UnspecFunc->isDefinition()) @@ -2623,8 +2621,8 @@ void swift::trySpecializeApplyOfGeneric( // cloning the callee. Otherwise, strip it off so that we can optimize // the body more. IsSerialized_t Serialized = IsNotSerialized; - if (F->isSerialized() && RefF->isSerialized()) - Serialized = IsSerializable; + if (F->isSerialized()) + Serialized = IsSerialized; // If it is OnoneSupport consider all specializations as non-serialized // as we do not SIL serialize their bodies. @@ -2731,6 +2729,17 @@ void swift::trySpecializeApplyOfGeneric( << SpecializedF->getLoweredFunctionType() << "\n"); NewFunctions.push_back(SpecializedF); } + if (F->isSerialized() && !SpecializedF->hasValidLinkageForFragileInline()) { + // If the specialized function already exists as a "IsNotSerialized" function, + // but now it's called from a "IsSerialized" function, we need to mark it as + // IsSerialized. + SpecializedF->setSerialized(IsSerialized); + assert(SpecializedF->hasValidLinkageForFragileInline()); + + // ... including all referenced shared functions. + FuncBuilder.getModule().linkFunction(SpecializedF, + SILModule::LinkingMode::LinkAll); + } ORE.emit([&]() { std::string Str; @@ -2873,9 +2882,10 @@ static SILFunction *lookupExistingSpecialization(SILModule &M, // TODO: Cache optimized specializations and perform lookup here? // Only check that this function exists, but don't read // its body. It can save some compile-time. - if (isKnownPrespecialization(FunctionName)) - return M.findFunction(FunctionName, SILLinkage::PublicExternal); - + if (isKnownPrespecialization(FunctionName)){ + return M.loadFunction(FunctionName, SILModule::LinkingMode::LinkAll, + SILLinkage::PublicExternal); + } return nullptr; } diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp index f2f471f44b0ae..687c216796fd2 100644 --- a/lib/Sema/CSApply.cpp +++ b/lib/Sema/CSApply.cpp @@ -378,10 +378,12 @@ namespace { /// /// \param expr The expression to be coerced. /// \param toType The type to which the expression will be coerced. + /// \param locator Locator describing where this existential conversion occurs. /// /// \return The coerced expression, whose type will be equivalent to /// \c toType. - Expr *coerceExistential(Expr *expr, Type toType); + Expr *coerceExistential(Expr *expr, Type toType, + ConstraintLocatorBuilder locator); /// Coerce an expression of (possibly unchecked) optional /// type to have a different (possibly unchecked) optional type. @@ -5275,51 +5277,6 @@ collectExistentialConformances(Type fromType, Type toType, return toType->getASTContext().AllocateCopy(conformances); } -Expr *ExprRewriter::coerceExistential(Expr *expr, Type toType) { - Type fromType = cs.getType(expr); - Type fromInstanceType = fromType; - Type toInstanceType = toType; - - // Look through metatypes - while ((fromInstanceType->is() || - fromInstanceType->is()) && - toInstanceType->is()) { - if (!fromInstanceType->is()) - fromInstanceType = fromInstanceType->castTo()->getInstanceType(); - toInstanceType = toInstanceType->castTo()->getExistentialInstanceType(); - } - - ASTContext &ctx = cs.getASTContext(); - - auto conformances = - collectExistentialConformances(fromInstanceType, toInstanceType, - cs.DC->getParentModule()); - - // For existential-to-existential coercions, open the source existential. - if (fromType->isAnyExistentialType()) { - fromType = OpenedArchetypeType::getAny(fromType->getCanonicalType(), - cs.DC->getGenericSignatureOfContext()); - - auto *archetypeVal = cs.cacheType( - new (ctx) OpaqueValueExpr(expr->getSourceRange(), fromType)); - - auto *result = cs.cacheType(ErasureExpr::create(ctx, archetypeVal, toType, - conformances)); - return cs.cacheType( - new (ctx) OpenExistentialExpr(expr, archetypeVal, result, - cs.getType(result))); - } - - // Load tuples with lvalue elements. - if (auto tupleType = fromType->getAs()) { - if (tupleType->hasLValueType()) { - expr = cs.coerceToRValue(expr); - } - } - - return cs.cacheType(ErasureExpr::create(ctx, expr, toType, conformances)); -} - /// Given that the given expression is an implicit conversion added /// to the target by coerceToType, find out how many OptionalEvaluationExprs /// it includes and the target. @@ -6044,15 +6001,9 @@ static Expr *buildElementConversion(ExprRewriter &rewriter, static CollectionUpcastConversionExpr::ConversionPair buildOpaqueElementConversion(ExprRewriter &rewriter, SourceRange srcRange, - Type srcCollectionType, Type destCollectionType, + Type srcType, Type destType, bool bridged, ConstraintLocatorBuilder locator, unsigned typeArgIndex) { - // We don't need this stuff unless we've got generalized casts. - Type srcType = srcCollectionType->castTo() - ->getGenericArgs()[typeArgIndex]; - Type destType = destCollectionType->castTo() - ->getGenericArgs()[typeArgIndex]; - // Build the conversion. auto &cs = rewriter.getConstraintSystem(); ASTContext &ctx = cs.getASTContext(); @@ -6201,9 +6152,12 @@ Expr *ExprRewriter::buildCollectionUpcastExpr( ASTContext &ctx = cs.getASTContext(); // Build the first value conversion. + auto fromArgs = cs.getType(expr)->castTo()->getGenericArgs(); + auto toArgs = toType->castTo()->getGenericArgs(); auto conv = - buildOpaqueElementConversion(*this, expr->getLoc(), cs.getType(expr), - toType, bridged, locator, 0); + buildOpaqueElementConversion(*this, expr->getLoc(), + fromArgs[0], toArgs[0], + bridged, locator, 0); // For single-parameter collections, form the upcast. if (ConstraintSystem::isArrayType(toType) || @@ -6217,8 +6171,9 @@ Expr *ExprRewriter::buildCollectionUpcastExpr( // Build the second value conversion. auto conv2 = - buildOpaqueElementConversion(*this, expr->getLoc(), cs.getType(expr), - toType, bridged, locator, 1); + buildOpaqueElementConversion(*this, expr->getLoc(), + fromArgs[1], toArgs[1], + bridged, locator, 1); return cs.cacheType( new (ctx) CollectionUpcastConversionExpr(expr, toType, conv, conv2)); @@ -6270,6 +6225,106 @@ Expr *ExprRewriter::buildObjCBridgeExpr(Expr *expr, Type toType, return forceBridgeFromObjectiveC(expr, toType); } +Expr *ExprRewriter::coerceExistential(Expr *expr, Type toType, + ConstraintLocatorBuilder locator) { + Type fromType = cs.getType(expr); + Type fromInstanceType = fromType; + Type toInstanceType = toType; + + // Look through metatypes + while ((fromInstanceType->is() || + fromInstanceType->is()) && + toInstanceType->is()) { + if (!fromInstanceType->is()) + fromInstanceType = fromInstanceType->castTo()->getInstanceType(); + toInstanceType = toInstanceType->castTo()->getExistentialInstanceType(); + } + + ASTContext &ctx = cs.getASTContext(); + + auto conformances = + collectExistentialConformances(fromInstanceType, toInstanceType, + cs.DC->getParentModule()); + + // Use the requirements of any parameterized protocols to build out fake + // argument conversions that can be used to infer opaque types. + SmallVector argConversions; + + auto fromConstraintType = fromInstanceType; + if (auto existential = fromConstraintType->getAs()) + fromConstraintType = existential->getConstraintType(); + + auto toConstraintType = toInstanceType; + if (auto existential = toConstraintType->getAs()) + toConstraintType = existential->getConstraintType(); + + auto fromPPT = fromConstraintType->getAs(); + auto toPPT = toConstraintType->getAs(); + + if (fromPPT && toPPT) { + assert(fromPPT->getArgs().size() >= toPPT->getArgs().size()); + for (unsigned i = 0; i < toPPT->getArgs().size(); ++i) { + auto firstTy = fromPPT->getArgs()[i]; + auto secondTy = toPPT->getArgs()[i]; + auto conv = + buildOpaqueElementConversion(*this, expr->getLoc(), + firstTy, + secondTy, + /*bridged*/ false, + locator, i); + argConversions.push_back(conv); + } + } else if ((fromPPT || toPPT) && + !fromInstanceType->isExistentialType()) { + auto parameterized = fromConstraintType; + auto base = toConstraintType; + if (toPPT) + std::swap(parameterized, base); + + SmallVector reqs; + parameterized->castTo() + ->getRequirements(base, reqs); + + for (unsigned i = 0; i < reqs.size(); ++i) { + const auto &req = reqs[i]; + assert(req.getKind() == RequirementKind::SameType); + auto conv = + buildOpaqueElementConversion(*this, expr->getLoc(), + req.getFirstType(), + req.getSecondType(), + /*bridged*/ false, + locator, i); + argConversions.push_back(conv); + } + } + + // For existential-to-existential coercions, open the source existential. + if (fromType->isAnyExistentialType()) { + fromType = OpenedArchetypeType::getAny(fromType->getCanonicalType(), + cs.DC->getGenericSignatureOfContext()); + + auto *archetypeVal = cs.cacheType( + new (ctx) OpaqueValueExpr(expr->getSourceRange(), fromType)); + + auto *result = cs.cacheType(ErasureExpr::create(ctx, archetypeVal, toType, + conformances, + argConversions)); + return cs.cacheType( + new (ctx) OpenExistentialExpr(expr, archetypeVal, result, + cs.getType(result))); + } + + // Load tuples with lvalue elements. + if (auto tupleType = fromType->getAs()) { + if (tupleType->hasLValueType()) { + expr = cs.coerceToRValue(expr); + } + } + + return cs.cacheType(ErasureExpr::create(ctx, expr, toType, + conformances, argConversions)); +} + Expr *ConstraintSystem::addImplicitLoadExpr(Expr *expr) { return TypeChecker::addImplicitLoadExpr( getASTContext(), expr, [this](Expr *expr) { return getType(expr); }, @@ -6359,7 +6414,7 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType, case ConversionRestrictionKind::Existential: case ConversionRestrictionKind::MetatypeToExistentialMetatype: - return coerceExistential(expr, toType); + return coerceExistential(expr, toType, locator); case ConversionRestrictionKind::ClassMetatypeToAnyObject: { assert(ctx.LangOpts.EnableObjCInterop && @@ -6905,7 +6960,7 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType, case TypeKind::ProtocolComposition: case TypeKind::ParameterizedProtocol: case TypeKind::Protocol: - return coerceExistential(expr, toType); + return coerceExistential(expr, toType, locator); // Coercion to Optional. case TypeKind::BoundGenericEnum: { @@ -7509,8 +7564,8 @@ Expr *ExprRewriter::finishApply(ApplyExpr *apply, Type openedType, apply->setArgs(args); cs.setType(apply, fnType->getResult()); - // If this is a call to a distributed method thunk, let's mark the - // call as implicitly throwing. + // If this is a call to a distributed method thunk, + // let's mark the call as implicitly throwing. if (isDistributedThunk(callee, apply->getFn())) { auto *FD = cast(callee.getDecl()); if (!FD->hasThrows()) diff --git a/lib/Sema/CSGen.cpp b/lib/Sema/CSGen.cpp index 9d292b284a53b..c6b195ae125b3 100644 --- a/lib/Sema/CSGen.cpp +++ b/lib/Sema/CSGen.cpp @@ -3733,11 +3733,9 @@ static bool generateInitPatternConstraints( return cs.generateWrappedPropertyTypeConstraints( wrappedVar, cs.getType(target.getAsExpr()), patternType); - if (!patternType->is()) { - // Add a conversion constraint between the types. - cs.addConstraint(ConstraintKind::Conversion, cs.getType(target.getAsExpr()), - patternType, locator, /*isFavored*/true); - } + // Add a conversion constraint between the types. + cs.addConstraint(ConstraintKind::Conversion, cs.getType(target.getAsExpr()), + patternType, locator, /*isFavored*/true); return false; } diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp index 9163b9c2bb0ae..b4809cbaecfbc 100644 --- a/lib/Sema/CSSimplify.cpp +++ b/lib/Sema/CSSimplify.cpp @@ -1348,7 +1348,8 @@ namespace { static Optional< std::tuple> shouldOpenExistentialCallArgument( - ValueDecl *callee, unsigned paramIdx, Type paramTy, Type argTy) { + ValueDecl *callee, unsigned paramIdx, Type paramTy, Type argTy, + Expr *argExpr, ConstraintSystem &cs) { if (!callee) return None; @@ -1382,6 +1383,20 @@ shouldOpenExistentialCallArgument( if (!paramTy->hasTypeVariable()) return None; + // An argument expression that explicitly coerces to an existential + // disables the implicit opening of the existential. + if (argExpr) { + if (auto argCoercion = dyn_cast( + argExpr->getSemanticsProvidingExpr())) { + if (auto typeRepr = argCoercion->getCastTypeRepr()) { + if (auto toType = cs.getType(typeRepr)) { + if (toType->isAnyExistentialType()) + return None; + } + } + } + } + OpenedExistentialAdjustments adjustments; // If the argument is inout, strip it off and we can add it back. @@ -1670,10 +1685,10 @@ static ConstraintSystem::TypeMatchResult matchCallArguments( auto argTy = argument.getOldType(); bool matchingAutoClosureResult = param.isAutoClosure(); + auto *argExpr = getArgumentExpr(locator.getAnchor(), argIdx); if (param.isAutoClosure() && !isSynthesizedArgument(argument)) { auto &ctx = cs.getASTContext(); auto *fnType = paramTy->castTo(); - auto *argExpr = getArgumentExpr(locator.getAnchor(), argIdx); // If this is a call to a function with a closure argument and the // parameter is an autoclosure, let's just increment the score here @@ -1715,7 +1730,7 @@ static ConstraintSystem::TypeMatchResult matchCallArguments( // If the argument is an existential type and the parameter is generic, // consider opening the existential type. if (auto existentialArg = shouldOpenExistentialCallArgument( - callee, paramIdx, paramTy, argTy)) { + callee, paramIdx, paramTy, argTy, argExpr, cs)) { // My kingdom for a decent "if let" in C++. TypeVariableType *openedTypeVar; Type existentialType; @@ -3120,8 +3135,18 @@ ConstraintSystem::matchDeepEqualityTypes(Type type1, Type type2, return result; } + // Arguments of parameterized protocol types have to match on the nose. + if (auto ppt1 = type1->getAs()) { + auto ppt2 = type2->castTo(); + return matchDeepTypeArguments(*this, subflags, + ppt1->getArgs(), + ppt2->getArgs(), + locator); + } + return getTypeMatchSuccess(); } + // Handle nominal types that are not directly generic. if (auto nominal1 = type1->getAs()) { auto nominal2 = type2->castTo(); @@ -3435,6 +3460,68 @@ ConstraintSystem::matchExistentialTypes(Type type1, Type type2, } } + auto constraintType1 = type1; + if (auto existential = constraintType1->getAs()) + constraintType1 = existential->getConstraintType(); + + auto constraintType2 = type2; + if (auto existential = constraintType2->getAs()) + constraintType2 = existential->getConstraintType(); + + auto ppt1 = constraintType1->getAs(); + auto ppt2 = constraintType2->getAs(); + + // With two parameterized protocols, we've already made sure conformance + // constraints are satisified. Try to match the arguments! + if (ppt1 && ppt2) { + ArrayRef longerArgs = ppt1->getArgs(); + ArrayRef shorterArgs = ppt2->getArgs(); + // The more constrained of the two types had better be the first type - + // otherwise we're forgetting requirements. + if (longerArgs.size() < shorterArgs.size()) { + return getTypeMatchFailure(locator); + } + + // Line up the the arguments of the parameterized protocol. + // FIXME: Extend the locator path to point to the argument + // inducing the requirement. + for (const auto &pair : llvm::zip_first(shorterArgs, longerArgs)) { + auto result = matchTypes(std::get<0>(pair), std::get<1>(pair), + ConstraintKind::Bind, + subflags, locator); + if (result.isFailure()) + return result; + } + } else if (ppt1 && type2->isExistentialType()) { + // P converts to (P & Q & ...) trivially... + return getTypeMatchSuccess(); + } else if (ppt2 && type1->isExistentialType()) { + // But (P & Q & ...) does not convert to P + return getTypeMatchFailure(locator); + } else if (ppt1 || ppt2) { + auto parameterized = constraintType1; + auto base = constraintType2; + if (ppt2) + std::swap(parameterized, base); + + // One of the two is parameterized, and the other is a concrete type. + // Substitute the base into the requirements of the parameterized type and + // discharge the requirements of the parameterized protocol. + // FIXME: Extend the locator path to point to the argument + // inducing the requirement. + SmallVector reqs; + parameterized->castTo() + ->getRequirements(base, reqs); + for (const auto &req : reqs) { + assert(req.getKind() == RequirementKind::SameType); + auto result = matchTypes(req.getFirstType(), req.getSecondType(), + ConstraintKind::Bind, + subflags, locator); + if (result.isFailure()) + return result; + } + } + return getTypeMatchSuccess(); } @@ -10113,18 +10200,8 @@ ConstraintSystem::simplifyOpenedExistentialOfConstraint( if (type2->isAnyExistentialType()) { // We have the existential side. Produce an opened archetype and bind // type1 to it. - bool isMetatype = false; - auto instanceTy = type2; - if (auto metaTy = type2->getAs()) { - isMetatype = true; - instanceTy = metaTy->getExistentialInstanceType(); - } - assert(instanceTy->isExistentialType()); - Type openedTy = - OpenedArchetypeType::get(instanceTy->getCanonicalType(), - DC->getGenericSignatureOfContext()); - if (isMetatype) - openedTy = MetatypeType::get(openedTy, getASTContext()); + Type openedTy = openExistentialType(type2, getConstraintLocator(locator)) + .first; return matchTypes(type1, openedTy, ConstraintKind::Bind, subflags, locator); } if (!type2->isTypeVariableOrMember()) diff --git a/lib/Sema/CodeSynthesis.cpp b/lib/Sema/CodeSynthesis.cpp index 5d265b053ef3d..60e06e29bca89 100644 --- a/lib/Sema/CodeSynthesis.cpp +++ b/lib/Sema/CodeSynthesis.cpp @@ -292,8 +292,8 @@ static ConstructorDecl *createImplicitConstructor(NominalTypeDecl *decl, params.push_back(arg); } } else if (ICK == ImplicitConstructorKind::DefaultDistributedActor) { - assert(isa(decl)); - assert(decl->isDistributedActor() && + auto classDecl = dyn_cast(decl); + assert(classDecl && decl->isDistributedActor() && "Only 'distributed actor' type can gain implicit distributed actor init"); /// Add 'system' parameter to default init of distributed actors. @@ -305,7 +305,7 @@ static ConstructorDecl *createImplicitConstructor(NominalTypeDecl *decl, auto *arg = new (ctx) ParamDecl(SourceLoc(), Loc, ctx.Id_system, Loc, ctx.Id_system, decl); arg->setSpecifier(ParamSpecifier::Default); - arg->setInterfaceType(getDistributedActorSystemType(decl)); + arg->setInterfaceType(getDistributedActorSystemType(classDecl)); arg->setImplicit(); params.push_back(arg); diff --git a/lib/Sema/CodeSynthesisDistributedActor.cpp b/lib/Sema/CodeSynthesisDistributedActor.cpp index c99e2881c43e0..47aaaf16689d9 100644 --- a/lib/Sema/CodeSynthesisDistributedActor.cpp +++ b/lib/Sema/CodeSynthesisDistributedActor.cpp @@ -21,6 +21,7 @@ #include "swift/AST/Initializer.h" #include "swift/AST/ParameterList.h" #include "swift/AST/TypeCheckRequests.h" +#include "swift/AST/ASTMangler.h" #include "swift/AST/DistributedDecl.h" #include "swift/Basic/Defer.h" #include "swift/ClangImporter/ClangModule.h" @@ -30,6 +31,11 @@ #include "DerivedConformances.h" using namespace swift; + +/******************************************************************************/ +/************************ PROPERTY SYNTHESIS **********************************/ +/******************************************************************************/ + // Note: This would be nice to implement in DerivedConformanceDistributedActor, // but we can't since those are lazily triggered and an implementation exists // for the 'id' property because 'Identifiable.id' has an extension that impls @@ -38,14 +44,11 @@ using namespace swift; // The "derived" mechanisms are not really geared towards emitting for // what already has a witness. static VarDecl *addImplicitDistributedActorIDProperty( - NominalTypeDecl *nominal) { + ClassDecl *nominal) { if (!nominal || !nominal->isDistributedActor()) return nullptr; - // ==== if the 'id' already exists, return it auto &C = nominal->getASTContext(); -// if (auto existing = nominal->lookupDirect(C.Id_id)) -// return existing; // ==== Synthesize and add 'id' property to the actor decl Type propertyType = getDistributedActorIDType(nominal); @@ -81,9 +84,517 @@ static VarDecl *addImplicitDistributedActorIDProperty( } /******************************************************************************/ -/************************ SYNTHESIS ENTRY POINT *******************************/ +/*********************** DISTRIBUTED THUNK SYNTHESIS **************************/ +/******************************************************************************/ + +static void forwardParameters(AbstractFunctionDecl *afd, + SmallVectorImpl &forwardingParams) { + auto &C = afd->getASTContext(); + for (auto param : *afd->getParameters()) { + forwardingParams.push_back(new (C) DeclRefExpr( + ConcreteDeclRef(param), DeclNameLoc(), /*implicit=*/true, + swift::AccessSemantics::Ordinary, + afd->mapTypeIntoContext(param->getInterfaceType()))); + } +} + +static std::pair +deriveBodyDistributed_thunk(AbstractFunctionDecl *thunk, void *context) { + auto implicit = true; + ASTContext &C = thunk->getASTContext(); + auto module = thunk->getParentModule(); + + // mock locations, we're a thunk and don't really need detailed locations + const SourceLoc sloc = SourceLoc(); + const DeclNameLoc dloc = DeclNameLoc(); + + auto func = static_cast(context); + auto funcDC = func->getDeclContext(); + NominalTypeDecl *nominal = funcDC->getSelfNominalTypeDecl(); + assert(nominal && nominal->isDistributedActor() && + "Distributed function must be part of distributed actor"); + + auto selfDecl = thunk->getImplicitSelfDecl(); + selfDecl->getAttrs().add(new (C) KnownToBeLocalAttr(implicit)); + auto selfRefExpr = new (C) DeclRefExpr(selfDecl, dloc, implicit); + + // === return type + Type returnTy = func->getResultInterfaceType(); + auto isVoidReturn = returnTy->isVoid(); + + // === self.actorSystem + ProtocolDecl *DAS = C.getDistributedActorSystemDecl(); + Type systemTy = getConcreteReplacementForProtocolActorSystemType(thunk); + assert(systemTy && "distributed thunk can only be synthesized with concrete " + "actor system types"); + NominalTypeDecl *systemDecl = systemTy->getAnyNominal(); + assert(systemDecl); + auto systemConfRef = module->lookupConformance(systemTy, DAS); + assert(systemConfRef && "ActorSystem must conform to DistributedActorSystem"); + + // === ActorSystem.InvocationEncoder + Type invocationEncoderTy = + getDistributedActorSystemInvocationEncoderType(systemDecl); + NominalTypeDecl *invocationEncoderDecl = invocationEncoderTy->getAnyNominal(); + + // === Type: + StructDecl *RCT = C.getRemoteCallTargetDecl(); + Type remoteCallTargetTy = RCT->getDeclaredInterfaceType(); + + // === __isRemoteActor(self) + ArgumentList *isRemoteArgs = + ArgumentList::forImplicitSingle(C, /*label=*/Identifier(), selfRefExpr); + + FuncDecl *isRemoteFn = C.getIsRemoteDistributedActor(); + assert(isRemoteFn && "Could not find 'is remote' function, is the " + "'_Distributed' module available?"); + auto isRemoteDeclRef = + UnresolvedDeclRefExpr::createImplicit(C, isRemoteFn->getName()); + auto isRemote = + CallExpr::createImplicit(C, isRemoteDeclRef, isRemoteArgs); + + // === local branch ---------------------------------------------------------- + // -- forward arguments + SmallVector forwardingParams; + forwardParameters(thunk, forwardingParams); + auto funcRef = UnresolvedDeclRefExpr::createImplicit(C, func->getName()); + auto forwardingArgList = ArgumentList::forImplicitCallTo(funcRef->getName(), forwardingParams, C); + + auto funcDeclRef = + UnresolvedDotExpr::createImplicit(C, selfRefExpr, func->getBaseName()); + Expr *localFuncCall = CallExpr::createImplicit(C, funcDeclRef, forwardingArgList); + localFuncCall = AwaitExpr::createImplicit(C, sloc, localFuncCall); + if (func->hasThrows()) { + localFuncCall = TryExpr::createImplicit(C, sloc, localFuncCall); + } + auto returnLocalFuncCall = new (C) ReturnStmt(sloc, localFuncCall, implicit); + auto localBranchStmt = + BraceStmt::create(C, sloc, {returnLocalFuncCall}, sloc, implicit); + + // === remote branch -------------------------------------------------------- + SmallVector remoteBranchStmts; + // --- self.actorSystem + auto systemProperty = nominal->getDistributedActorSystemProperty(); + auto systemRefExpr = + UnresolvedDotExpr::createImplicit( + C, new (C) DeclRefExpr(selfDecl, dloc, implicit), // TODO: make createImplicit + C.Id_actorSystem); + + auto *systemVar = + new (C) VarDecl(/*isStatic=*/false, VarDecl::Introducer::Let, sloc, + C.Id_system, thunk); + systemVar->setInterfaceType(systemProperty->getInterfaceType()); + systemVar->setImplicit(); + systemVar->setSynthesized(); + + Pattern *systemPattern = NamedPattern::createImplicit(C, systemVar); + + auto systemPB = PatternBindingDecl::createImplicit( + C, StaticSpellingKind::None, systemPattern, systemRefExpr, + thunk); + + remoteBranchStmts.push_back(systemPB); + remoteBranchStmts.push_back(systemVar); + + // --- invocationEncoder = system.makeInvocationEncoder() + auto *invocationVar = + new (C) VarDecl(/*isStatic=*/false, VarDecl::Introducer::Var, sloc, + C.Id_invocation, thunk); + invocationVar->setInterfaceType(invocationEncoderTy); + invocationVar->setImplicit(); + invocationVar->setSynthesized(); + + { + Pattern *invocationPattern = NamedPattern::createImplicit(C, invocationVar); + + FuncDecl *makeInvocationEncoderDecl = + C.getMakeInvocationEncoderOnDistributedActorSystem(func); + auto makeInvocationExpr = UnresolvedDotExpr::createImplicit( + C, new (C) DeclRefExpr(ConcreteDeclRef(systemVar), dloc, implicit), + makeInvocationEncoderDecl->getName()); + auto *makeInvocationArgs = ArgumentList::createImplicit(C, {}); + auto makeInvocationCallExpr = + CallExpr::createImplicit(C, makeInvocationExpr, makeInvocationArgs); + makeInvocationCallExpr->setThrows(false); + + auto invocationEncoderPB = PatternBindingDecl::createImplicit( + C, StaticSpellingKind::None, invocationPattern, makeInvocationCallExpr, + thunk); + remoteBranchStmts.push_back(invocationEncoderPB); + remoteBranchStmts.push_back(invocationVar); + } + + // --- Recording invocation details + // -- recordGenericSubstitution(s) + if (func->isGeneric() || nominal->isGeneric()) { + auto recordGenericSubstitutionDecl = + C.getRecordGenericSubstitutionOnDistributedInvocationEncoder(invocationEncoderDecl); + assert(recordGenericSubstitutionDecl); + auto recordGenericSubstitutionDeclRef = + UnresolvedDeclRefExpr::createImplicit( + C, recordGenericSubstitutionDecl->getName()); + + auto sig = func->getGenericSignature(); + for (auto genParamType : sig.getGenericParams()) { + + auto subTypeExpr = new (C) DotSelfExpr( + TypeExpr::createImplicit(thunk->mapTypeIntoContext(genParamType), C), + sloc, sloc, thunk->mapTypeIntoContext(genParamType)); + + auto recordGenericSubArgsList = + ArgumentList::forImplicitCallTo( + recordGenericSubstitutionDeclRef->getName(), + {subTypeExpr}, + C); + + Expr *recordGenericSub = + CallExpr::createImplicit(C, + UnresolvedDotExpr::createImplicit(C, + new (C) DeclRefExpr(ConcreteDeclRef(invocationVar), dloc, implicit, AccessSemantics::Ordinary), + recordGenericSubstitutionDecl->getName()), + recordGenericSubArgsList); + recordGenericSub = TryExpr::createImplicit(C, sloc, recordGenericSub); + + remoteBranchStmts.push_back(recordGenericSub); + } + } + + // -- recordArgument(s) + { + auto recordArgumentDecl = + C.getRecordArgumentOnDistributedInvocationEncoder(invocationEncoderDecl); + assert(recordArgumentDecl); + + for (auto param : *thunk->getParameters()) { + auto recordArgumentDeclRef = UnresolvedDeclRefExpr::createImplicit( + C, recordArgumentDecl->getName()); + + auto recordArgArgsList = ArgumentList::forImplicitCallTo( + recordArgumentDeclRef->getName(), + { + new (C) DeclRefExpr( + ConcreteDeclRef(param), dloc, implicit, + AccessSemantics::Ordinary, + thunk->mapTypeIntoContext(param->getInterfaceType())) + }, C); + + auto tryRecordArgExpr = TryExpr::createImplicit(C, sloc, + CallExpr::createImplicit(C, + UnresolvedDotExpr::createImplicit(C, + new (C) DeclRefExpr(ConcreteDeclRef(invocationVar), dloc, implicit, AccessSemantics::Ordinary), + recordArgumentDecl->getName()), + recordArgArgsList)); + + remoteBranchStmts.push_back(tryRecordArgExpr); + } + } + + // -- recordErrorType + if (func->hasThrows()) { + // Error.self + auto errorDecl = C.getErrorDecl(); + auto *errorTypeExpr = new (C) DotSelfExpr( + UnresolvedDeclRefExpr::createImplicit(C, errorDecl->getName()), sloc, + sloc, errorDecl->getDeclaredInterfaceType()); + + auto recordErrorDecl = C.getRecordErrorTypeOnDistributedInvocationEncoder( + invocationEncoderDecl); + assert(recordErrorDecl); + auto recordErrorDeclRef = + UnresolvedDeclRefExpr::createImplicit(C, recordErrorDecl->getName()); + + auto recordArgsList = ArgumentList::forImplicitCallTo( + recordErrorDeclRef->getName(), + {errorTypeExpr}, + C); + auto tryRecordErrorTyExpr = TryExpr::createImplicit(C, sloc, + CallExpr::createImplicit(C, + UnresolvedDotExpr::createImplicit(C, + new (C) DeclRefExpr(ConcreteDeclRef(invocationVar), dloc, implicit, AccessSemantics::Ordinary), + recordErrorDecl->getName()), + recordArgsList)); + + remoteBranchStmts.push_back(tryRecordErrorTyExpr); + } + + // -- recordReturnType + if (!isVoidReturn) { + // Result.self + auto resultType = func->getResultInterfaceType(); + auto *metaTypeRef = TypeExpr::createImplicit(resultType, C); + auto *resultTypeExpr = + new (C) DotSelfExpr(metaTypeRef, sloc, sloc, resultType); + + auto recordReturnTypeDecl = + C.getRecordReturnTypeOnDistributedInvocationEncoder( + invocationEncoderDecl); + auto recordReturnTypeDeclRef = + UnresolvedDeclRefExpr::createImplicit(C, recordReturnTypeDecl->getName()); + + auto recordArgsList = ArgumentList::forImplicitCallTo( + recordReturnTypeDeclRef->getName(), + {resultTypeExpr}, + C); + auto tryRecordReturnTyExpr = TryExpr::createImplicit(C, sloc, + CallExpr::createImplicit(C, + UnresolvedDotExpr::createImplicit(C, + new (C) DeclRefExpr(ConcreteDeclRef(invocationVar), dloc, implicit, + AccessSemantics::Ordinary), + recordReturnTypeDecl->getName()), + recordArgsList)); + + remoteBranchStmts.push_back(tryRecordReturnTyExpr); + } + + // -- doneRecording + { + auto doneRecordingDecl = + C.getDoneRecordingOnDistributedInvocationEncoder(invocationEncoderDecl); + auto doneRecordingDeclRef = + UnresolvedDeclRefExpr::createImplicit(C, doneRecordingDecl->getName()); + + auto argsList = + ArgumentList::forImplicitCallTo(doneRecordingDeclRef->getName(), {}, C); + auto tryDoneRecordingExpr = TryExpr::createImplicit(C, sloc, + CallExpr::createImplicit(C, + UnresolvedDotExpr::createImplicit(C, + new (C) DeclRefExpr(ConcreteDeclRef(invocationVar), dloc, implicit, + AccessSemantics::Ordinary, + invocationVar->getInterfaceType()), + doneRecordingDecl->getName()), + argsList)); + + remoteBranchStmts.push_back(tryDoneRecordingExpr); + } + + // === Prepare the 'RemoteCallTarget' + VarDecl *targetVar = + new (C) VarDecl(/*isStatic=*/false, VarDecl::Introducer::Let, sloc, + C.Id_target, thunk); + + { + // --- Mangle the thunk name + Mangle::ASTMangler mangler; + auto symbolKind = swift::Mangle::ASTMangler::SymbolKind::DistributedThunk; + auto mangled = C.AllocateCopy(mangler.mangleEntity(thunk, symbolKind)); + StringRef mangledTargetStringRef = StringRef(mangled); + auto mangledTargetStringLiteral = new (C) + StringLiteralExpr(mangledTargetStringRef, SourceRange(), implicit); + + // --- let target = RemoteCallTarget() + targetVar->setInterfaceType(remoteCallTargetTy); + targetVar->setImplicit(); + targetVar->setSynthesized(); + + Pattern *targetPattern = NamedPattern::createImplicit(C, targetVar); + + auto remoteCallTargetInitDecl = + RCT->getDistributedRemoteCallTargetInitFunction(); + auto remoteCallTargetInitDeclRef = UnresolvedDeclRefExpr::createImplicit( + C, remoteCallTargetInitDecl->getEffectiveFullName()); + + auto initTargetExpr = UnresolvedDeclRefExpr::createImplicit( + C, RCT->getName()); + auto initTargetArgs = ArgumentList::forImplicitCallTo( + remoteCallTargetInitDeclRef->getName(), + {mangledTargetStringLiteral}, C); + + auto initTargetCallExpr = + CallExpr::createImplicit(C, initTargetExpr, initTargetArgs); + + auto targetPB = PatternBindingDecl::createImplicit( + C, StaticSpellingKind::None, targetPattern, initTargetCallExpr, thunk); + + remoteBranchStmts.push_back(targetPB); + remoteBranchStmts.push_back(targetVar); + } + + // === Make the 'remoteCall(Void)(...)' + { + auto remoteCallDecl = + C.getRemoteCallOnDistributedActorSystem(systemDecl, isVoidReturn); + auto systemRemoteCallRef = + UnresolvedDotExpr::createImplicit( + C, new (C) DeclRefExpr(ConcreteDeclRef(systemVar), dloc, implicit), + remoteCallDecl->getName()); + + SmallVector args; + // -- on actor: Act + args.push_back(new (C) DeclRefExpr(selfDecl, dloc, implicit, + swift::AccessSemantics::Ordinary, + selfDecl->getInterfaceType())); + // -- target: RemoteCallTarget + args.push_back(new (C) DeclRefExpr(ConcreteDeclRef(targetVar), dloc, implicit, + AccessSemantics::Ordinary, + RCT->getDeclaredInterfaceType())); + // -- invocation: inout InvocationEncoder + args.push_back(new (C) InOutExpr(sloc, + new (C) DeclRefExpr(ConcreteDeclRef(invocationVar), dloc, + implicit, AccessSemantics::Ordinary, invocationEncoderTy), invocationEncoderTy, implicit)); + + // -- throwing: Err.Type + if (func->hasThrows()) { + // Error.self + auto errorDecl = C.getErrorDecl(); + auto *errorTypeExpr = new (C) DotSelfExpr( + UnresolvedDeclRefExpr::createImplicit(C, errorDecl->getName()), sloc, + sloc, errorDecl->getDeclaredInterfaceType()); + + args.push_back(errorTypeExpr); + } else { + // Never.self + auto neverDecl = C.getNeverDecl(); + auto *neverTypeExpr = new (C) DotSelfExpr( + UnresolvedDeclRefExpr::createImplicit(C, neverDecl->getName()), sloc, + sloc, neverDecl->getDeclaredInterfaceType()); + args.push_back(neverTypeExpr); + } + + // -- returning: Res.Type + if (!isVoidReturn) { + // Result.self + auto resultType = func->getResultInterfaceType(); + auto *metaTypeRef = TypeExpr::createImplicit(resultType, C); + auto *resultTypeExpr = + new (C) DotSelfExpr(metaTypeRef, sloc, sloc, resultType); + + args.push_back(resultTypeExpr); + } + + assert(args.size() == remoteCallDecl->getParameters()->size()); + auto remoteCallArgs = ArgumentList::forImplicitCallTo( + systemRemoteCallRef->getName(), args, C); + + Expr *remoteCallExpr = + CallExpr::createImplicit(C, systemRemoteCallRef, remoteCallArgs); + remoteCallExpr = AwaitExpr::createImplicit(C, sloc, remoteCallExpr); + remoteCallExpr = TryExpr::createImplicit(C, sloc, remoteCallExpr); + auto returnRemoteCall = + new (C) ReturnStmt(sloc, remoteCallExpr, implicit); + remoteBranchStmts.push_back(returnRemoteCall); + } + + // --------------------------------------------------------------------------- + auto remoteBranchStmt = + BraceStmt::create(C, sloc, remoteBranchStmts, sloc, implicit); + + // --------------------------------------------------------------------------- + // === if (isRemote(...) else + auto ifStmt = new (C) IfStmt(sloc, /*condition=*/isRemote, + /*then=*/remoteBranchStmt, sloc, + /*else=*/localBranchStmt, implicit, C); + + auto body = BraceStmt::create(C, sloc, {ifStmt}, sloc, implicit); + return {body, /*isTypeChecked=*/false}; +} + +static FuncDecl *createDistributedThunkFunction(FuncDecl *func) { + auto &C = func->getASTContext(); + auto DC = func->getDeclContext(); + + auto systemTy = getConcreteReplacementForProtocolActorSystemType(func); + assert(systemTy && + "Thunk synthesis must have concrete actor system type available"); + + DeclName thunkName = func->getName(); + + // --- Prepare generic parameters + GenericParamList *genericParamList = nullptr; + if (auto genericParams = func->getGenericParams()) { + genericParamList = genericParams->clone(DC); + } + + GenericSignature thunkGenSig = + buildGenericSignature(C, func->getGenericSignature(), + /*addedParameters=*/{}, + /*addedRequirements=*/{}); + + // --- Prepare parameters + auto funcParams = func->getParameters(); + SmallVector paramDecls; + for (unsigned i : indices(*func->getParameters())) { + auto funcParam = funcParams->get(i); + + auto paramName = funcParam->getParameterName(); + // If internal name is empty it could only mean either + // `_:` or `x _: ...`, so let's auto-generate a name + // to be used in the body of a thunk. + if (paramName.empty()) { + paramName = C.getIdentifier("p" + llvm::utostr(i)); + } + + auto paramDecl = new (C) + ParamDecl(SourceLoc(), + /*argumentNameLoc=*/SourceLoc(), funcParam->getArgumentName(), + /*parameterNameLoc=*/SourceLoc(), paramName, DC); + + paramDecl->setImplicit(true); + paramDecl->setSpecifier(funcParam->getSpecifier()); + paramDecl->setInterfaceType(funcParam->getInterfaceType()); + + paramDecls.push_back(paramDecl); + } + ParameterList *params = ParameterList::create(C, paramDecls); // = funcParams->clone(C); + + auto thunk = FuncDecl::createImplicit(C, swift::StaticSpellingKind::None, + thunkName, SourceLoc(), + /*async=*/true, /*throws=*/true, + genericParamList, + params, + func->getResultInterfaceType(), + DC); + thunk->setSynthesized(true); + thunk->getAttrs().add(new (C) NonisolatedAttr(/*implicit=*/true)); + thunk->setGenericSignature(thunkGenSig); + thunk->copyFormalAccessFrom(func, /*sourceIsParentContext=*/false); + thunk->setBodySynthesizer(deriveBodyDistributed_thunk, func); + + return thunk; +} + +/******************************************************************************/ +/*********************** SYNTHESIS ENTRY POINTS *******************************/ /******************************************************************************/ +FuncDecl *GetDistributedThunkRequest::evaluate( + Evaluator &evaluator, AbstractFunctionDecl *distributedTarget) const { + if (!distributedTarget->isDistributed()) + return nullptr; + + auto &C = distributedTarget->getASTContext(); + auto DC = distributedTarget->getDeclContext(); + + if (!getConcreteReplacementForProtocolActorSystemType(distributedTarget)) { + // Don't synthesize thunks, unless there is a *concrete* ActorSystem. + // TODO(distributed): we should be able to lift this eventually, + // and allow resolving distributed actor protocols. + return nullptr; + } + + // Force type-checking the original function, so we can avoid synthesizing + // the thunks (which would have many of the same errors, if they are caused + // by a bad source function signature, e.g. missing conformances etc). + (void) TypeChecker::typeCheckDecl(distributedTarget); + if (distributedTarget->getDiags().hadAnyError()) { + return nullptr; + } + + if (auto func = dyn_cast(distributedTarget)) { + // not via `ensureDistributedModuleLoaded` to avoid generating a warning, + // we won't be emitting the offending decl after all. + if (!C.getLoadedModule(C.Id_Distributed)) + return nullptr; + + auto nominal = DC->getSelfNominalTypeDecl(); // NOTE: Always from DC + assert(nominal); + + // --- Prepare the "distributed thunk" which does the "maybe remote" dance: + return createDistributedThunkFunction(func); + } + + llvm_unreachable("Unable to synthesize distributed thunk"); +} + VarDecl *GetDistributedActorIDPropertyRequest::evaluate( Evaluator &evaluator, NominalTypeDecl *actor) const { if (!actor->isDistributedActor()) @@ -96,29 +607,52 @@ VarDecl *GetDistributedActorIDPropertyRequest::evaluate( if (!C.getLoadedModule(C.Id_Distributed)) return nullptr; - return addImplicitDistributedActorIDProperty(actor); + auto classDecl = dyn_cast(actor); + if (!classDecl) + return nullptr; + + return addImplicitDistributedActorIDProperty(classDecl); } + VarDecl *GetDistributedActorSystemPropertyRequest::evaluate( - Evaluator &evaluator, NominalTypeDecl *actor) const { - if (!actor->isDistributedActor()) - return nullptr; + Evaluator &evaluator, NominalTypeDecl *nominal) const { + auto &C = nominal->getASTContext(); + auto module = nominal->getParentModule(); - auto &C = actor->getASTContext(); + auto DAS = C.getDistributedActorSystemDecl(); + auto f = DAS->lookupDirect(C.Id_makeInvocationEncoder); // not via `ensureDistributedModuleLoaded` to avoid generating a warning, // we won't be emitting the offending decl after all. if (!C.getLoadedModule(C.Id_Distributed)) return nullptr; - auto module = C.getStdlibModule(); - auto DistSystemProtocol = - C.getProtocol(KnownProtocolKind::DistributedActorSystem); + if (!nominal->isDistributedActor()) + return nullptr; + + if (auto proto = dyn_cast(nominal)) { + auto DistributedActorProto = C.getDistributedActorDecl(); + for (auto system : DistributedActorProto->lookupDirect(C.Id_actorSystem)) { + if (auto var = dyn_cast(system)) { + auto conformance = module->conformsToProtocol( + proto->mapTypeIntoContext(var->getInterfaceType()), + DAS); + + if (conformance.isInvalid()) + continue; + + return var; + } + } + + return nullptr; + } - for (auto system : actor->lookupDirect(C.Id_actorSystem)) { + for (auto system : nominal->lookupDirect(C.Id_actorSystem)) { if (auto var = dyn_cast(system)) { - auto conformance = module->conformsToProtocol(var->getInterfaceType(), - DistSystemProtocol); + auto conformance = module->conformsToProtocol( + var->getInterfaceType(), DAS); if (conformance.isInvalid()) continue; diff --git a/lib/Sema/ConstraintSystem.cpp b/lib/Sema/ConstraintSystem.cpp index 35edbd945c27b..30e6315fb3747 100644 --- a/lib/Sema/ConstraintSystem.cpp +++ b/lib/Sema/ConstraintSystem.cpp @@ -6023,7 +6023,7 @@ void ConstraintSystem::maybeProduceFallbackDiagnostic( /// Because opened archetypes are not part of the surface language, these /// constraints render the member inaccessible. static bool doesMemberHaveUnfulfillableConstraintsWithExistentialBase( - Type baseTy, const ValueDecl *member, const DeclContext *useDC) { + Type baseTy, const ValueDecl *member) { const auto sig = member->getInnermostDeclContext()->getGenericSignatureOfContext(); @@ -6060,7 +6060,7 @@ static bool doesMemberHaveUnfulfillableConstraintsWithExistentialBase( return Action::Stop; } } isDependentOnSelfWalker(member->getASTContext().getOpenedArchetypeSignature( - baseTy, useDC->getGenericSignatureOfContext())); + baseTy, GenericSignature())); for (const auto &req : sig.getRequirements()) { switch (req.getKind()) { @@ -6107,7 +6107,7 @@ bool ConstraintSystem::isMemberAvailableOnExistential( // the actual signature of the opened archetype in context, rather it cares // about whether you can "hold" `baseTy.member` properly in the abstract. const auto info = member->findExistentialSelfReferences( - baseTy, DC->getModuleScopeContext(), + baseTy, /*treatNonResultCovariantSelfAsInvariant=*/false); if (info.selfRef > TypePosition::Covariant || info.assocTypeRef > TypePosition::Covariant) { @@ -6121,8 +6121,7 @@ bool ConstraintSystem::isMemberAvailableOnExistential( } if (doesMemberHaveUnfulfillableConstraintsWithExistentialBase(baseTy, - member, - DC)) { + member)) { return false; } diff --git a/lib/Sema/DerivedConformanceDistributedActor.cpp b/lib/Sema/DerivedConformanceDistributedActor.cpp index d98846fafd42c..933d6eadc5e4a 100644 --- a/lib/Sema/DerivedConformanceDistributedActor.cpp +++ b/lib/Sema/DerivedConformanceDistributedActor.cpp @@ -128,15 +128,17 @@ static ValueDecl *deriveDistributedActor_id(DerivedConformance &derived) { static ValueDecl *deriveDistributedActor_actorSystem( DerivedConformance &derived) { - assert(derived.Nominal->isDistributedActor()); auto &C = derived.Context; + auto classDecl = dyn_cast(derived.Nominal); + assert(classDecl && derived.Nominal->isDistributedActor()); + // ``` // nonisolated // let actorSystem: ActorSystem // ``` // (no need for @actorIndependent because it is an immutable let) - auto propertyType = getDistributedActorSystemType(derived.Nominal); + auto propertyType = getDistributedActorSystemType(classDecl); VarDecl *propDecl; PatternBindingDecl *pbDecl; diff --git a/lib/Sema/PreCheckExpr.cpp b/lib/Sema/PreCheckExpr.cpp index 17b06efe2b90a..695e4cddb17e5 100644 --- a/lib/Sema/PreCheckExpr.cpp +++ b/lib/Sema/PreCheckExpr.cpp @@ -667,7 +667,11 @@ Expr *TypeChecker::resolveDeclRefExpr(UnresolvedDeclRefExpr *UDRE, if (UDRE->isImplicit()) { return TypeExpr::createImplicitForDecl( UDRE->getNameLoc(), D, LookupDC, - LookupDC->mapTypeIntoContext(D->getInterfaceType())); + // It might happen that LookupDC is null if this is checking + // synthesized code, in that case, don't map the type into context, + // but return as is -- the synthesis should ensure the type is correct. + LookupDC ? LookupDC->mapTypeIntoContext(D->getInterfaceType()) + : D->getInterfaceType()); } else { return TypeExpr::createForDecl(UDRE->getNameLoc(), D, LookupDC); } diff --git a/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp index 7e01731106281..30872942f259c 100644 --- a/lib/Sema/TypeCheckAttr.cpp +++ b/lib/Sema/TypeCheckAttr.cpp @@ -317,6 +317,8 @@ class AttributeChecker : public AttributeVisitor { void visitUnsafeInheritExecutorAttr(UnsafeInheritExecutorAttr *attr); void checkBackDeployAttrs(ArrayRef Attrs); + + void visitKnownToBeLocalAttr(KnownToBeLocalAttr *attr); }; } // end anonymous namespace @@ -5680,27 +5682,26 @@ void AttributeChecker::visitDistributedActorAttr(DistributedActorAttr *attr) { } // distributed func must be declared inside an distributed actor - if (dc->getSelfClassDecl() && - !dc->getSelfClassDecl()->isDistributedActor()) { - diagnoseAndRemoveAttr( - attr, diag::distributed_actor_func_not_in_distributed_actor); - return; - } else if (auto protoDecl = dc->getSelfProtocolDecl()){ - if (!protoDecl->inheritsFromDistributedActor()) { - auto diag = diagnoseAndRemoveAttr( - attr, diag::distributed_actor_func_not_in_distributed_actor); - diagnoseDistributedFunctionInNonDistributedActorProtocol( - protoDecl, diag); - return; + auto selfTy = dc->getSelfTypeInContext(); + if (!selfTy->isDistributedActor()) { + auto diagnostic = diagnoseAndRemoveAttr( + attr, diag::distributed_actor_func_not_in_distributed_actor); + + if (auto *protoDecl = dc->getSelfProtocolDecl()) { + diagnoseDistributedFunctionInNonDistributedActorProtocol(protoDecl, + diagnostic); } - } else if (dc->getSelfStructDecl() || dc->getSelfEnumDecl()) { - diagnoseAndRemoveAttr( - attr, diag::distributed_actor_func_not_in_distributed_actor); return; } } } +void AttributeChecker::visitKnownToBeLocalAttr(KnownToBeLocalAttr *attr) { + if (!D->isImplicit()) { + diagnoseAndRemoveAttr(attr, diag::distributed_local_cannot_be_used); + } +} + void AttributeChecker::visitNonisolatedAttr(NonisolatedAttr *attr) { // 'nonisolated' can be applied to global and static/class variables // that do not have storage. diff --git a/lib/Sema/TypeCheckConcurrency.cpp b/lib/Sema/TypeCheckConcurrency.cpp index dd9cb3a9557d0..14bcc69072005 100644 --- a/lib/Sema/TypeCheckConcurrency.cpp +++ b/lib/Sema/TypeCheckConcurrency.cpp @@ -1568,15 +1568,24 @@ namespace { /// and we reach up to mark the CallExpr. void markNearestCallAsImplicitly( Optional setAsync, - bool setThrows = false, bool setDistributedThunk = false) { + bool setThrows = false, + bool setDistributedThunk = false) { assert(applyStack.size() > 0 && "not contained within an Apply?"); const auto End = applyStack.rend(); for (auto I = applyStack.rbegin(); I != End; ++I) if (auto call = dyn_cast(*I)) { - if (setAsync) call->setImplicitlyAsync(*setAsync); - if (setThrows) call->setImplicitlyThrows(true); - if (setDistributedThunk) call->setShouldApplyDistributedThunk(true); + if (setAsync) { + call->setImplicitlyAsync(*setAsync); + } + if (setThrows) { + call->setImplicitlyThrows(true); + }else { + call->setImplicitlyThrows(false); + } + if (setDistributedThunk) { + call->setShouldApplyDistributedThunk(true); + } return; } llvm_unreachable("expected a CallExpr in applyStack!"); @@ -1903,6 +1912,39 @@ namespace { return nullptr; } + VarDecl *findReferencedBaseSelf(Expr *expr) { + if (auto selfVar = getReferencedParamOrCapture(expr)) + if (selfVar->isSelfParameter() || selfVar->isSelfParamCapture()) + return selfVar; + + // Look through identity expressions and implicit conversions. + Expr *prior; + do { + prior = expr; + + expr = expr->getSemanticsProvidingExpr(); + + if (auto conversion = dyn_cast(expr)) + expr = conversion->getSubExpr(); + } while (prior != expr); + + if (auto call = dyn_cast(expr)) { + for (auto arg : *call->getArgs()) { + if (auto declRef = dyn_cast(arg.getExpr())) { + if (auto var = dyn_cast(declRef->getDecl())) { + if (var->isSelfParameter()) { + return var; + } + } + } + } + } + + + // Not a self reference. + return nullptr; + } + static FuncDecl *findAnnotatableFunction(DeclContext *dc) { auto fn = dyn_cast(dc); if (!fn) return nullptr; @@ -2149,6 +2191,14 @@ namespace { return None; } + if (auto baseSelf = findReferencedBaseSelf(context)) { + if (baseSelf->getAttrs().hasAttribute()) { + return std::make_pair( + /*setThrows=*/false, + /*isDistributedThunk=*/false); + } + } + // Check that we have a distributed function. auto func = dyn_cast(decl); if (!func || !func->isDistributed()) { @@ -2160,7 +2210,9 @@ namespace { return None; } - return std::make_pair(!func->hasThrows(), true); + return std::make_pair( + /*setThrows=*/!func->hasThrows(), + /*isDistributedThunk=*/true); } /// Attempts to identify and mark a valid cross-actor use of a synchronous @@ -2863,7 +2915,8 @@ namespace { bool performDistributedChecks = isolation.getActorType()->isDistributedActor() && !isolatedActor.isPotentiallyIsolated && - !isa(member); + !isa(member) && + !member->getAttrs().hasAttribute(); if (performDistributedChecks) { if (auto access = checkDistributedAccess(memberLoc, member, context)){ // This is a distributed access, so mark it as throwing or @@ -3050,10 +3103,6 @@ namespace { } } - /// Determine whether the given reference is to a method on - /// a remote distributed actor in the given context. - bool isDistributedThunk(ConcreteDeclRef ref, Expr *context, - bool isInAsyncLetInitializer); }; } @@ -3119,7 +3168,7 @@ void swift::checkFunctionActorIsolation(AbstractFunctionDecl *decl) { if (auto superInit = ctor->getSuperInitCall()) superInit->walk(checker); } - if (auto attr = decl->getAttrs().getAttribute()) { + if (decl->getAttrs().hasAttribute()) { if (auto func = dyn_cast(decl)) { checkDistributedFunction(func, /*diagnose=*/true); } diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp index af6422b95ca57..1b55bc7febfc1 100644 --- a/lib/Sema/TypeCheckDecl.cpp +++ b/lib/Sema/TypeCheckDecl.cpp @@ -681,7 +681,7 @@ ExistentialRequiresAnyRequest::evaluate(Evaluator &evaluator, // For value members, look at their type signatures. if (auto valueMember = dyn_cast(member)) { const auto info = valueMember->findExistentialSelfReferences( - decl->getDeclaredInterfaceType(), decl, + decl->getDeclaredInterfaceType(), /*treatNonResultCovariantSelfAsInvariant=*/false); if (info.selfRef > TypePosition::Covariant || info.assocTypeRef) { return true; diff --git a/lib/Sema/TypeCheckDeclOverride.cpp b/lib/Sema/TypeCheckDeclOverride.cpp index 37eef2895ee26..ce472148e7fa3 100644 --- a/lib/Sema/TypeCheckDeclOverride.cpp +++ b/lib/Sema/TypeCheckDeclOverride.cpp @@ -1573,6 +1573,7 @@ namespace { UNINTERESTING_ATTR(CompileTimeConst) UNINTERESTING_ATTR(BackDeploy) + UNINTERESTING_ATTR(KnownToBeLocal) UNINTERESTING_ATTR(UnsafeInheritExecutor) diff --git a/lib/Sema/TypeCheckDeclPrimary.cpp b/lib/Sema/TypeCheckDeclPrimary.cpp index 5973d09d056ab..d2fbe1060194e 100644 --- a/lib/Sema/TypeCheckDeclPrimary.cpp +++ b/lib/Sema/TypeCheckDeclPrimary.cpp @@ -350,7 +350,7 @@ static void installCodingKeysIfNecessary(NominalTypeDecl *NTD) { (void)evaluateOrDefault(NTD->getASTContext().evaluator, req, {}); } -// TODO: same ugly hack as Codable does... +// TODO(distributed): same ugly hack as Codable does... static void installDistributedActorIfNecessary(NominalTypeDecl *NTD) { auto req = ResolveImplicitMemberRequest{NTD, ImplicitMemberAction::ResolveDistributedActor}; @@ -2499,7 +2499,7 @@ class DeclChecker : public DeclVisitor { } if (CD->isDistributedActor()) { - TypeChecker::checkDistributedActor(CD); + TypeChecker::checkDistributedActor(SF, CD); } // Force lowering of stored properties. @@ -3051,7 +3051,7 @@ class DeclChecker : public DeclVisitor { checkExplicitAvailability(ED); if (nominal->isDistributedActor()) - TypeChecker::checkDistributedActor(dyn_cast(nominal)); + TypeChecker::checkDistributedActor(SF, nominal); } void visitTopLevelCodeDecl(TopLevelCodeDecl *TLCD) { diff --git a/lib/Sema/TypeCheckDistributed.cpp b/lib/Sema/TypeCheckDistributed.cpp index 8c902c1285bdc..8bd39063ebde1 100644 --- a/lib/Sema/TypeCheckDistributed.cpp +++ b/lib/Sema/TypeCheckDistributed.cpp @@ -454,7 +454,7 @@ bool swift::checkDistributedFunction(FuncDecl *func, bool diagnose) { assert(func->isDistributed()); auto &C = func->getASTContext(); - auto declContext = func->getDeclContext(); + auto DC = func->getDeclContext(); auto module = func->getParentModule(); /// If no distributed module is available, then no reason to even try checks. @@ -464,10 +464,10 @@ bool swift::checkDistributedFunction(FuncDecl *func, bool diagnose) { // === All parameters and the result type must conform // SerializationRequirement llvm::SmallPtrSet serializationRequirements; - if (auto extension = dyn_cast(declContext)) { + if (auto extension = dyn_cast(DC)) { serializationRequirements = extractDistributedSerializationRequirements( C, extension->getGenericRequirements()); - } else if (auto actor = dyn_cast(declContext)) { + } else if (auto actor = dyn_cast(DC)) { auto systemProp = actor->getDistributedActorSystemProperty(); serializationRequirements = getDistributedSerializationRequirementProtocols( systemProp->getInterfaceType()->getAnyNominal(), @@ -585,9 +585,14 @@ bool swift::checkDistributedActorProperty(VarDecl *var, bool diagnose) { return false; } -void swift::checkDistributedActorProperties(const ClassDecl *decl) { +void swift::checkDistributedActorProperties(const NominalTypeDecl *decl) { auto &C = decl->getASTContext(); + if (isa(decl)) { + // protocols don't matter for stored property checking + return; + } + for (auto member : decl->getMembers()) { if (auto prop = dyn_cast(member)) { if (prop->isSynthesized()) @@ -645,45 +650,58 @@ void swift::checkDistributedActorConstructor(const ClassDecl *decl, ConstructorD // ==== ------------------------------------------------------------------------ -void TypeChecker::checkDistributedActor(ClassDecl *decl) { - if (!decl) +void TypeChecker::checkDistributedActor(SourceFile *SF, NominalTypeDecl *nominal) { + if (!nominal) return; // ==== Ensure the _Distributed module is available, // without it there's no reason to check the decl in more detail anyway. - if (!swift::ensureDistributedModuleLoaded(decl)) + if (!swift::ensureDistributedModuleLoaded(nominal)) return; // ==== Constructors // --- Get the default initializer // If applicable, this will create the default 'init(transport:)' initializer - (void)decl->getDefaultInitializer(); + (void)nominal->getDefaultInitializer(); - for (auto member : decl->getMembers()) { + for (auto member : nominal->getMembers()) { // --- Check all constructors - if (auto ctor = dyn_cast(member)) - checkDistributedActorConstructor(decl, ctor); + if (auto ctor = dyn_cast(member)) { + if (auto classDecl = dyn_cast(nominal)) { + checkDistributedActorConstructor(classDecl, ctor); + continue; + } + } + + // --- Ensure all thunks + if (auto func = dyn_cast(member)) { + if (!func->isDistributed()) + continue; + + if (auto thunk = func->getDistributedThunk()) { + SF->DelayedFunctions.push_back(thunk); + } + } } // ==== Properties - checkDistributedActorProperties(decl); + checkDistributedActorProperties(nominal); // --- Synthesize the 'id' property here rather than via derived conformance // because the 'DerivedConformanceDistributedActor' won't trigger for 'id' // because it has a default impl via 'Identifiable' (ObjectIdentifier) // which we do not want. - (void)decl->getDistributedActorIDProperty(); + (void)nominal->getDistributedActorIDProperty(); } llvm::SmallPtrSet swift::getDistributedSerializationRequirementProtocols( NominalTypeDecl *nominal, ProtocolDecl *protocol) { - if (!protocol) { + if (!protocol || !nominal) { return {}; } - auto ty = getDistributedSerializationRequirementType(nominal, protocol); - if (ty->hasError()) { + if (!ty || ty->hasError()) { return {}; } diff --git a/lib/Sema/TypeCheckDistributed.h b/lib/Sema/TypeCheckDistributed.h index 97d13241fdbc2..6c0a3c7ec09f0 100644 --- a/lib/Sema/TypeCheckDistributed.h +++ b/lib/Sema/TypeCheckDistributed.h @@ -38,7 +38,7 @@ class NominalTypeDecl; bool ensureDistributedModuleLoaded(Decl *decl); /// Check for illegal property declarations (e.g. re-declaring transport or id) -void checkDistributedActorProperties(const ClassDecl *decl); +void checkDistributedActorProperties(const NominalTypeDecl *decl); /// The local and resolve distributed actor constructors have special rules to check. void checkDistributedActorConstructor(const ClassDecl *decl, ConstructorDecl *ctor); diff --git a/lib/Sema/TypeCheckEffects.cpp b/lib/Sema/TypeCheckEffects.cpp index aec66b7fd57cc..4dee003487800 100644 --- a/lib/Sema/TypeCheckEffects.cpp +++ b/lib/Sema/TypeCheckEffects.cpp @@ -2071,7 +2071,8 @@ class CheckEffectsCoverage : public EffectsHandlingWalker llvm::DenseMap parentMap; static bool isEffectAnchor(Expr *e) { - return isa(e) || isa(e) || isa(e); + return isa(e) || isa(e) || + isa(e); } static bool isAnchorTooEarly(Expr *e) { @@ -2091,24 +2092,13 @@ class CheckEffectsCoverage : public EffectsHandlingWalker if (parent && !isAnchorTooEarly(parent)) { return parent; } - if (isInterpolatedString) { - // TODO: I'm being gentle with the casts to avoid breaking things - // If we see incorrect fix-it locations in string interpolations - // we need to change how this behaves - // Assert builds will crash giving us a bug to fix, non-asserts will - // quietly "just work". assert(parent == nullptr && "Expected to be at top of expression"); - assert(isa(lastParent) && - "Expected top of string interpolation to be CalExpr"); - assert(cast(lastParent)->getArgs()->isUnlabeledUnary() && - "Expected unary arg in string interpolation call"); - if (auto *callExpr = dyn_cast(lastParent)) { - if (auto *unaryArg = callExpr->getArgs()->getUnlabeledUnaryExpr()) + if (ArgumentList *args = lastParent->getArgs()) { + if (Expr *unaryArg = args->getUnlabeledUnaryExpr()) return unaryArg; } } - return lastParent; } diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp index 4ad1cee6ef771..af1a6e13ba2b2 100644 --- a/lib/Sema/TypeCheckProtocol.cpp +++ b/lib/Sema/TypeCheckProtocol.cpp @@ -29,6 +29,7 @@ #include "swift/AST/AccessScope.h" #include "swift/AST/ClangModuleLoader.h" #include "swift/AST/Decl.h" +#include "swift/AST/DistributedDecl.h" #include "swift/AST/Effects.h" #include "swift/AST/ExistentialLayout.h" #include "swift/AST/GenericEnvironment.h" @@ -1043,7 +1044,7 @@ swift::matchWitness(WitnessChecker::RequirementEnvironmentCache &reqEnvCache, // the default witness for 'Collection.Iterator', which is defined // as 'IndexingIterator'. const auto selfRefInfo = req->findExistentialSelfReferences( - proto->getDeclaredInterfaceType(), dc, + proto->getDeclaredInterfaceType(), /*treatNonResultCovariantSelfAsInvariant=*/true); if (!selfRefInfo.assocTypeRef) { covariantSelf = classDecl; @@ -4065,7 +4066,7 @@ void ConformanceChecker::checkNonFinalClassWitness(ValueDecl *requirement, // Check whether this requirement uses Self in a way that might // prevent conformance from succeeding. const auto selfRefInfo = requirement->findExistentialSelfReferences( - Proto->getDeclaredInterfaceType(), DC, + Proto->getDeclaredInterfaceType(), /*treatNonResultCovariantSelfAsInvariant=*/true); if (selfRefInfo.selfRef == TypePosition::Invariant) { @@ -4840,6 +4841,102 @@ ResolveWitnessResult ConformanceChecker::resolveTypeWitnessViaLookup( return ResolveWitnessResult::ExplicitFailed; } +/// FIXME: It feels like this could be part of findExistentialSelfReferences(). +static Optional +hasInvariantSelfRequirement(const ProtocolDecl *proto, + ArrayRef reqSig) { + auto selfTy = proto->getSelfInterfaceType(); + + auto containsInvariantSelf = [&](Type t) -> bool { + struct Walker : public TypeWalker { + Type SelfTy; + bool Found = false; + + Walker(Type selfTy) : SelfTy(selfTy) {} + + Action walkToTypePre(Type ty) override { + // Check for 'Self'. + if (ty->isEqual(SelfTy)) { + Found = true; + return Action::Stop; + } + + // 'Self.A' is OK. + if (ty->is()) + return Action::SkipChildren; + + return Action::Continue; + } + }; + + Walker walker(selfTy); + t.walk(walker); + + return walker.Found; + }; + + for (auto req : reqSig) { + switch (req.getKind()) { + case RequirementKind::SameType: + if (req.getSecondType()->isTypeParameter()) { + if (req.getFirstType()->isEqual(selfTy)) + return req; + } else { + if (containsInvariantSelf(req.getSecondType())) + return req; + } + continue; + case RequirementKind::Superclass: + if (containsInvariantSelf(req.getSecondType())) + return req; + continue; + case RequirementKind::Conformance: + case RequirementKind::Layout: + continue; + } + + llvm_unreachable("Bad requirement kind"); + } + + return None; +} + +static void diagnoseInvariantSelfRequirement( + SourceLoc loc, Type adoptee, const ProtocolDecl *proto, + Requirement req, DiagnosticEngine &diags) { + Type firstType, secondType; + unsigned kind = 0; + + switch (req.getKind()) { + case RequirementKind::SameType: + if (req.getSecondType()->isTypeParameter()) { + // eg, 'Self == Self.A.B' + firstType = req.getSecondType(); + secondType = req.getFirstType(); + } else { + // eg, 'Self.A.B == G' + firstType = req.getFirstType(); + secondType = req.getSecondType(); + } + kind = 0; + break; + case RequirementKind::Superclass: + // eg, 'Self.A.B : G' + firstType = req.getFirstType(); + secondType = req.getSecondType(); + kind = 1; + break; + case RequirementKind::Conformance: + case RequirementKind::Layout: + llvm_unreachable("Invalid requirement kind"); + } + + diags.diagnose(loc, diag::non_final_class_cannot_conform_to_self_same_type, + adoptee, proto->getDeclaredInterfaceType(), + firstType, kind, secondType) + .warnUntilSwiftVersion(6); +} + void ConformanceChecker::ensureRequirementsAreSatisfied() { Conformance->finishSignatureConformances(); auto proto = Conformance->getProtocol(); @@ -4867,15 +4964,8 @@ void ConformanceChecker::ensureRequirementsAreSatisfied() { // instead of the concrete class type itself. if (auto *classDecl = Adoptee->getClassOrBoundGenericClass()) { if (!classDecl->isSemanticallyFinal()) { - for (auto req : reqSig) { - if (req.getKind() == RequirementKind::SameType && - req.getFirstType()->isEqual(proto->getSelfInterfaceType())) { - diags.diagnose(Loc, diag::non_final_class_cannot_conform_to_self_same_type, - Adoptee, proto->getDeclaredInterfaceType(), - req.getSecondType()) - .warnUntilSwiftVersion(6); - break; - } + if (auto req = hasInvariantSelfRequirement(proto, reqSig)) { + diagnoseInvariantSelfRequirement(Loc, Adoptee, proto, *req, diags); } } } @@ -5386,6 +5476,28 @@ void swift::diagnoseConformanceFailure(Type T, return; } + // Special case: a distributed actor conformance often can fail because of + // a missing ActorSystem (or DefaultDistributedActorSystem) typealias. + // In this case, the "normal" errors are an avalanche of errors related to + // missing things in the actor that don't help users diagnose the root problem. + // Instead, we want to suggest adding the typealias. + if (Proto->isSpecificProtocol(KnownProtocolKind::DistributedActor)) { + auto nominal = T->getNominalOrBoundGenericNominal(); + if (!nominal) + return; + + // If it is missing the ActorSystem type, suggest adding it: + auto systemTy = getDistributedActorSystemType(/*actor=*/nominal); + if (!systemTy || systemTy->hasError()) { + diags.diagnose(ComplainLoc, + diag::distributed_actor_conformance_missing_system_type, + nominal->getName()); + diags.diagnose(nominal->getStartLoc(), + diag::note_distributed_actor_system_can_be_defined_using_defaultdistributedactorsystem); + return; + } + } + // Special case: for enums with a raw type, explain that the failing // conformance to RawRepresentable was inferred. if (auto enumDecl = T->getEnumOrBoundGenericEnum()) { diff --git a/lib/Sema/TypeCheckType.h b/lib/Sema/TypeCheckType.h index 90fd27c82f164..01823eea6b6a2 100644 --- a/lib/Sema/TypeCheckType.h +++ b/lib/Sema/TypeCheckType.h @@ -282,12 +282,12 @@ class TypeResolutionOptions { case Context::Inherited: case Context::ExtensionBinding: case Context::GenericRequirement: + case Context::ExistentialConstraint: return true; case Context::None: case Context::TypeAliasDecl: case Context::GenericTypeAliasDecl: case Context::MetatypeBase: - case Context::ExistentialConstraint: case Context::InExpression: case Context::ExplicitCastExpr: case Context::ForEachStmt: diff --git a/lib/Sema/TypeChecker.h b/lib/Sema/TypeChecker.h index 0fb475b381361..1a57ee612dff2 100644 --- a/lib/Sema/TypeChecker.h +++ b/lib/Sema/TypeChecker.h @@ -1051,7 +1051,7 @@ diagnosePotentialOpaqueTypeUnavailability(SourceRange ReferenceRange, const UnavailabilityReason &Reason); /// Type check a 'distributed actor' declaration. -void checkDistributedActor(ClassDecl *decl); +void checkDistributedActor(SourceFile *SF, NominalTypeDecl *decl); void checkConcurrencyAvailability(SourceRange ReferenceRange, const DeclContext *ReferenceDC); diff --git a/lib/Serialization/DeserializeSIL.cpp b/lib/Serialization/DeserializeSIL.cpp index e227d63f60527..5a9f105096954 100644 --- a/lib/Serialization/DeserializeSIL.cpp +++ b/lib/Serialization/DeserializeSIL.cpp @@ -69,7 +69,6 @@ fromStableSILLinkage(unsigned value) { case SIL_LINKAGE_PRIVATE: return SILLinkage::Private; case SIL_LINKAGE_PUBLIC_EXTERNAL: return SILLinkage::PublicExternal; case SIL_LINKAGE_HIDDEN_EXTERNAL: return SILLinkage::HiddenExternal; - case SIL_LINKAGE_SHARED_EXTERNAL: return SILLinkage::SharedExternal; default: return None; } } @@ -623,11 +622,11 @@ SILDeserializer::readSILFunctionChecked(DeclID FID, SILFunction *existingFn, // Don't override the transparency or linkage of a function with // an existing declaration, except if we deserialized a // PublicNonABI function, which has HiddenExternal when - // referenced as a declaration, and SharedExternal when it has + // referenced as a declaration, and Shared when it has // a deserialized body. if (isAvailableExternally(fn->getLinkage())) { - if (linkage == SILLinkage::PublicNonABI) { - fn->setLinkage(SILLinkage::SharedExternal); + if (linkage == SILLinkage::PublicNonABI || linkage == SILLinkage::Shared) { + fn->setLinkage(SILLinkage::Shared); } else if (hasPublicVisibility(linkage)) { // Cross-module-optimization can change the linkage to public. In this // case we need to update the linkage of the function (which is @@ -884,6 +883,10 @@ SILDeserializer::readSILFunctionChecked(DeclID FID, SILFunction *existingFn, if (Callback) Callback->didDeserializeFunctionBody(MF->getAssociatedModule(), fn); + if (!MF->isSIB() && !SILMod.isSerialized()) { + assert((fn->isSerialized() || fn->empty()) && + "deserialized function must have the IsSerialized flag set"); + } return fn; } @@ -3521,8 +3524,8 @@ llvm::Expected unsigned IsDeclaration; unsigned Serialized; ProtocolConformanceID conformance; - WitnessTableLayout::readRecord(scratch, RawLinkage, - IsDeclaration, Serialized, conformance); + WitnessTableLayout::readRecord(scratch, RawLinkage, IsDeclaration, + Serialized, conformance); auto Linkage = fromStableSILLinkage(RawLinkage); if (!Linkage) { @@ -3543,7 +3546,7 @@ llvm::Expected theConformance); if (!existingWt) - existingWt = SILMod.lookUpWitnessTable(theConformance, false); + existingWt = SILMod.lookUpWitnessTable(theConformance); auto wT = existingWt; // If we have an existing witness table, verify that the conformance matches diff --git a/lib/Serialization/ModuleFormat.h b/lib/Serialization/ModuleFormat.h index b92813ce15e76..a8fe71727065e 100644 --- a/lib/Serialization/ModuleFormat.h +++ b/lib/Serialization/ModuleFormat.h @@ -56,7 +56,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0; /// describe what change you made. The content of this comment isn't important; /// it just ensures a conflict if two people change the module format. /// Don't worry about adhering to the 80-column limit for this line. -const uint16_t SWIFTMODULE_VERSION_MINOR = 677; // Opaque archetypes carry a generic signature +const uint16_t SWIFTMODULE_VERSION_MINOR = 678; // remove shared_external linkage /// A standard hash seed used for all string hashes in a serialized module. /// diff --git a/lib/Serialization/SILFormat.h b/lib/Serialization/SILFormat.h index f8e945206f660..c09024e80c982 100644 --- a/lib/Serialization/SILFormat.h +++ b/lib/Serialization/SILFormat.h @@ -44,7 +44,6 @@ enum SILLinkageEncoding : uint8_t { SIL_LINKAGE_PRIVATE, SIL_LINKAGE_PUBLIC_EXTERNAL, SIL_LINKAGE_HIDDEN_EXTERNAL, - SIL_LINKAGE_SHARED_EXTERNAL, }; using SILLinkageField = BCFixed<4>; @@ -266,7 +265,7 @@ namespace sil_block { using SILFunctionLayout = BCRecordLayout, // transparent - BCFixed<2>, // serialized + BCFixed<1>, // serialized BCFixed<2>, // thunks: signature optimized/reabstraction BCFixed<1>, // without_actually_escaping BCFixed<3>, // specialPurpose diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp index 5c202eb730088..fb3eb39486904 100644 --- a/lib/Serialization/Serialization.cpp +++ b/lib/Serialization/Serialization.cpp @@ -4963,6 +4963,7 @@ void Serializer::writeAllDeclsAndTypes() { registerDeclTypeAbbr(); registerDeclTypeAbbr(); registerDeclTypeAbbr(); + registerDeclTypeAbbr(); registerDeclTypeAbbr(); registerDeclTypeAbbr(); registerDeclTypeAbbr(); diff --git a/lib/Serialization/SerializeSIL.cpp b/lib/Serialization/SerializeSIL.cpp index aa590d11c0fcf..6dd3be56ef52a 100644 --- a/lib/Serialization/SerializeSIL.cpp +++ b/lib/Serialization/SerializeSIL.cpp @@ -65,7 +65,6 @@ static unsigned toStableSILLinkage(SILLinkage linkage) { case SILLinkage::Private: return SIL_LINKAGE_PRIVATE; case SILLinkage::PublicExternal: return SIL_LINKAGE_PUBLIC_EXTERNAL; case SILLinkage::HiddenExternal: return SIL_LINKAGE_HIDDEN_EXTERNAL; - case SILLinkage::SharedExternal: return SIL_LINKAGE_SHARED_EXTERNAL; } llvm_unreachable("bad linkage"); } @@ -363,9 +362,8 @@ void SILSerializer::addReferencedSILFunction(const SILFunction *F, return; } - if (F->getLinkage() == SILLinkage::Shared && !DeclOnly) { - assert(F->isSerialized() == IsSerializable || - F->hasForeignBody()); + if (F->getLinkage() == SILLinkage::Shared) { + assert(F->isSerialized() || F->hasForeignBody()); FuncsToEmit[F] = false; functionWorklist.push_back(F); @@ -2601,22 +2599,20 @@ void SILSerializer::writeSILVTable(const SILVTable &vt) { for (auto &entry : vt.getEntries()) { SmallVector ListOfValues; - // Do not emit entries which are not public or serialized, unless everything - // has to be serialized. - if (!ShouldSerializeAll && entry.getImplementation() && - !entry.getImplementation()->isPossiblyUsedExternally() && - !entry.getImplementation()->isSerialized()) - continue; - handleSILDeclRef(S, entry.getMethod(), ListOfValues); - addReferencedSILFunction(entry.getImplementation(), true); - // Each entry is a pair of SILDeclRef and SILFunction. - VTableEntryLayout::emitRecord( - Out, ScratchRecord, SILAbbrCodes[VTableEntryLayout::Code], - // SILFunction name - S.addUniquedStringRef(entry.getImplementation()->getName()), - toStableVTableEntryKind(entry.getKind()), - entry.isNonOverridden(), - ListOfValues); + SILFunction *impl = entry.getImplementation(); + + if (ShouldSerializeAll || impl->hasValidLinkageForFragileRef()) { + handleSILDeclRef(S, entry.getMethod(), ListOfValues); + addReferencedSILFunction(impl, true); + // Each entry is a pair of SILDeclRef and SILFunction. + VTableEntryLayout::emitRecord( + Out, ScratchRecord, SILAbbrCodes[VTableEntryLayout::Code], + // SILFunction name + S.addUniquedStringRef(impl->getName()), + toStableVTableEntryKind(entry.getKind()), + entry.isNonOverridden(), + ListOfValues); + } } } @@ -2807,12 +2803,8 @@ bool SILSerializer::shouldEmitFunctionBody(const SILFunction *F, if (F->isExternalDeclaration()) return false; - // Never serialize any function definitions available externally, unless - // it is a referenced shared function (see the explanation in - // SILSerializer::writeSILFunction). - // TODO: Special handling for resilient mode. - if (F->isAvailableExternally() && - !(isReference && hasSharedVisibility(F->getLinkage()))) + // Never serialize any function definitions available externally. + if (F->isAvailableExternally()) return false; // If we are asked to serialize everything, go ahead and do it. @@ -2820,7 +2812,9 @@ bool SILSerializer::shouldEmitFunctionBody(const SILFunction *F, return true; // If F is serialized, we should always emit its body. - if (F->isSerialized() == IsSerialized) + // Shared functions are only serialized if they are referenced from another + // serialized function. This is handled in `addReferencedSILFunction`. + if (F->isSerialized() && !hasSharedVisibility(F->getLinkage())) return true; return false; diff --git a/lib/Serialization/SerializedSILLoader.cpp b/lib/Serialization/SerializedSILLoader.cpp index e46a4b0583f12..410a38f55de13 100644 --- a/lib/Serialization/SerializedSILLoader.cpp +++ b/lib/Serialization/SerializedSILLoader.cpp @@ -48,7 +48,8 @@ SILFunction *SerializedSILLoader::lookupSILFunction(SILFunction *Callee, // another has the full definition. SILFunction *retVal = nullptr; for (auto &Des : LoadedSILSections) { - if (auto Func = Des->lookupSILFunction(Callee, onlyUpdateLinkage)) { + if (auto Func = Des->lookupSILFunction(Callee, + /*declarationOnly*/ onlyUpdateLinkage)) { LLVM_DEBUG(llvm::dbgs() << "Deserialized " << Func->getName() << " from " << Des->getModuleIdentifier().str() << "\n"); if (!Func->empty()) @@ -60,13 +61,9 @@ SILFunction *SerializedSILLoader::lookupSILFunction(SILFunction *Callee, } SILFunction *SerializedSILLoader::lookupSILFunction(StringRef Name, - bool declarationOnly, Optional Linkage) { - // It is possible that one module has a declaration of a SILFunction, while - // another has the full definition. - SILFunction *retVal = nullptr; for (auto &Des : LoadedSILSections) { - if (auto Func = Des->lookupSILFunction(Name, declarationOnly)) { + if (auto *Func = Des->lookupSILFunction(Name, /*declarationOnly*/ true)) { LLVM_DEBUG(llvm::dbgs() << "Deserialized " << Func->getName() << " from " << Des->getModuleIdentifier().str() << "\n"); if (Linkage) { @@ -81,12 +78,10 @@ SILFunction *SerializedSILLoader::lookupSILFunction(StringRef Name, continue; } } - if (!Func->empty() || declarationOnly) - return Func; - retVal = Func; + return Func; } } - return retVal; + return nullptr; } bool SerializedSILLoader::hasSILFunction(StringRef Name, diff --git a/lib/TBDGen/TBDGen.cpp b/lib/TBDGen/TBDGen.cpp index e876c487ea660..6ed3a8f29316b 100644 --- a/lib/TBDGen/TBDGen.cpp +++ b/lib/TBDGen/TBDGen.cpp @@ -718,9 +718,10 @@ void TBDGenVisitor::visitAbstractFunctionDecl(AbstractFunctionDecl *AFD) { addSymbol(SILDeclRef(AFD).asForeign()); } - if (AFD->isDistributed()) { - addSymbol(SILDeclRef(AFD).asDistributed()); - addAsyncFunctionPointerSymbol(SILDeclRef(AFD).asDistributed()); + if (auto distributedThunk = AFD->getDistributedThunk()) { + auto thunk = SILDeclRef(distributedThunk).asDistributed(); + addSymbol(thunk); + addAsyncFunctionPointerSymbol(thunk); } // Add derivative function symbols. diff --git a/stdlib/cmake/modules/AddSwiftStdlib.cmake b/stdlib/cmake/modules/AddSwiftStdlib.cmake index 45ecf1719eed5..c87d89ccbee27 100644 --- a/stdlib/cmake/modules/AddSwiftStdlib.cmake +++ b/stdlib/cmake/modules/AddSwiftStdlib.cmake @@ -377,11 +377,15 @@ function(_add_target_variant_c_compile_flags) if(SWIFT_STDLIB_SUPPORTS_BACKTRACE_REPORTING) list(APPEND result "-DSWIFT_STDLIB_SUPPORTS_BACKTRACE_REPORTING") endif() - + if(SWIFT_STDLIB_ENABLE_UNICODE_DATA) list(APPEND result "-D" "SWIFT_STDLIB_ENABLE_UNICODE_DATA") endif() + if(SWIFT_STDLIB_CONCURRENCY_TRACING) + list(APPEND result "-DSWIFT_STDLIB_CONCURRENCY_TRACING") + endif() + list(APPEND result ${SWIFT_STDLIB_EXTRA_C_COMPILE_FLAGS}) set("${CFLAGS_RESULT_VAR_NAME}" "${result}" PARENT_SCOPE) diff --git a/stdlib/cmake/modules/StdlibOptions.cmake b/stdlib/cmake/modules/StdlibOptions.cmake index a4354b0c7dd67..f83c150f98d49 100644 --- a/stdlib/cmake/modules/StdlibOptions.cmake +++ b/stdlib/cmake/modules/StdlibOptions.cmake @@ -183,3 +183,14 @@ option(SWIFT_FREESTANDING_FLAVOR set(SWIFT_STDLIB_ENABLE_LTO OFF CACHE STRING "Build Swift stdlib with LTO. One must specify the form of LTO by setting this to one of: 'full', 'thin'. This option only affects the standard library and runtime, not tools.") + +if("${SWIFT_HOST_VARIANT_SDK}" IN_LIST SWIFT_DARWIN_PLATFORMS) + set(SWIFT_STDLIB_CONCURRENCY_TRACING_default TRUE) +else() + set(SWIFT_STDLIB_CONCURRENCY_TRACING_default FALSE) +endif() + +option(SWIFT_STDLIB_CONCURRENCY_TRACING + "Enable concurrency tracing in the runtime; assumes the presence of os_log(3) + and the os_signpost(3) API." + "${SWIFT_STDLIB_CONCURRENCY_TRACING_default}") diff --git a/stdlib/public/Concurrency/Actor.swift b/stdlib/public/Concurrency/Actor.swift index 788b5ad908e88..c8abc4ef078eb 100644 --- a/stdlib/public/Concurrency/Actor.swift +++ b/stdlib/public/Concurrency/Actor.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2020 Apple Inc. and the Swift project authors +// Copyright (c) 2020-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 @@ -13,12 +13,29 @@ import Swift @_implementationOnly import _SwiftConcurrencyShims +/// Common marker protocol providing a shared "base" for both (local) `Actor` +/// and (potentially remote) `DistributedActor` types. +/// +/// The `AnyActor` marker protocol generalizes over all actor types, including +/// distributed ones. In practice, this protocol can be used to restrict +/// protocols, or generic parameters to only be usable with actors, which +/// provides the guarantee that calls may be safely made on instances of given +/// type without worrying about the thread-safety of it -- as they are +/// guaranteed to follow the actor-style isolation semantics. +/// +/// While both local and distributed actors are conceptually "actors", there are +/// some important isolation model differences between the two, which make it +/// impossible for one to refine the other. +@_marker +@available(SwiftStdlib 5.1, *) +public protocol AnyActor: AnyObject, Sendable {} + /// Common protocol to which all actors conform. /// -/// The `Actor` protocol generalizes over all actor types. Actor types +/// The `Actor` protocol generalizes over all `actor` types. Actor types /// implicitly conform to this protocol. @available(SwiftStdlib 5.1, *) -public protocol Actor: AnyObject, Sendable { +public protocol Actor: AnyActor, Sendable { /// Retrieve the executor for this actor as an optimized, unowned /// reference. diff --git a/stdlib/public/Concurrency/AsyncStream.swift b/stdlib/public/Concurrency/AsyncStream.swift index 7571e6b8aba64..18187a7682ba7 100644 --- a/stdlib/public/Concurrency/AsyncStream.swift +++ b/stdlib/public/Concurrency/AsyncStream.swift @@ -428,3 +428,6 @@ extension AsyncStream.Continuation { return storage.yield(()) } } + +@available(SwiftStdlib 5.1, *) +extension AsyncStream: @unchecked Sendable where Element: Sendable { } diff --git a/stdlib/public/Concurrency/AsyncStreamBuffer.swift b/stdlib/public/Concurrency/AsyncStreamBuffer.swift index 41aed33a72637..7aaae004ce622 100644 --- a/stdlib/public/Concurrency/AsyncStreamBuffer.swift +++ b/stdlib/public/Concurrency/AsyncStreamBuffer.swift @@ -17,7 +17,7 @@ import Swift import Darwin func _lockWordCount() -> Int { - let sz = + let sz = MemoryLayout.size / MemoryLayout.size return max(sz, 1) } @@ -57,7 +57,7 @@ extension AsyncStream { typealias TerminationHandler = @Sendable (Continuation.Termination) -> Void struct State { - var continuation: UnsafeContinuation? + var continuations = [UnsafeContinuation]() var pending = _Deque() let limit: Continuation.BufferingPolicy var onTermination: TerminationHandler? @@ -105,7 +105,7 @@ extension AsyncStream { } } - func cancel() { + @Sendable func cancel() { lock() // swap out the handler before we invoke it to prevent double cancel let handler = state.onTermination @@ -123,7 +123,9 @@ extension AsyncStream { lock() let limit = state.limit let count = state.pending.count - if let continuation = state.continuation { + + if !state.continuations.isEmpty { + let continuation = state.continuations.removeFirst() if count > 0 { if !state.terminal { switch limit { @@ -151,17 +153,14 @@ extension AsyncStream { } else { result = .terminated } - state.continuation = nil let toSend = state.pending.removeFirst() unlock() continuation.resume(returning: toSend) } else if state.terminal { - state.continuation = nil result = .terminated unlock() continuation.resume(returning: nil) } else { - state.continuation = nil switch limit { case .unbounded: result = .enqueued(remaining: .max) @@ -212,15 +211,15 @@ extension AsyncStream { state.onTermination = nil state.terminal = true - if let continuation = state.continuation { + if let continuation = state.continuations.first { if state.pending.count > 0 { - state.continuation = nil + state.continuations.removeFirst() let toSend = state.pending.removeFirst() unlock() handler?(.finished) continuation.resume(returning: toSend) } else if state.terminal { - state.continuation = nil + state.continuations.removeFirst() unlock() handler?(.finished) continuation.resume(returning: nil) @@ -236,22 +235,20 @@ extension AsyncStream { func next(_ continuation: UnsafeContinuation) { lock() - if state.continuation == nil { - if state.pending.count > 0 { - let toSend = state.pending.removeFirst() - unlock() - continuation.resume(returning: toSend) - } else if state.terminal { - unlock() - continuation.resume(returning: nil) - } else { - state.continuation = continuation - unlock() - } + state.continuations.append(continuation) + if state.pending.count > 0 { + let cont = state.continuations.removeFirst() + let toSend = state.pending.removeFirst() + unlock() + cont.resume(returning: toSend) + } else if state.terminal { + let cont = state.continuations.removeFirst() + unlock() + cont.resume(returning: nil) } else { unlock() - fatalError("attempt to await next() on more than one task") } + } func next() async -> Element? { @@ -341,7 +338,7 @@ extension AsyncThrowingStream { } } - func cancel() { + @Sendable func cancel() { lock() // swap out the handler before we invoke it to prevent double cancel let handler = state.onTermination @@ -595,3 +592,4 @@ final class _AsyncStreamCriticalStorage: @unchecked Sendable { return storage } } + diff --git a/stdlib/public/Concurrency/AsyncThrowingStream.swift b/stdlib/public/Concurrency/AsyncThrowingStream.swift index a1bc39ce1c220..6371f7fa22938 100644 --- a/stdlib/public/Concurrency/AsyncThrowingStream.swift +++ b/stdlib/public/Concurrency/AsyncThrowingStream.swift @@ -471,3 +471,6 @@ extension AsyncThrowingStream.Continuation { storage.yield(()) } } + +@available(SwiftStdlib 5.1, *) +extension AsyncThrowingStream: @unchecked Sendable where Element: Sendable { } diff --git a/stdlib/public/Concurrency/Tracing.h b/stdlib/public/Concurrency/Tracing.h index 7f76596751a65..4bc9cf03972cc 100644 --- a/stdlib/public/Concurrency/Tracing.h +++ b/stdlib/public/Concurrency/Tracing.h @@ -96,7 +96,7 @@ void job_run_end(ExecutorRef *executor, job_run_info info); } // namespace concurrency } // namespace swift -#if __has_include() +#if SWIFT_STDLIB_CONCURRENCY_TRACING #include "TracingSignpost.h" #else #include "TracingStubs.h" diff --git a/stdlib/public/Concurrency/TracingSignpost.cpp b/stdlib/public/Concurrency/TracingSignpost.cpp index b761c7142cb74..3efaf4d0f7b80 100644 --- a/stdlib/public/Concurrency/TracingSignpost.cpp +++ b/stdlib/public/Concurrency/TracingSignpost.cpp @@ -14,7 +14,7 @@ // //===----------------------------------------------------------------------===// -#if __has_include() +#if SWIFT_STDLIB_CONCURRENCY_TRACING #include "TracingSignpost.h" #include diff --git a/stdlib/public/Concurrency/TracingSignpost.h b/stdlib/public/Concurrency/TracingSignpost.h index 56fafc9074323..1301bdfd34bdb 100644 --- a/stdlib/public/Concurrency/TracingSignpost.h +++ b/stdlib/public/Concurrency/TracingSignpost.h @@ -52,6 +52,7 @@ #define SWIFT_LOG_ACTOR_STATE_CHANGED_NAME "actor_state_changed" #define SWIFT_LOG_ACTOR_JOB_QUEUE_NAME "actor_job_queue" #define SWIFT_LOG_TASK_LIFETIME_NAME "task_lifetime" +#define SWIFT_LOG_TASK_FLAGS_CHANGED_NAME "task_flags_changed" #define SWIFT_LOG_TASK_STATUS_CHANGED_NAME "task_status_changed" #define SWIFT_LOG_TASK_WAIT_NAME "task_wait" #define SWIFT_LOG_JOB_ENQUEUE_GLOBAL_NAME "job_enqueue_global" @@ -201,7 +202,7 @@ inline void task_status_changed(AsyncTask *task, uintptr_t flags) { inline void task_flags_changed(AsyncTask *task, uint32_t flags) { ENSURE_LOGS(); auto id = os_signpost_id_make_with_pointer(TaskLog, task); - os_signpost_event_emit(TaskLog, id, SWIFT_LOG_TASK_STATUS_CHANGED_NAME, + os_signpost_event_emit(TaskLog, id, SWIFT_LOG_TASK_FLAGS_CHANGED_NAME, "task=%" PRIx64 " flags=0x%" PRIx32, task->getTaskId(), flags); } diff --git a/stdlib/public/Distributed/DistributedActor.swift b/stdlib/public/Distributed/DistributedActor.swift index cc8f2223cdcc1..fe975a4a0f38a 100644 --- a/stdlib/public/Distributed/DistributedActor.swift +++ b/stdlib/public/Distributed/DistributedActor.swift @@ -13,17 +13,6 @@ import Swift import _Concurrency -// ==== Any Actor ------------------------------------------------------------- - -/// Shared "base" protocol for both (local) `Actor` and (potentially remote) -/// `DistributedActor`. -/// -/// FIXME(distributed): We'd need Actor to also conform to this, but don't want to add that conformance in _Concurrency yet. -@_marker -@available(SwiftStdlib 5.7, *) -public protocol AnyActor: Sendable, AnyObject { -} - // ==== Distributed Actor ----------------------------------------------------- /// Common protocol to which all distributed actors conform implicitly. @@ -151,9 +140,9 @@ extension DistributedActor { // ==== isRemote / isLocal ----------------------------------------------------- @_silgen_name("swift_distributed_actor_is_remote") -func __isRemoteActor(_ actor: AnyObject) -> Bool +public func __isRemoteActor(_ actor: AnyObject) -> Bool -func __isLocalActor(_ actor: AnyObject) -> Bool { +public func __isLocalActor(_ actor: AnyObject) -> Bool { return !__isRemoteActor(actor) } diff --git a/stdlib/public/Distributed/DistributedActorSystem.swift b/stdlib/public/Distributed/DistributedActorSystem.swift index bf028df3417a3..194f88ded5ccc 100644 --- a/stdlib/public/Distributed/DistributedActorSystem.swift +++ b/stdlib/public/Distributed/DistributedActorSystem.swift @@ -15,7 +15,7 @@ import _Concurrency @available(SwiftStdlib 5.7, *) public protocol DistributedActorSystem: Sendable { /// The identity used by actors that communicate via this transport - associatedtype ActorID: Sendable & Hashable & Codable // TODO: make Codable conditional here + associatedtype ActorID: Sendable & Hashable & Codable // TODO(distributed): make Codable conditional here associatedtype InvocationEncoder: DistributedTargetInvocationEncoder associatedtype InvocationDecoder: DistributedTargetInvocationDecoder @@ -106,7 +106,6 @@ public protocol DistributedActorSystem: Sendable { /// The returned `DistributedTargetInvocation` will be populated with all /// arguments, generic substitutions, and specific error and return types /// that are associated with this specific invocation. - @inlinable func makeInvocationEncoder() -> InvocationEncoder // /// Invoked by the Swift runtime when making a remote call. @@ -344,7 +343,7 @@ func _executeDistributedTarget( // MARK: Support types /// A distributed 'target' can be a `distributed func` or `distributed` computed property. @available(SwiftStdlib 5.7, *) -public struct RemoteCallTarget { +public struct RemoteCallTarget { // TODO: ship this around always; make printing nice let _mangledName: String // TODO: StaticString would be better here; no arc, codesize of cleanups // Only intended to be created by the _Distributed library. @@ -358,7 +357,7 @@ public struct RemoteCallTarget { } // .Base.hello(hi:) - public var fullName: String { + public var fullName: String { // TODO: make description fatalError("NOT IMPLEMENTED YET: \(#function)") } } @@ -412,7 +411,7 @@ public protocol DistributedTargetInvocationEncoder { // /// // /// Record the error type of the distributed method. // /// This method will not be invoked if the target is not throwing. -// mutating func recordErrorType(_ type: E.Type) throws +// mutating func recordErrorType(_ type: E.Type) throws // TODO: make not adhoc // /// Ad-hoc requirement // /// diff --git a/stdlib/public/Reflection/TypeLowering.cpp b/stdlib/public/Reflection/TypeLowering.cpp index 03dab8a117456..b311bacb94dd6 100644 --- a/stdlib/public/Reflection/TypeLowering.cpp +++ b/stdlib/public/Reflection/TypeLowering.cpp @@ -1698,6 +1698,11 @@ class HasFixedSize return true; } + bool + visitParameterizedProtocolTypeRef(const ParameterizedProtocolTypeRef *PPT) { + return true; + } + bool visitSILBoxTypeRef(const SILBoxTypeRef *SB) { return true; @@ -1814,6 +1819,11 @@ class HasSingletonMetatype return MetatypeRepresentation::Thin; } + MetatypeRepresentation + visitParameterizedProtocolTypeRef(const ParameterizedProtocolTypeRef *PPT) { + return MetatypeRepresentation::Thin; + } + MetatypeRepresentation visitMetatypeTypeRef(const MetatypeTypeRef *M) { if (M->wasAbstract()) return MetatypeRepresentation::Thick; @@ -2260,6 +2270,11 @@ class LowerType return builder.build(ExternalTypeInfo); } + const TypeInfo * + visitParameterizedProtocolTypeRef(const ParameterizedProtocolTypeRef *PPT) { + return visitProtocolCompositionTypeRef(PPT->getBase()); + } + const TypeInfo *visitMetatypeTypeRef(const MetatypeTypeRef *M) { switch (HasSingletonMetatype().visit(M)) { case MetatypeRepresentation::Unknown: diff --git a/stdlib/public/Reflection/TypeRef.cpp b/stdlib/public/Reflection/TypeRef.cpp index 519ec464613cb..f1eef063ee2c5 100644 --- a/stdlib/public/Reflection/TypeRef.cpp +++ b/stdlib/public/Reflection/TypeRef.cpp @@ -237,6 +237,15 @@ class PrintTypeRef : public TypeRefVisitor { stream << ")"; } + void + visitParameterizedProtocolTypeRef(const ParameterizedProtocolTypeRef *PPT) { + printHeader("parameterized_protocol"); + printRec(PPT->getBase()); + for (auto param : PPT->getArgs()) + printRec(param); + stream << ")"; + } + void visitMetatypeTypeRef(const MetatypeTypeRef *M) { printHeader("metatype"); if (M->wasAbstract()) @@ -421,6 +430,11 @@ struct TypeRefIsConcrete return true; } + bool + visitParameterizedProtocolTypeRef(const ParameterizedProtocolTypeRef *PPT) { + return visit(PPT->getBase()); + } + bool visitMetatypeTypeRef(const MetatypeTypeRef *M) { return visit(M->getInstanceType()); } @@ -762,6 +776,17 @@ class DemanglingForTypeRef return node; } + Demangle::NodePointer + visitParameterizedProtocolTypeRef(const ParameterizedProtocolTypeRef *PPT) { + auto node = Dem.createNode(Node::Kind::ParameterizedProtocol); + node->addChild(visit(PPT->getBase()), Dem); + auto genericArgsList = Dem.createNode(Node::Kind::TypeList); + for (auto param : PPT->getArgs()) + genericArgsList->addChild(visit(param), Dem); + node->addChild(genericArgsList, Dem); + return node; + } + Demangle::NodePointer visitMetatypeTypeRef(const MetatypeTypeRef *M) { auto node = Dem.createNode(Node::Kind::Metatype); // FIXME: This is lossy. @objc_metatype is also abstract. @@ -1072,6 +1097,15 @@ class ThickenMetatype return PC; } + const TypeRef * + visitParameterizedProtocolTypeRef(const ParameterizedProtocolTypeRef *PPT) { + std::vector ThickArgs; + for (auto Param : PPT->getArgs()) + ThickArgs.push_back(visit(Param)); + return ParameterizedProtocolTypeRef::create(Builder, PPT->getBase(), + ThickArgs); + } + const TypeRef *visitMetatypeTypeRef(const MetatypeTypeRef *M) { return MetatypeTypeRef::create(Builder, visit(M->getInstanceType()), /*WasAbstract=*/true); @@ -1219,6 +1253,15 @@ class TypeRefSubstitution return EM; } + const TypeRef * + visitParameterizedProtocolTypeRef(const ParameterizedProtocolTypeRef *PPT) { + std::vector substArg; + for (auto Param : PPT->getArgs()) + substArg.push_back(visit(Param)); + return ParameterizedProtocolTypeRef::create(Builder, PPT->getBase(), + substArg); + } + const TypeRef * visitGenericTypeParameterTypeRef(const GenericTypeParameterTypeRef *GTP) { auto found = Substitutions.find({GTP->getDepth(), GTP->getIndex()}); diff --git a/stdlib/public/core/CocoaArray.swift b/stdlib/public/core/CocoaArray.swift index 12a6707106b4a..04d08fd658fd6 100644 --- a/stdlib/public/core/CocoaArray.swift +++ b/stdlib/public/core/CocoaArray.swift @@ -131,20 +131,22 @@ internal struct _CocoaArrayWrapper: RandomAccessCollection { subRange bounds: Range, initializing target: UnsafeMutablePointer ) -> UnsafeMutablePointer { - let nsSubRange = SwiftShims._SwiftNSRange( - location: bounds.lowerBound, - length: bounds.upperBound - bounds.lowerBound) - - // Copies the references out of the NSArray without retaining them - core.getObjects(target, range: nsSubRange) - - // Make another pass to retain the copied objects - var result = target - for _ in bounds { - result.initialize(to: result.pointee) - result += 1 + return withExtendedLifetime(buffer) { + let nsSubRange = SwiftShims._SwiftNSRange( + location: bounds.lowerBound, + length: bounds.upperBound - bounds.lowerBound) + + // Copies the references out of the NSArray without retaining them + core.getObjects(target, range: nsSubRange) + + // Make another pass to retain the copied objects + var result = target + for _ in bounds { + result.initialize(to: result.pointee) + result += 1 + } + return result } - return result } @_alwaysEmitIntoClient diff --git a/stdlib/public/runtime/MetadataLookup.cpp b/stdlib/public/runtime/MetadataLookup.cpp index a4bf6d8ec9fb1..21c7773171860 100644 --- a/stdlib/public/runtime/MetadataLookup.cpp +++ b/stdlib/public/runtime/MetadataLookup.cpp @@ -1507,6 +1507,13 @@ class DecodedMetadataBuilder { protocols.size(), protocols.data()); } + TypeLookupErrorOr + createParameterizedProtocolType(BuiltType base, + llvm::ArrayRef args) const { + // FIXME: Runtime plumbing. + return BuiltType(); + } + TypeLookupErrorOr createDynamicSelfType(BuiltType selfType) const { // Free-standing mangled type strings should not contain DynamicSelfType. return BuiltType(); diff --git a/test/APIJSON/apigen.swift b/test/APIJSON/apigen.swift index 68ceefa5f993c..98e52a96609d4 100644 --- a/test/APIJSON/apigen.swift +++ b/test/APIJSON/apigen.swift @@ -1,6 +1,6 @@ // REQUIRES: objc_interop, OS=macosx // RUN: %empty-directory(%t) -// RUN: %target-swift-frontend %s -typecheck -emit-module-interface-path %t/MyModule.swiftinterface -enable-library-evolution -module-name MyModule -swift-version 5 +// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) %s -typecheck -emit-module-interface-path %t/MyModule.swiftinterface -enable-library-evolution -module-name MyModule -swift-version 5 // RUN: %target-swift-api-extract -o - -pretty-print %t/MyModule.swiftinterface -module-name MyModule -module-cache-path %t | %FileCheck %s import Foundation diff --git a/test/APIJSON/non-objc-class.swift b/test/APIJSON/non-objc-class.swift index 3ba94c0193e8c..f0accd014b3d7 100644 --- a/test/APIJSON/non-objc-class.swift +++ b/test/APIJSON/non-objc-class.swift @@ -1,6 +1,6 @@ // REQUIRES: objc_interop, OS=macosx // RUN: %empty-directory(%t) -// RUN: %target-swift-frontend %s -typecheck -emit-module-interface-path %t/MyModule.swiftinterface -enable-library-evolution -module-name MyModule -swift-version 5 +// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) %s -typecheck -emit-module-interface-path %t/MyModule.swiftinterface -enable-library-evolution -module-name MyModule -swift-version 5 // RUN: %target-swift-api-extract -o - -pretty-print %t/MyModule.swiftinterface -module-name MyModule -module-cache-path %t | %FileCheck %s import Foundation diff --git a/test/APIJSON/spi.swift b/test/APIJSON/spi.swift index 302757399da3b..294f26242b7f0 100644 --- a/test/APIJSON/spi.swift +++ b/test/APIJSON/spi.swift @@ -1,9 +1,9 @@ // REQUIRES: objc_interop, OS=macosx // RUN: %empty-directory(%t) -// RUN: %target-swift-frontend %s -typecheck -emit-module-interface-path %t/MyModule.swiftinterface -enable-library-evolution -module-name MyModule -swift-version 5 +// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) %s -typecheck -emit-module-interface-path %t/MyModule.swiftinterface -enable-library-evolution -module-name MyModule -swift-version 5 // RUN: %target-swift-api-extract -o - -pretty-print %t/MyModule.swiftinterface -module-name MyModule -module-cache-path %t | %FileCheck %s -// RUN: %target-swift-frontend %s -emit-module -emit-module-path %t/MyModule.swiftmodule -enable-library-evolution -module-name MyModule -swift-version 5 +// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) %s -emit-module -emit-module-path %t/MyModule.swiftmodule -enable-library-evolution -module-name MyModule -swift-version 5 // RUN: %target-swift-api-extract -o - -pretty-print %t/MyModule.swiftmodule -module-name MyModule -module-cache-path %t | %FileCheck %s --check-prefix=CHECK-SPI import Foundation diff --git a/test/AutoDiff/SILOptimizer/differentiability_witness_inlining.sil b/test/AutoDiff/SILOptimizer/differentiability_witness_inlining.sil index fd0f24fe138c9..42051ae462985 100644 --- a/test/AutoDiff/SILOptimizer/differentiability_witness_inlining.sil +++ b/test/AutoDiff/SILOptimizer/differentiability_witness_inlining.sil @@ -26,7 +26,7 @@ sil @witness_defined_in_module_vjp : $@convention(thin) (Float) -> (Float, @owne sil @witness_definition_not_available : $@convention(thin) (Float) -> Float -sil public_external [transparent] [serialized] @$sSf1poiyS2f_SftFZ : $@convention(method) (Float, Float, @thin Float.Type) -> Float +sil public_external [transparent] @$sSf1poiyS2f_SftFZ : $@convention(method) (Float, Float, @thin Float.Type) -> Float sil @test : $@convention(thin) (Float) -> () { bb0(%0 : $Float): diff --git a/test/AutoDiff/compiler_crashers_fixed/sr15849-mutating-functions-with-control-flow.swift b/test/AutoDiff/compiler_crashers_fixed/sr15849-mutating-functions-with-control-flow.swift new file mode 100644 index 0000000000000..b852bc915def1 --- /dev/null +++ b/test/AutoDiff/compiler_crashers_fixed/sr15849-mutating-functions-with-control-flow.swift @@ -0,0 +1,213 @@ +// RUN: %empty-directory(%t) +// RUN: %target-build-swift -O -g -debug-info-format=dwarf -emit-module -module-name sr15849 -emit-module-path %t/sr15849.swiftmodule -swift-version 5 -c %S/sr15849-mutating-functions-with-control-flow.swift + +// SR-15849: Mutating functions with control flow can cause assertion failure +// for conflicting debug variable type. + +import _Differentiation + +// Declare `Tensor` + +class TensorHandle {} // Crash requires `class` and not `struct` + +struct Tensor { + let handle: TensorHandle +} + +extension Tensor: Differentiable { + typealias TangentVector = Tensor +} + +extension Tensor: AdditiveArithmetic { + static func == (lhs: Tensor, rhs: Tensor) -> Bool { fatalError() } + static func != (lhs: Tensor, rhs: Tensor) -> Bool { fatalError() } + + static var zero: Tensor { fatalError() } + + @differentiable(reverse) + static func + (lhs: Tensor, rhs: Tensor) -> Tensor { fatalError() } + static func - (lhs: Tensor, rhs: Tensor) -> Tensor { fatalError() } +} + +// Make `+=` differentiable + +extension Tensor { + @derivative(of: +) + static func _vjpAdd(lhs: Tensor, rhs: Tensor) -> ( + value: Tensor, pullback: (Tensor) -> (Tensor, Tensor) + ) { + fatalError() + } + + static func += (lhs: inout Tensor, rhs: Tensor) { + lhs = lhs + rhs + } +} + +// Declare `BatchNorm` + +protocol Layer: Differentiable { + associatedtype Input + associatedtype Output: Differentiable + + @differentiable(reverse) + func callAsFunction(_ input: Input) -> Output +} + +struct BatchNorm: Layer { // Crash requires conformance to `Layer` + @noDerivative let momentum: Scalar // Crash requires `@noDerivative` + var offset: Tensor + + @differentiable(reverse) + func callAsFunction(_ input: Tensor) -> Tensor { + var offset = self.offset + if true { // Crash requires `if true` + offset += offset // Using `offset = offset + offset` stops the crash + } + return offset + } +} + +// Original crash: + +/* +SIL verification failed: conflicting debug variable type!: DebugVars[argNum].second == DebugVarTy +Verifying instruction: + %5 = apply %4<τ_0_0>(%3) : $@convention(method) <τ_0_0> (@thin BatchNorm<τ_0_0>.TangentVector.Type) -> @owned BatchNorm<τ_0_0>.TangentVector // users: %39, %69, %47, %13, %40, %20 +-> debug_value %5 : $BatchNorm<τ_0_0>.TangentVector, let, name "self", argno 2, implicit, expr op_deref // id: %20 +In function: +// pullback of BatchNorm.callAsFunction(_:) +sil private @$s10TensorFlow9BatchNormV14callAsFunctionyAA01_A0VyxGAGFlTJpUSpSr : $@convention(thin) <τ_0_0> (@guaranteed _Tensor<τ_0_0>, @owned _AD__$s10TensorFlow9BatchNormV14callAsFunctionyAA01_A0VyxGAGF_bb3__PB__src_0_wrt_1_l<τ_0_0>) -> @out BatchNorm<τ_0_0>.TangentVector { +// %0 // user: %87 +// %1 // user: %17 +// %2 // users: %50, %16 +bb0(%0 : $*BatchNorm<τ_0_0>.TangentVector, %1 : $_Tensor<τ_0_0>, %2 : $_AD__$s10TensorFlow9BatchNormV14callAsFunctionyAA01_A0VyxGAGF_bb3__PB__src_0_wrt_1_l<τ_0_0>): + %3 = metatype $@thin BatchNorm<τ_0_0>.TangentVector.Type // user: %5 + // function_ref static BatchNorm.TangentVector.zero.getter + %4 = function_ref @$s10TensorFlow9BatchNormV13TangentVectorV4zeroAEyx_GvgZ : $@convention(method) <τ_0_0> (@thin BatchNorm<τ_0_0>.TangentVector.Type) -> @owned BatchNorm<τ_0_0>.TangentVector // user: %5 + %5 = apply %4<τ_0_0>(%3) : $@convention(method) <τ_0_0> (@thin BatchNorm<τ_0_0>.TangentVector.Type) -> @owned BatchNorm<τ_0_0>.TangentVector // users: %39, %69, %47, %13, %40, %20 + %6 = alloc_stack $_Tensor<τ_0_0>, var, name "offset" // users: %41, %19, %33, %27, %21, %10, %91 + %7 = metatype $@thin _Tensor<τ_0_0>.Type // user: %9 + // function_ref static _Tensor.zero.getter + %8 = function_ref @$s10TensorFlow01_A0V4zeroACyxGvgZ : $@convention(method) <τ_0_0> (@thin _Tensor<τ_0_0>.Type) -> @owned _Tensor<τ_0_0> // user: %9 + %9 = apply %8<τ_0_0>(%7) : $@convention(method) <τ_0_0> (@thin _Tensor<τ_0_0>.Type) -> @owned _Tensor<τ_0_0> // users: %26, %43, %68, %74, %53, %62, %79, %81, %82, %11, %10 + store %9 to %6 : $*_Tensor<τ_0_0> // id: %10 + debug_value %9 : $_Tensor<τ_0_0>, var, name "offset" // id: %11 + %12 = alloc_stack $_Tensor<τ_0_0>, let, (name "self", loc "/Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/Layers/Normalization.swift":70:8, scope 0), argno 2, implicit, type $*BatchNorm<τ_0_0>.TangentVector, expr op_fragment:#BatchNorm.TangentVector.offset // users: %84, %57, %70, %85, %72, %59, %14, %90 + %13 = struct_extract %5 : $BatchNorm<τ_0_0>.TangentVector, #BatchNorm.TangentVector.offset // users: %72, %59, %14 + store %13 to %12 : $*_Tensor<τ_0_0> // id: %14 + %15 = alloc_stack $_Tensor<τ_0_0>, var, name "offset" // users: %56, %22, %35, %29, %23, %49, %89 + %16 = struct_extract %2 : $_AD__$s10TensorFlow9BatchNormV14callAsFunctionyAA01_A0VyxGAGF_bb3__PB__src_0_wrt_1_l<τ_0_0>, #_AD__$s10TensorFlow9BatchNormV14callAsFunctionyAA01_A0VyxGAGF_bb3__PB__src_0_wrt_1_l.predecessor // user: %44 + debug_value %1 : $_Tensor<τ_0_0> // id: %17 + // function_ref specialized static _Tensor.+= infix(_:_:) + %18 = function_ref @$s10TensorFlow01_A0V2peoiyyACyxGz_AEtFZTf4ndd_n : $@convention(thin) <τ_0_0> (@inout _Tensor<τ_0_0>) -> () // users: %84, %56, %19 + %19 = apply %18<τ_0_0>(%6) : $@convention(thin) <τ_0_0> (@inout _Tensor<τ_0_0>) -> () + debug_value %5 : $BatchNorm<τ_0_0>.TangentVector, let, name "self", argno 2, implicit, expr op_deref // id: %20 + %21 = load %6 : $*_Tensor<τ_0_0> // users: %24, %23 + %22 = struct_element_addr %15 : $*_Tensor<τ_0_0>, #_Tensor.handle // users: %61, %66, %34, %28 + store %21 to %15 : $*_Tensor<τ_0_0> // id: %23 + %24 = struct_extract %21 : $_Tensor<τ_0_0>, #_Tensor.handle // user: %25 + strong_retain %24 : $_TensorHandle // id: %25 + release_value %9 : $_Tensor<τ_0_0> // id: %26 + %27 = load %6 : $*_Tensor<τ_0_0> // users: %30, %29 + %28 = load %22 : $*_TensorHandle // user: %32 + store %27 to %15 : $*_Tensor<τ_0_0> // id: %29 + %30 = struct_extract %27 : $_Tensor<τ_0_0>, #_Tensor.handle // user: %31 + strong_retain %30 : $_TensorHandle // id: %31 + strong_release %28 : $_TensorHandle // id: %32 + %33 = load %6 : $*_Tensor<τ_0_0> // users: %36, %35 + %34 = load %22 : $*_TensorHandle // user: %38 + store %33 to %15 : $*_Tensor<τ_0_0> // id: %35 + %36 = struct_extract %33 : $_Tensor<τ_0_0>, #_Tensor.handle // user: %37 + strong_retain %36 : $_TensorHandle // id: %37 + strong_release %34 : $_TensorHandle // id: %38 + release_value %5 : $BatchNorm<τ_0_0>.TangentVector // id: %39 + debug_value %5 : $BatchNorm<τ_0_0>.TangentVector, let, name "self", argno 2, implicit, expr op_deref // id: %40 + %41 = struct_element_addr %6 : $*_Tensor<τ_0_0>, #_Tensor.handle // user: %42 + %42 = load %41 : $*_TensorHandle // users: %46, %75 + release_value %9 : $_Tensor<τ_0_0> // id: %43 + switch_enum %16 : $_AD__$s10TensorFlow9BatchNormV14callAsFunctionyAA01_A0VyxGAGF_bb3__Pred__src_0_wrt_1_l<τ_0_0>, case #_AD__$s10TensorFlow9BatchNormV14callAsFunctionyAA01_A0VyxGAGF_bb3__Pred__src_0_wrt_1_l.bb1!enumelt: bb1, case #_AD__$s10TensorFlow9BatchNormV14callAsFunctionyAA01_A0VyxGAGF_bb3__Pred__src_0_wrt_1_l.bb2!enumelt: bb2 // id: %44 + +// %45 // user: %48 +bb1(%45 : $_AD__$s10TensorFlow9BatchNormV14callAsFunctionyAA01_A0VyxGAGF_bb1__PB__src_0_wrt_1_l<τ_0_0>): // Preds: bb0 + strong_release %42 : $_TensorHandle // id: %46 + release_value %5 : $BatchNorm<τ_0_0>.TangentVector // id: %47 + %48 = struct_extract %45 : $_AD__$s10TensorFlow9BatchNormV14callAsFunctionyAA01_A0VyxGAGF_bb1__PB__src_0_wrt_1_l<τ_0_0>, #_AD__$s10TensorFlow9BatchNormV14callAsFunctionyAA01_A0VyxGAGF_bb1__PB__src_0_wrt_1_l.pullback_0 // user: %49 + %49 = apply %48(%15) : $@callee_guaranteed @substituted <τ_0_0, τ_0_1, τ_0_2, τ_0_3 where τ_0_0 == τ_0_1, τ_0_2 == τ_0_3> (@inout _Tensor<τ_0_0>) -> @owned _Tensor<τ_0_2> for <τ_0_0, τ_0_0, τ_0_0, τ_0_0> // user: %54 + release_value %2 : $_AD__$s10TensorFlow9BatchNormV14callAsFunctionyAA01_A0VyxGAGF_bb3__PB__src_0_wrt_1_l<τ_0_0> // id: %50 + // function_ref specialized static _Tensor.+ infix(_:_:) + %51 = function_ref @$s10TensorFlow01_A0V1poiyACyxGAE_AEtFZTf4ddd_n : $@convention(thin) <τ_0_0> () -> @owned _Tensor<τ_0_0> // user: %52 + %52 = apply %51<τ_0_0>() : $@convention(thin) <τ_0_0> () -> @owned _Tensor<τ_0_0> // users: %63, %55 + release_value %9 : $_Tensor<τ_0_0> // id: %53 + release_value %49 : $_Tensor<τ_0_0> // id: %54 + debug_value %52 : $_Tensor<τ_0_0> // id: %55 + %56 = apply %18<τ_0_0>(%15) : $@convention(thin) <τ_0_0> (@inout _Tensor<τ_0_0>) -> () + %57 = struct_element_addr %12 : $*_Tensor<τ_0_0>, #_Tensor.handle // user: %58 + %58 = load %57 : $*_TensorHandle // user: %60 + store %13 to %12 : $*_Tensor<τ_0_0> // id: %59 + strong_release %58 : $_TensorHandle // id: %60 + %61 = load %22 : $*_TensorHandle // user: %64 + release_value %9 : $_Tensor<τ_0_0> // id: %62 + release_value %52 : $_Tensor<τ_0_0> // id: %63 + br bb3(%61 : $_TensorHandle) // id: %64 + +bb2(%65 : $_AD__$s10TensorFlow9BatchNormV14callAsFunctionyAA01_A0VyxGAGF_bb2__PB__src_0_wrt_1_l<τ_0_0>): // Preds: bb0 + %66 = load %22 : $*_TensorHandle // user: %67 + strong_release %66 : $_TensorHandle // id: %67 + release_value %9 : $_Tensor<τ_0_0> // id: %68 + release_value %5 : $BatchNorm<τ_0_0>.TangentVector // id: %69 + %70 = struct_element_addr %12 : $*_Tensor<τ_0_0>, #_Tensor.handle // user: %71 + %71 = load %70 : $*_TensorHandle // user: %73 + store %13 to %12 : $*_Tensor<τ_0_0> // id: %72 + strong_release %71 : $_TensorHandle // id: %73 + release_value %9 : $_Tensor<τ_0_0> // id: %74 + br bb3(%42 : $_TensorHandle) // id: %75 + +// %76 // user: %80 +bb3(%76 : $_TensorHandle): // Preds: bb1 bb2 + // function_ref specialized static _Tensor.+ infix(_:_:) + %77 = function_ref @$s10TensorFlow01_A0V1poiyACyxGAE_AEtFZTf4ddd_n : $@convention(thin) <τ_0_0> () -> @owned _Tensor<τ_0_0> // user: %78 + %78 = apply %77<τ_0_0>() : $@convention(thin) <τ_0_0> () -> @owned _Tensor<τ_0_0> // users: %88, %83 + release_value %9 : $_Tensor<τ_0_0> // id: %79 + strong_release %76 : $_TensorHandle // id: %80 + release_value %9 : $_Tensor<τ_0_0> // id: %81 + debug_value %9 : $_Tensor<τ_0_0>, var, name "offset" // id: %82 + debug_value %78 : $_Tensor<τ_0_0> // id: %83 + %84 = apply %18<τ_0_0>(%12) : $@convention(thin) <τ_0_0> (@inout _Tensor<τ_0_0>) -> () + %85 = load %12 : $*_Tensor<τ_0_0> // user: %86 + %86 = struct $BatchNorm<τ_0_0>.TangentVector (%85 : $_Tensor<τ_0_0>) // user: %87 + store %86 to %0 : $*BatchNorm<τ_0_0>.TangentVector // id: %87 + release_value %78 : $_Tensor<τ_0_0> // id: %88 + dealloc_stack %15 : $*_Tensor<τ_0_0> // id: %89 + dealloc_stack %12 : $*_Tensor<τ_0_0> // id: %90 + dealloc_stack %6 : $*_Tensor<τ_0_0> // id: %91 + %92 = tuple () // user: %93 + return %92 : $() // id: %93 +} // end sil function '$s10TensorFlow9BatchNormV14callAsFunctionyAA01_A0VyxGAGFlTJpUSpSr' + +Please submit a bug report (https://swift.org/contributing/#reporting-bugs) and include the project and the crash backtrace. +Stack dump: +0. Program arguments: /Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-2022-02-03-a.xctoolchain/usr/bin/swift-frontend -frontend -c /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/Bindings/EagerExecution.swift /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/Bindings/RawOpsAugmented.swift /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/Bindings/RawOpsDispatching.swift /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/Bindings/RawOpsGenerated.swift /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/Bindings/TFTensorOperation.swift /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/Core/BroadcastingPullback.swift /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/Core/CopyableToDevice.swift /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/Core/DataTypes.swift /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/Core/DifferentialOperators.swift /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/Core/ElementaryFunctions.swift /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/Core/EuclideanDifferentiable.swift /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/Core/Execution.swift /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/Core/KeyPathIterable.swift /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/Core/LazyTensorContext.swift /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/Core/LazyTensorOperation.swift /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/Core/LazyTensorShapeInference.swift /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/Core/LazyTensorTFFunctionBuilder.swift /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/Core/LazyTensorTrace.swift /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/Core/LazyTensorTraceCache.swift /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/Core/MixedPrecision.swift /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/Core/PointwiseMultiplicative.swift /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/Core/Runtime.swift /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/Core/ShapedArray.swift /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/Core/StringTensor.swift /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/Core/Tensor.swift /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/Core/TensorGroup.swift /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/Core/TensorHandle.swift /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/Core/TensorShape.swift /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/Core/Threading.swift /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/Core/Utilities.swift /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/Core/VectorProtocol.swift /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/Initializers.swift /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/Layers/Normalization.swift /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/Operators/Basic.swift /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/Operators/Math.swift /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/StdlibExtensions.swift /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/X10/APIs/CrossReplicaSum.swift /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/X10/APIs/DeviceScope.swift /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/X10/APIs/RawOpsManual.swift /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/X10/Device.swift /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/X10/RawOpsXLAGenerated.swift /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/X10/XLAScalarType.swift /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/X10/XLATensor.swift -supplementary-output-file-map /var/folders/qn/86czb43d3pv03bfnxvb3x66h0000gn/T/TemporaryDirectory.wBRIea/supplementaryOutputs-1 -target arm64-apple-macosx10.13 -Xllvm -aarch64-use-tbi -enable-objc-interop -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.1.sdk -I /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release -I /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/lib -F /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Frameworks -color-diagnostics -g -debug-info-format=dwarf -module-cache-path /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/ModuleCache -swift-version 5 -O -D SWIFT_PACKAGE -D DEFAULT_BACKEND_EAGER -D TENSORFLOW_USE_STANDARD_TOOLCHAIN -new-driver-path /Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-2022-02-03-a.xctoolchain/usr/bin/swift-driver -resource-dir /Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-2022-02-03-a.xctoolchain/usr/lib/swift -Xcc -fmodule-map-file=/Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/checkouts/swift-numerics/Sources/_NumericsShims/include/module.modulemap -Xcc -I -Xcc /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/checkouts/swift-numerics/Sources/_NumericsShims/include -Xcc -fmodule-map-file=/Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/CX10Modules/include/module.modulemap -Xcc -I -Xcc /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/CX10Modules/include -Xcc -fmodule-map-file=/Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/CTensorFlow/include/module.modulemap -Xcc -I -Xcc /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/CTensorFlow/include -Xcc -I/Users/philipturner/Documents/building-tensorflow/Library/tensorflow-2.8.0/usr/include -module-name TensorFlow -target-sdk-version 12.1 -parse-as-library -num-threads 10 -o /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/TensorFlow.build/Bindings/EagerExecution.swift.o -o /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/TensorFlow.build/Bindings/RawOpsAugmented.swift.o -o /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/TensorFlow.build/Bindings/RawOpsDispatching.swift.o -o /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/TensorFlow.build/Bindings/RawOpsGenerated.swift.o -o /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/TensorFlow.build/Bindings/TFTensorOperation.swift.o -o /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/TensorFlow.build/Core/BroadcastingPullback.swift.o -o /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/TensorFlow.build/Core/CopyableToDevice.swift.o -o /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/TensorFlow.build/Core/DataTypes.swift.o -o /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/TensorFlow.build/Core/DifferentialOperators.swift.o -o /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/TensorFlow.build/Core/ElementaryFunctions.swift.o -o /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/TensorFlow.build/Core/EuclideanDifferentiable.swift.o -o /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/TensorFlow.build/Core/Execution.swift.o -o /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/TensorFlow.build/Core/KeyPathIterable.swift.o -o /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/TensorFlow.build/Core/LazyTensorContext.swift.o -o /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/TensorFlow.build/Core/LazyTensorOperation.swift.o -o /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/TensorFlow.build/Core/LazyTensorShapeInference.swift.o -o /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/TensorFlow.build/Core/LazyTensorTFFunctionBuilder.swift.o -o /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/TensorFlow.build/Core/LazyTensorTrace.swift.o -o /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/TensorFlow.build/Core/LazyTensorTraceCache.swift.o -o /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/TensorFlow.build/Core/MixedPrecision.swift.o -o /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/TensorFlow.build/Core/PointwiseMultiplicative.swift.o -o /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/TensorFlow.build/Core/Runtime.swift.o -o /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/TensorFlow.build/Core/ShapedArray.swift.o -o /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/TensorFlow.build/Core/StringTensor.swift.o -o /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/TensorFlow.build/Core/Tensor.swift.o -o /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/TensorFlow.build/Core/TensorGroup.swift.o -o /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/TensorFlow.build/Core/TensorHandle.swift.o -o /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/TensorFlow.build/Core/TensorShape.swift.o -o /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/TensorFlow.build/Core/Threading.swift.o -o /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/TensorFlow.build/Core/Utilities.swift.o -o /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/TensorFlow.build/Core/VectorProtocol.swift.o -o /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/TensorFlow.build/Initializers.swift.o -o /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/TensorFlow.build/Layers/Normalization.swift.o -o /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/TensorFlow.build/Operators/Basic.swift.o -o /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/TensorFlow.build/Operators/Math.swift.o -o /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/TensorFlow.build/StdlibExtensions.swift.o -o /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/TensorFlow.build/X10/APIs/CrossReplicaSum.swift.o -o /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/TensorFlow.build/X10/APIs/DeviceScope.swift.o -o /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/TensorFlow.build/X10/APIs/RawOpsManual.swift.o -o /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/TensorFlow.build/X10/Device.swift.o -o /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/TensorFlow.build/X10/RawOpsXLAGenerated.swift.o -o /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/TensorFlow.build/X10/XLAScalarType.swift.o -o /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/.build/arm64-apple-macosx/release/TensorFlow.build/X10/XLATensor.swift.o +1. Apple Swift version 5.7-dev (LLVM cd2992b90c95d01, Swift ab85807f0646caa) +2. Compiling with the current language version +3. While verifying SIL function "@$s10TensorFlow9BatchNormV14callAsFunctionyAA01_A0VyxGAGFlTJpUSpSr". + for 'callAsFunction(_:)' (at /Users/philipturner/Documents/building-tensorflow/swift-for-tensorflow/Sources/TensorFlow/Layers/Normalization.swift:70:3) +Stack dump without symbol names (ensure you have llvm-symbolizer in your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point to it): +0 swift-frontend 0x0000000108961c54 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) + 56 +1 swift-frontend 0x0000000108960eb4 llvm::sys::RunSignalHandlers() + 128 +2 swift-frontend 0x00000001089622b8 SignalHandler(int) + 304 +3 libsystem_platform.dylib 0x00000001bb5304e4 _sigtramp + 56 +4 libsystem_pthread.dylib 0x00000001bb518eb0 pthread_kill + 288 +5 libsystem_c.dylib 0x00000001bb456314 abort + 164 +6 swift-frontend 0x00000001046aec58 (anonymous namespace)::SILVerifier::_require(bool, llvm::Twine const&, std::__1::function const&) + 1432 +7 swift-frontend 0x00000001046c8c6c (anonymous namespace)::SILVerifier::visitSILInstruction(swift::SILInstruction*) + 5104 +8 swift-frontend 0x00000001046b25e8 (anonymous namespace)::SILVerifier::visitSILBasicBlock(swift::SILBasicBlock*) + 1204 +9 swift-frontend 0x00000001046b1090 (anonymous namespace)::SILVerifier::visitSILFunction(swift::SILFunction*) + 7636 +10 swift-frontend 0x00000001046ae150 swift::SILModule::verify() const + 216 +11 swift-frontend 0x0000000104570a14 swift::CompilerInstance::performSILProcessing(swift::SILModule*) + 636 +12 swift-frontend 0x0000000104517814 performCompileStepsPostSILGen(swift::CompilerInstance&, std::__1::unique_ptr >, llvm::PointerUnion, swift::PrimarySpecificPaths const&, int&, swift::FrontendObserver*) + 716 +13 swift-frontend 0x00000001045171d8 swift::performCompileStepsPostSema(swift::CompilerInstance&, int&, swift::FrontendObserver*) + 1028 +14 swift-frontend 0x0000000104518c74 swift::performFrontend(llvm::ArrayRef, char const*, void*, swift::FrontendObserver*) + 2940 +15 swift-frontend 0x0000000104454900 swift::mainEntry(int, char const**) + 500 +16 dyld 0x0000000110f490f4 start + 520 +*/ diff --git a/test/ClangImporter/attr-swift_name.swift b/test/ClangImporter/attr-swift_name.swift index 31f6eb56107ae..76f335d62bf78 100644 --- a/test/ClangImporter/attr-swift_name.swift +++ b/test/ClangImporter/attr-swift_name.swift @@ -45,14 +45,6 @@ func test(_ i: Int) { // CHECK: SWIFT_NAME(MutuallyCircularNameA.Inner) @interface MutuallyCircularNameB : NSObject @end // CHECK-NOT: {{warning|note}}: // CHECK: note: please report this issue to the owners of 'ObjCIRExtras' - // CHECK-NOT: warning: - - // CHECK: warning: cycle detected while resolving 'MutuallyCircularNameA' in swift_name attribute for 'MutuallyCircularNameB' - // CHECK: SWIFT_NAME(MutuallyCircularNameA.Inner) @interface MutuallyCircularNameB : NSObject @end // CHECK-NOT: {{warning|note}}: - // CHECK: note: while resolving 'MutuallyCircularNameB' in swift_name attribute for 'MutuallyCircularNameA' // CHECK: SWIFT_NAME(MutuallyCircularNameB.Inner) @interface MutuallyCircularNameA : NSObject @end - // CHECK-NOT: {{warning|note}}: - // CHECK: note: please report this issue to the owners of 'ObjCIRExtras' - // CHECK-NOT: warning: } diff --git a/test/ClangImporter/static_inline_serialize.swift b/test/ClangImporter/static_inline_serialize.swift index 6f2e259ce22b4..139c4e4bbee0f 100644 --- a/test/ClangImporter/static_inline_serialize.swift +++ b/test/ClangImporter/static_inline_serialize.swift @@ -6,7 +6,7 @@ // RUN: %target-swift-frontend -module-name test -O -emit-sil %s -I %t -enable-objc-interop | %FileCheck %s // RUN: %target-swift-frontend -module-name test -O -emit-ir %s -I %t -enable-objc-interop | %FileCheck --check-prefix=CHECK-IR %s -// CHECK: sil shared_external [clang c_inline_func] @c_inline_func : $@convention(c) (Int32) -> Int32 +// CHECK: sil shared [clang c_inline_func] @c_inline_func : $@convention(c) (Int32) -> Int32 // CHECK-IR-LABEL: define{{.*}} i32 @"$s4test6mytest1xs5Int32VAE_tF"(i32 %0) // CHECK-IR: = add {{.*}}, 27 diff --git a/test/Constraints/opened_existentials_suppression.swift b/test/Constraints/opened_existentials_suppression.swift new file mode 100644 index 0000000000000..933d0b4cdc978 --- /dev/null +++ b/test/Constraints/opened_existentials_suppression.swift @@ -0,0 +1,11 @@ +// RUN: %target-swift-frontend -enable-experimental-opened-existential-types -typecheck -dump-ast -parse-as-library %s | %FileCheck %s + +protocol P { } + +func acceptsBox(_ value: T) { } + +// CHECK: passBox +// CHECK-NOT: open_existential_expr +func passBox(p: P) { + acceptsBox(p as P) +} diff --git a/test/DebugInfo/debug_value_addr.swift b/test/DebugInfo/debug_value_addr.swift index e642824372177..2a25dc98b9f2c 100644 --- a/test/DebugInfo/debug_value_addr.swift +++ b/test/DebugInfo/debug_value_addr.swift @@ -1,8 +1,8 @@ // RUN: %target-swift-frontend -primary-file %s -emit-ir -g -o - | %FileCheck %s // RUN: %target-swift-frontend %s -emit-sil -g -o - | %FileCheck -check-prefix=CHECK-SIL %s -// Temporarily disable on arm64 (rdar://89237318) -// UNSUPPORTED: CPU=arm64 +// rdar://89237318 +// REQUIRES: rdar89237318 // Verify that -Onone shadow copies are emitted for debug_value_addr // instructions. diff --git a/test/DebugInfo/move_function_dbginfo.swift b/test/DebugInfo/move_function_dbginfo.swift index f04edd054674e..41f4b02c9e2cc 100644 --- a/test/DebugInfo/move_function_dbginfo.swift +++ b/test/DebugInfo/move_function_dbginfo.swift @@ -3,6 +3,9 @@ // RUN: %target-swift-frontend -parse-as-library -Xllvm -sil-disable-pass=alloc-stack-hoisting -g -c %s -o %t/out.o // RUN: %llvm-dwarfdump --show-children %t/out.o | %FileCheck -check-prefix=DWARF %s +// rdar://90028779 +// REQUIRES: rdar90028779 + // This test checks that: // // 1. At the IR level, we insert the appropriate llvm.dbg.addr, llvm.dbg.value. diff --git a/test/DebugInfo/sil_based_dbg.swift b/test/DebugInfo/sil_based_dbg.swift index de40d43c72d09..55200b54f83aa 100644 --- a/test/DebugInfo/sil_based_dbg.swift +++ b/test/DebugInfo/sil_based_dbg.swift @@ -20,9 +20,9 @@ public func testit() { // To create something like `alloc_stack ..., (name "foo", loc ..., scope 0)...` // as our testing input, we're only running SROA over the input swift code. // RUN: %target-swift-frontend -enable-copy-propagation=requested-passes-only -enable-lexical-lifetimes=false %s -disable-debugger-shadow-copies -emit-sil -g -o %t/stage1.sil -// RUN: %target-sil-opt -enable-copy-propagation=requested-passes-only -enable-lexical-lifetimes=false -sil-print-debuginfo -access-marker-elim -sroa %t/stage1.sil -o %t/stage2.sil +// RUN: %target-sil-opt -parse-serialized-sil -enable-copy-propagation=requested-passes-only -enable-lexical-lifetimes=false -sil-print-debuginfo -access-marker-elim -sroa %t/stage1.sil -o %t/stage2.sil // The verification shouldn't fail -// RUN: %target-swift-frontend -enable-copy-propagation=requested-passes-only -enable-lexical-lifetimes=false %t/stage2.sil -sil-verify-all -sil-based-debuginfo -g -emit-sil -o %t/out.sil +// RUN: %target-swift-frontend -Xllvm -parse-serialized-sil -enable-copy-propagation=requested-passes-only -enable-lexical-lifetimes=false %t/stage2.sil -sil-verify-all -sil-based-debuginfo -g -emit-sil -o %t/out.sil // RUN: %FileCheck %s --check-prefix=CHECK_DBG_SCOPE < %t/out.sil struct TheStruct { var the_member : Int diff --git a/test/Demangle/Inputs/manglings.txt b/test/Demangle/Inputs/manglings.txt index 6566f3957c4d8..faad55870b393 100644 --- a/test/Demangle/Inputs/manglings.txt +++ b/test/Demangle/Inputs/manglings.txt @@ -420,10 +420,15 @@ $sSIxip6foobarP ---> foobar in Swift.DefaultIndices.subscript : A $s13__lldb_expr_110$10016c2d8yXZ1B10$10016c2e0LLC ---> __lldb_expr_1.(unknown context at $10016c2d8).(B in $10016c2e0) $s__TJO ---> $s__TJO $s6Foobar7Vector2VAASdRszlE10simdMatrix5scale6rotate9translateSo0C10_double3x3aACySdG_SdAJtFZ0D4TypeL_aySd__GD ---> MatrixType #1 in static (extension in Foobar):Foobar.Vector2.simdMatrix(scale: Foobar.Vector2, rotate: Swift.Double, translate: Foobar.Vector2) -> __C.simd_double3x3 -$s17distributed_thunk2DAC1fyyFTE ---> distributed thunk for distributed_thunk.DA.f() -> () +$s17distributed_thunk2DAC1fyyFTE ---> distributed thunk distributed_thunk.DA.f() -> () $s16distributed_test1XC7computeyS2iFTF ---> distributed accessor for distributed_test.X.compute(Swift.Int) -> Swift.Int -$s27distributed_actor_accessors7MyActorC7simple2ySSSiFTETFHF ---> accessible function runtime record for distributed accessor for distributed thunk for distributed_actor_accessors.MyActor.simple2(Swift.Int) -> Swift.String +$s27distributed_actor_accessors7MyActorC7simple2ySSSiFTETFHF ---> accessible function runtime record for distributed accessor for distributed thunk distributed_actor_accessors.MyActor.simple2(Swift.Int) -> Swift.String $s1A3bar1aySSYt_tF ---> A.bar(a: _const Swift.String) -> () $s1t1fyyFSiAA3StrVcs7KeyPathCyADSiGcfu_SiADcfu0_33_556644b740b1b333fecb81e55a7cce98ADSiTf3npk_n ---> function signature specialization ]> of implicit closure #2 (t.Str) -> Swift.Int in implicit closure #1 (Swift.KeyPath) -> (t.Str) -> Swift.Int in t.f() -> () $s21back_deploy_attribute0A12DeployedFuncyyFTwb ---> back deployment thunk for back_deploy_attribute.backDeployedFunc() -> () $s21back_deploy_attribute0A12DeployedFuncyyFTwB ---> back deployment fallback for back_deploy_attribute.backDeployedFunc() -> () +$s4test3FooVAAyyAA1P_pyxqd__XPlF ---> test.Foo.test(test.P) -> () +$s4test3FooVAAyyAA1P_pyxXPF ---> test.Foo.test(test.P) -> () +$s4test3FooVAAyyAA1P_pF ---> test.Foo.test(test.P) -> () +$s4test3FooVAAyyAA1P_pyqd__XPAaDRd__lF ---> test.Foo.test(test.P) -> () + 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 265387631ac38..8577f8792e2a0 100644 --- a/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_echo.swift +++ b/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_echo.swift @@ -32,7 +32,7 @@ func test() async throws { let ref = try Greeter.resolve(id: local.id, using: system) let reply = try await ref.echo(name: "Caplin") - // CHECK: >> remoteCall: on:main.Greeter, target:RemoteCallTarget(_mangledName: "$s4main7GreeterC4echo4nameS2S_tFTE"), invocation:FakeInvocationEncoder(genericSubs: [], arguments: ["Caplin"], returnType: Optional(Swift.String), errorType: nil), throwing:Swift.Never, returning:Swift.String + // CHECK: >> remoteCall: on:main.Greeter, target:RemoteCallTarget(_mangledName: "$s4main7GreeterC4echo4nameS2S_tYaKFTE"), invocation:FakeInvocationEncoder(genericSubs: [], arguments: ["Caplin"], returnType: Optional(Swift.String), errorType: nil), throwing:Swift.Never, returning:Swift.String // CHECK: << remoteCall return: Echo: Caplin print("reply: \(reply)") 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 377a14e05186a..dfd350ee9f916 100644 --- a/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_empty.swift +++ b/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_empty.swift @@ -31,7 +31,7 @@ func test() async throws { let ref = try Greeter.resolve(id: local.id, using: system) try await ref.empty() - // CHECK: >> remoteCallVoid: on:main.Greeter, target:RemoteCallTarget(_mangledName: "$s4main7GreeterC5emptyyyFTE"), invocation:FakeInvocationEncoder(genericSubs: [], arguments: [], returnType: nil, errorType: nil), throwing:Swift.Never + // CHECK: >> remoteCallVoid: on:main.Greeter, target:RemoteCallTarget(_mangledName: "$s4main7GreeterC5emptyyyYaKFTE"), invocation:FakeInvocationEncoder(genericSubs: [], arguments: [], returnType: nil, errorType: nil), throwing:Swift.Never // CHECK: << onReturn: () } 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 41b5ea7663643..3a6923ae3c7fa 100644 --- a/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_genericFunc.swift +++ b/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_genericFunc.swift @@ -14,6 +14,12 @@ // FIXME(distributed): Distributed actors currently have some issues on windows, isRemote always returns false. rdar://82593574 // UNSUPPORTED: windows +// FIXME(distributed): rdar://90078069 +// UNSUPPORTED: linux + +// FIXME(distributed): optimized builds optimize too aggressively somewhere +// REQUIRES: swift_test_mode_optimize_none + import _Distributed import FakeDistributedActorSystems @@ -21,6 +27,7 @@ typealias DefaultDistributedActorSystem = FakeRoundtripActorSystem distributed actor Greeter { distributed func generic(_ value: V) -> String { + _ = V.self return "\(value)" } @@ -42,7 +49,7 @@ func test() async throws { // CHECK: > encode argument: Caplin // CHECK: > encode return type: Swift.String // CHECK: > done recording - // CHECK: >> remoteCall: on:main.Greeter, target:RemoteCallTarget(_mangledName: "$s4main7GreeterC7genericySSxSeRzSERzlFTE"), invocation:FakeInvocationEncoder(genericSubs: [Swift.String], arguments: ["Caplin"], returnType: Optional(Swift.String), errorType: nil), throwing:Swift.Never, returning:Swift.String + // CHECK: >> remoteCall: on:main.Greeter, target:RemoteCallTarget(_mangledName: "$s4main7GreeterC7genericySSxYaKSeRzSERzlFTE"), invocation:FakeInvocationEncoder(genericSubs: [Swift.String], arguments: ["Caplin"], returnType: Optional(Swift.String), errorType: nil), throwing:Swift.Never, returning:Swift.String print("reply: \(r1)") // CHECK: reply: Caplin @@ -58,7 +65,7 @@ func test() async throws { // CHECK: > encode argument: [1, 2, 3] // CHECK: > encode return type: Swift.String // CHECK: > done recording - // CHECK: >> remoteCall: on:main.Greeter, target:RemoteCallTarget(_mangledName: "$s4main7GreeterC8generic26strict__SSSd_xSayq_GtSeRzSERzSeR_SER_r0_lFTE"), invocation:FakeInvocationEncoder(genericSubs: [Swift.String, Swift.Int], arguments: [2.0, "Caplin", [1, 2, 3]], returnType: Optional(Swift.String), errorType: nil), throwing:Swift.Never, returning:Swift.String + // CHECK: >> remoteCall: on:main.Greeter, target:RemoteCallTarget(_mangledName: "$s4main7GreeterC8generic26strict__SSSd_xSayq_GtYaKSeRzSERzSeR_SER_r0_lFTE"), invocation:FakeInvocationEncoder(genericSubs: [Swift.String, Swift.Int], arguments: [2.0, "Caplin", [1, 2, 3]], returnType: Optional(Swift.String), errorType: nil), throwing:Swift.Never, returning:Swift.String print("reply: \(r2)") // CHECK: reply: Caplin } 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 74cd2418123ff..18e2ed5bc99a3 100644 --- a/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_hello.swift +++ b/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_hello.swift @@ -32,7 +32,7 @@ func test() async throws { let ref = try Greeter.resolve(id: local.id, using: system) let response = try await ref.hello() - // CHECK: >> remoteCall: on:main.Greeter, target:RemoteCallTarget(_mangledName: "$s4main7GreeterC5helloSSyFTE"), invocation:FakeInvocationEncoder(genericSubs: [], arguments: [], returnType: Optional(Swift.String), errorType: nil), throwing:Swift.Never, returning:Swift.String + // CHECK: >> remoteCall: on:main.Greeter, target:RemoteCallTarget(_mangledName: "$s4main7GreeterC5helloSSyYaKFTE"), invocation:FakeInvocationEncoder(genericSubs: [], arguments: [], returnType: Optional(Swift.String), errorType: nil), throwing:Swift.Never, returning:Swift.String print("response: \(response)") // CHECK: response: Hello, World! 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 b4178579190e4..183a8b91bcf92 100644 --- a/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_take.swift +++ b/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_take.swift @@ -14,6 +14,12 @@ // FIXME(distributed): Distributed actors currently have some issues on windows, isRemote always returns false. rdar://82593574 // UNSUPPORTED: windows +// FIXME(distributed): rdar://90078069 +// UNSUPPORTED: linux + +// FIXME(distributed): optimized builds optimize too aggressively somewhere +// REQUIRES: swift_test_mode_optimize_none + import _Distributed import FakeDistributedActorSystems @@ -32,7 +38,7 @@ func test() async throws { let ref = try Greeter.resolve(id: local.id, using: system) try await ref.take(name: "Caplin") - // CHECK: >> remoteCallVoid: on:main.Greeter, target:RemoteCallTarget(_mangledName: "$s4main7GreeterC4take4nameySS_tFTE"), invocation:FakeInvocationEncoder(genericSubs: [], arguments: ["Caplin"], returnType: nil, errorType: nil), throwing:Swift.Never + // CHECK: >> remoteCallVoid: on:main.Greeter, target:RemoteCallTarget(_mangledName: "$s4main7GreeterC4take4nameySS_tYaKFTE"), invocation:FakeInvocationEncoder(genericSubs: [], arguments: ["Caplin"], returnType: nil, errorType: nil), throwing:Swift.Never // CHECK: take: Caplin } 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 6db23e216831b..a04c743f70065 100644 --- a/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_takeThrowReturn.swift +++ b/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_takeThrowReturn.swift @@ -35,7 +35,7 @@ func test() async throws { do { let value = try await ref.takeThrowReturn(name: "Example") - // CHECK: >> remoteCall: on:main.Greeter, target:RemoteCallTarget(_mangledName: "$s4main7GreeterC15takeThrowReturn4nameS2S_tYaKFTE"), invocation:FakeInvocationEncoder(genericSubs: [], arguments: ["Example"], returnType: Optional(Swift.String), errorType: Optional(Swift.Error.Protocol)), throwing:Swift.Error.Protocol, returning:Swift.String + // CHECK: >> remoteCall: on:main.Greeter, target:RemoteCallTarget(_mangledName: "$s4main7GreeterC15takeThrowReturn4nameS2S_tYaKFTE"), invocation:FakeInvocationEncoder(genericSubs: [], arguments: ["Example"], returnType: Optional(Swift.String), errorType: Optional(Swift.Error)), throwing:Swift.Error, returning:Swift.String print("did not throw") // CHECK-NOT: did not throw 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 1ca0a34b981f0..c93fb29d5b46a 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 @@ -14,6 +14,12 @@ // FIXME(distributed): Distributed actors currently have some issues on windows, isRemote always returns false. rdar://82593574 // UNSUPPORTED: windows +// FIXME(distributed): rdar://90078069 +// UNSUPPORTED: linux + +// FIXME(distributed): optimized builds optimize too aggressively somewhere +// REQUIRES: swift_test_mode_optimize_none + import _Distributed import FakeDistributedActorSystems @@ -38,7 +44,7 @@ func test() async throws { let ref = try Greeter.resolve(id: local.id, using: system) try await ref.take(name: "Caplin", int: 1337) - // CHECK: >> remoteCallVoid: on:main.Greeter, target:RemoteCallTarget(_mangledName: "$s4main7GreeterC4take4name3intySS_SitFTE"), invocation:FakeInvocationEncoder(genericSubs: [], arguments: ["Caplin", 1337], returnType: nil, errorType: nil), throwing:Swift.Never + // CHECK: >> remoteCallVoid: on:main.Greeter, target:RemoteCallTarget(_mangledName: "$s4main7GreeterC4take4name3intySS_SitYaKFTE"), invocation:FakeInvocationEncoder(genericSubs: [], arguments: ["Caplin", 1337], returnType: nil, errorType: nil), throwing:Swift.Never // try await ref.take(name: "Caplin", int: 1337, clazz: .init()) // FIXME(distributed): crashes 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 c0fe2cc1e44c1..d439fdb65538f 100644 --- a/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_throw.swift +++ b/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_throw.swift @@ -35,7 +35,7 @@ func test() async throws { do { try await ref.maybeThrows() - // CHECK: >> remoteCallVoid: on:main.Greeter, target:RemoteCallTarget(_mangledName: "$s4main7GreeterC11maybeThrowsyyKFTE"), invocation:FakeInvocationEncoder(genericSubs: [], arguments: [], returnType: nil, errorType: Optional(Swift.Error.Protocol)), throwing:Swift.Error.Protocol + // CHECK: >> remoteCallVoid: on:main.Greeter, target:RemoteCallTarget(_mangledName: "$s4main7GreeterC11maybeThrowsyyYaKFTE"), invocation:FakeInvocationEncoder(genericSubs: [], arguments: [], returnType: nil, errorType: Optional(Swift.Error)), throwing:Swift.Error print("did not throw") // CHECK-NOT: did not throw diff --git a/test/Distributed/Runtime/distributed_actor_hop_to.swift b/test/Distributed/Runtime/distributed_actor_hop_to.swift new file mode 100644 index 0000000000000..d0c04ea50c281 --- /dev/null +++ b/test/Distributed/Runtime/distributed_actor_hop_to.swift @@ -0,0 +1,53 @@ +// RUN: %empty-directory(%t) +// RUN: %target-swift-frontend-emit-module -emit-module-path %t/FakeDistributedActorSystems.swiftmodule -module-name FakeDistributedActorSystems -disable-availability-checking %S/../Inputs/FakeDistributedActorSystems.swift +// RUN: %target-build-swift -module-name main -Xfrontend -enable-experimental-distributed -Xfrontend -disable-availability-checking -j2 -parse-as-library -I %t %s %S/../Inputs/FakeDistributedActorSystems.swift -o %t/a.out +// RUN: %target-run %t/a.out | %FileCheck %s --color + +// REQUIRES: executable_test +// REQUIRES: concurrency +// REQUIRES: distributed + +// rdar://76038845 +// UNSUPPORTED: use_os_stdlib +// UNSUPPORTED: back_deployment_runtime + +// FIXME(distributed): Distributed actors currently have some issues on windows, isRemote always returns false. rdar://82593574 +// UNSUPPORTED: windows + + +import _Distributed +import FakeDistributedActorSystems + +typealias DefaultDistributedActorSystem = FakeRoundtripActorSystem + +protocol LifecycleWatch: DistributedActor where ActorSystem == FakeRoundtripActorSystem { +} + +extension LifecycleWatch { + func watch() async throws { + // nothing here + print("executed: \(#function)") + } + + distributed func test() async throws { + print("executed: \(#function)") + try await self.watch() + print("done executed: \(#function)") + } +} + +distributed actor Worker: LifecycleWatch { +} + +@main struct Main { + static func main() async { + let worker: any LifecycleWatch = Worker(system: DefaultDistributedActorSystem()) + try! await worker.test() + + // CHECK: executed: test() + // CHECK: executed: watch() + // CHECK: done executed: test() + + print("OK") // CHECK: OK + } +} diff --git a/test/Distributed/Runtime/distributed_actor_remoteCall.swift b/test/Distributed/Runtime/distributed_actor_remoteCall.swift index 336da75f4b96e..90d730c696b06 100644 --- a/test/Distributed/Runtime/distributed_actor_remoteCall.swift +++ b/test/Distributed/Runtime/distributed_actor_remoteCall.swift @@ -14,6 +14,12 @@ // FIXME(distributed): Distributed actors currently have some issues on windows, isRemote always returns false. rdar://82593574 // UNSUPPORTED: windows +// FIXME(distributed): rdar://90078069 +// UNSUPPORTED: linux + +// FIXME(distributed): optimized builds optimize too aggressively somewhere +// REQUIRES: swift_test_mode_optimize_none + import _Distributed final class Obj: @unchecked Sendable, Codable {} @@ -281,19 +287,19 @@ struct FakeResultHandler: DistributedTargetInvocationResultHandler { typealias DefaultDistributedActorSystem = FakeActorSystem // actual mangled name: -let emptyName = "$s4main7GreeterC5emptyyyFTE" -let helloName = "$s4main7GreeterC5helloSSyFTE" -let answerName = "$s4main7GreeterC6answerSiyFTE" -let largeResultName = "$s4main7GreeterC11largeResultAA11LargeStructVyFTE" -let enumResultName = "$s4main7GreeterC10enumResultAA1EOyFTE" -let echoName = "$s4main7GreeterC4echo4name3ageS2S_SitFTE" -let generic1Name = "$s4main7GreeterC8generic11ayx_tSeRzSERzlFTE" -let generic2Name = "$s4main7GreeterC8generic21a1byx_q_tSeRzSERzSeR_SER_r0_lFTE" -let generic3Name = "$s4main7GreeterC8generic31a1b1cyx_Sayq_Gq0_tSeRzSERzSeR_SER_SeR0_SER0_r1_lFTE" -let generic4Name = "$s4main7GreeterC8generic41a1b1cyx_AA1SVyq_GSayq0_GtSeRzSERzSeR_SER_SeR0_SER0_r1_lFTE" -let generic5Name = "$s4main7GreeterC8generic51a1b1c1dyx_AA1SVyq_Gq0_q1_tSeRzSERzSeR_SER_SeR0_SER0_SeR1_SER1_r2_lFTE" -let genericOptionalName = "$s4main7GreeterC15genericOptional1tyxSg_tSeRzSERzlFTE" -let expectsDecodeErrorName = "$s4main7GreeterC18expectsDecodeError1vySiSgSgSg_tFTE" +let emptyName = "$s4main7GreeterC5emptyyyYaKFTE" +let helloName = "$s4main7GreeterC5helloSSyYaKFTE" +let answerName = "$s4main7GreeterC6answerSiyYaKFTE" +let largeResultName = "$s4main7GreeterC11largeResultAA11LargeStructVyYaKFTE" +let enumResultName = "$s4main7GreeterC10enumResultAA1EOyYaKFTE" +let echoName = "$s4main7GreeterC4echo4name3ageS2S_SitYaKFTE" +let generic1Name = "$s4main7GreeterC8generic11ayx_tYaKSeRzSERzlFTE" +let generic2Name = "$s4main7GreeterC8generic21a1byx_q_tYaKSeRzSERzSeR_SER_r0_lFTE" +let generic3Name = "$s4main7GreeterC8generic31a1b1cyx_Sayq_Gq0_tYaKSeRzSERzSeR_SER_SeR0_SER0_r1_lFTE" +let generic4Name = "$s4main7GreeterC8generic41a1b1cyx_AA1SVyq_GSayq0_GtYaKSeRzSERzSeR_SER_SeR0_SER0_r1_lFTE" +let generic5Name = "$s4main7GreeterC8generic51a1b1c1dyx_AA1SVyq_Gq0_q1_tYaKSeRzSERzSeR_SER_SeR0_SER0_SeR1_SER1_r2_lFTE" +let genericOptionalName = "$s4main7GreeterC15genericOptional1tyxSg_tYaKSeRzSERzlFTE" +let expectsDecodeErrorName = "$s4main7GreeterC18expectsDecodeError1vySiSgSgSg_tYaKFTE" func test() async throws { let system = DefaultDistributedActorSystem() diff --git a/test/Distributed/Runtime/distributed_actor_remoteCall_roundtrip.swift b/test/Distributed/Runtime/distributed_actor_remoteCall_roundtrip.swift index 463d0d996b57d..fcb782acc3eac 100644 --- a/test/Distributed/Runtime/distributed_actor_remoteCall_roundtrip.swift +++ b/test/Distributed/Runtime/distributed_actor_remoteCall_roundtrip.swift @@ -16,6 +16,9 @@ // FIXME(distributed): Distributed actors currently have some issues on windows, isRemote always returns false. rdar://82593574 // UNSUPPORTED: windows +// FIXME(distributed): rdar://90078069 +// UNSUPPORTED: linux + import _Distributed import FakeDistributedActorSystems diff --git a/test/Distributed/Runtime/distributed_actor_remote_functions.swift b/test/Distributed/Runtime/distributed_actor_remote_functions.swift index b783045806f09..fe0feaa163f7f 100644 --- a/test/Distributed/Runtime/distributed_actor_remote_functions.swift +++ b/test/Distributed/Runtime/distributed_actor_remote_functions.swift @@ -8,6 +8,12 @@ // UNSUPPORTED: use_os_stdlib // UNSUPPORTED: back_deployment_runtime +// FIXME(distributed): rdar://90078069 +// UNSUPPORTED: linux + +// FIXME(distributed): optimized builds optimize too aggressively somewhere +// REQUIRES: swift_test_mode_optimize_none + import _Distributed import _Concurrency @@ -128,7 +134,7 @@ struct FakeActorSystem: DistributedActorSystem { Act.ID == ActorID, Err: Error, Res: SerializationRequirement { - guard target.mangledName != "$s4main28SomeSpecificDistributedActorC24helloThrowsTransportBoomSSyKFTE" else { + guard target.mangledName != "$s4main28SomeSpecificDistributedActorC24helloThrowsTransportBoomSSyYaKFTE" else { throw Boom("system") } @@ -237,15 +243,15 @@ func test_remote_invoke(address: ActorAddress, system: FakeActorSystem) async { // TODO(distributed): remote - helloAsyncThrows: remote(_remote_impl_helloAsyncThrows()) // CHECK: remote - helloAsyncThrows: remote($s4main28SomeSpecificDistributedActorC16helloAsyncThrowsSSyYaKFTE) // TODO(distributed): remote - helloAsync: remote() - // CHECK: remote - helloAsync: remote($s4main28SomeSpecificDistributedActorC10helloAsyncSSyYaFTE) + // CHECK: remote - helloAsync: remote($s4main28SomeSpecificDistributedActorC10helloAsyncSSyYaKFTE) // TODO(distributed): remote - helloThrows: remote(_remote_impl_helloThrows()) - // CHECK: remote - helloThrows: remote($s4main28SomeSpecificDistributedActorC11helloThrowsSSyKFTE) + // CHECK: remote - helloThrows: remote($s4main28SomeSpecificDistributedActorC11helloThrowsSSyYaKFTE) // TODO(distributed): remote - hello: remote(_remote_impl_hello()) - // CHECK: remote - hello: remote($s4main28SomeSpecificDistributedActorC5helloSSyFTE) + // CHECK: remote - hello: remote($s4main28SomeSpecificDistributedActorC5helloSSyYaKFTE) // TODO(distributed): remote - callTaskSelf: remote(_remote_impl_callTaskSelf()) - // CHECK: remote - callTaskSelf: remote($s4main28SomeSpecificDistributedActorC12callTaskSelfSSyYaFTE) + // CHECK: remote - callTaskSelf: remote($s4main28SomeSpecificDistributedActorC12callTaskSelfSSyYaKFTE) // TODO(distributed): remote - callDetachedSelf: remote(_remote_impl_callDetachedSelf()) - // CHECK: remote - callDetachedSelf: remote($s4main28SomeSpecificDistributedActorC16callDetachedSelfSSyYaFTE) + // CHECK: remote - callDetachedSelf: remote($s4main28SomeSpecificDistributedActorC16callDetachedSelfSSyYaKFTE) // CHECK: remote - helloThrowsTransportBoom: Boom(whoFailed: "system") print(local) diff --git a/test/Distributed/SIL/distributed_actor_remoteCall_sil.swift b/test/Distributed/SIL/distributed_actor_remoteCall_sil.swift deleted file mode 100644 index a1787d0330031..0000000000000 --- a/test/Distributed/SIL/distributed_actor_remoteCall_sil.swift +++ /dev/null @@ -1,108 +0,0 @@ -// RUN: %empty-directory(%t) -// RUN: %target-swift-frontend-emit-module -emit-module-path %t/FakeDistributedActorSystems.swiftmodule -module-name FakeDistributedActorSystems -disable-availability-checking %S/../Inputs/FakeDistributedActorSystems.swift -// RUN: %target-swift-frontend -module-name remoteCall -primary-file %s -emit-sil -enable-experimental-distributed -disable-availability-checking -I %t | %FileCheck %s --enable-var-scope --color -// REQUIRES: concurrency -// REQUIRES: distributed - -import _Distributed -import FakeDistributedActorSystems - -typealias DefaultDistributedActorSystem = FakeActorSystem - -distributed actor MyDistActor { - distributed func test() {} -} - -// TODO(distributed): very naive test, SIL for discussion and cleanup - -// MyDistActor.test() -// CHECK: sil hidden [thunk] [distributed] @$s10remoteCall11MyDistActorC4testyyFTE : $@convention(method) @async (@guaranteed MyDistActor) -> @error Error { -// CHECK: %0 "self" // users: %34, %28, %7, %41, %40, %1 -// CHECK: bb0(%0 : $MyDistActor): -// CHECK: %1 = init_existential_ref %0 : $MyDistActor : $MyDistActor, $AnyObject // user: %3 -// CHECK: // function_ref swift_distributed_actor_is_remote -// CHECK: %2 = function_ref @swift_distributed_actor_is_remote : $@convention(thin) (@guaranteed AnyObject) -> Bool // user: %3 -// CHECK: %3 = apply %2(%1) : $@convention(thin) (@guaranteed AnyObject) -> Bool // user: %4 -// CHECK: %4 = struct_extract %3 : $Bool, #Bool._value // user: %5 -// CHECK: cond_br %4, bb1, bb4 // id: %5 - -// CHECK: bb1: // Preds: bb0 -// CHECK: %6 = alloc_stack $FakeInvocationEncoder // users: %13, %63, %62, %55, %54, %38, %37, %14 -// CHECK: %7 = ref_element_addr %0 : $MyDistActor, #MyDistActor.actorSystem // user: %8 -// CHECK: %8 = load %7 : $*FakeActorSystem // users: %12, %11, %9 -// CHECK: retain_value %8 : $FakeActorSystem // id: %9 -// CHECK: // function_ref FakeActorSystem.makeInvocationEncoder() -// CHECK: %10 = function_ref @$s27FakeDistributedActorSystems0aC6SystemV21makeInvocationEncoderAA0agH0VyF : $@convention(method) (@guaranteed FakeActorSystem) -> @owned FakeInvocationEncoder // user: %11 -// CHECK: %11 = apply %10(%8) : $@convention(method) (@guaranteed FakeActorSystem) -> @owned FakeInvocationEncoder // user: %13 -// CHECK: release_value %8 : $FakeActorSystem // id: %12 -// CHECK: store %11 to %6 : $*FakeInvocationEncoder // id: %13 -// CHECK: %14 = begin_access [modify] [static] %6 : $*FakeInvocationEncoder // users: %58, %51, %34, %36, %16 -// CHECK: // function_ref FakeInvocationEncoder.doneRecording() -// CHECK: %15 = function_ref @$s27FakeDistributedActorSystems0A17InvocationEncoderV13doneRecordingyyKF : $@convention(method) (@inout FakeInvocationEncoder) -> @error Error // user: %16 -// CHECK: try_apply %15(%14) : $@convention(method) (@inout FakeInvocationEncoder) -> @error Error, normal bb2, error bb3 // id: %16 - -// CHECK: bb2(%17 : $()): // Preds: bb1 -// CHECK: %18 = alloc_stack $RemoteCallTarget // users: %61, %60, %53, %52, %34, %27 -// CHECK: %19 = metatype $@thin RemoteCallTarget.Type // user: %27 -// CHECK: %20 = string_literal utf8 "$s10remoteCall11MyDistActorC4testyyFTE" // user: %25 -// CHECK: %21 = integer_literal $Builtin.Word, 38 // user: %25 -// CHECK: %22 = integer_literal $Builtin.Int1, -1 // user: %25 -// CHECK: %23 = metatype $@thin String.Type // user: %25 -// CHECK: // function_ref String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:) -// CHECK: %24 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %25 -// CHECK: %25 = apply %24(%20, %21, %22, %23) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %27 -// CHECK: // function_ref RemoteCallTarget.init(_mangledName:) -// CHECK: %26 = function_ref @$s12_Distributed16RemoteCallTargetV12_mangledNameACSS_tcfC : $@convention(method) (@owned String, @thin RemoteCallTarget.Type) -> @out RemoteCallTarget // user: %27 -// CHECK: %27 = apply %26(%18, %25, %19) : $@convention(method) (@owned String, @thin RemoteCallTarget.Type) -> @out RemoteCallTarget -// CHECK: %28 = ref_element_addr %0 : $MyDistActor, #MyDistActor.actorSystem // user: %29 -// CHECK: %29 = load %28 : $*FakeActorSystem // users: %59, %50, %34, %30 -// CHECK: retain_value %29 : $FakeActorSystem // id: %30 -// CHECK: %31 = metatype $@thick Never.Type // user: %34 -// CHECK: %32 = metatype $@thick ().Type -// CHECK: // function_ref FakeActorSystem.remoteCallVoid(on:target:invocation:throwing:) -// CHECK: %33 = function_ref @$s27FakeDistributedActorSystems0aC6SystemV14remoteCallVoid2on6target10invocation8throwingyx_01_B006RemoteG6TargetVAA0A17InvocationEncoderVzq_mtYaKAI0bC0Rzs5ErrorR_AA0C7AddressV2IDRtzr0_lF : $@convention(method) @async <τ_0_0, τ_0_1 where τ_0_0 : DistributedActor, τ_0_1 : Error, τ_0_0.ID == ActorAddress> (@guaranteed τ_0_0, @in_guaranteed RemoteCallTarget, @inout FakeInvocationEncoder, @thick τ_0_1.Type, @guaranteed FakeActorSystem) -> @error Error // user: %34 -// CHECK: try_apply %33(%0, %18, %14, %31, %29) : $@convention(method) @async <τ_0_0, τ_0_1 where τ_0_0 : DistributedActor, τ_0_1 : Error, τ_0_0.ID == ActorAddress> (@guaranteed τ_0_0, @in_guaranteed RemoteCallTarget, @inout FakeInvocationEncoder, @thick τ_0_1.Type, @guaranteed FakeActorSystem) -> @error Error, normal bb8, error bb9 // id: %34 - -// CHECK: // %35 // user: %39 -// CHECK: bb3(%35 : $Error): // Preds: bb1 -// CHECK: end_access %14 : $*FakeInvocationEncoder // id: %36 -// CHECK: destroy_addr %6 : $*FakeInvocationEncoder // id: %37 -// CHECK: dealloc_stack %6 : $*FakeInvocationEncoder // id: %38 -// CHECK: br bb7(%35 : $Error) // id: %39 - -// CHECK: bb4: // Preds: bb0 -// CHECK: %40 = class_method %0 : $MyDistActor, #MyDistActor.test : (isolated MyDistActor) -> () -> (), $@convention(method) (@guaranteed MyDistActor) -> () // user: %41 -// CHECK: %41 = apply %40(%0) : $@convention(method) (@guaranteed MyDistActor) -> () // user: %43 -// CHECK: br bb5 // id: %42 - -// CHECK: bb5: // Preds: bb4 -// CHECK: br bb6(%41 : $()) // id: %43 - -// CHECK: // %44 // user: %45 -// CHECK: bb6(%44 : $()): // Preds: bb8 bb5 -// CHECK: return %44 : $() // id: %45 - -// CHECK: // %46 // user: %47 -// CHECK: bb7(%46 : $Error): // Preds: bb9 bb3 -// CHECK: throw %46 : $Error // id: %47 - -// CHECK: bb8(%48 : $()): // Preds: bb2 -// CHECK: %49 = tuple () // user: %56 -// CHECK: release_value %29 : $FakeActorSystem // id: %50 -// CHECK: end_access %14 : $*FakeInvocationEncoder // id: %51 -// CHECK: destroy_addr %18 : $*RemoteCallTarget // id: %52 -// CHECK: dealloc_stack %18 : $*RemoteCallTarget // id: %53 -// CHECK: destroy_addr %6 : $*FakeInvocationEncoder // id: %54 -// CHECK: dealloc_stack %6 : $*FakeInvocationEncoder // id: %55 -// CHECK: br bb6(%49 : $()) // id: %56 - -// CHECK: // %57 // user: %64 -// CHECK: bb9(%57 : $Error): // Preds: bb2 -// CHECK: end_access %14 : $*FakeInvocationEncoder // id: %58 -// CHECK: release_value %29 : $FakeActorSystem // id: %59 -// CHECK: destroy_addr %18 : $*RemoteCallTarget // id: %60 -// CHECK: dealloc_stack %18 : $*RemoteCallTarget // id: %61 -// CHECK: destroy_addr %6 : $*FakeInvocationEncoder // id: %62 -// CHECK: dealloc_stack %6 : $*FakeInvocationEncoder // id: %63 -// CHECK: br bb7(%57 : $Error) // id: %64 -// CHECK: } // end sil function '$s10remoteCall11MyDistActorC4testyyFTE' diff --git a/test/Distributed/actor_protocols.swift b/test/Distributed/actor_protocols.swift index 82ee2fa261405..f0afbbc8b473e 100644 --- a/test/Distributed/actor_protocols.swift +++ b/test/Distributed/actor_protocols.swift @@ -22,14 +22,16 @@ class C: Actor, UnsafeSendable { } struct S: Actor { - // expected-error@-1{{non-class type 'S' cannot conform to class protocol 'Actor'}} + // expected-error@-1{{non-class type 'S' cannot conform to class protocol 'AnyActor'}} + // expected-error@-2{{non-class type 'S' cannot conform to class protocol 'Actor'}} nonisolated var unownedExecutor: UnownedSerialExecutor { fatalError() } } struct E: Actor { - // expected-error@-1{{non-class type 'E' cannot conform to class protocol 'Actor'}} + // expected-error@-1{{non-class type 'E' cannot conform to class protocol 'AnyActor'}} + // expected-error@-2{{non-class type 'E' cannot conform to class protocol 'Actor'}} nonisolated var unownedExecutor: UnownedSerialExecutor { fatalError() } diff --git a/test/Distributed/distributed_actor_accessor_section_coff.swift b/test/Distributed/distributed_actor_accessor_section_coff.swift index 2b3de9d20476d..c438ba1844a02 100644 --- a/test/Distributed/distributed_actor_accessor_section_coff.swift +++ b/test/Distributed/distributed_actor_accessor_section_coff.swift @@ -88,53 +88,53 @@ public distributed actor MyOtherActor { /// ---> Let's check that distributed accessors and thunks are emitted as accessible functions /// -> `MyActor.simple1` -// CHECK: @"$s27distributed_actor_accessors7MyActorC7simple1yySiFTEHF" = private constant +// CHECK: @"$s27distributed_actor_accessors7MyActorC7simple1yySiYaKFTEHF" = private constant // CHECK-SAME: @"symbolic Si___________pIetMHygzo_ 27distributed_actor_accessors7MyActorC s5ErrorP" -// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple1yySiFTETFTu" to i64) +// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple1yySiYaKFTETFTu" to i{{32|64}}) // CHECK-SAME: , section ".sw5acfn$B", {{.*}} /// -> `MyActor.simple2` -// CHECK: @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiFTEHF" = private constant +// CHECK: @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiYaKFTEHF" = private constant // CHECK-SAME: @"symbolic Si_____SS______pIetMHygozo_ 27distributed_actor_accessors7MyActorC s5ErrorP" -// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiFTETFTu" to i64 +// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiYaKFTETFTu" to i{{32|64}}) // CHECK-SAME: , section ".sw5acfn$B", {{.*}} /// -> `MyActor.simple3` -// CHECK: @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSFTEHF" = private constant +// CHECK: @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSYaKFTEHF" = private constant // CHECK-SAME: @"symbolic SS_____Si______pIetMHggdzo_ 27distributed_actor_accessors7MyActorC s5ErrorP" -// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSFTETFTu" to i64) +// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSYaKFTETFTu" to i{{32|64}}) // CHECK-SAME: , section ".sw5acfn$B", {{.*}} /// -> `MyActor.single_case_enum` -// CHECK: @"$s27distributed_actor_accessors7MyActorC16single_case_enumyAA7SimpleEOAFFTEHF" = private constant +// CHECK: @"$s27distributed_actor_accessors7MyActorC16single_case_enumyAA7SimpleEOAFYaKFTEHF" = private constant // CHECK-SAME: @"symbolic __________AA______pIetMHygdzo_ 27distributed_actor_accessors7SimpleEO AA7MyActorC s5ErrorP" -// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC16single_case_enumyAA7SimpleEOAFFTETFTu" to i64) +// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC16single_case_enumyAA7SimpleEOAFYaKFTETFTu" to i{{32|64}}) // CHECK-SAME: , section ".sw5acfn$B", {{.*}} /// -> `MyActor.with_indirect_enums` -// CHECK: @"$s27distributed_actor_accessors7MyActorC19with_indirect_enumsyAA9IndirectEOAF_SitFTEHF" = private constant +// CHECK: @"$s27distributed_actor_accessors7MyActorC19with_indirect_enumsyAA9IndirectEOAF_SitYaKFTEHF" = private constant // CHECK-SAME: @"symbolic _____Si_____AA______pIetMHgygozo_ 27distributed_actor_accessors9IndirectEO AA7MyActorC s5ErrorP" -// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC19with_indirect_enumsyAA9IndirectEOAF_SitFTETFTu" to i64 +// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC19with_indirect_enumsyAA9IndirectEOAF_SitYaKFTETFTu" to i{{32|64}}) // CHECK-SAME: , section ".sw5acfn$B", {{.*}} /// -> `MyActor.complex` -// CHECK: @"$s27distributed_actor_accessors7MyActorC7complexyAA11LargeStructVSaySiG_AA3ObjCSSSgAFtFTEHF" = private constant +// CHECK: @"$s27distributed_actor_accessors7MyActorC7complexyAA11LargeStructVSaySiG_AA3ObjCSSSgAFtYaKFTEHF" = private constant // CHECK-SAME: @"symbolic SaySiG_____SSSg__________AD______pIetMHgggngrzo_ 27distributed_actor_accessors3ObjC AA11LargeStructV AA7MyActorC s5ErrorP" -// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7complexyAA11LargeStructVSaySiG_AA3ObjCSSSgAFtFTETFTu" to i64) +// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7complexyAA11LargeStructVSaySiG_AA3ObjCSSSgAFtYaKFTETFTu" to i{{32|64}}) // CHECK-SAME: , section ".sw5acfn$B", {{.*}} /// -> `MyOtherActor.empty` -// CHECK: @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyFTEHF" = private constant +// CHECK: @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyYaKFTEHF" = private constant // CHECK-SAME: @"symbolic ___________pIetMHgzo_ 27distributed_actor_accessors12MyOtherActorC s5ErrorP" -// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyFTETFTu" to i64) +// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyYaKFTETFTu" to i{{32|64}}) // CHECK-SAME: , section ".sw5acfn$B", {{.*}} // CHECK: @llvm.used = appending global [{{.*}} x i8*] [ -// CHECK-SAME: @"$s27distributed_actor_accessors7MyActorC7simple1yySiFTEHF" -// CHECK-SAME: @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiFTEHF" -// CHECK-SAME: @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSFTEHF" -// CHECK-SAME: @"$s27distributed_actor_accessors7MyActorC16single_case_enumyAA7SimpleEOAFFTEHF" -// CHECK-SAME: @"$s27distributed_actor_accessors7MyActorC19with_indirect_enumsyAA9IndirectEOAF_SitFTEHF" -// CHECK-SAME: @"$s27distributed_actor_accessors7MyActorC7complexyAA11LargeStructVSaySiG_AA3ObjCSSSgAFtFTEHF" -// CHECK-SAME: @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyFTEHF" +// CHECK-SAME: @"$s27distributed_actor_accessors7MyActorC7simple1yySiYaKFTEHF" +// CHECK-SAME: @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiYaKFTEHF" +// CHECK-SAME: @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSYaKFTEHF" +// CHECK-SAME: @"$s27distributed_actor_accessors7MyActorC16single_case_enumyAA7SimpleEOAFYaKFTEHF" +// CHECK-SAME: @"$s27distributed_actor_accessors7MyActorC19with_indirect_enumsyAA9IndirectEOAF_SitYaKFTEHF" +// CHECK-SAME: @"$s27distributed_actor_accessors7MyActorC7complexyAA11LargeStructVSaySiG_AA3ObjCSSSgAFtYaKFTEHF" +// CHECK-SAME: @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyYaKFTEHF" // CHECK-SAME: ], section "llvm.metadata" diff --git a/test/Distributed/distributed_actor_accessor_section_elf.swift b/test/Distributed/distributed_actor_accessor_section_elf.swift index 0fae7da3bdc27..f6b0a61bb0fa2 100644 --- a/test/Distributed/distributed_actor_accessor_section_elf.swift +++ b/test/Distributed/distributed_actor_accessor_section_elf.swift @@ -86,53 +86,53 @@ public distributed actor MyOtherActor { /// ---> Let's check that distributed accessors and thunks are emitted as accessible functions /// -> `MyActor.simple1` -// CHECK: @"$s27distributed_actor_accessors7MyActorC7simple1yySiFTEHF" = private constant +// CHECK: @"$s27distributed_actor_accessors7MyActorC7simple1yySiYaKFTEHF" = private constant // CHECK-SAME: @"symbolic Si___________pIetMHygzo_ 27distributed_actor_accessors7MyActorC s5ErrorP" -// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple1yySiFTETFTu" to i64) +// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple1yySiYaKFTETFTu" to i{{32|64}}) // CHECK-SAME: , section "swift5_accessible_functions", {{.*}} /// -> `MyActor.simple2` -// CHECK: @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiFTEHF" = private constant +// CHECK: @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiYaKFTEHF" = private constant // CHECK-SAME: @"symbolic Si_____SS______pIetMHygozo_ 27distributed_actor_accessors7MyActorC s5ErrorP" -// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiFTETFTu" to i64) +// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiYaKFTETFTu" to i{{32|64}}) // CHECK-SAME: , section "swift5_accessible_functions", {{.*}} /// -> `MyActor.simple3` -// CHECK: @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSFTEHF" = private constant +// CHECK: @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSYaKFTEHF" = private constant // CHECK-SAME: @"symbolic SS_____Si______pIetMHggdzo_ 27distributed_actor_accessors7MyActorC s5ErrorP" -// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSFTETFTu" to i64) +// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSYaKFTETFTu" to i{{32|64}}) // CHECK-SAME: , section "swift5_accessible_functions", {{.*}} /// -> `MyActor.single_case_enum` -// CHECK: @"$s27distributed_actor_accessors7MyActorC16single_case_enumyAA7SimpleEOAFFTEHF" = private constant +// CHECK: @"$s27distributed_actor_accessors7MyActorC16single_case_enumyAA7SimpleEOAFYaKFTEHF" = private constant // CHECK-SAME: @"symbolic __________AA______pIetMHygdzo_ 27distributed_actor_accessors7SimpleEO AA7MyActorC s5ErrorP" -// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC16single_case_enumyAA7SimpleEOAFFTETFTu" to i64) +// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC16single_case_enumyAA7SimpleEOAFYaKFTETFTu" to i{{32|64}}) // CHECK-SAME: , section "swift5_accessible_functions", {{.*}} /// -> `MyActor.with_indirect_enums` -// CHECK: @"$s27distributed_actor_accessors7MyActorC19with_indirect_enumsyAA9IndirectEOAF_SitFTEHF" = private constant +// CHECK: @"$s27distributed_actor_accessors7MyActorC19with_indirect_enumsyAA9IndirectEOAF_SitYaKFTEHF" = private constant // CHECK-SAME: @"symbolic _____Si_____AA______pIetMHgygozo_ 27distributed_actor_accessors9IndirectEO AA7MyActorC s5ErrorP" -// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC19with_indirect_enumsyAA9IndirectEOAF_SitFTETFTu" to i64) +// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC19with_indirect_enumsyAA9IndirectEOAF_SitYaKFTETFTu" to i{{32|64}}) // CHECK-SAME: , section "swift5_accessible_functions", {{.*}} /// -> `MyActor.complex` -// CHECK: @"$s27distributed_actor_accessors7MyActorC7complexyAA11LargeStructVSaySiG_AA3ObjCSSSgAFtFTEHF" = private constant +// CHECK: @"$s27distributed_actor_accessors7MyActorC7complexyAA11LargeStructVSaySiG_AA3ObjCSSSgAFtYaKFTEHF" = private constant // CHECK-SAME: @"symbolic SaySiG_____SSSg__________AD______pIetMHgggngrzo_ 27distributed_actor_accessors3ObjC AA11LargeStructV AA7MyActorC s5ErrorP" -// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7complexyAA11LargeStructVSaySiG_AA3ObjCSSSgAFtFTETFTu" to i64) +// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7complexyAA11LargeStructVSaySiG_AA3ObjCSSSgAFtYaKFTETFTu" to i{{32|64}}) // CHECK-SAME: , section "swift5_accessible_functions", {{.*}} /// -> `MyOtherActor.empty` -// CHECK: @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyFTEHF" = private constant +// CHECK: @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyYaKFTEHF" = private constant // CHECK-SAME: @"symbolic ___________pIetMHgzo_ 27distributed_actor_accessors12MyOtherActorC s5ErrorP" -// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyFTETFTu" to i64) +// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyYaKFTETFTu" to i{{32|64}}) // CHECK-SAME: , section "swift5_accessible_functions", {{.*}} // CHECK: @llvm.compiler.used = appending global [{{.*}} x i8*] [ -// CHECK-SAME: @"$s27distributed_actor_accessors7MyActorC7simple1yySiFTEHF" -// CHECK-SAME: @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiFTEHF" -// CHECK-SAME: @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSFTEHF" -// CHECK-SAME: @"$s27distributed_actor_accessors7MyActorC16single_case_enumyAA7SimpleEOAFFTEHF" -// CHECK-SAME: @"$s27distributed_actor_accessors7MyActorC19with_indirect_enumsyAA9IndirectEOAF_SitFTEHF" -// CHECK-SAME: @"$s27distributed_actor_accessors7MyActorC7complexyAA11LargeStructVSaySiG_AA3ObjCSSSgAFtFTEHF" -// CHECK-SAME: @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyFTEHF" +// CHECK-SAME: @"$s27distributed_actor_accessors7MyActorC7simple1yySiYaKFTEHF" +// CHECK-SAME: @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiYaKFTEHF" +// CHECK-SAME: @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSYaKFTEHF" +// CHECK-SAME: @"$s27distributed_actor_accessors7MyActorC16single_case_enumyAA7SimpleEOAFYaKFTEHF" +// CHECK-SAME: @"$s27distributed_actor_accessors7MyActorC19with_indirect_enumsyAA9IndirectEOAF_SitYaKFTEHF" +// CHECK-SAME: @"$s27distributed_actor_accessors7MyActorC7complexyAA11LargeStructVSaySiG_AA3ObjCSSSgAFtYaKFTEHF" +// CHECK-SAME: @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyYaKFTEHF" // CHECK-SAME: ], section "llvm.metadata" diff --git a/test/Distributed/distributed_actor_accessor_section_macho.swift b/test/Distributed/distributed_actor_accessor_section_macho.swift index 159d168566438..bb455978ac489 100644 --- a/test/Distributed/distributed_actor_accessor_section_macho.swift +++ b/test/Distributed/distributed_actor_accessor_section_macho.swift @@ -11,7 +11,7 @@ import _Distributed import FakeDistributedActorSystems -@available(SwiftStdlib 5.5, *) +@available(SwiftStdlib 5.7, *) typealias DefaultDistributedActorSystem = FakeActorSystem enum SimpleE : Codable { @@ -86,53 +86,53 @@ public distributed actor MyOtherActor { /// ---> Let's check that distributed accessors and thunks are emitted as accessible functions /// -> `MyActor.simple1` -// CHECK: @"$s27distributed_actor_accessors7MyActorC7simple1yySiFTEHF" = private constant +// CHECK: @"$s27distributed_actor_accessors7MyActorC7simple1yySiYaKFTEHF" = private constant // CHECK-SAME: @"symbolic Si___________pIetMHygzo_ 27distributed_actor_accessors7MyActorC s5ErrorP" -// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple1yySiFTETFTu" to i{{32|64}}) +// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple1yySiYaKFTETFTu" to i{{32|64}}) // CHECK-SAME: , section {{"swift5_accessible_functions"|".sw5acfn$B"|"__TEXT, __swift5_acfuncs, regular"}} /// -> `MyActor.simple2` -// CHECK: @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiFTEHF" = private constant +// CHECK: @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiYaKFTEHF" = private constant // CHECK-SAME: @"symbolic Si_____SS______pIetMHygozo_ 27distributed_actor_accessors7MyActorC s5ErrorP" -// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiFTETFTu" to i{{32|64}}) +// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiYaKFTETFTu" to i{{32|64}}) // CHECK-SAME: , section {{"swift5_accessible_functions"|".sw5acfn$B"|"__TEXT, __swift5_acfuncs, regular"}} /// -> `MyActor.simple3` -// CHECK: @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSFTEHF" = private constant +// CHECK: @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSYaKFTEHF" = private constant // CHECK-SAME: @"symbolic SS_____Si______pIetMHggdzo_ 27distributed_actor_accessors7MyActorC s5ErrorP" -// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSFTETFTu" to i{{32|64}}) +// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSYaKFTETFTu" to i{{32|64}}) // CHECK-SAME: , section {{"swift5_accessible_functions"|".sw5acfn$B"|"__TEXT, __swift5_acfuncs, regular"}} /// -> `MyActor.single_case_enum` -// CHECK: @"$s27distributed_actor_accessors7MyActorC16single_case_enumyAA7SimpleEOAFFTEHF" = private constant +// CHECK: @"$s27distributed_actor_accessors7MyActorC16single_case_enumyAA7SimpleEOAFYaKFTEHF" = private constant // CHECK-SAME: @"symbolic __________AA______pIetMHygdzo_ 27distributed_actor_accessors7SimpleEO AA7MyActorC s5ErrorP" -// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC16single_case_enumyAA7SimpleEOAFFTETFTu" to i{{32|64}}) +// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC16single_case_enumyAA7SimpleEOAFYaKFTETFTu" to i{{32|64}}) // CHECK-SAME: , section {{"swift5_accessible_functions"|".sw5acfn$B"|"__TEXT, __swift5_acfuncs, regular"}} /// -> `MyActor.with_indirect_enums` -// CHECK: @"$s27distributed_actor_accessors7MyActorC19with_indirect_enumsyAA9IndirectEOAF_SitFTEHF" = private constant +// CHECK: @"$s27distributed_actor_accessors7MyActorC19with_indirect_enumsyAA9IndirectEOAF_SitYaKFTEHF" = private constant // CHECK-SAME: @"symbolic _____Si_____AA______pIetMHgygozo_ 27distributed_actor_accessors9IndirectEO AA7MyActorC s5ErrorP" -// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC19with_indirect_enumsyAA9IndirectEOAF_SitFTETFTu" to i{{32|64}}) +// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC19with_indirect_enumsyAA9IndirectEOAF_SitYaKFTETFTu" to i{{32|64}}) // CHECK-SAME: , section {{"swift5_accessible_functions"|".sw5acfn$B"|"__TEXT, __swift5_acfuncs, regular"}} /// -> `MyActor.complex` -// CHECK: @"$s27distributed_actor_accessors7MyActorC7complexyAA11LargeStructVSaySiG_AA3ObjCSSSgAFtFTEHF" = private constant +// CHECK: @"$s27distributed_actor_accessors7MyActorC7complexyAA11LargeStructVSaySiG_AA3ObjCSSSgAFtYaKFTEHF" = private constant // CHECK-SAME: @"symbolic SaySiG_____SSSg__________AD______pIetMHgggngrzo_ 27distributed_actor_accessors3ObjC AA11LargeStructV AA7MyActorC s5ErrorP" -// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7complexyAA11LargeStructVSaySiG_AA3ObjCSSSgAFtFTETFTu" to i{{32|64}}) +// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7complexyAA11LargeStructVSaySiG_AA3ObjCSSSgAFtYaKFTETFTu" to i{{32|64}}) // CHECK-SAME: , section {{"swift5_accessible_functions"|".sw5acfn$B"|"__TEXT, __swift5_acfuncs, regular"}} /// -> `MyOtherActor.empty` -// CHECK: @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyFTEHF" = private constant +// CHECK: @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyYaKFTEHF" = private constant // CHECK-SAME: @"symbolic ___________pIetMHgzo_ 27distributed_actor_accessors12MyOtherActorC s5ErrorP" -// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyFTETFTu" to i{{32|64}}) +// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyYaKFTETFTu" to i{{32|64}}) // CHECK-SAME: , section {{"swift5_accessible_functions"|".sw5acfn$B"|"__TEXT, __swift5_acfuncs, regular"}} // CHECK: @llvm.used = appending global [{{.*}} x i8*] [ -// CHECK-SAME: @"$s27distributed_actor_accessors7MyActorC7simple1yySiFTEHF" -// CHECK-SAME: @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiFTEHF" -// CHECK-SAME: @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSFTEHF" -// CHECK-SAME: @"$s27distributed_actor_accessors7MyActorC16single_case_enumyAA7SimpleEOAFFTEHF" -// CHECK-SAME: @"$s27distributed_actor_accessors7MyActorC19with_indirect_enumsyAA9IndirectEOAF_SitFTEHF" -// CHECK-SAME: @"$s27distributed_actor_accessors7MyActorC7complexyAA11LargeStructVSaySiG_AA3ObjCSSSgAFtFTEHF" -// CHECK-SAME: @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyFTEHF" +// CHECK-SAME: @"$s27distributed_actor_accessors7MyActorC7simple1yySiYaKFTEHF" +// CHECK-SAME: @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiYaKFTEHF" +// CHECK-SAME: @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSYaKFTEHF" +// CHECK-SAME: @"$s27distributed_actor_accessors7MyActorC16single_case_enumyAA7SimpleEOAFYaKFTEHF" +// CHECK-SAME: @"$s27distributed_actor_accessors7MyActorC19with_indirect_enumsyAA9IndirectEOAF_SitYaKFTEHF" +// CHECK-SAME: @"$s27distributed_actor_accessors7MyActorC7complexyAA11LargeStructVSaySiG_AA3ObjCSSSgAFtYaKFTEHF" +// CHECK-SAME: @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyYaKFTEHF" // CHECK-SAME: ], section "llvm.metadata" diff --git a/test/Distributed/distributed_actor_accessor_thunks_32bit.swift b/test/Distributed/distributed_actor_accessor_thunks_32bit.swift index adeb2afd4ef39..2fe53d78cbbb6 100644 --- a/test/Distributed/distributed_actor_accessor_thunks_32bit.swift +++ b/test/Distributed/distributed_actor_accessor_thunks_32bit.swift @@ -8,6 +8,8 @@ // REQUIRES: CPU=i386 +// UNSUPPORTED: OS=windows-msvc + import _Distributed import FakeDistributedActorSystems @@ -90,9 +92,9 @@ public distributed actor MyOtherActor { /// Let's make sure that accessor loads the data from the buffer and calls expected accessor -// CHECK: define hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7simple1yySiFTE" +// CHECK: define hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7simple1yySiYaKFTE" -// CHECK: define internal swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7simple1yySiFTETF"(%swift.context* swiftasync %0, %swift.opaque* nocapture %1, i8* %2, i8* %3, {{.*}}, %T27distributed_actor_accessors7MyActorC* [[ACTOR:%.*]], %swift.type* [[DECODER_TYPE:%.*]], i8** [[DECODER_PROTOCOL_WITNESS:%.*]]) +// CHECK: define internal swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7simple1yySiYaKFTETF"(%swift.context* swiftasync %0, %swift.opaque* nocapture %1, i8* %2, i8* %3, {{.*}}, %T27distributed_actor_accessors7MyActorC* [[ACTOR:%.*]], %swift.type* [[DECODER_TYPE:%.*]], i8** [[DECODER_PROTOCOL_WITNESS:%.*]]) /// Read the current offset and cast an element to `Int` @@ -133,9 +135,9 @@ public distributed actor MyOtherActor { /// Setup task context for async call to `simple1` thunk -// CHECK-DIRECT: [[CONTEXT_SIZE:%.*]] = load i32, i32* getelementptr inbounds (%swift.async_func_pointer, %swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple1yySiFTETu", i32 0, i32 1) -// CHECK-INDIRECT: [[ADDR:%[0-9]+]] = load %swift.async_func_pointer*, %swift.async_func_pointer** inttoptr (i64 and (i64 ptrtoint (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple1yySiFTETu" to i64), i64 -2) to %swift.async_func_pointer**), align 8 -// CHECK-INDIRECT-NEXT: [[SELECT:%[0-9]+]] = select i1 true, %swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple1yySiFTETu", %swift.async_func_pointer* [[ADDR]] +// CHECK-DIRECT: [[CONTEXT_SIZE:%.*]] = load i32, i32* getelementptr inbounds (%swift.async_func_pointer, %swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple1yySiYaKFTETu", i32 0, i32 1) +// CHECK-INDIRECT: [[ADDR:%[0-9]+]] = load %swift.async_func_pointer*, %swift.async_func_pointer** inttoptr (i64 and (i64 ptrtoint (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple1yySiYaKFTETu" to i64), i64 -2) to %swift.async_func_pointer**), align 8 +// CHECK-INDIRECT-NEXT: [[SELECT:%[0-9]+]] = select i1 true, %swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple1yySiYaKFTETu", %swift.async_func_pointer* [[ADDR]] // CHECK-INDIRECT-NEXT: [[LOAD:%[0-9]+]] = getelementptr inbounds %swift.async_func_pointer, %swift.async_func_pointer* [[SELECT]], i32 0, i32 1 // CHECK-INDIRECT-NEXT: [[CONTEXT_SIZE:%.*]] = load i32, i32* [[LOAD]] // CHECK-NEXT: [[THUNK_ASYNC_CONTEXT:%.*]] = call swiftcc i8* @swift_task_alloc(i32 [[CONTEXT_SIZE]]) @@ -144,7 +146,7 @@ public distributed actor MyOtherActor { /// Call distributed thunk for `simple1` and `end` async context without results // CHECK: [[THUNK_RESULT:%.*]] = call { i8*, %swift.error* } (i32, i8*, i8*, ...) @llvm.coro.suspend.async.sl_p0i8p0s_swift.errorss( -// CHECK-SAME: i8* bitcast (void (%swift.context*, i32, %T27distributed_actor_accessors7MyActorC*)* @"$s27distributed_actor_accessors7MyActorC7simple1yySiFTE" to i8*) +// CHECK-SAME: i8* bitcast (void (%swift.context*, i32, %T27distributed_actor_accessors7MyActorC*)* @"$s27distributed_actor_accessors7MyActorC7simple1yySiYaKFTE" to i8*) // CHECK-SAME: %swift.context* [[THUNK_CONTEXT_PTR]], // CHECK-SAME: i32 [[ARG_VAL]], // CHECK-SAME: %T27distributed_actor_accessors7MyActorC* [[ACTOR]]) @@ -155,9 +157,9 @@ public distributed actor MyOtherActor { /// ---> Thunk and distributed method accessor for `simple2` -// CHECK: define hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiFTE" +// CHECK: define hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiYaKFTE" -// CHECK: define internal swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiFTETF" +// CHECK: define internal swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiYaKFTETF" // CHECK: [[COERCED_RESULT_SLOT:%.*]] = bitcast i8* {{.*}} to %TSS* @@ -166,9 +168,9 @@ public distributed actor MyOtherActor { /// Setup task context for async call to `simple2` thunk -// CHECK-DIRECT: [[CONTEXT_SIZE:%.*]] = load i32, i32* getelementptr inbounds (%swift.async_func_pointer, %swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiFTETu", i32 0, i32 1) -// CHECK-INDIRECT: [[ADDR:%[0-9]+]] = load %swift.async_func_pointer*, %swift.async_func_pointer** inttoptr (i64 and (i64 ptrtoint (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiFTETu" to i64), i64 -2) to %swift.async_func_pointer**), align 8 -// CHECK-INDIRECT-NEXT: [[SELECT:%[0-9]+]] = select i1 true, %swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiFTETu", %swift.async_func_pointer* [[ADDR]] +// CHECK-DIRECT: [[CONTEXT_SIZE:%.*]] = load i32, i32* getelementptr inbounds (%swift.async_func_pointer, %swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiYaKFTETu", i32 0, i32 1) +// CHECK-INDIRECT: [[ADDR:%[0-9]+]] = load %swift.async_func_pointer*, %swift.async_func_pointer** inttoptr (i64 and (i64 ptrtoint (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiYaKFTETu" to i64), i64 -2) to %swift.async_func_pointer**), align 8 +// CHECK-INDIRECT-NEXT: [[SELECT:%[0-9]+]] = select i1 true, %swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiYaKFTETu", %swift.async_func_pointer* [[ADDR]] // CHECK-INDIRECT-NEXT: [[LOAD:%[0-9]+]] = getelementptr inbounds %swift.async_func_pointer, %swift.async_func_pointer* [[SELECT]], i32 0, i32 1 // CHECK-INDIRECT-NEXT: [[CONTEXT_SIZE:%.*]] = load i32, i32* [[LOAD]] // CHECK-NEXT: [[THUNK_ASYNC_CONTEXT:%.*]] = call swiftcc i8* @swift_task_alloc(i32 [[CONTEXT_SIZE]]) @@ -177,7 +179,7 @@ public distributed actor MyOtherActor { /// Call the thunk with extracted argument value // CHECK: [[THUNK_RESULT:%.*]] = call { i8*, i32, i32, i32, %swift.error* } (i32, i8*, i8*, ...) @llvm.coro.suspend.async.sl_p0i8i32i32i32p0s_swift.errorss( -// CHECK-SAME: i8* bitcast (void (%swift.context*, i32, %T27distributed_actor_accessors7MyActorC*)* @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiFTE" to i8*) +// CHECK-SAME: i8* bitcast (void (%swift.context*, i32, %T27distributed_actor_accessors7MyActorC*)* @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiYaKFTE" to i8*) // CHECK-SAME: %swift.context* [[THUNK_CONTEXT_PTR]], // CHECK-SAME: i32 [[NATIVE_ARG_VAL]], // CHECK-SAME: %T27distributed_actor_accessors7MyActorC* [[ACTOR]]) @@ -196,10 +198,10 @@ public distributed actor MyOtherActor { /// ---> Thunk and distributed method accessor for `simple3` -// CHECK: define hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSFTE" +// CHECK: define hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSYaKFTE" /// !!! in `simple3` interesting bits are: argument value extraction (because string is exploded into N arguments) and call to distributed thunk -// CHECK: define internal swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSFTETF"(%swift.context* swiftasync %0, %swift.opaque* nocapture [[ARG_DECODER:%.*]], i8* [[ARG_TYPES:%.*]], i8* [[RESULT_BUFF:%.*]], i8* [[SUBS:%.*]], i8* [[WITNESS_TABLES:%.*]], i32 [[NUM_WITNESS_TABLES:%.*]], %T27distributed_actor_accessors7MyActorC* [[ACTOR]], %swift.type* [[DECODER_TYPE:%.*]], i8** [[DECODER_PROTOCOL_WITNESS:%.*]]) +// CHECK: define internal swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSYaKFTETF"(%swift.context* swiftasync %0, %swift.opaque* nocapture [[ARG_DECODER:%.*]], i8* [[ARG_TYPES:%.*]], i8* [[RESULT_BUFF:%.*]], i8* [[SUBS:%.*]], i8* [[WITNESS_TABLES:%.*]], i32 [[NUM_WITNESS_TABLES:%.*]], %T27distributed_actor_accessors7MyActorC* [[ACTOR]], %swift.type* [[DECODER_TYPE:%.*]], i8** [[DECODER_PROTOCOL_WITNESS:%.*]]) // CHECK: [[TYPED_RESULT_BUFF:%.*]] = bitcast i8* [[RESULT_BUFF]] to %TSi* @@ -216,9 +218,9 @@ public distributed actor MyOtherActor { /// Setup task context for async call to `simple3` thunk -// CHECK-DIRECT: [[CONTEXT_SIZE:%.*]] = load i32, i32* getelementptr inbounds (%swift.async_func_pointer, %swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSFTETu", i32 0, i32 1) -// CHECK-INDIRECT: [[ADDR:%[0-9]+]] = load %swift.async_func_pointer*, %swift.async_func_pointer** inttoptr (i64 and (i64 ptrtoint (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSFTETu" to i64), i64 -2) to %swift.async_func_pointer**), align 8 -// CHECK-INDIRECT-NEXT: [[SELECT:%[0-9]+]] = select i1 true, %swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSFTETu", %swift.async_func_pointer* [[ADDR]] +// CHECK-DIRECT: [[CONTEXT_SIZE:%.*]] = load i32, i32* getelementptr inbounds (%swift.async_func_pointer, %swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSYaKFTETu", i32 0, i32 1) +// CHECK-INDIRECT: [[ADDR:%[0-9]+]] = load %swift.async_func_pointer*, %swift.async_func_pointer** inttoptr (i64 and (i64 ptrtoint (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSYaKFTETu" to i64), i64 -2) to %swift.async_func_pointer**), align 8 +// CHECK-INDIRECT-NEXT: [[SELECT:%[0-9]+]] = select i1 true, %swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSYaKFTETu", %swift.async_func_pointer* [[ADDR]] // CHECK-INDIRECT-NEXT: [[LOAD:%[0-9]+]] = getelementptr inbounds %swift.async_func_pointer, %swift.async_func_pointer* [[SELECT]], i32 0, i32 1 // CHECK-INDIRECT-NEXT: [[CONTEXT_SIZE:%.*]] = load i32, i32* [[LOAD]] // CHECK-NEXT: [[THUNK_ASYNC_CONTEXT:%.*]] = call swiftcc i8* @swift_task_alloc(i32 [[CONTEXT_SIZE]]) @@ -244,7 +246,7 @@ public distributed actor MyOtherActor { // CHECK: [[THUNK_CONTEXT_PTR:%.*]] = bitcast i8* [[THUNK_ASYNC_CONTEXT]] to %swift.context* // CHECK: [[THUNK_RESULT:%.*]] = call { i8*, i32, %swift.error* } (i32, i8*, i8*, ...) @llvm.coro.suspend.async.sl_p0i8i32p0s_swift.errorss( -// CHECK-SAME: i8* bitcast (void (%swift.context*, i32, i32, i32, %T27distributed_actor_accessors7MyActorC*)* @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSFTE" to i8*), +// CHECK-SAME: i8* bitcast (void (%swift.context*, i32, i32, i32, %T27distributed_actor_accessors7MyActorC*)* @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSYaKFTE" to i8*), // CHECK-SAME: %swift.context* [[THUNK_CONTEXT_PTR]], // CHECK-SAME: i32 [[STR_ARG_SIZE]], // CHECK-SAME: i32 [[STR_ARG_VAL]], @@ -260,9 +262,9 @@ public distributed actor MyOtherActor { /// --> Thunk and distributed method accessor for `single_case_enum` -// CHECK: define hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC16single_case_enumyAA7SimpleEOAFFTE" +// CHECK: define hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC16single_case_enumyAA7SimpleEOAFYaKFTE" -// CHECK: define internal swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC16single_case_enumyAA7SimpleEOAFFTETF"(%swift.context* swiftasync %0, %swift.opaque* nocapture [[ARG_DECODER:%.*]], i8* [[ARG_TYPES:%.*]], i8* [[RESULT_BUFF:%.*]], i8* [[SUBS:%.*]], i8* [[WITNESS_TABLES:%.*]], i32 [[NUM_WITNESS_TABLES:%.*]], %T27distributed_actor_accessors7MyActorC* [[ACTOR]], %swift.type* [[DECODER_TYPE]], i8** [[DECODER_PROTOCOL_WITNESS:%.*]]) +// CHECK: define internal swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC16single_case_enumyAA7SimpleEOAFYaKFTETF"(%swift.context* swiftasync %0, %swift.opaque* nocapture [[ARG_DECODER:%.*]], i8* [[ARG_TYPES:%.*]], i8* [[RESULT_BUFF:%.*]], i8* [[SUBS:%.*]], i8* [[WITNESS_TABLES:%.*]], i32 [[NUM_WITNESS_TABLES:%.*]], %T27distributed_actor_accessors7MyActorC* [[ACTOR]], %swift.type* [[DECODER_TYPE]], i8** [[DECODER_PROTOCOL_WITNESS:%.*]]) /// Let's check that the call doesn't have any arguments and returns nothing. @@ -272,8 +274,8 @@ public distributed actor MyOtherActor { /// --> Thunk and distributed method accessor for `with_indirect_enums` -// CHECK: define hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC19with_indirect_enumsyAA9IndirectEOAF_SitFTE" -// CHECK: define internal swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC19with_indirect_enumsyAA9IndirectEOAF_SitFTETF" +// CHECK: define hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC19with_indirect_enumsyAA9IndirectEOAF_SitYaKFTE" +// CHECK: define internal swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC19with_indirect_enumsyAA9IndirectEOAF_SitYaKFTETF" /// First, Load both arguments from the buffer. @@ -306,9 +308,9 @@ public distributed actor MyOtherActor { /// ---> Thunk and distributed method for `complex` -// CHECK: define hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7complexyAA11LargeStructVSaySiG_AA3ObjCSSSgAFtFTE" +// CHECK: define hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7complexyAA11LargeStructVSaySiG_AA3ObjCSSSgAFtYaKFTE" -// CHECK: define internal swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7complexyAA11LargeStructVSaySiG_AA3ObjCSSSgAFtFTETF"(%swift.context* swiftasync {{.*}}, %swift.opaque* nocapture [[ARG_DECODER:%.*]], i8* [[ARG_TYPES:%.*]], i8* [[RESULT_BUFF:%.*]], i8* [[SUBS:%.*]], i8* [[WITNESS_TABLES:%.*]], i32 [[NUM_WITNESS_TABLES:%.*]], %T27distributed_actor_accessors7MyActorC* [[ACTOR]], %swift.type* [[DECODER_TYPE:%.*]], i8** [[DECODER_PROTOCOL_WITNESS:%.*]]) +// CHECK: define internal swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7complexyAA11LargeStructVSaySiG_AA3ObjCSSSgAFtYaKFTETF"(%swift.context* swiftasync {{.*}}, %swift.opaque* nocapture [[ARG_DECODER:%.*]], i8* [[ARG_TYPES:%.*]], i8* [[RESULT_BUFF:%.*]], i8* [[SUBS:%.*]], i8* [[WITNESS_TABLES:%.*]], i32 [[NUM_WITNESS_TABLES:%.*]], %T27distributed_actor_accessors7MyActorC* [[ACTOR]], %swift.type* [[DECODER_TYPE:%.*]], i8** [[DECODER_PROTOCOL_WITNESS:%.*]]) /// First, let's check that all of the different argument types here are loaded correctly. @@ -367,7 +369,7 @@ public distributed actor MyOtherActor { /// ---> Accessor for `genericArgs` -// CHECK: define internal swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC11genericArgsyyx_Sayq_GtSeRzSERzSeR_SER_r0_lFTETF"(%swift.context* swiftasync %0, %swift.opaque* nocapture [[ARG_DECODER:%.*]], i8* [[ARG_TYPES:%.*]], i8* [[RESULT_BUF:%.*]], i8* [[GENERIC_SUBS:%.*]], i8* [[WITNESS_TABLES:%.*]], i32 [[NUM_WITNESS_TABLES:%.*]], %T27distributed_actor_accessors7MyActorC* [[ACTOR:%.*]], %swift.type* [[DECODER_TYPE:%.*]], i8** [[DECODER_PROTOCOL_WITNESS:%.*]]) +// CHECK: define internal swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC11genericArgsyyx_Sayq_GtYaKSeRzSERzSeR_SER_r0_lFTETF"(%swift.context* swiftasync %0, %swift.opaque* nocapture [[ARG_DECODER:%.*]], i8* [[ARG_TYPES:%.*]], i8* [[RESULT_BUF:%.*]], i8* [[GENERIC_SUBS:%.*]], i8* [[WITNESS_TABLES:%.*]], i32 [[NUM_WITNESS_TABLES:%.*]], %T27distributed_actor_accessors7MyActorC* [[ACTOR:%.*]], %swift.type* [[DECODER_TYPE:%.*]], i8** [[DECODER_PROTOCOL_WITNESS:%.*]]) /// ---> Load `T` @@ -423,17 +425,17 @@ public distributed actor MyOtherActor { /// Let's check that there is argument decoding since parameter list is empty -// CHECK: define internal swift{{(tail)?}}cc void @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyFTETF"(%swift.context* swiftasync {{.*}}, %swift.opaque* nocapture [[ARG_DECODER:%.*]], i8* [[ARG_TYPES:%.*]], i8* [[RESULT_BUFF:%.*]], i8* [[SUBS:%.*]], i8* [[WITNESS_TABLES:%.*]], i32 [[NUM_WITNESS_TABLES:%.*]], %T27distributed_actor_accessors12MyOtherActorC* {{.*}}, %swift.type* [[DECODER_TYPE:%.*]], i8** [[DECODER_PROTOCOL_WITNESS:%.*]]) +// CHECK: define internal swift{{(tail)?}}cc void @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyYaKFTETF"(%swift.context* swiftasync {{.*}}, %swift.opaque* nocapture [[ARG_DECODER:%.*]], i8* [[ARG_TYPES:%.*]], i8* [[RESULT_BUFF:%.*]], i8* [[SUBS:%.*]], i8* [[WITNESS_TABLES:%.*]], i32 [[NUM_WITNESS_TABLES:%.*]], %T27distributed_actor_accessors12MyOtherActorC* {{.*}}, %swift.type* [[DECODER_TYPE:%.*]], i8** [[DECODER_PROTOCOL_WITNESS:%.*]]) // CHECK-NEXT: entry: // CHECK-NEXT: {{.*}} = alloca %swift.context* // CHECK-NEXT: %swifterror = alloca %swift.error* -// CHECK-NEXT: {{.*}} = call token @llvm.coro.id.async(i32 8, i32 16, i32 0, i8* bitcast (%swift.async_func_pointer* @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyFTETFTu" to i8*)) +// CHECK-NEXT: {{.*}} = call token @llvm.coro.id.async(i32 8, i32 16, i32 0, i8* bitcast (%swift.async_func_pointer* @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyYaKFTETFTu" to i8*)) // CHECK-NEXT: {{.*}} = call i8* @llvm.coro.begin(token {{%.*}}, i8* null) // CHECK-NEXT: store %swift.context* {{.*}}, %swift.context** {{.*}} // CHECK-NEXT: store %swift.error* null, %swift.error** %swifterror // CHECK-NEXT: {{.*}} = bitcast i8* [[RESULT_BUFF]] to %swift.opaque* -// CHECK-DIRECT-NEXT: {{.*}} = load i32, i32* getelementptr inbounds (%swift.async_func_pointer, %swift.async_func_pointer* @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyFTETu", i32 0, i32 1) -// CHECK-INDIRECT-NEXT: [[ADDR:%[0-9]+]] = load %swift.async_func_pointer*, %swift.async_func_pointer** inttoptr (i64 and (i64 ptrtoint (%swift.async_func_pointer* @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyFTETu" to i64), i64 -2) to %swift.async_func_pointer**), align 8 -// CHECK-INDIRECT-NEXT: [[SELECT:%[0-9]+]] = select i1 true, %swift.async_func_pointer* @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyFTETu", %swift.async_func_pointer* [[ADDR]] +// CHECK-DIRECT-NEXT: {{.*}} = load i32, i32* getelementptr inbounds (%swift.async_func_pointer, %swift.async_func_pointer* @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyYaKFTETu", i32 0, i32 1) +// CHECK-INDIRECT-NEXT: [[ADDR:%[0-9]+]] = load %swift.async_func_pointer*, %swift.async_func_pointer** inttoptr (i64 and (i64 ptrtoint (%swift.async_func_pointer* @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyYaKFTETu" to i64), i64 -2) to %swift.async_func_pointer**), align 8 +// CHECK-INDIRECT-NEXT: [[SELECT:%[0-9]+]] = select i1 true, %swift.async_func_pointer* @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyYaKFTETu", %swift.async_func_pointer* [[ADDR]] // CHECK-INDIRECT-NEXT: [[LOAD:%[0-9]+]] = getelementptr inbounds %swift.async_func_pointer, %swift.async_func_pointer* [[SELECT]], i32 0, i32 1 // CHECK-INDIRECT-NEXT: {{.*}} = load i32, i32* [[LOAD]] diff --git a/test/Distributed/distributed_actor_accessor_thunks_64bit.swift b/test/Distributed/distributed_actor_accessor_thunks_64bit.swift index 47e23e6f9e42b..ac9caf654b798 100644 --- a/test/Distributed/distributed_actor_accessor_thunks_64bit.swift +++ b/test/Distributed/distributed_actor_accessor_thunks_64bit.swift @@ -6,7 +6,9 @@ // REQUIRES: concurrency // REQUIRES: distributed -// REQUIRES: CPU=x86_64 +// REQUIRES: CPU=x86_64 || CPU=arm64 + +// UNSUPPORTED: OS=windows-msvc import _Distributed import FakeDistributedActorSystems @@ -90,9 +92,9 @@ public distributed actor MyOtherActor { /// Let's make sure that accessor loads the data from the buffer and calls expected accessor -// CHECK: define hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7simple1yySiFTE" +// CHECK: define hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7simple1yySiYaKFTE" -// CHECK: define internal swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7simple1yySiFTETF"(%swift.context* swiftasync %0, %swift.opaque* nocapture %1, i8* %2, i8* %3, {{.*}}, %T27distributed_actor_accessors7MyActorC* [[ACTOR:%.*]], %swift.type* [[DECODER_TYPE:%.*]], i8** [[DECODER_PROTOCOL_WITNESS:%.*]]) +// CHECK: define internal swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7simple1yySiYaKFTETF"(%swift.context* swiftasync %0, %swift.opaque* nocapture %1, i8* %2, i8* %3, {{.*}}, %T27distributed_actor_accessors7MyActorC* [[ACTOR:%.*]], %swift.type* [[DECODER_TYPE:%.*]], i8** [[DECODER_PROTOCOL_WITNESS:%.*]]) /// Read the current offset and cast an element to `Int` @@ -132,9 +134,9 @@ public distributed actor MyOtherActor { /// Setup task context for async call to `simple1` thunk -// CHECK-DIRECT: [[CONTEXT_SIZE:%.*]] = load i32, i32* getelementptr inbounds (%swift.async_func_pointer, %swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple1yySiFTETu", i32 0, i32 1) -// CHECK-INDIRECT: [[ADDR:%[0-9]+]] = load %swift.async_func_pointer*, %swift.async_func_pointer** inttoptr (i64 and (i64 ptrtoint (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple1yySiFTETu" to i64), i64 -2) to %swift.async_func_pointer**), align 8 -// CHECK-INDIRECT-NEXT: [[SELECT:%[0-9]+]] = select i1 true, %swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple1yySiFTETu", %swift.async_func_pointer* [[ADDR]] +// CHECK-DIRECT: [[CONTEXT_SIZE:%.*]] = load i32, i32* getelementptr inbounds (%swift.async_func_pointer, %swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple1yySiYaKFTETu", i32 0, i32 1) +// CHECK-INDIRECT: [[ADDR:%[0-9]+]] = load %swift.async_func_pointer*, %swift.async_func_pointer** inttoptr (i64 and (i64 ptrtoint (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple1yySiYaKFTETu" to i64), i64 -2) to %swift.async_func_pointer**) +// CHECK-INDIRECT-NEXT: [[SELECT:%[0-9]+]] = select i1 true, %swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple1yySiYaKFTETu", %swift.async_func_pointer* [[ADDR]] // CHECK-INDIRECT-NEXT: [[LOAD:%[0-9]+]] = getelementptr inbounds %swift.async_func_pointer, %swift.async_func_pointer* [[SELECT]], i32 0, i32 1 // CHECK-INDIRECT-NEXT: [[CONTEXT_SIZE:%.*]] = load i32, i32* [[LOAD]] // CHECK-NEXT: [[CONTEXT_SIZE_64:%.*]] = zext i32 [[CONTEXT_SIZE]] to i64 @@ -144,7 +146,7 @@ public distributed actor MyOtherActor { /// Call distributed thunk for `simple1` and `end` async context without results // CHECK: [[THUNK_RESULT:%.*]] = call { i8*, %swift.error* } (i32, i8*, i8*, ...) @llvm.coro.suspend.async.sl_p0i8p0s_swift.errorss( -// CHECK-SAME: i8* bitcast (void (%swift.context*, i64, %T27distributed_actor_accessors7MyActorC*)* @"$s27distributed_actor_accessors7MyActorC7simple1yySiFTE" to i8*), +// CHECK-SAME: i8* bitcast (void (%swift.context*, i64, %T27distributed_actor_accessors7MyActorC*)* @"$s27distributed_actor_accessors7MyActorC7simple1yySiYaKFTE" to i8*), // CHECK-SAME: %swift.context* [[THUNK_CONTEXT_PTR]], // CHECK-SAME: i64 [[ARG_VAL]], // CHECK-SAME: %T27distributed_actor_accessors7MyActorC* [[ACTOR]]) @@ -155,18 +157,18 @@ public distributed actor MyOtherActor { /// ---> Thunk and distributed method accessor for `simple2` -// CHECK: define hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiFTE" +// CHECK: define hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiYaKFTE" -// CHECK: define internal swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiFTETF" +// CHECK: define internal swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiYaKFTETF" /// !!! - We are not going to double-check argument extraction here since it's the same as `simple1`. // CHECK: [[NATIVE_ARG_VAL:%.*]] = load i64, i64* %._value /// Setup task context for async call to `simple2` thunk -// CHECK-DIRECT: [[CONTEXT_SIZE:%.*]] = load i32, i32* getelementptr inbounds (%swift.async_func_pointer, %swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiFTETu", i32 0, i32 1) -// CHECK-INDIRECT: [[ADDR:%[0-9]+]] = load %swift.async_func_pointer*, %swift.async_func_pointer** inttoptr (i64 and (i64 ptrtoint (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiFTETu" to i64), i64 -2) to %swift.async_func_pointer**), align 8 -// CHECK-INDIRECT-NEXT: [[SELECT:%[0-9]+]] = select i1 true, %swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiFTETu", %swift.async_func_pointer* [[ADDR]] +// CHECK-DIRECT: [[CONTEXT_SIZE:%.*]] = load i32, i32* getelementptr inbounds (%swift.async_func_pointer, %swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiYaKFTETu", i32 0, i32 1) +// CHECK-INDIRECT: [[ADDR:%[0-9]+]] = load %swift.async_func_pointer*, %swift.async_func_pointer** inttoptr (i64 and (i64 ptrtoint (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiYaKFTETu" to i64), i64 -2) to %swift.async_func_pointer**), align 8 +// CHECK-INDIRECT-NEXT: [[SELECT:%[0-9]+]] = select i1 true, %swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiYaKFTETu", %swift.async_func_pointer* [[ADDR]] // CHECK-INDIRECT-NEXT: [[LOAD:%[0-9]+]] = getelementptr inbounds %swift.async_func_pointer, %swift.async_func_pointer* [[SELECT]], i32 0, i32 1 // CHECK-INDIRECT-NEXT: [[CONTEXT_SIZE:%.*]] = load i32, i32* [[LOAD]] // CHECK-NEXT: [[CONTEXT_SIZE_64:%.*]] = zext i32 [[CONTEXT_SIZE]] to i64 @@ -176,7 +178,7 @@ public distributed actor MyOtherActor { /// Call the thunk with extracted argument value // CHECK: [[THUNK_RESULT:%.*]] = call { i8*, i64, %swift.bridge*, %swift.error* } (i32, i8*, i8*, ...) @llvm.coro.suspend.async.sl_p0i8i64p0s_swift.bridgesp0s_swift.errorss( -// CHECK-SAME: i8* bitcast (void (%swift.context*, i64, %T27distributed_actor_accessors7MyActorC*)* @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiFTE" to i8*), +// CHECK-SAME: i8* bitcast (void (%swift.context*, i64, %T27distributed_actor_accessors7MyActorC*)* @"$s27distributed_actor_accessors7MyActorC7simple2ySSSiYaKFTE" to i8*), // CHECK-SAME: %swift.context* [[THUNK_CONTEXT_PTR]], // CHECK-SAME: i64 [[NATIVE_ARG_VAL]], // CHECK-SAME: %T27distributed_actor_accessors7MyActorC* [[ACTOR]]) @@ -199,10 +201,10 @@ public distributed actor MyOtherActor { /// ---> Thunk and distributed method accessor for `simple3` -// CHECK: define hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSFTE" +// CHECK: define hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSYaKFTE" /// !!! in `simple3` interesting bits are: argument value extraction (because string is exploded into N arguments) and call to distributed thunk -// CHECK: define internal swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSFTETF"(%swift.context* swiftasync %0, %swift.opaque* nocapture [[ARG_DECODER:%.*]], i8* [[ARG_TYPES:%.*]], i8* [[RESULT_BUFF:%.*]], i8* [[SUBS:%.*]], i8* [[WITNESS_TABLES:%.*]], i64 [[NUM_WITNESS_TABLES:%.*]], %T27distributed_actor_accessors7MyActorC* [[ACTOR]], %swift.type* [[DECODER_TYPE:%.*]], i8** [[DECODER_PROTOCOL_WITNESS:%.*]]) +// CHECK: define internal swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSYaKFTETF"(%swift.context* swiftasync %0, %swift.opaque* nocapture [[ARG_DECODER:%.*]], i8* [[ARG_TYPES:%.*]], i8* [[RESULT_BUFF:%.*]], i8* [[SUBS:%.*]], i8* [[WITNESS_TABLES:%.*]], i64 [[NUM_WITNESS_TABLES:%.*]], %T27distributed_actor_accessors7MyActorC* [[ACTOR]], %swift.type* [[DECODER_TYPE:%.*]], i8** [[DECODER_PROTOCOL_WITNESS:%.*]]) // CHECK: [[TYPED_RESULT_BUFF:%.*]] = bitcast i8* [[RESULT_BUFF]] to %TSi* @@ -216,11 +218,11 @@ public distributed actor MyOtherActor { /// Setup task context for async call to `simple3` thunk -// CHECK-INDIRECT: [[ADDR:%[0-9]+]] = load %swift.async_func_pointer*, %swift.async_func_pointer** inttoptr (i64 and (i64 ptrtoint (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSFTETu" to i64), i64 -2) to %swift.async_func_pointer**), align 8 -// CHECK-INDIRECT-NEXT: [[SELECT:%[0-9]+]] = select i1 true, %swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSFTETu", %swift.async_func_pointer* [[ADDR]] +// CHECK-INDIRECT: [[ADDR:%[0-9]+]] = load %swift.async_func_pointer*, %swift.async_func_pointer** inttoptr (i64 and (i64 ptrtoint (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSYaKFTETu" to i64), i64 -2) to %swift.async_func_pointer**), align 8 +// CHECK-INDIRECT-NEXT: [[SELECT:%[0-9]+]] = select i1 true, %swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSYaKFTETu", %swift.async_func_pointer* [[ADDR]] // CHECK-INDIRECT-NEXT: [[LOAD:%[0-9]+]] = getelementptr inbounds %swift.async_func_pointer, %swift.async_func_pointer* [[SELECT]], i32 0, i32 1 // CHECK-INDIRECT-NEXT: [[CONTEXT_SIZE:%.*]] = load i32, i32* [[LOAD]] -// CHECK-DIRECT: [[CONTEXT_SIZE:%.*]] = load i32, i32* getelementptr inbounds (%swift.async_func_pointer, %swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSFTETu", i32 0, i32 1) +// CHECK-DIRECT: [[CONTEXT_SIZE:%.*]] = load i32, i32* getelementptr inbounds (%swift.async_func_pointer, %swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSYaKFTETu", i32 0, i32 1) // CHECK-NEXT: [[CONTEXT_SIZE_64:%.*]] = zext i32 [[CONTEXT_SIZE]] to i64 // CHECK-NEXT: [[THUNK_ASYNC_CONTEXT:%.*]] = call swiftcc i8* @swift_task_alloc(i64 [[CONTEXT_SIZE_64]]) // CHECK: [[THUNK_CONTEXT_PTR:%.*]] = bitcast i8* [[THUNK_ASYNC_CONTEXT]] to %swift.context* @@ -228,7 +230,7 @@ public distributed actor MyOtherActor { /// Call distributed thunk with exploaded string value // CHECK: [[THUNK_RESULT:%.*]] = call { i8*, i64, %swift.error* } (i32, i8*, i8*, ...) @llvm.coro.suspend.async.sl_p0i8i64p0s_swift.errorss( -// CHECK-SAME: i8* bitcast (void (%swift.context*, i64, %swift.bridge*, %T27distributed_actor_accessors7MyActorC*)* @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSFTE" to i8*), +// CHECK-SAME: i8* bitcast (void (%swift.context*, i64, %swift.bridge*, %T27distributed_actor_accessors7MyActorC*)* @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSYaKFTE" to i8*), // CHECK-SAME: %swift.context* [[THUNK_CONTEXT_PTR]], // CHECK-SAME: i64 [[STR_SIZE]], // CHECK-SAME: %swift.bridge* [[STR_VAL]], @@ -243,9 +245,9 @@ public distributed actor MyOtherActor { /// --> Thunk and distributed method accessor for `single_case_enum` -// CHECK: define hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC16single_case_enumyAA7SimpleEOAFFTE" +// CHECK: define hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC16single_case_enumyAA7SimpleEOAFYaKFTE" -// CHECK: define internal swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC16single_case_enumyAA7SimpleEOAFFTETF"(%swift.context* swiftasync %0, %swift.opaque* nocapture [[ARG_DECODER:%.*]], i8* [[ARG_TYPES:%.*]], i8* [[RESULT_BUFF:%.*]], i8* [[SUBS:%.*]], i8* [[WITNESS_TABLES:%.*]], i64 [[NUM_WITNESS_TABLES:%.*]], %T27distributed_actor_accessors7MyActorC* [[ACTOR]], %swift.type* [[DECODER_TYPE]], i8** [[DECODER_PROTOCOL_WITNESS:%.*]]) +// CHECK: define internal swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC16single_case_enumyAA7SimpleEOAFYaKFTETF"(%swift.context* swiftasync %0, %swift.opaque* nocapture [[ARG_DECODER:%.*]], i8* [[ARG_TYPES:%.*]], i8* [[RESULT_BUFF:%.*]], i8* [[SUBS:%.*]], i8* [[WITNESS_TABLES:%.*]], i64 [[NUM_WITNESS_TABLES:%.*]], %T27distributed_actor_accessors7MyActorC* [[ACTOR]], %swift.type* [[DECODER_TYPE]], i8** [[DECODER_PROTOCOL_WITNESS:%.*]]) /// Let's check that the call doesn't have any arguments and returns nothing. @@ -255,8 +257,8 @@ public distributed actor MyOtherActor { /// --> Thunk and distributed method accessor for `with_indirect_enums` -// CHECK: define hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC19with_indirect_enumsyAA9IndirectEOAF_SitFTE" -// CHECK: define internal swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC19with_indirect_enumsyAA9IndirectEOAF_SitFTETF" +// CHECK: define hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC19with_indirect_enumsyAA9IndirectEOAF_SitYaKFTE" +// CHECK: define internal swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC19with_indirect_enumsyAA9IndirectEOAF_SitYaKFTETF" /// First, Load both arguments from the buffer. @@ -289,9 +291,9 @@ public distributed actor MyOtherActor { /// ---> Thunk and distributed method for `complex` -// CHECK: define hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7complexyAA11LargeStructVSaySiG_AA3ObjCSSSgAFtFTE" +// CHECK: define hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7complexyAA11LargeStructVSaySiG_AA3ObjCSSSgAFtYaKFTE" -// CHECK: define internal swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7complexyAA11LargeStructVSaySiG_AA3ObjCSSSgAFtFTETF"(%swift.context* swiftasync {{.*}}, %swift.opaque* nocapture [[ARG_DECODER:%.*]], i8* [[ARG_TYPES:%.*]], i8* [[RESULT_BUFF:%.*]], i8* [[SUBS:%.*]], i8* [[WITNESS_TABLES:%.*]], i64 [[NUM_WITNESS_TABLES:%.*]], %T27distributed_actor_accessors7MyActorC* [[ACTOR]], %swift.type* [[DECODER_TYPE:%.*]], i8** [[DECODER_PROTOCOL_WITNESS:%.*]]) +// CHECK: define internal swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7complexyAA11LargeStructVSaySiG_AA3ObjCSSSgAFtYaKFTETF"(%swift.context* swiftasync {{.*}}, %swift.opaque* nocapture [[ARG_DECODER:%.*]], i8* [[ARG_TYPES:%.*]], i8* [[RESULT_BUFF:%.*]], i8* [[SUBS:%.*]], i8* [[WITNESS_TABLES:%.*]], i64 [[NUM_WITNESS_TABLES:%.*]], %T27distributed_actor_accessors7MyActorC* [[ACTOR]], %swift.type* [[DECODER_TYPE:%.*]], i8** [[DECODER_PROTOCOL_WITNESS:%.*]]) /// First, let's check that all of the different argument types here are loaded correctly. @@ -346,7 +348,7 @@ public distributed actor MyOtherActor { /// ---> Accessor for `genericArgs` -// CHECK: define internal swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC11genericArgsyyx_Sayq_GtSeRzSERzSeR_SER_r0_lFTETF"(%swift.context* swiftasync %0, %swift.opaque* nocapture [[ARG_DECODER:%.*]], i8* [[ARG_TYPES:%.*]], i8* [[RESULT_BUF:%.*]], i8* [[GENERIC_SUBS:%.*]], i8* [[WITNESS_TABLES:%.*]], i64 [[NUM_WITNESS_TABLES:%.*]], %T27distributed_actor_accessors7MyActorC* [[ACTOR:%.*]], %swift.type* [[DECODER_TYPE:%.*]], i8** [[DECODER_PROTOCOL_WITNESS:%.*]]) +// CHECK: define internal swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC11genericArgsyyx_Sayq_GtYaKSeRzSERzSeR_SER_r0_lFTETF"(%swift.context* swiftasync %0, %swift.opaque* nocapture [[ARG_DECODER:%.*]], i8* [[ARG_TYPES:%.*]], i8* [[RESULT_BUF:%.*]], i8* [[GENERIC_SUBS:%.*]], i8* [[WITNESS_TABLES:%.*]], i64 [[NUM_WITNESS_TABLES:%.*]], %T27distributed_actor_accessors7MyActorC* [[ACTOR:%.*]], %swift.type* [[DECODER_TYPE:%.*]], i8** [[DECODER_PROTOCOL_WITNESS:%.*]]) /// ---> Load `T` @@ -399,17 +401,17 @@ public distributed actor MyOtherActor { /// Let's check that there is argument decoding since parameter list is empty -// CHECK: define internal swift{{(tail)?}}cc void @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyFTETF"(%swift.context* swiftasync {{.*}}, %swift.opaque* nocapture [[ARG_DECODER:%.*]], i8* [[ARG_TYPES:%.*]], i8* [[RESULT_BUFF:%.*]], i8* [[SUBS:%.*]], i8* [[WITNESS_TABLES:%.*]], i64 [[NUM_WITNESS_TABLES:%.*]], %T27distributed_actor_accessors12MyOtherActorC* {{.*}}, %swift.type* [[DECODER_TYPE:%.*]], i8** [[DECODER_PROTOCOL_WITNESS:%.*]]) +// CHECK: define internal swift{{(tail)?}}cc void @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyYaKFTETF"(%swift.context* swiftasync {{.*}}, %swift.opaque* nocapture [[ARG_DECODER:%.*]], i8* [[ARG_TYPES:%.*]], i8* [[RESULT_BUFF:%.*]], i8* [[SUBS:%.*]], i8* [[WITNESS_TABLES:%.*]], i64 [[NUM_WITNESS_TABLES:%.*]], %T27distributed_actor_accessors12MyOtherActorC* {{.*}}, %swift.type* [[DECODER_TYPE:%.*]], i8** [[DECODER_PROTOCOL_WITNESS:%.*]]) // CHECK-NEXT: entry: // CHECK-NEXT: {{.*}} = alloca %swift.context* // CHECK-NEXT: %swifterror = alloca swifterror %swift.error* -// CHECK-NEXT: {{.*}} = call token @llvm.coro.id.async(i32 16, i32 16, i32 0, i8* bitcast (%swift.async_func_pointer* @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyFTETFTu" to i8*)) +// CHECK-NEXT: {{.*}} = call token @llvm.coro.id.async(i32 16, i32 16, i32 0, i8* bitcast (%swift.async_func_pointer* @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyYaKFTETFTu" to i8*)) // CHECK-NEXT: {{.*}} = call i8* @llvm.coro.begin(token {{%.*}}, i8* null) // CHECK-NEXT: store %swift.context* {{.*}}, %swift.context** {{.*}} // CHECK-NEXT: store %swift.error* null, %swift.error** %swifterror // CHECK-NEXT: {{.*}} = bitcast i8* [[RESULT_BUFF]] to %swift.opaque* -// CHECK-DIRECT-NEXT: {{.*}} = load i32, i32* getelementptr inbounds (%swift.async_func_pointer, %swift.async_func_pointer* @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyFTETu", i32 0, i32 1) -// CHECK-INDIRECT-NEXT: [[ADDR:%[0-9]+]] = load %swift.async_func_pointer*, %swift.async_func_pointer** inttoptr (i64 and (i64 ptrtoint (%swift.async_func_pointer* @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyFTETu" to i64), i64 -2) to %swift.async_func_pointer**), align 8 -// CHECK-INDIRECT-NEXT: [[SELECT:%[0-9]+]] = select i1 true, %swift.async_func_pointer* @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyFTETu", %swift.async_func_pointer* [[ADDR]] +// CHECK-DIRECT-NEXT: {{.*}} = load i32, i32* getelementptr inbounds (%swift.async_func_pointer, %swift.async_func_pointer* @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyYaKFTETu", i32 0, i32 1) +// CHECK-INDIRECT-NEXT: [[ADDR:%[0-9]+]] = load %swift.async_func_pointer*, %swift.async_func_pointer** inttoptr (i64 and (i64 ptrtoint (%swift.async_func_pointer* @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyYaKFTETu" to i64), i64 -2) to %swift.async_func_pointer**), align 8 +// CHECK-INDIRECT-NEXT: [[SELECT:%[0-9]+]] = select i1 true, %swift.async_func_pointer* @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyYaKFTETu", %swift.async_func_pointer* [[ADDR]] // CHECK-INDIRECT-NEXT: [[LOAD:%[0-9]+]] = getelementptr inbounds %swift.async_func_pointer, %swift.async_func_pointer* [[SELECT]], i32 0, i32 1 // CHECK-INDIRECT-NEXT: {{.*}} = load i32, i32* [[LOAD]] diff --git a/test/Distributed/distributed_actor_async_let.swift b/test/Distributed/distributed_actor_async_let.swift index fe6e9cf2f230f..f9f29a4ee50ae 100644 --- a/test/Distributed/distributed_actor_async_let.swift +++ b/test/Distributed/distributed_actor_async_let.swift @@ -18,56 +18,65 @@ distributed actor Philosopher { philosophy = "Epistemology" } - distributed func hi() -> String { "Hi!" } + distributed func hi1() -> String { "Hi!" } +// distributed func hi2() -> String { "Hi!" } +// distributed func hi3() -> String { "Hi!" } +// distributed func hi4() -> String { "Hi!" } +// distributed func hi5() -> String { "Hi!" } +// distributed func hi6() -> String { "Hi!" } +// distributed func hi7() -> String { "Hi!" } +// distributed func hi8() -> String { "Hi!" } +// distributed func hi9() -> String { "Hi!" } func test(other: Philosopher) async throws { // self -------------------------------------------------------------------- - async let alet = self.hi() // none + async let alet = self.hi1() // none _ = await alet // Ok - `self.hi()` isn't throwing - Task { - _ = self.hi() // none - } - - Task.detached { - _ = await self.hi() // async - } - - // other ------------------------------------------------------------------- - - async let otherLet = other.hi() // hi = async throws because of `other` - _ = try await otherLet - - Task { - _ = try await other.hi() // hi = async throws - } - - Task.detached { - _ = try await other.hi() // hi = async throws - } - - // known to be local ------------------------------------------------------- - - // FIXME(distributed): relies on the "secretly known to be local" hack in typechecking - let _: String? = await other.whenLocal { __secretlyKnownToBeLocal in - // we're able to get state of what would otherwise be distributed-isolated: - __secretlyKnownToBeLocal.philosophy - } +// Task { +// _ = self.hi1() // none +// } +// +// Task.detached { +// _ = await self.hi2() // async +// } } - static func test(iso: isolated Philosopher) async throws { - _ = iso.hi() // we're "in the actor" already, since isolated - - // isolated parameter ------------------------------------------------------ - async let otherLet = iso.hi() // async - _ = await otherLet - - Task { - _ = await iso.hi() // none - } - - Task.detached { - _ = await iso.hi() // async - } - } +// // other ------------------------------------------------------------------- +// +// async let otherLet = other.hi3() // hi = async throws because of `other` +// _ = try await otherLet +// +// Task { +// _ = try await other.hi4() // hi = async throws +// } +// +// Task.detached { +// _ = try await other.hi5() // hi = async throws +// } +// +// // known to be local ------------------------------------------------------- +// +// // FIXME(distributed): relies on the "secretly known to be local" hack in typechecking +// let _: String? = await other.whenLocal { __secretlyKnownToBeLocal in +// // we're able to get state of what would otherwise be distributed-isolated: +// __secretlyKnownToBeLocal.philosophy +// } +// } +// +// static func test(iso: isolated Philosopher) async throws { +// _ = iso.h6() // we're "in the actor" already, since isolated +// +// // isolated parameter ------------------------------------------------------ +// async let otherLet = iso.hi7() // async +// _ = await otherLet +// +// Task { +// _ = await iso.hi8() // none +// } +// +// Task.detached { +// _ = await iso.hi9() // async +// } +// } } diff --git a/test/Distributed/distributed_actor_generic.swift b/test/Distributed/distributed_actor_generic.swift index 018a7b5484f89..534420fd06582 100644 --- a/test/Distributed/distributed_actor_generic.swift +++ b/test/Distributed/distributed_actor_generic.swift @@ -9,6 +9,15 @@ import FakeDistributedActorSystems typealias DefaultDistributedActorSystem = FakeActorSystem -distributed actor Worker { - distributed func test(item: WorkItem) {} +typealias Message = Sendable & Codable + +distributed actor GreeterX { + distributed func generic(_ value: V) -> String { + return "\(value)" + } + + distributed func generic2( + strict: Double, _ value: A, _ bs: [B]) -> String { + return "\(value) \(bs)" + } } diff --git a/test/Distributed/distributed_actor_isolation.swift b/test/Distributed/distributed_actor_isolation.swift index f53eba79c28ab..9582fba37da35 100644 --- a/test/Distributed/distributed_actor_isolation.swift +++ b/test/Distributed/distributed_actor_isolation.swift @@ -45,7 +45,8 @@ distributed actor DistributedActor_1 { distributed static func distributedStatic() {} // expected-error{{'distributed' method cannot be 'static'}} distributed class func distributedClass() {} // expected-error@-1{{class methods are only allowed within classes; use 'static' to declare a static method}} - // expected-error@-2{{'distributed' method cannot be 'static'}} // TODO(distributed): should call out 'class' instead? + // expected-error@-2{{'distributed' method cannot be 'static'}} + // expected-error@-3{{class methods are only allowed within classes; use 'static' to declare a static method}} func hello() {} // expected-note{{distributed actor-isolated instance method 'hello()' declared here}} func helloAsync() async {} // expected-note{{distributed actor-isolated instance method 'helloAsync()' declared here}} diff --git a/test/Distributed/distributed_actor_system_missing.swift b/test/Distributed/distributed_actor_system_missing.swift new file mode 100644 index 0000000000000..4ac8f31d8a86b --- /dev/null +++ b/test/Distributed/distributed_actor_system_missing.swift @@ -0,0 +1,16 @@ +// RUN: %target-swift-frontend -typecheck -verify -enable-experimental-distributed -disable-availability-checking -I %t 2>&1 %s + +// UNSUPPORTED: back_deploy_concurrency +// REQUIRES: concurrency +// REQUIRES: distributed + +import _Distributed + +distributed actor DA { + // expected-error@-1{{distributed actor 'DA' does not declare ActorSystem it can be used with.}} + + // expected-note@-3{{you can provide a module-wide default actor system by declaring:}} + + // Note to add the typealias is diagnosed on the protocol: + // _Distributed.DistributedActor:3:20: note: diagnostic produced elsewhere: protocol requires nested type 'ActorSystem'; do you want to add it? +} diff --git a/test/Distributed/distributed_actor_system_missing_adhoc_requirement_impls.swift b/test/Distributed/distributed_actor_system_missing_adhoc_requirement_impls.swift index b22f400e3fca8..b92a4b6f5bd0b 100644 --- a/test/Distributed/distributed_actor_system_missing_adhoc_requirement_impls.swift +++ b/test/Distributed/distributed_actor_system_missing_adhoc_requirement_impls.swift @@ -40,6 +40,61 @@ struct MissingRemoteCall: DistributedActorSystem { } } +struct MissingRemoteCall_missing_makeInvocationEncoder: DistributedActorSystem { + // expected-error@-1{{type 'MissingRemoteCall_missing_makeInvocationEncoder' does not conform to protocol 'DistributedActorSystem'}} + + typealias ActorID = ActorAddress + typealias InvocationDecoder = FakeInvocationDecoder + typealias InvocationEncoder = FakeInvocationEncoder + typealias SerializationRequirement = Codable + + func resolve(id: ActorID, as actorType: Act.Type) + throws -> Act? where Act: DistributedActor { + return nil + } + + func assignID(_ actorType: Act.Type) -> ActorID + where Act: DistributedActor { + ActorAddress(parse: "fake://123") + } + + func actorReady(_ actor: Act) + where Act: DistributedActor, + Act.ID == ActorID { + } + + func remoteCall( + on actor: Act, + target: RemoteCallTarget, + invocation: inout InvocationEncoder, + throwing: Err.Type, + returning: Res.Type + ) async throws -> Res + where Act: DistributedActor, + Act.ID == ActorID, + Err: Error, + Res: SerializationRequirement { + fatalError("NOT IMPLEMENTED \(#function)") + } + + func remoteCallVoid( + on actor: Act, + target: RemoteCallTarget, + invocation: inout InvocationEncoder, + throwing: Err.Type + ) async throws + where Act: DistributedActor, + Act.ID == ActorID, + Err: Error { + fatalError("NOT IMPLEMENTED \(#function)") + } + + func resignID(_ id: ActorID) { + } + + // func makeInvocationEncoder() -> InvocationEncoder {} // MISSING +} + struct Error_wrongReturn: DistributedActorSystem { // expected-error@-1{{struct 'Error_wrongReturn' is missing witness for protocol requirement 'remoteCall'}} // expected-note@-2{{protocol 'Error_wrongReturn' requires function 'remoteCall' with signature:}} @@ -499,7 +554,7 @@ struct FakeInvocationEncoder_missing_recordArgument2: DistributedTargetInvocatio typealias SerializationRequirement = Codable mutating func recordGenericSubstitution(_ type: T.Type) throws {} - mutating func recordArgument(_ argument: Argument) throws {} // BAD + mutating func recordArgument(_ argument: Argument) throws {} // BAD mutating func recordReturnType(_ type: R.Type) throws {} mutating func recordErrorType(_ type: E.Type) throws {} mutating func doneRecording() throws {} diff --git a/test/Distributed/distributed_protocols_distributed_func_serialization_requirements.swift b/test/Distributed/distributed_protocols_distributed_func_serialization_requirements.swift index 1de73c8a74cbf..265eba969a85a 100644 --- a/test/Distributed/distributed_protocols_distributed_func_serialization_requirements.swift +++ b/test/Distributed/distributed_protocols_distributed_func_serialization_requirements.swift @@ -1,6 +1,6 @@ // RUN: %empty-directory(%t) // RUN: %target-swift-frontend-emit-module -emit-module-path %t/FakeDistributedActorSystems.swiftmodule -module-name FakeDistributedActorSystems -disable-availability-checking %S/Inputs/FakeDistributedActorSystems.swift -// RUN: %target-swift-frontend -typecheck -verify -enable-experimental-distributed -disable-availability-checking -I %t 2>&1 %s +// RUN: %target-swift-frontend -typecheck -verify -verify-ignore-unknown -enable-experimental-distributed -disable-availability-checking -I %t 2>&1 %s // REQUIRES: concurrency // REQUIRES: distributed @@ -21,6 +21,7 @@ distributed actor SpecifyRequirement: NoSerializationRequirementYet { distributed func test() -> NotCodable { .init() } + } extension NoSerializationRequirementYet { @@ -45,3 +46,9 @@ extension NoSerializationRequirementYet .init() } } + +// FIXME(distributed): remove the -verify-ignore-unknown +// :0: error: unexpected error produced: instance method 'recordReturnType' requires that 'NotCodable' conform to 'Decodable' +// :0: error: unexpected error produced: instance method 'recordReturnType' requires that 'NotCodable' conform to 'Encodable' +// :0: error: unexpected error produced: instance method 'remoteCall(on:target:invocation:throwing:returning:)' requires that 'NotCodable' conform to 'Decodable' +// :0: error: unexpected error produced: instance method 'remoteCall(on:target:invocation:throwing:returning:)' requires that 'NotCodable' conform to 'Encodable' diff --git a/test/Generics/concrete_conformance_minimization.swift b/test/Generics/concrete_conformance_minimization.swift index 0f47e3b069d89..1c3ad243eec0a 100644 --- a/test/Generics/concrete_conformance_minimization.swift +++ b/test/Generics/concrete_conformance_minimization.swift @@ -1,5 +1,6 @@ // RUN: %target-swift-frontend -typecheck %s -debug-generic-signatures -requirement-machine-protocol-signatures=on -requirement-machine-inferred-signatures=on 2>&1 | %FileCheck %s // RUN: %target-swift-frontend -typecheck %s -debug-generic-signatures -requirement-machine-protocol-signatures=on -requirement-machine-inferred-signatures=on -disable-requirement-machine-concrete-contraction 2>&1 | %FileCheck %s +// RUN: %target-swift-frontend -typecheck %s -debug-generic-signatures -requirement-machine-protocol-signatures=on -requirement-machine-inferred-signatures=on -disable-requirement-machine-concrete-contraction -enable-requirement-machine-loop-normalization 2>&1 | %FileCheck %s struct MyOptionSet : OptionSet { let rawValue: UInt diff --git a/test/Generics/concrete_conformance_rule_simplified.swift b/test/Generics/concrete_conformance_rule_simplified.swift index 5f372b4728c8a..42b6790a80c4e 100644 --- a/test/Generics/concrete_conformance_rule_simplified.swift +++ b/test/Generics/concrete_conformance_rule_simplified.swift @@ -1,5 +1,6 @@ // RUN: %target-swift-frontend -typecheck %s -debug-generic-signatures -requirement-machine-inferred-signatures=on 2>&1 | %FileCheck %s // RUN: %target-swift-frontend -typecheck %s -debug-generic-signatures -requirement-machine-inferred-signatures=on -disable-requirement-machine-concrete-contraction 2>&1 | %FileCheck %s +// RUN: %target-swift-frontend -typecheck %s -debug-generic-signatures -requirement-machine-inferred-signatures=on -disable-requirement-machine-concrete-contraction -enable-requirement-machine-loop-normalization 2>&1 | %FileCheck %s protocol P1 {} diff --git a/test/Generics/loop_normalization_1.swift b/test/Generics/loop_normalization_1.swift new file mode 100644 index 0000000000000..ec3ab2ed4d3e3 --- /dev/null +++ b/test/Generics/loop_normalization_1.swift @@ -0,0 +1,40 @@ +// RUN: %target-swift-frontend -typecheck %s -debug-generic-signatures -requirement-machine-inferred-signatures=on 2>&1 | %FileCheck %s +// RUN: %target-swift-frontend -typecheck %s -debug-generic-signatures -requirement-machine-inferred-signatures=on -enable-requirement-machine-loop-normalization 2>&1 | %FileCheck %s + +protocol P { + associatedtype T +} + +struct C {} + +// CHECK-LABEL: .f1@ +// CHECK-NEXT: Generic signature: +func f1(_: T, _: U) where T.T == C, T.T == U.T { } + +// CHECK-LABEL: .f2@ +// CHECK-NEXT: Generic signature: +func f2(_: T, _: U) where U.T == C, T.T == U.T { } + +// CHECK-LABEL: .f3@ +// CHECK-NEXT: Generic signature: +func f3(_: T, _: U) where T.T == C, U.T == C, T.T == U.T { } + +// CHECK-LABEL: .f4@ +// CHECK-NEXT: Generic signature: +func f4(_: T, _: U) where T.T == C, T.T == U.T, U.T == C { } + +// CHECK-LABEL: .f5@ +// CHECK-NEXT: Generic signature: +func f5(_: T, _: U) where T.T == U.T, T.T == C, U.T == C { } + +// CHECK-LABEL: .f6@ +// CHECK-NEXT: Generic signature: +func f6(_: T, _: U) where U.T == C, T.T == C, T.T == U.T { } + +// CHECK-LABEL: .f7@ +// CHECK-NEXT: Generic signature: +func f7(_: T, _: U) where T.T == C, U.T == C, T.T == U.T { } + +// CHECK-LABEL: .f8@ +// CHECK-NEXT: Generic signature: +func f8(_: T, _: U) where T.T == U.T, U.T == C, T.T == C { } diff --git a/test/Generics/loop_normalization_2.swift b/test/Generics/loop_normalization_2.swift new file mode 100644 index 0000000000000..d76726d123d48 --- /dev/null +++ b/test/Generics/loop_normalization_2.swift @@ -0,0 +1,29 @@ +// RUN: %target-swift-frontend -typecheck %s -debug-generic-signatures -requirement-machine-protocol-signatures=on 2>&1 | %FileCheck %s +// RUN: %target-swift-frontend -typecheck %s -debug-generic-signatures -requirement-machine-protocol-signatures=on -enable-requirement-machine-loop-normalization 2>&1 | %FileCheck %s + +protocol P1 { + associatedtype A +} + +protocol P2 : P1 where A == S0 { + associatedtype B : P2 = S2 + where B.A == A, B.B == B +} + +struct S0 {} + +struct S1 : P2 {} + +struct S2 : P2 {} + +// CHECK-LABEL: .Q1@ +// CHECK-NEXT: Requirement signature: +protocol Q1 { + associatedtype T where T : P2, T == S1 +} + +// CHECK-LABEL: .Q2@ +// CHECK-NEXT: Requirement signature: +protocol Q2 { + associatedtype T where T : P2, T == S2 +} diff --git a/test/Generics/non_final_class_conforms_same_type_requirement_on_self.swift b/test/Generics/non_final_class_conforms_same_type_requirement_on_self.swift index e1f45a3eb4fb6..d9593de6ee2c9 100644 --- a/test/Generics/non_final_class_conforms_same_type_requirement_on_self.swift +++ b/test/Generics/non_final_class_conforms_same_type_requirement_on_self.swift @@ -14,7 +14,7 @@ public protocol Q { // exactly equal C; since C is not final, this means the conformance // is not covariant. public class C : P { -// expected-warning@-1 {{non-final class 'C' cannot safely conform to protocol 'P', which requires that 'Self' is exactly equal to 'Self.A.B'; this is an error in Swift 6}} +// expected-warning@-1 {{non-final class 'C' cannot safely conform to protocol 'P', which requires that 'Self.A.B' is exactly equal to 'Self'; this is an error in Swift 6}} public typealias A = D } @@ -45,3 +45,32 @@ public func takesBoth1(_: T) where T : P, T : C {} // CHECK-LABEL: Generic signature: public func takesBoth2(_: U) where U : C, U : P {} + +// 'Self' can also occur inside of a concrete type or superclass requirement. +public class G {} + +public protocol ConcreteExampleP { + associatedtype A : Q where A.B == G +} + +public class ConcreteExampleC : ConcreteExampleP { +// expected-warning@-1 {{non-final class 'ConcreteExampleC' cannot safely conform to protocol 'ConcreteExampleP', which requires that 'Self.A.B' is exactly equal to 'G'; this is an error in Swift 6}} + public typealias A = ConcreteExampleD +} + +public class ConcreteExampleD : Q { + public typealias B = G +} + +public protocol SuperclassExampleP { + associatedtype A : Q where A.B : G +} + +public class SuperclassExampleC : SuperclassExampleP { +// expected-warning@-1 {{non-final class 'SuperclassExampleC' cannot safely conform to protocol 'SuperclassExampleP', which requires that 'Self.A.B' inherit from 'G'; this is an error in Swift 6}} + public typealias A = SuperclassExampleD +} + +public class SuperclassExampleD : Q { + public typealias B = G +} \ No newline at end of file diff --git a/test/Generics/rdar80503090.swift b/test/Generics/rdar80503090.swift index d2b7a56ce3f29..0cb4584228ba7 100644 --- a/test/Generics/rdar80503090.swift +++ b/test/Generics/rdar80503090.swift @@ -20,7 +20,7 @@ extension P where T : Q { } class C : P {} -// expected-warning@-1 {{non-final class 'C' cannot safely conform to protocol 'P', which requires that 'Self' is exactly equal to 'Self.T'; this is an error in Swift 6}} +// expected-warning@-1 {{non-final class 'C' cannot safely conform to protocol 'P', which requires that 'Self.T' is exactly equal to 'Self'; this is an error in Swift 6}} extension P where T : C { // CHECK-LABEL: Generic signature: diff --git a/test/Generics/rdar89921930.swift b/test/Generics/rdar89921930.swift new file mode 100644 index 0000000000000..412de151ecbca --- /dev/null +++ b/test/Generics/rdar89921930.swift @@ -0,0 +1,16 @@ +// RUN: %target-swift-frontend -typecheck -verify %s + +// This used to hit a circularity. + +public protocol P {} + +public struct G {} + +public typealias A = G + +public protocol Circle { + associatedtype X : P + associatedtype Y where Y == A +} + + diff --git a/test/Generics/redundant_parent_path_in_protocol.swift b/test/Generics/redundant_parent_path_in_protocol.swift index 2cc19f6af4ce8..34f348e97e30c 100644 --- a/test/Generics/redundant_parent_path_in_protocol.swift +++ b/test/Generics/redundant_parent_path_in_protocol.swift @@ -1,4 +1,5 @@ // RUN: %target-swift-frontend -typecheck %s -debug-generic-signatures -requirement-machine-protocol-signatures=on 2>&1 | %FileCheck %s +// RUN: %target-swift-frontend -typecheck %s -debug-generic-signatures -requirement-machine-protocol-signatures=on -enable-requirement-machine-loop-normalization 2>&1 | %FileCheck %s // CHECK-LABEL: redundant_parent_path_in_protocol.(file).P1@ // CHECK-NEXT: Requirement signature: diff --git a/test/IRGen/async/partial_apply_forwarder.sil b/test/IRGen/async/partial_apply_forwarder.sil index fe491a4356b35..79988aee0b9c9 100644 --- a/test/IRGen/async/partial_apply_forwarder.sil +++ b/test/IRGen/async/partial_apply_forwarder.sil @@ -43,7 +43,7 @@ entry(%e : $E): } -sil hidden_external @takingP : $@async @convention(method) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> () { +sil hidden @takingP : $@async @convention(method) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> () { entry(%p : $*τ_0_0): %0 = builtin "int_trap"() : $Never unreachable diff --git a/test/IRGen/casts.sil b/test/IRGen/casts.sil index 0fb44be91d06f..9cccf157c36af 100644 --- a/test/IRGen/casts.sil +++ b/test/IRGen/casts.sil @@ -339,7 +339,7 @@ entry(%x : $OA): @objc class OB {} sil_vtable OB {} -sil hidden_external @$s5casts2OBCACycfcTo : $@convention(thin) (OB) -> OB { +sil hidden @$s5casts2OBCACycfcTo : $@convention(thin) (OB) -> OB { entry(%x : $OB): return %x : $OB } diff --git a/test/IRGen/sil_linkage.sil b/test/IRGen/sil_linkage.sil index 58016f44301e9..d0f6d90b45e7c 100644 --- a/test/IRGen/sil_linkage.sil +++ b/test/IRGen/sil_linkage.sil @@ -8,21 +8,15 @@ sil_stage canonical // CHECK: define{{( dllexport)?}}{{( protected)?}} swiftcc void @public_transparent_function_test() {{.*}} { // PRIMARY: define weak_odr hidden swiftcc void @public_non_abi_function_test() {{.*}} { // WMO: define linkonce_odr hidden swiftcc void @public_non_abi_function_test() {{.*}} { -// CHECK: define hidden swiftcc void @hidden_fragile_function_test() {{.*}} { // CHECK: define linkonce_odr hidden swiftcc void @shared_fragile_function_test() {{.*}} { -// CHECK: define{{( internal)?}} swiftcc void @private_fragile_function_test() {{.*}} { // Public external functions are not emitted into clients. // CHECK: declare{{( dllimport)?}} swiftcc void @public_external_fragile_function_def_test() -// CHECK: define{{( protected)?}} available_externally{{ (hidden)?}}{{( dllimport)?}} swiftcc void @hidden_external_fragile_function_def_test() {{.*}} { -// CHECK: define linkonce_odr hidden swiftcc void @shared_external_fragile_function_def_test() {{.*}} { // CHECK: define{{( protected)?}}{{( dllexport)?}} swiftcc void @public_resilient_function_test() {{.*}} { // CHECK: define hidden swiftcc void @hidden_resilient_function_test() {{.*}} { // CHECK: define linkonce_odr hidden swiftcc void @shared_resilient_function_test() {{.*}} { // CHECK: define internal swiftcc void @private_resilient_function_test() {{.*}}{ // Public external functions are not emitted into clients. // CHECK: declare{{( dllimport)?}} swiftcc void @public_external_resilient_function_def_test() -// CHECK: define{{( protected)?}} available_externally hidden{{( dllimport)?}} swiftcc void @hidden_external_resilient_function_def_test() {{.*}} { -// CHECK: define linkonce_odr hidden swiftcc void @shared_external_resilient_function_def_test() {{.*}} { sil public [serialized] @public_fragile_function_test : $@convention(thin) () -> () { %0 = tuple() @@ -44,36 +38,16 @@ sil non_abi [serialized] @public_non_abi_function_test : $@convention(thin) () - return %0 : $() } -sil hidden [serialized] @hidden_fragile_function_test : $@convention(thin) () -> () { - %0 = tuple() - return %0 : $() -} - sil shared [serialized] @shared_fragile_function_test : $@convention(thin) () -> () { %0 = tuple() return %0 : $() } -sil private [serialized] @private_fragile_function_test : $@convention(thin) () -> () { - %0 = tuple() - return %0 : $() -} - sil public_external [serialized] @public_external_fragile_function_def_test : $@convention(thin) () -> () { %0 = tuple() return %0 : $() } -sil hidden_external [serialized] @hidden_external_fragile_function_def_test : $@convention(thin) () -> () { - %0 = tuple() - return %0 : $() -} - -sil shared_external [serialized] @shared_external_fragile_function_def_test : $@convention(thin) () -> () { - %0 = tuple() - return %0 : $() -} - sil public_external [serialized] @public_external_fragile_function_decl_test : $@convention(thin) () -> () sil hidden_external [serialized] @hidden_external_fragile_function_decl_test : $@convention(thin) () -> () @@ -104,17 +78,7 @@ sil private @private_resilient_function_test : $@convention(thin) () -> () { return %0 : $() } -sil public_external @public_external_resilient_function_def_test : $@convention(thin) () -> () { - %0 = tuple() - return %0 : $() -} - -sil hidden_external @hidden_external_resilient_function_def_test : $@convention(thin) () -> () { - %0 = tuple() - return %0 : $() -} - -sil shared_external @shared_external_resilient_function_def_test : $@convention(thin) () -> () { +sil public_external [serialized] @public_external_resilient_function_def_test : $@convention(thin) () -> () { %0 = tuple() return %0 : $() } @@ -141,12 +105,8 @@ sil public @use_all_symbols : $@convention(thin) () -> () { %t0 = function_ref @public_transparent_fragile_function_test : $@convention(thin) () -> () %t1 = function_ref @public_transparent_function_test : $@convention(thin) () -> () %t2 = function_ref @public_non_abi_function_test : $@convention(thin) () -> () - %1 = function_ref @hidden_fragile_function_test : $@convention(thin) () -> () %2 = function_ref @shared_fragile_function_test : $@convention(thin) () -> () - %3 = function_ref @private_fragile_function_test : $@convention(thin) () -> () %4 = function_ref @public_external_fragile_function_def_test : $@convention(thin) () -> () - %5 = function_ref @hidden_external_fragile_function_def_test : $@convention(thin) () -> () - %6 = function_ref @shared_external_fragile_function_def_test : $@convention(thin) () -> () %8 = function_ref @public_external_fragile_function_decl_test : $@convention(thin) () -> () %9 = function_ref @hidden_external_fragile_function_decl_test : $@convention(thin) () -> () // %10 = function_ref @shared_external_fragile_function_decl_test : $@convention(thin) () -> () @@ -156,8 +116,6 @@ sil public @use_all_symbols : $@convention(thin) () -> () { %14 = function_ref @shared_resilient_function_test : $@convention(thin) () -> () %15 = function_ref @private_resilient_function_test : $@convention(thin) () -> () %16 = function_ref @public_external_resilient_function_def_test : $@convention(thin) () -> () - %17 = function_ref @hidden_external_resilient_function_def_test : $@convention(thin) () -> () - %18 = function_ref @shared_external_resilient_function_def_test : $@convention(thin) () -> () // %19 = function_ref @private_external_resilient_function_def_test : $@convention(thin) () -> () %20 = function_ref @public_external_resilient_function_decl_test : $@convention(thin) () -> () %21 = function_ref @hidden_external_resilient_function_decl_test : $@convention(thin) () -> () @@ -165,12 +123,8 @@ sil public @use_all_symbols : $@convention(thin) () -> () { // %23 = function_ref @private_external_resilient_function_decl_test : $@convention(thin) () -> () apply %0() : $@convention(thin) () -> () - apply %1() : $@convention(thin) () -> () apply %2() : $@convention(thin) () -> () - apply %3() : $@convention(thin) () -> () apply %4() : $@convention(thin) () -> () - apply %5() : $@convention(thin) () -> () - apply %6() : $@convention(thin) () -> () apply %8() : $@convention(thin) () -> () apply %9() : $@convention(thin) () -> () // apply %10() : $@convention(thin) () -> () @@ -180,8 +134,6 @@ sil public @use_all_symbols : $@convention(thin) () -> () { apply %14() : $@convention(thin) () -> () apply %15() : $@convention(thin) () -> () apply %16() : $@convention(thin) () -> () - apply %17() : $@convention(thin) () -> () - apply %18() : $@convention(thin) () -> () // apply %19() : $@convention(thin) () -> () apply %20() : $@convention(thin) () -> () apply %21() : $@convention(thin) () -> () diff --git a/test/IRGen/unused.sil b/test/IRGen/unused.sil index 7eb4e36e34575..b214a4afda51a 100644 --- a/test/IRGen/unused.sil +++ b/test/IRGen/unused.sil @@ -13,7 +13,7 @@ bb0: return %1 : $() } -sil public_external @bar : $@convention(thin) () -> () { +sil public_external [serialized] @bar : $@convention(thin) () -> () { bb0: %1 = tuple () return %1 : $() diff --git a/test/Interop/Cxx/class/constructors-silgen.swift b/test/Interop/Cxx/class/constructors-silgen.swift index f8d762ad43eef..f0cfcb1600405 100644 --- a/test/Interop/Cxx/class/constructors-silgen.swift +++ b/test/Interop/Cxx/class/constructors-silgen.swift @@ -39,7 +39,7 @@ public func singleMemberTypeNoArgInit() { let i = IntWrapper() } -// CHECK-LABEL: sil shared [transparent] [serializable] [ossa] @$sSo10IntWrapperV1xABs5Int32V_tcfC : $@convention(method) (Int32, @thin IntWrapper.Type) -> IntWrapper +// CHECK-LABEL: sil shared [transparent] [serialized] [ossa] @$sSo10IntWrapperV1xABs5Int32V_tcfC : $@convention(method) (Int32, @thin IntWrapper.Type) -> IntWrapper // CHECK: bb0([[I:%[0-9]+]] : $Int32, %{{[0-9]+}} : $@thin IntWrapper.Type): // CHECK-NEXT: [[S:%.*]] = struct $IntWrapper ([[I]] : $Int32) // CHECK-NEXT: return [[S]] @@ -48,7 +48,7 @@ public func singleMemberTypeValueInit() { let i = IntWrapper(x: 42) } -// CHECK-LABEL: sil shared [transparent] [serializable] [ossa] @$sSo25DefaultConstructorDeletedV1aABSpys5Int32VG_tcfC : $@convention(method) (UnsafeMutablePointer, @thin DefaultConstructorDeleted.Type) -> DefaultConstructorDeleted +// CHECK-LABEL: sil shared [transparent] [serialized] [ossa] @$sSo25DefaultConstructorDeletedV1aABSpys5Int32VG_tcfC : $@convention(method) (UnsafeMutablePointer, @thin DefaultConstructorDeleted.Type) -> DefaultConstructorDeleted // CHECK: bb0([[A:%.*]] : $UnsafeMutablePointer // CHECK-NEXT: [[OUT:%.*]] = struct $DefaultConstructorDeleted ([[A]] : $UnsafeMutablePointer) // CHECK-NEXT: return [[OUT]] : $DefaultConstructorDeleted diff --git a/test/Interop/Cxx/class/type-classification-non-trivial-silgen.swift b/test/Interop/Cxx/class/type-classification-non-trivial-silgen.swift index 80e6ebe4d4ee9..03ce9a77487e0 100644 --- a/test/Interop/Cxx/class/type-classification-non-trivial-silgen.swift +++ b/test/Interop/Cxx/class/type-classification-non-trivial-silgen.swift @@ -80,7 +80,7 @@ public func testStructWithSubobjectCopyConstructorAndValue() -> Bool { } // StructWithSubobjectCopyConstructorAndValue.init(member:) -// CHECK-LABEL: sil shared [transparent] [serializable] [ossa] @$sSo42StructWithSubobjectCopyConstructorAndValueV6memberABSo0abdefG0V_tcfC : $@convention(method) (@in StructWithCopyConstructorAndValue, @thin StructWithSubobjectCopyConstructorAndValue.Type) -> @out StructWithSubobjectCopyConstructorAndValue +// CHECK-LABEL: sil shared [transparent] [serialized] [ossa] @$sSo42StructWithSubobjectCopyConstructorAndValueV6memberABSo0abdefG0V_tcfC : $@convention(method) (@in StructWithCopyConstructorAndValue, @thin StructWithSubobjectCopyConstructorAndValue.Type) -> @out StructWithSubobjectCopyConstructorAndValue // CHECK: [[MEMBER:%.*]] = struct_element_addr %0 : $*StructWithSubobjectCopyConstructorAndValue, #StructWithSubobjectCopyConstructorAndValue.member // CHECK: copy_addr [take] %1 to [initialization] [[MEMBER]] : $*StructWithCopyConstructorAndValue // CHECK-LABEL: end sil function '$sSo42StructWithSubobjectCopyConstructorAndValueV6memberABSo0abdefG0V_tcfC' diff --git a/test/Interop/Cxx/foreign-reference/singleton-silgen.swift b/test/Interop/Cxx/foreign-reference/singleton-silgen.swift index f5f68edbf2f08..51fc326ad4db6 100644 --- a/test/Interop/Cxx/foreign-reference/singleton-silgen.swift +++ b/test/Interop/Cxx/foreign-reference/singleton-silgen.swift @@ -38,4 +38,4 @@ public func test() { // CHECK-LABEL: sil [clang DeletedSpecialMembers.test] @{{_ZNK21DeletedSpecialMembers4testEv|\?test\@DeletedSpecialMembers\@\@QEBAHXZ}} : $@convention(cxx_method) (@in_guaranteed DeletedSpecialMembers) -> Int32 -// CHECK-LABEL: sil [serializable] [clang mutateIt] @{{_Z8mutateItR21DeletedSpecialMembers|\?mutateIt\@\@YAXAEAUDeletedSpecialMembers\@\@\@Z}} : $@convention(c) (DeletedSpecialMembers) -> () +// CHECK-LABEL: sil [serialized] [clang mutateIt] @{{_Z8mutateItR21DeletedSpecialMembers|\?mutateIt\@\@YAXAEAUDeletedSpecialMembers\@\@\@Z}} : $@convention(c) (DeletedSpecialMembers) -> () diff --git a/test/Interop/Cxx/templates/define-referenced-inline.swift b/test/Interop/Cxx/templates/define-referenced-inline.swift index e30b969fd23a9..c03cc0914ed31 100644 --- a/test/Interop/Cxx/templates/define-referenced-inline.swift +++ b/test/Interop/Cxx/templates/define-referenced-inline.swift @@ -1,9 +1,6 @@ // RUN: %target-run-simple-swift(-I %S/Inputs -Xfrontend -enable-cxx-interop -Xcc -fno-exceptions) // // REQUIRES: executable_test -// -// Enable this everywhere once we have a solution for modularizing libstdc++: rdar://87654514 -// REQUIRES: OS=macosx import DefineReferencedInline import StdlibUnittest diff --git a/test/Interop/Cxx/templates/dependent-types-silgen.swift b/test/Interop/Cxx/templates/dependent-types-silgen.swift index e47726870b3bd..631886e6d60a8 100644 --- a/test/Interop/Cxx/templates/dependent-types-silgen.swift +++ b/test/Interop/Cxx/templates/dependent-types-silgen.swift @@ -41,4 +41,4 @@ public func test() -> Int64 { } // CHECK-LABEL: sil [clang __CxxTemplateInst1MIxE.getValue] @{{_ZNK1MIxE8getValueEv|\?getValue@\?\$M@_J@@QEBA_JXZ}} : $@convention(cxx_method) (@in_guaranteed __CxxTemplateInst1MIxE) -> Int64 -// CHECK-LABEL: sil [serializable] [clang dependantReturnTypeInffered] @{{_Z27dependantReturnTypeInfferedIxE1MIT_ES1_|\?\?\$dependantReturnTypeInffered@_J@@YA\?AU\?\$M@_J@@_J@Z}} : $@convention(c) (Int64) -> __CxxTemplateInst1MIxE \ No newline at end of file +// CHECK-LABEL: sil [serialized] [clang dependantReturnTypeInffered] @{{_Z27dependantReturnTypeInfferedIxE1MIT_ES1_|\?\?\$dependantReturnTypeInffered@_J@@YA\?AU\?\$M@_J@@_J@Z}} : $@convention(c) (Int64) -> __CxxTemplateInst1MIxE diff --git a/test/Interop/Cxx/templates/dependent-types.swift b/test/Interop/Cxx/templates/dependent-types.swift index 8d0b97c90b02e..ee6dafd23bf87 100644 --- a/test/Interop/Cxx/templates/dependent-types.swift +++ b/test/Interop/Cxx/templates/dependent-types.swift @@ -2,8 +2,8 @@ // // REQUIRES: executable_test // -// For some reason this is failing on i386: rdar://89166707. -// XFAIL: CPU=i386 +// Failing on 32-bit platforms (rdar://89296327) (rdar://89166707) +// XFAIL: PTRSIZE=32 import DependentTypes import StdlibUnittest diff --git a/test/ModuleInterface/back-deploy-attr.swift b/test/ModuleInterface/back-deploy-attr.swift index eb6111bb19617..ac0d9bcc1b046 100644 --- a/test/ModuleInterface/back-deploy-attr.swift +++ b/test/ModuleInterface/back-deploy-attr.swift @@ -2,7 +2,9 @@ // Ensure @_backDeploy attributes and function bodies are printed in // swiftinterface files. -// RUN: %target-swiftc_driver -emit-module -o %t/Test.swiftmodule -emit-module-interface-path %t/Test.swiftinterface -enable-library-evolution -verify-emitted-module-interface -module-name Test %s +// RUN: %target-swiftc_driver -emit-module -o %t/Test.swiftmodule -emit-module-interface-path %t/Test.swiftinterface %s -enable-library-evolution -verify-emitted-module-interface -module-name Test \ +// RUN: -Xfrontend -define-availability -Xfrontend "_macOS12_1:macOS 12.1" \ +// RUN: -Xfrontend -define-availability -Xfrontend "_myProject 1.0:macOS 12.1, iOS 15.1" // RUN: %FileCheck %s --check-prefix FROMSOURCE --check-prefix CHECK < %t/Test.swiftinterface // FIXME(backDeploy): Remove this step in favor of a test that exercises using @@ -10,7 +12,9 @@ // Ensure @_backDeploy attributes and function bodies are present after // deserializing .swiftmodule files. -// RUN: %target-swift-frontend -emit-module -o /dev/null -merge-modules %t/Test.swiftmodule -disable-objc-attr-requires-foundation-module -emit-module-interface-path %t/TestFromModule.swiftinterface -module-name Test +// RUN: %target-swift-frontend -emit-module -o /dev/null -merge-modules %t/Test.swiftmodule -disable-objc-attr-requires-foundation-module -emit-module-interface-path %t/TestFromModule.swiftinterface -module-name Test \ +// RUN: -define-availability "_macOS12_1:macOS 12.1" \ +// RUN: -define-availability "_myProject 1.0:macOS 12.1, iOS 15.1" // RUN: %FileCheck %s --check-prefix FROMMODULE --check-prefix CHECK < %t/TestFromModule.swiftinterface public struct TopLevelStruct { @@ -66,10 +70,25 @@ public struct TopLevelStruct { } // CHECK: @_backDeploy(macOS 12.0) -// FROMSOURCE: public func backDeployTopLevelFunc() -> Swift.Int { return 47 } -// FROMMODULE: public func backDeployTopLevelFunc() -> Swift.Int +// FROMSOURCE: public func backDeployTopLevelFunc1() -> Swift.Int { return 47 } +// FROMMODULE: public func backDeployTopLevelFunc1() -> Swift.Int @available(macOS 11.0, *) @_backDeploy(macOS 12.0) -public func backDeployTopLevelFunc() -> Int { return 47 } +public func backDeployTopLevelFunc1() -> Int { return 47 } -// FIXME(backDeploy): Availability macros should be supported +// MARK: - Availability macros + +// CHECK: @_backDeploy(macOS 12.1) +// FROMSOURCE: public func backDeployTopLevelFunc2() -> Swift.Int { return 48 } +// FROMMODULE: public func backDeployTopLevelFunc2() -> Swift.Int +@available(macOS 11.0, *) +@_backDeploy(_macOS12_1) +public func backDeployTopLevelFunc2() -> Int { return 48 } + +// CHECK: @_backDeploy(macOS 12.1) +// CHECK: @_backDeploy(iOS 15.1) +// FROMSOURCE: public func backDeployTopLevelFunc3() -> Swift.Int { return 49 } +// FROMMODULE: public func backDeployTopLevelFunc3() -> Swift.Int +@available(macOS 11.0, iOS 14.0, *) +@_backDeploy(_myProject 1.0) +public func backDeployTopLevelFunc3() -> Int { return 49 } diff --git a/test/ModuleInterface/concurrency.swift b/test/ModuleInterface/concurrency.swift index 4d9cf8b029d6e..ecee6e3d4f966 100644 --- a/test/ModuleInterface/concurrency.swift +++ b/test/ModuleInterface/concurrency.swift @@ -14,6 +14,11 @@ public func reasyncFn(_: () async -> ()) reasync { fatalError() } +@available(SwiftStdlib 5.5, *) +public func takesSendable( + _ block: @Sendable @escaping () async throws -> Void +) { } + // RUN: %target-typecheck-verify-swift -enable-experimental-concurrency -I %t #else @@ -29,3 +34,7 @@ func callFn() async { // CHECK: // swift-module-flags:{{.*}} -enable-experimental-concurrency // CHECK: public func fn() async // CHECK: public func reasyncFn(_: () async -> ()) reasync +// CHECK: public func takesSendable(_ block: @escaping @Sendable () async throws -> + +// RUN: %target-swift-frontend -typecheck -enable-library-evolution -enable-experimental-concurrency -emit-module-interface-path %t/Library.swiftinterface -DLIBRARY -module-name Library %s -module-interface-preserve-types-as-written +// RUN: %FileCheck %s <%t/Library.swiftinterface diff --git a/test/Parse/original_defined_in_attr.swift b/test/Parse/original_defined_in_attr.swift index a71fa33d475e3..7e546ae9edb3f 100644 --- a/test/Parse/original_defined_in_attr.swift +++ b/test/Parse/original_defined_in_attr.swift @@ -7,20 +7,21 @@ public func foo() {} @_originallyDefinedIn(modulename: "foo", OSX 13.13) // expected-error {{expected 'module: "original"' in the first argument to @_originallyDefinedIn}} public func foo1() {} -@_originallyDefinedIn(module: "foo", OSX 13.13.3) // expected-warning {{@_originallyDefinedIn only uses major and minor version number}} expected-error {{'@_originallyDefinedIn' requires that 'ToplevelClass' have explicit availability for macOS}} +@_originallyDefinedIn(module: "foo", OSX 13.13.3) // expected-warning {{'@_originallyDefinedIn' only uses major and minor version number}} +// expected-error@-1 {{'@_originallyDefinedIn' requires that 'ToplevelClass' have explicit availability for macOS}} public class ToplevelClass {} -@_originallyDefinedIn(module: "foo") // expected-error {{expected at least one platform version in @_originallyDefinedIn}} +@_originallyDefinedIn(module: "foo") // expected-error {{expected at least one platform version in '@_originallyDefinedIn' attribute}} public class ToplevelClass1 {} @_originallyDefinedIn(OSX 13.13.3) // expected-error {{expected 'module: "original"' in the first argument to @_originallyDefinedIn}} public class ToplevelClass2 {} -@_originallyDefinedIn(module: "foo", // expected-error {{expected at least one platform version in @_originallyDefinedIn}} -public class ToplevelClass3 {} +@_originallyDefinedIn(module: "foo", +public class ToplevelClass3 {} // expected-error {{expected platform in '@_originallyDefinedIn' attribute}} @available(OSX 13.10, *) -@_originallyDefinedIn(module: "foo", * 13.13) // expected-warning {{* as platform name has no effect}} expected-error {{expected at least one platform version in @_originallyDefinedIn}} +@_originallyDefinedIn(module: "foo", * 13.13) // expected-warning {{* as platform name has no effect}} expected-error {{expected at least one platform version in '@_originallyDefinedIn' attribute}} @_originallyDefinedIn(module: "foo", OSX 13.13, iOS 7.0) @_originallyDefinedIn(module: "foo", OSX 13.14, * 7.0) // expected-warning {{* as platform name has no effect}} expected-error {{'@_originallyDefinedIn' contains multiple versions for macOS}} public class ToplevelClass4 { diff --git a/test/Prototypes/BigInt-windows.swift b/test/Prototypes/BigInt-windows.swift deleted file mode 100644 index 7a83d7ad2e145..0000000000000 --- a/test/Prototypes/BigInt-windows.swift +++ /dev/null @@ -1,13 +0,0 @@ -// This test is intentionally specialized on windows because `not --crash` -// behaves differently there: the exit code from the crashing frontend -// invocations is mapped to `-21` there, which lit's `not` along does not remap -// correctly. -// See rdar://problem/65251059 -// REQUIRES: OS=windows-msvc - -// RUN: %empty-directory(%t) -// RUN: not --crash %target-build-swift -swift-version 4 -o %t/a.out %S/BigInt.swift -// RUN: %target-run %t/a.out -// REQUIRES: executable_test -// REQUIRES: CPU=x86_64 -// XFAIL: asserts diff --git a/test/Prototypes/BigInt.swift b/test/Prototypes/BigInt.swift index 624dd7fafd667..3c88a46291d28 100644 --- a/test/Prototypes/BigInt.swift +++ b/test/Prototypes/BigInt.swift @@ -11,17 +11,12 @@ //===----------------------------------------------------------------------===// // RUN: %empty-directory(%t) -// RUN: %target-build-swift -swift-version 4 -o %t/a.out %s +// RUN: %target-build-swift -swift-version 4 -o %t/a.out %s -Xfrontend -requirement-machine-inferred-signatures=on -Xfrontend -requirement-machine-abstract-signatures=on -Xfrontend -requirement-machine-protocol-signatures=on // RUN: %target-codesign %t/a.out // RUN: %target-run %t/a.out // REQUIRES: executable_test // REQUIRES: CPU=x86_64 -// See rdar://problem/65251059 -// UNSUPPORTED: windows -// rdar://problem/65015626 -// XFAIL: asserts - import StdlibUnittest #if canImport(Darwin) import Darwin diff --git a/test/Reflection/typeref_decoding_objc.swift b/test/Reflection/typeref_decoding_objc.swift index 7ff16dcde4334..1459a965cb66a 100644 --- a/test/Reflection/typeref_decoding_objc.swift +++ b/test/Reflection/typeref_decoding_objc.swift @@ -3,6 +3,9 @@ // RUN: %target-swift-reflection-dump -binary-filename %t/%target-library-name(TypesToReflect) | %FileCheck %s --check-prefix=CHECK-%target-ptrsize --check-prefix=CHECK // REQUIRES: objc_interop +// Temporarily disable on arm64e (rdar://89986398) +// UNSUPPORTED: CPU=arm64e + // Disable asan builds until we build swift-reflection-dump and the reflection library with the same compile: rdar://problem/30406870 // REQUIRES: no_asan diff --git a/test/SIL/Parser/array_roundtrip.swift b/test/SIL/Parser/array_roundtrip.swift index 527b67da0a639..b4178c46ea0db 100644 --- a/test/SIL/Parser/array_roundtrip.swift +++ b/test/SIL/Parser/array_roundtrip.swift @@ -1,4 +1,4 @@ -// RUN: %target-swift-frontend %s -emit-sil -Ounchecked -Xllvm -sil-disable-pass=cmo | %target-sil-opt +// RUN: %target-swift-frontend %s -emit-sil -Ounchecked -Xllvm -sil-disable-pass=cmo | %target-sil-opt -parse-serialized-sil // Fails if the positions of the two Collection subscript requirements are // reversed. rdar://problem/46650834 diff --git a/test/SIL/Parser/basic.sil b/test/SIL/Parser/basic.sil index 52dd16c3707a8..4a92177607135 100644 --- a/test/SIL/Parser/basic.sil +++ b/test/SIL/Parser/basic.sil @@ -1355,13 +1355,6 @@ bb0: return %0 : $() } -// CHECK-LABEL: sil shared_external @test_shared_external_definition : $@convention(thin) () -> () { -sil shared_external @test_shared_external_definition : $@convention(thin) () -> () { -bb0: - %0 = tuple () - return %0 : $() -} - // CHECK-LABEL: sil @select_enum : $@convention(thin) (@in Beth) -> () { sil @select_enum : $@convention(thin) (@in Beth) -> () { bb0(%0 : $*Beth): diff --git a/test/SIL/Parser/linkage.sil b/test/SIL/Parser/linkage.sil index e3d226bc0993b..2500aa5fc875c 100644 --- a/test/SIL/Parser/linkage.sil +++ b/test/SIL/Parser/linkage.sil @@ -12,8 +12,8 @@ bb0: return %0 : $() } -// CHECK-LABEL: sil non_abi @always_emit_into_client_definition : $@convention(thin) () -> () -sil non_abi @always_emit_into_client_definition : $() -> () { +// CHECK-LABEL: sil non_abi [serialized] @always_emit_into_client_definition : $@convention(thin) () -> () +sil non_abi [serialized] @always_emit_into_client_definition : $() -> () { bb0: %0 = tuple () return %0 : $() @@ -40,8 +40,8 @@ bb0: return %0 : $() } -// CHECK-LABEL: sil public_external @public_available_externally_definition : $@convention(thin) () -> () -sil public_external @public_available_externally_definition : $() -> () { +// CHECK-LABEL: sil public_external [serialized] @public_available_externally_definition : $@convention(thin) () -> () +sil public_external [serialized] @public_available_externally_definition : $() -> () { bb0: %0 = tuple () return %0 : $() diff --git a/test/SIL/Parser/without_actually_escaping.sil b/test/SIL/Parser/without_actually_escaping.sil index cd45ceadb88b4..8eb0e7e9a2ec9 100644 --- a/test/SIL/Parser/without_actually_escaping.sil +++ b/test/SIL/Parser/without_actually_escaping.sil @@ -2,8 +2,8 @@ // thunk for @escaping @callee_guaranteed () -> () // Check that the [without_actually_escaping] thunk attribute is parsed and printed. -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [without_actually_escaping] [ossa] @testWithoutActuallyEscapingThunk : $@convention(thin) (@guaranteed @callee_guaranteed () -> ()) -> () { -sil shared [transparent] [serializable] [reabstraction_thunk] [without_actually_escaping] [ossa] @testWithoutActuallyEscapingThunk : $@convention(thin) (@guaranteed @callee_guaranteed () -> ()) -> () { +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [without_actually_escaping] [ossa] @testWithoutActuallyEscapingThunk : $@convention(thin) (@guaranteed @callee_guaranteed () -> ()) -> () { +sil shared [transparent] [serialized] [reabstraction_thunk] [without_actually_escaping] [ossa] @testWithoutActuallyEscapingThunk : $@convention(thin) (@guaranteed @callee_guaranteed () -> ()) -> () { bb0(%0 : @guaranteed $@callee_guaranteed () -> ()): %1 = apply %0() : $@callee_guaranteed () -> () return %1 : $() diff --git a/test/SIL/Serialization/boxes.sil b/test/SIL/Serialization/boxes.sil index 1e4df3b4a3f55..c04dbedf0c9fa 100644 --- a/test/SIL/Serialization/boxes.sil +++ b/test/SIL/Serialization/boxes.sil @@ -17,8 +17,8 @@ struct Q: P {} // TODO: Transform boxes by transforming their arguments, not as single-field, // so that they work as parameters in generic SIL functions. -// CHECK-LABEL: sil hidden [serialized] [ossa] @AA_box_type_parsing : $@convention(thin) ( -sil hidden [serialized] [ossa] @AA_box_type_parsing : $@convention(thin) ( +// CHECK-LABEL: sil hidden [ossa] @AA_box_type_parsing : $@convention(thin) ( +sil hidden [ossa] @AA_box_type_parsing : $@convention(thin) ( // CHECK: <τ_0_0> { var τ_0_0 } , { var B }, // CHECK: <τ_0_0 where τ_0_0 : P> { let τ_0_0 } , @@ -39,8 +39,8 @@ entry(%0 : @unowned ${ var E }, %1 : @unowned ${ let F }, %2 : @u unreachable } -// CHECK-LABEL: sil hidden [serialized] [ossa] @BB_box_type_parsing_in_generic_function : $@convention(thin) ( -sil hidden [serialized] [ossa] @BB_box_type_parsing_in_generic_function : $@convention(thin) ( +// CHECK-LABEL: sil hidden [ossa] @BB_box_type_parsing_in_generic_function : $@convention(thin) ( +sil hidden [ossa] @BB_box_type_parsing_in_generic_function : $@convention(thin) ( // CHECK: <τ_0_0> { var τ_0_0 } , { var B }, // CHECK: <τ_0_0 where τ_0_0 : P> { let τ_0_0 } , @@ -61,8 +61,8 @@ entry(%0 : @unowned ${ var E }, %1 : @unowned ${ let F }, %2 : @u unreachable } -// CHECK-LABEL: sil hidden [serialized] [ossa] @CC_same_generic_param_name_in_multiple_box_signatures : $@convention(thin) ( -sil hidden [serialized] [ossa] @CC_same_generic_param_name_in_multiple_box_signatures : $@convention(thin) ( +// CHECK-LABEL: sil hidden [ossa] @CC_same_generic_param_name_in_multiple_box_signatures : $@convention(thin) ( +sil hidden [ossa] @CC_same_generic_param_name_in_multiple_box_signatures : $@convention(thin) ( // CHECK: <τ_0_0> { var τ_0_0 } , { var A } , // CHECK: <τ_0_0> { var τ_0_0 } @@ -73,8 +73,8 @@ entry(%0 : @unowned $ { var A } , %1 : @unowned $ { var A } ) unreachable } -// CHECK-LABEL: sil hidden [serialized] [ossa] @DD_same_generic_param_name_in_outer_scope : $@convention(thin) ( -sil hidden [serialized] [ossa] @DD_same_generic_param_name_in_outer_scope : $@convention(thin) ( +// CHECK-LABEL: sil hidden [ossa] @DD_same_generic_param_name_in_outer_scope : $@convention(thin) ( +sil hidden [ossa] @DD_same_generic_param_name_in_outer_scope : $@convention(thin) ( // CHECK: <τ_0_0> { var τ_0_0 } { var A } // CHECK: ) -> () @@ -83,20 +83,20 @@ entry(%0 : @unowned $ { var B } ): unreachable } -// CHECK-LABEL: sil hidden [serialized] [ossa] @EE_box_ownership : $@convention(thin) (@owned { var Int }, @guaranteed <τ_0_0> { let τ_0_0 } ) -> () -sil hidden [serialized ] [ossa] @EE_box_ownership : $@convention(thin) (@owned { var Int }, @guaranteed { let T } ) -> () { +// CHECK-LABEL: sil hidden [ossa] @EE_box_ownership : $@convention(thin) (@owned { var Int }, @guaranteed <τ_0_0> { let τ_0_0 } ) -> () +sil hidden [ossa] @EE_box_ownership : $@convention(thin) (@owned { var Int }, @guaranteed { let T } ) -> () { entry(%0 : @owned ${ var Int }, %1 : @guaranteed $ { let T } ): unreachable } -// CHECK-LABEL: sil hidden [serialized] [ossa] @FF_address_of_box -sil hidden [serialized] [ossa] @FF_address_of_box : $@convention(thin) (@in { var Int }, @in { let T } ) -> () { +// CHECK-LABEL: sil hidden [ossa] @FF_address_of_box +sil hidden [ossa] @FF_address_of_box : $@convention(thin) (@in { var Int }, @in { let T } ) -> () { // CHECK: %0 : $*{ var Int }, %1 : $*<τ_0_0> { let τ_0_0 } entry(%0 : $*{ var Int }, %1 : $* { let T } ): unreachable } -sil [serialized] @serialize_all : $@convention(thin) () -> () { +sil @serialize_all : $@convention(thin) () -> () { entry: %0 = function_ref @AA_box_type_parsing : $@convention(thin) ({ var B }, { let C }, { var D }, { let Int }, { var Int, let String }, {}, { var X, let Z }>) -> () %1 = function_ref @BB_box_type_parsing_in_generic_function : $@convention(thin) ({ var B }, { let C }, { var D }, { let Int }, { var Int, let String }, {}, { var X, let Z }>) -> () diff --git a/test/SIL/Serialization/function-global-function.sil b/test/SIL/Serialization/function-global-function.sil index 98c3ae38de89a..eb31e4bcb179e 100644 --- a/test/SIL/Serialization/function-global-function.sil +++ b/test/SIL/Serialization/function-global-function.sil @@ -19,7 +19,7 @@ bb0: return %7 : $() } -sil shared [serializable] @calledFromFuncPtr : $@convention(thin) () -> () { +sil shared [serialized] @calledFromFuncPtr : $@convention(thin) () -> () { bb0: %6 = tuple () return %6 : $() diff --git a/test/SIL/Serialization/opaque_values_serialize.sil b/test/SIL/Serialization/opaque_values_serialize.sil index a2d572623c5e6..376e5202f7b2b 100644 --- a/test/SIL/Serialization/opaque_values_serialize.sil +++ b/test/SIL/Serialization/opaque_values_serialize.sil @@ -87,8 +87,8 @@ bb0(%0 : $Foo): // Test @in/@out serialization. // ---- -// CHECK-LABEL: sil hidden [serialized] @serialize_identity : $@convention(thin) (@in T) -> @out T { -sil hidden [serialized] @serialize_identity : $@convention(thin) (@in T) -> @out T { +// CHECK-LABEL: sil [serialized] @serialize_identity : $@convention(thin) (@in T) -> @out T { +sil [serialized] @serialize_identity : $@convention(thin) (@in T) -> @out T { // CHECK: bb0(%0 : $T): bb0(%0 : $T): // CHECK: return %0 : $T @@ -101,8 +101,8 @@ bb0(%0 : $T): sil @doWithS : $@convention(method) (S) -> () -// CHECK-LABEL: sil hidden [transparent] [serialized] [thunk] @serialize_mutating : $@convention(witness_method: Foo) (@in_guaranteed S) -> () { -sil hidden [transparent] [serialized] [thunk] @serialize_mutating : $@convention(witness_method: Foo) (@in_guaranteed S) -> () { +// CHECK-LABEL: sil [transparent] [serialized] [thunk] @serialize_mutating : $@convention(witness_method: Foo) (@in_guaranteed S) -> () { +sil [transparent] [serialized] [thunk] @serialize_mutating : $@convention(witness_method: Foo) (@in_guaranteed S) -> () { // CHECK: bb0(%0 : $S): bb0(%0 : $S): %f = function_ref @doWithS : $@convention(method) (S) -> () diff --git a/test/SIL/Serialization/public_external.sil b/test/SIL/Serialization/public_external.sil index c0babe9f02511..77cead0ad015f 100644 --- a/test/SIL/Serialization/public_external.sil +++ b/test/SIL/Serialization/public_external.sil @@ -25,27 +25,27 @@ import Builtin // Some functions are marked transparent to prevent ExternalDefsToDecls opt from // converting them into declarations. -sil public_external @pe : $@convention(thin) () -> () { +sil public_external [serialized] @pe : $@convention(thin) () -> () { %0 = tuple() return %0 : $() } -sil public_external [transparent] @transparent_pe : $@convention(thin) () -> () { +sil public_external [serialized] [transparent] @transparent_pe : $@convention(thin) () -> () { %0 = tuple() return %0 : $() } -sil hidden_external @he : $@convention(thin) () -> () { +sil hidden @he : $@convention(thin) () -> () { %0 = tuple() return %0 : $() } -sil hidden_external [transparent] @tranparent_he : $@convention(thin) () -> () { +sil hidden [transparent] @tranparent_he : $@convention(thin) () -> () { %0 = tuple() return %0 : $() } -sil shared_external @se : $@convention(thin) () -> () { +sil shared @se : $@convention(thin) () -> () { %0 = tuple() return %0 : $() } @@ -56,32 +56,32 @@ sil shared_external @se : $@convention(thin) () -> () { // do not serialize even their declrations. // CHECK-NOT: sil{{.*}}@fn1 : $@convention(thin) () -> () -sil public_external [noinline] @fn1 : $@convention(thin) () -> () { +sil public_external [serialized] [noinline] @fn1 : $@convention(thin) () -> () { %0 = tuple() return %0 : $() } // CHECK-NOT: sil{{.*}}@fn2: $@convention(thin) () -> () -sil public_external [noinline] @fn2 : $@convention(thin) () -> () { +sil public_external [serialized] [noinline] @fn2 : $@convention(thin) () -> () { %0 = tuple() return %0 : $() } // CHECK-NOT: sil{{.*}}@fn3 : $@convention(thin) () -> () -sil public_external [noinline] @fn3 : $@convention(thin) () -> () { +sil public_external [serialized] [noinline] @fn3 : $@convention(thin) () -> () { %0 = tuple() return %0 : $() } // CHECK-NOT: sil{{.*}}@fn4 : $@convention(thin) () -> () -sil public_external [noinline] @fn4 : $@convention(thin) () -> () { +sil public_external [serialized] [noinline] @fn4 : $@convention(thin) () -> () { %0 = tuple() return %0 : $() } // Emit the declaration of this function, because it is referenced from serialized // function use_external_functions. -sil public_external [noinline] @used_external_fn : $@convention(thin) () -> () { +sil public_external [serialized] [noinline] @used_external_fn : $@convention(thin) () -> () { %0 = tuple() return %0 : $() } @@ -94,7 +94,7 @@ sil public_external [noinline] @used_external_fn : $@convention(thin) () -> () { // CHECK-NOT: sil{{.*}}@public_external_fn : $@convention(thin) () -> () { // But declaration should be present. // CHECK: sil{{.*}}@public_external_fn : $@convention(thin) () -> () -sil public_external [noinline] @public_external_fn : $@convention(thin) () -> () { +sil public_external [serialized] [noinline] @public_external_fn : $@convention(thin) () -> () { %0 = function_ref @fn1 : $@convention(thin) () -> () %1 = apply %0 () : $@convention(thin) () -> () %2 = function_ref @fn2 : $@convention(thin) () -> () diff --git a/test/SIL/Serialization/public_non_abi.sil b/test/SIL/Serialization/public_non_abi.sil index c43403da326af..dee6123d43774 100644 --- a/test/SIL/Serialization/public_non_abi.sil +++ b/test/SIL/Serialization/public_non_abi.sil @@ -20,11 +20,11 @@ bb0: } // Make sure the function body is deserialized. -// CHECK-LABEL: sil shared_external @public_non_abi_function : $@convention(thin) () -> () +// CHECK-LABEL: sil shared @public_non_abi_function : $@convention(thin) () -> () // CHECK: function_ref @other_public_non_abi_function // CHECK: return sil hidden_external [serialized] @public_non_abi_function : $@convention(thin) () -> () // Make sure the function body is deserialized. -// CHECK-LABEL: sil shared_external @other_public_non_abi_function : $@convention(thin) () -> () +// CHECK-LABEL: sil shared @other_public_non_abi_function : $@convention(thin) () -> () // CHECK: return diff --git a/test/SIL/Serialization/shared_function_serialization.sil b/test/SIL/Serialization/shared_function_serialization.sil index 350cba1fde203..39eaa0c5b7314 100644 --- a/test/SIL/Serialization/shared_function_serialization.sil +++ b/test/SIL/Serialization/shared_function_serialization.sil @@ -5,7 +5,7 @@ // CHECK: sil private @top_level_code // CHECK: sil public_external [serialized] [ossa] @$ss1XVABycfC{{.*}} // CHECK: sil public_external [serialized] [ossa] @$ss17the_thing_it_does1xys1XV_tF{{.*}} -// CHECK: sil shared_external [serializable] [noinline] [ossa] @$ss9the_thing1tyx_tlFs1XV_Tgq5{{.*}} +// CHECK: sil shared [serialized] [noinline] [ossa] @$ss9the_thing1tyx_tlFs1XV_Tgq5{{.*}} sil_stage canonical diff --git a/test/SIL/Serialization/visibility.sil b/test/SIL/Serialization/visibility.sil index 57a0072a4105d..5bb0de450cda3 100644 --- a/test/SIL/Serialization/visibility.sil +++ b/test/SIL/Serialization/visibility.sil @@ -8,10 +8,7 @@ import Builtin // positive/negative checks to simplify things. // NEG-CHECK-NOT: sil_global private @private_global : $Builtin.Word -// NEG-CHECK-NOT: sil private @private_function : $@convention(thin) () -> () // NEG-CHECK-NOT: sil @references_private_global : $@convention(thin) () -> () { -// NEG-CHECK-NOT: sil @references_private_function : $@convention(thin) () -> () { -// NEG-CHECK-NOT: sil private @private_function_test : $@convention(thin) () -> () // Check Global Variables. // CHECK-DAG: sil_global shared [serialized] @shared_global : $Builtin.Word @@ -21,41 +18,26 @@ import Builtin // Check that all functions are defined/declared appropriately. // NEG-CHECK-NOT: sil [serialized] @public_external_function_test : $@convention(thin) () -> () { // CHECK-DAG: sil [serialized] [canonical] @public_external_function_test : $@convention(thin) () -> () -// CHECK-DAG: sil hidden [serialized] [canonical] @hidden_function_test : $@convention(thin) () -> () { // CHECK-DAG: sil [serialized] [canonical] @references_public_function : $@convention(thin) () -> () { // CHECK-DAG: sil [serialized] [canonical] @references_shared_function : $@convention(thin) () -> () { -// CHECK-DAG: sil [serialized] [canonical] @references_hidden_function : $@convention(thin) () -> () { -// CHECK-DAG: sil [serialized] [canonical] @references_private_function : $@convention(thin) () -> () // CHECK-DAG: sil [serialized] [canonical] @references_public_global : $@convention(thin) () -> () { // CHECK-DAG: sil [serialized] [canonical] @references_shared_global : $@convention(thin) () -> () { // CHECK-DAG: sil [serialized] [canonical] @references_hidden_global : $@convention(thin) () -> () { // CHECK-DAG: sil [serialized] [canonical] @references_private_global : $@convention(thin) () -> () -// CHECK-DAG: sil hidden_external [serialized] [canonical] @hidden_external_function_test : $@convention(thin) () -> () // CHECK-DAG: sil [serialized] [canonical] @public_function_test : $@convention(thin) () -> () { // CHECK-DAG: sil [serialized] [canonical] @public_function : $@convention(thin) () -> () { -// CHECK-DAG: sil hidden [serialized] [canonical] @hidden_function : $@convention(thin) () -> () { -// CHECK-DAG: sil shared_external [serialized] [canonical] @shared_external_function_test : $@convention(thin) () -> () +// CHECK-DAG: sil shared [serialized] [canonical] @shared_external_function_test : $@convention(thin) () -> () sil_global private [serialized] @private_global : $Builtin.Word sil_global [serialized] @public_global : $Builtin.Word sil_global shared [serialized] @shared_global : $Builtin.Word sil_global hidden [serialized] @hidden_global : $Builtin.Word -sil private [serialized] @private_function : $@convention(thin) () -> () { - %0 = integer_literal $Builtin.Int32, 0 - %1 = tuple() - return %1 : $() -} sil [serialized] @references_private_global : $@convention(thin) () -> () { %0 = global_addr @private_global : $*Builtin.Word %1 = tuple() return %1 : $() } -sil [serialized] @references_private_function : $@convention(thin) () -> () { - %0 = function_ref @private_function : $@convention(thin) () -> () - %1 = tuple() - return %1 : $() -} sil shared [serialized] @shared_function : $@convention(thin) () -> () { %0 = integer_literal $Builtin.Int32, 1 @@ -73,22 +55,11 @@ sil [serialized] @references_shared_function : $@convention(thin) () -> () { return %1 : $() } -sil hidden [serialized] @hidden_function : $@convention(thin) () -> () { - %0 = integer_literal $Builtin.Int32, 2 - %1 = tuple() - return %1 : $() -} sil [serialized] @references_hidden_global : $@convention(thin) () -> () { %0 = global_addr @hidden_global : $*Builtin.Word %1 = tuple() return %1 : $() } -sil [serialized] @references_hidden_function : $@convention(thin) () -> () { - %0 = function_ref @hidden_function : $@convention(thin) () -> () - %1 = tuple() - return %1 : $() -} - sil [serialized] @public_function : $@convention(thin) () -> () { %0 = integer_literal $Builtin.Int32, 4 %1 = tuple() @@ -106,61 +77,15 @@ sil [serialized] @references_public_function : $@convention(thin) () -> () { return %1 : $() } -sil private [serialized] @private_function_test : $@convention(thin) () -> () { - %0 = function_ref @references_public_function : $@convention(thin) () -> () - %1 = function_ref @references_shared_function : $@convention(thin) () -> () - %2 = function_ref @references_hidden_function : $@convention(thin) () -> () - %3 = function_ref @references_private_function : $@convention(thin) () -> () - %4 = function_ref @references_public_global : $@convention(thin) () -> () - %5 = function_ref @references_shared_global : $@convention(thin) () -> () - %6 = function_ref @references_hidden_global : $@convention(thin) () -> () - %7 = function_ref @references_private_global : $@convention(thin) () -> () - apply %0() : $@convention(thin) () -> () - apply %1() : $@convention(thin) () -> () - apply %2() : $@convention(thin) () -> () - apply %3() : $@convention(thin) () -> () - apply %4() : $@convention(thin) () -> () - apply %5() : $@convention(thin) () -> () - apply %6() : $@convention(thin) () -> () - apply %7() : $@convention(thin) () -> () - %8 = tuple() - return %8 : $() -} - sil shared [serialized] @shared_function_test : $@convention(thin) () -> () { %0 = function_ref @references_public_function : $@convention(thin) () -> () %1 = function_ref @references_shared_function : $@convention(thin) () -> () - %2 = function_ref @references_hidden_function : $@convention(thin) () -> () - %3 = function_ref @references_private_function : $@convention(thin) () -> () %4 = function_ref @references_public_global : $@convention(thin) () -> () %5 = function_ref @references_shared_global : $@convention(thin) () -> () %6 = function_ref @references_hidden_global : $@convention(thin) () -> () %7 = function_ref @references_private_global : $@convention(thin) () -> () apply %0() : $@convention(thin) () -> () apply %1() : $@convention(thin) () -> () - apply %2() : $@convention(thin) () -> () - apply %3() : $@convention(thin) () -> () - apply %4() : $@convention(thin) () -> () - apply %5() : $@convention(thin) () -> () - apply %6() : $@convention(thin) () -> () - apply %7() : $@convention(thin) () -> () - %8 = tuple() - return %8 : $() -} - -sil hidden [serialized] @hidden_function_test : $@convention(thin) () -> () { - %0 = function_ref @references_public_function : $@convention(thin) () -> () - %1 = function_ref @references_shared_function : $@convention(thin) () -> () - %2 = function_ref @references_hidden_function : $@convention(thin) () -> () - %3 = function_ref @references_private_function : $@convention(thin) () -> () - %4 = function_ref @references_public_global : $@convention(thin) () -> () - %5 = function_ref @references_shared_global : $@convention(thin) () -> () - %6 = function_ref @references_hidden_global : $@convention(thin) () -> () - %7 = function_ref @references_private_global : $@convention(thin) () -> () - apply %0() : $@convention(thin) () -> () - apply %1() : $@convention(thin) () -> () - apply %2() : $@convention(thin) () -> () - apply %3() : $@convention(thin) () -> () apply %4() : $@convention(thin) () -> () apply %5() : $@convention(thin) () -> () apply %6() : $@convention(thin) () -> () @@ -172,37 +97,12 @@ sil hidden [serialized] @hidden_function_test : $@convention(thin) () -> () { sil [serialized] @public_function_test : $@convention(thin) () -> () { %0 = function_ref @references_public_function : $@convention(thin) () -> () %1 = function_ref @references_shared_function : $@convention(thin) () -> () - %2 = function_ref @references_hidden_function : $@convention(thin) () -> () - %3 = function_ref @references_private_function : $@convention(thin) () -> () - %4 = function_ref @references_public_global : $@convention(thin) () -> () - %5 = function_ref @references_shared_global : $@convention(thin) () -> () - %6 = function_ref @references_hidden_global : $@convention(thin) () -> () - %7 = function_ref @references_private_global : $@convention(thin) () -> () - apply %0() : $@convention(thin) () -> () - apply %1() : $@convention(thin) () -> () - apply %2() : $@convention(thin) () -> () - apply %3() : $@convention(thin) () -> () - apply %4() : $@convention(thin) () -> () - apply %5() : $@convention(thin) () -> () - apply %6() : $@convention(thin) () -> () - apply %7() : $@convention(thin) () -> () - %8 = tuple() - return %8 : $() -} - -sil hidden_external [serialized] @hidden_external_function_test : $@convention(thin) () -> () { - %0 = function_ref @references_public_function : $@convention(thin) () -> () - %1 = function_ref @references_shared_function : $@convention(thin) () -> () - %2 = function_ref @references_hidden_function : $@convention(thin) () -> () - %3 = function_ref @references_private_function : $@convention(thin) () -> () %4 = function_ref @references_public_global : $@convention(thin) () -> () %5 = function_ref @references_shared_global : $@convention(thin) () -> () %6 = function_ref @references_hidden_global : $@convention(thin) () -> () %7 = function_ref @references_private_global : $@convention(thin) () -> () apply %0() : $@convention(thin) () -> () apply %1() : $@convention(thin) () -> () - apply %2() : $@convention(thin) () -> () - apply %3() : $@convention(thin) () -> () apply %4() : $@convention(thin) () -> () apply %5() : $@convention(thin) () -> () apply %6() : $@convention(thin) () -> () @@ -211,26 +111,16 @@ sil hidden_external [serialized] @hidden_external_function_test : $@convention(t return %8 : $() } -sil [serialized] @hidden_external_function_test_caller : $@convention(thin) () -> () { - %0 = function_ref @hidden_external_function_test : $@convention(thin) () -> () - %1 = apply %0() : $@convention(thin) () -> () - %2 = tuple() - return %2 : $() -} sil public_external [serialized] @public_external_function_test : $@convention(thin) () -> () { %0 = function_ref @references_public_function : $@convention(thin) () -> () %1 = function_ref @references_shared_function : $@convention(thin) () -> () - %2 = function_ref @references_hidden_function : $@convention(thin) () -> () - %3 = function_ref @references_private_function : $@convention(thin) () -> () %4 = function_ref @references_public_global : $@convention(thin) () -> () %5 = function_ref @references_shared_global : $@convention(thin) () -> () %6 = function_ref @references_hidden_global : $@convention(thin) () -> () %7 = function_ref @references_private_global : $@convention(thin) () -> () apply %0() : $@convention(thin) () -> () apply %1() : $@convention(thin) () -> () - apply %2() : $@convention(thin) () -> () - apply %3() : $@convention(thin) () -> () apply %4() : $@convention(thin) () -> () apply %5() : $@convention(thin) () -> () apply %6() : $@convention(thin) () -> () @@ -246,19 +136,15 @@ sil [serialized] @public_external_function_test_caller : $@convention(thin) () - return %2 : $() } -sil shared_external [serialized] @shared_external_function_test : $@convention(thin) () -> () { +sil shared [serialized] @shared_external_function_test : $@convention(thin) () -> () { %0 = function_ref @references_public_function : $@convention(thin) () -> () %1 = function_ref @references_shared_function : $@convention(thin) () -> () - %2 = function_ref @references_hidden_function : $@convention(thin) () -> () - %3 = function_ref @references_private_function : $@convention(thin) () -> () %4 = function_ref @references_public_global : $@convention(thin) () -> () %5 = function_ref @references_shared_global : $@convention(thin) () -> () %6 = function_ref @references_hidden_global : $@convention(thin) () -> () %7 = function_ref @references_private_global : $@convention(thin) () -> () apply %0() : $@convention(thin) () -> () apply %1() : $@convention(thin) () -> () - apply %2() : $@convention(thin) () -> () - apply %3() : $@convention(thin) () -> () apply %4() : $@convention(thin) () -> () apply %5() : $@convention(thin) () -> () apply %6() : $@convention(thin) () -> () diff --git a/test/SIL/Serialization/without_actually_escaping.sil b/test/SIL/Serialization/without_actually_escaping.sil index e9b97b4e6396e..03d6569aea6ba 100644 --- a/test/SIL/Serialization/without_actually_escaping.sil +++ b/test/SIL/Serialization/without_actually_escaping.sil @@ -6,8 +6,8 @@ // thunk for @escaping @callee_guaranteed () -> () // Check that the [without_actually_escaping] thunk attribute is parsed and printed. -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [without_actually_escaping] [ossa] @f1_testWithoutActuallyEscapingThunk : $@convention(thin) (@guaranteed @callee_guaranteed () -> ()) -> () { -sil shared [transparent] [serializable] [reabstraction_thunk] [without_actually_escaping] [ossa] @f1_testWithoutActuallyEscapingThunk : $@convention(thin) (@guaranteed @callee_guaranteed () -> ()) -> () { +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [without_actually_escaping] [ossa] @f1_testWithoutActuallyEscapingThunk : $@convention(thin) (@guaranteed @callee_guaranteed () -> ()) -> () { +sil shared [transparent] [serialized] [reabstraction_thunk] [without_actually_escaping] [ossa] @f1_testWithoutActuallyEscapingThunk : $@convention(thin) (@guaranteed @callee_guaranteed () -> ()) -> () { bb0(%0 : @guaranteed $@callee_guaranteed () -> ()): %1 = apply %0() : $@callee_guaranteed () -> () return %1 : $() diff --git a/test/SIL/printer_include_decls.swift b/test/SIL/printer_include_decls.swift index 9e53c13673a42..be9f7abf87b66 100644 --- a/test/SIL/printer_include_decls.swift +++ b/test/SIL/printer_include_decls.swift @@ -1,7 +1,7 @@ // RUN: rm -f %t.* // RUN: %target-swift-frontend -emit-sil %s -o %t.sil // RUN: %FileCheck --input-file=%t.sil %s -// RUN: %target-swift-frontend -emit-silgen %t.sil -module-name=printer_include_decl | %FileCheck %s +// RUN: %target-swift-frontend -Xllvm -parse-serialized-sil -emit-silgen %t.sil -module-name=printer_include_decl | %FileCheck %s var x: Int // CHECK: var x: Int diff --git a/test/SILGen/SILDeclRef.swift b/test/SILGen/SILDeclRef.swift index 41184c7e88a6a..1624c3f1dc029 100644 --- a/test/SILGen/SILDeclRef.swift +++ b/test/SILGen/SILDeclRef.swift @@ -1,5 +1,5 @@ // RUN: %target-swift-emit-sil %s | %FileCheck %s -// RUN: %target-swift-emit-sil %s | %target-sil-opt -enable-sil-verify-all -module-name="SILDeclRef" - | %FileCheck %s +// RUN: %target-swift-emit-sil %s | %target-sil-opt -parse-serialized-sil -enable-sil-verify-all -module-name="SILDeclRef" - | %FileCheck %s // Check that all SILDeclRefs are represented in the text form with a signature. // This allows to avoid ambiguities which sometimes arise e.g. when a diff --git a/test/SILGen/c_modify_linkage.swift b/test/SILGen/c_modify_linkage.swift index d6b655b59decb..ba88652dcc498 100644 --- a/test/SILGen/c_modify_linkage.swift +++ b/test/SILGen/c_modify_linkage.swift @@ -14,8 +14,8 @@ extension NSReferencePoint: Pointable {} // Make sure synthesized modify accessors have shared linkage // for properties imported from Clang. -// CHECK-LABEL: sil shared [serializable] [ossa] @$sSo7NSPointV1ySfvM +// CHECK-LABEL: sil shared [serialized] [ossa] @$sSo7NSPointV1ySfvM -// CHECK-LABEL: sil shared [serializable] [ossa] @$sSo16NSReferencePointC1xSfvM +// CHECK-LABEL: sil shared [serialized] [ossa] @$sSo16NSReferencePointC1xSfvM -// CHECK-LABEL: sil shared [serializable] [ossa] @$sSo16NSReferencePointC1ySfvM +// CHECK-LABEL: sil shared [serialized] [ossa] @$sSo16NSReferencePointC1ySfvM diff --git a/test/SILGen/cdecl.swift b/test/SILGen/cdecl.swift index 7099c98148c69..a42de840936b5 100644 --- a/test/SILGen/cdecl.swift +++ b/test/SILGen/cdecl.swift @@ -21,7 +21,7 @@ func orange(_ x: Int) -> Int { return x } -// CHECK-LABEL: sil [serializable] [thunk] [ossa] @cauliflower : $@convention(c) +// CHECK-LABEL: sil [serialized] [thunk] [ossa] @cauliflower : $@convention(c) // CHECK: function_ref @$s5cdecl8broccoli{{[_0-9a-zA-Z]*}}F // CHECK-LABEL: sil [ossa] @$s5cdecl8broccoli{{[_0-9a-zA-Z]*}}F @_cdecl("cauliflower") diff --git a/test/SILGen/cf.swift b/test/SILGen/cf.swift index 82f3d6a6185fa..40fe68a1cc330 100644 --- a/test/SILGen/cf.swift +++ b/test/SILGen/cf.swift @@ -58,9 +58,9 @@ protocol Impedance { extension CCImpedance: Impedance {} // CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$sSo11CCImpedanceV2cf9ImpedanceA2cDP4real9ComponentQzvgTW -// CHECK-LABEL: sil shared [transparent] [serializable] [ossa] @$sSo11CCImpedanceV4realSdvg +// CHECK-LABEL: sil shared [transparent] [serialized] [ossa] @$sSo11CCImpedanceV4realSdvg // CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$sSo11CCImpedanceV2cf9ImpedanceA2cDP4imag9ComponentQzvgTW -// CHECK-LABEL: sil shared [transparent] [serializable] [ossa] @$sSo11CCImpedanceV4imagSdvg +// CHECK-LABEL: sil shared [transparent] [serialized] [ossa] @$sSo11CCImpedanceV4imagSdvg class MyMagnetism : CCMagnetismModel { // CHECK-LABEL: sil hidden [thunk] [ossa] @$s2cf11MyMagnetismC15getRefrigerator{{[_0-9a-zA-Z]*}}FTo : $@convention(objc_method) (MyMagnetism) -> @autoreleased CCRefrigerator diff --git a/test/SILGen/convenience_init_peer_delegation_import.swift b/test/SILGen/convenience_init_peer_delegation_import.swift index ff54eb1bbd599..54a216978a850 100644 --- a/test/SILGen/convenience_init_peer_delegation_import.swift +++ b/test/SILGen/convenience_init_peer_delegation_import.swift @@ -34,7 +34,7 @@ extension ImportedClass { // CHECK-LABEL: sil hidden [ossa] @$sSo13ImportedClassC39convenience_init_peer_delegation_importE16objcToDesignatedAByt_tcfC // CHECK: function_ref @$sSo13ImportedClassC39convenience_init_peer_delegation_importE16objcToDesignatedAByt_tcfcTD : // CHECK: end sil function '$sSo13ImportedClassC39convenience_init_peer_delegation_importE16objcToDesignatedAByt_tcfC' - // CHECK-LABEL: sil shared [transparent] [serializable] [thunk] [ossa] @$sSo13ImportedClassC39convenience_init_peer_delegation_importE16objcToDesignatedAByt_tcfcTD + // CHECK-LABEL: sil shared [transparent] [serialized] [thunk] [ossa] @$sSo13ImportedClassC39convenience_init_peer_delegation_importE16objcToDesignatedAByt_tcfcTD // CHECK: objc_method %0 : $ImportedClass, #ImportedClass.init!initializer.foreign // CHECK: end sil function '$sSo13ImportedClassC39convenience_init_peer_delegation_importE16objcToDesignatedAByt_tcfcTD' // CHECK-LABEL: sil hidden [ossa] @$sSo13ImportedClassC39convenience_init_peer_delegation_importE16objcToDesignatedAByt_tcfc @@ -49,7 +49,7 @@ extension ImportedClass { // CHECK-LABEL: sil hidden [ossa] @$sSo13ImportedClassC39convenience_init_peer_delegation_importE17objcToConvenienceAByt_tcfC // CHECK: function_ref @$sSo13ImportedClassC39convenience_init_peer_delegation_importE17objcToConvenienceAByt_tcfcTD : // CHECK: end sil function '$sSo13ImportedClassC39convenience_init_peer_delegation_importE17objcToConvenienceAByt_tcfC' - // CHECK-LABEL: sil shared [transparent] [serializable] [thunk] [ossa] @$sSo13ImportedClassC39convenience_init_peer_delegation_importE17objcToConvenienceAByt_tcfcTD + // CHECK-LABEL: sil shared [transparent] [serialized] [thunk] [ossa] @$sSo13ImportedClassC39convenience_init_peer_delegation_importE17objcToConvenienceAByt_tcfcTD // CHECK: objc_method %0 : $ImportedClass, #ImportedClass.init!initializer.foreign // CHECK: end sil function '$sSo13ImportedClassC39convenience_init_peer_delegation_importE17objcToConvenienceAByt_tcfcTD' // CHECK-LABEL: sil hidden [ossa] @$sSo13ImportedClassC39convenience_init_peer_delegation_importE17objcToConvenienceAByt_tcfc @@ -65,7 +65,7 @@ extension ImportedClass { // CHECK-LABEL: sil hidden [ossa] @$sSo13ImportedClassC39convenience_init_peer_delegation_importE24objcToConvenienceFactoryAByt_tcfC // CHECK: function_ref @$sSo13ImportedClassC39convenience_init_peer_delegation_importE24objcToConvenienceFactoryAByt_tcfcTD : // CHECK: end sil function '$sSo13ImportedClassC39convenience_init_peer_delegation_importE24objcToConvenienceFactoryAByt_tcfC' - // CHECK-LABEL: sil shared [transparent] [serializable] [thunk] [ossa] @$sSo13ImportedClassC39convenience_init_peer_delegation_importE24objcToConvenienceFactoryAByt_tcfcTD + // CHECK-LABEL: sil shared [transparent] [serialized] [thunk] [ossa] @$sSo13ImportedClassC39convenience_init_peer_delegation_importE24objcToConvenienceFactoryAByt_tcfcTD // CHECK: objc_method %0 : $ImportedClass, #ImportedClass.init!initializer.foreign // CHECK: end sil function '$sSo13ImportedClassC39convenience_init_peer_delegation_importE24objcToConvenienceFactoryAByt_tcfcTD' // CHECK-LABEL: sil hidden [ossa] @$sSo13ImportedClassC39convenience_init_peer_delegation_importE24objcToConvenienceFactoryAByt_tcfc @@ -81,7 +81,7 @@ extension ImportedClass { // CHECK-LABEL: sil hidden [ossa] @$sSo13ImportedClassC39convenience_init_peer_delegation_importE19objcToNormalFactoryAByt_tcfC // CHECK: function_ref @$sSo13ImportedClassC39convenience_init_peer_delegation_importE19objcToNormalFactoryAByt_tcfcTD : // CHECK: end sil function '$sSo13ImportedClassC39convenience_init_peer_delegation_importE19objcToNormalFactoryAByt_tcfC' - // CHECK-LABEL: sil shared [transparent] [serializable] [thunk] [ossa] @$sSo13ImportedClassC39convenience_init_peer_delegation_importE19objcToNormalFactoryAByt_tcfcTD + // CHECK-LABEL: sil shared [transparent] [serialized] [thunk] [ossa] @$sSo13ImportedClassC39convenience_init_peer_delegation_importE19objcToNormalFactoryAByt_tcfcTD // CHECK: objc_method %0 : $ImportedClass, #ImportedClass.init!initializer.foreign // CHECK: end sil function '$sSo13ImportedClassC39convenience_init_peer_delegation_importE19objcToNormalFactoryAByt_tcfcTD' // CHECK-LABEL: sil hidden [ossa] @$sSo13ImportedClassC39convenience_init_peer_delegation_importE19objcToNormalFactoryAByt_tcfc diff --git a/test/SILGen/default_arguments_local.swift b/test/SILGen/default_arguments_local.swift index 2d1f4613944b0..3134495c7b6d3 100644 --- a/test/SILGen/default_arguments_local.swift +++ b/test/SILGen/default_arguments_local.swift @@ -65,7 +65,7 @@ class ArtClass { @inlinable public func outer() { // CHECK-LABEL: sil shared [serialized] [ossa] @$s23default_arguments_local5outeryyF5innerL_1xySi_tFfA_ : $@convention(thin) () -> Int { - // CHECK-LABEL: sil shared [serializable] [ossa] @$s23default_arguments_local5outeryyF5innerL_1xySi_tF : $@convention(thin) (Int) -> () { + // CHECK-LABEL: sil shared [serialized] [ossa] @$s23default_arguments_local5outeryyF5innerL_1xySi_tF : $@convention(thin) (Int) -> () { func inner(x: Int = 0) {} inner() diff --git a/test/SILGen/distributed_thunk.swift b/test/SILGen/distributed_thunk.swift index bedc45b85be05..dd039918c5aa4 100644 --- a/test/SILGen/distributed_thunk.swift +++ b/test/SILGen/distributed_thunk.swift @@ -1,4 +1,4 @@ -// RUN: %target-swift-emit-silgen %s -enable-experimental-distributed -disable-availability-checking | %FileCheck %s --dump-input=fail +// RUN: %target-swift-emit-silgen %s -enable-experimental-distributed -disable-availability-checking | %FileCheck %s --dump-input=always // REQUIRES: concurrency // REQUIRES: distributed @@ -9,7 +9,7 @@ distributed actor DA { } extension DA { - // CHECK-LABEL: sil hidden [thunk] [distributed] [ossa] @$s17distributed_thunk2DAC1fyyFTE : $@convention(method) @async (@guaranteed DA) -> @error Error + // CHECK-LABEL: sil hidden [thunk] [distributed] [ossa] @$s17distributed_thunk2DAC1fyyYaKFTE : $@convention(method) @async (@guaranteed DA) -> @error Error // CHECK: function_ref @swift_distributed_actor_is_remote // Call the actor function diff --git a/test/SILGen/dynamic.swift b/test/SILGen/dynamic.swift index 5786ad180cf02..4fb83f0a5e207 100644 --- a/test/SILGen/dynamic.swift +++ b/test/SILGen/dynamic.swift @@ -82,7 +82,7 @@ protocol Proto { // TODO: dynamic initializing ctor must be objc dispatched // CHECK-LABEL: sil hidden [ossa] @$s7dynamic3{{[_0-9a-zA-Z]*}}fC // CHECK: function_ref @$s7dynamic3{{[_0-9a-zA-Z]*}}fcTD -// CHECK-LABEL: sil shared [transparent] [serializable] [thunk] [ossa] @$s7dynamic3{{[_0-9a-zA-Z]*}}fcTD +// CHECK-LABEL: sil shared [transparent] [serialized] [thunk] [ossa] @$s7dynamic3{{[_0-9a-zA-Z]*}}fcTD // CHECK: objc_method {{%.*}} : $Foo, #Foo.init!initializer.foreign : // CHECK-LABEL: sil hidden [thunk] [ossa] @$s7dynamic3{{[_0-9a-zA-Z]*}}fcTo @@ -125,27 +125,27 @@ protocol Proto { // Dynamic witnesses use objc dispatch: // CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s7dynamic3FooCAA5ProtoA2aDP0A6Method{{[_0-9a-zA-Z]*}}FTW // CHECK: function_ref @$s7dynamic3FooC0A6Method{{[_0-9a-zA-Z]*}}FTD -// CHECK-LABEL: sil shared [transparent] [serializable] [thunk] [ossa] @$s7dynamic3FooC0A6Method{{[_0-9a-zA-Z]*}}FTD +// CHECK-LABEL: sil shared [transparent] [serialized] [thunk] [ossa] @$s7dynamic3FooC0A6Method{{[_0-9a-zA-Z]*}}FTD // CHECK: objc_method {{%.*}} : $Foo, #Foo.dynamicMethod!foreign : // CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s7dynamic3FooCAA5ProtoA2aDP0A4PropSivgTW // CHECK: function_ref @$s7dynamic3FooC0A4PropSivgTD -// CHECK-LABEL: sil shared [transparent] [serializable] [thunk] [ossa] @$s7dynamic3FooC0A4PropSivgTD +// CHECK-LABEL: sil shared [transparent] [serialized] [thunk] [ossa] @$s7dynamic3FooC0A4PropSivgTD // CHECK: objc_method {{%.*}} : $Foo, #Foo.dynamicProp!getter.foreign : // CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s7dynamic3FooCAA5ProtoA2aDP0A4PropSivsTW // CHECK: function_ref @$s7dynamic3FooC0A4PropSivsTD -// CHECK-LABEL: sil shared [transparent] [serializable] [thunk] [ossa] @$s7dynamic3FooC0A4PropSivsTD +// CHECK-LABEL: sil shared [transparent] [serialized] [thunk] [ossa] @$s7dynamic3FooC0A4PropSivsTD // CHECK: objc_method {{%.*}} : $Foo, #Foo.dynamicProp!setter.foreign : // CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s7dynamic3FooCAA5ProtoA2aDPAAS2i_tcigTW // CHECK: function_ref @$s7dynamic3FooCAAS2i_tcigTD -// CHECK-LABEL: sil shared [transparent] [serializable] [thunk] [ossa] @$s7dynamic3FooCAAS2i_tcigTD +// CHECK-LABEL: sil shared [transparent] [serialized] [thunk] [ossa] @$s7dynamic3FooCAAS2i_tcigTD // CHECK: objc_method {{%.*}} : $Foo, #Foo.subscript!getter.foreign : // CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s7dynamic3FooCAA5ProtoA2aDPAAS2i_tcisTW // CHECK: function_ref @$s7dynamic3FooCAAS2i_tcisTD -// CHECK-LABEL: sil shared [transparent] [serializable] [thunk] [ossa] @$s7dynamic3FooCAAS2i_tcisTD +// CHECK-LABEL: sil shared [transparent] [serialized] [thunk] [ossa] @$s7dynamic3FooCAAS2i_tcisTD // CHECK: objc_method {{%.*}} : $Foo, #Foo.subscript!setter.foreign : // Superclass dispatch diff --git a/test/SILGen/errors.swift b/test/SILGen/errors.swift index fa245c30228b5..c17797bceec6e 100644 --- a/test/SILGen/errors.swift +++ b/test/SILGen/errors.swift @@ -497,7 +497,7 @@ func create(_ fn: () throws -> T) throws -> T { func testThunk(_ fn: () throws -> Int) throws -> Int { return try create(fn) } -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sSis5Error_pIgdzo_SisAA_pIegrzo_TR : $@convention(thin) (@noescape @callee_guaranteed () -> (Int, @error Error)) -> (@out Int, @error Error) +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sSis5Error_pIgdzo_SisAA_pIegrzo_TR : $@convention(thin) (@noescape @callee_guaranteed () -> (Int, @error Error)) -> (@out Int, @error Error) // CHECK: bb0(%0 : $*Int, %1 : $@noescape @callee_guaranteed () -> (Int, @error Error)): // CHECK: try_apply %1() // CHECK: bb1([[T0:%.*]] : $Int): diff --git a/test/SILGen/existential_member_accesses_self_assoctype.swift b/test/SILGen/existential_member_accesses_self_assoctype.swift index 56dd083e96016..4768e536394dd 100644 --- a/test/SILGen/existential_member_accesses_self_assoctype.swift +++ b/test/SILGen/existential_member_accesses_self_assoctype.swift @@ -139,7 +139,7 @@ func testCovariantSelfMethod7(p: any P) { // CHECK: [[WITNESS:%[0-9]+]] = witness_method $[[OPENED_TY]], #P.covariantSelfMethod8 : (Self) -> ((Self...) -> ()) -> () // CHECK: apply [[WITNESS]]<[[OPENED_TY]]>([[STEP3]], [[OPENED]]) : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1 where τ_0_0 == τ_0_1> (@guaranteed Array<τ_0_0>) -> () for <τ_0_0, τ_0_0>, @in_guaranteed τ_0_0) -> () -// CHECK: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @[[SELF_ARRAY_THUNK_NAME]] +// CHECK: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @[[SELF_ARRAY_THUNK_NAME]] // CHECK: [[ARRAY_UPCAST:%[0-9]+]] = function_ref @$ss15_arrayForceCastySayq_GSayxGr0_lF // CHECK: apply [[ARRAY_UPCAST]]<τ_0_0, P> // CHECK: } // end sil function '[[SELF_ARRAY_THUNK_NAME]]' @@ -242,7 +242,7 @@ func testCovariantSelfProperty7(p: any P) { // CHECK: debug_value %{{[0-9]+}} : $@callee_guaranteed (@noescape @callee_guaranteed (@guaranteed Array

) -> ()) -> (), let, name "x" // CHECK: } // end sil function '$s42existential_member_accesses_self_assoctype26testCovariantSelfProperty81pyAA1P_p_tF' -// CHECK: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @[[THUNK_NAME]] +// CHECK: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @[[THUNK_NAME]] // CHECK: function_ref @[[SELF_ARRAY_THUNK_NAME]] // CHECK: } // end sil function '[[THUNK_NAME]]' func testCovariantSelfProperty8(p: any P) { @@ -423,7 +423,7 @@ func testCovariantAssocMethod7(p: any P) { // CHECK: [[WITNESS:%[0-9]+]] = witness_method $[[OPENED_TY]], #P.covariantAssocMethod8 : (Self) -> ((Self.A...) -> ()) -> () // CHECK: apply [[WITNESS]]<[[OPENED_TY]]>([[STEP3]], [[OPENED]]) : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1 where τ_0_0 == τ_0_1> (@guaranteed Array<τ_0_0>) -> () for <τ_0_0.A, τ_0_0.A>, @in_guaranteed τ_0_0) -> () -// CHECK: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @[[ASSOCTYPE_ARRAY_THUNK_NAME]] +// CHECK: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @[[ASSOCTYPE_ARRAY_THUNK_NAME]] // CHECK: [[ARRAY_UPCAST:%[0-9]+]] = function_ref @$ss15_arrayForceCastySayq_GSayxGr0_lF // CHECK: apply [[ARRAY_UPCAST]]<τ_0_0.A, Any> // CHECK: } // end sil function '[[ASSOCTYPE_ARRAY_THUNK_NAME]]' @@ -525,7 +525,7 @@ func testCovariantAssocProperty7(p: any P) { // CHECK: debug_value %{{[0-9]+}} : $@callee_guaranteed (@noescape @callee_guaranteed (@guaranteed Array) -> ()) -> (), let, name "x" // CHECK: } // end sil function '$s42existential_member_accesses_self_assoctype27testCovariantAssocProperty81pyAA1P_p_tF' -// CHECK: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @[[THUNK_NAME]] +// CHECK: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @[[THUNK_NAME]] // CHECK: function_ref @[[ASSOCTYPE_ARRAY_THUNK_NAME]] // CHECK: } // end sil function '[[THUNK_NAME]]' func testCovariantAssocProperty8(p: any P) { diff --git a/test/SILGen/external_definitions.swift b/test/SILGen/external_definitions.swift index a8ef3c60c3ea5..291472bab1096 100644 --- a/test/SILGen/external_definitions.swift +++ b/test/SILGen/external_definitions.swift @@ -23,13 +23,13 @@ hasNoPrototype() // CHECK: apply [[NOPROTO]]() // -- Constructors for imported NSObject -// CHECK-LABEL: sil shared [serializable] [ossa] @$sSo8NSObjectC{{[_0-9a-zA-Z]*}}fC : $@convention(method) (@thick NSObject.Type) -> @owned NSObject +// CHECK-LABEL: sil shared [serialized] [ossa] @$sSo8NSObjectC{{[_0-9a-zA-Z]*}}fC : $@convention(method) (@thick NSObject.Type) -> @owned NSObject // -- Constructors for imported Ansible -// CHECK-LABEL: sil shared [serializable] [ossa] @$sSo7AnsibleC{{[_0-9a-zA-Z]*}}fC : $@convention(method) (@in Optional, @thick Ansible.Type) -> @owned Optional +// CHECK-LABEL: sil shared [serialized] [ossa] @$sSo7AnsibleC{{[_0-9a-zA-Z]*}}fC : $@convention(method) (@in Optional, @thick Ansible.Type) -> @owned Optional // -- Native Swift thunk for NSAnse -// CHECK: sil shared [serializable] [thunk] [ossa] @$sSo6NSAnseySo7AnsibleCSgADFTO : $@convention(thin) (@guaranteed Optional) -> @owned Optional { +// CHECK: sil shared [serialized] [thunk] [ossa] @$sSo6NSAnseySo7AnsibleCSgADFTO : $@convention(thin) (@guaranteed Optional) -> @owned Optional { // CHECK: bb0([[ARG0:%.*]] : @guaranteed $Optional): // CHECK: [[ARG0_COPY:%.*]] = copy_value [[ARG0]] // CHECK: [[FUNC:%.*]] = function_ref @NSAnse : $@convention(c) (Optional) -> @autoreleased Optional diff --git a/test/SILGen/foreign_to_native_inout_self.swift b/test/SILGen/foreign_to_native_inout_self.swift index 5044d7f1b02c9..7051a943222c5 100644 --- a/test/SILGen/foreign_to_native_inout_self.swift +++ b/test/SILGen/foreign_to_native_inout_self.swift @@ -6,10 +6,10 @@ protocol FakeIterator { extension MyIterator : FakeIterator {} -// CHECK-LABEL: sil shared [serializable] [thunk] [ossa] @$sSo10MyIteratora4nextyyFTO : $@convention(method) (@inout MyIterator) -> () { +// CHECK-LABEL: sil shared [serialized] [thunk] [ossa] @$sSo10MyIteratora4nextyyFTO : $@convention(method) (@inout MyIterator) -> () { // CHECK: bb0(%0 : $*MyIterator): // CHECK: [[FN:%.*]] = function_ref @MyIteratorNext : $@convention(c) (@inout MyIterator) -> () // CHECK: apply [[FN]](%0) : $@convention(c) (@inout MyIterator) -> () // CHECK: [[RESULT:%.*]] = tuple () // CHECK: return [[RESULT]] : $() -// CHECK: } \ No newline at end of file +// CHECK: } diff --git a/test/SILGen/function_conversion.swift b/test/SILGen/function_conversion.swift index 91f74bf318db8..5762bd9875559 100644 --- a/test/SILGen/function_conversion.swift +++ b/test/SILGen/function_conversion.swift @@ -124,13 +124,13 @@ func convOptionalTrivial(_ t1: @escaping (Trivial?) -> Trivial) { let _: (Trivial?) -> Trivial? = t1 } -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$s19function_conversion7TrivialVSgACIegyd_AcDIegyd_TR : $@convention(thin) (Trivial, @guaranteed @callee_guaranteed (Optional) -> Trivial) -> Optional +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$s19function_conversion7TrivialVSgACIegyd_AcDIegyd_TR : $@convention(thin) (Trivial, @guaranteed @callee_guaranteed (Optional) -> Trivial) -> Optional // CHECK: [[ENUM:%.*]] = enum $Optional // CHECK-NEXT: apply %1([[ENUM]]) // CHECK-NEXT: enum $Optional // CHECK-NEXT: return -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$s19function_conversion7TrivialVSgACIegyd_A2DIegyd_TR : $@convention(thin) (Optional, @guaranteed @callee_guaranteed (Optional) -> Trivial) -> Optional +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$s19function_conversion7TrivialVSgACIegyd_A2DIegyd_TR : $@convention(thin) (Optional, @guaranteed @callee_guaranteed (Optional) -> Trivial) -> Optional // CHECK: apply %1(%0) // CHECK-NEXT: enum $Optional // CHECK-NEXT: return @@ -146,7 +146,7 @@ func convOptionalLoadable(_ l1: @escaping (Loadable?) -> Loadable) { let _: (Loadable?) -> Loadable? = l1 } -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$s19function_conversion8LoadableVSgACIeggo_A2DIeggo_TR : $@convention(thin) (@guaranteed Optional, @guaranteed @callee_guaranteed (@guaranteed Optional) -> @owned Loadable) -> @owned Optional +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$s19function_conversion8LoadableVSgACIeggo_A2DIeggo_TR : $@convention(thin) (@guaranteed Optional, @guaranteed @callee_guaranteed (@guaranteed Optional) -> @owned Loadable) -> @owned Optional // CHECK: apply %1(%0) // CHECK-NEXT: enum $Optional // CHECK-NEXT: return @@ -158,7 +158,7 @@ func convOptionalAddrOnly(_ a1: @escaping (AddrOnly?) -> AddrOnly) { let _: (AddrOnly?) -> AddrOnly? = a1 } -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$s19function_conversion8AddrOnlyVSgACIegnr_A2DIegnr_TR : $@convention(thin) (@in_guaranteed Optional, @guaranteed @callee_guaranteed (@in_guaranteed Optional) -> @out AddrOnly) -> @out Optional +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$s19function_conversion8AddrOnlyVSgACIegnr_A2DIegnr_TR : $@convention(thin) (@in_guaranteed Optional, @guaranteed @callee_guaranteed (@in_guaranteed Optional) -> @out AddrOnly) -> @out Optional // CHECK: [[TEMP:%.*]] = alloc_stack $AddrOnly // CHECK-NEXT: apply %2([[TEMP]], %1) // CHECK-NEXT: init_enum_data_addr %0 : $*Optional @@ -195,7 +195,7 @@ func convExistentialTrivial(_ t2: @escaping (Q) -> Trivial, t3: @escaping (Q?) - let _: (P) -> P = t2 } -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$s19function_conversion1Q_pAA7TrivialVIegnd_AdA1P_pIegyr_TR : $@convention(thin) (Trivial, @guaranteed @callee_guaranteed (@in_guaranteed Q) -> Trivial) -> @out P +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$s19function_conversion1Q_pAA7TrivialVIegnd_AdA1P_pIegyr_TR : $@convention(thin) (Trivial, @guaranteed @callee_guaranteed (@in_guaranteed Q) -> Trivial) -> @out P // CHECK: alloc_stack $Q // CHECK-NEXT: init_existential_addr // CHECK-NEXT: store @@ -204,7 +204,7 @@ func convExistentialTrivial(_ t2: @escaping (Q) -> Trivial, t3: @escaping (Q?) - // CHECK-NEXT: store // CHECK: return -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$s19function_conversion1Q_pSgAA7TrivialVIegnd_AESgAA1P_pIegyr_TR +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$s19function_conversion1Q_pSgAA7TrivialVIegnd_AESgAA1P_pIegyr_TR // CHECK: switch_enum // CHECK: bb1([[TRIVIAL:%.*]] : $Trivial): // CHECK: init_existential_addr @@ -219,7 +219,7 @@ func convExistentialTrivial(_ t2: @escaping (Q) -> Trivial, t3: @escaping (Q?) - // CHECK: store // CHECK: return -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$s19function_conversion1Q_pAA7TrivialVIegnd_AA1P_pAaE_pIegnr_TR : $@convention(thin) (@in_guaranteed P, @guaranteed @callee_guaranteed (@in_guaranteed Q) -> Trivial) -> @out P +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$s19function_conversion1Q_pAA7TrivialVIegnd_AA1P_pAaE_pIegnr_TR : $@convention(thin) (@in_guaranteed P, @guaranteed @callee_guaranteed (@in_guaranteed Q) -> Trivial) -> @out P // CHECK: [[TMP:%.*]] = alloc_stack $Q // CHECK-NEXT: open_existential_addr immutable_access %1 : $*P // CHECK-NEXT: init_existential_addr [[TMP]] : $*Q @@ -247,7 +247,7 @@ func convExistentialMetatype(_ em: @escaping (Q.Type?) -> Trivial.Type) { let _: (P.Type) -> P.Type = em } -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$s19function_conversion1Q_pXmTSgAA7TrivialVXMtIegyd_AEXMtAA1P_pXmTIegyd_TR : $@convention(thin) (@thin Trivial.Type, @guaranteed @callee_guaranteed (Optional<@thick Q.Type>) -> @thin Trivial.Type) -> @thick P.Type +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$s19function_conversion1Q_pXmTSgAA7TrivialVXMtIegyd_AEXMtAA1P_pXmTIegyd_TR : $@convention(thin) (@thin Trivial.Type, @guaranteed @callee_guaranteed (Optional<@thick Q.Type>) -> @thin Trivial.Type) -> @thick P.Type // CHECK: [[META:%.*]] = metatype $@thick Trivial.Type // CHECK-NEXT: init_existential_metatype [[META]] : $@thick Trivial.Type, $@thick Q.Type // CHECK-NEXT: enum $Optional<@thick Q.Type> @@ -256,7 +256,7 @@ func convExistentialMetatype(_ em: @escaping (Q.Type?) -> Trivial.Type) { // CHECK-NEXT: init_existential_metatype {{.*}} : $@thick Trivial.Type, $@thick P.Type // CHECK-NEXT: return -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$s19function_conversion1Q_pXmTSgAA7TrivialVXMtIegyd_AEXMtSgAA1P_pXmTIegyd_TR : $@convention(thin) (Optional<@thin Trivial.Type>, @guaranteed @callee_guaranteed (Optional<@thick Q.Type>) -> @thin Trivial.Type) -> @thick P.Type +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$s19function_conversion1Q_pXmTSgAA7TrivialVXMtIegyd_AEXMtSgAA1P_pXmTIegyd_TR : $@convention(thin) (Optional<@thin Trivial.Type>, @guaranteed @callee_guaranteed (Optional<@thick Q.Type>) -> @thin Trivial.Type) -> @thick P.Type // CHECK: switch_enum %0 : $Optional<@thin Trivial.Type> // CHECK: bb1([[META:%.*]] : $@thin Trivial.Type): // CHECK-NEXT: metatype $@thick Trivial.Type @@ -270,7 +270,7 @@ func convExistentialMetatype(_ em: @escaping (Q.Type?) -> Trivial.Type) { // CHECK-NEXT: init_existential_metatype {{.*}} : $@thick Trivial.Type, $@thick P.Type // CHECK-NEXT: return -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$s19function_conversion1Q_pXmTSgAA7TrivialVXMtIegyd_AA1P_pXmTAaF_pXmTIegyd_TR : $@convention(thin) (@thick P.Type, @guaranteed @callee_guaranteed (Optional<@thick Q.Type>) -> @thin Trivial.Type) -> @thick P.Type +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$s19function_conversion1Q_pXmTSgAA7TrivialVXMtIegyd_AA1P_pXmTAaF_pXmTIegyd_TR : $@convention(thin) (@thick P.Type, @guaranteed @callee_guaranteed (Optional<@thick Q.Type>) -> @thin Trivial.Type) -> @thick P.Type // CHECK: open_existential_metatype %0 : $@thick P.Type to $@thick (@opened({{.*}}) P).Type // CHECK-NEXT: init_existential_metatype %2 : $@thick (@opened({{.*}}) P).Type, $@thick Q.Type // CHECK-NEXT: enum $Optional<@thick Q.Type> @@ -303,20 +303,20 @@ func convUpcastMetatype(_ c4: @escaping (Parent.Type, Trivial?) -> Child.Type, let _: (Child.Type?, Trivial) -> Parent.Type? = c5 } -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$s19function_conversion6ParentCXMTAA7TrivialVSgAA5ChildCXMTIegyyd_AHXMTAeCXMTIegyyd_TR : $@convention(thin) (@thick Child.Type, Trivial, @guaranteed @callee_guaranteed (@thick Parent.Type, Optional) -> @thick Child.Type) -> @thick Parent.Type +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$s19function_conversion6ParentCXMTAA7TrivialVSgAA5ChildCXMTIegyyd_AHXMTAeCXMTIegyyd_TR : $@convention(thin) (@thick Child.Type, Trivial, @guaranteed @callee_guaranteed (@thick Parent.Type, Optional) -> @thick Child.Type) -> @thick Parent.Type // CHECK: upcast %0 : $@thick Child.Type to $@thick Parent.Type // CHECK: apply // CHECK: upcast {{.*}} : $@thick Child.Type to $@thick Parent.Type // CHECK: return -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$s19function_conversion6ParentCXMTSgAA7TrivialVSgAA5ChildCXMTIegyyd_AIXMTAfCXMTIegyyd_TR : $@convention(thin) (@thick Child.Type, Trivial, @guaranteed @callee_guaranteed (Optional<@thick Parent.Type>, Optional) -> @thick Child.Type) -> @thick Parent.Type +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$s19function_conversion6ParentCXMTSgAA7TrivialVSgAA5ChildCXMTIegyyd_AIXMTAfCXMTIegyyd_TR : $@convention(thin) (@thick Child.Type, Trivial, @guaranteed @callee_guaranteed (Optional<@thick Parent.Type>, Optional) -> @thick Child.Type) -> @thick Parent.Type // CHECK: upcast %0 : $@thick Child.Type to $@thick Parent.Type // CHECK: enum $Optional<@thick Parent.Type> // CHECK: apply // CHECK: upcast {{.*}} : $@thick Child.Type to $@thick Parent.Type // CHECK: return -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$s19function_conversion6ParentCXMTSgAA7TrivialVSgAA5ChildCXMTIegyyd_AIXMTSgAfDIegyyd_TR : $@convention(thin) (Optional<@thick Child.Type>, Trivial, @guaranteed @callee_guaranteed (Optional<@thick Parent.Type>, Optional) -> @thick Child.Type) -> Optional<@thick Parent.Type> +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$s19function_conversion6ParentCXMTSgAA7TrivialVSgAA5ChildCXMTIegyyd_AIXMTSgAfDIegyyd_TR : $@convention(thin) (Optional<@thick Child.Type>, Trivial, @guaranteed @callee_guaranteed (Optional<@thick Parent.Type>, Optional) -> @thick Child.Type) -> Optional<@thick Parent.Type> // CHECK: unchecked_trivial_bit_cast %0 : $Optional<@thick Child.Type> to $Optional<@thick Parent.Type> // CHECK: apply // CHECK: upcast {{.*}} : $@thick Child.Type to $@thick Parent.Type @@ -336,7 +336,7 @@ func convFuncExistential(_ f1: @escaping (Any) -> (Int) -> Int) { let _: (@escaping (Int) -> Int) -> Any = f1 } -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sypS2iIegyd_Iegno_S2iIegyd_ypIeggr_TR : $@convention(thin) (@guaranteed @callee_guaranteed (Int) -> Int, @guaranteed @callee_guaranteed (@in_guaranteed Any) -> @owned @callee_guaranteed (Int) -> Int) -> @out Any { +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sypS2iIegyd_Iegno_S2iIegyd_ypIeggr_TR : $@convention(thin) (@guaranteed @callee_guaranteed (Int) -> Int, @guaranteed @callee_guaranteed (@in_guaranteed Any) -> @owned @callee_guaranteed (Int) -> Int) -> @out Any { // CHECK: [[EXISTENTIAL:%.*]] = alloc_stack $Any // CHECK: [[COPIED_VAL:%.*]] = copy_value // CHECK: function_ref @$sS2iIegyd_S2iIegnr_TR @@ -352,7 +352,7 @@ func convFuncExistential(_ f1: @escaping (Any) -> (Int) -> Int) { // CHECK-NEXT: store {{.*}} to {{.*}} : $*@callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for // CHECK: return -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sS2iIegyd_S2iIegnr_TR : $@convention(thin) (@in_guaranteed Int, @guaranteed @callee_guaranteed (Int) -> Int) -> @out Int +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sS2iIegyd_S2iIegnr_TR : $@convention(thin) (@in_guaranteed Int, @guaranteed @callee_guaranteed (Int) -> Int) -> @out Int // CHECK: [[LOADED:%.*]] = load [trivial] %1 : $*Int // CHECK-NEXT: apply %2([[LOADED]]) // CHECK-NEXT: store {{.*}} to [trivial] %0 @@ -368,7 +368,7 @@ func convClassBoundArchetypeUpcast(_ f1: @escaping (Parent) -> (T, T let _: (T) -> (Parent, Trivial?) = f1 } -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$s19function_conversion6ParentCxAA7TrivialVIeggod_xAcESgIeggod_ACRbzlTR : $@convention(thin) (@guaranteed T, @guaranteed @callee_guaranteed (@guaranteed Parent) -> (@owned T, Trivial)) -> (@owned Parent, Optional) +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$s19function_conversion6ParentCxAA7TrivialVIeggod_xAcESgIeggod_ACRbzlTR : $@convention(thin) (@guaranteed T, @guaranteed @callee_guaranteed (@guaranteed Parent) -> (@owned T, Trivial)) -> (@owned Parent, Optional) // CHECK: bb0([[ARG:%.*]] : @guaranteed $T, [[CLOSURE:%.*]] : @guaranteed $@callee_guaranteed (@guaranteed Parent) -> (@owned T, Trivial)): // CHECK: [[CASTED_ARG:%.*]] = upcast [[ARG]] : $T to $Parent // CHECK: [[RESULT:%.*]] = apply %1([[CASTED_ARG]]) @@ -386,7 +386,7 @@ func convClassBoundMetatypeArchetypeUpcast(_ f1: @escaping (Parent.T let _: (T.Type) -> (Parent.Type, Trivial?) = f1 } -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$s19function_conversion6ParentCXMTxXMTAA7TrivialVIegydd_xXMTACXMTAESgIegydd_ACRbzlTR : $@convention(thin) (@thick T.Type, @guaranteed @callee_guaranteed (@thick Parent.Type) -> (@thick T.Type, Trivial)) -> (@thick Parent.Type, Optional) +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$s19function_conversion6ParentCXMTxXMTAA7TrivialVIegydd_xXMTACXMTAESgIegydd_ACRbzlTR : $@convention(thin) (@thick T.Type, @guaranteed @callee_guaranteed (@thick Parent.Type) -> (@thick T.Type, Trivial)) -> (@thick Parent.Type, Optional) // CHECK: bb0([[META:%.*]] : // CHECK: upcast %0 : $@thick T.Type // CHECK-NEXT: apply @@ -403,9 +403,9 @@ func convClassBoundMetatypeArchetypeUpcast(_ f1: @escaping (Parent.T // CHECK: function_ref @$s19function_conversion1Q_pIegn_AA1P_pIegn_TR // CHECK: function_ref @$sSi_SitSgIegy_S2iIegyy_TR -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$s19function_conversion1Q_pIegn_AA1P_pIegn_TR : $@convention(thin) (@in_guaranteed P, @guaranteed @callee_guaranteed (@in_guaranteed Q) -> ()) -> () +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$s19function_conversion1Q_pIegn_AA1P_pIegn_TR : $@convention(thin) (@in_guaranteed P, @guaranteed @callee_guaranteed (@in_guaranteed Q) -> ()) -> () -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sSi_SitSgIegy_S2iIegyy_TR : $@convention(thin) (Int, Int, @guaranteed @callee_guaranteed (Optional<(Int, Int)>) -> ()) -> () +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sSi_SitSgIegy_S2iIegyy_TR : $@convention(thin) (Int, Int, @guaranteed @callee_guaranteed (Optional<(Int, Int)>) -> ()) -> () func convTupleScalar(_ f1: @escaping (Q) -> (), f2: @escaping (_ parent: Q) -> (), @@ -427,7 +427,7 @@ func convTupleScalarOpaque(_ f: @escaping (T...) -> ()) -> ((_ args: T...) -> // CHECK-NEXT: return [[THUNK]] // CHECK-NEXT: } // end sil function '$s19function_conversion25convTupleToOptionalDirectySi_SitSgSicSi_SitSicF' -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sS3iIegydd_S2i_SitSgIegyd_TR : $@convention(thin) (Int, @guaranteed @callee_guaranteed (Int) -> (Int, Int)) -> Optional<(Int, Int)> +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sS3iIegydd_S2i_SitSgIegyd_TR : $@convention(thin) (Int, @guaranteed @callee_guaranteed (Int) -> (Int, Int)) -> Optional<(Int, Int)> // CHECK: bb0(%0 : $Int, %1 : @guaranteed $@callee_guaranteed (Int) -> (Int, Int)): // CHECK: [[RESULT:%.*]] = apply %1(%0) // CHECK-NEXT: ([[LEFT:%.*]], [[RIGHT:%.*]]) = destructure_tuple [[RESULT]] @@ -450,7 +450,7 @@ func convTupleToOptionalDirect(_ f: @escaping (Int) -> (Int, Int)) -> (Int) -> ( // CHECK-NEXT: return [[THUNK_CONV]] // CHECK-NEXT: } // end sil function '$s19function_conversion27convTupleToOptionalIndirectyx_xtSgxcx_xtxclF' -// CHECK: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sxxxIegnrr_xx_xtSgIegnr_lTR : $@convention(thin) (@in_guaranteed T, @guaranteed @callee_guaranteed (@in_guaranteed T) -> (@out T, @out T)) -> @out Optional<(T, T)> +// CHECK: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sxxxIegnrr_xx_xtSgIegnr_lTR : $@convention(thin) (@in_guaranteed T, @guaranteed @callee_guaranteed (@in_guaranteed T) -> (@out T, @out T)) -> @out Optional<(T, T)> // CHECK: bb0(%0 : $*Optional<(T, T)>, %1 : $*T, %2 : @guaranteed $@callee_guaranteed (@in_guaranteed T) -> (@out T, @out T)): // CHECK: [[OPTIONAL:%.*]] = init_enum_data_addr %0 : $*Optional<(T, T)>, #Optional.some!enumelt // CHECK-NEXT: [[LEFT:%.*]] = tuple_element_addr [[OPTIONAL]] : $*(T, T), 0 @@ -470,7 +470,7 @@ func convTupleToOptionalIndirect(_ f: @escaping (T) -> (T, T)) -> (T) -> (T, // CHECK: function_ref @$s19function_conversion15convAnyHashable1tyx_tSHRzlFSbs0dE0V_AEtcfU_ // CHECK: function_ref @$ss11AnyHashableVABSbIegnnd_xxSbIegnnd_SHRzlTR -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$ss11AnyHashableVABSbIegnnd_xxSbIegnnd_SHRzlTR : $@convention(thin) (@in_guaranteed T, @in_guaranteed T, @guaranteed @callee_guaranteed (@in_guaranteed AnyHashable, @in_guaranteed AnyHashable) -> Bool) -> Bool +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$ss11AnyHashableVABSbIegnnd_xxSbIegnnd_SHRzlTR : $@convention(thin) (@in_guaranteed T, @in_guaranteed T, @guaranteed @callee_guaranteed (@in_guaranteed AnyHashable, @in_guaranteed AnyHashable) -> Bool) -> Bool // CHECK: alloc_stack $AnyHashable // CHECK: function_ref @$ss21_convertToAnyHashableys0cD0VxSHRzlF // CHECK: apply {{.*}} @@ -516,13 +516,13 @@ func convTupleAny(_ f1: @escaping () -> (), let _: ((Int, Int)) -> () = f4 } -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sIeg_ypIegr_TR : $@convention(thin) (@guaranteed @callee_guaranteed () -> ()) -> @out Any +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sIeg_ypIegr_TR : $@convention(thin) (@guaranteed @callee_guaranteed () -> ()) -> @out Any // CHECK: init_existential_addr %0 : $*Any, $() // CHECK-NEXT: apply %1() // CHECK-NEXT: tuple () // CHECK-NEXT: return -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sIeg_ypSgIegr_TR : $@convention(thin) (@guaranteed @callee_guaranteed () -> ()) -> @out Optional +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sIeg_ypSgIegr_TR : $@convention(thin) (@guaranteed @callee_guaranteed () -> ()) -> @out Optional // CHECK: [[ENUM_PAYLOAD:%.*]] = init_enum_data_addr %0 : $*Optional, #Optional.some!enumelt // CHECK-NEXT: init_existential_addr [[ENUM_PAYLOAD]] : $*Any, $() // CHECK-NEXT: apply %1() @@ -530,7 +530,7 @@ func convTupleAny(_ f1: @escaping () -> (), // CHECK-NEXT: tuple () // CHECK-NEXT: return -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sS2iIegdd_ypIegr_TR : $@convention(thin) (@guaranteed @callee_guaranteed () -> (Int, Int)) -> @out Any +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sS2iIegdd_ypIegr_TR : $@convention(thin) (@guaranteed @callee_guaranteed () -> (Int, Int)) -> @out Any // CHECK: [[ANY_PAYLOAD:%.*]] = init_existential_addr %0 // CHECK-NEXT: [[LEFT_ADDR:%.*]] = tuple_element_addr [[ANY_PAYLOAD]] // CHECK-NEXT: [[RIGHT_ADDR:%.*]] = tuple_element_addr [[ANY_PAYLOAD]] @@ -541,7 +541,7 @@ func convTupleAny(_ f1: @escaping () -> (), // CHECK-NEXT: tuple () // CHECK-NEXT: return -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sS2iIegdd_ypSgIegr_TR : $@convention(thin) (@guaranteed @callee_guaranteed () -> (Int, Int)) -> @out Optional { +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sS2iIegdd_ypSgIegr_TR : $@convention(thin) (@guaranteed @callee_guaranteed () -> (Int, Int)) -> @out Optional { // CHECK: [[OPTIONAL_PAYLOAD:%.*]] = init_enum_data_addr %0 // CHECK-NEXT: [[ANY_PAYLOAD:%.*]] = init_existential_addr [[OPTIONAL_PAYLOAD]] // CHECK-NEXT: [[LEFT_ADDR:%.*]] = tuple_element_addr [[ANY_PAYLOAD]] @@ -554,7 +554,7 @@ func convTupleAny(_ f1: @escaping () -> (), // CHECK-NEXT: tuple () // CHECK-NEXT: return -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sypIegn_S2iIegyy_TR : $@convention(thin) (Int, Int, @guaranteed @callee_guaranteed (@in_guaranteed Any) -> ()) -> () +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sypIegn_S2iIegyy_TR : $@convention(thin) (Int, Int, @guaranteed @callee_guaranteed (@in_guaranteed Any) -> ()) -> () // CHECK: [[ANY_VALUE:%.*]] = alloc_stack $Any // CHECK-NEXT: [[ANY_PAYLOAD:%.*]] = init_existential_addr [[ANY_VALUE]] // CHECK-NEXT: [[LEFT_ADDR:%.*]] = tuple_element_addr [[ANY_PAYLOAD]] @@ -567,7 +567,7 @@ func convTupleAny(_ f1: @escaping () -> (), // CHECK-NEXT: dealloc_stack [[ANY_VALUE]] // CHECK-NEXT: return -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sypSgIegn_S2iIegyy_TR : $@convention(thin) (Int, Int, @guaranteed @callee_guaranteed (@in_guaranteed Optional) -> ()) -> () +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sypSgIegn_S2iIegyy_TR : $@convention(thin) (Int, Int, @guaranteed @callee_guaranteed (@in_guaranteed Optional) -> ()) -> () // CHECK: [[ANY_VALUE:%.*]] = alloc_stack $Any // CHECK-NEXT: [[ANY_PAYLOAD:%.*]] = init_existential_addr [[ANY_VALUE]] // CHECK-NEXT: [[LEFT_ADDR:%.*]] = tuple_element_addr [[ANY_PAYLOAD]] diff --git a/test/SILGen/function_conversion_objc.swift b/test/SILGen/function_conversion_objc.swift index b146489730065..988024812f0e4 100644 --- a/test/SILGen/function_conversion_objc.swift +++ b/test/SILGen/function_conversion_objc.swift @@ -11,7 +11,7 @@ func convMetatypeToObject(_ f: @escaping (NSObject) -> NSObject.Type) { let _: (NSObject) -> AnyObject = f } -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sSo8NSObjectCABXMTIeggd_AByXlIeggo_TR : $@convention(thin) (@guaranteed NSObject, @guaranteed @callee_guaranteed (@guaranteed NSObject) -> @thick NSObject.Type) -> @owned AnyObject { +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sSo8NSObjectCABXMTIeggd_AByXlIeggo_TR : $@convention(thin) (@guaranteed NSObject, @guaranteed @callee_guaranteed (@guaranteed NSObject) -> @thick NSObject.Type) -> @owned AnyObject { // CHECK: apply %1(%0) // CHECK: thick_to_objc_metatype {{.*}} : $@thick NSObject.Type to $@objc_metatype NSObject.Type // CHECK: objc_metatype_to_object {{.*}} : $@objc_metatype NSObject.Type to $AnyObject @@ -26,7 +26,7 @@ func convExistentialMetatypeToObject(_ f: @escaping (NSBurrito) -> NSBurrito.Typ let _: (NSBurrito) -> AnyObject = f } -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$s24function_conversion_objc9NSBurrito_pAaB_pXmTIeggd_AaB_pyXlIeggo_TR : $@convention(thin) (@guaranteed NSBurrito, @guaranteed @callee_guaranteed (@guaranteed NSBurrito) -> @thick NSBurrito.Type) -> @owned AnyObject +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$s24function_conversion_objc9NSBurrito_pAaB_pXmTIeggd_AaB_pyXlIeggo_TR : $@convention(thin) (@guaranteed NSBurrito, @guaranteed @callee_guaranteed (@guaranteed NSBurrito) -> @thick NSBurrito.Type) -> @owned AnyObject // CHECK: apply %1(%0) // CHECK: thick_to_objc_metatype {{.*}} : $@thick NSBurrito.Type to $@objc_metatype NSBurrito.Type // CHECK: objc_existential_metatype_to_object {{.*}} : $@objc_metatype NSBurrito.Type to $AnyObject @@ -39,7 +39,7 @@ func convProtocolMetatypeToObject(_ f: @escaping () -> NSBurrito.Protocol) { let _: () -> Protocol = f } -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$s24function_conversion_objc9NSBurrito_pXMtIegd_So8ProtocolCIego_TR : $@convention(thin) (@guaranteed @callee_guaranteed () -> @thin NSBurrito.Protocol) -> @owned Protocol +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$s24function_conversion_objc9NSBurrito_pXMtIegd_So8ProtocolCIego_TR : $@convention(thin) (@guaranteed @callee_guaranteed () -> @thin NSBurrito.Protocol) -> @owned Protocol // CHECK: apply %0() : $@callee_guaranteed () -> @thin NSBurrito.Protocol // CHECK: objc_protocol #NSBurrito : $Protocol // CHECK: copy_value @@ -83,9 +83,9 @@ func blockToFuncExistential(_ x: @escaping @convention(block) () -> Int) -> () - return x } -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sSiIeyBd_SiIegd_TR : $@convention(thin) (@guaranteed @convention(block) () -> Int) -> Int +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sSiIeyBd_SiIegd_TR : $@convention(thin) (@guaranteed @convention(block) () -> Int) -> Int -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sSiIegd_ypIegr_TR : $@convention(thin) (@guaranteed @callee_guaranteed () -> Int) -> @out Any +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sSiIegd_ypIegr_TR : $@convention(thin) (@guaranteed @callee_guaranteed () -> Int) -> @out Any // C function pointer conversions diff --git a/test/SILGen/function_conversion_se0110.swift b/test/SILGen/function_conversion_se0110.swift index ee8772577355f..606b24fed1f0c 100644 --- a/test/SILGen/function_conversion_se0110.swift +++ b/test/SILGen/function_conversion_se0110.swift @@ -12,7 +12,7 @@ func givesTwo(_ fn: (Any, Any) -> ()) { } // reabstraction thunk helper from @callee_guaranteed (@in_guaranteed Any, @in_guaranteed Any) -> () to @escaping @callee_guaranteed (@unowned Swift.Int, @unowned Swift.Int) -> () -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sypypIgnn_S2iIegyy_TR : $@convention(thin) (Int, Int, @noescape @callee_guaranteed (@in_guaranteed Any, @in_guaranteed Any) -> ()) -> () +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sypypIgnn_S2iIegyy_TR : $@convention(thin) (Int, Int, @noescape @callee_guaranteed (@in_guaranteed Any, @in_guaranteed Any) -> ()) -> () func takesTwoGeneric(_: (T) -> ()) -> T {} @@ -22,7 +22,7 @@ func givesTwoGeneric(_ fn: (Int, Int) -> ()) { } // reabstraction thunk helper from @callee_guaranteed (@unowned Swift.Int, @unowned Swift.Int) -> () to @escaping @callee_guaranteed (@in_guaranteed (Swift.Int, Swift.Int)) -> () -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sS2iIgyy_Si_SitIegn_TR : $@convention(thin) (@in_guaranteed (Int, Int), @noescape @callee_guaranteed (Int, Int) -> ()) -> () +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sS2iIgyy_Si_SitIegn_TR : $@convention(thin) (@in_guaranteed (Int, Int), @noescape @callee_guaranteed (Int, Int) -> ()) -> () // Use a silly trick to bind T := (Int, Int) here @@ -35,7 +35,7 @@ func givesNoneGeneric(_ fn: () -> ()) { } // reabstraction thunk helper from @callee_guaranteed () -> () to @escaping @callee_guaranteed (@in_guaranteed ()) -> () -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sIg_ytIegn_TR : $@convention(thin) (@in_guaranteed (), @noescape @callee_guaranteed () -> ()) -> () +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sIg_ytIegn_TR : $@convention(thin) (@in_guaranteed (), @noescape @callee_guaranteed () -> ()) -> () // "Tuple splat" still works if there are __owned parameters. @@ -49,7 +49,7 @@ func givesTwoAnyObjectOwned(_ fn: (__owned AnyObject, __owned AnyObject) -> ()) takesTwoAnyObject(fn) } -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$syXlyXlIgxx_yXlyXlIeggg_TR : $@convention(thin) (@guaranteed AnyObject, @guaranteed AnyObject, @noescape @callee_guaranteed (@owned AnyObject, @owned AnyObject) -> ()) -> () { +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$syXlyXlIgxx_yXlyXlIeggg_TR : $@convention(thin) (@guaranteed AnyObject, @guaranteed AnyObject, @noescape @callee_guaranteed (@owned AnyObject, @owned AnyObject) -> ()) -> () { // CHECK: bb0(%0 : @guaranteed $AnyObject, %1 : @guaranteed $AnyObject, %2 : $@noescape @callee_guaranteed (@owned AnyObject, @owned AnyObject) -> ()): // CHECK-NEXT: [[FIRST:%.*]] = copy_value %0 // CHECK-NEXT: [[SECOND:%.*]] = copy_value %1 diff --git a/test/SILGen/generic_objc_block_bridge.swift b/test/SILGen/generic_objc_block_bridge.swift index 3c041743cfe93..e3a8ed396b765 100644 --- a/test/SILGen/generic_objc_block_bridge.swift +++ b/test/SILGen/generic_objc_block_bridge.swift @@ -12,4 +12,4 @@ class Tubb: Butt { } } -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sS2iIyByd_S2iIegyd_TR : $@convention(thin) (Int, @guaranteed @convention(block) @noescape (Int) -> Int) -> Int { +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sS2iIyByd_S2iIegyd_TR : $@convention(thin) (Int, @guaranteed @convention(block) @noescape (Int) -> Int) -> Int { diff --git a/test/SILGen/guaranteed_self.swift b/test/SILGen/guaranteed_self.swift index 76a1aeb9f6a07..8a97ce7f363cf 100644 --- a/test/SILGen/guaranteed_self.swift +++ b/test/SILGen/guaranteed_self.swift @@ -365,7 +365,7 @@ class D: C { super.init() } - // CHECK-LABEL: sil shared [transparent] [serializable] [thunk] [ossa] @$s15guaranteed_self1DC3foo{{[_0-9a-zA-Z]*}}FTD : $@convention(method) (Int, @guaranteed D) -> () + // CHECK-LABEL: sil shared [transparent] [serialized] [thunk] [ossa] @$s15guaranteed_self1DC3foo{{[_0-9a-zA-Z]*}}FTD : $@convention(method) (Int, @guaranteed D) -> () // CHECK: bb0({{.*}} [[SELF:%.*]] : @guaranteed $D): // CHECK: [[SELF_COPY:%.*]] = copy_value [[SELF]] // CHECK: destroy_value [[SELF_COPY]] diff --git a/test/SILGen/imported_struct_array_field.swift b/test/SILGen/imported_struct_array_field.swift index dcfb35762ef6e..d45a4437fe18f 100644 --- a/test/SILGen/imported_struct_array_field.swift +++ b/test/SILGen/imported_struct_array_field.swift @@ -1,6 +1,6 @@ // RUN: %target-swift-emit-silgen -enable-objc-interop -disable-objc-attr-requires-foundation-module -import-objc-header %S/Inputs/array_typedef.h %s | %FileCheck %s -// CHECK-LABEL: sil shared [transparent] [serializable] [ossa] @$sSo4NameV{{[_0-9a-zA-Z]*}}fC : $@convention(method) (UInt8, UInt8, UInt8, UInt8, @thin Name.Type) -> Name +// CHECK-LABEL: sil shared [transparent] [serialized] [ossa] @$sSo4NameV{{[_0-9a-zA-Z]*}}fC : $@convention(method) (UInt8, UInt8, UInt8, UInt8, @thin Name.Type) -> Name func useImportedArrayTypedefInit() -> Name { return Name(name: (0, 0, 0, 0)) } diff --git a/test/SILGen/inlinable_attribute.swift b/test/SILGen/inlinable_attribute.swift index b0aa618b58c06..a733d52e2f58a 100644 --- a/test/SILGen/inlinable_attribute.swift +++ b/test/SILGen/inlinable_attribute.swift @@ -136,15 +136,15 @@ private class PrivateDerivedFromUFI : UFIBase {} // CHECK-LABEL: sil [serialized] [ossa] @$s19inlinable_attribute3basyyF @inlinable public func bas() { - // CHECK-LABEL: sil shared [serializable] [ossa] @$s19inlinable_attribute3basyyF3zimL_yyF + // CHECK-LABEL: sil shared [serialized] [ossa] @$s19inlinable_attribute3basyyF3zimL_yyF func zim() { - // CHECK-LABEL: sil shared [serializable] [ossa] @$s19inlinable_attribute3basyyF3zimL_yyF4zangL_yyF + // CHECK-LABEL: sil shared [serialized] [ossa] @$s19inlinable_attribute3basyyF3zimL_yyF4zangL_yyF func zang() { } } // CHECK-LABEL: sil shared [serialized] [ossa] @$s19inlinable_attribute3bas{{[_0-9a-zA-Z]*}}U_ let _ = { - // CHECK-LABEL: sil shared [serializable] [ossa] @$s19inlinable_attribute3basyyFyycfU_7zippityL_yyF + // CHECK-LABEL: sil shared [serialized] [ossa] @$s19inlinable_attribute3basyyFyycfU_7zippityL_yyF func zippity() { } } } @@ -168,18 +168,18 @@ public func global(_ x: Int) -> Int { return x } let _: @convention(c) (Int) -> Int = local } -// CHECK-LABEL: sil shared [serializable] [thunk] [ossa] @$s19inlinable_attribute6globalyS2iFTo : $@convention(c) (Int) -> Int +// CHECK-LABEL: sil shared [serialized] [thunk] [ossa] @$s19inlinable_attribute6globalyS2iFTo : $@convention(c) (Int) -> Int // CHECK: function_ref @$s19inlinable_attribute6globalyS2iF // CHECK: return // CHECK-LABEL: sil shared [serialized] [ossa] @$s19inlinable_attribute16cFunctionPointeryyFS2icfU_ : $@convention(thin) (Int) -> Int { -// CHECK-LABEL: sil shared [serializable] [thunk] [ossa] @$s19inlinable_attribute16cFunctionPointeryyFS2icfU_To : $@convention(c) (Int) -> Int { +// CHECK-LABEL: sil shared [serialized] [thunk] [ossa] @$s19inlinable_attribute16cFunctionPointeryyFS2icfU_To : $@convention(c) (Int) -> Int { // CHECK: function_ref @$s19inlinable_attribute16cFunctionPointeryyFS2icfU_ // CHECK: return -// CHECK-LABEL: sil shared [serializable] [ossa] @$s19inlinable_attribute16cFunctionPointeryyF5localL_yS2iF : $@convention(thin) (Int) -> Int { +// CHECK-LABEL: sil shared [serialized] [ossa] @$s19inlinable_attribute16cFunctionPointeryyF5localL_yS2iF : $@convention(thin) (Int) -> Int { -// CHECK-LABEL: sil shared [serializable] [thunk] [ossa] @$s19inlinable_attribute16cFunctionPointeryyF5localL_yS2iFTo : $@convention(c) (Int) -> Int { +// CHECK-LABEL: sil shared [serialized] [thunk] [ossa] @$s19inlinable_attribute16cFunctionPointeryyF5localL_yS2iFTo : $@convention(c) (Int) -> Int { // CHECK: function_ref @$s19inlinable_attribute16cFunctionPointeryyF5localL_yS2iF // CHECK: return diff --git a/test/SILGen/isolated_parameters.swift b/test/SILGen/isolated_parameters.swift index 833d65ef85995..dc63c2ae2c85c 100644 --- a/test/SILGen/isolated_parameters.swift +++ b/test/SILGen/isolated_parameters.swift @@ -10,3 +10,17 @@ public actor A { // CHECK: sil{{.*}} [ossa] @$s4test13takesIsolatedyyAA1ACYiF @available(SwiftStdlib 5.1, *) public func takesIsolated(_: isolated A) { } + +@available(SwiftStdlib 5.1, *) +public func takeClosureWithIsolatedParam(body: (isolated A) async -> Void) { } + +// Emit the unnamed parameter when it's isolated, so that we can hop to it. +// CHECK-LABEL: sil private [ossa] @$s4test0A24ClosureWithIsolatedParamyyFyAA1ACYiYaXEfU_ : $@convention(thin) @async (@guaranteed A) +// CHECK: bb0(%0 : @guaranteed $A): +// CHECK: [[COPY:%.*]] = copy_value %0 : $A +// CHECK-NEXT: [[BORROW:%.*]] = begin_borrow [[COPY]] : $A +// CHECK-NEXT: hop_to_executor [[BORROW]] : $A +@available(SwiftStdlib 5.1, *) +public func testClosureWithIsolatedParam() { + takeClosureWithIsolatedParam { _ in } +} diff --git a/test/SILGen/keypaths_inlinable.swift b/test/SILGen/keypaths_inlinable.swift index 1adf2dbcbcdb1..f72f0fe7985a4 100644 --- a/test/SILGen/keypaths_inlinable.swift +++ b/test/SILGen/keypaths_inlinable.swift @@ -26,21 +26,21 @@ public struct KeypathStruct { _ = \KeypathStruct[0, ""] } -// RESILIENT-LABEL: sil shared [serializable] [thunk] [ossa] @$s18keypaths_inlinable13KeypathStructV6storedSivpACTKq : $@convention(thin) (@in_guaranteed KeypathStruct) -> @out Int +// RESILIENT-LABEL: sil shared [serialized] [thunk] [ossa] @$s18keypaths_inlinable13KeypathStructV6storedSivpACTKq : $@convention(thin) (@in_guaranteed KeypathStruct) -> @out Int // RESILIENT: function_ref @$s18keypaths_inlinable13KeypathStructV6storedSivg -// RESILIENT-LABEL: sil shared [serializable] [thunk] [ossa] @$s18keypaths_inlinable13KeypathStructV6storedSivpACTkq : $@convention(thin) (@in_guaranteed Int, @inout KeypathStruct) -> () +// RESILIENT-LABEL: sil shared [serialized] [thunk] [ossa] @$s18keypaths_inlinable13KeypathStructV6storedSivpACTkq : $@convention(thin) (@in_guaranteed Int, @inout KeypathStruct) -> () // RESILIENT: function_ref @$s18keypaths_inlinable13KeypathStructV6storedSivs -// CHECK-LABEL: sil shared [serializable] [thunk] [ossa] @$s18keypaths_inlinable13KeypathStructV8computedSSvpACTKq : $@convention(thin) (@in_guaranteed KeypathStruct) -> @out String +// CHECK-LABEL: sil shared [serialized] [thunk] [ossa] @$s18keypaths_inlinable13KeypathStructV8computedSSvpACTKq : $@convention(thin) (@in_guaranteed KeypathStruct) -> @out String -// CHECK-LABEL: sil shared [serializable] [thunk] [ossa] @$s18keypaths_inlinable13KeypathStructV8computedSSvpACTkq : $@convention(thin) (@in_guaranteed String, @inout KeypathStruct) -> () +// CHECK-LABEL: sil shared [serialized] [thunk] [ossa] @$s18keypaths_inlinable13KeypathStructV8computedSSvpACTkq : $@convention(thin) (@in_guaranteed String, @inout KeypathStruct) -> () -// CHECK-LABEL: sil shared [serializable] [thunk] [ossa] @$sSiSSTHq : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool +// CHECK-LABEL: sil shared [serialized] [thunk] [ossa] @$sSiSSTHq : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool -// CHECK-LABEL: sil shared [serializable] [thunk] [ossa] @$sSiSSThq : $@convention(thin) (UnsafeRawPointer) -> Int +// CHECK-LABEL: sil shared [serialized] [thunk] [ossa] @$sSiSSThq : $@convention(thin) (UnsafeRawPointer) -> Int -// CHECK-LABEL: sil shared [serializable] [thunk] [ossa] @$s18keypaths_inlinable13KeypathStructVySbSi_SStcipACTKq : $@convention(thin) (@in_guaranteed KeypathStruct, UnsafeRawPointer) -> @out Bool +// CHECK-LABEL: sil shared [serialized] [thunk] [ossa] @$s18keypaths_inlinable13KeypathStructVySbSi_SStcipACTKq : $@convention(thin) (@in_guaranteed KeypathStruct, UnsafeRawPointer) -> @out Bool -// CHECK-LABEL: sil shared [serializable] [thunk] [ossa] @$s18keypaths_inlinable13KeypathStructVySbSi_SStcipACTkq : $@convention(thin) (@in_guaranteed Bool, @inout KeypathStruct, UnsafeRawPointer) -> () +// CHECK-LABEL: sil shared [serialized] [thunk] [ossa] @$s18keypaths_inlinable13KeypathStructVySbSi_SStcipACTkq : $@convention(thin) (@in_guaranteed Bool, @inout KeypathStruct, UnsafeRawPointer) -> () diff --git a/test/SILGen/modify_objc.swift b/test/SILGen/modify_objc.swift index 7f76e4f95b1f4..567f7dcdb836b 100644 --- a/test/SILGen/modify_objc.swift +++ b/test/SILGen/modify_objc.swift @@ -24,7 +24,7 @@ extension ClassWithBlockProperty : ProtocolWithBlockProperty {} // CHECK-NEXT: ([[ADDR:%.*]], [[TOKEN:%.*]]) = begin_apply [[FN]]([[SELF]]) // CHECK-NEXT: yield [[ADDR]] : $*Optional<@callee_guaranteed (@guaranteed Optional) -> ()> -// CHECK-LABEL: sil shared [serializable] [ossa] @$sSo22ClassWithBlockPropertyC5blockySSSgcSgvM : +// CHECK-LABEL: sil shared [serialized] [ossa] @$sSo22ClassWithBlockPropertyC5blockySSSgcSgvM : // CHECK-SAME: $@yield_once @convention(method) (@guaranteed ClassWithBlockProperty) -> @yields @inout Optional<@callee_guaranteed (@guaranteed Optional) -> ()> // Protocol witness for 'dependentBlock' @@ -41,7 +41,7 @@ extension ClassWithBlockProperty : ProtocolWithBlockProperty {} // CHECK-NEXT: store [[OUT_FUNCTION]] to [init] [[TEMP]] : // CHECK-NEXT: yield [[TEMP]] -// CHECK-LABEL: sil shared [serializable] [ossa] @$sSo22ClassWithBlockPropertyC09dependentC0ySSSgcSgvM : +// CHECK-LABEL: sil shared [serialized] [ossa] @$sSo22ClassWithBlockPropertyC09dependentC0ySSSgcSgvM : // CHECK-SAME: $@yield_once @convention(method) (@guaranteed ClassWithBlockProperty) -> @yields @inout Optional<@callee_guaranteed (@guaranteed Optional) -> ()> // Make sure 'modify' implementations for 'dynamic' properties go through diff --git a/test/SILGen/nested_generics.swift b/test/SILGen/nested_generics.swift index 5f35add663588..5b332ef1fc300 100644 --- a/test/SILGen/nested_generics.swift +++ b/test/SILGen/nested_generics.swift @@ -155,7 +155,7 @@ func eatDinnerConcrete(d: inout Lunch.NewYork>.Dinner.NewYork) -> (@out nested_generics.HotDogs.American) to @escaping @callee_guaranteed (@guaranteed nested_generics.Pizzas.NewYork) -> (@unowned nested_generics.HotDogs.American) -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$s15nested_generics6PizzasV7NewYorkCyAA11ChiliFlakesV_GAA7HotDogsC8AmericanVIeggr_AhLIeggd_TR : $@convention(thin) (@guaranteed Pizzas.NewYork, @guaranteed @callee_guaranteed (@guaranteed Pizzas.NewYork) -> @out HotDogs.American) -> HotDogs.American +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$s15nested_generics6PizzasV7NewYorkCyAA11ChiliFlakesV_GAA7HotDogsC8AmericanVIeggr_AhLIeggd_TR : $@convention(thin) (@guaranteed Pizzas.NewYork, @guaranteed @callee_guaranteed (@guaranteed Pizzas.NewYork) -> @out HotDogs.American) -> HotDogs.American // CHECK-LABEL: // nested_generics.eatDinnerConcrete(d: inout nested_generics.Lunch.NewYork>.Dinner, t: nested_generics.Deli.Pepperoni, u: nested_generics.Deli.Mustard) -> () // CHECK-LABEL: sil hidden [ossa] @$s15nested_generics17eatDinnerConcrete1d1t1uyAA5LunchV0D0VyAA6PizzasV7NewYorkCyAA6PepperV_G_AA7HotDogsC8AmericanVGz_AA4DeliC9PepperoniCyAO_GAW7MustardOyAO_GtF : $@convention(thin) (@inout Lunch.NewYork>.Dinner, @guaranteed Deli.Pepperoni, Deli.Mustard) -> () @@ -177,7 +177,7 @@ func eatDinnerConcrete(d: inout Lunch.NewYork>.Dinner.NewYork) -> (@out nested_generics.HotDogs.American) to @escaping @callee_guaranteed (@guaranteed nested_generics.Pizzas.NewYork) -> (@unowned nested_generics.HotDogs.American) -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$s15nested_generics6PizzasV7NewYorkCyAA6PepperV_GAA7HotDogsC8AmericanVIeggr_AhLIeggd_TR : $@convention(thin) (@guaranteed Pizzas.NewYork, @guaranteed @callee_guaranteed (@guaranteed Pizzas.NewYork) -> @out HotDogs.American) -> HotDogs.American +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$s15nested_generics6PizzasV7NewYorkCyAA6PepperV_GAA7HotDogsC8AmericanVIeggr_AhLIeggd_TR : $@convention(thin) (@guaranteed Pizzas.NewYork, @guaranteed @callee_guaranteed (@guaranteed Pizzas.NewYork) -> @out HotDogs.American) -> HotDogs.American // CHECK-LABEL: // closure #1 (nested_generics.Pizzas.NewYork) -> nested_generics.HotDogs.American in nested_generics.calls() -> () // CHECK-LABEL: sil private [ossa] @$s15nested_generics5callsyyFAA7HotDogsC8AmericanVAA6PizzasV7NewYorkCyAA6PepperV_GcfU_ : diff --git a/test/SILGen/newtype.swift b/test/SILGen/newtype.swift index d8fb876c64a3b..10c383f4c2efd 100644 --- a/test/SILGen/newtype.swift +++ b/test/SILGen/newtype.swift @@ -16,7 +16,7 @@ func createErrorDomain(str: String) -> ErrorDomain { return ErrorDomain(rawValue: str) } -// CHECK-RAW-LABEL: sil shared [transparent] [serializable] [ossa] @$sSo14SNTErrorDomaina8rawValueABSS_tcfC +// CHECK-RAW-LABEL: sil shared [transparent] [serialized] [ossa] @$sSo14SNTErrorDomaina8rawValueABSS_tcfC // CHECK-RAW: bb0([[STR:%[0-9]+]] : @owned $String, // CHECK-RAW: [[SELF_BOX:%[0-9]+]] = alloc_box ${ var ErrorDomain } // CHECK-RAW: [[MARKED_SELF_BOX:%[0-9]+]] = mark_uninitialized [rootself] [[SELF_BOX]] @@ -37,7 +37,7 @@ func getRawValue(ed: ErrorDomain) -> String { return ed.rawValue } -// CHECK-RAW-LABEL: sil shared [serializable] [ossa] @$sSo14SNTErrorDomaina8rawValueSSvg +// CHECK-RAW-LABEL: sil shared [serialized] [ossa] @$sSo14SNTErrorDomaina8rawValueSSvg // CHECK-RAW: bb0([[SELF:%[0-9]+]] : @guaranteed $ErrorDomain): // CHECK-RAW: [[STORED_VALUE:%[0-9]+]] = struct_extract [[SELF]] : $ErrorDomain, #ErrorDomain._rawValue // CHECK-RAW: [[STORED_VALUE_COPY:%.*]] = copy_value [[STORED_VALUE]] diff --git a/test/SILGen/nsmanaged-witness.swift b/test/SILGen/nsmanaged-witness.swift index 8c138caa2fb34..bd06b0a679837 100644 --- a/test/SILGen/nsmanaged-witness.swift +++ b/test/SILGen/nsmanaged-witness.swift @@ -61,5 +61,5 @@ extension Foo: NativeIntProperty {} // TODO: We can't emit a vtable entry for modify for ObjC types. // CHECK-NOT: class_method {{.*}}Foo{{.*}}intProperty{{.*}}modify -// CHECK-LABEL: sil shared [serializable] [ossa] @$sSo3FooC11intPropertys5Int32VvM +// CHECK-LABEL: sil shared [serialized] [ossa] @$sSo3FooC11intPropertys5Int32VvM diff --git a/test/SILGen/objc_blocks_bridging.swift b/test/SILGen/objc_blocks_bridging.swift index 6da816f1ae941..80e7de30141a5 100644 --- a/test/SILGen/objc_blocks_bridging.swift +++ b/test/SILGen/objc_blocks_bridging.swift @@ -42,7 +42,7 @@ import Foundation return f(x) } - // GUARANTEED-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sSo8NSStringCABIyBya_S2SIeggo_TR : $@convention(thin) (@guaranteed String, @guaranteed @convention(block) @noescape (NSString) -> @autoreleased NSString) -> @owned String { + // GUARANTEED-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sSo8NSStringCABIyBya_S2SIeggo_TR : $@convention(thin) (@guaranteed String, @guaranteed @convention(block) @noescape (NSString) -> @autoreleased NSString) -> @owned String { // GUARANTEED: bb0(%0 : @guaranteed $String, [[BLOCK:%.*]] : @guaranteed $@convention(block) @noescape (NSString) -> @autoreleased NSString): // GUARANTEED: [[BRIDGE:%.*]] = function_ref @$sSS10FoundationE19_bridgeToObjectiveCSo8NSStringCyF // GUARANTEED: [[NSSTR:%.*]] = apply [[BRIDGE]](%0) @@ -146,7 +146,7 @@ class Test: NSObject { @objc func blockTakesBlock() -> ((Int) -> Int) -> Int {} } -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sS2iIgyd_SiIegyd_S2iIyByd_SiIeyByd_TR +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sS2iIgyd_SiIegyd_S2iIyByd_SiIeyByd_TR // CHECK: [[BLOCK_COPY:%.*]] = copy_block [[ORIG_BLOCK:%.*]] : // CHECK: [[CLOSURE:%.*]] = partial_apply [callee_guaranteed] {{%.*}}([[BLOCK_COPY]]) // CHECK: [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[CLOSURE]] @@ -156,14 +156,14 @@ class Test: NSObject { func clearDraggingItemImageComponentsProvider(_ x: NSDraggingItem) { x.imageComponentsProvider = { [] } } -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sSayypGIego_So7NSArrayCSgIeyBa_TR +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sSayypGIego_So7NSArrayCSgIeyBa_TR // CHECK: [[CONVERT:%.*]] = function_ref @$sSa10FoundationE19_bridgeToObjectiveCSo7NSArrayCyF // CHECK: [[CONVERTED:%.*]] = apply [[CONVERT]] // CHECK: [[OPTIONAL:%.*]] = enum $Optional, #Optional.some!enumelt, [[CONVERTED]] // CHECK: return [[OPTIONAL]] // CHECK-LABEL: sil hidden [ossa] @{{.*}}bridgeNonnullBlockResult{{.*}} -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sSSIego_So8NSStringCSgIeyBa_TR +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sSSIego_So8NSStringCSgIeyBa_TR // CHECK: [[CONVERT:%.*]] = function_ref @$sSS10FoundationE19_bridgeToObjectiveCSo8NSStringCyF // CHECK: [[BRIDGED:%.*]] = apply [[CONVERT]] // CHECK: [[OPTIONAL_BRIDGED:%.*]] = enum $Optional, #Optional.some!enumelt, [[BRIDGED]] @@ -296,8 +296,8 @@ struct GenericStruct { o.someDynamicMethod(closure: closure) } } -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sIg_Iegy_IyB_IyBy_TR : $@convention(c) (@inout_aliasable @block_storage @callee_guaranteed (@noescape @callee_guaranteed () -> ()) -> (), @convention(block) @noescape () -> ()) -> () { -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sIyB_Ieg_TR : $@convention(thin) (@guaranteed @convention(block) @noescape () -> ()) -> () +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sIg_Iegy_IyB_IyBy_TR : $@convention(c) (@inout_aliasable @block_storage @callee_guaranteed (@noescape @callee_guaranteed () -> ()) -> (), @convention(block) @noescape () -> ()) -> () { +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sIyB_Ieg_TR : $@convention(thin) (@guaranteed @convention(block) @noescape () -> ()) -> () // rdar://35402696 func takeOptStringFunction(fn: (String) -> String?) {} diff --git a/test/SILGen/objc_bridging.swift b/test/SILGen/objc_bridging.swift index c7354d442bcdc..05c3213065362 100644 --- a/test/SILGen/objc_bridging.swift +++ b/test/SILGen/objc_bridging.swift @@ -503,7 +503,7 @@ func forceNSArrayMembers() -> (NSArray, NSArray) { // arguments lifetime-extends the bridged pointer for the right duration. // -// CHECK-LABEL: sil shared [serializable] [ossa] @$sSo7NSArrayC7objects5countABSPyyXlSgGSg_s5Int32VtcfC +// CHECK-LABEL: sil shared [serialized] [ossa] @$sSo7NSArrayC7objects5countABSPyyXlSgGSg_s5Int32VtcfC // CHECK: [[SELF:%.*]] = alloc_ref_dynamic // CHECK: [[METHOD:%.*]] = function_ref @$sSo7NSArrayC7objects5countABSPyyXlSgGSg_s5Int32VtcfcTO // CHECK: [[RESULT:%.*]] = apply [[METHOD]] @@ -613,7 +613,7 @@ func defineNonStandardBlock(x: Any) { let fn : @convention(block) (Any) -> Any = { y in takeTwoAnys(x, y) } } -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sypypIegnr_yXlyXlIeyBya_TR : $@convention(c) (@inout_aliasable @block_storage @callee_guaranteed (@in_guaranteed Any) -> @out Any, AnyObject) -> @autoreleased AnyObject +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sypypIegnr_yXlyXlIeyBya_TR : $@convention(c) (@inout_aliasable @block_storage @callee_guaranteed (@in_guaranteed Any) -> @out Any, AnyObject) -> @autoreleased AnyObject // CHECK: bb0(%0 : $*@block_storage @callee_guaranteed (@in_guaranteed Any) -> @out Any, %1 : @unowned $AnyObject): // CHECK: [[T0:%.*]] = copy_value %1 : $AnyObject // CHECK: [[T1:%.*]] = open_existential_ref [[T0]] : $AnyObject diff --git a/test/SILGen/objc_bridging_any.swift b/test/SILGen/objc_bridging_any.swift index c0e4601b4fb92..3a9bf359fb602 100644 --- a/test/SILGen/objc_bridging_any.swift +++ b/test/SILGen/objc_bridging_any.swift @@ -477,7 +477,7 @@ class SwiftIdLover : NSObject, Anyable { // CHECK-NEXT: destroy_value [[SELF_COPY]] // CHECK-NEXT: return [[RESULT]] - // CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$syXlIyBy_ypIegn_TR + // CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$syXlIyBy_ypIegn_TR // CHECK: bb0([[ANY:%.*]] : $*Any, [[BLOCK:%.*]] : @guaranteed $@convention(block) @noescape (AnyObject) -> ()): // CHECK-NEXT: [[OPENED_ANY:%.*]] = open_existential_addr immutable_access [[ANY]] : $*Any to $*[[OPENED_TYPE:@opened.*Any]], // CHECK: [[TMP:%.*]] = alloc_stack @@ -515,7 +515,7 @@ class SwiftIdLover : NSObject, Anyable { // CHECK-NEXT: dealloc_stack [[BLOCK_STORAGE]] // CHECK-NEXT: return [[BLOCK]] - // CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sypIegn_yXlIeyBy_TR : $@convention(c) (@inout_aliasable @block_storage @callee_guaranteed (@in_guaranteed Any) -> (), AnyObject) -> () + // CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sypIegn_yXlIeyBy_TR : $@convention(c) (@inout_aliasable @block_storage @callee_guaranteed (@in_guaranteed Any) -> (), AnyObject) -> () // CHECK: bb0([[BLOCK_STORAGE:%.*]] : $*@block_storage @callee_guaranteed (@in_guaranteed Any) -> (), [[ANY:%.*]] : @unowned $AnyObject): // CHECK-NEXT: [[BLOCK_STORAGE_ADDR:%.*]] = project_block_storage [[BLOCK_STORAGE]] // CHECK-NEXT: [[FUNCTION:%.*]] = load [copy] [[BLOCK_STORAGE_ADDR]] @@ -556,7 +556,7 @@ class SwiftIdLover : NSObject, Anyable { // CHECK-NEXT: destroy_value [[ANY_COPY]] // CHECK-NEXT: return [[RESULT]] - // CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$syXlIyBa_ypIegr_TR : $@convention(thin) (@guaranteed @convention(block) @noescape () -> @autoreleased AnyObject) -> @out Any + // CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$syXlIyBa_ypIegr_TR : $@convention(thin) (@guaranteed @convention(block) @noescape () -> @autoreleased AnyObject) -> @out Any // CHECK: bb0([[ANY_ADDR:%.*]] : $*Any, [[BLOCK:%.*]] : @guaranteed $@convention(block) @noescape () -> @autoreleased AnyObject): // CHECK-NEXT: [[BRIDGED:%.*]] = apply [[BLOCK]]() // CHECK-NEXT: [[OPTIONAL:%.*]] = unchecked_ref_cast [[BRIDGED]] @@ -593,7 +593,7 @@ class SwiftIdLover : NSObject, Anyable { // CHECK-NEXT: dealloc_stack [[BLOCK_STORAGE]] // CHECK-NEXT: return [[BLOCK]] - // CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sypIegr_yXlIeyBa_TR : $@convention(c) (@inout_aliasable @block_storage @callee_guaranteed () -> @out Any) -> @autoreleased AnyObject + // CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sypIegr_yXlIeyBa_TR : $@convention(c) (@inout_aliasable @block_storage @callee_guaranteed () -> @out Any) -> @autoreleased AnyObject // CHECK: bb0(%0 : $*@block_storage @callee_guaranteed () -> @out Any): // CHECK-NEXT: [[BLOCK_STORAGE_ADDR:%.*]] = project_block_storage %0 // CHECK-NEXT: [[FUNCTION:%.*]] = load [copy] [[BLOCK_STORAGE_ADDR]] @@ -619,7 +619,7 @@ class SwiftIdLover : NSObject, Anyable { @objc func methodReturningBlockReturningAny() -> (() -> Any) { fatalError() } @objc func methodReturningBlockReturningOptionalAny() -> (() -> Any?) { fatalError() } - // CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sypSgIegr_yXlSgIeyBa_TR + // CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sypSgIegr_yXlSgIeyBa_TR // CHECK: function_ref @$ss27_bridgeAnythingToObjectiveC{{.*}}F override init() { fatalError() } diff --git a/test/SILGen/objc_currying.swift b/test/SILGen/objc_currying.swift index afc08673a2d5b..7289643be3638 100644 --- a/test/SILGen/objc_currying.swift +++ b/test/SILGen/objc_currying.swift @@ -191,8 +191,8 @@ func curry_initializer() -> (Int) -> Gizmo? { return Gizmo.init(bellsOn:) } -// CHECK-LABEL: sil shared [serializable] [ossa] @$sSo5GizmoC7bellsOnABSgSi_tcfC : $@convention(method) (Int, @thick Gizmo.Type) -> @owned Optional { +// CHECK-LABEL: sil shared [serialized] [ossa] @$sSo5GizmoC7bellsOnABSgSi_tcfC : $@convention(method) (Int, @thick Gizmo.Type) -> @owned Optional { // CHECK-LABEL: sil private [ossa] @$s13objc_currying17curry_initializerSo5GizmoCSgSicyFAESicfu_ : $@convention(thin) (Int) -> @owned Optional { -// CHECK-LABEL: sil shared [serializable] [thunk] [ossa] @$sSo5GizmoC7bellsOnABSgSi_tcfcTO : $@convention(method) (Int, @owned Gizmo) -> @owned Optional { +// CHECK-LABEL: sil shared [serialized] [thunk] [ossa] @$sSo5GizmoC7bellsOnABSgSi_tcfcTO : $@convention(method) (Int, @owned Gizmo) -> @owned Optional { diff --git a/test/SILGen/objc_enum.swift b/test/SILGen/objc_enum.swift index a245f54acb6c5..e67b8a48e407a 100644 --- a/test/SILGen/objc_enum.swift +++ b/test/SILGen/objc_enum.swift @@ -7,8 +7,8 @@ import gizmo -// CHECK-DAG: sil shared [serializable] [ossa] @$sSo16NSRuncingOptionsV{{[_0-9a-zA-Z]*}}fC -// CHECK-DAG: sil shared [serializable] [ossa] @$sSo16NSRuncingOptionsV8rawValueSivg +// CHECK-DAG: sil shared [serialized] [ossa] @$sSo16NSRuncingOptionsV{{[_0-9a-zA-Z]*}}fC +// CHECK-DAG: sil shared [serialized] [ossa] @$sSo16NSRuncingOptionsV8rawValueSivg // Non-payload enum ctors don't need to be instantiated at all. // NEGATIVE-NOT: sil shared [transparent] [ossa] @$sSo16NSRuncingOptionsV5MinceAbBmF diff --git a/test/SILGen/objc_factory_init.swift b/test/SILGen/objc_factory_init.swift index 1f687ac5af828..99d8c3d57424a 100644 --- a/test/SILGen/objc_factory_init.swift +++ b/test/SILGen/objc_factory_init.swift @@ -5,7 +5,7 @@ import Foundation import ImportAsMember.Class -// CHECK-LABEL: sil shared [serializable] [thunk] [ossa] @$sSo4HiveC5queenABSgSo3BeeCSg_tcfCTO : $@convention(method) (@owned Optional, @thick Hive.Type) -> @owned Optional +// CHECK-LABEL: sil shared [serialized] [thunk] [ossa] @$sSo4HiveC5queenABSgSo3BeeCSg_tcfCTO : $@convention(method) (@owned Optional, @thick Hive.Type) -> @owned Optional func testInstanceTypeFactoryMethod(queen: Bee) { // CHECK: bb0([[QUEEN:%[0-9]+]] : @owned $Optional, [[HIVE_META:%[0-9]+]] : $@thick Hive.Type): // CHECK-NEXT: [[HIVE_META_OBJC:%[0-9]+]] = thick_to_objc_metatype [[HIVE_META]] : $@thick Hive.Type to $@objc_metatype Hive.Type diff --git a/test/SILGen/objc_imported_generic.swift b/test/SILGen/objc_imported_generic.swift index 15b9dae286f29..e6819ac1ee185 100644 --- a/test/SILGen/objc_imported_generic.swift +++ b/test/SILGen/objc_imported_generic.swift @@ -11,7 +11,7 @@ func callInitializer() { _ = GenericClass(thing: NSObject()) } -// CHECK-LABEL: sil shared [serializable] [ossa] @$sSo12GenericClassC5thingAByxGSgxSg_tcfC +// CHECK-LABEL: sil shared [serialized] [ossa] @$sSo12GenericClassC5thingAByxGSgxSg_tcfC // CHECK: thick_to_objc_metatype {{%.*}} : $@thick GenericClass.Type to $@objc_metatype GenericClass.Type public func genericMethodOnAnyObject(o: AnyObject, b: Bool) -> AnyObject { @@ -115,13 +115,13 @@ func configureWithoutOptions() { _ = GenericClass(options: nil) } -// CHECK-LABEL: sil shared [serializable] [thunk] [ossa] @$sSo12GenericClassC13arrayOfThingsAByxGSgSayxG_tcfcTO +// CHECK-LABEL: sil shared [serialized] [thunk] [ossa] @$sSo12GenericClassC13arrayOfThingsAByxGSgSayxG_tcfcTO // CHECK: objc_method {{%.*}} : $GenericClass, #GenericClass.init!initializer.foreign {{.*}}, $@convention(objc_method) @pseudogeneric <τ_0_0 where τ_0_0 : AnyObject> (NSArray, @owned GenericClass<τ_0_0>) -> @owned Optional> // foreign to native thunk for init(options:), uses GenericOption : Hashable // conformance -// CHECK-LABEL: sil shared [serializable] [thunk] [ossa] @$sSo12GenericClassC7optionsAByxGSgSDySo0A6OptionaypGSg_tcfcTO : $@convention(method) (@owned Optional>, @owned GenericClass) -> @owned Optional> +// CHECK-LABEL: sil shared [serialized] [thunk] [ossa] @$sSo12GenericClassC7optionsAByxGSgSDySo0A6OptionaypGSg_tcfcTO : $@convention(method) (@owned Optional>, @owned GenericClass) -> @owned Optional> // CHECK: [[FN:%.*]] = function_ref @$sSD10FoundationE19_bridgeToObjectiveCSo12NSDictionaryCyF : $@convention(method) <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (@guaranteed Dictionary<τ_0_0, τ_0_1>) -> @owned NSDictionary // CHECK: apply [[FN]]({{.*}}) : $@convention(method) <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (@guaranteed Dictionary<τ_0_0, τ_0_1>) -> @owned NSDictionary // CHECK: return diff --git a/test/SILGen/objc_imported_init.swift b/test/SILGen/objc_imported_init.swift index 3ddb95e6c8d30..9ca9f376588eb 100644 --- a/test/SILGen/objc_imported_init.swift +++ b/test/SILGen/objc_imported_init.swift @@ -4,7 +4,7 @@ import Foundation // Ensure we emit allocating constructor thunks for ObjC initializers that // were inherited. -// CHECK-LABEL: sil shared [serializable] [ossa] @$sSo3FooCABycfC : $@convention(method) (@thick Foo.Type) -> @owned Foo { +// CHECK-LABEL: sil shared [serialized] [ossa] @$sSo3FooCABycfC : $@convention(method) (@thick Foo.Type) -> @owned Foo { func foo() { _ = Foo() } diff --git a/test/SILGen/objc_init_unavailable.swift b/test/SILGen/objc_init_unavailable.swift index 3cc885ff775fc..7d3f30accff67 100644 --- a/test/SILGen/objc_init_unavailable.swift +++ b/test/SILGen/objc_init_unavailable.swift @@ -10,10 +10,10 @@ public func callUnavailableInit(name: String) -> ClassWithUnavailableInit { // CHECK: function_ref @$sSo24ClassWithUnavailableInitC8bundleIDABSgSSSg_tcfC : $@convention(method) (@owned Optional, @thick ClassWithUnavailableInit.Type) -> @owned Optional // CHECK: return -// CHECK-LABEL: sil shared [serializable] [ossa] @$sSo24ClassWithUnavailableInitC8bundleIDABSgSSSg_tcfC : $@convention(method) (@owned Optional, @thick ClassWithUnavailableInit.Type) -> @owned Optional { +// CHECK-LABEL: sil shared [serialized] [ossa] @$sSo24ClassWithUnavailableInitC8bundleIDABSgSSSg_tcfC : $@convention(method) (@owned Optional, @thick ClassWithUnavailableInit.Type) -> @owned Optional { // CHECK: function_ref @$sSo24ClassWithUnavailableInitC8bundleIDABSgSSSg_tcfcTO : $@convention(method) (@owned Optional, @owned ClassWithUnavailableInit) -> @owned Optional // CHECK: return -// CHECK-LABEL: sil shared [serializable] [thunk] [ossa] @$sSo24ClassWithUnavailableInitC8bundleIDABSgSSSg_tcfcTO : $@convention(method) (@owned Optional, @owned ClassWithUnavailableInit) -> @owned Optional { +// CHECK-LABEL: sil shared [serialized] [thunk] [ossa] @$sSo24ClassWithUnavailableInitC8bundleIDABSgSSSg_tcfcTO : $@convention(method) (@owned Optional, @owned ClassWithUnavailableInit) -> @owned Optional { // CHECK: objc_method %1 : $ClassWithUnavailableInit, #ClassWithUnavailableInit.init!initializer.foreign : (ClassWithUnavailableInit.Type) -> (String?) -> ClassWithUnavailableInit?, $@convention(objc_method) (Optional, @owned ClassWithUnavailableInit) -> @owned Optional -// CHECK: return \ No newline at end of file +// CHECK: return diff --git a/test/SILGen/objc_ownership_conventions.swift b/test/SILGen/objc_ownership_conventions.swift index a7bda4d5226a6..b5db92ec1cb04 100644 --- a/test/SILGen/objc_ownership_conventions.swift +++ b/test/SILGen/objc_ownership_conventions.swift @@ -12,7 +12,7 @@ func test3() -> NSObject { // CHECK: [[GIZMO_NS:%[0-9]+]] = upcast [[GIZMO:%[0-9]+]] : $Gizmo to $NSObject // CHECK: return [[GIZMO_NS]] : $NSObject - // CHECK-LABEL: sil shared [serializable] [ossa] @$sSo5GizmoC{{[_0-9a-zA-Z]*}}fC : $@convention(method) (@thick Gizmo.Type) -> @owned Optional + // CHECK-LABEL: sil shared [serialized] [ossa] @$sSo5GizmoC{{[_0-9a-zA-Z]*}}fC : $@convention(method) (@thick Gizmo.Type) -> @owned Optional // alloc is implicitly ns_returns_retained // init is implicitly ns_consumes_self and ns_returns_retained // CHECK: bb0([[GIZMO_META:%[0-9]+]] : $@thick Gizmo.Type): diff --git a/test/SILGen/objc_subscript.swift b/test/SILGen/objc_subscript.swift index f9ec54392f334..b1b6902c9ec4f 100644 --- a/test/SILGen/objc_subscript.swift +++ b/test/SILGen/objc_subscript.swift @@ -55,6 +55,6 @@ extension Guisemeau: SubscriptProto {} // CHECK: function_ref @$sSo9GuisemeauCyypSgSicigTO // CHECK: end sil function '$sSo9GuisemeauC14objc_subscript14SubscriptProtoA2cDPyypSgSicigTW' -// CHECK-LABEL: sil shared [serializable] [thunk] [ossa] @$sSo9GuisemeauCyypSgSicigTO +// CHECK-LABEL: sil shared [serialized] [thunk] [ossa] @$sSo9GuisemeauCyypSgSicigTO // CHECK: objc_method {{%[0-9]+}} : $Guisemeau, #Guisemeau.subscript!getter.foreign : (Guisemeau) -> (Int) -> Any?, $@convention(objc_method) (Int, Guisemeau) -> @autoreleased Optional // CHECK: end sil function '$sSo9GuisemeauCyypSgSicigTO' diff --git a/test/SILGen/objc_witnesses.swift b/test/SILGen/objc_witnesses.swift index fd70195f249e5..f851a3b0e56c6 100644 --- a/test/SILGen/objc_witnesses.swift +++ b/test/SILGen/objc_witnesses.swift @@ -64,7 +64,7 @@ protocol Subscriptable { // CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$sSo7NSArrayC14objc_witnesses13SubscriptableA2cDPyypSicigTW : // CHECK: function_ref @$sSo7NSArrayCyypSicigTO : $@convention(method) (Int, @guaranteed NSArray) -> @out Any -// CHECK-LABEL: sil shared [serializable] [thunk] [ossa] @$sSo7NSArrayCyypSicigTO : $@convention(method) (Int, @guaranteed NSArray) -> @out Any { +// CHECK-LABEL: sil shared [serialized] [thunk] [ossa] @$sSo7NSArrayCyypSicigTO : $@convention(method) (Int, @guaranteed NSArray) -> @out Any { // CHECK: objc_method {{%.*}} : $NSArray, #NSArray.subscript!getter.foreign extension NSArray: Subscriptable {} @@ -79,10 +79,10 @@ class Electron : Orbital { } // CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s14objc_witnesses8ElectronCAA7OrbitalA2aDP13quantumNumberSivgTW -// CHECK-LABEL: sil shared [transparent] [serializable] [thunk] [ossa] @$s14objc_witnesses8ElectronC13quantumNumberSivgTD +// CHECK-LABEL: sil shared [transparent] [serialized] [thunk] [ossa] @$s14objc_witnesses8ElectronC13quantumNumberSivgTD // CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s14objc_witnesses8ElectronCAA7OrbitalA2aDP13quantumNumberSivsTW -// CHECK-LABEL: sil shared [transparent] [serializable] [thunk] [ossa] @$s14objc_witnesses8ElectronC13quantumNumberSivsTD +// CHECK-LABEL: sil shared [transparent] [serialized] [thunk] [ossa] @$s14objc_witnesses8ElectronC13quantumNumberSivsTD // witness is a dynamic thunk and is public: @@ -95,7 +95,7 @@ public class Positron : Lepton { } // CHECK-LABEL: sil shared [transparent] [serialized] [thunk] [ossa] @$s14objc_witnesses8PositronCAA6LeptonA2aDP4spinSfvgTW -// CHECK-LABEL: sil shared [transparent] [serializable] [thunk] [ossa] @$s14objc_witnesses8PositronC4spinSfvgTD +// CHECK-LABEL: sil shared [transparent] [serialized] [thunk] [ossa] @$s14objc_witnesses8PositronC4spinSfvgTD // Override of property defined in @objc extension diff --git a/test/SILGen/opaque_values_silgen.swift b/test/SILGen/opaque_values_silgen.swift index c3aef9b597c0f..3f95233c63f53 100644 --- a/test/SILGen/opaque_values_silgen.swift +++ b/test/SILGen/opaque_values_silgen.swift @@ -129,7 +129,7 @@ enum AddressOnlyEnum { // part of s280_convExistTrivial: conversion between existential types - reabstraction thunk // --- -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] @$s20opaque_values_silgen1P_pAA13TrivialStructVIegnd_AA2P2_pAaE_pIegnr_TR : $@convention(thin) (@in_guaranteed P2, @guaranteed @callee_guaranteed (@in_guaranteed P) -> TrivialStruct) -> @out P2 { +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] @$s20opaque_values_silgen1P_pAA13TrivialStructVIegnd_AA2P2_pAaE_pIegnr_TR : $@convention(thin) (@in_guaranteed P2, @guaranteed @callee_guaranteed (@in_guaranteed P) -> TrivialStruct) -> @out P2 { // CHECK: bb0([[ARG0:%.*]] : $P2, [[ARG1:%.*]] : $@callee_guaranteed (@in_guaranteed P) -> TrivialStruct): // CHECK: [[OPENED_ARG:%.*]] = open_existential_value [[ARG]] : $P2 to $@opened({{.*}}) P2 // CHECK: [[COPIED_VAL:%.*]] = copy_value [[OPENED_ARG]] @@ -144,7 +144,7 @@ enum AddressOnlyEnum { // part of s290_convOptExistTriv: conversion between existential types - reabstraction thunk - optionals case // --- -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] @$s20opaque_values_silgen1P_pSgAA13TrivialStructVIegnd_AESgAA2P2_pIegyr_TR : $@convention(thin) (Optional, @guaranteed @callee_guaranteed (@in_guaranteed Optional

) -> TrivialStruct) -> @out P2 { +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] @$s20opaque_values_silgen1P_pSgAA13TrivialStructVIegnd_AESgAA2P2_pIegyr_TR : $@convention(thin) (Optional, @guaranteed @callee_guaranteed (@in_guaranteed Optional

) -> TrivialStruct) -> @out P2 { // CHECK: bb0([[ARG0:%.*]] : $Optional, [[ARG1:%.*]] : $@callee_guaranteed (@in_guaranteed Optional

) -> TrivialStruct): // CHECK: switch_enum [[ARG0]] : $Optional, case #Optional.some!enumelt: bb2, case #Optional.none!enumelt: bb1 // CHECK: bb1: @@ -1087,7 +1087,7 @@ public func s020_______assignToVar() { // s270_convOptAnyStruct continued Test: reabstraction thunk helper // --- -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] @$s20opaque_values_silgen9AnyStructVSgACIegnr_A2DIegnr_TR : $@convention(thin) (@in_guaranteed Optional, @guaranteed @callee_guaranteed (@in_guaranteed Optional) -> @out AnyStruct) -> @out Optional { +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] @$s20opaque_values_silgen9AnyStructVSgACIegnr_A2DIegnr_TR : $@convention(thin) (@in_guaranteed Optional, @guaranteed @callee_guaranteed (@in_guaranteed Optional) -> @out AnyStruct) -> @out Optional { // CHECK: bb0([[ARG0:%.*]] : $Optional, [[ARG1:%.*]] : $@callee_guaranteed (@in_guaranteed Optional) -> @out AnyStruct): // CHECK: [[APPLYARG:%.*]] = apply [[ARG1]]([[ARG0]]) : $@callee_guaranteed (@in_guaranteed Optional) -> @out AnyStruct // CHECK: [[RETVAL:%.*]] = enum $Optional, #Optional.some!enumelt, [[APPLYARG]] : $AnyStruct @@ -1096,7 +1096,7 @@ public func s020_______assignToVar() { // s300__convETupleToAny continued Test: reabstraction of () to Any // --- -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] @$sIeg_ypIegr_TR : $@convention(thin) (@guaranteed @callee_guaranteed () -> ()) -> @out Any { +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] @$sIeg_ypIegr_TR : $@convention(thin) (@guaranteed @callee_guaranteed () -> ()) -> @out Any { // CHECK: bb0([[ARG:%.*]] : $@callee_guaranteed () -> ()): // CHECK: [[ASTACK:%.*]] = alloc_stack $Any // CHECK: [[IADDR:%.*]] = init_existential_addr [[ASTACK]] : $*Any, $() @@ -1108,7 +1108,7 @@ public func s020_______assignToVar() { // s310_convIntTupleAny continued Test: reabstraction of non-empty tuple to Any // --- -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] @$sS2iIegdd_ypIegr_TR : $@convention(thin) (@guaranteed @callee_guaranteed () -> (Int, Int)) -> @out Any { +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] @$sS2iIegdd_ypIegr_TR : $@convention(thin) (@guaranteed @callee_guaranteed () -> (Int, Int)) -> @out Any { // CHECK: bb0([[ARG:%.*]] : $@callee_guaranteed () -> (Int, Int)): // CHECK: [[ASTACK:%.*]] = alloc_stack $Any // CHECK: [[IADDR:%.*]] = init_existential_addr [[ASTACK]] : $*Any, $(Int, Int) @@ -1126,7 +1126,7 @@ public func s020_______assignToVar() { // CHECK-LABEL: } // end sil function '$sS2iIegdd_ypIegr_TR' -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] @{{.*}} : $@convention(thin) (Int, Int, Int, Int, Int, @guaranteed @callee_guaranteed (@in_guaranteed (Int, (Int, (Int, Int)), Int)) -> @out (Int, (Int, (Int, Int)), Int)) -> (Int, Int, Int, Int, Int) +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] @{{.*}} : $@convention(thin) (Int, Int, Int, Int, Int, @guaranteed @callee_guaranteed (@in_guaranteed (Int, (Int, (Int, Int)), Int)) -> @out (Int, (Int, (Int, Int)), Int)) -> (Int, Int, Int, Int, Int) // CHECK: bb0([[ARG0:%.*]] : $Int, [[ARG1:%.*]] : $Int, [[ARG2:%.*]] : $Int, [[ARG3:%.*]] : $Int, [[ARG4:%.*]] : $Int, [[ARG5:%.*]] : $@callee_guaranteed (@in_guaranteed (Int, (Int, (Int, Int)), Int)) -> @out (Int, (Int, (Int, Int)), Int)): // CHECK: [[TUPLE_TO_APPLY0:%.*]] = tuple ([[ARG2]] : $Int, [[ARG3]] : $Int) // CHECK: [[TUPLE_TO_APPLY1:%.*]] = tuple ([[ARG1]] : $Int, [[TUPLE_TO_APPLY0]] : $(Int, Int)) @@ -1143,7 +1143,7 @@ public func s020_______assignToVar() { // CHECK: return [[RET_VAL_TUPLE]] : $(Int, Int, Int, Int, Int) // CHECK-LABEL: } // end sil function '{{.*}}' -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] @{{.*}} : $@convention(thin) (Int, @in_guaranteed T, @guaranteed @callee_guaranteed (@in_guaranteed (Int, T)) -> @out (Int, T)) -> (Int, @out T) { +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] @{{.*}} : $@convention(thin) (Int, @in_guaranteed T, @guaranteed @callee_guaranteed (@in_guaranteed (Int, T)) -> @out (Int, T)) -> (Int, @out T) { // CHECK: bb0([[ARG0:%.*]] : $Int, [[ARG1:%.*]] : $T, [[ARG2:%.*]] : $@callee_guaranteed (@in_guaranteed (Int, T)) -> @out (Int, T)): // CHECK: [[TUPLE_TO_APPLY:%.*]] = tuple ([[ARG0]] : $Int, [[ARG1]] : $T) // CHECK: [[TUPLE_APPLY:%.*]] = apply [[ARG2]]([[TUPLE_TO_APPLY]]) : $@callee_guaranteed (@in_guaranteed (Int, T)) -> @out (Int, T) @@ -1201,7 +1201,7 @@ extension Dictionary { // s400______maybeCloneP continued Test: reabstraction thunk // --- -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] @$sxSgIegr_20opaque_values_silgen8Clonable_pSgIegr_AbCRzlTR : $@convention(thin) <τ_0_0 where τ_0_0 : Clonable> (@guaranteed @callee_guaranteed () -> @out Optional<τ_0_0>) -> @out Optional { +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] @$sxSgIegr_20opaque_values_silgen8Clonable_pSgIegr_AbCRzlTR : $@convention(thin) <τ_0_0 where τ_0_0 : Clonable> (@guaranteed @callee_guaranteed () -> @out Optional<τ_0_0>) -> @out Optional { // CHECK: bb0([[ARG:%.*]] : $@callee_guaranteed () -> @out Optional<τ_0_0>): // CHECK: [[APPLY_ARG:%.*]] = apply [[ARG]]() : $@callee_guaranteed () -> @out Optional<τ_0_0> // CHECK: switch_enum [[APPLY_ARG]] : $Optional<τ_0_0>, case #Optional.some!enumelt: bb2, case #Optional.none!enumelt: bb1 @@ -1218,7 +1218,7 @@ extension Dictionary { // s320__transImplodeAny continued Test: reabstraction thunk // --- -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] @$sypIegn_S2iIegyy_TR : $@convention(thin) (Int, Int, @guaranteed @callee_guaranteed (@in_guaranteed Any) -> ()) -> () { +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] @$sypIegn_S2iIegyy_TR : $@convention(thin) (Int, Int, @guaranteed @callee_guaranteed (@in_guaranteed Any) -> ()) -> () { // CHECK: bb0([[ARG0:%.*]] : $Int, [[ARG1:%.*]] : $Int, [[ARG2:%.*]] : $@callee_guaranteed (@in_guaranteed Any) -> ()): // CHECK: [[ASTACK:%.*]] = alloc_stack $Any // CHECK: [[IADDR:%.*]] = init_existential_addr [[ASTACK]] : $*Any, $(Int, Int) diff --git a/test/SILGen/partial_apply_protocol.swift b/test/SILGen/partial_apply_protocol.swift index 71ee86fd5b418..df924123b5394 100644 --- a/test/SILGen/partial_apply_protocol.swift +++ b/test/SILGen/partial_apply_protocol.swift @@ -42,7 +42,7 @@ func testClonable(c: Clonable) { let _: () -> () -> Clonable = c.getCloneFn } -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sxIegr_22partial_apply_protocol8Clonable_pIegr_AaBRzlTR : $@convention(thin) <τ_0_0 where τ_0_0 : Clonable> (@guaranteed @callee_guaranteed () -> @out τ_0_0) -> @out Clonable +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sxIegr_22partial_apply_protocol8Clonable_pIegr_AaBRzlTR : $@convention(thin) <τ_0_0 where τ_0_0 : Clonable> (@guaranteed @callee_guaranteed () -> @out τ_0_0) -> @out Clonable // CHECK: bb0(%0 : $*Clonable, %1 : @guaranteed $@callee_guaranteed () -> @out τ_0_0): // CHECK-NEXT: [[INNER_RESULT:%.*]] = alloc_stack $τ_0_0 // CHECK-NEXT: apply %1([[INNER_RESULT]]) diff --git a/test/SILGen/protocol_enum_witness.swift b/test/SILGen/protocol_enum_witness.swift index 0cf47d79b70ae..234d03122dbfc 100644 --- a/test/SILGen/protocol_enum_witness.swift +++ b/test/SILGen/protocol_enum_witness.swift @@ -34,7 +34,7 @@ enum InternalEnumWithPublicStruct : Foo { // CHECK-NEXT: return [[TUPLE]] : $() // CHECK-END: } -// CHECK-LABEL: sil shared [transparent] [serializable] [ossa] @$s21protocol_enum_witness3BarO6buttonyA2CmF : $@convention(method) (@thin Bar.Type) -> Bar { +// CHECK-LABEL: sil shared [transparent] [serialized] [ossa] @$s21protocol_enum_witness3BarO6buttonyA2CmF : $@convention(method) (@thin Bar.Type) -> Bar { // CHECK: bb0({{%.*}} : $@thin Bar.Type): // CHECK-NEXT: [[CASE:%.*]] = enum $Bar, #Bar.button!enumelt // CHECK-NEXT: return [[CASE]] : $Bar diff --git a/test/SILGen/protocol_with_superclass.swift b/test/SILGen/protocol_with_superclass.swift index 8f3c86bc2f9bc..b8ce5f9979fc7 100644 --- a/test/SILGen/protocol_with_superclass.swift +++ b/test/SILGen/protocol_with_superclass.swift @@ -278,7 +278,7 @@ func passesFuncTakingBaseClass() { // CHECK-LABEL: sil hidden [ossa] @$s24protocol_with_superclass25passesFuncTakingBaseClassyyF : $@convention(thin) () -> () -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$s24protocol_with_superclass9BaseClassCIegg_AA12RefinedProto_pIegg_TR : $@convention(thin) (@guaranteed RefinedProto, @guaranteed @callee_guaranteed (@guaranteed BaseClass) -> ()) -> () +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$s24protocol_with_superclass9BaseClassCIegg_AA12RefinedProto_pIegg_TR : $@convention(thin) (@guaranteed RefinedProto, @guaranteed @callee_guaranteed (@guaranteed BaseClass) -> ()) -> () // CHECK: [[PAYLOAD:%.*]] = open_existential_ref %0 : $RefinedProto to $@opened("{{.*}}") RefinedProto // CHECK: [[COPY:%.*]] = copy_value [[PAYLOAD]] // CHECK: [[UPCAST:%.*]] = upcast [[COPY]] : $@opened("{{.*}}") RefinedProto to $BaseClass diff --git a/test/SILGen/protocol_with_superclass_where_clause.swift b/test/SILGen/protocol_with_superclass_where_clause.swift index 750fee765dd4f..fefe5571ff40c 100644 --- a/test/SILGen/protocol_with_superclass_where_clause.swift +++ b/test/SILGen/protocol_with_superclass_where_clause.swift @@ -278,7 +278,7 @@ func passesFuncTakingBaseClass() { // CHECK-LABEL: sil hidden [ossa] @$s24protocol_with_superclass25passesFuncTakingBaseClassyyF : $@convention(thin) () -> () -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$s24protocol_with_superclass9BaseClassCIegg_AA12RefinedProto_pIegg_TR : $@convention(thin) (@guaranteed RefinedProto, @guaranteed @callee_guaranteed (@guaranteed BaseClass) -> ()) -> () +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$s24protocol_with_superclass9BaseClassCIegg_AA12RefinedProto_pIegg_TR : $@convention(thin) (@guaranteed RefinedProto, @guaranteed @callee_guaranteed (@guaranteed BaseClass) -> ()) -> () // CHECK: [[PAYLOAD:%.*]] = open_existential_ref %0 : $RefinedProto to $@opened("{{.*}}") RefinedProto // CHECK: [[COPY:%.*]] = copy_value [[PAYLOAD]] // CHECK: [[UPCAST:%.*]] = upcast [[COPY]] : $@opened("{{.*}}") RefinedProto to $BaseClass diff --git a/test/SILGen/reabstract.swift b/test/SILGen/reabstract.swift index a480cfc9b961a..a68773ff4d3fa 100644 --- a/test/SILGen/reabstract.swift +++ b/test/SILGen/reabstract.swift @@ -48,7 +48,7 @@ func test0() { // MANDATORY-NEXT: return // MANDATORY-NEXT: } // end sil function '$s10reabstract5test0yyF' -// CHECK: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] [[THUNK]] : $@convention(thin) (@in_guaranteed Int, @noescape @callee_guaranteed (Int) -> Optional) -> @out Optional { +// CHECK: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] [[THUNK]] : $@convention(thin) (@in_guaranteed Int, @noescape @callee_guaranteed (Int) -> Optional) -> @out Optional { // CHECK: [[T0:%.*]] = load [trivial] %1 : $*Int // CHECK-NEXT: [[T1:%.*]] = apply %2([[T0]]) // CHECK-NEXT: store [[T1]] to [trivial] %0 @@ -91,12 +91,12 @@ func testInoutOpaque(_ c: C, i: Int) { // CHECK: apply [[CLOSURE2]] // CHECK: } // end sil function '$s10reabstract15testInoutOpaque_1iyAA1CC_SitF' -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$s10reabstract1CCSiIegly_ACSiytIeglnr_TR : $@convention(thin) (@inout C, @in_guaranteed Int, @guaranteed @callee_guaranteed (@inout C, Int) -> ()) -> @out () { +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$s10reabstract1CCSiIegly_ACSiytIeglnr_TR : $@convention(thin) (@inout C, @in_guaranteed Int, @guaranteed @callee_guaranteed (@inout C, Int) -> ()) -> @out () { func closureTakingOptional(_ fn: (Int?) -> ()) {} closureTakingOptional({ (_: Any) -> () in }) -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sypIgn_SiSgIegy_TR : $@convention(thin) (Optional, @noescape @callee_guaranteed (@in_guaranteed Any) -> ()) -> () +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sypIgn_SiSgIegy_TR : $@convention(thin) (Optional, @noescape @callee_guaranteed (@in_guaranteed Any) -> ()) -> () // CHECK: [[ANYADDR:%.*]] = alloc_stack $Any // CHECK: [[OPTADDR:%.*]] = init_existential_addr [[ANYADDR]] : $*Any, $Optional // CHECK: store %0 to [trivial] [[OPTADDR]] : $*Optional @@ -105,7 +105,7 @@ closureTakingOptional({ (_: Any) -> () in }) // Same behavior as above with other ownership qualifiers. func evenLessFun(_ s: __shared C, _ o: __owned C) {} -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$s10reabstract1CCACIeggx_A2CytIegnir_TR : $@convention(thin) (@in_guaranteed C, @in C, @guaranteed @callee_guaranteed (@guaranteed C, @owned C) -> ()) -> @out () +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$s10reabstract1CCACIeggx_A2CytIegnir_TR : $@convention(thin) (@in_guaranteed C, @in C, @guaranteed @callee_guaranteed (@guaranteed C, @owned C) -> ()) -> @out () func testSharedOwnedOpaque(_ s: C, o: C) { let box = Box(t: evenLessFun) box.t(s, o) @@ -113,7 +113,7 @@ func testSharedOwnedOpaque(_ s: C, o: C) { // Make sure that when we generate the reabstraction thunk from Klass -> P, we // pass off the value at +1. -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$s10reabstract1P_pIegg_xIegg_AaBRzlTR : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@guaranteed τ_0_0, @guaranteed @callee_guaranteed (@guaranteed P) -> ()) -> () { +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$s10reabstract1P_pIegg_xIegg_AaBRzlTR : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@guaranteed τ_0_0, @guaranteed @callee_guaranteed (@guaranteed P) -> ()) -> () { // CHECK: bb0([[ARG:%.*]] : @guaranteed $τ_0_0, // CHECK: [[ARG_COPY:%.*]] = copy_value [[ARG]] // CHECK: [[EXISTENTIAL:%.*]] = init_existential_ref [[ARG_COPY]] diff --git a/test/SILGen/reabstract_lvalue.swift b/test/SILGen/reabstract_lvalue.swift index 95600f67faca7..499f73317fe3f 100644 --- a/test/SILGen/reabstract_lvalue.swift +++ b/test/SILGen/reabstract_lvalue.swift @@ -36,8 +36,8 @@ func reabstractFunctionInOut() { consumeGenericInOut(&minimallyAbstracted) } -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sSiSdIegyd_SiSdIegnr_TR : $@convention(thin) (@in_guaranteed Int, @guaranteed @callee_guaranteed (Int) -> Double) -> @out Double -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sSiSdIegnr_SiSdIegyd_TR : $@convention(thin) (Int, @guaranteed @callee_guaranteed (@in_guaranteed Int) -> @out Double) -> Double +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sSiSdIegyd_SiSdIegnr_TR : $@convention(thin) (@in_guaranteed Int, @guaranteed @callee_guaranteed (Int) -> Double) -> @out Double +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sSiSdIegnr_SiSdIegyd_TR : $@convention(thin) (Int, @guaranteed @callee_guaranteed (@in_guaranteed Int) -> @out Double) -> Double // CHECK-LABEL: sil hidden [ossa] @$s17reabstract_lvalue0A13MetatypeInOutyyF : $@convention(thin) () -> () func reabstractMetatypeInOut() { diff --git a/test/SILGen/shared.swift b/test/SILGen/shared.swift index 93c24f58ea5ac..4689abad87270 100644 --- a/test/SILGen/shared.swift +++ b/test/SILGen/shared.swift @@ -85,7 +85,7 @@ func shared_to_owned_conversion(_ f : (__shared Int, __shared ValueAggregate, __ // ======== REABSTRACTION THUNK ========= - // CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] @$sSi6shared14ValueAggregateVAA03RefC0CIgyxx_SiAcEIegygg_TR : $@convention(thin) (Int, @guaranteed ValueAggregate, @guaranteed RefAggregate, @noescape @callee_guaranteed (Int, @owned ValueAggregate, @owned RefAggregate) -> ()) -> () + // CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] @$sSi6shared14ValueAggregateVAA03RefC0CIgyxx_SiAcEIegygg_TR : $@convention(thin) (Int, @guaranteed ValueAggregate, @guaranteed RefAggregate, @noescape @callee_guaranteed (Int, @owned ValueAggregate, @owned RefAggregate) -> ()) -> () // CHECK: bb0([[TRIVIAL_VAL:%[0-9]+]] : $Int, [[VALUE_VAL:%[0-9]+]] : @guaranteed $ValueAggregate, [[REF_VAL:%[0-9]+]] : @guaranteed $RefAggregate, [[FUNC:%[0-9]+]] : $@noescape @callee_guaranteed (Int, @owned ValueAggregate, @owned RefAggregate) -> ()): // CHECK: [[COPY_VALUE_VAL:%[0-9]+]] = copy_value [[VALUE_VAL]] : $ValueAggregate // CHECK: [[COPY_REF_VAL:%[0-9]+]] = copy_value [[REF_VAL]] : $RefAggregate @@ -111,7 +111,7 @@ func owned_to_shared_conversion(_ f : (Int, ValueAggregate, RefAggregate) -> Voi // ======== REABSTRACTION THUNK ========= - // CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] @$sSi6shared14ValueAggregateVAA03RefC0CIgygg_SiAcEIegyxx_TR : $@convention(thin) (Int, @owned ValueAggregate, @owned RefAggregate, @noescape @callee_guaranteed (Int, @guaranteed ValueAggregate, @guaranteed RefAggregate) -> ()) -> () + // CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] @$sSi6shared14ValueAggregateVAA03RefC0CIgygg_SiAcEIegyxx_TR : $@convention(thin) (Int, @owned ValueAggregate, @owned RefAggregate, @noescape @callee_guaranteed (Int, @guaranteed ValueAggregate, @guaranteed RefAggregate) -> ()) -> () // CHECK: bb0([[TRIVIAL_VAL:%[0-9]+]] : $Int, [[VALUE_VAL:%[0-9]+]] : @owned $ValueAggregate, [[REF_VAL:%[0-9]+]] : @owned $RefAggregate, [[FUNC:%[0-9]+]] : $@noescape @callee_guaranteed (Int, @guaranteed ValueAggregate, @guaranteed RefAggregate) -> ()): // CHECK: [[BORROW_VALUE_VAL:%[0-9]+]] = begin_borrow [[VALUE_VAL]] : $ValueAggregate // CHECK: [[BORROW_REF_VAL:%[0-9]+]] = begin_borrow [[REF_VAL]] : $RefAggregate diff --git a/test/SILGen/tuple_attribute_reabstraction.swift b/test/SILGen/tuple_attribute_reabstraction.swift index 9ed293475a7cd..a39d18ed8d0ea 100644 --- a/test/SILGen/tuple_attribute_reabstraction.swift +++ b/test/SILGen/tuple_attribute_reabstraction.swift @@ -16,9 +16,9 @@ public func f() { // We shouldn't have @autoclosure and @escaping attributes in the lowered tuple type: -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sIg_Ieg_Iegyg_xlyytIsgr_xlyytIsegr_ytIegnnr_TR : $@convention(thin) (@in_guaranteed @noescape @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>, @in_guaranteed @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>, @guaranteed @callee_guaranteed (@noescape @callee_guaranteed () -> (), @guaranteed @callee_guaranteed () -> ()) -> ()) -> @out () +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sIg_Ieg_Iegyg_xlyytIsgr_xlyytIsegr_ytIegnnr_TR : $@convention(thin) (@in_guaranteed @noescape @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>, @in_guaranteed @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>, @guaranteed @callee_guaranteed (@noescape @callee_guaranteed () -> (), @guaranteed @callee_guaranteed () -> ()) -> ()) -> @out () // The one-element vararg tuple ([Int]...) should be exploded and not treated as opaque, // even though its materializable: -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sSaySiGIegg_AAytIegnr_TR : $@convention(thin) (@in_guaranteed Array, @guaranteed @callee_guaranteed (@guaranteed Array) -> ()) -> @out () +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sSaySiGIegg_AAytIegnr_TR : $@convention(thin) (@in_guaranteed Array, @guaranteed @callee_guaranteed (@guaranteed Array) -> ()) -> @out () diff --git a/test/SILGen/vtable_thunks.swift b/test/SILGen/vtable_thunks.swift index 5537755f2bb6c..d063d6f5e961b 100644 --- a/test/SILGen/vtable_thunks.swift +++ b/test/SILGen/vtable_thunks.swift @@ -249,7 +249,7 @@ class Derived : Base { // CHECK: [[OUTER:%.*]] = partial_apply [callee_guaranteed] [[THUNK]]([[INNER]]) // CHECK: return [[OUTER]] -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$s13vtable_thunks1SVIegd_ACSgIegd_TR +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$s13vtable_thunks1SVIegd_ACSgIegd_TR // CHECK: [[INNER:%.*]] = apply %0() // CHECK: [[OUTER:%.*]] = enum $Optional, #Optional.some!enumelt, [[INNER]] : $S // CHECK: return [[OUTER]] : $Optional @@ -261,7 +261,7 @@ class Derived : Base { // CHECK: [[OUTER:%.*]] = partial_apply [callee_guaranteed] [[THUNK]]([[INNER]]) // CHECK: return [[OUTER]] -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$s13vtable_thunks1SVSgAA4NootCIego_Iegyo_AcA3AapCSgIego_Iegyo_TR +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$s13vtable_thunks1SVSgAA4NootCIego_Iegyo_AcA3AapCSgIego_Iegyo_TR // CHECK: [[ARG:%.*]] = enum $Optional, #Optional.some!enumelt, %0 // CHECK: [[INNER:%.*]] = apply %1([[ARG]]) // CHECK: [[OUTER:%.*]] = convert_function [[INNER]] : $@callee_guaranteed () -> @owned Noot to $@callee_guaranteed () -> @owned Optional diff --git a/test/SILGen/without_actually_escaping.swift b/test/SILGen/without_actually_escaping.swift index bde36e5fb0dca..c1b7c4f2c1a94 100644 --- a/test/SILGen/without_actually_escaping.swift +++ b/test/SILGen/without_actually_escaping.swift @@ -19,7 +19,7 @@ func letEscape(f: () -> ()) -> () -> () { // thunk for @callee_guaranteed () -> () // The thunk must be [without_actually_escaping]. -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [without_actually_escaping] [ossa] @$sIg_Ieg_TR : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> () { +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [without_actually_escaping] [ossa] @$sIg_Ieg_TR : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> () { // CHECK-LABEL: sil hidden [ossa] @$s25without_actually_escaping14letEscapeThrow1fyycyycyKXE_tKF // CHECK: bb0([[ARG:%.*]] : $@noescape @callee_guaranteed () -> (@owned @callee_guaranteed () -> (), @error Error)): @@ -49,7 +49,7 @@ func letEscapeThrow(f: () throws -> () -> ()) throws -> () -> () { // thunk for @callee_guaranteed () -> (@owned @escaping @callee_guaranteed () -> (), @error @owned Error) // The thunk must be [without_actually_escaping]. -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [without_actually_escaping] [ossa] @$sIeg_s5Error_pIgozo_Ieg_sAA_pIegozo_TR : $@convention(thin) (@noescape @callee_guaranteed () -> (@owned @callee_guaranteed () -> (), @error Error)) -> (@owned @callee_guaranteed () -> (), @error Error) { +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [without_actually_escaping] [ossa] @$sIeg_s5Error_pIgozo_Ieg_sAA_pIegozo_TR : $@convention(thin) (@noescape @callee_guaranteed () -> (@owned @callee_guaranteed () -> (), @error Error)) -> (@owned @callee_guaranteed () -> (), @error Error) { // We used to crash on this example because we would use the wrong substitution // map. diff --git a/test/SILGen/witnesses_class.swift b/test/SILGen/witnesses_class.swift index 4d6e6b0066fa4..b5b69765f3ac1 100644 --- a/test/SILGen/witnesses_class.swift +++ b/test/SILGen/witnesses_class.swift @@ -84,9 +84,9 @@ class UsesDefaults : HasDefaults {} // Invariant Self, since type signature contains an associated type: -// CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s15witnesses_class12UsesDefaultsCyqd__GAA03HasD0A2aEP16hasDefaultTakesTyy1TQzFTW : $@convention(witness_method: HasDefaults) <τ_0_0><τ_1_0 where τ_0_0 : UsesDefaults<τ_1_0>, τ_1_0 : Barable> (@in_guaranteed UsesDefaults<τ_1_0>, @in_guaranteed τ_0_0) -> () +// CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s15witnesses_class12UsesDefaultsCyxGAA03HasD0A2aEP16hasDefaultTakesTyy1TQzFTW : $@convention(witness_method: HasDefaults) <τ_0_0 where τ_0_0 : Barable> (@in_guaranteed UsesDefaults<τ_0_0>, @in_guaranteed UsesDefaults<τ_0_0>) -> () // CHECK: [[FN:%.*]] = function_ref @$s15witnesses_class11HasDefaultsPAAE16hasDefaultTakesTyy1TQzF : $@convention(method) <τ_0_0 where τ_0_0 : HasDefaults> (@in_guaranteed τ_0_0.T, @in_guaranteed τ_0_0) -> () -// CHECK: apply [[FN]]<τ_0_0>( +// CHECK: apply [[FN]]>( // CHECK: return // Covariant Self: @@ -98,9 +98,9 @@ class UsesDefaults : HasDefaults {} // Invariant Self, since type signature contains an associated type: -// CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s15witnesses_class12UsesDefaultsCyqd__GAA03HasD0A2aEP23hasDefaultGenericTakesTyy1TQz_qd__tAA7FooableRd__lFTW : $@convention(witness_method: HasDefaults) <τ_0_0><τ_1_0 where τ_0_0 : UsesDefaults<τ_1_0>, τ_1_0 : Barable><τ_2_0 where τ_2_0 : Fooable> (@in_guaranteed UsesDefaults<τ_1_0>, @guaranteed τ_2_0, @in_guaranteed τ_0_0) -> () +// // CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s15witnesses_class12UsesDefaultsCyxGAA03HasD0A2aEP23hasDefaultGenericTakesTyy1TQz_qd__tAA7FooableRd__lFTW : $@convention(witness_method: HasDefaults) <τ_0_0 where τ_0_0 : Barable><τ_1_0 where τ_1_0 : Fooable> (@in_guaranteed UsesDefaults<τ_0_0>, @guaranteed τ_1_0, @in_guaranteed UsesDefaults<τ_0_0>) -> () // CHECK: [[FN:%.*]] = function_ref @$s15witnesses_class11HasDefaultsPAAE23hasDefaultGenericTakesTyy1TQz_qd__tAA7FooableRd__lF : $@convention(method) <τ_0_0 where τ_0_0 : HasDefaults><τ_1_0 where τ_1_0 : Fooable> (@in_guaranteed τ_0_0.T, @guaranteed τ_1_0, @in_guaranteed τ_0_0) -> () -// CHECK: apply [[FN]]<τ_0_0, τ_2_0>( +// CHECK: apply [[FN]], τ_1_0>( // CHECK: return protocol ReturnsCovariantSelf { diff --git a/test/SILOptimizer/Inputs/pre_specialized_module.swift b/test/SILOptimizer/Inputs/pre_specialized_module.swift index 7dec0b9f32f23..e4a00cf690b26 100644 --- a/test/SILOptimizer/Inputs/pre_specialized_module.swift +++ b/test/SILOptimizer/Inputs/pre_specialized_module.swift @@ -18,6 +18,7 @@ public func publicPrespecialized2(_ t: T) { } @_specialize(exported: true, where T == Int) @_specialize(exported: true, where T == Double) @_alwaysEmitIntoClient +@inline(never) internal func internalEmitIntoClientPrespecialized(_ t: T) { } diff --git a/test/SILOptimizer/OSLogMandatoryOptTest.sil b/test/SILOptimizer/OSLogMandatoryOptTest.sil index 0454c6c7aff69..1b7215cd0504c 100644 --- a/test/SILOptimizer/OSLogMandatoryOptTest.sil +++ b/test/SILOptimizer/OSLogMandatoryOptTest.sil @@ -1066,7 +1066,10 @@ protocol CVarArgStub {} extension Int64 : CVarArgStub {} // _finalizeUninitializedArray(_:) -sil shared_external [serialized] [_semantics "array.finalize_intrinsic"] @$ss27_finalizeUninitializedArrayySayxGABnlF : $@convention(thin) (@owned Array) -> @owned Array +sil shared [serialized] [_semantics "array.finalize_intrinsic"] @$ss27_finalizeUninitializedArrayySayxGABnlF : $@convention(thin) (@owned Array) -> @owned Array { +bb0(%0 : $Array): + return %0 : $Array +} // Test that the OSLogOptimization does not fail while attempting to // fold CVarArgStubs in animation signposts. diff --git a/test/SILOptimizer/abcopts.sil b/test/SILOptimizer/abcopts.sil index af77fdcd96e51..35d4da216266f 100644 --- a/test/SILOptimizer/abcopts.sil +++ b/test/SILOptimizer/abcopts.sil @@ -1,6 +1,6 @@ -// RUN: %target-sil-opt -enable-sil-verify-all -loop-rotate -dce -jumpthread-simplify-cfg -abcopts -enable-abcopts=1 %s | %FileCheck %s -// RUN: %target-sil-opt -enable-sil-verify-all -loop-rotate -dce -jumpthread-simplify-cfg -abcopts -dce -enable-abcopts -enable-abc-hoisting %s | %FileCheck %s --check-prefix=HOIST -// RUN: %target-sil-opt -enable-sil-verify-all -abcopts %s | %FileCheck %s --check-prefix=RANGECHECK +// RUN: %target-sil-opt -parse-serialized-sil -enable-sil-verify-all -loop-rotate -dce -jumpthread-simplify-cfg -abcopts -enable-abcopts=1 %s | %FileCheck %s +// RUN: %target-sil-opt -parse-serialized-sil -enable-sil-verify-all -loop-rotate -dce -jumpthread-simplify-cfg -abcopts -dce -enable-abcopts -enable-abc-hoisting %s | %FileCheck %s --check-prefix=HOIST +// RUN: %target-sil-opt -parse-serialized-sil -enable-sil-verify-all -abcopts %s | %FileCheck %s --check-prefix=RANGECHECK sil_stage canonical diff --git a/test/SILOptimizer/abcopts_ossa_guaranteed.sil b/test/SILOptimizer/abcopts_ossa_guaranteed.sil index 5edfedc1c2d36..0ffba19cc2504 100644 --- a/test/SILOptimizer/abcopts_ossa_guaranteed.sil +++ b/test/SILOptimizer/abcopts_ossa_guaranteed.sil @@ -1,4 +1,4 @@ -// RUN: %target-sil-opt -enable-sil-verify-all -abcopts %s | %FileCheck %s +// RUN: %target-sil-opt -parse-serialized-sil -enable-sil-verify-all -abcopts %s | %FileCheck %s sil_stage canonical diff --git a/test/SILOptimizer/abcopts_ossa_owned.sil b/test/SILOptimizer/abcopts_ossa_owned.sil index 2c399587ff033..7e325f4618af6 100644 --- a/test/SILOptimizer/abcopts_ossa_owned.sil +++ b/test/SILOptimizer/abcopts_ossa_owned.sil @@ -1,4 +1,4 @@ -// RUN: %target-sil-opt -enable-sil-verify-all -abcopts %s | %FileCheck %s +// RUN: %target-sil-opt -parse-serialized-sil -enable-sil-verify-all -abcopts %s | %FileCheck %s sil_stage canonical diff --git a/test/SILOptimizer/access_marker_verify_objc.swift b/test/SILOptimizer/access_marker_verify_objc.swift index c3e1ed48efe35..2cc9fcff777ea 100644 --- a/test/SILOptimizer/access_marker_verify_objc.swift +++ b/test/SILOptimizer/access_marker_verify_objc.swift @@ -47,7 +47,7 @@ class HasBlockImpl: HasBlock { // CHECK-LABEL: } // end sil function '$s25access_marker_verify_objc12HasBlockImplC5blockyyS2iXEFTo' // thunk for @callee_unowned @convention(block) (@unowned Int) -> (@unowned Int) -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sS2iIyByd_S2iIegyd_TR : $@convention(thin) (Int, @guaranteed @convention(block) @noescape (Int) -> Int) -> Int { +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sS2iIyByd_S2iIegyd_TR : $@convention(thin) (Int, @guaranteed @convention(block) @noescape (Int) -> Int) -> Int { // CHECK: bb0(%0 : $Int, %1 : @guaranteed $@convention(block) @noescape (Int) -> Int): // CHECK: %{{.*}} = apply %1(%0) : $@convention(block) @noescape (Int) -> Int // CHECK: return %{{.*}} : $Int diff --git a/test/SILOptimizer/arcsequenceopts_uniquecheck.sil b/test/SILOptimizer/arcsequenceopts_uniquecheck.sil index 97c4066e1b5cb..16e597570b726 100644 --- a/test/SILOptimizer/arcsequenceopts_uniquecheck.sil +++ b/test/SILOptimizer/arcsequenceopts_uniquecheck.sil @@ -114,7 +114,7 @@ bb0(%0 : $*C, %1 : $*C): // // thunk for @callee_guaranteed () -> () -sil shared [transparent] [serializable] [reabstraction_thunk] [without_actually_escaping] @$sIg_Ieg_TR : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> () { +sil shared [transparent] [serialized] [reabstraction_thunk] [without_actually_escaping] @$sIg_Ieg_TR : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> () { bb0(%0 : $@noescape @callee_guaranteed () -> ()): %1 = apply %0() : $@noescape @callee_guaranteed () -> () return %1 : $() diff --git a/test/SILOptimizer/array_property_opt.sil b/test/SILOptimizer/array_property_opt.sil index 82db3dbaf0e85..56f24664b3361 100644 --- a/test/SILOptimizer/array_property_opt.sil +++ b/test/SILOptimizer/array_property_opt.sil @@ -1,4 +1,4 @@ -// RUN: %target-sil-opt -enable-sil-verify-all %s -array-property-opt | %FileCheck %s +// RUN: %target-sil-opt -parse-serialized-sil -enable-sil-verify-all %s -array-property-opt | %FileCheck %s sil_stage canonical diff --git a/test/SILOptimizer/array_property_opt_ossa_guaranteed.sil b/test/SILOptimizer/array_property_opt_ossa_guaranteed.sil index 490e38c6087b0..4713a888bac30 100644 --- a/test/SILOptimizer/array_property_opt_ossa_guaranteed.sil +++ b/test/SILOptimizer/array_property_opt_ossa_guaranteed.sil @@ -1,4 +1,4 @@ -// RUN: %target-sil-opt -enable-sil-verify-all %s -array-property-opt | %FileCheck %s +// RUN: %target-sil-opt -parse-serialized-sil -enable-sil-verify-all %s -array-property-opt | %FileCheck %s sil_stage canonical diff --git a/test/SILOptimizer/array_property_opt_ossa_owned.sil b/test/SILOptimizer/array_property_opt_ossa_owned.sil index 21b193f81c365..e9f53f754b8f3 100644 --- a/test/SILOptimizer/array_property_opt_ossa_owned.sil +++ b/test/SILOptimizer/array_property_opt_ossa_owned.sil @@ -1,4 +1,4 @@ -// RUN: %target-sil-opt -enable-sil-verify-all %s -array-property-opt | %FileCheck %s +// RUN: %target-sil-opt -parse-serialized-sil -enable-sil-verify-all %s -array-property-opt | %FileCheck %s sil_stage canonical diff --git a/test/SILOptimizer/capture_promotion_resilient.sil b/test/SILOptimizer/capture_promotion_resilient.sil index 5f03c8ec0d691..53211f57bccb6 100644 --- a/test/SILOptimizer/capture_promotion_resilient.sil +++ b/test/SILOptimizer/capture_promotion_resilient.sil @@ -43,12 +43,12 @@ bb0(%0 : $*ResilientStruct): return %5 : $@callee_guaranteed () -> () } -// CHECK-LABEL: sil [serializable] [ossa] @test_capture_promotion_2 : +// CHECK-LABEL: sil [serialized] [ossa] @test_capture_promotion_2 : // CHECK: [[F:%.*]] = function_ref @closure0 : $@convention(thin) (@guaranteed <τ_0_0> { var τ_0_0 } ) -> () // CHECK: [[C:%.*]] = partial_apply [callee_guaranteed] [[F]]({{.*}}) : $@convention(thin) (@guaranteed <τ_0_0> { var τ_0_0 } ) -> () // CHECK: return [[C]] // CHECK: } // end sil function 'test_capture_promotion_2' -sil [serializable] [ossa] @test_capture_promotion_2 : $@convention(thin) (@in_guaranteed ResilientStruct) -> @owned @callee_guaranteed () -> () { +sil [serialized] [ossa] @test_capture_promotion_2 : $@convention(thin) (@in_guaranteed ResilientStruct) -> @owned @callee_guaranteed () -> () { bb0(%0 : $*ResilientStruct): %1 = alloc_box $<τ_0_0> { var τ_0_0 } %2 = project_box %1 : $<τ_0_0> { var τ_0_0 } , 0 diff --git a/test/SILOptimizer/closure_specialize_consolidated.sil b/test/SILOptimizer/closure_specialize_consolidated.sil index 4c57b12ad0613..d633a27d78579 100644 --- a/test/SILOptimizer/closure_specialize_consolidated.sil +++ b/test/SILOptimizer/closure_specialize_consolidated.sil @@ -695,13 +695,13 @@ sil @$s4test3bazSiSi1m_tcSiF : $@convention(thin) (Int32, Int32) -> Int32 // SIL verification should catch the incorrect type. // rdar:://19321284 -// CHECK-LABEL: sil hidden [serialized] @callee : $@convention(thin) (Builtin.Int32) -> () { -sil hidden [serialized] @callee : $@convention(thin) (Builtin.Int32) -> () { +// CHECK-LABEL: sil [serialized] @callee : $@convention(thin) (Builtin.Int32) -> () { +sil [serialized] @callee : $@convention(thin) (Builtin.Int32) -> () { bb0(%0 : $Builtin.Int32): unreachable } -sil hidden [serialized] @thunk : $@convention(thin) (@callee_owned () -> ()) -> @out () { +sil shared [serialized] @thunk : $@convention(thin) (@callee_owned () -> ()) -> @out () { bb0(%0 : $*(), %1 : $@callee_owned () -> ()): apply %1() : $@callee_owned () -> () %9999 = tuple() @@ -711,7 +711,7 @@ bb0(%0 : $*(), %1 : $@callee_owned () -> ()): // CHECK-LABEL: @test_closure_propagation : $@convention(thin) () -> () { // REMOVECLOSURES-LABEL: @test_closure_propagation : $@convention(thin) () -> () { // REMOVECLOSURES-NOT: partial_apply -sil hidden [serialized] @test_closure_propagation : $@convention(thin) () -> () { +sil [serialized] @test_closure_propagation : $@convention(thin) () -> () { bb0: %f1 = function_ref @callee : $@convention(thin) (Builtin.Int32) -> () %i1 = integer_literal $Builtin.Int32, 24 diff --git a/test/SILOptimizer/dont_broaden_cxx_address_only.sil b/test/SILOptimizer/dont_broaden_cxx_address_only.sil index 1eae83fbcb09a..759b403e935e1 100644 --- a/test/SILOptimizer/dont_broaden_cxx_address_only.sil +++ b/test/SILOptimizer/dont_broaden_cxx_address_only.sil @@ -16,7 +16,7 @@ import CXXTypesWithUserProvidedDestructor // CHECK-NEXT: tuple // CHECK-NEXT: return // CHECK-LABEL: end sil function 'test_foo' -sil shared [transparent] [serializable] [ossa] @test_foo : $@convention(method) (Int32, @thin HasUserProvidedDestructor.Type) -> @out HasUserProvidedDestructor { +sil shared [transparent] [serialized] [ossa] @test_foo : $@convention(method) (Int32, @thin HasUserProvidedDestructor.Type) -> @out HasUserProvidedDestructor { bb0(%0 : $*HasUserProvidedDestructor, %1 : $Int32, %2 : $@thin HasUserProvidedDestructor.Type): %3 = struct_element_addr %0 : $*HasUserProvidedDestructor, #HasUserProvidedDestructor.x store %1 to [trivial] %3 : $*Int32 @@ -34,7 +34,7 @@ bb0(%0 : $*HasUserProvidedDestructor, %1 : $Int32, %2 : $@thin HasUserProvidedDe // CHECK-NEXT: tuple // CHECK-NEXT: return // CHECK-LABEL: end sil function 'test_bar' -sil shared [transparent] [serializable] [ossa] @test_bar : $@convention(method) (Int32, @thin HasMemberWithUserProvidedDestructor.Type) -> @out HasMemberWithUserProvidedDestructor { +sil shared [transparent] [serialized] [ossa] @test_bar : $@convention(method) (Int32, @thin HasMemberWithUserProvidedDestructor.Type) -> @out HasMemberWithUserProvidedDestructor { bb0(%0 : $*HasMemberWithUserProvidedDestructor, %1 : $Int32, %2 : $@thin HasMemberWithUserProvidedDestructor.Type): %3 = struct_element_addr %0 : $*HasMemberWithUserProvidedDestructor, #HasMemberWithUserProvidedDestructor.y %3a = struct_element_addr %3 : $*Loadable, #Loadable.x diff --git a/test/SILOptimizer/escape_analysis.sil b/test/SILOptimizer/escape_analysis.sil index ba72279678681..9bf1cbbc923c2 100644 --- a/test/SILOptimizer/escape_analysis.sil +++ b/test/SILOptimizer/escape_analysis.sil @@ -1,4 +1,4 @@ -// RUN: %target-sil-opt %s -escapes-dump -escapes-internal-verify -o /dev/null | %FileCheck %s +// RUN: %target-sil-opt -parse-serialized-sil %s -escapes-dump -escapes-internal-verify -o /dev/null | %FileCheck %s // REQUIRES: asserts diff --git a/test/SILOptimizer/exclusivity_static_diagnostics.sil b/test/SILOptimizer/exclusivity_static_diagnostics.sil index f93bb7385d15f..6644b01a8c7c8 100644 --- a/test/SILOptimizer/exclusivity_static_diagnostics.sil +++ b/test/SILOptimizer/exclusivity_static_diagnostics.sil @@ -1083,7 +1083,7 @@ bb0(%0 : $Optional>, %1 : $*Int32): return %v : $() } -sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @mutatingNoescapeThunk : $@convention(thin) (UnsafePointer, @guaranteed @callee_guaranteed (Optional>) -> ()) -> () { +sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @mutatingNoescapeThunk : $@convention(thin) (UnsafePointer, @guaranteed @callee_guaranteed (Optional>) -> ()) -> () { bb0(%0 : $UnsafePointer, %1 : @guaranteed $@callee_guaranteed (Optional>) -> ()): %e = enum $Optional>, #Optional.some!enumelt, %0 : $UnsafePointer %c = apply %1(%e) : $@callee_guaranteed (Optional>) -> () @@ -1231,7 +1231,7 @@ bb0(%0 : $Int, %1 : $*Int): return %v : $() } -sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @partialApplyPhiThunk : $@convention(thin) (@in_guaranteed Int, @guaranteed @noescape @callee_guaranteed (Int) -> (@error Error)) -> (@error Error) { +sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @partialApplyPhiThunk : $@convention(thin) (@in_guaranteed Int, @guaranteed @noescape @callee_guaranteed (Int) -> (@error Error)) -> (@error Error) { bb0(%0 : $*Int, %1 : $@noescape @callee_guaranteed (Int) -> (@error Error)): %val = load [trivial] %0 : $*Int try_apply %1(%val) : $@noescape @callee_guaranteed (Int) -> (@error Error), normal bb1, error bb2 @@ -1346,8 +1346,8 @@ bb0(%0 : $*Int): return %14 : $() } -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [without_actually_escaping] [ossa] @thunkForWithoutActuallyEscapingVerify : $@convention(thin) (@guaranteed @callee_guaranteed () -> ()) -> () { -sil shared [transparent] [serializable] [reabstraction_thunk] [without_actually_escaping] [ossa] @thunkForWithoutActuallyEscapingVerify : $@convention(thin) (@guaranteed @callee_guaranteed () -> ()) -> () { +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [without_actually_escaping] [ossa] @thunkForWithoutActuallyEscapingVerify : $@convention(thin) (@guaranteed @callee_guaranteed () -> ()) -> () { +sil shared [transparent] [serialized] [reabstraction_thunk] [without_actually_escaping] [ossa] @thunkForWithoutActuallyEscapingVerify : $@convention(thin) (@guaranteed @callee_guaranteed () -> ()) -> () { bb0(%0 : @guaranteed $@callee_guaranteed () -> ()): %1 = apply %0() : $@callee_guaranteed () -> () return %1 : $() @@ -1400,7 +1400,7 @@ bb0(%0 : $Int): sil [ossa] @testWithoutActuallyEscapingBlockVerifyClosure : $@convention(thin) (@inout_aliasable Int) -> () // thunk for @escaping @callee_guaranteed () -> () -sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sIeg_IeyB_TR : $@convention(c) (@inout_aliasable @block_storage @callee_guaranteed () -> ()) -> () { +sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sIeg_IeyB_TR : $@convention(c) (@inout_aliasable @block_storage @callee_guaranteed () -> ()) -> () { // %0 bb0(%0 : $*@block_storage @callee_guaranteed () -> ()): %1 = project_block_storage %0 : $*@block_storage @callee_guaranteed () -> () @@ -1527,7 +1527,7 @@ bb0(%0 : $Int, %1 : $*Int, %2 : $*Dictionary): } // thunk for @callee_guaranteed () -> (@unowned Int) -sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sSiIgd_SiIegr_TR : $@convention(thin) (@noescape @callee_guaranteed () -> Int) -> @out Int { +sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sSiIgd_SiIegr_TR : $@convention(thin) (@noescape @callee_guaranteed () -> Int) -> @out Int { bb0(%0 : $*Int, %1 : $@noescape @callee_guaranteed () -> Int): %2 = apply %1() : $@noescape @callee_guaranteed () -> Int store %2 to [trivial] %0 : $*Int diff --git a/test/SILOptimizer/exclusivity_static_diagnostics_inlined.swift b/test/SILOptimizer/exclusivity_static_diagnostics_inlined.swift index a47be2a43e3f0..43c9d0cfeda34 100644 --- a/test/SILOptimizer/exclusivity_static_diagnostics_inlined.swift +++ b/test/SILOptimizer/exclusivity_static_diagnostics_inlined.swift @@ -1,8 +1,8 @@ // RUN: %empty-directory(%t) // RUN: %target-swift-frontend -enforce-exclusivity=none -emit-sil -Onone %s -o %t/Onone.sil -// RUN: %target-sil-opt %t/Onone.sil -inline -o %t/inlined.sil +// RUN: %target-sil-opt -parse-serialized-sil %t/Onone.sil -inline -o %t/inlined.sil // RUN: %FileCheck %s --check-prefix=INLINE < %t/inlined.sil -// RUN: %target-sil-opt -enable-sil-verify-all %t/inlined.sil -enforce-exclusivity=unchecked -diagnose-static-exclusivity -o /dev/null +// RUN: %target-sil-opt -parse-serialized-sil -enable-sil-verify-all %t/inlined.sil -enforce-exclusivity=unchecked -diagnose-static-exclusivity -o /dev/null public protocol SomeP { var someV: Int { get set } diff --git a/test/SILOptimizer/functionsigopts.sil b/test/SILOptimizer/functionsigopts.sil index 4a5b14bb0bc66..c4faee425fc26 100644 --- a/test/SILOptimizer/functionsigopts.sil +++ b/test/SILOptimizer/functionsigopts.sil @@ -644,8 +644,8 @@ bb3: return %4 : $() } -// CHECK-NOT: sil hidden [serialized] @private_dead_arg_with_callsites : $@convention(thin) (Builtin.NativeObject, Builtin.NativeObject) -> () { -sil private [serialized] @private_dead_arg_with_callsites : $@convention(thin) (Builtin.NativeObject, Builtin.NativeObject) -> () { +// CHECK-NOT: sil hidden @private_dead_arg_with_callsites : $@convention(thin) (Builtin.NativeObject, Builtin.NativeObject) -> () { +sil private @private_dead_arg_with_callsites : $@convention(thin) (Builtin.NativeObject, Builtin.NativeObject) -> () { bb0(%0 : $Builtin.NativeObject, %1 : $Builtin.NativeObject): // make it a non-trivial function %c1 = builtin "assert_configuration"() : $Builtin.Int32 @@ -686,13 +686,13 @@ bb3: return %4 : $() } -// CHECK-LABEL: sil [serialized] @dead_arg_callsite_1 : $@convention(thin) (Builtin.NativeObject, Builtin.NativeObject) -> () { +// CHECK-LABEL: sil @dead_arg_callsite_1 : $@convention(thin) (Builtin.NativeObject, Builtin.NativeObject) -> () { // CHECK: bb0 // CHECK: [[OPT_FUN:%[0-9]+]] = function_ref @$s23dead_arg_with_callsitesTfq4dn_n : $@convention(thin) (Builtin.NativeObject) -> () // CHECK-NEXT: apply [[OPT_FUN]]( -// CHECK: [[PRIV_OPT_FUN:%[0-9]+]] = function_ref @$s31private_dead_arg_with_callsitesTfq4dn_n : $@convention(thin) (Builtin.NativeObject) -> () +// CHECK: [[PRIV_OPT_FUN:%[0-9]+]] = function_ref @$s31private_dead_arg_with_callsitesTf4dn_n : $@convention(thin) (Builtin.NativeObject) -> () // CHECK-NEXT: apply [[PRIV_OPT_FUN]] -sil [serialized] @dead_arg_callsite_1 : $@convention(thin) (Builtin.NativeObject, Builtin.NativeObject) -> () { +sil @dead_arg_callsite_1 : $@convention(thin) (Builtin.NativeObject, Builtin.NativeObject) -> () { bb0(%0 : $Builtin.NativeObject, %1 : $Builtin.NativeObject): %2 = function_ref @dead_arg_with_callsites : $@convention(thin) (Builtin.NativeObject, Builtin.NativeObject) -> () %3 = apply %2(%0, %1) : $@convention(thin) (Builtin.NativeObject, Builtin.NativeObject) -> () @@ -1446,7 +1446,7 @@ bb0(%0 : $Optional<(foo, foo)>): // Check if externally available functions are optimized. -sil public_external [noinline] @externally_available_with_dead_arg : $@convention(thin) (@guaranteed foo) -> () { +sil public_external [serialized] [noinline] @externally_available_with_dead_arg : $@convention(thin) (@guaranteed foo) -> () { bb0(%0 : $foo): %r = tuple() return %r : $() @@ -1454,7 +1454,7 @@ bb0(%0 : $foo): // CHECK-LABEL: sil @call_externally_available // CHECK: bb{{[0-9]+}}([[FOO:%.*]] : $foo): -// CHECK: [[F:%[0-9]+]] = function_ref @$s34externally_available_with_dead_argTf4d_n : $@convention(thin) () -> () +// CHECK: [[F:%[0-9]+]] = function_ref @$s34externally_available_with_dead_argTfq4d_n : $@convention(thin) () -> () // CHECK: apply [[F]]() // CHECK: return // CHECK-LABEL: } // end sil function 'call_externally_available' @@ -1848,7 +1848,7 @@ bb0(%0 : $*T): // CHECK-NEXT: tuple // CHECK-NEXT: return -// CHECK-LABEL: sil shared [serialized] @$s31private_dead_arg_with_callsitesTfq4dn_n : $@convention(thin) (Builtin.NativeObject) -> () { +// CHECK-LABEL: sil private @$s31private_dead_arg_with_callsitesTf4dn_n : $@convention(thin) (Builtin.NativeObject) -> () { // CHECK: bb0( // CHECK-LABEL: sil shared [serialized] @$s37owned_to_guaranteed_with_error_resultTfq4gn_n : $@convention(thin) (@guaranteed Builtin.NativeObject, Int) -> (Int, @error Error) { diff --git a/test/SILOptimizer/functionsigopts_trivial.sil b/test/SILOptimizer/functionsigopts_trivial.sil index e6341c02abe6d..b8490743e7f3d 100644 --- a/test/SILOptimizer/functionsigopts_trivial.sil +++ b/test/SILOptimizer/functionsigopts_trivial.sil @@ -1,4 +1,4 @@ -// RUN: %target-sil-opt -sil-inline-generics -enable-sil-verify-all -inline -function-signature-opts %s | %FileCheck %s +// RUN: %target-sil-opt -parse-serialized-sil -sil-inline-generics -enable-sil-verify-all -inline -function-signature-opts %s | %FileCheck %s import Builtin import Swift diff --git a/test/SILOptimizer/hoist_destroy_addr.sil b/test/SILOptimizer/hoist_destroy_addr.sil index 04e9e720946fa..f1d5b4589920e 100644 --- a/test/SILOptimizer/hoist_destroy_addr.sil +++ b/test/SILOptimizer/hoist_destroy_addr.sil @@ -365,6 +365,44 @@ entry(%addr : $*X, %instance : @owned $X): return %retval : $() } +// Hoist up to a (transitive) use of an address_to_pointer instruction. In +// particular, do _some_ hoisting despite the fact that such an instruction is +// a use. +// +// CHECK-LABEL: sil [ossa] @hoist_upto_address_to_pointer_use : {{.*}} { +// CHECK: address_to_pointer +// CHECK: pointer_to_address +// CHECK: load [copy] +// CHECK: destroy_addr +// CHECK: tuple +// CHECK-LABEL: } // end sil function 'hoist_upto_address_to_pointer_use' +sil [ossa] @hoist_upto_address_to_pointer_use : $@convention(thin) (@in X) -> (@owned X) { +entry(%instance : $*X): + %pointer = address_to_pointer %instance : $*X to $Builtin.RawPointer + %addr = pointer_to_address %pointer : $Builtin.RawPointer to $*X + %value = load [copy] %addr : $*X + %retval = tuple () + destroy_addr %instance : $*X + return %value : $X +} + +// Hoist even if the pointerified address gets used. +// +// CHECK-LABEL: sil [ossa] @hoist_despite_use_of_pointer : {{.*}} { +// CHECK: {{bb[0-9]+}}([[INSTANCE:%[^,]+]] : +// CHECK-NEXT: destroy_addr [[INSTANCE]] +// CHECK-LABEL: } // end sil function 'hoist_despite_use_of_pointer' +sil [ossa] @hoist_despite_use_of_pointer : $@convention(thin) (@inout X) -> () { +entry(%instance : $*X): + %addr_for_pointer = alloc_stack $Builtin.RawPointer + %pointer = address_to_pointer %instance : $*X to $Builtin.RawPointer + store %pointer to [trivial] %addr_for_pointer : $*Builtin.RawPointer + %retval = tuple () + destroy_addr %instance : $*X + dealloc_stack %addr_for_pointer : $*Builtin.RawPointer + return %retval : $() +} + // Fold destroy_addr and a load [copy] into a load [take] even when that // load [take] is guarded by an access scope. // diff --git a/test/SILOptimizer/mandatory-specializer.sil b/test/SILOptimizer/mandatory-specializer.sil index 987151061c8bd..7322863e3982a 100644 --- a/test/SILOptimizer/mandatory-specializer.sil +++ b/test/SILOptimizer/mandatory-specializer.sil @@ -31,7 +31,12 @@ bb0(%0 : $Builtin.Int32): return %2 : $Builtin.Int32 } -sil shared_external [transparent] [serialized] [thunk] [canonical] @$sSiSLsSL1loiySbx_xtFZTW : $@convention(witness_method: Comparable) (@in_guaranteed Int, @in_guaranteed Int, @thick Int.Type) -> Bool +sil shared [transparent] [serialized] [thunk] [canonical] @$sSiSLsSL1loiySbx_xtFZTW : $@convention(witness_method: Comparable) (@in_guaranteed Int, @in_guaranteed Int, @thick Int.Type) -> Bool { +bb0(%0 : $*Int, %1 : $*Int, %2 : $@thick Int.Type): + %3 = integer_literal $Builtin.Int1, 0 + %4 = struct $Bool (%3 : $Builtin.Int1) + return %4 : $Bool +} sil_witness_table public_external [serialized] Int: Comparable module Swift { base_protocol Equatable: Int: Equatable module Swift diff --git a/test/SILOptimizer/mem2reg_lifetime.sil b/test/SILOptimizer/mem2reg_lifetime.sil index cad9d4853165e..e887ee3519417 100644 --- a/test/SILOptimizer/mem2reg_lifetime.sil +++ b/test/SILOptimizer/mem2reg_lifetime.sil @@ -1328,9 +1328,9 @@ entry(%either : @owned $E): %addr = alloc_stack [lexical] $E store %either to [init] %addr : $*E %either2 = load [take] %addr : $*E + dealloc_stack %addr : $*E switch_enum %either2 : $E, case #E.one!enumelt: one one(%instance : @owned $C): - dealloc_stack %addr : $*E return %instance : $C } diff --git a/test/SILOptimizer/mem2reg_lifetime_nontrivial.sil b/test/SILOptimizer/mem2reg_lifetime_nontrivial.sil index 5e5ebb443d5bf..47fda98b81cb8 100644 --- a/test/SILOptimizer/mem2reg_lifetime_nontrivial.sil +++ b/test/SILOptimizer/mem2reg_lifetime_nontrivial.sil @@ -1101,7 +1101,8 @@ enum KlassOptional { sil @return_optional_or_error : $@convention(thin) () -> (@owned KlassOptional, @error Error) // CHECK-LABEL: sil [ossa] @test_deadphi4 : -// CHECK-NOT: alloc_stack +// mem2reg cannot optimize an enum location which spans over multiple blocks. +// CHECK: alloc_stack // CHECK-LABEL: } // end sil function 'test_deadphi4' sil [ossa] @test_deadphi4 : $@convention(thin) (@owned KlassOptional) -> () { bb0(%0 : @owned $KlassOptional): diff --git a/test/SILOptimizer/mem2reg_ossa.sil b/test/SILOptimizer/mem2reg_ossa.sil index 6ba1605be7bd1..164972e5fa087 100644 --- a/test/SILOptimizer/mem2reg_ossa.sil +++ b/test/SILOptimizer/mem2reg_ossa.sil @@ -488,3 +488,53 @@ bb0: dealloc_stack %1 : $*((), ()) return %16 : $((), ()) } + +// CHECK-LABEL: sil [ossa] @dont_optimize_optional_in_multiple_blocks : +// CHECK: alloc_stack +// CHECK: } // end sil function 'dont_optimize_optional_in_multiple_blocks' +sil [ossa] @dont_optimize_optional_in_multiple_blocks : $@convention(method) (@guaranteed Optional) -> () { +bb0(%0 : @guaranteed $Optional): + %1 = copy_value %0 : $Optional + %32 = alloc_stack $Optional + store %1 to [init] %32 : $*Optional + switch_enum %0 : $Optional, case #Optional.some!enumelt: bb6, case #Optional.none!enumelt: bb5 + +bb5: + dealloc_stack %32 : $*Optional + br bb7 + +bb6(%50 : @guaranteed $Klass): + %53 = load [take] %32 : $*Optional + destroy_value %53 : $Optional + dealloc_stack %32 : $*Optional + br bb7 + +bb7: + %r = tuple () + return %r : $() +} + +// CHECK-LABEL: sil [ossa] @optimize_optional_in_single_block : +// CHECK-NOT: alloc_stack +// CHECK: } // end sil function 'optimize_optional_in_single_block' +sil [ossa] @optimize_optional_in_single_block : $@convention(method) (@guaranteed Optional) -> () { +bb0(%0 : @guaranteed $Optional): + switch_enum %0 : $Optional, case #Optional.some!enumelt: bb6, case #Optional.none!enumelt: bb5 + +bb5: + br bb7 + +bb6(%50 : @guaranteed $Klass): + %32 = alloc_stack $Optional + %1 = copy_value %0 : $Optional + store %1 to [init] %32 : $*Optional + %53 = load [take] %32 : $*Optional + destroy_value %53 : $Optional + dealloc_stack %32 : $*Optional + br bb7 + +bb7: + %r = tuple () + return %r : $() +} + diff --git a/test/SILOptimizer/mem2reg_ossa_nontrivial.sil b/test/SILOptimizer/mem2reg_ossa_nontrivial.sil index 3db25869b706d..3a5e5ab866c40 100644 --- a/test/SILOptimizer/mem2reg_ossa_nontrivial.sil +++ b/test/SILOptimizer/mem2reg_ossa_nontrivial.sil @@ -7,8 +7,17 @@ import Swift // Declarations // ////////////////// +typealias AnyObject = Builtin.AnyObject + class Klass {} +class X {} + +struct S { + var v1: AnyObject + var v2: AnyObject +} + struct SmallCodesizeStruct { var cls1 : Klass var cls2 : Klass @@ -40,6 +49,10 @@ public enum FakeOptional { case none } +struct UInt8 { + var _value : Builtin.Int8 +} + sil [ossa] @get_nontrivialstruct : $@convention(thin) () -> @owned NonTrivialStruct sil [ossa] @get_nontrivialenum : $@convention(thin) () -> @owned NonTrivialEnum sil [ossa] @get_optionalnontrivialstruct : $@convention(thin) () -> @owned FakeOptional @@ -1021,7 +1034,8 @@ enum KlassOptional { sil @return_optional_or_error : $@convention(thin) () -> (@owned KlassOptional, @error Error) // CHECK-LABEL: sil [ossa] @test_deadphi4 : -// CHECK-NOT: alloc_stack +// mem2reg cannot optimize an enum location which spans over multiple blocks. +// CHECK: alloc_stack // CHECK-LABEL: } // end sil function 'test_deadphi4' sil [ossa] @test_deadphi4 : $@convention(thin) (@owned KlassOptional) -> () { bb0(%0 : @owned $KlassOptional): @@ -1113,3 +1127,102 @@ bb9: return %res : $() } +// Test that a load [take] of an unchecked_addr_cast doesn't get promoted. +// +// CHECK-LABEL: sil [ossa] @load_take_unchecked_addr_cast : {{.*}} { +// CHECK: load [take] +// CHECK-LABEL: } // end sil function 'load_take_unchecked_addr_cast' +sil [ossa] @load_take_unchecked_addr_cast : $@convention(thin) (@guaranteed AnyObject) -> () { +entry(%instance : @guaranteed $AnyObject): + %copy = copy_value %instance : $AnyObject + %storage = alloc_stack $AnyObject + store %copy to [init] %storage : $*AnyObject + %cast_addr = unchecked_addr_cast %storage : $*AnyObject to $*Klass + %value = load [take] %cast_addr : $*Klass + dealloc_stack %storage : $*AnyObject + destroy_value %value : $Klass + %retval = tuple () + return %retval : $() +} + +// Don't bail if the original address is destroyed even if we see a cast. +// +// CHECK-LABEL: sil [ossa] @destroy_original_storage : {{.*}} { +// CHECK: destroy_value +// CHECK-LABEL: } // end sil function 'destroy_original_storage' +sil [ossa] @destroy_original_storage : $@convention(thin) (@guaranteed AnyObject) -> () { +entry(%instance : @guaranteed $AnyObject): + %copy = copy_value %instance : $AnyObject + %storage = alloc_stack $AnyObject + store %copy to [init] %storage : $*AnyObject + %cast_addr = unchecked_addr_cast %storage : $*AnyObject to $*Klass + %value = load [copy] %cast_addr : $*Klass + destroy_addr %storage : $*AnyObject + dealloc_stack %storage : $*AnyObject + destroy_value %value : $Klass + %retval = tuple () + return %retval : $() +} + +// Bail if the address produced by an unchecked_addr_cast is destroyed. +// +// CHECK-LABEL: sil [ossa] @destroy_addr_unchecked_addr_cast : {{.*}} { +// CHECK: unchecked_addr_cast +// CHECK: load [copy] +// CHECK-LABEL: } // end sil function 'destroy_addr_unchecked_addr_cast' +sil [ossa] @destroy_addr_unchecked_addr_cast : $@convention(thin) (@guaranteed AnyObject) -> () { +entry(%instance : @guaranteed $AnyObject): + %copy = copy_value %instance : $AnyObject + %storage = alloc_stack $AnyObject + store %copy to [init] %storage : $*AnyObject + %cast_addr = unchecked_addr_cast %storage : $*AnyObject to $*Klass + %value = load [copy] %cast_addr : $*Klass + destroy_addr %cast_addr : $*Klass + dealloc_stack %storage : $*AnyObject + destroy_value %value : $Klass + %retval = tuple () + return %retval : $() +} + +// Bail if there's a load [take] of one of multiple non-trivial fields. +// +// CHECK-LABEL: sil [ossa] @load_take_one_of_two_nontrivial_struct_fields : {{.*}} { +// CHECK: load [take] +// CHECK: destroy_addr +// CHECK-LABEL: } // end sil function 'load_take_one_of_two_nontrivial_struct_fields' +sil [ossa] @load_take_one_of_two_nontrivial_struct_fields : $@convention(thin) (@guaranteed S) -> () { +entry(%instance : @guaranteed $S): + %copy = copy_value %instance : $S + %storage = alloc_stack $S + store %copy to [init] %storage : $*S + %v1_addr = struct_element_addr %storage : $*S, #S.v1 + %cast_addr = unchecked_addr_cast %v1_addr : $*AnyObject to $*Klass + %value = load [take] %cast_addr : $*Klass + %v2_addr = struct_element_addr %storage : $*S, #S.v2 + destroy_addr %v2_addr : $*AnyObject + //destroy_addr %storage : $*S + dealloc_stack %storage : $*S + destroy_value %value : $Klass + %retval = tuple () + return %retval : $() +} + +// Don't bail if we happen to see an unchecked_addr_cast but then load [take] +// the original address. +// +// CHECK-LABEL: sil [ossa] @load_take_original_despite_cast : {{.*}} { +// CHECK: unchecked_bitwise_cast +// CHECK: destroy_value +// CHECK-LABEL: } // end sil function 'load_take_original_despite_cast' +sil [ossa] @load_take_original_despite_cast : $@convention(thin) (@owned AnyObject) -> () { +entry(%instance : @owned $AnyObject): + %74 = alloc_stack $AnyObject + store %instance to [init] %74 : $*AnyObject + %76 = unchecked_addr_cast %74 : $*AnyObject to $*UInt8 + %77 = load [trivial] %76 : $*UInt8 + %79 = load [take] %74 : $*AnyObject + destroy_value %79 : $AnyObject + dealloc_stack %74 : $*AnyObject + %82 = tuple () + return %82 : $() +} diff --git a/test/SILOptimizer/no-external-defs-onone.sil b/test/SILOptimizer/no-external-defs-onone.sil index fe592f33859e4..046df6f55074f 100644 --- a/test/SILOptimizer/no-external-defs-onone.sil +++ b/test/SILOptimizer/no-external-defs-onone.sil @@ -3,26 +3,25 @@ // CHECK-DAG: define linkonce_odr hidden swiftcc void @shared_external_test() // CHECK-DAG: declare {{(dllimport )?}}swiftcc void @public_external_test() // Non-public external symbols are emitted into clients. -// CHECK-DAG: define available_externally hidden swiftcc void @hidden_external_test() +// CHECK-DAG: declare swiftcc void @hidden_external_test() // CHECK-NOT: public_external_unused_test +// TODO: update check line for the hidden_external_test for Windows. +// UNSUPPORTED: windows -sil public_external @public_external_test : $@convention(thin) () -> () { +sil public_external [serialized] @public_external_test : $@convention(thin) () -> () { %0 = tuple() return %0 : $() } -sil hidden_external @hidden_external_test : $@convention(thin) () -> () { - %0 = tuple() - return %0 : $() -} +sil hidden_external @hidden_external_test : $@convention(thin) () -> () -sil shared_external @shared_external_test : $@convention(thin) () -> () { +sil shared @shared_external_test : $@convention(thin) () -> () { %0 = tuple() return %0 : $() } -sil public_external @public_external_unused_test : $@convention(thin) () -> () { +sil public_external [serialized] @public_external_unused_test : $@convention(thin) () -> () { %0 = tuple() return %0 : $() } diff --git a/test/SILOptimizer/performance_inliner.sil b/test/SILOptimizer/performance_inliner.sil index 8ec364ad875cf..327e123a9f599 100644 --- a/test/SILOptimizer/performance_inliner.sil +++ b/test/SILOptimizer/performance_inliner.sil @@ -1,4 +1,4 @@ -// RUN: %target-sil-opt -enable-sil-verify-all %s -inline -sil-combine | %FileCheck %s +// RUN: %target-sil-opt -parse-serialized-sil -enable-sil-verify-all %s -inline -sil-combine | %FileCheck %s sil_stage canonical @@ -649,30 +649,6 @@ sil @public_function_test : $@convention(thin) () -> () { return %8 : $() } -// CHECK-LABEL: sil hidden_external @hidden_external_function_test : $@convention(thin) () -> () { -// CHECK-NOT: function_ref -// CHECK: return -sil hidden_external @hidden_external_function_test : $@convention(thin) () -> () { - %0 = function_ref @references_public_function : $@convention(thin) () -> () - %1 = function_ref @references_shared_function : $@convention(thin) () -> () - %2 = function_ref @references_hidden_function : $@convention(thin) () -> () - %3 = function_ref @references_private_function : $@convention(thin) () -> () - %4 = function_ref @references_public_global : $@convention(thin) () -> () - %5 = function_ref @references_shared_global : $@convention(thin) () -> () - %6 = function_ref @references_hidden_global : $@convention(thin) () -> () - %7 = function_ref @references_private_global : $@convention(thin) () -> () - apply %0() : $@convention(thin) () -> () - apply %1() : $@convention(thin) () -> () - apply %2() : $@convention(thin) () -> () - apply %3() : $@convention(thin) () -> () - apply %4() : $@convention(thin) () -> () - apply %5() : $@convention(thin) () -> () - apply %6() : $@convention(thin) () -> () - apply %7() : $@convention(thin) () -> () - %8 = tuple() - return %8 : $() -} - // CHECK-LABEL: sil public_external @public_external_function_test : $@convention(thin) () -> () { // CHECK-NOT: function_ref // CHECK: return diff --git a/test/SILOptimizer/pre_specialize.swift b/test/SILOptimizer/pre_specialize.swift index 1eced39f4c2f6..eeee1ec7ad9a6 100644 --- a/test/SILOptimizer/pre_specialize.swift +++ b/test/SILOptimizer/pre_specialize.swift @@ -1,20 +1,20 @@ // RUN: %empty-directory(%t) // RUN: %target-swift-frontend -emit-module-path %t/pre_specialized_module.swiftmodule %S/Inputs/pre_specialized_module.swift -// RUN: %target-swift-frontend -I %t -O -emit-sil %s | %FileCheck %s --check-prefix=OPT -check-prefix=OPT-%target-os +// RUN: %target-swift-frontend -I %t -O -Xllvm -sil-disable-pass=function-signature-opts -emit-sil %s | %FileCheck %s --check-prefix=OPT -check-prefix=OPT-%target-os // RUN: %target-swift-frontend -I %t -Onone -emit-sil %s | %FileCheck %s --check-prefix=NONE -check-prefix=NONE-%target-os // RUN: %empty-directory(%t) // RUN: %target-swift-frontend -O -emit-module-path %t/pre_specialized_module.swiftmodule %S/Inputs/pre_specialized_module.swift -// RUN: %target-swift-frontend -I %t -O -emit-sil %s | %FileCheck %s --check-prefix=OPT +// RUN: %target-swift-frontend -I %t -O -Xllvm -sil-disable-pass=function-signature-opts -emit-sil %s | %FileCheck %s --check-prefix=OPT // RUN: %empty-directory(%t) // RUN: %target-swift-frontend -O -enable-library-evolution -emit-module-path %t/pre_specialized_module.swiftmodule %S/Inputs/pre_specialized_module.swift -// RUN: %target-swift-frontend -I %t -O -emit-sil %s | %FileCheck %s --check-prefix=OPT +// RUN: %target-swift-frontend -I %t -O -Xllvm -sil-disable-pass=function-signature-opts -emit-sil %s | %FileCheck %s --check-prefix=OPT // RUN: %empty-directory(%t) // RUN: %target-swift-frontend -O -swift-version 5 -enable-library-evolution -emit-module -o /dev/null -emit-module-interface-path %t/pre_specialized_module.swiftinterface %S/Inputs/pre_specialized_module.swift -module-name pre_specialized_module -// RUN: %target-swift-frontend -I %t -O -emit-sil %s | %FileCheck %s --check-prefix=OPT +// RUN: %target-swift-frontend -I %t -O -Xllvm -sil-disable-pass=function-signature-opts -emit-sil %s | %FileCheck %s --check-prefix=OPT import pre_specialized_module @@ -103,7 +103,7 @@ public func usePrespecializedEntryPoints() { public func usePrespecializedEntryPointsAvailability() { publicPrespecialized(SomeData()) } -// OPT: sil [signature_optimized_thunk] [always_inline] @$s22pre_specialized_module16publicInlineableyyxlFSd_Ts5 : $@convention(thin) (Double) -> () { +// OPT: sil @$s22pre_specialized_module16publicInlineableyyxlFSd_Ts5 : $@convention(thin) (Double) -> () { // NONE: sil @$s22pre_specialized_module16publicInlineableyyxlFSd_Ts5 : $@convention(thin) (Double) -> () { @_specialize(exported: true, target: publicInlineable(_:), where T == Double) public func specializeTarget(_ t: T) {} diff --git a/test/SILOptimizer/side-effect.sil b/test/SILOptimizer/side-effect.sil index 7727750d97483..91ef07e40f407 100644 --- a/test/SILOptimizer/side-effect.sil +++ b/test/SILOptimizer/side-effect.sil @@ -1,4 +1,4 @@ -// RUN: %target-sil-opt %s -module-name Swift -side-effects-dump -o /dev/null | %FileCheck %s +// RUN: %target-sil-opt %s -parse-serialized-sil -module-name Swift -side-effects-dump -o /dev/null | %FileCheck %s // REQUIRES: asserts @@ -535,19 +535,3 @@ bb0: return %r : $() } -sil shared_external @shared_external_func : $@convention(thin) () -> () { -bb0: - %r = tuple () - return %r : $() -} - -// CHECK-LABEL: sil @call_shared_external_func -// CHECK-NEXT: -sil @call_shared_external_func : $@convention(thin) () -> () { -bb0: - %u = function_ref @shared_external_func : $@convention(thin) () -> () - %a = apply %u() : $@convention(thin) () -> () - %r = tuple () - return %r : $() -} - diff --git a/test/SILOptimizer/sil_combine.sil b/test/SILOptimizer/sil_combine.sil index 7eb3739180a60..d9deb977a1edf 100644 --- a/test/SILOptimizer/sil_combine.sil +++ b/test/SILOptimizer/sil_combine.sil @@ -1403,7 +1403,7 @@ class AnotherClass : MyNSObj { } sil @MyNSObj_self : $@convention(method) (@guaranteed MyNSObj) -> @owned MyNSObj -sil shared [transparent] [serializable] [reabstraction_thunk] @reabstraction_thunk1 : $@convention(thin) (@in (), @owned @callee_owned () -> @owned AnotherClass) -> @out AnotherClass { +sil shared [transparent] [serialized] [reabstraction_thunk] @reabstraction_thunk1 : $@convention(thin) (@in (), @owned @callee_owned () -> @owned AnotherClass) -> @out AnotherClass { bb0(%0 : $*AnotherClass, %1 : $*(), %2 : $@callee_owned () -> @owned AnotherClass): %3 = apply %2() : $@callee_owned () -> @owned AnotherClass store %3 to %0 : $*AnotherClass @@ -1412,7 +1412,7 @@ bb0(%0 : $*AnotherClass, %1 : $*(), %2 : $@callee_owned () -> @owned AnotherClas } // @nonobjc curry thunk of MyNSObj.self() -sil shared [serializable] [thunk] @curry_thunk_for_MyNSObj_self : $@convention(thin) (@owned MyNSObj) -> @owned @callee_owned () -> @owned MyNSObj { +sil shared [serialized] [thunk] @curry_thunk_for_MyNSObj_self : $@convention(thin) (@owned MyNSObj) -> @owned @callee_owned () -> @owned MyNSObj { bb0(%0 : $MyNSObj): // function_ref @nonobjc MyNSObj.self() %1 = function_ref @MyNSObj_self : $@convention(method) (@guaranteed MyNSObj) -> @owned MyNSObj diff --git a/test/SILOptimizer/sil_combine_ossa.sil b/test/SILOptimizer/sil_combine_ossa.sil index fc45bdc573735..8fa4387d4e22f 100644 --- a/test/SILOptimizer/sil_combine_ossa.sil +++ b/test/SILOptimizer/sil_combine_ossa.sil @@ -1688,7 +1688,7 @@ class AnotherClass : MyNSObj { } sil [ossa] @MyNSObj_self : $@convention(method) (@guaranteed MyNSObj) -> @owned MyNSObj -sil shared [ossa] [transparent] [serializable] [reabstraction_thunk] @reabstraction_thunk1 : $@convention(thin) (@in (), @owned @callee_owned () -> @owned AnotherClass) -> @out AnotherClass { +sil shared [ossa] [transparent] [serialized] [reabstraction_thunk] @reabstraction_thunk1 : $@convention(thin) (@in (), @owned @callee_owned () -> @owned AnotherClass) -> @out AnotherClass { bb0(%0 : $*AnotherClass, %1 : $*(), %2 : @owned $@callee_owned () -> @owned AnotherClass): %3 = apply %2() : $@callee_owned () -> @owned AnotherClass store %3 to [init] %0 : $*AnotherClass @@ -1697,7 +1697,7 @@ bb0(%0 : $*AnotherClass, %1 : $*(), %2 : @owned $@callee_owned () -> @owned Anot } // @nonobjc curry thunk of MyNSObj.self() -sil shared [ossa] [serializable] [thunk] @curry_thunk_for_MyNSObj_self : $@convention(thin) (@owned MyNSObj) -> @owned @callee_owned () -> @owned MyNSObj { +sil shared [ossa] [serialized] [thunk] @curry_thunk_for_MyNSObj_self : $@convention(thin) (@owned MyNSObj) -> @owned @callee_owned () -> @owned MyNSObj { bb0(%0 : @owned $MyNSObj): // function_ref @nonobjc MyNSObj.self() %1 = function_ref @MyNSObj_self : $@convention(method) (@guaranteed MyNSObj) -> @owned MyNSObj diff --git a/test/SILOptimizer/sil_combine_peephole_thick_to_objc_metatype.sil b/test/SILOptimizer/sil_combine_peephole_thick_to_objc_metatype.sil index 6c0182dbd3b0a..6cfa1250e59bf 100644 --- a/test/SILOptimizer/sil_combine_peephole_thick_to_objc_metatype.sil +++ b/test/SILOptimizer/sil_combine_peephole_thick_to_objc_metatype.sil @@ -160,5 +160,5 @@ bb0(%0 : $AnyObject): } // class_copyMethodList -sil [serializable] [clang class_copyMethodList] @class_copyMethodList : $@convention(c) (Optional<@objc_metatype AnyObject.Type>, Optional>) -> Optional> -sil [serializable] @foo : $@convention(thin) (@guaranteed AnyObject) -> @thick AnyObject.Type +sil [serialized] [clang class_copyMethodList] @class_copyMethodList : $@convention(c) (Optional<@objc_metatype AnyObject.Type>, Optional>) -> Optional> +sil [serialized] @foo : $@convention(thin) (@guaranteed AnyObject) -> @thick AnyObject.Type diff --git a/test/SILOptimizer/sil_combine_peephole_thick_to_objc_metatype_ossa.sil b/test/SILOptimizer/sil_combine_peephole_thick_to_objc_metatype_ossa.sil index 93095a0cd9b5a..15859522aece3 100644 --- a/test/SILOptimizer/sil_combine_peephole_thick_to_objc_metatype_ossa.sil +++ b/test/SILOptimizer/sil_combine_peephole_thick_to_objc_metatype_ossa.sil @@ -159,5 +159,5 @@ bb0(%0 : @guaranteed $AnyObject): } // class_copyMethodList -sil [serializable] [clang class_copyMethodList] @class_copyMethodList : $@convention(c) (Optional<@objc_metatype AnyObject.Type>, Optional>) -> Optional> -sil [serializable] @foo : $@convention(thin) (@guaranteed AnyObject) -> @thick AnyObject.Type +sil [serialized] [clang class_copyMethodList] @class_copyMethodList : $@convention(c) (Optional<@objc_metatype AnyObject.Type>, Optional>) -> Optional> +sil [serialized] @foo : $@convention(thin) (@guaranteed AnyObject) -> @thick AnyObject.Type diff --git a/test/SILOptimizer/sil_verify_all_triggers_verifier_without_asserts.sil b/test/SILOptimizer/sil_verify_all_triggers_verifier_without_asserts.sil index 9219a75e49e2a..d1f77ff7c295e 100644 --- a/test/SILOptimizer/sil_verify_all_triggers_verifier_without_asserts.sil +++ b/test/SILOptimizer/sil_verify_all_triggers_verifier_without_asserts.sil @@ -5,6 +5,8 @@ // UNSUPPORTED: asserts +// REQUIRES: rdar89986815 + class Klass {} sil [ossa] @leaky_code : $@convention(thin) () -> () { diff --git a/test/SILOptimizer/specialize.sil b/test/SILOptimizer/specialize.sil index bf6997f34dde3..007e00ad51a86 100644 --- a/test/SILOptimizer/specialize.sil +++ b/test/SILOptimizer/specialize.sil @@ -1,4 +1,4 @@ -// RUN: %target-sil-opt -enable-sil-verify-all -sil-partial-specialization -generic-specializer -save-optimization-record-path=%t.yaml %/s | %FileCheck %s +// RUN: %target-sil-opt -parse-serialized-sil -enable-sil-verify-all -sil-partial-specialization -generic-specializer -save-optimization-record-path=%t.yaml %/s | %FileCheck %s // RUN: %FileCheck -check-prefix=YAML %s < %t.yaml sil_stage canonical @@ -367,7 +367,7 @@ bb0(%0 : $Int32, %1 : $*T, %2 : $<τ_0_0> { var τ_0_0 } ): } // static Swift.+ infix (Swift.Int32, Swift.Int32) -> Swift.Int32 -sil public_external [transparent] [serialized] @$ss1poiys5Int32VAC_ACtFZ : $@convention(thin) (Int32, Int32) -> Int32 { +sil public_external [transparent] @$ss1poiys5Int32VAC_ACtFZ : $@convention(thin) (Int32, Int32) -> Int32 { bb0(%0 : $Int32, %1 : $Int32): %2 = struct_extract %0 : $Int32, #Int32._value // user: %5 %3 = struct_extract %1 : $Int32, #Int32._value // user: %5 diff --git a/test/SILOptimizer/specialize_ossa.sil b/test/SILOptimizer/specialize_ossa.sil index 789a9b2153a70..613c7aa859ea4 100644 --- a/test/SILOptimizer/specialize_ossa.sil +++ b/test/SILOptimizer/specialize_ossa.sil @@ -1,4 +1,4 @@ -// RUN: %target-sil-opt -enable-sil-verify-all -sil-partial-specialization -generic-specializer %s | %FileCheck %s +// RUN: %target-sil-opt -parse-serialized-sil -enable-sil-verify-all -sil-partial-specialization -generic-specializer %s | %FileCheck %s sil_stage canonical diff --git a/test/SILOptimizer/string_optimization.sil b/test/SILOptimizer/string_optimization.sil index 9357799475ed8..83d0c07ec2ea5 100644 --- a/test/SILOptimizer/string_optimization.sil +++ b/test/SILOptimizer/string_optimization.sil @@ -1,4 +1,4 @@ -// RUN: %target-sil-opt %s -string-optimization -sil-combine | %FileCheck %s +// RUN: %target-sil-opt %s -parse-serialized-sil -string-optimization -sil-combine | %FileCheck %s sil_stage canonical diff --git a/test/Sema/diag_originally_definedin.swift b/test/Sema/diag_originally_definedin.swift index faac38c508c48..454ed0555748c 100644 --- a/test/Sema/diag_originally_definedin.swift +++ b/test/Sema/diag_originally_definedin.swift @@ -17,11 +17,16 @@ public class C { public class D {} @available(macOS 10.9, *) -@_originallyDefinedIn(module: "original", _myProject 2.0) // expected-error {{expected at least one platform version in @_originallyDefinedIn}} -// expected-error @-1 {{reference to undefined version '2.0' for availability macro '_myProject'}} +@_originallyDefinedIn(module: "original", _myProject 2.0) // expected-error {{reference to undefined version '2.0' for availability macro '_myProject'}} public func macroVersionned() {} // Fallback to the default diagnostic when the macro is unknown. @available(macOS 10.9, *) -@_originallyDefinedIn(module: "original", _unknownMacro) // expected-error {{expected at least one platform version in @_originallyDefinedIn}} +@_originallyDefinedIn(module: "original", _unknownMacro) // expected-warning {{unknown platform '_unknownMacro' for attribute '@_originallyDefinedIn'}} +// expected-error@-1 {{expected version number in '@_originallyDefinedIn' attribute}} public func macroUnknown() {} + +@available(macOS 10.9, *) +@_originallyDefinedIn(module: "original", swift 5.1) // expected-warning {{unknown platform 'swift' for attribute '@_originallyDefinedIn'}} +// expected-error@-1 {{expected at least one platform version in '@_originallyDefinedIn' attribute}} +public func swiftVersionMacro() {} diff --git a/test/Serialization/Inputs/def_basic.sil b/test/Serialization/Inputs/def_basic.sil index 4eecab7724893..cccc9fcee2441 100644 --- a/test/Serialization/Inputs/def_basic.sil +++ b/test/Serialization/Inputs/def_basic.sil @@ -25,7 +25,7 @@ bb0: } // This references a public global so we *SHOULD* deserialize this. -// CHECK-LABEL: sil public_external [transparent] [serialized] @_TV18lazy_global_access4Type10staticPropySia_public : $@convention(thin) () -> Builtin.RawPointer { +// CHECK-LABEL: sil public_external [transparent] @_TV18lazy_global_access4Type10staticPropySia_public : $@convention(thin) () -> Builtin.RawPointer { sil [transparent] [serialized] @_TV18lazy_global_access4Type10staticPropySia_public : $@convention(thin) () -> Builtin.RawPointer { bb0: // CHECK: alloc_global @public_global @@ -57,7 +57,7 @@ class Class2 { // Instructions -// CHECK-LABEL: sil public_external [transparent] [serialized] @test1 : $@convention(thin) () -> () +// CHECK-LABEL: sil public_external [transparent] @test1 : $@convention(thin) () -> () sil [transparent] [serialized] @test1 : $@convention(thin) () -> () { bb0: // CHECK: bb0: %0 = tuple () // CHECK: %0 = tuple () @@ -69,7 +69,7 @@ bb1: } // Forward referenced values. -// CHECK-LABEL: sil public_external [transparent] [serialized] @test2 : $@convention(thin) (Int) -> () +// CHECK-LABEL: sil public_external [transparent] @test2 : $@convention(thin) (Int) -> () sil [transparent] [serialized] @test2 : $@convention(thin) (Int) -> () { // CHECK: bb1: // CHECK: %[[VAL:[0-9]+]] = tuple () @@ -574,7 +574,7 @@ bb0(%0 : $*SomeProtocol): return %6 : $@thick SomeProtocol.Type } -// CHECK-LABEL: sil public_external [transparent] [serialized] @test_unreachable +// CHECK-LABEL: sil public_external [transparent] @test_unreachable sil [transparent] [serialized] @test_unreachable : $@convention(thin) () -> () { bb0: unreachable @@ -596,7 +596,7 @@ bb0(%0 : $SomeClass): return %5 : $() } -// CHECK-LABEL: sil public_external [transparent] [serialized] @test_basic_block_arguments +// CHECK-LABEL: sil public_external [transparent] @test_basic_block_arguments sil [transparent] [serialized] @test_basic_block_arguments : $@convention(thin) (Builtin.Int1) -> Builtin.Word { bb0(%0 : $Builtin.Int1): // CHECK: cond_br @@ -614,7 +614,7 @@ bb3(%6 : $Builtin.Word): return %6 : $Builtin.Word } -// CHECK-LABEL: sil public_external [transparent] [serialized] @test_cond_branch_basic_block_args +// CHECK-LABEL: sil public_external [transparent] @test_cond_branch_basic_block_args sil [transparent] [serialized] @test_cond_branch_basic_block_args : $@convention(thin) (Int, Builtin.Int1) -> Int { bb0(%0 : $Int, %1 : $Builtin.Int1): cond_br %1, bb1(%0 : $Int), bb2(%0 : $Int) @@ -627,7 +627,7 @@ bb3(%4 : $Int): return %4 : $Int } -// CHECK-LABEL: sil public_external [transparent] [serialized] @test_builtin_func_ref +// CHECK-LABEL: sil public_external [transparent] @test_builtin_func_ref sil [transparent] [serialized] @test_builtin_func_ref : $@convention(thin) (Builtin.Int1, Builtin.Int1) -> Builtin.Int1 { bb0(%0 : $Builtin.Int1, %1 : $Builtin.Int1): %2 = alloc_box $<τ_0_0> { var τ_0_0 } @@ -645,7 +645,7 @@ bb0(%0 : $Builtin.Int1, %1 : $Builtin.Int1): return %10 : $Builtin.Int1 } -// CHECK-LABEL: sil public_external [transparent] [serialized] @test_dealloc_ref +// CHECK-LABEL: sil public_external [transparent] @test_dealloc_ref sil [transparent] [serialized] @test_dealloc_ref : $@convention(thin) () -> () { bb0: %0 = alloc_ref $Class1 @@ -654,7 +654,7 @@ bb0: return %2 : $() } -// CHECK-LABEL: sil public_external [transparent] [serialized] @test_dealloc_partial_ref +// CHECK-LABEL: sil public_external [transparent] @test_dealloc_partial_ref sil [transparent] [serialized] @test_dealloc_partial_ref : $@convention(thin) () -> () { bb0: %0 = alloc_ref $Class1 @@ -664,7 +664,7 @@ bb0: return %2 : $() } -// CHECK-LABEL: sil public_external [transparent] [serialized] @test_dealloc_box +// CHECK-LABEL: sil public_external [transparent] @test_dealloc_box sil [transparent] [serialized] @test_dealloc_box : $@convention(thin) () -> () { bb0: %0 = alloc_box $<τ_0_0> { var τ_0_0 } @@ -673,7 +673,7 @@ bb0: return %2 : $() } -// CHECK-LABEL: sil public_external [transparent] [serialized] @test_stack_flag +// CHECK-LABEL: sil public_external [transparent] @test_stack_flag sil [transparent] [serialized] @test_stack_flag : $@convention(thin) () -> () { bb0: // CHECK: alloc_ref [stack] $Class1 @@ -684,7 +684,7 @@ bb0: return %2 : $() } -// CHECK-LABEL: sil public_external [transparent] [serialized] @test_tail_elems +// CHECK-LABEL: sil public_external [transparent] @test_tail_elems sil [transparent] [serialized] @test_tail_elems : $@convention(thin) (Builtin.Word, Builtin.Word) -> () { bb0(%0 : $Builtin.Word, %1 : $Builtin.Word): // CHECK: alloc_ref [tail_elems $Val * %0 : $Builtin.Word] [tail_elems $Aleph * %1 : $Builtin.Word] $Class1 @@ -695,7 +695,7 @@ bb0(%0 : $Builtin.Word, %1 : $Builtin.Word): return %3 : $() } -// CHECK-LABEL: sil public_external [transparent] [serialized] @test_tail_elems_dynamic +// CHECK-LABEL: sil public_external [transparent] @test_tail_elems_dynamic sil [transparent] [serialized] @test_tail_elems_dynamic : $@convention(thin) (Builtin.Word, Builtin.Word, @thick Class1.Type) -> () { bb0(%0 : $Builtin.Word, %1 : $Builtin.Word, %2 : $@thick Class1.Type): // CHECK: alloc_ref_dynamic [tail_elems $Val * %0 : $Builtin.Word] [tail_elems $Aleph * %1 : $Builtin.Word] %2 : $@thick Class1 @@ -706,7 +706,7 @@ bb0(%0 : $Builtin.Word, %1 : $Builtin.Word, %2 : $@thick Class1.Type): return %4 : $() } -// CHECK-LABEL: sil public_external [transparent] [serialized] @test_tail_addr +// CHECK-LABEL: sil public_external [transparent] @test_tail_addr sil [transparent] [serialized] @test_tail_addr : $@convention(thin) (@owned Class1, Builtin.Word) -> @owned Class1 { bb0(%0 : $Class1, %1 : $Builtin.Word): // CHECK: [[T:%[0-9]+]] = ref_tail_addr %0 : $Class1, $Val @@ -716,7 +716,7 @@ bb0(%0 : $Class1, %1 : $Builtin.Word): return %0 : $Class1 } -// CHECK-LABEL: sil public_external [transparent] [serialized] @test_cow_mutation +// CHECK-LABEL: sil public_external [transparent] @test_cow_mutation sil [transparent] [serialized] @test_cow_mutation : $@convention(thin) (@owned Class1) -> @owned Class1 { bb0(%0 : $Class1): // CHECK: (%1, %2) = begin_cow_mutation %0 : $Class1 @@ -765,7 +765,7 @@ sil [transparent] [serialized] @$s6switch1ayyF : $@convention(thin) () -> () sil [transparent] [serialized] @$s6switch1byyF : $@convention(thin) () -> () sil [transparent] [serialized] @$s6switch1cyyF : $@convention(thin) () -> () -// CHECK-LABEL: sil public_external [transparent] [serialized] @test_switch_union : $@convention(thin) (MaybePair) -> () +// CHECK-LABEL: sil public_external [transparent] @test_switch_union : $@convention(thin) (MaybePair) -> () sil [transparent] [serialized] @test_switch_union : $@convention(thin) (MaybePair) -> () { bb0(%0 : $MaybePair): %1 = alloc_box $<τ_0_0> { var τ_0_0 } @@ -807,7 +807,7 @@ enum MaybeAddressOnlyPair { case Left(Q) } -// CHECK-LABEL: sil public_external [transparent] [serialized] @test_switch_union_addr : $@convention(thin) (@in MaybeAddressOnlyPair) -> () +// CHECK-LABEL: sil public_external [transparent] @test_switch_union_addr : $@convention(thin) (@in MaybeAddressOnlyPair) -> () sil [transparent] [serialized] @test_switch_union_addr : $@convention(thin) (@in MaybeAddressOnlyPair) -> () { bb0(%0 : $*MaybeAddressOnlyPair): // CHECK: switch_enum_addr [[ENUM:%.*]] : $*MaybeAddressOnlyPair, case #MaybeAddressOnlyPair.Neither!enumelt: bb{{.*}}, case #MaybeAddressOnlyPair.Left!enumelt: bb @@ -826,7 +826,7 @@ bb3: return %t : $() } -// CHECK-LABEL: sil public_external [transparent] [serialized] @test_switch_value : $@convention(thin) (Builtin.Word) -> () +// CHECK-LABEL: sil public_external [transparent] @test_switch_value : $@convention(thin) (Builtin.Word) -> () sil [transparent] [serialized] @test_switch_value : $@convention(thin) (Builtin.Word) -> () { bb0(%0 : $Builtin.Word): // CHECK: switch_value %{{.*}} : $Builtin.Word, case %1: bb2, case %2: bb1 @@ -854,7 +854,7 @@ class ConcreteClass : ClassP { struct Spoon : Bendable { } -// CHECK-LABEL: sil public_external [transparent] [serialized] @test_init_existential : $@convention(thin) (Spoon) -> @out Bendable +// CHECK-LABEL: sil public_external [transparent] @test_init_existential : $@convention(thin) (Spoon) -> @out Bendable sil [transparent] [serialized] @test_init_existential : $@convention(thin) (Spoon) -> @out Bendable { bb0(%0 : $*Bendable, %1 : $Spoon): %2 = alloc_box $<τ_0_0> { var τ_0_0 } @@ -871,7 +871,7 @@ bb0(%0 : $*Bendable, %1 : $Spoon): return %8 : $() } -// CHECK-LABEL: sil public_external [transparent] [serialized] @test_existential_ref : $@convention(thin) (ConcreteClass) -> ClassP +// CHECK-LABEL: sil public_external [transparent] @test_existential_ref : $@convention(thin) (ConcreteClass) -> ClassP sil [transparent] [serialized] @test_existential_ref : $@convention(thin) (ConcreteClass) -> ClassP { bb0(%0 : $ConcreteClass): %1 = alloc_box $<τ_0_0> { var τ_0_0 } @@ -885,13 +885,14 @@ bb0(%0 : $ConcreteClass): return %5 : $ClassP } -sil [transparent] [serialized] @test_store : $@convention(thin) (Int, @inout Int) -> () { // CHECK-LABEL: sil public_external [transparent] [serialized] @test_store +// CHECK-LABEL: sil public_external [transparent] @test_store +sil [transparent] [serialized] @test_store : $@convention(thin) (Int, @inout Int) -> () { bb0(%0 : $Int, %1 : $*Int): store %0 to %1 : $*Int // CHECK: store unreachable } -// CHECK-LABEL: sil public_external [transparent] [serialized] @test_transparent : $@convention(thin) () -> () { +// CHECK-LABEL: sil public_external [transparent] @test_transparent : $@convention(thin) () -> () { sil [transparent] [serialized] @test_transparent : $@convention(thin) () -> () { bb0: // CHECK: function_ref @@ -902,7 +903,7 @@ bb0: return %2 : $() } -// CHECK-LABEL: sil public_external [transparent] [serialized] [thunk] @test_thunk : $@convention(thin) () -> () { +// CHECK-LABEL: sil public_external [transparent] [thunk] @test_thunk : $@convention(thin) () -> () { sil [transparent] [serialized] [thunk] @test_thunk : $@convention(thin) () -> () { bb0: %0 = tuple () @@ -961,7 +962,7 @@ sil [transparent] [serialized] @takes_unnamed_closure : $@convention(thin) (@cal sil [transparent] [serialized] @takes_int64_float32 : $@convention(thin) (Int, Float32) -> () -// CHECK-LABEL: sil public_external [transparent] [serialized] @test_partial_apply : $@convention(thin) (Float) -> @callee_owned (Int) -> () { +// CHECK-LABEL: sil public_external [transparent] @test_partial_apply : $@convention(thin) (Float) -> @callee_owned (Int) -> () { sil [transparent] [serialized] @test_partial_apply : $@convention(thin) (Float32) -> @callee_owned (Int) -> () { bb0(%0 : $Float32): %1 = function_ref @takes_int64_float32 : $@convention(thin) (Int, Float) -> () @@ -974,7 +975,7 @@ class X { @objc func f() { } } -// CHECK-LABEL: sil public_external [transparent] [serialized] @test_dynamic_lookup_br : $@convention(thin) (AnyObject) -> () +// CHECK-LABEL: sil public_external [transparent] @test_dynamic_lookup_br : $@convention(thin) (AnyObject) -> () sil [transparent] [serialized] @test_dynamic_lookup_br : $@convention(thin) (AnyObject) -> () { bb0(%0 : $AnyObject): %1 = alloc_box $<τ_0_0> { var τ_0_0 } @@ -998,7 +999,7 @@ bb3: return %28 : $() } -// CHECK-LABEL: sil public_external [transparent] [serialized] @test_mark_fn_escape +// CHECK-LABEL: sil public_external [transparent] @test_mark_fn_escape sil [transparent] [serialized] @test_mark_fn_escape : $@convention(thin) () -> () { %b = alloc_box $<τ_0_0> { var τ_0_0 } %ba = project_box %b : $<τ_0_0> { var τ_0_0 } , 0 @@ -1012,7 +1013,7 @@ sil [transparent] [serialized] @test_mark_fn_escape : $@convention(thin) () -> ( return %28 : $() } -// CHECK-LABEL: sil public_external [transparent] [serialized] @test_copy_release_value +// CHECK-LABEL: sil public_external [transparent] @test_copy_release_value sil [transparent] [serialized] @test_copy_release_value : $@convention(thin) (X) -> (X) { bb0(%0 : $X): retain_value %0 : $X @@ -1023,7 +1024,7 @@ bb0(%0 : $X): // CHECK-NEXT: return [[T0]] : $X } -// CHECK-LABEL: sil public_external [transparent] [serialized] @test_set_deallocating +// CHECK-LABEL: sil public_external [transparent] @test_set_deallocating sil [transparent] [serialized] @test_set_deallocating : $@convention(thin) (X) -> (X) { bb0(%0 : $X): set_deallocating %0 : $X @@ -1032,7 +1033,7 @@ bb0(%0 : $X): // CHECK-NEXT: return [[T0]] : $X } -// CHECK-LABEL: sil public_external [transparent] [serialized] @test_pointer_to_address +// CHECK-LABEL: sil public_external [transparent] @test_pointer_to_address sil [transparent] [serialized] @test_pointer_to_address : $@convention(thin) (Builtin.RawPointer, X) -> () { bb0(%0 : $Builtin.RawPointer, %1 : $X): %2 = pointer_to_address %0 : $Builtin.RawPointer to $*X @@ -1047,7 +1048,7 @@ bb0(%0 : $Builtin.RawPointer, %1 : $X): return %28 : $() } -// CHECK-LABEL: sil public_external [transparent] [serialized] @test_bind_memory +// CHECK-LABEL: sil public_external [transparent] @test_bind_memory sil [transparent] [serialized] @test_bind_memory : $@convention(thin) (Builtin.RawPointer, Builtin.Word) -> () { bb0(%0 : $Builtin.RawPointer, %1 : $Builtin.Word): %2 = bind_memory %0 : $Builtin.RawPointer, %1 : $Builtin.Word to $*X @@ -1063,7 +1064,7 @@ bb0(%0 : $Builtin.RawPointer, %1 : $Builtin.Word): @_transparent public func serialize_all() { } -// CHECK: sil public_external [transparent] [serialized] @cond_fail_test : $@convention(thin) (Builtin.Int1) -> () { +// CHECK: sil public_external [transparent] @cond_fail_test : $@convention(thin) (Builtin.Int1) -> () { sil [transparent] [serialized] @cond_fail_test : $@convention(thin) (Builtin.Int1) -> () { entry(%0 : $Builtin.Int1): // CHECK: cond_fail %0 : $Builtin.Int1, "message" @@ -1072,7 +1073,7 @@ entry(%0 : $Builtin.Int1): return %1 : $() } -// CHECK-LABEL: sil public_external [transparent] [serialized] @test_dynamic_lifetime_flag : $@convention(thin) () -> () +// CHECK-LABEL: sil public_external [transparent] @test_dynamic_lifetime_flag : $@convention(thin) () -> () sil [transparent] [serialized] @test_dynamic_lifetime_flag : $@convention(thin) () -> () { bb0: // CHECK: alloc_box [dynamic_lifetime] $<τ_0_0> { var τ_0_0 } @@ -1084,7 +1085,7 @@ bb0: return %2 : $() } -// CHECK-LABEL: sil public_external [transparent] [serialized] @block_storage_type +// CHECK-LABEL: sil public_external [transparent] @block_storage_type sil [transparent] [serialized] @block_storage_type : $@convention(thin) (Int) -> @convention(block) () -> () { entry(%0 : $Int): // CHECK: [[STORAGE:%.*]] = alloc_stack $@block_storage Int @@ -1103,7 +1104,7 @@ entry(%0 : $Int): return %b : $@convention(block) () -> () } -// CHECK-LABEL: sil public_external [transparent] [serialized] @bitcasts : $@convention(thin) (@owned Class1) -> @owned (Class2, Int) { +// CHECK-LABEL: sil public_external [transparent] @bitcasts : $@convention(thin) (@owned Class1) -> @owned (Class2, Int) { // CHECK: bb0(%0 : $Class1): // CHECK-NEXT: %1 = unchecked_ref_cast %0 : $Class1 to $Class2 // CHECK-NEXT: %2 = unchecked_trivial_bit_cast %0 : $Class1 to $Int @@ -1122,7 +1123,7 @@ sil [transparent] [serialized] @block_invoke : $@convention(c) (@inout_aliasable // Test try_apply and throws // rdar://20925014 -// CHECK-LABEL: sil public_external [transparent] [serialized] @test_try_apply : $@convention(thin) (@convention(thin) () -> @error Error) -> @error Error { +// CHECK-LABEL: sil public_external [transparent] @test_try_apply : $@convention(thin) (@convention(thin) () -> @error Error) -> @error Error { sil [transparent] [serialized] @test_try_apply : $@convention(thin) (@convention(thin) () -> @error Error) -> @error Error { bb0(%0 : $@convention(thin) () -> @error Error): // CHECK: try_apply %0() : $@convention(thin) () -> @error Error, normal bb2, error bb1 @@ -1137,7 +1138,7 @@ bb2(%3 : $Error): } // Test apply with the nothrow attribute -// CHECK-LABEL: sil public_external [transparent] [serialized] @test_try_nothrow : $@convention(thin) (@convention(thin) () -> @error Error) -> () { +// CHECK-LABEL: sil public_external [transparent] @test_try_nothrow : $@convention(thin) (@convention(thin) () -> @error Error) -> () { sil [transparent] [serialized] @test_try_nothrow : $@convention(thin) (@convention(thin) () -> @error Error) -> () { bb0(%0 : $@convention(thin) () -> @error Error): // CHECK: apply [nothrow] %0() : $@convention(thin) () -> @error Error @@ -1146,7 +1147,7 @@ bb0(%0 : $@convention(thin) () -> @error Error): return %2 : $() } -// CHECK-LABEL: sil public_external [transparent] [serialized] @box_type : $@convention(thin) (<τ_0_0> { var τ_0_0 } , Int) -> () { +// CHECK-LABEL: sil public_external [transparent] @box_type : $@convention(thin) (<τ_0_0> { var τ_0_0 } , Int) -> () { sil [transparent] [serialized] @box_type : $@convention(thin) (<τ_0_0> { var τ_0_0 } , Int) -> () { // CHECK: bb0(%0 : $<τ_0_0> { var τ_0_0 } , %1 : $Int): bb0(%0 : $<τ_0_0> { var τ_0_0 } , %1 : $Int): @@ -1161,7 +1162,7 @@ bb0(%0 : $<τ_0_0> { var τ_0_0 } , %1 : $Int): // CHECK-LABEL: @test_forward_ref sil [transparent] [serialized] @test_forward_ref : $@convention(thin) (UInt8, UInt8) -> UInt8 -// CHECK-LABEL: sil public_external [transparent] [serialized] @partial_apply : $@convention(thin) (@convention(thin) (Int) -> @out Int, Int) -> Int { +// CHECK-LABEL: sil public_external [transparent] @partial_apply : $@convention(thin) (@convention(thin) (Int) -> @out Int, Int) -> Int { // CHECK: [[PA:%.*]] = partial_apply {{%.*}}({{%.*}}) : $@convention(thin) (Int) -> @out Int // CHECK: apply [[PA]]({{%.*}}) : $@callee_owned () -> @out Int sil [transparent] [serialized] @partial_apply : $@convention(thin) (@convention(thin) (Int) -> @out Int, Int) -> Int { @@ -1190,7 +1191,7 @@ struct GenericStruct { var x : T } -// CHECK-LABEL: sil public_external [transparent] [serialized] @extract_generic_struct +// CHECK-LABEL: sil public_external [transparent] @extract_generic_struct sil [transparent] [serialized] @extract_generic_struct : $@convention(thin) (GenericStruct) -> Int64 { entry(%0 : $GenericStruct): // CHECK: %1 = struct_extract %0 : $GenericStruct, #GenericStruct.x @@ -1199,7 +1200,7 @@ entry(%0 : $GenericStruct): return %1 : $Int64 } -// CHECK-LABEL: sil public_external [transparent] [serialized] @select_enum : $@convention(thin) (@in Beth) -> () { +// CHECK-LABEL: sil public_external [transparent] @select_enum : $@convention(thin) (@in Beth) -> () { sil [transparent] [serialized] @select_enum : $@convention(thin) (@in Beth) -> () { bb0(%0 : $*Beth): %1 = load %0 : $*Beth @@ -1221,7 +1222,7 @@ struct SomeError: Error { var _code: Int { get } } -// CHECK-LABEL: sil public_external [transparent] [serialized] @existential_box : $@convention(thin) (SomeError) -> () { +// CHECK-LABEL: sil public_external [transparent] @existential_box : $@convention(thin) (SomeError) -> () { sil [transparent] [serialized] @existential_box : $@convention(thin) (SomeError) -> () { bb0(%0 : $SomeError): // CHECK: %1 = alloc_existential_box $Error, $SomeError @@ -1239,7 +1240,7 @@ bb0(%0 : $SomeError): return undef : $() } -// CHECK-LABEL: sil public_external [transparent] [serialized] @bridge_object : $@convention(thin) (@owned Class1, Builtin.Word) -> () { +// CHECK-LABEL: sil public_external [transparent] @bridge_object : $@convention(thin) (@owned Class1, Builtin.Word) -> () { // CHECK: bb0([[X:%.*]] : $Class1, [[W:%.*]] : $Builtin.Word): // CHECK-NEXT: [[A:%.*]] = ref_to_bridge_object [[X]] : $Class1, [[W]] : $Builtin.Word // CHECK-NEXT: [[B:%.*]] = bridge_object_to_ref [[A]] : $Builtin.BridgeObject to $Class1 @@ -1253,12 +1254,12 @@ entry(%x : $Class1, %w : $Builtin.Word): return undef : $() } -// CHECK-LABEL: sil public_external [transparent] [serialized] [reabstraction_thunk] @a_reabstraction_thunk : $@convention(thin) () -> () { +// CHECK-LABEL: sil public_external [transparent] [reabstraction_thunk] @a_reabstraction_thunk : $@convention(thin) () -> () { sil [transparent] [serialized] [reabstraction_thunk] @a_reabstraction_thunk : $@convention(thin) () -> () { %1 = tuple() return %1 : $() } -// CHECK-LABEL: sil public_external [transparent] [serialized] [thunk] @a_regular_thunk : $@convention(thin) () -> () { +// CHECK-LABEL: sil public_external [transparent] [thunk] @a_regular_thunk : $@convention(thin) () -> () { sil [transparent] [serialized] [thunk] @a_regular_thunk : $@convention(thin) () -> () { %1 = tuple() return %1 : $() @@ -1271,7 +1272,7 @@ public class WeakUnownedTest { deinit } -// CHECK-LABEL: sil public_external [transparent] [serialized] @weak_unowned : $@convention(thin) (@owned WeakUnownedTest, @owned AnyObject) -> () +// CHECK-LABEL: sil public_external [transparent] @weak_unowned : $@convention(thin) (@owned WeakUnownedTest, @owned AnyObject) -> () sil [transparent] [serialized] @weak_unowned : $@convention(thin) (@owned WeakUnownedTest, @owned AnyObject) -> () { bb0(%0 : $WeakUnownedTest, %1 : $AnyObject): %2 = ref_element_addr %0 : $WeakUnownedTest, #WeakUnownedTest.unownedVal @@ -1296,7 +1297,7 @@ class A { init() } -// CHECK-LABEL: sil public_external [transparent] [serialized] @test_access : $@convention(thin) (@guaranteed A) -> () { +// CHECK-LABEL: sil public_external [transparent] @test_access : $@convention(thin) (@guaranteed A) -> () { // CHECK: begin_access [read] [dynamic] // CHECK: end_access // CHECK: begin_access [read] [dynamic] [no_nested_conflict] @@ -1329,7 +1330,7 @@ bb0(%0 : $A): return %20 : $() } -// CHECK-LABEL: sil public_external [transparent] [serialized] @test_builtin_access : $@convention(thin) (@guaranteed A) -> () { +// CHECK-LABEL: sil public_external [transparent] @test_builtin_access : $@convention(thin) (@guaranteed A) -> () { // CHECK: begin_access [read] [dynamic] [builtin] // CHECK: end_access // CHECK: begin_unpaired_access [read] [dynamic] [builtin] diff --git a/test/Serialization/Inputs/def_basic_objc.sil b/test/Serialization/Inputs/def_basic_objc.sil index 3f12e31072588..bc69c44781a6b 100644 --- a/test/Serialization/Inputs/def_basic_objc.sil +++ b/test/Serialization/Inputs/def_basic_objc.sil @@ -31,7 +31,7 @@ sil [serialized] [ossa] @$sSSSSycSSmcfC : $@convention(thin) (@thin String.Type) protocol SomeClassProtocol : class {} -// CHECK-LABEL: sil public_external [transparent] [serialized] @metatype_to_object +// CHECK-LABEL: sil public_external [transparent] @metatype_to_object // CHECK: {{%.*}} = objc_metatype_to_object {{%.*}} : $@objc_metatype SomeClass.Type to $AnyObject // CHECK: {{%.*}} = objc_existential_metatype_to_object {{%.*}} : $@objc_metatype SomeClassProtocol.Type to $AnyObject sil [transparent] [serialized] [ossa] @metatype_to_object : $@convention(thin) (@objc_metatype SomeClass.Type, @objc_metatype SomeClassProtocol.Type) -> @owned (AnyObject, AnyObject) { @@ -44,7 +44,7 @@ entry(%a : $@objc_metatype SomeClass.Type, %b : $@objc_metatype SomeClassProtoco @objc protocol ObjCProto {} -// CHECK-LABEL: sil public_external [transparent] [serialized] @protocol_conversion +// CHECK-LABEL: sil public_external [transparent] @protocol_conversion sil [transparent] [serialized] [ossa] @protocol_conversion : $@convention(thin) () -> @owned Protocol { entry: // CHECK: {{%.*}} = objc_protocol #ObjCProto : $Protocol diff --git a/test/Serialization/Inputs/def_concurrency.sil b/test/Serialization/Inputs/def_concurrency.sil index 0c489762b6acc..21e347c0979e2 100644 --- a/test/Serialization/Inputs/def_concurrency.sil +++ b/test/Serialization/Inputs/def_concurrency.sil @@ -8,7 +8,7 @@ actor Act { } @_transparent public func serialize_all() { } -// CHECK-LABEL: sil public_external [transparent] [serialized] @test_hop_to_executor_actor +// CHECK-LABEL: sil public_external [transparent] @test_hop_to_executor_actor sil [transparent] [serialized] @test_hop_to_executor_actor : $@convention(thin) (@guaranteed Act) -> () { bb0(%0 : $Act): // CHECK: hop_to_executor %0 : $Act @@ -19,7 +19,7 @@ bb0(%0 : $Act): return %2 : $() } -// CHECK-LABEL: sil public_external [transparent] [serialized] @test_hop_to_executor_builtin +// CHECK-LABEL: sil public_external [transparent] @test_hop_to_executor_builtin sil [transparent] [serialized] @test_hop_to_executor_builtin : $@convention(thin) (@guaranteed Builtin.Executor) -> () { bb0(%0 : $Builtin.Executor): // CHECK: hop_to_executor %0 : $Builtin.Executor diff --git a/test/Serialization/basic_sil.swift b/test/Serialization/basic_sil.swift index 8aab900fafcd2..8561ef5894ea2 100644 --- a/test/Serialization/basic_sil.swift +++ b/test/Serialization/basic_sil.swift @@ -2,7 +2,7 @@ // RUN: %target-build-swift -emit-module -Xfrontend -disable-diagnostic-passes -whole-module-optimization -Xfrontend -enable-objc-interop -o %t/def_basic.swiftmodule %S/Inputs/def_basic.sil // RUN: llvm-bcanalyzer %t/def_basic.swiftmodule | %FileCheck %s // RUN: %target-build-swift -emit-sil -I %t %s -o %t/basic_sil.sil -// RUN: %target-sil-opt -I %t %t/basic_sil.sil -performance-linker | %FileCheck %S/Inputs/def_basic.sil +// RUN: %target-sil-opt -parse-serialized-sil -I %t %t/basic_sil.sil -performance-linker | %FileCheck %S/Inputs/def_basic.sil // This test currently is written such that no optimizations are assumed. // REQUIRES: swift_test_mode_optimize_none diff --git a/test/Serialization/basic_sil_objc.swift b/test/Serialization/basic_sil_objc.swift index 527279829f615..d58c26ac375b8 100644 --- a/test/Serialization/basic_sil_objc.swift +++ b/test/Serialization/basic_sil_objc.swift @@ -3,7 +3,7 @@ // RUN: llvm-bcanalyzer %t/def_basic_objc.swiftmodule | %FileCheck %s // RUN: %target-build-swift -Xfrontend %clang-importer-sdk -emit-sil -I %t %s -o %t/basic_sil_objc.sil -// RUN: %target-sil-opt %t/basic_sil_objc.sil -performance-linker -I %t | %FileCheck %S/Inputs/def_basic_objc.sil +// RUN: %target-sil-opt -parse-serialized-sil %t/basic_sil_objc.sil -performance-linker -I %t | %FileCheck %S/Inputs/def_basic_objc.sil // This test currently is written such that no optimizations are assumed. // REQUIRES: swift_test_mode_optimize_none diff --git a/test/Serialization/concurrency_sil.swift b/test/Serialization/concurrency_sil.swift index 7d7e0067735f2..bc77e4ec307db 100644 --- a/test/Serialization/concurrency_sil.swift +++ b/test/Serialization/concurrency_sil.swift @@ -2,7 +2,7 @@ // RUN: %target-build-swift -emit-module -Xfrontend -disable-availability-checking -Xfrontend -disable-diagnostic-passes -whole-module-optimization -Xfrontend -enable-objc-interop -o %t/def_concurrency.swiftmodule %S/Inputs/def_concurrency.sil // RUN: llvm-bcanalyzer %t/def_concurrency.swiftmodule | %FileCheck %s // RUN: %target-build-swift -emit-sil -I %t %s -o %t/concurrency_sil.sil -// RUN: %target-sil-opt -I %t %t/concurrency_sil.sil -performance-linker | %FileCheck %S/Inputs/def_concurrency.sil +// RUN: %target-sil-opt -parse-serialized-sil -I %t %t/concurrency_sil.sil -performance-linker | %FileCheck %S/Inputs/def_concurrency.sil // This test currently is written such that no optimizations are assumed. // REQUIRES: swift_test_mode_optimize_none diff --git a/test/Serialization/early-serialization.swift b/test/Serialization/early-serialization.swift index 1c41551ab0eb8..b8bb3d41d1f80 100644 --- a/test/Serialization/early-serialization.swift +++ b/test/Serialization/early-serialization.swift @@ -28,7 +28,7 @@ public struct Array { } // Check that a specialized version of a function is produced -// CHECK: sil shared [serializable] [_semantics "array.get_capacity"] [canonical] [ossa] @$sSa12_getCapacitySiyFSi_Tgq5 : $@convention(method) (Array) -> Int +// CHECK: sil shared [serialized] [_semantics "array.get_capacity"] [canonical] [ossa] @$sSa12_getCapacitySiyFSi_Tgq5 : $@convention(method) (Array) -> Int // Check that a call of a @_semantics function was not inlined if early-serialization is enabled. // CHECK: sil [serialized] [canonical] [ossa] @$ss28userOfSemanticsAnnotatedFuncySiSaySiGF diff --git a/test/api-digester/stability-concurrency-abi.test b/test/api-digester/stability-concurrency-abi.test index 0b31d1d0171b3..670dd052326e0 100644 --- a/test/api-digester/stability-concurrency-abi.test +++ b/test/api-digester/stability-concurrency-abi.test @@ -58,5 +58,7 @@ Func AsyncSequence.map(_:) is now with @preconcurrency Func AsyncSequence.prefix(while:) is now with @preconcurrency Func MainActor.run(resultType:body:) has generic signature change from to Func MainActor.run(resultType:body:) has mangled name changing from 'static Swift.MainActor.run(resultType: A.Type, body: @Swift.MainActor @Sendable () throws -> A) async throws -> A' to 'static Swift.MainActor.run(resultType: A.Type, body: @Swift.MainActor @Sendable () throws -> A) async throws -> A' +Protocol Actor has added inherited protocol AnyActor +Protocol Actor has generic signature change from to Struct CheckedContinuation has removed conformance to UnsafeSendable // *** DO NOT DISABLE OR XFAIL THIS TEST. *** (See comment above.) diff --git a/test/attr/attr_backDeploy.swift b/test/attr/attr_backDeploy.swift index e1d7587c85846..9b1c2556abcce 100644 --- a/test/attr/attr_backDeploy.swift +++ b/test/attr/attr_backDeploy.swift @@ -1,4 +1,5 @@ -// RUN: %target-typecheck-verify-swift -parse-as-library +// RUN: %target-typecheck-verify-swift -parse-as-library \ +// RUN: -define-availability "_myProject 2.0:macOS 12.0" // MARK: - Valid declarations @@ -192,6 +193,7 @@ public func transparentFunc() {} // MARK: - Attribute parsing +@available(macOS 11.0, *) @_backDeploy(macOS 12.0, unknownOS 1.0) // expected-warning {{unknown platform 'unknownOS' for attribute '@_backDeploy'}} public func unknownOSFunc() {} @@ -230,8 +232,27 @@ public func trailingWildcardFunc() {} @_backDeploy(macOS 12.0, *, iOS 15.0) // expected-warning {{* as platform name has no effect in '@_backDeploy' attribute}} public func embeddedWildcardFunc() {} +@_backDeploy(_myProject 3.0) // expected-error {{reference to undefined version '3.0' for availability macro '_myProject'}} +public func macroVersionned() {} + +@_backDeploy(_myProject) // expected-error {{reference to undefined version '0' for availability macro '_myProject'}} +public func missingMacroVersion() {} + +// Fall back to the default diagnostic when the macro is unknown. +@_backDeploy(_unknownMacro) // expected-warning {{unknown platform '_unknownMacro' for attribute '@_backDeploy'}} +// expected-error@-1 {{expected version number in '@_backDeploy' attribute}} +public func unknownMacroMissingVersion() {} + +@_backDeploy(_unknownMacro 1.0) // expected-warning {{unknown platform '_unknownMacro' for attribute '@_backDeploy'}} +// expected-error@-1 {{expected at least one platform version in '@_backDeploy' attribute}} +public func unknownMacroVersionned() {} + +@available(macOS 11.0, *) +@_backDeploy(_unknownMacro 1.0, _myProject 2.0) // expected-warning {{unknown platform '_unknownMacro' for attribute '@_backDeploy'}} +public func knownAndUnknownMacroVersionned() {} + @_backDeploy() // expected-error {{expected at least one platform version in '@_backDeploy' attribute}} -public func zeroPlatformVersionsFunc() {} +public func emptyPlatformVersionsFunc() {} @_backDeploy // expected-error {{expected '(' in '_backDeploy' attribute}} public func expectedLeftParenFunc() {} diff --git a/test/decl/protocol/existential_member_accesses_self_assoctype.swift b/test/decl/protocol/existential_member_accesses_self_assoctype.swift index c8962bf15cb81..97b6126ee0c4a 100644 --- a/test/decl/protocol/existential_member_accesses_self_assoctype.swift +++ b/test/decl/protocol/existential_member_accesses_self_assoctype.swift @@ -560,6 +560,8 @@ extension UnfulfillableGenericRequirements { A: Sequence, A.Element: Sequence, U.A == A.Element.Element {} func method7(_: U) where U: UnfulfillableGenericRequirements & Class {} + + func method8(_: U) where U == Self.A {} } do { let exist: any UnfulfillableGenericRequirements @@ -579,6 +581,19 @@ do { exist.method7(false) // expected-error@-1 {{instance method 'method7' requires that 'U' conform to 'UnfulfillableGenericRequirements'}} // expected-error@-2 {{member 'method7' cannot be used on value of type 'any UnfulfillableGenericRequirements'; consider using a generic constraint instead}} + + exist.method8(false) + // expected-error@-1 {{member 'method8' cannot be used on value of type 'any UnfulfillableGenericRequirements'; consider using a generic constraint instead}} +} + +// Make sure this also works in a generic context! +struct G { + func doIt() { + let exist: any UnfulfillableGenericRequirements + + exist.method8(false) + // expected-error@-1 {{member 'method8' cannot be used on value of type 'any UnfulfillableGenericRequirements'; consider using a generic constraint instead}} + } } protocol UnfulfillableGenericRequirementsDerived1: UnfulfillableGenericRequirements where A == Bool {} protocol UnfulfillableGenericRequirementsDerived2: UnfulfillableGenericRequirements where A == Class {} diff --git a/test/lit.cfg b/test/lit.cfg index 96038f48685ab..597f6c16940e1 100644 --- a/test/lit.cfg +++ b/test/lit.cfg @@ -940,6 +940,7 @@ config.target_cxx_lib = '-lc++' config.target_msvc_runtime_opt = '' config.target_static_library_prefix = 'lib' config.target_static_library_suffix = '.a' +config.target_env_prefix = '' if run_vendor == 'apple': target_specific_module_triple = '{}-apple-{}'.format( @@ -954,6 +955,7 @@ if run_vendor == 'apple': config.target_codesign = make_path(config.swift_utils, "swift-darwin-postprocess.py") else: config.target_codesign = "codesign -f -s -" + config.target_library_path_var = "DYLD_LIBRARY_PATH" config.target_runtime = "objc" config.available_features.add('libdispatch') @@ -1080,6 +1082,8 @@ if run_vendor == 'apple': xcrun_sdk_name = "watchos" target_future_version = "9.99.0" + config.target_env_prefix = 'IOS_CHILD_' + config.target_cc_options = ( "-target %s %s" % (config.variant_triple, clang_mcp_opt)) @@ -1122,6 +1126,8 @@ if run_vendor == 'apple': target_specific_module_triple += "-simulator" + config.target_env_prefix = 'SIMCTL_CHILD_' + config.target_cc_options = ( "-target %s %s" % (config.variant_triple, clang_mcp_opt)) @@ -1330,6 +1336,7 @@ elif run_os in ['windows-msvc']: config.target_msvc_runtime_opt = '-%s -D_MT' % config.swift_stdlib_msvc_runtime if 'D' in config.swift_stdlib_msvc_runtime: config.target_msvc_runtime_opt += ' -D_DLL' + config.target_env_prefix = '' config.target_build_swift = \ ('%r -target %s %s %s %s %s -libc %s' % \ @@ -1439,6 +1446,7 @@ elif (run_os in ['linux-gnu', 'linux-gnueabihf', 'freebsd', 'openbsd', 'windows- config.target_shared_library_suffix = ".so" config.target_sdk_name = "android" config.target_cc_options = "-fPIE" + config.target_env_prefix = 'ANDROID_CHILD_' else: lit_config.note("Testing Linux " + config.variant_triple) config.target_object_format = "elf" @@ -1446,6 +1454,7 @@ elif (run_os in ['linux-gnu', 'linux-gnueabihf', 'freebsd', 'openbsd', 'windows- config.target_shared_library_suffix = ".so" config.target_sdk_name = "linux" config.target_cc_options = "-fPIE" + config.target_library_path_var = "LD_LIBRARY_PATH" config.target_runtime = "native" config.target_swift_autolink_extract = inferSwiftBinary("swift-autolink-extract") @@ -1572,6 +1581,8 @@ elif run_os == 'linux-androideabi' or run_os == 'linux-android': config.target_runtime = "native" config.target_swift_autolink_extract = inferSwiftBinary("swift-autolink-extract") config.target_sdk_name = "android" + config.target_library_path_var = "LD_LIBRARY_PATH" + config.target_env_prefix = 'ANDROID_CHILD_' config.resource_dir_opt = ("-resource-dir %s" % test_resource_dir) # Since NDK r19, the headers and libraries are available in a unified # sysroot at $NDK_PATH/toolchains/llvm/prebuilt/$prebuilt_directory/sysroot, @@ -1807,19 +1818,6 @@ config.substitutions.append(('%string_processing_module', string_processing_modu config.substitutions.append(('%/string_processing_module', '/'.join(os.path.normpath(string_processing_module).split(os.sep)))) -# Different OS's require different prefixes for the environment variables to be -# propagated to the calling contexts. -# In order to make tests OS-agnostic, names of environment variables should be -# prefixed with `%env-`, which is then expanded to the appropriate prefix. -SIMULATOR_ENV_PREFIX = 'SIMCTL_CHILD_' -ENV_VAR_PREFIXES = { - 'iphonesimulator': SIMULATOR_ENV_PREFIX, - 'watchsimulator': SIMULATOR_ENV_PREFIX, - 'appletvsimulator': SIMULATOR_ENV_PREFIX, - 'android': 'ANDROID_CHILD_' -} -TARGET_ENV_PREFIX = ENV_VAR_PREFIXES.get(config.target_sdk_name, "") if not kIsAndroid else "" - back_deployment_runtime = lit_config.params.get('back_deployment_runtime', None) if back_deployment_runtime is not None: config.available_features.add('back_deployment_runtime') @@ -1829,7 +1827,32 @@ if run_vendor == 'apple': if 'back_deploy_concurrency' in config.available_features: concurrency_back_deploy_path = os.path.join(os.path.dirname(swift_obj_root), os.path.basename(swift_obj_root).replace("swift-", "backdeployconcurrency-"), 'lib', 'swift-5.5', run_os) -if 'remote_run_host' in lit_config.params: +def os_stdlib_paths(): + if run_vendor == 'apple': + if run_os == 'maccatalyst': + return ["/System/iOSSupport/usr/lib/swift", "/usr/lib/swift"] + else: + return ["/usr/lib/swift"] + else: + lit_config.fatal("Unsupported platform for os_stdlib_paths") + +# This returns a shell variable assignment of the form = +# where is whatever environment variable we need to set to +# override dynamic library locations. (Usually DYLD_LIBRARY_PATH or +# LD_LIBRARY_PATH, sometimes prefixed by a special annotation to tunnel the +# setting through a helper tool.) +# +# The return value is designed to be passed to `/usr/bin/env` when executing a +# binary on the test target. +# +# The single parameter is an array of directory paths that hold the libraries. +def construct_library_path_env(dirs): + return "{0}{1}='{2}' ".format( + config.target_env_prefix, + config.target_library_path_var, + os.path.pathsep.join(dirs)) + +def configure_remote_run(): if 'remote_run_tmpdir' not in lit_config.params: lit_config.fatal("'remote_run_host' provided, but no " "'remote_run_tmpdir'") @@ -1837,16 +1860,18 @@ if 'remote_run_host' in lit_config.params: remote_run_host = lit_config.params['remote_run_host'] remote_tmp_dir = lit_config.params['remote_run_tmpdir'] remote_lib_dir = os.path.join(remote_tmp_dir, 'stdlib') - remote_run_lib_path = '' - if 'use_os_stdlib' not in lit_config.params: - remote_run_lib_path = remote_lib_dir - else: + remote_run_lib_path = [remote_lib_dir] + if 'use_os_stdlib' in lit_config.params: config.available_features.add('use_os_stdlib') - os_stdlib_path = '' - if run_vendor == 'apple': - #If we get swift-in-the-OS for non-Apple platforms, add a condition here - os_stdlib_path = "/usr/lib/swift" - remote_run_lib_path = os.path.pathsep.join((os_stdlib_path, remote_lib_dir)) + remote_run_lib_path = os_stdlib_paths() + [remote_lib_dir] + lit_config.note('Remote testing with the standard libraries in the OS') + elif 'back_deployment_runtime' in lit_config.params: + lit_config.note('Remote testing with back deployment libraries') + else: + lit_config.note('Remote testing with the just-built libraries') + + lit_config.note( + 'Remote library load path: {0}'.format(os.path.pathsep.join(remote_run_lib_path))) remote_run_extra_args_param = lit_config.params.get('remote_run_extra_args') remote_run_extra_args = shlex.split(remote_run_extra_args_param or '') @@ -1893,23 +1918,38 @@ if 'remote_run_host' in lit_config.params: os.path.dirname(local_swift_reflection_test), 'bin/') + print("Contents of {0} on {1} after upload:".format( + remote_lib_dir, remote_run_host)) + subprocess.check_call( + [ + os.path.join(config.swift_utils, 'remote-run'), + '--remote-dir', remote_tmp_dir, + ] + remote_run_extra_args + [ + remote_run_host, + '--', + 'ls', '-l', remote_lib_dir + ]) + + config.target_env_prefix = 'REMOTE_RUN_CHILD_' config.target_run = ( - "/usr/bin/env " - "REMOTE_RUN_CHILD_DYLD_LIBRARY_PATH='{0}' " # Apple option - "REMOTE_RUN_CHILD_LD_LIBRARY_PATH='{0}' " # Linux option - "'{1}'/remote-run --input-prefix '{2}' --output-prefix %t " - "--remote-dir '{3}'%t {4} {5}".format(remote_run_lib_path, - config.swift_utils, - config.swift_src_root, - remote_tmp_dir, - ' '.join(remote_run_extra_args), - remote_run_host)) + "/usr/bin/env " + + construct_library_path_env(remote_run_lib_path) + + "'{0}'/remote-run ".format(config.swift_utils) + + "--input-prefix '{0}' ".format(config.src_root) + + "--output-prefix %t " + + "--remote-dir '{0}'%t ".format(remote_tmp_dir) + + "{0} ".format(' '.join(remote_run_extra_args)) + + "{0}".format(remote_run_host)) config.target_swift_reflection_test = os.path.join( remote_tmp_dir, 'bin', swift_reflection_test_name) - TARGET_ENV_PREFIX = 'REMOTE_RUN_CHILD_' config.available_features.add('remote_run') -config.substitutions.append(('%env-', TARGET_ENV_PREFIX)) +# Different OS's require different prefixes for the environment variables to be +# propagated to the calling contexts. +# In order to make tests OS-agnostic, names of environment variables should be +# prefixed with `%env-`, which is then expanded to the appropriate prefix. +config.substitutions.append(('%env-', config.target_env_prefix)) + config.substitutions.append(("%target-sdk-name", config.target_sdk_name)) simulator_sdks = [ @@ -2080,42 +2120,40 @@ if 'concurrency' in config.available_features: else: config.available_features.add('concurrency_runtime') -# Set up testing with the standard libraries coming from the OS / just-built libraries -# default Swift tests to use the just-built libraries -target_stdlib_path = platform_dylib_dir -if not kIsWindows: - libdispatch_path = getattr(config, 'libdispatch_artifact_dir', '') - if 'use_os_stdlib' not in lit_config.params: - if run_os == 'maccatalyst': - # Under macCatalyst we need to have the unzippered twin dylib dir come before - # the zippered/macosx dylib dir so that unzippered twins are picked upload_dylibs - # before the macOS variant. - target_stdlib_path = "{0}:{1}".format(platform_module_dir, target_stdlib_path) - lit_config.note('Testing with the just-built libraries at ' + target_stdlib_path) - config.target_run = ( - "/usr/bin/env " - "DYLD_LIBRARY_PATH='{0}' " # Apple option - "LD_LIBRARY_PATH='{0}:{1}' " # Linux option - "SIMCTL_CHILD_DYLD_LIBRARY_PATH='{0}' " # Simulator option - .format(target_stdlib_path, libdispatch_path)) + config.target_run - else: - config.available_features.add('use_os_stdlib') - os_stdlib_path = '' - if run_vendor == 'apple': - #If we get swift-in-the-OS for non-Apple platforms, add a condition here - os_stdlib_path = "/usr/lib/swift" - if run_os == 'maccatalyst': - os_stdlib_path = "/System/iOSSupport/usr/lib/swift:/usr/lib/swift" - - all_stdlib_path = os.path.pathsep.join((os_stdlib_path, concurrency_back_deploy_path, target_stdlib_path)) - - lit_config.note('Testing with the standard libraries coming from the OS ' + all_stdlib_path) - config.target_run = ( - "/usr/bin/env " - "DYLD_LIBRARY_PATH='{0}' " # Apple option - "LD_LIBRARY_PATH='{0}:{1}' " # Linux option - "SIMCTL_CHILD_DYLD_LIBRARY_PATH='{0}' " # Simulator option - .format(all_stdlib_path, libdispatch_path)) + config.target_run +# Set up testing with the standard libraries coming from either the OS, the back +# deployment runtime or the just-built libraries. By default, we run tests with +# the just-built libraries. +target_stdlib_path = [platform_dylib_dir] +if run_os == 'maccatalyst': + # Under macCatalyst we need to have the unzippered twin dylib dir come before + # the zippered/macosx dylib dir so that unzippered twins are picked upload_dylibs + # before the macOS variant. + target_stdlib_path = [platform_module_dir, platform_dylib_dir] + +if run_vendor != 'apple': + libdispatch_path = getattr(config, 'libdispatch_artifact_dir', None) + if libdispatch_path is not None: + target_stdlib_path.append(libdispatch_path) + +if 'remote-run-host' in lit_config.params: + configure_remote_run() +elif not kIsWindows and not run_os == 'wasi': + if 'use_os_stdlib' in lit_config.params: + config.available_features.add('use_os_stdlib') + + target_stdlib_path = os_stdlib_paths() + [concurrency_back_deploy_path] + target_stdlib_path + + lit_config.note('Testing with the standard libraries in the OS') + elif 'back_deployment_runtime' in lit_config.params: + lit_config.note('Testing with back deployment runtime libraries') + else: + lit_config.note('Testing with the just-built libraries') + + lit_config.note('Library load path: {0}'.format(os.path.pathsep.join(target_stdlib_path))) + config.target_run = ( + "/usr/bin/env " + + construct_library_path_env(target_stdlib_path) + + config.target_run) # When running with the JIT on Darwin, force the usage of the just built stdlib # when running the frontend. This is because we currently JIT in process @@ -2442,7 +2480,7 @@ config.substitutions.append(('%import-static-libdispatch', getattr(config, 'impo config.environment['SWIFT_DEBUG_ENABLE_COW_CHECKS'] = 'false' # Add this to the command which runs an executable to enable COW checks in the swift runtime. -config.substitutions.append(('%enable-cow-checking', TARGET_ENV_PREFIX + 'SWIFT_DEBUG_ENABLE_COW_CHECKS=true;')) +config.substitutions.append(('%enable-cow-checking', config.target_env_prefix + 'SWIFT_DEBUG_ENABLE_COW_CHECKS=true;')) # We add an expansion to ensure that migrator tests can search for the api diff # data dir from the host compiler toolchain instead of the resource dir of the @@ -2477,10 +2515,10 @@ if config.lldb_build_root != "": # Disable randomized hash seeding by default. Tests need to manually opt in to # random seeds by unsetting the SWIFT_DETERMINISTIC_HASHING environment # variable. -config.environment[TARGET_ENV_PREFIX + 'SWIFT_DETERMINISTIC_HASHING'] = '1' +config.environment[config.target_env_prefix + 'SWIFT_DETERMINISTIC_HASHING'] = '1' # Enable malloc scribble during tests by default. -config.environment[TARGET_ENV_PREFIX + 'SWIFT_DEBUG_ENABLE_MALLOC_SCRIBBLE'] = 'YES' +config.environment[config.target_env_prefix + 'SWIFT_DEBUG_ENABLE_MALLOC_SCRIBBLE'] = 'YES' # Run lsb_release on the target to be tested and return the results. def linux_get_lsb_release(): diff --git a/test/type/parameterized_protocol.swift b/test/type/parameterized_protocol.swift index 9d9e70723162e..8e270633d54a3 100644 --- a/test/type/parameterized_protocol.swift +++ b/test/type/parameterized_protocol.swift @@ -24,6 +24,12 @@ protocol Sequence { // expected-note@-1 {{protocol requires nested type 'Element'; do you want to add it?}} } +extension Sequence { + func map(_ transform: (Self.Element) -> Other) -> ConcreteSequence { + return ConcreteSequence() + } +} + struct ConcreteSequence : Sequence {} protocol EquatableSequence {} @@ -158,10 +164,8 @@ func returnsSequenceOfInt1() -> Sequence {} // expected-error@-1 {{protocol type with generic arguments can only be used as a generic constraint}} func takesSequenceOfInt2(_: any Sequence) {} -// expected-error@-1 {{protocol type with generic arguments can only be used as a generic constraint}} func returnsSequenceOfInt2() -> any Sequence {} -// expected-error@-1 {{protocol type with generic arguments can only be used as a generic constraint}} func typeExpr() { _ = Sequence.self @@ -175,3 +179,45 @@ protocol SomeProto {} func protocolCompositionNotSupported(_: SomeProto & Sequence) {} // expected-error@-1 {{non-protocol, non-class type 'Sequence' cannot be used within a protocol-constrained type}} +protocol DoubleWide { + var x: X { get } + var y: Y { get } +} + +extension Int: DoubleWide { + typealias X = Int + typealias Y = Int + var x: X { 0 } + var y: X { 0 } +} + +struct Collapse: DoubleWide { + typealias X = T + typealias Y = T + + var x: X + var y: X { self.x } +} + +func test() -> any DoubleWide, some DoubleWide> { return Collapse(x: 42) } + +func diagonalizeAny(_ x: any Sequence) -> any Sequence<(Int, Int)> { + return x.map { ($0, $0) } +} + +func erase(_ x: ConcreteSequence) -> any Sequence { + return x as any Sequence +} + +protocol Sponge {} + +func saturation(_ dry: any Sponge, _ wet: any Sponge) { + _ = dry as any Sponge + // expected-error@-1 {{'any Sponge' is not convertible to 'any Sponge'}} + // expected-note@-2 {{did you mean to use 'as!' to force downcast?}} + _ = dry as any Sponge + + _ = wet as any Sponge // Ok + _ = wet as any Sponge // Ok + _ = wet as any Sponge // expected-error {{cannot convert value of type 'any Sponge' to type 'any Sponge' in coercion}} +} diff --git a/test/type/subclass_composition.swift b/test/type/subclass_composition.swift index cc84e47e41830..658e7f38c58c6 100644 --- a/test/type/subclass_composition.swift +++ b/test/type/subclass_composition.swift @@ -46,30 +46,29 @@ struct Unrelated {} // // If a class conforms to a protocol concretely, the resulting protocol -// composition type should be equivalent to the class type. -// -// FIXME: Disabled for now. +// composition type should be equivalent to the class type for redeclaration +// checking purposes. // -func alreadyConforms(_: Base) {} // expected-note {{'alreadyConforms' previously declared here}} -func alreadyConforms(_: Base & P1) {} // FIXME e/xpected-error {{invalid redeclaration of 'alreadyConforms'}} expected-note {{'alreadyConforms' previously declared here}} +func alreadyConforms(_: Base) {} // expected-note 3 {{'alreadyConforms' previously declared here}} +func alreadyConforms(_: Base & P1) {} // expected-error {{invalid redeclaration of 'alreadyConforms'}} func alreadyConforms(_: Base & AnyObject) {} // expected-error {{invalid redeclaration of 'alreadyConforms'}} func alreadyConforms(_: Base & P1 & AnyObject) {} // expected-error {{invalid redeclaration of 'alreadyConforms'}} -func alreadyConformsMeta(_: Base.Type) {} // expected-note {{'alreadyConformsMeta' previously declared here}} -func alreadyConformsMeta(_: (Base & P1).Type) {} // FIXME e/xpected-error {{invalid redeclaration of 'alreadyConformsMeta'}} expected-note {{'alreadyConformsMeta' previously declared here}} -func alreadyConformsMeta(_: (Base & P1).Protocol) {} // FIXME e/xpected-error {{invalid redeclaration of 'alreadyConformsMeta'}} expected-note 3 {{'alreadyConformsMeta' previously declared here}} +func alreadyConformsMeta(_: Base.Type) {} // expected-note 7 {{'alreadyConformsMeta' previously declared here}} +func alreadyConformsMeta(_: (Base & P1).Type) {} // expected-error {{invalid redeclaration of 'alreadyConformsMeta'}} +func alreadyConformsMeta(_: (Base & P1).Protocol) {} // expected-error {{invalid redeclaration of 'alreadyConformsMeta'}} func alreadyConformsMeta(_: (any Base & P1).Type) {} // expected-error {{invalid redeclaration of 'alreadyConformsMeta'}} func alreadyConformsMeta(_: (Base & AnyObject).Type) {} // expected-error {{invalid redeclaration of 'alreadyConformsMeta'}} func alreadyConformsMeta(_: (Base & P1 & AnyObject).Type) {} // expected-error {{invalid redeclaration of 'alreadyConformsMeta'}} func alreadyConformsMeta(_: (Base & P1 & AnyObject).Protocol) {} // expected-error {{invalid redeclaration of 'alreadyConformsMeta'}} func alreadyConformsMeta(_: (any Base & P1 & AnyObject).Type) {} // expected-error {{invalid redeclaration of 'alreadyConformsMeta'}} -func alreadyConforms(_: P3) {} // e/xpected-note {{'alreadyConforms' previously declared here}} -func alreadyConforms(_: P3 & AnyObject) {} // FIXME e/xpected-error {{invalid redeclaration of 'alreadyConforms'}} +func alreadyConforms(_: P3) {} // expected-note {{'alreadyConforms' previously declared here}} +func alreadyConforms(_: P3 & AnyObject) {} // expected-error {{invalid redeclaration of 'alreadyConforms'}} -func alreadyConformsMeta(_: P3.Type) {} // FIXME e/xpected-note {{'alreadyConformsMeta' previously declared here}} -func alreadyConformsMeta(_: (P3 & AnyObject).Type) {} // FIXME ex/pected-error {{invalid redeclaration of 'alreadyConformsMeta'}} +func alreadyConformsMeta(_: P3.Type) {} // expected-note {{'alreadyConformsMeta' previously declared here}} +func alreadyConformsMeta(_: (P3 & AnyObject).Type) {} // expected-error {{invalid redeclaration of 'alreadyConformsMeta'}} // SE-0156 stipulates that a composition can contain multiple classes, as long // as they are all the same. diff --git a/tools/swift-inspect/Sources/swift-inspect/Backtrace.swift b/tools/swift-inspect/Sources/swift-inspect/Backtrace.swift index 4142ce925a213..bcd18a0db4bbb 100644 --- a/tools/swift-inspect/Sources/swift-inspect/Backtrace.swift +++ b/tools/swift-inspect/Sources/swift-inspect/Backtrace.swift @@ -20,7 +20,7 @@ internal enum BacktraceStyle { internal func backtrace(_ stack: [swift_reflection_ptr_t], style: BacktraceStyle, _ symbolicate: (swift_addr_t) -> (module: String?, symbol: String?)) -> String { func entry(_ address: swift_reflection_ptr_t) -> String { - let (module, symbol) = symbolicate(address) + let (module, symbol) = symbolicate(swift_addr_t(address)) return "\(hex: address) (\(module ?? "")) \(symbol ?? "")" } diff --git a/tools/swift-inspect/Sources/swift-inspect/RemoteMirror+Extensions.swift b/tools/swift-inspect/Sources/swift-inspect/RemoteMirror+Extensions.swift index 9da0ea2a3f971..eabdc29da4931 100644 --- a/tools/swift-inspect/Sources/swift-inspect/RemoteMirror+Extensions.swift +++ b/tools/swift-inspect/Sources/swift-inspect/RemoteMirror+Extensions.swift @@ -65,7 +65,7 @@ extension SwiftReflectionContextRef { } internal func name(type: swift_reflection_ptr_t) -> String? { - let typeref: UInt64 = swift_reflection_typeRefForMetadata(self, UInt(type)) + let typeref = swift_reflection_typeRefForMetadata(self, UInt(type)) if typeref == 0 { return nil } guard let name = swift_reflection_copyDemangledNameForTypeRef(self, typeref) else { @@ -97,7 +97,7 @@ extension SwiftReflectionContextRef { internal func isArrayOfClass(_ array: swift_reflection_ptr_t) -> Bool { guard isContiguousArray(array) else { return false } - let typeref: UInt64 = swift_reflection_typeRefForMetadata(self, UInt(array)) + let typeref = swift_reflection_typeRefForMetadata(self, UInt(array)) if typeref == 0 { return false } let count = swift_reflection_genericArgumentCountOfTypeRef(typeref) diff --git a/utils/build-presets.ini b/utils/build-presets.ini index 71be70733273d..8a4091acff347 100644 --- a/utils/build-presets.ini +++ b/utils/build-presets.ini @@ -2400,7 +2400,7 @@ native-llvm-tools-path=%(toolchain_path)s native-clang-tools-path=%(toolchain_path)s build-ninja -lit-args=--filter=stdlib/ -v +lit-args=--filter=':: stdlib/' -v only-executable-test [preset: stdlib_RD_standalone,build] @@ -2528,6 +2528,7 @@ swift-stdlib-has-environ=0 swift-stdlib-has-locale=0 swift-runtime-static-image-inspection=1 swift-stdlib-single-threaded-runtime=1 +swift-stdlib-concurrency-tracing=0 swift-stdlib-os-versioning=0 swift-stdlib-has-commandline=0 swift-stdlib-lto=full diff --git a/utils/build-script-impl b/utils/build-script-impl index 70bb5db2ef4ff..bb752f242c10a 100755 --- a/utils/build-script-impl +++ b/utils/build-script-impl @@ -210,6 +210,7 @@ KNOWN_SETTINGS=( swift-stdlib-supports-backtrace-reporting "" "whether to build stdlib assuming the runtime environment provides the backtrace(3) API, if not set defaults to true on all platforms except for Cygwin, Haiku and wasm" swift-runtime-static-image-inspection "0" "whether to build stdlib assuming the runtime environment only supports a single runtime image with Swift code" swift-stdlib-single-threaded-runtime "0" "whether to build stdlib as a single-threaded runtime only" + swift-stdlib-concurrency-tracing "" "whether to enable tracing signposts for concurrency; default is 1 on Darwin platforms, 0 otherwise" swift-stdlib-os-versioning "1" "whether to build stdlib with availability based on OS versions (Darwin only)" swift-stdlib-has-commandline "1" "whether to build stdlib with the CommandLine enum and support for argv/argc" swift-stdlib-stable-abi "" "should stdlib be built with stable ABI, if not set defaults to true on Darwin, false otherwise" @@ -2229,6 +2230,13 @@ for host in "${ALL_HOSTS[@]}"; do ) fi + if [[ "${SWIFT_STDLIB_CONCURRENCY_TRACING}" ]] ; then + cmake_options=( + "${cmake_options[@]}" + -DSWIFT_STDLIB_CONCURRENCY_TRACING:BOOL=$(true_false "${SWIFT_STDLIB_CONCURRENCY_TRACING}") + ) + fi + build_targets=(all "${SWIFT_STDLIB_TARGETS[@]}") if [[ $(true_false "${build_perf_testsuite_this_time}") == "TRUE" ]]; then native_swift_tools_path="$(build_directory_bin ${LOCAL_HOST} swift)" diff --git a/utils/check-incremental b/utils/check-incremental index 2bcdb29f127ea..551ac6a8b829a 100755 --- a/utils/check-incremental +++ b/utils/check-incremental @@ -35,7 +35,8 @@ def compile_and_stat(compile_args, output_file): """ subprocess.check_call(compile_args) - md5 = subprocess.check_output(["md5", "-q", output_file], text=True) + md5 = subprocess.check_output(["md5", "-q", output_file], + universal_newlines=True) mtime = time.ctime(os.path.getmtime(output_file)) if VERBOSE: diff --git a/utils/refactor-check-compiles.py b/utils/refactor-check-compiles.py index 9d14f8f7d4bcb..b2912f725164e 100755 --- a/utils/refactor-check-compiles.py +++ b/utils/refactor-check-compiles.py @@ -9,7 +9,7 @@ def run_cmd(cmd, desc): try: - return subprocess.check_output(cmd) + return subprocess.check_output(cmd, universal_newlines=True) except subprocess.CalledProcessError: print('FAILED ' + desc + ':', file=sys.stderr) print(' '.join(cmd), file=sys.stderr) @@ -130,7 +130,7 @@ def main(): '-source-filename', args.source_filename, '-rewritten-output-file', temp_file_path, '-pos', args.pos - ] + extra_refactor_args + extra_both_args, desc='producing edit').decode("utf-8") + ] + extra_refactor_args + extra_both_args, desc='producing edit') sys.stdout.write(dump_text_output) run_cmd([ diff --git a/utils/swift-darwin-postprocess.py b/utils/swift-darwin-postprocess.py index 4076137a2f782..2be9232e2beeb 100755 --- a/utils/swift-darwin-postprocess.py +++ b/utils/swift-darwin-postprocess.py @@ -32,7 +32,8 @@ def main(arguments): # (rdar://78851265) def unrpathize(filename): dylibsOutput = subprocess.check_output( - ['xcrun', 'dyldinfo', '-dylibs', filename]) + ['xcrun', 'dyldinfo', '-dylibs', filename], + universal_newlines=True) # Do not rewrite @rpath-relative load commands for these libraries: # they are test support libraries that are never installed under @@ -60,8 +61,7 @@ def unrpathize(filename): # Build a command to invoke install_name_tool. command = ['install_name_tool'] - for binaryline in dylibsOutput.splitlines(): - line = binaryline.decode("utf-8", "strict") + for line in dylibsOutput.splitlines(): match = dylib_regex.match(line) if match and match.group('filename') not in allow_list: command.append('-change') diff --git a/utils/swift-rpathize.py b/utils/swift-rpathize.py index 72a684797f15f..8c310697f1b41 100755 --- a/utils/swift-rpathize.py +++ b/utils/swift-rpathize.py @@ -55,7 +55,8 @@ def main(arguments): def rpathize(filename): dylibsOutput = subprocess.check_output( - ['xcrun', 'dyldinfo', '-dylibs', filename]) + ['xcrun', 'dyldinfo', '-dylibs', filename], + universal_newlines=True) # The output from dyldinfo -dylibs is a line of header followed by one # install name per line, indented with spaces. @@ -64,8 +65,7 @@ def rpathize(filename): # Build a command to invoke install_name_tool. command = ['install_name_tool'] - for binaryline in dylibsOutput.splitlines(): - line = binaryline.decode("utf-8", "strict") + for line in dylibsOutput.splitlines(): match = dylib_regex.match(line) if match: command.append('-change') diff --git a/utils/swift_build_support/swift_build_support/shell.py b/utils/swift_build_support/swift_build_support/shell.py index 32c39811aa06f..4c529440f420c 100644 --- a/utils/swift_build_support/swift_build_support/shell.py +++ b/utils/swift_build_support/swift_build_support/shell.py @@ -132,12 +132,11 @@ def capture(command, stderr=None, env=None, dry_run=None, echo=True, _env = dict(os.environ) _env.update(env) try: - out = subprocess.check_output(command, env=_env, stderr=stderr) - # Coerce to `str` hack. not py3 `byte`, not py2 `unicode`. - return str(out.decode()) + return subprocess.check_output(command, env=_env, stderr=stderr, + universal_newlines=True) except subprocess.CalledProcessError as e: if allow_non_zero_exit: - return str(e.output.decode()) + return e.output if optional: return None _fatal_error( @@ -213,25 +212,29 @@ def run(*args, **kwargs): echo_output = kwargs.pop('echo', False) dry_run = kwargs.pop('dry_run', False) env = kwargs.pop('env', None) + prefix = kwargs.pop('prefix', '') if dry_run: - _echo_command(dry_run, *args, env=env) + _echo_command(dry_run, *args, env=env, prompt="{0}+ ".format(prefix)) return(None, 0, args) my_pipe = subprocess.Popen( - *args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs) - (stdout, stderr) = my_pipe.communicate() + *args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, + universal_newlines=True, + **kwargs) + (output, _) = my_pipe.communicate() ret = my_pipe.wait() if lock: lock.acquire() if echo_output: - print(repo_path) - _echo_command(dry_run, *args, env=env) - if stdout: - print(stdout, end="") - if stderr: - print(stderr, end="") - print() + sys.stdout.flush() + sys.stderr.flush() + _echo_command(dry_run, *args, env=env, prompt="{0}+ ".format(prefix)) + if output: + for line in output.splitlines(): + print("{0}{1}".format(prefix, line)) + sys.stdout.flush() + sys.stderr.flush() if lock: lock.release() @@ -240,6 +243,6 @@ def run(*args, **kwargs): eout.ret = ret eout.args = args eout.repo_path = repo_path - eout.stderr = stderr + eout.stderr = output raise eout - return (stdout, 0, args) + return (output, 0, args) diff --git a/utils/update_checkout/update_checkout/update_checkout.py b/utils/update_checkout/update_checkout/update_checkout.py index 2b9e859999f85..e064d4d5342e7 100755 --- a/utils/update_checkout/update_checkout/update_checkout.py +++ b/utils/update_checkout/update_checkout/update_checkout.py @@ -70,7 +70,7 @@ def check_parallel_results(results, op): print("%s failed (ret=%d): %s" % (r.repo_path, r.ret, r)) fail_count += 1 if r.stderr: - print(r.stderr.decode('utf-8')) + print(r.stderr) return fail_count @@ -125,7 +125,9 @@ def update_single_repository(pool_args): return try: - print("Updating '" + repo_path + "'") + prefix = "[{0}] ".format(os.path.basename(repo_path)).ljust(40) + print(prefix + "Updating '" + repo_path + "'") + with shell.pushd(repo_path, dry_run=False, echo=False): cross_repo = False checkout_target = None @@ -141,15 +143,20 @@ def update_single_repository(pool_args): # The clean option restores a repository to pristine condition. if should_clean: - shell.run(['git', 'clean', '-fdx'], echo=True) - shell.run(['git', 'submodule', 'foreach', '--recursive', 'git', - 'clean', '-fdx'], echo=True) - shell.run(['git', 'submodule', 'foreach', '--recursive', 'git', - 'reset', '--hard', 'HEAD'], echo=True) - shell.run(['git', 'reset', '--hard', 'HEAD'], echo=True) + shell.run(['git', 'clean', '-fdx'], + echo=True, prefix=prefix) + shell.run(['git', 'submodule', 'foreach', '--recursive', + 'git', 'clean', '-fdx'], + echo=True, prefix=prefix) + shell.run(['git', 'submodule', 'foreach', '--recursive', + 'git', 'reset', '--hard', 'HEAD'], + echo=True, prefix=prefix) + shell.run(['git', 'reset', '--hard', 'HEAD'], + echo=True, prefix=prefix) # It is possible to reset --hard and still be mid-rebase. try: - shell.run(['git', 'rebase', '--abort'], echo=True) + shell.run(['git', 'rebase', '--abort'], + echo=True, prefix=prefix) except Exception: pass @@ -166,15 +173,17 @@ def update_single_repository(pool_args): except Exception: shell.run(["git", "fetch", "--recurse-submodules=yes", "--tags"], - echo=True) + echo=True, prefix=prefix) try: - shell.run(['git', 'checkout', checkout_target], echo=True) + shell.run(['git', 'checkout', checkout_target], + echo=True, prefix=prefix) except Exception as originalException: try: result = shell.run(['git', 'rev-parse', checkout_target]) revision = result[0].strip() - shell.run(['git', 'checkout', revision], echo=True) + shell.run(['git', 'checkout', revision], + echo=True, prefix=prefix) except Exception: raise originalException @@ -182,13 +191,14 @@ def update_single_repository(pool_args): # .git/FETCH_HEAD updates the not-for-merge attributes based on # which branch was checked out during the fetch. shell.run(["git", "fetch", "--recurse-submodules=yes", "--tags"], - echo=True) + echo=True, prefix=prefix) # If we were asked to reset to the specified branch, do the hard # reset and return. if checkout_target and reset_to_remote and not cross_repo: full_target = full_target_name('origin', checkout_target) - shell.run(['git', 'reset', '--hard', full_target], echo=True) + shell.run(['git', 'reset', '--hard', full_target], + echo=True, prefix=prefix) return # Query whether we have a "detached HEAD", which will mean that @@ -215,13 +225,15 @@ def update_single_repository(pool_args): # --rebase" that respects rebase.autostash. See # http://stackoverflow.com/a/30209750/125349 if not cross_repo and not detached_head: - shell.run(["git", "rebase", "FETCH_HEAD"], echo=True) + shell.run(["git", "rebase", "FETCH_HEAD"], + echo=True, prefix=prefix) elif detached_head: - print(repo_path, - "\nDetached HEAD; probably checked out a tag. No need " - "to rebase.\n") + print(prefix + + "Detached HEAD; probably checked out a tag. No need " + "to rebase.") - shell.run(["git", "submodule", "update", "--recursive"], echo=True) + shell.run(["git", "submodule", "update", "--recursive"], + echo=True, prefix=prefix) except Exception: (type, value, tb) = sys.exc_info() print('Error on repo "%s": %s' % (repo_path, traceback.format_exc())) @@ -431,12 +443,12 @@ def validate_config(config): def full_target_name(repository, target): - tag = shell.capture(["git", "tag", "-l", target], echo=True).strip() + tag = shell.capture(["git", "tag", "-l", target], echo=False).strip() if tag == target: return tag branch = shell.capture(["git", "branch", "--list", target], - echo=True).strip().replace("* ", "") + echo=False).strip().replace("* ", "") if branch == target: name = "%s/%s" % (repository, target) return name diff --git a/validation-test/SIL/crashers_fixed/005-swift-silfunction-verify.sil b/validation-test/SIL/crashers_fixed/005-swift-silfunction-verify.sil index 0dc738830e0f0..3d442e6b23988 100644 --- a/validation-test/SIL/crashers_fixed/005-swift-silfunction-verify.sil +++ b/validation-test/SIL/crashers_fixed/005-swift-silfunction-verify.sil @@ -1,2 +1,2 @@ // RUN: %target-sil-opt %s -sil shared_external@a:$()->() +sil public_external@a:$()->() diff --git a/validation-test/Sema/wmo_verify_loaded.swift b/validation-test/Sema/wmo_verify_loaded.swift index c8ccc5f82a234..9db52976988e7 100644 --- a/validation-test/Sema/wmo_verify_loaded.swift +++ b/validation-test/Sema/wmo_verify_loaded.swift @@ -20,7 +20,7 @@ extension Notification.Name {} // NSPasteboardType.init(rawValue:) // - just make sure it has a body. -// CHECK-LABEL: sil shared [transparent] [serializable] [ossa] @$sSo16NSPasteboardTypea8rawValueABSS_tcfC : $@convention(method) (@owned String, @thin NSPasteboard.PasteboardType.Type) -> @owned NSPasteboard.PasteboardType { +// CHECK-LABEL: sil shared [transparent] [serialized] [ossa] @$sSo16NSPasteboardTypea8rawValueABSS_tcfC : $@convention(method) (@owned String, @thin NSPasteboard.PasteboardType.Type) -> @owned NSPasteboard.PasteboardType { // CHECK: bb0(%0 : @owned $String, %1 : $@thin NSPasteboard.PasteboardType.Type): // CHECK: return %{{.*}} : $NSPasteboard.PasteboardType // CHECK-LABEL: } // end sil function '$sSo16NSPasteboardTypea8rawValueABSS_tcfC' diff --git a/validation-test/compiler_crashers_2/unsupported_recursive_opaque_conformance.swift b/validation-test/compiler_crashers_2/unsupported_recursive_opaque_conformance.swift new file mode 100644 index 0000000000000..58f10d25472ca --- /dev/null +++ b/validation-test/compiler_crashers_2/unsupported_recursive_opaque_conformance.swift @@ -0,0 +1,25 @@ +// RUN: not --crash %target-swift-frontend -disable-availability-checking -emit-ir -enable-parameterized-protocol-types %s + +// REQUIRES: asserts + +protocol P { + var x: X { get } + var y: Y { get } +} + +extension Int: P { + typealias X = Int + typealias Y = Int + var x: X { 0 } + var y: X { 0 } +} + +struct Foo: P { + typealias X = T + typealias Y = T + + var x: X + var y: X { self.x } +} + +func test() -> any P, some P> { return Foo(x: 42) } diff --git a/validation-test/compiler_crashers_2_fixed/0189-sr10033.swift b/validation-test/compiler_crashers_2_fixed/0189-sr10033.swift index d799d00c1503d..6c7ccbf5eb582 100644 --- a/validation-test/compiler_crashers_2_fixed/0189-sr10033.swift +++ b/validation-test/compiler_crashers_2_fixed/0189-sr10033.swift @@ -15,9 +15,9 @@ extension P2 { } class C1 : P1 { -// expected-warning@-1 {{non-final class 'C1' cannot safely conform to protocol 'P1', which requires that 'Self' is exactly equal to 'Self.A2.A1'; this is an error in Swift 6}} +// expected-warning@-1 {{non-final class 'C1' cannot safely conform to protocol 'P1', which requires that 'Self.A2.A1' is exactly equal to 'Self'; this is an error in Swift 6}} class A2 : P2 { - // expected-warning@-1 {{non-final class 'C1.A2' cannot safely conform to protocol 'P2', which requires that 'Self' is exactly equal to 'Self.A1.A2'; this is an error in Swift 6}} + // expected-warning@-1 {{non-final class 'C1.A2' cannot safely conform to protocol 'P2', which requires that 'Self.A1.A2' is exactly equal to 'Self'; this is an error in Swift 6}} typealias A1 = C1 } } diff --git a/validation-test/stdlib/ArrayTrapsObjC.swift b/validation-test/stdlib/ArrayTrapsObjC.swift index f6b8af5d1e735..0bbf644ffe019 100644 --- a/validation-test/stdlib/ArrayTrapsObjC.swift +++ b/validation-test/stdlib/ArrayTrapsObjC.swift @@ -4,6 +4,9 @@ // REQUIRES: executable_test // REQUIRES: objc_interop +// Temporarily disable for backdeployment (rdar://89821303) +// UNSUPPORTED: use_os_stdlib + import StdlibUnittest import Foundation