Skip to content

Commit

Permalink
Fully qualify uses of Result in scaffolding/macro code
Browse files Browse the repository at this point in the history
PR mozilla#1469 introduced an incompatibility with a local `type Result<T> =
std::result::Result<T, MyError>` type alias. As can be seen with the included
test without the fix applied:

```
error[E0107]: this type alias takes 1 generic argument but 2 generic arguments were supplied
  --> /mounted_workdir/target/debug/build/unary-result-alias-f408c03f1955dadd/out/unary-result-alias.uniffi.rs:79:1
   |
79 | / #[::uniffi::ffi_converter_error(
80 | |     tag = crate::UniFfiTag,
81 | |     flat_error,
82 | |
83 | | )]
   | |  ^
   | |  |
   | |__expected 1 generic argument
   |    help: remove this generic argument
   |
note: type alias defined here, with 1 generic parameter: `T`
  --> fixtures/regressions/unary-result-alias/src/lib.rs:7:10
   |
7  | pub type Result<T> = std::result::Result<T, MyError>;
   |          ^^^^^^ -
   = note: this error originates in the macro `::uniffi::ffi_converter_default_return` which comes from the expansion of the attribute macro `::uniffi::ffi_converter_error` (in Nightly builds, run with -Z macro-backtrace for more info)
```

Fixing the macros in `uniffi_core` to use `::std::result::Result` fixes that.

This exposes a further case in the generated code:

```
error[E0107]: this type alias takes 1 generic argument but 2 generic arguments were supplied
   --> /mounted_workdir/target/debug/build/unary-result-alias-f408c03f1955dadd/out/unary-result-alias.uniffi.rs:108:40
    |
108 |     uniffi::rust_call(call_status, || <Result<(), r#MyError> as ::uniffi::FfiConverter<crate::UniFfiTag>>::lower_return(
    |                                        ^^^^^^     --------- help: remove this generic argument
    |                                        |
    |                                        expected 1 generic argument
    |
note: type alias defined here, with 1 generic parameter: `T`
   --> fixtures/regressions/unary-result-alias/src/lib.rs:7:10
    |
7   | pub type Result<T> = std::result::Result<T, MyError>;
    |          ^^^^^^ -
```

So the same change is required to the output produced by bindgen.
  • Loading branch information
ijc committed Apr 6, 2023
1 parent d0220e3 commit 96aa912
Show file tree
Hide file tree
Showing 12 changed files with 86 additions and 3 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ members = [
"fixtures/regressions/missing-newline",
"fixtures/regressions/swift-callbacks-omit-labels",
"fixtures/regressions/swift-dictionary-nesting",
"fixtures/regressions/unary-result-alias",
"fixtures/uitests",
"fixtures/uniffi-fixture-time",
"fixtures/version-mismatch",
Expand Down
20 changes: 20 additions & 0 deletions fixtures/regressions/unary-result-alias/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[package]
name = "unary-result-alias"
version = "0.1.0"
edition = "2021"
license = "MPL-2.0"
publish = false

[lib]
name = "uniffi_unary_result_alias"
crate-type = ["lib", "cdylib"]

[dependencies]
uniffi = { path = "../../../uniffi" }
thiserror = "1.0"

[build-dependencies]
uniffi = {path = "../../../uniffi", features = ["build"] }

[dev-dependencies]
uniffi = {path = "../../../uniffi", features = ["bindgen-tests"] }
7 changes: 7 additions & 0 deletions fixtures/regressions/unary-result-alias/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Ensure that generated bindings are compatible with crates which have a
local

```rust
pub enum MyError { ... };
pub type Result<T> = std::result::Result<T, MyError>
```
7 changes: 7 additions & 0 deletions fixtures/regressions/unary-result-alias/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

fn main() {
uniffi::generate_scaffolding("./src/unary-result-alias.udl").unwrap();
}
13 changes: 13 additions & 0 deletions fixtures/regressions/unary-result-alias/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#[derive(Debug, thiserror::Error)]
pub enum MyError {
#[error("Badness has happened")]
AllGoneWrong,
}

pub type Result<T> = std::result::Result<T, MyError>;

pub fn returns_unary_result_alias() -> Result<()> {
Ok(())
}

include!(concat!(env!("OUT_DIR"), "/unary-result-alias.uniffi.rs"));
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[Error]
enum MyError {
"AllGoneWrong",
};

namespace unary_result_alias {
[Throws=MyError]
void returns_unary_result_alias();
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// This is just a basic "it compiled and ran" test.
// What we're really guarding against is failure to
// compile the bindings as a result of buggy codegen.

import uniffi.unary_result_alias.*

returnsUnaryResultAlias()
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# This is just a basic "it loaded and ran" test.
# What we're really guarding against is failure to
# load the bindings as a result of buggy codegen.

from unary_result_alias import *

returns_unary_result_alias()
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// This is just a basic "it compiled and run" test.
// What we're really guarding against is failure to
// compile the bindings as a result of buggy codegen.

import unary_result_alias

try returnsUnaryResultAlias()
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
uniffi::build_foreign_language_testcases!(
"tests/bindings/test.py",
"tests/bindings/test.kts",
"tests/bindings/test.swift",
);
2 changes: 1 addition & 1 deletion uniffi_bindgen/src/scaffolding/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ mod filters {
};
Ok(match callable.throws_type() {
Some(e) => format!(
"<Result<{}, {}> as ::uniffi::FfiConverter<crate::UniFfiTag>>",
"<std::result::Result<{}, {}> as ::uniffi::FfiConverter<crate::UniFfiTag>>",
result_type,
type_rs(&e)?
),
Expand Down
4 changes: 2 additions & 2 deletions uniffi_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ macro_rules! ffi_converter_default_return {
($uniffi_tag:ty) => {
type ReturnType = <Self as $crate::FfiConverter<$uniffi_tag>>::FfiType;

fn lower_return(v: Self) -> Result<Self::FfiType, $crate::RustBuffer> {
fn lower_return(v: Self) -> ::std::result::Result<Self::FfiType, $crate::RustBuffer> {
Ok(<Self as $crate::FfiConverter<$uniffi_tag>>::lower(v))
}
};
Expand Down Expand Up @@ -338,7 +338,7 @@ macro_rules! ffi_converter_forward {
<$T as $crate::FfiConverter<$existing_impl_tag>>::lower(obj)
}

fn lower_return(v: Self) -> Result<Self::ReturnType, $crate::RustBuffer> {
fn lower_return(v: Self) -> ::std::result::Result<Self::ReturnType, $crate::RustBuffer> {
<$T as $crate::FfiConverter<$existing_impl_tag>>::lower_return(v)
}

Expand Down

0 comments on commit 96aa912

Please sign in to comment.