Skip to content

Commit 7c0bdff

Browse files
committed
Improve misleading diagnostics regarding implicit Sendable conformances
1 parent ba43a4d commit 7c0bdff

File tree

3 files changed

+25
-4
lines changed

3 files changed

+25
-4
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1923,6 +1923,12 @@ ERROR(type_cannot_conform, none,
19231923
NOTE(only_concrete_types_conform_to_protocols,none,
19241924
"only concrete types such as structs, enums and classes can conform to protocols",
19251925
())
1926+
NOTE(nonsendable_function_type,none,
1927+
"a function type must be marked '@Sendable' to conform to 'Sendable'", ())
1928+
NOTE(nonsendable_tuple_type,none,
1929+
"a tuple type must be composed of 'Sendable' elements to conform to "
1930+
"'Sendable'", ())
1931+
19261932
NOTE(required_by_opaque_return,none,
19271933
"required by opaque return type of %0 %1", (DescriptiveDeclKind, DeclName))
19281934
NOTE(required_by_decl,none,

lib/Sema/CSDiagnostics.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,21 @@ bool MissingConformanceFailure::diagnoseTypeCannotConform(
544544
nonConformingType->isEqual(protocolType),
545545
protocolType);
546546

547-
emitDiagnostic(diag::only_concrete_types_conform_to_protocols);
547+
bool emittedSpecializedNote = false;
548+
if (auto protoType = protocolType->getAs<ProtocolType>()) {
549+
if (protoType->getDecl()->isSpecificProtocol(KnownProtocolKind::Sendable)) {
550+
if (nonConformingType->is<FunctionType>()) {
551+
emitDiagnostic(diag::nonsendable_function_type);
552+
emittedSpecializedNote = true;
553+
} else if (nonConformingType->is<TupleType>()) {
554+
emitDiagnostic(diag::nonsendable_tuple_type);
555+
emittedSpecializedNote = true;
556+
}
557+
}
558+
}
559+
560+
if (!emittedSpecializedNote)
561+
emitDiagnostic(diag::only_concrete_types_conform_to_protocols);
548562

549563
if (auto *OTD = dyn_cast<OpaqueTypeDecl>(AffectedDecl)) {
550564
auto *namingDecl = OTD->getNamingDecl();

test/decl/protocol/special/Sendable.swift

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,12 @@ func testSendableBuiltinConformances(
2222
// Errors
2323
acceptSendable((i, ns)) // expected-error{{global function 'acceptSendable' requires that 'NotSendable' conform to 'Sendable'}}
2424
acceptSendable(nsf) // expected-error{{type '() -> Void' cannot conform to 'Sendable'}}
25-
// FIXME: expected-note@-1{{only concrete types such as structs, enums and classes can conform to protocols}}
25+
// expected-note@-1{{a function type must be marked '@Sendable' to conform to 'Sendable'}}
2626
acceptSendable((nsf, i)) // expected-error{{type '() -> Void' cannot conform to 'Sendable'}}
27-
// FIXME: expected-note@-1{{only concrete types such as structs, enums and classes can conform to protocols}}
27+
// expected-note@-1{{a function type must be marked '@Sendable' to conform to 'Sendable'}}
2828
// expected-note@-2{{requirement from conditional conformance of '(() -> Void, Int)' to 'Sendable'}}
2929
acceptSendable(funNotSendable) // expected-error{{type '() -> Void' cannot conform to 'Sendable'}}
30-
// FIXME: expected-note@-1{{only concrete types such as structs, enums and classes can conform to protocols}}
30+
// expected-note@-1{{a function type must be marked '@Sendable' to conform to 'Sendable'}}
3131
// expected-note@-2{{requirement from conditional conformance of '(Int, () -> Void, NotSendable.Type)' to 'Sendable'}}
32+
acceptSendable((i, ns)) // expected-error{{global function 'acceptSendable' requires that 'NotSendable' conform to 'Sendable'}}
3233
}

0 commit comments

Comments
 (0)