Skip to content

Commit 6832c5a

Browse files
authored
Merge pull request #19512 from BenjaminBrienen/update-stdx
Upstream stdx changes
2 parents 588948f + 428ee50 commit 6832c5a

File tree

11 files changed

+131
-97
lines changed

11 files changed

+131
-97
lines changed

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/stdx/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ rust-version.workspace = true
1313

1414
[dependencies]
1515
backtrace = { version = "0.3.74", optional = true }
16-
jod-thread = "0.1.2"
16+
jod-thread = "1.0.0"
1717
crossbeam-channel.workspace = true
1818
itertools.workspace = true
1919
tracing.workspace = true

crates/stdx/src/anymap.rs

Lines changed: 49 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
//! This file is a port of only the necessary features from <https://github.com/chris-morgan/anymap> version 1.0.0-beta.2 for use within rust-analyzer.
2+
//!
23
//! Copyright © 2014–2022 Chris Morgan.
34
//! COPYING: <https://github.com/chris-morgan/anymap/blob/master/COPYING>
45
//! Note that the license is changed from Blue Oak Model 1.0.0 or MIT or Apache-2.0 to MIT OR Apache-2.0
@@ -20,14 +21,14 @@
2021

2122
use core::hash::Hasher;
2223

23-
/// A hasher designed to eke a little more speed out, given `TypeId`s known characteristics.
24+
/// A hasher designed to eke a little more speed out, given `TypeId`'s known characteristics.
2425
///
25-
/// Specifically, this is a no-op hasher that expects to be fed a u64s worth of
26+
/// Specifically, this is a no-op hasher that expects to be fed a u64's worth of
2627
/// randomly-distributed bits. It works well for `TypeId` (eliminating start-up time, so that my
27-
/// get_missing benchmark is ~30ns rather than ~900ns, and being a good deal faster after that, so
28-
/// that my insert_and_get_on_260_types benchmark is ~12μs instead of ~21.5μs), but will
28+
/// `get_missing` benchmark is ~30ns rather than ~900ns, and being a good deal faster after that, so
29+
/// that my `insert_and_get_on_260_types` benchmark is ~12μs instead of ~21.5μs), but will
2930
/// panic in debug mode and always emit zeros in release mode for any other sorts of inputs, so
30-
/// yeah, dont use it! 😀
31+
/// yeah, don't use it! 😀
3132
#[derive(Default)]
3233
pub struct TypeIdHasher {
3334
value: u64,
@@ -36,9 +37,9 @@ pub struct TypeIdHasher {
3637
impl Hasher for TypeIdHasher {
3738
#[inline]
3839
fn write(&mut self, bytes: &[u8]) {
39-
// This expects to receive exactly one 64-bit value, and theres no realistic chance of
40-
// that changing, but I dont want to depend on something that isnt expressly part of the
41-
// contract for safety. But Im OK with release builds putting everything in one bucket
40+
// This expects to receive exactly one 64-bit value, and there's no realistic chance of
41+
// that changing, but I don't want to depend on something that isn't expressly part of the
42+
// contract for safety. But I'm OK with release builds putting everything in one bucket
4243
// if it *did* change (and debug builds panicking).
4344
debug_assert_eq!(bytes.len(), 8);
4445
let _ = bytes.try_into().map(|array| self.value = u64::from_ne_bytes(array));
@@ -59,7 +60,7 @@ use ::std::collections::hash_map;
5960
/// Raw access to the underlying `HashMap`.
6061
///
6162
/// This alias is provided for convenience because of the ugly third generic parameter.
62-
#[allow(clippy::disallowed_types)] // Uses a custom hasher
63+
#[expect(clippy::disallowed_types, reason = "Uses a custom hasher")]
6364
pub type RawMap<A> = hash_map::HashMap<TypeId, Box<A>, BuildHasherDefault<TypeIdHasher>>;
6465

6566
/// A collection containing zero or one values for any given type and allowing convenient,
@@ -73,19 +74,20 @@ pub type RawMap<A> = hash_map::HashMap<TypeId, Box<A>, BuildHasherDefault<TypeId
7374
///
7475
/// Cumulatively, there are thus six forms of map:
7576
///
76-
/// - <code>[Map]&lt;dyn [core::any::Any]&gt;</code>,
77+
/// - `[Map]<dyn [core::any::Any]>`,
7778
/// also spelled [`AnyMap`] for convenience.
78-
/// - <code>[Map]&lt;dyn [core::any::Any] + Send&gt;</code>
79-
/// - <code>[Map]&lt;dyn [core::any::Any] + Send + Sync&gt;</code>
79+
/// - `[Map]<dyn [core::any::Any] + Send>`
80+
/// - `[Map]<dyn [core::any::Any] + Send + Sync>`
8081
///
8182
/// ## Example
8283
///
83-
/// (Here using the [`AnyMap`] convenience alias; the first line could use
84-
/// <code>[anymap::Map][Map]::&lt;[core::any::Any]&gt;::new()</code> instead if desired.)
84+
/// (Here, the [`AnyMap`] convenience alias is used;
85+
/// the first line could use `[anymap::Map][Map]::<[core::any::Any]>::new()`
86+
/// instead if desired.)
8587
///
8688
/// ```
8789
/// # use stdx::anymap;
88-
#[doc = "let mut data = anymap::AnyMap::new();"]
90+
/// let mut data = anymap::AnyMap::new();
8991
/// assert_eq!(data.get(), None::<&i32>);
9092
/// ```
9193
///
@@ -95,11 +97,11 @@ pub struct Map<A: ?Sized + Downcast = dyn Any> {
9597
raw: RawMap<A>,
9698
}
9799

98-
/// The most common type of `Map`: just using `Any`; <code>[Map]&lt;dyn [Any]&gt;</code>.
100+
/// The most common type of `Map`: just using `Any`; `[Map]<dyn [Any]>`.
99101
///
100102
/// Why is this a separate type alias rather than a default value for `Map<A>`?
101-
/// `Map::new()` doesnt seem to be happy to infer that it should go with the default
102-
/// value. Its a bit sad, really. Ah well, I guess this approach will do.
103+
/// `Map::new()` doesn't seem to be happy to infer that it should go with the default
104+
/// value. It's a bit sad, really. Ah well, I guess this approach will do.
103105
pub type AnyMap = Map<dyn Any>;
104106

105107
impl<A: ?Sized + Downcast> Default for Map<A> {
@@ -113,6 +115,7 @@ impl<A: ?Sized + Downcast> Map<A> {
113115
/// Returns a reference to the value stored in the collection for the type `T`,
114116
/// if it exists.
115117
#[inline]
118+
#[must_use]
116119
pub fn get<T: IntoBox<A>>(&self) -> Option<&T> {
117120
self.raw.get(&TypeId::of::<T>()).map(|any| unsafe { any.downcast_ref_unchecked::<T>() })
118121
}
@@ -132,51 +135,52 @@ impl<A: ?Sized + Downcast> Map<A> {
132135
}
133136

134137
/// A view into a single occupied location in an `Map`.
135-
pub struct OccupiedEntry<'a, A: ?Sized + Downcast, V: 'a> {
136-
inner: hash_map::OccupiedEntry<'a, TypeId, Box<A>>,
138+
pub struct OccupiedEntry<'map, A: ?Sized + Downcast, V: 'map> {
139+
inner: hash_map::OccupiedEntry<'map, TypeId, Box<A>>,
137140
type_: PhantomData<V>,
138141
}
139142

140143
/// A view into a single empty location in an `Map`.
141-
pub struct VacantEntry<'a, A: ?Sized + Downcast, V: 'a> {
142-
inner: hash_map::VacantEntry<'a, TypeId, Box<A>>,
144+
pub struct VacantEntry<'map, A: ?Sized + Downcast, V: 'map> {
145+
inner: hash_map::VacantEntry<'map, TypeId, Box<A>>,
143146
type_: PhantomData<V>,
144147
}
145148

146149
/// A view into a single location in an `Map`, which may be vacant or occupied.
147-
pub enum Entry<'a, A: ?Sized + Downcast, V> {
150+
pub enum Entry<'map, A: ?Sized + Downcast, V> {
148151
/// An occupied Entry
149-
Occupied(OccupiedEntry<'a, A, V>),
152+
Occupied(OccupiedEntry<'map, A, V>),
150153
/// A vacant Entry
151-
Vacant(VacantEntry<'a, A, V>),
154+
Vacant(VacantEntry<'map, A, V>),
152155
}
153156

154-
impl<'a, A: ?Sized + Downcast, V: IntoBox<A>> Entry<'a, A, V> {
157+
impl<'map, A: ?Sized + Downcast, V: IntoBox<A>> Entry<'map, A, V> {
155158
/// Ensures a value is in the entry by inserting the result of the default function if
156159
/// empty, and returns a mutable reference to the value in the entry.
157160
#[inline]
158-
pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V {
161+
pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'map mut V {
159162
match self {
160163
Entry::Occupied(inner) => inner.into_mut(),
161164
Entry::Vacant(inner) => inner.insert(default()),
162165
}
163166
}
164167
}
165168

166-
impl<'a, A: ?Sized + Downcast, V: IntoBox<A>> OccupiedEntry<'a, A, V> {
167-
/// Converts the OccupiedEntry into a mutable reference to the value in the entry
169+
impl<'map, A: ?Sized + Downcast, V: IntoBox<A>> OccupiedEntry<'map, A, V> {
170+
/// Converts the `OccupiedEntry` into a mutable reference to the value in the entry
168171
/// with a lifetime bound to the collection itself
169172
#[inline]
170-
pub fn into_mut(self) -> &'a mut V {
173+
#[must_use]
174+
pub fn into_mut(self) -> &'map mut V {
171175
unsafe { self.inner.into_mut().downcast_mut_unchecked() }
172176
}
173177
}
174178

175-
impl<'a, A: ?Sized + Downcast, V: IntoBox<A>> VacantEntry<'a, A, V> {
176-
/// Sets the value of the entry with the VacantEntry's key,
179+
impl<'map, A: ?Sized + Downcast, V: IntoBox<A>> VacantEntry<'map, A, V> {
180+
/// Sets the value of the entry with the `VacantEntry`'s key,
177181
/// and returns a mutable reference to it
178182
#[inline]
179-
pub fn insert(self, value: V) -> &'a mut V {
183+
pub fn insert(self, value: V) -> &'map mut V {
180184
unsafe { self.inner.insert(value.into_box()).downcast_mut_unchecked() }
181185
}
182186
}
@@ -201,14 +205,13 @@ mod tests {
201205
#[test]
202206
fn type_id_hasher() {
203207
use core::any::TypeId;
204-
use core::hash::Hash;
208+
use core::hash::Hash as _;
205209
fn verify_hashing_with(type_id: TypeId) {
206210
let mut hasher = TypeIdHasher::default();
207211
type_id.hash(&mut hasher);
208-
// SAFETY: u64 is valid for all bit patterns.
209-
let _ = hasher.finish();
212+
_ = hasher.finish();
210213
}
211-
// Pick a variety of types, just to demonstrate its all sane. Normal, zero-sized, unsized, &c.
214+
// Pick a variety of types, just to demonstrate it's all sane. Normal, zero-sized, unsized, &c.
212215
verify_hashing_with(TypeId::of::<usize>());
213216
verify_hashing_with(TypeId::of::<()>());
214217
verify_hashing_with(TypeId::of::<str>());
@@ -220,34 +223,34 @@ mod tests {
220223
/// Methods for downcasting from an `Any`-like trait object.
221224
///
222225
/// This should only be implemented on trait objects for subtraits of `Any`, though you can
223-
/// implement it for other types and itll work fine, so long as your implementation is correct.
226+
/// implement it for other types and it'll work fine, so long as your implementation is correct.
224227
pub trait Downcast {
225228
/// Gets the `TypeId` of `self`.
226229
fn type_id(&self) -> TypeId;
227230

228231
// Note the bound through these downcast methods is 'static, rather than the inexpressible
229232
// concept of Self-but-as-a-trait (where Self is `dyn Trait`). This is sufficient, exceeding
230-
// TypeIds requirements. Sure, you *can* do CloneAny.downcast_unchecked::<NotClone>() and the
231-
// type system wont protect you, but that doesnt introduce any unsafety: the method is
233+
// TypeId's requirements. Sure, you *can* do CloneAny.downcast_unchecked::<NotClone>() and the
234+
// type system won't protect you, but that doesn't introduce any unsafety: the method is
232235
// already unsafe because you can specify the wrong type, and if this were exposing safe
233236
// downcasting, CloneAny.downcast::<NotClone>() would just return an error, which is just as
234237
// correct.
235238
//
236-
// Now in theory we could also add T: ?Sized, but that doesnt play nicely with the common
237-
// implementation, so Im doing without it.
239+
// Now in theory we could also add T: ?Sized, but that doesn't play nicely with the common
240+
// implementation, so I'm doing without it.
238241

239242
/// Downcast from `&Any` to `&T`, without checking the type matches.
240243
///
241244
/// # Safety
242245
///
243-
/// The caller must ensure that `T` matches the trait object, on pain of *undefined behaviour*.
246+
/// The caller must ensure that `T` matches the trait object, on pain of *undefined behavior*.
244247
unsafe fn downcast_ref_unchecked<T: 'static>(&self) -> &T;
245248

246249
/// Downcast from `&mut Any` to `&mut T`, without checking the type matches.
247250
///
248251
/// # Safety
249252
///
250-
/// The caller must ensure that `T` matches the trait object, on pain of *undefined behaviour*.
253+
/// The caller must ensure that `T` matches the trait object, on pain of *undefined behavior*.
251254
unsafe fn downcast_mut_unchecked<T: 'static>(&mut self) -> &mut T;
252255
}
253256

@@ -267,12 +270,12 @@ macro_rules! implement {
267270

268271
#[inline]
269272
unsafe fn downcast_ref_unchecked<T: 'static>(&self) -> &T {
270-
unsafe { &*(self as *const Self as *const T) }
273+
unsafe { &*std::ptr::from_ref::<Self>(self).cast::<T>() }
271274
}
272275

273276
#[inline]
274277
unsafe fn downcast_mut_unchecked<T: 'static>(&mut self) -> &mut T {
275-
unsafe { &mut *(self as *mut Self as *mut T) }
278+
unsafe { &mut *std::ptr::from_mut::<Self>(self).cast::<T>() }
276279
}
277280
}
278281

crates/stdx/src/lib.rs

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ pub mod thread;
1717
pub use itertools;
1818

1919
#[inline(always)]
20-
pub fn is_ci() -> bool {
20+
pub const fn is_ci() -> bool {
2121
option_env!("CI").is_some()
2222
}
2323

@@ -26,14 +26,14 @@ pub fn hash_once<Hasher: std::hash::Hasher + Default>(thing: impl std::hash::Has
2626
}
2727

2828
#[must_use]
29-
#[allow(clippy::print_stderr)]
29+
#[expect(clippy::print_stderr, reason = "only visible to developers")]
3030
pub fn timeit(label: &'static str) -> impl Drop {
3131
let start = Instant::now();
32-
defer(move || eprintln!("{}: {:.2?}", label, start.elapsed()))
32+
defer(move || eprintln!("{}: {:.2}", label, start.elapsed().as_nanos()))
3333
}
3434

3535
/// Prints backtrace to stderr, useful for debugging.
36-
#[allow(clippy::print_stderr)]
36+
#[expect(clippy::print_stderr, reason = "only visible to developers")]
3737
pub fn print_backtrace() {
3838
#[cfg(feature = "backtrace")]
3939
eprintln!("{:?}", backtrace::Backtrace::new());
@@ -126,6 +126,7 @@ where
126126
}
127127

128128
// Taken from rustc.
129+
#[must_use]
129130
pub fn to_camel_case(ident: &str) -> String {
130131
ident
131132
.trim_matches('_')
@@ -156,7 +157,7 @@ pub fn to_camel_case(ident: &str) -> String {
156157

157158
camel_cased_component
158159
})
159-
.fold((String::new(), None), |(acc, prev): (_, Option<String>), next| {
160+
.fold((String::new(), None), |(mut acc, prev): (_, Option<String>), next| {
160161
// separate two components with an underscore if their boundary cannot
161162
// be distinguished using an uppercase/lowercase case distinction
162163
let join = prev
@@ -166,16 +167,20 @@ pub fn to_camel_case(ident: &str) -> String {
166167
Some(!char_has_case(l) && !char_has_case(f))
167168
})
168169
.unwrap_or(false);
169-
(acc + if join { "_" } else { "" } + &next, Some(next))
170+
acc.push_str(if join { "_" } else { "" });
171+
acc.push_str(&next);
172+
(acc, Some(next))
170173
})
171174
.0
172175
}
173176

174177
// Taken from rustc.
175-
pub fn char_has_case(c: char) -> bool {
178+
#[must_use]
179+
pub const fn char_has_case(c: char) -> bool {
176180
c.is_lowercase() || c.is_uppercase()
177181
}
178182

183+
#[must_use]
179184
pub fn is_upper_snake_case(s: &str) -> bool {
180185
s.chars().all(|c| c.is_uppercase() || c == '_' || c.is_numeric())
181186
}
@@ -188,6 +193,7 @@ pub fn replace(buf: &mut String, from: char, to: &str) {
188193
*buf = buf.replace(from, to);
189194
}
190195

196+
#[must_use]
191197
pub fn trim_indent(mut text: &str) -> String {
192198
if text.starts_with('\n') {
193199
text = &text[1..];
@@ -249,8 +255,8 @@ impl ops::DerefMut for JodChild {
249255

250256
impl Drop for JodChild {
251257
fn drop(&mut self) {
252-
let _ = self.0.kill();
253-
let _ = self.0.wait();
258+
_ = self.0.kill();
259+
_ = self.0.wait();
254260
}
255261
}
256262

@@ -259,12 +265,11 @@ impl JodChild {
259265
command.spawn().map(Self)
260266
}
261267

268+
#[must_use]
269+
#[cfg(not(target_arch = "wasm32"))]
262270
pub fn into_inner(self) -> std::process::Child {
263-
if cfg!(target_arch = "wasm32") {
264-
panic!("no processes on wasm");
265-
}
266271
// SAFETY: repr transparent, except on WASM
267-
unsafe { std::mem::transmute::<JodChild, std::process::Child>(self) }
272+
unsafe { std::mem::transmute::<Self, std::process::Child>(self) }
268273
}
269274
}
270275

crates/stdx/src/non_empty_vec.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ pub struct NonEmptyVec<T> {
88

99
impl<T> NonEmptyVec<T> {
1010
#[inline]
11-
pub fn new(first: T) -> Self {
12-
NonEmptyVec { first, rest: Vec::new() }
11+
pub const fn new(first: T) -> Self {
12+
Self { first, rest: Vec::new() }
1313
}
1414

1515
#[inline]
@@ -24,7 +24,7 @@ impl<T> NonEmptyVec<T> {
2424

2525
#[inline]
2626
pub fn push(&mut self, value: T) {
27-
self.rest.push(value)
27+
self.rest.push(value);
2828
}
2929

3030
#[inline]

crates/stdx/src/panic_context.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ impl Drop for PanicContext {
1616
}
1717

1818
pub fn enter(frame: String) -> PanicContext {
19-
#[allow(clippy::print_stderr)]
19+
#[expect(clippy::print_stderr, reason = "already panicking anyway")]
2020
fn set_hook() {
2121
let default_hook = panic::take_hook();
2222
panic::set_hook(Box::new(move |panic_info| {

0 commit comments

Comments
 (0)