Skip to content

Make HaspMap and RawTable to be repr(C) #140

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

Closed
wants to merge 1 commit into from

Conversation

kvark
Copy link

@kvark kvark commented Jan 13, 2020

Adding repr(C) isn't expected to change anything, since the RawTable consists purely of pointers and pointer-sized integers. It will, however, make it possible to pass hashmaps across the FFI boundary, which would be useful to Gecko-integrated Rust projects, such as wgpu.
cc @Gankra

@Gankra
Copy link

Gankra commented Jan 13, 2020

I think this should be ~fine to do, as we aren't guaranteeing these facts in the standard library, just in HashBrown, which is ostensibly dedicated to being a particular implementation. Furthermore the cbindgen usecase doesn't preclude actually changing the layout of these structs, because all that usecase needs is the ability to compute the current layout; not a guarantee that future versions won't change the layout.

Specifically outlining/inling/removing/adding fields is fine. More specifically, adding an Allocator generic parameter/field is also fine, because the default Global one should be zero-sized, and cbindgen ignores zero-sized things (just as it would for BuildHasherDefault).

@Gankra
Copy link

Gankra commented Jan 13, 2020

Clarification: adding an FFI-hostile item to the representation would be "breaking". So anything non-trivial from std, or almost any tagged union besides Option<NonNull>. I do not anticipate this needing to be done.

@Amanieu
Copy link
Member

Amanieu commented Jan 13, 2020

AFAIK you don't need repr(C) to pass a pointer to a HashMap through the FFI boundary. repr(C) is only needed if you pass a HashMap by value, but then the FFI side would need to know the exact size and alignment of the HashMap object.

@kvark
Copy link
Author

kvark commented Jan 13, 2020

@Amanieu I do want to pass it by value in order to avoid indirection in hot code.

@Amanieu
Copy link
Member

Amanieu commented Jan 13, 2020

I don't think repr(C) will really help here since all it does is fix the field order in the struct. Generally the internal details of the HashMap type, including its fields and their ordering, is not something that we provide API guarantees for.

Your best bet here might be to have an assert to check that the HashMap size/align are what you expect them to be, and then silence the FFI-unsafe warning.

Could you show me the code where you try to pass a HashMap through FFI?

@Gankra
Copy link

Gankra commented Jan 13, 2020 via email

@@ -190,6 +190,7 @@ pub enum DefaultHashBuilder {}
/// // use the values stored in map
/// }
/// ```
#[repr(C)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a comment explaining exactly why we are adding repr(C) here?

@@ -329,6 +329,7 @@ impl<T> Bucket<T> {
}

/// A raw hash table with an unsafe API.
#[repr(C)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And here.

@Gankra
Copy link

Gankra commented Jan 14, 2020

Oh right yea I was discussing this more with kvark and reminded myself of The Destructor Problem. Destructors affect ABI significantly, so in reality HashMap shouldn't ever be passed by-value, it should be passed by-mutable-ref and swapped. That said it's still "fine" to store in C++ as long as you're fine with leaks.

@bors
Copy link
Contributor

bors commented Mar 16, 2020

☔ The latest upstream changes (presumably #146) made this pull request unmergeable. Please resolve the merge conflicts.

@Gankra
Copy link

Gankra commented Apr 13, 2020

we should just close this

@Amanieu Amanieu closed this Apr 13, 2020
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.

4 participants