Skip to content

Commit e21bf2f

Browse files
committed
[Concurrency] Downgrade @preconcurrency conformance requirement failures to
warnings in Swift 6 mode.
1 parent a31a9d3 commit e21bf2f

6 files changed

+49
-18
lines changed

lib/Sema/TypeCheckAvailability.cpp

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ static bool diagnoseSubstitutionMapAvailability(
6666
SourceLoc loc, SubstitutionMap subs, const ExportContext &where,
6767
Type depTy = Type(), Type replacementTy = Type(),
6868
bool warnIfConformanceUnavailablePreSwift6 = false,
69-
bool suppressParameterizationCheckForOptional = false);
69+
bool suppressParameterizationCheckForOptional = false,
70+
bool preconcurrency = false);
7071

7172
/// Diagnose uses of unavailable declarations in types.
7273
static bool
@@ -3990,8 +3991,12 @@ bool ExprAvailabilityWalker::diagnoseDeclRefAvailability(
39903991
}
39913992

39923993
if (R.isValid()) {
3993-
if (diagnoseSubstitutionMapAvailability(R.Start, declRef.getSubstitutions(),
3994-
Where)) {
3994+
if (diagnoseSubstitutionMapAvailability(
3995+
R.Start, declRef.getSubstitutions(), Where,
3996+
Type(), Type(),
3997+
/*warnIfConformanceUnavailablePreSwift6*/false,
3998+
/*suppressParameterizationCheckForOptional*/false,
3999+
/*preconcurrency*/D->preconcurrency())) {
39954000
return true;
39964001
}
39974002
}
@@ -4489,7 +4494,8 @@ class ProblematicTypeFinder : public TypeDeclFinder {
44894494
/*depTy=*/Type(),
44904495
/*replacementTy=*/Type(),
44914496
/*warnIfConformanceUnavailablePreSwift6=*/false,
4492-
/*suppressParameterizationCheckForOptional=*/ty->isOptional());
4497+
/*suppressParameterizationCheckForOptional=*/ty->isOptional(),
4498+
/*preconcurrency*/ty->getAnyNominal()->preconcurrency());
44934499
return Action::Continue;
44944500
}
44954501

@@ -4539,17 +4545,19 @@ void swift::diagnoseTypeAvailability(const TypeRepr *TR, Type T, SourceLoc loc,
45394545
}
45404546

45414547
static void diagnoseMissingConformance(
4542-
SourceLoc loc, Type type, ProtocolDecl *proto, const DeclContext *fromDC) {
4548+
SourceLoc loc, Type type, ProtocolDecl *proto, const DeclContext *fromDC,
4549+
bool preconcurrency) {
45434550
assert(proto->isSpecificProtocol(KnownProtocolKind::Sendable));
4544-
diagnoseMissingSendableConformance(loc, type, fromDC);
4551+
diagnoseMissingSendableConformance(loc, type, fromDC, preconcurrency);
45454552
}
45464553

45474554
bool
45484555
swift::diagnoseConformanceAvailability(SourceLoc loc,
45494556
ProtocolConformanceRef conformance,
45504557
const ExportContext &where,
45514558
Type depTy, Type replacementTy,
4552-
bool warnIfConformanceUnavailablePreSwift6) {
4559+
bool warnIfConformanceUnavailablePreSwift6,
4560+
bool preconcurrency) {
45534561
assert(!where.isImplicit());
45544562

45554563
if (conformance.isInvalid() || conformance.isAbstract())
@@ -4561,7 +4569,8 @@ swift::diagnoseConformanceAvailability(SourceLoc loc,
45614569
for (auto patternConf : pack->getPatternConformances()) {
45624570
diagnosed |= diagnoseConformanceAvailability(
45634571
loc, patternConf, where, depTy, replacementTy,
4564-
warnIfConformanceUnavailablePreSwift6);
4572+
warnIfConformanceUnavailablePreSwift6,
4573+
preconcurrency);
45654574
}
45664575
return diagnosed;
45674576
}
@@ -4581,7 +4590,8 @@ swift::diagnoseConformanceAvailability(SourceLoc loc,
45814590
if (auto builtinConformance = dyn_cast<BuiltinProtocolConformance>(rootConf)){
45824591
if (builtinConformance->isMissing()) {
45834592
diagnoseMissingConformance(loc, builtinConformance->getType(),
4584-
builtinConformance->getProtocol(), DC);
4593+
builtinConformance->getProtocol(), DC,
4594+
preconcurrency);
45854595
}
45864596
}
45874597

@@ -4640,7 +4650,8 @@ swift::diagnoseConformanceAvailability(SourceLoc loc,
46404650
SubstitutionMap subConformanceSubs = concreteConf->getSubstitutionMap();
46414651
if (diagnoseSubstitutionMapAvailability(loc, subConformanceSubs, where,
46424652
depTy, replacementTy,
4643-
warnIfConformanceUnavailablePreSwift6))
4653+
warnIfConformanceUnavailablePreSwift6,
4654+
preconcurrency))
46444655
return true;
46454656

46464657
return false;
@@ -4649,12 +4660,14 @@ swift::diagnoseConformanceAvailability(SourceLoc loc,
46494660
bool diagnoseSubstitutionMapAvailability(
46504661
SourceLoc loc, SubstitutionMap subs, const ExportContext &where, Type depTy,
46514662
Type replacementTy, bool warnIfConformanceUnavailablePreSwift6,
4652-
bool suppressParameterizationCheckForOptional) {
4663+
bool suppressParameterizationCheckForOptional,
4664+
bool preconcurrency) {
46534665
bool hadAnyIssues = false;
46544666
for (ProtocolConformanceRef conformance : subs.getConformances()) {
46554667
if (diagnoseConformanceAvailability(loc, conformance, where,
46564668
depTy, replacementTy,
4657-
warnIfConformanceUnavailablePreSwift6))
4669+
warnIfConformanceUnavailablePreSwift6,
4670+
preconcurrency))
46584671
hadAnyIssues = true;
46594672
}
46604673

lib/Sema/TypeCheckAvailability.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,8 @@ diagnoseConformanceAvailability(SourceLoc loc,
230230
const ExportContext &context,
231231
Type depTy=Type(),
232232
Type replacementTy=Type(),
233-
bool warnIfConformanceUnavailablePreSwift6 = false);
233+
bool warnIfConformanceUnavailablePreSwift6 = false,
234+
bool preconcurrency = false);
234235

235236
/// Diagnose uses of unavailable declarations. Returns true if a diagnostic
236237
/// was emitted.

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1237,9 +1237,10 @@ bool swift::diagnoseNonSendableTypesInReference(
12371237
}
12381238

12391239
void swift::diagnoseMissingSendableConformance(
1240-
SourceLoc loc, Type type, const DeclContext *fromDC) {
1240+
SourceLoc loc, Type type, const DeclContext *fromDC, bool preconcurrency) {
1241+
SendableCheckContext sendableContext(fromDC, preconcurrency);
12411242
diagnoseNonSendableTypes(
1242-
type, fromDC, /*inDerivedConformance*/Type(),
1243+
type, sendableContext, /*inDerivedConformance*/Type(),
12431244
loc, diag::non_sendable_type);
12441245
}
12451246

lib/Sema/TypeCheckConcurrency.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ bool diagnoseNonSendableTypesInReference(
324324

325325
/// Produce a diagnostic for a missing conformance to Sendable.
326326
void diagnoseMissingSendableConformance(
327-
SourceLoc loc, Type type, const DeclContext *fromDC);
327+
SourceLoc loc, Type type, const DeclContext *fromDC, bool preconcurrency);
328328

329329
/// If the given nominal type is public and does not explicitly
330330
/// state whether it conforms to Sendable, provide a diagnostic.

test/Concurrency/predates_concurrency_swift6.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,3 +191,19 @@ func conversionDowngrade() {
191191
withSendableClosure(ns)
192192
// expected-warning@-1 {{converting non-sendable function value to '@Sendable () -> Void' may introduce data races}}
193193
}
194+
195+
@preconcurrency
196+
func requireSendable<T: Sendable>(_: T) {}
197+
198+
@preconcurrency
199+
struct RequireSendable<T: Sendable> {}
200+
201+
class NotSendable {} // expected-note 2 {{class 'NotSendable' does not conform to the 'Sendable' protocol}}
202+
203+
typealias T = RequireSendable<NotSendable>
204+
// expected-warning@-1 {{type 'NotSendable' does not conform to the 'Sendable' protocol}}
205+
206+
func testRequirementDowngrade(ns: NotSendable) {
207+
requireSendable(ns)
208+
// expected-warning@-1 {{type 'NotSendable' does not conform to the 'Sendable' protocol}}
209+
}

test/Concurrency/sendable_objc_attr_in_type_context_swift6.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,13 +116,13 @@ func test_sendable_attr_in_type_context(test: Test) {
116116

117117
// TODO(diagnostics): Duplicate diagnostics
118118
TestWithSendableID().add(MyValue())
119-
// expected-error@-1 3 {{type 'MyValue' does not conform to the 'Sendable' protocol}}
119+
// expected-warning@-1 3 {{type 'MyValue' does not conform to the 'Sendable' protocol}}
120120

121121
TestWithSendableSuperclass().add(SendableMyValue()) // Ok
122122

123123
// TODO(diagnostics): Duplicate diagnostics
124124
TestWithSendableSuperclass().add(MyValue())
125-
// expected-error@-1 3 {{type 'MyValue' does not conform to the 'Sendable' protocol}}
125+
// expected-warning@-1 3 {{type 'MyValue' does not conform to the 'Sendable' protocol}}
126126
}
127127

128128
class TestConformanceWithStripping : InnerSendableTypes {

0 commit comments

Comments
 (0)