2023-11-29 10:39:24 -05:00
|
|
|
---
|
|
|
|
|
minutes: 5
|
|
|
|
|
---
|
|
|
|
|
|
2023-01-17 16:41:51 +00:00
|
|
|
# Implementing Unsafe Traits
|
|
|
|
|
|
2023-12-31 00:15:07 +01:00
|
|
|
Like with functions, you can mark a trait as `unsafe` if the implementation must
|
|
|
|
|
guarantee particular conditions to avoid undefined behaviour.
|
2023-01-17 16:41:51 +00:00
|
|
|
|
|
|
|
|
For example, the `zerocopy` crate has an unsafe trait that looks
|
2024-11-04 14:01:45 +03:00
|
|
|
[something like this](https://docs.rs/zerocopy/latest/zerocopy/trait.IntoBytes.html):
|
2023-01-17 16:41:51 +00:00
|
|
|
|
|
|
|
|
```rust,editable
|
2024-11-04 14:01:45 +03:00
|
|
|
use std::{mem, slice};
|
2023-01-17 16:41:51 +00:00
|
|
|
|
|
|
|
|
/// ...
|
|
|
|
|
/// # Safety
|
|
|
|
|
/// The type must have a defined representation and no padding.
|
2024-11-04 14:01:45 +03:00
|
|
|
pub unsafe trait IntoBytes {
|
2023-01-17 16:41:51 +00:00
|
|
|
fn as_bytes(&self) -> &[u8] {
|
2024-11-04 14:01:45 +03:00
|
|
|
let len = mem::size_of_val(self);
|
2024-12-13 09:17:37 +00:00
|
|
|
let slf: *const Self = self;
|
|
|
|
|
unsafe { slice::from_raw_parts(slf.cast::<u8>(), len) }
|
2023-01-17 16:41:51 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-12 18:19:19 +01:00
|
|
|
// SAFETY: `u32` has a defined representation and no padding.
|
2024-11-04 14:01:45 +03:00
|
|
|
unsafe impl IntoBytes for u32 {}
|
2023-01-17 16:41:51 +00:00
|
|
|
```
|
|
|
|
|
|
|
|
|
|
<details>
|
|
|
|
|
|
2023-12-31 00:15:07 +01:00
|
|
|
There should be a `# Safety` section on the Rustdoc for the trait explaining the
|
|
|
|
|
requirements for the trait to be safely implemented.
|
2023-01-17 16:41:51 +00:00
|
|
|
|
2024-11-04 14:01:45 +03:00
|
|
|
The actual safety section for `IntoBytes` is rather longer and more complicated.
|
2023-01-17 16:41:51 +00:00
|
|
|
|
|
|
|
|
The built-in `Send` and `Sync` traits are unsafe.
|
|
|
|
|
|
|
|
|
|
</details>
|