From 56e230fb577f9a81280d4df71dc296b258491262 Mon Sep 17 00:00:00 2001 From: NathanRoyer Date: Thu, 7 Sep 2023 11:31:41 +0200 Subject: [PATCH 1/2] Make thin-vec compatible with no_std --- Cargo.toml | 3 ++- src/lib.rs | 52 +++++++++++++++++++++++++++++----------------------- 2 files changed, 31 insertions(+), 24 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 51423e2..5074c44 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,8 @@ readme = "README.md" [features] unstable = [] -default = [] +default = ["std"] +std = [] # Gecko specific features. These features cause thin-vec to have the same layout # and behaviour as nsTArray, allowing it to be used in C++ FFI. Requires diff --git a/src/lib.rs b/src/lib.rs index 4900773..29ca9ea 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -141,21 +141,26 @@ //! //! [pinned]: https://doc.rust-lang.org/std/pin/index.html +#![cfg_attr(not(feature = "std"), no_std)] + #![allow(clippy::comparison_chain, clippy::missing_safety_doc)] -use std::alloc::*; -use std::borrow::*; -use std::cmp::*; -use std::convert::TryFrom; -use std::convert::TryInto; -use std::hash::*; -use std::iter::FromIterator; -use std::marker::PhantomData; -use std::ops::Bound; -use std::ops::{Deref, DerefMut, RangeBounds}; -use std::ptr::NonNull; -use std::slice::IterMut; -use std::{fmt, io, mem, ptr, slice}; +extern crate alloc; + +use alloc::{vec::Vec, boxed::Box}; +use alloc::alloc::*; +use core::borrow::*; +use core::cmp::*; +use core::convert::TryFrom; +use core::convert::TryInto; +use core::hash::*; +use core::iter::FromIterator; +use core::marker::PhantomData; +use core::ops::Bound; +use core::ops::{Deref, DerefMut, RangeBounds}; +use core::ptr::NonNull; +use core::slice::IterMut; +use core::{fmt, mem, ptr, slice}; use impl_details::*; @@ -1124,7 +1129,7 @@ impl ThinVec { min_cap_bytes.next_power_of_two() as usize }; - let cap = (bytes - std::mem::size_of::
()) / elem_size; + let cap = (bytes - core::mem::size_of::
()) / elem_size; unsafe { self.reallocate(cap); } @@ -2013,7 +2018,7 @@ impl From<[T; N]> for ThinVec { /// assert_eq!(ThinVec::from([1, 2, 3]), thin_vec![1, 2, 3]); /// ``` fn from(s: [T; N]) -> ThinVec { - std::iter::IntoIterator::into_iter(s).collect() + core::iter::IntoIterator::into_iter(s).collect() } } @@ -2255,11 +2260,11 @@ impl DoubleEndedIterator for IntoIter { impl ExactSizeIterator for IntoIter {} -impl std::iter::FusedIterator for IntoIter {} +impl core::iter::FusedIterator for IntoIter {} // SAFETY: the length calculation is trivial, we're an array! And if it's wrong we're So Screwed. #[cfg(feature = "unstable")] -unsafe impl std::iter::TrustedLen for IntoIter {} +unsafe impl core::iter::TrustedLen for IntoIter {} impl Drop for IntoIter { #[inline] @@ -2421,9 +2426,9 @@ impl<'a, T> ExactSizeIterator for Drain<'a, T> {} // SAFETY: we need to keep track of this perfectly Or Else anyway! #[cfg(feature = "unstable")] -unsafe impl std::iter::TrustedLen for Drain<'_, T> {} +unsafe impl core::iter::TrustedLen for Drain<'_, T> {} -impl std::iter::FusedIterator for Drain<'_, T> {} +impl core::iter::FusedIterator for Drain<'_, T> {} impl<'a, T> Drop for Drain<'a, T> { fn drop(&mut self) { @@ -2610,21 +2615,22 @@ impl Drain<'_, T> { /// Write is implemented for `ThinVec` by appending to the vector. /// The vector will grow as needed. /// This implementation is identical to the one for `Vec`. -impl io::Write for ThinVec { +#[cfg(feature = "std")] +impl std::io::Write for ThinVec { #[inline] - fn write(&mut self, buf: &[u8]) -> io::Result { + fn write(&mut self, buf: &[u8]) -> std::io::Result { self.extend_from_slice(buf); Ok(buf.len()) } #[inline] - fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { + fn write_all(&mut self, buf: &[u8]) -> std::io::Result<()> { self.extend_from_slice(buf); Ok(()) } #[inline] - fn flush(&mut self) -> io::Result<()> { + fn flush(&mut self) -> std::io::Result<()> { Ok(()) } } From 9deda745df55e8fe2812387bf7ab48c1c7d60933 Mon Sep 17 00:00:00 2001 From: Aria Beingessner Date: Sat, 2 Dec 2023 22:00:59 -0500 Subject: [PATCH 2/2] fix: make tests check no_std, fix clippy/fmt --- .github/workflows/rust.yml | 14 ++++++++------ src/lib.rs | 27 +++++++++++++++++---------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 8245618..54e4fba 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -24,7 +24,7 @@ jobs: run: MIRIFLAGS=-Zmiri-strict-provenance cargo miri test - name: Test (gecko-ffi) with Miri run: MIRIFLAGS=-Zmiri-strict-provenance cargo miri test --features=gecko-ffi - + build: runs-on: ubuntu-latest steps: @@ -39,7 +39,9 @@ jobs: run: cargo test --features=serde --verbose - name: Run tests (gecko-ffi) run: cargo test --tests --features=gecko-ffi --verbose - + - name: Run tests (no_std) + run: cargo test --tests --no-default-features --verbose + fmt: runs-on: ubuntu-latest steps: @@ -54,8 +56,8 @@ jobs: with: command: fmt args: --all -- --check - - + + clippy: runs-on: ubuntu-latest steps: @@ -72,8 +74,8 @@ jobs: with: token: ${{ secrets.GITHUB_TOKEN }} args: --workspace --tests --examples - - + + docs: runs-on: ubuntu-latest env: diff --git a/src/lib.rs b/src/lib.rs index 29ca9ea..6616514 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -142,13 +142,12 @@ //! [pinned]: https://doc.rust-lang.org/std/pin/index.html #![cfg_attr(not(feature = "std"), no_std)] - #![allow(clippy::comparison_chain, clippy::missing_safety_doc)] extern crate alloc; -use alloc::{vec::Vec, boxed::Box}; use alloc::alloc::*; +use alloc::{boxed::Box, vec::Vec}; use core::borrow::*; use core::cmp::*; use core::convert::TryFrom; @@ -1971,7 +1970,7 @@ impl FromIterator for ThinVec { #[inline] fn from_iter>(iter: I) -> ThinVec { let mut vec = ThinVec::new(); - vec.extend(iter.into_iter()); + vec.extend(iter); vec } } @@ -2640,10 +2639,11 @@ impl std::io::Write for ThinVec { #[cfg(test)] mod tests { use super::{ThinVec, MAX_CAP}; + use crate::alloc::{string::ToString, vec}; #[test] fn test_size_of() { - use std::mem::size_of; + use core::mem::size_of; assert_eq!(size_of::>(), size_of::<&u8>()); assert_eq!(size_of::>>(), size_of::<&u8>()); @@ -2831,6 +2831,7 @@ mod tests { assert_eq!(v.into_iter().count(), 0); let v = ThinVec::::new(); + #[allow(clippy::never_loop)] for _ in v.into_iter() { unreachable!(); } @@ -2840,6 +2841,7 @@ mod tests { let mut v = ThinVec::::new(); assert_eq!(v.drain(..).len(), 0); + #[allow(clippy::never_loop)] for _ in v.drain(..) { unreachable!() } @@ -2853,6 +2855,7 @@ mod tests { let mut v = ThinVec::::new(); assert_eq!(v.splice(.., []).len(), 0); + #[allow(clippy::never_loop)] for _ in v.splice(.., []) { unreachable!() } @@ -3016,8 +3019,12 @@ mod std_tests { #![allow(clippy::reversed_empty_ranges)] use super::*; - use std::mem::size_of; - use std::usize; + use crate::alloc::{ + format, + string::{String, ToString}, + }; + use core::mem::size_of; + use core::usize; struct DropCounter<'a> { count: &'a mut u32, @@ -3675,7 +3682,7 @@ mod std_tests { fn test_splice_forget() { let mut v = thin_vec![1, 2, 3, 4, 5]; let a = [10, 11, 12]; - ::std::mem::forget(v.splice(2..4, a.iter().cloned())); + ::core::mem::forget(v.splice(2..4, a.iter().cloned())); assert_eq!(v, &[1, 2]); } @@ -4194,7 +4201,7 @@ mod std_tests { let v: ThinVec<$typename> = ThinVec::with_capacity(1 /* ensure allocation */); let head_ptr: *mut $typename = v.data_raw(); assert_eq!( - head_ptr as usize % std::mem::align_of::<$typename>(), + head_ptr as usize % core::mem::align_of::<$typename>(), 0, "expected Header::data<{}> to be aligned", stringify!($typename) @@ -4202,8 +4209,8 @@ mod std_tests { }}; } - const HEADER_SIZE: usize = std::mem::size_of::
(); - assert_eq!(2 * std::mem::size_of::(), HEADER_SIZE); + const HEADER_SIZE: usize = core::mem::size_of::
(); + assert_eq!(2 * core::mem::size_of::(), HEADER_SIZE); #[repr(C, align(128))] struct Funky(T);