Реализация небезопасных трейтов
Как и для функций, трейт можно пометить как unsafe, если реализация должна гарантировать определённые условия, чтобы избежать неопределённого поведения.
Например, в крейте zerocopy есть небезопасный трейт, который выглядит примерно так:
// Copyright 2023 Google LLC
// SPDX-License-Identifier: Apache-2.0
use std::{mem, slice};
/// ...
/// # Safety
/// Тип должен иметь определённое представление и не содержать выравнивающих байтов (padding).
pub unsafe trait IntoBytes {
fn as_bytes(&self) -> &[u8] {
let len = mem::size_of_val(self);
let slf: *const Self = self;
unsafe { slice::from_raw_parts(slf.cast::<u8>(), len) }
}
}
// SAFETY: `u32` имеет определённое представление и не содержит выравнивающих байтов (padding).
unsafe impl IntoBytes for u32 {}
This slide should take about 5 minutes.
У трейта в Rustdoc должен быть раздел # Safety, объясняющий требования для безопасной реализации трейта.
Сам раздел о безопасности для IntoBytes гораздо длиннее и сложнее.
Встроенные трейты Send и Sync — небезопасные.