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

Start emitting unions in stable mode #832

Closed
fitzgen opened this issue Jul 20, 2017 · 15 comments
Closed

Start emitting unions in stable mode #832

fitzgen opened this issue Jul 20, 2017 · 15 comments

Comments

@fitzgen
Copy link
Member

fitzgen commented Jul 20, 2017

They're in stable now: https://blog.rust-lang.org/2017/07/20/Rust-1.19.html

Basically, we can go through all of the places where we check ctx.options().unstable_rust and use that to decide whether to use unions or not, and just always use the unions. We can also get rid of the BindgenUnion type now.

And finally, we can update the user guide's section on using unions.

I'm happy to mentor anyone who wants to pick this up.

@fitzgen fitzgen added the E-easy label Jul 20, 2017
@highfive
Copy link

Hi! If you have any questions regarding this issue, feel free to make a comment here, or ask it in the #servo channel in IRC.

If you intend to work on this issue, then add @highfive: assign me to your comment, and I'll assign this to you. 😄

@tmfink
Copy link
Contributor

tmfink commented Jul 21, 2017

Currently, we have a bool indicating stable vs. unstable.
Instead, should we have an enum that indicates the "flavor"/"epoch"/"channel" to support?

Bindgen code:

#[allow(non_camel_case_types)]
#[derive(Debug)]
enum RustVersion {
    Stable_1_0,
    Stable_1_15,
    Stable_1_20,
    Nightly,
}

const LATEST_STABLE: RustVersion = RustVersion::Stable_1_20;

Use case:

let bindings = bindgen::Builder::default()
        .rust_version(RustSupport::Stable_1_15)  // Specify Rust version here
        .header("wrapper.h")
        .generate()
        .expect("Unable to generate bindings");

This would allow users to upgrade bindgen versions without getting breaking changes in the generated Rust code (like using unions unless nightly or >= Stable 1.19).

This may be more trouble than it's worth. Thoughts?

@tmfink
Copy link
Contributor

tmfink commented Jul 21, 2017

@highfive: assign me

@highfive
Copy link

Hey @tmfink! Thanks for your interest in working on this issue. It's now assigned to you!

@fitzgen
Copy link
Member Author

fitzgen commented Jul 21, 2017

Instead, should we have an enum that indicates the "flavor"/"epoch"/"channel" to support?

I think this is a good idea.

That said, I'd nitpick the enum to be something like:

pub enum TargetRust {
    // As far as available features goes, no difference between stable 1.X and
    // beta 1.X from our perspective...
    //
    // (major, minor)
    StableAndBeta(u8, u8),

    // Everything else...
    Nightly
}

Although ideally we would be able to turn individual nightly features on and off too. I suppose we could make the nightly variant be a struct variant with a bool for each feature?

@fitzgen
Copy link
Member Author

fitzgen commented Jul 21, 2017

And thanks for picking this up @tmfink ! Let me know if you have any questions :)

@tmfink
Copy link
Contributor

tmfink commented Jul 22, 2017

No problem @fitzgen!

I would prefer that TargetRust has discrete values for each Stable/Beta like I described in my previous comment. That way:

  • Code will not compile if a nonsensical variant like StableAndBeta(255, 255) were used because the equivalent variant would not be defined.
  • I think that users would find it easier to select a TargetRust variant if an exhaustive list were defined. There would not be as many possible variants; we only need a new TargetRust variant when bindgen might use a new feature. For example, I don't think bindgen ever output code that used try!, so adding ? would not have required us to add a new target variant.

As for implementation, I think the interface should accept a RustFeatures struct that contains a bool for each feature. We can make the internal fields private and expose a public builder pattern constructor. We can impl From<TargetRust> for RustFeatures to make the conversions.

I think that TargetRust::Nightly should give a RustFeatures with all features enabled. If users want more control over which features to use in nightly, they can just manually build a RustFeatures struct with the builder pattern.

Another small detail: if we go with StableAndBeta(major, minor), lets use u32 to be safe--the overhead would not really matter.

@emilio
Copy link
Contributor

emilio commented Jul 22, 2017

Note that emitting unions have impact in stuff like whether a type can derive Debug or not, which is somewhat unfortunate...

I'd personally like to keep unions not the default, but I guess I can bite the bullet if needed.

@tmfink
Copy link
Contributor

tmfink commented Jul 23, 2017

@emilio I feel like the language support of union is worth not being able to derive Debug. Using bindgen's stable union types is a bit awkward. Over time, we may get more support (lints, etc.) that make union easier to use.

@emilio
Copy link
Contributor

emilio commented Jul 23, 2017

Yeah, I guess that's fair.

@fitzgen
Copy link
Member Author

fitzgen commented Jul 24, 2017

Regarding feature flags and rust target versions: I think we really want to keep this as simple as possible to avoid the explosion of potential bugs from every combination of features. I agree we want to have a notion of the target rust version/channel and its supported features, but we should just do the minimum that achieves that IMO.

Regarding union making things not derive(Debug): an alleviation is to emit our own Debug impls when they can't be derived. Even something as simple as

impl ::std::fmt::Debug for Elephant {
    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
        write!(f, "Elephant {{ ... }}")
    }
}

is likely good enough.

bors-servo pushed a commit that referenced this issue Aug 4, 2017
Feature 832 custom rust target

Addresses #832.

Instead of specifying whether or not to use stable, specify the Rust
release to support (one of several stable/beta releases or nightly).
The `--unstable-rust` option is still accepted and implies `--rust-target nightly`.

The definitions of `RustTarget` and `RustFeatures` are created with
macros.

In order to keep the test outputs the same,
`bindgen-flags: --rust-target 1.0` was added to test headers.

**Todo:**

- [x] Create `RustFeatures`/`RustTarget` structs
- [x] Replace uses of `unstable` with `RustFeatures` query
- [x] Add new tests
- [x] Fix doc comments TODOs
@fitzgen
Copy link
Member Author

fitzgen commented Aug 4, 2017

Fixed in #859

@fitzgen fitzgen closed this as completed Aug 4, 2017
@tmfink
Copy link
Contributor

tmfink commented Aug 4, 2017

We still need to update the book chapter on unions.

bors-servo pushed a commit that referenced this issue Aug 14, 2017
Re-add --rust-target option to replace --unstable-rust

Re-apply commit. Addresses #832

Instead of specifying whether or not to use stable, specify the Rust
release to support (one of several stable/beta releases or nightly).
The `--unstable-rust` option is still accepted and implies nightly.

The definitions of `RustTarget` and `RustFeatures` are created with
macros.

For each test that uses unions, there is a version that uses the latest stable
and 1.0.
@tmfink
Copy link
Contributor

tmfink commented Aug 19, 2017

@fitzgen I am working on the Using the Union Types Generated by Bindgen chapter of the user's guide.

tmfink added a commit to tmfink/rust-bindgen that referenced this issue Aug 19, 2017
tmfink added a commit to tmfink/rust-bindgen that referenced this issue Aug 19, 2017
bors-servo pushed a commit that referenced this issue Aug 20, 2017
Update doc for unions

Addresses #832

I also modified the `--help` text to print the default Rust target.
@fitzgen
Copy link
Member Author

fitzgen commented Aug 21, 2017

@fitzgen I working on the Using the Union Types Generated by Bindgen chapter of the user's guide.

Awesome, thanks! 👍

bors-servo pushed a commit that referenced this issue Aug 28, 2017
Bump version to 0.30.0

Version bump, primarily to get #832 and #892 in now that 1.19 is out and untagged unions are usable in stable!

r? @emilio
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants