Skip to content

Commit 264099e

Browse files
committed
Improve misleading diagnostics regarding implicit Sendable conformances
(cherry picked from commit 7c0bdff)
1 parent 14e601e commit 264099e

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
@@ -1916,6 +1916,12 @@ ERROR(type_cannot_conform, none,
19161916
NOTE(only_concrete_types_conform_to_protocols,none,
19171917
"only concrete types such as structs, enums and classes can conform to protocols",
19181918
())
1919+
NOTE(nonsendable_function_type,none,
1920+
"a function type must be marked '@Sendable' to conform to 'Sendable'", ())
1921+
NOTE(nonsendable_tuple_type,none,
1922+
"a tuple type must be composed of 'Sendable' elements to conform to "
1923+
"'Sendable'", ())
1924+
19191925
NOTE(required_by_opaque_return,none,
19201926
"required by opaque return type of %0 %1", (DescriptiveDeclKind, DeclName))
19211927
NOTE(required_by_decl,none,

lib/Sema/CSDiagnostics.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,21 @@ bool MissingConformanceFailure::diagnoseTypeCannotConform(
533533
nonConformingType->isEqual(protocolType),
534534
protocolType);
535535

536-
emitDiagnostic(diag::only_concrete_types_conform_to_protocols);
536+
bool emittedSpecializedNote = false;
537+
if (auto protoType = protocolType->getAs<ProtocolType>()) {
538+
if (protoType->getDecl()->isSpecificProtocol(KnownProtocolKind::Sendable)) {
539+
if (nonConformingType->is<FunctionType>()) {
540+
emitDiagnostic(diag::nonsendable_function_type);
541+
emittedSpecializedNote = true;
542+
} else if (nonConformingType->is<TupleType>()) {
543+
emitDiagnostic(diag::nonsendable_tuple_type);
544+
emittedSpecializedNote = true;
545+
}
546+
}
547+
}
548+
549+
if (!emittedSpecializedNote)
550+
emitDiagnostic(diag::only_concrete_types_conform_to_protocols);
537551

538552
if (auto *OTD = dyn_cast<OpaqueTypeDecl>(AffectedDecl)) {
539553
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)