Skip to content

Commit 232d94c

Browse files
Merge pull request #65320 from AnthonyLatsis/revert-f608802cfe498b8684e4ea63603fe99073102ce6-5.8
[5.8 🍒] Revert "Sema: Emit diagnostics when walking into collection literals with defaulted types"
2 parents 399457f + 8c3b35d commit 232d94c

10 files changed

+35
-83
lines changed

lib/Sema/MiscDiagnostics.cpp

Lines changed: 28 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -110,15 +110,13 @@ static void diagSyntacticUseRestrictions(const Expr *E, const DeclContext *DC,
110110
SmallPtrSet<DeclRefExpr*, 4> AlreadyDiagnosedBitCasts;
111111

112112
bool IsExprStmt;
113-
bool HasReachedSemanticsProvidingExpr;
114113

115114
ASTContext &Ctx;
116115
const DeclContext *DC;
117116

118117
public:
119118
DiagnoseWalker(const DeclContext *DC, bool isExprStmt)
120-
: IsExprStmt(isExprStmt), HasReachedSemanticsProvidingExpr(false),
121-
Ctx(DC->getASTContext()), DC(DC) {}
119+
: IsExprStmt(isExprStmt), Ctx(DC->getASTContext()), DC(DC) {}
122120

123121
PreWalkResult<Pattern *> walkToPatternPre(Pattern *P) override {
124122
return Action::SkipChildren(P);
@@ -133,16 +131,6 @@ static void diagSyntacticUseRestrictions(const Expr *E, const DeclContext *DC,
133131
bool shouldWalkIntoTapExpression() override { return false; }
134132

135133
PreWalkResult<Expr *> walkToExprPre(Expr *E) override {
136-
if (auto collection = dyn_cast<CollectionExpr>(E)) {
137-
if (collection->isTypeDefaulted()) {
138-
// Diagnose type defaulted collection literals in subexpressions as
139-
// warnings to preserve source compatibility.
140-
diagnoseTypeDefaultedCollectionExpr(
141-
collection, Ctx,
142-
/*downgradeToWarning=*/HasReachedSemanticsProvidingExpr);
143-
}
144-
}
145-
146134
// See through implicit conversions of the expression. We want to be able
147135
// to associate the parent of this expression with the ultimate callee.
148136
auto Base = E;
@@ -345,11 +333,6 @@ static void diagSyntacticUseRestrictions(const Expr *E, const DeclContext *DC,
345333
checkMoveExpr(moveExpr);
346334
}
347335

348-
if (!HasReachedSemanticsProvidingExpr &&
349-
E == E->getSemanticsProvidingExpr()) {
350-
HasReachedSemanticsProvidingExpr = true;
351-
}
352-
353336
return Action::Continue(E);
354337
}
355338

@@ -472,34 +455,25 @@ static void diagSyntacticUseRestrictions(const Expr *E, const DeclContext *DC,
472455
return false;
473456
}
474457

475-
/// Diagnose a collection literal with a defaulted type such as \c [Any].
476-
static void diagnoseTypeDefaultedCollectionExpr(CollectionExpr *c,
477-
ASTContext &ctx,
478-
bool downgradeToWarning) {
479-
// Produce a diagnostic with a fixit to add the defaulted type as an
480-
// explicit annotation.
481-
auto &diags = ctx.Diags;
482-
483-
if (c->getNumElements() == 0) {
484-
InFlightDiagnostic inFlight =
485-
diags.diagnose(c->getLoc(), diag::collection_literal_empty);
486-
inFlight.highlight(c->getSourceRange());
487-
488-
if (downgradeToWarning) {
489-
inFlight.limitBehavior(DiagnosticBehavior::Warning);
490-
}
491-
} else {
458+
/// We have a collection literal with a defaulted type, e.g. of [Any]. Emit
459+
/// an error if it was inferred to this type in an invalid context, which is
460+
/// one in which the parent expression is not itself a collection literal.
461+
void checkTypeDefaultedCollectionExpr(CollectionExpr *c) {
462+
// If the parent is a non-expression, or is not itself a literal, then
463+
// produce an error with a fixit to add the type as an explicit
464+
// annotation.
465+
if (c->getNumElements() == 0)
466+
Ctx.Diags.diagnose(c->getLoc(), diag::collection_literal_empty)
467+
.highlight(c->getSourceRange());
468+
else {
492469
assert(c->getType()->hasTypeRepr() &&
493470
"a defaulted type should always be printable");
494-
InFlightDiagnostic inFlight = diags.diagnose(
495-
c->getLoc(), diag::collection_literal_heterogeneous, c->getType());
496-
inFlight.highlight(c->getSourceRange());
497-
inFlight.fixItInsertAfter(c->getEndLoc(),
498-
" as " + c->getType()->getString());
499-
500-
if (downgradeToWarning) {
501-
inFlight.limitBehavior(DiagnosticBehavior::Warning);
502-
}
471+
Ctx.Diags
472+
.diagnose(c->getLoc(), diag::collection_literal_heterogeneous,
473+
c->getType())
474+
.highlight(c->getSourceRange())
475+
.fixItInsertAfter(c->getEndLoc(),
476+
" as " + c->getType()->getString());
503477
}
504478
}
505479

@@ -1374,6 +1348,16 @@ static void diagSyntacticUseRestrictions(const Expr *E, const DeclContext *DC,
13741348

13751349
DiagnoseWalker Walker(DC, isExprStmt);
13761350
const_cast<Expr *>(E)->walk(Walker);
1351+
1352+
// Diagnose uses of collection literals with defaulted types at the top
1353+
// level.
1354+
if (auto collection =
1355+
dyn_cast<CollectionExpr>(E->getSemanticsProvidingExpr())) {
1356+
if (collection->isTypeDefaulted()) {
1357+
Walker.checkTypeDefaultedCollectionExpr(
1358+
const_cast<CollectionExpr *>(collection));
1359+
}
1360+
}
13771361
}
13781362

13791363

test/Constraints/array_literal.swift

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,11 @@ func defaultToAny(i: Int, s: String) {
126126
// expected-error@-1{{heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional}}
127127
let _: Int = a1 // expected-error{{value of type '[Any]'}}
128128

129+
let _ = ([1, "a"])
130+
// expected-error@-1{{heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional}}
131+
let _ = [1, true, []]
132+
// expected-error@-1:11 {{heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional}}
133+
129134
let a2: Array = [1, "a", 3.5]
130135
// expected-error@-1{{heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional}}
131136
let _: Int = a2 // expected-error{{value of type '[Any]'}}
@@ -146,9 +151,7 @@ func defaultToAny(i: Int, s: String) {
146151
let _: [Any] = [1, "a", 3.5]
147152
let _: [Any] = [1, "a", [3.5, 3.7, 3.9]]
148153
let _: [Any] = [1, "a", [3.5, "b", 3]]
149-
// expected-warning@-1{{heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional}}
150154
let _: [Any] = [1, [2, [3]]]
151-
// expected-warning@-1{{heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional}}
152155

153156
func f1() -> [Any] {
154157
[]
@@ -157,41 +160,25 @@ func defaultToAny(i: Int, s: String) {
157160
let _: [Any?] = [1, "a", nil, 3.5]
158161
let _: [Any?] = [1, "a", nil, [3.5, 3.7, 3.9]]
159162
let _: [Any?] = [1, "a", nil, [3.5, "b", nil]]
160-
// expected-warning@-1{{heterogeneous collection literal could only be inferred to '[Any?]'; add explicit type annotation if this is intentional}}
161163
let _: [Any?] = [1, [2, [3]]]
162-
// expected-warning@-1{{heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional}}
163164
let _: [Any?] = [1, nil, [2, nil, [3]]]
164-
// expected-warning@-1{{heterogeneous collection literal could only be inferred to '[Any?]'; add explicit type annotation if this is intentional}}
165165

166166
let a6 = [B(), C()]
167167
let _: Int = a6 // expected-error{{value of type '[A]'}}
168168

169169
let a7: some Collection = [1, "Swift"]
170-
// expected-warning@-1{{heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional}} {{41-41= as [Any]}}
171170
let _: (any Sequence)? = [1, "Swift"]
172-
// expected-warning@-1{{heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional}}
173171
let _: any Sequence = [1, nil, "Swift"]
174-
// expected-warning@-1{{heterogeneous collection literal could only be inferred to '[Any?]'; add explicit type annotation if this is intentional}}
175-
let _ = [1, true, ([], 1)]
176-
// expected-error@-1 {{heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional}}
177-
// expected-warning@-2 {{empty collection literal requires an explicit type}}
178172
let _ = true ? [] : []
179-
// expected-warning@-1{{empty collection literal requires an explicit type}}
180173
let _ = (true, ([1, "Swift"]))
181-
//expected-warning@-1{{heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional}}
182-
let _ = ([1, true])
183-
//expected-error@-1{{heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional}}
184174

185175
func f2<T>(_: [T]) {}
186176

187177
func f3<T>() -> [T]? {}
188178

189179
f2([])
190-
// expected-warning@-1{{empty collection literal requires an explicit type}}
191180
f2([1, nil, ""])
192-
// expected-warning@-1{{heterogeneous collection literal could only be inferred to '[Any?]'; add explicit type annotation if this is intentional}}
193181
_ = f3() ?? []
194-
// expected-warning@-1{{empty collection literal requires an explicit type}}
195182
}
196183

197184
func noInferAny(iob: inout B, ioc: inout C) {

test/Constraints/casts.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,6 @@ func test_compatibility_coercions(_ arr: [Int], _ optArr: [Int]?, _ dict: [Strin
338338

339339
// The array can also be inferred to be [Any].
340340
_ = ([] ?? []) as Array // expected-warning {{left side of nil coalescing operator '??' has non-optional type '[Any]', so the right side is never used}}
341-
// expected-warning@-1{{empty collection literal requires an explicit type}}
342341

343342
// rdar://88334481 – Don't apply the compatibility logic for collection literals.
344343
typealias Magic<T> = T

test/Constraints/casts_swift6.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ func test_compatibility_coercions(_ arr: [Int], _ optArr: [Int]?, _ dict: [Strin
5757

5858
// The array can also be inferred to be [Any].
5959
_ = ([] ?? []) as Array // expected-warning {{left side of nil coalescing operator '??' has non-optional type '[Any]', so the right side is never used}}
60-
// expected-warning@-1 {{empty collection literal requires an explicit type}}
6160

6261
// Cases from rdar://88334481
6362
typealias Magic<T> = T

test/Constraints/construction.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,6 @@ do {
175175

176176
// rdar://problem/34670592 - Compiler crash on heterogeneous collection literal
177177
_ = Array([1, "hello"]) // Ok
178-
// expected-warning@-1 {{heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional}}
179178

180179
func init_via_non_const_metatype(_ s1: S1.Type) {
181180
_ = s1(i: 42) // expected-error {{initializing from a metatype value must reference 'init' explicitly}} {{9-9=.init}}

test/Constraints/dictionary_literal.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ class B : A { }
120120
class C : A { }
121121

122122
func testDefaultExistentials() {
123+
let _ = ["a": ["b": ["c": ["d", 1, true]]]]
124+
123125
let _ = ["a" : 1, "b" : 2.5, "c" : "hello"]
124126
// expected-error@-1{{heterogeneous collection literal could only be inferred to '[String : Any]'; add explicit type annotation if this is intentional}}{{46-46= as [String : Any]}}
125127

@@ -139,7 +141,6 @@ func testDefaultExistentials() {
139141
"b": ["a", 2, 3.14159],
140142
"c": ["a": 2, "b": 3.5]]
141143
// expected-error@-3{{heterogeneous collection literal could only be inferred to '[String : Any]'; add explicit type annotation if this is intentional}}
142-
// expected-warning@-3{{heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional}}
143144

144145
let d3 = ["b" : B(), "c" : C()]
145146
let _: Int = d3 // expected-error{{value of type '[String : A]'}}

test/Constraints/subscript.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,6 @@ extension Int {
104104
let _ = 1["1"] // expected-error {{ambiguous use of 'subscript(_:)'}}
105105

106106
let squares = [ 1, 2, 3 ].reduce([:]) { (dict, n) in
107-
// expected-warning@-1 {{empty collection literal requires an explicit type}}
108107
var dict = dict
109108
dict[n] = n * n
110109
return dict

test/IDE/print_usrs_opaque_types.swift

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,34 +9,29 @@
99
func testUnifyingGenericParams<T, U>(x: T) -> some Collection where T == U {
1010
// expected-warning@-1 {{same-type requirement makes generic parameters 'U' and 'T' equivalent}}
1111
return []
12-
// expected-warning@-1 {{empty collection literal requires an explicit type}}
1312
}
1413

1514
// CHECK: [[@LINE+1]]:{{[0-9]+}} s:14swift_ide_test0C22UnifyingGenericParams21xQrx_tSlRz7ElementQzRs_r0_lF
1615
func testUnifyingGenericParams2<T, U>(x: T) -> some Collection where T: Collection, U == T.Element {
1716
return []
18-
// expected-warning@-1 {{empty collection literal requires an explicit type}}
1917
}
2018

2119
// CHECK: [[@LINE+1]]:{{[0-9]+}} s:14swift_ide_test0C24ConcretizingGenericParam1xQrSi_tSiRszlF
2220
func testConcretizingGenericParam<T>(x: T) -> some Collection where T == Int {
2321
// expected-warning@-1 {{same-type requirement makes generic parameter 'T' non-generic}}
2422
return []
25-
// expected-warning@-1 {{empty collection literal requires an explicit type}}
2623
}
2724

2825
struct GenericContext<T> {
2926
// CHECK: [[@LINE+1]]:{{[0-9]+}} s:14swift_ide_test14GenericContextV0c8UnifyingD6Params1xQrx_tqd__RszlF
3027
func testUnifyingGenericParams<U>(x: T) -> some Collection where T == U {
3128
// expected-warning@-1 {{same-type requirement makes generic parameters 'U' and 'T' equivalent}}
3229
return []
33-
// expected-warning@-1 {{empty collection literal requires an explicit type}}
3430
}
3531

3632
// CHECK: [[@LINE+1]]:{{[0-9]+}} s:14swift_ide_test14GenericContextV0c8UnifyingD7Params21xQrx_tSlRz7ElementQzRsd__lF
3733
func testUnifyingGenericParams2<U>(x: T) -> some Collection where T: Collection, U == T.Element {
3834
return []
39-
// expected-warning@-1 {{empty collection literal requires an explicit type}}
4035
}
4136

4237
// CHECK: [[@LINE+1]]:{{[0-9]+}} s:14swift_ide_test14GenericContextVyQrxcqd__Rszluip
@@ -45,7 +40,6 @@ struct GenericContext<T> {
4540
// CHECK: [[@LINE+1]]:{{[0-9]+}} s:14swift_ide_test14GenericContextVyQrxcqd__Rszluig
4641
get {
4742
return []
48-
// expected-warning@-1 {{empty collection literal requires an explicit type}}
4943
}
5044
}
5145
}
@@ -54,7 +48,6 @@ extension GenericContext where T == Int {
5448
// CHECK: [[@LINE+1]]:{{[0-9]+}} s:14swift_ide_test14GenericContextVAASiRszlE0c12ConcretizingD5Param1xQrSi_tF
5549
func testConcretizingGenericParam(x: T) -> some Collection {
5650
return []
57-
// expected-warning@-1 {{empty collection literal requires an explicit type}}
5851
}
5952
}
6053

@@ -65,22 +58,19 @@ extension TooGenericTooContext where T == U {
6558
// CHECK: [[@LINE+1]]:{{[0-9]+}} s:14swift_ide_test010TooGenericD7ContextVAAq_RszrlE0c8UnifyingE6Params1xQrx_tF
6659
func testUnifyingGenericParams(x: T) -> some Collection {
6760
return []
68-
// expected-warning@-1 {{empty collection literal requires an explicit type}}
6961
}
7062
}
7163

7264
extension TooGenericTooContext where T: Collection, U == T.Element {
7365
// CHECK: [[@LINE+1]]:{{[0-9]+}} s:14swift_ide_test010TooGenericD7ContextVAASlRz7ElementQzRs_rlE0c8UnifyingE7Params21xQrx_tF
7466
func testUnifyingGenericParams2(x: T) -> some Collection {
7567
return []
76-
// expected-warning@-1 {{empty collection literal requires an explicit type}}
7768
}
7869
}
7970
extension TooGenericTooContext where T == Int {
8071
// CHECK: [[@LINE+1]]:{{[0-9]+}} s:14swift_ide_test010TooGenericD7ContextVAASiRszrlE0c12ConcretizingE5Param1xQrSi_tF
8172
func testConcretizingGenericParam(x: T) -> some Collection {
8273
return []
83-
// expected-warning@-1 {{empty collection literal requires an explicit type}}
8474
}
8575
}
8676

test/Parse/matching_patterns.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -307,8 +307,6 @@ do {
307307
while case let _ as [Derived] = arr {}
308308
// expected-warning@-1 {{'let' pattern has no effect; sub-pattern didn't bind any variables}}
309309

310-
// FIXME: https://github.com/apple/swift/issues/61850
311-
// expected-warning@+1 {{heterogeneous collection literal could only be inferred to '[[Base]]'; add explicit type annotation if this is intentional}}
312310
for case _ as [Derived] in [arr] {}
313311

314312
if case is [Derived] = arr {}

test/expr/cast/objc_coerce_array.swift

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,9 @@ var x = 1
77
_ = [x] as [NSNumber]
88

99
_ = ["x":["y":"z","a":1]] as [String : [String : AnyObject]]
10-
// expected-warning@-1{{heterogeneous collection literal could only be inferred to '[String : AnyObject]'; add explicit type annotation if this is intentiona}}
1110
_ = ["x":["z",1]] as [String : [AnyObject]]
12-
// expected-warning@-1{{heterogeneous collection literal could only be inferred to '[AnyObject]'; add explicit type annotation if this is intentional}}
1311
_ = [["y":"z","a":1]] as [[String : AnyObject]]
14-
// expected-warning@-1{{heterogeneous collection literal could only be inferred to '[String : AnyObject]'; add explicit type annotation if this is intentional}}
1512
_ = [["z",1]] as [[AnyObject]]
16-
// expected-warning@-1{{heterogeneous collection literal could only be inferred to '[AnyObject]'; add explicit type annotation if this is intentional}}
1713

1814
var y: Any = 1
1915

0 commit comments

Comments
 (0)