-
Notifications
You must be signed in to change notification settings - Fork 10.2k
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
[Don't merge] Use conditional conformances to implement Equatable for Optional, Array and Dictionary #12868
Closed
Closed
[Don't merge] Use conditional conformances to implement Equatable for Optional, Array and Dictionary #12868
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains 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 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 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 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 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 |
---|---|---|
|
@@ -313,98 +313,100 @@ func _diagnoseUnexpectedNilOptional(_filenameStart: Builtin.RawPointer, | |
line: UInt(_line)) | ||
} | ||
|
||
/// Returns a Boolean value indicating whether two optional instances are | ||
/// equal. | ||
/// | ||
/// Use this equal-to operator (`==`) to compare any two optional instances of | ||
/// a type that conforms to the `Equatable` protocol. The comparison returns | ||
/// `true` if both arguments are `nil` or if the two arguments wrap values | ||
/// that are equal. Conversely, the comparison returns `false` if only one of | ||
/// the arguments is `nil` or if the two arguments wrap values that are not | ||
/// equal. | ||
/// | ||
/// let group1 = [1, 2, 3, 4, 5] | ||
/// let group2 = [1, 3, 5, 7, 9] | ||
/// if group1.first == group2.first { | ||
/// print("The two groups start the same.") | ||
/// } | ||
/// // Prints "The two groups start the same." | ||
/// | ||
/// You can also use this operator to compare a non-optional value to an | ||
/// optional that wraps the same type. The non-optional value is wrapped as an | ||
/// optional before the comparison is made. In the following example, the | ||
/// `numberToMatch` constant is wrapped as an optional before comparing to the | ||
/// optional `numberFromString`: | ||
/// | ||
/// let numberToFind: Int = 23 | ||
/// let numberFromString: Int? = Int("23") // Optional(23) | ||
/// if numberToFind == numberFromString { | ||
/// print("It's a match!") | ||
/// } | ||
/// // Prints "It's a match!" | ||
/// | ||
/// An instance that is expressed as a literal can also be used with this | ||
/// operator. In the next example, an integer literal is compared with the | ||
/// optional integer `numberFromString`. The literal `23` is inferred as an | ||
/// `Int` instance and then wrapped as an optional before the comparison is | ||
/// performed. | ||
/// | ||
/// if 23 == numberFromString { | ||
/// print("It's a match!") | ||
/// } | ||
/// // Prints "It's a match!" | ||
/// | ||
/// - Parameters: | ||
/// - lhs: An optional value to compare. | ||
/// - rhs: Another optional value to compare. | ||
@_inlineable | ||
public func == <T: Equatable>(lhs: T?, rhs: T?) -> Bool { | ||
switch (lhs, rhs) { | ||
case let (l?, r?): | ||
return l == r | ||
case (nil, nil): | ||
return true | ||
default: | ||
return false | ||
extension Optional : Equatable where Wrapped : Equatable { | ||
/// Returns a Boolean value indicating whether two optional instances are | ||
/// equal. | ||
/// | ||
/// Use this equal-to operator (`==`) to compare any two optional instances of | ||
/// a type that conforms to the `Equatable` protocol. The comparison returns | ||
/// `true` if both arguments are `nil` or if the two arguments wrap values | ||
/// that are equal. Conversely, the comparison returns `false` if only one of | ||
/// the arguments is `nil` or if the two arguments wrap values that are not | ||
/// equal. | ||
/// | ||
/// let group1 = [1, 2, 3, 4, 5] | ||
/// let group2 = [1, 3, 5, 7, 9] | ||
/// if group1.first == group2.first { | ||
/// print("The two groups start the same.") | ||
/// } | ||
/// // Prints "The two groups start the same." | ||
/// | ||
/// You can also use this operator to compare a non-optional value to an | ||
/// optional that wraps the same type. The non-optional value is wrapped as an | ||
/// optional before the comparison is made. In the following example, the | ||
/// `numberToMatch` constant is wrapped as an optional before comparing to the | ||
/// optional `numberFromString`: | ||
/// | ||
/// let numberToFind: Int = 23 | ||
/// let numberFromString: Int? = Int("23") // Optional(23) | ||
/// if numberToFind == numberFromString { | ||
/// print("It's a match!") | ||
/// } | ||
/// // Prints "It's a match!" | ||
/// | ||
/// An instance that is expressed as a literal can also be used with this | ||
/// operator. In the next example, an integer literal is compared with the | ||
/// optional integer `numberFromString`. The literal `23` is inferred as an | ||
/// `Int` instance and then wrapped as an optional before the comparison is | ||
/// performed. | ||
/// | ||
/// if 23 == numberFromString { | ||
/// print("It's a match!") | ||
/// } | ||
/// // Prints "It's a match!" | ||
/// | ||
/// - Parameters: | ||
/// - lhs: An optional value to compare. | ||
/// - rhs: Another optional value to compare. | ||
@_inlineable | ||
public static func ==(lhs: Wrapped?, rhs: Wrapped?) -> Bool { | ||
switch (lhs, rhs) { | ||
case let (l?, r?): | ||
return l == r | ||
case (nil, nil): | ||
return true | ||
default: | ||
return false | ||
} | ||
} | ||
|
||
/// Returns a Boolean value indicating whether two optional instances are not | ||
/// equal. | ||
/// | ||
/// Use this not-equal-to operator (`!=`) to compare any two optional instances | ||
/// of a type that conforms to the `Equatable` protocol. The comparison | ||
/// returns `true` if only one of the arguments is `nil` or if the two | ||
/// arguments wrap values that are not equal. The comparison returns `false` | ||
/// if both arguments are `nil` or if the two arguments wrap values that are | ||
/// equal. | ||
/// | ||
/// let group1 = [2, 4, 6, 8, 10] | ||
/// let group2 = [1, 3, 5, 7, 9] | ||
/// if group1.first != group2.first { | ||
/// print("The two groups start differently.") | ||
/// } | ||
/// // Prints "The two groups start differently." | ||
/// | ||
/// You can also use this operator to compare a non-optional value to an | ||
/// optional that wraps the same type. The non-optional value is wrapped as an | ||
/// optional before the comparison is made. In this example, the | ||
/// `numberToMatch` constant is wrapped as an optional before comparing to the | ||
/// optional `numberFromString`: | ||
/// | ||
/// let numberToFind: Int = 23 | ||
/// let numberFromString: Int? = Int("not-a-number") // nil | ||
/// if numberToFind != numberFromString { | ||
/// print("No match.") | ||
/// } | ||
/// // Prints "No match." | ||
/// | ||
/// - Parameters: | ||
/// - lhs: An optional value to compare. | ||
/// - rhs: Another optional value to compare. | ||
@_inlineable | ||
public static func !=(lhs: Wrapped?, rhs: Wrapped?) -> Bool { | ||
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. Ditto |
||
return !(lhs == rhs) | ||
} | ||
} | ||
|
||
/// Returns a Boolean value indicating whether two optional instances are not | ||
/// equal. | ||
/// | ||
/// Use this not-equal-to operator (`!=`) to compare any two optional instances | ||
/// of a type that conforms to the `Equatable` protocol. The comparison | ||
/// returns `true` if only one of the arguments is `nil` or if the two | ||
/// arguments wrap values that are not equal. The comparison returns `false` | ||
/// if both arguments are `nil` or if the two arguments wrap values that are | ||
/// equal. | ||
/// | ||
/// let group1 = [2, 4, 6, 8, 10] | ||
/// let group2 = [1, 3, 5, 7, 9] | ||
/// if group1.first != group2.first { | ||
/// print("The two groups start differently.") | ||
/// } | ||
/// // Prints "The two groups start differently." | ||
/// | ||
/// You can also use this operator to compare a non-optional value to an | ||
/// optional that wraps the same type. The non-optional value is wrapped as an | ||
/// optional before the comparison is made. In this example, the | ||
/// `numberToMatch` constant is wrapped as an optional before comparing to the | ||
/// optional `numberFromString`: | ||
/// | ||
/// let numberToFind: Int = 23 | ||
/// let numberFromString: Int? = Int("not-a-number") // nil | ||
/// if numberToFind != numberFromString { | ||
/// print("No match.") | ||
/// } | ||
/// // Prints "No match." | ||
/// | ||
/// - Parameters: | ||
/// - lhs: An optional value to compare. | ||
/// - rhs: Another optional value to compare. | ||
@_inlineable | ||
public func != <T : Equatable>(lhs: T?, rhs: T?) -> Bool { | ||
return !(lhs == rhs) | ||
} | ||
|
||
// Enable pattern matching against the nil literal, even if the element type | ||
|
This file contains 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,17 @@ | ||
// RUN: %target-typecheck-verify-swift -typecheck %s -verify | ||
|
||
// rdar://problem/35480952 | ||
|
||
postfix operator %%% | ||
protocol P { | ||
static postfix func %%%(lhs: Self) | ||
} | ||
protocol Q {} | ||
struct Foo<T> {} | ||
extension Foo: P where T : Q { | ||
static postfix func %%%(lhs: Foo<T>) {} | ||
} | ||
|
||
func useIt<T: Q>(_: T.Type) { | ||
Foo<T>()%%% | ||
} |
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.
@airspeedswift We no longer need to define
operator!=
do we?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.
Unless its implementation is more efficient than
!(==)
.