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 by-value struct function argument error on Windows #13997

Closed
SiegeLord opened this issue May 6, 2014 · 2 comments
Closed

FFI by-value struct function argument error on Windows #13997

SiegeLord opened this issue May 6, 2014 · 2 comments
Labels
A-FFI Area: Foreign function interface (FFI) O-windows Operating system: Windows

Comments

@SiegeLord
Copy link
Contributor

This is somewhat complicated and requires an intermediate crate. There is no error (as far as this test can tell) if the intermediate crate is removed. Take these 3 files:

bug.c

#include <stdio.h>

typedef struct
{
    float a, b, c, d;
} S;

void test(S a)
{
    printf("%f %f %f %f\n", a.a, a.b, a.c, a.d);
}

bug.rs

#![crate_id="bug"]
#![crate_type="lib"]

pub struct S
{
    pub a: f32,
    pub b: f32,
    pub c: f32,
    pub d: f32,
}

#[link(name = "bug")]
extern "C"
{
    pub fn test(b: S);
}

test.rs

extern crate bug;

use bug::{test, S};

fn main()
{
    unsafe
    {
        let s1 = S{a: 1.0, b: 2.0, c: 3.0, d: 4.0};
        test(s1);
    }
}

Compile it all together and run test.exe:

gcc -shared bug.c -olibbug.dll
rustc bug.rs
rustc test.rs -L.
test

The output I get is:

0.000000 0.000000 1.000000 2.000000

Expected output:

1.000000 2.000000 3.000000 4.000000

GCC version:

gcc (rev5, Built by MinGW-W64 project) 4.8.1
@klutzy
Copy link
Contributor

klutzy commented May 26, 2014

Test code works now! Seems to be fixed by #14191

@thestinger
Copy link
Contributor

Closing since that PR added a test.

bors added a commit to rust-lang-ci/rust that referenced this issue Mar 3, 2024
…, r=Veykril

feature: Add `destructure_struct_binding`

Adds an assist for destructuring a struct in a binding (rust-lang#8673). I saw that rust-lang#13997 has been abandoned for a while, so I thought I'd give it a go.

## Example

```rust
let foo = Foo { bar: 1, baz: 2 };
let bar2 = foo.bar;
let baz2 = foo.baz;
let foo2 = foo;

let fizz = Fizz(1, 2);
let buzz = fizz.0;
```
becomes
```rust
let Foo { bar, baz } = Foo { bar: 1, baz: 2 };
let bar2 = bar;
let baz2 = baz;
let foo2 = todo!();

let Fizz(_0, _1) = Fizz(1, 2);
let buzz = _0;
```

More examples in the tests.

## What is included?

- [x] Destructure record, tuple, and unit struct bindings
- [x] Edit field usages
- [x] Non-exhaustive structs in foreign crates and private fields get hidden behind `..`
- [x] Nested bindings
- [x] Carry over `mut` and `ref mut` in nested bindings to fields, i.e. `let Foo { ref mut bar } = ...` becomes `let Foo { bar: Bar { baz: ref mut baz } } = ...`
- [x] Attempt to resolve collisions with other names in the scope
- [x] If the binding is to a reference, field usages are dereferenced if required
- [x] Use shorthand notation if possible

## Known limitations

- `let foo = Foo { bar: 1 }; foo;` currently results in `let Foo { bar } = Foo { bar: 1 }; todo!();` instead of reassembling the struct. This requires user intervention.
- Unused fields are not currently omitted. I thought that this is more ergonomic, as there already is a quick fix action for adding `: _` to unused field patterns.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-FFI Area: Foreign function interface (FFI) O-windows Operating system: Windows
Projects
None yet
Development

No branches or pull requests

4 participants