uniffi-rs icon indicating copy to clipboard operation
uniffi-rs copied to clipboard

uniffi-bindgen 0.14.0 - Swift errors with associated data do not conform with the Error protocol

Open AlexDBlack opened this issue 3 years ago • 0 comments

Related: https://github.com/mozilla/uniffi-rs/issues/1062 Note it's a different problem and fix required (i.e., fixing #1062 won't fix this), but this Swift code generation issue can be reproduced with the same test case.

In Uniffi, it's possible to define errors in two ways: [Error] enum MyError - with String messages [Enum] interface MyError - with arbitrary associated data https://mozilla.github.io/uniffi-rs/udl/errors.html

Using the latter produces Swift error enumerations that do not conform with the Error protocol.

Interface definition:

namespace test {
    [Throws=TestError]
    string foo();
};

[Enum]
interface TestError {
    FirstError(string err);
    SecondError(u32 value);
};

Generated Swift enumeration (error) and function call:

public enum TestError {
    case firstError(err: String )
    case secondError(value: UInt32 )
}

public func foo() throws -> String {
    let _retval = try
    
    
    rustCallWithError(TestError.self) {
    
    test_8c63_foo( $0)
}
    return try String.lift(_retval)
}

private func rustCallWithError<T, E: ViaFfiUsingByteBuffer & Error>(_ errorClass: E.Type, _ callback: (UnsafeMutablePointer<RustCallStatus>) -> T) throws -> T {

Note that the Error type for rustCallWithError requires conformance with the Error protocol -- which the generated TestError enumeration does not have.

The fix: the TestError type needs to conform to the Swift Error protocol i.e.,

public enum TestError {

should become

public enum TestError : Error {

Example of this producing a compilation error in XCode: image

┆Issue is synchronized with this Jira Task ┆Issue Number: UNIFFI-95

AlexDBlack avatar Oct 05 '21 07:10 AlexDBlack