Skip to content

Commit bb3ae47

Browse files
authored
Merge pull request #21681 from DougGregor/collection-literal-default-lookup-sr-9611-5.0
[5.0] [Type checker] Array/dictionary literals define to Swift.(Array|Dictionary)
2 parents 5bf394d + 0c7ec65 commit bb3ae47

File tree

3 files changed

+31
-19
lines changed

3 files changed

+31
-19
lines changed

lib/Sema/TypeCheckExpr.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,7 @@ static Type lookupDefaultLiteralType(TypeChecker &TC, DeclContext *dc,
658658
Type TypeChecker::getDefaultType(ProtocolDecl *protocol, DeclContext *dc) {
659659
Type *type = nullptr;
660660
const char *name = nullptr;
661+
bool performLocalLookup = true;
661662

662663
// ExpressibleByUnicodeScalarLiteral -> UnicodeScalarType
663664
if (protocol ==
@@ -711,13 +712,15 @@ Type TypeChecker::getDefaultType(ProtocolDecl *protocol, DeclContext *dc) {
711712
KnownProtocolKind::ExpressibleByArrayLiteral)){
712713
type = &ArrayLiteralType;
713714
name = "Array";
715+
performLocalLookup = false;
714716
}
715717
// ExpressibleByDictionaryLiteral -> Dictionary
716718
else if (protocol == getProtocol(
717719
SourceLoc(),
718720
KnownProtocolKind::ExpressibleByDictionaryLiteral)) {
719721
type = &DictionaryLiteralType;
720722
name = "Dictionary";
723+
performLocalLookup = false;
721724
}
722725
// _ExpressibleByColorLiteral -> _ColorLiteralType
723726
else if (protocol == getProtocol(
@@ -746,7 +749,8 @@ Type TypeChecker::getDefaultType(ProtocolDecl *protocol, DeclContext *dc) {
746749

747750
// If we haven't found the type yet, look for it now.
748751
if (!*type) {
749-
*type = lookupDefaultLiteralType(*this, dc, name);
752+
if (performLocalLookup)
753+
*type = lookupDefaultLiteralType(*this, dc, name);
750754

751755
if (!*type)
752756
*type = lookupDefaultLiteralType(*this, getStdlibModule(dc), name);
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
// SR-9611: Array type locally interfers with array literals.
4+
struct Array { }
5+
6+
func foo() {
7+
_ = ["a", "b", "c"]
8+
}

test/Constraints/dictionary_literal.swift

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ final class DictStringInt : ExpressibleByDictionaryLiteral {
66
init(dictionaryLiteral elements: (String, Int)...) { }
77
}
88

9-
final class Dictionary<K, V> : ExpressibleByDictionaryLiteral {
9+
final class MyDictionary<K, V> : ExpressibleByDictionaryLiteral {
1010
typealias Key = K
1111
typealias Value = V
1212
init(dictionaryLiteral elements: (K, V)...) { }
1313
}
1414

1515
func useDictStringInt(_ d: DictStringInt) {}
16-
func useDict<K, V>(_ d: Dictionary<K,V>) {}
16+
func useDict<K, V>(_ d: MyDictionary<K,V>) {}
1717

1818
// Concrete dictionary literals.
1919
useDictStringInt(["Hello" : 1])
@@ -30,7 +30,7 @@ useDictStringInt(["Hello" : nil])
3030
// expected-error@-1 {{'nil' is not compatible with expected dictionary value type 'Int'}}
3131

3232
typealias FuncBoolToInt = (Bool) -> Int
33-
let dict1: Dictionary<String, FuncBoolToInt> = ["Hello": nil]
33+
let dict1: MyDictionary<String, FuncBoolToInt> = ["Hello": nil]
3434
// expected-error@-1 {{'nil' is not compatible with expected dictionary value type '(Bool) -> Int'}}
3535

3636
// Generic dictionary literals.
@@ -39,7 +39,7 @@ useDict(["Hello" : 1, "World" : 2])
3939
useDict(["Hello" : 1.5, "World" : 2])
4040
useDict([1 : 1.5, 3 : 2.5])
4141

42-
// Fall back to Dictionary<K, V> if no context is otherwise available.
42+
// Fall back to Swift.Dictionary<K, V> if no context is otherwise available.
4343
var a = ["Hello" : 1, "World" : 2]
4444
var a2 : Dictionary<String, Int> = a
4545
var a3 = ["Hello" : 1]
@@ -52,20 +52,20 @@ var b3 = [1 : 2.5]
5252
// <rdar://problem/22584076> QoI: Using array literal init with dictionary produces bogus error
5353

5454
// expected-note @+1 {{did you mean to use a dictionary literal instead?}}
55-
var _: Dictionary<String, (Int) -> Int>? = [ // expected-error {{dictionary of type 'Dictionary<String, (Int) -> Int>' cannot be initialized with array literal}}
55+
var _: MyDictionary<String, (Int) -> Int>? = [ // expected-error {{dictionary of type 'MyDictionary<String, (Int) -> Int>' cannot be initialized with array literal}}
5656
"closure_1" as String, {(Int) -> Int in 0},
5757
"closure_2", {(Int) -> Int in 0}]
5858

5959

60-
var _: Dictionary<String, Int>? = ["foo", 1] // expected-error {{dictionary of type 'Dictionary<String, Int>' cannot be initialized with array literal}}
61-
// expected-note @-1 {{did you mean to use a dictionary literal instead?}} {{41-42=:}}
60+
var _: MyDictionary<String, Int>? = ["foo", 1] // expected-error {{dictionary of type 'MyDictionary<String, Int>' cannot be initialized with array literal}}
61+
// expected-note @-1 {{did you mean to use a dictionary literal instead?}} {{43-44=:}}
6262

63-
var _: Dictionary<String, Int>? = ["foo", 1, "bar", 42] // expected-error {{dictionary of type 'Dictionary<String, Int>' cannot be initialized with array literal}}
64-
// expected-note @-1 {{did you mean to use a dictionary literal instead?}} {{41-42=:}} {{51-52=:}}
63+
var _: MyDictionary<String, Int>? = ["foo", 1, "bar", 42] // expected-error {{dictionary of type 'MyDictionary<String, Int>' cannot be initialized with array literal}}
64+
// expected-note @-1 {{did you mean to use a dictionary literal instead?}} {{43-44=:}} {{53-54=:}}
6565

66-
var _: Dictionary<String, Int>? = ["foo", 1.0, 2] // expected-error {{cannot convert value of type '[Any]' to specified type 'Dictionary<String, Int>?'}}
66+
var _: MyDictionary<String, Int>? = ["foo", 1.0, 2] // expected-error {{cannot convert value of type '[Any]' to specified type 'MyDictionary<String, Int>?'}}
6767

68-
var _: Dictionary<String, Int>? = ["foo" : 1.0] // expected-error {{cannot convert value of type 'Double' to expected dictionary value type 'Int'}}
68+
var _: MyDictionary<String, Int>? = ["foo" : 1.0] // expected-error {{cannot convert value of type 'Double' to expected dictionary value type 'Int'}}
6969

7070

7171
// <rdar://problem/24058895> QoI: Should handle [] in dictionary contexts better
@@ -78,33 +78,33 @@ class C : A { }
7878

7979
func testDefaultExistentials() {
8080
let _ = ["a" : 1, "b" : 2.5, "c" : "hello"]
81-
// expected-error@-1{{heterogeneous collection literal could only be inferred to 'Dictionary<String, Any>'; add explicit type annotation if this is intentional}}{{46-46= as Dictionary<String, Any>}}
81+
// 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]}}
8282

8383
let _: [String : Any] = ["a" : 1, "b" : 2.5, "c" : "hello"]
8484

8585
let _ = ["a" : 1, "b" : nil, "c" : "hello"]
86-
// expected-error@-1{{heterogeneous collection literal could only be inferred to 'Dictionary<String, Any?>'; add explicit type annotation if this is intentional}}{{46-46= as Dictionary<String, Any?>}}
86+
// 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?]}}
8787

8888
let _: [String : Any?] = ["a" : 1, "b" : nil, "c" : "hello"]
8989

9090
let d2 = [:]
9191
// expected-error@-1{{empty collection literal requires an explicit type}}
9292

93-
let _: Int = d2 // expected-error{{value of type 'Dictionary<AnyHashable, Any>'}}
93+
let _: Int = d2 // expected-error{{value of type '[AnyHashable : Any]'}}
9494

9595
let _ = ["a": 1,
9696
"b": ["a", 2, 3.14159],
9797
"c": ["a": 2, "b": 3.5]]
98-
// expected-error@-3{{heterogeneous collection literal could only be inferred to 'Dictionary<String, Any>'; add explicit type annotation if this is intentional}}
98+
// expected-error@-3{{heterogeneous collection literal could only be inferred to '[String : Any]'; add explicit type annotation if this is intentional}}
9999

100100
let d3 = ["b" : B(), "c" : C()]
101-
let _: Int = d3 // expected-error{{value of type 'Dictionary<String, A>'}}
101+
let _: Int = d3 // expected-error{{value of type '[String : A]'}}
102102

103103
let _ = ["a" : B(), 17 : "seventeen", 3.14159 : "Pi"]
104-
// expected-error@-1{{heterogeneous collection literal could only be inferred to 'Dictionary<AnyHashable, Any>'}}
104+
// expected-error@-1{{heterogeneous collection literal could only be inferred to '[AnyHashable : Any]'}}
105105

106106
let _ = ["a" : "hello", 17 : "string"]
107-
// expected-error@-1{{heterogeneous collection literal could only be inferred to 'Dictionary<AnyHashable, String>'}}
107+
// expected-error@-1{{heterogeneous collection literal could only be inferred to '[AnyHashable : String]'}}
108108
}
109109

110110
// SR-4952, rdar://problem/32330004 - Assertion failure during swift::ASTVisitor<::FailureDiagnosis,...>::visit

0 commit comments

Comments
 (0)