Skip to content

Commit cee2aea

Browse files
authored
Merge pull request #82846 from DougGregor/isolated-conformance-to-sendablemetatype-proto-error
[SE-0470] Promote isolated-conformance-to-sendable-metatype protocol to an error
2 parents e67be5c + 56e38b3 commit cee2aea

File tree

6 files changed

+63
-28
lines changed

6 files changed

+63
-28
lines changed

include/swift/AST/Concurrency.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@
1919

2020
namespace swift {
2121

22+
/// Find the imported module that treats the given nominal type as "preconcurrency", or return `nullptr`
23+
/// if there is no such module.
24+
ModuleDecl *moduleImportForPreconcurrency(NominalTypeDecl *nominal,
25+
const DeclContext *fromDC);
26+
2227
/// Determinate the appropriate diagnostic behavior to used when emitting
2328
/// concurrency diagnostics when referencing the given nominal type from the
2429
/// given declaration context.

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8685,9 +8685,9 @@ GROUPED_ERROR(isolated_conformance_wrong_domain,IsolatedConformances,none,
86858685
GROUPED_WARNING(isolated_conformance_will_become_nonisolated,IsolatedConformances,none,
86868686
"conformance of %0 to %1 should be marked 'nonisolated' to retain its behavior with upcoming feature 'InferIsolatedConformances'",
86878687
(const ValueDecl *, const ValueDecl *))
8688-
GROUPED_WARNING(isolated_conformance_to_sendable_metatype,IsolatedConformances,none,
8689-
"%0 conformance of %1 to SendableMetatype-inheriting %kind2 can never "
8690-
"be used with generic code", (ActorIsolation, Type, const ValueDecl *))
8688+
GROUPED_ERROR(isolated_conformance_to_sendable_metatype,IsolatedConformances,none,
8689+
"cannot form %0 conformance of %1 to SendableMetatype-inheriting %kind2",
8690+
(ActorIsolation, Type, const ValueDecl *))
86918691
86928692
//===----------------------------------------------------------------------===//
86938693
// MARK: @_inheritActorContext

lib/AST/Concurrency.cpp

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -19,29 +19,35 @@
1919

2020
using namespace swift;
2121

22-
std::optional<DiagnosticBehavior>
23-
swift::getConcurrencyDiagnosticBehaviorLimit(NominalTypeDecl *nominal,
24-
const DeclContext *fromDC,
25-
bool ignoreExplicitConformance) {
26-
ModuleDecl *importedModule = nullptr;
22+
ModuleDecl *swift::moduleImportForPreconcurrency(
23+
NominalTypeDecl *nominal, const DeclContext *fromDC) {
24+
// If the declaration itself has the @preconcurrency attribute,
25+
// respect it.
2726
if (nominal->getAttrs().hasAttribute<PreconcurrencyAttr>()) {
28-
// If the declaration itself has the @preconcurrency attribute,
29-
// respect it.
30-
importedModule = nominal->getParentModule();
31-
} else {
32-
// Determine whether this nominal type is visible via a @preconcurrency
33-
// import.
34-
auto import = nominal->findImport(fromDC);
35-
auto sourceFile = fromDC->getParentSourceFile();
27+
return nominal->getParentModule();
28+
}
3629

37-
if (!import || !import->options.contains(ImportFlags::Preconcurrency))
38-
return std::nullopt;
30+
// Determine whether this nominal type is visible via a @preconcurrency
31+
// import.
32+
auto import = nominal->findImport(fromDC);
33+
auto sourceFile = fromDC->getParentSourceFile();
3934

40-
if (sourceFile)
41-
sourceFile->setImportUsedPreconcurrency(*import);
35+
if (!import || !import->options.contains(ImportFlags::Preconcurrency))
36+
return nullptr;
4237

43-
importedModule = import->module.importedModule;
44-
}
38+
if (sourceFile)
39+
sourceFile->setImportUsedPreconcurrency(*import);
40+
41+
return import->module.importedModule;
42+
}
43+
44+
std::optional<DiagnosticBehavior>
45+
swift::getConcurrencyDiagnosticBehaviorLimit(NominalTypeDecl *nominal,
46+
const DeclContext *fromDC,
47+
bool ignoreExplicitConformance) {
48+
ModuleDecl *importedModule = moduleImportForPreconcurrency(nominal, fromDC);
49+
if (!importedModule)
50+
return std::nullopt;
4551

4652
// When the type is explicitly non-Sendable, @preconcurrency imports
4753
// downgrade the diagnostic to a warning in Swift 6.

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8308,18 +8308,20 @@ RawConformanceIsolationRequest::evaluate(
83088308
globalActorTypeExpr->setType(MetatypeType::get(globalActorType));
83098309
}
83108310

8311-
// Isolated conformance to a SendableMetatype-inheriting protocol can
8312-
// never be used generically. Warn about it.
8311+
// Cannot form an isolated conformance to a SendableMetatype-inheriting
8312+
// protocol. Diagnose it.
83138313
if (auto sendableMetatype =
83148314
ctx.getProtocol(KnownProtocolKind::SendableMetatype)) {
8315-
if (proto->inheritsFrom(sendableMetatype) &&
8316-
!getActorIsolation(proto).preconcurrency()) {
8315+
if (proto->inheritsFrom(sendableMetatype)) {
8316+
bool isPreconcurrency = moduleImportForPreconcurrency(
8317+
proto, conformance->getDeclContext()) != nullptr;
83178318
ctx.Diags.diagnose(
83188319
conformance->getLoc(),
83198320
diag::isolated_conformance_to_sendable_metatype,
83208321
ActorIsolation::forGlobalActor(globalActorType),
83218322
conformance->getType(),
8322-
proto);
8323+
proto)
8324+
.limitBehaviorIf(isPreconcurrency, DiagnosticBehavior::Warning);
83238325
}
83248326
}
83258327

test/Concurrency/isolated_conformance.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ protocol R: SendableMetatype {
151151
func f()
152152
}
153153

154-
// expected-warning@+1{{main actor-isolated conformance of 'RSendableSMainActor' to SendableMetatype-inheriting protocol 'R' can never be used with generic code}}
154+
// expected-error@+1{{cannot form main actor-isolated conformance of 'RSendableSMainActor' to SendableMetatype-inheriting protocol 'R'}}
155155
@MainActor struct RSendableSMainActor: @MainActor R {
156156
func f() { }
157157
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// RUN: %target-swift-frontend -typecheck -verify -target %target-swift-5.1-abi-triple -swift-version 6 %s
2+
3+
// REQUIRES: concurrency
4+
5+
protocol P: SendableMetatype {
6+
func f()
7+
}
8+
9+
@preconcurrency
10+
protocol Q: SendableMetatype {
11+
func f()
12+
}
13+
14+
// expected-error@+1{{cannot form main actor-isolated conformance of 'PSendableSMainActor' to SendableMetatype-inheriting protocol 'P'}}
15+
@MainActor struct PSendableSMainActor: @MainActor P {
16+
func f() { }
17+
}
18+
19+
// expected-warning@+1{{cannot form main actor-isolated conformance of 'QSendableSMainActor' to SendableMetatype-inheriting protocol 'Q'}}
20+
@MainActor struct QSendableSMainActor: @MainActor Q {
21+
func f() { }
22+
}

0 commit comments

Comments
 (0)