diff --git a/src/SUMMARY.md b/src/SUMMARY.md index cf3e523d..8bd114d2 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -166,6 +166,7 @@ - [Unions](unsafe/unions.md) - [Calling Unsafe Functions](unsafe/unsafe-functions.md) - [Extern Functions](unsafe/extern-functions.md) + - [Implementing Unsafe Traits](unsafe/unsafe-traits.md) - [Exercises](exercises/day-3/afternoon.md) - [Safe FFI Wrapper](exercises/day-3/safe-ffi-wrapper.md) diff --git a/src/unsafe/unsafe-traits.md b/src/unsafe/unsafe-traits.md new file mode 100644 index 00000000..060b63bf --- /dev/null +++ b/src/unsafe/unsafe-traits.md @@ -0,0 +1,37 @@ +# Implementing Unsafe Traits + +Like with functions, you can mark a trait as `unsafe` if the implementation must guarantee +particular conditions to avoid undefined behaviour. + +For example, the `zerocopy` crate has an unsafe trait that looks +[something like this](https://docs.rs/zerocopy/latest/zerocopy/trait.AsBytes.html): + +```rust,editable +use std::mem::size_of_val; +use std::slice; + +/// ... +/// # Safety +/// The type must have a defined representation and no padding. +pub unsafe trait AsBytes { + fn as_bytes(&self) -> &[u8] { + unsafe { + slice::from_raw_parts(self as *const Self as *const u8, size_of_val(self)) + } + } +} + +// Safe because u32 has a defined representation and no padding. +unsafe impl AsBytes for u32 {} +``` + +
+ +There should be a `# Safety` section on the Rustdoc for the trait explaining the requirements for +the trait to be safely implemented. + +The actual safety section for `AsBytes` is rather longer and more complicated. + +The built-in `Send` and `Sync` traits are unsafe. + +