-
Notifications
You must be signed in to change notification settings - Fork 10.6k
SE-0235: Add Result<Success, Failure: Error> to Standard Library #20958
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
Conversation
|
I did run into some awkwardness on line 74 of the tests, where I couldn't use the property accessor for |
It should be the year of first publication: See SR-7507 and #14576 (comment). |
test/stdlib/Result.swift
Outdated
| return nil | ||
| } | ||
|
|
||
| var error: Error? { |
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.
This is nested inside var value: Value?, which is why you aren't able to call result.error. IMO, it's better to just remove this extension and remove those tests.
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.
Thanks, fixed in 7fb5905. I'd like to leave the tests for now, as they're the only ones testing the unwrapping. I can remove the property extension if you think that's important.
|
@benrimmington @slavapestov Copyright year fixed in 7fb5905. |
|
@natecook1000, do you mind looking at the doc comments? |
|
@swift-ci Please test |
|
Now that #20629 has been merged, I would expect the diff to only contain stdlib changes... |
|
Build failed |
Co-Authored-By: jshier <[email protected]>
Co-Authored-By: jshier <[email protected]>
| expectEqual(newResult4, .failure(.err)) | ||
| } | ||
|
|
||
| ResultTests.test("Equatable") { |
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.
Did you consider using the checkEquatable from StdlibUnitTest?
https://github.com/apple/swift/blob/master/stdlib/private/StdlibUnittest/StdlibUnittest.swift#L2171
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.
No, as I mostly cribbed these tests by looking at those from Optional and earlier feedback. I didn't know that existed. Can you provide an example of what they would simplify here?
In general, is there any documentation around this special StdlibUnittest API or testing requirements for the standard library?
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 was just thinking out loud really. These conformances are synthesized by the compiler, and should be working. Otherwise we're in trouble.
In general, is there any documentation around this special StdlibUnittest API or testing requirements for the standard library?
Unfortunately no.
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.
Can you provide an example of what they would simplify here?
It's not about simplification. Just that checkEquatable tests for the cases you and I might not necessarily think about, like whether == is transitive or not, or whether the implementation is correct in that == is the opposite of !=.
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've added a use of checkEquatable, in additional to the tests that were already there. Let me know if there're any other scenarios you want tested, or if you feel the tests are now redundant.
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.
Note: checkHashable starts by calling checkEquatable -- so it is okay to omit the checkEquatable test if we have tests elsewhere with checkHashable.
|
@jshier do you mind creating a separate PR for the |
|
@swift-ci Please test |
Sure. From this same branch to the |
|
#21073 isn't merged yet. |
Just
But when it lands, we will have a PR ready for CI :-) |
|
Build failed |
Is it worth squashing the stdlib commits and rebasing from master? |
| let result1: Result<Int, Err> = .success(1) | ||
| let result2: Result<Int, Err> = .success(2) | ||
| let result3: Result<Int, Err> = .failure(.err) | ||
| checkHashable([result1, result2, result3], equalityOracle: { $0 == $1 }) |
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.
It would also be useful to have a hashing check with potentially colliding Success/Failure hash encodings:
| checkHashable([result1, result2, result3], equalityOracle: { $0 == $1 }) | |
| checkHashable([result1, result2, result3], equalityOracle: { $0 == $1 }) | |
| let confusables: [Result<Err, Err>] = [ | |
| .success(.err) | |
| .success(.derr) | |
| .failure(.err) | |
| .failure(.derr) | |
| ] | |
| checkHashable(confusables, equalityOracle: { $0 == $1 }) |
checkHashable verifies that all four of these cases have different hash encodings. (The original implementation of hash(into:) had an issue with this, so it's not a theoretical concern.)
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.
Added.
xwu
left a comment
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.
Some comments on the documentation.
stdlib/public/core/Result.swift
Outdated
| public init(catching body: () throws -> Success) { | ||
| do { | ||
| let value = try body() | ||
| self = .success(value) |
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.
Why split these lines instead of just
self = .success(try body())
? I'm curious, as that's something I do a lot in my code
xwu
left a comment
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.
Some minor nits, but I like the changes to the documentation; @natecook1000, of course, is the guru and may have wiser thoughts.
stdlib/public/core/Result.swift
Outdated
| /// | ||
| /// - Parameter transform: A closure that takes the success value of the | ||
| /// instance. | ||
| /// - Returns: A`Result` instance, either from the closure or the previous |
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.
| /// - Returns: A`Result` instance, either from the closure or the previous | |
| /// - Returns: A `Result` instance, either from the closure or the previous |
stdlib/public/core/Result.swift
Outdated
| /// Get the success value as a throwing expression. | ||
| /// | ||
| /// - Returns: The success value, if the instance is `.success`. | ||
| /// - Throws: The failure value, if the instance is `.failure`. |
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.
| /// - Throws: The failure value, if the instance is `.failure`. | |
| /// - Throws: The failure value, if the instance is `.failure`. |
stdlib/public/core/Result.swift
Outdated
|
|
||
| extension Result where Failure == Swift.Error { | ||
| /// Create an instance by evaluating a throwing closure, capturing the | ||
| /// returned value as a `.success` or any thrown error as `.failure`. |
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.
| /// returned value as a `.success` or any thrown error as `.failure`. | |
| /// returned value as a `.success` or any thrown error as a `.failure`. |
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.
![]()
|
@swift-ci Please test |
|
Build failed |
|
Build failed |
|
swiftlang/swift-package-manager#1912 |
|
Build failed |
|
Build failed |
|
swiftlang/swift-package-manager#1912 |
|
Build failed |
|
@swift-ci Please test source compatibility |
|
@moiseev Should there be a CHANGELOG entry for this? Also, should I do a PR to update the proposal text to match the final implementation? |
|
@jshier update to a proposal would be great. Don't know the policy for UPD: Yes, please update the |
This PR adds the updated
Resultimplementation for SE-0235, as I broke the last PR when trying to rebase off of @rjmccall'sErrorself conformance PR. Previous PR discussion and review was here.This PR includes #20629, as
Errorself conformance is required for this implementation ofResult.