diff --git a/src/alloc.rs b/src/alloc.rs index 59c3eb4c5..250d1f112 100644 --- a/src/alloc.rs +++ b/src/alloc.rs @@ -2,6 +2,22 @@ pub(crate) use self::inner::AllocError; pub(crate) use self::inner::{Allocator, Global, do_alloc}; +// Since `ToOwned` is defined in `alloc`, this would prevent us from using +// this crate in `alloc`; that would be a circular dependency. To get around +// this particular restriction for `ToOwned`, we just make our own `ToOwned` +// trait here that `alloc` can blanket-forward to its own definition of +// `ToOwned` instead. +#[cfg(feature = "rustc-dep-of-std")] +#[expect(missing_docs)] +pub trait ToOwned { + type Owned: core::borrow::Borrow; + fn to_owned(&self) -> Self::Owned; +} + +// In every other case, we just use the regular `ToOwned`. +#[cfg(not(feature = "rustc-dep-of-std"))] +pub(crate) use stdalloc::borrow::ToOwned; + // Nightly-case. // Use unstable `allocator_api` feature. // This is compatible with `allocator-api2` which can be enabled or not. diff --git a/src/lib.rs b/src/lib.rs index d0cfd10e4..924fbf0cb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -69,6 +69,9 @@ pub use crate::hasher::DefaultHashBuilder; #[cfg(feature = "default-hasher")] pub use crate::hasher::DefaultHasher; +#[cfg(feature = "rustc-dep-of-std")] +pub use crate::alloc::ToOwned; + pub mod hash_map { //! A hash map implemented with quadratic probing and SIMD lookup. pub use crate::map::*; diff --git a/src/map.rs b/src/map.rs index 279c71595..965583746 100644 --- a/src/map.rs +++ b/src/map.rs @@ -1,3 +1,4 @@ +use crate::alloc::ToOwned; use crate::alloc::{Allocator, Global}; use crate::raw::{Bucket, RawDrain, RawExtractIf, RawIntoIter, RawIter, RawTable}; use crate::{DefaultHashBuilder, Equivalent, TryReserveError}; @@ -8,7 +9,6 @@ use core::iter::FusedIterator; use core::marker::PhantomData; use core::mem; use core::ops::Index; -use stdalloc::borrow::ToOwned; #[cfg(feature = "raw-entry")] pub use crate::raw_entry::*; @@ -5073,12 +5073,11 @@ mod test_map { use super::Entry::{Occupied, Vacant}; use super::EntryRef; use super::HashMap; - use crate::alloc::{AllocError, Allocator, Global}; + use crate::alloc::{AllocError, Allocator, Global, ToOwned}; use core::alloc::Layout; use core::ptr::NonNull; use core::sync::atomic::{AtomicI8, Ordering}; use rand::{Rng, SeedableRng, rngs::SmallRng}; - use std::borrow::ToOwned; use std::cell::RefCell; use std::vec::Vec; use stdalloc::string::String; diff --git a/src/set.rs b/src/set.rs index e2a33a8b2..16b1b5848 100644 --- a/src/set.rs +++ b/src/set.rs @@ -1574,7 +1574,13 @@ where entry.remove(); } map::EntryRef::Vacant(entry) => { - entry.insert(()); + // SAFETY: We know that `item.clone()` is equivalent to `item`. + // + // This is *required* to get around the lack of *any* impl + // for `ToOwned` when compiling as `rustc-dep-of-std`. + unsafe { + entry.insert_with_key_unchecked(item.clone(), ()); + } } } }