Merge from rustc ยท model-checking/verify-rust-std@c6e53ce (original) (raw)
37 files changed
lines changed
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1705,7 +1705,7 @@ impl<'a, T, A: Allocator> CursorMut<'a, T, A> { | ||
1705 | 1705 | unsafe { |
1706 | 1706 | self.current = unlinked_node.as_ref().next; |
1707 | 1707 | self.list.unlink_node(unlinked_node); |
1708 | -let unlinked_node = Box::from_raw(unlinked_node.as_ptr()); | |
1708 | +let unlinked_node = Box::from_raw_in(unlinked_node.as_ptr(), &self.list.alloc); | |
1709 | 1709 | Some(unlinked_node.element) |
1710 | 1710 | } |
1711 | 1711 | } |
@@ -1946,7 +1946,7 @@ where | ||
1946 | 1946 | if (self.pred)(&mut node.as_mut().element) { |
1947 | 1947 | // `unlink_node` is okay with aliasing `element` references. |
1948 | 1948 | self.list.unlink_node(node); |
1949 | -return Some(Box::from_raw(node.as_ptr()).element); | |
1949 | +return Some(Box::from_raw_in(node.as_ptr(), &self.list.alloc).element); | |
1950 | 1950 | } |
1951 | 1951 | } |
1952 | 1952 | } |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1164,3 +1164,42 @@ fn test_drop_panic() { | ||
1164 | 1164 | |
1165 | 1165 | assert_eq!(unsafe { DROPS }, 8); |
1166 | 1166 | } |
1167 | + | |
1168 | +#[test] | |
1169 | +fn test_allocator() { | |
1170 | +use core::alloc::AllocError; | |
1171 | +use core::alloc::Allocator; | |
1172 | +use core::alloc::Layout; | |
1173 | +use core::cell::Cell; | |
1174 | + | |
1175 | +struct A { | |
1176 | +has_allocated: Cell<bool>, | |
1177 | +has_deallocated: Cell<bool>, | |
1178 | +} | |
1179 | + | |
1180 | +unsafe impl Allocator for A { | |
1181 | +fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> { | |
1182 | +assert!(!self.has_allocated.get()); | |
1183 | +self.has_allocated.set(true); | |
1184 | + | |
1185 | +Global.allocate(layout) | |
1186 | +} | |
1187 | + | |
1188 | +unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) { | |
1189 | +assert!(!self.has_deallocated.get()); | |
1190 | +self.has_deallocated.set(true); | |
1191 | + | |
1192 | +unsafe { Global.deallocate(ptr, layout) } | |
1193 | +} | |
1194 | +} | |
1195 | + | |
1196 | +let alloc = &A { has_allocated: Cell::new(false), has_deallocated: Cell::new(false) }; | |
1197 | +{ | |
1198 | +let mut list = LinkedList::new_in(alloc); | |
1199 | + list.push_back(5u32); | |
1200 | + list.remove(0); | |
1201 | +} | |
1202 | + | |
1203 | +assert!(alloc.has_allocated.get()); | |
1204 | +assert!(alloc.has_deallocated.get()); | |
1205 | +} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -257,8 +257,6 @@ use core::intrinsics::abort; | ||
257 | 257 | #[cfg(not(no_global_oom_handling))] |
258 | 258 | use core::iter; |
259 | 259 | use core:๐:{PhantomData, Unsize}; |
260 | -#[cfg(not(no_global_oom_handling))] | |
261 | -use core::mem::size_of_val; | |
262 | 260 | use core::mem::{self, align_of_val_raw, forget, ManuallyDrop}; |
263 | 261 | use core::ops::{CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn, Receiver}; |
264 | 262 | use core::panic::{RefUnwindSafe, UnwindSafe}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -18,8 +18,6 @@ use core::intrinsics::abort; | ||
18 | 18 | #[cfg(not(no_global_oom_handling))] |
19 | 19 | use core::iter; |
20 | 20 | use core:๐:{PhantomData, Unsize}; |
21 | -#[cfg(not(no_global_oom_handling))] | |
22 | -use core::mem::size_of_val; | |
23 | 21 | use core::mem::{self, align_of_val_raw}; |
24 | 22 | use core::ops::{CoerceUnsized, Deref, DerefPure, DispatchFromDyn, Receiver}; |
25 | 23 | use core::panic::{RefUnwindSafe, UnwindSafe}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -8,6 +8,7 @@ use std::{ | ||
8 | 8 | }; |
9 | 9 | |
10 | 10 | #[test] |
11 | +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] | |
11 | 12 | fn test_shrink_to_unwind() { |
12 | 13 | // This tests that `shrink_to` leaves the deque in a consistent state when |
13 | 14 | // the call to `RawVec::shrink_to_fit` unwinds. The code is adapted from #123369 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -82,6 +82,20 @@ | ||
82 | 82 | //! |
83 | 83 | //! The corresponding [`Sync`] version of `OnceCell` is [`OnceLock`]. |
84 | 84 | //! |
85 | +//! ## `LazyCell<T, F>` | |
86 | +//! | |
87 | +//! A common pattern with OnceCell is, for a given OnceCell, to use the same function on every | |
88 | +//! call to [`OnceCell::get_or_init`] with that cell. This is what is offered by [`LazyCell`], | |
89 | +//! which pairs cells of `T` with functions of `F`, and always calls `F` before it yields `&T`. | |
90 | +//! This happens implicitly by simply attempting to dereference the LazyCell to get its contents, | |
91 | +//! so its use is much more transparent with a place which has been initialized by a constant. | |
92 | +//! | |
93 | +//! More complicated patterns that don't fit this description can be built on `OnceCell` instead. | |
94 | +//! | |
95 | +//! `LazyCell` works by providing an implementation of `impl Deref` that calls the function, | |
96 | +//! so you can just use it by dereference (e.g. `*lazy_cell` or `lazy_cell.deref()`). | |
97 | +//! | |
98 | +//! The corresponding [`Sync`] version of `LazyCell<T, F>` is [`LazyLock<T, F>`]. | |
85 | 99 | //! |
86 | 100 | //! # When to choose interior mutability |
87 | 101 | //! |
@@ -230,6 +244,7 @@ | ||
230 | 244 | //! [`RwLock`]: ../../std/sync/struct.RwLock.html |
231 | 245 | //! [`Mutex`]: ../../std/sync/struct.Mutex.html |
232 | 246 | //! [`OnceLock`]: ../../std/sync/struct.OnceLock.html |
247 | +//! [`LazyLock<T, F>`]: ../../std/sync/struct.LazyLock.html | |
233 | 248 | //! [`Sync`]: ../../std/marker/trait.Sync.html |
234 | 249 | //! [`atomic`]: crate::sync::atomic |
235 | 250 | |
@@ -238,7 +253,7 @@ | ||
238 | 253 | use crate::cmp::Ordering; |
239 | 254 | use crate::fmt::{self, Debug, Display}; |
240 | 255 | use crate:๐:{PhantomData, Unsize}; |
241 | -use crate::mem::{self, size_of}; | |
256 | +use crate::mem; | |
242 | 257 | use crate::ops::{CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn}; |
243 | 258 | use crate::ptr::{self, NonNull}; |
244 | 259 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -65,7 +65,6 @@ | ||
65 | 65 | |
66 | 66 | use crate:๐:DiscriminantKind; |
67 | 67 | use crate:๐:Tuple; |
68 | -use crate::mem::align_of; | |
69 | 68 | use crate::ptr; |
70 | 69 | use crate::ub_checks; |
71 | 70 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -4,8 +4,8 @@ use crate::ops::Try; | ||
4 | 4 | |
5 | 5 | /// An iterator that links two iterators together, in a chain. |
6 | 6 | /// |
7 | -/// This `struct` is created by [`Iterator::chain`]. See its documentation | |
8 | -/// for more. | |
7 | +/// This `struct` is created by [`chain`] or [`Iterator::chain`]. See their | |
8 | +/// documentation for more. | |
9 | 9 | /// |
10 | 10 | /// # Examples |
11 | 11 | /// |
@@ -38,6 +38,39 @@ impl<A, B> Chain<A, B> { | ||
38 | 38 | } |
39 | 39 | } |
40 | 40 | |
41 | +/// Converts the arguments to iterators and links them together, in a chain. | |
42 | +/// | |
43 | +/// See the documentation of [`Iterator::chain`] for more. | |
44 | +/// | |
45 | +/// # Examples | |
46 | +/// | |
47 | +/// ``` | |
48 | +/// #![feature(iter_chain)] | |
49 | +/// | |
50 | +/// use std::iter::chain; | |
51 | +/// | |
52 | +/// let a = [1, 2, 3]; | |
53 | +/// let b = [4, 5, 6]; | |
54 | +/// | |
55 | +/// let mut iter = chain(a, b); | |
56 | +/// | |
57 | +/// assert_eq!(iter.next(), Some(1)); | |
58 | +/// assert_eq!(iter.next(), Some(2)); | |
59 | +/// assert_eq!(iter.next(), Some(3)); | |
60 | +/// assert_eq!(iter.next(), Some(4)); | |
61 | +/// assert_eq!(iter.next(), Some(5)); | |
62 | +/// assert_eq!(iter.next(), Some(6)); | |
63 | +/// assert_eq!(iter.next(), None); | |
64 | +/// ``` | |
65 | +#[unstable(feature = "iter_chain", reason = "recently added", issue = "125964")] | |
66 | +pub fn chain<A, B>(a: A, b: B) -> Chain<A::IntoIter, B::IntoIter> | |
67 | +where | |
68 | +A: IntoIterator, | |
69 | +B: IntoIterator<Item = A::Item>, | |
70 | +{ | |
71 | +Chain::new(a.into_iter(), b.into_iter()) | |
72 | +} | |
73 | + | |
41 | 74 | #[stable(feature = "rust1", since = "1.0.0")] |
42 | 75 | impl<A, B> Iterator for Chain<A, B> |
43 | 76 | where |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -41,6 +41,9 @@ pub use self::array_chunks::ArrayChunks; | ||
41 | 41 | #[unstable(feature = "std_internals", issue = "none")] |
42 | 42 | pub use self::by_ref_sized::ByRefSized; |
43 | 43 | |
44 | +#[unstable(feature = "iter_chain", reason = "recently added", issue = "125964")] | |
45 | +pub use self::chain::chain; | |
46 | + | |
44 | 47 | #[stable(feature = "iter_cloned", since = "1.1.0")] |
45 | 48 | pub use self::cloned::Cloned; |
46 | 49 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -428,6 +428,8 @@ pub use self::traits::{ | ||
428 | 428 | DoubleEndedIterator, ExactSizeIterator, Extend, FromIterator, IntoIterator, Product, Sum, |
429 | 429 | }; |
430 | 430 | |
431 | +#[unstable(feature = "iter_chain", reason = "recently added", issue = "125964")] | |
432 | +pub use self::adapters::chain; | |
431 | 433 | #[stable(feature = "iter_zip", since = "1.59.0")] |
432 | 434 | pub use self::adapters::zip; |
433 | 435 | #[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1569,7 +1569,12 @@ pub(crate) mod builtin { | ||
1569 | 1569 | #[rustc_builtin_macro] |
1570 | 1570 | #[macro_export] |
1571 | 1571 | #[rustc_diagnostic_item = "assert_macro"] |
1572 | - #[allow_internal_unstable(panic_internals, edition_panic, generic_assert_internals)] | |
1572 | + #[allow_internal_unstable( | |
1573 | + core_intrinsics, | |
1574 | + panic_internals, | |
1575 | + edition_panic, | |
1576 | + generic_assert_internals | |
1577 | +)] | |
1573 | 1578 | macro_rules! assert { |
1574 | 1579 | ($cond:expr $(,)?) => {{ /* compiler built-in */ }}; |
1575 | 1580 | ($cond:expr, (((arg:tt)+) => {{ /* compiler built-in */ }}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -120,12 +120,8 @@ use crate::slice; | ||
120 | 120 | /// use std::mem::{self, MaybeUninit}; |
121 | 121 | /// |
122 | 122 | /// let data = { |
123 | -/// // Create an uninitialized array of `MaybeUninit`. The `assume_init` is | |
124 | -/// // safe because the type we are claiming to have initialized here is a | |
125 | -/// // bunch of `MaybeUninit`s, which do not require initialization. | |
126 | -/// let mut data: [MaybeUninit<Vec>; 1000] = unsafe { | |
127 | -/// MaybeUninit::uninit().assume_init() | |
128 | -/// }; | |
123 | +/// // Create an uninitialized array of `MaybeUninit`. | |
124 | +/// let mut data: [MaybeUninit<Vec>; 1000] = [const { MaybeUninit::uninit() }; 1000]; | |
129 | 125 | /// |
130 | 126 | /// // Dropping a `MaybeUninit` does nothing, so if there is a panic during this loop, |
131 | 127 | /// // we have a memory leak, but there is no memory safety issue. |
@@ -147,10 +143,8 @@ use crate::slice; | ||
147 | 143 | /// ``` |
148 | 144 | /// use std::mem::MaybeUninit; |
149 | 145 | /// |
150 | -/// // Create an uninitialized array of `MaybeUninit`. The `assume_init` is | |
151 | -/// // safe because the type we are claiming to have initialized here is a | |
152 | -/// // bunch of `MaybeUninit`s, which do not require initialization. | |
153 | -/// let mut data: [MaybeUninit; 1000] = unsafe { MaybeUninit::uninit().assume_init() }; | |
146 | +/// // Create an uninitialized array of `MaybeUninit`. | |
147 | +/// let mut data: [MaybeUninit; 1000] = [const { MaybeUninit::uninit() }; 1000]; | |
154 | 148 | /// // Count the number of elements we have assigned. |
155 | 149 | /// let mut data_len: usize = 0; |
156 | 150 | /// |
@@ -348,8 +342,7 @@ impl MaybeUninit { | ||
348 | 342 | #[must_use] |
349 | 343 | #[inline(always)] |
350 | 344 | pub const fn uninit_array<const N: usize>() -> [Self; N] { |
351 | -// SAFETY: An uninitialized `[MaybeUninit<_>; LEN]` is valid. | |
352 | -unsafe { MaybeUninit::<[MaybeUninit<T>; N]>::uninit().assume_init() } | |
345 | +[const { MaybeUninit::uninit() }; N] | |
353 | 346 | } |
354 | 347 | |
355 | 348 | /// Creates a new `MaybeUninit` in an uninitialized state, with the memory being |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -14,6 +14,9 @@ pub use crate::ops::{Drop, Fn, FnMut, FnOnce}; | ||
14 | 14 | #[stable(feature = "core_prelude", since = "1.4.0")] |
15 | 15 | #[doc(no_inline)] |
16 | 16 | pub use crate::mem::drop; |
17 | +#[stable(feature = "size_of_prelude", since = "CURRENT_RUSTC_VERSION")] | |
18 | +#[doc(no_inline)] | |
19 | +pub use crate::mem::{align_of, align_of_val, size_of, size_of_val}; | |
17 | 20 | |
18 | 21 | // Re-exported types and traits |
19 | 22 | #[stable(feature = "core_prelude", since = "1.4.0")] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -415,7 +415,7 @@ use crate::intrinsics; | ||
415 | 415 | use crate:๐:FnPtr; |
416 | 416 | use crate::ub_checks; |
417 | 417 | |
418 | -use crate::mem::{self, align_of, size_of, MaybeUninit}; | |
418 | +use crate::mem::{self, MaybeUninit}; | |
419 | 419 | |
420 | 420 | mod alignment; |
421 | 421 | #[unstable(feature = "ptr_alignment_type", issue = "102070")] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,6 @@ | ||
1 | 1 | //! Free functions to create `&[T]` and `&mut [T]`. |
2 | 2 | |
3 | 3 | use crate::array; |
4 | -use crate::mem::{align_of, size_of}; | |
5 | 4 | use crate::ops::Range; |
6 | 5 | use crate::ptr; |
7 | 6 | use crate::ub_checks; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1296,7 +1296,6 @@ impl AtomicPtr { | ||
1296 | 1296 | #[cfg(target_has_atomic_equal_alignment = "ptr")] |
1297 | 1297 | #[unstable(feature = "atomic_from_mut", issue = "76314")] |
1298 | 1298 | pub fn from_mut(v: &mut *mut T) -> &mut Self { |
1299 | -use crate::mem::align_of; | |
1300 | 1299 | let [] = [(); align_of::<AtomicPtr<()>>() - align_of::<*mut ()>()]; |
1301 | 1300 | // SAFETY: |
1302 | 1301 | // - the mutable reference guarantees unique ownership. |
@@ -2286,7 +2285,6 @@ macro_rules! atomic_int { | ||
2286 | 2285 | #[$cfg_align] |
2287 | 2286 | #[unstable(feature = "atomic_from_mut", issue = "76314")] |
2288 | 2287 | pub fn from_mut(v: &mut $int_type) -> &mut Self { |
2289 | -use crate::mem::align_of; | |
2290 | 2288 | let [] = [(); align_of::<Self>() - align_of::<$int_type>()]; |
2291 | 2289 | // SAFETY: |
2292 | 2290 | // - the mutable reference guarantees unique ownership. |
@@ -2354,7 +2352,6 @@ macro_rules! atomic_int { | ||
2354 | 2352 | #[$cfg_align] |
2355 | 2353 | #[unstable(feature = "atomic_from_mut", issue = "76314")] |
2356 | 2354 | pub fn from_mut_slice(v: &mut [$int_type]) -> &mut [Self] { |
2357 | -use crate::mem::align_of; | |
2358 | 2355 | let [] = [(); align_of::<Self>() - align_of::<$int_type>()]; |
2359 | 2356 | // SAFETY: |
2360 | 2357 | // - the mutable reference guarantees unique ownership. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -2,6 +2,14 @@ use super::*; | ||
2 | 2 | use core::iter::*; |
3 | 3 | use core::num::NonZero; |
4 | 4 | |
5 | +#[test] | |
6 | +fn test_chain() { | |
7 | +let xs = [0, 1, 2, 3, 4, 5]; | |
8 | +let ys = [30, 40, 50, 60]; | |
9 | +let expected = [0, 1, 2, 3, 4, 5, 30, 40, 50, 60]; | |
10 | +assert_eq!(Vec::from_iter(chain(xs, ys)), expected); | |
11 | +} | |
12 | + | |
5 | 13 | #[test] |
6 | 14 | fn test_iterator_chain() { |
7 | 15 | let xs = [0, 1, 2, 3, 4, 5]; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -75,6 +75,7 @@ | ||
75 | 75 | #![feature(ip)] |
76 | 76 | #![feature(iter_advance_by)] |
77 | 77 | #![feature(iter_array_chunks)] |
78 | +#![feature(iter_chain)] | |
78 | 79 | #![feature(iter_collect_into)] |
79 | 80 | #![feature(iter_partition_in_place)] |
80 | 81 | #![feature(iter_intersperse)] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -96,7 +96,7 @@ where | ||
96 | 96 | fn cast<U>(self) -> Self::CastPtr<U> { |
97 | 97 | // SimdElement currently requires zero-sized metadata, so this should never fail. |
98 | 98 | // If this ever changes, `simd_cast_ptr` should produce a post-mono error. |
99 | -use core::{mem::size_of, ptr::Pointee}; | |
99 | +use core::ptr::Pointee; | |
100 | 100 | assert_eq!(size_of::<<T as Pointee>::Metadata>(), 0); |
101 | 101 | assert_eq!(size_of::<<U as Pointee>::Metadata>(), 0); |
102 | 102 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -93,7 +93,7 @@ where | ||
93 | 93 | fn cast<U>(self) -> Self::CastPtr<U> { |
94 | 94 | // SimdElement currently requires zero-sized metadata, so this should never fail. |
95 | 95 | // If this ever changes, `simd_cast_ptr` should produce a post-mono error. |
96 | -use core::{mem::size_of, ptr::Pointee}; | |
96 | +use core::ptr::Pointee; | |
97 | 97 | assert_eq!(size_of::<<T as Pointee>::Metadata>(), 0); |
98 | 98 | assert_eq!(size_of::<<U as Pointee>::Metadata>(), 0); |
99 | 99 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -7,7 +7,6 @@ | ||
7 | 7 | use std::collections::HashMap; |
8 | 8 | use std::hash::BuildHasherDefault; |
9 | 9 | use std::hash::Hasher; |
10 | -use std::mem::size_of; | |
11 | 10 | use std::ops::BitXor; |
12 | 11 | |
13 | 12 | /// Type alias for a hashmap using the `fx` hash algorithm. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1218,7 +1218,7 @@ where | ||
1218 | 1218 | /// will cause the map to produce seemingly random results. Higher-level and |
1219 | 1219 | /// more foolproof APIs like `entry` should be preferred when possible. |
1220 | 1220 | /// |
1221 | - /// In particular, the hash used to initialized the raw entry must still be | |
1221 | + /// In particular, the hash used to initialize the raw entry must still be | |
1222 | 1222 | /// consistent with the hash of the key that is ultimately stored in the entry. |
1223 | 1223 | /// This is because implementations of HashMap may need to recompute hashes |
1224 | 1224 | /// when resizing, at which point only the keys are available. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -104,7 +104,6 @@ | ||
104 | 104 | |
105 | 105 | use super::{Custom, ErrorData, ErrorKind, RawOsError, SimpleMessage}; |
106 | 106 | use core:๐:PhantomData; |
107 | -use core::mem::{align_of, size_of}; | |
108 | 107 | use core::ptr::{self, NonNull}; |
109 | 108 | |
110 | 109 | // The 2 least-significant bits are used as tag. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1190,9 +1190,8 @@ pub trait IsTerminal: crate::sealed::Sealed { | ||
1190 | 1190 | /// |
1191 | 1191 | /// - If you run this example by piping some text to it, e.g. `echo "foo" | path/to/executable` |
1192 | 1192 | /// it will print: `Hello foo`. |
1193 | - /// - If you instead run the example interactively by running the executable directly, it will | |
1194 | - /// panic with the message "Expected input to be piped to the process". | |
1195 | - /// | |
1193 | + /// - If you instead run the example interactively by running `path/to/executable` directly, it will | |
1194 | + /// prompt for input. | |
1196 | 1195 | /// |
1197 | 1196 | /// [changes]: io#platform-specific-behavior |
1198 | 1197 | /// [`Stdin`]: crate::io::Stdin |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -3,7 +3,7 @@ | ||
3 | 3 | use super::{sockaddr_un, SocketAddr}; |
4 | 4 | use crate::io::{self, IoSlice, IoSliceMut}; |
5 | 5 | use crate:๐:PhantomData; |
6 | -use crate::mem::{size_of, zeroed}; | |
6 | +use crate::mem::zeroed; | |
7 | 7 | use crate::os::unix::io::RawFd; |
8 | 8 | use crate::path::Path; |
9 | 9 | use crate::ptr::{eq, read_unaligned}; |