Skip to content

Commit 4a48c94

Browse files
[Sema] Perform availability checks in literals initializers
1 parent e2a41d1 commit 4a48c94

File tree

2 files changed

+184
-6
lines changed

2 files changed

+184
-6
lines changed

lib/Sema/TypeCheckAvailability.cpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3254,13 +3254,22 @@ class ExprAvailabilityWalker : public ASTWalker {
32543254
maybeDiagStorageAccess(S->getDecl().getDecl(), S->getSourceRange(), DC);
32553255
}
32563256
}
3257-
if (auto *RLE = dyn_cast<RegexLiteralExpr>(E)) {
3258-
// Regex literals require both the Regex<Output> type to be available, as
3259-
// well as the initializer that is implicitly called.
3260-
auto Range = RLE->getSourceRange();
3261-
diagnoseDeclRefAvailability(Context.getRegexDecl(), Range);
3262-
diagnoseDeclRefAvailability(RLE->getInitializer(), Range);
3257+
3258+
if (auto *LE = dyn_cast<LiteralExpr>(E)) {
3259+
auto Range = LE->getSourceRange();
3260+
if (auto *RLE = dyn_cast<RegexLiteralExpr>(LE)) {
3261+
// Regex literals require both the Regex<Output> type to be available,
3262+
// as well as the initializer that is implicitly called.
3263+
diagnoseDeclRefAvailability(Context.getRegexDecl(), Range);
3264+
}
3265+
diagnoseDeclRefAvailability(LE->getInitializer(), Range);
32633266
}
3267+
3268+
if (auto *CE = dyn_cast<CollectionExpr>(E)) {
3269+
// Diagnose availability of implicit collection literal initializers.
3270+
diagnoseDeclRefAvailability(CE->getInitializer(), CE->getSourceRange());
3271+
}
3272+
32643273
if (auto *EE = dyn_cast<ErasureExpr>(E)) {
32653274
maybeDiagParameterizedExistentialErasure(EE, Where);
32663275
}

test/Sema/availability_literals.swift

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
// RUN: %target-typecheck-verify-swift -swift-version 5
2+
3+
// REQUIRES: OS=macosx
4+
5+
// https://github.com/apple/swift/issues/61564
6+
// ExpressibleByStringLiteral
7+
struct SLD {}
8+
@available(*, deprecated)
9+
extension SLD: ExpressibleByStringLiteral {
10+
init(stringLiteral value: StringLiteralType) {}
11+
}
12+
13+
let _ = SLD(stringLiteral: "") // expected-warning{{'init(stringLiteral:)' is deprecated}}
14+
let _: SLD = "" // expected-warning{{'init(stringLiteral:)' is deprecated}}
15+
16+
17+
struct SLU {}
18+
@available(macOS 100, *)
19+
extension SLU: ExpressibleByStringLiteral {
20+
init(stringLiteral value: StringLiteralType) {}
21+
}
22+
23+
let _ = SLU(stringLiteral: "") // expected-error{{'init(stringLiteral:)' is only available in macOS 100 or newer}} expected-note{{add 'if #available' version check}}
24+
let _: SLU = "" // expected-error{{'init(stringLiteral:)' is only available in macOS 100 or newer}} expected-note{{add 'if #available' version check}}
25+
26+
// ExpressibleByIntegerLiteral
27+
struct ILD {}
28+
@available(*, deprecated)
29+
extension ILD: ExpressibleByIntegerLiteral {
30+
init(integerLiteral value: IntegerLiteralType) {}
31+
}
32+
33+
let _ = ILD(integerLiteral: 1) // expected-warning{{'init(integerLiteral:)' is deprecated}}
34+
let _: ILD = 1 // expected-warning{{'init(integerLiteral:)' is deprecated}}
35+
36+
struct ILU {}
37+
38+
@available(macOS 100, *)
39+
extension ILU: ExpressibleByIntegerLiteral {
40+
init(integerLiteral value: IntegerLiteralType) {}
41+
}
42+
43+
let _ = ILU(integerLiteral: 1) // expected-error{{'init(integerLiteral:)' is only available in macOS 100 or newer}} expected-note{{add 'if #available' version check}}
44+
let _: ILU = 1 // expected-error{{'init(integerLiteral:)' is only available in macOS 100 or newer}} expected-note{{add 'if #available' version check}}
45+
46+
// ExpressibleByNilLiteral
47+
struct NLD {}
48+
49+
@available(*, deprecated)
50+
extension NLD: ExpressibleByNilLiteral {
51+
init(nilLiteral: ()) {}
52+
}
53+
54+
let _: NLD = .init(nilLiteral: ()) // expected-warning{{'init(nilLiteral:)' is deprecated}}
55+
let _: NLD = nil // expected-warning{{'init(nilLiteral:)' is deprecated}}
56+
57+
struct NLU {}
58+
59+
@available(macOS 100, *)
60+
extension NLU: ExpressibleByNilLiteral {
61+
init(nilLiteral: ()) {}
62+
}
63+
64+
let _: NLU = .init(nilLiteral: ()) // expected-error{{'init(nilLiteral:)' is only available in macOS 100 or newer}} expected-note{{add 'if #available' version check}}
65+
let _: NLU = nil // expected-error{{'init(nilLiteral:)' is only available in macOS 100 or newer}} expected-note{{add 'if #available' version check}}
66+
67+
// ExpressibleByBooleanLiteral
68+
struct BLD {}
69+
@available(*, deprecated)
70+
extension BLD: ExpressibleByBooleanLiteral {
71+
init(booleanLiteral value: BooleanLiteralType) {}
72+
}
73+
let _: BLD = .init(booleanLiteral: false) // expected-warning{{'init(booleanLiteral:)' is deprecated}}
74+
let _: BLD = false // expected-warning{{'init(booleanLiteral:)' is deprecated}}
75+
76+
struct BLU {}
77+
@available(macOS 100, *)
78+
extension BLU: ExpressibleByBooleanLiteral {
79+
init(booleanLiteral value: BooleanLiteralType) {}
80+
}
81+
let _: BLU = .init(booleanLiteral: false) // expected-error{{'init(booleanLiteral:)' is only available in macOS 100 or newer}} expected-note{{add 'if #available' version check}}
82+
let _: BLU = false // expected-error{{'init(booleanLiteral:)' is only available in macOS 100 or newer}} expected-note{{add 'if #available' version check}}
83+
84+
// ExpressibleByFloatLiteral
85+
struct FLD {}
86+
@available(*, deprecated)
87+
extension FLD: ExpressibleByFloatLiteral {
88+
init(floatLiteral value: FloatLiteralType) {}
89+
}
90+
let _: FLD = .init(floatLiteral: 0.1) // expected-warning{{'init(floatLiteral:)' is deprecated}}
91+
let _: FLD = 0.1 // expected-warning{{'init(floatLiteral:)' is deprecated}}
92+
93+
struct FLU {}
94+
@available(macOS 100, *)
95+
extension FLU: ExpressibleByFloatLiteral {
96+
init(floatLiteral value: FloatLiteralType) {}
97+
}
98+
let _: FLU = .init(floatLiteral: 0.1) // expected-error{{'init(floatLiteral:)' is only available in macOS 100 or newer}} expected-note{{add 'if #available' version check}}
99+
let _: FLU = 0.1 // expected-error{{'init(floatLiteral:)' is only available in macOS 100 or newer}} expected-note{{add 'if #available' version check}}
100+
101+
// ExpressibleByArrayLiteral
102+
struct ALD {}
103+
@available(*, deprecated)
104+
extension ALD: ExpressibleByArrayLiteral {
105+
init(arrayLiteral elements: Int...) {}
106+
}
107+
let _: ALD = .init(arrayLiteral: 1) // expected-warning{{'init(arrayLiteral:)' is deprecated}}
108+
let _: ALD = [1] // expected-warning{{'init(arrayLiteral:)' is deprecated}}
109+
110+
struct ALU {}
111+
@available(macOS 100, *)
112+
extension ALU: ExpressibleByArrayLiteral {
113+
init(arrayLiteral elements: Int...) {}
114+
}
115+
let _: ALU = .init(arrayLiteral: 1) // expected-error{{'init(arrayLiteral:)' is only available in macOS 100 or newer}} expected-note{{add 'if #available' version check}}
116+
let _: ALU = [1] // expected-error{{'init(arrayLiteral:)' is only available in macOS 100 or newer}} expected-note{{add 'if #available' version check}}
117+
118+
// ExpressibleByDictionaryLiteral
119+
struct DLD {}
120+
@available(*, deprecated)
121+
extension DLD: ExpressibleByDictionaryLiteral {
122+
init(dictionaryLiteral elements: (Int, Int)...) {}
123+
}
124+
let _: DLD = .init(dictionaryLiteral: (1,1)) // expected-warning{{'init(dictionaryLiteral:)' is deprecated}}
125+
let _: DLD = [1: 1] // expected-warning{{'init(dictionaryLiteral:)' is deprecated}}
126+
127+
struct DLU {}
128+
@available(macOS 100, *)
129+
extension DLU: ExpressibleByDictionaryLiteral {
130+
init(dictionaryLiteral elements: (Int, Int)...) {}
131+
}
132+
let _: DLU = .init(dictionaryLiteral: (1,1)) // expected-error{{'init(dictionaryLiteral:)' is only available in macOS 100 or newer}} expected-note{{add 'if #available' version check}}
133+
let _: DLU = [1: 1] // expected-error{{'init(dictionaryLiteral:)' is only available in macOS 100 or newer}} expected-note{{add 'if #available' version check}}
134+
135+
// ExpressibleByUnicodeScalarLiteral
136+
struct USLD {}
137+
@available(*, deprecated)
138+
extension USLD: ExpressibleByUnicodeScalarLiteral {
139+
typealias UnicodeScalarLiteralType = Character
140+
init(unicodeScalarLiteral value: UnicodeScalarLiteralType) {}
141+
}
142+
let _: USLD = .init(unicodeScalarLiteral: "a") // expected-warning{{'init(unicodeScalarLiteral:)' is deprecated}}
143+
let _: USLD = "a" // expected-warning{{'init(unicodeScalarLiteral:)' is deprecated}}
144+
145+
struct USLU {}
146+
@available(macOS 100, *)
147+
extension USLU: ExpressibleByUnicodeScalarLiteral {
148+
typealias UnicodeScalarLiteralType = Character
149+
init(unicodeScalarLiteral value: UnicodeScalarLiteralType) {}
150+
}
151+
let _: USLU = .init(unicodeScalarLiteral: "a") // expected-error{{'init(unicodeScalarLiteral:)' is only available in macOS 100 or newer}} expected-note{{add 'if #available' version check}}
152+
let _: USLU = "a" // expected-error{{'init(unicodeScalarLiteral:)' is only available in macOS 100 or newer}} expected-note{{add 'if #available' version check}}
153+
154+
//ExpressibleByExtendedGraphemeClusterLiteral
155+
struct GCLD {}
156+
@available(*, deprecated)
157+
extension GCLD: ExpressibleByExtendedGraphemeClusterLiteral {
158+
init(extendedGraphemeClusterLiteral value: Character) {}
159+
}
160+
let _: GCLD = .init(extendedGraphemeClusterLiteral: "🇧🇷") // expected-warning{{'init(extendedGraphemeClusterLiteral:)' is deprecated}}
161+
let _: GCLD = "🇧🇷" // expected-warning{{'init(extendedGraphemeClusterLiteral:)' is deprecated}}
162+
163+
struct GCLU {}
164+
@available(macOS 100, *)
165+
extension GCLU: ExpressibleByExtendedGraphemeClusterLiteral {
166+
init(extendedGraphemeClusterLiteral value: Character) {}
167+
}
168+
let _: GCLU = .init(extendedGraphemeClusterLiteral: "🇧🇷") // expected-error{{'init(extendedGraphemeClusterLiteral:)' is only available in macOS 100 or newer}} expected-note{{add 'if #available' version check}}
169+
let _: GCLU = "🇧🇷" // expected-error{{'init(extendedGraphemeClusterLiteral:)' is only available in macOS 100 or newer}} expected-note{{add 'if #available' version check}}

0 commit comments

Comments
 (0)