-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[Sema] Perform availability checks in literals initializers #61805
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
LucianoPAlmeida
merged 1 commit into
swiftlang:main
from
LucianoPAlmeida:availability-check-literal
Nov 2, 2022
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
// RUN: %target-typecheck-verify-swift -swift-version 5 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I love the thoroughness of this test, thanks! |
||
|
||
// REQUIRES: OS=macosx | ||
|
||
// https://github.com/apple/swift/issues/61564 | ||
// ExpressibleByStringLiteral | ||
struct SLD {} | ||
@available(*, deprecated) | ||
extension SLD: ExpressibleByStringLiteral { | ||
init(stringLiteral value: StringLiteralType) {} | ||
} | ||
|
||
let _ = SLD(stringLiteral: "") // expected-warning{{'init(stringLiteral:)' is deprecated}} | ||
let _: SLD = "" // expected-warning{{'init(stringLiteral:)' is deprecated}} | ||
|
||
|
||
struct SLU {} | ||
@available(macOS 100, *) | ||
extension SLU: ExpressibleByStringLiteral { | ||
init(stringLiteral value: StringLiteralType) {} | ||
} | ||
|
||
let _ = SLU(stringLiteral: "") // expected-error{{'init(stringLiteral:)' is only available in macOS 100 or newer}} expected-note{{add 'if #available' version check}} | ||
let _: SLU = "" // expected-error{{'init(stringLiteral:)' is only available in macOS 100 or newer}} expected-note{{add 'if #available' version check}} | ||
|
||
// ExpressibleByIntegerLiteral | ||
struct ILD {} | ||
@available(*, deprecated) | ||
extension ILD: ExpressibleByIntegerLiteral { | ||
init(integerLiteral value: IntegerLiteralType) {} | ||
} | ||
|
||
let _ = ILD(integerLiteral: 1) // expected-warning{{'init(integerLiteral:)' is deprecated}} | ||
let _: ILD = 1 // expected-warning{{'init(integerLiteral:)' is deprecated}} | ||
|
||
struct ILU {} | ||
|
||
@available(macOS 100, *) | ||
extension ILU: ExpressibleByIntegerLiteral { | ||
init(integerLiteral value: IntegerLiteralType) {} | ||
} | ||
|
||
let _ = ILU(integerLiteral: 1) // expected-error{{'init(integerLiteral:)' is only available in macOS 100 or newer}} expected-note{{add 'if #available' version check}} | ||
let _: ILU = 1 // expected-error{{'init(integerLiteral:)' is only available in macOS 100 or newer}} expected-note{{add 'if #available' version check}} | ||
|
||
// ExpressibleByNilLiteral | ||
struct NLD {} | ||
|
||
@available(*, deprecated) | ||
extension NLD: ExpressibleByNilLiteral { | ||
init(nilLiteral: ()) {} | ||
} | ||
|
||
let _: NLD = .init(nilLiteral: ()) // expected-warning{{'init(nilLiteral:)' is deprecated}} | ||
let _: NLD = nil // expected-warning{{'init(nilLiteral:)' is deprecated}} | ||
|
||
struct NLU {} | ||
|
||
@available(macOS 100, *) | ||
extension NLU: ExpressibleByNilLiteral { | ||
init(nilLiteral: ()) {} | ||
} | ||
|
||
let _: NLU = .init(nilLiteral: ()) // expected-error{{'init(nilLiteral:)' is only available in macOS 100 or newer}} expected-note{{add 'if #available' version check}} | ||
let _: NLU = nil // expected-error{{'init(nilLiteral:)' is only available in macOS 100 or newer}} expected-note{{add 'if #available' version check}} | ||
|
||
// ExpressibleByBooleanLiteral | ||
struct BLD {} | ||
@available(*, deprecated) | ||
extension BLD: ExpressibleByBooleanLiteral { | ||
init(booleanLiteral value: BooleanLiteralType) {} | ||
} | ||
let _: BLD = .init(booleanLiteral: false) // expected-warning{{'init(booleanLiteral:)' is deprecated}} | ||
let _: BLD = false // expected-warning{{'init(booleanLiteral:)' is deprecated}} | ||
|
||
struct BLU {} | ||
@available(macOS 100, *) | ||
extension BLU: ExpressibleByBooleanLiteral { | ||
init(booleanLiteral value: BooleanLiteralType) {} | ||
} | ||
let _: BLU = .init(booleanLiteral: false) // expected-error{{'init(booleanLiteral:)' is only available in macOS 100 or newer}} expected-note{{add 'if #available' version check}} | ||
let _: BLU = false // expected-error{{'init(booleanLiteral:)' is only available in macOS 100 or newer}} expected-note{{add 'if #available' version check}} | ||
|
||
// ExpressibleByFloatLiteral | ||
struct FLD {} | ||
@available(*, deprecated) | ||
extension FLD: ExpressibleByFloatLiteral { | ||
init(floatLiteral value: FloatLiteralType) {} | ||
} | ||
let _: FLD = .init(floatLiteral: 0.1) // expected-warning{{'init(floatLiteral:)' is deprecated}} | ||
let _: FLD = 0.1 // expected-warning{{'init(floatLiteral:)' is deprecated}} | ||
|
||
struct FLU {} | ||
@available(macOS 100, *) | ||
extension FLU: ExpressibleByFloatLiteral { | ||
init(floatLiteral value: FloatLiteralType) {} | ||
} | ||
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}} | ||
let _: FLU = 0.1 // expected-error{{'init(floatLiteral:)' is only available in macOS 100 or newer}} expected-note{{add 'if #available' version check}} | ||
|
||
// ExpressibleByArrayLiteral | ||
struct ALD {} | ||
@available(*, deprecated) | ||
extension ALD: ExpressibleByArrayLiteral { | ||
init(arrayLiteral elements: Int...) {} | ||
} | ||
let _: ALD = .init(arrayLiteral: 1) // expected-warning{{'init(arrayLiteral:)' is deprecated}} | ||
let _: ALD = [1] // expected-warning{{'init(arrayLiteral:)' is deprecated}} | ||
|
||
struct ALU {} | ||
@available(macOS 100, *) | ||
extension ALU: ExpressibleByArrayLiteral { | ||
init(arrayLiteral elements: Int...) {} | ||
} | ||
let _: ALU = .init(arrayLiteral: 1) // expected-error{{'init(arrayLiteral:)' is only available in macOS 100 or newer}} expected-note{{add 'if #available' version check}} | ||
let _: ALU = [1] // expected-error{{'init(arrayLiteral:)' is only available in macOS 100 or newer}} expected-note{{add 'if #available' version check}} | ||
|
||
// ExpressibleByDictionaryLiteral | ||
struct DLD {} | ||
@available(*, deprecated) | ||
extension DLD: ExpressibleByDictionaryLiteral { | ||
init(dictionaryLiteral elements: (Int, Int)...) {} | ||
} | ||
let _: DLD = .init(dictionaryLiteral: (1,1)) // expected-warning{{'init(dictionaryLiteral:)' is deprecated}} | ||
let _: DLD = [1: 1] // expected-warning{{'init(dictionaryLiteral:)' is deprecated}} | ||
|
||
struct DLU {} | ||
@available(macOS 100, *) | ||
extension DLU: ExpressibleByDictionaryLiteral { | ||
init(dictionaryLiteral elements: (Int, Int)...) {} | ||
} | ||
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}} | ||
let _: DLU = [1: 1] // expected-error{{'init(dictionaryLiteral:)' is only available in macOS 100 or newer}} expected-note{{add 'if #available' version check}} | ||
|
||
// ExpressibleByUnicodeScalarLiteral | ||
struct USLD {} | ||
@available(*, deprecated) | ||
extension USLD: ExpressibleByUnicodeScalarLiteral { | ||
typealias UnicodeScalarLiteralType = Character | ||
init(unicodeScalarLiteral value: UnicodeScalarLiteralType) {} | ||
} | ||
let _: USLD = .init(unicodeScalarLiteral: "a") // expected-warning{{'init(unicodeScalarLiteral:)' is deprecated}} | ||
let _: USLD = "a" // expected-warning{{'init(unicodeScalarLiteral:)' is deprecated}} | ||
|
||
struct USLU {} | ||
@available(macOS 100, *) | ||
extension USLU: ExpressibleByUnicodeScalarLiteral { | ||
typealias UnicodeScalarLiteralType = Character | ||
init(unicodeScalarLiteral value: UnicodeScalarLiteralType) {} | ||
} | ||
let _: USLU = .init(unicodeScalarLiteral: "a") // expected-error{{'init(unicodeScalarLiteral:)' is only available in macOS 100 or newer}} expected-note{{add 'if #available' version check}} | ||
let _: USLU = "a" // expected-error{{'init(unicodeScalarLiteral:)' is only available in macOS 100 or newer}} expected-note{{add 'if #available' version check}} | ||
|
||
//ExpressibleByExtendedGraphemeClusterLiteral | ||
struct GCLD {} | ||
@available(*, deprecated) | ||
extension GCLD: ExpressibleByExtendedGraphemeClusterLiteral { | ||
init(extendedGraphemeClusterLiteral value: Character) {} | ||
} | ||
let _: GCLD = .init(extendedGraphemeClusterLiteral: "🇧🇷") // expected-warning{{'init(extendedGraphemeClusterLiteral:)' is deprecated}} | ||
let _: GCLD = "🇧🇷" // expected-warning{{'init(extendedGraphemeClusterLiteral:)' is deprecated}} | ||
|
||
struct GCLU {} | ||
@available(macOS 100, *) | ||
extension GCLU: ExpressibleByExtendedGraphemeClusterLiteral { | ||
init(extendedGraphemeClusterLiteral value: Character) {} | ||
} | ||
let _: GCLU = .init(extendedGraphemeClusterLiteral: "🇧🇷") // expected-error{{'init(extendedGraphemeClusterLiteral:)' is only available in macOS 100 or newer}} expected-note{{add 'if #available' version check}} | ||
let _: GCLU = "🇧🇷" // expected-error{{'init(extendedGraphemeClusterLiteral:)' is only available in macOS 100 or newer}} expected-note{{add 'if #available' version check}} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if this is something that ought to be applied to the result type of a literal in general. e.g for:
We're implicitly forming a call to
S(integerLiteral: 0)
, but aren't erroring that it's unavailable.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A long term goal of mine is to run availability checks on the transformed AST so that we can catch these issues in a more generalized way. Not sure if that applies directly here but it seems like it might.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah these literal cases are tricky because we don't actually form the call in the AST, we emit them directly in SILGen
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll create an issue to track that case and look at it separately =]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hamishknight @tshortli Issue created #61890