Skip to content
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

ffi struct produces warnings on Rust 1.79.0 or +nightly #270

Closed
sax opened this issue Apr 24, 2024 · 5 comments · Fixed by #278
Closed

ffi struct produces warnings on Rust 1.79.0 or +nightly #270

sax opened this issue Apr 24, 2024 · 5 comments · Fixed by #278

Comments

@sax
Copy link
Contributor

sax commented Apr 24, 2024

I have a struct that I use to convert wrapped errors to strings that can be sent to Swift:

#[swift_bridge::bridge]
mod ffi {
  #[swift_bridge(swift_repr = "struct")]
  pub struct BridgedError {
    pub inner: String
  }
}

This compiles without any errors in Rust 1.77.2, but when I compile it with nightly it produces the following warning:

> cargo +nightly build -Zbuild-std --package my-bridge --target aarch64-apple-darwin

error: field `0` is never read
  --> rust/my-bridge/src/lib.rs:17:14
   |
14 | #[swift_bridge::bridge]
   | ----------------------- field in this variant
...
17 |   pub struct BridgedError {
   |              ^^^^^^^^^^^^
   |
note: the lint level is defined here
  --> rust/my-bridge/src/lib.rs:2:38
   |
2  | #![cfg_attr(feature = "strict", deny(warnings))]
   |                                      ^^^^^^^^
   = note: `#[deny(dead_code)]` implied by `#[deny(warnings)]`
help: consider changing the field to be of unit type to suppress this warning while preserving the field numbering, or remove the field
   |
17 |   pub struct () {
   |              ~~

I'm starting to play around with cross-compiling to watchOS, tvOS, and eventually visionOS, but am finding these targets only seem to build on nightly.

@chinedufn
Copy link
Owner

chinedufn commented Apr 28, 2024

Thanks for reporting this.

Looks like a similar to issue was opened for rustc 3 weeks ago rust-lang/rust#123418


Mind sharing a simple bridge module that reproduces this warning?

I cannot reproduce this warning using the provided example.

@Bright-Shard
Copy link
Contributor

Bright-Shard commented Apr 28, 2024

Also on nightly some of the ui tests fail to run. It looks like very minor issues - unexpected warnings (maybe related to that issue?) and some of the spans seem to have changed.

Output
test tests/ui/args-into-argument-not-found.rs ... mismatch

EXPECTED:
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
error: Argument "arg_typo" was not found in "fn some_function(..)"
 --> tests/ui/args-into-argument-not-found.rs:7:42
  |
7 |         #[swift_bridge(args_into = (arg, arg_typo))]
  |                                          ^^^^^^^^

error: Argument "bar" was not found in "fn some_method(..)"
  --> tests/ui/args-into-argument-not-found.rs:13:42
   |
13 |         #[swift_bridge(args_into = (foo, bar))]
   |                                          ^^^
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈

ACTUAL OUTPUT:
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
error: Argument "arg_typo" was not found in "fn some_function(..)"
 --> tests/ui/args-into-argument-not-found.rs:7:42
  |
7 |         #[swift_bridge(args_into = (arg, arg_typo))]
  |                                          ^^^^^^^^

error: Argument "bar" was not found in "fn some_method(..)"
  --> tests/ui/args-into-argument-not-found.rs:13:42
   |
13 |         #[swift_bridge(args_into = (foo, bar))]
   |                                          ^^^

warning: unused variable: `arg`
  --> tests/ui/args-into-argument-not-found.rs:18:18
   |
18 | fn some_function(arg: u8) {}
   |                  ^^^ help: if this is intentional, prefix it with an underscore: `_arg`
   |
   = note: `#[warn(unused_variables)]` on by default

warning: unused variable: `foo`
  --> tests/ui/args-into-argument-not-found.rs:23:27
   |
23 |     fn some_method(&self, foo: u8) {}
   |                           ^^^ help: if this is intentional, prefix it with an underscore: `_foo`
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
note: If the actual output is the correct output you can bless it by rerunning
      your test with the environment variable TRYBUILD=overwrite

test tests/ui/incorrect-argument-type.rs ... mismatch

EXPECTED:
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
error[E0308]: mismatched types
  --> tests/ui/incorrect-argument-type.rs:15:16
   |
10 | #[swift_bridge::bridge]
   | ----------------------- arguments to this function are incorrect
...
15 |         fn fn1(arg: &str);
   |                ^^^^^^ expected `u16`, found `&str`
   |
note: function defined here
  --> tests/ui/incorrect-argument-type.rs:24:4
   |
24 | fn some_function(_arg: u16) {}
   |    ^^^^^^^^^^^^^ ---------
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈

ACTUAL OUTPUT:
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
error[E0308]: mismatched types
  --> tests/ui/incorrect-argument-type.rs:15:16
   |
10 | #[swift_bridge::bridge]
   | ----------------------- arguments to this function are incorrect
...
15 |         fn fn1(arg: &str);
   |                ^^^^^^^^^ expected `u16`, found `&str`
   |
note: function defined here
  --> tests/ui/incorrect-argument-type.rs:24:4
   |
24 | fn some_function(_arg: u16) {}
   |    ^^^^^^^^^^^^^ ---------
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
note: If the actual output is the correct output you can bless it by rerunning
      your test with the environment variable TRYBUILD=overwrite

test tests/ui/incorrect-return-type.rs ... mismatch

EXPECTED:
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
error[E0308]: mismatched types
  --> tests/ui/incorrect-return-type.rs:6:1
   |
6  |   #[swift_bridge::bridge]
   |   ^^^^^^^^^^^^^^^^^^^^^^^ expected `SomeType`, found `&SomeType`
...
9  |           type SomeType;
   |  ______________-
10 | |
11 | |         #[swift_bridge(rust_name = "some_function")]
   | |_________- expected due to this
   |
   = note: this error originates in the attribute macro `swift_bridge::bridge` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0308]: mismatched types
  --> tests/ui/incorrect-return-type.rs:6:1
   |
6  |   #[swift_bridge::bridge]
   |   ^^^^^^^^^^^^^^^^^^^^^^^ expected `SomeType`, found `Option<SomeType>`
...
9  |           type SomeType;
   |  ______________-
10 | |
11 | |         #[swift_bridge(rust_name = "some_function")]
12 | |         fn fn1() -> SomeType;
13 | |         #[swift_bridge(rust_name = "another_function")]
   | |_________- expected due to this
   |
   = note: expected struct `SomeType`
                found enum `Option<SomeType>`
   = note: this error originates in the attribute macro `swift_bridge::bridge` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider using `Option::expect` to unwrap the `Option<SomeType>` value, panicking if the value is an `Option::None`
   |
6  | #[swift_bridge::bridge].expect("REASON")
   |                        +++++++++++++++++
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈

ACTUAL OUTPUT:
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
error[E0308]: mismatched types
  --> tests/ui/incorrect-return-type.rs:6:1
   |
6  |   #[swift_bridge::bridge]
   |   ^^^^^^^^^^^^^^^^^^^^^^^ expected `SomeType`, found `&SomeType`
...
9  |           type SomeType;
   |  ______________-
10 | |
11 | |         #[swift_bridge(rust_name = "some_function")]
12 | |         fn fn1() -> SomeType;
   | |_____________________________- expected due to this
   |
   = note: this error originates in the attribute macro `swift_bridge::bridge` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0308]: mismatched types
  --> tests/ui/incorrect-return-type.rs:6:1
   |
6  |   #[swift_bridge::bridge]
   |   ^^^^^^^^^^^^^^^^^^^^^^^ expected `SomeType`, found `Option<SomeType>`
...
9  |           type SomeType;
   |  ______________-
10 | |
11 | |         #[swift_bridge(rust_name = "some_function")]
12 | |         fn fn1() -> SomeType;
13 | |         #[swift_bridge(rust_name = "another_function")]
14 | |         fn fn2() -> SomeType;
   | |_____________________________- expected due to this
   |
   = note: expected struct `SomeType`
                found enum `Option<SomeType>`
   = note: this error originates in the attribute macro `swift_bridge::bridge` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider using `Option::expect` to unwrap the `Option<SomeType>` value, panicking if the value is an `Option::None`
   |
6  | #[swift_bridge::bridge].expect("REASON")
   |                        +++++++++++++++++
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
note: If the actual output is the correct output you can bless it by rerunning
      your test with the environment variable TRYBUILD=overwrite

test tests/ui/invalid-associated-to-attribute.rs ... ok
test tests/ui/invalid-copy-attribute.rs ... ok
test tests/ui/invalid-module-item.rs ... ok
test tests/ui/opaque-copy-type-mut-ref.rs ... ok
test tests/ui/unrecognized-argument-attribute.rs ... ok
test tests/ui/unrecognized-enum-attribute.rs ... ok
test tests/ui/unrecognized-function-attribute.rs ... ok
test tests/ui/unrecognized-opaque-type-attribute.rs ... ok


test ui_tests::ui ... FAILED

@sax
Copy link
Contributor Author

sax commented May 2, 2024

@chinedufn Took a bit longer than expected, but here's a gist you can clone and see the issue:
https://gist.github.com/sax/9c4b3b841d15ed62fde135da28b783fa

@sax
Copy link
Contributor Author

sax commented Jun 14, 2024

This error occurs on Rust 1.79.0, which was just released yesterday.

@sax sax changed the title ffi struct produces warnings on +nightly ffi struct produces warnings on Rust 1.79.0 or +nightly Jun 16, 2024
@sax
Copy link
Contributor Author

sax commented Jun 17, 2024

Ok, I just verified that this problem happens when bridging a function or method returning a Result where the error variant is an ffi struct. When I instead change all of my code to return a Result<whatever, String>, then the compiler warning disappears.

I take advantage of the ? operator quite a bit, so am going to hold off on making the change. I've been going through the swift-bridge code as well as the expansion of my crate (using cargo-expand), but I really can't see where the problem is coming from.

chinedufn pushed a commit that referenced this issue Jun 21, 2024
…pe>` (#278)

In Rust 1.79.0, dead code warnings are emitted from enums where the compiler does not infer that wrapped data is used, even when the enum has been annotated with `#[repr(C]`. This warning triggers in `swift-bridge` when defining transparent structs or enums that will be returned in error results.

This appears to be a regression in the `dead_code` rustc lint. Pending upstream fixes to rustc, this change to `swift-bridge` annotates generated result enums with `#[allow(unused)]`.

Fixes #270

```
error: field `0` is never read
   |
1  | #[swift_bridge::bridge]
   | ----------------------- field in this variant
...
3  |     enum ResultTransparentEnum {
   |          ^^^^^^^^^^^^^^^^^^^^^
   |
help: consider changing the field to be of unit type to suppress this warning while preserving the field numbering, or remove the field
   |
3  |     enum () {
   |          ~~
```

## Example bridge

The following bridge code is the minimal reproduction case:

``` rust
#[swift_bridge::bridge]
mod ffi {
    #[swift_bridge(swift_repr = "struct")]
    struct TransparentErrorStruct(pub String);

    extern "Rust" {
        fn rust_func_returns_result_transparent_struct(
            succeed: bool
        ) -> Result<(), TransparentErrorStruct>;
    }
}

fn rust_func_returns_result_transparent_struct(
    succeed: bool
) -> Result<(), ffi::ResultTestTransparentStruct> {
    if succeed {
        Ok(())
    } else {
        Err(ffi::ResultTestTransparentStruct("failed".to_string()))
    }
}

impl std::error::Error for ffi:: TransparentErrorStruct {}

impl std::fmt::Debug for ffi:: TransparentErrorStruct {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self)
    }
}

impl std::fmt::Display for ffi:: TransparentErrorStruct {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.0)
    }
}
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants