@@ -511,7 +511,6 @@ static bool varIsSafeAcrossActors(const ModuleDecl *fromModule,
511511 return true ;
512512
513513 if (!var->isLet ()) {
514- ASTContext &ctx = var->getASTContext ();
515514 // A mutable storage of a value type accessed from within the module is
516515 // okay.
517516 if (dyn_cast_or_null<StructDecl>(var->getDeclContext ()->getAsDecl ()) &&
@@ -841,16 +840,25 @@ SendableCheckContext::preconcurrencyBehavior(Decl *decl) const {
841840 return std::nullopt ;
842841
843842 if (auto *nominal = dyn_cast<NominalTypeDecl>(decl)) {
844- // Determine whether this nominal type is visible via a @preconcurrency
845- // import.
846- auto import = nominal->findImport (fromDC);
847- auto sourceFile = fromDC->getParentSourceFile ();
843+ ModuleDecl *importedModule = nullptr ;
844+ if (nominal->getAttrs ().hasAttribute <PreconcurrencyAttr>()) {
845+ // If the declaration itself has the @preconcurrency attribute,
846+ // respect it.
847+ importedModule = nominal->getParentModule ();
848+ } else {
849+ // Determine whether this nominal type is visible via a @preconcurrency
850+ // import.
851+ auto import = nominal->findImport (fromDC);
852+ auto sourceFile = fromDC->getParentSourceFile ();
848853
849- if (!import || !import ->options .contains (ImportFlags::Preconcurrency))
850- return std::nullopt ;
854+ if (!import || !import ->options .contains (ImportFlags::Preconcurrency))
855+ return std::nullopt ;
851856
852- if (sourceFile)
853- sourceFile->setImportUsedPreconcurrency (*import );
857+ if (sourceFile)
858+ sourceFile->setImportUsedPreconcurrency (*import );
859+
860+ importedModule = import ->module .importedModule ;
861+ }
854862
855863 // When the type is explicitly non-Sendable, @preconcurrency imports
856864 // downgrade the diagnostic to a warning in Swift 6.
@@ -859,7 +867,7 @@ SendableCheckContext::preconcurrencyBehavior(Decl *decl) const {
859867
860868 // When the type is implicitly non-Sendable, `@preconcurrency` suppresses
861869 // diagnostics until the imported module enables Swift 6.
862- return import -> module . importedModule ->isConcurrencyChecked ()
870+ return importedModule->isConcurrencyChecked ()
863871 ? DiagnosticBehavior::Warning
864872 : DiagnosticBehavior::Ignore;
865873 }
@@ -5709,7 +5717,7 @@ static bool checkSendableInstanceStorage(
57095717 /* inDerivedConformance*/ Type (), element->getLoc (),
57105718 [&](Type type, DiagnosticBehavior behavior) {
57115719 auto preconcurrency =
5712- context.preconcurrencyBehavior (elementType ->getAnyNominal ());
5720+ context.preconcurrencyBehavior (type ->getAnyNominal ());
57135721 if (isImplicitSendableCheck (check)) {
57145722 // If this is for an externally-visible conformance, fail.
57155723 if (check == SendableCheck::ImplicitForExternallyVisible) {
@@ -5720,7 +5728,7 @@ static bool checkSendableInstanceStorage(
57205728 // If we are to ignore this diagnostic, just continue.
57215729 if (behavior == DiagnosticBehavior::Ignore ||
57225730 preconcurrency == DiagnosticBehavior::Ignore)
5723- return false ;
5731+ return true ;
57245732
57255733 invalid = true ;
57265734 return true ;
@@ -6831,3 +6839,14 @@ ActorReferenceResult ActorReferenceResult::forReference(
68316839
68326840 return forEntersActor (declIsolation, options);
68336841}
6842+
6843+ bool swift::diagnoseNonSendableFromDeinit (
6844+ SourceLoc refLoc, VarDecl *var, DeclContext *dc) {
6845+ return diagnoseIfAnyNonSendableTypes (var->getTypeInContext (),
6846+ SendableCheckContext (dc),
6847+ Type (),
6848+ SourceLoc (),
6849+ refLoc,
6850+ diag::non_sendable_from_deinit,
6851+ var->getDescriptiveKind (), var->getName ());
6852+ }
0 commit comments