Skip to content

Commit 8fd02d7

Browse files
authored
Merge pull request #80190 from DougGregor/conformance-isolation-diagnostics
Rework diagnostics for conformance isolation failures
2 parents 8443b5f + 1b1f28d commit 8fd02d7

18 files changed

+565
-317
lines changed

include/swift/AST/ASTContextGlobalCache.h

+55-1
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,71 @@
1818
//===----------------------------------------------------------------------===//
1919

2020
#include "swift/AST/ASTContext.h"
21+
#include "swift/AST/ActorIsolation.h"
22+
#include <variant>
2123

2224
namespace swift {
2325

26+
class NormalProtocolConformance;
27+
class ValueDecl;
28+
29+
/// Describes an isolation error where the witness has actor isolation that
30+
/// conflicts with the requirement's expectation.
31+
struct WitnessIsolationError {
32+
/// The requirement declaration.
33+
ValueDecl *requirement;
34+
35+
/// The witness.
36+
ValueDecl *witness;
37+
38+
/// The pre-Swift-6 diagnostic behavior.
39+
DiagnosticBehavior behavior;
40+
41+
/// Whether the witness is missing "distributed".
42+
bool isMissingDistributed;
43+
44+
/// The isolation of the requirement, mapped into the conformance.
45+
ActorIsolation requirementIsolation;
46+
47+
/// The isolation domain that the witness would need to go into for it
48+
/// to be suitable for the requirement.
49+
ActorIsolation referenceIsolation;
50+
51+
/// Diagnose this witness isolation error.
52+
void diagnose(const NormalProtocolConformance *conformance) const;
53+
};
54+
55+
/// Describes an isolation error involving an associated conformance.
56+
struct AssociatedConformanceIsolationError {
57+
ProtocolConformance *isolatedConformance;
58+
59+
/// Diagnose this associated conformance isolation error.
60+
void diagnose(const NormalProtocolConformance *conformance) const;
61+
};
62+
63+
/// Describes an isolation error that occurred during conformance checking.
64+
using ConformanceIsolationError = std::variant<
65+
WitnessIsolationError, AssociatedConformanceIsolationError>;
66+
2467
/// A collection of side tables associated with the ASTContext itself, meant
25-
// as
68+
/// as a way to keep sparse information out of the AST nodes themselves and
69+
/// not require one to touch ASTContext.h to add such information.
2670
struct ASTContext::GlobalCache {
2771
/// Mapping from normal protocol conformances to the explicitly-specified
2872
/// global actor isolations, e.g., when the conformance was spelled
2973
/// `@MainActor P` or similar.
3074
llvm::DenseMap<const NormalProtocolConformance *, TypeExpr *>
3175
conformanceExplicitGlobalActorIsolation;
76+
77+
/// Mapping from normal protocol conformances to the set of actor isolation
78+
/// problems that occur within the conformances.
79+
///
80+
/// This map will be empty for well-formed code, and is used to accumulate
81+
/// information so that the diagnostics can be coalesced.
82+
llvm::DenseMap<
83+
const NormalProtocolConformance *,
84+
std::vector<ConformanceIsolationError>
85+
> conformanceIsolationErrors;
3286
};
3387

3488
} // end namespace

include/swift/AST/DiagnosticsSema.def

+29-26
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,6 @@ NOTE(opaque_return_type_declared_here,none,
4242
"opaque return type declared here", ())
4343
NOTE(default_value_declared_here,none,
4444
"default value declared here", ())
45-
NOTE(protocol_requirement_declared_here,none,
46-
"requirement %0 declared here", (const ValueDecl *))
4745

4846
//------------------------------------------------------------------------------
4947
// MARK: Constraint solver diagnostics
@@ -2743,8 +2741,6 @@ WARNING(add_predates_concurrency_import,none,
27432741
GROUPED_WARNING(remove_predates_concurrency_import,PreconcurrencyImport,
27442742
DefaultIgnore,
27452743
"'@preconcurrency' attribute on module %0 has no effect", (Identifier))
2746-
NOTE(add_preconcurrency_to_conformance,none,
2747-
"add '@preconcurrency' to the %0 conformance to defer isolation checking to run time", (DeclName))
27482744
WARNING(remove_public_import,none,
27492745
"public import of %0 was not used in public declarations or inlinable code",
27502746
(Identifier))
@@ -5444,15 +5440,7 @@ ERROR(async_in_nonasync_function,none,
54445440
(unsigned, bool))
54455441
NOTE(note_add_async_to_function,none,
54465442
"add 'async' to function %0 to make it asynchronous", (const ValueDecl *))
5447-
NOTE(note_add_nonisolated_to_decl,none,
5448-
"add 'nonisolated' to %0 to make this %kindonly0 not isolated to the actor",
5449-
(const ValueDecl *))
5450-
NOTE(note_add_async_and_throws_to_decl,none,
5451-
"mark the protocol requirement %0 '%select{|async|throws|async throws}1' "
5452-
"to allow actor-isolated conformances",
5453-
(const ValueDecl *, unsigned))
5454-
NOTE(note_add_distributed_to_decl,none,
5455-
"add 'distributed' to %0 to make this %kindonly0 satisfy the protocol requirement",
5443+
NOTE(note_non_distributed,none, "non-distributed %kind0",
54565444
(const ValueDecl *))
54575445
ERROR(invalid_isolated_calls_in_body,none,
54585446
"calls to '@%0'-isolated' code in %kind1",
@@ -5684,6 +5672,11 @@ ERROR(distributed_actor_func_unsupported_specifier, none,
56845672
ERROR(distributed_actor_func_variadic, none,
56855673
"cannot declare variadic argument %0 in %kind1",
56865674
(DeclName, const ValueDecl *))
5675+
ERROR(conformance_missing_distributed,none,
5676+
"conformance of %0 to distributed %kind1 uses non-distributed operations",
5677+
(Type, const ValueDecl *))
5678+
NOTE(note_add_distributed_multi,none,
5679+
"mark all declarations used in the conformance 'distributed'", ())
56875680
NOTE(actor_mutable_state,none,
56885681
"mutation of this %0 is only permitted within the actor",
56895682
(DescriptiveDeclKind))
@@ -5702,16 +5695,26 @@ NOTE(shared_state_make_immutable,none,
57025695
(const ValueDecl *))
57035696
NOTE(shared_state_nonisolated_unsafe,none,
57045697
"disable concurrency-safety checks if accesses are protected by an external synchronization mechanism", (const ValueDecl *))
5705-
ERROR(actor_isolated_witness,none,
5706-
"%select{|distributed }0%1 %kind2 cannot be used to satisfy %3 "
5707-
"requirement from protocol %base4",
5708-
(bool, ActorIsolation, const ValueDecl *, ActorIsolation,
5709-
const ValueDecl *))
5698+
NOTE(note_actor_isolated_witness,none,
5699+
"%0 %kind1 cannot satisfy %2 requirement",
5700+
(ActorIsolation, const ValueDecl *, ActorIsolation))
57105701
ERROR(actor_cannot_conform_to_global_actor_protocol,none,
57115702
"actor %0 cannot conform to global actor isolated protocol %1",
57125703
(Type, Type))
57135704
NOTE(protocol_isolated_to_global_actor_here,none,
57145705
"%0 is isolated to global actor %1 here", (Type, Type))
5706+
ERROR(conformance_mismatched_isolation,none,
5707+
"conformance of %0 to %kind1 involves isolation mismatches "
5708+
"and can cause data races",
5709+
(Type, const ValueDecl *))
5710+
ERROR(conformance_mismatched_isolation_common,none,
5711+
"conformance of %0 to %kind1 crosses into %2 code and can cause "
5712+
"data races", (Type, const ValueDecl *, ActorIsolation))
5713+
NOTE(note_make_conformance_preconcurrency,none,
5714+
"turn data races into runtime errors with '@preconcurrency'",
5715+
())
5716+
NOTE(note_make_witnesses_nonisolated,none,
5717+
"mark all declarations used in the conformance 'nonisolated'", ())
57155718

57165719
ERROR(isolated_parameter_not_actor,none,
57175720
"'isolated' parameter type %0 does not conform to 'Actor' "
@@ -8369,21 +8372,21 @@ ERROR(attr_abi_incompatible_with_silgen_name,none,
83698372
ERROR(isolated_conformance_experimental_feature,none,
83708373
"isolated conformances require experimental feature "
83718374
" 'IsolatedConformances'", ())
8375+
NOTE(note_isolate_conformance_to_global_actor,none,
8376+
"isolate this conformance to the %select{global actor %0|main actor}1 "
8377+
"with '@%2'", (Type, bool, StringRef))
8378+
NOTE(note_depends_on_isolated_conformance,none,
8379+
"conformance depends on %0 conformance of %1 to %kind2",
8380+
(ActorIsolation, Type, const ValueDecl *))
83728381
ERROR(nonisolated_conformance_depends_on_isolated_conformance,none,
83738382
"conformance of %0 to %1 depends on %2 conformance of %3 to %4; mark it as '%5'",
83748383
(Type, DeclName, ActorIsolation, Type, DeclName, StringRef))
8375-
ERROR(isolated_conformance_mismatch_with_associated_isolation,none,
8376-
"%0 conformance of %1 to %2 cannot depend on %3 conformance of %4 to %5",
8377-
(ActorIsolation, Type, DeclName, ActorIsolation, Type, DeclName))
8378-
NOTE(add_isolated_to_conformance,none,
8379-
"add '%0' to the %1 conformance to restrict it to %2 code",
8380-
(StringRef, DeclName, ActorIsolation))
83818384
ERROR(isolated_conformance_with_sendable,none,
8382-
"%4 conformance of %0 to %1 cannot be used to satisfy conformance "
8385+
"%4 conformance of %0 to %1 cannot satisfy conformance "
83838386
"requirement for a %select{`Sendable`|`SendableMetatype`}2 type "
83848387
"parameter %3", (Type, DeclName, bool, Type, ActorIsolation))
83858388
ERROR(isolated_conformance_with_sendable_simple,none,
8386-
"%2 conformance of %0 to %1 cannot be used to satisfy "
8389+
"%2 conformance of %0 to %1 cannot satisfy "
83878390
"conformance requirement for a `Sendable` type parameter ",
83888391
(Type, DeclName, ActorIsolation))
83898392
ERROR(isolated_conformance_wrong_domain,none,

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)