Use `Result` with stable size, alignment, and ABI guarantees ?
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 3k
- Forks
- 386
- Avg merge
- 1h 43m
- Merged PRs (30d)
- 1
Description
👋 Hi folks,
Since RFC 3391 (https://github.com/rust-lang/rfcs/pull/3391) the Result type's documentation has a Representation section that describes conditions where Result<T, E> can have the same size, alignment and ABI guarantees as Option<U>.
E.g.
For example,
NonZeroI32qualifies for theOptionrepresentation guarantees, and()is a zero-sized type with alignment 1, no fields, and it isn’tnon_exhaustive. This means that bothResult<NonZeroI32, ()>andResult<(), NonZeroI32>have the same size, alignment, and ABI guarantees asOption<NonZeroI32>. The only difference is the implied semantics:
Option<NonZeroI32>is “a non-zero i32 might be present”
Result<NonZeroI32, ()>is “a non-zero i32 success result, if any”
Result<(), NonZeroI32>is “a non-zero i32 error result, if any”
I'm trying to lean on this guarantee to implement FFI for a Rust function that wants to use the implied semantics of returning Result<(), NonZeroU32> to mean "a non-zero u32 error result, if any":
pub const MAY_FAIL_ARG_ZERO_ERR: u32 = 99;
#[no_mangle]
extern "C" fn may_fail(arg: u32) -> Result<(), NonZeroU32> {
match arg == 0 {
true => Err(NonZeroU32::new(MAY_FAIL_ARG_ZERO_ERR).unwrap()),
false => Ok(()),
}
}
This code compiles, and generates no warnings about unsafe FFI type usage with rust stable.
However, the cbindgen (0.27.0) result is not what I expect:
#define MAY_FAIL_ARG_ZERO_ERR 99
typedef struct Result_u32 Result_u32;
struct Result_u32 may_fail(uint32_t arg);
If I change may_fail to return Option<NonZeroU32>, I get the results I expected, but I've lost the implied semantics I want to maintain on the Rust-side:
#define MAY_FAIL_ARG_ZERO_ERR 99
uint32_t may_fail(uint32_t arg);
Is there a workaround I could use to get cbindgen to play nice with "stable representation" Result instances? Is my understanding flawed in some other way?
Thanks!
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the Rust may_fail example and compare cbindgen 0.27.0 output for Result<(), NonZeroU32> versus Option<NonZeroU32>. Trace how cbindgen represents Result and determine whether stable representation guarantees can be recognized; done means documenting a valid workaround or clearly scoping the required support.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- tooling
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100