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

Follow standard for opaque types in case of SEXPREC #205

Closed
wants to merge 7 commits into from

Conversation

CGMossa
Copy link
Member

@CGMossa CGMossa commented Nov 16, 2023

Since SEXPREC is an opaque type, that R doesn't want us to construct, or know anything about, or even
want us to make assumptions about. But, currently, we do! We assume that it is Send, Sync and Pin.
(see cargo doc pictures below).

I've made an issue about this rust-lang/rust-bindgen#2685, because
bindgen has an opaque_type, mechanism, and it is not producing a version with the
!Send,!Sync,!Pin. But the https://stackoverflow.com/questions/38315383/whats-the-rust-idiom-to-define-a-field-pointing-to-a-c-opaque-pointer, and https://doc.rust-lang.org/nomicon/ffi.html#representing-opaque-structs,
explains how to do this:

Going from

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct SEXPREC {
    _unused: [u8; 0],
}

to

#[repr(C)]
pub struct SEXPREC {
    _data: [u8; 0],
    _marker:
        core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>,
}

Results of this code can only be read-off cargo doc, so see the images below:

Currently:
image

Now:
image

Depends on:

ensures that the opaque type doesn't implement `Send`, `Sync`, or `Pin`.
@CGMossa
Copy link
Member Author

CGMossa commented Nov 16, 2023

/bindings

@CGMossa
Copy link
Member Author

CGMossa commented Nov 16, 2023

An example of the issues mentioned in #204 is here. What do I do now to showcase a PR? It breaks CI, so no-one will look. Even if the resulting bindings would work, if they were the ones saved and used in this PR.

@CGMossa
Copy link
Member Author

CGMossa commented Nov 16, 2023

@yutannihilation

@CGMossa
Copy link
Member Author

CGMossa commented Nov 17, 2023

@yutannihilation, since this works now, I'd like your thoughts on this.

@yutannihilation
Copy link
Contributor

Looks great, but let me confirm. In my understanding, SEXPREC is not a type of opaque type that needs to be exposed to the user because the API interface always uses SEXP, not SEXPREC directly. Does it make sense to block both SEXP and SEXPREC and manually define as below?

pub type SEXP = *mut ::std::os::raw::c_void;

@CGMossa
Copy link
Member Author

CGMossa commented Nov 18, 2023

I'm not sure. I don't think we should make SEXP a void*.

I believe Opaque Type atleast implies that it is a type we don't know how to construct, and that we are not allowed to construct. In Rust, that's accomplished with a private field, thus making it impossible to construct the type outside of the defining module.

I tried to do this:
image

But then SEXP becomes
image

Which is, in my opinion, the wrong definition. Because we can construct this.

I don't think we should blindly trust what bindgen produces. It is actively being developed.

I'm not sure if this PR has any impact. I think we should maybe include this PR, just for correctness.
I hope someone explains if this has an impact. Atleast this PR follows rust-documentation. Otherwise I don't know at all...

@yutannihilation
Copy link
Contributor

After reading the Rustonomicon again, I found my understanding about the opaque type was wrong, sorry. It seems you are right.

In this case, I'm still wondering if it's any better to expose the "type-safe" SEXPREC than to hide everything behind c_void because, unlike the Rustonomicon's example, the users always have to use SEXP. Anyway, except for this nitpicky point, I don't see any problem so I'm approving.

(JFYI, I decided to use *mut c_void in my smaller alternative to libR-sys, so I'll share if I find some difference that might matter)

@CGMossa
Copy link
Member Author

CGMossa commented Nov 18, 2023

Ok. Thanks for approval.
However, I'll wait until the fix for ci has been reviewed, and if someone on the bindgen part, or another rust ffi expert says something.

@CGMossa
Copy link
Member Author

CGMossa commented Nov 18, 2023

This is the wrong approach. SEXPREC should be regarded as c_void. I'll put another PR, once I figure out how to make bindgen produce what I want..

@CGMossa CGMossa closed this Nov 18, 2023
@CGMossa CGMossa reopened this Nov 18, 2023
@CGMossa CGMossa closed this Nov 18, 2023
@CGMossa CGMossa deleted the sexp_opaque branch November 18, 2023 15:43
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 this pull request may close these issues.

2 participants