Skip to content

Commit c8f3524

Browse files
committed
[CSDiagnostics/Tests] Add tests for any Sendable vs. Any interaction in non-strict concurrency contexts
1 parent fb54682 commit c8f3524

File tree

3 files changed

+171
-0
lines changed

3 files changed

+171
-0
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2798,6 +2798,9 @@ ERROR(types_not_inherited_decl,none,
27982798
ERROR(types_not_inherited_in_decl_ref,none,
27992799
"referencing %kind0 on %1 requires that %2 inherit from %3",
28002800
(const ValueDecl *, Type, Type, Type))
2801+
ERROR(cannot_reference_conditional_member_on_base_multiple_mismatches,none,
2802+
"cannot reference %kind0 on %1",
2803+
(const ValueDecl *, Type))
28012804
NOTE(where_requirement_failure_one_subst,none,
28022805
"where %0 = %1", (Type, Type))
28032806
NOTE(where_requirement_failure_both_subst,none,

lib/Sema/CSDiagnostics.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,6 +1044,34 @@ bool GenericArgumentsMismatchFailure::diagnoseAsError() {
10441044
break;
10451045
}
10461046

1047+
case ConstraintLocator::Member: {
1048+
auto *memberLoc = getConstraintLocator(anchor, path);
1049+
auto selectedOverload = getOverloadChoiceIfAvailable(memberLoc);
1050+
if (!selectedOverload)
1051+
return false;
1052+
1053+
auto baseTy = selectedOverload->choice.getBaseType()->getRValueType();
1054+
auto *memberRef = selectedOverload->choice.getDecl();
1055+
1056+
if (Mismatches.size() == 1) {
1057+
auto mismatchIdx = Mismatches.front();
1058+
auto actualArgTy = getActual()->getGenericArgs()[mismatchIdx];
1059+
auto requiredArgTy = getRequired()->getGenericArgs()[mismatchIdx];
1060+
1061+
emitDiagnostic(diag::types_not_equal_in_decl_ref, memberRef, baseTy,
1062+
actualArgTy, requiredArgTy);
1063+
emitDiagnosticAt(memberRef, diag::decl_declared_here, memberRef);
1064+
return true;
1065+
}
1066+
1067+
emitDiagnostic(
1068+
diag::cannot_reference_conditional_member_on_base_multiple_mismatches,
1069+
memberRef, baseTy);
1070+
emitDiagnosticAt(memberRef, diag::decl_declared_here, memberRef);
1071+
emitNotesForMismatches();
1072+
return true;
1073+
}
1074+
10471075
default:
10481076
break;
10491077
}
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
// RUN: %target-typecheck-verify-swift
2+
// RUN: %target-typecheck-verify-swift -swift-version 5 -strict-concurrency=complete -verify-additional-prefix swift6-
3+
// RUN: %target-typecheck-verify-swift -swift-version 6 -verify-additional-prefix swift6-
4+
5+
class User {
6+
@preconcurrency var dict: [String : any Sendable] = [:]
7+
@preconcurrency var arr: [any Sendable] = []
8+
// Note: No Set because `any Sendable` is not Hashable
9+
}
10+
11+
extension Dictionary where Key == String, Value == Any {
12+
func onlyWhenValueAny() {} // expected-swift6-note {{'onlyWhenValueAny()' declared here}}
13+
}
14+
15+
extension Array where Element == Any {
16+
func onlyWhenValueAny() {} // expected-swift6-note {{'onlyWhenValueAny()' declared here}}
17+
}
18+
19+
func test_conditional_on_collections(u: User) {
20+
u.dict.onlyWhenValueAny() // Ok with non-strict concurrency
21+
// expected-swift6-error@-1 {{referencing instance method 'onlyWhenValueAny()' on '[String : any Sendable]' requires the types 'any Sendable' and 'Any' be equivalent}}
22+
u.arr.onlyWhenValueAny() // Ok with non-strict concurrency
23+
// expected-swift6-error@-1 {{referencing instance method 'onlyWhenValueAny()' on '[any Sendable]' requires the types 'any Sendable' and 'Any' be equivalent}}
24+
}
25+
26+
// Check that `any Sendable` extension is preferred.
27+
28+
extension Dictionary where Key == String, Value == Any {
29+
func noAmbiguity() {}
30+
}
31+
32+
extension Array where Element == Any {
33+
func noAmbiguity() {}
34+
}
35+
36+
extension Dictionary where Key == String, Value == any Sendable {
37+
func noAmbiguity() {}
38+
}
39+
40+
extension Array where Element == any Sendable {
41+
func noAmbiguity() {}
42+
}
43+
44+
func test_no_ambiguity_with_Sendable_extension(u: User) {
45+
u.dict.noAmbiguity() // Ok in general
46+
u.arr.noAmbiguity() // Ok in general
47+
}
48+
49+
struct S<T> {
50+
// expected-note@-1 3 {{arguments to generic parameter 'T' ('any Sendable' and 'Any') are expected to be equal}}
51+
// expected-note@-2 4 {{arguments to generic parameter 'T' ('(any Sendable) -> Void' and '(Any) -> Void') are expected to be equal}}
52+
// expected-swift6-note@-3 3 {{arguments to generic parameter 'T' ('any Sendable' and 'Any') are expected to be equal}}
53+
}
54+
55+
extension S where T == Any {
56+
func anyOnly() {} // expected-note {{'anyOnly()' declared here}} expected-swift6-note {{'anyOnly()' declared here}}
57+
}
58+
59+
struct TestGeneral {
60+
@preconcurrency var v: S<any Sendable>
61+
@preconcurrency var optV: S<[(any Sendable)?]>
62+
@preconcurrency var nonOptV: S<[any Sendable]>
63+
@preconcurrency var funcV: S<((any Sendable)) -> Void>
64+
65+
var regularV: S<any Sendable>
66+
var regularOptV: S<[(any Sendable)?]>
67+
var regularFuncV: S<((any Sendable)) -> Void>
68+
69+
func accepts_any(_: S<Any>) {}
70+
func accepts_opt_any(_: S<[Any?]>) {}
71+
func accepts_func_any(_: S<(Any) -> Void>) {}
72+
73+
func test_contextual() -> S<Any> {
74+
v // Ok with non-strict concurrency
75+
// expected-swift6-error@-1 {{cannot convert return expression of type 'S<any Sendable>' to return type 'S<Any>'}}
76+
}
77+
78+
func test_contextual_error() -> S<Any> {
79+
regularV // expected-error {{cannot convert return expression of type 'S<any Sendable>' to return type 'S<Any>'}}
80+
}
81+
82+
func test_member_ref() {
83+
v.anyOnly() // Ok with non-strict concurrency
84+
// expected-swift6-error@-1 {{referencing instance method 'anyOnly()' on 'S<any Sendable>' requires the types 'any Sendable' and 'Any' be equivalent}}
85+
regularV.anyOnly()
86+
// expected-error@-1 {{referencing instance method 'anyOnly()' on 'S<any Sendable>' requires the types 'any Sendable' and 'Any' be equivalent}}
87+
}
88+
89+
func test_passing_as_argument(t: TestGeneral) {
90+
accepts_any(v) // Ok with non-strict concurrency
91+
// expected-swift6-error@-1 {{cannot convert value of type 'S<any Sendable>' to expected argument type 'S<Any>'}}
92+
accepts_any(t.v) // Ok with non-strict concurrency
93+
// expected-swift6-error@-1 {{cannot convert value of type 'S<any Sendable>' to expected argument type 'S<Any>'}}
94+
95+
accepts_any(regularV) // expected-error {{cannot convert value of type 'S<any Sendable>' to expected argument type 'S<Any>'}}
96+
accepts_any(t.regularV) // expected-error {{cannot convert value of type 'S<any Sendable>' to expected argument type 'S<Any>'}}
97+
}
98+
99+
func test_complex_contextual() -> S<[Any?]> {
100+
optV // Ok with non-strict concurrency
101+
// expected-swift6-error@-1 {{cannot convert return expression of type 'S<[(any Sendable)?]>' to return type 'S<[Any?]>'}}
102+
// expected-swift6-note@-2 {{arguments to generic parameter 'Wrapped' ('any Sendable' and 'Any') are expected to be equal}}
103+
}
104+
105+
func test_complex_contextual_error() {
106+
let _: S<[Any?]> = optV // Ok with non-strict concurrency
107+
// expected-swift6-error@-1 {{cannot assign value of type 'S<[(any Sendable)?]>' to type 'S<[Any?]>'}}
108+
// expected-swift6-note@-2 {{arguments to generic parameter 'Wrapped' ('any Sendable' and 'Any') are expected to be equal}}
109+
let _: S<[Any?]> = nonOptV // expected-error {{cannot assign value of type 'S<[any Sendable]>' to type 'S<[Any?]>'}}
110+
// expected-note@-1 {{arguments to generic parameter 'Element' ('any Sendable' and 'Any?') are expected to be equal}}
111+
let _: S<[Any?]> = regularOptV // expected-error {{cannot assign value of type 'S<[(any Sendable)?]>' to type 'S<[Any?]>'}}
112+
// expected-note@-1 {{arguments to generic parameter 'Wrapped' ('any Sendable' and 'Any') are expected to be equal}}
113+
}
114+
115+
func test_complex_with_argument(t: TestGeneral) {
116+
accepts_opt_any(optV) // Ok with non-strict concurrency
117+
// expected-swift6-error@-1 {{cannot convert value of type 'S<[(any Sendable)?]>' to expected argument type 'S<[Any?]>'}}
118+
// expected-swift6-note@-2 {{arguments to generic parameter 'Wrapped' ('any Sendable' and 'Any') are expected to be equal}}
119+
accepts_opt_any(t.optV) // Ok with non-strict concurrency
120+
// expected-swift6-error@-1 {{cannot convert value of type 'S<[(any Sendable)?]>' to expected argument type 'S<[Any?]>'}}
121+
// expected-swift6-note@-2 {{arguments to generic parameter 'Wrapped' ('any Sendable' and 'Any') are expected to be equal}}
122+
123+
accepts_opt_any(nonOptV) // expected-error {{cannot convert value of type 'S<[any Sendable]>' to expected argument type 'S<[Any?]>'}}
124+
// expected-note@-1 {{arguments to generic parameter 'Element' ('any Sendable' and 'Any?') are expected to be equal}}
125+
accepts_opt_any(t.nonOptV) // expected-error {{cannot convert value of type 'S<[any Sendable]>' to expected argument type 'S<[Any?]>'}}
126+
// expected-note@-1 {{arguments to generic parameter 'Element' ('any Sendable' and 'Any?') are expected to be equal}}
127+
accepts_opt_any(regularOptV) // expected-error {{cannot convert value of type 'S<[(any Sendable)?]>' to expected argument type 'S<[Any?]>'}}
128+
// expected-note@-1 {{arguments to generic parameter 'Wrapped' ('any Sendable' and 'Any') are expected to be equal}}
129+
}
130+
131+
func test_no_function_conversions() {
132+
let _: S<(Any) -> Void> = funcV // expected-error {{cannot assign value of type 'S<(any Sendable) -> Void>' to type 'S<(Any) -> Void>'}}
133+
let _: S<(Any) -> Void> = regularFuncV // expected-error {{cannot assign value of type 'S<(any Sendable) -> Void>' to type 'S<(Any) -> Void>'}}
134+
135+
accepts_func_any(funcV)
136+
// expected-error@-1 {{cannot convert value of type 'S<(any Sendable) -> Void>' to expected argument type 'S<(Any) -> Void>'}}
137+
accepts_func_any(regularFuncV)
138+
// expected-error@-1 {{cannot convert value of type 'S<(any Sendable) -> Void>' to expected argument type 'S<(Any) -> Void>'}}
139+
}
140+
}

0 commit comments

Comments
 (0)