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

Parsing of Option<NonZero<T>> #95

Open
RivenSkaye opened this issue Oct 14, 2024 · 0 comments
Open

Parsing of Option<NonZero<T>> #95

RivenSkaye opened this issue Oct 14, 2024 · 0 comments

Comments

@RivenSkaye
Copy link

RivenSkaye commented Oct 14, 2024

The NonZero* integer types (all stemming from std::num::NonZero) support an FFI-safe Null Pointer Optimization for guaranteeing layout, namely Option<NonZero<T>> can use the niche of a struct (in this case inputs being 0) to represent the None case with the same size and alignment as the underlying type. This optimization is specifically defined for NonZero

Looking through the code, I'm not seeing any handling for this (or any other NPOs for that matter) while they can make the Rust code a lot more ergonomic to both read and write. For example:

use std::num::NonZeroU32;
static DEFAULT_NUMBER: i64 = -1;
/// NPO means C# can give us 0 and this code will function!
/// Uses the special-cased "system" calling convention, which will compile to different conventions depending on
// 32-bit or 64-bit Windows targets, as these use different C calling conventions.
#[no_mangle]
pub extern "system" fn convert_int(num: Option<NonZero32>) -> i64 {
    match num {
        None => DEFAULT_NUMBER,
        Some(n) => n as _ // Safe, all values for u32 fit in the positive range of i64
    }
}

With the corresponding C# code being able to safely do

var rand = new Random();
uint number = (uint)(rand.Next(0, 2)); // always returns 0 or 1 because the upper bound is exclusive
long conv = convert_int(number)
if (conv < 0) Console.WriteLine("We passed a zero to Rust!")
else Console.WriteLine("We passed a non-zero value!")

And a stable Rust playground for this as well

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

No branches or pull requests

1 participant