Skip to content

Commit 8e0d01b

Browse files
committedAug 19, 2017
Implement From<&[T]> and others for Arc/Rc
Implements RFC 1845, adding implementations of: * `From<&[T]>` for `Rc<[T]>` * `From<&str>` for `Rc<str>` * `From<String>` for `Rc<str>` * `From<Box<T: ?Sized>>` for `Rc<T>` * `From<Vec<T>>` for `Rc<[T]>` * and likewise for `Arc<_>` Also removes now-obsolete internal methods `Rc::__from_array` and `Rc::__from_str`, replacing their use with `Rc::from`.
1 parent 7f397bd commit 8e0d01b

File tree

3 files changed

+587
-66
lines changed

3 files changed

+587
-66
lines changed
 

‎src/liballoc/arc.rs

+295-5
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,13 @@
1616
//!
1717
//! [arc]: struct.Arc.html
1818
19-
use boxed::Box;
20-
2119
use core::sync::atomic;
2220
use core::sync::atomic::Ordering::{Acquire, Relaxed, Release, SeqCst};
2321
use core::borrow;
2422
use core::fmt;
2523
use core::cmp::Ordering;
2624
use core::intrinsics::abort;
27-
use core::mem;
28-
use core::mem::uninitialized;
25+
use core::mem::{self, size_of_val, uninitialized};
2926
use core::ops::Deref;
3027
use core::ops::CoerceUnsized;
3128
use core::ptr::{self, Shared};
@@ -34,7 +31,10 @@ use core::hash::{Hash, Hasher};
3431
use core::{isize, usize};
3532
use core::convert::From;
3633

37-
use heap::{Heap, Alloc, Layout};
34+
use heap::{Heap, Alloc, Layout, box_free};
35+
use boxed::Box;
36+
use string::String;
37+
use vec::Vec;
3838

3939
/// A soft limit on the amount of references that may be made to an `Arc`.
4040
///
@@ -532,6 +532,141 @@ impl<T: ?Sized> Arc<T> {
532532
}
533533
}
534534

535+
impl<T: ?Sized> Arc<T> {
536+
// Allocates an `ArcInner<T>` with sufficient space for an unsized value
537+
unsafe fn allocate_for_ptr(ptr: *const T) -> *mut ArcInner<T> {
538+
// Create a fake ArcInner to find allocation size and alignment
539+
let fake_ptr = ptr as *mut ArcInner<T>;
540+
541+
let layout = Layout::for_value(&*fake_ptr);
542+
543+
let mem = Heap.alloc(layout)
544+
.unwrap_or_else(|e| Heap.oom(e));
545+
546+
// Initialize the real ArcInner
547+
let inner = set_data_ptr(ptr as *mut T, mem) as *mut ArcInner<T>;
548+
549+
ptr::write(&mut (*inner).strong, atomic::AtomicUsize::new(1));
550+
ptr::write(&mut (*inner).weak, atomic::AtomicUsize::new(1));
551+
552+
inner
553+
}
554+
555+
fn from_box(v: Box<T>) -> Arc<T> {
556+
unsafe {
557+
let bptr = Box::into_raw(v);
558+
559+
let value_size = size_of_val(&*bptr);
560+
let ptr = Self::allocate_for_ptr(bptr);
561+
562+
// Copy value as bytes
563+
ptr::copy_nonoverlapping(
564+
bptr as *const T as *const u8,
565+
&mut (*ptr).data as *mut _ as *mut u8,
566+
value_size);
567+
568+
// Free the allocation without dropping its contents
569+
box_free(bptr);
570+
571+
Arc { ptr: Shared::new_unchecked(ptr) }
572+
}
573+
}
574+
}
575+
576+
// Sets the data pointer of a `?Sized` raw pointer.
577+
//
578+
// For a slice/trait object, this sets the `data` field and leaves the rest
579+
// unchanged. For a sized raw pointer, this simply sets the pointer.
580+
unsafe fn set_data_ptr<T: ?Sized, U>(mut ptr: *mut T, data: *mut U) -> *mut T {
581+
ptr::write(&mut ptr as *mut _ as *mut *mut u8, data as *mut u8);
582+
ptr
583+
}
584+
585+
impl<T> Arc<[T]> {
586+
// Copy elements from slice into newly allocated Arc<[T]>
587+
//
588+
// Unsafe because the caller must either take ownership or bind `T: Copy`
589+
unsafe fn copy_from_slice(v: &[T]) -> Arc<[T]> {
590+
let v_ptr = v as *const [T];
591+
let ptr = Self::allocate_for_ptr(v_ptr);
592+
593+
ptr::copy_nonoverlapping(
594+
v.as_ptr(),
595+
&mut (*ptr).data as *mut [T] as *mut T,
596+
v.len());
597+
598+
Arc { ptr: Shared::new_unchecked(ptr) }
599+
}
600+
}
601+
602+
// Specialization trait used for From<&[T]>
603+
trait ArcFromSlice<T> {
604+
fn from_slice(slice: &[T]) -> Self;
605+
}
606+
607+
impl<T: Clone> ArcFromSlice<T> for Arc<[T]> {
608+
#[inline]
609+
default fn from_slice(v: &[T]) -> Self {
610+
// Panic guard while cloning T elements.
611+
// In the event of a panic, elements that have been written
612+
// into the new ArcInner will be dropped, then the memory freed.
613+
struct Guard<T> {
614+
mem: *mut u8,
615+
elems: *mut T,
616+
layout: Layout,
617+
n_elems: usize,
618+
}
619+
620+
impl<T> Drop for Guard<T> {
621+
fn drop(&mut self) {
622+
use core::slice::from_raw_parts_mut;
623+
624+
unsafe {
625+
let slice = from_raw_parts_mut(self.elems, self.n_elems);
626+
ptr::drop_in_place(slice);
627+
628+
Heap.dealloc(self.mem, self.layout.clone());
629+
}
630+
}
631+
}
632+
633+
unsafe {
634+
let v_ptr = v as *const [T];
635+
let ptr = Self::allocate_for_ptr(v_ptr);
636+
637+
let mem = ptr as *mut _ as *mut u8;
638+
let layout = Layout::for_value(&*ptr);
639+
640+
// Pointer to first element
641+
let elems = &mut (*ptr).data as *mut [T] as *mut T;
642+
643+
let mut guard = Guard{
644+
mem: mem,
645+
elems: elems,
646+
layout: layout,
647+
n_elems: 0,
648+
};
649+
650+
for (i, item) in v.iter().enumerate() {
651+
ptr::write(elems.offset(i as isize), item.clone());
652+
guard.n_elems += 1;
653+
}
654+
655+
// All clear. Forget the guard so it doesn't free the new ArcInner.
656+
mem::forget(guard);
657+
658+
Arc { ptr: Shared::new_unchecked(ptr) }
659+
}
660+
}
661+
}
662+
663+
impl<T: Copy> ArcFromSlice<T> for Arc<[T]> {
664+
#[inline]
665+
fn from_slice(v: &[T]) -> Self {
666+
unsafe { Arc::copy_from_slice(v) }
667+
}
668+
}
669+
535670
#[stable(feature = "rust1", since = "1.0.0")]
536671
impl<T: ?Sized> Clone for Arc<T> {
537672
/// Makes a clone of the `Arc` pointer.
@@ -1216,8 +1351,56 @@ impl<T> From<T> for Arc<T> {
12161351
}
12171352
}
12181353

1354+
#[stable(feature = "shared_from_slice", since = "1.21.0")]
1355+
impl<'a, T: Clone> From<&'a [T]> for Arc<[T]> {
1356+
#[inline]
1357+
fn from(v: &[T]) -> Arc<[T]> {
1358+
<Self as ArcFromSlice<T>>::from_slice(v)
1359+
}
1360+
}
1361+
1362+
#[stable(feature = "shared_from_slice", since = "1.21.0")]
1363+
impl<'a> From<&'a str> for Arc<str> {
1364+
#[inline]
1365+
fn from(v: &str) -> Arc<str> {
1366+
unsafe { mem::transmute(<Arc<[u8]>>::from(v.as_bytes())) }
1367+
}
1368+
}
1369+
1370+
#[stable(feature = "shared_from_slice", since = "1.21.0")]
1371+
impl From<String> for Arc<str> {
1372+
#[inline]
1373+
fn from(v: String) -> Arc<str> {
1374+
Arc::from(&v[..])
1375+
}
1376+
}
1377+
1378+
#[stable(feature = "shared_from_slice", since = "1.21.0")]
1379+
impl<T: ?Sized> From<Box<T>> for Arc<T> {
1380+
#[inline]
1381+
fn from(v: Box<T>) -> Arc<T> {
1382+
Arc::from_box(v)
1383+
}
1384+
}
1385+
1386+
#[stable(feature = "shared_from_slice", since = "1.21.0")]
1387+
impl<T> From<Vec<T>> for Arc<[T]> {
1388+
#[inline]
1389+
fn from(mut v: Vec<T>) -> Arc<[T]> {
1390+
unsafe {
1391+
let arc = Arc::copy_from_slice(&v);
1392+
1393+
// Allow the Vec to free its memory, but not destroy its contents
1394+
v.set_len(0);
1395+
1396+
arc
1397+
}
1398+
}
1399+
}
1400+
12191401
#[cfg(test)]
12201402
mod tests {
1403+
use std::boxed::Box;
12211404
use std::clone::Clone;
12221405
use std::sync::mpsc::channel;
12231406
use std::mem::drop;
@@ -1520,6 +1703,113 @@ mod tests {
15201703
}
15211704
t.join().unwrap();
15221705
}
1706+
1707+
#[test]
1708+
fn test_from_str() {
1709+
let r: Arc<str> = Arc::from("foo");
1710+
1711+
assert_eq!(&r[..], "foo");
1712+
}
1713+
1714+
#[test]
1715+
fn test_copy_from_slice() {
1716+
let s: &[u32] = &[1, 2, 3];
1717+
let r: Arc<[u32]> = Arc::from(s);
1718+
1719+
assert_eq!(&r[..], [1, 2, 3]);
1720+
}
1721+
1722+
#[test]
1723+
fn test_clone_from_slice() {
1724+
#[derive(Clone, Debug, Eq, PartialEq)]
1725+
struct X(u32);
1726+
1727+
let s: &[X] = &[X(1), X(2), X(3)];
1728+
let r: Arc<[X]> = Arc::from(s);
1729+
1730+
assert_eq!(&r[..], s);
1731+
}
1732+
1733+
#[test]
1734+
#[should_panic]
1735+
fn test_clone_from_slice_panic() {
1736+
use std::string::{String, ToString};
1737+
1738+
struct Fail(u32, String);
1739+
1740+
impl Clone for Fail {
1741+
fn clone(&self) -> Fail {
1742+
if self.0 == 2 {
1743+
panic!();
1744+
}
1745+
Fail(self.0, self.1.clone())
1746+
}
1747+
}
1748+
1749+
let s: &[Fail] = &[
1750+
Fail(0, "foo".to_string()),
1751+
Fail(1, "bar".to_string()),
1752+
Fail(2, "baz".to_string()),
1753+
];
1754+
1755+
// Should panic, but not cause memory corruption
1756+
let _r: Arc<[Fail]> = Arc::from(s);
1757+
}
1758+
1759+
#[test]
1760+
fn test_from_box() {
1761+
let b: Box<u32> = box 123;
1762+
let r: Arc<u32> = Arc::from(b);
1763+
1764+
assert_eq!(*r, 123);
1765+
}
1766+
1767+
#[test]
1768+
fn test_from_box_str() {
1769+
use std::string::String;
1770+
1771+
let s = String::from("foo").into_boxed_str();
1772+
let r: Arc<str> = Arc::from(s);
1773+
1774+
assert_eq!(&r[..], "foo");
1775+
}
1776+
1777+
#[test]
1778+
fn test_from_box_slice() {
1779+
let s = vec![1, 2, 3].into_boxed_slice();
1780+
let r: Arc<[u32]> = Arc::from(s);
1781+
1782+
assert_eq!(&r[..], [1, 2, 3]);
1783+
}
1784+
1785+
#[test]
1786+
fn test_from_box_trait() {
1787+
use std::fmt::Display;
1788+
use std::string::ToString;
1789+
1790+
let b: Box<Display> = box 123;
1791+
let r: Arc<Display> = Arc::from(b);
1792+
1793+
assert_eq!(r.to_string(), "123");
1794+
}
1795+
1796+
#[test]
1797+
fn test_from_box_trait_zero_sized() {
1798+
use std::fmt::Debug;
1799+
1800+
let b: Box<Debug> = box ();
1801+
let r: Arc<Debug> = Arc::from(b);
1802+
1803+
assert_eq!(format!("{:?}", r), "()");
1804+
}
1805+
1806+
#[test]
1807+
fn test_from_vec() {
1808+
let v = vec![1, 2, 3];
1809+
let r: Arc<[u32]> = Arc::from(v);
1810+
1811+
assert_eq!(&r[..], [1, 2, 3]);
1812+
}
15231813
}
15241814

15251815
#[stable(feature = "rust1", since = "1.0.0")]

‎src/liballoc/rc.rs

+291-60
Original file line numberDiff line numberDiff line change
@@ -252,14 +252,15 @@ use core::hash::{Hash, Hasher};
252252
use core::intrinsics::abort;
253253
use core::marker;
254254
use core::marker::Unsize;
255-
use core::mem::{self, forget, size_of, size_of_val, uninitialized};
255+
use core::mem::{self, forget, size_of_val, uninitialized};
256256
use core::ops::Deref;
257257
use core::ops::CoerceUnsized;
258258
use core::ptr::{self, Shared};
259259
use core::convert::From;
260260

261261
use heap::{Heap, Alloc, Layout, box_free};
262-
use raw_vec::RawVec;
262+
use string::String;
263+
use vec::Vec;
263264

264265
struct RcBox<T: ?Sized> {
265266
strong: Cell<usize>,
@@ -421,64 +422,6 @@ impl<T> Rc<T> {
421422
}
422423
}
423424

424-
impl Rc<str> {
425-
/// Constructs a new `Rc<str>` from a string slice.
426-
#[doc(hidden)]
427-
#[unstable(feature = "rustc_private",
428-
reason = "for internal use in rustc",
429-
issue = "27812")]
430-
pub fn __from_str(value: &str) -> Rc<str> {
431-
unsafe {
432-
// Allocate enough space for `RcBox<str>`.
433-
let aligned_len = 2 + (value.len() + size_of::<usize>() - 1) / size_of::<usize>();
434-
let vec = RawVec::<usize>::with_capacity(aligned_len);
435-
let ptr = vec.ptr();
436-
forget(vec);
437-
// Initialize fields of `RcBox<str>`.
438-
*ptr.offset(0) = 1; // strong: Cell::new(1)
439-
*ptr.offset(1) = 1; // weak: Cell::new(1)
440-
ptr::copy_nonoverlapping(value.as_ptr(), ptr.offset(2) as *mut u8, value.len());
441-
// Combine the allocation address and the string length into a fat pointer to `RcBox`.
442-
let rcbox_ptr: *mut RcBox<str> = mem::transmute([ptr as usize, value.len()]);
443-
assert!(aligned_len * size_of::<usize>() == size_of_val(&*rcbox_ptr));
444-
Rc { ptr: Shared::new_unchecked(rcbox_ptr) }
445-
}
446-
}
447-
}
448-
449-
impl<T> Rc<[T]> {
450-
/// Constructs a new `Rc<[T]>` from a `Box<[T]>`.
451-
#[doc(hidden)]
452-
#[unstable(feature = "rustc_private",
453-
reason = "for internal use in rustc",
454-
issue = "27812")]
455-
pub fn __from_array(value: Box<[T]>) -> Rc<[T]> {
456-
unsafe {
457-
let ptr: *mut RcBox<[T]> =
458-
mem::transmute([mem::align_of::<RcBox<[T; 1]>>(), value.len()]);
459-
// FIXME(custom-DST): creating this invalid &[T] is dubiously defined,
460-
// we should have a better way of getting the size/align
461-
// of a DST from its unsized part.
462-
let ptr = Heap.alloc(Layout::for_value(&*ptr))
463-
.unwrap_or_else(|e| Heap.oom(e));
464-
let ptr: *mut RcBox<[T]> = mem::transmute([ptr as usize, value.len()]);
465-
466-
// Initialize the new RcBox.
467-
ptr::write(&mut (*ptr).strong, Cell::new(1));
468-
ptr::write(&mut (*ptr).weak, Cell::new(1));
469-
ptr::copy_nonoverlapping(
470-
value.as_ptr(),
471-
&mut (*ptr).value as *mut [T] as *mut T,
472-
value.len());
473-
474-
// Free the original allocation without freeing its (moved) contents.
475-
box_free(Box::into_raw(value));
476-
477-
Rc { ptr: Shared::new_unchecked(ptr as *mut _) }
478-
}
479-
}
480-
}
481-
482425
impl<T: ?Sized> Rc<T> {
483426
/// Creates a new [`Weak`][weak] pointer to this value.
484427
///
@@ -665,6 +608,140 @@ impl<T: Clone> Rc<T> {
665608
}
666609
}
667610

611+
impl<T: ?Sized> Rc<T> {
612+
// Allocates an `RcBox<T>` with sufficient space for an unsized value
613+
unsafe fn allocate_for_ptr(ptr: *const T) -> *mut RcBox<T> {
614+
// Create a fake RcBox to find allocation size and alignment
615+
let fake_ptr = ptr as *mut RcBox<T>;
616+
617+
let layout = Layout::for_value(&*fake_ptr);
618+
619+
let mem = Heap.alloc(layout)
620+
.unwrap_or_else(|e| Heap.oom(e));
621+
622+
// Initialize the real RcBox
623+
let inner = set_data_ptr(ptr as *mut T, mem) as *mut RcBox<T>;
624+
625+
ptr::write(&mut (*inner).strong, Cell::new(1));
626+
ptr::write(&mut (*inner).weak, Cell::new(1));
627+
628+
inner
629+
}
630+
631+
fn from_box(v: Box<T>) -> Rc<T> {
632+
unsafe {
633+
let bptr = Box::into_raw(v);
634+
635+
let value_size = size_of_val(&*bptr);
636+
let ptr = Self::allocate_for_ptr(bptr);
637+
638+
// Copy value as bytes
639+
ptr::copy_nonoverlapping(
640+
bptr as *const T as *const u8,
641+
&mut (*ptr).value as *mut _ as *mut u8,
642+
value_size);
643+
644+
// Free the allocation without dropping its contents
645+
box_free(bptr);
646+
647+
Rc { ptr: Shared::new_unchecked(ptr) }
648+
}
649+
}
650+
}
651+
652+
// Sets the data pointer of a `?Sized` raw pointer.
653+
//
654+
// For a slice/trait object, this sets the `data` field and leaves the rest
655+
// unchanged. For a sized raw pointer, this simply sets the pointer.
656+
unsafe fn set_data_ptr<T: ?Sized, U>(mut ptr: *mut T, data: *mut U) -> *mut T {
657+
ptr::write(&mut ptr as *mut _ as *mut *mut u8, data as *mut u8);
658+
ptr
659+
}
660+
661+
impl<T> Rc<[T]> {
662+
// Copy elements from slice into newly allocated Rc<[T]>
663+
//
664+
// Unsafe because the caller must either take ownership or bind `T: Copy`
665+
unsafe fn copy_from_slice(v: &[T]) -> Rc<[T]> {
666+
let v_ptr = v as *const [T];
667+
let ptr = Self::allocate_for_ptr(v_ptr);
668+
669+
ptr::copy_nonoverlapping(
670+
v.as_ptr(),
671+
&mut (*ptr).value as *mut [T] as *mut T,
672+
v.len());
673+
674+
Rc { ptr: Shared::new_unchecked(ptr) }
675+
}
676+
}
677+
678+
trait RcFromSlice<T> {
679+
fn from_slice(slice: &[T]) -> Self;
680+
}
681+
682+
impl<T: Clone> RcFromSlice<T> for Rc<[T]> {
683+
#[inline]
684+
default fn from_slice(v: &[T]) -> Self {
685+
// Panic guard while cloning T elements.
686+
// In the event of a panic, elements that have been written
687+
// into the new RcBox will be dropped, then the memory freed.
688+
struct Guard<T> {
689+
mem: *mut u8,
690+
elems: *mut T,
691+
layout: Layout,
692+
n_elems: usize,
693+
}
694+
695+
impl<T> Drop for Guard<T> {
696+
fn drop(&mut self) {
697+
use core::slice::from_raw_parts_mut;
698+
699+
unsafe {
700+
let slice = from_raw_parts_mut(self.elems, self.n_elems);
701+
ptr::drop_in_place(slice);
702+
703+
Heap.dealloc(self.mem, self.layout.clone());
704+
}
705+
}
706+
}
707+
708+
unsafe {
709+
let v_ptr = v as *const [T];
710+
let ptr = Self::allocate_for_ptr(v_ptr);
711+
712+
let mem = ptr as *mut _ as *mut u8;
713+
let layout = Layout::for_value(&*ptr);
714+
715+
// Pointer to first element
716+
let elems = &mut (*ptr).value as *mut [T] as *mut T;
717+
718+
let mut guard = Guard{
719+
mem: mem,
720+
elems: elems,
721+
layout: layout,
722+
n_elems: 0,
723+
};
724+
725+
for (i, item) in v.iter().enumerate() {
726+
ptr::write(elems.offset(i as isize), item.clone());
727+
guard.n_elems += 1;
728+
}
729+
730+
// All clear. Forget the guard so it doesn't free the new RcBox.
731+
forget(guard);
732+
733+
Rc { ptr: Shared::new_unchecked(ptr) }
734+
}
735+
}
736+
}
737+
738+
impl<T: Copy> RcFromSlice<T> for Rc<[T]> {
739+
#[inline]
740+
fn from_slice(v: &[T]) -> Self {
741+
unsafe { Rc::copy_from_slice(v) }
742+
}
743+
}
744+
668745
#[stable(feature = "rust1", since = "1.0.0")]
669746
impl<T: ?Sized> Deref for Rc<T> {
670747
type Target = T;
@@ -959,6 +1036,53 @@ impl<T> From<T> for Rc<T> {
9591036
}
9601037
}
9611038

1039+
#[stable(feature = "shared_from_slice", since = "1.21.0")]
1040+
impl<'a, T: Clone> From<&'a [T]> for Rc<[T]> {
1041+
#[inline]
1042+
fn from(v: &[T]) -> Rc<[T]> {
1043+
<Self as RcFromSlice<T>>::from_slice(v)
1044+
}
1045+
}
1046+
1047+
#[stable(feature = "shared_from_slice", since = "1.21.0")]
1048+
impl<'a> From<&'a str> for Rc<str> {
1049+
#[inline]
1050+
fn from(v: &str) -> Rc<str> {
1051+
unsafe { mem::transmute(<Rc<[u8]>>::from(v.as_bytes())) }
1052+
}
1053+
}
1054+
1055+
#[stable(feature = "shared_from_slice", since = "1.21.0")]
1056+
impl From<String> for Rc<str> {
1057+
#[inline]
1058+
fn from(v: String) -> Rc<str> {
1059+
Rc::from(&v[..])
1060+
}
1061+
}
1062+
1063+
#[stable(feature = "shared_from_slice", since = "1.21.0")]
1064+
impl<T: ?Sized> From<Box<T>> for Rc<T> {
1065+
#[inline]
1066+
fn from(v: Box<T>) -> Rc<T> {
1067+
Rc::from_box(v)
1068+
}
1069+
}
1070+
1071+
#[stable(feature = "shared_from_slice", since = "1.21.0")]
1072+
impl<T> From<Vec<T>> for Rc<[T]> {
1073+
#[inline]
1074+
fn from(mut v: Vec<T>) -> Rc<[T]> {
1075+
unsafe {
1076+
let rc = Rc::copy_from_slice(&v);
1077+
1078+
// Allow the Vec to free its memory, but not destroy its contents
1079+
v.set_len(0);
1080+
1081+
rc
1082+
}
1083+
}
1084+
}
1085+
9621086
/// `Weak` is a version of [`Rc`] that holds a non-owning reference to the
9631087
/// managed value. The value is accessed by calling [`upgrade`] on the `Weak`
9641088
/// pointer, which returns an [`Option`]`<`[`Rc`]`<T>>`.
@@ -1465,6 +1589,113 @@ mod tests {
14651589
assert!(Rc::ptr_eq(&five, &same_five));
14661590
assert!(!Rc::ptr_eq(&five, &other_five));
14671591
}
1592+
1593+
#[test]
1594+
fn test_from_str() {
1595+
let r: Rc<str> = Rc::from("foo");
1596+
1597+
assert_eq!(&r[..], "foo");
1598+
}
1599+
1600+
#[test]
1601+
fn test_copy_from_slice() {
1602+
let s: &[u32] = &[1, 2, 3];
1603+
let r: Rc<[u32]> = Rc::from(s);
1604+
1605+
assert_eq!(&r[..], [1, 2, 3]);
1606+
}
1607+
1608+
#[test]
1609+
fn test_clone_from_slice() {
1610+
#[derive(Clone, Debug, Eq, PartialEq)]
1611+
struct X(u32);
1612+
1613+
let s: &[X] = &[X(1), X(2), X(3)];
1614+
let r: Rc<[X]> = Rc::from(s);
1615+
1616+
assert_eq!(&r[..], s);
1617+
}
1618+
1619+
#[test]
1620+
#[should_panic]
1621+
fn test_clone_from_slice_panic() {
1622+
use std::string::{String, ToString};
1623+
1624+
struct Fail(u32, String);
1625+
1626+
impl Clone for Fail {
1627+
fn clone(&self) -> Fail {
1628+
if self.0 == 2 {
1629+
panic!();
1630+
}
1631+
Fail(self.0, self.1.clone())
1632+
}
1633+
}
1634+
1635+
let s: &[Fail] = &[
1636+
Fail(0, "foo".to_string()),
1637+
Fail(1, "bar".to_string()),
1638+
Fail(2, "baz".to_string()),
1639+
];
1640+
1641+
// Should panic, but not cause memory corruption
1642+
let _r: Rc<[Fail]> = Rc::from(s);
1643+
}
1644+
1645+
#[test]
1646+
fn test_from_box() {
1647+
let b: Box<u32> = box 123;
1648+
let r: Rc<u32> = Rc::from(b);
1649+
1650+
assert_eq!(*r, 123);
1651+
}
1652+
1653+
#[test]
1654+
fn test_from_box_str() {
1655+
use std::string::String;
1656+
1657+
let s = String::from("foo").into_boxed_str();
1658+
let r: Rc<str> = Rc::from(s);
1659+
1660+
assert_eq!(&r[..], "foo");
1661+
}
1662+
1663+
#[test]
1664+
fn test_from_box_slice() {
1665+
let s = vec![1, 2, 3].into_boxed_slice();
1666+
let r: Rc<[u32]> = Rc::from(s);
1667+
1668+
assert_eq!(&r[..], [1, 2, 3]);
1669+
}
1670+
1671+
#[test]
1672+
fn test_from_box_trait() {
1673+
use std::fmt::Display;
1674+
use std::string::ToString;
1675+
1676+
let b: Box<Display> = box 123;
1677+
let r: Rc<Display> = Rc::from(b);
1678+
1679+
assert_eq!(r.to_string(), "123");
1680+
}
1681+
1682+
#[test]
1683+
fn test_from_box_trait_zero_sized() {
1684+
use std::fmt::Debug;
1685+
1686+
let b: Box<Debug> = box ();
1687+
let r: Rc<Debug> = Rc::from(b);
1688+
1689+
assert_eq!(format!("{:?}", r), "()");
1690+
}
1691+
1692+
#[test]
1693+
fn test_from_vec() {
1694+
let v = vec![1, 2, 3];
1695+
let r: Rc<[u32]> = Rc::from(v);
1696+
1697+
assert_eq!(&r[..], [1, 2, 3]);
1698+
}
14681699
}
14691700

14701701
#[stable(feature = "rust1", since = "1.0.0")]

‎src/librustc_metadata/decoder.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -892,7 +892,7 @@ impl<'a, 'tcx> CrateMetadata {
892892
if def_key.disambiguated_data.data == DefPathData::StructCtor {
893893
item = self.entry(def_key.parent.unwrap());
894894
}
895-
let result = Rc::__from_array(self.get_attributes(&item).into_boxed_slice());
895+
let result: Rc<[ast::Attribute]> = Rc::from(self.get_attributes(&item));
896896
let vec_ = &mut self.attribute_cache.borrow_mut()[node_as];
897897
if vec_.len() < node_index + 1 {
898898
vec_.resize(node_index + 1, None);

0 commit comments

Comments
 (0)
Please sign in to comment.