Comments (2)
As indicated in #1892 the stable usage in the book violates stacked borrows.
This kind of pattern is tracked in rust-lang/unsafe-code-guidelines#256. I guess the nice thing is that we don't have interior mutability in bindgen-generated stuff, so right now it kinda works?
The larger problem is that H won't derive Copy even if __IncompleteArrayField does (since that won't be known at bindgen's build time) and so you wind up with something like this
I guess you'd need to use something like clone_into
or ptr::write
or something to get the "Clone" into the right allocation? Implementing a safe Clone for Foo
would be totally unsound, afaict... Given that you're effectively relying on memmoving the header into the allocation anyways, why can't you just do that (memcpy
-ing it)? Exposing clone()
and such is kinda unsound by default. for _ in foo.clone().fam_member.as_slice() {
-> boom...
from rust-bindgen.
As indicated in #1892 the stable usage in the book violates stacked borrows.
This kind of pattern is tracked in rust-lang/unsafe-code-guidelines#256. I guess the nice thing is that we don't have interior mutability in bindgen-generated stuff, so right now it kinda works?
I don't see where interior mutability becomes a problem. The test here seems to be fine?
I did see that tracking issue. There are several implementation examples that are similar in the thread to the fambox
implementation. The workaround described in the issue is fine. Use a pointer:
pub struct FamBox<H: FamHeader, O: Owner> {
// Pointer to backing buffer including fam.
ptr: NonNull<u8>,
// Type markers
ty: PhantomData<(H, O)>,
}
The larger problem is that H won't derive Copy even if __IncompleteArrayField does (since that won't be known at bindgen's build time) and so you wind up with something like this
I guess you'd need to use something like
clone_into
orptr::write
or something to get the "Clone" into the right allocation? Implementing a safeClone for Foo
would be totally unsound, afaict... Given that you're effectively relying on memmoving the header into the allocation anyways, why can't you just do that (memcpy
-ing it)? Exposingclone()
and such is kinda unsound by default.for _ in foo.clone().fam_member.as_slice() {
-> boom...
You seem to keep implying that the struct is only valid while allocated next to its fam members. What I'm trying to say is under another conceptualization, the struct is valid as long as it describes a fam even if the fam doesn't exist. To actually access the fam with safe code requires already having provided it into the allocation.
As an example from the README.md
:
First you create the header and buffers which do not reside in their final location (or use the builder):
let data_buffer = [0, 1, 2, 3, 4, 5];
let header = encapsulated_struct::protocol_msg::new(1, 2, data_buffer.len())?;
At this point the header
is not followed by the data it will eventually reside with. However, it can also not safely access the fam's data in this form so it doesn't matter.
then you allocate the struct in a usable form
let header_and_fam = FamBoxOwned::from_fn(header, |i| data_buffer[i]);
let header = encapsulated_struct::protocol_msg::new(1, 2, data_buffer.len())?;
assert_eq!(header_and_fam.header(), &header);
assert_eq!(header_and_fam.fam(), data_buffer); // <- Notice that this is now safe for users of the data-structure.
assert_eq!(
usize::from(*header_and_fam.header().length()),
size_of::<protocol_msg>() + core::mem::size_of_val(&data_buffer)
);
A clone of the header would be a valid header not attached to any data.
let new_header = header_and_fam.header().clone()
but only the header which precedes the fam's data is able to access it:
let fam = header_and_fam.fam(); // <- safe and valid
let fam = new_header.fam() // <- no such method
Yes, you can do
// Safety: Not safe.
let fam = unsafe { new_header.elements.as_slice(1) }
But you violated memory safety with unsafe
which is not an issue.
Hopefully this makes it clear why H: Clone, H::Element: Clone
is needed for FamBox<H, Owned>: Clone
and memcpy would not be valid? You're making clones, not moving the structs with memcpy.
/** [`Owned`] impls */
impl<H: FamHeader + Clone> Clone for FamBox<H, Owned>
where
H::Element: Clone,
{
/// The buffer, including the header and fam, is copied into a new allocation.
#[inline]
fn clone(&self) -> Self {
let (header, fam) = self.as_parts();
FamBox::from_fn(header.clone(), |i| fam[i].clone())
}
}
from rust-bindgen.
Related Issues (20)
- Incorrect field offset when C struct is __attribute__((packed, aligned(8)))
- Windows keeps using MSVC, even when `CC` and `CXX` are set explicitly and empty `PATH` HOT 3
- Bindings for define statements using scientific notation HOT 2
- Panic: Couldn't resolve constant type, and it wasn't an nondeductible auto type or unexposed type! HOT 2
- How to handle C array of undefined size? HOT 1
- Installing bindgen twice with `cargo install --locked` creates different binaries. HOT 2
- Allow wrap-static-fns to be used without experimental feature HOT 2
- Generate `unsafe extern` blocks (Edition 2024) HOT 2
- 🐛Mixed EOL files created on WinOS HOT 1
- new() not found in Callbacks HOT 6
- Clippy warning with 0.70: this operation has no effect HOT 5
- build.rs, Builder and no tests? HOT 4
- ci: unexpected warning with cargo install --locked due to outdated Cargo.lock [easy] [not urgent]
- Support `import_name` and `import_module` attributes when targeting `wasm32` HOT 1
- How to remove the Option in generated function pointer? HOT 1
- _Atomic crashes bindgen even when blocklisted HOT 3
- [libclang5] Wrong code generation surfaced by #2787 HOT 6
- Generate `std::ffi::*` instead of the `std::os::raw::*` types HOT 1
- Linking issues when using Rust-bindgen for a USB CAN driver DLL HOT 3
- Wrong values generated of constants defined by #define for a linux header file. HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from rust-bindgen.