From 6c40a03221e288a1196ea7405f97ead00264b5f6 Mon Sep 17 00:00:00 2001 From: Parker Timmerman Date: Sun, 29 Dec 2024 15:14:42 -0500 Subject: [PATCH] ci: Pin Rust Version, don't use Nightly `rustfmt` features, fix Fuzz workflow (#414) * start * pin Rust version for clippy, doc, and fmt to 1.83.0 * change rustfmt settings to not use nightly * cargo fmt --all * clippy * pin Rust version for ci.yml * pin a Nightly version in CI, fix test, maybe fix fuzzing * use Nightly for cargo doc, use pinned Nightly for fuzzing * fix fuzzer to account for change in #379 --- .github/workflows/ci.yml | 24 +++++++------ .github/workflows/clippy.yml | 20 +++++------ .github/workflows/cross_platform.yml | 5 +-- .github/workflows/fuzz.yml | 24 ++++++------- .rustfmt.toml | 8 ----- bench/benches/apis.rs | 7 +--- bench/benches/compact_str.rs | 12 ++----- bench/benches/comparison.rs | 7 +--- bench/benches/random.rs | 8 +---- compact_str/src/features/arbitrary.rs | 11 ++---- compact_str/src/features/borsh.rs | 18 ++-------- compact_str/src/features/bytes.rs | 10 ++---- compact_str/src/features/diesel.rs | 8 +---- compact_str/src/features/quickcheck.rs | 5 +-- compact_str/src/features/rkyv.rs | 14 ++------ compact_str/src/features/serde.rs | 25 ++++--------- compact_str/src/features/sqlx.rs | 19 ++-------- compact_str/src/lib.rs | 49 +++++++------------------- compact_str/src/repr/bytes.rs | 9 ++--- compact_str/src/repr/heap.rs | 41 +++++---------------- compact_str/src/repr/inline.rs | 11 ++---- compact_str/src/repr/iter.rs | 12 ++----- compact_str/src/repr/mod.rs | 20 +++-------- compact_str/src/repr/num.rs | 11 ++---- compact_str/src/repr/smallvec.rs | 5 +-- compact_str/src/repr/static_str.rs | 13 ++----- compact_str/src/tests.rs | 24 +++++-------- compact_str/src/traits.rs | 33 ++++------------- examples/diesel/src/lib.rs | 10 ++---- examples/sqlx/src/lib.rs | 15 ++------ examples/traits/src/main.rs | 5 +-- fuzz/src/bin/debug.rs | 5 +-- fuzz/src/creation.rs | 28 ++++++++++----- fuzz/src/lib.rs | 7 ++-- 34 files changed, 144 insertions(+), 379 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fe03363fe..40424d7d0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,6 +12,8 @@ env: RUSTFLAGS: "-D warnings" PROPTEST_CASES: 10000 MIRIFLAGS: "-Zmiri-strict-provenance" + RUST_VERSION: 1.83.0 + RUST_NIGHTLY_VERSION: "nightly-2024-12-20" jobs: check: @@ -21,7 +23,7 @@ jobs: - uses: actions/checkout@v4 - name: Install toolchain - run: rustup toolchain install stable --no-self-update --profile minimal + run: rustup toolchain install ${{ env.RUST_VERSION }} --no-self-update --profile minimal - uses: Swatinem/rust-cache@v2 - name: Check @@ -32,8 +34,8 @@ jobs: fail-fast: false matrix: include: - - toolchain: stable - - toolchain: nightly + - toolchain: ${{ env.RUST_VERSION }} + - toolchain: ${{ env.RUST_NIGHTLY_VERSION }} name: cargo test runs-on: ubuntu-latest @@ -62,8 +64,8 @@ jobs: - name: Install toolchain run: | - rustup toolchain install nightly --no-self-update --profile minimal --component miri - rustup override set nightly + rustup toolchain install ${{ env.RUST_NIGHTLYVERSION }} --no-self-update --profile minimal --component miri + rustup override set ${{ env.RUST_NIGHTLYVERSION }} - name: Install cargo-nextest uses: taiki-e/install-action@nextest - uses: Swatinem/rust-cache@v2 @@ -83,8 +85,8 @@ jobs: - name: Install toolchain run: | - rustup toolchain install nightly --no-self-update --profile minimal - rustup override set nightly + rustup toolchain install ${{ env.RUST_NIGHTLYVERSION }} --no-self-update --profile minimal + rustup override set ${{ env.RUST_NIGHTLYVERSION }} - name: Install cargo-nextest uses: taiki-e/install-action@nextest - uses: Swatinem/rust-cache@v2 @@ -106,8 +108,8 @@ jobs: - name: Install toolchain run: | - rustup toolchain install nightly --no-self-update --profile minimal - rustup override set nightly + rustup toolchain install ${{ env.RUST_VERSION }} --no-self-update --profile minimal + rustup override set ${{ env.RUST_VERSION }} - uses: Swatinem/rust-cache@v2 with: key: ${{ matrix.ex }} @@ -127,8 +129,8 @@ jobs: - name: Install toolchain run: | - rustup toolchain install nightly --no-self-update --profile minimal - rustup override set nightly + rustup toolchain install ${{ env.RUST_VERSION }} --no-self-update --profile minimal + rustup override set ${{ env.RUST_VERSION }} - uses: Swatinem/rust-cache@v2 with: key: ${{ matrix.ex }}-test diff --git a/.github/workflows/clippy.yml b/.github/workflows/clippy.yml index 42a6aca12..38fac38bb 100644 --- a/.github/workflows/clippy.yml +++ b/.github/workflows/clippy.yml @@ -10,6 +10,8 @@ name: Clippy env: CARGO_TERM_COLOR: "always" RUSTFLAGS: "-D warnings" + RUST_VERSION: 1.83.0 + RUST_NIGHTLY_VERSION: "nightly-2024-12-20" jobs: fmt: @@ -21,8 +23,8 @@ jobs: - name: Install toolchain run: | - rustup toolchain install nightly --no-self-update --profile minimal --component rustfmt - rustup override set nightly + rustup toolchain install ${{ env.RUST_VERSION }} --no-self-update --profile minimal --component rustfmt + rustup override set ${{ env.RUST_VERSION }} - name: Run rustfmt Workspace run: cargo fmt --all -- --check @@ -38,15 +40,14 @@ jobs: - name: Install toolchain run: | - rustup toolchain install nightly --no-self-update --profile minimal --component clippy - rustup override set nightly + rustup toolchain install ${{ env.RUST_VERSION }} --no-self-update --profile minimal --component clippy + rustup override set ${{ env.RUST_VERSION }} - uses: Swatinem/rust-cache@v2 - - name: Run clippy Workspace - run: cargo clippy --no-deps --tests + run: cargo clippy --no-deps --tests --all-features - name: Run clippy compact_str - run: cargo clippy --no-deps --tests --manifest-path compact_str/Cargo.toml + run: cargo clippy --no-deps --tests --all-features --manifest-path compact_str/Cargo.toml doc: name: cargo doc @@ -59,9 +60,8 @@ jobs: - name: Install toolchain run: | - rustup toolchain install nightly --no-self-update --profile minimal - rustup override set nightly + rustup toolchain install ${{ env.RUST_NIGHTLY_VERSION }} --no-self-update --profile minimal + rustup override set ${{ env.RUST_NIGHTLY_VERSION }} - uses: Swatinem/rust-cache@v2 - - name: Run rustdoc run: cargo doc --all-features --no-deps --manifest-path compact_str/Cargo.toml diff --git a/.github/workflows/cross_platform.yml b/.github/workflows/cross_platform.yml index 2ddc1865e..ea15bfb5d 100644 --- a/.github/workflows/cross_platform.yml +++ b/.github/workflows/cross_platform.yml @@ -18,6 +18,7 @@ env: PROPTEST_CASES: 1000 RUSTFLAGS: "-D warnings" MIRIFAGS: "-Zmiri-tag-raw-pointers -Zmiri-check-number-validity" + RUST_NIGHTLY_VERSION: "nightly-2024-12-20" jobs: cross-test: @@ -67,8 +68,8 @@ jobs: - name: Install toolchain run: | - rustup toolchain install nightly --no-self-update --profile minimal --component miri --target ${{ matrix.target }} - rustup override set nightly + rustup toolchain install ${{ env.RUST_NIGHTLY_VERSION }} --no-self-update --profile minimal --component miri --target ${{ matrix.target }} + rustup override set ${{ env.RUST_NIGHTLY_VERSION }} - name: Install cross if: "matrix.cross" uses: taiki-e/install-action@cross diff --git a/.github/workflows/fuzz.yml b/.github/workflows/fuzz.yml index 6febd35be..205f6c6ec 100644 --- a/.github/workflows/fuzz.yml +++ b/.github/workflows/fuzz.yml @@ -4,11 +4,11 @@ on: - main pull_request: paths: - - 'compact_str/**' - - 'fuzz/**' - - '.github/workflows/fuzz.yml' - - '!CHANGELOG.md' - - '!**/README.md' + - "compact_str/**" + - "fuzz/**" + - ".github/workflows/fuzz.yml" + - "!CHANGELOG.md" + - "!**/README.md" workflow_dispatch: # schedule: # - cron: '0 01,13 * * *' @@ -18,6 +18,7 @@ name: Fuzz env: CARGO_TERM_COLOR: "always" RUSTFLAGS: "-D warnings -Zrandomize-layout" + RUST_NIGHTLY_VERSION: "nightly-2024-12-20" jobs: libFuzzer_x86_64: @@ -26,17 +27,16 @@ jobs: steps: - uses: actions/checkout@v4 name: Checkout compact_str - + - name: Install toolchain run: | - rustup toolchain install nightly-2024-06-01 --no-self-update --profile minimal - rustup override set nightly-2024-06-01 + rustup toolchain install ${{ env.RUST_NIGHTLY_VERSION }} --no-self-update + rustup override set ${{ env.RUST_NIGHTLY_VERSION }} - name: Install cargo-fuzz - uses: taiki-e/install-action@v2 - with: - tool: cargo-fuzz - - uses: Swatinem/rust-cache@v2 + run: | + cargo install cargo-fuzz + - uses: Swatinem/rust-cache@v2 - name: Set Fuzz Time run: | diff --git a/.rustfmt.toml b/.rustfmt.toml index 7d2831d81..dba831ab6 100644 --- a/.rustfmt.toml +++ b/.rustfmt.toml @@ -1,10 +1,2 @@ -group_imports = "StdExternalCrate" -imports_granularity = "Module" -imports_layout = "Vertical" reorder_modules = true - max_width = 100 - -comment_width = 100 -wrap_comments = true - diff --git a/bench/benches/apis.rs b/bench/benches/apis.rs index 074cfbf5a..8e6bf5b19 100644 --- a/bench/benches/apis.rs +++ b/bench/benches/apis.rs @@ -3,12 +3,7 @@ use std::time::Instant; use compact_str::CompactString; -use criterion::{ - black_box, - criterion_group, - criterion_main, - Criterion, -}; +use criterion::{black_box, criterion_group, criterion_main, Criterion}; static VERY_LONG_STR: &str = include_str!("../data/moby10b.txt"); diff --git a/bench/benches/compact_str.rs b/bench/benches/compact_str.rs index 8b1376f9c..f83858ee9 100644 --- a/bench/benches/compact_str.rs +++ b/bench/benches/compact_str.rs @@ -1,14 +1,6 @@ -use compact_str::{ - CompactString, - ToCompactString, -}; +use compact_str::{CompactString, ToCompactString}; use compact_str_6::CompactString as CompactString6; -use criterion::{ - criterion_group, - criterion_main, - BenchmarkId, - Criterion, -}; +use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion}; fn bench_new(c: &mut Criterion) { c.bench_with_input( diff --git a/bench/benches/comparison.rs b/bench/benches/comparison.rs index 1a9a495b4..8827f2f70 100644 --- a/bench/benches/comparison.rs +++ b/bench/benches/comparison.rs @@ -1,10 +1,5 @@ use compact_str::CompactString; -use criterion::{ - criterion_group, - criterion_main, - BenchmarkId, - Criterion, -}; +use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion}; use smartstring::alias::String as SmartString; use smol_str::SmolStr; diff --git a/bench/benches/random.rs b/bench/benches/random.rs index c9a3a2b92..9453f85a8 100644 --- a/bench/benches/random.rs +++ b/bench/benches/random.rs @@ -1,12 +1,6 @@ //! Random benchmarks to determine if one bit of code is faster than another -use criterion::{ - black_box, - criterion_group, - criterion_main, - BenchmarkId, - Criterion, -}; +use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion}; fn if_statement_min(c: &mut Criterion) { let mask = 192; diff --git a/compact_str/src/features/arbitrary.rs b/compact_str/src/features/arbitrary.rs index 235fd06fa..0867e81fa 100644 --- a/compact_str/src/features/arbitrary.rs +++ b/compact_str/src/features/arbitrary.rs @@ -1,10 +1,6 @@ //! Implements the [`arbitrary::Arbitrary`] trait for [`CompactString`] -use arbitrary::{ - Arbitrary, - Result, - Unstructured, -}; +use arbitrary::{Arbitrary, Result, Unstructured}; use crate::CompactString; @@ -26,10 +22,7 @@ impl<'a> Arbitrary<'a> for CompactString { #[cfg(test)] mod test { - use arbitrary::{ - Arbitrary, - Unstructured, - }; + use arbitrary::{Arbitrary, Unstructured}; use crate::CompactString; diff --git a/compact_str/src/features/borsh.rs b/compact_str/src/features/borsh.rs index 6f174879f..ccdf8d2ef 100644 --- a/compact_str/src/features/borsh.rs +++ b/compact_str/src/features/borsh.rs @@ -4,17 +4,8 @@ use alloc::string::String; use alloc::vec::Vec; use core::str; -use borsh::io::{ - Error, - ErrorKind, - Read, - Result, - Write, -}; -use borsh::{ - BorshDeserialize, - BorshSerialize, -}; +use borsh::io::{Error, ErrorKind, Read, Result, Write}; +use borsh::{BorshDeserialize, BorshSerialize}; use crate::repr::MAX_SIZE; use crate::CompactString; @@ -80,10 +71,7 @@ mod tests { use test_strategy::proptest; - use crate::repr::{ - HEAP_MASK, - MAX_SIZE, - }; + use crate::repr::{HEAP_MASK, MAX_SIZE}; use crate::CompactString; fn assert_roundtrip(s: &str) { diff --git a/compact_str/src/features/bytes.rs b/compact_str/src/features/bytes.rs index a26b1a7a5..ebf25689a 100644 --- a/compact_str/src/features/bytes.rs +++ b/compact_str/src/features/bytes.rs @@ -2,10 +2,7 @@ use core::str::Utf8Error; use bytes::Buf; -use crate::{ - CompactString, - Repr, -}; +use crate::{CompactString, Repr}; impl CompactString { /// Converts a buffer of bytes to a [`CompactString`] @@ -77,10 +74,7 @@ mod test { use proptest::prelude::*; use test_strategy::proptest; - use crate::tests::{ - rand_bytes, - rand_unicode, - }; + use crate::tests::{rand_bytes, rand_unicode}; use crate::CompactString; const MAX_SIZE: usize = core::mem::size_of::(); diff --git a/compact_str/src/features/diesel.rs b/compact_str/src/features/diesel.rs index f7933ef78..2e0e2ee67 100644 --- a/compact_str/src/features/diesel.rs +++ b/compact_str/src/features/diesel.rs @@ -3,13 +3,7 @@ // Copied and adapted from // -use diesel::{ - backend, - deserialize, - expression, - serialize, - sql_types, -}; +use diesel::{backend, deserialize, expression, serialize, sql_types}; use crate::CompactString; diff --git a/compact_str/src/features/quickcheck.rs b/compact_str/src/features/quickcheck.rs index 34caa0cfc..93dba6652 100644 --- a/compact_str/src/features/quickcheck.rs +++ b/compact_str/src/features/quickcheck.rs @@ -3,10 +3,7 @@ use alloc::boxed::Box; use alloc::vec::Vec; -use quickcheck::{ - Arbitrary, - Gen, -}; +use quickcheck::{Arbitrary, Gen}; use crate::CompactString; diff --git a/compact_str/src/features/rkyv.rs b/compact_str/src/features/rkyv.rs index 8dd10682a..0e56fb4f2 100644 --- a/compact_str/src/features/rkyv.rs +++ b/compact_str/src/features/rkyv.rs @@ -1,17 +1,7 @@ #![cfg_attr(docsrs, doc(cfg(feature = "rkyv")))] -use rkyv::string::{ - ArchivedString, - StringResolver, -}; -use rkyv::{ - Archive, - Deserialize, - DeserializeUnsized, - Fallible, - Serialize, - SerializeUnsized, -}; +use rkyv::string::{ArchivedString, StringResolver}; +use rkyv::{Archive, Deserialize, DeserializeUnsized, Fallible, Serialize, SerializeUnsized}; use crate::CompactString; diff --git a/compact_str/src/features/serde.rs b/compact_str/src/features/serde.rs index a78dd8207..e3d5b35a0 100644 --- a/compact_str/src/features/serde.rs +++ b/compact_str/src/features/serde.rs @@ -1,12 +1,7 @@ use alloc::string::String; use alloc::vec::Vec; -use serde::de::{ - Deserializer, - Error, - Unexpected, - Visitor, -}; +use serde::de::{Deserializer, Error, Unexpected, Visitor}; use crate::CompactString; @@ -78,16 +73,10 @@ impl<'de> serde::Deserialize<'de> for CompactString { #[cfg(test)] mod tests { - use alloc::string::{ - String, - ToString, - }; + use alloc::string::{String, ToString}; use alloc::vec::Vec; - use serde::{ - Deserialize, - Serialize, - }; + use serde::{Deserialize, Serialize}; use test_strategy::proptest; use crate::CompactString; @@ -109,7 +98,7 @@ mod tests { #[test] fn test_roundtrip() { let name = "Ferris the Crab"; - let phones = vec!["1-800-111-1111", "2-222-222-2222"]; + let phones = ["1-800-111-1111", "2-222-222-2222"]; let address = Some("123 Sesame Street"); let std = PersonString { @@ -142,13 +131,13 @@ mod tests { fn proptest_roundtrip(name: String, phones: Vec, address: Option) { let std = PersonString { name: name.clone(), - phones: phones.iter().map(|s| s.clone()).collect(), + phones: phones.to_vec(), address: address.clone(), }; let compact = PersonCompactString { name: name.into(), - phones: phones.iter().map(|s| CompactString::from(s)).collect(), - address: address.map(|s| CompactString::from(s)), + phones: phones.iter().map(CompactString::from).collect(), + address: address.map(CompactString::from), }; let std_json = serde_json::to_string(&std).unwrap(); diff --git a/compact_str/src/features/sqlx.rs b/compact_str/src/features/sqlx.rs index 3e37b2ca1..314f118fb 100644 --- a/compact_str/src/features/sqlx.rs +++ b/compact_str/src/features/sqlx.rs @@ -5,23 +5,10 @@ use sqlx::error::BoxDynError; feature = "sqlx-postgres", feature = "sqlx-sqlite" ))] -use sqlx::{ - database::HasArguments, - encode::IsNull, - Encode, -}; -use sqlx::{ - Database, - Decode, - Type, - Value, - ValueRef, -}; +use sqlx::{database::HasArguments, encode::IsNull, Encode}; +use sqlx::{Database, Decode, Type, Value, ValueRef}; -use crate::{ - CompactString, - ToCompactString, -}; +use crate::{CompactString, ToCompactString}; #[cfg_attr(docsrs, doc(cfg(feature = "sqlx")))] impl Type for CompactString diff --git a/compact_str/src/lib.rs b/compact_str/src/lib.rs index 0b8ace663..d1f6a5447 100644 --- a/compact_str/src/lib.rs +++ b/compact_str/src/lib.rs @@ -14,33 +14,13 @@ use alloc::boxed::Box; use alloc::string::String; #[doc(hidden)] // Referenced in macros. pub use core; -use core::borrow::{ - Borrow, - BorrowMut, -}; +use core::borrow::{Borrow, BorrowMut}; use core::cmp::Ordering; -use core::hash::{ - Hash, - Hasher, -}; +use core::hash::{Hash, Hasher}; use core::iter::FusedIterator; -use core::ops::{ - Add, - AddAssign, - Bound, - Deref, - DerefMut, - RangeBounds, -}; -use core::str::{ - FromStr, - Utf8Error, -}; -use core::{ - fmt, - mem, - slice, -}; +use core::ops::{Add, AddAssign, Bound, Deref, DerefMut, RangeBounds}; +use core::str::{FromStr, Utf8Error}; +use core::{fmt, mem, slice}; #[cfg(feature = "std")] use std::ffi::OsStr; @@ -52,10 +32,7 @@ mod repr; use repr::Repr; mod traits; -pub use traits::{ - CompactStringExt, - ToCompactString, -}; +pub use traits::{CompactStringExt, ToCompactString}; #[cfg(test)] mod tests; @@ -2066,7 +2043,7 @@ impl PartialEq for String { } } -impl<'a> PartialEq<&'a CompactString> for String { +impl PartialEq<&CompactString> for String { fn eq(&self, other: &&CompactString) -> bool { self.as_str() == other.as_str() } @@ -2084,7 +2061,7 @@ impl PartialEq for str { } } -impl<'a> PartialEq<&'a CompactString> for str { +impl PartialEq<&'_ CompactString> for str { fn eq(&self, other: &&CompactString) -> bool { self == other.as_str() } @@ -2102,13 +2079,13 @@ impl PartialEq for &&str { } } -impl<'a> PartialEq for Cow<'a, str> { +impl PartialEq for Cow<'_, str> { fn eq(&self, other: &CompactString) -> bool { *self == other.as_str() } } -impl<'a> PartialEq for &Cow<'a, str> { +impl PartialEq for &Cow<'_, str> { fn eq(&self, other: &CompactString) -> bool { *self == other.as_str() } @@ -2120,8 +2097,8 @@ impl PartialEq for &CompactString { } } -impl<'a> PartialEq> for &CompactString { - fn eq(&self, other: &Cow<'a, str>) -> bool { +impl PartialEq> for &CompactString { + fn eq(&self, other: &Cow<'_, str>) -> bool { self.as_str() == other } } @@ -2446,7 +2423,7 @@ impl Extend for CompactString { } } -impl<'a> Extend for Cow<'a, str> { +impl Extend for Cow<'_, str> { fn extend>(&mut self, iter: T) { self.to_mut().extend(iter); } diff --git a/compact_str/src/repr/bytes.rs b/compact_str/src/repr/bytes.rs index 312a930a0..ebf76e9e4 100644 --- a/compact_str/src/repr/bytes.rs +++ b/compact_str/src/repr/bytes.rs @@ -2,10 +2,7 @@ use core::str::Utf8Error; use bytes::Buf; -use super::{ - Repr, - MAX_SIZE, -}; +use super::{Repr, MAX_SIZE}; use crate::UnwrapWithMsg; impl Repr { @@ -161,8 +158,8 @@ mod test { let mut queue = alloc::collections::VecDeque::with_capacity(data.len()); // create a non-contiguous slice of memory in queue - front.into_iter().copied().for_each(|x| queue.push_back(x)); - back.into_iter().copied().for_each(|x| queue.push_front(x)); + front.iter().copied().for_each(|x| queue.push_back(x)); + back.iter().copied().for_each(|x| queue.push_front(x)); // make sure it's non-contiguous let (a, b) = queue.as_slices(); diff --git a/compact_str/src/repr/heap.rs b/compact_str/src/repr/heap.rs index 5bdc79e95..fc12b13d5 100644 --- a/compact_str/src/repr/heap.rs +++ b/compact_str/src/repr/heap.rs @@ -1,19 +1,9 @@ use core::alloc::Layout; -use core::{ - cmp, - mem, - ptr, -}; +use core::{cmp, mem, ptr}; use super::capacity::Capacity; -use super::{ - Repr, - MAX_SIZE, -}; -use crate::{ - ReserveError, - UnwrapWithMsg, -}; +use super::{Repr, MAX_SIZE}; +use crate::{ReserveError, UnwrapWithMsg}; /// The minimum size we'll allocate on the heap is one usize larger than our max inline size const MIN_HEAP_SIZE: usize = MAX_SIZE + mem::size_of::(); @@ -353,15 +343,9 @@ pub(crate) unsafe fn do_alloc(layout: Layout) -> Result, Reserv } mod heap_capacity { - use core::{ - alloc, - ptr, - }; + use core::{alloc, ptr}; - use super::{ - do_alloc, - StrBuffer, - }; + use super::{do_alloc, StrBuffer}; use crate::ReserveError; /// SAFETY: `capacity` must not be zero @@ -397,15 +381,9 @@ mod heap_capacity { } mod inline_capacity { - use core::{ - alloc, - ptr, - }; + use core::{alloc, ptr}; - use super::{ - do_alloc, - StrBuffer, - }; + use super::{do_alloc, StrBuffer}; use crate::ReserveError; /// # SAFETY: @@ -443,10 +421,7 @@ mod inline_capacity { mod test { use test_case::test_case; - use super::{ - HeapBuffer, - MIN_HEAP_SIZE, - }; + use super::{HeapBuffer, MIN_HEAP_SIZE}; const EIGHTEEN_MB: usize = 18 * 1024 * 1024; diff --git a/compact_str/src/repr/inline.rs b/compact_str/src/repr/inline.rs index 5fe559e03..b6201cbbe 100644 --- a/compact_str/src/repr/inline.rs +++ b/compact_str/src/repr/inline.rs @@ -1,10 +1,6 @@ use core::ptr; -use super::{ - Repr, - LENGTH_MASK, - MAX_SIZE, -}; +use super::{Repr, LENGTH_MASK, MAX_SIZE}; /// A buffer stored on the stack whose size is equal to the stack size of `String` #[cfg(target_pointer_width = "64")] @@ -158,10 +154,7 @@ mod tests { use quickcheck_macros::quickcheck; - use crate::repr::{ - InlineBuffer, - MAX_SIZE, - }; + use crate::repr::{InlineBuffer, MAX_SIZE}; #[test] fn test_into_array() { diff --git a/compact_str/src/repr/iter.rs b/compact_str/src/repr/iter.rs index b10a4ae93..74225ad16 100644 --- a/compact_str/src/repr/iter.rs +++ b/compact_str/src/repr/iter.rs @@ -4,16 +4,8 @@ use alloc::borrow::Cow; use alloc::boxed::Box; use alloc::string::String; -use super::{ - InlineBuffer, - Repr, - EMPTY, - MAX_SIZE, -}; -use crate::{ - CompactString, - UnwrapWithMsg, -}; +use super::{InlineBuffer, Repr, EMPTY, MAX_SIZE}; +use crate::{CompactString, UnwrapWithMsg}; impl FromIterator for Repr { #[inline] diff --git a/compact_str/src/repr/mod.rs b/compact_str/src/repr/mod.rs index 58d69b045..88498c50d 100644 --- a/compact_str/src/repr/mod.rs +++ b/compact_str/src/repr/mod.rs @@ -1,10 +1,7 @@ use alloc::borrow::Cow; use alloc::boxed::Box; use core::str::Utf8Error; -use core::{ - mem, - ptr, -}; +use core::{mem, ptr}; #[cfg(feature = "bytes")] mod bytes; @@ -29,10 +26,7 @@ use last_utf8_char::LastByte; use static_str::StaticStr; pub(crate) use traits::IntoRepr; -use crate::{ - ReserveError, - UnwrapWithMsg, -}; +use crate::{ReserveError, UnwrapWithMsg}; /// The max size of a string we can fit inline pub(crate) const MAX_SIZE: usize = core::mem::size_of::(); @@ -802,19 +796,13 @@ fn ensure_read(value: usize) -> usize { #[cfg(test)] mod tests { - use alloc::string::{ - String, - ToString, - }; + use alloc::string::{String, ToString}; use alloc::vec::Vec; use quickcheck_macros::quickcheck; use test_case::test_case; - use super::{ - Repr, - MAX_SIZE, - }; + use super::{Repr, MAX_SIZE}; use crate::ReserveError; const EIGHTEEN_MB: usize = 18 * 1024 * 1024; diff --git a/compact_str/src/repr/num.rs b/compact_str/src/repr/num.rs index 429a45f11..a43ccc962 100644 --- a/compact_str/src/repr/num.rs +++ b/compact_str/src/repr/num.rs @@ -3,18 +3,11 @@ //! Adapted from the implementation in the `std` library at //! -use core::{ - mem, - num, - ptr, -}; +use core::{mem, num, ptr}; use super::traits::IntoRepr; use super::Repr; -use crate::{ - ToCompactStringError, - UnwrapWithMsg, -}; +use crate::{ToCompactStringError, UnwrapWithMsg}; const DEC_DIGITS_LUT: &[u8] = b"\ 0001020304050607080910111213141516171819\ diff --git a/compact_str/src/repr/smallvec.rs b/compact_str/src/repr/smallvec.rs index 6f914d32e..b813f8024 100644 --- a/compact_str/src/repr/smallvec.rs +++ b/compact_str/src/repr/smallvec.rs @@ -1,9 +1,6 @@ use smallvec::SmallVec; -use super::{ - Repr, - MAX_SIZE, -}; +use super::{Repr, MAX_SIZE}; impl Repr { /// Consumes the [`Repr`] returning a byte vector in a [`SmallVec`] diff --git a/compact_str/src/repr/static_str.rs b/compact_str/src/repr/static_str.rs index 2a7b141ac..ff6d560ca 100644 --- a/compact_str/src/repr/static_str.rs +++ b/compact_str/src/repr/static_str.rs @@ -1,15 +1,6 @@ -use core::{ - mem, - ptr, - slice, - str, -}; +use core::{mem, ptr, slice, str}; -use super::{ - Repr, - MAX_SIZE, - STATIC_STR_MASK, -}; +use super::{Repr, MAX_SIZE, STATIC_STR_MASK}; pub(super) const DISCRIMINANT_SIZE: usize = MAX_SIZE - mem::size_of::<&'static str>(); diff --git a/compact_str/src/tests.rs b/compact_str/src/tests.rs index 3397d5f92..1a15c71cb 100644 --- a/compact_str/src/tests.rs +++ b/compact_str/src/tests.rs @@ -1,26 +1,16 @@ use alloc::borrow::Cow; use alloc::boxed::Box; -use alloc::string::{ - String, - ToString, -}; +use alloc::string::{String, ToString}; use alloc::vec::Vec; use core::str::FromStr; -use core::{ - num, - slice, -}; +use core::{num, slice}; use proptest::collection::SizeRange; use proptest::prelude::*; use test_case::test_case; use test_strategy::proptest; -use crate::{ - format_compact, - CompactString, - ToCompactString, -}; +use crate::{format_compact, CompactString, ToCompactString}; #[cfg(target_pointer_width = "64")] const MAX_SIZE: usize = 24; @@ -1231,7 +1221,9 @@ fn test_into_string_empty_str() { let new_str_len = new_string.len(); let new_str_cap = new_string.capacity(); - assert_eq!(String::new().as_ptr(), new_str_addr); + let empty_string = String::new(); + + assert_eq!(empty_string.as_ptr(), new_str_addr); assert_eq!(str_len, new_str_len); assert_eq!(str_len, new_str_cap); } @@ -1247,7 +1239,9 @@ fn test_into_string_empty_static_str() { let new_str_len = new_string.len(); let new_str_cap = new_string.capacity(); - assert_eq!(String::new().as_ptr(), new_str_addr); + let empty_string = String::new(); + + assert_eq!(empty_string.as_ptr(), new_str_addr); assert_eq!(str_len, new_str_len); assert_eq!(str_len, new_str_cap); } diff --git a/compact_str/src/traits.rs b/compact_str/src/traits.rs index da0ccbb26..00e29c6b4 100644 --- a/compact_str/src/traits.rs +++ b/compact_str/src/traits.rs @@ -1,24 +1,11 @@ use alloc::string::String; -use core::fmt::{ - self, - Write, -}; +use core::fmt::{self, Write}; use core::num; -use castaway::{ - match_type, - LifetimeFree, -}; - -use super::repr::{ - IntoRepr, - Repr, -}; -use crate::{ - CompactString, - ToCompactStringError, - UnwrapWithMsg, -}; +use castaway::{match_type, LifetimeFree}; + +use super::repr::{IntoRepr, Repr}; +use crate::{CompactString, ToCompactStringError, UnwrapWithMsg}; /// A trait for converting a value to a `CompactString`. /// @@ -213,20 +200,14 @@ where #[cfg(test)] mod tests { - use alloc::string::{ - String, - ToString, - }; + use alloc::string::{String, ToString}; use alloc::vec::Vec; use core::num; use proptest::prelude::*; use test_strategy::proptest; - use super::{ - CompactStringExt, - ToCompactString, - }; + use super::{CompactStringExt, ToCompactString}; use crate::CompactString; #[test] diff --git a/examples/diesel/src/lib.rs b/examples/diesel/src/lib.rs index 9df000337..ceb222965 100644 --- a/examples/diesel/src/lib.rs +++ b/examples/diesel/src/lib.rs @@ -3,18 +3,12 @@ mod models; mod schema; -use compact_str::{ - format_compact, - CompactString, -}; +use compact_str::{format_compact, CompactString}; use diesel::prelude::*; use diesel::sql_query; use tempfile::tempdir; -use crate::models::{ - NewTodo, - Todo, -}; +use crate::models::{NewTodo, Todo}; use crate::schema::todos; use crate::schema::todos::dsl::*; diff --git a/examples/sqlx/src/lib.rs b/examples/sqlx/src/lib.rs index 1c02e8065..c4f6a5fda 100644 --- a/examples/sqlx/src/lib.rs +++ b/examples/sqlx/src/lib.rs @@ -2,19 +2,8 @@ use std::hint::black_box; -use compact_str::{ - format_compact, - CompactString, -}; -use sqlx::{ - query, - query_as, - query_with, - Acquire, - Arguments, - Executor, - Row, -}; +use compact_str::{format_compact, CompactString}; +use sqlx::{query, query_as, query_with, Acquire, Arguments, Executor, Row}; use tempfile::tempdir; const TITLE: CompactString = CompactString::const_new("Say hello!"); diff --git a/examples/traits/src/main.rs b/examples/traits/src/main.rs index d69958d51..29dacb37d 100644 --- a/examples/traits/src/main.rs +++ b/examples/traits/src/main.rs @@ -1,7 +1,4 @@ -use compact_str::{ - CompactStringExt, - ToCompactString, -}; +use compact_str::{CompactStringExt, ToCompactString}; fn main() { // CompactStringExt allows you to join collections to create a CompactString diff --git a/fuzz/src/bin/debug.rs b/fuzz/src/bin/debug.rs index 4364fd335..52299a0cd 100644 --- a/fuzz/src/bin/debug.rs +++ b/fuzz/src/bin/debug.rs @@ -5,10 +5,7 @@ use std::path::PathBuf; -use arbitrary::{ - Arbitrary, - Unstructured, -}; +use arbitrary::{Arbitrary, Unstructured}; use compact_str_fuzz::Scenario; pub fn main() { diff --git a/fuzz/src/creation.rs b/fuzz/src/creation.rs index 8d4e2cbd2..b9e01a42e 100644 --- a/fuzz/src/creation.rs +++ b/fuzz/src/creation.rs @@ -9,11 +9,7 @@ use std::num; use std::str::FromStr; use arbitrary::Arbitrary; -use compact_str::{ - CompactString, - CompactStringExt, - ToCompactString, -}; +use compact_str::{CompactString, CompactStringExt, ToCompactString}; static EMPTY_STATIC_STR: &str = ""; static SHORT_STATIC_STR: &str = "hello"; @@ -22,10 +18,7 @@ static LONG_STATIC_STR: &str = "this isn't too long, but longer than our inline static HUGE_STATIC_STR: &str = include_str!("../../bench/data/moby10b.txt"); use super::assert_properly_allocated; -use crate::{ - MAX_INLINE_LENGTH, - MIN_HEAP_CAPACITY, -}; +use crate::{MAX_INLINE_LENGTH, MIN_HEAP_CAPACITY}; #[derive(Arbitrary, Debug)] pub enum Creation<'a> { @@ -348,6 +341,23 @@ impl Creation<'_> { } } BytesUnchecked(data) => { + // There's an edge case where the final byte of this buffer == `HEAP_MASK`, which + // is invalid UTF-8, but would result in us creating an inline variant, that + // identifies as a heap variant. If a user ever tried to reference the data at + // all, we'd incorrectly try and read data from an invalid memory address, causing + // undefined behavior. + // + // To prevent breaking the fuzzer we special case this scenario. + let mut fixed_data; + let data = if data.len() == MAX_INLINE_LENGTH && data[data.len() - 1] >= 0b11000000 + { + fixed_data = data.to_vec(); + fixed_data[data.len() - 1] = 1; + &fixed_data + } else { + data + }; + // The data provided might not be valid UTF-8. We mainly want to make sure we don't // panic, and the data is written correctly. Before returning either of these types // we'll make sure they contain valid data diff --git a/fuzz/src/lib.rs b/fuzz/src/lib.rs index 656c91ea4..b78b34724 100644 --- a/fuzz/src/lib.rs +++ b/fuzz/src/lib.rs @@ -14,10 +14,7 @@ use arbitrary::Arbitrary; use compact_str::CompactString; use rand::rngs::SmallRng; use rand::SeedableRng; -use rand_distr::{ - Distribution, - SkewNormal, -}; +use rand_distr::{Distribution, SkewNormal}; const MAX_INLINE_LENGTH: usize = std::mem::size_of::(); const MIN_HEAP_CAPACITY: usize = std::mem::size_of::() * 4; @@ -40,7 +37,7 @@ pub struct Scenario<'a> { pub seed: u64, } -impl<'a> Scenario<'a> { +impl Scenario<'_> { /// Run the provided scenario, asserting for correct behavior pub fn run(self) { // Given random creation method, if we can create a string