mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Revert "Sema: Emit diagnostics when walking into collection literals with defaulted types"
This reverts commit f608802cfe.
This commit is contained in:
@@ -112,15 +112,13 @@ static void diagSyntacticUseRestrictions(const Expr *E, const DeclContext *DC,
|
||||
SmallPtrSet<DeclRefExpr*, 4> AlreadyDiagnosedBitCasts;
|
||||
|
||||
bool IsExprStmt;
|
||||
bool HasReachedSemanticsProvidingExpr;
|
||||
|
||||
ASTContext &Ctx;
|
||||
const DeclContext *DC;
|
||||
|
||||
public:
|
||||
DiagnoseWalker(const DeclContext *DC, bool isExprStmt)
|
||||
: IsExprStmt(isExprStmt), HasReachedSemanticsProvidingExpr(false),
|
||||
Ctx(DC->getASTContext()), DC(DC) {}
|
||||
: IsExprStmt(isExprStmt), Ctx(DC->getASTContext()), DC(DC) {}
|
||||
|
||||
MacroWalking getMacroWalkingBehavior() const override {
|
||||
return MacroWalking::Expansion;
|
||||
@@ -139,16 +137,6 @@ static void diagSyntacticUseRestrictions(const Expr *E, const DeclContext *DC,
|
||||
bool shouldWalkIntoTapExpression() override { return false; }
|
||||
|
||||
PreWalkResult<Expr *> walkToExprPre(Expr *E) override {
|
||||
if (auto collection = dyn_cast<CollectionExpr>(E)) {
|
||||
if (collection->isTypeDefaulted()) {
|
||||
// Diagnose type defaulted collection literals in subexpressions as
|
||||
// warnings to preserve source compatibility.
|
||||
diagnoseTypeDefaultedCollectionExpr(
|
||||
collection, Ctx,
|
||||
/*downgradeToWarning=*/HasReachedSemanticsProvidingExpr);
|
||||
}
|
||||
}
|
||||
|
||||
// See through implicit conversions of the expression. We want to be able
|
||||
// to associate the parent of this expression with the ultimate callee.
|
||||
auto Base = E;
|
||||
@@ -356,11 +344,6 @@ static void diagSyntacticUseRestrictions(const Expr *E, const DeclContext *DC,
|
||||
checkBorrowExpr(borrowExpr);
|
||||
}
|
||||
|
||||
if (!HasReachedSemanticsProvidingExpr &&
|
||||
E == E->getSemanticsProvidingExpr()) {
|
||||
HasReachedSemanticsProvidingExpr = true;
|
||||
}
|
||||
|
||||
return Action::Continue(E);
|
||||
}
|
||||
|
||||
@@ -508,34 +491,25 @@ static void diagSyntacticUseRestrictions(const Expr *E, const DeclContext *DC,
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Diagnose a collection literal with a defaulted type such as \c [Any].
|
||||
static void diagnoseTypeDefaultedCollectionExpr(CollectionExpr *c,
|
||||
ASTContext &ctx,
|
||||
bool downgradeToWarning) {
|
||||
// Produce a diagnostic with a fixit to add the defaulted type as an
|
||||
// explicit annotation.
|
||||
auto &diags = ctx.Diags;
|
||||
|
||||
if (c->getNumElements() == 0) {
|
||||
InFlightDiagnostic inFlight =
|
||||
diags.diagnose(c->getLoc(), diag::collection_literal_empty);
|
||||
inFlight.highlight(c->getSourceRange());
|
||||
|
||||
if (downgradeToWarning) {
|
||||
inFlight.limitBehavior(DiagnosticBehavior::Warning);
|
||||
}
|
||||
} else {
|
||||
/// We have a collection literal with a defaulted type, e.g. of [Any]. Emit
|
||||
/// an error if it was inferred to this type in an invalid context, which is
|
||||
/// one in which the parent expression is not itself a collection literal.
|
||||
void checkTypeDefaultedCollectionExpr(CollectionExpr *c) {
|
||||
// If the parent is a non-expression, or is not itself a literal, then
|
||||
// produce an error with a fixit to add the type as an explicit
|
||||
// annotation.
|
||||
if (c->getNumElements() == 0)
|
||||
Ctx.Diags.diagnose(c->getLoc(), diag::collection_literal_empty)
|
||||
.highlight(c->getSourceRange());
|
||||
else {
|
||||
assert(c->getType()->hasTypeRepr() &&
|
||||
"a defaulted type should always be printable");
|
||||
InFlightDiagnostic inFlight = diags.diagnose(
|
||||
c->getLoc(), diag::collection_literal_heterogeneous, c->getType());
|
||||
inFlight.highlight(c->getSourceRange());
|
||||
inFlight.fixItInsertAfter(c->getEndLoc(),
|
||||
" as " + c->getType()->getString());
|
||||
|
||||
if (downgradeToWarning) {
|
||||
inFlight.limitBehavior(DiagnosticBehavior::Warning);
|
||||
}
|
||||
Ctx.Diags
|
||||
.diagnose(c->getLoc(), diag::collection_literal_heterogeneous,
|
||||
c->getType())
|
||||
.highlight(c->getSourceRange())
|
||||
.fixItInsertAfter(c->getEndLoc(),
|
||||
" as " + c->getType()->getString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1421,6 +1395,16 @@ static void diagSyntacticUseRestrictions(const Expr *E, const DeclContext *DC,
|
||||
|
||||
DiagnoseWalker Walker(DC, isExprStmt);
|
||||
const_cast<Expr *>(E)->walk(Walker);
|
||||
|
||||
// Diagnose uses of collection literals with defaulted types at the top
|
||||
// level.
|
||||
if (auto collection =
|
||||
dyn_cast<CollectionExpr>(E->getSemanticsProvidingExpr())) {
|
||||
if (collection->isTypeDefaulted()) {
|
||||
Walker.checkTypeDefaultedCollectionExpr(
|
||||
const_cast<CollectionExpr *>(collection));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -126,6 +126,11 @@ func defaultToAny(i: Int, s: String) {
|
||||
// expected-error@-1{{heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional}}
|
||||
let _: Int = a1 // expected-error{{value of type '[Any]'}}
|
||||
|
||||
let _ = ([1, "a"])
|
||||
// expected-error@-1{{heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional}}
|
||||
let _ = [1, true, []]
|
||||
// expected-error@-1:11 {{heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional}}
|
||||
|
||||
let a2: Array = [1, "a", 3.5]
|
||||
// expected-error@-1{{heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional}}
|
||||
let _: Int = a2 // expected-error{{value of type '[Any]'}}
|
||||
@@ -146,9 +151,7 @@ func defaultToAny(i: Int, s: String) {
|
||||
let _: [Any] = [1, "a", 3.5]
|
||||
let _: [Any] = [1, "a", [3.5, 3.7, 3.9]]
|
||||
let _: [Any] = [1, "a", [3.5, "b", 3]]
|
||||
// expected-warning@-1{{heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional}}
|
||||
let _: [Any] = [1, [2, [3]]]
|
||||
// expected-warning@-1{{heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional}}
|
||||
|
||||
func f1() -> [Any] {
|
||||
[]
|
||||
@@ -157,41 +160,25 @@ func defaultToAny(i: Int, s: String) {
|
||||
let _: [Any?] = [1, "a", nil, 3.5]
|
||||
let _: [Any?] = [1, "a", nil, [3.5, 3.7, 3.9]]
|
||||
let _: [Any?] = [1, "a", nil, [3.5, "b", nil]]
|
||||
// expected-warning@-1{{heterogeneous collection literal could only be inferred to '[Any?]'; add explicit type annotation if this is intentional}}
|
||||
let _: [Any?] = [1, [2, [3]]]
|
||||
// expected-warning@-1{{heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional}}
|
||||
let _: [Any?] = [1, nil, [2, nil, [3]]]
|
||||
// expected-warning@-1{{heterogeneous collection literal could only be inferred to '[Any?]'; add explicit type annotation if this is intentional}}
|
||||
|
||||
let a6 = [B(), C()]
|
||||
let _: Int = a6 // expected-error{{value of type '[A]'}}
|
||||
|
||||
let a7: some Collection = [1, "Swift"]
|
||||
// expected-warning@-1{{heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional}} {{41-41= as [Any]}}
|
||||
let _: (any Sequence)? = [1, "Swift"]
|
||||
// expected-warning@-1{{heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional}}
|
||||
let _: any Sequence = [1, nil, "Swift"]
|
||||
// expected-warning@-1{{heterogeneous collection literal could only be inferred to '[Any?]'; add explicit type annotation if this is intentional}}
|
||||
let _ = [1, true, ([], 1)]
|
||||
// expected-error@-1 {{heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional}}
|
||||
// expected-warning@-2 {{empty collection literal requires an explicit type}}
|
||||
let _ = true ? [] : []
|
||||
// expected-warning@-1{{empty collection literal requires an explicit type}}
|
||||
let _ = (true, ([1, "Swift"]))
|
||||
//expected-warning@-1{{heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional}}
|
||||
let _ = ([1, true])
|
||||
//expected-error@-1{{heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional}}
|
||||
|
||||
func f2<T>(_: [T]) {}
|
||||
|
||||
func f3<T>() -> [T]? {}
|
||||
|
||||
f2([])
|
||||
// expected-warning@-1{{empty collection literal requires an explicit type}}
|
||||
f2([1, nil, ""])
|
||||
// expected-warning@-1{{heterogeneous collection literal could only be inferred to '[Any?]'; add explicit type annotation if this is intentional}}
|
||||
_ = f3() ?? []
|
||||
// expected-warning@-1{{empty collection literal requires an explicit type}}
|
||||
}
|
||||
|
||||
func noInferAny(iob: inout B, ioc: inout C) {
|
||||
|
||||
@@ -338,7 +338,6 @@ func test_compatibility_coercions(_ arr: [Int], _ optArr: [Int]?, _ dict: [Strin
|
||||
|
||||
// The array can also be inferred to be [Any].
|
||||
_ = ([] ?? []) as Array // expected-warning {{left side of nil coalescing operator '??' has non-optional type '[Any]', so the right side is never used}}
|
||||
// expected-warning@-1{{empty collection literal requires an explicit type}}
|
||||
|
||||
// rdar://88334481 – Don't apply the compatibility logic for collection literals.
|
||||
typealias Magic<T> = T
|
||||
|
||||
@@ -57,7 +57,6 @@ func test_compatibility_coercions(_ arr: [Int], _ optArr: [Int]?, _ dict: [Strin
|
||||
|
||||
// The array can also be inferred to be [Any].
|
||||
_ = ([] ?? []) as Array // expected-warning {{left side of nil coalescing operator '??' has non-optional type '[Any]', so the right side is never used}}
|
||||
// expected-warning@-1 {{empty collection literal requires an explicit type}}
|
||||
|
||||
// Cases from rdar://88334481
|
||||
typealias Magic<T> = T
|
||||
|
||||
@@ -175,7 +175,6 @@ do {
|
||||
|
||||
// rdar://problem/34670592 - Compiler crash on heterogeneous collection literal
|
||||
_ = Array([1, "hello"]) // Ok
|
||||
// expected-warning@-1 {{heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional}}
|
||||
|
||||
func init_via_non_const_metatype(_ s1: S1.Type) {
|
||||
_ = s1(i: 42) // expected-error {{initializing from a metatype value must reference 'init' explicitly}} {{9-9=.init}}
|
||||
|
||||
@@ -120,6 +120,8 @@ class B : A { }
|
||||
class C : A { }
|
||||
|
||||
func testDefaultExistentials() {
|
||||
let _ = ["a": ["b": ["c": ["d", 1, true]]]]
|
||||
|
||||
let _ = ["a" : 1, "b" : 2.5, "c" : "hello"]
|
||||
// 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]}}
|
||||
|
||||
@@ -139,7 +141,6 @@ func testDefaultExistentials() {
|
||||
"b": ["a", 2, 3.14159],
|
||||
"c": ["a": 2, "b": 3.5]]
|
||||
// expected-error@-3{{heterogeneous collection literal could only be inferred to '[String : Any]'; add explicit type annotation if this is intentional}}
|
||||
// expected-warning@-3{{heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional}}
|
||||
|
||||
let d3 = ["b" : B(), "c" : C()]
|
||||
let _: Int = d3 // expected-error{{value of type '[String : A]'}}
|
||||
|
||||
@@ -104,7 +104,6 @@ extension Int {
|
||||
let _ = 1["1"] // expected-error {{ambiguous use of 'subscript(_:)'}}
|
||||
|
||||
let squares = [ 1, 2, 3 ].reduce([:]) { (dict, n) in
|
||||
// expected-warning@-1 {{empty collection literal requires an explicit type}}
|
||||
var dict = dict
|
||||
dict[n] = n * n
|
||||
return dict
|
||||
|
||||
@@ -9,20 +9,17 @@
|
||||
func testUnifyingGenericParams<T, U>(x: T) -> some Collection where T == U {
|
||||
// expected-warning@-1 {{same-type requirement makes generic parameters 'U' and 'T' equivalent}}
|
||||
return []
|
||||
// expected-warning@-1 {{empty collection literal requires an explicit type}}
|
||||
}
|
||||
|
||||
// CHECK: [[@LINE+1]]:{{[0-9]+}} s:14swift_ide_test0C22UnifyingGenericParams21xQrx_tSlRz7ElementQzRs_r0_lF
|
||||
func testUnifyingGenericParams2<T, U>(x: T) -> some Collection where T: Collection, U == T.Element {
|
||||
return []
|
||||
// expected-warning@-1 {{empty collection literal requires an explicit type}}
|
||||
}
|
||||
|
||||
// CHECK: [[@LINE+1]]:{{[0-9]+}} s:14swift_ide_test0C24ConcretizingGenericParam1xQrSi_tSiRszlF
|
||||
func testConcretizingGenericParam<T>(x: T) -> some Collection where T == Int {
|
||||
// expected-warning@-1 {{same-type requirement makes generic parameter 'T' non-generic}}
|
||||
return []
|
||||
// expected-warning@-1 {{empty collection literal requires an explicit type}}
|
||||
}
|
||||
|
||||
struct GenericContext<T> {
|
||||
@@ -30,13 +27,11 @@ struct GenericContext<T> {
|
||||
func testUnifyingGenericParams<U>(x: T) -> some Collection where T == U {
|
||||
// expected-warning@-1 {{same-type requirement makes generic parameters 'U' and 'T' equivalent}}
|
||||
return []
|
||||
// expected-warning@-1 {{empty collection literal requires an explicit type}}
|
||||
}
|
||||
|
||||
// CHECK: [[@LINE+1]]:{{[0-9]+}} s:14swift_ide_test14GenericContextV0c8UnifyingD7Params21xQrx_tSlRz7ElementQzRsd__lF
|
||||
func testUnifyingGenericParams2<U>(x: T) -> some Collection where T: Collection, U == T.Element {
|
||||
return []
|
||||
// expected-warning@-1 {{empty collection literal requires an explicit type}}
|
||||
}
|
||||
|
||||
// CHECK: [[@LINE+1]]:{{[0-9]+}} s:14swift_ide_test14GenericContextVyQrxcqd__Rszluip
|
||||
@@ -45,7 +40,6 @@ struct GenericContext<T> {
|
||||
// CHECK: [[@LINE+1]]:{{[0-9]+}} s:14swift_ide_test14GenericContextVyQrxcqd__Rszluig
|
||||
get {
|
||||
return []
|
||||
// expected-warning@-1 {{empty collection literal requires an explicit type}}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -54,7 +48,6 @@ extension GenericContext where T == Int {
|
||||
// CHECK: [[@LINE+1]]:{{[0-9]+}} s:14swift_ide_test14GenericContextVAASiRszlE0c12ConcretizingD5Param1xQrSi_tF
|
||||
func testConcretizingGenericParam(x: T) -> some Collection {
|
||||
return []
|
||||
// expected-warning@-1 {{empty collection literal requires an explicit type}}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +58,6 @@ extension TooGenericTooContext where T == U {
|
||||
// CHECK: [[@LINE+1]]:{{[0-9]+}} s:14swift_ide_test010TooGenericD7ContextVAAq_RszrlE0c8UnifyingE6Params1xQrx_tF
|
||||
func testUnifyingGenericParams(x: T) -> some Collection {
|
||||
return []
|
||||
// expected-warning@-1 {{empty collection literal requires an explicit type}}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,14 +65,12 @@ extension TooGenericTooContext where T: Collection, U == T.Element {
|
||||
// CHECK: [[@LINE+1]]:{{[0-9]+}} s:14swift_ide_test010TooGenericD7ContextVAASlRz7ElementQzRs_rlE0c8UnifyingE7Params21xQrx_tF
|
||||
func testUnifyingGenericParams2(x: T) -> some Collection {
|
||||
return []
|
||||
// expected-warning@-1 {{empty collection literal requires an explicit type}}
|
||||
}
|
||||
}
|
||||
extension TooGenericTooContext where T == Int {
|
||||
// CHECK: [[@LINE+1]]:{{[0-9]+}} s:14swift_ide_test010TooGenericD7ContextVAASiRszrlE0c12ConcretizingE5Param1xQrSi_tF
|
||||
func testConcretizingGenericParam(x: T) -> some Collection {
|
||||
return []
|
||||
// expected-warning@-1 {{empty collection literal requires an explicit type}}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -307,8 +307,6 @@ do {
|
||||
while case let _ as [Derived] = arr {}
|
||||
// expected-warning@-1 {{'let' pattern has no effect; sub-pattern didn't bind any variables}}
|
||||
|
||||
// FIXME: https://github.com/apple/swift/issues/61850
|
||||
// expected-warning@+1 {{heterogeneous collection literal could only be inferred to '[[Base]]'; add explicit type annotation if this is intentional}}
|
||||
for case _ as [Derived] in [arr] {}
|
||||
|
||||
if case is [Derived] = arr {}
|
||||
|
||||
@@ -328,8 +328,6 @@ do {
|
||||
while case let _ as [Derived] = arr {}
|
||||
// expected-warning@-1 {{'let' pattern has no effect; sub-pattern didn't bind any variables}}
|
||||
|
||||
// FIXME: https://github.com/apple/swift/issues/61850
|
||||
// expected-warning@+1 {{heterogeneous collection literal could only be inferred to '[[Base]]'; add explicit type annotation if this is intentional}}
|
||||
for case _ as [Derived] in [arr] {}
|
||||
|
||||
if case is [Derived] = arr {}
|
||||
|
||||
@@ -7,13 +7,9 @@ var x = 1
|
||||
_ = [x] as [NSNumber]
|
||||
|
||||
_ = ["x":["y":"z","a":1]] as [String : [String : AnyObject]]
|
||||
// expected-warning@-1{{heterogeneous collection literal could only be inferred to '[String : AnyObject]'; add explicit type annotation if this is intentiona}}
|
||||
_ = ["x":["z",1]] as [String : [AnyObject]]
|
||||
// expected-warning@-1{{heterogeneous collection literal could only be inferred to '[AnyObject]'; add explicit type annotation if this is intentional}}
|
||||
_ = [["y":"z","a":1]] as [[String : AnyObject]]
|
||||
// expected-warning@-1{{heterogeneous collection literal could only be inferred to '[String : AnyObject]'; add explicit type annotation if this is intentional}}
|
||||
_ = [["z",1]] as [[AnyObject]]
|
||||
// expected-warning@-1{{heterogeneous collection literal could only be inferred to '[AnyObject]'; add explicit type annotation if this is intentional}}
|
||||
|
||||
var y: Any = 1
|
||||
|
||||
|
||||
Reference in New Issue
Block a user