diff --git a/docs/ABI/Mangling.rst b/docs/ABI/Mangling.rst index b8097b84ae5..51be48a85fd 100644 --- a/docs/ABI/Mangling.rst +++ b/docs/ABI/Mangling.rst @@ -365,7 +365,6 @@ Entities entity-spec ::= 'fP' // property wrapper backing initializer entity-spec ::= 'fW' // property wrapper init from projected value entity-spec ::= 'fD' // deallocating destructor; untyped - entity-spec ::= 'fZ' // isolated deallocating destructor; untyped entity-spec ::= 'fd' // non-deallocating destructor; untyped entity-spec ::= 'fE' // ivar destroyer; untyped entity-spec ::= 'fe' // ivar initializer; untyped diff --git a/include/swift/ABI/Executor.h b/include/swift/ABI/Executor.h index cfb94f04d68..2e2b43cbbb9 100644 --- a/include/swift/ABI/Executor.h +++ b/include/swift/ABI/Executor.h @@ -295,7 +295,6 @@ using ThrowingTaskFutureWaitContinuationFunction = SWIFT_CC(swiftasync) void (SWIFT_ASYNC_CONTEXT AsyncContext *, SWIFT_CONTEXT void *); -using DeinitWorkFunction = SWIFT_CC(swift) void(void *); template class AsyncFunctionPointer; diff --git a/include/swift/ABI/MetadataValues.h b/include/swift/ABI/MetadataValues.h index f350a24e11b..5e271adfeb8 100644 --- a/include/swift/ABI/MetadataValues.h +++ b/include/swift/ABI/MetadataValues.h @@ -2490,8 +2490,7 @@ enum class JobKind : size_t { DefaultActorInline = First_Reserved, DefaultActorSeparate, DefaultActorOverride, - NullaryContinuation, - IsolatedDeinit, + NullaryContinuation }; /// The priority of a job. Higher priorities are larger values. diff --git a/include/swift/AST/ASTMangler.h b/include/swift/AST/ASTMangler.h index 98aa335f278..89d29372862 100644 --- a/include/swift/AST/ASTMangler.h +++ b/include/swift/AST/ASTMangler.h @@ -34,12 +34,6 @@ class RootProtocolConformance; namespace Mangle { -enum class DestructorKind { - NonDeallocating, - Deallocating, - IsolatedDeallocating -}; - /// The mangler for AST declarations. class ASTMangler : public Mangler { protected: @@ -211,7 +205,7 @@ public: SymbolKind SKind = SymbolKind::Default); std::string mangleDestructorEntity(const DestructorDecl *decl, - DestructorKind kind, + bool isDeallocating, SymbolKind SKind = SymbolKind::Default); std::string mangleConstructorEntity(const ConstructorDecl *ctor, @@ -709,8 +703,8 @@ protected: bool tryAppendStandardSubstitution(const GenericTypeDecl *type); void appendConstructorEntity(const ConstructorDecl *ctor, bool isAllocating); - - void appendDestructorEntity(const DestructorDecl *decl, DestructorKind kind); + + void appendDestructorEntity(const DestructorDecl *decl, bool isDeallocating); /// \param accessorKindCode The code to describe the accessor and addressor /// kind. Usually retrieved using getCodeForAccessorKind. diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h index 4dbf50ef518..85922459eba 100644 --- a/include/swift/AST/Decl.h +++ b/include/swift/AST/Decl.h @@ -1368,10 +1368,6 @@ public: std::optional> getGlobalActorAttr() const; - /// Determine whether there is an explicit isolation attribute - /// of any kind. - bool hasExplicitIsolationAttribute() const; - /// If an alternative module name is specified for this decl, e.g. using /// @_originalDefinedIn attribute, this function returns this module name. StringRef getAlternateModuleName() const; @@ -3147,10 +3143,6 @@ public: /// Retrieve the declaration that this declaration overrides, if any. ValueDecl *getOverriddenDecl() const; - /// Retrieve the declaration that this declaration overrides, including super - /// deinit. - ValueDecl *getOverriddenDeclOrSuperDeinit() const; - /// Retrieve the declarations that this declaration overrides, if any. llvm::TinyPtrVector getOverriddenDecls() const; @@ -8915,10 +8907,6 @@ public: /// Retrieve the Objective-C selector for destructors. ObjCSelector getObjCSelector() const; - /// Retrieves destructor decl from the superclass, or nil if there is no - /// superclass - DestructorDecl *getSuperDeinit() const; - static bool classof(const Decl *D) { return D->getKind() == DeclKind::Destructor; } diff --git a/include/swift/AST/DeclAttr.def b/include/swift/AST/DeclAttr.def index 132efc5390c..5afb3e32b6f 100644 --- a/include/swift/AST/DeclAttr.def +++ b/include/swift/AST/DeclAttr.def @@ -434,9 +434,6 @@ SIMPLE_DECL_ATTR(rethrows, Rethrows, CONTEXTUAL_SIMPLE_DECL_ATTR(indirect, Indirect, DeclModifier | OnEnum | OnEnumElement | ABIBreakingToAdd | ABIBreakingToRemove | APIStableToAdd | APIStableToRemove, 60) -CONTEXTUAL_SIMPLE_DECL_ATTR(isolated, Isolated, - DeclModifier | OnDestructor | ABIBreakingToAdd | ABIBreakingToRemove | APIBreakingToAdd | APIBreakingToRemove, - 103) CONTEXTUAL_SIMPLE_DECL_ATTR(async, Async, DeclModifier | OnVar | OnFunc | ABIBreakingToAdd | ABIBreakingToRemove | APIBreakingToAdd | APIBreakingToRemove, 106) @@ -444,7 +441,7 @@ SIMPLE_DECL_ATTR(reasync, Reasync, OnFunc | OnConstructor | RejectByParser | ABIBreakingToAdd | ABIBreakingToRemove | APIBreakingToAdd | APIBreakingToRemove, 109) CONTEXTUAL_DECL_ATTR(nonisolated, Nonisolated, - DeclModifier | OnFunc | OnConstructor | OnDestructor | OnVar | OnSubscript | ABIStableToAdd | ABIStableToRemove | APIBreakingToAdd | APIStableToRemove, + DeclModifier | OnFunc | OnConstructor | OnVar | OnSubscript | ABIStableToAdd | ABIStableToRemove | APIBreakingToAdd | APIStableToRemove, 112) CONTEXTUAL_SIMPLE_DECL_ATTR(distributed, DistributedActor, DeclModifier | OnClass | OnFunc | OnAccessor | OnVar | ABIBreakingToAdd | ABIBreakingToRemove | APIBreakingToAdd | APIBreakingToRemove, diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index 68d49a7cfef..a0060db046b 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -5883,12 +5883,9 @@ ERROR(global_actor_not_usable_from_inline,none, NOTE(move_global_actor_attr_to_storage_decl,none, "move global actor attribute to %kind0", (const ValueDecl *)) -ERROR(actor_isolation_multiple_attr_2,none, +ERROR(actor_isolation_multiple_attr,none, "%kind0 has multiple actor-isolation attributes ('%1' and '%2')", (const Decl *, StringRef, StringRef)) -ERROR(actor_isolation_multiple_attr_3,none, - "%0 %1 has multiple actor-isolation attributes ('%2', '%3' and '%4')", - (const Decl *, StringRef, StringRef, StringRef)) ERROR(actor_isolation_override_mismatch,none, "%0 %kind1 has different actor isolation from %2 overridden declaration", (ActorIsolation, const ValueDecl *, ActorIsolation)) @@ -5905,14 +5902,6 @@ ERROR(async_named_decl_must_be_available_from_async,none, ERROR(async_unavailable_decl,none, "%kindbase0 is unavailable from asynchronous contexts%select{|; %1}1", (const ValueDecl *, StringRef)) - - -ERROR(isolated_deinit_no_isolation,none, - "deinit is marked isolated, but containing class %0 is not isolated to an actor", - (DeclName)) -ERROR(isolated_deinit_on_value_type,none, - "only classes and actors can have isolated deinit", - ()) //------------------------------------------------------------------------------ // MARK: String Processing diff --git a/include/swift/AST/PrintOptions.h b/include/swift/AST/PrintOptions.h index a1235708c5e..5d9eff9c612 100644 --- a/include/swift/AST/PrintOptions.h +++ b/include/swift/AST/PrintOptions.h @@ -37,8 +37,6 @@ class DeclContext; class Type; class ModuleDecl; enum class DeclAttrKind : unsigned; -class DeclAttribute; -class CustomAttr; class SynthesizedExtensionAnalyzer; struct PrintOptions; class SILPrintContext; @@ -344,10 +342,6 @@ struct PrintOptions { /// Suppress emitting @available(*, noasync) bool SuppressNoAsyncAvailabilityAttr = false; - /// Suppress emitting isolated or async deinit, and emit open containing class - /// as public - bool SuppressIsolatedDeinit = false; - /// Whether to print the \c{/*not inherited*/} comment on factory initializers. bool PrintFactoryInitializerComment = true; @@ -399,8 +393,6 @@ struct PrintOptions { DeclAttrKind::FixedLayout, DeclAttrKind::ShowInInterface, }; - std::vector ExcludeCustomAttrList = {}; - /// List of attribute kinds that should be printed exclusively. /// Empty means allow all. std::vector ExclusiveAttrList; @@ -635,8 +627,6 @@ struct PrintOptions { return false; } - bool excludeAttr(const DeclAttribute *DA) const; - /// Retrieve the set of options for verbose printing to users. static PrintOptions printVerbose() { PrintOptions result; @@ -692,8 +682,7 @@ struct PrintOptions { result.SkipPrivateSystemDecls = true; result.SkipUnderscoredSystemProtocols = true; result.SkipUnsafeCXXMethods = true; - result.SkipDeinit = false; // Deinit may have isolation attributes, which - // are part of the interface + result.SkipDeinit = true; result.EmptyLineBetweenDecls = true; result.CascadeDocComment = true; result.ShouldQualifyNestedDeclarations = diff --git a/include/swift/Basic/Features.def b/include/swift/Basic/Features.def index 59c94cf70f1..be3a8515216 100644 --- a/include/swift/Basic/Features.def +++ b/include/swift/Basic/Features.def @@ -408,8 +408,6 @@ SUPPRESSIBLE_EXPERIMENTAL_FEATURE(AllowUnsafeAttribute, true) /// Warn on use of unsafe constructs. EXPERIMENTAL_FEATURE(WarnUnsafe, true) -SUPPRESSIBLE_LANGUAGE_FEATURE(IsolatedDeinit, 371, "isolated/async deinit") - #undef EXPERIMENTAL_FEATURE_EXCLUDED_FROM_MODULE_INTERFACE #undef EXPERIMENTAL_FEATURE #undef UPCOMING_FEATURE diff --git a/include/swift/Demangling/DemangleNodes.def b/include/swift/Demangling/DemangleNodes.def index bd21f82e1fc..d2c00a280c7 100644 --- a/include/swift/Demangling/DemangleNodes.def +++ b/include/swift/Demangling/DemangleNodes.def @@ -153,7 +153,6 @@ NODE(InfixOperator) CONTEXT_NODE(Initializer) CONTEXT_NODE(InitAccessor) NODE(Isolated) -CONTEXT_NODE(IsolatedDeallocator) NODE(Sending) NODE(IsolatedAnyFunctionType) NODE(SendingResultFunctionType) diff --git a/include/swift/Runtime/Concurrency.h b/include/swift/Runtime/Concurrency.h index 6769881cd75..4d9a64c9db9 100644 --- a/include/swift/Runtime/Concurrency.h +++ b/include/swift/Runtime/Concurrency.h @@ -605,11 +605,6 @@ swift_task_createNullaryContinuationJob( size_t priority, AsyncTask *continuation); -SWIFT_EXPORT_FROM(swift_Concurrency) -SWIFT_CC(swift) -void swift_task_deinitOnExecutor(void *object, DeinitWorkFunction *work, - SerialExecutorRef newExecutor, size_t flags); - /// Report error about attempting to bind a task-local value from an illegal context. SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift) void swift_task_reportIllegalTaskLocalBindingWithinWithTaskGroup( diff --git a/include/swift/Runtime/RuntimeFunctions.def b/include/swift/Runtime/RuntimeFunctions.def index 7af3537db5a..9747e34c11d 100644 --- a/include/swift/Runtime/RuntimeFunctions.def +++ b/include/swift/Runtime/RuntimeFunctions.def @@ -2278,7 +2278,7 @@ FUNCTION(GetTypeByMangledNameInContextInMetadataState2, EFFECT(MetaData), MEMEFFECTS(ArgMemOnly)) -// AsyncTask *swift_task_getCurrent(); +// AsyncTask *swift_task_getCurrent();s FUNCTION(GetCurrentTask, swift_task_getCurrent, SwiftCC, ConcurrencyAvailability, @@ -2347,20 +2347,6 @@ FUNCTION(TaskSwitchFunc, ATTRS(NoUnwind), EFFECT(Concurrency), UNKNOWN_MEMEFFECTS) - -// void swift_task_deinitOnExecutor(void *object, -// DeinitWorkFunction *work, -// SerialExecutorRef newExecutor, -// size_t flags); -FUNCTION(DeinitOnExecutorFunc, - swift_task_deinitOnExecutor, SwiftCC, - ConcurrencyAvailability, - RETURNS(VoidTy), - ARGS(Int8PtrTy, Int8PtrTy, ExecutorFirstTy, ExecutorSecondTy, SizeTy), - ATTRS(NoUnwind), - EFFECT(Concurrency), - UNKNOWN_MEMEFFECTS) - // AsyncTask *swift_continuation_init(AsyncContext *continuationContext, // AsyncContinuationFlags); diff --git a/include/swift/SIL/SILDeclRef.h b/include/swift/SIL/SILDeclRef.h index 15a69905196..cb0ff397206 100644 --- a/include/swift/SIL/SILDeclRef.h +++ b/include/swift/SIL/SILDeclRef.h @@ -111,11 +111,11 @@ struct SILDeclRef { /// Initializer - this constant references the initializing constructor /// entry point of the class ConstructorDecl in loc. Initializer, - + /// EnumElement - this constant references the injection function for /// an EnumElementDecl. EnumElement, - + /// Destroyer - this constant references the destroying destructor for the /// DestructorDecl in loc. Destroyer, @@ -123,11 +123,7 @@ struct SILDeclRef { /// Deallocator - this constant references the deallocating /// destructor for the DestructorDecl in loc. Deallocator, - - /// Deallocator - this constant references the isolated deallocating - /// destructor for the DestructorDecl in loc. - IsolatedDeallocator, - + /// GlobalAccessor - this constant references the lazy-initializing /// accessor for the global VarDecl in loc. GlobalAccessor, @@ -343,8 +339,7 @@ struct SILDeclRef { } /// True if the SILDeclRef references a destructor entry point. bool isDestructor() const { - return kind == Kind::Destroyer || kind == Kind::Deallocator || - kind == Kind::IsolatedDeallocator; + return kind == Kind::Destroyer || kind == Kind::Deallocator; } /// True if the SILDeclRef references an enum entry point. bool isEnumElement() const { diff --git a/include/swift/SIL/SILModule.h b/include/swift/SIL/SILModule.h index 82e466e47be..b7442131f41 100644 --- a/include/swift/SIL/SILModule.h +++ b/include/swift/SIL/SILModule.h @@ -1113,9 +1113,6 @@ namespace Lowering { /// Determine whether the given class will be allocated/deallocated using the /// Objective-C runtime, i.e., +alloc and -dealloc. LLVM_LIBRARY_VISIBILITY bool usesObjCAllocator(ClassDecl *theClass); -/// Determine if isolating destructor is needed. -LLVM_LIBRARY_VISIBILITY bool needsIsolatingDestructor(DestructorDecl *dd); - } // namespace Lowering } // namespace swift diff --git a/lib/AST/ASTMangler.cpp b/lib/AST/ASTMangler.cpp index 821a2cfe1c4..8bf1fd9eb63 100644 --- a/lib/AST/ASTMangler.cpp +++ b/lib/AST/ASTMangler.cpp @@ -129,11 +129,11 @@ std::string ASTMangler::mangleEntity(const ValueDecl *decl, SymbolKind SKind) { } std::string ASTMangler::mangleDestructorEntity(const DestructorDecl *decl, - DestructorKind kind, + bool isDeallocating, SymbolKind SKind) { llvm::SaveAndRestore X(AllowInverses, inversesAllowed(decl)); beginMangling(); - appendDestructorEntity(decl, kind); + appendDestructorEntity(decl, isDeallocating); appendSymbolKind(SKind); return finalize(); } @@ -838,7 +838,7 @@ void ASTMangler::appendAnyDecl(const ValueDecl *Decl) { if (auto Ctor = dyn_cast(Decl)) { appendConstructorEntity(Ctor, /*isAllocating=*/false); } else if (auto Dtor = dyn_cast(Decl)) { - appendDestructorEntity(Dtor, DestructorKind::NonDeallocating); + appendDestructorEntity(Dtor, /*isDeallocating=*/false); } else if (auto GTD = dyn_cast(Decl)) { appendAnyGenericType(GTD); } else if (isa(Decl)) { @@ -940,7 +940,7 @@ std::string ASTMangler::mangleHasSymbolQuery(const ValueDecl *Decl) { if (auto Ctor = dyn_cast(Decl)) { appendConstructorEntity(Ctor, /*isAllocating=*/false); } else if (auto Dtor = dyn_cast(Decl)) { - appendDestructorEntity(Dtor, DestructorKind::NonDeallocating); + appendDestructorEntity(Dtor, /*isDeallocating=*/false); } else if (auto GTD = dyn_cast(Decl)) { appendAnyGenericType(GTD); } else if (isa(Decl)) { @@ -2447,8 +2447,8 @@ void ASTMangler::appendContext(const DeclContext *ctx, } if (auto dtor = dyn_cast(fn)) - return appendDestructorEntity(dtor, DestructorKind::NonDeallocating); - + return appendDestructorEntity(dtor, /*deallocating*/ false); + return appendEntity(fn); } @@ -3953,20 +3953,10 @@ void ASTMangler::appendConstructorEntity(const ConstructorDecl *ctor, } void ASTMangler::appendDestructorEntity(const DestructorDecl *dtor, - DestructorKind kind) { + bool isDeallocating) { BaseEntitySignature base(dtor); appendContextOf(dtor, base); - switch (kind) { - case DestructorKind::NonDeallocating: - appendOperator("fd"); - break; - case DestructorKind::Deallocating: - appendOperator("fD"); - break; - case DestructorKind::IsolatedDeallocating: - appendOperator("fZ"); - break; - } + appendOperator(isDeallocating ? "fD" : "fd"); } void ASTMangler::appendAccessorEntity(StringRef accessorKindCode, diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp index 8da925a114d..6b8d1da0feb 100644 --- a/lib/AST/ASTPrinter.cpp +++ b/lib/AST/ASTPrinter.cpp @@ -182,18 +182,6 @@ static bool shouldPrintAllSemanticDetails(const PrintOptions &options) { return false; } -bool PrintOptions::excludeAttr(const DeclAttribute *DA) const { - if (excludeAttrKind(DA->getKind())) { - return true; - } - if (auto CA = dyn_cast(DA)) { - if (std::any_of(ExcludeCustomAttrList.begin(), ExcludeCustomAttrList.end(), - [CA](CustomAttr *other) { return other == CA; })) - return true; - } - return false; -} - PrintOptions PrintOptions::printSwiftInterfaceFile(ModuleDecl *ModuleToPrint, bool preferTypeRepr, bool printFullConvention, @@ -834,13 +822,7 @@ class PrintAST : public ASTVisitor { if (D->getDeclContext()->isLocalContext()) return; - if (Options.SuppressIsolatedDeinit && - D->getFormalAccess() == AccessLevel::Open && - usesFeatureIsolatedDeinit(D)) { - printAccess(AccessLevel::Public); - } else { - printAccess(D->getFormalAccess()); - } + printAccess(D->getFormalAccess()); bool shouldSkipSetterAccess = llvm::is_contained(Options.ExcludeAttrList, DeclAttrKind::SetterAccess); @@ -1235,10 +1217,6 @@ void PrintAST::printAttributes(const Decl *D) { // Save the current number of exclude attrs to restore once we're done. unsigned originalExcludeAttrCount = Options.ExcludeAttrList.size(); - // ExcludeCustomAttrList stores instances of attributes, which are specific - // for each decl They cannot be shared across different decls. - assert(Options.ExcludeCustomAttrList.empty()); - if (Options.PrintImplicitAttrs) { // Don't print a redundant 'final' if we are printing a 'static' decl. @@ -1330,19 +1308,9 @@ void PrintAST::printAttributes(const Decl *D) { Options.ExcludeAttrList.push_back(DeclAttrKind::Borrowing); } - if (isa(D) && Options.SuppressIsolatedDeinit) { - Options.ExcludeAttrList.push_back(DeclAttrKind::Nonisolated); - Options.ExcludeAttrList.push_back(DeclAttrKind::Isolated); - if (auto globalActor = D->getGlobalActorAttr()) { - Options.ExcludeCustomAttrList.push_back(globalActor->first); - } - } - attrs.print(Printer, Options, D); - Options.ExcludeAttrList.resize(originalExcludeAttrCount); - Options.ExcludeCustomAttrList.clear(); } void PrintAST::printTypedPattern(const TypedPattern *TP) { @@ -3088,13 +3056,6 @@ suppressingFeatureBitwiseCopyable2(PrintOptions &options, options.ExcludeAttrList.resize(originalExcludeAttrCount); } -static void -suppressingFeatureIsolatedDeinit(PrintOptions &options, - llvm::function_ref action) { - llvm::SaveAndRestore scope(options.SuppressIsolatedDeinit, true); - action(); -} - static void suppressingFeatureAllowUnsafeAttribute(PrintOptions &options, llvm::function_ref action) { diff --git a/lib/AST/Attr.cpp b/lib/AST/Attr.cpp index b8347e44137..bd876653b0b 100644 --- a/lib/AST/Attr.cpp +++ b/lib/AST/Attr.cpp @@ -1033,7 +1033,7 @@ void DeclAttributes::print(ASTPrinter &Printer, const PrintOptions &Options, if (!Options.PrintUserInaccessibleAttrs && DeclAttribute::isUserInaccessible(DA->getKind())) continue; - if (Options.excludeAttr(DA)) + if (Options.excludeAttrKind(DA->getKind())) continue; // In the public interfaces of -library-level=api modules, skip attributes diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 2739724246b..1f4ba5601aa 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -997,26 +997,6 @@ std::optional Decl::getGlobalActorAttr() const { ctx.evaluator, GlobalActorAttributeRequest{mutableThis}, std::nullopt); } -bool Decl::hasExplicitIsolationAttribute() const { - if (auto nonisolatedAttr = getAttrs().getAttribute()) { - if (!nonisolatedAttr->isImplicit()) - return true; - } - - if (auto isolatedAttr = getAttrs().getAttribute()) { - if (!isolatedAttr->isImplicit()) { - return true; - } - } - - if (auto globalActorAttr = getGlobalActorAttr()) { - if (!globalActorAttr->first->isImplicit()) - return true; - } - - return false; -} - bool Decl::preconcurrency() const { if (getAttrs().hasAttribute()) return true; @@ -3332,16 +3312,6 @@ ValueDecl *ValueDecl::getOverriddenDecl() const { return overridden.front(); } -ValueDecl *ValueDecl::getOverriddenDeclOrSuperDeinit() const { - if (auto overridden = getOverriddenDecl()) { - return overridden; - } - if (auto dtor = dyn_cast(this)) { - return dtor->getSuperDeinit(); - } - return nullptr; -} - bool ValueDecl::overriddenDeclsComputed() const { return LazySemanticInfo.hasOverriddenComputed; } @@ -10898,16 +10868,6 @@ ObjCSelector DestructorDecl::getObjCSelector() const { return ObjCSelector(ctx, 0, ctx.Id_dealloc); } -DestructorDecl *DestructorDecl::getSuperDeinit() const { - auto declContext = getDeclContext()->getImplementedObjCContext(); - if (auto classDecl = dyn_cast(declContext)) { - if (auto superclass = classDecl->getSuperclassDecl()) { - return superclass->getDestructor(); - } - } - return nullptr; -} - SourceRange FuncDecl::getSourceRange() const { SourceLoc StartLoc = getStartLoc(); diff --git a/lib/AST/FeatureSet.cpp b/lib/AST/FeatureSet.cpp index 280d2806cf0..5f232958b46 100644 --- a/lib/AST/FeatureSet.cpp +++ b/lib/AST/FeatureSet.cpp @@ -232,23 +232,6 @@ static bool usesFeatureAllowUnsafeAttribute(Decl *decl) { UNINTERESTING_FEATURE(WarnUnsafe) -bool swift::usesFeatureIsolatedDeinit(const Decl *decl) { - if (auto cd = dyn_cast(decl)) { - return cd->getFormalAccess() == AccessLevel::Open && - usesFeatureIsolatedDeinit(cd->getDestructor()); - } else if (auto dd = dyn_cast(decl)) { - if (dd->hasExplicitIsolationAttribute()) { - return true; - } - if (auto superDD = dd->getSuperDeinit()) { - return usesFeatureIsolatedDeinit(superDD); - } - return false; - } else { - return false; - } -} - // ---------------------------------------------------------------------------- // MARK: - FeatureSet // ---------------------------------------------------------------------------- diff --git a/lib/AST/FeatureSet.h b/lib/AST/FeatureSet.h index 67fa5473097..30313ec3120 100644 --- a/lib/AST/FeatureSet.h +++ b/lib/AST/FeatureSet.h @@ -68,8 +68,6 @@ private: /// not part of the enclosing context. FeatureSet getUniqueFeaturesUsed(Decl *decl); -bool usesFeatureIsolatedDeinit(const Decl *decl); - } // end namespace swift #endif /* SWIFT_AST_FEATURES_H */ diff --git a/lib/ASTGen/Sources/ASTGen/DeclAttrs.swift b/lib/ASTGen/Sources/ASTGen/DeclAttrs.swift index de86e010ea8..4908c57a4e8 100644 --- a/lib/ASTGen/Sources/ASTGen/DeclAttrs.swift +++ b/lib/ASTGen/Sources/ASTGen/DeclAttrs.swift @@ -221,7 +221,6 @@ extension ASTGenVisitor { .inheritActorContext, .inheritsConvenienceInitializers, .inlinable, - .isolated, .lexicalLifetimes, .lldbDebuggerFunction, .marker, diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp index dafc3760e29..6fc00692f6e 100644 --- a/lib/ClangImporter/ImportDecl.cpp +++ b/lib/ClangImporter/ImportDecl.cpp @@ -5327,22 +5327,6 @@ namespace { result->setHasMissingVTableEntries(false); result->setMemberLoader(&Impl, 0); - // GetDestructorRequest does not trigger lazy member loading - // And typechecking may ask for destructor before member loading is - // triggered. Create deinit explicitly - auto deallocII = &clangCtx.Idents.get("dealloc"); - auto deallocSelector = clangCtx.Selectors.getNullarySelector(deallocII); - auto deallocName = clang::DeclarationName(deallocSelector); - for (auto nd : decl->lookup(deallocName)) { - if (auto deallocDecl = dyn_cast(nd)) { - if (deallocDecl->isInstanceMethod()) { - auto loc = Impl.importSourceLoc(deallocDecl->getLocation()); - auto dtor = Impl.createDeclWithClangNode( - deallocDecl, access, loc, result); - result->addMember(dtor); - } - } - } return result; } diff --git a/lib/Demangling/Demangler.cpp b/lib/Demangling/Demangler.cpp index b1aca9bafae..cab48bd4668 100644 --- a/lib/Demangling/Demangler.cpp +++ b/lib/Demangling/Demangler.cpp @@ -3982,10 +3982,6 @@ NodePointer Demangler::demangleFunctionEntity() { switch (nextChar()) { case 'D': Args = None; Kind = Node::Kind::Deallocator; break; case 'd': Args = None; Kind = Node::Kind::Destructor; break; - case 'Z': - Args = None; - Kind = Node::Kind::IsolatedDeallocator; - break; case 'E': Args = None; Kind = Node::Kind::IVarDestroyer; break; case 'e': Args = None; Kind = Node::Kind::IVarInitializer; break; case 'i': Args = None; Kind = Node::Kind::Initializer; break; diff --git a/lib/Demangling/NodePrinter.cpp b/lib/Demangling/NodePrinter.cpp index e0bd12c9c35..0d471960c39 100644 --- a/lib/Demangling/NodePrinter.cpp +++ b/lib/Demangling/NodePrinter.cpp @@ -367,7 +367,6 @@ private: case Node::Kind::CurryThunk: case Node::Kind::DispatchThunk: case Node::Kind::Deallocator: - case Node::Kind::IsolatedDeallocator: case Node::Kind::DeclContext: case Node::Kind::DefaultArgumentInitializer: case Node::Kind::DefaultAssociatedTypeMetadataAccessor: @@ -2723,12 +2722,6 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth, /*hasName*/ false, isClassType(Node->getChild(0)) ? "__deallocating_deinit" : "deinit"); - case Node::Kind::IsolatedDeallocator: - return printEntity(Node, depth, asPrefixContext, TypePrinting::NoType, - /*hasName*/ false, - isClassType(Node->getChild(0)) - ? "__isolated_deallocating_deinit" - : "deinit"); case Node::Kind::IVarInitializer: return printEntity(Node, depth, asPrefixContext, TypePrinting::NoType, /*hasName*/ false, "__ivar_initializer"); diff --git a/lib/Demangling/OldDemangler.cpp b/lib/Demangling/OldDemangler.cpp index 2a4b5f659b8..54578bb7f8e 100644 --- a/lib/Demangling/OldDemangler.cpp +++ b/lib/Demangling/OldDemangler.cpp @@ -1213,9 +1213,6 @@ private: if (Mangled.nextIf('D')) { entityKind = Node::Kind::Deallocator; hasType = false; - } else if (Mangled.nextIf('Z')) { - entityKind = Node::Kind::IsolatedDeallocator; - hasType = false; } else if (Mangled.nextIf('d')) { entityKind = Node::Kind::Destructor; hasType = false; diff --git a/lib/Demangling/OldRemangler.cpp b/lib/Demangling/OldRemangler.cpp index 4e86abcc087..9aafee53cf5 100644 --- a/lib/Demangling/OldRemangler.cpp +++ b/lib/Demangling/OldRemangler.cpp @@ -1197,12 +1197,6 @@ ManglingError Remangler::mangleDeallocator(Node *node, EntityContext &ctx, return mangleSimpleEntity(node, 'F', "D", ctx, depth + 1); } -ManglingError Remangler::mangleIsolatedDeallocator(Node *node, - EntityContext &ctx, - unsigned depth) { - return mangleSimpleEntity(node, 'F', "Z", ctx, depth + 1); -} - ManglingError Remangler::mangleDestructor(Node *node, EntityContext &ctx, unsigned depth) { return mangleSimpleEntity(node, 'F', "d", ctx, depth + 1); diff --git a/lib/Demangling/Remangler.cpp b/lib/Demangling/Remangler.cpp index 70fd1006858..f239ce7054a 100644 --- a/lib/Demangling/Remangler.cpp +++ b/lib/Demangling/Remangler.cpp @@ -1017,12 +1017,6 @@ ManglingError Remangler::mangleDeallocator(Node *node, unsigned depth) { return ManglingError::Success; } -ManglingError Remangler::mangleIsolatedDeallocator(Node *node, unsigned depth) { - RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); - Buffer << "fZ"; - return ManglingError::Success; -} - ManglingError Remangler::mangleDeclContext(Node *node, unsigned depth) { return mangleSingleChildNode(node, depth + 1); } diff --git a/lib/IRGen/GenObjC.cpp b/lib/IRGen/GenObjC.cpp index 6dae138b0bc..58b9ad03f31 100644 --- a/lib/IRGen/GenObjC.cpp +++ b/lib/IRGen/GenObjC.cpp @@ -663,7 +663,6 @@ namespace { case SILDeclRef::Kind::PropertyWrapperInitFromProjectedValue: case SILDeclRef::Kind::EntryPoint: case SILDeclRef::Kind::AsyncEntryPoint: - case SILDeclRef::Kind::IsolatedDeallocator: llvm_unreachable("Method does not have a selector"); case SILDeclRef::Kind::Destroyer: @@ -779,8 +778,6 @@ Callee irgen::getObjCMethodCallee(IRGenFunction &IGF, llvm::Value *selfValue, CalleeInfo &&info) { SILDeclRef method = methodInfo.getMethod(); - // Note that isolated deallocator is never called directly, only from regular - // deallocator assert((method.kind == SILDeclRef::Kind::Initializer || method.kind == SILDeclRef::Kind::Allocator || method.kind == SILDeclRef::Kind::Func diff --git a/lib/SIL/IR/SILDeclRef.cpp b/lib/SIL/IR/SILDeclRef.cpp index 2b76b0b0819..5890a4b4357 100644 --- a/lib/SIL/IR/SILDeclRef.cpp +++ b/lib/SIL/IR/SILDeclRef.cpp @@ -373,7 +373,6 @@ bool SILDeclRef::hasUserWrittenCode() const { case Kind::EnumElement: case Kind::Destroyer: case Kind::Deallocator: - case Kind::IsolatedDeallocator: case Kind::GlobalAccessor: case Kind::DefaultArgGenerator: case Kind::IVarInitializer: @@ -482,7 +481,6 @@ static LinkageLimit getLinkageLimit(SILDeclRef constant) { case Kind::Allocator: case Kind::Initializer: case Kind::Deallocator: - case Kind::IsolatedDeallocator: case Kind::Destroyer: { // @_alwaysEmitIntoClient declarations are like the default arguments of // public functions; they are roots for dead code elimination and have @@ -1284,16 +1282,12 @@ std::string SILDeclRef::mangle(ManglingKind MKind) const { case SILDeclRef::Kind::Deallocator: return mangler.mangleDestructorEntity(cast(getDecl()), - DestructorKind::Deallocating, SKind); + /*isDeallocating*/ true, + SKind); case SILDeclRef::Kind::Destroyer: return mangler.mangleDestructorEntity(cast(getDecl()), - DestructorKind::NonDeallocating, - SKind); - - case SILDeclRef::Kind::IsolatedDeallocator: - return mangler.mangleDestructorEntity(cast(getDecl()), - DestructorKind::IsolatedDeallocating, + /*isDeallocating*/ false, SKind); case SILDeclRef::Kind::Allocator: diff --git a/lib/SIL/IR/SILFunctionType.cpp b/lib/SIL/IR/SILFunctionType.cpp index d810fec8d89..8e3405fab7c 100644 --- a/lib/SIL/IR/SILFunctionType.cpp +++ b/lib/SIL/IR/SILFunctionType.cpp @@ -2871,14 +2871,6 @@ static CanSILFunctionType getNativeSILFunctionType( DefaultConventions(NormalParameterConvention::Guaranteed)); case SILDeclRef::Kind::Deallocator: return getSILFunctionTypeForConventions(DeallocatorConventions()); - case SILDeclRef::Kind::IsolatedDeallocator: { - // Use @convention(thin) instead of @convention(method) to properly bridge - // with runtime function. The latter expects 'work' argument to be - // SWIFT_CC(swift) aka @convention(thin). But the 'self' parameter must - // remain owned. - return getSILFunctionTypeForConventions( - DefaultConventions(NormalParameterConvention::Owned)); - } case SILDeclRef::Kind::AsyncEntryPoint: return getSILFunctionTypeForConventions( @@ -3723,7 +3715,6 @@ static ObjCSelectorFamily getObjCSelectorFamily(SILDeclRef c) { /// These constants don't correspond to method families we care about yet. case SILDeclRef::Kind::Destroyer: case SILDeclRef::Kind::Deallocator: - case SILDeclRef::Kind::IsolatedDeallocator: case SILDeclRef::Kind::IVarDestroyer: return ObjCSelectorFamily::None; @@ -4030,7 +4021,6 @@ TypeConverter::getDeclRefRepresentation(SILDeclRef c) { case SILDeclRef::Kind::StoredPropertyInitializer: case SILDeclRef::Kind::PropertyWrapperBackingInitializer: case SILDeclRef::Kind::PropertyWrapperInitFromProjectedValue: - case SILDeclRef::Kind::IsolatedDeallocator: return SILFunctionTypeRepresentation::Thin; case SILDeclRef::Kind::Func: @@ -4430,7 +4420,6 @@ static AbstractFunctionDecl *getBridgedFunction(SILDeclRef declRef) { case SILDeclRef::Kind::EnumElement: case SILDeclRef::Kind::Destroyer: case SILDeclRef::Kind::Deallocator: - case SILDeclRef::Kind::IsolatedDeallocator: case SILDeclRef::Kind::GlobalAccessor: case SILDeclRef::Kind::DefaultArgGenerator: case SILDeclRef::Kind::StoredPropertyInitializer: diff --git a/lib/SIL/IR/SILModule.cpp b/lib/SIL/IR/SILModule.cpp index 505878c91ca..a6857e0c3bc 100644 --- a/lib/SIL/IR/SILModule.cpp +++ b/lib/SIL/IR/SILModule.cpp @@ -992,25 +992,3 @@ bool Lowering::usesObjCAllocator(ClassDecl *theClass) { // allocation methods because they may have been overridden. return theClass->getObjectModel() == ReferenceCounting::ObjC; } - -bool Lowering::needsIsolatingDestructor(DestructorDecl *dd) { - auto ai = swift::getActorIsolation(dd); - if (!ai.isActorIsolated()) { - return false; - } - DestructorDecl *firstIsolated = dd; - while (true) { - DestructorDecl *next = firstIsolated->getSuperDeinit(); - if (!next) - break; - auto ai = swift::getActorIsolation(next); - if (!ai.isActorIsolated()) - break; - firstIsolated = next; - } - - // If isolation was introduced in ObjC code, then we assume that ObjC code - // also overrides retain/release to make sure that dealloc is called on the - // correct executor in the first place. - return firstIsolated->getClangNode().isNull(); -} diff --git a/lib/SIL/IR/SILPrinter.cpp b/lib/SIL/IR/SILPrinter.cpp index 884ce78354c..67e6404993e 100644 --- a/lib/SIL/IR/SILPrinter.cpp +++ b/lib/SIL/IR/SILPrinter.cpp @@ -372,9 +372,6 @@ void SILDeclRef::print(raw_ostream &OS) const { case SILDeclRef::Kind::Deallocator: OS << "!deallocator"; break; - case SILDeclRef::Kind::IsolatedDeallocator: - OS << "!isolateddeallocator"; - break; case SILDeclRef::Kind::IVarInitializer: OS << "!ivarinitializer"; break; @@ -4028,7 +4025,6 @@ void SILVTableEntry::print(llvm::raw_ostream &OS) const { case SILDeclRef::Kind::IVarDestroyer: case SILDeclRef::Kind::Destroyer: case SILDeclRef::Kind::Deallocator: - case SILDeclRef::Kind::IsolatedDeallocator: HasSingleImplementation = true; } // No need to emit the signature for methods that may have only diff --git a/lib/SIL/IR/SILSymbolVisitor.cpp b/lib/SIL/IR/SILSymbolVisitor.cpp index 034a0664a85..4e9802bf11e 100644 --- a/lib/SIL/IR/SILSymbolVisitor.cpp +++ b/lib/SIL/IR/SILSymbolVisitor.cpp @@ -715,9 +715,9 @@ public: } void visitDestructorDecl(DestructorDecl *DD) { - // Destructors come in three forms (non-deallocating, deallocating, isolated - // deallocating) Classes use all three but move only non-class nominal types - // only use the deallocating one. This is the deallocating one: + // Destructors come in two forms (deallocating and non-deallocating), like + // constructors above. Classes use both but move only non-class nominal + // types only use the deallocating one. This is the deallocating one: visitAbstractFunctionDecl(DD); if (auto parentClass = DD->getParent()->getSelfClassDecl()) { @@ -726,11 +726,6 @@ public: addFunction(SILDeclRef(DD, SILDeclRef::Kind::Destroyer)); } } - - // And isolated also does not always exist - if (Lowering::needsIsolatingDestructor(DD)) { - addFunction(SILDeclRef(DD, SILDeclRef::Kind::IsolatedDeallocator)); - } } void visitExtensionDecl(ExtensionDecl *ED) { diff --git a/lib/SIL/IR/TypeLowering.cpp b/lib/SIL/IR/TypeLowering.cpp index 9ae16271472..7113d003619 100644 --- a/lib/SIL/IR/TypeLowering.cpp +++ b/lib/SIL/IR/TypeLowering.cpp @@ -4051,11 +4051,10 @@ CanAnyFunctionType TypeConverter::makeConstantInterfaceType(SILDeclRef c) { case SILDeclRef::Kind::Destroyer: case SILDeclRef::Kind::Deallocator: - case SILDeclRef::Kind::IsolatedDeallocator: return getDestructorInterfaceType(cast(vd), - c.kind != SILDeclRef::Kind::Destroyer, + c.kind == SILDeclRef::Kind::Deallocator, c.isForeign); - + case SILDeclRef::Kind::GlobalAccessor: { VarDecl *var = cast(vd); assert(var->hasStorage() && @@ -4094,8 +4093,7 @@ TypeConverter::getGenericSignatureWithCapturedEnvironments(SILDeclRef c) { case SILDeclRef::Kind::Allocator: case SILDeclRef::Kind::Initializer: case SILDeclRef::Kind::Destroyer: - case SILDeclRef::Kind::Deallocator: - case SILDeclRef::Kind::IsolatedDeallocator: { + case SILDeclRef::Kind::Deallocator: { auto captureInfo = getLoweredLocalCaptures(c); return ::getGenericSignatureWithCapturedEnvironments( *c.getAnyFunctionRef(), captureInfo); diff --git a/lib/SIL/Parser/ParseSIL.cpp b/lib/SIL/Parser/ParseSIL.cpp index 9afe7418e07..becb4ddd707 100644 --- a/lib/SIL/Parser/ParseSIL.cpp +++ b/lib/SIL/Parser/ParseSIL.cpp @@ -1347,9 +1347,6 @@ bool SILParser::parseSILDeclRef(SILDeclRef &Result, } else if (!ParseState && Id.str() == "deallocator") { Kind = SILDeclRef::Kind::Deallocator; ParseState = 1; - } else if (!ParseState && Id.str() == "isolateddeallocator") { - Kind = SILDeclRef::Kind::IsolatedDeallocator; - ParseState = 1; } else if (!ParseState && Id.str() == "globalaccessor") { Kind = SILDeclRef::Kind::GlobalAccessor; ParseState = 1; diff --git a/lib/SILGen/SILGen.cpp b/lib/SILGen/SILGen.cpp index 9d5ce405991..9262b0daf97 100644 --- a/lib/SILGen/SILGen.cpp +++ b/lib/SILGen/SILGen.cpp @@ -455,10 +455,6 @@ FuncDecl *SILGenModule::getSwiftJobRun() { return lookupConcurrencyIntrinsic(getASTContext(), "_swiftJobRun"); } -FuncDecl *SILGenModule::getDeinitOnExecutor() { - return lookupConcurrencyIntrinsic(getASTContext(), "_deinitOnExecutor"); -} - FuncDecl *SILGenModule::getExit() { ASTContext &C = getASTContext(); @@ -756,18 +752,11 @@ SILFunction *SILGenModule::getFunction(SILDeclRef constant, return IGM.getFunction(constant, NotForDefinition); }); - if (constant.kind == SILDeclRef::Kind::Deallocator) { - // Deallocating destructor is always nonisolated. - // Isolation of the deinit applies only to isolated deallocator and - // destroyer. - F->setActorIsolation(ActorIsolation::forNonisolated(false)); - } else { - // If we have global actor isolation for our constant, put the isolation - // onto the function. - if (auto isolation = - getActorIsolationOfContext(constant.getInnermostDeclContext())) { - F->setActorIsolation(isolation); - } + // If we have global actor isolation for our constant, put the isolation onto + // the function. + if (auto isolation = + getActorIsolationOfContext(constant.getInnermostDeclContext())) { + F->setActorIsolation(isolation); } assert(F && "SILFunction should have been defined"); @@ -1126,23 +1115,26 @@ void SILGenModule::emitFunctionDefinition(SILDeclRef constant, SILFunction *f) { return; } - case SILDeclRef::Kind::IsolatedDeallocator: { - emitDeallocatorImpl(constant, f); - return; - } case SILDeclRef::Kind::Deallocator: { auto *dd = cast(constant.getDecl()); - if (needsIsolatingDestructor(dd)) { - auto loc = RegularLocation::getAutoGeneratedLocation(dd); - preEmitFunction(constant, f, loc); - PrettyStackTraceSILFunction X("silgen emitIsolatingDestructor", f); - f->createProfiler(constant); - SILGenFunction(*this, *f, dd).emitIsolatingDestructor(dd); - postEmitFunction(constant, f); - return; + auto *nom = dd->getDeclContext()->getSelfNominalTypeDecl(); + + if (auto *cd = dyn_cast(nom)) { + if (usesObjCAllocator(cd)) { + preEmitFunction(constant, f, dd); + PrettyStackTraceSILFunction X("silgen emitDestructor -dealloc", f); + f->createProfiler(constant); + SILGenFunction(*this, *f, dd).emitObjCDestructor(constant); + postEmitFunction(constant, f); + return; + } } - emitDeallocatorImpl(constant, f); + auto loc = RegularLocation::getAutoGeneratedLocation(dd); + preEmitFunction(constant, f, loc); + PrettyStackTraceSILFunction X("silgen emitDeallocatingDestructor", f); + SILGenFunction(*this, *f, dd).emitDeallocatingDestructor(dd); + postEmitFunction(constant, f); return; } @@ -1256,18 +1248,11 @@ void SILGenModule::preEmitFunction(SILDeclRef constant, SILFunction *F, F->setGenericEnvironment(genericEnv, capturedEnvs, forwardingSubs); } - if (constant.kind == SILDeclRef::Kind::Deallocator) { - // Deallocating destructor is always nonisolated. - // Isolation of the deinit applies only to isolated deallocator and - // destroyer. - F->setActorIsolation(ActorIsolation::forNonisolated(false)); - } else { - // If we have global actor isolation for our constant, put the isolation - // onto the function. - if (auto isolation = - getActorIsolationOfContext(constant.getInnermostDeclContext())) { - F->setActorIsolation(isolation); - } + // If we have global actor isolation for our constant, put the isolation onto + // the function. + if (auto isolation = + getActorIsolationOfContext(constant.getInnermostDeclContext())) { + F->setActorIsolation(isolation); } // Create a debug scope for the function using astNode as source location. @@ -1591,17 +1576,6 @@ bool SILGenModule::requiresIVarDestroyer(ClassDecl *cd) { /// TODO: This needs a better name. void SILGenModule::emitObjCAllocatorDestructor(ClassDecl *cd, DestructorDecl *dd) { - - const bool isActorIsolated = needsIsolatingDestructor(dd); - - // Emit the isolated deallocating destructor. - // If emitted, it implements actual deallocating and deallocating destructor - // only switches executor - if (dd->hasBody() && isActorIsolated) { - SILDeclRef dealloc(dd, SILDeclRef::Kind::IsolatedDeallocator); - emitFunctionDefinition(dealloc, getFunction(dealloc, ForDefinition)); - } - // Emit the native deallocating destructor for -dealloc. // Destructors are a necessary part of class metadata, so can't be delayed. if (shouldEmitFunctionBody(dd)) { @@ -1610,7 +1584,7 @@ void SILGenModule::emitObjCAllocatorDestructor(ClassDecl *cd, // Emit the Objective-C -dealloc entry point if it has // something to do beyond messaging the superclass's -dealloc. - if (!dd->getBody()->empty() || isActorIsolated) + if (!dd->getBody()->empty()) emitObjCDestructorThunk(dd); } @@ -1631,31 +1605,6 @@ void SILGenModule::emitObjCAllocatorDestructor(ClassDecl *cd, } } -void SILGenModule::emitDeallocatorImpl(SILDeclRef constant, SILFunction *f) { - auto *dd = cast(constant.getDecl()); - auto *nom = dd->getDeclContext()->getSelfNominalTypeDecl(); - - if (auto *cd = dyn_cast(nom)) { - if (usesObjCAllocator(cd)) { - preEmitFunction(constant, f, dd); - PrettyStackTraceSILFunction X("silgen emitDestructor -dealloc", f); - f->createProfiler(constant); - SILGenFunction(*this, *f, dd).emitObjCDestructor(constant); - postEmitFunction(constant, f); - return; - } - } - - auto loc = RegularLocation::getAutoGeneratedLocation(dd); - preEmitFunction(constant, f, loc); - PrettyStackTraceSILFunction X("silgen emitDeallocatingDestructor", f); - bool isIsolated = constant.kind == SILDeclRef::Kind::IsolatedDeallocator; - SILGenFunction(*this, *f, dd).emitDeallocatingDestructor(dd, isIsolated); - - postEmitFunction(constant, f); - return; -} - void SILGenModule::emitDestructor(ClassDecl *cd, DestructorDecl *dd) { emitAbstractFuncDecl(dd); @@ -1679,15 +1628,6 @@ void SILGenModule::emitDestructor(ClassDecl *cd, DestructorDecl *dd) { emitFunctionDefinition(destroyer, getFunction(destroyer, ForDefinition)); } - // Emit the isolated deallocating destructor. - // If emitted, it implements actual deallocating and deallocating destructor - // only switches executor - if (needsIsolatingDestructor(dd)) { - SILDeclRef deallocator(dd, SILDeclRef::Kind::IsolatedDeallocator); - emitFunctionDefinition(deallocator, - getFunction(deallocator, ForDefinition)); - } - // Emit the deallocating destructor. { SILDeclRef deallocator(dd, SILDeclRef::Kind::Deallocator); diff --git a/lib/SILGen/SILGen.h b/lib/SILGen/SILGen.h index 6d9973b03ed..ac293ad7a63 100644 --- a/lib/SILGen/SILGen.h +++ b/lib/SILGen/SILGen.h @@ -552,8 +552,6 @@ public: FuncDecl *getAsyncMainDrainQueue(); /// Retrieve the _Concurrency._swiftJobRun intrinsic. FuncDecl *getSwiftJobRun(); - /// Retrieve the _Concurrency._deinitOnExecutor intrinsic. - FuncDecl *getDeinitOnExecutor(); // Retrieve the _SwiftConcurrencyShims.exit intrinsic. FuncDecl *getExit(); @@ -625,12 +623,6 @@ private: /// Emit the deallocator for a class that uses the objc allocator. void emitObjCAllocatorDestructor(ClassDecl *cd, DestructorDecl *dd); - - /// Emit the actual body of deallocator. - /// If deinit is isolated, function should be an isolated deallocator, an - /// actual deallocator is just a thunk that switches executors. If deinit is - /// isolated, function should be the deallocator itself. - void emitDeallocatorImpl(SILDeclRef constant, SILFunction *f); }; } // end namespace Lowering diff --git a/lib/SILGen/SILGenDestructor.cpp b/lib/SILGen/SILGenDestructor.cpp index eba6ac68bb2..4dada4be452 100644 --- a/lib/SILGen/SILGenDestructor.cpp +++ b/lib/SILGen/SILGenDestructor.cpp @@ -15,7 +15,6 @@ #include "SILGenFunction.h" #include "SILGenFunctionBuilder.h" #include "SwitchEnumBuilder.h" -#include "swift/AST/ConformanceLookup.h" #include "swift/AST/Decl.h" #include "swift/AST/GenericSignature.h" #include "swift/AST/SubstitutionMap.h" @@ -30,38 +29,46 @@ using namespace swift; using namespace Lowering; -void SILGenFunction::emitDistributedRemoteActorDeinit( - SILValue selfValue, DestructorDecl *dd, bool isIsolated, - llvm::function_ref emitLocalDeinit) { - RegularLocation loc(dd); - loc.markAutoGenerated(); +void SILGenFunction::emitDestroyingDestructor(DestructorDecl *dd) { + MagicFunctionName = DeclName(SGM.M.getASTContext().getIdentifier("deinit")); + + RegularLocation Loc(dd); + if (dd->isImplicit()) + Loc.markAutoGenerated(); + + if (dd->requiresUnavailableDeclABICompatibilityStubs()) + emitApplyOfUnavailableCodeReached(); auto cd = cast(dd->getDeclContext()->getSelfNominalTypeDecl()); - if (isIsolated || !cd->isDistributedActor()) { - emitLocalDeinit(); - B.createReturn(loc, emitEmptyTuple(loc)); - return; - } + auto &C = cd->getASTContext(); + SILValue selfValue = emitSelfDeclForDestructor(dd->getImplicitSelfDecl()); - auto remoteBB = createBasicBlock("remoteActorDeinitBB"); - auto finishBB = createBasicBlock("finishDeinitBB"); - auto localBB = createBasicBlock("localActorDeinitBB"); + // Create a basic block to jump to for the implicit destruction behavior + // of releasing the elements and calling the superclass destructor. + // We won't actually emit the block until we finish with the destructor body. + prepareEpilog(dd, std::nullopt, std::nullopt, CleanupLocation(Loc)); - auto selfTy = F.mapTypeIntoContext(cd->getDeclaredInterfaceType()); - emitDistributedIfRemoteBranch(SILLocation(loc), selfValue, selfTy, - /*if remote=*/remoteBB, /*if local=*/localBB); + auto cleanupLoc = CleanupLocation(Loc); - // Emit remote BB - { - B.emitBlock(remoteBB); + SILBasicBlock *deinitBodyBB = nullptr; + SILBasicBlock *finishBB = nullptr; + if (cd->isDistributedActor()) { + auto remoteBB = createBasicBlock("remoteActorDeinitBB"); + finishBB = createBasicBlock("finishDeinitBB"); + deinitBodyBB = createBasicBlock("deinitBodyBB"); - auto cleanupLoc = CleanupLocation(loc); + // FIXME: what should the type of management be for this? + auto managedSelf = ManagedValue::forBorrowedRValue(selfValue); - auto &C = cd->getASTContext(); + auto selfTy = F.mapTypeIntoContext(cd->getDeclaredInterfaceType()); + emitDistributedIfRemoteBranch( + SILLocation(Loc), + managedSelf, selfTy, + /*if remote=*/remoteBB, + /*if local=*/deinitBodyBB); { - FullExpr CleanupScope(Cleanups, cleanupLoc); - ManagedValue borrowedSelf = emitManagedBeginBorrow(loc, selfValue); + B.emitBlock(remoteBB); // Note that we do NOT execute user-declared the deinit body. // They would be free to access state which does not exist in a remote DA @@ -75,73 +82,17 @@ void SILGenFunction::emitDistributedRemoteActorDeinit( // Just to double-check, we only want to destroy `id` and `actorSystem` if (vd->getBaseIdentifier() == C.Id_id || vd->getBaseIdentifier() == C.Id_actorSystem) { - destroyClassMember(cleanupLoc, borrowedSelf, vd); + destroyClassMember(cleanupLoc, managedSelf, vd); } } - if (cd->isRootDefaultActor()) { - emitDestroyDefaultActor(cleanupLoc, borrowedSelf.getValue()); - } + B.createBranch(SILLocation(Loc), finishBB); } - - B.createDeallocRef(loc, selfValue); - - B.createBranch(loc, finishBB); } - // Emit local BB - { - B.emitBlock(localBB); - emitLocalDeinit(); - B.createBranch(loc, finishBB); - } - - // Emit finish BB - B.emitBlock(finishBB); - - // Return. - B.createReturn(loc, emitEmptyTuple(loc)); -} - -void SILGenFunction::emitDestroyingDestructor(DestructorDecl *dd) { - MagicFunctionName = DeclName(SGM.M.getASTContext().getIdentifier("deinit")); - - RegularLocation Loc(dd); - if (dd->isImplicit()) - Loc.markAutoGenerated(); - - if (dd->requiresUnavailableDeclABICompatibilityStubs()) - emitApplyOfUnavailableCodeReached(); - - auto cd = cast(dd->getDeclContext()); - SILValue selfValue = emitSelfDeclForDestructor(dd->getImplicitSelfDecl()); - ManagedValue managedSelf; - if (selfValue->getOwnershipKind() == OwnershipKind::Unowned) { - managedSelf = ManagedValue::forUnownedObjectValue(selfValue); - } else { - managedSelf = ManagedValue::forBorrowedRValue(selfValue); - } - - auto ai = swift::getActorIsolation(dd); - auto actor = emitExecutor(Loc, ai, managedSelf); - if (actor) { - ExpectedExecutor = *actor; - } - - // Jump to the expected executor. - if (ExpectedExecutor) { - // For a synchronous function, check that we're on the same executor. - // Note: if we "know" that the code is completely Sendable-safe, this - // is unnecessary. The type checker will need to make this determination. - emitPreconditionCheckExpectedExecutor(Loc, ExpectedExecutor); - } - - // Create a basic block to jump to for the implicit destruction behavior - // of releasing the elements and calling the superclass destructor. - // We won't actually emit the block until we finish with the destructor body. - prepareEpilog(dd, std::nullopt, std::nullopt, CleanupLocation(Loc)); - // Emit the destructor body. + if (deinitBodyBB) + B.emitBlock(deinitBodyBB); emitProfilerIncrement(dd->getTypecheckedBody()); emitStmt(dd->getTypecheckedBody()); @@ -153,8 +104,6 @@ void SILGenFunction::emitDestroyingDestructor(DestructorDecl *dd) { if (!maybeReturnValue) return; - auto cleanupLoc = CleanupLocation(Loc); - // If we have a superclass, invoke its destructor. SILValue resultSelfValue; SILType objectPtrTy = SILType::getNativeObjectType(F.getASTContext()); @@ -208,7 +157,7 @@ void SILGenFunction::emitDestroyingDestructor(DestructorDecl *dd) { } // Release our members. - emitClassMemberDestruction(borrowedValue, cd, cleanupLoc); + emitClassMemberDestruction(borrowedValue, cd, cleanupLoc, finishBB); S.pop(); @@ -224,17 +173,15 @@ void SILGenFunction::emitDestroyingDestructor(DestructorDecl *dd) { B.createReturn(returnLoc, resultSelfValue); } -void SILGenFunction::emitDeallocatingDestructor(DestructorDecl *dd, - bool isIsolated) { +void SILGenFunction::emitDeallocatingDestructor(DestructorDecl *dd) { auto *nom = dd->getDeclContext()->getSelfNominalTypeDecl(); if (isa(nom)) - return emitDeallocatingClassDestructor(dd, isIsolated); + return emitDeallocatingClassDestructor(dd); assert(!nom->canBeCopyable()); return emitDeallocatingMoveOnlyDestructor(dd); } -void SILGenFunction::emitDeallocatingClassDestructor(DestructorDecl *dd, - bool isIsolated) { +void SILGenFunction::emitDeallocatingClassDestructor(DestructorDecl *dd) { MagicFunctionName = DeclName(SGM.M.getASTContext().getIdentifier("deinit")); // The deallocating destructor is always auto-generated. @@ -248,47 +195,47 @@ void SILGenFunction::emitDeallocatingClassDestructor(DestructorDecl *dd, SILValue initialSelfValue = emitSelfDeclForDestructor(dd->getImplicitSelfDecl()); - emitDistributedRemoteActorDeinit(initialSelfValue, dd, isIsolated, [=] { - // Form a reference to the destroying destructor. - SILDeclRef dtorConstant(dd, SILDeclRef::Kind::Destroyer); - auto classTy = initialSelfValue->getType(); + // Form a reference to the destroying destructor. + SILDeclRef dtorConstant(dd, SILDeclRef::Kind::Destroyer); + auto classTy = initialSelfValue->getType(); - auto subMap = F.getForwardingSubstitutionMap(); + auto subMap = F.getForwardingSubstitutionMap(); - ManagedValue dtorValue; - SILType dtorTy; - std::tie(dtorValue, dtorTy) = - emitSiblingMethodRef(loc, initialSelfValue, dtorConstant, subMap); + ManagedValue dtorValue; + SILType dtorTy; + std::tie(dtorValue, dtorTy) + = emitSiblingMethodRef(loc, initialSelfValue, dtorConstant, subMap); - // Call the destroying destructor. - SILValue selfForDealloc; - { - FullExpr CleanupScope(Cleanups, CleanupLocation(loc)); - ManagedValue borrowedSelf = emitManagedBeginBorrow(loc, initialSelfValue); - selfForDealloc = B.createApply(loc, dtorValue.forward(*this), subMap, - borrowedSelf.getUnmanagedValue()); - } + // Call the destroying destructor. + SILValue selfForDealloc; + { + FullExpr CleanupScope(Cleanups, CleanupLocation(loc)); + ManagedValue borrowedSelf = emitManagedBeginBorrow(loc, initialSelfValue); + selfForDealloc = B.createApply(loc, dtorValue.forward(*this), subMap, + borrowedSelf.getUnmanagedValue()); + } - // Balance out the +1 from the self argument using end_lifetime. - // - // The issue here is that: - // - // 1. Self is passed into deallocating deinits at +1. - // 2. Destroying deinits take in self as a +0 value that is then returned at - // +1. - // - // This means that the lifetime of self can not be modeled statically in a - // deallocating deinit without analyzing the body of the destroying deinit - // (something that violates semantic sil). Thus we add an artificial destroy - // of self before the actual destroy of self so that the verifier can - // understand that self is being properly balanced. - B.createEndLifetime(loc, initialSelfValue); + // Balance out the +1 from the self argument using end_lifetime. + // + // The issue here is that: + // + // 1. Self is passed into deallocating deinits at +1. + // 2. Destroying deinits take in self as a +0 value that is then returned at + // +1. + // + // This means that the lifetime of self can not be modeled statically in a + // deallocating deinit without analyzing the body of the destroying deinit + // (something that violates semantic sil). Thus we add an artificial destroy of + // self before the actual destroy of self so that the verifier can understand + // that self is being properly balanced. + B.createEndLifetime(loc, initialSelfValue); - // Deallocate the object. - selfForDealloc = B.createUncheckedRefCast(loc, selfForDealloc, classTy); - B.createDeallocRef(loc, selfForDealloc); + // Deallocate the object. + selfForDealloc = B.createUncheckedRefCast(loc, selfForDealloc, classTy); + B.createDeallocRef(loc, selfForDealloc); - }); + // Return. + B.createReturn(loc, emitEmptyTuple(loc)); } void SILGenFunction::emitDeallocatingMoveOnlyDestructor(DestructorDecl *dd) { @@ -336,85 +283,6 @@ void SILGenFunction::emitDeallocatingMoveOnlyDestructor(DestructorDecl *dd) { B.createReturn(loc, emitEmptyTuple(loc)); } -void SILGenFunction::emitIsolatingDestructor(DestructorDecl *dd) { - MagicFunctionName = DeclName(SGM.M.getASTContext().getIdentifier("deinit")); - - // The deallocating destructor is always auto-generated. - RegularLocation loc(dd); - loc.markAutoGenerated(); - - // Emit the prolog. - SILValue selfValue = emitSelfDeclForDestructor(dd->getImplicitSelfDecl()); - - // Remote actor proxies don't need isolation - // Emit check for remote actor before performing isolation - emitDistributedRemoteActorDeinit(selfValue, dd, false, [=] { - // Form a reference to the destroying destructor. - SILDeclRef dtorConstant(dd, SILDeclRef::Kind::IsolatedDeallocator); - auto classTy = selfValue->getType(); - auto classDecl = classTy.getASTType()->getAnyNominal(); - ManagedValue dtorValue; - SILType dtorTy; - auto subMap = classTy.getASTType()->getContextSubstitutionMap(classDecl); - std::tie(dtorValue, dtorTy) = - emitSiblingMethodRef(loc, selfValue, dtorConstant, subMap); - - // Get an executor - auto ai = swift::getActorIsolation(dd); - SILValue executor; - { - FullExpr CleanupScope(Cleanups, CleanupLocation(loc)); - auto actor = *emitExecutor( - loc, ai, ManagedValue::forUnmanagedOwnedValue(selfValue)); - executor = B.createExtractExecutor(loc, actor); - } - - // Get deinitOnExecutor - FuncDecl *swiftDeinitOnExecutorDecl = SGM.getDeinitOnExecutor(); - assert(swiftDeinitOnExecutorDecl && - "Failed to find swift_task_deinitOnExecutor function decl"); - SILFunction *swiftDeinitOnExecutorSILFunc = SGM.getFunction( - SILDeclRef(swiftDeinitOnExecutorDecl, SILDeclRef::Kind::Func), - NotForDefinition); - SILValue swiftDeinitOnExecutorFunc = - B.createFunctionRefFor(loc, swiftDeinitOnExecutorSILFunc); - - // Cast self to AnyObject preserving owned ownership - CanType selfType = selfValue->getType().getASTType(); - CanType anyObjectType = getASTContext().getAnyObjectType(); - SILType anyObjectLoweredType = - getTypeLowering(anyObjectType).getLoweredType(); - auto conformances = collectExistentialConformances( - selfType->getCanonicalType(), anyObjectType); - auto castedSelf = B.createInitExistentialRef( - loc, anyObjectLoweredType, selfType, selfValue, conformances); - - // Cast isolated deallocator to (__owned AnyObject) -> Void - auto workFuncType1 = SILFunctionType::get( - /*genericSig*/ nullptr, SILFunctionType::ExtInfo::getThin(), - SILCoroutineKind::None, ParameterConvention::Direct_Unowned, - {SILParameterInfo(anyObjectLoweredType.getASTType(), - ParameterConvention::Direct_Owned)}, - /*interfaceYields*/ {}, - /* results */ {}, - /*interfaceErrorResults*/ std::nullopt, - /* patternSubs */ {}, - /* invocationSubs */ {}, getASTContext()); - SILType workFuncType = SILType::getPrimitiveObjectType(workFuncType1); - SILValue dtx = dtorValue.getValue(); - auto castedDeallocator = - B.createConvertFunction(loc, dtx, workFuncType, false); - - auto wordTy = SILType::getBuiltinWordType(getASTContext()); - auto *flagsInst = - B.createIntegerLiteral(loc, wordTy, 0); - - // Schedule isolated execution - B.createApply(loc, swiftDeinitOnExecutorFunc, {}, - {castedSelf, castedDeallocator, executor, flagsInst}); - }); -} - void SILGenFunction::emitIVarDestroyer(SILDeclRef ivarDestroyer) { auto cd = cast(ivarDestroyer.getDecl()); RegularLocation loc(cd); @@ -447,7 +315,7 @@ void SILGenFunction::emitIVarDestroyer(SILDeclRef ivarDestroyer) { cleanupLoc, selfValue.forward(*this), OwnershipKind::Guaranteed); selfValue = emitManagedBorrowedRValueWithCleanup(guaranteedSelf); } - emitClassMemberDestruction(selfValue, cd, cleanupLoc); + emitClassMemberDestruction(selfValue, cd, cleanupLoc, /*finishBB=*/nullptr); } B.createReturn(loc, emitEmptyTuple(loc)); @@ -604,20 +472,10 @@ void SILGenFunction::emitRecursiveChainDestruction(ManagedValue selfValue, } } -void SILGenFunction::emitDestroyDefaultActor(CleanupLocation cleanupLoc, - SILValue selfValue) { - // TODO(distributed): we may need to call the distributed destroy here - // instead? - auto builtinName = getASTContext().getIdentifier( - getBuiltinName(BuiltinValueKind::DestroyDefaultActor)); - auto resultTy = SGM.Types.getEmptyTupleType(); - - B.createBuiltin(cleanupLoc, builtinName, resultTy, /*subs*/ {}, {selfValue}); -} - void SILGenFunction::emitClassMemberDestruction(ManagedValue selfValue, ClassDecl *cd, - CleanupLocation cleanupLoc) { + CleanupLocation cleanupLoc, + SILBasicBlock *finishBB) { assert(selfValue.getOwnershipKind() == OwnershipKind::Guaranteed); // Before we destroy all fields, we check if any of them are @@ -640,11 +498,22 @@ void SILGenFunction::emitClassMemberDestruction(ManagedValue selfValue, assert(recursiveLinks.size() == 1 && "Only linear recursion supported."); emitRecursiveChainDestruction(selfValue, cd, recursiveLinks[0], cleanupLoc); } + + if (finishBB) + B.createBranch(cleanupLoc, finishBB); } { + if (finishBB) + B.emitBlock(finishBB); + if (cd->isRootDefaultActor()) { - emitDestroyDefaultActor(cleanupLoc, selfValue.getValue()); + auto builtinName = getASTContext().getIdentifier( + getBuiltinName(BuiltinValueKind::DestroyDefaultActor)); + auto resultTy = SGM.Types.getEmptyTupleType(); + + B.createBuiltin(cleanupLoc, builtinName, resultTy, /*subs*/{}, + { selfValue.getValue() }); } } } diff --git a/lib/SILGen/SILGenDistributed.cpp b/lib/SILGen/SILGenDistributed.cpp index 60524cf4107..295eea38a62 100644 --- a/lib/SILGen/SILGenDistributed.cpp +++ b/lib/SILGen/SILGenDistributed.cpp @@ -90,36 +90,31 @@ static void initializeProperty(SILGenFunction &SGF, SILLocation loc, /// } /// \endverbatim void SILGenFunction::emitDistributedIfRemoteBranch(SILLocation Loc, - SILValue selfValue, + ManagedValue selfValue, Type selfTy, SILBasicBlock *isRemoteBB, SILBasicBlock *isLocalBB) { ASTContext &ctx = getASTContext(); - SILValue isRemoteResultUnwrapped; - { - FullExpr CleanupScope(Cleanups, CleanupLocation(Loc)); - ManagedValue borrowedSelf = emitManagedBeginBorrow(Loc, selfValue); + FuncDecl *isRemoteFn = ctx.getIsRemoteDistributedActor(); + assert(isRemoteFn && "Could not find 'is remote' function, is the " + "'Distributed' module available?"); - FuncDecl *isRemoteFn = ctx.getIsRemoteDistributedActor(); - assert(isRemoteFn && "Could not find 'is remote' function, is the " - "'Distributed' module available?"); + auto conformances = collectExistentialConformances( + selfTy->getCanonicalType(), ctx.getAnyObjectType()); - auto conformances = collectExistentialConformances( - selfTy->getCanonicalType(), ctx.getAnyObjectType()); + ManagedValue selfAnyObject = B.createInitExistentialRef( + Loc, + /*existentialType=*/getLoweredType(ctx.getAnyObjectType()), + /*formalConcreteType=*/selfTy->getCanonicalType(), + selfValue, conformances); + auto result = emitApplyOfLibraryIntrinsic( + Loc, isRemoteFn, SubstitutionMap(), {selfAnyObject}, SGFContext()); - ManagedValue selfAnyObject = B.createInitExistentialRef( - Loc, - /*existentialType=*/getLoweredType(ctx.getAnyObjectType()), - /*formalConcreteType=*/selfTy->getCanonicalType(), borrowedSelf, - conformances); - auto result = emitApplyOfLibraryIntrinsic( - Loc, isRemoteFn, SubstitutionMap(), {selfAnyObject}, SGFContext()); + SILValue isRemoteResult = std::move(result).forwardAsSingleValue(*this, Loc); + SILValue isRemoteResultUnwrapped = + emitUnwrapIntegerResult(Loc, isRemoteResult); - SILValue isRemoteResult = - std::move(result).forwardAsSingleValue(*this, Loc); - isRemoteResultUnwrapped = emitUnwrapIntegerResult(Loc, isRemoteResult); - } B.createCondBranch(Loc, isRemoteResultUnwrapped, isRemoteBB, isLocalBB); } @@ -546,3 +541,100 @@ void SILGenFunction::emitDistributedActorSystemResignIDCall( SILType(), { idRef }); } + +void +SILGenFunction::emitConditionalResignIdentityCall(SILLocation loc, + ClassDecl *actorDecl, + ManagedValue actorSelf, + SILBasicBlock *continueBB, + SILBasicBlock *finishBB) { + assert(actorDecl->isDistributedActor() && + "only distributed actors have actorSystem lifecycle hooks in deinit"); + assert(continueBB && finishBB && + "need valid continue and finish basic blocks"); + + auto selfTy = F.mapTypeIntoContext(actorDecl->getDeclaredInterfaceType()); + + // we only system.resignID if we are a local actor, + // and thus the address was created by system.assignID. + auto isRemoteBB = createBasicBlock("isRemoteBB"); + auto isLocalBB = createBasicBlock("isLocalBB"); + + // if __isRemoteActor(self) { + // ... + // } else { + // ... + // } + emitDistributedIfRemoteBranch(loc, + actorSelf, selfTy, + /*if remote*/isRemoteBB, + /*if local*/isLocalBB); + + // if remote, return early; the user defined deinit should not run. + { + B.emitBlock(isRemoteBB); + B.createBranch(loc, finishBB); + } + + // if local, resign identity. + { + B.emitBlock(isLocalBB); + + emitDistributedActorSystemResignIDCall(loc, actorDecl, actorSelf); + + B.createBranch(loc, continueBB); + } +} + +/******************************************************************************/ +/******************* DISTRIBUTED DEINIT: class memberwise destruction *********/ +/******************************************************************************/ + +void SILGenFunction::emitDistributedActorClassMemberDestruction( + SILLocation cleanupLoc, ManagedValue selfValue, ClassDecl *cd, + SILBasicBlock *normalMemberDestroyBB, + SILBasicBlock *remoteMemberDestroyBB, + SILBasicBlock *finishBB) { + auto selfTy = cd->getDeclaredInterfaceType(); + + Scope scope(Cleanups, CleanupLocation(cleanupLoc)); + + auto isLocalBB = createBasicBlock("isLocalBB"); + + // if __isRemoteActor(self) { + // ... + // } else { + // ... + // } + emitDistributedIfRemoteBranch(cleanupLoc, + selfValue, selfTy, + /*if remote*/remoteMemberDestroyBB, + /*if local*/isLocalBB); + + // // if __isRemoteActor(self) + // { + // // destroy only self.id and self.actorSystem + // } + { + B.emitBlock(remoteMemberDestroyBB); + + for (VarDecl *vd : cd->getStoredProperties()) { + if (getActorIsolation(vd) == ActorIsolation::ActorInstance) + continue; + + destroyClassMember(cleanupLoc, selfValue, vd); + } + + B.createBranch(cleanupLoc, finishBB); + } + + // // else (local distributed actor) + // { + // + // } + { + B.emitBlock(isLocalBB); + + B.createBranch(cleanupLoc, normalMemberDestroyBB); + } +} diff --git a/lib/SILGen/SILGenFunction.cpp b/lib/SILGen/SILGenFunction.cpp index a9c5125e354..dddb9f3f2af 100644 --- a/lib/SILGen/SILGenFunction.cpp +++ b/lib/SILGen/SILGenFunction.cpp @@ -180,7 +180,6 @@ DeclName SILGenModule::getMagicFunctionName(SILDeclRef ref) { case SILDeclRef::Kind::Allocator: return getMagicFunctionName(cast(ref.getDecl())); case SILDeclRef::Kind::Deallocator: - case SILDeclRef::Kind::IsolatedDeallocator: case SILDeclRef::Kind::Destroyer: return getMagicFunctionName(cast(ref.getDecl())); case SILDeclRef::Kind::GlobalAccessor: diff --git a/lib/SILGen/SILGenFunction.h b/lib/SILGen/SILGenFunction.h index aed6b036101..47050ab7e43 100644 --- a/lib/SILGen/SILGenFunction.h +++ b/lib/SILGen/SILGenFunction.h @@ -815,20 +815,16 @@ public: /// Generates code for class/move only deallocating destructor. This calls the /// destroying destructor and then deallocates 'self'. - void emitDeallocatingDestructor(DestructorDecl *dd, bool isIsolated); + void emitDeallocatingDestructor(DestructorDecl *dd); - /// Generates code for a class (isolated-)deallocating destructor. This + /// Generates code for a class deallocating destructor. This /// calls the destroying destructor and then deallocates 'self'. - void emitDeallocatingClassDestructor(DestructorDecl *dd, bool isIsolated); + void emitDeallocatingClassDestructor(DestructorDecl *dd); /// Generates code for the deinit of the move only type and destroys all of /// the fields. void emitDeallocatingMoveOnlyDestructor(DestructorDecl *dd); - /// Generates code for a class deallocating destructor that switches executor - /// and calls isolated deallocating destuctor on the right executor. - void emitIsolatingDestructor(DestructorDecl *dd); - /// Whether we are inside a constructor whose hops are injected by /// definite initialization. bool isCtorWithHopsInjectedByDefiniteInit(); @@ -906,8 +902,12 @@ public: /// /// \param selfValue The 'self' value. /// \param cd The class declaration whose members are being destroyed. + /// \param finishBB If set, used as the basic block after members have been + /// destroyed, and we're ready to perform final cleanups + /// before returning. void emitClassMemberDestruction(ManagedValue selfValue, ClassDecl *cd, - CleanupLocation cleanupLoc); + CleanupLocation cleanupLoc, + SILBasicBlock* finishBB); /// Generates code to destroy the instance variables of a move only non-class /// nominal type. @@ -2522,8 +2522,9 @@ public: /// corresponding SIL function for it. void emitDistributedActorFactory(FuncDecl *fd); // TODO(distributed): this is the "resolve" - void emitDistributedIfRemoteBranch(SILLocation Loc, SILValue selfValue, - Type selfTy, SILBasicBlock *isRemoteBB, + void emitDistributedIfRemoteBranch(SILLocation Loc, + ManagedValue selfValue, Type selfTy, + SILBasicBlock *isRemoteBB, SILBasicBlock *isLocalBB); /// Notify transport that actor has initialized successfully, @@ -2546,14 +2547,22 @@ public: /// \param actorSelf the SIL value representing the distributed actor instance void emitDistributedActorSystemResignIDCall(SILLocation loc, ClassDecl *actorDecl, ManagedValue actorSelf); + + /// Emit code that tests whether the distributed actor is local, and if so, + /// resigns the distributed actor's identity. + /// \param continueBB the target block where execution will continue after + /// the conditional call, whether actor is local or remote. + void emitConditionalResignIdentityCall(SILLocation loc, + ClassDecl *actorDecl, + ManagedValue actorSelf, + SILBasicBlock *continueBB, + SILBasicBlock *finishBB); - /// Emits check for remote actor and a branch that implements deallocating - /// deinit for remote proxy. Calls \p emitLocalDeinit to generate branch for - /// local actor. - void - emitDistributedRemoteActorDeinit(SILValue selfValue, DestructorDecl *dd, - bool isIsolated, - llvm::function_ref emitLocalDeinit); + void emitDistributedActorClassMemberDestruction( + SILLocation cleanupLoc, ManagedValue selfValue, ClassDecl *cd, + SILBasicBlock *normalMemberDestroyBB, + SILBasicBlock *remoteMemberDestroyBB, + SILBasicBlock *finishBB); //===--------------------------------------------------------------------===// // Declarations @@ -2658,9 +2667,6 @@ public: /// Destroy the class member. void destroyClassMember(SILLocation L, ManagedValue selfValue, VarDecl *D); - /// Destroy the default actor implementation. - void emitDestroyDefaultActor(CleanupLocation cleanupLoc, SILValue selfValue); - /// Enter a cleanup to deallocate a stack variable. CleanupHandle enterDeallocStackCleanup(SILValue address); diff --git a/lib/SILOptimizer/UtilityPasses/Link.cpp b/lib/SILOptimizer/UtilityPasses/Link.cpp index d124f9ddb05..866428427c1 100644 --- a/lib/SILOptimizer/UtilityPasses/Link.cpp +++ b/lib/SILOptimizer/UtilityPasses/Link.cpp @@ -63,9 +63,6 @@ public: #define UNKNOWN_MEMEFFECTS #include "swift/Runtime/RuntimeFunctions.def" - - // swift_retainCount is not part of private contract between the compiler and runtime, but we still need to link it - linkEmbeddedRuntimeFunctionByName("swift_retainCount", { RefCounting }); } void linkEmbeddedRuntimeFunctionByName(StringRef name, diff --git a/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp index cffbdbcc883..67a55915a99 100644 --- a/lib/Sema/TypeCheckAttr.cpp +++ b/lib/Sema/TypeCheckAttr.cpp @@ -110,18 +110,6 @@ public: return true; } - void diagnoseIsolatedDeinitInValueTypes(DeclAttribute *attr) { - if (isa(D)) { - if (auto nominal = dyn_cast(D->getDeclContext())) { - if (!isa(nominal)) { - // only classes and actors can have isolated deinit. - diagnoseAndRemoveAttr(attr, diag::isolated_deinit_on_value_type); - return; - } - } - } - } - template InFlightDiagnostic diagnose(ArgTypes &&... Args) const { return Ctx.Diags.diagnose(std::forward(Args)...); @@ -341,7 +329,6 @@ public: void visitReasyncAttr(ReasyncAttr *attr); void visitNonisolatedAttr(NonisolatedAttr *attr); - void visitIsolatedAttr(IsolatedAttr *attr); void visitNoImplicitCopyAttr(NoImplicitCopyAttr *attr); @@ -4320,7 +4307,6 @@ void AttributeChecker::visitCustomAttr(CustomAttr *attr) { // If the nominal type is a global actor, let the global actor attribute // retrieval request perform checking for us. if (nominal->isGlobalActor()) { - diagnoseIsolatedDeinitInValueTypes(attr); (void)D->getGlobalActorAttr(); if (auto value = dyn_cast(D)) { (void)getActorIsolation(value); @@ -7249,8 +7235,6 @@ void AttributeChecker::visitNonisolatedAttr(NonisolatedAttr *attr) { } } - diagnoseIsolatedDeinitInValueTypes(attr); - if (auto VD = dyn_cast(D)) { //'nonisolated(unsafe)' is meaningless for computed properties, functions etc. auto var = dyn_cast(VD); @@ -7267,10 +7251,6 @@ void AttributeChecker::visitNonisolatedAttr(NonisolatedAttr *attr) { } } -void AttributeChecker::visitIsolatedAttr(IsolatedAttr *attr) { - diagnoseIsolatedDeinitInValueTypes(attr); -} - void AttributeChecker::visitGlobalActorAttr(GlobalActorAttr *attr) { auto nominal = dyn_cast(D); if (!nominal) @@ -7285,8 +7265,6 @@ void AttributeChecker::visitGlobalActorAttr(GlobalActorAttr *attr) { return; } - diagnoseIsolatedDeinitInValueTypes(attr); - (void)nominal->isGlobalActor(); } diff --git a/lib/Sema/TypeCheckConcurrency.cpp b/lib/Sema/TypeCheckConcurrency.cpp index 63f3a8d5daa..617ac6bc0b8 100644 --- a/lib/Sema/TypeCheckConcurrency.cpp +++ b/lib/Sema/TypeCheckConcurrency.cpp @@ -38,8 +38,6 @@ using namespace swift; -static ActorIsolation getOverriddenIsolationFor(const ValueDecl *value); - /// Determine whether it makes sense to infer an attribute in the given /// context. static bool shouldInferAttributeInContext(const DeclContext *dc) { @@ -129,17 +127,11 @@ bool swift::usesFlowSensitiveIsolation(AbstractFunctionDecl const *fn) { if (!fn) return false; - // Only designated constructors or nonisolated destructors use this kind of - // isolation. + // Only designated constructors or destructors use this kind of isolation. if (auto const* ctor = dyn_cast(fn)) { if (!ctor->isDesignatedInit()) return false; - } else if (auto const *dtor = dyn_cast(fn)) { - if (getActorIsolation(const_cast(dtor)) - .isActorIsolated()) { - return false; - } - } else { + } else if (!isa(fn)) { return false; } @@ -438,8 +430,7 @@ GlobalActorAttributeRequest::evaluate( } } else if (isa(decl)) { // Extensions are okay. - } else if (isa(decl) || isa(decl) || - isa(decl)) { + } else if (isa(decl) || isa(decl)) { // None of the accessors/addressors besides a getter are allowed // to have a global actor attribute. if (auto *accessor = dyn_cast(decl)) { @@ -514,9 +505,9 @@ Type swift::getExplicitGlobalActor(ClosureExpr *closure) { /// A 'let' declaration is safe across actors if it is either /// nonisolated or it is accessed from within the same module. -static bool varIsSafeAcrossActors(const ModuleDecl *fromModule, VarDecl *var, +static bool varIsSafeAcrossActors(const ModuleDecl *fromModule, + VarDecl *var, const ActorIsolation &varIsolation, - std::optional actorInstance, ActorReferenceResult::Options &options) { bool accessWithinModule = @@ -563,11 +554,6 @@ static bool varIsSafeAcrossActors(const ModuleDecl *fromModule, VarDecl *var, return false; } - // If it's distributed, but known to be local, it's ok - // TODO: Check if this can be obtained from the isolation, without a need for separate argument - if (actorInstance && actorInstance->isKnownToBeLocal()) { - return true; - } // If it's distributed, generally variable access is not okay... if (auto nominalParent = var->getDeclContext()->getSelfNominalTypeDecl()) { if (nominalParent->isDistributedActor()) @@ -594,7 +580,7 @@ bool swift::isLetAccessibleAnywhere(const ModuleDecl *fromModule, VarDecl *let, ActorReferenceResult::Options &options) { auto isolation = getActorIsolation(let); - return varIsSafeAcrossActors(fromModule, let, isolation, std::nullopt, options); + return varIsSafeAcrossActors(fromModule, let, isolation, options); } bool swift::isLetAccessibleAnywhere(const ModuleDecl *fromModule, @@ -1746,42 +1732,32 @@ static bool wasLegacyEscapingUseRestriction(AbstractFunctionDecl *fn) { assert(fn->getDeclContext()->getSelfClassDecl()->isAnyActor()); assert(isa(fn) || isa(fn)); - auto isolationKind = getActorIsolation(fn).getKind(); - if (isa(fn)) { - switch (isolationKind) { - case ActorIsolation::GlobalActor: - case ActorIsolation::ActorInstance: - // Isolated deinits did not exist before - return false; - case ActorIsolation::Nonisolated: - case ActorIsolation::NonisolatedUnsafe: - case ActorIsolation::Unspecified: - assert(!fn->hasAsync()); - return true; - case ActorIsolation::Erased: - llvm_unreachable("destructor decl cannot have erased isolation"); - } - } else if (auto *ctor = dyn_cast(fn)) { - switch (isolationKind) { + // according to today's isolation, determine whether it use to have the + // escaping-use restriction + switch (getActorIsolation(fn).getKind()) { case ActorIsolation::Nonisolated: case ActorIsolation::NonisolatedUnsafe: case ActorIsolation::GlobalActor: // convenience inits did not have the restriction. - if (ctor->isConvenienceInit()) - return false; - break; + if (auto *ctor = dyn_cast(fn)) + if (ctor->isConvenienceInit()) + return false; + + break; // goto basic case + case ActorIsolation::ActorInstance: // none of these had the restriction affect them. assert(fn->hasAsync()); return false; + case ActorIsolation::Erased: llvm_unreachable("function decl cannot have erased isolation"); case ActorIsolation::Unspecified: // this is basically just objc-marked inits. break; - } - } + }; + return !(fn->hasAsync()); // basic case: not async = had restriction. } @@ -4698,6 +4674,23 @@ ActorIsolation swift::determineClosureActorIsolation( return checker.determineClosureIsolation(closure); } +/// Determine whethere there is an explicit isolation attribute +/// of any kind. +static bool hasExplicitIsolationAttribute(const Decl *decl) { + if (auto nonisolatedAttr = + decl->getAttrs().getAttribute()) { + if (!nonisolatedAttr->isImplicit()) + return true; + } + + if (auto globalActorAttr = decl->getGlobalActorAttr()) { + if (!globalActorAttr->first->isImplicit()) + return true; + } + + return false; +} + /// Determine actor isolation solely from attributes. /// /// \returns the actor isolation determined from attributes alone (with no @@ -4708,7 +4701,6 @@ getIsolationFromAttributes(const Decl *decl, bool shouldDiagnose = true, bool onlyExplicit = false) { // Look up attributes on the declaration that can affect its actor isolation. // If any of them are present, use that attribute. - auto isolatedAttr = decl->getAttrs().getAttribute(); auto nonisolatedAttr = decl->getAttrs().getAttribute(); auto globalActorAttr = decl->getGlobalActorAttr(); @@ -4716,60 +4708,23 @@ getIsolationFromAttributes(const Decl *decl, bool shouldDiagnose = true, if (onlyExplicit) { if (nonisolatedAttr && nonisolatedAttr->isImplicit()) nonisolatedAttr = nullptr; - if (isolatedAttr && isolatedAttr->isImplicit()) - isolatedAttr = nullptr; if (globalActorAttr && globalActorAttr->first->isImplicit()) globalActorAttr = std::nullopt; } - unsigned numIsolationAttrs = (isolatedAttr ? 1 : 0) + - (nonisolatedAttr ? 1 : 0) + - (globalActorAttr ? 1 : 0); - if (numIsolationAttrs == 0) { - if (isa(decl) && !decl->isImplicit()) { - return ActorIsolation::forNonisolated(false); - } + unsigned numIsolationAttrs = + (nonisolatedAttr ? 1 : 0) + (globalActorAttr ? 1 : 0); + if (numIsolationAttrs == 0) return std::nullopt; - } // Only one such attribute is valid, but we only actually care of one of // them is a global actor. if (numIsolationAttrs > 1 && globalActorAttr && shouldDiagnose) { - struct NameAndRange { - StringRef name; - SourceRange range; - - NameAndRange(StringRef _name, SourceRange _range) - : name(_name), range(_range) {} - }; - - llvm::SmallVector attributes; - if (isolatedAttr) { - attributes.push_back(NameAndRange(isolatedAttr->getAttrName(), - isolatedAttr->getRangeWithAt())); - } - if (nonisolatedAttr) { - attributes.push_back(NameAndRange(nonisolatedAttr->getAttrName(), - nonisolatedAttr->getRangeWithAt())); - } - if (globalActorAttr) { - attributes.push_back( - NameAndRange(globalActorAttr->second->getName().str(), - globalActorAttr->first->getRangeWithAt())); - } - if (attributes.size() == 3) { - decl->diagnose(diag::actor_isolation_multiple_attr_3, decl, - attributes[0].name, attributes[1].name, attributes[2].name) - .highlight(attributes[0].range) - .highlight(attributes[1].range) - .highlight(attributes[2].range); - } else { - assert(attributes.size() == 2); - decl->diagnose(diag::actor_isolation_multiple_attr_2, decl, - attributes[0].name, attributes[1].name) - .highlight(attributes[0].range) - .highlight(attributes[1].range); - } + decl->diagnose(diag::actor_isolation_multiple_attr, decl, + nonisolatedAttr->getAttrName(), + globalActorAttr->second->getName().str()) + .highlight(nonisolatedAttr->getRangeWithAt()) + .highlight(globalActorAttr->first->getRangeWithAt()); } // If the declaration is explicitly marked 'nonisolated', report it as @@ -4778,54 +4733,6 @@ getIsolationFromAttributes(const Decl *decl, bool shouldDiagnose = true, return ActorIsolation::forNonisolated(nonisolatedAttr->isUnsafe()); } - // If the declaration is explicitly marked 'isolated', infer actor isolation - // from the context. Currently applies only to DestructorDecl - if (isolatedAttr) { - assert(isa(decl)); - - auto dc = decl->getDeclContext(); - auto selfTypeDecl = dc->getSelfNominalTypeDecl(); - std::optional result; - if (selfTypeDecl) { - if (selfTypeDecl->isAnyActor()) { - result = ActorIsolation::forActorInstanceSelf(selfTypeDecl); - } else { - // If the declaration is in an extension that has one of the isolation - // attributes, use that. - if (auto ext = dyn_cast(dc)) { - result = getIsolationFromAttributes(ext); - } - - if (!result) { - result = getActorIsolation(selfTypeDecl); - } - } - - if (!result || !result->isActorIsolated()) { - if (shouldDiagnose) { - ASTContext &ctx = decl->getASTContext(); - ctx.Diags.diagnose(isolatedAttr->getLocation(), - diag::isolated_deinit_no_isolation, - selfTypeDecl->getName()); - } - // Try to use isolation of the overridden decl as a recovery strategy. - // This prevents additions errors about mismatched isolation. - if (auto value = dyn_cast(decl)) { - ValueDecl *overriddenValue = value->getOverriddenDeclOrSuperDeinit(); - if (overriddenValue) { - // use the overridden decl's iso as the default isolation for this - // decl. - auto overriddenIsolation = getOverriddenIsolationFor(value); - if (overriddenIsolation.isActorIsolated()) { - result = overriddenIsolation; - } - } - } - } - } - return result; - } - // If the declaration is marked with a global actor, report it as being // part of that global actor. if (globalActorAttr) { @@ -5186,6 +5093,7 @@ getMemberIsolationPropagation(const ValueDecl *value) { case DeclKind::OpaqueType: case DeclKind::Param: case DeclKind::Module: + case DeclKind::Destructor: case DeclKind::EnumCase: case DeclKind::EnumElement: case DeclKind::Macro: @@ -5198,13 +5106,6 @@ getMemberIsolationPropagation(const ValueDecl *value) { case DeclKind::Constructor: return MemberIsolationPropagation::AnyIsolation; - case DeclKind::Destructor: - if (value->getAttrs().getAttribute()) { - return MemberIsolationPropagation::AnyIsolation; - } else { - return std::nullopt; - } - case DeclKind::Func: case DeclKind::Accessor: case DeclKind::Subscript: @@ -5371,8 +5272,8 @@ namespace { /// Return the isolation of the declaration overridden by this declaration, /// in the context of the -static ActorIsolation getOverriddenIsolationFor(const ValueDecl *value) { - auto overridden = value->getOverriddenDeclOrSuperDeinit(); +static ActorIsolation getOverriddenIsolationFor(ValueDecl *value) { + auto overridden = value->getOverriddenDecl(); assert(overridden && "Doesn't have an overridden declaration"); auto isolation = getActorIsolation(overridden); @@ -5417,16 +5318,9 @@ static OverrideIsolationResult validOverrideIsolation( auto declContext = value->getInnermostDeclContext(); auto &ctx = declContext->getASTContext(); - // Normally we are checking if overriding declaration can be called by calling - // overriden declaration. But in case of destructors, overriden declaration is - // always callable by definition and we are checking that subclass deinit can - // call super deinit. - bool isDtor = isa(value); - auto refResult = ActorReferenceResult::forReference( - valueRef, SourceLoc(), declContext, std::nullopt, std::nullopt, - isDtor ? overriddenIsolation : isolation, - isDtor ? isolation : overriddenIsolation); + valueRef, SourceLoc(), declContext, std::nullopt, std::nullopt, isolation, + overriddenIsolation); switch (refResult) { case ActorReferenceResult::SameConcurrencyDomain: return OverrideIsolationResult::Allowed; @@ -5483,13 +5377,6 @@ static std::optional getIsolatedParamIndex(ValueDecl *value) { return std::nullopt; } -static bool belongsToActor(ValueDecl *value) { - if (auto nominal = value->getDeclContext()->getSelfNominalTypeDecl()) { - return nominal->isAnyActor(); - } - return false; -} - /// Verifies rules about `isolated` parameters for the given decl. There is more /// checking about these in TypeChecker::checkParameterList. /// @@ -5523,46 +5410,10 @@ static void checkDeclWithIsolatedParameter(ValueDecl *value) { } } -static void addAttributesForActorIsolation(ValueDecl *value, - ActorIsolation isolation) { - ASTContext &ctx = value->getASTContext(); - switch (isolation) { - case ActorIsolation::Nonisolated: - case ActorIsolation::NonisolatedUnsafe: { - value->getAttrs().add(new (ctx) NonisolatedAttr( - isolation == ActorIsolation::NonisolatedUnsafe, /*implicit=*/true)); - break; - } - case ActorIsolation::GlobalActor: { - auto typeExpr = TypeExpr::createImplicit(isolation.getGlobalActor(), ctx); - auto attr = - CustomAttr::create(ctx, SourceLoc(), typeExpr, /*implicit=*/true); - value->getAttrs().add(attr); - - if (isolation.preconcurrency() && - !value->getAttrs().hasAttribute()) { - auto preconcurrency = new (ctx) PreconcurrencyAttr(/*isImplicit*/ true); - value->getAttrs().add(preconcurrency); - } - break; - } - case ActorIsolation::Erased: - llvm_unreachable("cannot add attributes for erased isolation"); - case ActorIsolation::ActorInstance: { - // Nothing to do. Default value for actors. - assert(belongsToActor(value)); - break; - } - case ActorIsolation::Unspecified: { - // Nothing to do. Default value for non-actors. - assert(!belongsToActor(value)); - break; - } - } -} - InferredActorIsolation ActorIsolationRequest::evaluate( Evaluator &evaluator, ValueDecl *value) const { + auto &ctx = value->getASTContext(); + // If this declaration has actor-isolated "self", it's isolated to that // actor. if (evaluateOrDefault(evaluator, HasIsolatedSelfRequest{value}, false)) { @@ -5596,7 +5447,6 @@ InferredActorIsolation ActorIsolationRequest::evaluate( } auto isolationFromAttr = getIsolationFromAttributes(value); - ASTContext &ctx = value->getASTContext(); if (isolationFromAttr && isolationFromAttr->preconcurrency() && !value->getAttrs().hasAttribute()) { auto preconcurrency = @@ -5623,7 +5473,6 @@ InferredActorIsolation ActorIsolationRequest::evaluate( }; } } - // If this declaration has one of the actor isolation attributes, report // that. if (isolationFromAttr) { @@ -5658,7 +5507,7 @@ InferredActorIsolation ActorIsolationRequest::evaluate( // Look for and remember the overridden declaration's isolation. std::optional overriddenIso; - ValueDecl *overriddenValue = value->getOverriddenDeclOrSuperDeinit(); + ValueDecl *overriddenValue = value->getOverriddenDecl(); if (overriddenValue) { // use the overridden decl's iso as the default isolation for this decl. defaultIsolation = getOverriddenIsolationFor(value); @@ -5708,15 +5557,25 @@ InferredActorIsolation ActorIsolationRequest::evaluate( inferred.preconcurrency()); } - // Add nonisolated attribute - addAttributesForActorIsolation(value, inferred); + value->getAttrs().add(new (ctx) NonisolatedAttr( + inferred == ActorIsolation::NonisolatedUnsafe, /*implicit=*/true)); break; case ActorIsolation::Erased: llvm_unreachable("cannot infer erased isolation"); + case ActorIsolation::GlobalActor: { - // Add global actor attribute - addAttributesForActorIsolation(value, inferred); + auto typeExpr = TypeExpr::createImplicit(inferred.getGlobalActor(), ctx); + auto attr = + CustomAttr::create(ctx, SourceLoc(), typeExpr, /*implicit=*/true); + value->getAttrs().add(attr); + + if (inferred.preconcurrency() && + !value->getAttrs().hasAttribute()) { + auto preconcurrency = new (ctx) PreconcurrencyAttr(/*isImplicit*/ true); + value->getAttrs().add(preconcurrency); + } + break; } @@ -5962,12 +5821,8 @@ bool HasIsolatedSelfRequest::evaluate( // Check whether this member can be isolated to an actor at all. auto memberIsolation = getMemberIsolationPropagation(value); - if (!memberIsolation) { - // Actors don't have inheritance (except inheriting from NSObject), - // but if it were introduced, we would need to check for isolation - // of the deinit in the super class. + if (!memberIsolation) return false; - } switch (*memberIsolation) { case MemberIsolationPropagation::GlobalActor: @@ -5979,15 +5834,13 @@ bool HasIsolatedSelfRequest::evaluate( // Check whether the default isolation was overridden by any attributes on // this declaration. - auto attrIsolation = getIsolationFromAttributes(value); + if (getIsolationFromAttributes(value)) + return false; + // ... or its extension context. - if (!attrIsolation) { - if (auto ext = dyn_cast(dc)) { - attrIsolation = getIsolationFromAttributes(ext); - } - } - if (attrIsolation) { - return attrIsolation == ActorIsolation::forActorInstanceSelf(selfTypeDecl); + if (auto ext = dyn_cast(dc)) { + if (getIsolationFromAttributes(ext)) + return false; } // If this is a variable, check for a property wrapper that alters its @@ -6086,7 +5939,7 @@ void swift::checkOverrideActorIsolation(ValueDecl *value) { if (isa(value)) return; - auto overridden = value->getOverriddenDeclOrSuperDeinit(); + auto overridden = value->getOverriddenDecl(); if (!overridden) return; @@ -6235,14 +6088,14 @@ bool swift::contextRequiresStrictConcurrencyChecking( } else if (auto decl = dc->getAsDecl()) { // If any isolation attributes are present, we're using concurrency // features. - if (decl->hasExplicitIsolationAttribute()) + if (hasExplicitIsolationAttribute(decl)) return true; // Extensions of explicitly isolated types are using concurrency // features. if (auto *extension = dyn_cast(decl)) { auto *nominal = extension->getExtendedNominal(); - if (nominal && nominal->hasExplicitIsolationAttribute() && + if (nominal && hasExplicitIsolationAttribute(nominal) && !getActorIsolation(nominal).preconcurrency()) return true; } @@ -6255,7 +6108,7 @@ bool swift::contextRequiresStrictConcurrencyChecking( // If we're in an accessor declaration, also check the storage // declaration. if (auto accessor = dyn_cast(decl)) { - if (accessor->getStorage()->hasExplicitIsolationAttribute()) + if (hasExplicitIsolationAttribute(accessor->getStorage())) return true; } } @@ -7215,7 +7068,7 @@ static ActorIsolation getActorIsolationForReference(ValueDecl *decl, if (auto var = dyn_cast(decl)) { auto *fromModule = fromDC->getParentModule(); ActorReferenceResult::Options options = std::nullopt; - if (varIsSafeAcrossActors(fromModule, var, declIsolation, std::nullopt, options) && + if (varIsSafeAcrossActors(fromModule, var, declIsolation, options) && var->getTypeInContext()->isSendableType()) return ActorIsolation::forNonisolated(/*unsafe*/false); @@ -7278,12 +7131,12 @@ static bool isNonValueReference(const ValueDecl *value) { case DeclKind::PrecedenceGroup: case DeclKind::PrefixOperator: case DeclKind::TopLevelCode: + case DeclKind::Destructor: case DeclKind::MacroExpansion: return true; case DeclKind::EnumElement: case DeclKind::Constructor: - case DeclKind::Destructor: case DeclKind::Param: case DeclKind::Var: case DeclKind::Accessor: @@ -7322,8 +7175,8 @@ bool swift::isAccessibleAcrossActors( // 'let' declarations are immutable, so some of them can be accessed across // actors. if (auto var = dyn_cast(value)) { - return varIsSafeAcrossActors(fromDC->getParentModule(), var, isolation, - actorInstance, options); + return varIsSafeAcrossActors( + fromDC->getParentModule(), var, isolation, options); } return false; diff --git a/lib/Sema/TypeCheckDeclOverride.cpp b/lib/Sema/TypeCheckDeclOverride.cpp index 6134230605f..964701b1b4b 100644 --- a/lib/Sema/TypeCheckDeclOverride.cpp +++ b/lib/Sema/TypeCheckDeclOverride.cpp @@ -1570,7 +1570,6 @@ namespace { UNINTERESTING_ATTR(Indirect) UNINTERESTING_ATTR(InheritsConvenienceInitializers) UNINTERESTING_ATTR(Inline) - UNINTERESTING_ATTR(Isolated) UNINTERESTING_ATTR(Optimize) UNINTERESTING_ATTR(Exclusivity) UNINTERESTING_ATTR(NoLocks) diff --git a/lib/Sema/TypeCheckDeclPrimary.cpp b/lib/Sema/TypeCheckDeclPrimary.cpp index 1725b3b2205..48c5cee00bf 100644 --- a/lib/Sema/TypeCheckDeclPrimary.cpp +++ b/lib/Sema/TypeCheckDeclPrimary.cpp @@ -2308,7 +2308,8 @@ public: (void) VD->getFormalAccess(); // Compute overrides. - checkOverrideActorIsolation(VD); + if (!VD->getOverriddenDecls().empty()) + checkOverrideActorIsolation(VD); // Check whether the member is @objc or dynamic. (void) VD->isObjC(); diff --git a/lib/Sema/TypeCheckDistributed.cpp b/lib/Sema/TypeCheckDistributed.cpp index aa470639a75..31776410ed0 100644 --- a/lib/Sema/TypeCheckDistributed.cpp +++ b/lib/Sema/TypeCheckDistributed.cpp @@ -729,11 +729,6 @@ void TypeChecker::checkDistributedActor(SourceFile *SF, NominalTypeDecl *nominal // --- Ensure 'distributed func' all thunks if (auto func = dyn_cast(member)) { - if (auto dtor = dyn_cast(func)) { - ASTContext &C = dtor->getASTContext(); - auto selfDecl = dtor->getImplicitSelfDecl(); - selfDecl->getAttrs().add(new (C) KnownToBeLocalAttr(true)); - } if (!func->isDistributed()) continue; diff --git a/stdlib/public/CompatibilityOverride/CompatibilityOverrideConcurrency.def b/stdlib/public/CompatibilityOverride/CompatibilityOverrideConcurrency.def index d10b42d6dc4..e8d4c68eecb 100644 --- a/stdlib/public/CompatibilityOverride/CompatibilityOverrideConcurrency.def +++ b/stdlib/public/CompatibilityOverride/CompatibilityOverrideConcurrency.def @@ -142,11 +142,6 @@ OVERRIDE_ACTOR(task_switch, void, TaskContinuationFunction *resumeFunction, SerialExecutorRef newExecutor), (resumeToContext, resumeFunction, newExecutor)) -OVERRIDE_ACTOR(task_deinitOnExecutor, void, - SWIFT_EXPORT_FROM(swift_Concurrency), SWIFT_CC(swift), swift::, - (void *object, DeinitWorkFunction *work, SerialExecutorRef newExecutor, size_t flags), - (object, work, newExecutor, flags)) - OVERRIDE_TASK(task_create_common, AsyncTaskAndContext, SWIFT_EXPORT_FROM(swift_Concurrency), SWIFT_CC(swift), swift::, (size_t taskCreateFlags, diff --git a/stdlib/public/Concurrency/Actor.cpp b/stdlib/public/Concurrency/Actor.cpp index a0e2d2cb4b1..8efaee575d5 100644 --- a/stdlib/public/Concurrency/Actor.cpp +++ b/stdlib/public/Concurrency/Actor.cpp @@ -322,7 +322,7 @@ bool _task_serialExecutor_isSameExclusiveExecutionContext( // allowed to crash, because it is used to power "log warnings" data race // detector. This mode is going away in Swift 6, but until then we allow this. // This override exists primarily to be able to test both code-paths. -enum IsCurrentExecutorCheckMode : unsigned { +enum IsCurrentExecutorCheckMode: unsigned { /// The default mode when an app was compiled against "new" enough SDK. /// It allows crashing in isCurrentExecutor, and calls into `checkIsolated`. Swift6_UseCheckIsolated_AllowCrash, @@ -333,6 +333,8 @@ enum IsCurrentExecutorCheckMode : unsigned { /// used, and `checkIsolated` cannot be invoked. Legacy_NoCheckIsolated_NonCrashing, }; +static IsCurrentExecutorCheckMode isCurrentExecutorMode = + Swift6_UseCheckIsolated_AllowCrash; // Shimming call to Swift runtime because Swift Embedded does not have // these symbols defined. @@ -381,9 +383,8 @@ bool swift_bincompat_useLegacyNonCrashingExecutorChecks() { static void checkIsCurrentExecutorMode(void *context) { bool useLegacyMode = swift_bincompat_useLegacyNonCrashingExecutorChecks(); - auto checkMode = static_cast(context); - *checkMode = useLegacyMode ? Legacy_NoCheckIsolated_NonCrashing - : Swift6_UseCheckIsolated_AllowCrash; + isCurrentExecutorMode = useLegacyMode ? Legacy_NoCheckIsolated_NonCrashing + : Swift6_UseCheckIsolated_AllowCrash; } // Implemented in Swift to avoid some annoying hard-coding about @@ -401,10 +402,20 @@ extern "C" SWIFT_CC(swift) void _swift_task_enqueueOnExecutor( const SerialExecutorWitnessTable *wtable); SWIFT_CC(swift) -static bool isCurrentExecutor(SerialExecutorRef expectedExecutor, - IsCurrentExecutorCheckMode checkMode) { +static bool swift_task_isCurrentExecutorImpl(SerialExecutorRef expectedExecutor) { auto current = ExecutorTrackingInfo::current(); + // To support old applications on apple platforms which assumed this call + // does not crash, try to use a more compatible mode for those apps. + // + // We only allow returning `false` directly from this function when operating + // in 'Legacy_NoCheckIsolated_NonCrashing' mode. If allowing crashes, we + // instead must call into 'checkIsolated' or crash directly. + // + // Whenever we confirm an executor equality, we can return true, in any mode. + static swift::once_t checkModeToken; + swift::once(checkModeToken, checkIsCurrentExecutorMode, nullptr); + if (!current) { // We have no current executor, i.e. we are running "outside" of Swift // Concurrency. We could still be running on a thread/queue owned by @@ -421,14 +432,14 @@ static bool isCurrentExecutor(SerialExecutorRef expectedExecutor, // Otherwise, as last resort, let the expected executor check using // external means, as it may "know" this thread is managed by it etc. - if (checkMode == Swift6_UseCheckIsolated_AllowCrash) { + if (isCurrentExecutorMode == Swift6_UseCheckIsolated_AllowCrash) { swift_task_checkIsolated(expectedExecutor); // will crash if not same context // checkIsolated did not crash, so we are on the right executor, after all! return true; } - assert(checkMode == Legacy_NoCheckIsolated_NonCrashing); + assert(isCurrentExecutorMode == Legacy_NoCheckIsolated_NonCrashing); return false; } @@ -459,7 +470,7 @@ static bool isCurrentExecutor(SerialExecutorRef expectedExecutor, // the crashing 'dispatch_assert_queue(main queue)' which will either crash // or confirm we actually are on the main queue; or the custom expected // executor has a chance to implement a similar queue check. - if (checkMode == Legacy_NoCheckIsolated_NonCrashing) { + if (isCurrentExecutorMode == Legacy_NoCheckIsolated_NonCrashing) { if ((expectedExecutor.isMainExecutor() && !currentExecutor.isMainExecutor()) || (!expectedExecutor.isMainExecutor() && currentExecutor.isMainExecutor())) { return false; @@ -520,7 +531,7 @@ static bool isCurrentExecutor(SerialExecutorRef expectedExecutor, // Note that this only works because the closure in assumeIsolated is // synchronous, and will not cause suspensions, as that would require the // presence of a Task. - if (checkMode == Swift6_UseCheckIsolated_AllowCrash) { + if (isCurrentExecutorMode == Swift6_UseCheckIsolated_AllowCrash) { swift_task_checkIsolated(expectedExecutor); // will crash if not same context // The checkIsolated call did not crash, so we are on the right executor. @@ -529,28 +540,10 @@ static bool isCurrentExecutor(SerialExecutorRef expectedExecutor, // In the end, since 'checkIsolated' could not be used, so we must assume // that the executors are not the same context. - assert(checkMode == Legacy_NoCheckIsolated_NonCrashing); + assert(isCurrentExecutorMode == Legacy_NoCheckIsolated_NonCrashing); return false; } -SWIFT_CC(swift) -static bool -swift_task_isCurrentExecutorImpl(SerialExecutorRef expectedExecutor) { - // To support old applications on apple platforms which assumed this call - // does not crash, try to use a more compatible mode for those apps. - // - // We only allow returning `false` directly from this function when operating - // in 'Legacy_NoCheckIsolated_NonCrashing' mode. If allowing crashes, we - // instead must call into 'checkIsolated' or crash directly. - // - // Whenever we confirm an executor equality, we can return true, in any mode. - static IsCurrentExecutorCheckMode checkMode; - static swift::once_t checkModeToken; - swift::once(checkModeToken, checkIsCurrentExecutorMode, &checkMode); - - return isCurrentExecutor(expectedExecutor, checkMode); -} - /// Logging level for unexpected executors: /// 0 - no logging -- will be IGNORED when Swift6 mode of isCurrentExecutor is used /// 1 - warn on each instance -- will be IGNORED when Swift6 mode of isCurrentExecutor is used @@ -1034,11 +1027,6 @@ protected: // synchronously, no job queue is needed and the lock will handle all priority // escalation logic Mutex drainLock; - // Actor can be deinitialized while lock is still being held. - // We maintain separate reference counter for the lock to make sure that - // lock is destroyed and memory is freed when both actor is deinitialized - // and lock is unlocked. - std::atomic lockReferenceCount; #else // Note: There is some padding that is added here by the compiler in order to // enforce alignment. This is space that is available for us to use in @@ -1135,7 +1123,6 @@ public: this->isDistributedRemoteActor = isDistributedRemote; #if SWIFT_CONCURRENCY_ACTORS_AS_LOCKS new (&this->drainLock) Mutex(); - lockReferenceCount = 1; #else _status().store(ActiveActorStatus(), std::memory_order_relaxed); new (&this->prioritizedJobs) PriorityQueue(); @@ -1158,11 +1145,6 @@ public: /// Unlock an actor bool unlock(bool forceUnlock); -#if SWIFT_CONCURRENCY_ACTORS_AS_LOCKS - void retainLock(); - void releaseLock(); -#endif - #if !SWIFT_CONCURRENCY_ACTORS_AS_LOCKS /// Enqueue a job onto the actor. void enqueue(Job *job, JobPriority priority); @@ -1651,6 +1633,8 @@ static void defaultActorDrain(DefaultActorImpl *actor) { done: ; // Suppress a -Wc++23-extensions warning #endif + // Balances with the retain taken in ProcessOutOfLineJob::process + swift_release(actor); } SWIFT_CC(swiftasync) @@ -1659,28 +1643,15 @@ void ProcessOutOfLineJob::process(Job *job) { DefaultActorImpl *actor = self->Actor; delete self; + + // Balances with the swift_release in defaultActorDrain() + swift_retain(actor); return defaultActorDrain(actor); // 'return' forces tail call } #endif /* !SWIFT_CONCURRENCY_ACTORS_AS_LOCKS */ void DefaultActorImpl::destroy() { - HeapObject *object = asAbstract(this); - size_t retainCount = swift_retainCount(object); - if (SWIFT_UNLIKELY(retainCount > 1)) { - auto descriptor = object->metadata->getTypeContextDescriptor(); - - swift_Concurrency_fatalError(0, - "Object %p of class %s deallocated with non-zero retain " - "count %zd. This object's deinit, or something called " - "from it, may have created a strong reference to self " - "which outlived deinit, resulting in a dangling " - "reference.\n", - object, - descriptor ? descriptor->Name.get() : "", - retainCount); - } - #if SWIFT_CONCURRENCY_ACTORS_AS_LOCKS // TODO (rokhinip): Do something to assert that the lock is unowned #else @@ -1700,9 +1671,7 @@ void DefaultActorImpl::destroy() { } void DefaultActorImpl::deallocate() { -#if SWIFT_CONCURRENCY_ACTORS_AS_LOCKS - releaseLock(); -#else +#if !SWIFT_CONCURRENCY_ACTORS_AS_LOCKS // If we're running, mark ourselves as ready for deallocation but don't // deallocate yet. When we stop running the actor - at unlock() time - we'll // do the actual deallocation. @@ -1718,8 +1687,8 @@ void DefaultActorImpl::deallocate() { } assert(oldState.isIdle()); - deallocateUnconditional(); #endif + deallocateUnconditional(); } void DefaultActorImpl::deallocateUnconditional() { @@ -1732,7 +1701,6 @@ void DefaultActorImpl::deallocateUnconditional() { bool DefaultActorImpl::tryLock(bool asDrainer) { #if SWIFT_CONCURRENCY_ACTORS_AS_LOCKS - retainLock(); this->drainLock.lock(); return true; #else /* SWIFT_CONCURRENCY_ACTORS_AS_LOCKS */ @@ -1845,7 +1813,6 @@ bool DefaultActorImpl::unlock(bool forceUnlock) { #if SWIFT_CONCURRENCY_ACTORS_AS_LOCKS this->drainLock.unlock(); - releaseLock(); return true; #else bool distributedActorIsRemote = swift_distributed_actor_is_remote(this); @@ -1935,18 +1902,6 @@ bool DefaultActorImpl::unlock(bool forceUnlock) #endif } -#if SWIFT_CONCURRENCY_ACTORS_AS_LOCKS -void DefaultActorImpl::retainLock() { - lockReferenceCount.fetch_add(1, std::memory_order_acquire); -} -void DefaultActorImpl::releaseLock() { - if (1 == lockReferenceCount.fetch_add(-1, std::memory_order_release)) { - drainLock.~Mutex(); - deallocateUnconditional(); - } -} -#endif - SWIFT_CC(swift) static void swift_job_runImpl(Job *job, SerialExecutorRef executor) { ExecutorTrackingInfo trackingInfo; @@ -2249,117 +2204,6 @@ static void swift_task_switchImpl(SWIFT_ASYNC_CONTEXT AsyncContext *resumeContex task->flagAsAndEnqueueOnExecutor(newExecutor); } -#if !SWIFT_CONCURRENCY_ACTORS_AS_LOCKS -namespace { -/// Job that allows to use executor API to schedule a block of task-less -/// synchronous code. -class IsolatedDeinitJob : public Job { -private: - void *Object; - DeinitWorkFunction *Work; - -public: - IsolatedDeinitJob(JobPriority priority, void *object, - DeinitWorkFunction *work) - : Job({JobKind::IsolatedDeinit, priority}, &process), Object(object), - Work(work) {} - - SWIFT_CC(swiftasync) - static void process(Job *_job) { - auto *job = cast(_job); - void *object = job->Object; - DeinitWorkFunction *work = job->Work; - delete job; - return work(object); - } - - static bool classof(const Job *job) { - return job->Flags.getKind() == JobKind::IsolatedDeinit; - } -}; -} // namespace -#endif - -SWIFT_CC(swift) -static void swift_task_deinitOnExecutorImpl(void *object, - DeinitWorkFunction *work, - SerialExecutorRef newExecutor, - size_t rawFlags) { - // If the current executor is compatible with running the new executor, - // we can just immediately continue running with the resume function - // we were passed in. - // - // Note that isCurrentExecutor() returns true for @MainActor - // when running on the main thread without any executor. - // - // We always use "legacy" checking mode here, because that's the desired - // behaviour for this use case. This does not change with SDK version or - // language mode. - if (isCurrentExecutor(newExecutor, Legacy_NoCheckIsolated_NonCrashing)) { - return work(object); // 'return' forces tail call - } - -#if SWIFT_CONCURRENCY_ACTORS_AS_LOCKS - // In this mode taking actor lock is the only possible implementation -#else - // Otherwise, it is an optimisation applied when deinitializing default actors - if (newExecutor.isDefaultActor() && object == newExecutor.getIdentity()) { -#endif - // Try to take the lock. This should always succeed, unless someone is - // running the actor using unsafe unowned reference. - if (asImpl(newExecutor.getDefaultActor())->tryLock(false)) { - - // Don't unlock current executor, because we must preserve it when - // returning. If we release the lock, we might not be able to get it back. - // It cannot produce deadlocks, because: - // * we use tryLock(), not lock() - // * each object can be deinitialized only once, so call graph of - // deinit's cannot have cycles. - - // Function runOnAssumedThread() tries to reuse existing tracking info, - // but we don't have a tail call anyway, so this does not help much here. - // Always create new tracking info to keep code simple. - ExecutorTrackingInfo trackingInfo; - - // The only place where ExecutorTrackingInfo::getTaskExecutor() is - // called is in swift_task_switch(), but swift_task_switch() cannot be - // called from the synchronous code. So it does not really matter what is - // set in the ExecutorTrackingInfo::ActiveExecutor for the duration of the - // isolated deinit - it is unobservable anyway. - TaskExecutorRef taskExecutor = TaskExecutorRef::undefined(); - trackingInfo.enterAndShadow(newExecutor, taskExecutor); - - // Run the work. - work(object); - - // `work` is a synchronous function, it cannot call swift_task_switch() - // If it calls any synchronous API that may change executor inside - // tracking info, that API is also responsible for changing it back. - assert(newExecutor == trackingInfo.getActiveExecutor()); - assert(taskExecutor == trackingInfo.getTaskExecutor()); - - // Leave the tracking frame - trackingInfo.leave(); - - // Give up the current actor. - asImpl(newExecutor.getDefaultActor())->unlock(true); - return; - } else { -#if SWIFT_CONCURRENCY_ACTORS_AS_LOCKS - assert(false && "Should not enqueue onto default actor in actor as locks model"); -#endif - } -#if !SWIFT_CONCURRENCY_ACTORS_AS_LOCKS - } - auto currentTask = swift_task_getCurrent(); - auto priority = currentTask ? swift_task_currentPriority(currentTask) - : swift_task_getCurrentThreadPriority(); - - auto job = new IsolatedDeinitJob(priority, object, work); - swift_task_enqueue(job, newExecutor); -#endif -} - /*****************************************************************************/ /************************* GENERIC ACTOR INTERFACES **************************/ /*****************************************************************************/ diff --git a/stdlib/public/Concurrency/Executor.swift b/stdlib/public/Concurrency/Executor.swift index 2b9209ab3a3..53919252ad8 100644 --- a/stdlib/public/Concurrency/Executor.swift +++ b/stdlib/public/Concurrency/Executor.swift @@ -539,12 +539,3 @@ internal final class DispatchQueueShim: @unchecked Sendable, SerialExecutor { } } #endif // SWIFT_CONCURRENCY_USES_DISPATCH - - -@available(SwiftStdlib 5.6, *) // TODO: Clarify version -@_silgen_name("swift_task_deinitOnExecutor") -@usableFromInline -internal func _deinitOnExecutor(_ object: __owned AnyObject, - _ work: @convention(thin) (__owned AnyObject) -> Void, - _ executor: Builtin.Executor, - _ flags: Builtin.Word) diff --git a/stdlib/public/Distributed/DistributedDefaultExecutor.swift b/stdlib/public/Distributed/DistributedDefaultExecutor.swift index abe0aca19c8..37237e9a8e9 100644 --- a/stdlib/public/Distributed/DistributedDefaultExecutor.swift +++ b/stdlib/public/Distributed/DistributedDefaultExecutor.swift @@ -23,19 +23,11 @@ internal final class DistributedRemoteActorReferenceExecutor: SerialExecutor { internal init() {} - #if SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY - @inlinable - func enqueue(_ job: UnownedJob) { - let jobDescription = job.description - fatalError("Attempted to enqueue ExecutorJob (\(jobDescription)) on executor of remote distributed actor reference!") - } - #else @inlinable public func enqueue(_ job: consuming ExecutorJob) { let jobDescription = job.description fatalError("Attempted to enqueue ExecutorJob (\(jobDescription)) on executor of remote distributed actor reference!") } - #endif // !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY public func asUnownedSerialExecutor() -> UnownedSerialExecutor { UnownedSerialExecutor(ordinary: self) diff --git a/stdlib/public/core/EmbeddedRuntime.swift b/stdlib/public/core/EmbeddedRuntime.swift index e16809211ba..c719f06a9d3 100644 --- a/stdlib/public/core/EmbeddedRuntime.swift +++ b/stdlib/public/core/EmbeddedRuntime.swift @@ -309,13 +309,7 @@ public func swift_bridgeObjectRelease_n(object: Builtin.RawPointer, n: UInt32) { swift_release_n(object: untaggedObject, n: n) } -@_cdecl("swift_retainCount") -public func swift_retainCount(object: Builtin.RawPointer) -> Int { - if !isValidPointerForNativeRetain(object: object) { return 0 } - let o = UnsafeMutablePointer(object) - let refcount = refcountPointer(for: o) - return loadAcquire(refcount) & HeapObject.refcountMask -} + /// Refcount helpers diff --git a/test/Concurrency/Runtime/actor_deinit_escaping_self.swift b/test/Concurrency/Runtime/actor_deinit_escaping_self.swift deleted file mode 100644 index 1604c7d5578..00000000000 --- a/test/Concurrency/Runtime/actor_deinit_escaping_self.swift +++ /dev/null @@ -1,46 +0,0 @@ -// RUN: %target-run-simple-swift( -Xfrontend -disable-availability-checking %import-libdispatch -parse-as-library) - -// REQUIRES: executable_test -// REQUIRES: libdispatch -// REQUIRES: concurrency -// REQUIRES: concurrency_runtime -// UNSUPPORTED: back_deployment_runtime - -import _Concurrency -import Dispatch -import StdlibUnittest - -func formatAddr(_ obj: AnyObject) -> String { - "0x" + String(unsafeBitCast(obj, to: UInt.self), radix: 16) -} - -actor EscapeLocked { - var k: Int = 1 - - func increment() { - k += 1 - } - - isolated deinit { - let g = DispatchGroup() - g.enter() - Task.detached { - await self.increment() - g.leave() - } - let r = g.wait(timeout: .now() + .milliseconds(500)) - expectEqual(r, .timedOut) - expectCrashLater(withMessage: "Object \(formatAddr(self)) of class EscapeLocked deallocated with non-zero retain count 2. This object's deinit, or something called from it, may have created a strong reference to self which outlived deinit, resulting in a dangling reference.") - } -} - -@main struct Main { - static func main() async { - // Ideally these tests should be compile-time errors - let tests = TestSuite("EscapingSelf") - tests.test("escape while locked") { - _ = EscapeLocked() - } - await runAllTestsAsync() - } -} diff --git a/test/Concurrency/Runtime/actor_recursive_deinit.swift b/test/Concurrency/Runtime/actor_recursive_deinit.swift deleted file mode 100644 index 0e4434ac760..00000000000 --- a/test/Concurrency/Runtime/actor_recursive_deinit.swift +++ /dev/null @@ -1,79 +0,0 @@ -// RUN: %target-run-simple-swift(-Xfrontend -disable-availability-checking -parse-stdlib -parse-as-library) | %FileCheck %s - -// REQUIRES: executable_test -// REQUIRES: concurrency - -// REQUIRES: concurrency_runtime -// UNSUPPORTED: back_deployment_runtime - -// Compiler crashes because builtin "ifdef_SWIFT_STDLIB_PRINT_DISABLED"() gets lowered as "i32 0", -// which triggers assertion in LLVM, which expects it to be i1 -// XFAIL: freestanding - -import Swift -import _Concurrency - -#if canImport(Darwin) -import Darwin -typealias ThreadID = pthread_t -func getCurrentThreadID() -> ThreadID { pthread_self() } -func equalThreadIDs(_ a: ThreadID, _ b: ThreadID) -> Bool { pthread_equal(a, b) != 0 } -#elseif canImport(Glibc) -import Glibc -typealias ThreadID = pthread_t -func getCurrentThreadID() -> ThreadID { pthread_self() } -func equalThreadIDs(_ a: ThreadID, _ b: ThreadID) -> Bool { pthread_equal(a, b) != 0 } -#elseif os(Windows) -import WinSDK -typealias ThreadID = UInt32 -func getCurrentThreadID() -> ThreadID { GetCurrentThreadId() } -func equalThreadIDs(_ a: ThreadID, _ b: ThreadID) -> Bool { a == b } -#endif - -var mainThread: ThreadID? -func isMainThread() -> Bool { - return equalThreadIDs(getCurrentThreadID(), mainThread!) -} - -@_silgen_name("swift_task_isCurrentExecutor") -private func isCurrentExecutor(_ executor: Builtin.Executor) -> Bool - -func getExecutor(_ a: any Actor) -> Builtin.Executor { - let pack: (AnyObject, UnsafeRawPointer?) = (a, UnsafeRawPointer?.none) - return unsafeBitCast(pack, to: Builtin.Executor.self) -} - -func isCurrent(_ a: any Actor) -> Bool { - return isCurrentExecutor(getExecutor(a)) -} - -actor Foo { - let name: String - let child: Foo? - - init(_ name: String, _ child: Foo?) { - self.name = name - self.child = child - } - - isolated deinit { - print("DEINIT: \(self.name) isolated:\(isCurrent(self)) mainThread:\(isMainThread())") - } -} - -// CHECK: DEINIT: a isolated:true mainThread:true -// CHECK: DEINIT: b isolated:true mainThread:true -// CHECK: DEINIT: c isolated:true mainThread:true -// CHECK: DEINIT: d isolated:true mainThread:true -// CHECK: DONE - -@main -struct Main { - static func main() async { - mainThread = getCurrentThreadID() - do { - _ = Foo("a", Foo("b", Foo("c", Foo("d", nil)))) - } - print("DONE") - } -} diff --git a/test/Concurrency/Runtime/async_task_locals_isolated_deinit.swift b/test/Concurrency/Runtime/async_task_locals_isolated_deinit.swift deleted file mode 100644 index 77bf99ccc10..00000000000 --- a/test/Concurrency/Runtime/async_task_locals_isolated_deinit.swift +++ /dev/null @@ -1,191 +0,0 @@ -// RUN: %empty-directory(%t) -// RUN: %target-build-swift -plugin-path %swift-plugin-dir -Xfrontend -disable-availability-checking -parse-stdlib %import-libdispatch %s -o %t/a.out -// RUN: %target-codesign %t/a.out -// RUN: %env-SWIFT_IS_CURRENT_EXECUTOR_LEGACY_MODE_OVERRIDE=swift6 %target-run %t/a.out - -// REQUIRES: libdispatch -// REQUIRES: executable_test -// REQUIRES: concurrency -// REQUIRES: concurrency_runtime -// UNSUPPORTED: back_deployment_runtime - -import Swift -import _Concurrency -import Dispatch -import StdlibUnittest - -@_silgen_name("swift_task_isCurrentExecutor") -private func isCurrentExecutor(_ executor: Builtin.Executor) -> Bool - -private func isCurrentExecutor(_ executor: UnownedSerialExecutor) -> Bool { - isCurrentExecutor(unsafeBitCast(executor, to: Builtin.Executor.self)) -} - -extension DispatchGroup { - func enter(_ count: Int) { - for _ in 0.. Void) { - work() - } -} - -class Probe { - var probeExpectedExecutor: UnownedSerialExecutor - let probeExpectedNumber: Int - let probeGroup: DispatchGroup - - init(expectedNumber: Int, group: DispatchGroup) { - self.probeExpectedExecutor = AnotherActor.shared.unownedExecutor - self.probeExpectedNumber = expectedNumber - self.probeGroup = group - group.enter() - } - - deinit { - expectTrue(isCurrentExecutor(probeExpectedExecutor)) - expectEqual(probeExpectedNumber, TL.number) - checkTaskLocalStack() - probeGroup.leave() - } -} - -class ClassNoOp: Probe { - let expectedNumber: Int - let group: DispatchGroup - let probe: Probe - - override init(expectedNumber: Int, group: DispatchGroup) { - self.expectedNumber = expectedNumber - self.group = group - self.probe = Probe(expectedNumber: expectedNumber, group: group) - super.init(expectedNumber: expectedNumber, group: group) - } - - @AnotherActor - deinit { - expectTrue(isCurrentExecutor(AnotherActor.shared.unownedExecutor)) - expectEqual(expectedNumber, TL.number) - checkTaskLocalStack() - group.leave() - } -} - -let tests = TestSuite("Isolated Deinit") - -if #available(SwiftStdlib 5.1, *) { - tests.test("class sync fast path") { - let group = DispatchGroup() - group.enter(1) - Task { - await TL.$number.withValue(42) { - await AnotherActor.shared.performTesting { - _ = ClassNoOp(expectedNumber: 42, group: group) - } - } - } - group.wait() - } - - tests.test("class sync slow path") { - let group = DispatchGroup() - group.enter(1) - Task { - TL.$number.withValue(99) { - _ = ClassNoOp(expectedNumber: 0, group: group) - } - } - group.wait() - } - - tests.test("actor sync fast path") { - let group = DispatchGroup() - group.enter(1) - Task { - TL.$number.withValue(99) { - // Despite last release happening not on the actor itself, - // this is still a fast path due to optimisation for deallocating actors. - _ = ActorNoOp(expectedNumber: 99, group: group) - } - } - group.wait() - } - - tests.test("actor sync slow path") { - let group = DispatchGroup() - group.enter(1) - Task { - TL.$number.withValue(99) { - // Using ProxyActor breaks optimization - _ = ProxyActor(expectedNumber: 0, group: group) - } - } - group.wait() - } - - tests.test("no TLs") { - let group = DispatchGroup() - group.enter(2) - Task { - _ = ActorNoOp(expectedNumber: 0, group: group) - _ = ClassNoOp(expectedNumber: 0, group: group) - } - group.wait() - } -} - -runAllTests() - diff --git a/test/Concurrency/Runtime/async_task_locals_isolated_deinit_freestanding.swift b/test/Concurrency/Runtime/async_task_locals_isolated_deinit_freestanding.swift deleted file mode 100644 index 3ab07133766..00000000000 --- a/test/Concurrency/Runtime/async_task_locals_isolated_deinit_freestanding.swift +++ /dev/null @@ -1,87 +0,0 @@ -// RUN: %empty-directory(%t) -// RUN: %target-build-swift -plugin-path %swift-plugin-dir -Xfrontend -disable-availability-checking -parse-stdlib %s -Xfrontend -concurrency-model=task-to-thread -g -o %t/a.out -// RUN: %target-codesign %t/a.out -// RUN: %env-SWIFT_IS_CURRENT_EXECUTOR_LEGACY_MODE_OVERRIDE=swift6 %target-run %t/a.out - -// REQUIRES: freestanding -// REQUIRES: executable_test -// REQUIRES: concurrency -// REQUIRES: concurrency_runtime - -@_spi(_TaskToThreadModel) import _Concurrency -import StdlibUnittest -import Darwin -import Swift - -@_silgen_name("swift_task_isCurrentExecutor") -private func isCurrentExecutor(_ executor: Builtin.Executor) -> Bool - -private func isCurrentExecutor(_ executor: UnownedSerialExecutor) -> Bool { - isCurrentExecutor(unsafeBitCast(executor, to: Builtin.Executor.self)) -} - -@available(SwiftStdlib 5.1, *) -struct TL { - @TaskLocal - static var number: Int = 0 -} - -func checkTaskLocalStack() { - TL.$number.withValue(-999) { - expectEqual(-999, TL.number) - } -} - -actor ActorNoOp { - let expectedNumber: Int - let probe: Probe - - init(expectedNumber: Int) { - self.expectedNumber = expectedNumber - self.probe = Probe(expectedNumber: expectedNumber) - self.probe.probeExpectedExecutor = self.unownedExecutor - } - - isolated deinit { - expectTrue(isCurrentExecutor(self.unownedExecutor)) - expectEqual(expectedNumber, TL.number) - checkTaskLocalStack() - } -} - -class Probe { - var probeExpectedExecutor: UnownedSerialExecutor! - let probeExpectedNumber: Int - - init(expectedNumber: Int) { - self.probeExpectedExecutor = nil - self.probeExpectedNumber = expectedNumber - } - - deinit { - expectTrue(isCurrentExecutor(probeExpectedExecutor)) - expectEqual(probeExpectedNumber, TL.number) - checkTaskLocalStack() - } -} - -let tests = TestSuite("Isolated Deinit") - -if #available(SwiftStdlib 5.1, *) { - tests.test("actor sync not isolated") { - Task.runInline { - TL.$number.withValue(99) { - // Freestanding runtime always executes deinit inline - _ = ActorNoOp(expectedNumber: 99) - } - } - } - - tests.test("no TLs") { - Task.runInline { - _ = ActorNoOp(expectedNumber: 0) - } - } -} - -runAllTests() diff --git a/test/Concurrency/Runtime/isolated_deinit_main_sync.swift b/test/Concurrency/Runtime/isolated_deinit_main_sync.swift deleted file mode 100644 index 63003bea82f..00000000000 --- a/test/Concurrency/Runtime/isolated_deinit_main_sync.swift +++ /dev/null @@ -1,24 +0,0 @@ -// RUN: %target-run-simple-swift(-Xfrontend -disable-availability-checking) | %FileCheck %s - -var isDead: Bool = false - -public class Foo { - @MainActor - deinit { - print("DEINIT") - isDead = true - } -} - -func main() { - print("isDead = \(isDead)") - do { - _ = Foo() - } - print("isDead = \(isDead)") -} - -// CHECK: isDead = false -// CHECK: DEINIT -// CHECK: isDead = true -main() diff --git a/test/Concurrency/deinit_isolation.swift b/test/Concurrency/deinit_isolation.swift deleted file mode 100644 index b46b949ded7..00000000000 --- a/test/Concurrency/deinit_isolation.swift +++ /dev/null @@ -1,555 +0,0 @@ -// RUN: %target-swift-frontend -disable-availability-checking -parse-as-library -emit-silgen -verify %s -// RUN: %target-swift-frontend -disable-availability-checking -parse-as-library -emit-silgen -DSILGEN %s | %FileCheck %s -// RUN: %target-swift-frontend -disable-availability-checking -parse-as-library -emit-silgen -DSILGEN %s | %FileCheck -check-prefix=CHECK-SYMB %s - -// REQUIRES: concurrency - -// Fixtures - -@globalActor final actor FirstActor { - static let shared = FirstActor() -} - -@globalActor final actor SecondActor { - static let shared = SecondActor() -} - -@globalActor private final actor PrivateActor { - static let shared = PrivateActor() -} - -@FirstActor -func isolatedFunc() {} // expected-note 15{{calls to global function 'isolatedFunc()' from outside of its actor context are implicitly asynchronous}} - -// CHECK-LABEL: class BaseWithNonisolatedDeinit { -// CHECK: {{(@objc )?}}deinit -// CHECK: } -// CHECK-SYMB-NOT: BaseWithNonisolatedDeinit.__isolated_deallocating_deinit -// CHECK-SYMB-NOT: @$s16deinit_isolation25BaseWithNonisolatedDeinitCfZ -// CHECK-SYMB: // BaseWithNonisolatedDeinit.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation25BaseWithNonisolatedDeinitCfD : $@convention(method) (@owned BaseWithNonisolatedDeinit) -> () { -class BaseWithNonisolatedDeinit {} - -// CHECK-LABEL: class BaseWithDeinitIsolatedOnFirstActor { -// CHECK: {{(@objc )?}}@FirstActor deinit -// CHECK: } -// CHECK-SYMB: BaseWithDeinitIsolatedOnFirstActor.__isolated_deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: global_actor. type: FirstActor -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation34BaseWithDeinitIsolatedOnFirstActorCfZ : $@convention(thin) (@owned BaseWithDeinitIsolatedOnFirstActor) -> () { -// CHECK-SYMB: BaseWithDeinitIsolatedOnFirstActor.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation34BaseWithDeinitIsolatedOnFirstActorCfD : $@convention(method) (@owned BaseWithDeinitIsolatedOnFirstActor) -> () { -class BaseWithDeinitIsolatedOnFirstActor { - @FirstActor deinit {} // expected-note 3{{overridden declaration is here}} -} - -@FirstActor -class BaseIsolatedOnFirstActor {} - -@SecondActor -class BaseIsolatedOnSecondActor {} - -// CHECK-LABEL: class BaseWithDeinitIsolatedOnSecondActor { -// CHECK: {{(@objc )?}}@SecondActor deinit -// CHECK: } -// CHECK-SYMB: BaseWithDeinitIsolatedOnSecondActor.__isolated_deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: global_actor. type: SecondActor -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation35BaseWithDeinitIsolatedOnSecondActorCfZ : $@convention(thin) (@owned BaseWithDeinitIsolatedOnSecondActor) -> () { -// CHECK-SYMB: BaseWithDeinitIsolatedOnSecondActor.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation35BaseWithDeinitIsolatedOnSecondActorCfD : $@convention(method) (@owned BaseWithDeinitIsolatedOnSecondActor) -> () { -class BaseWithDeinitIsolatedOnSecondActor { - @SecondActor deinit {} // expected-note 3{{overridden declaration is here}} -} - -// MARK: - Part 1 - Actors - -// CHECK-LABEL: actor ImplicitDeinitActor { -// CHECK: {{(@objc )?}} deinit -// CHECK: } -// CHECK-SYMB-NOT: ImplicitDeinitActor.__isolated_deallocating_deinit -// CHECK-SYMB-NOT: @$s16deinit_isolation19ImplicitDeinitActorCfZ -// CHECK-SYMB: // ImplicitDeinitActor.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation19ImplicitDeinitActorCfD : $@convention(method) (@owned ImplicitDeinitActor) -> () { -actor ImplicitDeinitActor { - // nonisolated deinit -} - -// CHECK-LABEL: actor DefaultDeinitActor { -// CHECK: {{(@objc )?}}deinit -// CHECK: } -// CHECK-SYMB-NOT: DefaultDeinitActor.__isolated_deallocating_deinit -// CHECK-SYMB-NOT: @$s16deinit_isolation18DefaultDeinitActorCfZ -// CHECK-SYMB: // DefaultDeinitActor.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation18DefaultDeinitActorCfD : $@convention(method) (@owned DefaultDeinitActor) -> () { -actor DefaultDeinitActor { - // self-isolated deinit - deinit { -#if !SILGEN - isolatedFunc() // expected-error {{call to global actor 'FirstActor'-isolated global function 'isolatedFunc()' in a synchronous nonisolated context}} -#endif - } -} - -// CHECK-LABEL: actor PropagatedDeinitActor { -// CHECK: {{(@objc )?}}isolated deinit -// CHECK: } -// CHECK-SYMB: // PropagatedDeinitActor.__isolated_deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: actor_instance. name: 'self' -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation21PropagatedDeinitActorCfZ : $@convention(thin) (@owned PropagatedDeinitActor) -> () { -// CHECK-SYMB: // PropagatedDeinitActor.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation21PropagatedDeinitActorCfD : $@convention(method) (@owned PropagatedDeinitActor) -> () { -actor PropagatedDeinitActor { - // self-isolated deinit - isolated deinit { -#if !SILGEN - isolatedFunc() // expected-error {{call to global actor 'FirstActor'-isolated global function 'isolatedFunc()' in a synchronous actor-isolated context}} -#endif - } -} - -// CHECK-LABEL: actor NonisolatedDeinitActor { -// CHECK: {{(@objc )?}}nonisolated deinit -// CHECK: } -// CHECK-SYMB-NOT: NonisolatedDeinitActor.__isolated_deallocating_deinit -// CHECK-SYMB-NOT: @$s16deinit_isolation22NonisolatedDeinitActorCfZ -// CHECK-SYMB: // NonisolatedDeinitActor.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation22NonisolatedDeinitActorCfD : $@convention(method) (@owned NonisolatedDeinitActor) -> () { -actor NonisolatedDeinitActor { - // nonisolated deinit - nonisolated deinit { -#if !SILGEN - isolatedFunc() // expected-error {{call to global actor 'FirstActor'-isolated global function 'isolatedFunc()' in a synchronous nonisolated context}} -#endif - } -} - -// CHECK-LABEL: actor IsolatedDeinitActor { -// CHECK: {{(@objc )?}}@FirstActor deinit -// CHECK: } -// CHECK-SYMB: // IsolatedDeinitActor.__isolated_deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: global_actor. type: FirstActor -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation19IsolatedDeinitActorCfZ : $@convention(thin) (@owned IsolatedDeinitActor) -> () { -// CHECK-SYMB: // IsolatedDeinitActor.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation19IsolatedDeinitActorCfD : $@convention(method) (@owned IsolatedDeinitActor) -> () { -actor IsolatedDeinitActor { - // FirstActor-isolated deinit - @FirstActor deinit { - isolatedFunc() // ok - } -} - -// MARK: - Part 2 - Classes -// MARK: - Part 2.1 - Without base class - -// CHECK-LABEL: @FirstActor class ImplicitDeinit { -// CHECK: {{(@objc )?}}deinit -// CHECK: } -// CHECK-SYMB-NOT: ImplicitDeinit.__isolated_deallocating_deinit -// CHECK-SYMB-NOT: @$s16deinit_isolation14ImplicitDeinitCfZ -// CHECK-SYMB: // ImplicitDeinit.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation14ImplicitDeinitCfD : $@convention(method) (@owned ImplicitDeinit) -> () { -@FirstActor -class ImplicitDeinit { - // nonisolated deinit -} - -// CHECK-LABEL: @FirstActor class DefaultDeinit { -// CHECK: {{(@objc )?}} deinit -// CHECK: } -// CHECK-SYMB-NOT: DefaultDeinit.__isolated_deallocating_deinit -// CHECK-SYMB-NOT: @$s16deinit_isolation13DefaultDeinitCfZ -// CHECK-SYMB: // DefaultDeinit.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation13DefaultDeinitCfD : $@convention(method) (@owned DefaultDeinit) -> () { -@FirstActor -class DefaultDeinit { - deinit { -#if !SILGEN - isolatedFunc() // expected-error {{call to global actor 'FirstActor'-isolated global function 'isolatedFunc()' in a synchronous nonisolated context}} -#endif - } -} - -// CHECK-LABEL: @FirstActor class PropagatedDeinit { -// CHECK: {{(@objc )?}}isolated deinit -// CHECK: } -// CHECK-SYMB: // PropagatedDeinit.__isolated_deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: global_actor. type: FirstActor -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation16PropagatedDeinitCfZ : $@convention(thin) (@owned PropagatedDeinit) -> () { -// CHECK-SYMB: // PropagatedDeinit.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation16PropagatedDeinitCfD : $@convention(method) (@owned PropagatedDeinit) -> () { -@FirstActor -class PropagatedDeinit { - // FirstActor-isolated deinit - isolated deinit { - isolatedFunc() // ok - } -} - -#if !SILGEN -class BadPropagatedDeinit { - isolated deinit {} // expected-error {{deinit is marked isolated, but containing class 'BadPropagatedDeinit' is not isolated to an actor}} -} -#endif - -// CHECK-LABEL: @FirstActor class NonisolatedDeinit { -// CHECK: {{(@objc )?}}nonisolated deinit -// CHECK: } -// CHECK-SYMB-NOT: NonisolatedDeinit.__isolated_deallocating_deinit -// CHECK-SYMB-NOT: @$s16deinit_isolation17NonisolatedDeinitCfZ -// CHECK-SYMB: // NonisolatedDeinit.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation17NonisolatedDeinitCfD : $@convention(method) (@owned NonisolatedDeinit) -> () { -@FirstActor -class NonisolatedDeinit { - // nonisolated deinit - nonisolated deinit { -#if !SILGEN - isolatedFunc() // expected-error {{call to global actor 'FirstActor'-isolated global function 'isolatedFunc()' in a synchronous nonisolated context}} -#endif - } -} - -// CHECK-LABEL: class IsolatedDeinit { -// CHECK: {{(@objc )?}}@FirstActor deinit -// CHECK: } -// CHECK-SYMB: // IsolatedDeinit.__isolated_deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: global_actor. type: FirstActor -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation14IsolatedDeinitCfZ : $@convention(thin) (@owned IsolatedDeinit) -> () { -// CHECK-SYMB: // IsolatedDeinit.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation14IsolatedDeinitCfD : $@convention(method) (@owned IsolatedDeinit) -> () { -class IsolatedDeinit { - // FirstActor-isolated deinit - @FirstActor deinit { - isolatedFunc() // ok - } -} - -// CHECK-LABEL: @FirstActor class DifferentIsolatedDeinit { -// CHECK: {{(@objc )?}}@SecondActor deinit -// CHECK: } -// CHECK-SYMB: // DifferentIsolatedDeinit.__isolated_deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: global_actor. type: SecondActor -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation23DifferentIsolatedDeinitCfZ : $@convention(thin) (@owned DifferentIsolatedDeinit) -> () { -// CHECK-SYMB: // DifferentIsolatedDeinit.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation23DifferentIsolatedDeinitCfD : $@convention(method) (@owned DifferentIsolatedDeinit) -> () { -@FirstActor -class DifferentIsolatedDeinit { - // SecondActor-isolated deinit - @SecondActor deinit { -#if !SILGEN - isolatedFunc() // expected-error {{call to global actor 'FirstActor'-isolated global function 'isolatedFunc()' in a synchronous global actor 'SecondActor'-isolated context}} -#endif - } -} - -// MARK: - Part 2.2 - Base class with nonisolated deinit - -// CHECK-LABEL: @_inheritsConvenienceInitializers @FirstActor class ImplicitDeinitInheritNonisolated : BaseWithNonisolatedDeinit { -// CHECK: {{(@objc )?}}deinit -// CHECK: } -// CHECK-SYMB-NOT: ImplicitDeinitInheritNonisolated.__isolated_deallocating_deinit -// CHECK-SYMB-NOT: @$s16deinit_isolation32ImplicitDeinitInheritNonisolatedCfZ -// CHECK-SYMB: // ImplicitDeinitInheritNonisolated.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation32ImplicitDeinitInheritNonisolatedCfD : $@convention(method) (@owned ImplicitDeinitInheritNonisolated) -> () { -@FirstActor -class ImplicitDeinitInheritNonisolated: BaseWithNonisolatedDeinit { - // nonisolated deinit -} - -// CHECK-LABEL: @_inheritsConvenienceInitializers @FirstActor class DefaultDeinitInheritNonisolated : BaseWithNonisolatedDeinit { -// CHECK: {{(@objc )?}} deinit -// CHECK: } -// CHECK-SYMB-NOT: // DefaultDeinitInheritNonisolated.__isolated_deallocating_deinit -// CHECK-SYMB-NOT: sil hidden [ossa] @$s16deinit_isolation31DefaultDeinitInheritNonisolatedCfZ : $@convention(thin) (@owned DefaultDeinitInheritNonisolated) -> () { -// CHECK-SYMB: // DefaultDeinitInheritNonisolated.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation31DefaultDeinitInheritNonisolatedCfD : $@convention(method) (@owned DefaultDeinitInheritNonisolated) -> () { -@FirstActor -class DefaultDeinitInheritNonisolated: BaseWithNonisolatedDeinit { - // nonisolated deinit - deinit { -#if !SILGEN - isolatedFunc() // expected-error {{call to global actor 'FirstActor'-isolated global function 'isolatedFunc()' in a synchronous nonisolated context}} -#endif - } -} - -#if !SILGEN -class BadPropagatedDeinitInheritNonisolated: BaseWithNonisolatedDeinit { - isolated deinit {} // expected-error {{deinit is marked isolated, but containing class 'BadPropagatedDeinitInheritNonisolated' is not isolated to an actor}} -} -#endif - -// CHECK-LABEL: @_inheritsConvenienceInitializers @FirstActor class PropagatedDeinitInheritNonisolated : BaseWithNonisolatedDeinit { -// CHECK: {{(@objc )?}}isolated deinit -// CHECK: } -// CHECK-SYMB: // PropagatedDeinitInheritNonisolated.__isolated_deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: global_actor. type: FirstActor -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation34PropagatedDeinitInheritNonisolatedCfZ : $@convention(thin) (@owned PropagatedDeinitInheritNonisolated) -> () { -// CHECK-SYMB: // PropagatedDeinitInheritNonisolated.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation34PropagatedDeinitInheritNonisolatedCfD : $@convention(method) (@owned PropagatedDeinitInheritNonisolated) -> () { -@FirstActor -class PropagatedDeinitInheritNonisolated: BaseWithNonisolatedDeinit { - // FirstActor-isolated deinit - isolated deinit { - isolatedFunc() // ok - } -} - -// CHECK-LABEL: @_inheritsConvenienceInitializers @FirstActor class NonisolatedDeinitInheritNonisolated : BaseWithNonisolatedDeinit { -// CHECK: {{(@objc )?}}nonisolated deinit -// CHECK: } -// CHECK-SYMB-NOT: NonisolatedDeinitInheritNonisolated.__isolated_deallocating_deinit -// CHECK-SYMB-NOT: @$s16deinit_isolation024NonisolatedDeinitInheritC0CfZ -// CHECK-SYMB: // NonisolatedDeinitInheritNonisolated.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation024NonisolatedDeinitInheritC0CfD : $@convention(method) (@owned NonisolatedDeinitInheritNonisolated) -> () { -@FirstActor -class NonisolatedDeinitInheritNonisolated: BaseWithNonisolatedDeinit { - // nonisolated deinit - nonisolated deinit { -#if !SILGEN - isolatedFunc() // expected-error {{call to global actor 'FirstActor'-isolated global function 'isolatedFunc()' in a synchronous nonisolated context}} -#endif - } -} - -// CHECK-LABEL: @_inheritsConvenienceInitializers class IsolatedDeinitInheritNonisolated : BaseWithNonisolatedDeinit { -// CHECK: {{(@objc )?}}@FirstActor deinit -// CHECK: } -// CHECK-SYMB: // IsolatedDeinitInheritNonisolated.__isolated_deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: global_actor. type: FirstActor -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation32IsolatedDeinitInheritNonisolatedCfZ : $@convention(thin) (@owned IsolatedDeinitInheritNonisolated) -> () { -// CHECK-SYMB: // IsolatedDeinitInheritNonisolated.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation32IsolatedDeinitInheritNonisolatedCfD : $@convention(method) (@owned IsolatedDeinitInheritNonisolated) -> () { -class IsolatedDeinitInheritNonisolated: BaseWithNonisolatedDeinit { - // FirstActor-isolated deinit - @FirstActor deinit { - isolatedFunc() // ok - } -} - -// CHECK-LABEL: @_inheritsConvenienceInitializers @FirstActor class DifferentIsolatedDeinitInheritNonisolated : BaseWithNonisolatedDeinit { -// CHECK: {{(@objc )?}}@SecondActor deinit -// CHECK: } -// CHECK-SYMB: // DifferentIsolatedDeinitInheritNonisolated.__isolated_deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: global_actor. type: SecondActor -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation41DifferentIsolatedDeinitInheritNonisolatedCfZ : $@convention(thin) (@owned DifferentIsolatedDeinitInheritNonisolated) -> () { -// CHECK-SYMB: // DifferentIsolatedDeinitInheritNonisolated.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation41DifferentIsolatedDeinitInheritNonisolatedCfD : $@convention(method) (@owned DifferentIsolatedDeinitInheritNonisolated) -> () { -@FirstActor -class DifferentIsolatedDeinitInheritNonisolated: BaseWithNonisolatedDeinit { - // SecondActor-isolated deinit - @SecondActor deinit { -#if !SILGEN - isolatedFunc() // expected-error {{call to global actor 'FirstActor'-isolated global function 'isolatedFunc()' in a synchronous global actor 'SecondActor'-isolated context}} -#endif - } -} - -// MARK: - Part 2.3 - Base class with isolated deinit - -// CHECK-LABEL: @_inheritsConvenienceInitializers @FirstActor class ImplicitDeinitInheritIsolated1 : BaseWithDeinitIsolatedOnFirstActor { -// CHECK: {{(@objc )?}}deinit -// CHECK: } -// CHECK-SYMB: // ImplicitDeinitInheritIsolated1.__isolated_deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: global_actor. type: FirstActor -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation30ImplicitDeinitInheritIsolated1CfZ : $@convention(thin) (@owned ImplicitDeinitInheritIsolated1) -> () { -// CHECK-SYMB: // ImplicitDeinitInheritIsolated1.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation30ImplicitDeinitInheritIsolated1CfD : $@convention(method) (@owned ImplicitDeinitInheritIsolated1) -> () { -@FirstActor -class ImplicitDeinitInheritIsolated1: BaseWithDeinitIsolatedOnFirstActor { - // FirstActor-isolated deinit -} - -#if !SILGEN -@FirstActor -class DefaultDeinitIsolated1: BaseWithDeinitIsolatedOnFirstActor { - // nonisolated deinit - deinit { // expected-error {{nonisolated deinitializer 'deinit' has different actor isolation from global actor 'FirstActor'-isolated overridden declaration}} - isolatedFunc() // expected-error {{call to global actor 'FirstActor'-isolated global function 'isolatedFunc()' in a synchronous nonisolated context}} - } -} -#endif - -#if !SILGEN -class BadPropagatedDeinitIsolated: BaseWithDeinitIsolatedOnFirstActor { - //unexpected error produced: nonisolated deinitializer 'deinit' has different actor isolation from global actor 'FirstActor'-isolated overridden declaration - - isolated deinit {} // expected-error {{deinit is marked isolated, but containing class 'BadPropagatedDeinitIsolated' is not isolated to an actor}} -} -#endif - -// CHECK-LABEL: @_inheritsConvenienceInitializers @FirstActor class GoodPropagatedDeinitIsolated1 : BaseIsolatedOnFirstActor { -// CHECK: {{(@objc )?}}isolated deinit -// CHECK: } -// CHECK-SYMB: // GoodPropagatedDeinitIsolated1.__isolated_deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: global_actor. type: FirstActor -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation29GoodPropagatedDeinitIsolated1CfZ : $@convention(thin) (@owned GoodPropagatedDeinitIsolated1) -> () { -// CHECK-SYMB: // GoodPropagatedDeinitIsolated1.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation29GoodPropagatedDeinitIsolated1CfD : $@convention(method) (@owned GoodPropagatedDeinitIsolated1) -> () { -class GoodPropagatedDeinitIsolated1: BaseIsolatedOnFirstActor { - isolated deinit { - isolatedFunc() // ok - } -} - -// CHECK-LABEL: @_inheritsConvenienceInitializers @FirstActor class PropagatedDeinitIsolated1 : BaseWithDeinitIsolatedOnFirstActor { -// CHECK: {{(@objc )?}}isolated deinit -// CHECK: } -// CHECK-SYMB: // PropagatedDeinitIsolated1.__isolated_deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: global_actor. type: FirstActor -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation25PropagatedDeinitIsolated1CfZ : $@convention(thin) (@owned PropagatedDeinitIsolated1) -> () { -// CHECK-SYMB: // PropagatedDeinitIsolated1.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation25PropagatedDeinitIsolated1CfD : $@convention(method) (@owned PropagatedDeinitIsolated1) -> () { -@FirstActor -class PropagatedDeinitIsolated1: BaseWithDeinitIsolatedOnFirstActor { - // FirstActor-isolated deinit - isolated deinit { - isolatedFunc() // ok - } -} - -#if !SILGEN -@FirstActor -class NonisolatedDeinitIsolated1: BaseWithDeinitIsolatedOnFirstActor { - // nonisolated deinit - nonisolated deinit { // expected-error {{nonisolated deinitializer 'deinit' has different actor isolation from global actor 'FirstActor'-isolated overridden declaration}} - isolatedFunc() // expected-error {{call to global actor 'FirstActor'-isolated global function 'isolatedFunc()' in a synchronous nonisolated context}} - } -} -#endif - -// CHECK-LABEL: @_inheritsConvenienceInitializers class IsolatedDeinitIsolated1 : BaseWithDeinitIsolatedOnFirstActor { -// CHECK: {{(@objc )?}}@FirstActor deinit -// CHECK: } -// CHECK-SYMB: // IsolatedDeinitIsolated1.__isolated_deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: global_actor. type: FirstActor -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation23IsolatedDeinitIsolated1CfZ : $@convention(thin) (@owned IsolatedDeinitIsolated1) -> () { -// CHECK-SYMB: // IsolatedDeinitIsolated1.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation23IsolatedDeinitIsolated1CfD : $@convention(method) (@owned IsolatedDeinitIsolated1) -> () { -class IsolatedDeinitIsolated1: BaseWithDeinitIsolatedOnFirstActor { - // FirstActor-isolated deinit - @FirstActor deinit { - isolatedFunc() // ok - } -} - -#if !SILGEN -@FirstActor -class DifferentIsolatedDeinitIsolated1: BaseWithDeinitIsolatedOnFirstActor { - // error - @SecondActor deinit { // expected-error {{global actor 'SecondActor'-isolated deinitializer 'deinit' has different actor isolation from global actor 'FirstActor'-isolated overridden declaration}} - isolatedFunc() // expected-error {{call to global actor 'FirstActor'-isolated global function 'isolatedFunc()' in a synchronous global actor 'SecondActor'-isolated context}} - } -} -#endif - -// MARK: - Part 2.4 - Base class with isolated deinit with different actor - -// CHECK-LABEL: @_inheritsConvenienceInitializers @FirstActor class ImplicitDeinitInheritIsolated2 : BaseWithDeinitIsolatedOnSecondActor { -// CHECK: {{(@objc )?}} deinit -// CHECK: } -// CHECK-SYMB: // ImplicitDeinitInheritIsolated2.__isolated_deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: global_actor. type: SecondActor -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation30ImplicitDeinitInheritIsolated2CfZ : $@convention(thin) (@owned ImplicitDeinitInheritIsolated2) -> () { -// CHECK-SYMB: // ImplicitDeinitInheritIsolated2.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation30ImplicitDeinitInheritIsolated2CfD : $@convention(method) (@owned ImplicitDeinitInheritIsolated2) -> () { -@FirstActor -class ImplicitDeinitInheritIsolated2: BaseWithDeinitIsolatedOnSecondActor { - // SecondActor-isolated deinit -} - -// CHECK-LABEL: @_inheritsConvenienceInitializers @SecondActor class GoodPropagatedDeinitIsolated2 : BaseIsolatedOnSecondActor { -// CHECK: {{(@objc )?}}isolated deinit -// CHECK: } -// CHECK-SYMB: // GoodPropagatedDeinitIsolated2.__isolated_deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: global_actor. type: SecondActor -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation29GoodPropagatedDeinitIsolated2CfZ : $@convention(thin) (@owned GoodPropagatedDeinitIsolated2) -> () { -// CHECK-SYMB: // GoodPropagatedDeinitIsolated2.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation29GoodPropagatedDeinitIsolated2CfD : $@convention(method) (@owned GoodPropagatedDeinitIsolated2) -> () { -class GoodPropagatedDeinitIsolated2: BaseIsolatedOnSecondActor { - isolated deinit { -#if !SILGEN - isolatedFunc() // expected-error {{call to global actor 'FirstActor'-isolated global function 'isolatedFunc()' in a synchronous global actor 'SecondActor'-isolated context}} -#endif - } -} - -#if !SILGEN -@FirstActor -class PropagatedDeinitIsolated2: BaseWithDeinitIsolatedOnSecondActor { - // SecondActor-isolated deinit - isolated deinit { // expected-error {{global actor 'FirstActor'-isolated deinitializer 'deinit' has different actor isolation from global actor 'SecondActor'-isolated overridden declaration}} - isolatedFunc() // ok - } -} -#endif - -#if !SILGEN -@FirstActor -class NonisolatedDeinitIsolated2: BaseWithDeinitIsolatedOnSecondActor { - // nonisolated deinit - nonisolated deinit { // expected-error {{nonisolated deinitializer 'deinit' has different actor isolation from global actor 'SecondActor'-isolated overridden declaration}} - isolatedFunc() // expected-error {{call to global actor 'FirstActor'-isolated global function 'isolatedFunc()' in a synchronous nonisolated context}} - } -} -#endif - -#if !SILGEN -class IsolatedDeinitIsolated2: BaseWithDeinitIsolatedOnSecondActor { - // FirstActor-isolated deinit - @FirstActor deinit { // expected-error {{global actor 'FirstActor'-isolated deinitializer 'deinit' has different actor isolation from global actor 'SecondActor'-isolated overridden declaration}} - isolatedFunc() // ok - } -} -#endif - -// CHECK-LABEL: @_inheritsConvenienceInitializers @FirstActor class DifferentIsolatedDeinitIsolated2 : BaseWithDeinitIsolatedOnSecondActor { -// CHECK: {{(@objc )?}}@SecondActor deinit -// CHECK: } -// CHECK-SYMB: // DifferentIsolatedDeinitIsolated2.__isolated_deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: global_actor. type: SecondActor -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation32DifferentIsolatedDeinitIsolated2CfZ : $@convention(thin) (@owned DifferentIsolatedDeinitIsolated2) -> () { -// CHECK-SYMB: // DifferentIsolatedDeinitIsolated2.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s16deinit_isolation32DifferentIsolatedDeinitIsolated2CfD : $@convention(method) (@owned DifferentIsolatedDeinitIsolated2) -> () { -@FirstActor -class DifferentIsolatedDeinitIsolated2: BaseWithDeinitIsolatedOnSecondActor { - // SecondActor-isolated deinit - @SecondActor deinit { -#if !SILGEN - isolatedFunc() // expected-error {{call to global actor 'FirstActor'-isolated global function 'isolatedFunc()' in a synchronous global actor 'SecondActor'-isolated context}} -#endif - } -} - -#if !SILGEN -public class PublicIsolatedOnPrivateActor { - // TODO: Both should be producing an error - @PrivateActor public func ababahalamaha() {} - @PrivateActor deinit {} -} -#endif diff --git a/test/Concurrency/deinit_isolation_import/Inputs/Alpha.framework/Modules/module.modulemap b/test/Concurrency/deinit_isolation_import/Inputs/Alpha.framework/Modules/module.modulemap deleted file mode 100644 index 6b9f7b16e3b..00000000000 --- a/test/Concurrency/deinit_isolation_import/Inputs/Alpha.framework/Modules/module.modulemap +++ /dev/null @@ -1,4 +0,0 @@ -framework module Alpha [system] { - header "Alpha-Swift.h" - requires objc -} diff --git a/test/Concurrency/deinit_isolation_import/Inputs/Alpha.swift b/test/Concurrency/deinit_isolation_import/Inputs/Alpha.swift deleted file mode 100644 index 712fbc9873d..00000000000 --- a/test/Concurrency/deinit_isolation_import/Inputs/Alpha.swift +++ /dev/null @@ -1,7 +0,0 @@ -import ObjectiveC - -@objc open class RoundtripNonisolated: NSObject {} - -@objc open class RoundtripIsolated: NSObject { - @MainActor deinit {} -} diff --git a/test/Concurrency/deinit_isolation_import/Inputs/Beta.framework/Modules/module.modulemap b/test/Concurrency/deinit_isolation_import/Inputs/Beta.framework/Modules/module.modulemap deleted file mode 100644 index d930a10d9e9..00000000000 --- a/test/Concurrency/deinit_isolation_import/Inputs/Beta.framework/Modules/module.modulemap +++ /dev/null @@ -1,6 +0,0 @@ -framework module Beta { - umbrella header "Beta.h" - - export * - module * { export * } -} diff --git a/test/Concurrency/deinit_isolation_import/Inputs/Beta.h b/test/Concurrency/deinit_isolation_import/Inputs/Beta.h deleted file mode 100644 index 0ec66e3fcf9..00000000000 --- a/test/Concurrency/deinit_isolation_import/Inputs/Beta.h +++ /dev/null @@ -1,42 +0,0 @@ -@import Foundation; -@import Alpha; - -#define MAIN_ACTOR __attribute__((swift_attr("@MainActor"))) - -@interface BaseNonisolated : NSObject -@end -@interface DerivedNonisolated : BaseNonisolated -@end - -MAIN_ACTOR -@interface BaseIsolatedClass : NSObject -@end -@interface DerivedIsolatedClass : BaseIsolatedClass -@end - -@interface BaseIsolatedDealloc : NSObject -- (void)dealloc MAIN_ACTOR; -@end -@interface DerivedIsolatedDealloc : BaseIsolatedDealloc -@end - -@protocol DeallocP -- (void)dealloc MAIN_ACTOR; -@end - -@interface DeallocIsolatedFromProtocol : NSObject -@end - -@interface DeallocIsolatedFromCategory : NSObject -@end - -@interface DeallocIsolatedFromCategory (Extra) -- (void)dealloc MAIN_ACTOR; -@end - -@interface DeallocIsolatedFromExtension : NSObject -@end - -@interface DeallocIsolatedFromExtension () -- (void)dealloc MAIN_ACTOR; -@end diff --git a/test/Concurrency/deinit_isolation_import/test.swift b/test/Concurrency/deinit_isolation_import/test.swift deleted file mode 100644 index 386da4da763..00000000000 --- a/test/Concurrency/deinit_isolation_import/test.swift +++ /dev/null @@ -1,489 +0,0 @@ -// RUN: %empty-directory(%t/Frameworks) -// RUN: INPUT_DIR=%S/Inputs -// RUN: cp -R $INPUT_DIR/Alpha.framework %t/Frameworks/ -// RUN: %empty-directory(%t/Frameworks/Alpha.framework/Modules/Alpha.swiftmodule) -// RUN: %empty-directory(%t/Frameworks/Alpha.framework/Headers/) -// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -disable-implicit-string-processing-module-import -parse-as-library -module-name Alpha \ -// RUN: -emit-module -o %t/Frameworks/Alpha.framework/Modules/Alpha.swiftmodule/%module-target-triple.swiftmodule \ -// RUN: -enable-objc-interop -disable-objc-attr-requires-foundation-module \ -// RUN: -emit-objc-header -emit-objc-header-path %t/Frameworks/Alpha.framework/Headers/Alpha-Swift.h $INPUT_DIR/Alpha.swift -// RUN: cp -R $INPUT_DIR/Beta.framework %t/Frameworks/ -// RUN: %empty-directory(%t/Frameworks/Beta.framework/Headers/) -// RUN: cp $INPUT_DIR/Beta.h %t/Frameworks/Beta.framework/Headers/Beta.h -// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -disable-implicit-string-processing-module-import -disable-availability-checking -typecheck -verify %s -F %t/Frameworks -F %clang-importer-sdk-path/frameworks -// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -disable-implicit-string-processing-module-import -disable-availability-checking -parse-as-library -emit-silgen -DSILGEN %s -F %t/Frameworks -F %clang-importer-sdk-path/frameworks | %FileCheck %s -// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -disable-implicit-string-processing-module-import -disable-availability-checking -parse-as-library -emit-silgen -DSILGEN %s -F %t/Frameworks -F %clang-importer-sdk-path/frameworks | %FileCheck -check-prefix=CHECK-SYMB %s - -// REQUIRES: concurrency -// REQUIRES: objc_interop - -// Note: intentionally importing Alpha implicitly -import Beta - -@globalActor final actor AnotherActor { - static let shared = AnotherActor() -} - -// MARK: - RoundtripNonisolated - -@MainActor -func isolatedFunc() {} // expected-note 15{{calls to global function 'isolatedFunc()' from outside of its actor context are implicitly asynchronous}} - -// CHECK-LABEL: @objc @_inheritsConvenienceInitializers class ProbeImplicit_RoundtripNonisolated : RoundtripNonisolated { -// CHECK: @objc deinit -// CHECK: } -// CHECK-SYMB-NOT: ProbeImplicit_RoundtripNonisolated.__isolated_deallocating_deinit -// CHECK-SYMB-NOT: @$s4test34ProbeImplicit_RoundtripNonisolatedCfZ -// CHECK-SYMB: // ProbeImplicit_RoundtripNonisolated.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s4test34ProbeImplicit_RoundtripNonisolatedCfD : $@convention(method) (@owned ProbeImplicit_RoundtripNonisolated) -> () { -class ProbeImplicit_RoundtripNonisolated: RoundtripNonisolated {} - -// CHECK-LABEL: @objc @_inheritsConvenienceInitializers class ProbeDefault_RoundtripNonisolated : RoundtripNonisolated { -// CHECK: @objc deinit -// CHECK: } -// CHECK-SYMB-NOT: ProbeDefault_RoundtripNonisolated.__isolated_deallocating_deinit -// CHECK-SYMB-NOT: @$s4test33ProbeDefault_RoundtripNonisolatedCfZ -// CHECK-SYMB: // ProbeDefault_RoundtripNonisolated.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s4test33ProbeDefault_RoundtripNonisolatedCfD : $@convention(method) (@owned ProbeDefault_RoundtripNonisolated) -> () { -class ProbeDefault_RoundtripNonisolated: RoundtripNonisolated { - deinit { -#if !SILGEN - isolatedFunc() // expected-error {{call to main actor-isolated global function 'isolatedFunc()' in a synchronous nonisolated context}} -#endif - } -} - -#if !SILGEN -class ProbeIsolated_RoundtripNonisolated: RoundtripNonisolated { - isolated deinit { // expected-error {{deinit is marked isolated, but containing class 'ProbeIsolated_RoundtripNonisolated' is not isolated to an actor}} - isolatedFunc() // expected-error {{call to main actor-isolated global function 'isolatedFunc()' in a synchronous nonisolated context}} - } -} -#endif - -// CHECK-LABEL: @objc @_inheritsConvenienceInitializers class ProbeGlobal_RoundtripNonisolated : RoundtripNonisolated { -// CHECK: @objc @AnotherActor deinit -// CHECK: } -// CHECK-SYMB: ProbeGlobal_RoundtripNonisolated.__isolated_deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: global_actor. type: AnotherActor -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s4test32ProbeGlobal_RoundtripNonisolatedCfZ : $@convention(thin) (@owned ProbeGlobal_RoundtripNonisolated) -> () { -// CHECK-SYMB: // ProbeGlobal_RoundtripNonisolated.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s4test32ProbeGlobal_RoundtripNonisolatedCfD : $@convention(method) (@owned ProbeGlobal_RoundtripNonisolated) -> () { -class ProbeGlobal_RoundtripNonisolated: RoundtripNonisolated { - @AnotherActor deinit { -#if !SILGEN - isolatedFunc() // expected-error {{call to main actor-isolated global function 'isolatedFunc()' in a synchronous global actor 'AnotherActor'-isolated context}} -#endif - } -} - -// MARK: - RoundtripIsolated - -// CHECK-LABEL: @objc @_inheritsConvenienceInitializers class ProbeImplicit_RoundtripIsolated : RoundtripIsolated { -// Note: Type-checked as isolated, but no @MainActor attribute, because attributes are not added for overriding members -// CHECK: @objc deinit -// CHECK: } -// CHECK-SYMB: ProbeImplicit_RoundtripIsolated.__isolated_deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: global_actor. type: MainActor -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s4test31ProbeImplicit_RoundtripIsolatedCfZ : $@convention(thin) (@owned ProbeImplicit_RoundtripIsolated) -> () { -// CHECK-SYMB: // ProbeImplicit_RoundtripIsolated.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s4test31ProbeImplicit_RoundtripIsolatedCfD : $@convention(method) (@owned ProbeImplicit_RoundtripIsolated) -> () { -class ProbeImplicit_RoundtripIsolated: RoundtripIsolated {} - -#if !SILGEN -class ProbeDefault_RoundtripIsolated: RoundtripIsolated { - deinit {} // expected-error {{nonisolated deinitializer 'deinit' has different actor isolation from main actor-isolated overridden declaration}} -} -#endif - -#if !SILGEN -class ProbeIsolated_RoundtripIsolated: RoundtripIsolated { - isolated deinit { // expected-error {{deinit is marked isolated, but containing class 'ProbeIsolated_RoundtripIsolated' is not isolated to an actor}} - isolatedFunc() // ok, isolation of the overridden deinit is used as a recovery strategy - } -} -#endif - -// CHECK-LABEL: @objc @_inheritsConvenienceInitializers class ProbeGlobal_RoundtripIsolated : RoundtripIsolated { -// CHECK: @objc @MainActor deinit -// CHECK: } -// CHECK-SYMB: ProbeGlobal_RoundtripIsolated.__isolated_deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: global_actor. type: MainActor -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s4test29ProbeGlobal_RoundtripIsolatedCfZ : $@convention(thin) (@owned ProbeGlobal_RoundtripIsolated) -> () { -// CHECK-SYMB: // ProbeGlobal_RoundtripIsolated.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s4test29ProbeGlobal_RoundtripIsolatedCfD : $@convention(method) (@owned ProbeGlobal_RoundtripIsolated) -> () { -class ProbeGlobal_RoundtripIsolated: RoundtripIsolated { -#if !SILGEN - @AnotherActor deinit {} // expected-error {{global actor 'AnotherActor'-isolated deinitializer 'deinit' has different actor isolation from main actor-isolated overridden declaration}} -#else - @MainActor deinit {} -#endif -} - -// MARK: - BaseNonisolated - -// CHECK-LABEL: @objc @_inheritsConvenienceInitializers class ProbeImplicit_BaseNonisolated : BaseNonisolated { -// CHECK: @objc deinit -// CHECK: } -// CHECK-SYMB-NOT: ProbeImplicit_BaseNonisolated.__isolated_deallocating_deinit -// CHECK-SYMB-NOT: @$s4test29ProbeImplicit_BaseNonisolatedCfZ -// CHECK-SYMB: // ProbeImplicit_BaseNonisolated.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s4test29ProbeImplicit_BaseNonisolatedCfD : $@convention(method) (@owned ProbeImplicit_BaseNonisolated) -> () { -class ProbeImplicit_BaseNonisolated: BaseNonisolated {} - -// CHECK-LABEL: @objc @_inheritsConvenienceInitializers class ProbeDefault_BaseNonisolated : BaseNonisolated { -// CHECK: @objc deinit -// CHECK: } -// CHECK-SYMB-NOT: ProbeDefault_BaseNonisolated.__isolated_deallocating_deinit -// CHECK-SYMB-NOT: @$s4test28ProbeDefault_BaseNonisolatedCfZ -// CHECK-SYMB: // ProbeDefault_BaseNonisolated.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s4test28ProbeDefault_BaseNonisolatedCfD : $@convention(method) (@owned ProbeDefault_BaseNonisolated) -> () { -class ProbeDefault_BaseNonisolated: BaseNonisolated { - deinit { -#if !SILGEN - isolatedFunc() // expected-error {{call to main actor-isolated global function 'isolatedFunc()' in a synchronous nonisolated context}} -#endif - } -} - -#if !SILGEN -class ProbeIsolated_BaseNonisolated: BaseNonisolated { - isolated deinit { // expected-error {{deinit is marked isolated, but containing class 'ProbeIsolated_BaseNonisolated' is not isolated to an actor}} - isolatedFunc() // expected-error {{call to main actor-isolated global function 'isolatedFunc()' in a synchronous nonisolated context}} - } -} -#endif - -// CHECK-LABEL: @objc @_inheritsConvenienceInitializers class ProbeGlobal_BaseNonisolated : BaseNonisolated { -// CHECK: @objc @AnotherActor deinit -// CHECK: } -// CHECK-SYMB: ProbeGlobal_BaseNonisolated.__isolated_deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: global_actor. type: AnotherActor -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s4test27ProbeGlobal_BaseNonisolatedCfZ : $@convention(thin) (@owned ProbeGlobal_BaseNonisolated) -> () { -// CHECK-SYMB: // ProbeGlobal_BaseNonisolated.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s4test27ProbeGlobal_BaseNonisolatedCfD : $@convention(method) (@owned ProbeGlobal_BaseNonisolated) -> () { -class ProbeGlobal_BaseNonisolated: BaseNonisolated { - @AnotherActor deinit { -#if !SILGEN - isolatedFunc() // expected-error {{call to main actor-isolated global function 'isolatedFunc()' in a synchronous global actor 'AnotherActor'-isolated context}} -#endif - } -} - -// MARK: - DerivedNonisolated - -// CHECK-LABEL: @objc @_inheritsConvenienceInitializers class ProbeImplicit_DerivedNonisolated : DerivedNonisolated { -// CHECK: @objc deinit -// CHECK: } -// CHECK-SYMB-NOT: ProbeImplicit_DerivedNonisolated.__isolated_deallocating_deinit -// CHECK-SYMB-NOT: @$s4test32ProbeImplicit_DerivedNonisolatedCfZ -// CHECK-SYMB: // ProbeImplicit_DerivedNonisolated.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s4test32ProbeImplicit_DerivedNonisolatedCfD : $@convention(method) (@owned ProbeImplicit_DerivedNonisolated) -> () { -class ProbeImplicit_DerivedNonisolated: DerivedNonisolated {} - -// CHECK-LABEL: @objc @_inheritsConvenienceInitializers class ProbeDefault_DerivedNonisolated : DerivedNonisolated { -// CHECK: @objc deinit -// CHECK: } -// CHECK-SYMB-NOT: ProbeDefault_DerivedNonisolated.__isolated_deallocating_deinit -// CHECK-SYMB-NOT: @$s4test31ProbeDefault_DerivedNonisolatedCfZ -// CHECK-SYMB: // ProbeDefault_DerivedNonisolated.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s4test31ProbeDefault_DerivedNonisolatedCfD : $@convention(method) (@owned ProbeDefault_DerivedNonisolated) -> () { -class ProbeDefault_DerivedNonisolated: DerivedNonisolated { - deinit { -#if !SILGEN - isolatedFunc() // expected-error {{call to main actor-isolated global function 'isolatedFunc()' in a synchronous nonisolated context}} -#endif - } -} - -#if !SILGEN -class ProbeIsolated_DerivedNonisolated: DerivedNonisolated { - isolated deinit { // expected-error {{deinit is marked isolated, but containing class 'ProbeIsolated_DerivedNonisolated' is not isolated to an actor}} - isolatedFunc() // expected-error {{call to main actor-isolated global function 'isolatedFunc()' in a synchronous nonisolated context}} - } -} -#endif - -// CHECK-LABEL: @objc @_inheritsConvenienceInitializers class ProbeGlobal_DerivedNonisolated : DerivedNonisolated { -// CHECK: @objc @AnotherActor deinit -// CHECK: } -// CHECK-SYMB: ProbeGlobal_DerivedNonisolated.__isolated_deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: global_actor. type: AnotherActor -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s4test30ProbeGlobal_DerivedNonisolatedCfZ : $@convention(thin) (@owned ProbeGlobal_DerivedNonisolated) -> () { -// CHECK-SYMB: // ProbeGlobal_DerivedNonisolated.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s4test30ProbeGlobal_DerivedNonisolatedCfD : $@convention(method) (@owned ProbeGlobal_DerivedNonisolated) -> () { -class ProbeGlobal_DerivedNonisolated: DerivedNonisolated { - @AnotherActor deinit { -#if !SILGEN - isolatedFunc() // expected-error {{call to main actor-isolated global function 'isolatedFunc()' in a synchronous global actor 'AnotherActor'-isolated context}} -#endif - } -} - -// MARK: - BaseIsolatedClass - -// CHECK-LABEL: @objc @_inheritsConvenienceInitializers @MainActor @preconcurrency class ProbeImplicit_BaseIsolatedClass : BaseIsolatedClass { -// CHECK: @objc deinit -// CHECK: } -// CHECK-SYMB-NOT: ProbeImplicit_BaseIsolatedClass.__isolated_deallocating_deinit -// CHECK-SYMB-NOT: @$s4test31ProbeImplicit_BaseIsolatedClassCfZ -// CHECK-SYMB: // ProbeImplicit_BaseIsolatedClass.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s4test31ProbeImplicit_BaseIsolatedClassCfD : $@convention(method) (@owned ProbeImplicit_BaseIsolatedClass) -> () { -class ProbeImplicit_BaseIsolatedClass: BaseIsolatedClass {} - -// CHECK-LABEL: @objc @_inheritsConvenienceInitializers @MainActor @preconcurrency class ProbeDefault_BaseIsolatedClass : BaseIsolatedClass { -// CHECK: @objc deinit -// CHECK: } -// CHECK-SYMB-NOT: ProbeDefault_BaseIsolatedClass.__isolated_deallocating_deinit -// CHECK-SYMB-NOT: @$s4test30ProbeDefault_BaseIsolatedClassCfZ -// CHECK-SYMB: // ProbeDefault_BaseIsolatedClass.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s4test30ProbeDefault_BaseIsolatedClassCfD : $@convention(method) (@owned ProbeDefault_BaseIsolatedClass) -> () { -class ProbeDefault_BaseIsolatedClass: BaseIsolatedClass { - deinit { -#if !SILGEN - isolatedFunc() // expected-error {{call to main actor-isolated global function 'isolatedFunc()' in a synchronous nonisolated context}} -#endif - } -} - -// CHECK-LABEL: @objc @_inheritsConvenienceInitializers @MainActor @preconcurrency class ProbeIsolated_BaseIsolatedClass : BaseIsolatedClass { -// CHECK: @objc @preconcurrency isolated deinit -// CHECK: } -// CHECK-SYMB: ProbeIsolated_BaseIsolatedClass.__isolated_deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: global_actor. type: MainActor -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s4test018ProbeIsolated_BaseC5ClassCfZ : $@convention(thin) (@owned ProbeIsolated_BaseIsolatedClass) -> () { -// CHECK-SYMB: // ProbeIsolated_BaseIsolatedClass.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s4test018ProbeIsolated_BaseC5ClassCfD : $@convention(method) (@owned ProbeIsolated_BaseIsolatedClass) -> () { -class ProbeIsolated_BaseIsolatedClass: BaseIsolatedClass { - isolated deinit { - isolatedFunc() - } -} - -// CHECK-LABEL: @objc @_inheritsConvenienceInitializers @MainActor @preconcurrency class ProbeGlobal_BaseIsolatedClass : BaseIsolatedClass { -// CHECK: @objc @AnotherActor deinit -// CHECK: } -// CHECK-SYMB: ProbeGlobal_BaseIsolatedClass.__isolated_deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: global_actor. type: AnotherActor -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s4test29ProbeGlobal_BaseIsolatedClassCfZ : $@convention(thin) (@owned ProbeGlobal_BaseIsolatedClass) -> () { -// CHECK-SYMB: // ProbeGlobal_BaseIsolatedClass.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s4test29ProbeGlobal_BaseIsolatedClassCfD : $@convention(method) (@owned ProbeGlobal_BaseIsolatedClass) -> () { -class ProbeGlobal_BaseIsolatedClass: BaseIsolatedClass { - @AnotherActor deinit { -#if !SILGEN - isolatedFunc() // expected-error {{call to main actor-isolated global function 'isolatedFunc()' in a synchronous global actor 'AnotherActor'-isolated context}} -#endif - } -} - -// MARK: - DerivedIsolatedClass - -// CHECK-LABEL: @objc @_inheritsConvenienceInitializers @MainActor @preconcurrency class ProbeImplicit_DerivedIsolatedClass : DerivedIsolatedClass { -// CHECK: @objc deinit -// CHECK: } -// CHECK-SYMB-NOT: ProbeImplicit_DerivedIsolatedClass.__isolated_deallocating_deinit -// CHECK-SYMB-NOT: @$s4test34ProbeImplicit_DerivedIsolatedClassCfZ -// CHECK-SYMB: // ProbeImplicit_DerivedIsolatedClass.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s4test34ProbeImplicit_DerivedIsolatedClassCfD : $@convention(method) (@owned ProbeImplicit_DerivedIsolatedClass) -> () { -class ProbeImplicit_DerivedIsolatedClass: DerivedIsolatedClass {} - -// CHECK-LABEL: @objc @_inheritsConvenienceInitializers @MainActor @preconcurrency class ProbeDefault_DerivedIsolatedClass : DerivedIsolatedClass { -// CHECK: @objc deinit -// CHECK: } -// CHECK-SYMB-NOT: ProbeDefault_DerivedIsolatedClass.__isolated_deallocating_deinit -// CHECK-SYMB-NOT: @$s4test33ProbeDefault_DerivedIsolatedClassCfZ -// CHECK-SYMB: // ProbeDefault_DerivedIsolatedClass.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s4test33ProbeDefault_DerivedIsolatedClassCfD : $@convention(method) (@owned ProbeDefault_DerivedIsolatedClass) -> () { -class ProbeDefault_DerivedIsolatedClass: DerivedIsolatedClass { - deinit { -#if !SILGEN - isolatedFunc() // expected-error {{call to main actor-isolated global function 'isolatedFunc()' in a synchronous nonisolated context}} -#endif - } -} - -// CHECK-LABEL: @objc @_inheritsConvenienceInitializers @MainActor @preconcurrency class ProbeIsolated_DerivedIsolatedClass : DerivedIsolatedClass { -// CHECK: @objc @preconcurrency isolated deinit -// CHECK: } -// CHECK-SYMB: ProbeIsolated_DerivedIsolatedClass.__isolated_deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: global_actor. type: MainActor -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s4test021ProbeIsolated_DerivedC5ClassCfZ : $@convention(thin) (@owned ProbeIsolated_DerivedIsolatedClass) -> () { -// CHECK-SYMB: // ProbeIsolated_DerivedIsolatedClass.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s4test021ProbeIsolated_DerivedC5ClassCfD : $@convention(method) (@owned ProbeIsolated_DerivedIsolatedClass) -> () { -class ProbeIsolated_DerivedIsolatedClass: DerivedIsolatedClass { - isolated deinit { - isolatedFunc() - } -} - -// CHECK-LABEL: @objc @_inheritsConvenienceInitializers @MainActor @preconcurrency class ProbeGlobal_DerivedIsolatedClass : DerivedIsolatedClass { -// CHECK: @objc @AnotherActor deinit -// CHECK: } -// CHECK-SYMB: ProbeGlobal_DerivedIsolatedClass.__isolated_deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: global_actor. type: AnotherActor -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s4test32ProbeGlobal_DerivedIsolatedClassCfZ : $@convention(thin) (@owned ProbeGlobal_DerivedIsolatedClass) -> () { -// CHECK-SYMB: // ProbeGlobal_DerivedIsolatedClass.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s4test32ProbeGlobal_DerivedIsolatedClassCfD : $@convention(method) (@owned ProbeGlobal_DerivedIsolatedClass) -> () { -class ProbeGlobal_DerivedIsolatedClass: DerivedIsolatedClass { - @AnotherActor deinit { -#if !SILGEN - isolatedFunc() // expected-error {{call to main actor-isolated global function 'isolatedFunc()' in a synchronous global actor 'AnotherActor'-isolated context}} -#endif - } -} - -// MARK: - BaseIsolatedDealloc - -// If isolation was introduced in ObjC code, then we assume that ObjC code also -// overrides retain/release to make sure that dealloc is called on the correct -// executor in the first place. - -// CHECK-LABEL: @objc @_inheritsConvenienceInitializers class ProbeImplicit_BaseIsolatedDealloc : BaseIsolatedDealloc { -// CHECK: @objc deinit -// CHECK: } -// CHECK-SYMB-NOT: ProbeImplicit_BaseIsolatedDealloc.__isolated_deallocating_deinit -// CHECK-SYMB-NOT: @$s4test33ProbeImplicit_BaseIsolatedDeallocCfZ -// CHECK-SYMB: // ProbeImplicit_BaseIsolatedDealloc.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s4test33ProbeImplicit_BaseIsolatedDeallocCfD : $@convention(method) (@owned ProbeImplicit_BaseIsolatedDealloc) -> () { -class ProbeImplicit_BaseIsolatedDealloc: BaseIsolatedDealloc {} - -#if !SILGEN -class ProbeDefault_BaseIsolatedDealloc: BaseIsolatedDealloc { - deinit { // expected-error {{nonisolated deinitializer 'deinit' has different actor isolation from main actor-isolated overridden declaration}} - isolatedFunc() // expected-error {{call to main actor-isolated global function 'isolatedFunc()' in a synchronous nonisolated context}} - } -} -#endif - -#if !SILGEN -class ProbeIsolated_BaseIsolatedDealloc: BaseIsolatedDealloc { - isolated deinit { //expected-error {{deinit is marked isolated, but containing class 'ProbeIsolated_BaseIsolatedDealloc' is not isolated to an actor}} - isolatedFunc() // ok, isolation of the overridden deinit is used as a recovery strategy - } -} -#endif - -// CHECK-LABEL: @objc @_inheritsConvenienceInitializers class ProbeGlobal_BaseIsolatedDealloc : BaseIsolatedDealloc { -// CHECK: @objc @MainActor deinit -// CHECK: } -// CHECK-SYMB-NOT: ProbeGlobal_BaseIsolatedDealloc.__isolated_deallocating_deinit -// CHECK-SYMB-NOT: @$s4test31ProbeGlobal_BaseIsolatedDeallocCfZ -// CHECK-SYMB: // ProbeGlobal_BaseIsolatedDealloc.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s4test31ProbeGlobal_BaseIsolatedDeallocCfD : $@convention(method) (@owned ProbeGlobal_BaseIsolatedDealloc) -> () { -class ProbeGlobal_BaseIsolatedDealloc: BaseIsolatedDealloc { -#if !SILGEN - @AnotherActor deinit {} // expected-error {{global actor 'AnotherActor'-isolated deinitializer 'deinit' has different actor isolation from main actor-isolated overridden declaration}} -#else - @MainActor deinit {} -#endif -} - -// MARK: - DerivedIsolatedDealloc - -// CHECK-LABEL: @objc @_inheritsConvenienceInitializers class ProbeImplicit_DerivedIsolatedDealloc : DerivedIsolatedDealloc { -// Note: Type-checked as isolated, but no @MainActor attribute, because attributes are not added for overriding members -// CHECK: @objc deinit -// CHECK: } -// CHECK-SYMB-NOT: ProbeImplicit_DerivedIsolatedDealloc.__isolated_deallocating_deinit -// CHECK-SYMB-NOT: @$s4test36ProbeImplicit_DerivedIsolatedDeallocCfZ -// CHECK-SYMB: // ProbeImplicit_DerivedIsolatedDealloc.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s4test36ProbeImplicit_DerivedIsolatedDeallocCfD : $@convention(method) (@owned ProbeImplicit_DerivedIsolatedDealloc) -> () { -class ProbeImplicit_DerivedIsolatedDealloc: DerivedIsolatedDealloc {} - -#if !SILGEN -class ProbeDefault_DerivedIsolatedDealloc: DerivedIsolatedDealloc { - deinit { // expected-error {{nonisolated deinitializer 'deinit' has different actor isolation from main actor-isolated overridden declaration}} - isolatedFunc() // expected-error {{call to main actor-isolated global function 'isolatedFunc()' in a synchronous nonisolated context}} - } -} -#endif - -#if !SILGEN -class ProbeIsolated_DerivedIsolatedDealloc: DerivedIsolatedDealloc { - isolated deinit { //expected-error {{deinit is marked isolated, but containing class 'ProbeIsolated_DerivedIsolatedDealloc' is not isolated to an actor}} - isolatedFunc() // ok, isolation of the overridden deinit is used as a recovery strategy - } -} -#endif - -// CHECK-LABEL: @objc @_inheritsConvenienceInitializers class ProbeGlobal_DerivedIsolatedDealloc : DerivedIsolatedDealloc { -// CHECK: @objc @MainActor deinit -// CHECK: } -// CHECK-SYMB-NOT: ProbeGlobal_DerivedIsolatedDealloc.__isolated_deallocating_deinit -// CHECK-SYMB-NOT: @$s4test34ProbeGlobal_DerivedIsolatedDeallocCfZ -// CHECK-SYMB: // ProbeGlobal_DerivedIsolatedDealloc.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s4test34ProbeGlobal_DerivedIsolatedDeallocCfD : $@convention(method) (@owned ProbeGlobal_DerivedIsolatedDealloc) -> () { -class ProbeGlobal_DerivedIsolatedDealloc: DerivedIsolatedDealloc { -#if !SILGEN - @AnotherActor deinit {} // expected-error {{global actor 'AnotherActor'-isolated deinitializer 'deinit' has different actor isolation from main actor-isolated overridden declaration}} -#else - @MainActor deinit {} -#endif -} - -// MARK: - Isolated dealloc outside main declaration - -// CHECK-LABEL: @objc @_inheritsConvenienceInitializers class ProbeImplicit_DeallocIsolatedFromProtocol : DeallocIsolatedFromProtocol { -// CHECK: @objc deinit -// CHECK: } -// CHECK-SYMB-NOT: ProbeImplicit_DeallocIsolatedFromProtocol.__isolated_deallocating_deinit -// CHECK-SYMB-NOT: @$s4test41ProbeImplicit_DeallocIsolatedFromProtocolCfZ -// CHECK-SYMB: // ProbeImplicit_DeallocIsolatedFromProtocol.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s4test41ProbeImplicit_DeallocIsolatedFromProtocolCfD : $@convention(method) (@owned ProbeImplicit_DeallocIsolatedFromProtocol) -> () { -class ProbeImplicit_DeallocIsolatedFromProtocol: DeallocIsolatedFromProtocol {} - -class ProbeGlobal_DeallocIsolatedFromProtocol: DeallocIsolatedFromProtocol { - @AnotherActor deinit {} // ok, base is not isolated -} - -// CHECK-LABEL: @objc @_inheritsConvenienceInitializers class ProbeImplicit_DeallocIsolatedFromCategory : DeallocIsolatedFromCategory { -// CHECK: @objc deinit -// CHECK: } -// CHECK-SYMB-NOT: ProbeImplicit_DeallocIsolatedFromCategory.__isolated_deallocating_deinit -// CHECK-SYMB-NOT: @$s4test41ProbeImplicit_DeallocIsolatedFromCategoryCfZ -// CHECK-SYMB: // ProbeImplicit_DeallocIsolatedFromCategory.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s4test41ProbeImplicit_DeallocIsolatedFromCategoryCfD : $@convention(method) (@owned ProbeImplicit_DeallocIsolatedFromCategory) -> () { -class ProbeImplicit_DeallocIsolatedFromCategory: DeallocIsolatedFromCategory {} - -class ProbeGlobal_DeallocIsolatedFromCategory: DeallocIsolatedFromCategory { - @AnotherActor deinit {} // ok, base is not isolated -} - -// CHECK-LABEL: @objc @_inheritsConvenienceInitializers class ProbeImplicit_DeallocIsolatedFromExtension : DeallocIsolatedFromExtension { -// CHECK: @objc deinit -// CHECK: } -// CHECK-SYMB-NOT: ProbeImplicit_DeallocIsolatedFromExtension.__isolated_deallocating_deinit -// CHECK-SYMB-NOT: @$s4test42ProbeImplicit_DeallocIsolatedFromExtensionCfZ -// CHECK-SYMB: // ProbeImplicit_DeallocIsolatedFromExtension.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s4test42ProbeImplicit_DeallocIsolatedFromExtensionCfD : $@convention(method) (@owned ProbeImplicit_DeallocIsolatedFromExtension) -> () { -class ProbeImplicit_DeallocIsolatedFromExtension: DeallocIsolatedFromExtension {} - -class ProbeGlobal_DeallocIsolatedFromExtension: DeallocIsolatedFromExtension { - @AnotherActor deinit {} // ok, base is not isolated -} diff --git a/test/Concurrency/deinit_isolation_in_value_types.swift b/test/Concurrency/deinit_isolation_in_value_types.swift deleted file mode 100644 index 28c4521e204..00000000000 --- a/test/Concurrency/deinit_isolation_in_value_types.swift +++ /dev/null @@ -1,56 +0,0 @@ -// RUN: %target-swift-frontend -disable-availability-checking -parse-as-library -emit-silgen -verify %s - -@globalActor final actor FirstActor { - static let shared = FirstActor() -} - -struct AS: ~Copyable { - @FirstActor deinit {} // expected-error {{only classes and actors can have isolated deinit}} -} - -@FirstActor -struct BS: ~Copyable { - isolated deinit {} // expected-error {{only classes and actors can have isolated deinit}} -} - -struct CS: ~Copyable { - isolated deinit {} // expected-error {{only classes and actors can have isolated deinit}} -} - -struct DS: ~Copyable { - nonisolated deinit {} // expected-error {{only classes and actors can have isolated deinit}} -} - -struct ES: ~Copyable { - @FirstActor isolated deinit {} // expected-error 2 {{only classes and actors can have isolated deinit}} -} - -enum AE: ~Copyable { - // expected-error@+1 {{deinitializers are not yet supported on noncopyable enums}} - @FirstActor deinit {} // expected-error {{only classes and actors can have isolated deinit}} -} - -@FirstActor -enum BE: ~Copyable { - case dummy - // expected-error@+1 {{deinitializers are not yet supported on noncopyable enums}} - isolated deinit {} // expected-error {{only classes and actors can have isolated deinit}} -} - -enum CE: ~Copyable { - case dummy - // expected-error@+1 {{deinitializers are not yet supported on noncopyable enums}} - isolated deinit {} // expected-error {{only classes and actors can have isolated deinit}} -} - -enum DE: ~Copyable { - case dummy - // expected-error@+1 {{deinitializers are not yet supported on noncopyable enums}} - nonisolated deinit {} // expected-error {{only classes and actors can have isolated deinit}} -} - -enum EE: ~Copyable { - case dummy - // expected-error@+1 {{deinitializers are not yet supported on noncopyable enums}} - @FirstActor isolated deinit {} // expected-error 2 {{only classes and actors can have isolated deinit}} -} diff --git a/test/Concurrency/deinit_isolation_objc.swift b/test/Concurrency/deinit_isolation_objc.swift deleted file mode 100644 index 9d55fde70b2..00000000000 --- a/test/Concurrency/deinit_isolation_objc.swift +++ /dev/null @@ -1,546 +0,0 @@ -// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -disable-implicit-string-processing-module-import -disable-availability-checking -parse-as-library -emit-silgen -verify %s -// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -disable-implicit-string-processing-module-import -disable-availability-checking -parse-as-library -emit-silgen -DSILGEN %s | %FileCheck %s -// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -disable-implicit-string-processing-module-import -disable-availability-checking -parse-as-library -emit-silgen -DSILGEN %s | %FileCheck -check-prefix=CHECK-SYMB %s - -// REQUIRES: concurrency -// REQUIRES: objc_interop - -import Foundation - -// Fixtures - -@globalActor final actor FirstActor { - static let shared = FirstActor() -} - -@globalActor final actor SecondActor { - static let shared = SecondActor() -} - - -@FirstActor -func isolatedFunc() {} // expected-note 15{{calls to global function 'isolatedFunc()' from outside of its actor context are implicitly asynchronous}} - -// CHECK-LABEL: @_inheritsConvenienceInitializers @objc class BaseWithNonisolatedDeinit : NSObject { -// CHECK: @objc deinit -// CHECK: } -// CHECK-SYMB-NOT: BaseWithNonisolatedDeinit.__isolated_deallocating_deinit -// CHECK-SYMB-NOT: @$s21deinit_isolation_objc25BaseWithNonisolatedDeinitCfZ -// CHECK-SYMB: // BaseWithNonisolatedDeinit.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc25BaseWithNonisolatedDeinitCfD : $@convention(method) (@owned BaseWithNonisolatedDeinit) -> () { -@objc class BaseWithNonisolatedDeinit : NSObject {} - -// CHECK-LABEL: @_inheritsConvenienceInitializers @objc class BaseWithDeinitIsolatedOnFirstActor : NSObject { -// CHECK: @objc @FirstActor deinit -// CHECK: } -// CHECK-SYMB: BaseWithDeinitIsolatedOnFirstActor.__isolated_deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: global_actor. type: FirstActor -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc34BaseWithDeinitIsolatedOnFirstActorCfZ : $@convention(thin) (@owned BaseWithDeinitIsolatedOnFirstActor) -> () { -// CHECK-SYMB: BaseWithDeinitIsolatedOnFirstActor.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc34BaseWithDeinitIsolatedOnFirstActorCfD : $@convention(method) (@owned BaseWithDeinitIsolatedOnFirstActor) -> () { -@objc class BaseWithDeinitIsolatedOnFirstActor : NSObject { - @FirstActor deinit {} // expected-note 3{{overridden declaration is here}} -} - -@FirstActor -@objc class BaseIsolatedOnFirstActor: NSObject {} - -@SecondActor -@objc class BaseIsolatedOnSecondActor: NSObject {} - -// CHECK-LABEL: @_inheritsConvenienceInitializers @objc class BaseWithDeinitIsolatedOnSecondActor : NSObject { -// CHECK: @objc @SecondActor deinit -// CHECK: } -// CHECK-SYMB: BaseWithDeinitIsolatedOnSecondActor.__isolated_deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: global_actor. type: SecondActor -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc35BaseWithDeinitIsolatedOnSecondActorCfZ : $@convention(thin) (@owned BaseWithDeinitIsolatedOnSecondActor) -> () { -// CHECK-SYMB: BaseWithDeinitIsolatedOnSecondActor.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc35BaseWithDeinitIsolatedOnSecondActorCfD : $@convention(method) (@owned BaseWithDeinitIsolatedOnSecondActor) -> () { -@objc class BaseWithDeinitIsolatedOnSecondActor: NSObject { - @SecondActor deinit {} // expected-note 3{{overridden declaration is here}} -} - -// MARK: - Part 1 - Actors - -// CHECK-LABEL: @_inheritsConvenienceInitializers @objc actor ImplicitDeinitActor : NSObject { -// CHECK: @objc deinit -// CHECK: } -// CHECK-SYMB-NOT: ImplicitDeinitActor.__isolated_deallocating_deinit -// CHECK-SYMB-NOT: @$s21deinit_isolation_objc19ImplicitDeinitActorCfZ -// CHECK-SYMB: // ImplicitDeinitActor.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc19ImplicitDeinitActorCfD : $@convention(method) (@owned ImplicitDeinitActor) -> () { -@objc actor ImplicitDeinitActor : NSObject { - // nonisolated deinit -} - -// CHECK-LABEL: @_inheritsConvenienceInitializers @objc actor DefaultDeinitActor : NSObject { -// CHECK: @objc deinit -// CHECK: } -// CHECK-SYMB-NOT: DefaultDeinitActor.__isolated_deallocating_deinit -// CHECK-SYMB-NOT: @$s21deinit_isolation_objc18DefaultDeinitActorCfZ -// CHECK-SYMB: // DefaultDeinitActor.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc18DefaultDeinitActorCfD : $@convention(method) (@owned DefaultDeinitActor) -> () { -@objc actor DefaultDeinitActor : NSObject { - // self-isolated deinit - deinit { -#if !SILGEN - isolatedFunc() // expected-error {{call to global actor 'FirstActor'-isolated global function 'isolatedFunc()' in a synchronous nonisolated context}} -#endif - } -} - -// CHECK-LABEL: @_inheritsConvenienceInitializers @objc actor PropagatedDeinitActor : NSObject { -// CHECK: @objc isolated deinit -// CHECK: } -// CHECK-SYMB: // PropagatedDeinitActor.__isolated_deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: actor_instance. name: 'self' -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc21PropagatedDeinitActorCfZ : $@convention(thin) (@owned PropagatedDeinitActor) -> () { -// CHECK-SYMB: // PropagatedDeinitActor.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc21PropagatedDeinitActorCfD : $@convention(method) (@owned PropagatedDeinitActor) -> () { -@objc actor PropagatedDeinitActor : NSObject { - // self-isolated deinit - isolated deinit { -#if !SILGEN - isolatedFunc() // expected-error {{call to global actor 'FirstActor'-isolated global function 'isolatedFunc()' in a synchronous actor-isolated context}} -#endif - } -} - -// CHECK-LABEL: @_inheritsConvenienceInitializers @objc actor NonisolatedDeinitActor : NSObject { -// CHECK: @objc nonisolated deinit -// CHECK: } -// CHECK-SYMB-NOT: NonisolatedDeinitActor.__isolated_deallocating_deinit -// CHECK-SYMB-NOT: @$s21deinit_isolation_objc22NonisolatedDeinitActorCfZ -// CHECK-SYMB: // NonisolatedDeinitActor.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc22NonisolatedDeinitActorCfD : $@convention(method) (@owned NonisolatedDeinitActor) -> () { -@objc actor NonisolatedDeinitActor : NSObject { - // nonisolated deinit - nonisolated deinit { -#if !SILGEN - isolatedFunc() // expected-error {{call to global actor 'FirstActor'-isolated global function 'isolatedFunc()' in a synchronous nonisolated context}} -#endif - } -} - -// CHECK-LABEL: @_inheritsConvenienceInitializers @objc actor IsolatedDeinitActor : NSObject { -// CHECK: @objc @FirstActor deinit -// CHECK: } -// CHECK-SYMB: // IsolatedDeinitActor.__isolated_deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: global_actor. type: FirstActor -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc19IsolatedDeinitActorCfZ : $@convention(thin) (@owned IsolatedDeinitActor) -> () { -// CHECK-SYMB: // IsolatedDeinitActor.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc19IsolatedDeinitActorCfD : $@convention(method) (@owned IsolatedDeinitActor) -> () { -@objc actor IsolatedDeinitActor : NSObject { - // FirstActor-isolated deinit - @FirstActor deinit { - isolatedFunc() // ok - } -} - -// MARK: - Part 2 - Classes -// MARK: - Part 2.1 - Without base class - -// CHECK-LABEL: @_inheritsConvenienceInitializers @FirstActor @objc class ImplicitDeinit : NSObject { -// CHECK: @objc deinit -// CHECK: } -// CHECK-SYMB-NOT: ImplicitDeinit.__isolated_deallocating_deinit -// CHECK-SYMB-NOT: @$s21deinit_isolation_objc14ImplicitDeinitCfZ -// CHECK-SYMB: // ImplicitDeinit.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc14ImplicitDeinitCfD : $@convention(method) (@owned ImplicitDeinit) -> () { -@FirstActor -@objc class ImplicitDeinit : NSObject { - // nonisolated deinit -} - -// CHECK-LABEL: @_inheritsConvenienceInitializers @FirstActor @objc class DefaultDeinit : NSObject { -// CHECK: @objc deinit -// CHECK: } -// CHECK-SYMB-NOT: DefaultDeinit.__isolated_deallocating_deinit -// CHECK-SYMB-NOT: @$s21deinit_isolation_objc13DefaultDeinitCfZ -// CHECK-SYMB: // DefaultDeinit.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc13DefaultDeinitCfD : $@convention(method) (@owned DefaultDeinit) -> () { -@FirstActor -@objc class DefaultDeinit: NSObject { - deinit { -#if !SILGEN - isolatedFunc() // expected-error {{call to global actor 'FirstActor'-isolated global function 'isolatedFunc()' in a synchronous nonisolated context}} -#endif - } -} - -// CHECK-LABEL: @_inheritsConvenienceInitializers @FirstActor @objc class PropagatedDeinit : NSObject { -// CHECK: @objc isolated deinit -// CHECK: } -// CHECK-SYMB: // PropagatedDeinit.__isolated_deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: global_actor. type: FirstActor -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc16PropagatedDeinitCfZ : $@convention(thin) (@owned PropagatedDeinit) -> () { -// CHECK-SYMB: // PropagatedDeinit.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc16PropagatedDeinitCfD : $@convention(method) (@owned PropagatedDeinit) -> () { -@FirstActor -@objc class PropagatedDeinit: NSObject { - // FirstActor-isolated deinit - isolated deinit { - isolatedFunc() // ok - } -} - -#if !SILGEN -@objc class BadPropagatedDeinit: NSObject { - isolated deinit {} // expected-error {{deinit is marked isolated, but containing class 'BadPropagatedDeinit' is not isolated to an actor}} -} -#endif - -// CHECK-LABEL: @_inheritsConvenienceInitializers @FirstActor @objc class NonisolatedDeinit : NSObject { -// CHECK: @objc nonisolated deinit -// CHECK: } -// CHECK-SYMB-NOT: NonisolatedDeinit.__isolated_deallocating_deinit -// CHECK-SYMB-NOT: @$s21deinit_isolation_objc17NonisolatedDeinitCfZ -// CHECK-SYMB: // NonisolatedDeinit.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc17NonisolatedDeinitCfD : $@convention(method) (@owned NonisolatedDeinit) -> () { -@FirstActor -@objc class NonisolatedDeinit : NSObject { - // nonisolated deinit - nonisolated deinit { -#if !SILGEN - isolatedFunc() // expected-error {{call to global actor 'FirstActor'-isolated global function 'isolatedFunc()' in a synchronous nonisolated context}} -#endif - } -} - -// CHECK-LABEL: @_inheritsConvenienceInitializers @objc class IsolatedDeinit : NSObject { -// CHECK: @objc @FirstActor deinit -// CHECK: } -// CHECK-SYMB: // IsolatedDeinit.__isolated_deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: global_actor. type: FirstActor -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc14IsolatedDeinitCfZ : $@convention(thin) (@owned IsolatedDeinit) -> () { -// CHECK-SYMB: // IsolatedDeinit.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc14IsolatedDeinitCfD : $@convention(method) (@owned IsolatedDeinit) -> () { -@objc class IsolatedDeinit : NSObject { - // FirstActor-isolated deinit - @FirstActor deinit { - isolatedFunc() // ok - } -} - -// CHECK-LABEL: @_inheritsConvenienceInitializers @FirstActor @objc class DifferentIsolatedDeinit : NSObject { -// CHECK: @objc @SecondActor deinit -// CHECK: } -// CHECK-SYMB: // DifferentIsolatedDeinit.__isolated_deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: global_actor. type: SecondActor -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc23DifferentIsolatedDeinitCfZ : $@convention(thin) (@owned DifferentIsolatedDeinit) -> () { -// CHECK-SYMB: // DifferentIsolatedDeinit.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc23DifferentIsolatedDeinitCfD : $@convention(method) (@owned DifferentIsolatedDeinit) -> () { -@FirstActor -@objc class DifferentIsolatedDeinit : NSObject { - // SecondActor-isolated deinit - @SecondActor deinit { -#if !SILGEN - isolatedFunc() // expected-error {{call to global actor 'FirstActor'-isolated global function 'isolatedFunc()' in a synchronous global actor 'SecondActor'-isolated context}} -#endif - } -} - -// MARK: - Part 2.2 - Base class with nonisolated deinit - -// CHECK-LABEL: @_inheritsConvenienceInitializers @FirstActor @objc class ImplicitDeinitInheritNonisolated : BaseWithNonisolatedDeinit { -// CHECK: @objc deinit -// CHECK: } -// CHECK-SYMB-NOT: ImplicitDeinitInheritNonisolated.__isolated_deallocating_deinit -// CHECK-SYMB-NOT: @$s21deinit_isolation_objc32ImplicitDeinitInheritNonisolatedCfZ -// CHECK-SYMB: // ImplicitDeinitInheritNonisolated.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc32ImplicitDeinitInheritNonisolatedCfD : $@convention(method) (@owned ImplicitDeinitInheritNonisolated) -> () { -@FirstActor -@objc class ImplicitDeinitInheritNonisolated: BaseWithNonisolatedDeinit { - // nonisolated deinit -} - -// CHECK-LABEL: @_inheritsConvenienceInitializers @FirstActor @objc class DefaultDeinitInheritNonisolated : BaseWithNonisolatedDeinit { -// CHECK: @objc deinit -// CHECK: } -// CHECK-SYMB-NOT: // DefaultDeinitInheritNonisolated.__isolated_deallocating_deinit -// CHECK-SYMB-NOT: sil hidden [ossa] @$s21deinit_isolation_objc31DefaultDeinitInheritNonisolatedCfZ : $@convention(thin) (@owned DefaultDeinitInheritNonisolated) -> () { -// CHECK-SYMB: // DefaultDeinitInheritNonisolated.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc31DefaultDeinitInheritNonisolatedCfD : $@convention(method) (@owned DefaultDeinitInheritNonisolated) -> () { -@FirstActor -@objc class DefaultDeinitInheritNonisolated: BaseWithNonisolatedDeinit { - // nonisolated deinit - deinit { -#if !SILGEN - isolatedFunc() // expected-error {{call to global actor 'FirstActor'-isolated global function 'isolatedFunc()' in a synchronous nonisolated context}} -#endif - } -} - -#if !SILGEN -@objc class BadPropagatedDeinitInheritNonisolated: BaseWithNonisolatedDeinit { - isolated deinit {} // expected-error {{deinit is marked isolated, but containing class 'BadPropagatedDeinitInheritNonisolated' is not isolated to an actor}} -} -#endif - -// CHECK-LABEL: @_inheritsConvenienceInitializers @FirstActor @objc class PropagatedDeinitInheritNonisolated : BaseWithNonisolatedDeinit { -// CHECK: @objc isolated deinit -// CHECK: } -// CHECK-SYMB: // PropagatedDeinitInheritNonisolated.__isolated_deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: global_actor. type: FirstActor -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc34PropagatedDeinitInheritNonisolatedCfZ : $@convention(thin) (@owned PropagatedDeinitInheritNonisolated) -> () { -// CHECK-SYMB: // PropagatedDeinitInheritNonisolated.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc34PropagatedDeinitInheritNonisolatedCfD : $@convention(method) (@owned PropagatedDeinitInheritNonisolated) -> () { -@FirstActor -@objc class PropagatedDeinitInheritNonisolated: BaseWithNonisolatedDeinit { - // FirstActor-isolated deinit - isolated deinit { - isolatedFunc() // ok - } -} - -// CHECK-LABEL: @_inheritsConvenienceInitializers @FirstActor @objc class NonisolatedDeinitInheritNonisolated : BaseWithNonisolatedDeinit { -// CHECK: @objc nonisolated deinit -// CHECK: } -// CHECK-SYMB-NOT: NonisolatedDeinitInheritNonisolated.__isolated_deallocating_deinit -// CHECK-SYMB-NOT: @$s21deinit_isolation_objc024NonisolatedDeinitInheritD0CfZ -// CHECK-SYMB: // NonisolatedDeinitInheritNonisolated.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc024NonisolatedDeinitInheritD0CfD : $@convention(method) (@owned NonisolatedDeinitInheritNonisolated) -> () { -@FirstActor -@objc class NonisolatedDeinitInheritNonisolated: BaseWithNonisolatedDeinit { - // nonisolated deinit - nonisolated deinit { -#if !SILGEN - isolatedFunc() // expected-error {{call to global actor 'FirstActor'-isolated global function 'isolatedFunc()' in a synchronous nonisolated context}} -#endif - } -} - -// CHECK-LABEL: @_inheritsConvenienceInitializers @objc class IsolatedDeinitInheritNonisolated : BaseWithNonisolatedDeinit { -// CHECK: @objc @FirstActor deinit -// CHECK: } -// CHECK-SYMB: // IsolatedDeinitInheritNonisolated.__isolated_deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: global_actor. type: FirstActor -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc32IsolatedDeinitInheritNonisolatedCfZ : $@convention(thin) (@owned IsolatedDeinitInheritNonisolated) -> () { -// CHECK-SYMB: // IsolatedDeinitInheritNonisolated.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc32IsolatedDeinitInheritNonisolatedCfD : $@convention(method) (@owned IsolatedDeinitInheritNonisolated) -> () { -@objc class IsolatedDeinitInheritNonisolated: BaseWithNonisolatedDeinit { - // FirstActor-isolated deinit - @FirstActor deinit { - isolatedFunc() // ok - } -} - -// CHECK-LABEL: @_inheritsConvenienceInitializers @FirstActor @objc class DifferentIsolatedDeinitInheritNonisolated : BaseWithNonisolatedDeinit { -// CHECK: @objc @SecondActor deinit -// CHECK: } -// CHECK-SYMB: // DifferentIsolatedDeinitInheritNonisolated.__isolated_deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: global_actor. type: SecondActor -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc41DifferentIsolatedDeinitInheritNonisolatedCfZ : $@convention(thin) (@owned DifferentIsolatedDeinitInheritNonisolated) -> () { -// CHECK-SYMB: // DifferentIsolatedDeinitInheritNonisolated.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc41DifferentIsolatedDeinitInheritNonisolatedCfD : $@convention(method) (@owned DifferentIsolatedDeinitInheritNonisolated) -> () { -@FirstActor -@objc class DifferentIsolatedDeinitInheritNonisolated: BaseWithNonisolatedDeinit { - // SecondActor-isolated deinit - @SecondActor deinit { -#if !SILGEN - isolatedFunc() // expected-error {{call to global actor 'FirstActor'-isolated global function 'isolatedFunc()' in a synchronous global actor 'SecondActor'-isolated context}} -#endif - } -} - -// MARK: - Part 2.3 - Base class with isolated deinit - -// CHECK-LABEL: @_inheritsConvenienceInitializers @FirstActor @objc class ImplicitDeinitInheritIsolated1 : BaseWithDeinitIsolatedOnFirstActor { -// CHECK: @objc deinit -// CHECK: } -// CHECK-SYMB: // ImplicitDeinitInheritIsolated1.__isolated_deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: global_actor. type: FirstActor -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc30ImplicitDeinitInheritIsolated1CfZ : $@convention(thin) (@owned ImplicitDeinitInheritIsolated1) -> () { -// CHECK-SYMB: // ImplicitDeinitInheritIsolated1.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc30ImplicitDeinitInheritIsolated1CfD : $@convention(method) (@owned ImplicitDeinitInheritIsolated1) -> () { -@FirstActor -@objc class ImplicitDeinitInheritIsolated1: BaseWithDeinitIsolatedOnFirstActor { - // FirstActor-isolated deinit -} - -#if !SILGEN -@FirstActor -@objc class DefaultDeinitIsolated1: BaseWithDeinitIsolatedOnFirstActor { - // nonisolated deinit - deinit { // expected-error {{nonisolated deinitializer 'deinit' has different actor isolation from global actor 'FirstActor'-isolated overridden declaration}} - isolatedFunc() // expected-error {{call to global actor 'FirstActor'-isolated global function 'isolatedFunc()' in a synchronous nonisolated context}} - } -} -#endif - -#if !SILGEN -@objc class BadPropagatedDeinitIsolated: BaseWithDeinitIsolatedOnFirstActor { - isolated deinit {} // expected-error {{deinit is marked isolated, but containing class 'BadPropagatedDeinitIsolated' is not isolated to an actor}} -} -#endif - -// CHECK-LABEL: @_inheritsConvenienceInitializers @objc @FirstActor class GoodPropagatedDeinitIsolated1 : BaseIsolatedOnFirstActor { -// CHECK: @objc isolated deinit -// CHECK: } -// CHECK-SYMB: // GoodPropagatedDeinitIsolated1.__isolated_deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: global_actor. type: FirstActor -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc29GoodPropagatedDeinitIsolated1CfZ : $@convention(thin) (@owned GoodPropagatedDeinitIsolated1) -> () { -// CHECK-SYMB: // GoodPropagatedDeinitIsolated1.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc29GoodPropagatedDeinitIsolated1CfD : $@convention(method) (@owned GoodPropagatedDeinitIsolated1) -> () { -@objc class GoodPropagatedDeinitIsolated1: BaseIsolatedOnFirstActor { - isolated deinit { - isolatedFunc() // ok - } -} - -// CHECK-LABEL: @_inheritsConvenienceInitializers @FirstActor @objc class PropagatedDeinitIsolated1 : BaseWithDeinitIsolatedOnFirstActor { -// CHECK: @objc isolated deinit -// CHECK: } -// CHECK-SYMB: // PropagatedDeinitIsolated1.__isolated_deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: global_actor. type: FirstActor -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc25PropagatedDeinitIsolated1CfZ : $@convention(thin) (@owned PropagatedDeinitIsolated1) -> () { -// CHECK-SYMB: // PropagatedDeinitIsolated1.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc25PropagatedDeinitIsolated1CfD : $@convention(method) (@owned PropagatedDeinitIsolated1) -> () { -@FirstActor -@objc class PropagatedDeinitIsolated1: BaseWithDeinitIsolatedOnFirstActor { - // FirstActor-isolated deinit - isolated deinit { - isolatedFunc() // ok - } -} - -#if !SILGEN -@FirstActor -@objc class NonisolatedDeinitIsolated1: BaseWithDeinitIsolatedOnFirstActor { - // nonisolated deinit - nonisolated deinit { // expected-error {{nonisolated deinitializer 'deinit' has different actor isolation from global actor 'FirstActor'-isolated overridden declaration}} - isolatedFunc() // expected-error {{call to global actor 'FirstActor'-isolated global function 'isolatedFunc()' in a synchronous nonisolated context}} - } -} -#endif - -// CHECK-LABEL: @_inheritsConvenienceInitializers @objc class IsolatedDeinitIsolated1 : BaseWithDeinitIsolatedOnFirstActor { -// CHECK: @objc @FirstActor deinit -// CHECK: } -// CHECK-SYMB: // IsolatedDeinitIsolated1.__isolated_deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: global_actor. type: FirstActor -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc23IsolatedDeinitIsolated1CfZ : $@convention(thin) (@owned IsolatedDeinitIsolated1) -> () { -// CHECK-SYMB: // IsolatedDeinitIsolated1.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc23IsolatedDeinitIsolated1CfD : $@convention(method) (@owned IsolatedDeinitIsolated1) -> () { -@objc class IsolatedDeinitIsolated1: BaseWithDeinitIsolatedOnFirstActor { - // FirstActor-isolated deinit - @FirstActor deinit { - isolatedFunc() // ok - } -} - -#if !SILGEN -@FirstActor -@objc class DifferentIsolatedDeinitIsolated1: BaseWithDeinitIsolatedOnFirstActor { - // error - @SecondActor deinit { // expected-error {{global actor 'SecondActor'-isolated deinitializer 'deinit' has different actor isolation from global actor 'FirstActor'-isolated overridden declaration}} - isolatedFunc() // expected-error {{call to global actor 'FirstActor'-isolated global function 'isolatedFunc()' in a synchronous global actor 'SecondActor'-isolated context}} - } -} -#endif - -// MARK: - Part 2.4 - Base class with isolated deinit with different actor - -// CHECK-LABEL: @_inheritsConvenienceInitializers @FirstActor @objc class ImplicitDeinitInheritIsolated2 : BaseWithDeinitIsolatedOnSecondActor { -// CHECK: @objc deinit -// CHECK: } -// CHECK-SYMB: // ImplicitDeinitInheritIsolated2.__isolated_deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: global_actor. type: SecondActor -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc30ImplicitDeinitInheritIsolated2CfZ : $@convention(thin) (@owned ImplicitDeinitInheritIsolated2) -> () { -// CHECK-SYMB: // ImplicitDeinitInheritIsolated2.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc30ImplicitDeinitInheritIsolated2CfD : $@convention(method) (@owned ImplicitDeinitInheritIsolated2) -> () { -@FirstActor -@objc class ImplicitDeinitInheritIsolated2: BaseWithDeinitIsolatedOnSecondActor { - // SecondActor-isolated deinit -} - -// CHECK-LABEL: @_inheritsConvenienceInitializers @objc @SecondActor class GoodPropagatedDeinitIsolated2 : BaseIsolatedOnSecondActor { -// CHECK: @objc isolated deinit -// CHECK: } -// CHECK-SYMB: // GoodPropagatedDeinitIsolated2.__isolated_deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: global_actor. type: SecondActor -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc29GoodPropagatedDeinitIsolated2CfZ : $@convention(thin) (@owned GoodPropagatedDeinitIsolated2) -> () { -// CHECK-SYMB: // GoodPropagatedDeinitIsolated2.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc29GoodPropagatedDeinitIsolated2CfD : $@convention(method) (@owned GoodPropagatedDeinitIsolated2) -> () { -@objc class GoodPropagatedDeinitIsolated2: BaseIsolatedOnSecondActor { - isolated deinit { -#if !SILGEN - isolatedFunc() // expected-error {{call to global actor 'FirstActor'-isolated global function 'isolatedFunc()' in a synchronous global actor 'SecondActor'-isolated context}} -#endif - } -} - -#if !SILGEN -@FirstActor -@objc class PropagatedDeinitIsolated2: BaseWithDeinitIsolatedOnSecondActor { - // SecondActor-isolated deinit - isolated deinit { // expected-error {{global actor 'FirstActor'-isolated deinitializer 'deinit' has different actor isolation from global actor 'SecondActor'-isolated overridden declaration}} - isolatedFunc() // ok - } -} -#endif - -#if !SILGEN -@FirstActor -@objc class NonisolatedDeinitIsolated2: BaseWithDeinitIsolatedOnSecondActor { - // nonisolated deinit - nonisolated deinit { // expected-error {{nonisolated deinitializer 'deinit' has different actor isolation from global actor 'SecondActor'-isolated overridden declaration}} - isolatedFunc() // expected-error {{call to global actor 'FirstActor'-isolated global function 'isolatedFunc()' in a synchronous nonisolated context}} - } -} -#endif - -#if !SILGEN -@objc class IsolatedDeinitIsolated2: BaseWithDeinitIsolatedOnSecondActor { - // FirstActor-isolated deinit - @FirstActor deinit { // expected-error {{global actor 'FirstActor'-isolated deinitializer 'deinit' has different actor isolation from global actor 'SecondActor'-isolated overridden declaration}} - isolatedFunc() // ok - } -} -#endif - -// CHECK-LABEL: @_inheritsConvenienceInitializers @FirstActor @objc class DifferentIsolatedDeinitIsolated2 : BaseWithDeinitIsolatedOnSecondActor { -// CHECK: @objc @SecondActor deinit -// CHECK: } -// CHECK-SYMB: // DifferentIsolatedDeinitIsolated2.__isolated_deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: global_actor. type: SecondActor -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc32DifferentIsolatedDeinitIsolated2CfZ : $@convention(thin) (@owned DifferentIsolatedDeinitIsolated2) -> () { -// CHECK-SYMB: // DifferentIsolatedDeinitIsolated2.__deallocating_deinit -// CHECK-SYMB-NEXT: // Isolation: nonisolated -// CHECK-SYMB-NEXT: sil hidden [ossa] @$s21deinit_isolation_objc32DifferentIsolatedDeinitIsolated2CfD : $@convention(method) (@owned DifferentIsolatedDeinitIsolated2) -> () { -@FirstActor -@objc class DifferentIsolatedDeinitIsolated2: BaseWithDeinitIsolatedOnSecondActor { - // SecondActor-isolated deinit - @SecondActor deinit { -#if !SILGEN - isolatedFunc() // expected-error {{call to global actor 'FirstActor'-isolated global function 'isolatedFunc()' in a synchronous global actor 'SecondActor'-isolated context}} -#endif - } -} - diff --git a/test/Concurrency/deinit_isolation_tbd.swift b/test/Concurrency/deinit_isolation_tbd.swift deleted file mode 100644 index 8e3d96004df..00000000000 --- a/test/Concurrency/deinit_isolation_tbd.swift +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-ir %s | %FileCheck %s - -public class Foo { - @MainActor - deinit {} -} - -// CHECK: @"$s20deinit_isolation_tbd3FooCfZ" -// CHECK: @"$s20deinit_isolation_tbd3FooCfD" diff --git a/test/Concurrency/flow_isolation.swift b/test/Concurrency/flow_isolation.swift index cd13a1cb270..4641a80a516 100644 --- a/test/Concurrency/flow_isolation.swift +++ b/test/Concurrency/flow_isolation.swift @@ -125,7 +125,7 @@ actor Demons { self.ns = x } - nonisolated deinit { + deinit { let _ = self.ns // expected-warning {{cannot access property 'ns' with a non-sendable type 'NonSendableType' from nonisolated deinit; this is an error in the Swift 6 language mode}} } } @@ -156,7 +156,7 @@ actor ExampleFromProposal { } - nonisolated deinit { + deinit { _ = self.immutableSendable // ok _ = self.mutableSendable // ok _ = self.nonSendable // expected-warning {{cannot access property 'nonSendable' with a non-sendable type 'NonSendableType' from nonisolated deinit; this is an error in the Swift 6 language mode}} @@ -196,7 +196,7 @@ class CheckGAIT1 { silly += 2 // expected-warning {{cannot access property 'silly' here in nonisolated initializer; this is an error in the Swift 6 language mode}} } - nonisolated deinit { + deinit { _ = ns // expected-warning {{cannot access property 'ns' with a non-sendable type 'NonSendableType' from nonisolated deinit; this is an error in the Swift 6 language mode}} f() // expected-note {{after calling instance method 'f()', only nonisolated properties of 'self' can be accessed from a deinit}} _ = silly // expected-warning {{cannot access property 'silly' here in deinitializer; this is an error in the Swift 6 language mode}} @@ -620,7 +620,7 @@ actor Ahmad { prop += 1 // expected-warning {{cannot access property 'prop' here in nonisolated initializer; this is an error in the Swift 6 language mode}} } - nonisolated deinit { + deinit { // expected-warning@+2 {{actor-isolated property 'computedProp' can not be referenced from a nonisolated context; this is an error in the Swift 6 language mode}} // expected-note@+1 {{after accessing property 'computedProp', only nonisolated properties of 'self' can be accessed from a deinit}} let x = computedProp @@ -660,7 +660,7 @@ actor Rain { } @available(SwiftStdlib 5.5, *) -actor NonIsolatedDeinitExceptionForSwift5 { +actor DeinitExceptionForSwift5 { var x: Int = 0 func cleanup() { // expected-note {{calls to instance method 'cleanup()' from outside of its actor context are implicitly asynchronous}} @@ -676,22 +676,6 @@ actor NonIsolatedDeinitExceptionForSwift5 { } } -@available(SwiftStdlib 5.5, *) -actor IsolatedDeinitExceptionForSwift5 { - var x: Int = 0 - - func cleanup() { - x = 0 - } - - isolated deinit { - cleanup() // ok - - x = 1 // ok - } -} - - @available(SwiftStdlib 5.5, *) actor OhBrother { private var giver: (OhBrother) -> Int diff --git a/test/Concurrency/voucher_propagation.swift b/test/Concurrency/voucher_propagation.swift index 4b8685d3bcc..851f01b53db 100644 --- a/test/Concurrency/voucher_propagation.swift +++ b/test/Concurrency/voucher_propagation.swift @@ -75,70 +75,6 @@ actor Counter { func get() -> Int { n } } -actor ActorWithSelfIsolatedDeinit { - let expectedVoucher: voucher_t? - let group: DispatchGroup - - init(expectedVoucher: voucher_t?, group: DispatchGroup) { - self.expectedVoucher = expectedVoucher - self.group = group - } - - isolated deinit { - expectTrue(isCurrentExecutor(self.unownedExecutor)) - let currentVoucher = voucher_copy() - expectEqual(expectedVoucher, currentVoucher) - os_release(currentVoucher) - group.leave() - } -} - -@globalActor actor AnotherActor: GlobalActor { - static let shared = AnotherActor() - - func performTesting(_ work: @Sendable () -> Void) { - work() - } -} - -actor ActorWithDeinitIsolatedOnAnother { - let expectedVoucher: voucher_t? - let group: DispatchGroup - - init(expectedVoucher: voucher_t?, group: DispatchGroup) { - self.expectedVoucher = expectedVoucher - self.group = group - } - - @AnotherActor - deinit { - expectTrue(isCurrentExecutor(AnotherActor.shared.unownedExecutor)) - let currentVoucher = voucher_copy() - expectEqual(expectedVoucher, currentVoucher) - os_release(currentVoucher) - group.leave() - } -} - -class ClassWithIsolatedDeinit { - let expectedVoucher: voucher_t? - let group: DispatchGroup - - init(expectedVoucher: voucher_t?, group: DispatchGroup) { - self.expectedVoucher = expectedVoucher - self.group = group - } - - @AnotherActor - deinit { - expectTrue(isCurrentExecutor(AnotherActor.shared.unownedExecutor)) - let currentVoucher = voucher_copy() - expectEqual(expectedVoucher, currentVoucher) - os_release(currentVoucher) - group.leave() - } -} - // Make a nice string for a pointer, like what %p would produce in printf. func ptrstr(_ ptr: T) -> String { "0x" + String(unsafeBitCast(ptr, to: UInt.self), radix: 16) @@ -174,8 +110,6 @@ let voucher_adopt = lookup("voucher_adopt") as @convention(c) (voucher_t?) let os_retain = lookup("os_retain") as @convention(c) (voucher_t?) -> voucher_t? let os_release = lookup("os_release") as @convention(c) (voucher_t?) -> Void -let isCurrentExecutor = lookup("swift_task_isCurrentExecutor") as @convention(thin) (UnownedSerialExecutor) -> Bool - // Run some async code with test vouchers. Wait for the async code to complete, // then verify that the vouchers aren't leaked. func withVouchers(call: @Sendable @escaping (voucher_t?, voucher_t?, voucher_t?) @@ -426,49 +360,6 @@ if #available(SwiftStdlib 5.1, *) { group.wait() } } - - tests.test("voucher propagation in isolated deinit [fast path]") { - withVouchers { v1, v2, v3 in - let group = DispatchGroup() - group.enter() - group.enter() - group.enter() - Task { - await AnotherActor.shared.performTesting { - adopt(voucher: v1) - _ = ClassWithIsolatedDeinit(expectedVoucher: v1, group: group) - } - await AnotherActor.shared.performTesting { - adopt(voucher: v2) - _ = ActorWithSelfIsolatedDeinit(expectedVoucher: v2, group: group) - } - await AnotherActor.shared.performTesting { - adopt(voucher: v3) - _ = ActorWithDeinitIsolatedOnAnother(expectedVoucher: v3, group: group) - } - } - group.wait() - } - } - - tests.test("voucher propagation in isolated deinit [slow path]") { - withVouchers { v1, v2, v3 in - let group = DispatchGroup() - group.enter() - group.enter() - Task { - do { - adopt(voucher: v1) - _ = ActorWithDeinitIsolatedOnAnother(expectedVoucher: v1, group: group) - } - do { - adopt(voucher: v2) - _ = ClassWithIsolatedDeinit(expectedVoucher: v2, group: group) - } - } - group.wait() - } - } } runAllTests() diff --git a/test/Demangle/Inputs/manglings.txt b/test/Demangle/Inputs/manglings.txt index 129739c67d0..761ac2b5926 100644 --- a/test/Demangle/Inputs/manglings.txt +++ b/test/Demangle/Inputs/manglings.txt @@ -105,7 +105,6 @@ _TF3foooP1xFTCS_3barVS_3bas_OS_3zim ---> foo.^ postfix(foo.bar, foo.bas) -> foo. _TFC3foo3barCfT_S0_ ---> foo.bar.__allocating_init() -> foo.bar _TFC3foo3barcfT_S0_ ---> foo.bar.init() -> foo.bar _TFC3foo3barD ---> foo.bar.__deallocating_deinit -_TFC3foo3barZ ---> foo.bar.__isolated_deallocating_deinit _TFC3foo3bard ---> foo.bar.deinit _TMPC3foo3bar ---> generic type metadata pattern for foo.bar _TMnC3foo3bar ---> nominal type descriptor for foo.bar diff --git a/test/Demangle/Inputs/simplified-manglings.txt b/test/Demangle/Inputs/simplified-manglings.txt index 40904c876e1..2283c67cba4 100644 --- a/test/Demangle/Inputs/simplified-manglings.txt +++ b/test/Demangle/Inputs/simplified-manglings.txt @@ -71,7 +71,6 @@ _TF3foooP1xFTCS_3barVS_3bas_OS_3zim ---> ^ postfix(_:_:) _TFC3foo3barCfT_S0_ ---> bar.__allocating_init() _TFC3foo3barcfT_S0_ ---> bar.init() _TFC3foo3barD ---> bar.__deallocating_deinit -_TFC3foo3barZ ---> bar.__isolated_deallocating_deinit _TFC3foo3bard ---> bar.deinit _TMPC3foo3bar ---> generic type metadata pattern for bar _TMnC3foo3bar ---> nominal type descriptor for bar diff --git a/test/Distributed/Runtime/distributed_actor_deinit.swift b/test/Distributed/Runtime/distributed_actor_deinit.swift index 3a428387c1f..cfcbd8b7790 100644 --- a/test/Distributed/Runtime/distributed_actor_deinit.swift +++ b/test/Distributed/Runtime/distributed_actor_deinit.swift @@ -1,9 +1,5 @@ -// RUN: %empty-directory(%t) -// RUN: %target-build-swift -Xfrontend -disable-availability-checking %import-libdispatch -parse-stdlib -parse-as-library -module-name=main %s -o %t/a.out -// RUN: %target-codesign %t/a.out -// RUN: %env-SWIFT_IS_CURRENT_EXECUTOR_LEGACY_MODE_OVERRIDE=legacy %target-run %t/a.out | %FileCheck %s +// RUN: %target-run-simple-swift( -Xfrontend -disable-availability-checking -parse-as-library) | %FileCheck %s -// REQUIRES: libdispatch // REQUIRES: executable_test // REQUIRES: concurrency // REQUIRES: distributed @@ -14,48 +10,7 @@ // FIXME(distributed): Distributed actors currently have some issues on windows, isRemote always returns false. rdar://82593574 // UNSUPPORTED: OS=windows-msvc -import Swift -import _Concurrency import Distributed -import Dispatch - -#if canImport(Darwin) -import Darwin -typealias ThreadID = pthread_t -func getCurrentThreadID() -> ThreadID { pthread_self() } -func equalThreadIDs(_ a: ThreadID, _ b: ThreadID) -> Bool { pthread_equal(a, b) != 0 } -#elseif canImport(Glibc) -import Glibc -typealias ThreadID = pthread_t -func getCurrentThreadID() -> ThreadID { pthread_self() } -func equalThreadIDs(_ a: ThreadID, _ b: ThreadID) -> Bool { pthread_equal(a, b) != 0 } -#elseif os(Windows) -import WinSDK -typealias ThreadID = UInt32 -func getCurrentThreadID() -> ThreadID { GetCurrentThreadId() } -func equalThreadIDs(_ a: ThreadID, _ b: ThreadID) -> Bool { a == b } -#endif - -var mainThread: ThreadID? -func isMainThread() -> Bool { - return equalThreadIDs(getCurrentThreadID(), mainThread!) -} - -@_silgen_name("swift_task_isCurrentExecutor") -private func isCurrentExecutor(_ executor: Builtin.Executor) -> Bool - -func getExecutor(_ a: AnyActor) -> Builtin.Executor { - let pack = (a, UnsafeRawPointer?.none) - return unsafeBitCast(pack, to: Builtin.Executor.self) -} - -func isCurrent(_ a: AnyActor) -> Bool { - return isCurrentExecutor(getExecutor(a)) -} - -func isMainExecutor() -> Bool { - isCurrentExecutor(Builtin.buildMainActorExecutorRef()) -} actor A {} @@ -70,78 +25,29 @@ distributed actor DA_userDefined { self.actorSystem = system } - nonisolated deinit {} + deinit {} } -distributed actor DA_userDefined_nonisolated { +distributed actor DA_userDefined2 { init(system: FakeActorSystem) { self.actorSystem = system } - nonisolated deinit { - print("Deinitializing \(self.id) remote:\(__isRemoteActor(self)) isolated:\(isCurrent(self)) mainThread:\(isMainThread())") - } -} - -distributed actor DA_userDefined_isolated { - init(system: FakeActorSystem) { - self.actorSystem = system - } - - isolated deinit { - print("Deinitializing \(self.id) remote:\(__isRemoteActor(self)) isolated:\(isCurrent(self)) mainThread:\(isMainThread())") - } -} - -distributed actor DA_state_nonisolated { - var name: String - var age: Int - - init(name: String, age: Int, system: FakeActorSystem) { - self.name = name - self.age = age - self.actorSystem = system - } - - nonisolated deinit { - print("Deinitializing \(self.id) name=\(name) age=\(age) remote:\(__isRemoteActor(self)) isolated:\(isCurrent(self)) mainThread:\(isMainThread())") - return - } -} - -distributed actor DA_state_isolated { - var name: String - var age: Int - - init(name: String, age: Int, system: FakeActorSystem) { - self.name = name - self.age = age - self.actorSystem = system - } - - isolated deinit { - print("Deinitializing \(self.id) name=\(name) age=\(age) remote:\(__isRemoteActor(self)) isolated:\(isCurrent(self)) mainThread:\(isMainThread())") - return - } -} - -@globalActor actor AnotherActor: GlobalActor { - static let shared = AnotherActor() -} - -distributed actor DA_state_isolated_on_another { - let name: String - let age: Int - - init(name: String, age: Int, system: FakeActorSystem) { - self.name = name - self.age = age - self.actorSystem = system - } - - @AnotherActor deinit { - print("Deinitializing \(self.id) name=\(name) age=\(age) remote:\(__isRemoteActor(self)) isolated-self:\(isCurrent(self)) isolated-other:\(isCurrent(AnotherActor.shared)) mainThread:\(isMainThread())") + print("Deinitializing \(self.id) remote:\(__isRemoteActor(self))") + } +} + +distributed actor DA_state { + var name = "Hello" + var age = 42 + + init(system: FakeActorSystem) { + self.actorSystem = system + } + + deinit { + print("Deinitializing \(self.id) remote:\(__isRemoteActor(self))") return } } @@ -163,16 +69,6 @@ final class FakeActorSystem: @unchecked Sendable, DistributedActorSystem { typealias ResultHandler = FakeResultHandler var n = 0 - let group: DispatchGroup - - init(group: DispatchGroup) { - self.group = group - } - - deinit { - print("Deinit ActorSystem: mainExecutor=\(isMainExecutor()) mainThread=\(isMainThread())") - group.leave() - } func resolve(id: ActorID, as actorType: Act.Type) throws -> Act? where Act: DistributedActor, @@ -278,17 +174,7 @@ typealias DefaultDistributedActorSystem = FakeActorSystem // ==== Execute ---------------------------------------------------------------- func test() { - let group = DispatchGroup() - var dummy: AnyObject? - - func check(factory: () -> AnyObject) { - dummy = factory() - // Test requires actor system to be released before the actor, - // so that release of the actor system from actor deinit is the last one - group.enter() - dummy = nil - group.wait() - } + let system = DefaultDistributedActorSystem() // no lifecycle things make sense for a normal actor, double check we didn't emit them print("before A") @@ -297,101 +183,46 @@ func test() { // CHECK: before A // CHECK: after A - check { - DA(system: DefaultDistributedActorSystem(group: group)) - } + _ = { () -> DA in + DA(system: system) + }() // CHECK: assign type:DA, address:[[ADDRESS:.*]] // CHECK: ready actor:main.DA, address:ActorAddress(address: "[[ADDR1:addr-[0-9]]]") // CHECK: resign address:ActorAddress(address: "[[ADDR1]]") - // CHECK-NEXT: Deinit ActorSystem: mainExecutor=true mainThread=true - check { - DA_userDefined(system: DefaultDistributedActorSystem(group: group)) - } + _ = { () -> DA_userDefined in + DA_userDefined(system: system) + }() // CHECK: assign type:DA_userDefined, address:[[ADDRESS:.*]] // CHECK: ready actor:main.DA_userDefined, address:ActorAddress(address: "[[ADDR2:addr-[0-9]]]") // CHECK: resign address:ActorAddress(address: "[[ADDR2]]") - // CHECK-NEXT: Deinit ActorSystem: mainExecutor=true mainThread=true // resign must happen as the _last thing_ after user-deinit completed - check { - DA_userDefined_nonisolated(system: DefaultDistributedActorSystem(group: group)) - } - // CHECK: assign type:DA_userDefined_nonisolated, address:[[ADDRESS:.*]] - // CHECK: ready actor:main.DA_userDefined_nonisolated, address:ActorAddress(address: "[[ADDR3:addr-[0-9]]]") - // CHECK: Deinitializing ActorAddress(address: "[[ADDR3]]") remote:false isolated:false mainThread:true + _ = { () -> DA_userDefined2 in + DA_userDefined2(system: system) + }() + // CHECK: assign type:DA_userDefined2, address:[[ADDRESS:.*]] + // CHECK: ready actor:main.DA_userDefined2, address:ActorAddress(address: "[[ADDR3:addr-[0-9]]]") + // CHECK: Deinitializing ActorAddress(address: "[[ADDR3]]") remote:false // CHECK-NEXT: resign address:ActorAddress(address: "[[ADDR3]]") - // CHECK-NEXT: Deinit ActorSystem: mainExecutor=true mainThread=true - + // resign must happen as the _last thing_ after user-deinit completed - check { - DA_userDefined_isolated(system: DefaultDistributedActorSystem(group: group)) - } - // CHECK: assign type:DA_userDefined_isolated, address:[[ADDRESS:.*]] - // CHECK: ready actor:main.DA_userDefined_isolated, address:ActorAddress(address: "[[ADDR4:addr-[0-9]]]") - // CHECK: Deinitializing ActorAddress(address: "[[ADDR4]]") remote:false isolated:true mainThread:true + _ = { () -> DA_state in + DA_state(system: system) + }() + // CHECK: assign type:DA_state, address:[[ADDRESS:.*]] + // CHECK: ready actor:main.DA_state, address:ActorAddress(address: "[[ADDR4:addr-[0-9]]]") + // CHECK: Deinitializing ActorAddress(address: "[[ADDR4]]") remote:false // CHECK-NEXT: resign address:ActorAddress(address: "[[ADDR4]]") - // CHECK-NEXT: Deinit ActorSystem: mainExecutor=false mainThread=true - - // resign must happen as the _last thing_ after user-deinit completed - check { - DA_state_nonisolated(name: "Foo", age:37, system: DefaultDistributedActorSystem(group: group)) - } - // CHECK: assign type:DA_state_nonisolated, address:[[ADDRESS:.*]] - // CHECK: ready actor:main.DA_state_nonisolated, address:ActorAddress(address: "[[ADDR5:addr-[0-9]]]") - // CHECK: Deinitializing ActorAddress(address: "[[ADDR5]]") name=Foo age=37 remote:false isolated:false mainThread:true - // CHECK-NEXT: resign address:ActorAddress(address: "[[ADDR5]]") - // CHECK-NEXT: Deinit ActorSystem: mainExecutor=true mainThread=true - - // resign must happen as the _last thing_ after user-deinit completed - check { - DA_state_isolated(name: "Bar", age:42, system: DefaultDistributedActorSystem(group: group)) - } - // CHECK: assign type:DA_state_isolated, address:[[ADDRESS:.*]] - // CHECK: ready actor:main.DA_state_isolated, address:ActorAddress(address: "[[ADDR6:addr-[0-9]]]") - // CHECK: Deinitializing ActorAddress(address: "[[ADDR6]]") name=Bar age=42 remote:false isolated:true mainThread:true - // CHECK-NEXT: resign address:ActorAddress(address: "[[ADDR6]]") - // CHECK-NEXT: Deinit ActorSystem: mainExecutor=false mainThread=true - - // resign must happen as the _last thing_ after user-deinit completed - check { - DA_state_isolated_on_another(name: "Baz", age:57, system: DefaultDistributedActorSystem(group: group)) - } - // CHECK: assign type:DA_state_isolated_on_another, address:[[ADDRESS:.*]] - // CHECK: ready actor:main.DA_state_isolated_on_another, address:ActorAddress(address: "[[ADDR6:addr-[0-9]]]") - // CHECK: Deinitializing ActorAddress(address: "[[ADDR6]]") name=Baz age=57 remote:false isolated-self:false isolated-other:true mainThread:false - // CHECK-NEXT: resign address:ActorAddress(address: "[[ADDR6]]") - // CHECK-NEXT: Deinit ActorSystem: mainExecutor=false mainThread=false // a remote actor should not resign it's address, it was never "assigned" it - check { - let address = ActorAddress(parse: "remote-1") - return try! DA_userDefined_nonisolated.resolve(id: address, using: DefaultDistributedActorSystem(group: group)) - } - // CHECK-NEXT: resolve type:DA_userDefined_nonisolated, address:ActorAddress(address: "remote-1") + let address = ActorAddress(parse: "remote-1") + _ = { () -> DA_userDefined2 in + try! DA_userDefined2.resolve(id: address, using: system) + }() + // CHECK-NEXT: resolve type:DA_userDefined2, address:ActorAddress(address: "[[ADDR5:remote-1]]") // MUST NOT run deinit body for a remote distributed actor - // CHECK-NOT: Deinitializing ActorAddress(address: "remote-1") - // CHECK-NEXT: Deinit ActorSystem: mainExecutor=true mainThread=true - - // a remote actor should not resign it's address, it was never "assigned" it - check { - let address = ActorAddress(parse: "remote-2") - return try! DA_userDefined_isolated.resolve(id: address, using: DefaultDistributedActorSystem(group: group)) - } - // CHECK-NEXT: resolve type:DA_userDefined_isolated, address:ActorAddress(address: "remote-2") - // MUST NOT run deinit body for a remote distributed actor - // CHECK-NOT: Deinitializing ActorAddress(address: "remote-2") - // CHECK-NEXT: Deinit ActorSystem: mainExecutor=true mainThread=true - - // a remote actor should not resign it's address, it was never "assigned" it - check { - let address = ActorAddress(parse: "remote-3") - return try! DA_state_isolated_on_another.resolve(id: address, using: DefaultDistributedActorSystem(group: group)) - } - // CHECK-NEXT: resolve type:DA_state_isolated_on_another, address:ActorAddress(address: "remote-3") - // MUST NOT run deinit body for a remote distributed actor - // CHECK-NOT: Deinitializing ActorAddress(address: "remote-3") - // CHECK-NEXT: Deinit ActorSystem: mainExecutor=true mainThread=true + // CHECK-NOT: Deinitializing ActorAddress(address: "remote-1") remote:true print("DONE") // CHECK-NEXT: DONE @@ -399,7 +230,6 @@ func test() { @main struct Main { static func main() async { - mainThread = getCurrentThreadID() test() } } diff --git a/test/Distributed/Runtime/distributed_actor_remote_fieldsDontCrashDeinit.swift b/test/Distributed/Runtime/distributed_actor_remote_fieldsDontCrashDeinit.swift index 8371812c47f..957dddcbaed 100644 --- a/test/Distributed/Runtime/distributed_actor_remote_fieldsDontCrashDeinit.swift +++ b/test/Distributed/Runtime/distributed_actor_remote_fieldsDontCrashDeinit.swift @@ -28,7 +28,7 @@ distributed actor SomeSpecificDistributedActor { self.age = 42 } - nonisolated deinit { + deinit { print("deinit \(self.id)") } diff --git a/test/Distributed/Runtime/distributed_actor_remote_retains_system.swift b/test/Distributed/Runtime/distributed_actor_remote_retains_system.swift index 92598c2bf5e..d09968ccc6b 100644 --- a/test/Distributed/Runtime/distributed_actor_remote_retains_system.swift +++ b/test/Distributed/Runtime/distributed_actor_remote_retains_system.swift @@ -11,7 +11,7 @@ import Distributed distributed actor SomeSpecificDistributedActor { - nonisolated deinit { + deinit { print("deinit \(self.id)") } } @@ -40,7 +40,7 @@ final class FakeActorSystem: DistributedActorSystem { typealias SerializationRequirement = Codable typealias ResultHandler = FakeResultHandler - nonisolated deinit { + deinit { print("deinit \(self)") } diff --git a/test/Distributed/SIL/distributed_actor_default_deinit_sil.swift b/test/Distributed/SIL/distributed_actor_default_deinit_sil.swift index 1c6c9bd87fc..ba84f57e543 100644 --- a/test/Distributed/SIL/distributed_actor_default_deinit_sil.swift +++ b/test/Distributed/SIL/distributed_actor_default_deinit_sil.swift @@ -7,11 +7,6 @@ // FIXME(distributed): test fails on optimized build: OSS - Swift (Tools Opt+No Assert, Stdlib Opt+DebInfo, Test Simulator) - macOS // REQUIRES: radar97074020 -// This test checks that we resign the identity for local deallocations, -// destroy only the correct stored properties whether remote or local, and also -// destroy the executor. It checks that remote actor proxies are not isolated. -// Additionally, we add basic coverage for a non-distributed actor's deinit. - import Distributed import FakeDistributedActorSystems @@ -19,11 +14,6 @@ typealias DefaultDistributedActorSystem = FakeActorSystem final class SomeClass: Sendable {} -@inline(never) -private nonisolated func doIt() {} - -// MARK: - Distributed actor with nonisolated deinit - distributed actor MyDistActor { let localOnlyField: SomeClass @@ -33,11 +23,20 @@ distributed actor MyDistActor { } } -// MARK: Destroying deinit +// MARK: distributed actor check -// CHECK-LABEL: // MyDistActor.deinit -// CHECK-NEXT: sil hidden{{.*}} @$s14default_deinit11MyDistActorCfd : $@convention(method) (@guaranteed MyDistActor) -> @owned Builtin.NativeObject { +// ===== ----------------------------------------------------------------------- +// CHECK-LABEL: sil hidden @$s14default_deinit11MyDistActorCfd : $@convention(method) (@guaranteed MyDistActor) -> @owned Builtin.NativeObject { // CHECK: bb0([[SELF:%[0-9]+]] : $MyDistActor): +// CHECK: [[EXI_SELF:%[0-9]+]] = init_existential_ref [[SELF]] : $MyDistActor : $MyDistActor, $AnyObject +// CHECK: [[IS_REMOTE_FN:%[0-9]+]] = function_ref @swift_distributed_actor_is_remote : $@convention(thin) (@guaranteed AnyObject) -> Bool +// CHECK: [[IS_REMOTE:%[0-9]+]] = apply [[IS_REMOTE_FN]]([[EXI_SELF]]) +// CHECK: [[RAW_BOOL:%[0-9]+]] = struct_extract [[IS_REMOTE]] : $Bool, #Bool._value +// CHECK: cond_br [[RAW_BOOL]], [[REMOTE_ACTOR_DEINIT_BB:bb[0-9]+]], [[DEINIT_BODY_BB:bb[0-9]+]] + +// ===== ----------------------------------------------------------------------- +// CHECK: // deinitBodyBB +// CHECK: [[DEINIT_BODY_BB]]: // Resign the ID by calling actorSystem.resignID, before we destroy properties: // CHECK: [[ID_REF:%[0-9]+]] = ref_element_addr [[SELF]] : $MyDistActor, #MyDistActor.id @@ -65,45 +64,14 @@ distributed actor MyDistActor { // CHECK: [[ACCESS:%[0-9]+]] = begin_access [deinit] [static] [[REF]] : $*SomeClass // CHECK: destroy_addr [[ACCESS]] : $*SomeClass // CHECK: end_access [[ACCESS]] : $*SomeClass - -// CHECK: [[BUILTIN:%[0-9]+]] = builtin "destroyDefaultActor"([[SELF]] : $MyDistActor) : $() -// CHECK: [[CAST:%[0-9]+]] = unchecked_ref_cast [[SELF]] : $MyDistActor to $Builtin.NativeObject -// CHECK: return [[CAST]] : $Builtin.NativeObject - -// CHECK: } // end sil function '$s14default_deinit11MyDistActorCfd' - -// MARK: Isolated deallocating deinit - -// ===== ----------------------------------------------------------------------- -// CHECK-NOT: MyDistActor.__isolated_deallocating_deinit -// CHECK-NOT: @$s14default_deinit11MyDistActorCfZ - -// MARK: Deallocating deinit - -// ===== ----------------------------------------------------------------------- -// CHECK-LABEL: MyDistActor.__deallocating_deinit -// CHECK-NEXT: sil hidden @$s14default_deinit11MyDistActorCfD : $@convention(method) (@owned MyDistActor) -> () { -// CHECK: bb0([[SELF:%[0-9]+]] : $MyDistActor): -// CHECK: [[EXI_SELF:%[0-9]+]] = init_existential_ref [[SELF]] : $MyDistActor : $MyDistActor, $AnyObject -// CHECK: [[IS_REMOTE_FN:%[0-9]+]] = function_ref @swift_distributed_actor_is_remote : $@convention(thin) (@guaranteed AnyObject) -> Bool -// CHECK: [[IS_REMOTE:%[0-9]+]] = apply [[IS_REMOTE_FN]]([[EXI_SELF]]) -// CHECK: [[RAW_BOOL:%[0-9]+]] = struct_extract [[IS_REMOTE]] : $Bool, #Bool._value -// CHECK: cond_br [[RAW_BOOL]], [[REMOTE_ACTOR_DEINIT_BB:bb[0-9]+]], [[LOCAL_ACTOR_DEINIT_BB:bb[0-9]+]] - -// ===== ----------------------------------------------------------------------- -// CHECK: // localActorDeinitBB -// CHECK: [[LOCAL_ACTOR_DEINIT_BB]]: -// CHECK: [[DESTROYER_REF:%[0-9]+]] = function_ref @$s14default_deinit11MyDistActorCfd : $@convention(method) (@guaranteed MyDistActor) -> @owned Builtin.NativeObject -// CHECK: [[UNTYPED_DESTOY_RESULT:%[0-9]+]] = apply [[DESTROYER_REF]]([[SELF]]) : $@convention(method) (@guaranteed MyDistActor) -> @owned Builtin.NativeObject -// CHECK: [[TYPED_DESTOY_RESULT:%[0-9]+]] = unchecked_ref_cast [[UNTYPED_DESTOY_RESULT]] : $Builtin.NativeObject to $MyDistActor -// CHECK: dealloc_ref [[TYPED_DESTOY_RESULT]] : $MyDistActor // CHECK: br [[FINISH_DEINIT_BB:bb[0-9]+]] // ===== ----------------------------------------------------------------------- // CHECK: // finishDeinitBB // CHECK: [[FINISH_DEINIT_BB]]: -// CHECK: [[RESULT:%[0-9]+]] = tuple () -// CHECK: return [[RESULT]] : $() +// CHECK: [[BUILTIN:%[0-9]+]] = builtin "destroyDefaultActor"([[SELF]] : $MyDistActor) : $() +// CHECK: [[CAST:%[0-9]+]] = unchecked_ref_cast [[SELF]] : $MyDistActor to $Builtin.NativeObject +// CHECK: return [[CAST]] : $Builtin.NativeObject // ===== ----------------------------------------------------------------------- // CHECK: // remoteActorDeinitBB @@ -120,147 +88,15 @@ distributed actor MyDistActor { // CHECK: [[ACCESS:%[0-9]+]] = begin_access [deinit] [static] [[REF]] : $*FakeActorSystem // CHECK: destroy_addr [[ACCESS]] : $*FakeActorSystem // CHECK: end_access [[ACCESS]] : $*FakeActorSystem - -// Destroy default actor implementation -// CHECK: [[BUILTIN:%[0-9]+]] = builtin "destroyDefaultActor"([[SELF]] : $MyDistActor) : $() - -// And deallocate the proxy -// CHECK: dealloc_ref [[SELF]] : $MyDistActor - -// Return // CHECK: br [[FINISH_DEINIT_BB]] -// CHECK: } // end sil function '$s14default_deinit11MyDistActorCfD' +// CHECK: } // end sil function '$s14default_deinit11MyDistActorCfd' -// ===== ----------------------------------------------------------------------- +// This test checks that we resign the identity for local deallocations, +// destroy only the correct stored properties whether remote or local, and also +// destroy the executor. -// MARK: - Distributed actor with isolated deinit - -distributed actor MyDistActorIsolated { - let localOnlyField: SomeClass - - init(system: FakeActorSystem) { - self.actorSystem = system - self.localOnlyField = SomeClass() - } - - deinit { - doIt() - } -} - -// MARK: Destroying deinit - -// CHECK-LABEL: // MyDistActorIsolated.deinit -// CHECK-NEXT: sil hidden{{.*}} @$s14default_deinit19MyDistActorIsolatedCfd : $@convention(method) (@guaranteed MyDistActorIsolated) -> @owned Builtin.NativeObject { -// CHECK: bb0([[SELF:%[0-9]+]] : $MyDistActorIsolated): - -// Resign the ID by calling actorSystem.resignID, before we destroy properties: -// CHECK: [[ID_REF:%[0-9]+]] = ref_element_addr [[SELF]] : $MyDistActorIsolated, #MyDistActorIsolated.id -// CHECK: [[SYS_REF:%[0-9]+]] = ref_element_addr [[SELF]] : $MyDistActorIsolated, #MyDistActorIsolated.actorSystem -// CHECK: [[ID_LOAD:%[0-9]+]] = load [[ID_REF]] : $*ActorAddress -// CHECK: [[SYS_LOAD:%[0-9]+]] = load [[SYS_REF]] : $*FakeActorSystem -// CHECK: [[FN_REF:%[0-9]+]] = function_ref @$s27FakeDistributedActorSystems0aC6SystemV8resignIDyyAA0C7AddressVF : $@convention(method) (@guaranteed ActorAddress, @guaranteed FakeActorSystem) -> () -// CHECK: [[DROP:%[0-9]+]] = apply [[FN_REF]]([[ID_LOAD]], [[SYS_LOAD]]) : $@convention(method) (@guaranteed ActorAddress, @guaranteed FakeActorSystem) -> () -// CHECK: [[DROP:%[0-9]+]] = tuple () - -// Destroy implicit Distributed Actor field: id -// CHECK: [[REF:%[0-9]+]] = ref_element_addr [[SELF]] : $MyDistActorIsolated, #MyDistActorIsolated.id -// CHECK: [[ACCESS:%[0-9]+]] = begin_access [deinit] [static] [[REF]] : $*ActorAddress -// CHECK: destroy_addr [[ACCESS]] : $*ActorAddress -// CHECK: end_access [[ACCESS]] : $*ActorAddress - -// Destroy implicit Distributed Actor field: actorSystem -// CHECK: [[REF:%[0-9]+]] = ref_element_addr [[SELF]] : $MyDistActorIsolated, #MyDistActorIsolated.actorSystem -// CHECK: [[ACCESS:%[0-9]+]] = begin_access [deinit] [static] [[REF]] : $*FakeActorSystem -// CHECK: destroy_addr [[ACCESS]] : $*FakeActorSystem -// CHECK: end_access [[ACCESS]] : $*FakeActorSystem - -// Destroy local fields: -// CHECK: [[REF:%[0-9]+]] = ref_element_addr [[SELF]] : $MyDistActorIsolated, #MyDistActorIsolated.localOnlyField -// CHECK: [[ACCESS:%[0-9]+]] = begin_access [deinit] [static] [[REF]] : $*SomeClass -// CHECK: destroy_addr [[ACCESS]] : $*SomeClass -// CHECK: end_access [[ACCESS]] : $*SomeClass - -// CHECK: [[BUILTIN:%[0-9]+]] = builtin "destroyDefaultActor"([[SELF]] : $MyDistActorIsolated) : $() -// CHECK: [[CAST:%[0-9]+]] = unchecked_ref_cast [[SELF]] : $MyDistActorIsolated to $Builtin.NativeObject -// CHECK: return [[CAST]] : $Builtin.NativeObject - -// CHECK: } // end sil function '$s14default_deinit19MyDistActorIsolatedCfd' - -// MARK: Isolated deallocating deinit - -// ===== ----------------------------------------------------------------------- -// CHECK-LABEL: MyDistActorIsolated.__isolated_deallocating_deinit -// CHECK-NEXT: sil hidden @$s14default_deinit19MyDistActorIsolatedCfZ : $@convention(thin) (@owned MyDistActorIsolated) -> () { -// CHECK: bb0([[SELF:%[0-9]+]] : $MyDistActorIsolated): -// CHECK: [[DESTROYER_REF:%[0-9]+]] = function_ref @$s14default_deinit19MyDistActorIsolatedCfd : $@convention(method) (@guaranteed MyDistActorIsolated) -> @owned Builtin.NativeObject -// CHECK: [[UNTYPED_DESTOY_RESULT:%[0-9]+]] = apply [[DESTROYER_REF]]([[SELF]]) : $@convention(method) (@guaranteed MyDistActorIsolated) -> @owned Builtin.NativeObject -// CHECK: [[TYPED_DESTOY_RESULT:%[0-9]+]] = unchecked_ref_cast [[UNTYPED_DESTOY_RESULT]] : $Builtin.NativeObject to $MyDistActorIsolated -// CHECK: dealloc_ref [[TYPED_DESTOY_RESULT]] : $MyDistActorIsolated -// CHECK: [[RESULT:%[0-9]+]] = tuple () -// CHECK: return [[RESULT]] : $() -// CHECK: } // end sil function '$s14default_deinit19MyDistActorIsolatedCfZ' - -// MARK: Deallocating deinit - -// ===== ----------------------------------------------------------------------- -// CHECK-LABEL: MyDistActorIsolated.__deallocating_deinit -// CHECK-NEXT: sil hidden @$s14default_deinit19MyDistActorIsolatedCfD : $@convention(method) (@owned MyDistActorIsolated) -> () { -// CHECK: bb0([[SELF:%[0-9]+]] : $MyDistActorIsolated): -// CHECK: [[EXI_SELF:%[0-9]+]] = init_existential_ref [[SELF]] : $MyDistActorIsolated : $MyDistActorIsolated, $AnyObject -// CHECK: [[IS_REMOTE_FN:%[0-9]+]] = function_ref @swift_distributed_actor_is_remote : $@convention(thin) (@guaranteed AnyObject) -> Bool -// CHECK: [[IS_REMOTE:%[0-9]+]] = apply [[IS_REMOTE_FN]]([[EXI_SELF]]) -// CHECK: [[RAW_BOOL:%[0-9]+]] = struct_extract [[IS_REMOTE]] : $Bool, #Bool._value -// CHECK: cond_br [[RAW_BOOL]], [[REMOTE_ACTOR_DEINIT_BB:bb[0-9]+]], [[LOCAL_ACTOR_DEINIT_BB:bb[0-9]+]] - -// ===== ----------------------------------------------------------------------- -// CHECK: // localActorDeinitBB -// CHECK: [[LOCAL_ACTOR_DEINIT_BB]]: -// CHECK: [[ISOLATED_REF:%[0-9]+]] = function_ref @$s14default_deinit19MyDistActorIsolatedCfZ : $@convention(thin) (@owned MyDistActorIsolated) -> () -// CHECK: [[EXECUTOR:%[0-9]+]] = extract_executor [[SELF]] : $MyDistActorIsolated -// CHECK: [[PERFORM_REF:%[0-9]+]] = function_ref @swift_task_deinitOnExecutor : $@convention(thin) (@owned AnyObject, @convention(thin) (@owned AnyObject) -> (), Builtin.Executor) -> () -// CHECK: [[SELF_AS_ANY_OBJECT:%[0-9]+]] = unchecked_bitwise_cast [[SELF]] : $MyDistActorIsolated to $AnyObject -// CHECK: [[ISOLATED_CASTED:%[0-9]+]] = convert_function [[ISOLATED_REF]] : $@convention(thin) (@owned MyDistActorIsolated) -> () to $@convention(thin) (@owned AnyObject) -> () -// CHECK: [[DROP:%[0-9]+]] = apply [[PERFORM_REF]]([[SELF_AS_ANY_OBJECT]], [[ISOLATED_CASTED]], [[EXECUTOR]]) : $@convention(thin) (@owned AnyObject, @convention(thin) (@owned AnyObject) -> (), Builtin.Executor) -> () -// CHECK: br [[FINISH_DEINIT_BB:bb[0-9]+]] - -// ===== ----------------------------------------------------------------------- -// CHECK: // finishDeinitBB -// CHECK: [[FINISH_DEINIT_BB]]: -// CHECK: [[RESULT:%[0-9]+]] = tuple () -// CHECK: return [[RESULT]] : $() - -// ===== ----------------------------------------------------------------------- -// CHECK: // remoteActorDeinitBB -// CHECK: [[REMOTE_ACTOR_DEINIT_BB]]: - -// Even just the remote deinit branch must destroy the ID -// CHECK: [[REF:%[0-9]+]] = ref_element_addr [[SELF]] : $MyDistActorIsolated, #MyDistActorIsolated.id -// CHECK: [[ACCESS:%[0-9]+]] = begin_access [deinit] [static] [[REF]] : $*ActorAddress -// CHECK: destroy_addr [[ACCESS]] : $*ActorAddress -// CHECK: end_access [[ACCESS]] : $*ActorAddress - -// As well as the actor system: -// CHECK: [[REF:%[0-9]+]] = ref_element_addr [[SELF]] : $MyDistActorIsolated, #MyDistActorIsolated.actorSystem -// CHECK: [[ACCESS:%[0-9]+]] = begin_access [deinit] [static] [[REF]] : $*FakeActorSystem -// CHECK: destroy_addr [[ACCESS]] : $*FakeActorSystem -// CHECK: end_access [[ACCESS]] : $*FakeActorSystem - -// Destroy default actor implementation -// CHECK: [[BUILTIN:%[0-9]+]] = builtin "destroyDefaultActor"([[SELF]] : $MyDistActorIsolated) : $() - -// And deallocate the proxy -// CHECK: dealloc_ref [[SELF]] : $MyDistActorIsolated - -// Return -// CHECK: br [[FINISH_DEINIT_BB]] - -// CHECK: } // end sil function '$s14default_deinit19MyDistActorIsolatedCfD' - -// ===== ----------------------------------------------------------------------- - -// MARK: - Local actor with nonisolated deinit +// MARK: local actor check @available(macOS 12, *) actor SimpleActor { @@ -270,11 +106,9 @@ actor SimpleActor { } } -// MARK: Destroying deinit +// additionally, we add basic coverage for a non-distributed actor's deinit -// ===== ----------------------------------------------------------------------- -// CHECK-LABEL: // SimpleActor.deinit -// CHECK-NEXT: sil hidden{{.*}} @$s14default_deinit11SimpleActorCfd : $@convention(method) (@guaranteed SimpleActor) -> @owned Builtin.NativeObject { +// CHECK-LABEL: sil hidden{{.*}} @$s14default_deinit11SimpleActorCfd : $@convention(method) (@guaranteed SimpleActor) -> @owned Builtin.NativeObject { // CHECK: bb0([[SELF:%[0-9]+]] : $SimpleActor): // CHECK: [[REF:%[0-9]+]] = ref_element_addr [[SELF]] : $SimpleActor, #SimpleActor.someField // CHECK: [[ACCESS:%[0-9]+]] = begin_access [deinit] [static] [[REF]] @@ -285,80 +119,4 @@ actor SimpleActor { // CHECK: return [[CAST]] : $Builtin.NativeObject // CHECK: } // end sil function '$s14default_deinit11SimpleActorCfd' -// MARK: Isolated deallocating deinit -// ===== ----------------------------------------------------------------------- -// CHECK-NOT: SimpleActor.__isolated_deallocating_deinit -// CHECK-NOT: @$s14default_deinit11SimpleActorCfZ - -// MARK: Deallocating deinit - -// ===== ----------------------------------------------------------------------- -// CHECK-LABEL: // SimpleActor.__deallocating_deinit -// CHECK-NEXT: sil hidden{{.*}} @$s14default_deinit11SimpleActorCfD : $@convention(method) (@owned SimpleActor) -> () { -// CHECK: bb0([[SELF:%[0-9]+]] : $SimpleActor): -// CHECK: [[DESTROYER_REF:%[0-9]+]] = function_ref @$s14default_deinit11SimpleActorCfd : $@convention(method) (@guaranteed SimpleActor) -> @owned Builtin.NativeObject -// CHECK: [[UNTYPED_DESTOY_RESULT:%[0-9]+]] = apply [[DESTROYER_REF]]([[SELF]]) : $@convention(method) (@guaranteed SimpleActor) -> @owned Builtin.NativeObject -// CHECK: [[TYPED_DESTOY_RESULT:%[0-9]+]] = unchecked_ref_cast [[UNTYPED_DESTOY_RESULT]] : $Builtin.NativeObject to $SimpleActor -// CHECK: dealloc_ref [[TYPED_DESTOY_RESULT]] : $SimpleActor -// CHECK: [[RESULT:%[0-9]+]] = tuple () -// CHECK: return [[RESULT]] : $() -// CHECK: } // end sil function '$s14default_deinit11SimpleActorCfD' - -// MARK: - Local actor with nonisolated deinit - -@available(macOS 12, *) -actor SimpleActorIsolated { - let someField: SomeClass - init() { - self.someField = SomeClass() - } - deinit { - doIt() - } -} - -// MARK: Destroying deinit - -// ===== ----------------------------------------------------------------------- -// CHECK-LABEL: // SimpleActorIsolated.deinit -// CHECK-NEXT: sil hidden{{.*}} @$s14default_deinit19SimpleActorIsolatedCfd : $@convention(method) (@guaranteed SimpleActorIsolated) -> @owned Builtin.NativeObject { -// CHECK: bb0([[SELF:%[0-9]+]] : $SimpleActorIsolated): -// CHECK: [[REF:%[0-9]+]] = ref_element_addr [[SELF]] : $SimpleActorIsolated, #SimpleActorIsolated.someField -// CHECK: [[ACCESS:%[0-9]+]] = begin_access [deinit] [static] [[REF]] -// CHECK: destroy_addr [[ACCESS]] : $*SomeClass -// CHECK: end_access [[ACCESS]] -// CHECK: builtin "destroyDefaultActor"([[SELF]] : $SimpleActorIsolated) -// CHECK: [[CAST:%[0-9]+]] = unchecked_ref_cast [[SELF]] -// CHECK: return [[CAST]] : $Builtin.NativeObject -// CHECK: } // end sil function '$s14default_deinit19SimpleActorIsolatedCfd' - -// MARK: Isolated deallocating deinit - -// ===== ----------------------------------------------------------------------- -// CHECK-LABEL: // SimpleActorIsolated.__isolated_deallocating_deinit -// CHECK-NEXT: sil hidden{{.*}} @$s14default_deinit19SimpleActorIsolatedCfZ : $@convention(thin) (@owned SimpleActorIsolated) -> () { -// CHECK: bb0([[SELF:%[0-9]+]] : $SimpleActorIsolated): -// CHECK: [[DESTROYER_REF:%[0-9]+]] = function_ref @$s14default_deinit19SimpleActorIsolatedCfd : $@convention(method) (@guaranteed SimpleActorIsolated) -> @owned Builtin.NativeObject -// CHECK: [[UNTYPED_DESTOY_RESULT:%[0-9]+]] = apply [[DESTROYER_REF]]([[SELF]]) : $@convention(method) (@guaranteed SimpleActorIsolated) -> @owned Builtin.NativeObject -// CHECK: [[TYPED_DESTOY_RESULT:%[0-9]+]] = unchecked_ref_cast [[UNTYPED_DESTOY_RESULT]] : $Builtin.NativeObject to $SimpleActorIsolated -// CHECK: dealloc_ref [[TYPED_DESTOY_RESULT]] : $SimpleActorIsolated -// CHECK: [[RESULT:%[0-9]+]] = tuple () -// CHECK: return [[RESULT]] : $() -// CHECK: } // end sil function '$s14default_deinit19SimpleActorIsolatedCfZ' - -// MARK: Deallocating deinit - -// ===== ----------------------------------------------------------------------- -// CHECK-LABEL: // SimpleActorIsolated.__deallocating_deinit -// CHECK-NEXT: sil hidden{{.*}} @$s14default_deinit19SimpleActorIsolatedCfD : $@convention(method) (@owned SimpleActorIsolated) -> () { -// CHECK: bb0([[SELF:%[0-9]+]] : $SimpleActorIsolated): -// CHECK: [[ISOLATED_REF:%[0-9]+]] = function_ref @$s14default_deinit19SimpleActorIsolatedCfZ : $@convention(thin) (@owned SimpleActorIsolated) -> () -// CHECK: [[EXECUTOR:%[0-9]+]] = extract_executor [[SELF]] : $SimpleActorIsolated -// CHECK: [[PERFORM_REF:%[0-9]+]] = function_ref @swift_task_deinitOnExecutor : $@convention(thin) (@owned AnyObject, @convention(thin) (@owned AnyObject) -> (), Builtin.Executor) -> () -// CHECK: [[SELF_AS_ANY_OBJECT:%[0-9]+]] = unchecked_bitwise_cast [[SELF]] : $SimpleActorIsolated to $AnyObject -// CHECK: [[ISOLATED_CASTED:%[0-9]+]] = convert_function [[ISOLATED_REF]] : $@convention(thin) (@owned SimpleActorIsolated) -> () to $@convention(thin) (@owned AnyObject) -> () -// CHECK: [[DROP:%[0-9]+]] = apply [[PERFORM_REF]]([[SELF_AS_ANY_OBJECT]], [[ISOLATED_CASTED]], [[EXECUTOR]]) : $@convention(thin) (@owned AnyObject, @convention(thin) (@owned AnyObject) -> (), Builtin.Executor) -> () -// CHECK: [[RESULT:%[0-9]+]] = tuple () -// CHECK: return [[RESULT]] : $() -// CHECK: } // end sil function '$s14default_deinit19SimpleActorIsolatedCfD' diff --git a/test/Distributed/SIL/distributed_actor_explicit_deinit_coverage.swift b/test/Distributed/SIL/distributed_actor_explicit_deinit_coverage.swift index 0ee4b2e49a9..844a71420da 100644 --- a/test/Distributed/SIL/distributed_actor_explicit_deinit_coverage.swift +++ b/test/Distributed/SIL/distributed_actor_explicit_deinit_coverage.swift @@ -17,9 +17,10 @@ distributed actor MyDistActor { self.actorSystem = system } - // CHECK-LABEL: sil hidden @$s13coverage_dist11MyDistActorCfd : $@convention(method) (@guaranteed MyDistActor) -> @owned Builtin.Nativ - // CHECK: bb0(%0 : $MyDistActor): - // CHECK-NEXT: debug_value + // CHECK-LABEL: sil hidden @$s13coverage_dist11MyDistActorCfd : $@convention(method) (@guaranteed MyDistActor) -> @owned Builtin.NativeObject + // CHECK: cond_br {{%[0-9]+}}, {{bb[0-9]+}}, [[DEINITBODYBB:bb[0-9]+]] + + // CHECK: [[DEINITBODYBB]]: // CHECK-NEXT: increment_profiler_counter 0 // CHECK: function_ref @$sSb6randomSbyFZ // CHECK: cond_br {{%[0-9]+}}, [[TRUEBB:bb[0-9]+]], {{bb[0-9]+}} diff --git a/test/ModuleInterface/SmokeTest.swiftinterface b/test/ModuleInterface/SmokeTest.swiftinterface index 2a89ed9710f..ea6b5663c57 100644 --- a/test/ModuleInterface/SmokeTest.swiftinterface +++ b/test/ModuleInterface/SmokeTest.swiftinterface @@ -13,6 +13,7 @@ // RUN: %target-swift-frontend -compile-module-from-interface -o %t/SmokeTest.swiftmodule %s // RUN: %target-swift-ide-test -print-module -module-to-print SmokeTest -I %t -source-filename x -print-interface > %t/SmokeTest.txt // RUN: %FileCheck %s < %t/SmokeTest.txt +// RUN: %FileCheck -check-prefix NEGATIVE %s < %t/SmokeTest.txt // RUN: llvm-bcanalyzer -dump %t/SmokeTest.swiftmodule | grep FILE_DEPENDENCY // CHECK-LABEL: public class TestClass @@ -32,7 +33,7 @@ public class TestClass { // CHECK: public static var propWithNoAccessors: Int{{$}} public static var propWithNoAccessors: Int - // CHECK: deinit + // NEGATIVE-NOT: deinit deinit } // CHECK: {{^}$}} diff --git a/test/ModuleInterface/isolated-deinit-compatibility.swift b/test/ModuleInterface/isolated-deinit-compatibility.swift deleted file mode 100644 index 72d4d35924f..00000000000 --- a/test/ModuleInterface/isolated-deinit-compatibility.swift +++ /dev/null @@ -1,221 +0,0 @@ -// RUN: %target-swift-frontend -disable-availability-checking -emit-silgen -verify %s -// RUN: %target-swift-emit-module-interface(%t.swiftinterface) -DEMIT_IFACE %s -disable-availability-checking -module-name IsolatedDeinitCompatibility -// RUN: %target-swift-typecheck-module-from-interface(%t.swiftinterface) -disable-availability-checking -module-name IsolatedDeinitCompatibility -// RUN: %FileCheck %s < %t.swiftinterface - -// MARK: Sync deinit in class - -// CHECK-NOT: # -// CHECK: open class SyncClassDefaultOpen { -// CHECK-NOT: # -// CHECK: {{(@objc )?}}deinit -// CHECK-NOT: # -// CHECK: } -open class SyncClassDefaultOpen { - deinit {} -} - -// CHECK-NOT: # -// CHECK: public class SyncClassDefaultPublic { -// CHECK-NOT: # -// CHECK: {{(@objc )?}}deinit -// CHECK-NOT: # -// CHECK: } -public class SyncClassDefaultPublic { - deinit {} -} - -// CHECK: #if {{.*}}$IsolatedDeinit -// CHECK-NOT: # -// CHECK: open class SyncClassGlobalActorOpen { -// CHECK-NOT: # -// CHECK: {{(@objc )?}}@_Concurrency.MainActor deinit -// CHECK-NOT: # -// CHECK: } -// CHECK-NOT: # -// CHECK: #else -// CHECK-NOT: # -// CHECK: public class SyncClassGlobalActorOpen { -// CHECK-NOT: # -// CHECK: {{(@objc )?}}deinit -// CHECK-NOT: # -// CHECK: } -// CHECK-NOT: # -// CHECK: #endif -open class SyncClassGlobalActorOpen { - @MainActor deinit {} -} - -// CHECK-NOT: # -// CHECK: public class SyncClassGlobalActorPublic { -// CHECK-NOT: # -// CHECK: #if {{.*}}$IsolatedDeinit -// CHECK-NOT: # -// CHECK: {{(@objc )?}}@_Concurrency.MainActor deinit -// CHECK-NOT: # -// CHECK: #else -// CHECK-NOT: # -// CHECK: {{(@objc )?}}deinit -// CHECK-NOT: # -// CHECK: #endif -// CHECK-NOT: # -// CHECK: } -public class SyncClassGlobalActorPublic { - @MainActor deinit {} -} - -// CHECK: #if {{.*}}$IsolatedDeinit -// CHECK-NOT: # -// CHECK: @_Concurrency.MainActor open class SyncClassIsolatedOpen { -// CHECK-NOT: # -// CHECK: {{(@objc )?}}isolated deinit -// CHECK-NOT: # -// CHECK: } -// CHECK-NOT: # -// CHECK: #else -// CHECK-NOT: # -// CHECK: @_Concurrency.MainActor public class SyncClassIsolatedOpen { -// CHECK-NOT: # -// CHECK: {{(@objc )?}}deinit -// CHECK-NOT: # -// CHECK: } -// CHECK-NOT: # -// CHECK: #endif -@MainActor -open class SyncClassIsolatedOpen { - isolated deinit {} -} - -// CHECK-NOT: # -// CHECK: @_Concurrency.MainActor public class SyncClassIsolatedPublic { -// CHECK-NOT: # -// CHECK: #if {{.*}}$IsolatedDeinit -// CHECK-NOT: # -// CHECK: {{(@objc )?}}isolated deinit -// CHECK-NOT: # -// CHECK: #else -// CHECK-NOT: # -// CHECK: {{(@objc )?}}deinit -// CHECK-NOT: # -// CHECK: #endif -// CHECK-NOT: # -// CHECK: } -@MainActor -public class SyncClassIsolatedPublic { - isolated deinit {} -} - -// CHECK: #if {{.*}}$IsolatedDeinit -// CHECK-NOT: # -// CHECK: @_Concurrency.MainActor open class SyncClassNonisolatedOpen { -// CHECK-NOT: # -// CHECK: {{(@objc )?}}nonisolated deinit -// CHECK-NOT: # -// CHECK: } -// CHECK-NOT: # -// CHECK: #else -// CHECK-NOT: # -// CHECK: @_Concurrency.MainActor public class SyncClassNonisolatedOpen { -// CHECK-NOT: # -// CHECK: {{(@objc )?}}deinit -// CHECK-NOT: # -// CHECK: } -// CHECK-NOT: # -// CHECK: #endif -@MainActor -open class SyncClassNonisolatedOpen { - nonisolated deinit {} -} - -// CHECK-NOT: # -// CHECK: @_Concurrency.MainActor public class SyncClassNonisolatedPublic { -// CHECK-NOT: # -// CHECK: #if {{.*}}$IsolatedDeinit -// CHECK-NOT: # -// CHECK: {{(@objc )?}}nonisolated deinit -// CHECK-NOT: # -// CHECK: #else -// CHECK-NOT: # -// CHECK: {{(@objc )?}}deinit -// CHECK-NOT: # -// CHECK: #endif -// CHECK-NOT: # -// CHECK: } -@MainActor -public class SyncClassNonisolatedPublic { - nonisolated deinit {} -} - -// MARK: Sync deinit in actor - -// CHECK-NOT: # -// CHECK: public actor SyncActorDefaultPublic { -// CHECK-NOT: # -// CHECK: {{(@objc )?}}deinit -// CHECK-NOT: # -// CHECK: } -public actor SyncActorDefaultPublic { - deinit {} -} - -// CHECK-NOT: # -// CHECK: public actor SyncActorGlobalActorPublic { -// CHECK-NOT: # -// CHECK: #if {{.*}}$IsolatedDeinit -// CHECK-NOT: # -// CHECK: {{(@objc )?}}@_Concurrency.MainActor deinit -// CHECK-NOT: # -// CHECK: #else -// CHECK-NOT: # -// CHECK: {{(@objc )?}}deinit -// CHECK-NOT: # -// CHECK: #endif -// CHECK-NOT: # -// CHECK: } -public actor SyncActorGlobalActorPublic { - @MainActor deinit {} -} - -// CHECK-NOT: # -// CHECK: public actor SyncActorIsolatedPublic { -// CHECK-NOT: # -// CHECK: #if {{.*}}$IsolatedDeinit -// CHECK-NOT: # -// CHECK: {{(@objc )?}}isolated deinit -// CHECK-NOT: # -// CHECK: #else -// CHECK-NOT: # -// CHECK: {{(@objc )?}}deinit -// CHECK-NOT: # -// CHECK: #endif -// CHECK-NOT: # -// CHECK: } -public actor SyncActorIsolatedPublic { - isolated deinit {} -} - -// CHECK-NOT: # -// CHECK: public actor SyncActorNonisolatedPublic { -// CHECK-NOT: # -// CHECK: #if {{.*}}$IsolatedDeinit -// CHECK-NOT: # -// CHECK: {{(@objc )?}}nonisolated deinit -// CHECK-NOT: # -// CHECK: #else -// CHECK-NOT: # -// CHECK: {{(@objc )?}}deinit -// CHECK-NOT: # -// CHECK: #endif -// CHECK-NOT: # -// CHECK: } -public actor SyncActorNonisolatedPublic { - nonisolated deinit {} -} - -// MARK: - Open actor - -// Check that open actors are not allowed -// If they become allowed in the future, extra test cases need to be added to this test -#if !EMIT_IFACE -open actor OpenActor {} // expected-error {{only classes and overridable class members can be declared 'open'; use 'public'}} -#endif diff --git a/test/SILGen/inlinable_attribute.swift b/test/SILGen/inlinable_attribute.swift index 5715f50fb1b..9e771e81941 100644 --- a/test/SILGen/inlinable_attribute.swift +++ b/test/SILGen/inlinable_attribute.swift @@ -38,7 +38,6 @@ public class MyCls { } public actor MyAct { - // CHECK-LABEL-NOT: sil [serialized] [ossa] @$s19inlinable_attribute5MyActCfZ : $@convention(thin) (@owned MyAct) -> () // CHECK-LABEL: sil [serialized] [ossa] @$s19inlinable_attribute5MyActCfD : $@convention(method) (@owned MyAct) -> () @inlinable deinit {} @@ -64,12 +63,6 @@ public actor MyAct { } } -public actor MyActIsolatedDeinit { - // CHECK-LABEL: sil [serialized] [ossa] @$s19inlinable_attribute19MyActIsolatedDeinitCfZ : $@convention(thin) (@owned MyActIsolatedDeinit) -> () - // CHECK-LABEL: sil [serialized] [ossa] @$s19inlinable_attribute19MyActIsolatedDeinitCfD : $@convention(method) (@owned MyActIsolatedDeinit) -> () - @inlinable isolated deinit {} -} - // Make sure enum case constructors for public and versioned enums are // [serialized]. @usableFromInline enum MyEnum { diff --git a/test/SILOptimizer/moveonly_raw_layout.swift b/test/SILOptimizer/moveonly_raw_layout.swift index d3ae63ba044..b5a05836e72 100644 --- a/test/SILOptimizer/moveonly_raw_layout.swift +++ b/test/SILOptimizer/moveonly_raw_layout.swift @@ -26,7 +26,6 @@ struct Lock: ~Copyable { } // CHECK-LABEL: // Lock.deinit - // CHECK-NEXT: // Isolation: nonisolated // CHECK-NEXT: sil{{.*}} @[[DEINIT:\$.*4LockV.*fD]] : deinit { // CHECK-NOT: destroy_addr diff --git a/test/Serialization/Recovery/implementation-only-override.swift b/test/Serialization/Recovery/implementation-only-override.swift index 11c2f9dd792..43fff1d1b95 100644 --- a/test/Serialization/Recovery/implementation-only-override.swift +++ b/test/Serialization/Recovery/implementation-only-override.swift @@ -18,7 +18,6 @@ import FooKit // CHECK-NEXT: /* placeholder for rwPropSECRET */ // CHECK-NEXT: /* placeholder for subscript(_:) */ // CHECK-NEXT: @_implementationOnly override var redefinedPropSECRET: Parent? -// CHECK-NEXT: deinit // CHECK-NEXT: } public class GoodChild: Parent { public override init() { super.init() } @@ -49,7 +48,6 @@ public class GoodChild: Parent { // CHECK-NEXT: /* placeholder for rwPropSECRET */ // CHECK-NEXT: /* placeholder for subscript(_:) */ // CHECK-NEXT: @_implementationOnly override var redefinedPropSECRET: Parent? -// CHECK-NEXT: deinit // CHECK-NEXT: } public class GoodGenericChild: Parent { public override init() { super.init() } @@ -74,7 +72,6 @@ public class GoodGenericChild: Parent { // CHECK-LABEL: class QuietChild : Parent { // CHECK-NEXT: /* placeholder for init(SECRET:) */ // CHECK-NEXT: /* placeholder for init(requiredSECRET:) */ -// CHECK-NEXT: deinit // CHECK-NEXT: } public class QuietChild: Parent { internal override init() { super.init() } @@ -112,7 +109,6 @@ internal class PrivateGrandchild: GoodChild { // CHECK-LABEL: class SubscriptChild : SubscriptParent { // CHECK-NEXT: @_implementationOnly override subscript(index: Int32) -> Parent? -// CHECK-NEXT: deinit // CHECK-NEXT: } public class SubscriptChild: SubscriptParent { @_implementationOnly public override subscript(_ index: Int32) -> Parent? { diff --git a/test/Serialization/Recovery/overrides.swift b/test/Serialization/Recovery/overrides.swift index 3a2c588c2fa..ebcb5e5e59f 100644 --- a/test/Serialization/Recovery/overrides.swift +++ b/test/Serialization/Recovery/overrides.swift @@ -103,13 +103,11 @@ public final class A_Sub3Final: Base { // CHECK-NEXT: var disappearingProperty: Int { get } // CHECK-NEXT: var disappearingPropertySetter: Int{{$}} // CHECK-NEXT: init() -// CHECK-NEXT: deinit // CHECK-NEXT: {{^}$}} // CHECK-LABEL: class A_Sub2 : A_Sub { // CHECK-NEXT: func disappearingMethod() // CHECK-NEXT: init() -// CHECK-NEXT: deinit // CHECK-NEXT: {{^}$}} // CHECK-LABEL: final class A_Sub3Final : Base { @@ -120,7 +118,6 @@ public final class A_Sub3Final: Base { // CHECK-NEXT: var disappearingProperty: Int { get } // CHECK-NEXT: var disappearingPropertySetter: Int{{$}} // CHECK-NEXT: init() -// CHECK-NEXT: deinit // CHECK-NEXT: {{^}$}} // CHECK-RECOVERY-LABEL: class A_Sub : Base { @@ -131,13 +128,11 @@ public final class A_Sub3Final: Base { // CHECK-RECOVERY-NEXT: /* placeholder for disappearingProperty */ // CHECK-RECOVERY-NEXT: var disappearingPropertySetter: Int{{$}} // CHECK-RECOVERY-NEXT: init() -// CHECK-RECOVERY-NEXT: deinit // CHECK-RECOVERY-NEXT: {{^}$}} // CHECK-RECOVERY-LABEL: class A_Sub2 : A_Sub { // CHECK-RECOVERY-NEXT: func disappearingMethod() // CHECK-RECOVERY-NEXT: init() -// CHECK-RECOVERY-NEXT: deinit // CHECK-RECOVERY-NEXT: {{^}$}} // CHECK-RECOVERY-LABEL: class A_Sub3Final : Base { @@ -148,7 +143,6 @@ public final class A_Sub3Final: Base { // CHECK-RECOVERY-NEXT: /* placeholder for disappearingProperty */ // CHECK-RECOVERY-NEXT: var disappearingPropertySetter: Int{{$}} // CHECK-RECOVERY-NEXT: init() -// CHECK-RECOVERY-NEXT: deinit // CHECK-RECOVERY-NEXT: {{^}$}} extension Base { @@ -166,7 +160,6 @@ public class B_GenericSub : GenericBase { // CHECK-NEXT: func nullabilityChangeMethod() -> Base? // CHECK-NEXT: func typeChangeMethod() -> Any // CHECK-NEXT: init() -// CHECK-NEXT: deinit // CHECK-NEXT: {{^}$}} // CHECK-RECOVERY-LABEL: class B_GenericSub : GenericBase { @@ -174,7 +167,6 @@ public class B_GenericSub : GenericBase { // CHECK-RECOVERY-NEXT: func nullabilityChangeMethod() -> Base? // CHECK-RECOVERY-NEXT: func typeChangeMethod() -> Any // CHECK-RECOVERY-NEXT: init() -// CHECK-RECOVERY-NEXT: deinit // CHECK-RECOVERY-NEXT: {{^}$}} @@ -185,13 +177,11 @@ public class C1_IndexedSubscriptDisappears : IndexedSubscriptDisappearsBase { // CHECK-LABEL: class C1_IndexedSubscriptDisappears : IndexedSubscriptDisappearsBase { // CHECK-NEXT: subscript(index: Int) -> Any { get } // CHECK-NEXT: init() -// CHECK-NEXT: deinit // CHECK-NEXT: {{^}$}} // CHECK-RECOVERY-LABEL: class C1_IndexedSubscriptDisappears : IndexedSubscriptDisappearsBase { // CHECK-RECOVERY-NEXT: /* placeholder for subscript(_:) */ // CHECK-RECOVERY-NEXT: init() -// CHECK-RECOVERY-NEXT: deinit // CHECK-RECOVERY-NEXT: {{^}$}} @@ -202,13 +192,11 @@ public class C2_KeyedSubscriptDisappears : KeyedSubscriptDisappearsBase { // CHECK-LABEL: class C2_KeyedSubscriptDisappears : KeyedSubscriptDisappearsBase { // CHECK-NEXT: subscript(key: Any) -> Any { get } // CHECK-NEXT: init() -// CHECK-NEXT: deinit // CHECK-NEXT: {{^}$}} // CHECK-RECOVERY-LABEL: class C2_KeyedSubscriptDisappears : KeyedSubscriptDisappearsBase { // CHECK-RECOVERY-NEXT: /* placeholder for subscript(_:) */ // CHECK-RECOVERY-NEXT: init() -// CHECK-RECOVERY-NEXT: deinit // CHECK-RECOVERY-NEXT: {{^}$}} @@ -219,13 +207,11 @@ public class C3_GenericIndexedSubscriptDisappears : GenericIndexedSubscriptDisap // CHECK-LABEL: class C3_GenericIndexedSubscriptDisappears : GenericIndexedSubscriptDisappearsBase { // CHECK-NEXT: subscript(index: Int) -> Base { get } // CHECK-NEXT: init() -// CHECK-NEXT: deinit // CHECK-NEXT: {{^}$}} // CHECK-RECOVERY-LABEL: class C3_GenericIndexedSubscriptDisappears : GenericIndexedSubscriptDisappearsBase { // CHECK-RECOVERY-NEXT: /* placeholder for subscript(_:) */ // CHECK-RECOVERY-NEXT: init() -// CHECK-RECOVERY-NEXT: deinit // CHECK-RECOVERY-NEXT: {{^}$}} @@ -236,13 +222,11 @@ public class C4_GenericKeyedSubscriptDisappears : GenericKeyedSubscriptDisappear // CHECK-LABEL: class C4_GenericKeyedSubscriptDisappears : GenericKeyedSubscriptDisappearsBase { // CHECK-NEXT: subscript(key: Any) -> Base { get } // CHECK-NEXT: init() -// CHECK-NEXT: deinit // CHECK-NEXT: {{^}$}} // CHECK-RECOVERY-LABEL: class C4_GenericKeyedSubscriptDisappears : GenericKeyedSubscriptDisappearsBase { // CHECK-RECOVERY-NEXT: /* placeholder for subscript(_:) */ // CHECK-RECOVERY-NEXT: init() -// CHECK-RECOVERY-NEXT: deinit // CHECK-RECOVERY-NEXT: {{^}$}} @@ -254,13 +238,11 @@ open class D1_DesignatedInitDisappears : DesignatedInitDisappearsBase { // CHECK-LABEL: class D1_DesignatedInitDisappears : DesignatedInitDisappearsBase { // CHECK-NEXT: init() // CHECK-NEXT: init(value: Int) -// CHECK-NEXT: deinit // CHECK-NEXT: {{^}$}} // CHECK-RECOVERY-LABEL: class D1_DesignatedInitDisappears : DesignatedInitDisappearsBase { // CHECK-RECOVERY-NEXT: init() // CHECK-RECOVERY-NEXT: /* placeholder for init(value:) */ -// CHECK-RECOVERY-NEXT: deinit // CHECK-RECOVERY-NEXT: {{^}$}} @@ -270,12 +252,10 @@ open class D2_OnlyDesignatedInitDisappears : OnlyDesignatedInitDisappearsBase { // CHECK-LABEL: class D2_OnlyDesignatedInitDisappears : OnlyDesignatedInitDisappearsBase { // CHECK-NEXT: init(value: Int) -// CHECK-NEXT: deinit // CHECK-NEXT: {{^}$}} // CHECK-RECOVERY-LABEL: class D2_OnlyDesignatedInitDisappears : OnlyDesignatedInitDisappearsBase { // CHECK-RECOVERY-NEXT: /* placeholder for init(value:) */ -// CHECK-RECOVERY-NEXT: deinit // CHECK-RECOVERY-NEXT: {{^}$}} @@ -285,12 +265,10 @@ open class D3_ConvenienceInitDisappears : ConvenienceInitDisappearsBase { // CHECK-LABEL: class D3_ConvenienceInitDisappears : ConvenienceInitDisappearsBase { // CHECK-NEXT: init() -// CHECK-NEXT: deinit // CHECK-NEXT: {{^}$}} // CHECK-RECOVERY-LABEL: class D3_ConvenienceInitDisappears : ConvenienceInitDisappearsBase { // CHECK-RECOVERY-NEXT: init() -// CHECK-RECOVERY-NEXT: deinit // CHECK-RECOVERY-NEXT: {{^}$}} @@ -302,13 +280,11 @@ open class D4_UnknownInitDisappears : UnknownInitDisappearsBase { // CHECK-LABEL: class D4_UnknownInitDisappears : UnknownInitDisappearsBase { // CHECK-NEXT: init() // CHECK-NEXT: init(value: Int) -// CHECK-NEXT: deinit // CHECK-NEXT: {{^}$}} // CHECK-RECOVERY-LABEL: class D4_UnknownInitDisappears : UnknownInitDisappearsBase { // CHECK-RECOVERY-NEXT: init() // CHECK-RECOVERY-NEXT: /* placeholder for init(value:) */ -// CHECK-RECOVERY-NEXT: deinit // CHECK-RECOVERY-NEXT: {{^}$}} @@ -319,13 +295,11 @@ open class D5_OnlyUnknownInitDisappears : OnlyUnknownInitDisappearsBase { // CHECK-LABEL: class D5_OnlyUnknownInitDisappears : OnlyUnknownInitDisappearsBase { // CHECK-NEXT: init(value: Int) // CHECK-NEXT: init() -// CHECK-NEXT: deinit // CHECK-NEXT: {{^}$}} // CHECK-RECOVERY-LABEL: class D5_OnlyUnknownInitDisappears : OnlyUnknownInitDisappearsBase { // CHECK-RECOVERY-NEXT: /* placeholder for init(value:) */ // CHECK-RECOVERY-NEXT: init() -// CHECK-RECOVERY-NEXT: deinit // CHECK-RECOVERY-NEXT: {{^}$}} open class D6_UnknownInitDisappearsGrandchild : D4_UnknownInitDisappears { @@ -336,13 +310,11 @@ open class D6_UnknownInitDisappearsGrandchild : D4_UnknownInitDisappears { // CHECK-LABEL: class D6_UnknownInitDisappearsGrandchild : D4_UnknownInitDisappears { // CHECK-NEXT: init() // CHECK-NEXT: init(value: Int) -// CHECK-NEXT: deinit // CHECK-NEXT: {{^}$}} // CHECK-RECOVERY-LABEL: class D6_UnknownInitDisappearsGrandchild : D4_UnknownInitDisappears { // CHECK-RECOVERY-NEXT: init() // CHECK-RECOVERY-NEXT: /* placeholder for init(value:) */ -// CHECK-RECOVERY-NEXT: deinit // CHECK-RECOVERY-NEXT: {{^}$}} open class D7_UnknownInitDisappearsGrandchildRequired : D4_UnknownInitDisappears { @@ -353,13 +325,11 @@ open class D7_UnknownInitDisappearsGrandchildRequired : D4_UnknownInitDisappears // CHECK-LABEL: class D7_UnknownInitDisappearsGrandchildRequired : D4_UnknownInitDisappears { // CHECK-NEXT: init() // CHECK-NEXT: init(value: Int) -// CHECK-NEXT: deinit // CHECK-NEXT: {{^}$}} // CHECK-RECOVERY-LABEL: class D7_UnknownInitDisappearsGrandchildRequired : D4_UnknownInitDisappears { // CHECK-RECOVERY-NEXT: init() // CHECK-RECOVERY-NEXT: /* placeholder for init(value:) */ -// CHECK-RECOVERY-NEXT: deinit // CHECK-RECOVERY-NEXT: {{^}$}} open class D8_UnknownInitDisappearsRequired : UnknownInitDisappearsBase { @@ -370,13 +340,11 @@ open class D8_UnknownInitDisappearsRequired : UnknownInitDisappearsBase { // CHECK-LABEL: class D8_UnknownInitDisappearsRequired : UnknownInitDisappearsBase { // CHECK-NEXT: init() // CHECK-NEXT: init(value: Int) -// CHECK-NEXT: deinit // CHECK-NEXT: {{^}$}} // CHECK-RECOVERY-LABEL: class D8_UnknownInitDisappearsRequired : UnknownInitDisappearsBase { // CHECK-RECOVERY-NEXT: init() // CHECK-RECOVERY-NEXT: /* placeholder for init(value:) */ -// CHECK-RECOVERY-NEXT: deinit // CHECK-RECOVERY-NEXT: {{^}$}} open class D9_UnknownInitDisappearsRequiredGrandchild : D8_UnknownInitDisappearsRequired { @@ -387,13 +355,11 @@ open class D9_UnknownInitDisappearsRequiredGrandchild : D8_UnknownInitDisappears // CHECK-LABEL: class D9_UnknownInitDisappearsRequiredGrandchild : D8_UnknownInitDisappearsRequired { // CHECK-NEXT: init() // CHECK-NEXT: init(value: Int) -// CHECK-NEXT: deinit // CHECK-NEXT: {{^}$}} // CHECK-RECOVERY-LABEL: class D9_UnknownInitDisappearsRequiredGrandchild : D8_UnknownInitDisappearsRequired { // CHECK-RECOVERY-NEXT: init() // CHECK-RECOVERY-NEXT: /* placeholder for init(value:) */ -// CHECK-RECOVERY-NEXT: deinit // CHECK-RECOVERY-NEXT: {{^}$}} public class E1_MethodWithDisappearingType : MethodWithDisappearingType { @@ -403,13 +369,11 @@ public class E1_MethodWithDisappearingType : MethodWithDisappearingType { // CHECK-LABEL: class E1_MethodWithDisappearingType : MethodWithDisappearingType { // CHECK-NEXT: override func boxItUp() -> BoxedInt // CHECK-NEXT: init() -// CHECK-NEXT: deinit // CHECK-NEXT: {{^}$}} // CHECK-RECOVERY-LABEL: class E1_MethodWithDisappearingType : MethodWithDisappearingType { // CHECK-RECOVERY-NEXT: /* placeholder for boxItUp() */ // CHECK-RECOVERY-NEXT: init() -// CHECK-RECOVERY-NEXT: deinit // CHECK-RECOVERY-NEXT: {{^}$}} public class E2_InitializerStub : InitializerWithDisappearingType { @@ -420,14 +384,12 @@ public class E2_InitializerStub : InitializerWithDisappearingType { // CHECK-NEXT: init(unrelatedValue: Int) // CHECK-NEXT: init(boxedInt box: BoxedInt) // CHECK-NEXT: init() -// CHECK-NEXT: deinit // CHECK-NEXT: {{^}$}} // CHECK-RECOVERY-LABEL: class E2_InitializerStub : InitializerWithDisappearingType { // CHECK-RECOVERY-NEXT: init(unrelatedValue: Int) // CHECK-RECOVERY-NEXT: /* placeholder for init(boxedInt:) */ // CHECK-RECOVERY-NEXT: init() -// CHECK-RECOVERY-NEXT: deinit // CHECK-RECOVERY-NEXT: {{^}$}} #endif // TEST diff --git a/test/Serialization/attr-nonisolated.swift b/test/Serialization/attr-nonisolated.swift index f72b61635a7..1ecd9f8861a 100644 --- a/test/Serialization/attr-nonisolated.swift +++ b/test/Serialization/attr-nonisolated.swift @@ -14,7 +14,6 @@ // MODULE-CHECK: actor UnsafeCounter { // MODULE-CHECK-NEXT: var storage: Int // MODULE-CHECK-NEXT: nonisolated var count: Int -// MODULE-CHECK-NEXT: deinit // MODULE-CHECK-NEXT: init() // MODULE-CHECK-NEXT: } diff --git a/test/SourceKit/InterfaceGen/gen_swift_module.swift b/test/SourceKit/InterfaceGen/gen_swift_module.swift index d746da74fd6..f128a71fc4d 100644 --- a/test/SourceKit/InterfaceGen/gen_swift_module.swift +++ b/test/SourceKit/InterfaceGen/gen_swift_module.swift @@ -6,7 +6,7 @@ func f(s : inout [Int]) { // RUN: %empty-directory(%t.mod) // RUN: %empty-directory(%t.mod/mcp) -// RUN: %swift -emit-module -o %t.mod/swift_mod.swiftmodule %S/Inputs/swift_mod.swift -parse-as-library -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import -disable-objc-interop +// RUN: %swift -emit-module -o %t.mod/swift_mod.swiftmodule %S/Inputs/swift_mod.swift -parse-as-library -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import // RUN: %sourcekitd-test -req=interface-gen -module swift_mod -- -Xfrontend -disable-implicit-concurrency-module-import -Xfrontend -disable-implicit-string-processing-module-import -I %t.mod > %t.response // RUN: %diff -u %s.response %t.response @@ -30,7 +30,7 @@ func f(s : inout [Int]) { // Test we can generate the interface of a module loaded via a .swiftinterface file correctly // RUN: %empty-directory(%t.mod) -// RUN: %swift -emit-module -o /dev/null -emit-module-interface-path %t.mod/swift_mod.swiftinterface -O %S/Inputs/swift_mod.swift -parse-as-library -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import -disable-objc-interop +// RUN: %swift -emit-module -o /dev/null -emit-module-interface-path %t.mod/swift_mod.swiftinterface -O %S/Inputs/swift_mod.swift -parse-as-library -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import // RUN: %sourcekitd-test -req=interface-gen -module swift_mod -- -Xfrontend -disable-implicit-concurrency-module-import -Xfrontend -disable-implicit-string-processing-module-import -I %t.mod -module-cache-path %t.mod/mcp > %t.response // RUN: %diff -u %s.from_swiftinterface.response %t.response @@ -63,15 +63,6 @@ func f(s : inout [Int]) { // CHECK-DECLARATIONS-ARRAY-NOT: key.offset:{{.*}}{{^[0-9]}}0{{^[0-9]}} // CHECK-DECLARATIONS-ARRAY: key.offset -// deinit -// CHECK-DECLARATIONS-ARRAY: key.kind: -// CHECK-DECLARATIONS-ARRAY-SAME: decl -// CHECK-DECLARATIONS-ARRAY-SAME: function.destructor -// CHECK-DECLARATIONS-ARRAY-NEXT: key.usr: -// CHECK-DECLARATIONS-ARRAY-SAME: s:9swift_mod7MyClassCfd -// CHECK-DECLARATIONS-ARRAY-NOT: key.offset:{{.*}}{{^[0-9]}}0{{^[0-9]}} -// CHECK-DECLARATIONS-ARRAY: key.offset - // CHECK-DECLARATIONS-ARRAY-NOT: int_method // CHECK-DECLARATIONS-ARRAY-NOT: fp_method // CHECK-DECLARATIONS-ARRAY-NOT: priv_method diff --git a/test/SourceKit/InterfaceGen/gen_swift_module.swift.from_swiftinterface.response b/test/SourceKit/InterfaceGen/gen_swift_module.swift.from_swiftinterface.response index d24a270fb3b..021cd262c0c 100644 --- a/test/SourceKit/InterfaceGen/gen_swift_module.swift.from_swiftinterface.response +++ b/test/SourceKit/InterfaceGen/gen_swift_module.swift.from_swiftinterface.response @@ -2,8 +2,6 @@ public class MyClass { public func pub_method() - - deinit } public protocol MyProto { @@ -46,76 +44,71 @@ public func pub_function() -> Int key.offset: 41, key.length: 10 }, - { - key.kind: source.lang.swift.syntaxtype.keyword, - key.offset: 59, - key.length: 6 - }, { key.kind: source.lang.swift.syntaxtype.attribute.builtin, - key.offset: 69, + key.offset: 57, key.length: 6 }, { key.kind: source.lang.swift.syntaxtype.keyword, - key.offset: 76, + key.offset: 64, key.length: 8 }, { key.kind: source.lang.swift.syntaxtype.identifier, - key.offset: 85, + key.offset: 73, key.length: 7 }, { key.kind: source.lang.swift.syntaxtype.identifier, - key.offset: 93, + key.offset: 81, key.length: 5 }, { key.kind: source.lang.swift.syntaxtype.keyword, - key.offset: 107, + key.offset: 95, key.length: 14 }, { key.kind: source.lang.swift.syntaxtype.identifier, - key.offset: 122, + key.offset: 110, key.length: 5 }, { key.kind: source.lang.swift.syntaxtype.attribute.builtin, - key.offset: 131, + key.offset: 119, key.length: 18 }, { key.kind: source.lang.swift.syntaxtype.attribute.builtin, - key.offset: 150, + key.offset: 138, key.length: 6 }, { key.kind: source.lang.swift.syntaxtype.keyword, - key.offset: 157, + key.offset: 145, key.length: 4 }, { key.kind: source.lang.swift.syntaxtype.identifier, - key.offset: 162, + key.offset: 150, key.length: 12 }, { key.kind: source.lang.swift.syntaxtype.typeidentifier, - key.offset: 180, + key.offset: 168, key.length: 3 } ] [ { key.kind: source.lang.swift.ref.associatedtype, - key.offset: 93, + key.offset: 81, key.length: 5 }, { key.kind: source.lang.swift.ref.struct, - key.offset: 180, + key.offset: 168, key.length: 3, key.is_system: 1 } @@ -126,11 +119,11 @@ public func pub_function() -> Int key.accessibility: source.lang.swift.accessibility.public, key.name: "MyClass", key.offset: 8, - key.length: 59, + key.length: 47, key.nameoffset: 14, key.namelength: 7, key.bodyoffset: 23, - key.bodylength: 43, + key.bodylength: 31, key.attributes: [ { key.offset: 1, @@ -161,15 +154,15 @@ public func pub_function() -> Int key.kind: source.lang.swift.decl.protocol, key.accessibility: source.lang.swift.accessibility.public, key.name: "MyProto", - key.offset: 76, + key.offset: 64, key.length: 53, - key.nameoffset: 85, + key.nameoffset: 73, key.namelength: 7, - key.bodyoffset: 101, + key.bodyoffset: 89, key.bodylength: 27, key.attributes: [ { - key.offset: 69, + key.offset: 57, key.length: 6, key.attribute: source.decl.attribute.public } @@ -179,9 +172,9 @@ public func pub_function() -> Int key.kind: source.lang.swift.decl.associatedtype, key.accessibility: source.lang.swift.accessibility.public, key.name: "Assoc", - key.offset: 107, + key.offset: 95, key.length: 20, - key.nameoffset: 122, + key.nameoffset: 110, key.namelength: 5 } ] @@ -190,19 +183,19 @@ public func pub_function() -> Int key.kind: source.lang.swift.decl.function.free, key.accessibility: source.lang.swift.accessibility.public, key.name: "pub_function()", - key.offset: 157, + key.offset: 145, key.length: 26, key.typename: "Int", - key.nameoffset: 162, + key.nameoffset: 150, key.namelength: 14, key.attributes: [ { - key.offset: 150, + key.offset: 138, key.length: 6, key.attribute: source.decl.attribute.public }, { - key.offset: 131, + key.offset: 119, key.length: 18, key.attribute: source.decl.attribute.discardableResult } diff --git a/test/abi/macOS/arm64/concurrency.swift b/test/abi/macOS/arm64/concurrency.swift index e9852df3139..43f74aa456d 100644 --- a/test/abi/macOS/arm64/concurrency.swift +++ b/test/abi/macOS/arm64/concurrency.swift @@ -335,6 +335,3 @@ Added: _$ss9TaskLocalC13withValueImpl_9operation9isolation4file4lineqd__xn_qd__y // Swift.TaskLocal.withValue(_: A, operation: () async throws -> A1, isolation: isolated Swift.Actor?, file: Swift.String, line: Swift.UInt) async throws -> A1 Added: _$ss9TaskLocalC9withValue_9operation9isolation4file4lineqd__x_qd__yYaKXEScA_pSgYiSSSutYaKlF Added: _$ss9TaskLocalC9withValue_9operation9isolation4file4lineqd__x_qd__yYaKXEScA_pSgYiSSSutYaKlFTu - -// isolated deinit -Added: _swift_task_deinitOnExecutor diff --git a/test/abi/macOS/x86_64/concurrency.swift b/test/abi/macOS/x86_64/concurrency.swift index 916906aa8a4..de838365767 100644 --- a/test/abi/macOS/x86_64/concurrency.swift +++ b/test/abi/macOS/x86_64/concurrency.swift @@ -335,6 +335,3 @@ Added: _$ss9TaskLocalC13withValueImpl_9operation9isolation4file4lineqd__xn_qd__y // Swift.TaskLocal.withValue(_: A, operation: () async throws -> A1, isolation: isolated Swift.Actor?, file: Swift.String, line: Swift.UInt) async throws -> A1 Added: _$ss9TaskLocalC9withValue_9operation9isolation4file4lineqd__x_qd__yYaKXEScA_pSgYiSSSutYaKlF Added: _$ss9TaskLocalC9withValue_9operation9isolation4file4lineqd__x_qd__yYaKXEScA_pSgYiSSSutYaKlFTu - -// isolated deinit -Added: _swift_task_deinitOnExecutor diff --git a/test/attr/global_actor.swift b/test/attr/global_actor.swift index 59b4df85d51..1ff6fdbdf73 100644 --- a/test/attr/global_actor.swift +++ b/test/attr/global_actor.swift @@ -80,7 +80,7 @@ struct Y { class SomeClass { @GA1 init() { } - @GA1 deinit { } + @GA1 deinit { } // expected-error{{deinitializer cannot have a global actor}} } @GA1 typealias Integer = Int // expected-error{{type alias cannot have a global actor}} diff --git a/tools/swift-ide-test/swift-ide-test.cpp b/tools/swift-ide-test/swift-ide-test.cpp index 05618f02bcb..e9259b93b52 100644 --- a/tools/swift-ide-test/swift-ide-test.cpp +++ b/tools/swift-ide-test/swift-ide-test.cpp @@ -368,9 +368,10 @@ ModuleAliases("module-alias", llvm::cl::cat(Category)); static llvm::cl::opt - SkipDeinit("skip-deinit", - llvm::cl::desc("Whether to skip printing destructors"), - llvm::cl::cat(Category), llvm::cl::init(false)); +SkipDeinit("skip-deinit", + llvm::cl::desc("Whether to skip printing destructors"), + llvm::cl::cat(Category), + llvm::cl::init(true)); static llvm::cl::opt SkipImports("skip-imports",