Skip to content

Commit 9213d0b

Browse files
authored
Merge pull request #42607 from DougGregor/existential-sendable-warnings-5.7-04182022
2 parents 6600e5c + 8c71843 commit 9213d0b

File tree

6 files changed

+84
-15
lines changed

6 files changed

+84
-15
lines changed

lib/Sema/CSApply.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5433,7 +5433,7 @@ collectExistentialConformances(Type fromType, Type toType,
54335433
SmallVector<ProtocolConformanceRef, 4> conformances;
54345434
for (auto proto : layout.getProtocols()) {
54355435
conformances.push_back(TypeChecker::containsProtocol(
5436-
fromType, proto, module));
5436+
fromType, proto, module, false, /*allowMissing=*/true));
54375437
}
54385438

54395439
return toType->getASTContext().AllocateCopy(conformances);

lib/Sema/CSSimplify.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7108,7 +7108,8 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint(
71087108
case ConstraintKind::SelfObjectOfProtocol: {
71097109
auto conformance = TypeChecker::containsProtocol(
71107110
type, protocol, DC->getParentModule(),
7111-
/*skipConditionalRequirements=*/true);
7111+
/*skipConditionalRequirements=*/true,
7112+
/*allowMissing=*/true);
71127113
if (conformance) {
71137114
return recordConformance(conformance);
71147115
}

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5672,7 +5672,8 @@ void ConformanceChecker::emitDelayedDiags() {
56725672

56735673
ProtocolConformanceRef
56745674
TypeChecker::containsProtocol(Type T, ProtocolDecl *Proto, ModuleDecl *M,
5675-
bool skipConditionalRequirements) {
5675+
bool skipConditionalRequirements,
5676+
bool allowMissing) {
56765677
// Existential types don't need to conform, i.e., they only need to
56775678
// contain the protocol.
56785679
if (T->isExistentialType()) {
@@ -5694,8 +5695,9 @@ TypeChecker::containsProtocol(Type T, ProtocolDecl *Proto, ModuleDecl *M,
56945695
if (auto superclass = layout.getSuperclass()) {
56955696
auto result =
56965697
(skipConditionalRequirements
5697-
? M->lookupConformance(superclass, Proto)
5698-
: TypeChecker::conformsToProtocol(superclass, Proto, M));
5698+
? M->lookupConformance(superclass, Proto, allowMissing)
5699+
: TypeChecker::conformsToProtocol(
5700+
superclass, Proto, M, allowMissing));
56995701
if (result) {
57005702
return result;
57015703
}
@@ -5713,13 +5715,22 @@ TypeChecker::containsProtocol(Type T, ProtocolDecl *Proto, ModuleDecl *M,
57135715
return ProtocolConformanceRef(Proto);
57145716
}
57155717

5718+
// FIXME: Unify with shouldCreateMissingConformances
5719+
if (allowMissing &&
5720+
Proto->isSpecificProtocol(KnownProtocolKind::Sendable)) {
5721+
return ProtocolConformanceRef(
5722+
M->getASTContext().getBuiltinConformance(
5723+
T, Proto, GenericSignature(), { },
5724+
BuiltinConformanceKind::Missing));
5725+
}
5726+
57165727
return ProtocolConformanceRef::forInvalid();
57175728
}
57185729

57195730
// For non-existential types, this is equivalent to checking conformance.
57205731
return (skipConditionalRequirements
5721-
? M->lookupConformance(T, Proto)
5722-
: TypeChecker::conformsToProtocol(T, Proto, M));
5732+
? M->lookupConformance(T, Proto, allowMissing)
5733+
: TypeChecker::conformsToProtocol(T, Proto, M, allowMissing));
57235734
}
57245735

57255736
ProtocolConformanceRef

lib/Sema/TypeChecker.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -791,7 +791,8 @@ Expr *addImplicitLoadExpr(
791791
/// an empty optional.
792792
ProtocolConformanceRef containsProtocol(Type T, ProtocolDecl *Proto,
793793
ModuleDecl *M,
794-
bool skipConditionalRequirements=false);
794+
bool skipConditionalRequirements=false,
795+
bool allowMissing=false);
795796

796797
/// Determine whether the given type conforms to the given protocol.
797798
///

test/ClangImporter/objc_async.swift

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
// REQUIRES: concurrency
55
import Foundation
66
import ObjCConcurrency
7+
// expected-remark@-1{{add '@preconcurrency' to suppress 'Sendable'-related warnings from module 'ObjCConcurrency'}}
78

89
@available(SwiftStdlib 5.5, *)
910
@MainActor func onlyOnMainActor() { }
@@ -322,6 +323,7 @@ func check() async {
322323
_ = await BazFrame(size: 0)
323324
}
324325

326+
@available(SwiftStdlib 5.5, *)
325327
func testSender(
326328
sender: NXSender,
327329
sendableObject: SendableClass,
@@ -333,7 +335,7 @@ func testSender(
333335
nonSendableGeneric: GenericObject<SendableClass>,
334336
ptr: UnsafeMutableRawPointer,
335337
stringArray: [String]
336-
) {
338+
) async {
337339
sender.sendAny(sendableObject)
338340
sender.sendAny(nonSendableObject)
339341
// expected-warning@-1 {{conformance of 'NonSendableClass' to 'Sendable' is unavailable}}
@@ -352,22 +354,22 @@ func testSender(
352354

353355
sender.sendProto(sendableProtos)
354356
sender.sendProto(nonSendableProtos)
355-
// expected-error@-1 {{argument type 'any LabellyProtocol & ObjCClub' does not conform to expected type 'Sendable'}}
356-
// FIXME(rdar://89992095): Should be a warning because we're in -warn-concurrency
357+
// expected-warning@-1 {{type 'any LabellyProtocol & ObjCClub' does not conform to the 'Sendable' protocol}}
357358

358359
sender.sendProtos(sendableProtos)
359360
sender.sendProtos(nonSendableProtos)
360-
// expected-error@-1 {{argument type 'any LabellyProtocol & ObjCClub' does not conform to expected type 'Sendable'}}
361-
// FIXME(rdar://89992095): Should be a warning because we're in -warn-concurrency
361+
// expected-warning@-1 {{type 'any LabellyProtocol & ObjCClub' does not conform to the 'Sendable' protocol}}
362362

363363
sender.sendAnyArray([sendableObject])
364364
sender.sendAnyArray([nonSendableObject])
365365
// expected-warning@-1 {{conformance of 'NonSendableClass' to 'Sendable' is unavailable}}
366366

367367
sender.sendGeneric(sendableGeneric)
368+
// expected-warning@-1{{type 'GenericObject<SendableClass>' does not conform to the 'Sendable' protocol}}
369+
// FIXME: Shouldn't warn
370+
368371
sender.sendGeneric(nonSendableGeneric)
369-
// expected-error@-1 {{argument type 'GenericObject<SendableClass>' does not conform to expected type 'Sendable'}}
370-
// FIXME(rdar://89992095): Should be a warning because we're in -warn-concurrency
372+
// expected-warning@-1 {{type 'GenericObject<SendableClass>' does not conform to the 'Sendable' protocol}}
371373

372374
sender.sendPtr(ptr)
373375
sender.sendStringArray(stringArray)
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// RUN: %target-typecheck-verify-swift -strict-concurrency=targeted
2+
// REQUIRES: concurrency
3+
// REQUIRES: OS=macosx
4+
5+
@preconcurrency func send(_: Sendable) { }
6+
func sendOpt(_: Sendable?) { }
7+
8+
enum E {
9+
case something(Sendable)
10+
}
11+
12+
@available(SwiftStdlib 5.1, *)
13+
func testE(a: Any, aOpt: Any?) async {
14+
send(a) // expected-warning{{type 'Any' does not conform to the 'Sendable' protocol}}
15+
sendOpt(a) // expected-warning{{type 'Any' does not conform to the 'Sendable' protocol}}
16+
sendOpt(aOpt) // expected-warning{{type 'Any' does not conform to the 'Sendable' protocol}}
17+
18+
let _: E = .something(a) // expected-warning{{type 'Any' does not conform to the 'Sendable' protocol}}
19+
_ = E.something(a) // expected-warning{{type 'Any' does not conform to the 'Sendable' protocol}}
20+
21+
var sendable: Sendable
22+
sendable = a // expected-warning{{type 'Any' does not conform to the 'Sendable' protocol}}
23+
24+
var arrayOfSendable: [Sendable]
25+
arrayOfSendable = [a, a] // expected-warning 2{{type 'Any' does not conform to the 'Sendable' protocol}}
26+
27+
func localFunc() { }
28+
sendable = localFunc // expected-warning{{type '() -> ()' does not conform to the 'Sendable' protocol}}
29+
// expected-note@-1{{a function type must be marked '@Sendable' to conform to 'Sendable'}}
30+
31+
_ = sendable
32+
_ = arrayOfSendable
33+
}
34+
35+
func testESilently(a: Any, aOpt: Any?) {
36+
send(a)
37+
sendOpt(a)
38+
sendOpt(aOpt)
39+
40+
let _: E = .something(a)
41+
_ = E.something(a)
42+
43+
var sendable: Sendable
44+
sendable = a
45+
46+
var arrayOfSendable: [Sendable]
47+
arrayOfSendable = [a, a]
48+
49+
func localFunc() { }
50+
sendable = localFunc
51+
52+
_ = sendable
53+
_ = arrayOfSendable
54+
}

0 commit comments

Comments
 (0)