Skip to content

Commit 5ee13ae

Browse files
authoredOct 29, 2024
Rollup merge of #132233 - WaffleLapkin:box-module-split, r=workingjubilee
Split `boxed.rs` into a few modules I wanted to add an impl for `Box<_>`, but was quickly discouraged by the 3K file. This splits off a couple bits, making it at least a bit more manageable. r? ````@workingjubilee```` (I think you are not bothered by refactorings like this?)
·
1.88.01.84.0
2 parents a70b90b + f0744ca commit 5ee13ae

File tree

4 files changed

+1094
-1061
lines changed

4 files changed

+1094
-1061
lines changed
 

‎library/alloc/src/boxed.rs

Lines changed: 152 additions & 1060 deletions
Large diffs are not rendered by default.

‎library/alloc/src/boxed/convert.rs

Lines changed: 747 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,747 @@
1+
use core::any::Any;
2+
use core::error::Error;
3+
use core::mem;
4+
use core::pin::Pin;
5+
#[cfg(not(no_global_oom_handling))]
6+
use core::{fmt, ptr};
7+
8+
use crate::alloc::Allocator;
9+
#[cfg(not(no_global_oom_handling))]
10+
use crate::borrow::Cow;
11+
use crate::boxed::Box;
12+
#[cfg(not(no_global_oom_handling))]
13+
use crate::raw_vec::RawVec;
14+
#[cfg(not(no_global_oom_handling))]
15+
use crate::str::from_boxed_utf8_unchecked;
16+
#[cfg(not(no_global_oom_handling))]
17+
use crate::string::String;
18+
#[cfg(not(no_global_oom_handling))]
19+
use crate::vec::Vec;
20+
21+
#[cfg(not(no_global_oom_handling))]
22+
#[stable(feature = "from_for_ptrs", since = "1.6.0")]
23+
impl<T> From<T> for Box<T> {
24+
/// Converts a `T` into a `Box<T>`
25+
///
26+
/// The conversion allocates on the heap and moves `t`
27+
/// from the stack into it.
28+
///
29+
/// # Examples
30+
///
31+
/// ```rust
32+
/// let x = 5;
33+
/// let boxed = Box::new(5);
34+
///
35+
/// assert_eq!(Box::from(x), boxed);
36+
/// ```
37+
fn from(t: T) -> Self {
38+
Box::new(t)
39+
}
40+
}
41+
42+
#[stable(feature = "pin", since = "1.33.0")]
43+
impl<T: ?Sized, A: Allocator> From<Box<T, A>> for Pin<Box<T, A>>
44+
where
45+
A: 'static,
46+
{
47+
/// Converts a `Box<T>` into a `Pin<Box<T>>`. If `T` does not implement [`Unpin`], then
48+
/// `*boxed` will be pinned in memory and unable to be moved.
49+
///
50+
/// This conversion does not allocate on the heap and happens in place.
51+
///
52+
/// This is also available via [`Box::into_pin`].
53+
///
54+
/// Constructing and pinning a `Box` with <code><Pin<Box\<T>>>::from([Box::new]\(x))</code>
55+
/// can also be written more concisely using <code>[Box::pin]\(x)</code>.
56+
/// This `From` implementation is useful if you already have a `Box<T>`, or you are
57+
/// constructing a (pinned) `Box` in a different way than with [`Box::new`].
58+
fn from(boxed: Box<T, A>) -> Self {
59+
Box::into_pin(boxed)
60+
}
61+
}
62+
63+
/// Specialization trait used for `From<&[T]>`.
64+
#[cfg(not(no_global_oom_handling))]
65+
trait BoxFromSlice<T> {
66+
fn from_slice(slice: &[T]) -> Self;
67+
}
68+
69+
#[cfg(not(no_global_oom_handling))]
70+
impl<T: Clone> BoxFromSlice<T> for Box<[T]> {
71+
#[inline]
72+
default fn from_slice(slice: &[T]) -> Self {
73+
slice.to_vec().into_boxed_slice()
74+
}
75+
}
76+
77+
#[cfg(not(no_global_oom_handling))]
78+
impl<T: Copy> BoxFromSlice<T> for Box<[T]> {
79+
#[inline]
80+
fn from_slice(slice: &[T]) -> Self {
81+
let len = slice.len();
82+
let buf = RawVec::with_capacity(len);
83+
unsafe {
84+
ptr::copy_nonoverlapping(slice.as_ptr(), buf.ptr(), len);
85+
buf.into_box(slice.len()).assume_init()
86+
}
87+
}
88+
}
89+
90+
#[cfg(not(no_global_oom_handling))]
91+
#[stable(feature = "box_from_slice", since = "1.17.0")]
92+
impl<T: Clone> From<&[T]> for Box<[T]> {
93+
/// Converts a `&[T]` into a `Box<[T]>`
94+
///
95+
/// This conversion allocates on the heap
96+
/// and performs a copy of `slice` and its contents.
97+
///
98+
/// # Examples
99+
/// ```rust
100+
/// // create a &[u8] which will be used to create a Box<[u8]>
101+
/// let slice: &[u8] = &[104, 101, 108, 108, 111];
102+
/// let boxed_slice: Box<[u8]> = Box::from(slice);
103+
///
104+
/// println!("{boxed_slice:?}");
105+
/// ```
106+
#[inline]
107+
fn from(slice: &[T]) -> Box<[T]> {
108+
<Self as BoxFromSlice<T>>::from_slice(slice)
109+
}
110+
}
111+
112+
#[cfg(not(no_global_oom_handling))]
113+
#[stable(feature = "box_from_cow", since = "1.45.0")]
114+
impl<T: Clone> From<Cow<'_, [T]>> for Box<[T]> {
115+
/// Converts a `Cow<'_, [T]>` into a `Box<[T]>`
116+
///
117+
/// When `cow` is the `Cow::Borrowed` variant, this
118+
/// conversion allocates on the heap and copies the
119+
/// underlying slice. Otherwise, it will try to reuse the owned
120+
/// `Vec`'s allocation.
121+
#[inline]
122+
fn from(cow: Cow<'_, [T]>) -> Box<[T]> {
123+
match cow {
124+
Cow::Borrowed(slice) => Box::from(slice),
125+
Cow::Owned(slice) => Box::from(slice),
126+
}
127+
}
128+
}
129+
130+
#[cfg(not(no_global_oom_handling))]
131+
#[stable(feature = "box_from_slice", since = "1.17.0")]
132+
impl From<&str> for Box<str> {
133+
/// Converts a `&str` into a `Box<str>`
134+
///
135+
/// This conversion allocates on the heap
136+
/// and performs a copy of `s`.
137+
///
138+
/// # Examples
139+
///
140+
/// ```rust
141+
/// let boxed: Box<str> = Box::from("hello");
142+
/// println!("{boxed}");
143+
/// ```
144+
#[inline]
145+
fn from(s: &str) -> Box<str> {
146+
unsafe { from_boxed_utf8_unchecked(Box::from(s.as_bytes())) }
147+
}
148+
}
149+
150+
#[cfg(not(no_global_oom_handling))]
151+
#[stable(feature = "box_from_cow", since = "1.45.0")]
152+
impl From<Cow<'_, str>> for Box<str> {
153+
/// Converts a `Cow<'_, str>` into a `Box<str>`
154+
///
155+
/// When `cow` is the `Cow::Borrowed` variant, this
156+
/// conversion allocates on the heap and copies the
157+
/// underlying `str`. Otherwise, it will try to reuse the owned
158+
/// `String`'s allocation.
159+
///
160+
/// # Examples
161+
///
162+
/// ```rust
163+
/// use std::borrow::Cow;
164+
///
165+
/// let unboxed = Cow::Borrowed("hello");
166+
/// let boxed: Box<str> = Box::from(unboxed);
167+
/// println!("{boxed}");
168+
/// ```
169+
///
170+
/// ```rust
171+
/// # use std::borrow::Cow;
172+
/// let unboxed = Cow::Owned("hello".to_string());
173+
/// let boxed: Box<str> = Box::from(unboxed);
174+
/// println!("{boxed}");
175+
/// ```
176+
#[inline]
177+
fn from(cow: Cow<'_, str>) -> Box<str> {
178+
match cow {
179+
Cow::Borrowed(s) => Box::from(s),
180+
Cow::Owned(s) => Box::from(s),
181+
}
182+
}
183+
}
184+
185+
#[stable(feature = "boxed_str_conv", since = "1.19.0")]
186+
impl<A: Allocator> From<Box<str, A>> for Box<[u8], A> {
187+
/// Converts a `Box<str>` into a `Box<[u8]>`
188+
///
189+
/// This conversion does not allocate on the heap and happens in place.
190+
///
191+
/// # Examples
192+
/// ```rust
193+
/// // create a Box<str> which will be used to create a Box<[u8]>
194+
/// let boxed: Box<str> = Box::from("hello");
195+
/// let boxed_str: Box<[u8]> = Box::from(boxed);
196+
///
197+
/// // create a &[u8] which will be used to create a Box<[u8]>
198+
/// let slice: &[u8] = &[104, 101, 108, 108, 111];
199+
/// let boxed_slice = Box::from(slice);
200+
///
201+
/// assert_eq!(boxed_slice, boxed_str);
202+
/// ```
203+
#[inline]
204+
fn from(s: Box<str, A>) -> Self {
205+
let (raw, alloc) = Box::into_raw_with_allocator(s);
206+
unsafe { Box::from_raw_in(raw as *mut [u8], alloc) }
207+
}
208+
}
209+
210+
#[cfg(not(no_global_oom_handling))]
211+
#[stable(feature = "box_from_array", since = "1.45.0")]
212+
impl<T, const N: usize> From<[T; N]> for Box<[T]> {
213+
/// Converts a `[T; N]` into a `Box<[T]>`
214+
///
215+
/// This conversion moves the array to newly heap-allocated memory.
216+
///
217+
/// # Examples
218+
///
219+
/// ```rust
220+
/// let boxed: Box<[u8]> = Box::from([4, 2]);
221+
/// println!("{boxed:?}");
222+
/// ```
223+
fn from(array: [T; N]) -> Box<[T]> {
224+
Box::new(array)
225+
}
226+
}
227+
228+
/// Casts a boxed slice to a boxed array.
229+
///
230+
/// # Safety
231+
///
232+
/// `boxed_slice.len()` must be exactly `N`.
233+
unsafe fn boxed_slice_as_array_unchecked<T, A: Allocator, const N: usize>(
234+
boxed_slice: Box<[T], A>,
235+
) -> Box<[T; N], A> {
236+
debug_assert_eq!(boxed_slice.len(), N);
237+
238+
let (ptr, alloc) = Box::into_raw_with_allocator(boxed_slice);
239+
// SAFETY: Pointer and allocator came from an existing box,
240+
// and our safety condition requires that the length is exactly `N`
241+
unsafe { Box::from_raw_in(ptr as *mut [T; N], alloc) }
242+
}
243+
244+
#[stable(feature = "boxed_slice_try_from", since = "1.43.0")]
245+
impl<T, const N: usize> TryFrom<Box<[T]>> for Box<[T; N]> {
246+
type Error = Box<[T]>;
247+
248+
/// Attempts to convert a `Box<[T]>` into a `Box<[T; N]>`.
249+
///
250+
/// The conversion occurs in-place and does not require a
251+
/// new memory allocation.
252+
///
253+
/// # Errors
254+
///
255+
/// Returns the old `Box<[T]>` in the `Err` variant if
256+
/// `boxed_slice.len()` does not equal `N`.
257+
fn try_from(boxed_slice: Box<[T]>) -> Result<Self, Self::Error> {
258+
if boxed_slice.len() == N {
259+
Ok(unsafe { boxed_slice_as_array_unchecked(boxed_slice) })
260+
} else {
261+
Err(boxed_slice)
262+
}
263+
}
264+
}
265+
266+
#[cfg(not(no_global_oom_handling))]
267+
#[stable(feature = "boxed_array_try_from_vec", since = "1.66.0")]
268+
impl<T, const N: usize> TryFrom<Vec<T>> for Box<[T; N]> {
269+
type Error = Vec<T>;
270+
271+
/// Attempts to convert a `Vec<T>` into a `Box<[T; N]>`.
272+
///
273+
/// Like [`Vec::into_boxed_slice`], this is in-place if `vec.capacity() == N`,
274+
/// but will require a reallocation otherwise.
275+
///
276+
/// # Errors
277+
///
278+
/// Returns the original `Vec<T>` in the `Err` variant if
279+
/// `boxed_slice.len()` does not equal `N`.
280+
///
281+
/// # Examples
282+
///
283+
/// This can be used with [`vec!`] to create an array on the heap:
284+
///
285+
/// ```
286+
/// let state: Box<[f32; 100]> = vec![1.0; 100].try_into().unwrap();
287+
/// assert_eq!(state.len(), 100);
288+
/// ```
289+
fn try_from(vec: Vec<T>) -> Result<Self, Self::Error> {
290+
if vec.len() == N {
291+
let boxed_slice = vec.into_boxed_slice();
292+
Ok(unsafe { boxed_slice_as_array_unchecked(boxed_slice) })
293+
} else {
294+
Err(vec)
295+
}
296+
}
297+
}
298+
299+
impl<A: Allocator> Box<dyn Any, A> {
300+
/// Attempts to downcast the box to a concrete type.
301+
///
302+
/// # Examples
303+
///
304+
/// ```
305+
/// use std::any::Any;
306+
///
307+
/// fn print_if_string(value: Box<dyn Any>) {
308+
/// if let Ok(string) = value.downcast::<String>() {
309+
/// println!("String ({}): {}", string.len(), string);
310+
/// }
311+
/// }
312+
///
313+
/// let my_string = "Hello World".to_string();
314+
/// print_if_string(Box::new(my_string));
315+
/// print_if_string(Box::new(0i8));
316+
/// ```
317+
#[inline]
318+
#[stable(feature = "rust1", since = "1.0.0")]
319+
pub fn downcast<T: Any>(self) -> Result<Box<T, A>, Self> {
320+
if self.is::<T>() { unsafe { Ok(self.downcast_unchecked::<T>()) } } else { Err(self) }
321+
}
322+
323+
/// Downcasts the box to a concrete type.
324+
///
325+
/// For a safe alternative see [`downcast`].
326+
///
327+
/// # Examples
328+
///
329+
/// ```
330+
/// #![feature(downcast_unchecked)]
331+
///
332+
/// use std::any::Any;
333+
///
334+
/// let x: Box<dyn Any> = Box::new(1_usize);
335+
///
336+
/// unsafe {
337+
/// assert_eq!(*x.downcast_unchecked::<usize>(), 1);
338+
/// }
339+
/// ```
340+
///
341+
/// # Safety
342+
///
343+
/// The contained value must be of type `T`. Calling this method
344+
/// with the incorrect type is *undefined behavior*.
345+
///
346+
/// [`downcast`]: Self::downcast
347+
#[inline]
348+
#[unstable(feature = "downcast_unchecked", issue = "90850")]
349+
pub unsafe fn downcast_unchecked<T: Any>(self) -> Box<T, A> {
350+
debug_assert!(self.is::<T>());
351+
unsafe {
352+
let (raw, alloc): (*mut dyn Any, _) = Box::into_raw_with_allocator(self);
353+
Box::from_raw_in(raw as *mut T, alloc)
354+
}
355+
}
356+
}
357+
358+
impl<A: Allocator> Box<dyn Any + Send, A> {
359+
/// Attempts to downcast the box to a concrete type.
360+
///
361+
/// # Examples
362+
///
363+
/// ```
364+
/// use std::any::Any;
365+
///
366+
/// fn print_if_string(value: Box<dyn Any + Send>) {
367+
/// if let Ok(string) = value.downcast::<String>() {
368+
/// println!("String ({}): {}", string.len(), string);
369+
/// }
370+
/// }
371+
///
372+
/// let my_string = "Hello World".to_string();
373+
/// print_if_string(Box::new(my_string));
374+
/// print_if_string(Box::new(0i8));
375+
/// ```
376+
#[inline]
377+
#[stable(feature = "rust1", since = "1.0.0")]
378+
pub fn downcast<T: Any>(self) -> Result<Box<T, A>, Self> {
379+
if self.is::<T>() { unsafe { Ok(self.downcast_unchecked::<T>()) } } else { Err(self) }
380+
}
381+
382+
/// Downcasts the box to a concrete type.
383+
///
384+
/// For a safe alternative see [`downcast`].
385+
///
386+
/// # Examples
387+
///
388+
/// ```
389+
/// #![feature(downcast_unchecked)]
390+
///
391+
/// use std::any::Any;
392+
///
393+
/// let x: Box<dyn Any + Send> = Box::new(1_usize);
394+
///
395+
/// unsafe {
396+
/// assert_eq!(*x.downcast_unchecked::<usize>(), 1);
397+
/// }
398+
/// ```
399+
///
400+
/// # Safety
401+
///
402+
/// The contained value must be of type `T`. Calling this method
403+
/// with the incorrect type is *undefined behavior*.
404+
///
405+
/// [`downcast`]: Self::downcast
406+
#[inline]
407+
#[unstable(feature = "downcast_unchecked", issue = "90850")]
408+
pub unsafe fn downcast_unchecked<T: Any>(self) -> Box<T, A> {
409+
debug_assert!(self.is::<T>());
410+
unsafe {
411+
let (raw, alloc): (*mut (dyn Any + Send), _) = Box::into_raw_with_allocator(self);
412+
Box::from_raw_in(raw as *mut T, alloc)
413+
}
414+
}
415+
}
416+
417+
impl<A: Allocator> Box<dyn Any + Send + Sync, A> {
418+
/// Attempts to downcast the box to a concrete type.
419+
///
420+
/// # Examples
421+
///
422+
/// ```
423+
/// use std::any::Any;
424+
///
425+
/// fn print_if_string(value: Box<dyn Any + Send + Sync>) {
426+
/// if let Ok(string) = value.downcast::<String>() {
427+
/// println!("String ({}): {}", string.len(), string);
428+
/// }
429+
/// }
430+
///
431+
/// let my_string = "Hello World".to_string();
432+
/// print_if_string(Box::new(my_string));
433+
/// print_if_string(Box::new(0i8));
434+
/// ```
435+
#[inline]
436+
#[stable(feature = "box_send_sync_any_downcast", since = "1.51.0")]
437+
pub fn downcast<T: Any>(self) -> Result<Box<T, A>, Self> {
438+
if self.is::<T>() { unsafe { Ok(self.downcast_unchecked::<T>()) } } else { Err(self) }
439+
}
440+
441+
/// Downcasts the box to a concrete type.
442+
///
443+
/// For a safe alternative see [`downcast`].
444+
///
445+
/// # Examples
446+
///
447+
/// ```
448+
/// #![feature(downcast_unchecked)]
449+
///
450+
/// use std::any::Any;
451+
///
452+
/// let x: Box<dyn Any + Send + Sync> = Box::new(1_usize);
453+
///
454+
/// unsafe {
455+
/// assert_eq!(*x.downcast_unchecked::<usize>(), 1);
456+
/// }
457+
/// ```
458+
///
459+
/// # Safety
460+
///
461+
/// The contained value must be of type `T`. Calling this method
462+
/// with the incorrect type is *undefined behavior*.
463+
///
464+
/// [`downcast`]: Self::downcast
465+
#[inline]
466+
#[unstable(feature = "downcast_unchecked", issue = "90850")]
467+
pub unsafe fn downcast_unchecked<T: Any>(self) -> Box<T, A> {
468+
debug_assert!(self.is::<T>());
469+
unsafe {
470+
let (raw, alloc): (*mut (dyn Any + Send + Sync), _) =
471+
Box::into_raw_with_allocator(self);
472+
Box::from_raw_in(raw as *mut T, alloc)
473+
}
474+
}
475+
}
476+
477+
#[cfg(not(no_global_oom_handling))]
478+
#[stable(feature = "rust1", since = "1.0.0")]
479+
impl<'a, E: Error + 'a> From<E> for Box<dyn Error + 'a> {
480+
/// Converts a type of [`Error`] into a box of dyn [`Error`].
481+
///
482+
/// # Examples
483+
///
484+
/// ```
485+
/// use std::error::Error;
486+
/// use std::fmt;
487+
/// use std::mem;
488+
///
489+
/// #[derive(Debug)]
490+
/// struct AnError;
491+
///
492+
/// impl fmt::Display for AnError {
493+
/// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
494+
/// write!(f, "An error")
495+
/// }
496+
/// }
497+
///
498+
/// impl Error for AnError {}
499+
///
500+
/// let an_error = AnError;
501+
/// assert!(0 == mem::size_of_val(&an_error));
502+
/// let a_boxed_error = Box::<dyn Error>::from(an_error);
503+
/// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
504+
/// ```
505+
fn from(err: E) -> Box<dyn Error + 'a> {
506+
Box::new(err)
507+
}
508+
}
509+
510+
#[cfg(not(no_global_oom_handling))]
511+
#[stable(feature = "rust1", since = "1.0.0")]
512+
impl<'a, E: Error + Send + Sync + 'a> From<E> for Box<dyn Error + Send + Sync + 'a> {
513+
/// Converts a type of [`Error`] + [`Send`] + [`Sync`] into a box of
514+
/// dyn [`Error`] + [`Send`] + [`Sync`].
515+
///
516+
/// # Examples
517+
///
518+
/// ```
519+
/// use std::error::Error;
520+
/// use std::fmt;
521+
/// use std::mem;
522+
///
523+
/// #[derive(Debug)]
524+
/// struct AnError;
525+
///
526+
/// impl fmt::Display for AnError {
527+
/// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
528+
/// write!(f, "An error")
529+
/// }
530+
/// }
531+
///
532+
/// impl Error for AnError {}
533+
///
534+
/// unsafe impl Send for AnError {}
535+
///
536+
/// unsafe impl Sync for AnError {}
537+
///
538+
/// let an_error = AnError;
539+
/// assert!(0 == mem::size_of_val(&an_error));
540+
/// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(an_error);
541+
/// assert!(
542+
/// mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
543+
/// ```
544+
fn from(err: E) -> Box<dyn Error + Send + Sync + 'a> {
545+
Box::new(err)
546+
}
547+
}
548+
549+
#[cfg(not(no_global_oom_handling))]
550+
#[stable(feature = "rust1", since = "1.0.0")]
551+
impl<'a> From<String> for Box<dyn Error + Send + Sync + 'a> {
552+
/// Converts a [`String`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
553+
///
554+
/// # Examples
555+
///
556+
/// ```
557+
/// use std::error::Error;
558+
/// use std::mem;
559+
///
560+
/// let a_string_error = "a string error".to_string();
561+
/// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(a_string_error);
562+
/// assert!(
563+
/// mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
564+
/// ```
565+
#[inline]
566+
fn from(err: String) -> Box<dyn Error + Send + Sync + 'a> {
567+
struct StringError(String);
568+
569+
impl Error for StringError {
570+
#[allow(deprecated)]
571+
fn description(&self) -> &str {
572+
&self.0
573+
}
574+
}
575+
576+
impl fmt::Display for StringError {
577+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
578+
fmt::Display::fmt(&self.0, f)
579+
}
580+
}
581+
582+
// Purposefully skip printing "StringError(..)"
583+
impl fmt::Debug for StringError {
584+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
585+
fmt::Debug::fmt(&self.0, f)
586+
}
587+
}
588+
589+
Box::new(StringError(err))
590+
}
591+
}
592+
593+
#[cfg(not(no_global_oom_handling))]
594+
#[stable(feature = "string_box_error", since = "1.6.0")]
595+
impl<'a> From<String> for Box<dyn Error + 'a> {
596+
/// Converts a [`String`] into a box of dyn [`Error`].
597+
///
598+
/// # Examples
599+
///
600+
/// ```
601+
/// use std::error::Error;
602+
/// use std::mem;
603+
///
604+
/// let a_string_error = "a string error".to_string();
605+
/// let a_boxed_error = Box::<dyn Error>::from(a_string_error);
606+
/// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
607+
/// ```
608+
fn from(str_err: String) -> Box<dyn Error + 'a> {
609+
let err1: Box<dyn Error + Send + Sync> = From::from(str_err);
610+
let err2: Box<dyn Error> = err1;
611+
err2
612+
}
613+
}
614+
615+
#[cfg(not(no_global_oom_handling))]
616+
#[stable(feature = "rust1", since = "1.0.0")]
617+
impl<'a> From<&str> for Box<dyn Error + Send + Sync + 'a> {
618+
/// Converts a [`str`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
619+
///
620+
/// [`str`]: prim@str
621+
///
622+
/// # Examples
623+
///
624+
/// ```
625+
/// use std::error::Error;
626+
/// use std::mem;
627+
///
628+
/// let a_str_error = "a str error";
629+
/// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(a_str_error);
630+
/// assert!(
631+
/// mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
632+
/// ```
633+
#[inline]
634+
fn from(err: &str) -> Box<dyn Error + Send + Sync + 'a> {
635+
From::from(String::from(err))
636+
}
637+
}
638+
639+
#[cfg(not(no_global_oom_handling))]
640+
#[stable(feature = "string_box_error", since = "1.6.0")]
641+
impl<'a> From<&str> for Box<dyn Error + 'a> {
642+
/// Converts a [`str`] into a box of dyn [`Error`].
643+
///
644+
/// [`str`]: prim@str
645+
///
646+
/// # Examples
647+
///
648+
/// ```
649+
/// use std::error::Error;
650+
/// use std::mem;
651+
///
652+
/// let a_str_error = "a str error";
653+
/// let a_boxed_error = Box::<dyn Error>::from(a_str_error);
654+
/// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
655+
/// ```
656+
fn from(err: &str) -> Box<dyn Error + 'a> {
657+
From::from(String::from(err))
658+
}
659+
}
660+
661+
#[cfg(not(no_global_oom_handling))]
662+
#[stable(feature = "cow_box_error", since = "1.22.0")]
663+
impl<'a, 'b> From<Cow<'b, str>> for Box<dyn Error + Send + Sync + 'a> {
664+
/// Converts a [`Cow`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
665+
///
666+
/// # Examples
667+
///
668+
/// ```
669+
/// use std::error::Error;
670+
/// use std::mem;
671+
/// use std::borrow::Cow;
672+
///
673+
/// let a_cow_str_error = Cow::from("a str error");
674+
/// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(a_cow_str_error);
675+
/// assert!(
676+
/// mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
677+
/// ```
678+
fn from(err: Cow<'b, str>) -> Box<dyn Error + Send + Sync + 'a> {
679+
From::from(String::from(err))
680+
}
681+
}
682+
683+
#[cfg(not(no_global_oom_handling))]
684+
#[stable(feature = "cow_box_error", since = "1.22.0")]
685+
impl<'a, 'b> From<Cow<'b, str>> for Box<dyn Error + 'a> {
686+
/// Converts a [`Cow`] into a box of dyn [`Error`].
687+
///
688+
/// # Examples
689+
///
690+
/// ```
691+
/// use std::error::Error;
692+
/// use std::mem;
693+
/// use std::borrow::Cow;
694+
///
695+
/// let a_cow_str_error = Cow::from("a str error");
696+
/// let a_boxed_error = Box::<dyn Error>::from(a_cow_str_error);
697+
/// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
698+
/// ```
699+
fn from(err: Cow<'b, str>) -> Box<dyn Error + 'a> {
700+
From::from(String::from(err))
701+
}
702+
}
703+
704+
impl dyn Error {
705+
/// Attempts to downcast the box to a concrete type.
706+
#[inline]
707+
#[stable(feature = "error_downcast", since = "1.3.0")]
708+
#[rustc_allow_incoherent_impl]
709+
pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<dyn Error>> {
710+
if self.is::<T>() {
711+
unsafe {
712+
let raw: *mut dyn Error = Box::into_raw(self);
713+
Ok(Box::from_raw(raw as *mut T))
714+
}
715+
} else {
716+
Err(self)
717+
}
718+
}
719+
}
720+
721+
impl dyn Error + Send {
722+
/// Attempts to downcast the box to a concrete type.
723+
#[inline]
724+
#[stable(feature = "error_downcast", since = "1.3.0")]
725+
#[rustc_allow_incoherent_impl]
726+
pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<dyn Error + Send>> {
727+
let err: Box<dyn Error> = self;
728+
<dyn Error>::downcast(err).map_err(|s| unsafe {
729+
// Reapply the `Send` marker.
730+
mem::transmute::<Box<dyn Error>, Box<dyn Error + Send>>(s)
731+
})
732+
}
733+
}
734+
735+
impl dyn Error + Send + Sync {
736+
/// Attempts to downcast the box to a concrete type.
737+
#[inline]
738+
#[stable(feature = "error_downcast", since = "1.3.0")]
739+
#[rustc_allow_incoherent_impl]
740+
pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<Self>> {
741+
let err: Box<dyn Error> = self;
742+
<dyn Error>::downcast(err).map_err(|s| unsafe {
743+
// Reapply the `Send + Sync` markers.
744+
mem::transmute::<Box<dyn Error>, Box<dyn Error + Send + Sync>>(s)
745+
})
746+
}
747+
}

‎library/alloc/src/boxed/iter.rs

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
use core::async_iter::AsyncIterator;
2+
use core::iter::FusedIterator;
3+
use core::pin::Pin;
4+
use core::slice;
5+
use core::task::{Context, Poll};
6+
7+
use crate::alloc::Allocator;
8+
#[cfg(not(no_global_oom_handling))]
9+
use crate::borrow::Cow;
10+
use crate::boxed::Box;
11+
#[cfg(not(no_global_oom_handling))]
12+
use crate::string::String;
13+
use crate::vec;
14+
#[cfg(not(no_global_oom_handling))]
15+
use crate::vec::Vec;
16+
17+
#[stable(feature = "rust1", since = "1.0.0")]
18+
impl<I: Iterator + ?Sized, A: Allocator> Iterator for Box<I, A> {
19+
type Item = I::Item;
20+
fn next(&mut self) -> Option<I::Item> {
21+
(**self).next()
22+
}
23+
fn size_hint(&self) -> (usize, Option<usize>) {
24+
(**self).size_hint()
25+
}
26+
fn nth(&mut self, n: usize) -> Option<I::Item> {
27+
(**self).nth(n)
28+
}
29+
fn last(self) -> Option<I::Item> {
30+
BoxIter::last(self)
31+
}
32+
}
33+
34+
trait BoxIter {
35+
type Item;
36+
fn last(self) -> Option<Self::Item>;
37+
}
38+
39+
impl<I: Iterator + ?Sized, A: Allocator> BoxIter for Box<I, A> {
40+
type Item = I::Item;
41+
default fn last(self) -> Option<I::Item> {
42+
#[inline]
43+
fn some<T>(_: Option<T>, x: T) -> Option<T> {
44+
Some(x)
45+
}
46+
47+
self.fold(None, some)
48+
}
49+
}
50+
51+
/// Specialization for sized `I`s that uses `I`s implementation of `last()`
52+
/// instead of the default.
53+
#[stable(feature = "rust1", since = "1.0.0")]
54+
impl<I: Iterator, A: Allocator> BoxIter for Box<I, A> {
55+
fn last(self) -> Option<I::Item> {
56+
(*self).last()
57+
}
58+
}
59+
60+
#[stable(feature = "rust1", since = "1.0.0")]
61+
impl<I: DoubleEndedIterator + ?Sized, A: Allocator> DoubleEndedIterator for Box<I, A> {
62+
fn next_back(&mut self) -> Option<I::Item> {
63+
(**self).next_back()
64+
}
65+
fn nth_back(&mut self, n: usize) -> Option<I::Item> {
66+
(**self).nth_back(n)
67+
}
68+
}
69+
#[stable(feature = "rust1", since = "1.0.0")]
70+
impl<I: ExactSizeIterator + ?Sized, A: Allocator> ExactSizeIterator for Box<I, A> {
71+
fn len(&self) -> usize {
72+
(**self).len()
73+
}
74+
fn is_empty(&self) -> bool {
75+
(**self).is_empty()
76+
}
77+
}
78+
79+
#[stable(feature = "fused", since = "1.26.0")]
80+
impl<I: FusedIterator + ?Sized, A: Allocator> FusedIterator for Box<I, A> {}
81+
82+
#[unstable(feature = "async_iterator", issue = "79024")]
83+
impl<S: ?Sized + AsyncIterator + Unpin> AsyncIterator for Box<S> {
84+
type Item = S::Item;
85+
86+
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
87+
Pin::new(&mut **self).poll_next(cx)
88+
}
89+
90+
fn size_hint(&self) -> (usize, Option<usize>) {
91+
(**self).size_hint()
92+
}
93+
}
94+
95+
/// This implementation is required to make sure that the `Box<[I]>: IntoIterator`
96+
/// implementation doesn't overlap with `IntoIterator for T where T: Iterator` blanket.
97+
#[stable(feature = "boxed_slice_into_iter", since = "1.80.0")]
98+
impl<I, A: Allocator> !Iterator for Box<[I], A> {}
99+
100+
/// This implementation is required to make sure that the `&Box<[I]>: IntoIterator`
101+
/// implementation doesn't overlap with `IntoIterator for T where T: Iterator` blanket.
102+
#[stable(feature = "boxed_slice_into_iter", since = "1.80.0")]
103+
impl<'a, I, A: Allocator> !Iterator for &'a Box<[I], A> {}
104+
105+
/// This implementation is required to make sure that the `&mut Box<[I]>: IntoIterator`
106+
/// implementation doesn't overlap with `IntoIterator for T where T: Iterator` blanket.
107+
#[stable(feature = "boxed_slice_into_iter", since = "1.80.0")]
108+
impl<'a, I, A: Allocator> !Iterator for &'a mut Box<[I], A> {}
109+
110+
// Note: the `#[rustc_skip_during_method_dispatch(boxed_slice)]` on `trait IntoIterator`
111+
// hides this implementation from explicit `.into_iter()` calls on editions < 2024,
112+
// so those calls will still resolve to the slice implementation, by reference.
113+
#[stable(feature = "boxed_slice_into_iter", since = "1.80.0")]
114+
impl<I, A: Allocator> IntoIterator for Box<[I], A> {
115+
type IntoIter = vec::IntoIter<I, A>;
116+
type Item = I;
117+
fn into_iter(self) -> vec::IntoIter<I, A> {
118+
self.into_vec().into_iter()
119+
}
120+
}
121+
122+
#[stable(feature = "boxed_slice_into_iter", since = "1.80.0")]
123+
impl<'a, I, A: Allocator> IntoIterator for &'a Box<[I], A> {
124+
type IntoIter = slice::Iter<'a, I>;
125+
type Item = &'a I;
126+
fn into_iter(self) -> slice::Iter<'a, I> {
127+
self.iter()
128+
}
129+
}
130+
131+
#[stable(feature = "boxed_slice_into_iter", since = "1.80.0")]
132+
impl<'a, I, A: Allocator> IntoIterator for &'a mut Box<[I], A> {
133+
type IntoIter = slice::IterMut<'a, I>;
134+
type Item = &'a mut I;
135+
fn into_iter(self) -> slice::IterMut<'a, I> {
136+
self.iter_mut()
137+
}
138+
}
139+
140+
#[cfg(not(no_global_oom_handling))]
141+
#[stable(feature = "boxed_slice_from_iter", since = "1.32.0")]
142+
impl<I> FromIterator<I> for Box<[I]> {
143+
fn from_iter<T: IntoIterator<Item = I>>(iter: T) -> Self {
144+
iter.into_iter().collect::<Vec<_>>().into_boxed_slice()
145+
}
146+
}
147+
148+
#[cfg(not(no_global_oom_handling))]
149+
#[stable(feature = "boxed_str_from_iter", since = "1.80.0")]
150+
impl FromIterator<char> for Box<str> {
151+
fn from_iter<T: IntoIterator<Item = char>>(iter: T) -> Self {
152+
String::from_iter(iter).into_boxed_str()
153+
}
154+
}
155+
156+
#[cfg(not(no_global_oom_handling))]
157+
#[stable(feature = "boxed_str_from_iter", since = "1.80.0")]
158+
impl<'a> FromIterator<&'a char> for Box<str> {
159+
fn from_iter<T: IntoIterator<Item = &'a char>>(iter: T) -> Self {
160+
String::from_iter(iter).into_boxed_str()
161+
}
162+
}
163+
164+
#[cfg(not(no_global_oom_handling))]
165+
#[stable(feature = "boxed_str_from_iter", since = "1.80.0")]
166+
impl<'a> FromIterator<&'a str> for Box<str> {
167+
fn from_iter<T: IntoIterator<Item = &'a str>>(iter: T) -> Self {
168+
String::from_iter(iter).into_boxed_str()
169+
}
170+
}
171+
172+
#[cfg(not(no_global_oom_handling))]
173+
#[stable(feature = "boxed_str_from_iter", since = "1.80.0")]
174+
impl FromIterator<String> for Box<str> {
175+
fn from_iter<T: IntoIterator<Item = String>>(iter: T) -> Self {
176+
String::from_iter(iter).into_boxed_str()
177+
}
178+
}
179+
180+
#[cfg(not(no_global_oom_handling))]
181+
#[stable(feature = "boxed_str_from_iter", since = "1.80.0")]
182+
impl<A: Allocator> FromIterator<Box<str, A>> for Box<str> {
183+
fn from_iter<T: IntoIterator<Item = Box<str, A>>>(iter: T) -> Self {
184+
String::from_iter(iter).into_boxed_str()
185+
}
186+
}
187+
188+
#[cfg(not(no_global_oom_handling))]
189+
#[stable(feature = "boxed_str_from_iter", since = "1.80.0")]
190+
impl<'a> FromIterator<Cow<'a, str>> for Box<str> {
191+
fn from_iter<T: IntoIterator<Item = Cow<'a, str>>>(iter: T) -> Self {
192+
String::from_iter(iter).into_boxed_str()
193+
}
194+
}

‎src/tools/miri/tests/fail/coroutine-pinned-moved.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ note: inside `<CoroutineIteratorAdapter<{static coroutine@tests/fail/coroutine-p
2323
|
2424
LL | match me.resume(()) {
2525
| ^^^^^^^^^^^^^
26-
= note: inside `<std::boxed::Box<CoroutineIteratorAdapter<{static coroutine@tests/fail/coroutine-pinned-moved.rs:LL:CC}>> as std::iter::Iterator>::next` at RUSTLIB/alloc/src/boxed.rs:LL:CC
26+
= note: inside `std::boxed::iter::<impl std::iter::Iterator for std::boxed::Box<CoroutineIteratorAdapter<{static coroutine@tests/fail/coroutine-pinned-moved.rs:LL:CC}>>>::next` at RUSTLIB/alloc/src/boxed/iter.rs:LL:CC
2727
note: inside `main`
2828
--> tests/fail/coroutine-pinned-moved.rs:LL:CC
2929
|

0 commit comments

Comments
 (0)
Please sign in to comment.