diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 613efa0..9ee487a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,7 +11,7 @@ jobs: test: strategy: matrix: - os: [ubuntu-latest, windows-latest, macos-latest] + os: [ubuntu-latest, macos-latest, windows-latest] rust: ["stable", "nightly"] no_std: [true, false] debug: [true, false] @@ -92,4 +92,4 @@ jobs: components: miri override: true - run: cargo miri setup - - run: cargo miri test --all-features --verbose --color=always + - run: cargo miri test --all-features --verbose diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 3c02253..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "rust-analyzer.check.features": "all", -} diff --git a/Cargo.toml b/Cargo.toml index ac934d3..5c339ff 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,6 +38,9 @@ ptr_metadata = [] error_in_core = [] allocator_api = [] +[dependencies] +sptr = "0.3.2" + [dev-dependencies] byteorder = "1.4" diff --git a/build.rs b/build.rs index 8549b51..0bce83d 100644 --- a/build.rs +++ b/build.rs @@ -8,6 +8,6 @@ fn main() { .stdout; let version = String::from_utf8_lossy(&output); if version.contains("nightly") { - println!("cargo:rustc-cfg=NIGHTLY") + println!("cargo:rustc-cfg=nightly") } } diff --git a/examples/default_impl.rs b/examples/default_impl.rs index b3afac2..d99d243 100644 --- a/examples/default_impl.rs +++ b/examples/default_impl.rs @@ -20,5 +20,5 @@ fn main() { // All stored data gets cleaned up once `memory` goes out of scope, or we // can forget it existed: - memory.forget(); + // memory.forget(); } diff --git a/examples/unsafe_impl.rs b/examples/unsafe_impl.rs index 208bb90..e0e2407 100644 --- a/examples/unsafe_impl.rs +++ b/examples/unsafe_impl.rs @@ -26,5 +26,5 @@ fn main() { // All stored data gets cleaned up once `memory` goes out of scope, or we // can forget it existed: - memory.forget(); + // memory.forget(); } diff --git a/src/lib.rs b/src/lib.rs index 63df4e3..39bd166 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,9 +1,12 @@ #![allow(incomplete_features)] +#![allow(unstable_name_collisions)] #![cfg_attr(feature = "no_std", no_std)] #![cfg_attr(feature = "ptr_metadata", feature(ptr_metadata, unsize))] #![cfg_attr(feature = "error_in_core", feature(error_in_core))] #![cfg_attr(feature = "allocator_api", feature(allocator_api))] -#![cfg_attr(all(doc, feature = "NIGHTLY"), feature(doc_auto_cfg))] +#![cfg_attr(all(doc, nightly), feature(doc_auto_cfg))] +#![cfg_attr(nightly, feature(strict_provenance))] +#![cfg_attr(nightly, warn(fuzzy_provenance_casts))] #![warn(missing_docs)] #![doc = include_str!("../doc/crate.md")] @@ -465,10 +468,17 @@ impl, A: ManageMemory> ContiguousMemory { /// let mut s: ContiguousMemory = ContiguousMemory::new(); /// /// assert!(s.try_grow_to(1024).is_ok()); + /// ``` + /// + /// The method returns an error if the system can't reserve requested + /// memory: + /// ```should_panic + /// # use contiguous_mem::ContiguousMemory; + /// # let mut s: ContiguousMemory = ContiguousMemory::new(); /// /// let required_size: usize = usize::MAX; // bad read? /// // can't allocate all addressable memory - /// assert!(s.try_grow_to(required_size).is_err()); + /// assert!(s.try_grow_to(required_size).is_ok()); // PANIC! /// ``` pub fn try_grow_to(&mut self, new_capacity: usize) -> Result, MemoryError> { let mut base = WritableInner::write(&self.inner.base).unwrap(); @@ -480,10 +490,10 @@ impl, A: ManageMemory> ContiguousMemory { return Ok(None); }; - let prev_base = *base; - base.address = unsafe { self.inner.alloc.grow(prev_base, new_capacity)? }; + let new_addr = unsafe { self.inner.alloc.grow(*base, new_capacity)? }; - Ok(if base.address != prev_base.address { + Ok(if new_addr != base.address { + base.address = new_addr; Some(*base) } else { None @@ -656,15 +666,17 @@ impl, A: ManageMemory> ContiguousMemory { /// /// assert!(s.try_reserve_exact(1024).is_ok()); /// assert_eq!(s.capacity(), 1024); + /// ``` /// - /// let el_count: usize = 42; - /// let el_size: usize = 288230376151711744; // bad read? + /// The method returns an error if the system can't reserve requested + /// memory: + /// ```should_panic + /// # use contiguous_mem::ContiguousMemory; + /// # let mut s: ContiguousMemory = ContiguousMemory::new(); /// - /// let mut required_size: usize = 0; - /// for i in 0..el_count { - /// required_size += el_size; - /// } - /// assert!(s.try_reserve_exact(required_size).is_err()); + /// let required_size: usize = usize::MAX; // bad read? + /// // can't allocate all addressable memory + /// assert!(s.try_reserve_exact(required_size).is_ok()); // PANIC! /// ``` pub fn try_reserve_exact( &mut self, diff --git a/src/memory.rs b/src/memory.rs index 477ce75..59e8d40 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -462,8 +462,8 @@ pub trait ManageMemory { unsafe fn grow(&self, base: MemoryBase, new_size: usize) -> Result; } -unsafe fn some_non_null_slice(data: *const u8, len: usize) -> Option> { - Some(NonNull::from(core::slice::from_raw_parts(data, len))) +unsafe fn some_non_null_slice(data: *mut u8, len: usize) -> Option> { + Some(NonNull::from(core::slice::from_raw_parts_mut(data, len))) } /// Default [memory manager](ManageMemory) that uses the methods exposed by diff --git a/src/range.rs b/src/range.rs index 99b50a6..94186fd 100644 --- a/src/range.rs +++ b/src/range.rs @@ -2,6 +2,8 @@ use core::fmt::Display; +use sptr::Strict; + use crate::raw::BaseAddress; /// Represents a range of bytes. @@ -133,12 +135,12 @@ impl ByteRange { #[inline] pub(crate) fn offset_base(&self, addr: BaseAddress) -> Option<*mut T> { - addr.map(|it| (it.as_ptr() as *mut u8 as usize + self.0) as *mut T) + addr.map(|it| (it.as_ptr() as *const u8).map_addr(|addr| addr + self.0) as *mut T) } #[inline] pub(crate) unsafe fn offset_base_unwrap(&self, addr: BaseAddress) -> *mut T { - (unsafe { addr.unwrap_unchecked().as_ptr() } as *mut u8 as usize + self.0) as *mut T + (addr.unwrap_unchecked().as_ptr() as *mut u8).map_addr(|addr| addr + self.0) as *mut T } }