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
Implement SE-0112: Improved NSError bridging #3459
Merged
Merged
Conversation
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
@swift-ci please test and merge |
DougGregor
force-pushed
the
nserror-bridging
branch
from
July 12, 2016 16:50
205eb22
to
4f0f80e
Compare
Introduce bridging of NSError to ErrorProtocol, so an Objective-C API expressed via an "NSError *" will be imported using ErrorProtocol in the Swift. For example, the Objective-C method: - (void)handleError:(NSError *)error userInteractionPermitted:(BOOL)userInteractionPermitted; will now be imported as: func handleError(_ error: ErrorProtocol, userInteractionPermitted: Bool) This is bullet (3) under the proposed solution of SE-0112. Note that we made one semantic change here: instead of removing the conformance of NSError to ErrorProtocol, which caused numerous problems both theoretical and actual because the model expects that an NSError conforms to ErrorProtocol without requiring wrapping, we instead limit the ErrorProtocol -> NSError conversion that would be implied by bridging. This is defensible in the short term because it also eliminates the implicit conversion, and aligns with SE-0072, which eliminates implicit bridging conversions altogether.
…subscript decls. For historical reasons, the "name shadowing" computation is only looking at the type---not even the interface type!---of declarations. For variables and subscripts, this means that the context (e.g., a constrained extension) wasn't been considered at all, leading to declarations from other imported modules being ignored. Patch up a little bit of this by using the overload signature's type for variables and subscripts, because I need it for ErrorProtocol's default implementations. Longer-term, we should be using the overload signature (or something very like it) for shadowing, consistently.
…mNSError An error type can conform to one or more of these new protocols to customize its behavior and representation. From an implementation standpoint, the protocol conformances are used to fill in the user-info dictionary in NSError to interoperate with the Cocoa error-handling system. There are a few outstanding problems with this implementation, although it is fully functional: * Population of the userInfo dictionary is currently eager; we should use user info providers on platforms where they are available. * At present, the Swift dynamic casting machinery is unable to unbox a _SwiftNativeNSError when trying to cast from it to (e.g.) an existential, which makes it impossible to retrieve the RecoverableError from the NSError. Instead, just capture the original error---hey, they're supposed to be value types anyway!---and use that to implement the entry points for the informal NSErrorRecoveryAttempting protocol. This is part (1) of the proposal solution.
Provides a localized description for an error, using Cocoa's error-handling logic. The first part of item (4) in SE-0112's proposed solution.
This is part of loosening _BridgedNSError up a bit, so it can work with error types that directly embed an NSError instance.
NSCocoaError was capturing only the code of a Cocoa error, making it basically useless. Instead, capture the entire NSError, the code of which is tracked by an nested, RawRepresentable type Code. Provide typed accessors for the common keys in the Cocoa error domain, e.g., NSFilePathErrorKey, NSStringEncodingErrorKey, NSUnderlyingErrorKey, and NSURLErrorKey, to make this type easier to use. This is specifically an implementation of part (4) of the proposed solution to SE-0112, which makes NSCocoaError more usable. It also adds localizedDescription to ErrorProtocol. However, it also introduces the infrastructure needed for importing error enumeration types more smoothly, e.g., ErrorCodeProtocol (underscored for now), the ~= operator for matching error codes, and so on. In essence, NSCocoaError is the pattern that the importer will follow.
This ensures that we don't lose information about the NSError when it is bridged to NSError. Use this to expose information for common keys in the NSURLError domain (NSURLErrorFailingURLErrorKey, NSURLErrorFailingURLStringErrorKey, NSURLErrorFailingURLPeerTrustErrorKey). This is effectively part of bullet (4) in the proposed solution of SE-0112, applied to NSURLError. There are a handful of other domains that need this treatment as well.
The error domain is meant to identify the type; it cannot meaningfully vary.
This will get clearer when SE-0104 gets implemented and we can use the Integer protocol.
The error code is now specified by POSIXErrorCode.
The error code is now specified by MachErrorCode.
A given Objective-C error enum, which is effectively an NS_ENUM that specifies its corresponding error domain, will now be mapped to an ErrorProtocol-conforming struct that wraps an NSError, much like NSCocoaError does. The actual enum is mapped to a nested "Code" enum. For example, CoreLocation's CLError becomes: struct CLError : ErrorProtocol { let _nsError: NSError // ... @objc enum Code : Int { case ... } } This implements bullet (2) in the proposed solution of SE-0112, so that Cocoa error types are mapped into structures that maintain the underlying NSError to allow more information to be extracted from it.
…very(optionIndex:resultHandler:).
This is bullet (5) of the proposed solution in SE-0112, and the last major piece to be implemented.
DougGregor
force-pushed
the
nserror-bridging
branch
from
July 12, 2016 17:54
4f0f80e
to
d53a2f6
Compare
kateinoigakukun
pushed a commit
that referenced
this pull request
Aug 31, 2022
Resolve conflicts with upstream `main`
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
What's in this pull request?
This pull request implements SE-0112
Resolved bug number: (rdar://problem/27174964)
It looks like this PR might address several other open issues on bugs.swift.org. I'll scrub those as well.
Before merging this pull request to apple/swift repository:
Triggering Swift CI
The swift-ci is triggered by writing a comment on this PR addressed to the GitHub user @swift-ci. Different tests will run depending on the specific comment that you use. The currently available comments are:
Smoke Testing
Validation Testing
Lint Testing
Note: Only members of the Apple organization can trigger swift-ci.