Skip to content

Commit 9ea735b

Browse files
committed
Rework diagnostics for conformance isolation failures
A protocol conformance can be ill-formed due to isolation mismatches between witnesses and requirements, or with associated conformances. Previously, such failures would be emitted as a number of separate errors (downgraded to warnings in Swift 5), one for each witness and potentially an extra for associated conformances. The rest was a potential flood of diagnostics that was hard to sort through. Collect all of the isolation-related problems for a given conformance together and produce a single error (downgraded to a warning when appropriate) that describes the overall issue. That error will have up to three notes suggesting specific courses of action: * Isolating the conformance (when the experimental feature is enabled) * Marking the witnesses as 'nonisolated' where needed * The diagnostic also has notes to point out the witnesses/associated conformances that have isolation problems. There is a new educational note that also describes these options. We give the same treatment to missing 'distributed' on witnesses to a distributed protocol.
1 parent 70bd52e commit 9ea735b

17 files changed

+415
-198
lines changed

include/swift/AST/ASTContextGlobalCache.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,7 @@ struct WitnessIsolationError {
4949
ActorIsolation referenceIsolation;
5050

5151
/// Diagnose this witness isolation error.
52-
void diagnose(const NormalProtocolConformance *conformance,
53-
bool &suggestedPreconcurrencyOrIsolated) const;
52+
void diagnose(const NormalProtocolConformance *conformance) const;
5453
};
5554

5655
/// Describes an isolation error involving an associated conformance.

include/swift/AST/DiagnosticsSema.def

+28-17
Original file line numberDiff line numberDiff line change
@@ -2734,8 +2734,6 @@ WARNING(add_predates_concurrency_import,none,
27342734
GROUPED_WARNING(remove_predates_concurrency_import,PreconcurrencyImport,
27352735
DefaultIgnore,
27362736
"'@preconcurrency' attribute on module %0 has no effect", (Identifier))
2737-
NOTE(add_preconcurrency_to_conformance,none,
2738-
"add '@preconcurrency' to the %0 conformance to defer isolation checking to run time", (DeclName))
27392737
WARNING(remove_public_import,none,
27402738
"public import of %0 was not used in public declarations or inlinable code",
27412739
(Identifier))
@@ -5435,11 +5433,7 @@ ERROR(async_in_nonasync_function,none,
54355433
(unsigned, bool))
54365434
NOTE(note_add_async_to_function,none,
54375435
"add 'async' to function %0 to make it asynchronous", (const ValueDecl *))
5438-
NOTE(note_add_nonisolated_to_decl,none,
5439-
"add 'nonisolated' to %0 to make this %kindonly0 not isolated to the actor",
5440-
(const ValueDecl *))
5441-
NOTE(note_add_distributed_to_decl,none,
5442-
"add 'distributed' to %0 to make this %kindonly0 satisfy the protocol requirement",
5436+
NOTE(note_non_distributed,none, "non-distributed %kind0",
54435437
(const ValueDecl *))
54445438
ERROR(invalid_isolated_calls_in_body,none,
54455439
"calls to '@%0'-isolated' code in %kind1",
@@ -5671,6 +5665,11 @@ ERROR(distributed_actor_func_unsupported_specifier, none,
56715665
ERROR(distributed_actor_func_variadic, none,
56725666
"cannot declare variadic argument %0 in %kind1",
56735667
(DeclName, const ValueDecl *))
5668+
ERROR(conformance_missing_distributed,none,
5669+
"conformance of %0 to distributed %kind1 uses non-distributed operations",
5670+
(Type, const ValueDecl *))
5671+
NOTE(note_add_distributed_multi,none,
5672+
"mark all declarations used in the conformance 'distributed'", ())
56745673
NOTE(actor_mutable_state,none,
56755674
"mutation of this %0 is only permitted within the actor",
56765675
(DescriptiveDeclKind))
@@ -5689,16 +5688,28 @@ NOTE(shared_state_make_immutable,none,
56895688
(const ValueDecl *))
56905689
NOTE(shared_state_nonisolated_unsafe,none,
56915690
"disable concurrency-safety checks if accesses are protected by an external synchronization mechanism", (const ValueDecl *))
5692-
ERROR(actor_isolated_witness,none,
5693-
"%select{|distributed }0%1 %kind2 cannot be used to satisfy %3 "
5694-
"requirement from protocol %base4",
5695-
(bool, ActorIsolation, const ValueDecl *, ActorIsolation,
5691+
NOTE(note_actor_isolated_witness,none,
5692+
"%0 %kind1 cannot be used to satisfy %2 "
5693+
"requirement from protocol %base3",
5694+
(ActorIsolation, const ValueDecl *, ActorIsolation,
56965695
const ValueDecl *))
56975696
ERROR(actor_cannot_conform_to_global_actor_protocol,none,
56985697
"actor %0 cannot conform to global actor isolated protocol %1",
56995698
(Type, Type))
57005699
NOTE(protocol_isolated_to_global_actor_here,none,
57015700
"%0 is isolated to global actor %1 here", (Type, Type))
5701+
ERROR(conformance_mismatched_isolation,none,
5702+
"conformance of %0 to %kind1 involves isolation mismatches "
5703+
"and can cause data races",
5704+
(Type, const ValueDecl *))
5705+
ERROR(conformance_mismatched_isolation_common,none,
5706+
"conformance of %0 to %kind1 crosses into %2 code and can cause "
5707+
"data races", (Type, const ValueDecl *, ActorIsolation))
5708+
NOTE(note_make_conformance_preconcurrency,none,
5709+
"turn data races into runtime errors with '@preconcurrency'",
5710+
())
5711+
NOTE(note_make_witnesses_nonisolated,none,
5712+
"mark all declarations used in the conformance 'nonisolated'", ())
57025713

57035714
ERROR(isolated_parameter_not_actor,none,
57045715
"'isolated' parameter type %0 does not conform to 'Actor' "
@@ -8318,15 +8329,15 @@ ERROR(attr_abi_incompatible_with_silgen_name,none,
83188329
ERROR(isolated_conformance_experimental_feature,none,
83198330
"isolated conformances require experimental feature "
83208331
" 'IsolatedConformances'", ())
8332+
NOTE(note_isolate_conformance_to_global_actor,none,
8333+
"isolate this conformance to the %select{global actor %0|main actor}1 "
8334+
"with '@%2'", (Type, bool, StringRef))
8335+
NOTE(note_depends_on_isolated_conformance,none,
8336+
"conformance depends on %0 conformance of %1 to %kind2",
8337+
(ActorIsolation, Type, const ValueDecl *))
83218338
ERROR(nonisolated_conformance_depends_on_isolated_conformance,none,
83228339
"conformance of %0 to %1 depends on %2 conformance of %3 to %4; mark it as '%5'",
83238340
(Type, DeclName, ActorIsolation, Type, DeclName, StringRef))
8324-
ERROR(isolated_conformance_mismatch_with_associated_isolation,none,
8325-
"%0 conformance of %1 to %2 cannot depend on %3 conformance of %4 to %5",
8326-
(ActorIsolation, Type, DeclName, ActorIsolation, Type, DeclName))
8327-
NOTE(add_isolated_to_conformance,none,
8328-
"add '%0' to the %1 conformance to restrict it to %2 code",
8329-
(StringRef, DeclName, ActorIsolation))
83308341
ERROR(isolated_conformance_with_sendable,none,
83318342
"%4 conformance of %0 to %1 cannot be used to satisfy conformance "
83328343
"requirement for a %select{`Sendable`|`SendableMetatype`}2 type "

include/swift/AST/EducationalNotes.def

+5
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,9 @@ EDUCATIONAL_NOTES(actor_isolated_call_decl,
107107
EDUCATIONAL_NOTES(error_in_swift_lang_mode,
108108
"error-in-future-swift-version.md")
109109

110+
EDUCATIONAL_NOTES(conformance_mismatched_isolation,
111+
"conformance-isolation.md")
112+
EDUCATIONAL_NOTES(conformance_mismatched_isolation_common,
113+
"conformance-isolation.md")
114+
110115
#undef EDUCATIONAL_NOTES

0 commit comments

Comments
 (0)