From e7b0f2badf7c3393f1b36339b121054d05353442 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Sun, 12 Mar 2017 14:04:52 -0400 Subject: Remove function invokation parens from documentation links. This was never established as a convention we should follow in the 'More API Documentation Conventions' RFC: https://github.com/rust-lang/rfcs/blob/master/text/1574-more-api-documentation-conventions.md --- src/liballoc/rc.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 6108a06634b..eb449b26606 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -13,7 +13,7 @@ //! Single-threaded reference-counting pointers. //! //! The type [`Rc`][`Rc`] provides shared ownership of a value of type `T`, -//! allocated in the heap. Invoking [`clone()`][clone] on [`Rc`] produces a new +//! allocated in the heap. Invoking [`clone`][clone] on [`Rc`] produces a new //! pointer to the same value in the heap. When the last [`Rc`] pointer to a //! given value is destroyed, the pointed-to value is also destroyed. //! @@ -30,7 +30,7 @@ //! threads. If you need multi-threaded, atomic reference counting, use //! [`sync::Arc`][arc]. //! -//! The [`downgrade()`][downgrade] method can be used to create a non-owning +//! The [`downgrade`][downgrade] method can be used to create a non-owning //! [`Weak`] pointer. A [`Weak`] pointer can be [`upgrade`][upgrade]d //! to an [`Rc`], but this will return [`None`] if the value has //! already been dropped. -- cgit 1.4.1-3-g733a5 From 10510aefb10aaad9e9c382acf973a40938d091ad Mon Sep 17 00:00:00 2001 From: Aaron Turon Date: Tue, 14 Mar 2017 21:01:18 -0700 Subject: Stabilize ptr_eq feature, closes #36497 --- src/liballoc/arc.rs | 6 +----- src/liballoc/rc.rs | 6 +----- 2 files changed, 2 insertions(+), 10 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 38d843263ff..b904d818feb 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -461,17 +461,13 @@ impl Arc { } #[inline] - #[unstable(feature = "ptr_eq", - reason = "newly added", - issue = "36497")] + #[stable(feature = "ptr_eq", since = "1.17.0")] /// Returns true if the two `Arc`s point to the same value (not /// just values that compare as equal). /// /// # Examples /// /// ``` - /// #![feature(ptr_eq)] - /// /// use std::sync::Arc; /// /// let five = Arc::new(5); diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index eb449b26606..a5d1381260b 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -551,17 +551,13 @@ impl Rc { } #[inline] - #[unstable(feature = "ptr_eq", - reason = "newly added", - issue = "36497")] + #[stable(feature = "ptr_eq", since = "1.17.0")] /// Returns true if the two `Rc`s point to the same value (not /// just values that compare as equal). /// /// # Examples /// /// ``` - /// #![feature(ptr_eq)] - /// /// use std::rc::Rc; /// /// let five = Rc::new(5); -- cgit 1.4.1-3-g733a5 From a8f4a1bd984091ffb8f87f9440e2483f94b44a20 Mon Sep 17 00:00:00 2001 From: Aaron Turon Date: Tue, 14 Mar 2017 21:10:02 -0700 Subject: Stabilize rc_raw feature, closes #37197 --- src/liballoc/arc.rs | 22 ++++++++------------ src/liballoc/rc.rs | 22 ++++++++------------ src/libcollections/lib.rs | 3 +++ src/libcollections/linked_list.rs | 34 +++++++++++++++---------------- src/libcollections/vec.rs | 4 ++-- src/libcollections/vec_deque.rs | 2 +- src/libcore/ptr.rs | 14 ++++++++++--- src/librustc_data_structures/array_vec.rs | 3 +-- src/librustc_data_structures/lib.rs | 1 - src/libstd/collections/hash/table.rs | 2 +- src/libstd/lib.rs | 1 - 11 files changed, 54 insertions(+), 54 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index b904d818feb..b6191c4d43e 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -287,17 +287,15 @@ impl Arc { /// # Examples /// /// ``` - /// #![feature(rc_raw)] - /// /// use std::sync::Arc; /// /// let x = Arc::new(10); /// let x_ptr = Arc::into_raw(x); /// assert_eq!(unsafe { *x_ptr }, 10); /// ``` - #[unstable(feature = "rc_raw", issue = "37197")] - pub fn into_raw(this: Self) -> *mut T { - let ptr = unsafe { &mut (**this.ptr).data as *mut _ }; + #[stable(feature = "rc_raw", since = "1.17.0")] + pub fn into_raw(this: Self) -> *const T { + let ptr = unsafe { &(**this.ptr).data as *const _ }; mem::forget(this); ptr } @@ -315,8 +313,6 @@ impl Arc { /// # Examples /// /// ``` - /// #![feature(rc_raw)] - /// /// use std::sync::Arc; /// /// let x = Arc::new(10); @@ -332,11 +328,11 @@ impl Arc { /// /// // The memory was freed when `x` went out of scope above, so `x_ptr` is now dangling! /// ``` - #[unstable(feature = "rc_raw", issue = "37197")] - pub unsafe fn from_raw(ptr: *mut T) -> Self { + #[stable(feature = "rc_raw", since = "1.17.0")] + pub unsafe fn from_raw(ptr: *const T) -> Self { // To find the corresponding pointer to the `ArcInner` we need to subtract the offset of the // `data` field from the pointer. - Arc { ptr: Shared::new((ptr as *mut u8).offset(-offset_of!(ArcInner, data)) as *mut _) } + Arc { ptr: Shared::new((ptr as *const u8).offset(-offset_of!(ArcInner, data)) as *const _) } } } @@ -448,7 +444,7 @@ impl Arc { // Non-inlined part of `drop`. #[inline(never)] unsafe fn drop_slow(&mut self) { - let ptr = *self.ptr; + let ptr = self.ptr.as_mut_ptr(); // Destroy the data at this time, even though we may not free the box // allocation itself (there may still be weak pointers lying around). @@ -624,7 +620,7 @@ impl Arc { // As with `get_mut()`, the unsafety is ok because our reference was // either unique to begin with, or became one upon cloning the contents. unsafe { - let inner = &mut **this.ptr; + let inner = &mut *this.ptr.as_mut_ptr(); &mut inner.data } } @@ -667,7 +663,7 @@ impl Arc { // the Arc itself to be `mut`, so we're returning the only possible // reference to the inner data. unsafe { - let inner = &mut **this.ptr; + let inner = &mut *this.ptr.as_mut_ptr(); Some(&mut inner.data) } } else { diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index a5d1381260b..e9b59017692 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -364,17 +364,15 @@ impl Rc { /// # Examples /// /// ``` - /// #![feature(rc_raw)] - /// /// use std::rc::Rc; /// /// let x = Rc::new(10); /// let x_ptr = Rc::into_raw(x); /// assert_eq!(unsafe { *x_ptr }, 10); /// ``` - #[unstable(feature = "rc_raw", issue = "37197")] - pub fn into_raw(this: Self) -> *mut T { - let ptr = unsafe { &mut (**this.ptr).value as *mut _ }; + #[stable(feature = "rc_raw", since = "1.17.0")] + pub fn into_raw(this: Self) -> *const T { + let ptr = unsafe { &mut (*this.ptr.as_mut_ptr()).value as *const _ }; mem::forget(this); ptr } @@ -392,8 +390,6 @@ impl Rc { /// # Examples /// /// ``` - /// #![feature(rc_raw)] - /// /// use std::rc::Rc; /// /// let x = Rc::new(10); @@ -409,11 +405,11 @@ impl Rc { /// /// // The memory was freed when `x` went out of scope above, so `x_ptr` is now dangling! /// ``` - #[unstable(feature = "rc_raw", issue = "37197")] - pub unsafe fn from_raw(ptr: *mut T) -> Self { + #[stable(feature = "rc_raw", since = "1.17.0")] + pub unsafe fn from_raw(ptr: *const T) -> Self { // To find the corresponding pointer to the `RcBox` we need to subtract the offset of the // `value` field from the pointer. - Rc { ptr: Shared::new((ptr as *mut u8).offset(-offset_of!(RcBox, value)) as *mut _) } + Rc { ptr: Shared::new((ptr as *const u8).offset(-offset_of!(RcBox, value)) as *const _) } } } @@ -543,7 +539,7 @@ impl Rc { #[stable(feature = "rc_unique", since = "1.4.0")] pub fn get_mut(this: &mut Self) -> Option<&mut T> { if Rc::is_unique(this) { - let inner = unsafe { &mut **this.ptr }; + let inner = unsafe { &mut *this.ptr.as_mut_ptr() }; Some(&mut inner.value) } else { None @@ -627,7 +623,7 @@ impl Rc { // reference count is guaranteed to be 1 at this point, and we required // the `Rc` itself to be `mut`, so we're returning the only possible // reference to the inner value. - let inner = unsafe { &mut **this.ptr }; + let inner = unsafe { &mut *this.ptr.as_mut_ptr() }; &mut inner.value } } @@ -673,7 +669,7 @@ unsafe impl<#[may_dangle] T: ?Sized> Drop for Rc { /// ``` fn drop(&mut self) { unsafe { - let ptr = *self.ptr; + let ptr = self.ptr.as_mut_ptr(); self.dec_strong(); if self.strong() == 0 { diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index a64fffab45c..10650dab583 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -133,10 +133,13 @@ mod std { #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)] pub enum Bound { /// An inclusive bound. + #[stable(feature = "collections_bound", since = "1.17.0")] Included(T), /// An exclusive bound. + #[stable(feature = "collections_bound", since = "1.17.0")] Excluded(T), /// An infinite endpoint. Indicates that there is no bound in this direction. + #[stable(feature = "collections_bound", since = "1.17.0")] Unbounded, } diff --git a/src/libcollections/linked_list.rs b/src/libcollections/linked_list.rs index d4f77d625b3..f58c87b801f 100644 --- a/src/libcollections/linked_list.rs +++ b/src/libcollections/linked_list.rs @@ -142,7 +142,7 @@ impl LinkedList { match self.head { None => self.tail = node, - Some(head) => (**head).prev = node, + Some(head) => (*head.as_mut_ptr()).prev = node, } self.head = node; @@ -154,12 +154,12 @@ impl LinkedList { #[inline] fn pop_front_node(&mut self) -> Option>> { self.head.map(|node| unsafe { - let node = Box::from_raw(*node); + let node = Box::from_raw(node.as_mut_ptr()); self.head = node.next; match self.head { None => self.tail = None, - Some(head) => (**head).prev = None, + Some(head) => (*head.as_mut_ptr()).prev = None, } self.len -= 1; @@ -177,7 +177,7 @@ impl LinkedList { match self.tail { None => self.head = node, - Some(tail) => (**tail).next = node, + Some(tail) => (*tail.as_mut_ptr()).next = node, } self.tail = node; @@ -189,12 +189,12 @@ impl LinkedList { #[inline] fn pop_back_node(&mut self) -> Option>> { self.tail.map(|node| unsafe { - let node = Box::from_raw(*node); + let node = Box::from_raw(node.as_mut_ptr()); self.tail = node.prev; match self.tail { None => self.head = None, - Some(tail) => (**tail).next = None, + Some(tail) => (*tail.as_mut_ptr()).next = None, } self.len -= 1; @@ -269,8 +269,8 @@ impl LinkedList { Some(tail) => { if let Some(other_head) = other.head.take() { unsafe { - (**tail).next = Some(other_head); - (**other_head).prev = Some(tail); + (*tail.as_mut_ptr()).next = Some(other_head); + (*other_head.as_mut_ptr()).prev = Some(tail); } self.tail = other.tail.take(); @@ -484,7 +484,7 @@ impl LinkedList { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn front_mut(&mut self) -> Option<&mut T> { - self.head.map(|node| unsafe { &mut (**node).element }) + self.head.map(|node| unsafe { &mut (*node.as_mut_ptr()).element }) } /// Provides a reference to the back element, or `None` if the list is @@ -530,7 +530,7 @@ impl LinkedList { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn back_mut(&mut self) -> Option<&mut T> { - self.tail.map(|node| unsafe { &mut (**node).element }) + self.tail.map(|node| unsafe { &mut (*node.as_mut_ptr()).element }) } /// Adds an element first in the list. @@ -675,9 +675,9 @@ impl LinkedList { let second_part_head; unsafe { - second_part_head = (**split_node.unwrap()).next.take(); + second_part_head = (*split_node.unwrap().as_mut_ptr()).next.take(); if let Some(head) = second_part_head { - (**head).prev = None; + (*head.as_mut_ptr()).prev = None; } } @@ -816,7 +816,7 @@ impl<'a, T> Iterator for IterMut<'a, T> { None } else { self.head.map(|node| unsafe { - let node = &mut **node; + let node = &mut *node.as_mut_ptr(); self.len -= 1; self.head = node.next; &mut node.element @@ -838,7 +838,7 @@ impl<'a, T> DoubleEndedIterator for IterMut<'a, T> { None } else { self.tail.map(|node| unsafe { - let node = &mut **node; + let node = &mut *node.as_mut_ptr(); self.len -= 1; self.tail = node.prev; &mut node.element @@ -896,8 +896,8 @@ impl<'a, T> IterMut<'a, T> { element: element, }))); - (**prev).next = node; - (**head).prev = node; + (*prev.as_mut_ptr()).next = node; + (*head.as_mut_ptr()).prev = node; self.list.len += 1; }, @@ -929,7 +929,7 @@ impl<'a, T> IterMut<'a, T> { if self.len == 0 { None } else { - self.head.map(|node| unsafe { &mut (**node).element }) + self.head.map(|node| unsafe { &mut (*node.as_mut_ptr()).element }) } } } diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index a717163f45e..7b408af13aa 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -2120,7 +2120,7 @@ unsafe impl<#[may_dangle] T> Drop for IntoIter { for _x in self.by_ref() {} // RawVec handles deallocation - let _ = unsafe { RawVec::from_raw_parts(*self.buf, self.cap) }; + let _ = unsafe { RawVec::from_raw_parts(self.buf.as_mut_ptr(), self.cap) }; } } @@ -2185,7 +2185,7 @@ impl<'a, T> Drop for Drain<'a, T> { if self.tail_len > 0 { unsafe { - let source_vec = &mut **self.vec; + let source_vec = &mut *self.vec.as_mut_ptr(); // memmove back untouched tail, update to new length let start = source_vec.len(); let tail = self.tail_start; diff --git a/src/libcollections/vec_deque.rs b/src/libcollections/vec_deque.rs index 1985be7f901..6a04d47a345 100644 --- a/src/libcollections/vec_deque.rs +++ b/src/libcollections/vec_deque.rs @@ -2125,7 +2125,7 @@ impl<'a, T: 'a> Drop for Drain<'a, T> { fn drop(&mut self) { for _ in self.by_ref() {} - let source_deque = unsafe { &mut **self.deque }; + let source_deque = unsafe { &mut *self.deque.as_mut_ptr() }; // T = source_deque_tail; H = source_deque_head; t = drain_tail; h = drain_head // diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index e4ad8cfd256..15174e72795 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -968,11 +968,19 @@ impl Shared { /// # Safety /// /// `ptr` must be non-null. - pub unsafe fn new(ptr: *mut T) -> Self { + pub unsafe fn new(ptr: *const T) -> Self { Shared { pointer: NonZero::new(ptr), _marker: PhantomData } } } +#[unstable(feature = "shared", issue = "27730")] +impl Shared { + /// Acquires the underlying pointer as a `*mut` pointer. + pub unsafe fn as_mut_ptr(&self) -> *mut T { + **self as _ + } +} + #[unstable(feature = "shared", issue = "27730")] impl Clone for Shared { fn clone(&self) -> Self { @@ -988,10 +996,10 @@ impl CoerceUnsized> for Shared where T: Unsiz #[unstable(feature = "shared", issue = "27730")] impl Deref for Shared { - type Target = *mut T; + type Target = *const T; #[inline] - fn deref(&self) -> &*mut T { + fn deref(&self) -> &*const T { unsafe { mem::transmute(&*self.pointer) } } } diff --git a/src/librustc_data_structures/array_vec.rs b/src/librustc_data_structures/array_vec.rs index 51e6e09ab50..29fbcb70756 100644 --- a/src/librustc_data_structures/array_vec.rs +++ b/src/librustc_data_structures/array_vec.rs @@ -248,7 +248,7 @@ impl<'a, A: Array> Drop for Drain<'a, A> { if self.tail_len > 0 { unsafe { - let source_array_vec = &mut **self.array_vec; + let source_array_vec = &mut *self.array_vec.as_mut_ptr(); // memmove back untouched tail, update to new length let start = source_array_vec.len(); let tail = self.tail_start; @@ -317,4 +317,3 @@ impl Default for ManuallyDrop { ManuallyDrop::new() } } - diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index f278325ebec..8ecfd75dc95 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -27,7 +27,6 @@ #![feature(shared)] #![feature(collections_range)] -#![feature(collections_bound)] #![cfg_attr(stage0,feature(field_init_shorthand))] #![feature(nonzero)] #![feature(rustc_private)] diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs index 2c8bb433e8a..211605bef1e 100644 --- a/src/libstd/collections/hash/table.rs +++ b/src/libstd/collections/hash/table.rs @@ -1154,7 +1154,7 @@ impl<'a, K, V> Iterator for Drain<'a, K, V> { fn next(&mut self) -> Option<(SafeHash, K, V)> { self.iter.next().map(|bucket| { unsafe { - (**self.table).size -= 1; + (*self.table.as_mut_ptr()).size -= 1; let (k, v) = ptr::read(bucket.pair); (SafeHash { hash: ptr::replace(bucket.hash, EMPTY_BUCKET) }, k, v) } diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 2c83518d388..206a37b8e5d 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -245,7 +245,6 @@ #![feature(char_escape_debug)] #![feature(char_internals)] #![feature(collections)] -#![feature(collections_bound)] #![feature(collections_range)] #![feature(compiler_builtins_lib)] #![feature(const_fn)] -- cgit 1.4.1-3-g733a5 From 1241a88fa9ddf5e645d1e6e93e04c435bbf15cd4 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 15 Mar 2017 07:58:27 -0700 Subject: Minor fixups to fix tidy errors --- src/liballoc/arc.rs | 5 ++++- src/libcollections/btree/map.rs | 2 ++ src/libcollections/btree/set.rs | 7 ++----- src/libcollections/range.rs | 2 -- src/libcollectionstest/lib.rs | 2 -- src/libcore/ptr.rs | 3 +-- src/libcoretest/lib.rs | 4 ---- 7 files changed, 9 insertions(+), 16 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index b6191c4d43e..1d616233881 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -332,7 +332,10 @@ impl Arc { pub unsafe fn from_raw(ptr: *const T) -> Self { // To find the corresponding pointer to the `ArcInner` we need to subtract the offset of the // `data` field from the pointer. - Arc { ptr: Shared::new((ptr as *const u8).offset(-offset_of!(ArcInner, data)) as *const _) } + let ptr = (ptr as *const u8).offset(-offset_of!(ArcInner, data)); + Arc { + ptr: Shared::new(ptr as *const _), + } } } diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs index a746175a5e9..53fe6b4bc9f 100644 --- a/src/libcollections/btree/map.rs +++ b/src/libcollections/btree/map.rs @@ -338,6 +338,7 @@ pub struct ValuesMut<'a, K: 'a, V: 'a> { } /// An iterator over a sub-range of BTreeMap's entries. +#[stable(feature = "btree_range", since = "1.17.0")] pub struct Range<'a, K: 'a, V: 'a> { front: Handle, K, V, marker::Leaf>, marker::Edge>, back: Handle, K, V, marker::Leaf>, marker::Edge>, @@ -351,6 +352,7 @@ impl<'a, K: 'a + fmt::Debug, V: 'a + fmt::Debug> fmt::Debug for Range<'a, K, V> } /// A mutable iterator over a sub-range of BTreeMap's entries. +#[stable(feature = "btree_range", since = "1.17.0")] pub struct RangeMut<'a, K: 'a, V: 'a> { front: Handle, K, V, marker::Leaf>, marker::Edge>, back: Handle, K, V, marker::Leaf>, marker::Edge>, diff --git a/src/libcollections/btree/set.rs b/src/libcollections/btree/set.rs index e3c990c80de..72d25f87bca 100644 --- a/src/libcollections/btree/set.rs +++ b/src/libcollections/btree/set.rs @@ -113,6 +113,7 @@ pub struct IntoIter { /// [`BTreeSet`]: struct.BTreeSet.html /// [`range`]: struct.BTreeSet.html#method.range #[derive(Debug)] +#[stable(feature = "btree_range", since = "1.17.0")] pub struct Range<'a, T: 'a> { iter: ::btree_map::Range<'a, T, ()>, } @@ -264,8 +265,6 @@ impl BTreeSet { /// # Examples /// /// ``` - /// #![feature(btree_range, collections_bound)] - /// /// use std::collections::BTreeSet; /// use std::collections::Bound::Included; /// @@ -278,9 +277,7 @@ impl BTreeSet { /// } /// assert_eq!(Some(&5), set.range(4..).next()); /// ``` - #[unstable(feature = "btree_range", - reason = "matches collection reform specification, waiting for dust to settle", - issue = "27787")] + #[stable(feature = "btree_range", since = "1.17.0")] pub fn range(&self, range: R) -> Range where K: Ord, T: Borrow, R: RangeArgument { diff --git a/src/libcollections/range.rs b/src/libcollections/range.rs index e4b94a1d70e..31e4d001397 100644 --- a/src/libcollections/range.rs +++ b/src/libcollections/range.rs @@ -29,7 +29,6 @@ pub trait RangeArgument { /// ``` /// #![feature(collections)] /// #![feature(collections_range)] - /// #![feature(collections_bound)] /// /// extern crate collections; /// @@ -52,7 +51,6 @@ pub trait RangeArgument { /// ``` /// #![feature(collections)] /// #![feature(collections_range)] - /// #![feature(collections_bound)] /// /// extern crate collections; /// diff --git a/src/libcollectionstest/lib.rs b/src/libcollectionstest/lib.rs index 98d0b1c8e15..618eb386c0f 100644 --- a/src/libcollectionstest/lib.rs +++ b/src/libcollectionstest/lib.rs @@ -13,11 +13,9 @@ #![feature(binary_heap_extras)] #![feature(binary_heap_peek_mut_pop)] #![feature(box_syntax)] -#![feature(btree_range)] #![feature(inclusive_range_syntax)] #![feature(collection_placement)] #![feature(collections)] -#![feature(collections_bound)] #![feature(const_fn)] #![feature(exact_size_is_empty)] #![feature(pattern)] diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 15174e72795..909e44df20a 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -658,7 +658,6 @@ impl Eq for *mut T {} /// # Examples /// /// ``` -/// #![feature(ptr_eq)] /// use std::ptr; /// /// let five = 5; @@ -673,7 +672,7 @@ impl Eq for *mut T {} /// assert!(ptr::eq(five_ref, same_five_ref)); /// assert!(!ptr::eq(five_ref, other_five_ref)); /// ``` -#[unstable(feature = "ptr_eq", reason = "newly added", issue = "36497")] +#[stable(feature = "ptr_eq", since = "1.17.0")] #[inline] pub fn eq(a: *const T, b: *const T) -> bool { a == b diff --git a/src/libcoretest/lib.rs b/src/libcoretest/lib.rs index e06b757691e..d84a1e22756 100644 --- a/src/libcoretest/lib.rs +++ b/src/libcoretest/lib.rs @@ -23,7 +23,6 @@ #![feature(nonzero)] #![feature(rand)] #![feature(raw)] -#![feature(result_expect_err)] #![feature(sip_hash_13)] #![feature(slice_patterns)] #![feature(step_by)] @@ -31,9 +30,6 @@ #![feature(try_from)] #![feature(unicode)] #![feature(unique)] -#![feature(ordering_chaining)] -#![feature(ptr_unaligned)] -#![feature(move_cell)] #![feature(fmt_internals)] extern crate core; -- cgit 1.4.1-3-g733a5 From d1d9626e7577546585f216f8ee11be824b374f78 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Wed, 15 Mar 2017 12:13:55 -0400 Subject: Fix up various links The unstable book, libstd, libcore, and liballoc all needed some adjustment. --- src/doc/unstable-book/src/plugin.md | 2 +- src/liballoc/arc.rs | 2 +- src/liballoc/rc.rs | 2 +- src/libcore/char.rs | 4 ++-- src/libcore/iter/iterator.rs | 4 ++-- src/libcore/mem.rs | 10 +++++----- src/libcore/raw.rs | 2 +- src/libstd/lib.rs | 10 +++++----- src/libstd/primitive_docs.rs | 4 ++-- 9 files changed, 20 insertions(+), 20 deletions(-) (limited to 'src/liballoc') diff --git a/src/doc/unstable-book/src/plugin.md b/src/doc/unstable-book/src/plugin.md index ca69b7084d3..3a1872e18dd 100644 --- a/src/doc/unstable-book/src/plugin.md +++ b/src/doc/unstable-book/src/plugin.md @@ -137,7 +137,7 @@ of extensions. See `Registry::register_syntax_extension` and the ## Tips and tricks -Some of the [macro debugging tips](../book/macros.html#debugging-macro-code) are applicable. +Some of the [macro debugging tips](../book/first-edition/macros.html#debugging-macro-code) are applicable. You can use `syntax::parse` to turn token trees into higher-level syntax elements like expressions: diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 1d616233881..28f6d97756f 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -102,7 +102,7 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize; /// [downgrade]: struct.Arc.html#method.downgrade /// [upgrade]: struct.Weak.html#method.upgrade /// [`None`]: ../../std/option/enum.Option.html#variant.None -/// [assoc]: ../../book/method-syntax.html#associated-functions +/// [assoc]: ../../book/first-edition/method-syntax.html#associated-functions /// /// # Examples /// diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index e9b59017692..561ccaa5ef5 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -215,7 +215,7 @@ //! [downgrade]: struct.Rc.html#method.downgrade //! [upgrade]: struct.Weak.html#method.upgrade //! [`None`]: ../../std/option/enum.Option.html#variant.None -//! [assoc]: ../../book/method-syntax.html#associated-functions +//! [assoc]: ../../book/first-edition/method-syntax.html#associated-functions //! [mutability]: ../../std/cell/index.html#introducing-mutability-inside-of-something-immutable #![stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libcore/char.rs b/src/libcore/char.rs index 649fdf394e4..19e69ca296d 100644 --- a/src/libcore/char.rs +++ b/src/libcore/char.rs @@ -94,7 +94,7 @@ pub const MAX: char = '\u{10ffff}'; /// /// [`char`]: ../../std/primitive.char.html /// [`u32`]: ../../std/primitive.u32.html -/// [`as`]: ../../book/casting-between-types.html#as +/// [`as`]: ../../book/first-edition/casting-between-types.html#as /// /// For an unsafe version of this function which ignores these checks, see /// [`from_u32_unchecked`]. @@ -146,7 +146,7 @@ pub fn from_u32(i: u32) -> Option { /// /// [`char`]: ../../std/primitive.char.html /// [`u32`]: ../../std/primitive.u32.html -/// [`as`]: ../../book/casting-between-types.html#as +/// [`as`]: ../../book/first-edition/casting-between-types.html#as /// /// # Safety /// diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 1301c311c14..fb98e43aa61 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -409,7 +409,7 @@ pub trait Iterator { /// If you're doing some sort of looping for a side effect, it's considered /// more idiomatic to use [`for`] than `map()`. /// - /// [`for`]: ../../book/loops.html#for + /// [`for`]: ../../book/first-edition/loops.html#for /// /// # Examples /// @@ -1306,7 +1306,7 @@ pub trait Iterator { /// use a `for` loop with a list of things to build up a result. Those /// can be turned into `fold()`s: /// - /// [`for`]: ../../book/loops.html#for + /// [`for`]: ../../book/first-edition/loops.html#for /// /// ``` /// let numbers = [1, 2, 3, 4, 5]; diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index ba65e4494a8..f5cf3724d07 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -164,7 +164,7 @@ pub use intrinsics::transmute; /// [uninit]: fn.uninitialized.html /// [clone]: ../clone/trait.Clone.html /// [swap]: fn.swap.html -/// [FFI]: ../../book/ffi.html +/// [FFI]: ../../book/first-edition/ffi.html /// [box]: ../../std/boxed/struct.Box.html /// [into_raw]: ../../std/boxed/struct.Box.html#method.into_raw /// [ub]: ../../reference/behavior-considered-undefined.html @@ -199,7 +199,7 @@ pub fn size_of() -> usize { /// then `size_of_val` can be used to get the dynamically-known size. /// /// [slice]: ../../std/primitive.slice.html -/// [trait object]: ../../book/trait-objects.html +/// [trait object]: ../../book/first-edition/trait-objects.html /// /// # Examples /// @@ -317,7 +317,7 @@ pub fn align_of_val(val: &T) -> usize { /// many of the same caveats. /// /// [uninit]: fn.uninitialized.html -/// [FFI]: ../../book/ffi.html +/// [FFI]: ../../book/first-edition/ffi.html /// [ub]: ../../reference/behavior-considered-undefined.html /// /// # Examples @@ -343,7 +343,7 @@ pub unsafe fn zeroed() -> T { /// This is useful for [FFI] functions and initializing arrays sometimes, /// but should generally be avoided. /// -/// [FFI]: ../../book/ffi.html +/// [FFI]: ../../book/first-edition/ffi.html /// /// # Undefined behavior /// @@ -525,7 +525,7 @@ pub fn replace(dest: &mut T, mut src: T) -> T { /// it will not release any borrows, as borrows are based on lexical scope. /// /// This effectively does nothing for -/// [types which implement `Copy`](../../book/ownership.html#copy-types), +/// [types which implement `Copy`](../../book/first-edition/ownership.html#copy-types), /// e.g. integers. Such values are copied and _then_ moved into the function, /// so the value persists after this function call. /// diff --git a/src/libcore/raw.rs b/src/libcore/raw.rs index a7d0d3899b1..a95f05227fb 100644 --- a/src/libcore/raw.rs +++ b/src/libcore/raw.rs @@ -25,7 +25,7 @@ /// Book][moreinfo] contains more details about the precise nature of /// these internals. /// -/// [moreinfo]: ../../book/trait-objects.html#representation +/// [moreinfo]: ../../book/first-edition/trait-objects.html#representation /// /// `TraitObject` is guaranteed to match layouts, but it is not the /// type of trait objects (e.g. the fields are not directly accessible diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index d01ed1e3fe6..3da5d4b94dd 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -174,7 +174,7 @@ //! [slice]: primitive.slice.html //! [`atomic`]: sync/atomic/index.html //! [`collections`]: collections/index.html -//! [`for`]: ../book/loops.html#for +//! [`for`]: ../book/first-edition/loops.html#for //! [`format!`]: macro.format.html //! [`fs`]: fs/index.html //! [`io`]: io/index.html @@ -189,14 +189,14 @@ //! [`sync`]: sync/index.html //! [`thread`]: thread/index.html //! [`use std::env`]: env/index.html -//! [`use`]: ../book/crates-and-modules.html#importing-modules-with-use -//! [crate root]: ../book/crates-and-modules.html#basic-terminology-crates-and-modules +//! [`use`]: ../book/first-edition/crates-and-modules.html#importing-modules-with-use +//! [crate root]: ../book/first-edition/crates-and-modules.html#basic-terminology-crates-and-modules //! [crates.io]: https://crates.io -//! [deref coercions]: ../book/deref-coercions.html +//! [deref coercions]: ../book/first-edition/deref-coercions.html //! [files]: fs/struct.File.html //! [multithreading]: thread/index.html //! [other]: #what-is-in-the-standard-library-documentation -//! [primitive types]: ../book/primitive-types.html +//! [primitive types]: ../book/first-edition/primitive-types.html #![crate_name = "std"] #![stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs index 7d6d16f4748..c738dc94406 100644 --- a/src/libstd/primitive_docs.rs +++ b/src/libstd/primitive_docs.rs @@ -29,7 +29,7 @@ /// ``` /// /// [`assert!`]: macro.assert.html -/// [`if`]: ../book/if.html +/// [`if`]: ../book/first-edition/if.html /// [`BitAnd`]: ops/trait.BitAnd.html /// [`BitOr`]: ops/trait.BitOr.html /// [`Not`]: ops/trait.Not.html @@ -490,7 +490,7 @@ mod prim_str { } /// assert_eq!(tuple.2, 'c'); /// ``` /// -/// For more about tuples, see [the book](../book/primitive-types.html#tuples). +/// For more about tuples, see [the book](../book/first-edition/primitive-types.html#tuples). /// /// # Trait implementations /// -- cgit 1.4.1-3-g733a5 From 13c818fa27e4dd3994881fb2f45c2dea3d23363d Mon Sep 17 00:00:00 2001 From: projektir Date: Tue, 11 Apr 2017 22:29:42 -0400 Subject: Updating docs for std::sync::Weak #29377 --- src/liballoc/arc.rs | 66 ++++++++++++++++++++++++++--------------------------- 1 file changed, 33 insertions(+), 33 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 28f6d97756f..182a107e3f7 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -165,18 +165,29 @@ unsafe impl Sync for Arc {} #[unstable(feature = "coerce_unsized", issue = "27732")] impl, U: ?Sized> CoerceUnsized> for Arc {} -/// A weak version of [`Arc`][arc]. +/// `Weak` is a version of [`Arc`] that holds a non-owning reference to the +/// managed value. The value is accessed by calling [`upgrade`] on the `Weak` +/// pointer, which returns an [`Option`]`<`[`Arc`]`>`. /// -/// `Weak` pointers do not count towards determining if the inner value -/// should be dropped. +/// Since a `Weak` reference does not count towards ownership, it will not +/// prevent the inner value from being dropped, and `Weak` itself makes no +/// guarantees about the value still being present and may return [`None`] +/// when [`upgrade`]d. /// -/// The typical way to obtain a `Weak` pointer is to call -/// [`Arc::downgrade`][downgrade]. +/// A `Weak` pointer is useful for keeping a temporary reference to the value +/// within [`Arc`] without extending its lifetime. It is also used to prevent +/// circular references between [`Arc`] pointers, since mutual owning references +/// would never allow either [`Arc`] to be dropped. For example, a tree could +/// have strong [`Arc`] pointers from parent nodes to children, and `Weak` +/// pointers from children back to their parents. /// -/// See the [`Arc`][arc] documentation for more details. +/// The typical way to obtain a `Weak` pointer is to call [`Arc::downgrade`]. /// -/// [arc]: struct.Arc.html -/// [downgrade]: struct.Arc.html#method.downgrade +/// [`Arc`]: struct.Arc.html +/// [`Arc::downgrade`]: struct.Arc.html#method.downgrade +/// [`upgrade`]: struct.Weak.html#method.upgrade +/// [`Option`]: ../../std/option/enum.Option.html +/// [`None`]: ../../std/option/enum.Option.html#variant.None #[stable(feature = "arc_weak", since = "1.4.0")] pub struct Weak { ptr: Shared>, @@ -766,14 +777,11 @@ unsafe impl<#[may_dangle] T: ?Sized> Drop for Arc { } impl Weak { - /// Constructs a new `Weak`, without an accompanying instance of `T`. - /// - /// This allocates memory for `T`, but does not initialize it. Calling - /// [`upgrade`][upgrade] on the return value always gives - /// [`None`][option]. + /// Constructs a new `Weak`, allocating memory for `T` without initializing + /// it. Calling [`upgrade`] on the return value always gives [`None`]. /// - /// [upgrade]: struct.Weak.html#method.upgrade - /// [option]: ../../std/option/enum.Option.html + /// [`upgrade`]: struct.Weak.html#method.upgrade + /// [`None`]: ../../std/option/enum.Option.html#variant.None /// /// # Examples /// @@ -798,13 +806,13 @@ impl Weak { } impl Weak { - /// Upgrades the `Weak` pointer to an [`Arc`][arc], if possible. + /// Attempts to upgrade the `Weak` pointer to an [`Arc`], extending + /// the lifetime of the value if successful. /// - /// Returns [`None`][option] if the strong count has reached zero and the - /// inner value was destroyed. + /// Returns [`None`] if the value has since been dropped. /// - /// [arc]: struct.Arc.html - /// [option]: ../../std/option/enum.Option.html + /// [`Arc`]: struct.Arc.html + /// [`None`]: ../../std/option/enum.Option.html#variant.None /// /// # Examples /// @@ -865,10 +873,7 @@ impl Weak { #[stable(feature = "arc_weak", since = "1.4.0")] impl Clone for Weak { - /// Makes a clone of the `Weak` pointer. - /// - /// This creates another pointer to the same inner value, increasing the - /// weak reference count. + /// Makes a clone of the `Weak` pointer that points to the same value. /// /// # Examples /// @@ -900,14 +905,11 @@ impl Clone for Weak { #[stable(feature = "downgraded_weak", since = "1.10.0")] impl Default for Weak { - /// Constructs a new `Weak`, without an accompanying instance of `T`. + /// Constructs a new `Weak`, allocating memory for `T` without initializing + /// it. Calling [`upgrade`] on the return value always gives [`None`]. /// - /// This allocates memory for `T`, but does not initialize it. Calling - /// [`upgrade`][upgrade] on the return value always gives - /// [`None`][option]. - /// - /// [upgrade]: struct.Weak.html#method.upgrade - /// [option]: ../../std/option/enum.Option.html + /// [`upgrade`]: struct.Weak.html#method.upgrade + /// [`None`]: ../../std/option/enum.Option.html#variant.None /// /// # Examples /// @@ -926,8 +928,6 @@ impl Default for Weak { impl Drop for Weak { /// Drops the `Weak` pointer. /// - /// This will decrement the weak reference count. - /// /// # Examples /// /// ``` -- cgit 1.4.1-3-g733a5 From f84cc0c0d0ff24e4cce5d05be3afd0347eb9d012 Mon Sep 17 00:00:00 2001 From: projektir Date: Wed, 12 Apr 2017 21:33:49 -0400 Subject: Updating docs for std::rc::Rc --- src/liballoc/rc.rs | 66 +++++++++++++++++++++++++++--------------------------- 1 file changed, 33 insertions(+), 33 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 561ccaa5ef5..fed718e9be4 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -922,18 +922,29 @@ impl From for Rc { } } -/// A weak version of [`Rc`][rc]. +/// `Weak` is a version of [`Rc`] that holds a non-owning reference to the +/// managed value. The value is accessed by calling [`upgrade`] on the `Weak` +/// pointer, which returns an [`Option`]`<`[`Rc`]`>`. /// -/// `Weak` pointers do not count towards determining if the inner value -/// should be dropped. +/// Since a `Weak` reference does not count towards ownership, it will not +/// prevent the inner value from being dropped, and `Weak` itself makes no +/// guarantees about the value still being present and may return [`None`] +/// when [`upgrade`]d. /// -/// The typical way to obtain a `Weak` pointer is to call -/// [`Rc::downgrade`][downgrade]. +/// A `Weak` pointer is useful for keeping a temporary reference to the value +/// within [`Rc`] without extending its lifetime. It is also used to prevent +/// circular references between [`Rc`] pointers, since mutual owning references +/// would never allow either [`Arc`] to be dropped. For example, a tree could +/// have strong [`Rc`] pointers from parent nodes to children, and `Weak` +/// pointers from children back to their parents. /// -/// See the [module-level documentation](./index.html) for more details. +/// The typical way to obtain a `Weak` pointer is to call [`Rc::downgrade`]. /// -/// [rc]: struct.Rc.html -/// [downgrade]: struct.Rc.html#method.downgrade +/// [`Rc`]: struct.Rc.html +/// [`Rc::downgrade`]: struct.Rc.html#method.downgrade +/// [`upgrade`]: struct.Weak.html#method.upgrade +/// [`Option`]: ../../std/option/enum.Option.html +/// [`None`]: ../../std/option/enum.Option.html#variant.None #[stable(feature = "rc_weak", since = "1.4.0")] pub struct Weak { ptr: Shared>, @@ -948,14 +959,11 @@ impl !marker::Sync for Weak {} impl, U: ?Sized> CoerceUnsized> for Weak {} impl Weak { - /// Constructs a new `Weak`, without an accompanying instance of `T`. - /// - /// This allocates memory for `T`, but does not initialize it. Calling - /// [`upgrade`][upgrade] on the return value always gives - /// [`None`][option]. + /// Constructs a new `Weak`, allocating memory for `T` without initializing + /// it. Calling [`upgrade`] on the return value always gives [`None`]. /// - /// [upgrade]: struct.Weak.html#method.upgrade - /// [option]: ../../std/option/enum.Option.html + /// [`upgrade`]: struct.Weak.html#method.upgrade + /// [`None`]: ../../std/option/enum.Option.html /// /// # Examples /// @@ -980,13 +988,13 @@ impl Weak { } impl Weak { - /// Upgrades the `Weak` pointer to an [`Rc`][rc], if possible. + /// Attempts to upgrade the `Weak` pointer to an [`Rc`], extending + /// the lifetime of the value if successful. /// - /// Returns [`None`][option] if the strong count has reached zero and the - /// inner value was destroyed. + /// Returns [`None`] if the value has since been dropped. /// - /// [rc]: struct.Rc.html - /// [option]: ../../std/option/enum.Option.html + /// [`Rc`]: struct.Rc.html + /// [`None`]: ../../std/option/enum.Option.html /// /// # Examples /// @@ -1021,8 +1029,6 @@ impl Weak { impl Drop for Weak { /// Drops the `Weak` pointer. /// - /// This will decrement the weak reference count. - /// /// # Examples /// /// ``` @@ -1061,10 +1067,7 @@ impl Drop for Weak { #[stable(feature = "rc_weak", since = "1.4.0")] impl Clone for Weak { - /// Makes a clone of the `Weak` pointer. - /// - /// This creates another pointer to the same inner value, increasing the - /// weak reference count. + /// Makes a clone of the `Weak` pointer that points to the same value. /// /// # Examples /// @@ -1091,14 +1094,11 @@ impl fmt::Debug for Weak { #[stable(feature = "downgraded_weak", since = "1.10.0")] impl Default for Weak { - /// Constructs a new `Weak`, without an accompanying instance of `T`. - /// - /// This allocates memory for `T`, but does not initialize it. Calling - /// [`upgrade`][upgrade] on the return value always gives - /// [`None`][option]. + /// Constructs a new `Weak`, allocating memory for `T` without initializing + /// it. Calling [`upgrade`] on the return value always gives [`None`]. /// - /// [upgrade]: struct.Weak.html#method.upgrade - /// [option]: ../../std/option/enum.Option.html + /// [`upgrade`]: struct.Weak.html#method.upgrade + /// [`None`]: ../../std/option/enum.Option.html /// /// # Examples /// -- cgit 1.4.1-3-g733a5 From 675475c4d3e3b1ebff5b761570f4a3f9a0ca23df Mon Sep 17 00:00:00 2001 From: Matt Brubeck Date: Thu, 9 Mar 2017 17:53:01 -0800 Subject: Specialize Vec::from_elem to use calloc or memset Fixes #38723. --- src/doc/unstable-book/src/allocator.md | 5 ++++ src/liballoc/heap.rs | 34 +++++++++++++++++++++++++ src/liballoc/raw_vec.rs | 17 ++++++++++++- src/liballoc_jemalloc/lib.rs | 21 ++++++++++++++++ src/liballoc_system/lib.rs | 34 ++++++++++++++++++++++--- src/libcollections/vec.rs | 35 +++++++++++++++++++++++--- src/test/run-pass/auxiliary/allocator-dummy.rs | 5 ++++ 7 files changed, 144 insertions(+), 7 deletions(-) (limited to 'src/liballoc') diff --git a/src/doc/unstable-book/src/allocator.md b/src/doc/unstable-book/src/allocator.md index 7261641698f..cfcf8e22d70 100644 --- a/src/doc/unstable-book/src/allocator.md +++ b/src/doc/unstable-book/src/allocator.md @@ -51,6 +51,11 @@ pub extern fn __rust_allocate(size: usize, _align: usize) -> *mut u8 { unsafe { libc::malloc(size as libc::size_t) as *mut u8 } } +#[no_mangle] +pub extern fn __rust_allocate_zeroed(size: usize, _align: usize) -> *mut u8 { + unsafe { libc::calloc(size as libc::size_t, 1) as *mut u8 } +} + #[no_mangle] pub extern fn __rust_deallocate(ptr: *mut u8, _old_size: usize, _align: usize) { unsafe { libc::free(ptr as *mut libc::c_void) } diff --git a/src/liballoc/heap.rs b/src/liballoc/heap.rs index 51e6f2f8bd7..08a0b2a6d00 100644 --- a/src/liballoc/heap.rs +++ b/src/liballoc/heap.rs @@ -23,6 +23,7 @@ use core::intrinsics::{min_align_of_val, size_of_val}; extern "C" { #[allocator] fn __rust_allocate(size: usize, align: usize) -> *mut u8; + fn __rust_allocate_zeroed(size: usize, align: usize) -> *mut u8; fn __rust_deallocate(ptr: *mut u8, old_size: usize, align: usize); fn __rust_reallocate(ptr: *mut u8, old_size: usize, size: usize, align: usize) -> *mut u8; fn __rust_reallocate_inplace(ptr: *mut u8, @@ -59,6 +60,20 @@ pub unsafe fn allocate(size: usize, align: usize) -> *mut u8 { __rust_allocate(size, align) } +/// Return a pointer to `size` bytes of memory aligned to `align` and +/// initialized to zeroes. +/// +/// On failure, return a null pointer. +/// +/// Behavior is undefined if the requested size is 0 or the alignment is not a +/// power of 2. The alignment must be no larger than the largest supported page +/// size on the platform. +#[inline] +pub unsafe fn allocate_zeroed(size: usize, align: usize) -> *mut u8 { + check_size_and_alignment(size, align); + __rust_allocate_zeroed(size, align) +} + /// Resize the allocation referenced by `ptr` to `size` bytes. /// /// On failure, return a null pointer and leave the original allocation intact. @@ -162,6 +177,25 @@ mod tests { use boxed::Box; use heap; + #[test] + fn allocate_zeroed() { + unsafe { + let size = 1024; + let ptr = heap::allocate_zeroed(size, 1); + if ptr.is_null() { + ::oom() + } + + let end = ptr.offset(size as isize); + let mut i = ptr; + while i < end { + assert_eq!(*i, 0); + i = i.offset(1); + } + heap::deallocate(ptr, size, 1); + } + } + #[test] fn basic_reallocate_inplace_noop() { unsafe { diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs index 357a2724e00..6a53d3a9ca5 100644 --- a/src/liballoc/raw_vec.rs +++ b/src/liballoc/raw_vec.rs @@ -81,7 +81,18 @@ impl RawVec { /// # Aborts /// /// Aborts on OOM + #[inline] pub fn with_capacity(cap: usize) -> Self { + RawVec::allocate(cap, false) + } + + /// Like `with_capacity` but guarantees the buffer is zeroed. + #[inline] + pub fn with_capacity_zeroed(cap: usize) -> Self { + RawVec::allocate(cap, true) + } + + fn allocate(cap: usize, zeroed: bool) -> Self { unsafe { let elem_size = mem::size_of::(); @@ -93,7 +104,11 @@ impl RawVec { heap::EMPTY as *mut u8 } else { let align = mem::align_of::(); - let ptr = heap::allocate(alloc_size, align); + let ptr = if zeroed { + heap::allocate_zeroed(alloc_size, align) + } else { + heap::allocate(alloc_size, align) + }; if ptr.is_null() { oom() } diff --git a/src/liballoc_jemalloc/lib.rs b/src/liballoc_jemalloc/lib.rs index 83cc1ef09c2..288531cb5b2 100644 --- a/src/liballoc_jemalloc/lib.rs +++ b/src/liballoc_jemalloc/lib.rs @@ -38,6 +38,10 @@ mod imp { target_os = "dragonfly", target_os = "windows", target_env = "musl"), link_name = "je_mallocx")] fn mallocx(size: size_t, flags: c_int) -> *mut c_void; + #[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios", + target_os = "dragonfly", target_os = "windows", target_env = "musl"), + link_name = "je_calloc")] + fn calloc(size: size_t, flags: c_int) -> *mut c_void; #[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios", target_os = "dragonfly", target_os = "windows", target_env = "musl"), link_name = "je_rallocx")] @@ -56,6 +60,8 @@ mod imp { fn nallocx(size: size_t, flags: c_int) -> size_t; } + const MALLOCX_ZERO: c_int = 0x40; + // The minimum alignment guaranteed by the architecture. This value is used to // add fast paths for low alignment values. In practice, the alignment is a // constant at the call site and the branch will be optimized out. @@ -91,6 +97,16 @@ mod imp { unsafe { mallocx(size as size_t, flags) as *mut u8 } } + #[no_mangle] + pub extern "C" fn __rust_allocate_zeroed(size: usize, align: usize) -> *mut u8 { + if align <= MIN_ALIGN { + unsafe { calloc(size as size_t, 1) as *mut u8 } + } else { + let flags = align_to_flags(align) | MALLOCX_ZERO; + unsafe { mallocx(size as size_t, flags) as *mut u8 } + } + } + #[no_mangle] pub extern "C" fn __rust_reallocate(ptr: *mut u8, _old_size: usize, @@ -135,6 +151,11 @@ mod imp { bogus() } + #[no_mangle] + pub extern "C" fn __rust_allocate_zeroed(_size: usize, _align: usize) -> *mut u8 { + bogus() + } + #[no_mangle] pub extern "C" fn __rust_reallocate(_ptr: *mut u8, _old_size: usize, diff --git a/src/liballoc_system/lib.rs b/src/liballoc_system/lib.rs index de2b75f62b6..6d47c2ff28f 100644 --- a/src/liballoc_system/lib.rs +++ b/src/liballoc_system/lib.rs @@ -44,6 +44,11 @@ pub extern "C" fn __rust_allocate(size: usize, align: usize) -> *mut u8 { unsafe { imp::allocate(size, align) } } +#[no_mangle] +pub extern "C" fn __rust_allocate_zeroed(size: usize, align: usize) -> *mut u8 { + unsafe { imp::allocate_zeroed(size, align) } +} + #[no_mangle] pub extern "C" fn __rust_deallocate(ptr: *mut u8, old_size: usize, align: usize) { unsafe { imp::deallocate(ptr, old_size, align) } @@ -121,6 +126,18 @@ mod imp { } } + pub unsafe fn allocate_zeroed(size: usize, align: usize) -> *mut u8 { + if align <= MIN_ALIGN { + libc::calloc(size as libc::size_t, 1) as *mut u8 + } else { + let ptr = aligned_malloc(size, align); + if !ptr.is_null() { + ptr::write_bytes(ptr, 0, size); + } + ptr + } + } + pub unsafe fn reallocate(ptr: *mut u8, old_size: usize, size: usize, align: usize) -> *mut u8 { if align <= MIN_ALIGN { libc::realloc(ptr as *mut libc::c_void, size as libc::size_t) as *mut u8 @@ -173,6 +190,8 @@ mod imp { #[repr(C)] struct Header(*mut u8); + + const HEAP_ZERO_MEMORY: DWORD = 0x00000008; const HEAP_REALLOC_IN_PLACE_ONLY: DWORD = 0x00000010; unsafe fn get_header<'a>(ptr: *mut u8) -> &'a mut Header { @@ -185,11 +204,12 @@ mod imp { aligned } - pub unsafe fn allocate(size: usize, align: usize) -> *mut u8 { + #[inline] + unsafe fn allocate_with_flags(size: usize, align: usize, flags: DWORD) -> *mut u8 { if align <= MIN_ALIGN { - HeapAlloc(GetProcessHeap(), 0, size as SIZE_T) as *mut u8 + HeapAlloc(GetProcessHeap(), flags, size as SIZE_T) as *mut u8 } else { - let ptr = HeapAlloc(GetProcessHeap(), 0, (size + align) as SIZE_T) as *mut u8; + let ptr = HeapAlloc(GetProcessHeap(), flags, (size + align) as SIZE_T) as *mut u8; if ptr.is_null() { return ptr; } @@ -197,6 +217,14 @@ mod imp { } } + pub unsafe fn allocate(size: usize, align: usize) -> *mut u8 { + allocate_with_flags(size, align, 0) + } + + pub unsafe fn allocate_zeroed(size: usize, align: usize) -> *mut u8 { + allocate_with_flags(size, align, HEAP_ZERO_MEMORY) + } + pub unsafe fn reallocate(ptr: *mut u8, _old_size: usize, size: usize, align: usize) -> *mut u8 { if align <= MIN_ALIGN { HeapReAlloc(GetProcessHeap(), 0, ptr as LPVOID, size as SIZE_T) as *mut u8 diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 8824185d280..f488e36c077 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -1370,9 +1370,38 @@ impl Vec { #[doc(hidden)] #[stable(feature = "rust1", since = "1.0.0")] pub fn from_elem(elem: T, n: usize) -> Vec { - let mut v = Vec::with_capacity(n); - v.extend_with_element(n, elem); - v + ::from_elem(elem, n) +} + +// Specialization trait used for Vec::from_elem +trait SpecFromElem: Sized { + fn from_elem(elem: Self, n: usize) -> Vec; +} + +impl SpecFromElem for T { + default fn from_elem(elem: Self, n: usize) -> Vec { + let mut v = Vec::with_capacity(n); + v.extend_with_element(n, elem); + v + } +} + +impl SpecFromElem for u8 { + #[inline] + fn from_elem(elem: u8, n: usize) -> Vec { + if elem == 0 { + return Vec { + buf: RawVec::with_capacity_zeroed(n), + len: n, + } + } + unsafe { + let mut v = Vec::with_capacity(n); + ptr::write_bytes(v.as_mut_ptr(), elem, n); + v.set_len(n); + v + } + } } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/test/run-pass/auxiliary/allocator-dummy.rs b/src/test/run-pass/auxiliary/allocator-dummy.rs index a1d21db8f4d..1133ace275b 100644 --- a/src/test/run-pass/auxiliary/allocator-dummy.rs +++ b/src/test/run-pass/auxiliary/allocator-dummy.rs @@ -27,6 +27,11 @@ pub extern fn __rust_allocate(size: usize, align: usize) -> *mut u8 { } } +#[no_mangle] +pub extern fn __rust_allocate_zeroed(size: usize, _align: usize) -> *mut u8 { + unsafe { libc::calloc(size as libc::size_t, 1) as *mut u8 } +} + #[no_mangle] pub extern fn __rust_deallocate(ptr: *mut u8, old_size: usize, align: usize) { unsafe { -- cgit 1.4.1-3-g733a5 From f4aaae9bdbca695d8d60feaa63cb09cf06598d50 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Thu, 20 Apr 2017 13:55:38 -0700 Subject: Remove Rc::would_wrap [unstable, deprecated since 1.15.0] --- src/doc/unstable-book/src/SUMMARY.md | 1 - .../unstable-book/src/library-features/rc-would-unwrap.md | 5 ----- src/liballoc/rc.rs | 13 ------------- 3 files changed, 19 deletions(-) delete mode 100644 src/doc/unstable-book/src/library-features/rc-would-unwrap.md (limited to 'src/liballoc') diff --git a/src/doc/unstable-book/src/SUMMARY.md b/src/doc/unstable-book/src/SUMMARY.md index 0d5aa4b5c42..cc03ac4d244 100644 --- a/src/doc/unstable-book/src/SUMMARY.md +++ b/src/doc/unstable-book/src/SUMMARY.md @@ -185,7 +185,6 @@ - [rand](library-features/rand.md) - [range_contains](library-features/range-contains.md) - [raw](library-features/raw.md) - - [rc_would_unwrap](library-features/rc-would-unwrap.md) - [retain_hash_collection](library-features/retain-hash-collection.md) - [reverse_cmp_key](library-features/reverse-cmp-key.md) - [rt](library-features/rt.md) diff --git a/src/doc/unstable-book/src/library-features/rc-would-unwrap.md b/src/doc/unstable-book/src/library-features/rc-would-unwrap.md deleted file mode 100644 index 462387dfdcc..00000000000 --- a/src/doc/unstable-book/src/library-features/rc-would-unwrap.md +++ /dev/null @@ -1,5 +0,0 @@ -# `rc_would_unwrap` - -The tracking issue for this feature is: [#28356] - -[#28356]: https://github.com/rust-lang/rust/issues/28356 diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index fed718e9be4..dab6cf011bd 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -341,19 +341,6 @@ impl Rc { } } - /// Checks whether [`Rc::try_unwrap`][try_unwrap] would return - /// [`Ok`]. - /// - /// [try_unwrap]: struct.Rc.html#method.try_unwrap - /// [`Ok`]: ../../std/result/enum.Result.html#variant.Ok - #[unstable(feature = "rc_would_unwrap", - reason = "just added for niche usecase", - issue = "28356")] - #[rustc_deprecated(since = "1.15.0", reason = "too niche; use `strong_count` instead")] - pub fn would_unwrap(this: &Self) -> bool { - Rc::strong_count(&this) == 1 - } - /// Consumes the `Rc`, returning the wrapped pointer. /// /// To avoid a memory leak the pointer must be converted back to an `Rc` using -- cgit 1.4.1-3-g733a5 From f0c5e8b8fc6d3631de39cfc250868da993ff4086 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Thu, 20 Apr 2017 14:02:20 -0700 Subject: Privatize Rc::is_unique [unstable, deprecated since 1.15.0] --- src/doc/unstable-book/src/SUMMARY.md | 1 - src/doc/unstable-book/src/library-features/is-unique.md | 7 ------- src/liballoc/rc.rs | 6 +----- 3 files changed, 1 insertion(+), 13 deletions(-) delete mode 100644 src/doc/unstable-book/src/library-features/is-unique.md (limited to 'src/liballoc') diff --git a/src/doc/unstable-book/src/SUMMARY.md b/src/doc/unstable-book/src/SUMMARY.md index cc03ac4d244..0362ed6ba9d 100644 --- a/src/doc/unstable-book/src/SUMMARY.md +++ b/src/doc/unstable-book/src/SUMMARY.md @@ -155,7 +155,6 @@ - [io_error_internals](library-features/io-error-internals.md) - [io](library-features/io.md) - [ip](library-features/ip.md) - - [is_unique](library-features/is-unique.md) - [iter_rfind](library-features/iter-rfind.md) - [libstd_io_internals](library-features/libstd-io-internals.md) - [libstd_sys_internals](library-features/libstd-sys-internals.md) diff --git a/src/doc/unstable-book/src/library-features/is-unique.md b/src/doc/unstable-book/src/library-features/is-unique.md deleted file mode 100644 index 6070006758b..00000000000 --- a/src/doc/unstable-book/src/library-features/is-unique.md +++ /dev/null @@ -1,7 +0,0 @@ -# `is_unique` - -The tracking issue for this feature is: [#28356] - -[#28356]: https://github.com/rust-lang/rust/issues/28356 - ------------------------- diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index dab6cf011bd..b12d89867c8 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -488,11 +488,7 @@ impl Rc { /// /// [weak]: struct.Weak.html #[inline] - #[unstable(feature = "is_unique", reason = "uniqueness has unclear meaning", - issue = "28356")] - #[rustc_deprecated(since = "1.15.0", - reason = "too niche; use `strong_count` and `weak_count` instead")] - pub fn is_unique(this: &Self) -> bool { + fn is_unique(this: &Self) -> bool { Rc::weak_count(this) == 0 && Rc::strong_count(this) == 1 } -- cgit 1.4.1-3-g733a5 From ece6c8434bc4eba1d3addfa4d5900264e55395fc Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Thu, 20 Apr 2017 15:08:41 +0300 Subject: cache attributes of items from foreign crates this avoids parsing item attributes on each call to `item_attrs`, which takes off 33% (!) of translation time and 50% (!) of trans-item collection time. --- src/liballoc/heap.rs | 6 ++---- src/liballoc/lib.rs | 1 + src/liballoc/rc.rs | 35 +++++++++++++++++++++++++++++++++-- src/librustc/middle/cstore.rs | 4 ++-- src/librustc/ty/instance.rs | 5 +---- src/librustc/ty/mod.rs | 24 ++++++++++++++++++++---- src/librustc_driver/driver.rs | 2 ++ src/librustc_metadata/creader.rs | 1 + src/librustc_metadata/cstore.rs | 3 ++- src/librustc_metadata/cstore_impl.rs | 6 +++--- src/librustc_metadata/decoder.rs | 21 ++++++++++++++++++--- 11 files changed, 85 insertions(+), 23 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/heap.rs b/src/liballoc/heap.rs index 08a0b2a6d00..056af13016c 100644 --- a/src/liballoc/heap.rs +++ b/src/liballoc/heap.rs @@ -16,7 +16,6 @@ issue = "27700")] use core::{isize, usize}; -#[cfg(not(test))] use core::intrinsics::{min_align_of_val, size_of_val}; #[allow(improper_ctypes)] @@ -158,10 +157,9 @@ unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 { } } -#[cfg(not(test))] -#[lang = "box_free"] +#[cfg_attr(not(test), lang = "box_free")] #[inline] -unsafe fn box_free(ptr: *mut T) { +pub(crate) unsafe fn box_free(ptr: *mut T) { let size = size_of_val(&*ptr); let align = min_align_of_val(&*ptr); // We do not allocate for Box when T is ZST, so deallocation is also not necessary. diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 0c01eabd593..c70d82392f9 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -87,6 +87,7 @@ #![feature(needs_allocator)] #![feature(optin_builtin_traits)] #![feature(placement_in_syntax)] +#![cfg_attr(stage0, feature(pub_restricted))] #![feature(shared)] #![feature(staged_api)] #![feature(unboxed_closures)] diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index fed718e9be4..69e5351cad5 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -239,7 +239,7 @@ use core::ops::CoerceUnsized; use core::ptr::{self, Shared}; use core::convert::From; -use heap::deallocate; +use heap::{allocate, deallocate, box_free}; use raw_vec::RawVec; struct RcBox { @@ -248,7 +248,6 @@ struct RcBox { value: T, } - /// A single-threaded reference-counting pointer. /// /// See the [module-level documentation](./index.html) for more details. @@ -438,6 +437,38 @@ impl Rc { } } +impl Rc<[T]> { + /// Constructs a new `Rc<[T]>` from a `Box<[T]>`. + #[doc(hidden)] + #[unstable(feature = "rustc_private", + reason = "for internal use in rustc", + issue = "0")] + pub fn __from_array(value: Box<[T]>) -> Rc<[T]> { + unsafe { + let ptr: *mut RcBox<[T]> = + mem::transmute([mem::align_of::>(), value.len()]); + // FIXME(custom-DST): creating this invalid &[T] is dubiously defined, + // we should have a better way of getting the size/align + // of a DST from its unsized part. + let ptr = allocate(size_of_val(&*ptr), align_of_val(&*ptr)); + let ptr: *mut RcBox<[T]> = mem::transmute([ptr as usize, value.len()]); + + // Initialize the new RcBox. + ptr::write(&mut (*ptr).strong, Cell::new(1)); + ptr::write(&mut (*ptr).weak, Cell::new(1)); + ptr::copy_nonoverlapping( + value.as_ptr(), + &mut (*ptr).value as *mut [T] as *mut T, + value.len()); + + // Free the original allocation without freeing its (moved) contents. + box_free(Box::into_raw(value)); + + Rc { ptr: Shared::new(ptr as *const _) } + } + } +} + impl Rc { /// Creates a new [`Weak`][weak] pointer to this value. /// diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index cbbfeacadb4..16b31bdb074 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -188,7 +188,7 @@ pub trait CrateStore { fn visibility(&self, def: DefId) -> ty::Visibility; fn visible_parent_map<'a>(&'a self) -> ::std::cell::Ref<'a, DefIdMap>; fn item_generics_cloned(&self, def: DefId) -> ty::Generics; - fn item_attrs(&self, def_id: DefId) -> Vec; + fn item_attrs(&self, def_id: DefId) -> Rc<[ast::Attribute]>; fn fn_arg_names(&self, did: DefId) -> Vec; // trait info @@ -323,7 +323,7 @@ impl CrateStore for DummyCrateStore { } fn item_generics_cloned(&self, def: DefId) -> ty::Generics { bug!("item_generics_cloned") } - fn item_attrs(&self, def_id: DefId) -> Vec { bug!("item_attrs") } + fn item_attrs(&self, def_id: DefId) -> Rc<[ast::Attribute]> { bug!("item_attrs") } fn fn_arg_names(&self, did: DefId) -> Vec { bug!("fn_arg_names") } // trait info diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index 67287f1b4ff..cfff3d0e573 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -13,10 +13,7 @@ use hir::def_id::DefId; use ty::{self, Ty, TypeFoldable, Substs}; use util::ppaux; -use std::borrow::Cow; use std::fmt; -use syntax::ast; - #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub struct Instance<'tcx> { @@ -59,7 +56,7 @@ impl<'tcx> InstanceDef<'tcx> { } #[inline] - pub fn attrs<'a>(&self, tcx: ty::TyCtxt<'a, 'tcx, 'tcx>) -> Cow<'tcx, [ast::Attribute]> { + pub fn attrs<'a>(&self, tcx: ty::TyCtxt<'a, 'tcx, 'tcx>) -> ty::Attributes<'tcx> { tcx.get_attrs(self.def_id()) } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index e355b69d6e6..7aa12429e5d 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -34,7 +34,6 @@ use ty::walk::TypeWalker; use util::nodemap::{NodeSet, DefIdMap, FxHashMap}; use serialize::{self, Encodable, Encoder}; -use std::borrow::Cow; use std::cell::{Cell, RefCell, Ref}; use std::collections::BTreeMap; use std::cmp; @@ -2036,6 +2035,23 @@ impl BorrowKind { } } +#[derive(Debug, Clone)] +pub enum Attributes<'gcx> { + Owned(Rc<[ast::Attribute]>), + Borrowed(&'gcx [ast::Attribute]) +} + +impl<'gcx> ::std::ops::Deref for Attributes<'gcx> { + type Target = [ast::Attribute]; + + fn deref(&self) -> &[ast::Attribute] { + match self { + &Attributes::Owned(ref data) => &data, + &Attributes::Borrowed(data) => data + } + } +} + impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn body_tables(self, body: hir::BodyId) -> &'gcx TypeckTables<'gcx> { self.item_tables(self.hir.body_owner_def_id(body)) @@ -2389,11 +2405,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } /// Get the attributes of a definition. - pub fn get_attrs(self, did: DefId) -> Cow<'gcx, [ast::Attribute]> { + pub fn get_attrs(self, did: DefId) -> Attributes<'gcx> { if let Some(id) = self.hir.as_local_node_id(did) { - Cow::Borrowed(self.hir.attrs(id)) + Attributes::Borrowed(self.hir.attrs(id)) } else { - Cow::Owned(self.sess.cstore.item_attrs(did)) + Attributes::Owned(self.sess.cstore.item_attrs(did)) } } diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index ac4e2bd5c10..438f482fa55 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -225,6 +225,8 @@ pub fn compile_input(sess: &Session, sess.code_stats.borrow().print_type_sizes(); } + if ::std::env::var("SKIP_LLVM").is_ok() { ::std::process::exit(0); } + let phase5_result = phase_5_run_llvm_passes(sess, &trans, &outputs); controller_entry_point!(after_llvm, diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index a8ee999505e..7bc0e8a512b 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -326,6 +326,7 @@ impl<'a> CrateLoader<'a> { cnum_map: RefCell::new(cnum_map), cnum: cnum, codemap_import_info: RefCell::new(vec![]), + attribute_cache: RefCell::new([Vec::new(), Vec::new()]), dep_kind: Cell::new(dep_kind), source: cstore::CrateSource { dylib: dylib, diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index 17a6a706e0a..72ad1d75a56 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -72,6 +72,7 @@ pub struct CrateMetadata { pub cnum_map: RefCell, pub cnum: CrateNum, pub codemap_import_info: RefCell>, + pub attribute_cache: RefCell<[Vec>>; 2]>, pub root: schema::CrateRoot, @@ -269,7 +270,7 @@ impl CrateMetadata { } pub fn is_staged_api(&self) -> bool { - for attr in self.get_item_attrs(CRATE_DEF_INDEX) { + for attr in self.get_item_attrs(CRATE_DEF_INDEX).iter() { if attr.path == "stable" || attr.path == "unstable" { return true; } diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 3cff063a8f5..e02c61f3646 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -149,7 +149,7 @@ impl CrateStore for cstore::CStore { self.get_crate_data(def.krate).get_generics(def.index) } - fn item_attrs(&self, def_id: DefId) -> Vec + fn item_attrs(&self, def_id: DefId) -> Rc<[ast::Attribute]> { self.dep_graph.read(DepNode::MetaData(def_id)); self.get_crate_data(def_id.krate).get_item_attrs(def_id.index) @@ -406,7 +406,7 @@ impl CrateStore for cstore::CStore { // Mark the attrs as used let attrs = data.get_item_attrs(id.index); - for attr in &attrs { + for attr in attrs.iter() { attr::mark_used(attr); } @@ -419,7 +419,7 @@ impl CrateStore for cstore::CStore { ident: ast::Ident::with_empty_ctxt(name), id: ast::DUMMY_NODE_ID, span: local_span, - attrs: attrs, + attrs: attrs.iter().cloned().collect(), node: ast::ItemKind::MacroDef(body.into()), vis: ast::Visibility::Inherited, }) diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index fac6079529e..2d562aceb65 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -31,6 +31,7 @@ use std::cell::Ref; use std::collections::BTreeMap; use std::io; use std::mem; +use std::rc::Rc; use std::str; use std::u32; @@ -859,10 +860,18 @@ impl<'a, 'tcx> CrateMetadata { } } - pub fn get_item_attrs(&self, node_id: DefIndex) -> Vec { + pub fn get_item_attrs(&self, node_id: DefIndex) -> Rc<[ast::Attribute]> { + let (node_as, node_index) = + (node_id.address_space().index(), node_id.as_array_index()); if self.is_proc_macro(node_id) { - return Vec::new(); + return Rc::new([]); } + + if let Some(&Some(ref val)) = + self.attribute_cache.borrow()[node_as].get(node_index) { + return val.clone(); + } + // The attributes for a tuple struct are attached to the definition, not the ctor; // we assume that someone passing in a tuple struct ctor is actually wanting to // look at the definition @@ -871,7 +880,13 @@ impl<'a, 'tcx> CrateMetadata { if def_key.disambiguated_data.data == DefPathData::StructCtor { item = self.entry(def_key.parent.unwrap()); } - self.get_attributes(&item) + let result = Rc::__from_array(self.get_attributes(&item).into_boxed_slice()); + let vec_ = &mut self.attribute_cache.borrow_mut()[node_as]; + if vec_.len() < node_index + 1 { + vec_.resize(node_index + 1, None); + } + vec_[node_index] = Some(result.clone()); + result } pub fn get_struct_field_names(&self, id: DefIndex) -> Vec { -- cgit 1.4.1-3-g733a5 From c66c6e96978cd81130587e9f4d1fa52dc1b183d6 Mon Sep 17 00:00:00 2001 From: Clar Charr Date: Tue, 11 Apr 2017 16:02:43 -0400 Subject: More methods for str boxes. --- src/doc/unstable-book/src/SUMMARY.md | 1 + .../src/library-features/str-box-extras.md | 9 +++++++++ src/liballoc/boxed.rs | 18 +++++++++++++----- src/liballoc/lib.rs | 2 ++ src/liballoc/str.rs | 21 +++++++++++++++++++++ src/libcollections/lib.rs | 1 + src/libcollections/str.rs | 11 ++++++++++- src/libcollections/string.rs | 5 +++-- 8 files changed, 60 insertions(+), 8 deletions(-) create mode 100644 src/doc/unstable-book/src/library-features/str-box-extras.md create mode 100644 src/liballoc/str.rs (limited to 'src/liballoc') diff --git a/src/doc/unstable-book/src/SUMMARY.md b/src/doc/unstable-book/src/SUMMARY.md index 3e041543977..76196173b11 100644 --- a/src/doc/unstable-book/src/SUMMARY.md +++ b/src/doc/unstable-book/src/SUMMARY.md @@ -207,6 +207,7 @@ - [str_checked_slicing](library-features/str-checked-slicing.md) - [str_escape](library-features/str-escape.md) - [str_internals](library-features/str-internals.md) + - [str_box_extras](library-features/str-box-extras.md) - [str_mut_extras](library-features/str-mut-extras.md) - [test](library-features/test.md) - [thread_id](library-features/thread-id.md) diff --git a/src/doc/unstable-book/src/library-features/str-box-extras.md b/src/doc/unstable-book/src/library-features/str-box-extras.md new file mode 100644 index 00000000000..d05dcafa84d --- /dev/null +++ b/src/doc/unstable-book/src/library-features/str-box-extras.md @@ -0,0 +1,9 @@ +# `str_box_extras` + +The tracking issue for this feature is: [#str_box_extras] + +[#str_box_extras]: https://github.com/rust-lang/rust/issues/41119 + +------------------------ + + diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 43b0d72186a..b03e3bb7a4b 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -68,6 +68,7 @@ use core::ops::{CoerceUnsized, Deref, DerefMut}; use core::ops::{BoxPlace, Boxed, InPlace, Place, Placer}; use core::ptr::{self, Unique}; use core::convert::From; +use str::from_boxed_utf8_unchecked; /// A value that represents the heap. This is the default place that the `box` /// keyword allocates into when no place is supplied. @@ -320,8 +321,7 @@ impl Default for Box<[T]> { #[stable(feature = "default_box_extra", since = "1.17.0")] impl Default for Box { fn default() -> Box { - let default: Box<[u8]> = Default::default(); - unsafe { mem::transmute(default) } + unsafe { from_boxed_utf8_unchecked(Default::default()) } } } @@ -366,7 +366,7 @@ impl Clone for Box { let buf = RawVec::with_capacity(len); unsafe { ptr::copy_nonoverlapping(self.as_ptr(), buf.ptr(), len); - mem::transmute(buf.into_box()) // bytes to str ~magic + from_boxed_utf8_unchecked(buf.into_box()) } } } @@ -441,8 +441,16 @@ impl<'a, T: Copy> From<&'a [T]> for Box<[T]> { #[stable(feature = "box_from_slice", since = "1.17.0")] impl<'a> From<&'a str> for Box { fn from(s: &'a str) -> Box { - let boxed: Box<[u8]> = Box::from(s.as_bytes()); - unsafe { mem::transmute(boxed) } + unsafe { from_boxed_utf8_unchecked(Box::from(s.as_bytes())) } + } +} + +#[stable(feature = "boxed_str_conv", since = "1.18.0")] +impl From> for Box<[u8]> { + fn from(s: Box) -> Self { + unsafe { + mem::transmute(s) + } } } diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 0c01eabd593..418a084da67 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -128,6 +128,8 @@ mod boxed_test; pub mod arc; pub mod rc; pub mod raw_vec; +#[unstable(feature = "str_box_extras", issue = "41119")] +pub mod str; pub mod oom; pub use oom::oom; diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs new file mode 100644 index 00000000000..c87db16a0f4 --- /dev/null +++ b/src/liballoc/str.rs @@ -0,0 +1,21 @@ +// Copyright 2012-2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Methods for dealing with boxed strings. +use core::mem; + +use boxed::Box; + +/// Converts a boxed slice of bytes to a boxed string slice without checking +/// that the string contains valid UTF-8. +#[unstable(feature = "str_box_extras", issue = "41119")] +pub unsafe fn from_boxed_utf8_unchecked(v: Box<[u8]>) -> Box { + mem::transmute(v) +} diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index 3bea61f6220..c3db76e6c75 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -60,6 +60,7 @@ #![feature(specialization)] #![feature(staged_api)] #![feature(str_internals)] +#![feature(str_box_extras)] #![feature(str_mut_extras)] #![feature(trusted_len)] #![feature(unicode)] diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index 8168e02bf82..964660183e7 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -70,14 +70,17 @@ pub use core::str::{Matches, RMatches}; #[stable(feature = "rust1", since = "1.0.0")] pub use core::str::{MatchIndices, RMatchIndices}; #[stable(feature = "rust1", since = "1.0.0")] -pub use core::str::{from_utf8, Chars, CharIndices, Bytes}; +pub use core::str::{from_utf8, from_utf8_mut, Chars, CharIndices, Bytes}; #[stable(feature = "rust1", since = "1.0.0")] pub use core::str::{from_utf8_unchecked, from_utf8_unchecked_mut, ParseBoolError}; +#[unstable(feature = "str_box_extras", issue = "41119")] +pub use alloc::str::from_boxed_utf8_unchecked; #[stable(feature = "rust1", since = "1.0.0")] pub use std_unicode::str::SplitWhitespace; #[stable(feature = "rust1", since = "1.0.0")] pub use core::str::pattern; + #[unstable(feature = "slice_concat_ext", reason = "trait should not have to exist", issue = "27747")] @@ -1715,6 +1718,12 @@ impl str { core_str::StrExt::parse(self) } + /// Converts a `Box` into a `Box<[u8]>` without copying or allocating. + #[unstable(feature = "str_box_extras", issue = "41119")] + pub fn into_boxed_bytes(self: Box) -> Box<[u8]> { + self.into() + } + /// Replaces all matches of a pattern with another string. /// /// `replace` creates a new [`String`], and copies the data from this string slice into it. diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index 8d6cf305112..69dfb466d70 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -56,10 +56,11 @@ #![stable(feature = "rust1", since = "1.0.0")] +use alloc::str as alloc_str; + use core::fmt; use core::hash; use core::iter::{FromIterator, FusedIterator}; -use core::mem; use core::ops::{self, Add, AddAssign, Index, IndexMut}; use core::ptr; use core::str as core_str; @@ -1398,7 +1399,7 @@ impl String { #[stable(feature = "box_str", since = "1.4.0")] pub fn into_boxed_str(self) -> Box { let slice = self.vec.into_boxed_slice(); - unsafe { mem::transmute::, Box>(slice) } + unsafe { alloc_str::from_boxed_utf8_unchecked(slice) } } } -- cgit 1.4.1-3-g733a5 From 5daf557a77391f14a26038d7ab70d424cfe5b040 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 20 Apr 2017 14:32:54 -0700 Subject: Update stage0 bootstrap compiler We've got a freshly minted beta compiler, let's update to use that on nightly! This has a few other changes associated with it as well * A bump to the rustc version number (to 1.19.0) * Movement of the `cargo` and `rls` submodules to their "proper" location in `src/tools/{cargo,rls}`. Now that Cargo workspaces support the `exclude` option this can work. * Updates of the `cargo` and `rls` submodules to their master branches. * Tweak to the `src/stage0.txt` format to be more amenable for Cargo version numbers. On the beta channel Cargo will bootstrap from a different version than rustc (e.g. the version numbers are different), so we need different configuration for this. * Addition of `dev` as a readable key in the `src/stage0.txt` format. If present then stage0 compilers are downloaded from `dev-static.rust-lang.org` instead of `static.rust-lang.org`. This is added to accomodate our updated release process with Travis and AppVeyor. --- .gitmodules | 11 +++---- cargo | 1 - rls | 1 - src/Cargo.toml | 6 ++++ src/bootstrap/bootstrap.py | 44 +++++++++++++++---------- src/bootstrap/channel.rs | 2 +- src/bootstrap/check.rs | 2 +- src/bootstrap/compile.rs | 5 +-- src/bootstrap/dist.rs | 6 ++-- src/bootstrap/lib.rs | 6 ++-- src/bootstrap/step.rs | 4 +-- src/liballoc/lib.rs | 1 - src/libcore/intrinsics.rs | 24 -------------- src/libcore/marker.rs | 2 +- src/libcore/num/mod.rs | 72 ----------------------------------------- src/libcore/ptr.rs | 5 --- src/librustc/lib.rs | 1 - src/librustc_incremental/lib.rs | 1 - src/libstd/lib.rs | 1 - src/rtstartup/rsbegin.rs | 9 +++++- src/rtstartup/rsend.rs | 14 +++++++- src/stage0.txt | 30 ++++++++++++++--- src/tools/cargo | 1 + src/tools/rls | 1 + src/tools/tidy/src/main.rs | 2 ++ 25 files changed, 100 insertions(+), 152 deletions(-) delete mode 160000 cargo delete mode 160000 rls create mode 160000 src/tools/cargo create mode 160000 src/tools/rls (limited to 'src/liballoc') diff --git a/.gitmodules b/.gitmodules index 9003f0750a2..7cd896b763f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -22,15 +22,14 @@ path = src/doc/nomicon url = https://github.com/rust-lang-nursery/nomicon.git [submodule "src/tools/cargo"] - path = cargo - url = https://github.com/rust-lang/cargo.git + path = src/tools/cargo + url = https://github.com/rust-lang/cargo [submodule "reference"] path = src/doc/reference url = https://github.com/rust-lang-nursery/reference.git [submodule "book"] path = src/doc/book url = https://github.com/rust-lang/book.git -[submodule "rls"] - path = rls - url = https://github.com/rust-lang-nursery/rls.git - +[submodule "src/tools/rls"] + path = src/tools/rls + url = https://github.com/rust-lang-nursery/rls diff --git a/cargo b/cargo deleted file mode 160000 index 03efb7fc8b0..00000000000 --- a/cargo +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 03efb7fc8b0dbb54973ee1b6188f3faf14fffe36 diff --git a/rls b/rls deleted file mode 160000 index 6ecff95fdc3..00000000000 --- a/rls +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 6ecff95fdc3ee7ceed2b9b0cc1a3a64876860bce diff --git a/src/Cargo.toml b/src/Cargo.toml index 8f6150c6438..9aca3e134d6 100644 --- a/src/Cargo.toml +++ b/src/Cargo.toml @@ -15,6 +15,12 @@ members = [ "tools/remote-test-server", ] +# These projects have their own Cargo.lock +exclude = [ + "tools/cargo", + "tools/rls", +] + # Curiously, compiletest will segfault if compiled with opt-level=3 on 64-bit # MSVC when running the compile-fail test suite when a should-fail test panics. # But hey if this is removed and it gets past the bots, sounds good to me. diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index e5f8143b418..2bccdef9b0a 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -159,19 +159,20 @@ def format_build_time(duration): class RustBuild(object): def download_stage0(self): cache_dst = os.path.join(self.build_dir, "cache") - rustc_cache = os.path.join(cache_dst, self.stage0_rustc_date()) + rustc_cache = os.path.join(cache_dst, self.stage0_date()) if not os.path.exists(rustc_cache): os.makedirs(rustc_cache) - channel = self.stage0_rustc_channel() + rustc_channel = self.stage0_rustc_channel() + cargo_channel = self.stage0_cargo_channel() if self.rustc().startswith(self.bin_root()) and \ (not os.path.exists(self.rustc()) or self.rustc_out_of_date()): self.print_what_it_means_to_bootstrap() if os.path.exists(self.bin_root()): shutil.rmtree(self.bin_root()) - filename = "rust-std-{}-{}.tar.gz".format(channel, self.build) - url = "https://static.rust-lang.org/dist/" + self.stage0_rustc_date() + filename = "rust-std-{}-{}.tar.gz".format(rustc_channel, self.build) + url = self._download_url + "/dist/" + self.stage0_date() tarball = os.path.join(rustc_cache, filename) if not os.path.exists(tarball): get("{}/{}".format(url, filename), tarball, verbose=self.verbose) @@ -179,8 +180,8 @@ class RustBuild(object): match="rust-std-" + self.build, verbose=self.verbose) - filename = "rustc-{}-{}.tar.gz".format(channel, self.build) - url = "https://static.rust-lang.org/dist/" + self.stage0_rustc_date() + filename = "rustc-{}-{}.tar.gz".format(rustc_channel, self.build) + url = self._download_url + "/dist/" + self.stage0_date() tarball = os.path.join(rustc_cache, filename) if not os.path.exists(tarball): get("{}/{}".format(url, filename), tarball, verbose=self.verbose) @@ -188,11 +189,11 @@ class RustBuild(object): self.fix_executable(self.bin_root() + "/bin/rustc") self.fix_executable(self.bin_root() + "/bin/rustdoc") with open(self.rustc_stamp(), 'w') as f: - f.write(self.stage0_rustc_date()) + f.write(self.stage0_date()) if "pc-windows-gnu" in self.build: - filename = "rust-mingw-{}-{}.tar.gz".format(channel, self.build) - url = "https://static.rust-lang.org/dist/" + self.stage0_rustc_date() + filename = "rust-mingw-{}-{}.tar.gz".format(rustc_channel, self.build) + url = self._download_url + "/dist/" + self.stage0_date() tarball = os.path.join(rustc_cache, filename) if not os.path.exists(tarball): get("{}/{}".format(url, filename), tarball, verbose=self.verbose) @@ -201,15 +202,15 @@ class RustBuild(object): if self.cargo().startswith(self.bin_root()) and \ (not os.path.exists(self.cargo()) or self.cargo_out_of_date()): self.print_what_it_means_to_bootstrap() - filename = "cargo-{}-{}.tar.gz".format(channel, self.build) - url = "https://static.rust-lang.org/dist/" + self.stage0_rustc_date() + filename = "cargo-{}-{}.tar.gz".format(cargo_channel, self.build) + url = self._download_url + "/dist/" + self.stage0_date() tarball = os.path.join(rustc_cache, filename) if not os.path.exists(tarball): get("{}/{}".format(url, filename), tarball, verbose=self.verbose) unpack(tarball, self.bin_root(), match="cargo", verbose=self.verbose) self.fix_executable(self.bin_root() + "/bin/cargo") with open(self.cargo_stamp(), 'w') as f: - f.write(self.stage0_rustc_date()) + f.write(self.stage0_date()) def fix_executable(self, fname): # If we're on NixOS we need to change the path to the dynamic loader @@ -264,12 +265,15 @@ class RustBuild(object): print("warning: failed to call patchelf: %s" % e) return - def stage0_rustc_date(self): - return self._rustc_date + def stage0_date(self): + return self._date def stage0_rustc_channel(self): return self._rustc_channel + def stage0_cargo_channel(self): + return self._cargo_channel + def rustc_stamp(self): return os.path.join(self.bin_root(), '.rustc-stamp') @@ -280,13 +284,13 @@ class RustBuild(object): if not os.path.exists(self.rustc_stamp()) or self.clean: return True with open(self.rustc_stamp(), 'r') as f: - return self.stage0_rustc_date() != f.read() + return self.stage0_date() != f.read() def cargo_out_of_date(self): if not os.path.exists(self.cargo_stamp()) or self.clean: return True with open(self.cargo_stamp(), 'r') as f: - return self.stage0_rustc_date() != f.read() + return self.stage0_date() != f.read() def bin_root(self): return os.path.join(self.build_dir, self.build, "stage0") @@ -585,7 +589,13 @@ def bootstrap(): shutil.rmtree('.cargo') data = stage0_data(rb.rust_root) - rb._rustc_channel, rb._rustc_date = data['rustc'].split('-', 1) + rb._date = data['date'] + rb._rustc_channel = data['rustc'] + rb._cargo_channel = data['cargo'] + if 'dev' in data: + rb._download_url = 'https://dev-static.rust-lang.org' + else: + rb._download_url = 'https://static.rust-lang.org' # Fetch/build the bootstrap rb.build = rb.build_triple() diff --git a/src/bootstrap/channel.rs b/src/bootstrap/channel.rs index a95bdcb3d26..1b9536fba35 100644 --- a/src/bootstrap/channel.rs +++ b/src/bootstrap/channel.rs @@ -23,7 +23,7 @@ use build_helper::output; use Build; // The version number -pub const CFG_RELEASE_NUM: &'static str = "1.18.0"; +pub const CFG_RELEASE_NUM: &'static str = "1.19.0"; // An optional number to put after the label, e.g. '.2' -> '-beta.2' // Be sure to make this starts with a dot to conform to semver pre-release diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index 1bcec2cdede..4e9f5913b49 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -106,7 +106,7 @@ pub fn cargo(build: &Build, stage: u32, host: &str) { let ref newpath = format!("{}{}{}", path.display(), sep, old_path); let mut cargo = build.cargo(compiler, Mode::Tool, host, "test"); - cargo.arg("--manifest-path").arg(build.src.join("cargo/Cargo.toml")); + cargo.arg("--manifest-path").arg(build.src.join("src/tools/cargo/Cargo.toml")); // Don't build tests dynamically, just a pain to work with cargo.env("RUSTC_NO_PREFER_DYNAMIC", "1"); diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 6f1de62d07e..c810a0e05d4 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -461,10 +461,7 @@ pub fn tool(build: &Build, stage: u32, target: &str, tool: &str) { let compiler = Compiler::new(stage, &build.config.build); let mut cargo = build.cargo(&compiler, Mode::Tool, target, "build"); - let mut dir = build.src.join(tool); - if !dir.exists() { - dir = build.src.join("src/tools").join(tool); - } + let dir = build.src.join("src/tools").join(tool); cargo.arg("--manifest-path").arg(dir.join("Cargo.toml")); // We don't want to build tools dynamically as they'll be running across diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 639ba5d5b0c..5e8d0f4e0c3 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -394,8 +394,6 @@ pub fn rust_src(build: &Build) { let src_dirs = [ "man", "src", - "cargo", - "rls", ]; let filter_fn = move |path: &Path| { @@ -576,7 +574,7 @@ pub fn cargo(build: &Build, stage: u32, target: &str) { println!("Dist cargo stage{} ({})", stage, target); let compiler = Compiler::new(stage, &build.config.build); - let src = build.src.join("cargo"); + let src = build.src.join("src/tools/cargo"); let etc = src.join("src/etc"); let release_num = build.release_num("cargo"); let name = pkgname(build, "cargo"); @@ -637,7 +635,7 @@ pub fn rls(build: &Build, stage: u32, target: &str) { println!("Dist RLS stage{} ({})", stage, target); let compiler = Compiler::new(stage, &build.config.build); - let src = build.src.join("rls"); + let src = build.src.join("src/tools/rls"); let release_num = build.release_num("rls"); let name = pkgname(build, "rls"); let version = build.rls_info.version(build, &release_num); diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 2852421ad28..017d4015134 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -234,8 +234,8 @@ impl Build { None => false, }; let rust_info = channel::GitInfo::new(&src); - let cargo_info = channel::GitInfo::new(&src.join("cargo")); - let rls_info = channel::GitInfo::new(&src.join("rls")); + let cargo_info = channel::GitInfo::new(&src.join("src/tools/cargo")); + let rls_info = channel::GitInfo::new(&src.join("src/tools/rls")); let src_is_git = src.join(".git").exists(); Build { @@ -1071,7 +1071,7 @@ impl Build { /// Returns the `a.b.c` version that the given package is at. fn release_num(&self, package: &str) -> String { let mut toml = String::new(); - let toml_file_name = self.src.join(&format!("{}/Cargo.toml", package)); + let toml_file_name = self.src.join(&format!("src/tools/{}/Cargo.toml", package)); t!(t!(File::open(toml_file_name)).read_to_string(&mut toml)); for line in toml.lines() { let prefix = "version = \""; diff --git a/src/bootstrap/step.rs b/src/bootstrap/step.rs index c15e889394f..f69b68a9545 100644 --- a/src/bootstrap/step.rs +++ b/src/bootstrap/step.rs @@ -574,7 +574,7 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules { .dep(|s| s.name("maybe-clean-tools")) .dep(|s| s.name("libstd-tool")) .run(move |s| compile::tool(build, s.stage, s.target, "remote-test-client")); - rules.build("tool-cargo", "cargo") + rules.build("tool-cargo", "src/tools/cargo") .host(true) .default(build.config.extended) .dep(|s| s.name("maybe-clean-tools")) @@ -588,7 +588,7 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules { .host(&build.config.build) }) .run(move |s| compile::tool(build, s.stage, s.target, "cargo")); - rules.build("tool-rls", "rls") + rules.build("tool-rls", "src/tools/rls") .host(true) .default(build.config.extended) .dep(|s| s.name("librustc-tool")) diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index fee0e1eb260..418a084da67 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -87,7 +87,6 @@ #![feature(needs_allocator)] #![feature(optin_builtin_traits)] #![feature(placement_in_syntax)] -#![cfg_attr(stage0, feature(pub_restricted))] #![feature(shared)] #![feature(staged_api)] #![feature(unboxed_closures)] diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index b0287631585..9f1870e56d3 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -46,7 +46,6 @@ issue = "0")] #![allow(missing_docs)] -#[cfg(not(stage0))] #[stable(feature = "drop_in_place", since = "1.8.0")] #[rustc_deprecated(reason = "no longer an intrinsic - use `ptr::drop_in_place` directly", since = "1.18.0")] @@ -645,27 +644,6 @@ extern "rust-intrinsic" { pub fn size_of_val(_: &T) -> usize; pub fn min_align_of_val(_: &T) -> usize; - #[cfg(stage0)] - /// Executes the destructor (if any) of the pointed-to value. - /// - /// This has two use cases: - /// - /// * It is *required* to use `drop_in_place` to drop unsized types like - /// trait objects, because they can't be read out onto the stack and - /// dropped normally. - /// - /// * It is friendlier to the optimizer to do this over `ptr::read` when - /// dropping manually allocated memory (e.g. when writing Box/Rc/Vec), - /// as the compiler doesn't need to prove that it's sound to elide the - /// copy. - /// - /// # Undefined Behavior - /// - /// This has all the same safety problems as `ptr::read` with respect to - /// invalid pointers, types, and double drops. - #[stable(feature = "drop_in_place", since = "1.8.0")] - pub fn drop_in_place(to_drop: *mut T); - /// Gets a static string slice containing the name of a type. pub fn type_name() -> &'static str; @@ -1261,11 +1239,9 @@ extern "rust-intrinsic" { /// Performs an unchecked left shift, resulting in undefined behavior when /// y < 0 or y >= N, where N is the width of T in bits. - #[cfg(not(stage0))] pub fn unchecked_shl(x: T, y: T) -> T; /// Performs an unchecked right shift, resulting in undefined behavior when /// y < 0 or y >= N, where N is the width of T in bits. - #[cfg(not(stage0))] pub fn unchecked_shr(x: T, y: T) -> T; /// Returns (a + b) mod 2N, where N is the width of T in bits. diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index c0aa650a1e8..3f32db12235 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -559,7 +559,7 @@ mod impls { /// any `UnsafeCell` internally, but not through an indirection. /// This affects, for example, whether a `static` of that type is /// placed in read-only static memory or writable static memory. -#[cfg_attr(not(stage0), lang = "freeze")] +#[lang = "freeze"] unsafe trait Freeze {} unsafe impl Freeze for .. {} diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 5c4a43fbd11..18e2c1d5c73 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -778,21 +778,12 @@ macro_rules! int_impl { /// ``` #[stable(feature = "num_wrapping", since = "1.2.0")] #[inline(always)] - #[cfg(not(stage0))] pub fn wrapping_shl(self, rhs: u32) -> Self { unsafe { intrinsics::unchecked_shl(self, (rhs & ($BITS - 1)) as $SelfT) } } - /// Stage 0 - #[stable(feature = "num_wrapping", since = "1.2.0")] - #[inline(always)] - #[cfg(stage0)] - pub fn wrapping_shl(self, rhs: u32) -> Self { - self.overflowing_shl(rhs).0 - } - /// Panic-free bitwise shift-right; yields `self >> mask(rhs)`, /// where `mask` removes any high-order bits of `rhs` that /// would cause the shift to exceed the bitwidth of the type. @@ -814,21 +805,12 @@ macro_rules! int_impl { /// ``` #[stable(feature = "num_wrapping", since = "1.2.0")] #[inline(always)] - #[cfg(not(stage0))] pub fn wrapping_shr(self, rhs: u32) -> Self { unsafe { intrinsics::unchecked_shr(self, (rhs & ($BITS - 1)) as $SelfT) } } - /// Stage 0 - #[stable(feature = "num_wrapping", since = "1.2.0")] - #[inline(always)] - #[cfg(stage0)] - pub fn wrapping_shr(self, rhs: u32) -> Self { - self.overflowing_shr(rhs).0 - } - /// Wrapping (modular) absolute value. Computes `self.abs()`, /// wrapping around at the boundary of the type. /// @@ -1039,19 +1021,10 @@ macro_rules! int_impl { /// ``` #[inline] #[stable(feature = "wrapping", since = "1.7.0")] - #[cfg(not(stage0))] pub fn overflowing_shl(self, rhs: u32) -> (Self, bool) { (self.wrapping_shl(rhs), (rhs > ($BITS - 1))) } - /// Stage 0 - #[inline] - #[stable(feature = "wrapping", since = "1.7.0")] - #[cfg(stage0)] - pub fn overflowing_shl(self, rhs: u32) -> (Self, bool) { - (self << (rhs & ($BITS - 1)), (rhs > ($BITS - 1))) - } - /// Shifts self right by `rhs` bits. /// /// Returns a tuple of the shifted version of self along with a boolean @@ -1070,19 +1043,10 @@ macro_rules! int_impl { /// ``` #[inline] #[stable(feature = "wrapping", since = "1.7.0")] - #[cfg(not(stage0))] pub fn overflowing_shr(self, rhs: u32) -> (Self, bool) { (self.wrapping_shr(rhs), (rhs > ($BITS - 1))) } - /// Stage 0 - #[inline] - #[stable(feature = "wrapping", since = "1.7.0")] - #[cfg(stage0)] - pub fn overflowing_shr(self, rhs: u32) -> (Self, bool) { - (self >> (rhs & ($BITS - 1)), (rhs > ($BITS - 1))) - } - /// Computes the absolute value of `self`. /// /// Returns a tuple of the absolute version of self along with a @@ -1946,21 +1910,12 @@ macro_rules! uint_impl { /// ``` #[stable(feature = "num_wrapping", since = "1.2.0")] #[inline(always)] - #[cfg(not(stage0))] pub fn wrapping_shl(self, rhs: u32) -> Self { unsafe { intrinsics::unchecked_shl(self, (rhs & ($BITS - 1)) as $SelfT) } } - /// Stage 0 - #[stable(feature = "num_wrapping", since = "1.2.0")] - #[inline(always)] - #[cfg(stage0)] - pub fn wrapping_shl(self, rhs: u32) -> Self { - self.overflowing_shl(rhs).0 - } - /// Panic-free bitwise shift-right; yields `self >> mask(rhs)`, /// where `mask` removes any high-order bits of `rhs` that /// would cause the shift to exceed the bitwidth of the type. @@ -1982,21 +1937,12 @@ macro_rules! uint_impl { /// ``` #[stable(feature = "num_wrapping", since = "1.2.0")] #[inline(always)] - #[cfg(not(stage0))] pub fn wrapping_shr(self, rhs: u32) -> Self { unsafe { intrinsics::unchecked_shr(self, (rhs & ($BITS - 1)) as $SelfT) } } - /// Stage 0 - #[stable(feature = "num_wrapping", since = "1.2.0")] - #[inline(always)] - #[cfg(stage0)] - pub fn wrapping_shr(self, rhs: u32) -> Self { - self.overflowing_shr(rhs).0 - } - /// Calculates `self` + `rhs` /// /// Returns a tuple of the addition along with a boolean indicating @@ -2160,19 +2106,10 @@ macro_rules! uint_impl { /// ``` #[inline] #[stable(feature = "wrapping", since = "1.7.0")] - #[cfg(not(stage0))] pub fn overflowing_shl(self, rhs: u32) -> (Self, bool) { (self.wrapping_shl(rhs), (rhs > ($BITS - 1))) } - /// Stage 0 - #[inline] - #[stable(feature = "wrapping", since = "1.7.0")] - #[cfg(stage0)] - pub fn overflowing_shl(self, rhs: u32) -> (Self, bool) { - (self << (rhs & ($BITS - 1)), (rhs > ($BITS - 1))) - } - /// Shifts self right by `rhs` bits. /// /// Returns a tuple of the shifted version of self along with a boolean @@ -2191,20 +2128,11 @@ macro_rules! uint_impl { /// ``` #[inline] #[stable(feature = "wrapping", since = "1.7.0")] - #[cfg(not(stage0))] pub fn overflowing_shr(self, rhs: u32) -> (Self, bool) { (self.wrapping_shr(rhs), (rhs > ($BITS - 1))) } - /// Stage 0 - #[inline] - #[stable(feature = "wrapping", since = "1.7.0")] - #[cfg(stage0)] - pub fn overflowing_shr(self, rhs: u32) -> (Self, bool) { - (self >> (rhs & ($BITS - 1)), (rhs > ($BITS - 1))) - } - /// Raises self to the power of `exp`, using exponentiation by squaring. /// /// # Examples diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 04480fc5d31..115326bb916 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -37,11 +37,6 @@ pub use intrinsics::copy; #[stable(feature = "rust1", since = "1.0.0")] pub use intrinsics::write_bytes; -#[cfg(stage0)] -#[stable(feature = "drop_in_place", since = "1.8.0")] -pub use intrinsics::drop_in_place; - -#[cfg(not(stage0))] /// Executes the destructor (if any) of the pointed-to value. /// /// This has two use cases: diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index e5a6930fefd..a3e5a14dbac 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -34,7 +34,6 @@ #![feature(loop_break_value)] #![feature(never_type)] #![feature(nonzero)] -#![cfg_attr(stage0, feature(pub_restricted))] #![feature(quote)] #![feature(rustc_diagnostic_macros)] #![feature(rustc_private)] diff --git a/src/librustc_incremental/lib.rs b/src/librustc_incremental/lib.rs index aa7eb36581f..95f0a96fdf9 100644 --- a/src/librustc_incremental/lib.rs +++ b/src/librustc_incremental/lib.rs @@ -24,7 +24,6 @@ #![feature(rand)] #![feature(conservative_impl_trait)] #![feature(sort_unstable)] -#![cfg_attr(stage0, feature(pub_restricted))] extern crate graphviz; #[macro_use] extern crate rustc; diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 70225da5f33..a4c3b276efd 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -318,7 +318,6 @@ #![feature(unwind_attributes)] #![feature(vec_push_all)] #![cfg_attr(test, feature(update_panic_count))] -#![cfg_attr(stage0, feature(pub_restricted))] #![cfg_attr(test, feature(float_bits_conv))] // Explicitly import the prelude. The compiler uses this same unstable attribute diff --git a/src/rtstartup/rsbegin.rs b/src/rtstartup/rsbegin.rs index e8b92aab1da..335817fddbb 100644 --- a/src/rtstartup/rsbegin.rs +++ b/src/rtstartup/rsbegin.rs @@ -34,10 +34,17 @@ trait Sync {} impl Sync for .. {} #[lang = "copy"] trait Copy {} -#[cfg_attr(not(stage0), lang = "freeze")] +#[lang = "freeze"] trait Freeze {} impl Freeze for .. {} +#[lang="drop_in_place"] +#[inline] +#[allow(unconditional_recursion)] +pub unsafe fn drop_in_place(to_drop: *mut T) { + drop_in_place(to_drop); +} + #[cfg(all(target_os="windows", target_arch = "x86", target_env="gnu"))] pub mod eh_frames { #[no_mangle] diff --git a/src/rtstartup/rsend.rs b/src/rtstartup/rsend.rs index 4c48d9af0e1..9229b4e3128 100644 --- a/src/rtstartup/rsend.rs +++ b/src/rtstartup/rsend.rs @@ -10,7 +10,7 @@ // See rsbegin.rs for details. -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, optin_builtin_traits)] #![crate_type="rlib"] #![no_core] @@ -19,6 +19,18 @@ trait Sized {} #[lang = "sync"] trait Sync {} impl Sync for T {} +#[lang = "copy"] +trait Copy {} +#[lang = "freeze"] +trait Freeze {} +impl Freeze for .. {} + +#[lang="drop_in_place"] +#[inline] +#[allow(unconditional_recursion)] +pub unsafe fn drop_in_place(to_drop: *mut T) { + drop_in_place(to_drop); +} #[cfg(all(target_os="windows", target_arch = "x86", target_env="gnu"))] pub mod eh_frames { diff --git a/src/stage0.txt b/src/stage0.txt index dc6931c1d0b..974be125651 100644 --- a/src/stage0.txt +++ b/src/stage0.txt @@ -8,8 +8,30 @@ # release. # # If you're looking at this file on the master branch, you'll likely see that -# rustc bootstraps from `beta-$date`, whereas if you're looking at a source -# tarball for a stable release you'll likely see `1.x.0-$date` where `1.x.0` was -# released on `$date` +# rustc and cargo are configured to `beta`, whereas if you're looking at a +# source tarball for a stable release you'll likely see `1.x.0` for rustc and +# `0.x.0` for Cargo where they were released on `date`. -rustc: beta-2017-04-05 +date: 2017-04-25 +rustc: beta +cargo: beta + +# When making a stable release the process currently looks like: +# +# 1. Produce stable build, upload it to dev-static +# 2. Produce a beta build from the previous stable build, upload to static +# 3. Produce a nightly build from previous beta, upload to static +# 4. Upload stable build to static, publish full release +# +# This means that there's a small window of time (a few days) where artifacts +# are downloaded from dev-static.rust-lang.org instead of static.rust-lang.org. +# In order to ease this transition we have an extra key is in this configuration +# file below. When uncommented this will instruct the bootstrap.py script to +# download from dev-static.rust-lang.org. +# +# This key is typically commented out at all times. If you're looking at a +# stable release tarball it should *definitely* be commented out. If you're +# looking at a beta source tarball and it's uncommented we'll shortly comment it +# out. + +#dev: 1 diff --git a/src/tools/cargo b/src/tools/cargo new file mode 160000 index 00000000000..fa7584c1495 --- /dev/null +++ b/src/tools/cargo @@ -0,0 +1 @@ +Subproject commit fa7584c1495c2d9c04a6416f8e7b546abfa88a52 diff --git a/src/tools/rls b/src/tools/rls new file mode 160000 index 00000000000..67babd2d637 --- /dev/null +++ b/src/tools/rls @@ -0,0 +1 @@ +Subproject commit 67babd2d63710444a3071dfd9184648fd85a6a3d diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index 3e7046d05f4..f14a6a03893 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -85,6 +85,8 @@ fn filter_dirs(path: &Path) -> bool { "src/liblibc", "src/vendor", "src/rt/hoedown", + "src/tools/cargo", + "src/tools/rls", ]; skip.iter().any(|p| path.ends_with(p)) } -- cgit 1.4.1-3-g733a5 From 7b05b88ce799fdba12caf6ba4e6419d3dc4702f6 Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Tue, 2 May 2017 12:38:12 -0700 Subject: Document the reasoning for the Acquire/Release handshake when dropping Arcs. --- src/liballoc/arc.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src/liballoc') diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 182a107e3f7..1df79074d3f 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -767,7 +767,18 @@ unsafe impl<#[may_dangle] T: ?Sized> Drop for Arc { // > through this reference must obviously happened before), and an // > "acquire" operation before deleting the object. // + // In particular, while the contents of an Arc are usually immutable, it's + // possible to have interior writes to something like a Mutex. Since a + // Mutex is not acquired when it is deleted, we can't rely on its + // synchronization logic to make writes in thread A visible to a destructor + // running in thread B. + // + // Also note that the Acquire fence here could probably be replaced with an + // Acquire load, which could improve performance in highly-contended + // situations. See [2]. + // // [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html) + // [2]: (https://github.com/rust-lang/rust/pull/41714) atomic::fence(Acquire); unsafe { -- cgit 1.4.1-3-g733a5 From 4ff583b1161c5c2e08c28a0740f34a526b39a8bc Mon Sep 17 00:00:00 2001 From: Alexis Beingessner Date: Tue, 4 Apr 2017 12:31:38 -0400 Subject: fallout from NonZero/Unique/Shared changes --- src/liballoc/arc.rs | 31 ++++------ src/liballoc/raw_vec.rs | 4 +- src/liballoc/rc.rs | 50 +++++++-------- src/libcollections/btree/node.rs | 18 +++--- src/libcollections/linked_list.rs | 72 +++++++++++++--------- src/libcollections/vec.rs | 15 +++-- src/libcollections/vec_deque.rs | 2 +- src/libcore/cell.rs | 4 +- src/libcore/tests/nonzero.rs | 4 +- src/libcore/tests/ptr.rs | 8 +-- src/libflate/lib.rs | 4 +- src/librustc/ty/subst.rs | 4 +- src/librustc_borrowck/borrowck/mir/gather_moves.rs | 2 +- src/librustc_data_structures/array_vec.rs | 2 +- .../obligation_forest/node_index.rs | 2 +- src/libstd/collections/hash/table.rs | 21 ++++--- 16 files changed, 123 insertions(+), 120 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 182a107e3f7..921db3c6959 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -277,8 +277,7 @@ impl Arc { atomic::fence(Acquire); unsafe { - let ptr = *this.ptr; - let elem = ptr::read(&(*ptr).data); + let elem = ptr::read(&this.ptr.as_ref().data); // Make a weak pointer to clean up the implicit strong-weak reference let _weak = Weak { ptr: this.ptr }; @@ -306,7 +305,7 @@ impl Arc { /// ``` #[stable(feature = "rc_raw", since = "1.17.0")] pub fn into_raw(this: Self) -> *const T { - let ptr = unsafe { &(**this.ptr).data as *const _ }; + let ptr: *const T = &*this; mem::forget(this); ptr } @@ -345,7 +344,7 @@ impl Arc { // `data` field from the pointer. let ptr = (ptr as *const u8).offset(-offset_of!(ArcInner, data)); Arc { - ptr: Shared::new(ptr as *const _), + ptr: Shared::new(ptr as *mut u8 as *mut _), } } } @@ -452,17 +451,17 @@ impl Arc { // `ArcInner` structure itself is `Sync` because the inner data is // `Sync` as well, so we're ok loaning out an immutable pointer to these // contents. - unsafe { &**self.ptr } + unsafe { self.ptr.as_ref() } } // Non-inlined part of `drop`. #[inline(never)] unsafe fn drop_slow(&mut self) { - let ptr = self.ptr.as_mut_ptr(); + let ptr = self.ptr.as_ptr(); // Destroy the data at this time, even though we may not free the box // allocation itself (there may still be weak pointers lying around). - ptr::drop_in_place(&mut (*ptr).data); + ptr::drop_in_place(&mut self.ptr.as_mut().data); if self.inner().weak.fetch_sub(1, Release) == 1 { atomic::fence(Acquire); @@ -488,9 +487,7 @@ impl Arc { /// assert!(!Arc::ptr_eq(&five, &other_five)); /// ``` pub fn ptr_eq(this: &Self, other: &Self) -> bool { - let this_ptr: *const ArcInner = *this.ptr; - let other_ptr: *const ArcInner = *other.ptr; - this_ptr == other_ptr + this.ptr.as_ptr() == other.ptr.as_ptr() } } @@ -621,7 +618,7 @@ impl Arc { // here (due to zeroing) because data is no longer accessed by // other threads (due to there being no more strong refs at this // point). - let mut swap = Arc::new(ptr::read(&(**weak.ptr).data)); + let mut swap = Arc::new(ptr::read(&weak.ptr.as_ref().data)); mem::swap(this, &mut swap); mem::forget(swap); } @@ -634,8 +631,7 @@ impl Arc { // As with `get_mut()`, the unsafety is ok because our reference was // either unique to begin with, or became one upon cloning the contents. unsafe { - let inner = &mut *this.ptr.as_mut_ptr(); - &mut inner.data + &mut this.ptr.as_mut().data } } } @@ -677,8 +673,7 @@ impl Arc { // the Arc itself to be `mut`, so we're returning the only possible // reference to the inner data. unsafe { - let inner = &mut *this.ptr.as_mut_ptr(); - Some(&mut inner.data) + Some(&mut this.ptr.as_mut().data) } } else { None @@ -867,7 +862,7 @@ impl Weak { #[inline] fn inner(&self) -> &ArcInner { // See comments above for why this is "safe" - unsafe { &**self.ptr } + unsafe { self.ptr.as_ref() } } } @@ -951,7 +946,7 @@ impl Drop for Weak { /// assert!(other_weak_foo.upgrade().is_none()); /// ``` fn drop(&mut self) { - let ptr = *self.ptr; + let ptr = self.ptr.as_ptr(); // If we find out that we were the last weak pointer, then its time to // deallocate the data entirely. See the discussion in Arc::drop() about @@ -1132,7 +1127,7 @@ impl fmt::Debug for Arc { #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Pointer for Arc { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Pointer::fmt(&*self.ptr, f) + fmt::Pointer::fmt(&self.ptr, f) } } diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs index 6a53d3a9ca5..1f6f5ba17ed 100644 --- a/src/liballoc/raw_vec.rs +++ b/src/liballoc/raw_vec.rs @@ -151,7 +151,7 @@ impl RawVec { /// heap::EMPTY if `cap = 0` or T is zero-sized. In the former case, you must /// be careful. pub fn ptr(&self) -> *mut T { - *self.ptr + self.ptr.ptr() } /// Gets the capacity of the allocation. @@ -563,7 +563,7 @@ unsafe impl<#[may_dangle] T> Drop for RawVec { let num_bytes = elem_size * self.cap; unsafe { - heap::deallocate(*self.ptr as *mut _, num_bytes, align); + heap::deallocate(self.ptr() as *mut u8, num_bytes, align); } } } diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 38dc9145835..d6dbf77bfac 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -230,7 +230,7 @@ use core::cell::Cell; use core::cmp::Ordering; use core::fmt; use core::hash::{Hash, Hasher}; -use core::intrinsics::{abort, assume}; +use core::intrinsics::abort; use core::marker; use core::marker::Unsize; use core::mem::{self, align_of_val, forget, size_of, size_of_val, uninitialized}; @@ -358,7 +358,7 @@ impl Rc { /// ``` #[stable(feature = "rc_raw", since = "1.17.0")] pub fn into_raw(this: Self) -> *const T { - let ptr = unsafe { &mut (*this.ptr.as_mut_ptr()).value as *const _ }; + let ptr: *const T = &*this; mem::forget(this); ptr } @@ -395,7 +395,11 @@ impl Rc { pub unsafe fn from_raw(ptr: *const T) -> Self { // To find the corresponding pointer to the `RcBox` we need to subtract the offset of the // `value` field from the pointer. - Rc { ptr: Shared::new((ptr as *const u8).offset(-offset_of!(RcBox, value)) as *const _) } + + let ptr = (ptr as *const u8).offset(-offset_of!(RcBox, value)); + Rc { + ptr: Shared::new(ptr as *mut u8 as *mut _) + } } } @@ -451,7 +455,7 @@ impl Rc<[T]> { // Free the original allocation without freeing its (moved) contents. box_free(Box::into_raw(value)); - Rc { ptr: Shared::new(ptr as *const _) } + Rc { ptr: Shared::new(ptr as *mut _) } } } } @@ -553,8 +557,9 @@ impl Rc { #[stable(feature = "rc_unique", since = "1.4.0")] pub fn get_mut(this: &mut Self) -> Option<&mut T> { if Rc::is_unique(this) { - let inner = unsafe { &mut *this.ptr.as_mut_ptr() }; - Some(&mut inner.value) + unsafe { + Some(&mut this.ptr.as_mut().value) + } } else { None } @@ -578,9 +583,7 @@ impl Rc { /// assert!(!Rc::ptr_eq(&five, &other_five)); /// ``` pub fn ptr_eq(this: &Self, other: &Self) -> bool { - let this_ptr: *const RcBox = *this.ptr; - let other_ptr: *const RcBox = *other.ptr; - this_ptr == other_ptr + this.ptr.as_ptr() == other.ptr.as_ptr() } } @@ -623,7 +626,7 @@ impl Rc { } else if Rc::weak_count(this) != 0 { // Can just steal the data, all that's left is Weaks unsafe { - let mut swap = Rc::new(ptr::read(&(**this.ptr).value)); + let mut swap = Rc::new(ptr::read(&this.ptr.as_ref().value)); mem::swap(this, &mut swap); swap.dec_strong(); // Remove implicit strong-weak ref (no need to craft a fake @@ -637,8 +640,9 @@ impl Rc { // reference count is guaranteed to be 1 at this point, and we required // the `Rc` itself to be `mut`, so we're returning the only possible // reference to the inner value. - let inner = unsafe { &mut *this.ptr.as_mut_ptr() }; - &mut inner.value + unsafe { + &mut this.ptr.as_mut().value + } } } @@ -683,12 +687,12 @@ unsafe impl<#[may_dangle] T: ?Sized> Drop for Rc { /// ``` fn drop(&mut self) { unsafe { - let ptr = self.ptr.as_mut_ptr(); + let ptr = self.ptr.as_ptr(); self.dec_strong(); if self.strong() == 0 { // destroy the contained object - ptr::drop_in_place(&mut (*ptr).value); + ptr::drop_in_place(self.ptr.as_mut()); // remove the implicit "strong weak" pointer now that we've // destroyed the contents. @@ -925,7 +929,7 @@ impl fmt::Debug for Rc { #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Pointer for Rc { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Pointer::fmt(&*self.ptr, f) + fmt::Pointer::fmt(&self.ptr, f) } } @@ -1067,7 +1071,7 @@ impl Drop for Weak { /// ``` fn drop(&mut self) { unsafe { - let ptr = *self.ptr; + let ptr = self.ptr.as_ptr(); self.dec_weak(); // the weak count starts at 1, and will only go to zero if all @@ -1175,12 +1179,7 @@ impl RcBoxPtr for Rc { #[inline(always)] fn inner(&self) -> &RcBox { unsafe { - // Safe to assume this here, as if it weren't true, we'd be breaking - // the contract anyway. - // This allows the null check to be elided in the destructor if we - // manipulated the reference count in the same function. - assume(!(*(&self.ptr as *const _ as *const *const ())).is_null()); - &(**self.ptr) + self.ptr.as_ref() } } } @@ -1189,12 +1188,7 @@ impl RcBoxPtr for Weak { #[inline(always)] fn inner(&self) -> &RcBox { unsafe { - // Safe to assume this here, as if it weren't true, we'd be breaking - // the contract anyway. - // This allows the null check to be elided in the destructor if we - // manipulated the reference count in the same function. - assume(!(*(&self.ptr as *const _ as *const *const ())).is_null()); - &(**self.ptr) + self.ptr.as_ref() } } } diff --git a/src/libcollections/btree/node.rs b/src/libcollections/btree/node.rs index e9bc29118d5..52cdd39d8f9 100644 --- a/src/libcollections/btree/node.rs +++ b/src/libcollections/btree/node.rs @@ -152,12 +152,12 @@ impl BoxedNode { } unsafe fn from_ptr(ptr: NonZero<*const LeafNode>) -> Self { - BoxedNode { ptr: Unique::new(*ptr as *mut LeafNode) } + BoxedNode { ptr: Unique::new(ptr.get() as *mut LeafNode) } } fn as_ptr(&self) -> NonZero<*const LeafNode> { unsafe { - NonZero::new(*self.ptr as *const LeafNode) + NonZero::new(self.ptr.as_ptr()) } } } @@ -241,7 +241,7 @@ impl Root { pub fn pop_level(&mut self) { debug_assert!(self.height > 0); - let top = *self.node.ptr as *mut u8; + let top = self.node.ptr.as_ptr() as *mut u8; self.node = unsafe { BoxedNode::from_ptr(self.as_mut() @@ -308,7 +308,7 @@ unsafe impl Send impl NodeRef { fn as_internal(&self) -> &InternalNode { unsafe { - &*(*self.node as *const InternalNode) + &*(self.node.get() as *const InternalNode) } } } @@ -316,7 +316,7 @@ impl NodeRef { impl<'a, K, V> NodeRef, K, V, marker::Internal> { fn as_internal_mut(&mut self) -> &mut InternalNode { unsafe { - &mut *(*self.node as *mut InternalNode) + &mut *(self.node.get() as *mut InternalNode) } } } @@ -358,7 +358,7 @@ impl NodeRef { fn as_leaf(&self) -> &LeafNode { unsafe { - &**self.node + &*self.node.get() } } @@ -510,7 +510,7 @@ impl<'a, K, V, Type> NodeRef, K, V, Type> { fn as_leaf_mut(&mut self) -> &mut LeafNode { unsafe { - &mut *(*self.node as *mut LeafNode) + &mut *(self.node.get() as *mut LeafNode) } } @@ -1253,13 +1253,13 @@ impl<'a, K, V> Handle, K, V, marker::Internal>, marker:: } heap::deallocate( - *right_node.node as *mut u8, + right_node.node.get() as *mut u8, mem::size_of::>(), mem::align_of::>() ); } else { heap::deallocate( - *right_node.node as *mut u8, + right_node.node.get() as *mut u8, mem::size_of::>(), mem::align_of::>() ); diff --git a/src/libcollections/linked_list.rs b/src/libcollections/linked_list.rs index adfd91bec48..ae258083546 100644 --- a/src/libcollections/linked_list.rs +++ b/src/libcollections/linked_list.rs @@ -161,7 +161,7 @@ impl LinkedList { match self.head { None => self.tail = node, - Some(head) => (*head.as_mut_ptr()).prev = node, + Some(mut head) => head.as_mut().prev = node, } self.head = node; @@ -173,12 +173,12 @@ impl LinkedList { #[inline] fn pop_front_node(&mut self) -> Option>> { self.head.map(|node| unsafe { - let node = Box::from_raw(node.as_mut_ptr()); + let node = Box::from_raw(node.as_ptr()); self.head = node.next; match self.head { None => self.tail = None, - Some(head) => (*head.as_mut_ptr()).prev = None, + Some(mut head) => head.as_mut().prev = None, } self.len -= 1; @@ -196,7 +196,7 @@ impl LinkedList { match self.tail { None => self.head = node, - Some(tail) => (*tail.as_mut_ptr()).next = node, + Some(mut tail) => tail.as_mut().next = node, } self.tail = node; @@ -208,12 +208,12 @@ impl LinkedList { #[inline] fn pop_back_node(&mut self) -> Option>> { self.tail.map(|node| unsafe { - let node = Box::from_raw(node.as_mut_ptr()); + let node = Box::from_raw(node.as_ptr()); self.tail = node.prev; match self.tail { None => self.head = None, - Some(tail) => (*tail.as_mut_ptr()).next = None, + Some(mut tail) => tail.as_mut().next = None, } self.len -= 1; @@ -285,11 +285,11 @@ impl LinkedList { pub fn append(&mut self, other: &mut Self) { match self.tail { None => mem::swap(self, other), - Some(tail) => { - if let Some(other_head) = other.head.take() { + Some(mut tail) => { + if let Some(mut other_head) = other.head.take() { unsafe { - (*tail.as_mut_ptr()).next = Some(other_head); - (*other_head.as_mut_ptr()).prev = Some(tail); + tail.as_mut().next = Some(other_head); + other_head.as_mut().prev = Some(tail); } self.tail = other.tail.take(); @@ -477,7 +477,9 @@ impl LinkedList { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn front(&self) -> Option<&T> { - self.head.map(|node| unsafe { &(**node).element }) + unsafe { + self.head.as_ref().map(|node| &node.as_ref().element) + } } /// Provides a mutable reference to the front element, or `None` if the list @@ -503,7 +505,9 @@ impl LinkedList { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn front_mut(&mut self) -> Option<&mut T> { - self.head.map(|node| unsafe { &mut (*node.as_mut_ptr()).element }) + unsafe { + self.head.as_mut().map(|node| &mut node.as_mut().element) + } } /// Provides a reference to the back element, or `None` if the list is @@ -523,7 +527,9 @@ impl LinkedList { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn back(&self) -> Option<&T> { - self.tail.map(|node| unsafe { &(**node).element }) + unsafe { + self.tail.as_ref().map(|node| &node.as_ref().element) + } } /// Provides a mutable reference to the back element, or `None` if the list @@ -549,7 +555,9 @@ impl LinkedList { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn back_mut(&mut self) -> Option<&mut T> { - self.tail.map(|node| unsafe { &mut (*node.as_mut_ptr()).element }) + unsafe { + self.tail.as_mut().map(|node| &mut node.as_mut().element) + } } /// Adds an element first in the list. @@ -694,9 +702,9 @@ impl LinkedList { let second_part_head; unsafe { - second_part_head = (*split_node.unwrap().as_mut_ptr()).next.take(); - if let Some(head) = second_part_head { - (*head.as_mut_ptr()).prev = None; + second_part_head = split_node.unwrap().as_mut().next.take(); + if let Some(mut head) = second_part_head { + head.as_mut().prev = None; } } @@ -788,7 +796,8 @@ impl<'a, T> Iterator for Iter<'a, T> { None } else { self.head.map(|node| unsafe { - let node = &**node; + // Need an unbound lifetime to get 'a + let node = &*node.as_ptr(); self.len -= 1; self.head = node.next; &node.element @@ -810,7 +819,8 @@ impl<'a, T> DoubleEndedIterator for Iter<'a, T> { None } else { self.tail.map(|node| unsafe { - let node = &**node; + // Need an unbound lifetime to get 'a + let node = &*node.as_ptr(); self.len -= 1; self.tail = node.prev; &node.element @@ -835,7 +845,8 @@ impl<'a, T> Iterator for IterMut<'a, T> { None } else { self.head.map(|node| unsafe { - let node = &mut *node.as_mut_ptr(); + // Need an unbound lifetime to get 'a + let node = &mut *node.as_ptr(); self.len -= 1; self.head = node.next; &mut node.element @@ -857,7 +868,8 @@ impl<'a, T> DoubleEndedIterator for IterMut<'a, T> { None } else { self.tail.map(|node| unsafe { - let node = &mut *node.as_mut_ptr(); + // Need an unbound lifetime to get 'a + let node = &mut *node.as_ptr(); self.len -= 1; self.tail = node.prev; &mut node.element @@ -903,8 +915,8 @@ impl<'a, T> IterMut<'a, T> { pub fn insert_next(&mut self, element: T) { match self.head { None => self.list.push_back(element), - Some(head) => unsafe { - let prev = match (**head).prev { + Some(mut head) => unsafe { + let mut prev = match head.as_ref().prev { None => return self.list.push_front(element), Some(prev) => prev, }; @@ -915,8 +927,8 @@ impl<'a, T> IterMut<'a, T> { element: element, }))); - (*prev.as_mut_ptr()).next = node; - (*head.as_mut_ptr()).prev = node; + prev.as_mut().next = node; + head.as_mut().prev = node; self.list.len += 1; }, @@ -948,7 +960,9 @@ impl<'a, T> IterMut<'a, T> { if self.len == 0 { None } else { - self.head.map(|node| unsafe { &mut (*node.as_mut_ptr()).element }) + unsafe { + self.head.as_mut().map(|node| &mut node.as_mut().element) + } } } } @@ -1276,21 +1290,21 @@ mod tests { assert_eq!(0, list.len); return; } - Some(node) => node_ptr = &**node, + Some(node) => node_ptr = &*node.as_ptr(), } loop { match (last_ptr, node_ptr.prev) { (None, None) => {} (None, _) => panic!("prev link for head"), (Some(p), Some(pptr)) => { - assert_eq!(p as *const Node, *pptr as *const Node); + assert_eq!(p as *const Node, pptr.as_ptr() as *const Node); } _ => panic!("prev link is none, not good"), } match node_ptr.next { Some(next) => { last_ptr = Some(node_ptr); - node_ptr = &**next; + node_ptr = &*next.as_ptr(); len += 1; } None => { diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index fc5de70e983..02ad0a67bda 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -1776,9 +1776,9 @@ impl SpecExtend> for Vec { // A common case is passing a vector into a function which immediately // re-collects into a vector. We can short circuit this if the IntoIter // has not been advanced at all. - if *iterator.buf == iterator.ptr as *mut T { + if iterator.buf.as_ptr() as *const _ == iterator.ptr { unsafe { - let vec = Vec::from_raw_parts(*iterator.buf as *mut T, + let vec = Vec::from_raw_parts(iterator.buf.as_ptr(), iterator.len(), iterator.cap); mem::forget(iterator); @@ -2269,7 +2269,7 @@ unsafe impl<#[may_dangle] T> Drop for IntoIter { for _x in self.by_ref() {} // RawVec handles deallocation - let _ = unsafe { RawVec::from_raw_parts(self.buf.as_mut_ptr(), self.cap) }; + let _ = unsafe { RawVec::from_raw_parts(self.buf.as_ptr(), self.cap) }; } } @@ -2334,7 +2334,7 @@ impl<'a, T> Drop for Drain<'a, T> { if self.tail_len > 0 { unsafe { - let source_vec = &mut *self.vec.as_mut_ptr(); + let source_vec = self.vec.as_mut(); // memmove back untouched tail, update to new length let start = source_vec.len(); let tail = self.tail_start; @@ -2456,8 +2456,7 @@ impl<'a, I: Iterator> Drop for Splice<'a, I> { unsafe { if self.drain.tail_len == 0 { - let vec = &mut *self.drain.vec.as_mut_ptr(); - vec.extend(self.replace_with.by_ref()); + self.drain.vec.as_mut().extend(self.replace_with.by_ref()); return } @@ -2498,7 +2497,7 @@ impl<'a, T> Drain<'a, T> { /// Fill that range as much as possible with new elements from the `replace_with` iterator. /// Return whether we filled the entire range. (`replace_with.next()` didn’t return `None`.) unsafe fn fill>(&mut self, replace_with: &mut I) -> bool { - let vec = &mut *self.vec.as_mut_ptr(); + let vec = self.vec.as_mut(); let range_start = vec.len; let range_end = self.tail_start; let range_slice = slice::from_raw_parts_mut( @@ -2518,7 +2517,7 @@ impl<'a, T> Drain<'a, T> { /// Make room for inserting more elements before the tail. unsafe fn move_tail(&mut self, extra_capacity: usize) { - let vec = &mut *self.vec.as_mut_ptr(); + let vec = self.vec.as_mut(); let used_capacity = self.tail_start + self.tail_len; vec.buf.reserve(used_capacity, extra_capacity); diff --git a/src/libcollections/vec_deque.rs b/src/libcollections/vec_deque.rs index 079d3acf376..e826c9432b5 100644 --- a/src/libcollections/vec_deque.rs +++ b/src/libcollections/vec_deque.rs @@ -2160,7 +2160,7 @@ impl<'a, T: 'a> Drop for Drain<'a, T> { fn drop(&mut self) { for _ in self.by_ref() {} - let source_deque = unsafe { &mut *self.deque.as_mut_ptr() }; + let source_deque = unsafe { self.deque.as_mut() }; // T = source_deque_tail; H = source_deque_head; t = drain_tail; h = drain_head // diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index f62057b3a52..7886f90b66e 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -132,7 +132,6 @@ //! use std::cell::Cell; //! use std::ptr::Shared; //! use std::intrinsics::abort; -//! use std::intrinsics::assume; //! //! struct Rc { //! ptr: Shared> @@ -171,8 +170,7 @@ //! impl RcBoxPtr for Rc { //! fn inner(&self) -> &RcBox { //! unsafe { -//! assume(!(*(&self.ptr as *const _ as *const *const ())).is_null()); -//! &(**self.ptr) +//! self.ptr.as_ref() //! } //! } //! } diff --git a/src/libcore/tests/nonzero.rs b/src/libcore/tests/nonzero.rs index 7a367ddeec8..588fffda35f 100644 --- a/src/libcore/tests/nonzero.rs +++ b/src/libcore/tests/nonzero.rs @@ -31,12 +31,12 @@ fn test_match_on_nonzero_option() { NonZero::new(42) }); match a { - Some(val) => assert_eq!(*val, 42), + Some(val) => assert_eq!(val.get(), 42), None => panic!("unexpected None while matching on Some(NonZero(_))") } match unsafe { Some(NonZero::new(43)) } { - Some(val) => assert_eq!(*val, 43), + Some(val) => assert_eq!(val.get(), 43), None => panic!("unexpected None while matching on Some(NonZero(_))") } } diff --git a/src/libcore/tests/ptr.rs b/src/libcore/tests/ptr.rs index 7f6f472bfbb..e28dc6a6881 100644 --- a/src/libcore/tests/ptr.rs +++ b/src/libcore/tests/ptr.rs @@ -166,10 +166,10 @@ fn test_set_memory() { #[test] fn test_unsized_unique() { - let xs: &mut [i32] = &mut [1, 2, 3]; - let ptr = unsafe { Unique::new(xs as *mut [i32]) }; - let ys = unsafe { &mut **ptr }; - let zs: &mut [i32] = &mut [1, 2, 3]; + let xs: &[i32] = &[1, 2, 3]; + let ptr = unsafe { Unique::new(xs as *const [i32] as *mut [i32]) }; + let ys = unsafe { ptr.as_ref() }; + let zs: &[i32] = &[1, 2, 3]; assert!(ys == zs); } diff --git a/src/libflate/lib.rs b/src/libflate/lib.rs index dedec7b1609..3619be82829 100644 --- a/src/libflate/lib.rs +++ b/src/libflate/lib.rs @@ -62,14 +62,14 @@ pub struct Bytes { impl Deref for Bytes { type Target = [u8]; fn deref(&self) -> &[u8] { - unsafe { slice::from_raw_parts(*self.ptr, self.len) } + unsafe { slice::from_raw_parts(self.ptr.as_ptr(), self.len) } } } impl Drop for Bytes { fn drop(&mut self) { unsafe { - libc::free(*self.ptr as *mut _); + libc::free(self.ptr.as_ptr() as *mut _); } } } diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs index c591845dd63..c9ffcee51c2 100644 --- a/src/librustc/ty/subst.rs +++ b/src/librustc/ty/subst.rs @@ -72,7 +72,7 @@ impl<'tcx> From> for Kind<'tcx> { impl<'tcx> Kind<'tcx> { #[inline] unsafe fn downcast(self, tag: usize) -> Option<&'tcx T> { - let ptr = *self.ptr; + let ptr = self.ptr.get(); if ptr & TAG_MASK == tag { Some(&*((ptr & !TAG_MASK) as *const _)) } else { @@ -102,7 +102,7 @@ impl<'tcx> fmt::Debug for Kind<'tcx> { } else if let Some(r) = self.as_region() { write!(f, "{:?}", r) } else { - write!(f, "", *self.ptr as *const ()) + write!(f, "", self.ptr.get() as *const ()) } } } diff --git a/src/librustc_borrowck/borrowck/mir/gather_moves.rs b/src/librustc_borrowck/borrowck/mir/gather_moves.rs index 81037fe40d9..ed5e539f245 100644 --- a/src/librustc_borrowck/borrowck/mir/gather_moves.rs +++ b/src/librustc_borrowck/borrowck/mir/gather_moves.rs @@ -43,7 +43,7 @@ mod indexes { unsafe { $Index(NonZero::new(idx + 1)) } } fn index(self) -> usize { - *self.0 - 1 + self.0.get() - 1 } } diff --git a/src/librustc_data_structures/array_vec.rs b/src/librustc_data_structures/array_vec.rs index 848e5a076bb..078bb801751 100644 --- a/src/librustc_data_structures/array_vec.rs +++ b/src/librustc_data_structures/array_vec.rs @@ -255,7 +255,7 @@ impl<'a, A: Array> Drop for Drain<'a, A> { if self.tail_len > 0 { unsafe { - let source_array_vec = &mut *self.array_vec.as_mut_ptr(); + let source_array_vec = self.array_vec.as_mut(); // memmove back untouched tail, update to new length let start = source_array_vec.len(); let tail = self.tail_start; diff --git a/src/librustc_data_structures/obligation_forest/node_index.rs b/src/librustc_data_structures/obligation_forest/node_index.rs index 1063bb3611e..023c56ca59b 100644 --- a/src/librustc_data_structures/obligation_forest/node_index.rs +++ b/src/librustc_data_structures/obligation_forest/node_index.rs @@ -23,6 +23,6 @@ impl NodeIndex { } pub fn get(self) -> usize { - (*self.index - 1) as usize + (self.index.get() - 1) as usize } } diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs index 9623706548b..0a488dfd53a 100644 --- a/src/libstd/collections/hash/table.rs +++ b/src/libstd/collections/hash/table.rs @@ -49,24 +49,25 @@ impl TaggedHashUintPtr { #[inline] fn set_tag(&mut self, value: bool) { - let usize_ptr = &*self.0 as *const *mut HashUint as *mut usize; + let mut usize_ptr = self.0.as_ptr() as usize; unsafe { if value { - *usize_ptr |= 1; + usize_ptr |= 1; } else { - *usize_ptr &= !1; + usize_ptr &= !1; } + self.0 = Unique::new(usize_ptr as *mut HashUint) } } #[inline] fn tag(&self) -> bool { - (*self.0 as usize) & 1 == 1 + (self.0.as_ptr() as usize) & 1 == 1 } #[inline] fn ptr(&self) -> *mut HashUint { - (*self.0 as usize & !1) as *mut HashUint + (self.0.as_ptr() as usize & !1) as *mut HashUint } } @@ -1112,10 +1113,12 @@ impl<'a, K, V> Iterator for Drain<'a, K, V> { #[inline] fn next(&mut self) -> Option<(SafeHash, K, V)> { - self.iter.next().map(|raw| unsafe { - (*self.table.as_mut_ptr()).size -= 1; - let (k, v) = ptr::read(raw.pair()); - (SafeHash { hash: ptr::replace(&mut *raw.hash(), EMPTY_BUCKET) }, k, v) + self.iter.next().map(|raw| { + unsafe { + self.table.as_mut().size -= 1; + let (k, v) = ptr::read(raw.pair()); + (SafeHash { hash: ptr::replace(&mut *raw.hash(), EMPTY_BUCKET) }, k, v) + } }) } -- cgit 1.4.1-3-g733a5 From c7cffc5f4ef1def337ca2a294c3ca855ee703419 Mon Sep 17 00:00:00 2001 From: Alexis Beingessner Date: Thu, 4 May 2017 14:48:58 -0400 Subject: Deprecate heap::EMPTY in favour of Unique::empty or otherwise. --- src/liballoc/boxed.rs | 2 +- src/liballoc/heap.rs | 6 ++++-- src/liballoc/raw_vec.rs | 26 ++++++++++++-------------- src/libarena/lib.rs | 4 +--- src/libcollections/vec.rs | 7 ++++--- src/libstd/collections/hash/table.rs | 3 ++- 6 files changed, 24 insertions(+), 24 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index b03e3bb7a4b..fc6929f896e 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -156,7 +156,7 @@ fn make_place() -> IntermediateBox { let align = mem::align_of::(); let p = if size == 0 { - heap::EMPTY as *mut u8 + mem::align_of::() as *mut u8 } else { let p = unsafe { heap::allocate(size, align) }; if p.is_null() { diff --git a/src/liballoc/heap.rs b/src/liballoc/heap.rs index 056af13016c..5ff21c86483 100644 --- a/src/liballoc/heap.rs +++ b/src/liballoc/heap.rs @@ -138,7 +138,9 @@ pub fn usable_size(size: usize, align: usize) -> usize { /// /// This preserves the non-null invariant for types like `Box`. The address /// may overlap with non-zero-size memory allocations. -pub const EMPTY: *mut () = 0x1 as *mut (); +#[rustc_deprecated(since = "1.19", reason = "Use Unique/Shared::empty() instead")] +#[unstable(feature = "heap_api", issue = "27700")] +pub const EMPTY: *mut () = 1 as *mut (); /// The allocator for unique pointers. // This function must not unwind. If it does, MIR trans will fail. @@ -147,7 +149,7 @@ pub const EMPTY: *mut () = 0x1 as *mut (); #[inline] unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 { if size == 0 { - EMPTY as *mut u8 + align as *mut u8 } else { let ptr = allocate(size, align); if ptr.is_null() { diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs index 1f6f5ba17ed..7edf07944ec 100644 --- a/src/liballoc/raw_vec.rs +++ b/src/liballoc/raw_vec.rs @@ -22,13 +22,13 @@ use core::cmp; /// involved. This type is excellent for building your own data structures like Vec and VecDeque. /// In particular: /// -/// * Produces heap::EMPTY on zero-sized types -/// * Produces heap::EMPTY on zero-length allocations +/// * Produces Unique::empty() on zero-sized types +/// * Produces Unique::empty() on zero-length allocations /// * Catches all overflows in capacity computations (promotes them to "capacity overflow" panics) /// * Guards against 32-bit systems allocating more than isize::MAX bytes /// * Guards against overflowing your length /// * Aborts on OOM -/// * Avoids freeing heap::EMPTY +/// * Avoids freeing Unique::empty() /// * Contains a ptr::Unique and thus endows the user with all related benefits /// /// This type does not in anyway inspect the memory that it manages. When dropped it *will* @@ -55,15 +55,13 @@ impl RawVec { /// it makes a RawVec with capacity `usize::MAX`. Useful for implementing /// delayed allocation. pub fn new() -> Self { - unsafe { - // !0 is usize::MAX. This branch should be stripped at compile time. - let cap = if mem::size_of::() == 0 { !0 } else { 0 }; + // !0 is usize::MAX. This branch should be stripped at compile time. + let cap = if mem::size_of::() == 0 { !0 } else { 0 }; - // heap::EMPTY doubles as "unallocated" and "zero-sized allocation" - RawVec { - ptr: Unique::new(heap::EMPTY as *mut T), - cap: cap, - } + // Unique::empty() doubles as "unallocated" and "zero-sized allocation" + RawVec { + ptr: Unique::empty(), + cap: cap, } } @@ -101,7 +99,7 @@ impl RawVec { // handles ZSTs and `cap = 0` alike let ptr = if alloc_size == 0 { - heap::EMPTY as *mut u8 + mem::align_of::() as *mut u8 } else { let align = mem::align_of::(); let ptr = if zeroed { @@ -148,10 +146,10 @@ impl RawVec { impl RawVec { /// Gets a raw pointer to the start of the allocation. Note that this is - /// heap::EMPTY if `cap = 0` or T is zero-sized. In the former case, you must + /// Unique::empty() if `cap = 0` or T is zero-sized. In the former case, you must /// be careful. pub fn ptr(&self) -> *mut T { - self.ptr.ptr() + self.ptr.as_ptr() } /// Gets the capacity of the allocation. diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index a3cfc15895e..321fa2edd56 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -31,7 +31,6 @@ #![feature(alloc)] #![feature(core_intrinsics)] #![feature(dropck_eyepatch)] -#![feature(heap_api)] #![feature(generic_param_attrs)] #![feature(staged_api)] #![cfg_attr(test, feature(test))] @@ -48,7 +47,6 @@ use std::mem; use std::ptr; use std::slice; -use alloc::heap; use alloc::raw_vec::RawVec; /// An arena that can hold objects of only one type. @@ -140,7 +138,7 @@ impl TypedArena { unsafe { if mem::size_of::() == 0 { self.ptr.set(intrinsics::arith_offset(self.ptr.get() as *mut u8, 1) as *mut T); - let ptr = heap::EMPTY as *mut T; + let ptr = mem::align_of::() as *mut T; // Don't drop the object. This `write` is equivalent to `forget`. ptr::write(ptr, object); &mut *ptr diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 02ad0a67bda..7ec5c29de6b 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -67,7 +67,6 @@ #![stable(feature = "rust1", since = "1.0.0")] use alloc::boxed::Box; -use alloc::heap::EMPTY; use alloc::raw_vec::RawVec; use borrow::ToOwned; use borrow::Cow; @@ -2192,7 +2191,8 @@ impl Iterator for IntoIter { self.ptr = arith_offset(self.ptr as *const i8, 1) as *mut T; // Use a non-null pointer value - Some(ptr::read(EMPTY as *mut T)) + // (self.ptr might be null because of wrapping) + Some(ptr::read(1 as *mut T)) } else { let old = self.ptr; self.ptr = self.ptr.offset(1); @@ -2231,7 +2231,8 @@ impl DoubleEndedIterator for IntoIter { self.end = arith_offset(self.end as *const i8, -1) as *mut T; // Use a non-null pointer value - Some(ptr::read(EMPTY as *mut T)) + // (self.end might be null because of wrapping) + Some(ptr::read(1 as *mut T)) } else { self.end = self.end.offset(-1); diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs index 0a488dfd53a..a15269cc87c 100644 --- a/src/libstd/collections/hash/table.rs +++ b/src/libstd/collections/hash/table.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use alloc::heap::{EMPTY, allocate, deallocate}; +use alloc::heap::{allocate, deallocate}; use cmp; use hash::{BuildHasher, Hash, Hasher}; @@ -33,6 +33,7 @@ use self::BucketState::*; type HashUint = usize; const EMPTY_BUCKET: HashUint = 0; +const EMPTY: usize = 1; /// Special `Unique` that uses the lower bit of the pointer /// to expose a boolean tag. -- cgit 1.4.1-3-g733a5 From 2f6744c5fc086fcedd6515240fce15ed641f2846 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Tue, 25 Apr 2017 11:24:06 -0400 Subject: Improve docs on Arc and Send/Sync This is something I always forget, so let's actually explain in the docs. --- src/liballoc/arc.rs | 39 +++++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 6d85183faf7..27ecefe043b 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -54,16 +54,33 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize; /// exception. If you need to mutate through an `Arc`, use [`Mutex`][mutex], /// [`RwLock`][rwlock], or one of the [`Atomic`][atomic] types. /// -/// `Arc` uses atomic operations for reference counting, so `Arc`s can be -/// sent between threads. In other words, `Arc` implements [`Send`] -/// as long as `T` implements [`Send`] and [`Sync`][sync]. The disadvantage is -/// that atomic operations are more expensive than ordinary memory accesses. -/// If you are not sharing reference-counted values between threads, consider -/// using [`rc::Rc`][`Rc`] for lower overhead. [`Rc`] is a safe default, because -/// the compiler will catch any attempt to send an [`Rc`] between threads. -/// However, a library might choose `Arc` in order to give library consumers +/// ## Thread Safety +/// +/// Unlike [`Rc`], `Arc` uses atomic operations for its reference +/// counting This means that it is thread-safe. The disadvantage is that +/// atomic operations are more expensive than ordinary memory accesses. If you +/// are not sharing reference-counted values between threads, consider using +/// [`Rc`] for lower overhead. [`Rc`] is a safe default, because the +/// compiler will catch any attempt to send an [`Rc`] between threads. +/// However, a library might choose `Arc` in order to give library consumers /// more flexibility. /// +/// `Arc` will implement [`Send`] and [`Sync`] as long as the `T` implements +/// [`Send`] and [`Sync`]. Why can't you put a non-thread-safe type `T` in an +/// `Arc` to make it thread-safe? This may be a bit counter-intuitive at +/// first: after all, isn't the point of `Arc` thread safety? The key is +/// this: `Arc` makes it thread safe to have multiple ownership of the same +/// data, but it doesn't add thread safety to its data. Consider +/// `Arc>`. `RefCell` isn't [`Sync`], and if `Arc` was always +/// [`Send`], `Arc>` would be as well. But then we'd have a problem: +/// `RefCell` is not thread safe; it keeps track of the borrowing count using +/// non-atomic operations. +/// +/// In the end, this means that you may need to pair `Arc` with some sort of +/// `std::sync` type, usually `Mutex`. +/// +/// ## Breaking cycles with `Weak` +/// /// The [`downgrade`][downgrade] method can be used to create a non-owning /// [`Weak`][weak] pointer. A [`Weak`][weak] pointer can be [`upgrade`][upgrade]d /// to an `Arc`, but this will return [`None`] if the value has already been @@ -74,6 +91,8 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize; /// strong `Arc` pointers from parent nodes to children, and [`Weak`][weak] /// pointers from children back to their parents. /// +/// ## `Deref` behavior +/// /// `Arc` automatically dereferences to `T` (via the [`Deref`][deref] trait), /// so you can call `T`'s methods on a value of type `Arc`. To avoid name /// clashes with `T`'s methods, the methods of `Arc` itself are [associated @@ -91,13 +110,13 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize; /// /// [arc]: struct.Arc.html /// [weak]: struct.Weak.html -/// [`Rc`]: ../../std/rc/struct.Rc.html +/// [`Rc`]: ../../std/rc/struct.Rc.html /// [clone]: ../../std/clone/trait.Clone.html#tymethod.clone /// [mutex]: ../../std/sync/struct.Mutex.html /// [rwlock]: ../../std/sync/struct.RwLock.html /// [atomic]: ../../std/sync/atomic/index.html /// [`Send`]: ../../std/marker/trait.Send.html -/// [sync]: ../../std/marker/trait.Sync.html +/// [`Sync`]: ../../std/marker/trait.Sync.html /// [deref]: ../../std/ops/trait.Deref.html /// [downgrade]: struct.Arc.html#method.downgrade /// [upgrade]: struct.Weak.html#method.upgrade -- cgit 1.4.1-3-g733a5 From 2f703e4304c1c9b15c616b7a08bac581af5ab430 Mon Sep 17 00:00:00 2001 From: Oliver Middleton Date: Sat, 20 May 2017 08:38:39 +0100 Subject: Correct some stability versions These were found by running tidy on stable versions of rust and finding features stabilised with the wrong version numbers. --- src/liballoc/boxed.rs | 2 +- src/libcollections/string.rs | 14 +++---- src/libcollections/vec.rs | 10 ++--- src/libcore/cell.rs | 2 +- src/libcore/iter/mod.rs | 2 +- src/libcore/num/mod.rs | 90 +++++++++++++++++++++---------------------- src/libcore/slice/mod.rs | 2 +- src/libcore/str/mod.rs | 8 ++-- src/libstd/env.rs | 4 +- src/libstd/error.rs | 6 +-- src/libstd/ffi/c_str.rs | 4 +- src/libstd/ffi/os_str.rs | 4 +- src/libstd/macros.rs | 4 +- src/libstd/net/ip.rs | 18 ++++----- src/libstd/path.rs | 6 +-- src/libstd/sync/condvar.rs | 2 +- src/libstd/sync/mpsc/mod.rs | 10 ++--- src/libstd/sync/mutex.rs | 4 +- src/libstd/sync/rwlock.rs | 2 +- src/libsyntax/feature_gate.rs | 2 +- 20 files changed, 98 insertions(+), 98 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index fc6929f896e..8a39be8fae8 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -445,7 +445,7 @@ impl<'a> From<&'a str> for Box { } } -#[stable(feature = "boxed_str_conv", since = "1.18.0")] +#[stable(feature = "boxed_str_conv", since = "1.19.0")] impl From> for Box<[u8]> { fn from(s: Box) -> Self { unsafe { diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index 31ab04e9f3b..55f0e01548f 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -1869,28 +1869,28 @@ impl ops::Index> for String { } } -#[stable(feature = "derefmut_for_string", since = "1.2.0")] +#[stable(feature = "derefmut_for_string", since = "1.3.0")] impl ops::IndexMut> for String { #[inline] fn index_mut(&mut self, index: ops::Range) -> &mut str { &mut self[..][index] } } -#[stable(feature = "derefmut_for_string", since = "1.2.0")] +#[stable(feature = "derefmut_for_string", since = "1.3.0")] impl ops::IndexMut> for String { #[inline] fn index_mut(&mut self, index: ops::RangeTo) -> &mut str { &mut self[..][index] } } -#[stable(feature = "derefmut_for_string", since = "1.2.0")] +#[stable(feature = "derefmut_for_string", since = "1.3.0")] impl ops::IndexMut> for String { #[inline] fn index_mut(&mut self, index: ops::RangeFrom) -> &mut str { &mut self[..][index] } } -#[stable(feature = "derefmut_for_string", since = "1.2.0")] +#[stable(feature = "derefmut_for_string", since = "1.3.0")] impl ops::IndexMut for String { #[inline] fn index_mut(&mut self, _index: ops::RangeFull) -> &mut str { @@ -1922,7 +1922,7 @@ impl ops::Deref for String { } } -#[stable(feature = "derefmut_for_string", since = "1.2.0")] +#[stable(feature = "derefmut_for_string", since = "1.3.0")] impl ops::DerefMut for String { #[inline] fn deref_mut(&mut self) -> &mut str { @@ -2080,14 +2080,14 @@ impl<'a> From<&'a str> for String { // note: test pulls in libstd, which causes errors here #[cfg(not(test))] -#[stable(feature = "string_from_box", since = "1.17.0")] +#[stable(feature = "string_from_box", since = "1.18.0")] impl From> for String { fn from(s: Box) -> String { s.into_string() } } -#[stable(feature = "box_from_str", since = "1.17.0")] +#[stable(feature = "box_from_str", since = "1.18.0")] impl Into> for String { fn into(self) -> Box { self.into_boxed_str() diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 7ec5c29de6b..38bc8104cd7 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -2034,7 +2034,7 @@ impl<'a, T: Clone> From<&'a [T]> for Vec { } } -#[stable(feature = "vec_from_mut", since = "1.21.0")] +#[stable(feature = "vec_from_mut", since = "1.19.0")] impl<'a, T: Clone> From<&'a mut [T]> for Vec { #[cfg(not(test))] fn from(s: &'a mut [T]) -> Vec { @@ -2055,14 +2055,14 @@ impl<'a, T> From> for Vec where [T]: ToOwned> { // note: test pulls in libstd, which causes errors here #[cfg(not(test))] -#[stable(feature = "vec_from_box", since = "1.17.0")] +#[stable(feature = "vec_from_box", since = "1.18.0")] impl From> for Vec { fn from(s: Box<[T]>) -> Vec { s.into_vec() } } -#[stable(feature = "box_from_vec", since = "1.17.0")] +#[stable(feature = "box_from_vec", since = "1.18.0")] impl Into> for Vec { fn into(self) -> Box<[T]> { self.into_boxed_slice() @@ -2080,14 +2080,14 @@ impl<'a> From<&'a str> for Vec { // Clone-on-write //////////////////////////////////////////////////////////////////////////////// -#[stable(feature = "cow_from_vec", since = "1.7.0")] +#[stable(feature = "cow_from_vec", since = "1.8.0")] impl<'a, T: Clone> From<&'a [T]> for Cow<'a, [T]> { fn from(s: &'a [T]) -> Cow<'a, [T]> { Cow::Borrowed(s) } } -#[stable(feature = "cow_from_vec", since = "1.7.0")] +#[stable(feature = "cow_from_vec", since = "1.8.0")] impl<'a, T: Clone> From> for Cow<'a, [T]> { fn from(v: Vec) -> Cow<'a, [T]> { Cow::Owned(v) diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 7886f90b66e..ea480f38947 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -1145,7 +1145,7 @@ impl UnsafeCell { } } -#[stable(feature = "unsafe_cell_default", since = "1.9.0")] +#[stable(feature = "unsafe_cell_default", since = "1.10.0")] impl Default for UnsafeCell { /// Creates an `UnsafeCell`, with the `Default` value for T. fn default() -> UnsafeCell { diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index 273f9d0e6f6..b90d08f948e 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -1655,7 +1655,7 @@ impl Iterator for Skip where I: Iterator { #[stable(feature = "rust1", since = "1.0.0")] impl ExactSizeIterator for Skip where I: ExactSizeIterator {} -#[stable(feature = "double_ended_skip_iterator", since = "1.8.0")] +#[stable(feature = "double_ended_skip_iterator", since = "1.9.0")] impl DoubleEndedIterator for Skip where I: DoubleEndedIterator + ExactSizeIterator { fn next_back(&mut self) -> Option { if self.len() > 0 { diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 8b4002fe9af..be093cca6a1 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -2682,8 +2682,8 @@ pub use num::dec2flt::ParseFloatError; // Conversions T -> T are covered by a blanket impl and therefore excluded // Some conversions from and to usize/isize are not implemented due to portability concerns macro_rules! impl_from { - ($Small: ty, $Large: ty) => { - #[stable(feature = "lossless_prim_conv", since = "1.5.0")] + ($Small: ty, $Large: ty, #[$attr:meta]) => { + #[$attr] impl From<$Small> for $Large { #[inline] fn from(small: $Small) -> $Large { @@ -2694,60 +2694,60 @@ macro_rules! impl_from { } // Unsigned -> Unsigned -impl_from! { u8, u16 } -impl_from! { u8, u32 } -impl_from! { u8, u64 } -impl_from! { u8, u128 } -impl_from! { u8, usize } -impl_from! { u16, u32 } -impl_from! { u16, u64 } -impl_from! { u16, u128 } -impl_from! { u32, u64 } -impl_from! { u32, u128 } -impl_from! { u64, u128 } +impl_from! { u8, u16, #[stable(feature = "lossless_int_conv", since = "1.5.0")] } +impl_from! { u8, u32, #[stable(feature = "lossless_int_conv", since = "1.5.0")] } +impl_from! { u8, u64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] } +impl_from! { u8, u128, #[unstable(feature = "i128", issue = "35118")] } +impl_from! { u8, usize, #[stable(feature = "lossless_int_conv", since = "1.5.0")] } +impl_from! { u16, u32, #[stable(feature = "lossless_int_conv", since = "1.5.0")] } +impl_from! { u16, u64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] } +impl_from! { u16, u128, #[unstable(feature = "i128", issue = "35118")] } +impl_from! { u32, u64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] } +impl_from! { u32, u128, #[unstable(feature = "i128", issue = "35118")] } +impl_from! { u64, u128, #[unstable(feature = "i128", issue = "35118")] } // Signed -> Signed -impl_from! { i8, i16 } -impl_from! { i8, i32 } -impl_from! { i8, i64 } -impl_from! { i8, i128 } -impl_from! { i8, isize } -impl_from! { i16, i32 } -impl_from! { i16, i64 } -impl_from! { i16, i128 } -impl_from! { i32, i64 } -impl_from! { i32, i128 } -impl_from! { i64, i128 } +impl_from! { i8, i16, #[stable(feature = "lossless_int_conv", since = "1.5.0")] } +impl_from! { i8, i32, #[stable(feature = "lossless_int_conv", since = "1.5.0")] } +impl_from! { i8, i64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] } +impl_from! { i8, i128, #[unstable(feature = "i128", issue = "35118")] } +impl_from! { i8, isize, #[stable(feature = "lossless_int_conv", since = "1.5.0")] } +impl_from! { i16, i32, #[stable(feature = "lossless_int_conv", since = "1.5.0")] } +impl_from! { i16, i64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] } +impl_from! { i16, i128, #[unstable(feature = "i128", issue = "35118")] } +impl_from! { i32, i64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] } +impl_from! { i32, i128, #[unstable(feature = "i128", issue = "35118")] } +impl_from! { i64, i128, #[unstable(feature = "i128", issue = "35118")] } // Unsigned -> Signed -impl_from! { u8, i16 } -impl_from! { u8, i32 } -impl_from! { u8, i64 } -impl_from! { u8, i128 } -impl_from! { u16, i32 } -impl_from! { u16, i64 } -impl_from! { u16, i128 } -impl_from! { u32, i64 } -impl_from! { u32, i128 } -impl_from! { u64, i128 } +impl_from! { u8, i16, #[stable(feature = "lossless_int_conv", since = "1.5.0")] } +impl_from! { u8, i32, #[stable(feature = "lossless_int_conv", since = "1.5.0")] } +impl_from! { u8, i64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] } +impl_from! { u8, i128, #[unstable(feature = "i128", issue = "35118")] } +impl_from! { u16, i32, #[stable(feature = "lossless_int_conv", since = "1.5.0")] } +impl_from! { u16, i64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] } +impl_from! { u16, i128, #[unstable(feature = "i128", issue = "35118")] } +impl_from! { u32, i64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] } +impl_from! { u32, i128, #[unstable(feature = "i128", issue = "35118")] } +impl_from! { u64, i128, #[unstable(feature = "i128", issue = "35118")] } // Note: integers can only be represented with full precision in a float if // they fit in the significand, which is 24 bits in f32 and 53 bits in f64. // Lossy float conversions are not implemented at this time. // Signed -> Float -impl_from! { i8, f32 } -impl_from! { i8, f64 } -impl_from! { i16, f32 } -impl_from! { i16, f64 } -impl_from! { i32, f64 } +impl_from! { i8, f32, #[stable(feature = "lossless_float_conv", since = "1.6.0")] } +impl_from! { i8, f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")] } +impl_from! { i16, f32, #[stable(feature = "lossless_float_conv", since = "1.6.0")] } +impl_from! { i16, f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")] } +impl_from! { i32, f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")] } // Unsigned -> Float -impl_from! { u8, f32 } -impl_from! { u8, f64 } -impl_from! { u16, f32 } -impl_from! { u16, f64 } -impl_from! { u32, f64 } +impl_from! { u8, f32, #[stable(feature = "lossless_float_conv", since = "1.6.0")] } +impl_from! { u8, f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")] } +impl_from! { u16, f32, #[stable(feature = "lossless_float_conv", since = "1.6.0")] } +impl_from! { u16, f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")] } +impl_from! { u32, f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")] } // Float -> Float -impl_from! { f32, f64 } +impl_from! { f32, f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")] } diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index e15eb8f2444..24ebfeb62e2 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -1450,7 +1450,7 @@ impl<'a, T> Clone for Iter<'a, T> { fn clone(&self) -> Iter<'a, T> { Iter { ptr: self.ptr, end: self.end, _marker: self._marker } } } -#[stable(feature = "slice_iter_as_ref", since = "1.12.0")] +#[stable(feature = "slice_iter_as_ref", since = "1.13.0")] impl<'a, T> AsRef<[T]> for Iter<'a, T> { fn as_ref(&self) -> &[T] { self.as_slice() diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 6b627430904..7fb941c091f 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -1597,7 +1597,7 @@ mod traits { /// byte offset of a character (as defined by `is_char_boundary`). /// Requires that `begin <= end` and `end <= len` where `len` is the /// length of the string. - #[stable(feature = "derefmut_for_string", since = "1.2.0")] + #[stable(feature = "derefmut_for_string", since = "1.3.0")] impl ops::IndexMut> for str { #[inline] fn index_mut(&mut self, index: ops::Range) -> &mut str { @@ -1632,7 +1632,7 @@ mod traits { /// `end`. /// /// Equivalent to `&mut self[0 .. end]`. - #[stable(feature = "derefmut_for_string", since = "1.2.0")] + #[stable(feature = "derefmut_for_string", since = "1.3.0")] impl ops::IndexMut> for str { #[inline] fn index_mut(&mut self, index: ops::RangeTo) -> &mut str { @@ -1672,7 +1672,7 @@ mod traits { /// to the end of the string. /// /// Equivalent to `&mut self[begin .. len]`. - #[stable(feature = "derefmut_for_string", since = "1.2.0")] + #[stable(feature = "derefmut_for_string", since = "1.3.0")] impl ops::IndexMut> for str { #[inline] fn index_mut(&mut self, index: ops::RangeFrom) -> &mut str { @@ -1708,7 +1708,7 @@ mod traits { /// never panic. /// /// Equivalent to `&mut self[0 .. len]`. - #[stable(feature = "derefmut_for_string", since = "1.2.0")] + #[stable(feature = "derefmut_for_string", since = "1.3.0")] impl ops::IndexMut for str { #[inline] fn index_mut(&mut self, _index: ops::RangeFull) -> &mut str { diff --git a/src/libstd/env.rs b/src/libstd/env.rs index 64eb52e28bc..27255bef849 100644 --- a/src/libstd/env.rs +++ b/src/libstd/env.rs @@ -680,7 +680,7 @@ impl ExactSizeIterator for Args { fn is_empty(&self) -> bool { self.inner.is_empty() } } -#[stable(feature = "env_iterators", since = "1.11.0")] +#[stable(feature = "env_iterators", since = "1.12.0")] impl DoubleEndedIterator for Args { fn next_back(&mut self) -> Option { self.inner.next_back().map(|s| s.into_string().unwrap()) @@ -707,7 +707,7 @@ impl ExactSizeIterator for ArgsOs { fn is_empty(&self) -> bool { self.inner.is_empty() } } -#[stable(feature = "env_iterators", since = "1.11.0")] +#[stable(feature = "env_iterators", since = "1.12.0")] impl DoubleEndedIterator for ArgsOs { fn next_back(&mut self) -> Option { self.inner.next_back() } } diff --git a/src/libstd/error.rs b/src/libstd/error.rs index 9ff7d746733..f56e3a5d780 100644 --- a/src/libstd/error.rs +++ b/src/libstd/error.rs @@ -193,7 +193,7 @@ impl From for Box { } } -#[stable(feature = "string_box_error", since = "1.7.0")] +#[stable(feature = "string_box_error", since = "1.6.0")] impl From for Box { fn from(str_err: String) -> Box { let err1: Box = From::from(str_err); @@ -209,7 +209,7 @@ impl<'a, 'b> From<&'b str> for Box { } } -#[stable(feature = "string_box_error", since = "1.7.0")] +#[stable(feature = "string_box_error", since = "1.6.0")] impl<'a> From<&'a str> for Box { fn from(err: &'a str) -> Box { From::from(String::from(err)) @@ -282,7 +282,7 @@ impl Error for char::DecodeUtf16Error { } } -#[stable(feature = "box_error", since = "1.7.0")] +#[stable(feature = "box_error", since = "1.8.0")] impl Error for Box { fn description(&self) -> &str { Error::description(&**self) diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index 44b62593fa3..f40475a4142 100644 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@ -419,14 +419,14 @@ impl<'a> From<&'a CStr> for Box { } } -#[stable(feature = "c_string_from_box", since = "1.17.0")] +#[stable(feature = "c_string_from_box", since = "1.18.0")] impl From> for CString { fn from(s: Box) -> CString { s.into_c_string() } } -#[stable(feature = "box_from_c_string", since = "1.17.0")] +#[stable(feature = "box_from_c_string", since = "1.18.0")] impl Into> for CString { fn into(self) -> Box { self.into_boxed_c_str() diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs index b90192dd8af..eaf0502a577 100644 --- a/src/libstd/ffi/os_str.rs +++ b/src/libstd/ffi/os_str.rs @@ -529,14 +529,14 @@ impl<'a> From<&'a OsStr> for Box { } } -#[stable(feature = "os_string_from_box", since = "1.17.0")] +#[stable(feature = "os_string_from_box", since = "1.18.0")] impl<'a> From> for OsString { fn from(boxed: Box) -> OsString { boxed.into_os_string() } } -#[stable(feature = "box_from_c_string", since = "1.17.0")] +#[stable(feature = "box_from_os_string", since = "1.18.0")] impl Into> for OsString { fn into(self) -> Box { self.into_boxed_os_str() diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index ef78ea6dfe8..df3fce0da76 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -143,7 +143,7 @@ macro_rules! println { /// /// Panics if writing to `io::stderr` fails. #[macro_export] -#[stable(feature = "eprint", since="1.18.0")] +#[stable(feature = "eprint", since = "1.19.0")] #[allow_internal_unstable] macro_rules! eprint { ($($arg:tt)*) => ($crate::io::_eprint(format_args!($($arg)*))); @@ -162,7 +162,7 @@ macro_rules! eprint { /// /// Panics if writing to `io::stderr` fails. #[macro_export] -#[stable(feature = "eprint", since="1.18.0")] +#[stable(feature = "eprint", since = "1.19.0")] macro_rules! eprintln { () => (eprint!("\n")); ($fmt:expr) => (eprint!(concat!($fmt, "\n"))); diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs index c46fe4a58c7..1e5368896af 100644 --- a/src/libstd/net/ip.rs +++ b/src/libstd/net/ip.rs @@ -657,7 +657,7 @@ impl PartialEq for Ipv4Addr { } } -#[stable(feature = "ip_cmp", since = "1.15.0")] +#[stable(feature = "ip_cmp", since = "1.16.0")] impl PartialEq for IpAddr { fn eq(&self, other: &Ipv4Addr) -> bool { match *self { @@ -667,7 +667,7 @@ impl PartialEq for IpAddr { } } -#[stable(feature = "ip_cmp", since = "1.15.0")] +#[stable(feature = "ip_cmp", since = "1.16.0")] impl PartialEq for Ipv4Addr { fn eq(&self, other: &IpAddr) -> bool { match *other { @@ -694,7 +694,7 @@ impl PartialOrd for Ipv4Addr { } } -#[stable(feature = "ip_cmp", since = "1.15.0")] +#[stable(feature = "ip_cmp", since = "1.16.0")] impl PartialOrd for IpAddr { fn partial_cmp(&self, other: &Ipv4Addr) -> Option { match *self { @@ -704,7 +704,7 @@ impl PartialOrd for IpAddr { } } -#[stable(feature = "ip_cmp", since = "1.15.0")] +#[stable(feature = "ip_cmp", since = "1.16.0")] impl PartialOrd for Ipv4Addr { fn partial_cmp(&self, other: &IpAddr) -> Option { match *other { @@ -1200,7 +1200,7 @@ impl PartialEq for Ipv6Addr { } } -#[stable(feature = "ip_cmp", since = "1.15.0")] +#[stable(feature = "ip_cmp", since = "1.16.0")] impl PartialEq for Ipv6Addr { fn eq(&self, other: &IpAddr) -> bool { match *other { @@ -1210,7 +1210,7 @@ impl PartialEq for Ipv6Addr { } } -#[stable(feature = "ip_cmp", since = "1.15.0")] +#[stable(feature = "ip_cmp", since = "1.16.0")] impl PartialEq for IpAddr { fn eq(&self, other: &Ipv6Addr) -> bool { match *self { @@ -1237,7 +1237,7 @@ impl PartialOrd for Ipv6Addr { } } -#[stable(feature = "ip_cmp", since = "1.15.0")] +#[stable(feature = "ip_cmp", since = "1.16.0")] impl PartialOrd for IpAddr { fn partial_cmp(&self, other: &Ipv6Addr) -> Option { match *self { @@ -1247,7 +1247,7 @@ impl PartialOrd for IpAddr { } } -#[stable(feature = "ip_cmp", since = "1.15.0")] +#[stable(feature = "ip_cmp", since = "1.16.0")] impl PartialOrd for Ipv6Addr { fn partial_cmp(&self, other: &IpAddr) -> Option { match *other { @@ -1302,7 +1302,7 @@ impl From<[u8; 16]> for Ipv6Addr { } } -#[stable(feature = "ipv6_from_segments", since = "1.15.0")] +#[stable(feature = "ipv6_from_segments", since = "1.16.0")] impl From<[u16; 8]> for Ipv6Addr { fn from(segments: [u16; 8]) -> Ipv6Addr { let [a, b, c, d, e, f, g, h] = segments; diff --git a/src/libstd/path.rs b/src/libstd/path.rs index f4b9a8972e3..e7d8c3007f6 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -1341,14 +1341,14 @@ impl<'a> From<&'a Path> for Box { } } -#[stable(feature = "path_buf_from_box", since = "1.17.0")] +#[stable(feature = "path_buf_from_box", since = "1.18.0")] impl<'a> From> for PathBuf { fn from(boxed: Box) -> PathBuf { boxed.into_path_buf() } } -#[stable(feature = "box_from_path_buf", since = "1.17.0")] +#[stable(feature = "box_from_path_buf", since = "1.18.0")] impl Into> for PathBuf { fn into(self) -> Box { self.into_boxed_path() @@ -1424,7 +1424,7 @@ impl Borrow for PathBuf { } } -#[stable(feature = "default_for_pathbuf", since = "1.16.0")] +#[stable(feature = "default_for_pathbuf", since = "1.17.0")] impl Default for PathBuf { fn default() -> Self { PathBuf::new() diff --git a/src/libstd/sync/condvar.rs b/src/libstd/sync/condvar.rs index 7ad9d9ee37c..c120a3045e4 100644 --- a/src/libstd/sync/condvar.rs +++ b/src/libstd/sync/condvar.rs @@ -461,7 +461,7 @@ impl fmt::Debug for Condvar { } } -#[stable(feature = "condvar_default", since = "1.9.0")] +#[stable(feature = "condvar_default", since = "1.10.0")] impl Default for Condvar { /// Creates a `Condvar` which is ready to be waited on and notified. fn default() -> Condvar { diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs index 2cb649ce67b..f7fb83aa3b9 100644 --- a/src/libstd/sync/mpsc/mod.rs +++ b/src/libstd/sync/mpsc/mod.rs @@ -921,7 +921,7 @@ impl Drop for Sender { } } -#[stable(feature = "mpsc_debug", since = "1.7.0")] +#[stable(feature = "mpsc_debug", since = "1.8.0")] impl fmt::Debug for Sender { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Sender {{ .. }}") @@ -1051,7 +1051,7 @@ impl Drop for SyncSender { } } -#[stable(feature = "mpsc_debug", since = "1.7.0")] +#[stable(feature = "mpsc_debug", since = "1.8.0")] impl fmt::Debug for SyncSender { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "SyncSender {{ .. }}") @@ -1517,7 +1517,7 @@ impl Drop for Receiver { } } -#[stable(feature = "mpsc_debug", since = "1.7.0")] +#[stable(feature = "mpsc_debug", since = "1.8.0")] impl fmt::Debug for Receiver { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Receiver {{ .. }}") @@ -1644,7 +1644,7 @@ impl error::Error for TryRecvError { } } -#[stable(feature = "mpsc_recv_timeout_error", since = "1.14.0")] +#[stable(feature = "mpsc_recv_timeout_error", since = "1.15.0")] impl fmt::Display for RecvTimeoutError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { @@ -1658,7 +1658,7 @@ impl fmt::Display for RecvTimeoutError { } } -#[stable(feature = "mpsc_recv_timeout_error", since = "1.14.0")] +#[stable(feature = "mpsc_recv_timeout_error", since = "1.15.0")] impl error::Error for RecvTimeoutError { fn description(&self) -> &str { match *self { diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs index 5c3eaa4668d..9a242a96d46 100644 --- a/src/libstd/sync/mutex.rs +++ b/src/libstd/sync/mutex.rs @@ -153,7 +153,7 @@ pub struct MutexGuard<'a, T: ?Sized + 'a> { #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T: ?Sized> !Send for MutexGuard<'a, T> { } -#[stable(feature = "mutexguard", since = "1.18.0")] +#[stable(feature = "mutexguard", since = "1.19.0")] unsafe impl<'a, T: ?Sized + Sync> Sync for MutexGuard<'a, T> { } impl Mutex { @@ -372,7 +372,7 @@ unsafe impl<#[may_dangle] T: ?Sized> Drop for Mutex { } } -#[stable(feature = "mutex_default", since = "1.9.0")] +#[stable(feature = "mutex_default", since = "1.10.0")] impl Default for Mutex { /// Creates a `Mutex`, with the `Default` value for T. fn default() -> Mutex { diff --git a/src/libstd/sync/rwlock.rs b/src/libstd/sync/rwlock.rs index d26f2f7bb7e..95bc8d30932 100644 --- a/src/libstd/sync/rwlock.rs +++ b/src/libstd/sync/rwlock.rs @@ -330,7 +330,7 @@ impl fmt::Debug for RwLock { } } -#[stable(feature = "rw_lock_default", since = "1.9.0")] +#[stable(feature = "rw_lock_default", since = "1.10.0")] impl Default for RwLock { /// Creates a new `RwLock`, with the `Default` value for T. fn default() -> RwLock { diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index b6a2c983fd4..d06a4807ac2 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -410,7 +410,7 @@ declare_features! ( (accepted, question_mark, "1.13.0", Some(31436)), // Allows `..` in tuple (struct) patterns (accepted, dotdot_in_tuple_patterns, "1.14.0", Some(33627)), - (accepted, item_like_imports, "1.14.0", Some(35120)), + (accepted, item_like_imports, "1.15.0", Some(35120)), // Allows using `Self` and associated types in struct expressions and patterns. (accepted, more_struct_aliases, "1.16.0", Some(37544)), // elide `'static` lifetimes in `static`s and `const`s -- cgit 1.4.1-3-g733a5