From 8e1f792ccf600ab523b3d52515ffb7ae86d156a7 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Tue, 16 Aug 2016 10:57:22 -0700 Subject: [PATCH 01/43] Bump boostrap compilers --- src/stage0.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/stage0.txt b/src/stage0.txt index aaf88a67d2749..b07347cfa685a 100644 --- a/src/stage0.txt +++ b/src/stage0.txt @@ -12,6 +12,6 @@ # tarball for a stable release you'll likely see `1.x.0-$date` where `1.x.0` was # released on `$date` -rustc: beta-2016-07-06 -rustc_key: 411fd48b +rustc: 1.11.0-2016-08-16 +rustc_key: 39b92f95 cargo: nightly-2016-07-05 From 4ce3c862d50d11d90cbf58e1a0444dbe72792976 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 11 Aug 2016 14:08:24 -0700 Subject: [PATCH 02/43] std: Stabilize APIs for the 1.12 release Stabilized * `Cell::as_ptr` * `RefCell::as_ptr` * `IpAddr::is_{unspecified,loopback,multicast}` * `Ipv6Addr::octets` * `LinkedList::contains` * `VecDeque::contains` * `ExitStatusExt::from_raw` - both on Unix and Windows * `Receiver::recv_timeout` * `RecvTimeoutError` * `BinaryHeap::peek_mut` * `PeekMut` * `iter::Product` * `iter::Sum` * `OccupiedEntry::remove_entry` * `VacantEntry::into_key` Deprecated * `Cell::as_unsafe_cell` * `RefCell::as_unsafe_cell` * `OccupiedEntry::remove_pair` Closes #27708 cc #27709 Closes #32313 Closes #32630 Closes #32713 Closes #34029 Closes #34392 Closes #34285 Closes #34529 --- src/libcollections/binary_heap.rs | 11 ++++---- src/libcollections/btree/map.rs | 19 ++++++++------ src/libcollections/linked_list.rs | 5 +--- src/libcollections/vec_deque.rs | 5 +--- src/libcollectionstest/lib.rs | 3 --- src/libcore/cell.rs | 36 +++++++++++++++++++++++++++ src/libcore/iter/traits.rs | 22 ++++++++-------- src/libcoretest/cell.rs | 10 ++++---- src/libcoretest/lib.rs | 1 - src/libstd/collections/hash/map.rs | 19 ++++++++------ src/libstd/net/ip.rs | 15 ++++------- src/libstd/sync/mpsc/mod.rs | 8 +++--- src/libstd/sys/unix/ext/process.rs | 2 +- src/libstd/sys/windows/ext/process.rs | 3 ++- src/libtest/lib.rs | 1 - 15 files changed, 94 insertions(+), 66 deletions(-) diff --git a/src/libcollections/binary_heap.rs b/src/libcollections/binary_heap.rs index b9f5c6fcab909..fe9b60c393f09 100644 --- a/src/libcollections/binary_heap.rs +++ b/src/libcollections/binary_heap.rs @@ -223,19 +223,19 @@ pub struct BinaryHeap { /// on `BinaryHeap`. See its documentation for details. /// /// [`peek_mut()`]: struct.BinaryHeap.html#method.peek_mut -#[unstable(feature = "binary_heap_peek_mut", issue = "34392")] +#[stable(feature = "binary_heap_peek_mut", since = "1.12.0")] pub struct PeekMut<'a, T: 'a + Ord> { heap: &'a mut BinaryHeap } -#[unstable(feature = "binary_heap_peek_mut", issue = "34392")] +#[stable(feature = "binary_heap_peek_mut", since = "1.12.0")] impl<'a, T: Ord> Drop for PeekMut<'a, T> { fn drop(&mut self) { self.heap.sift_down(0); } } -#[unstable(feature = "binary_heap_peek_mut", issue = "34392")] +#[stable(feature = "binary_heap_peek_mut", since = "1.12.0")] impl<'a, T: Ord> Deref for PeekMut<'a, T> { type Target = T; fn deref(&self) -> &T { @@ -243,7 +243,7 @@ impl<'a, T: Ord> Deref for PeekMut<'a, T> { } } -#[unstable(feature = "binary_heap_peek_mut", issue = "34392")] +#[stable(feature = "binary_heap_peek_mut", since = "1.12.0")] impl<'a, T: Ord> DerefMut for PeekMut<'a, T> { fn deref_mut(&mut self) -> &mut T { &mut self.heap.data[0] @@ -366,7 +366,6 @@ impl BinaryHeap { /// Basic usage: /// /// ``` - /// #![feature(binary_heap_peek_mut)] /// use std::collections::BinaryHeap; /// let mut heap = BinaryHeap::new(); /// assert!(heap.peek_mut().is_none()); @@ -380,7 +379,7 @@ impl BinaryHeap { /// } /// assert_eq!(heap.peek(), Some(&2)); /// ``` - #[unstable(feature = "binary_heap_peek_mut", issue = "34392")] + #[stable(feature = "binary_heap_peek_mut", since = "1.12.0")] pub fn peek_mut(&mut self) -> Option> { if self.is_empty() { None diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs index c3a7d4023754a..a2e2ad37acb84 100644 --- a/src/libcollections/btree/map.rs +++ b/src/libcollections/btree/map.rs @@ -1981,8 +1981,6 @@ impl<'a, K: Ord, V> VacantEntry<'a, K, V> { /// # Examples /// /// ``` - /// #![feature(map_entry_recover_keys)] - /// /// use std::collections::BTreeMap; /// use std::collections::btree_map::Entry; /// @@ -1992,7 +1990,7 @@ impl<'a, K: Ord, V> VacantEntry<'a, K, V> { /// v.into_key(); /// } /// ``` - #[unstable(feature = "map_entry_recover_keys", issue = "34285")] + #[stable(feature = "map_entry_recover_keys2", since = "1.12.0")] pub fn into_key(self) -> K { self.key } @@ -2074,13 +2072,18 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> { self.handle.reborrow().into_kv().0 } + /// Deprecated, renamed to `remove_entry` + #[unstable(feature = "map_entry_recover_keys", issue = "34285")] + #[rustc_deprecated(since = "1.12.0", reason = "renamed to `remove_entry`")] + pub fn remove_pair(self) -> (K, V) { + self.remove_entry() + } + /// Take ownership of the key and value from the map. /// /// # Examples /// /// ``` - /// #![feature(map_entry_recover_keys)] - /// /// use std::collections::BTreeMap; /// use std::collections::btree_map::Entry; /// @@ -2089,14 +2092,14 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> { /// /// if let Entry::Occupied(o) = map.entry("poneyland") { /// // We delete the entry from the map. - /// o.remove_pair(); + /// o.remove_entry(); /// } /// /// // If now try to get the value, it will panic: /// // println!("{}", map["poneyland"]); /// ``` - #[unstable(feature = "map_entry_recover_keys", issue = "34285")] - pub fn remove_pair(self) -> (K, V) { + #[stable(feature = "map_entry_recover_keys2", since = "1.12.0")] + pub fn remove_entry(self) -> (K, V) { self.remove_kv() } diff --git a/src/libcollections/linked_list.rs b/src/libcollections/linked_list.rs index 6842f02e0e19b..73aa67849fd2a 100644 --- a/src/libcollections/linked_list.rs +++ b/src/libcollections/linked_list.rs @@ -379,8 +379,6 @@ impl LinkedList { /// # Examples /// /// ``` - /// #![feature(linked_list_contains)] - /// /// use std::collections::LinkedList; /// /// let mut list: LinkedList = LinkedList::new(); @@ -392,8 +390,7 @@ impl LinkedList { /// assert_eq!(list.contains(&0), true); /// assert_eq!(list.contains(&10), false); /// ``` - #[unstable(feature = "linked_list_contains", reason = "recently added", - issue = "32630")] + #[stable(feature = "linked_list_contains", since = "1.12.0")] pub fn contains(&self, x: &T) -> bool where T: PartialEq { diff --git a/src/libcollections/vec_deque.rs b/src/libcollections/vec_deque.rs index 9c3792afa2f1c..aa42daec4c2d1 100644 --- a/src/libcollections/vec_deque.rs +++ b/src/libcollections/vec_deque.rs @@ -938,8 +938,6 @@ impl VecDeque { /// # Examples /// /// ``` - /// #![feature(vec_deque_contains)] - /// /// use std::collections::VecDeque; /// /// let mut vector: VecDeque = VecDeque::new(); @@ -950,8 +948,7 @@ impl VecDeque { /// assert_eq!(vector.contains(&1), true); /// assert_eq!(vector.contains(&10), false); /// ``` - #[unstable(feature = "vec_deque_contains", reason = "recently added", - issue = "32630")] + #[stable(feature = "vec_deque_contains", since = "1.12.0")] pub fn contains(&self, x: &T) -> bool where T: PartialEq { diff --git a/src/libcollectionstest/lib.rs b/src/libcollectionstest/lib.rs index ab3231b2b9955..f448fcf2dbf99 100644 --- a/src/libcollectionstest/lib.rs +++ b/src/libcollectionstest/lib.rs @@ -11,7 +11,6 @@ #![deny(warnings)] #![feature(binary_heap_extras)] -#![feature(binary_heap_peek_mut)] #![feature(box_syntax)] #![feature(btree_range)] #![feature(collections)] @@ -19,7 +18,6 @@ #![feature(const_fn)] #![feature(fn_traits)] #![feature(enumset)] -#![feature(linked_list_contains)] #![feature(pattern)] #![feature(rand)] #![feature(step_by)] @@ -27,7 +25,6 @@ #![feature(test)] #![feature(unboxed_closures)] #![feature(unicode)] -#![feature(vec_deque_contains)] #![feature(vec_into_iter_as_slice)] extern crate collections; diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 17ec325e257b0..a388012e1daf2 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -233,10 +233,28 @@ impl Cell { /// ``` #[inline] #[unstable(feature = "as_unsafe_cell", issue = "27708")] + #[rustc_deprecated(since = "1.12.0", reason = "renamed to as_ptr")] pub fn as_unsafe_cell(&self) -> &UnsafeCell { &self.value } + /// Returns a raw pointer to the underlying data in this cell. + /// + /// # Examples + /// + /// ``` + /// use std::cell::Cell; + /// + /// let c = Cell::new(5); + /// + /// let ptr = c.as_ptr(); + /// ``` + #[inline] + #[stable(feature = "cell_as_ptr", since = "1.12.0")] + pub fn as_ptr(&self) -> *mut T { + self.value.get() + } + /// Returns a mutable reference to the underlying data. /// /// This call borrows `Cell` mutably (at compile-time) which guarantees @@ -653,10 +671,28 @@ impl RefCell { /// ``` #[inline] #[unstable(feature = "as_unsafe_cell", issue = "27708")] + #[rustc_deprecated(since = "1.12.0", reason = "renamed to as_ptr")] pub unsafe fn as_unsafe_cell(&self) -> &UnsafeCell { &self.value } + /// Returns a raw pointer to the underlying data in this cell. + /// + /// # Examples + /// + /// ``` + /// use std::cell::RefCell; + /// + /// let c = RefCell::new(5); + /// + /// let ptr = c.as_ptr(); + /// ``` + #[inline] + #[stable(feature = "cell_as_ptr", since = "1.12.0")] + pub fn as_ptr(&self) -> *mut T { + self.value.get() + } + /// Returns a mutable reference to the underlying data. /// /// This call borrows `RefCell` mutably (at compile-time) so there is no diff --git a/src/libcore/iter/traits.rs b/src/libcore/iter/traits.rs index 4cbabe3f5edaf..cb509156e325e 100644 --- a/src/libcore/iter/traits.rs +++ b/src/libcore/iter/traits.rs @@ -563,10 +563,11 @@ impl<'a, I: ExactSizeIterator + ?Sized> ExactSizeIterator for &'a mut I {} /// implement the trait can be generated by the `sum` method. Like /// `FromIterator` this trait should rarely be called directly and instead /// interacted with through `Iterator::sum`. -#[unstable(feature = "iter_arith_traits", issue = "34529")] +#[stable(feature = "iter_arith_traits", since = "1.12.0")] pub trait Sum: Sized { /// Method which takes an iterator and generates `Self` from the elements by /// "summing up" the items. + #[stable(feature = "iter_arith_traits", since = "1.12.0")] fn sum>(iter: I) -> Self; } @@ -577,16 +578,17 @@ pub trait Sum: Sized { /// which implement the trait can be generated by the `product` method. Like /// `FromIterator` this trait should rarely be called directly and instead /// interacted with through `Iterator::product`. -#[unstable(feature = "iter_arith_traits", issue = "34529")] +#[stable(feature = "iter_arith_traits", since = "1.12.0")] pub trait Product: Sized { /// Method which takes an iterator and generates `Self` from the elements by /// multiplying the items. + #[stable(feature = "iter_arith_traits", since = "1.12.0")] fn product>(iter: I) -> Self; } macro_rules! integer_sum_product { ($($a:ident)*) => ($( - #[unstable(feature = "iter_arith_traits", issue = "34529")] + #[stable(feature = "iter_arith_traits", since = "1.12.0")] impl Sum for $a { fn sum>(iter: I) -> $a { iter.fold(0, |a, b| { @@ -595,7 +597,7 @@ macro_rules! integer_sum_product { } } - #[unstable(feature = "iter_arith_traits", issue = "34529")] + #[stable(feature = "iter_arith_traits", since = "1.12.0")] impl Product for $a { fn product>(iter: I) -> $a { iter.fold(1, |a, b| { @@ -604,7 +606,7 @@ macro_rules! integer_sum_product { } } - #[unstable(feature = "iter_arith_traits", issue = "34529")] + #[stable(feature = "iter_arith_traits", since = "1.12.0")] impl<'a> Sum<&'a $a> for $a { fn sum>(iter: I) -> $a { iter.fold(0, |a, b| { @@ -613,7 +615,7 @@ macro_rules! integer_sum_product { } } - #[unstable(feature = "iter_arith_traits", issue = "34529")] + #[stable(feature = "iter_arith_traits", since = "1.12.0")] impl<'a> Product<&'a $a> for $a { fn product>(iter: I) -> $a { iter.fold(1, |a, b| { @@ -626,28 +628,28 @@ macro_rules! integer_sum_product { macro_rules! float_sum_product { ($($a:ident)*) => ($( - #[unstable(feature = "iter_arith_traits", issue = "34529")] + #[stable(feature = "iter_arith_traits", since = "1.12.0")] impl Sum for $a { fn sum>(iter: I) -> $a { iter.fold(0.0, |a, b| a + b) } } - #[unstable(feature = "iter_arith_traits", issue = "34529")] + #[stable(feature = "iter_arith_traits", since = "1.12.0")] impl Product for $a { fn product>(iter: I) -> $a { iter.fold(1.0, |a, b| a * b) } } - #[unstable(feature = "iter_arith_traits", issue = "34529")] + #[stable(feature = "iter_arith_traits", since = "1.12.0")] impl<'a> Sum<&'a $a> for $a { fn sum>(iter: I) -> $a { iter.fold(0.0, |a, b| a + *b) } } - #[unstable(feature = "iter_arith_traits", issue = "34529")] + #[stable(feature = "iter_arith_traits", since = "1.12.0")] impl<'a> Product<&'a $a> for $a { fn product>(iter: I) -> $a { iter.fold(1.0, |a, b| a * *b) diff --git a/src/libcoretest/cell.rs b/src/libcoretest/cell.rs index a635620d12abd..a7c230ba979be 100644 --- a/src/libcoretest/cell.rs +++ b/src/libcoretest/cell.rs @@ -176,21 +176,21 @@ fn ref_mut_map_accessor() { } #[test] -fn as_unsafe_cell() { +fn as_ptr() { let c1: Cell = Cell::new(0); c1.set(1); - assert_eq!(1, unsafe { *c1.as_unsafe_cell().get() }); + assert_eq!(1, unsafe { *c1.as_ptr() }); let c2: Cell = Cell::new(0); - unsafe { *c2.as_unsafe_cell().get() = 1; } + unsafe { *c2.as_ptr() = 1; } assert_eq!(1, c2.get()); let r1: RefCell = RefCell::new(0); *r1.borrow_mut() = 1; - assert_eq!(1, unsafe { *r1.as_unsafe_cell().get() }); + assert_eq!(1, unsafe { *r1.as_ptr() }); let r2: RefCell = RefCell::new(0); - unsafe { *r2.as_unsafe_cell().get() = 1; } + unsafe { *r2.as_ptr() = 1; } assert_eq!(1, *r2.borrow()); } diff --git a/src/libcoretest/lib.rs b/src/libcoretest/lib.rs index 9428b4096bfec..9116344c57938 100644 --- a/src/libcoretest/lib.rs +++ b/src/libcoretest/lib.rs @@ -10,7 +10,6 @@ #![deny(warnings)] -#![feature(as_unsafe_cell)] #![feature(borrow_state)] #![feature(box_syntax)] #![feature(cell_extras)] diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 8039421ae7730..94710a9190f03 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -1640,13 +1640,18 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> { self.elem.read().0 } + /// Deprecated, renamed to `remove_entry` + #[unstable(feature = "map_entry_recover_keys", issue = "34285")] + #[rustc_deprecated(since = "1.12.0", reason = "renamed to `remove_entry`")] + pub fn remove_pair(self) -> (K, V) { + self.remove_entry() + } + /// Take the ownership of the key and value from the map. /// /// # Examples /// /// ``` - /// #![feature(map_entry_recover_keys)] - /// /// use std::collections::HashMap; /// use std::collections::hash_map::Entry; /// @@ -1655,13 +1660,13 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> { /// /// if let Entry::Occupied(o) = map.entry("poneyland") { /// // We delete the entry from the map. - /// o.remove_pair(); + /// o.remove_entry(); /// } /// /// assert_eq!(map.contains_key("poneyland"), false); /// ``` - #[unstable(feature = "map_entry_recover_keys", issue = "34285")] - pub fn remove_pair(self) -> (K, V) { + #[stable(feature = "map_entry_recover_keys2", since = "1.12.0")] + pub fn remove_entry(self) -> (K, V) { pop_internal(self.elem) } @@ -1808,8 +1813,6 @@ impl<'a, K: 'a, V: 'a> VacantEntry<'a, K, V> { /// # Examples /// /// ``` - /// #![feature(map_entry_recover_keys)] - /// /// use std::collections::HashMap; /// use std::collections::hash_map::Entry; /// @@ -1819,7 +1822,7 @@ impl<'a, K: 'a, V: 'a> VacantEntry<'a, K, V> { /// v.into_key(); /// } /// ``` - #[unstable(feature = "map_entry_recover_keys", issue = "34285")] + #[stable(feature = "map_entry_recover_keys2", since = "1.12.0")] pub fn into_key(self) -> K { self.key } diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs index 2a8bd0c88beb6..4c3b993497cf5 100644 --- a/src/libstd/net/ip.rs +++ b/src/libstd/net/ip.rs @@ -63,8 +63,7 @@ impl IpAddr { /// Returns true for the special 'unspecified' address ([IPv4], [IPv6]). /// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_unspecified /// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_unspecified - #[unstable(feature="ip", issue="27709", - reason="recently added and depends on unstable Ipv4Addr.is_unspecified()")] + #[stable(feature = "ip_shared", since = "1.12.0")] pub fn is_unspecified(&self) -> bool { match *self { IpAddr::V4(ref a) => a.is_unspecified(), @@ -75,7 +74,7 @@ impl IpAddr { /// Returns true if this is a loopback address ([IPv4], [IPv6]). /// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_loopback /// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_loopback - #[unstable(feature="ip", reason="recently added", issue="27709")] + #[stable(feature = "ip_shared", since = "1.12.0")] pub fn is_loopback(&self) -> bool { match *self { IpAddr::V4(ref a) => a.is_loopback(), @@ -86,8 +85,6 @@ impl IpAddr { /// Returns true if the address appears to be globally routable ([IPv4], [IPv6]). /// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_global /// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_global - #[unstable(feature="ip", issue="27709", - reason="recently added and depends on unstable Ip{v4,v6}Addr.is_global()")] pub fn is_global(&self) -> bool { match *self { IpAddr::V4(ref a) => a.is_global(), @@ -98,7 +95,7 @@ impl IpAddr { /// Returns true if this is a multicast address ([IPv4], [IPv6]). /// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_multicast /// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_multicast - #[unstable(feature="ip", reason="recently added", issue="27709")] + #[stable(feature = "ip_shared", since = "1.12.0")] pub fn is_multicast(&self) -> bool { match *self { IpAddr::V4(ref a) => a.is_multicast(), @@ -109,8 +106,6 @@ impl IpAddr { /// Returns true if this address is in a range designated for documentation ([IPv4], [IPv6]). /// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_documentation /// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_documentation - #[unstable(feature="ip", issue="27709", - reason="recently added and depends on unstable Ipv6Addr.is_documentation()")] pub fn is_documentation(&self) -> bool { match *self { IpAddr::V4(ref a) => a.is_documentation(), @@ -147,6 +142,7 @@ impl Ipv4Addr { /// This property is defined in _UNIX Network Programming, Second Edition_, /// W. Richard Stevens, p. 891; see also [ip7] /// [ip7][http://man7.org/linux/man-pages/man7/ip.7.html] + #[stable(feature = "ip_shared", since = "1.12.0")] pub fn is_unspecified(&self) -> bool { self.inner.s_addr == 0 } @@ -515,8 +511,7 @@ impl Ipv6Addr { } /// Returns the sixteen eight-bit integers the IPv6 address consists of. - #[unstable(feature = "ipv6_to_octets", reason = "needs some testing", - issue = "32313")] + #[stable(feature = "ipv6_to_octets", since = "1.12.0")] pub fn octets(&self) -> [u8; 16] { self.inner.s6_addr } diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs index 11f785dffd16a..d8b8c6a77a266 100644 --- a/src/libstd/sync/mpsc/mod.rs +++ b/src/libstd/sync/mpsc/mod.rs @@ -394,13 +394,15 @@ pub enum TryRecvError { /// This enumeration is the list of possible errors that `recv_timeout` could /// not return data when called. #[derive(PartialEq, Eq, Clone, Copy, Debug)] -#[unstable(feature = "mpsc_recv_timeout", issue = "34029")] +#[stable(feature = "mpsc_recv_timeout", since = "1.12.0")] pub enum RecvTimeoutError { /// This channel is currently empty, but the sender(s) have not yet /// disconnected, so data may yet become available. + #[stable(feature = "mpsc_recv_timeout", since = "1.12.0")] Timeout, /// This channel's sending half has become disconnected, and there will /// never be any more data received on this channel + #[stable(feature = "mpsc_recv_timeout", since = "1.12.0")] Disconnected, } @@ -912,8 +914,6 @@ impl Receiver { /// # Examples /// /// ```no_run - /// #![feature(mpsc_recv_timeout)] - /// /// use std::sync::mpsc::{self, RecvTimeoutError}; /// use std::time::Duration; /// @@ -922,7 +922,7 @@ impl Receiver { /// let timeout = Duration::from_millis(100); /// assert_eq!(Err(RecvTimeoutError::Timeout), recv.recv_timeout(timeout)); /// ``` - #[unstable(feature = "mpsc_recv_timeout", issue = "34029")] + #[stable(feature = "mpsc_recv_timeout", since = "1.12.0")] pub fn recv_timeout(&self, timeout: Duration) -> Result { // Do an optimistic try_recv to avoid the performance impact of // Instant::now() in the full-channel case. diff --git a/src/libstd/sys/unix/ext/process.rs b/src/libstd/sys/unix/ext/process.rs index 430ec5f94a6f8..dd70ba2e490ad 100644 --- a/src/libstd/sys/unix/ext/process.rs +++ b/src/libstd/sys/unix/ext/process.rs @@ -114,7 +114,7 @@ impl CommandExt for process::Command { pub trait ExitStatusExt { /// Creates a new `ExitStatus` from the raw underlying `i32` return value of /// a process. - #[unstable(feature = "exit_status_from", issue = "32713")] + #[stable(feature = "exit_status_from", since = "1.12.0")] fn from_raw(raw: i32) -> Self; /// If the process was terminated by a signal, returns that signal. diff --git a/src/libstd/sys/windows/ext/process.rs b/src/libstd/sys/windows/ext/process.rs index 56c6a73d4f82b..98166bf8cda09 100644 --- a/src/libstd/sys/windows/ext/process.rs +++ b/src/libstd/sys/windows/ext/process.rs @@ -83,10 +83,11 @@ impl IntoRawHandle for process::ChildStderr { } /// Windows-specific extensions to `std::process::ExitStatus` -#[unstable(feature = "exit_status_from", issue = "32713")] +#[stable(feature = "exit_status_from", since = "1.12.0")] pub trait ExitStatusExt { /// Creates a new `ExitStatus` from the raw underlying `u32` return value of /// a process. + #[stable(feature = "exit_status_from", since = "1.12.0")] fn from_raw(raw: u32) -> Self; } diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 850127d9f2950..2b4193306ddf5 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -42,7 +42,6 @@ #![feature(staged_api)] #![feature(question_mark)] #![feature(panic_unwind)] -#![feature(mpsc_recv_timeout)] extern crate getopts; extern crate term; From 66788cc28500b1a5e3b6a8e3901b96c3032366e2 Mon Sep 17 00:00:00 2001 From: Andrew Paseltiner Date: Tue, 16 Aug 2016 20:45:07 -0400 Subject: [PATCH 03/43] Make `vec::IntoIter` covariant again Closes #35721 --- src/libcollections/vec.rs | 15 +++++++++------ src/libcollectionstest/vec.rs | 3 ++- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index a6f817a89624c..3aefcc7d4cfa4 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -1453,10 +1453,11 @@ impl IntoIterator for Vec { } else { begin.offset(self.len() as isize) as *const T }; - let buf = ptr::read(&self.buf); + let cap = self.buf.cap(); mem::forget(self); IntoIter { - _buf: buf, + buf: Shared::new(begin), + cap: cap, ptr: begin, end: end, } @@ -1708,8 +1709,9 @@ impl<'a, T> FromIterator for Cow<'a, [T]> where T: Clone { /// [`IntoIterator`]: ../../std/iter/trait.IntoIterator.html #[stable(feature = "rust1", since = "1.0.0")] pub struct IntoIter { - _buf: RawVec, - ptr: *mut T, + buf: Shared, + cap: usize, + ptr: *const T, end: *const T, } @@ -1750,7 +1752,7 @@ impl IntoIter { #[unstable(feature = "vec_into_iter_as_slice", issue = "35601")] pub fn as_mut_slice(&self) -> &mut [T] { unsafe { - slice::from_raw_parts_mut(self.ptr, self.len()) + slice::from_raw_parts_mut(self.ptr as *mut T, self.len()) } } } @@ -1846,9 +1848,10 @@ impl Drop for IntoIter { #[unsafe_destructor_blind_to_params] fn drop(&mut self) { // destroy the remaining elements - for _x in self {} + for _x in self.by_ref() {} // RawVec handles deallocation + let _ = unsafe { RawVec::from_raw_parts(*self.buf, self.cap) }; } } diff --git a/src/libcollectionstest/vec.rs b/src/libcollectionstest/vec.rs index 9556174bd2294..537fabf8ab69b 100644 --- a/src/libcollectionstest/vec.rs +++ b/src/libcollectionstest/vec.rs @@ -11,7 +11,7 @@ use std::borrow::Cow; use std::iter::{FromIterator, repeat}; use std::mem::size_of; -use std::vec::Drain; +use std::vec::{Drain, IntoIter}; use test::Bencher; @@ -537,6 +537,7 @@ fn test_cow_from() { #[allow(dead_code)] fn assert_covariance() { fn drain<'new>(d: Drain<'static, &'static str>) -> Drain<'new, &'new str> { d } + fn into_iter<'new>(i: IntoIter<&'static str>) -> IntoIter<&'new str> { i } } #[bench] From 0180c43dd42520419e631fa6304096a5767150ab Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Tue, 16 Aug 2016 16:11:03 -0700 Subject: [PATCH 04/43] 1.11 changelog --- RELEASES.md | 177 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) diff --git a/RELEASES.md b/RELEASES.md index c798c56cd6d03..8817d7f88a738 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,180 @@ +Version 1.11.0 (2016-08-18) +=========================== + +Language +-------- + +* [`cfg_attr` works on `path` attributes] + (https://github.com/rust-lang/rust/pull/34546) +* [Support nested `cfg_attr` attributes] + (https://github.com/rust-lang/rust/pull/34216) +* [Allow statement-generating braced macro invocations at the end of blocks] + (https://github.com/rust-lang/rust/pull/34436) +* [Macros can be expanded inside of trait definitions] + (https://github.com/rust-lang/rust/pull/34213) +* [`#[macro_use]` works properly when it is itself expanded from a macro] + (https://github.com/rust-lang/rust/pull/34032) + +Stabilized APIs +--------------- + +* [`BinaryHeap::append`] + (https://doc.rust-lang.org/std/collections/binary_heap/struct.BinaryHeap.html#method.append) +* [`BTreeMap::append`] + (https://doc.rust-lang.org/std/collections/btree_map/struct.BTreeMap.html#method.append) +* [`BTreeMap::split_off`] + (https://doc.rust-lang.org/std/collections/btree_map/struct.BTreeMap.html#method.split_off) +* [`BTreeSet::append`] + (https://doc.rust-lang.org/std/collections/btree_set/struct.BTreeSet.html#method.append) +* [`BTreeSet::split_off`] + (https://doc.rust-lang.org/std/collections/btree_set/struct.BTreeSet.html#method.split_off) +* [`f32::to_degrees`] + (https://doc.rust-lang.org/std/primitive.f32.html#method.to_degrees) + (in libcore - previously stabilized in libstd) +* [`f32::to_radians`] + (https://doc.rust-lang.org/std/primitive.f32.html#method.to_radians) + (in libcore - previously stabilized in libstd) +* [`f64::to_degrees`] + (https://doc.rust-lang.org/std/primitive.f64.html#method.to_degrees) + (in libcore - previously stabilized in libstd) +* [`f64::to_radians`] + (https://doc.rust-lang.org/std/primitive.f64.html#method.to_radians) + (in libcore - previously stabilized in libstd) +* [`Iterator::sum`] + (https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.sum) +* [`Iterator::product`] + (https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.sum) +* [`Cell::get_mut`] + (https://doc.rust-lang.org/std/cell/struct.Cell.html#method.get_mut) +* [`RefCell::get_mut`] + (https://doc.rust-lang.org/std/cell/struct.RefCell.html#method.get_mut) + +Libraries +--------- + +* [The `thread_local!` macro supports multiple definitions in a single + invocation, and can apply attributes] + (https://github.com/rust-lang/rust/pull/34077) +* [`Cow` implements `Default`] + (https://github.com/rust-lang/rust/pull/34305) +* [`Wrapping` implements binary, octal, lower-hex and upper-hex + `Display` formatting] + (https://github.com/rust-lang/rust/pull/34190) +* [The range types implement `Hash`] + (https://github.com/rust-lang/rust/pull/34180) +* [`lookup_host` ignores unknown address types] + (https://github.com/rust-lang/rust/pull/34067) +* [`assert_eq!` accepts a custom error message, like `assert!` does] + (https://github.com/rust-lang/rust/pull/33976) +* [The main thread is now called "main" instead of "<main>"] + (https://github.com/rust-lang/rust/pull/33803) + +Cargo +----- + +* [Disallow specifying features of transitive deps] + (https://github.com/rust-lang/cargo/pull/2821) +* [Add color support for Windows consoles] + (https://github.com/rust-lang/cargo/pull/2804) +* [Fix `harness = false` on `[lib]` sections] + (https://github.com/rust-lang/cargo/pull/2795) +* [Don't panic when `links` contains a '.'] + (https://github.com/rust-lang/cargo/pull/2787) +* [Build scripts can emit warnings] + (https://github.com/rust-lang/cargo/pull/2630), + and `-vv` prints warnings for all crates. +* [Ignore file locks on OS X NFS mounts] + (https://github.com/rust-lang/cargo/pull/2720) +* [Don't warn about `package.metadata` keys] + (https://github.com/rust-lang/cargo/pull/2668). + This provides room for expansion by arbitrary tools. +* [Add support for cdylib crate types] + (https://github.com/rust-lang/cargo/pull/2741) +* [Prevent publishing crates when files are dirty] + (https://github.com/rust-lang/cargo/pull/2781) +* [Don't fetch all crates on clean] + (https://github.com/rust-lang/cargo/pull/2704) +* [Propagate --color option to rustc] + (https://github.com/rust-lang/cargo/pull/2779) +* [Fix `cargo doc --open` on Windows] + (https://github.com/rust-lang/cargo/pull/2780) +* [Improve autocompletion] + (https://github.com/rust-lang/cargo/pull/2772) +* [Configure colors of stderr as well as stdout] + (https://github.com/rust-lang/cargo/pull/2739) + +Performance +----------- + +* [Caching projections speeds up type check dramatically for some + workloads] + (https://github.com/rust-lang/rust/pull/33816) +* [The default `HashMap` hasher is SipHash 1-3 instead of SipHash 2-4] + (https://github.com/rust-lang/rust/pull/33940) + This hasher is faster, but is believed to provide sufficient + protection from collision attacks. +* [Comparison of `Ipv4Addr` is 10x faster] + (https://github.com/rust-lang/rust/pull/33891) + +Rustdoc +------- + +* [Fix empty implementation section on some module pages] + (https://github.com/rust-lang/rust/pull/34536) +* [Fix inlined renamed reexports in import lists] + (https://github.com/rust-lang/rust/pull/34479) +* [Fix search result layout for enum variants and struct fields] + (https://github.com/rust-lang/rust/pull/34477) +* [Fix issues with source links to external crates] + (https://github.com/rust-lang/rust/pull/34387) +* [Fix redirect pages for renamed reexports] + (https://github.com/rust-lang/rust/pull/34245) + +Tooling +------- + +* [rustc is better at finding the MSVC toolchain] + (https://github.com/rust-lang/rust/pull/34492) +* [When emitting debug info, rustc emits frame pointers for closures, + shims and glue, as it does for all other functions] + (https://github.com/rust-lang/rust/pull/33909) +* [rust-lldb warns about unsupported versions of LLDB] + (https://github.com/rust-lang/rust/pull/34646) +* Many more errors have been given error codes and extended + explanations +* API documentation continues to be improved, with many new examples + +Misc +---- + +* [rustc no longer hangs when dependencies recursively re-export + submodules] + (https://github.com/rust-lang/rust/pull/34542) +* [rustc requires LLVM 3.7+] + (https://github.com/rust-lang/rust/pull/34104) +* [The 'How Safe and Unsafe Interact' chapter of The Rustonomicon was + rewritten] + (https://github.com/rust-lang/rust/pull/33895) +* [rustc support 16-bit pointer sizes] + (https://github.com/rust-lang/rust/pull/33460). + No targets use this yet, but it works toward AVR support. + +Compatibility Notes +------------------- + +* [`const`s and `static`s may not have unsized types] + (https://github.com/rust-lang/rust/pull/34443) +* [The new follow-set rules that place restrictions on `macro_rules!` + in order to ensure syntax forward-compatibility have been enabled] + (https://github.com/rust-lang/rust/pull/33982) + This was an [ammendment to RFC 550] + (https://github.com/rust-lang/rfcs/pull/1384), + and has been a warning since 1.10. +* [`cfg` attribute process has been refactored to fix various bugs] + (https://github.com/rust-lang/rust/pull/33706). + This causes breakage in some corner cases. + + Version 1.10.0 (2016-07-07) =========================== From ed3a5b28e815dff2cbada3b87dbf58b216f80b3d Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Wed, 17 Aug 2016 04:13:43 +0300 Subject: [PATCH 05/43] Properly invalidate the early exit cache Fixes #35737 --- src/librustc_mir/build/scope.rs | 43 +++++++++++---------- src/test/run-pass/mir_early_return_scope.rs | 37 ++++++++++++++++++ 2 files changed, 60 insertions(+), 20 deletions(-) create mode 100644 src/test/run-pass/mir_early_return_scope.rs diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs index cae9e8379897c..ca9e108bb415a 100644 --- a/src/librustc_mir/build/scope.rs +++ b/src/librustc_mir/build/scope.rs @@ -198,8 +198,11 @@ impl<'tcx> Scope<'tcx> { /// /// Should always be run for all inner scopes when a drop is pushed into some scope enclosing a /// larger extent of code. - fn invalidate_cache(&mut self) { - self.cached_exits = FnvHashMap(); + /// + /// `unwind` controls whether caches for the unwind branch are also invalidated. + fn invalidate_cache(&mut self, unwind: bool) { + self.cached_exits.clear(); + if !unwind { return; } for dropdata in &mut self.drops { if let DropKind::Value { ref mut cached_block } = dropdata.kind { *cached_block = None; @@ -455,25 +458,29 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { }; for scope in self.scopes.iter_mut().rev() { - if scope.extent == extent { + let this_scope = scope.extent == extent; + // We must invalidate all the caches leading up to the scope we’re looking for, because + // the cached blocks will branch into build of scope not containing the new drop. If we + // add stuff to the currently inspected scope, then in some cases the non-unwind caches + // may become invalid, therefore we should invalidate these as well. The unwind caches + // will stay correct, because the already generated unwind blocks cannot be influenced + // by just added drop. + // + // If we’re scheduling cleanup for non-droppable type (i.e. DropKind::Storage), then we + // do not need to invalidate unwind branch, because DropKind::Storage does not end up + // built in the unwind branch currently. + let invalidate_unwind = needs_drop && !this_scope; + scope.invalidate_cache(invalidate_unwind); + if this_scope { if let DropKind::Value { .. } = drop_kind { scope.needs_cleanup = true; } - - // No need to invalidate any caches here. The just-scheduled drop will branch into - // the drop that comes before it in the vector. scope.drops.push(DropData { span: span, location: lvalue.clone(), kind: drop_kind }); return; - } else { - // We must invalidate all the cached_blocks leading up to the scope we’re - // looking for, because all of the blocks in the chain will become incorrect. - if let DropKind::Value { .. } = drop_kind { - scope.invalidate_cache() - } } } span_bug!(span, "extent {:?} not in scope to drop {:?}", extent, lvalue); @@ -490,11 +497,12 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { value: &Lvalue<'tcx>, item_ty: Ty<'tcx>) { for scope in self.scopes.iter_mut().rev() { + // We must invalidate all the caches leading up to and including the scope we’re + // looking for, because otherwise some of the blocks in the chain will become + // incorrect and must be rebuilt. + scope.invalidate_cache(true); if scope.extent == extent { assert!(scope.free.is_none(), "scope already has a scheduled free!"); - // We also must invalidate the caches in the scope for which the free is scheduled - // because the drops must branch into the free we schedule here. - scope.invalidate_cache(); scope.needs_cleanup = true; scope.free = Some(FreeData { span: span, @@ -503,11 +511,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { cached_block: None }); return; - } else { - // We must invalidate all the cached_blocks leading up to the scope we’re looking - // for, because otherwise some/most of the blocks in the chain will become - // incorrect. - scope.invalidate_cache(); } } span_bug!(span, "extent {:?} not in scope to free {:?}", extent, value); diff --git a/src/test/run-pass/mir_early_return_scope.rs b/src/test/run-pass/mir_early_return_scope.rs new file mode 100644 index 0000000000000..c27e57358b09b --- /dev/null +++ b/src/test/run-pass/mir_early_return_scope.rs @@ -0,0 +1,37 @@ +// Copyright 2016 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. + +static mut DROP: bool = false; + +struct ConnWrap(Conn); +impl ::std::ops::Deref for ConnWrap { + type Target=Conn; + fn deref(&self) -> &Conn { &self.0 } +} + +struct Conn; +impl Drop for Conn { + fn drop(&mut self) { unsafe { DROP = true; } } +} + +fn inner() { + let conn = &*match Some(ConnWrap(Conn)) { + Some(val) => val, + None => return, + }; + return; +} + +fn main() { + inner(); + unsafe { + assert_eq!(DROP, true); + } +} From 346b7683940860e80682e3887bc4975afcdf8e31 Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Thu, 18 Aug 2016 00:38:30 +0300 Subject: [PATCH 06/43] Nice graphs --- src/librustc_mir/build/scope.rs | 60 ++++++++++++++++++++++++++------- 1 file changed, 48 insertions(+), 12 deletions(-) diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs index ca9e108bb415a..dc1d63a291118 100644 --- a/src/librustc_mir/build/scope.rs +++ b/src/librustc_mir/build/scope.rs @@ -459,16 +459,52 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { for scope in self.scopes.iter_mut().rev() { let this_scope = scope.extent == extent; - // We must invalidate all the caches leading up to the scope we’re looking for, because - // the cached blocks will branch into build of scope not containing the new drop. If we - // add stuff to the currently inspected scope, then in some cases the non-unwind caches - // may become invalid, therefore we should invalidate these as well. The unwind caches - // will stay correct, because the already generated unwind blocks cannot be influenced - // by just added drop. + // When building drops, we try to cache chains of drops in such a way so these drops + // could be reused by the drops which would branch into the cached (already built) + // blocks. This, however, means that whenever we add a drop into a scope which already + // had some blocks built (and thus, cached) for it, we must invalidate all caches which + // might branch into the scope which had a drop just added to it. This is necessary, + // because otherwise some other code might use the cache to branch into already built + // chain of drops, essentially ignoring the newly added drop. // - // If we’re scheduling cleanup for non-droppable type (i.e. DropKind::Storage), then we - // do not need to invalidate unwind branch, because DropKind::Storage does not end up - // built in the unwind branch currently. + // For example consider there’s two scopes with a drop in each. These are built and + // thus the caches are filled: + // + // +--------------------------------------------------------+ + // | +---------------------------------+ | + // | | +--------+ +-------------+ | +---------------+ | + // | | | return | <-+ | drop(outer) | <-+ | drop(middle) | | + // | | +--------+ +-------------+ | +---------------+ | + // | +------------|outer_scope cache|--+ | + // +------------------------------|middle_scope cache|------+ + // + // Now, a new, inner-most scope is added along with a new drop into both inner-most and + // outer-most scopes: + // + // +------------------------------------------------------------+ + // | +----------------------------------+ | + // | | +--------+ +-------------+ | +---------------+ | +-------------+ + // | | | return | <+ | drop(new) | <-+ | drop(middle) | <--+| drop(inner) | + // | | +--------+ | | drop(outer) | | +---------------+ | +-------------+ + // | | +-+ +-------------+ | | + // | +---|invalid outer_scope cache|----+ | + // +----=----------------|invalid middle_scope cache|-----------+ + // + // If, when adding `drop(new)` we do not invalidate the cached blocks for both + // outer_scope and middle_scope, then, when building drops for the inner (right-most) + // scope, the old, cached blocks, without `drop(new)` will get used, producing the + // wrong results. + // + // The cache and its invalidation for unwind branch is somewhat special. The cache is + // per-drop, rather than per scope, which has a several different implications. Adding + // a new drop into a scope will not invalidate cached blocks of the prior drops in the + // scope. That is true, because none of the already existing drops will have an edge + // into a block with the newly added drop. + // + // Note that this code iterates scopes from the inner-most to the outer-most, + // invalidating caches of each scope visited. This way bare minimum of the + // caches gets invalidated. i.e. if a new drop is added into the middle scope, the + // cache of outer scpoe stays intact. let invalidate_unwind = needs_drop && !this_scope; scope.invalidate_cache(invalidate_unwind); if this_scope { @@ -497,9 +533,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { value: &Lvalue<'tcx>, item_ty: Ty<'tcx>) { for scope in self.scopes.iter_mut().rev() { - // We must invalidate all the caches leading up to and including the scope we’re - // looking for, because otherwise some of the blocks in the chain will become - // incorrect and must be rebuilt. + // See the comment in schedule_drop above. The primary difference is that we invalidate + // the unwind blocks unconditionally. That’s because the box free may be considered + // outer-most cleanup within the scope. scope.invalidate_cache(true); if scope.extent == extent { assert!(scope.free.is_none(), "scope already has a scheduled free!"); From 7bac1cb8e26f7709b17f818c85e2630f7e5c184a Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 22 Aug 2016 22:42:07 -0700 Subject: [PATCH 07/43] mk: Bump the beta version to .2 --- mk/main.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mk/main.mk b/mk/main.mk index c6c3e70abc37a..c857c02bb8835 100644 --- a/mk/main.mk +++ b/mk/main.mk @@ -18,7 +18,7 @@ CFG_RELEASE_NUM=1.12.0 # An optional number to put after the label, e.g. '.2' -> '-beta.2' # NB Make sure it starts with a dot to conform to semver pre-release # versions (section 9) -CFG_PRERELEASE_VERSION=.1 +CFG_PRERELEASE_VERSION=.2 ifeq ($(CFG_RELEASE_CHANNEL),stable) # This is the normal semver version string, e.g. "0.12.0", "0.12.0-nightly" From 93a2faceb52ffcd1602c31b9af5bd801cd6a8c8b Mon Sep 17 00:00:00 2001 From: Alex Burka Date: Sun, 21 Aug 2016 22:45:25 +0000 Subject: [PATCH 08/43] typeck: use NoExpectation to check return type of diverging fn This fixes #35849, a regression introduced by the typeck refactoring around TyNever/!. --- src/librustc/middle/liveness.rs | 8 +++++++- src/librustc_typeck/check/mod.rs | 8 +++++++- .../compile-fail/diverging-fn-tail-35849.rs | 16 ++++++++++++++++ src/test/run-fail/call-fn-never-arg.rs | 1 + src/test/run-pass/diverging-fn-tail-35849.rs | 18 ++++++++++++++++++ 5 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 src/test/compile-fail/diverging-fn-tail-35849.rs create mode 100644 src/test/run-pass/diverging-fn-tail-35849.rs diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 74d29b273ff2b..b83826de26dd6 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -1479,7 +1479,13 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { self.ir.tcx.region_maps.call_site_extent(id, body.id), &self.fn_ret(id)); - if self.live_on_entry(entry_ln, self.s.no_ret_var).is_some() { + if fn_ret.is_never() { + // FIXME(durka) this rejects code like `fn foo(x: !) -> ! { x }` + if self.live_on_entry(entry_ln, self.s.clean_exit_var).is_some() { + span_err!(self.ir.tcx.sess, sp, E0270, + "computation may converge in a function marked as diverging"); + } + } else if self.live_on_entry(entry_ln, self.s.no_ret_var).is_some() { let param_env = ParameterEnvironment::for_item(self.ir.tcx, id); let t_ret_subst = fn_ret.subst(self.ir.tcx, ¶m_env.free_substs); let is_nil = self.ir.tcx.infer_ctxt(None, Some(param_env), diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index d985d3ccbea89..5dae28c12a028 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -709,7 +709,13 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>, inherited.tables.borrow_mut().liberated_fn_sigs.insert(fn_id, fn_sig); - fcx.check_block_with_expected(body, ExpectHasType(fcx.ret_ty)); + // FIXME(aburka) do we need this special case? and should it be is_uninhabited? + let expected = if fcx.ret_ty.is_never() { + NoExpectation + } else { + ExpectHasType(fcx.ret_ty) + }; + fcx.check_block_with_expected(body, expected); fcx } diff --git a/src/test/compile-fail/diverging-fn-tail-35849.rs b/src/test/compile-fail/diverging-fn-tail-35849.rs new file mode 100644 index 0000000000000..6dc447b4dc887 --- /dev/null +++ b/src/test/compile-fail/diverging-fn-tail-35849.rs @@ -0,0 +1,16 @@ +// Copyright 2016 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. + +fn _converge() -> ! { //~ ERROR computation may converge + 42 +} + +fn main() { } + diff --git a/src/test/run-fail/call-fn-never-arg.rs b/src/test/run-fail/call-fn-never-arg.rs index 95101e70db951..b1aa76cd9bfe5 100644 --- a/src/test/run-fail/call-fn-never-arg.rs +++ b/src/test/run-fail/call-fn-never-arg.rs @@ -10,6 +10,7 @@ // Test that we can use a ! for an argument of type ! +// ignore-test FIXME(durka) can't be done with the current liveness code // error-pattern:wowzers! #![feature(never_type)] diff --git a/src/test/run-pass/diverging-fn-tail-35849.rs b/src/test/run-pass/diverging-fn-tail-35849.rs new file mode 100644 index 0000000000000..6c05a02e7183c --- /dev/null +++ b/src/test/run-pass/diverging-fn-tail-35849.rs @@ -0,0 +1,18 @@ +// Copyright 2016 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. + +fn assert_sizeof() -> ! { + unsafe { + ::std::mem::transmute::(panic!()) + } +} + +fn main() { } + From 2e1b8d37e973bfd7be704d58b43896d27e8048be Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Tue, 23 Aug 2016 09:07:23 +0300 Subject: [PATCH 09/43] rustc_trans: do not generate allocas for unused locals. --- src/librustc_trans/mir/analyze.rs | 6 ++++++ src/test/run-pass/mir_heavy_promoted.rs | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 src/test/run-pass/mir_heavy_promoted.rs diff --git a/src/librustc_trans/mir/analyze.rs b/src/librustc_trans/mir/analyze.rs index e0d959f4774a6..66eb78aef07b4 100644 --- a/src/librustc_trans/mir/analyze.rs +++ b/src/librustc_trans/mir/analyze.rs @@ -48,6 +48,12 @@ pub fn lvalue_locals<'bcx, 'tcx>(bcx: Block<'bcx,'tcx>, common::type_is_fat_ptr(bcx.tcx(), ty)); } else if common::type_is_imm_pair(bcx.ccx(), ty) { // We allow pairs and uses of any of their 2 fields. + } else if !analyzer.seen_assigned.contains(index) { + // No assignment has been seen, which means that + // either the local has been marked as lvalue + // already, or there is no possible initialization + // for the local, making any reads invalid. + // This is useful in weeding out dead temps. } else { // These sorts of types require an alloca. Note that // type_is_immediate() may *still* be true, particularly diff --git a/src/test/run-pass/mir_heavy_promoted.rs b/src/test/run-pass/mir_heavy_promoted.rs new file mode 100644 index 0000000000000..9e033421574b9 --- /dev/null +++ b/src/test/run-pass/mir_heavy_promoted.rs @@ -0,0 +1,18 @@ +// Copyright 2016 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. + +const TEST_DATA: [u8; 32 * 1024 * 1024] = [42; 32 * 1024 * 1024]; + +// Check that the promoted copy of TEST_DATA doesn't +// leave an alloca from an unused temp behind, which, +// without optimizations, can still blow the stack. +fn main() { + println!("{}", TEST_DATA.len()); +} From 3ca48fe73e4ce50f36839fb6e4486dcb3fc6c203 Mon Sep 17 00:00:00 2001 From: Ulrik Sverdrup Date: Wed, 24 Aug 2016 18:57:45 +0200 Subject: [PATCH 10/43] memrchr: Correct aligned offset computation The memrchr fallback did not compute the offset correctly. It was intentioned to land on usize-aligned addresses but did not. This was suspected to resulted in a crash on ARMv7 platform! This bug affected non-linux platforms. I think like this, if we have a slice with pointer `ptr` and length `len`, we want to find the last usize-aligned offset in the slice. The correct computation should be: For example if ptr = 1 and len = 6, and size_of::() is 4: [ x x x x x x ] 1 2 3 4 5 6 ^-- last aligned address at offset 3 from the start. The last aligned address is ptr + len - (ptr + len) % usize_size. Compute offset from the start as: offset = len - (ptr + len) % usize_size = 6 - (1 + 6) % 4 = 6 - 3 = 3. I believe the function's return value was always correct previously, if the platform supported unaligned addresses. --- src/libstd/memchr.rs | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/libstd/memchr.rs b/src/libstd/memchr.rs index a408b4378e19e..89b77a7d6614e 100644 --- a/src/libstd/memchr.rs +++ b/src/libstd/memchr.rs @@ -209,7 +209,7 @@ mod fallback { let end_align = (ptr as usize + len) & (usize_bytes - 1); let mut offset; if end_align > 0 { - offset = len - cmp::min(usize_bytes - end_align, len); + offset = len - cmp::min(end_align, len); if let Some(index) = text[offset..].iter().rposition(|elt| *elt == x) { return Some(offset + index); } @@ -309,6 +309,17 @@ mod fallback { fn no_match_reversed() { assert_eq!(None, memrchr(b'a', b"xyz")); } + + #[test] + fn each_alignment_reversed() { + let mut data = [1u8; 64]; + let needle = 2; + let pos = 40; + data[pos] = needle; + for start in 0..16 { + assert_eq!(Some(pos - start), memrchr(needle, &data[start..])); + } + } } #[cfg(test)] @@ -385,4 +396,15 @@ mod tests { fn no_match_reversed() { assert_eq!(None, memrchr(b'a', b"xyz")); } + + #[test] + fn each_alignment() { + let mut data = [1u8; 64]; + let needle = 2; + let pos = 40; + data[pos] = needle; + for start in 0..16 { + assert_eq!(Some(pos - start), memchr(needle, &data[start..])); + } + } } From f79ab4fca8bb25e1fdbeeef6ad98a3820ce43733 Mon Sep 17 00:00:00 2001 From: Ulrik Sverdrup Date: Wed, 24 Aug 2016 21:41:23 +0200 Subject: [PATCH 11/43] memrchr: Use a conditional instead of subtracting a complicated min This makes the critical calculation easier to understand. --- src/libstd/memchr.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/memchr.rs b/src/libstd/memchr.rs index 89b77a7d6614e..03f55f7ad6186 100644 --- a/src/libstd/memchr.rs +++ b/src/libstd/memchr.rs @@ -209,7 +209,7 @@ mod fallback { let end_align = (ptr as usize + len) & (usize_bytes - 1); let mut offset; if end_align > 0 { - offset = len - cmp::min(end_align, len); + offset = if end_align >= len { 0 } else { len - end_align }; if let Some(index) = text[offset..].iter().rposition(|elt| *elt == x) { return Some(offset + index); } From 74cf38c9e8e08c7e7e3e6f61c45131b13fc5b001 Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Mon, 29 Aug 2016 22:53:18 +0300 Subject: [PATCH 12/43] llvm: backport "[SimplifyCFG] Hoisting invalidates metadata". --- src/llvm | 2 +- src/rustllvm/llvm-auto-clean-trigger | 2 +- src/test/run-pass/issue-36023.rs | 32 ++++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 src/test/run-pass/issue-36023.rs diff --git a/src/llvm b/src/llvm index 786aad117be48..eee68eafa7e8e 160000 --- a/src/llvm +++ b/src/llvm @@ -1 +1 @@ -Subproject commit 786aad117be48547f4ca50fae84c4879fa992d4d +Subproject commit eee68eafa7e8e4ce996b49f5551636639a6c331a diff --git a/src/rustllvm/llvm-auto-clean-trigger b/src/rustllvm/llvm-auto-clean-trigger index 378810a8b89fc..67f8730c25825 100644 --- a/src/rustllvm/llvm-auto-clean-trigger +++ b/src/rustllvm/llvm-auto-clean-trigger @@ -1,4 +1,4 @@ # If this file is modified, then llvm will be forcibly cleaned and then rebuilt. # The actual contents of this file do not matter, but to trigger a change on the # build bots then the contents should be changed so git updates the mtime. -2016-08-07 +2016-08-23 diff --git a/src/test/run-pass/issue-36023.rs b/src/test/run-pass/issue-36023.rs new file mode 100644 index 0000000000000..f6c03b384f23d --- /dev/null +++ b/src/test/run-pass/issue-36023.rs @@ -0,0 +1,32 @@ +// Copyright 2016 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. + +use std::ops::Deref; + +fn main() { + if env_var("FOOBAR").as_ref().map(Deref::deref).ok() == Some("yes") { + panic!() + } + + let env_home: Result = Ok("foo-bar-baz".to_string()); + let env_home = env_home.as_ref().map(Deref::deref).ok(); + + if env_home == Some("") { panic!() } +} + +#[inline(never)] +fn env_var(s: &str) -> Result { + Err(VarError::NotPresent) +} + +pub enum VarError { + NotPresent, + NotUnicode(String), +} From b81c0a29a829e5f25ffa62535e694c886784f680 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Fri, 16 Sep 2016 01:34:41 +0000 Subject: [PATCH 13/43] Bump beta to .3 --- mk/main.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mk/main.mk b/mk/main.mk index c857c02bb8835..13afff45d3f6c 100644 --- a/mk/main.mk +++ b/mk/main.mk @@ -18,7 +18,7 @@ CFG_RELEASE_NUM=1.12.0 # An optional number to put after the label, e.g. '.2' -> '-beta.2' # NB Make sure it starts with a dot to conform to semver pre-release # versions (section 9) -CFG_PRERELEASE_VERSION=.2 +CFG_PRERELEASE_VERSION=.3 ifeq ($(CFG_RELEASE_CHANNEL),stable) # This is the normal semver version string, e.g. "0.12.0", "0.12.0-nightly" From 7611709a1f6030f716b8dd4a2bfc813f80ba3005 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Mon, 5 Sep 2016 12:56:29 +0200 Subject: [PATCH 14/43] Fix issue #36036. We were treating an associated type as unsized even when the concrete instantiation was actually sized. Fix is to normalize before checking if it is sized. --- src/librustc/ty/layout.rs | 2 +- .../issue-36036-associated-type-layout.rs | 36 +++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 src/test/run-pass/issue-36036-associated-type-layout.rs diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 195cece6bc4e0..7c944020e9352 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -803,10 +803,10 @@ impl<'a, 'gcx, 'tcx> Layout { ty::TyRef(_, ty::TypeAndMut { ty: pointee, .. }) | ty::TyRawPtr(ty::TypeAndMut { ty: pointee, .. }) => { let non_zero = !ty.is_unsafe_ptr(); + let pointee = normalize_associated_type(infcx, pointee); if pointee.is_sized(tcx, &infcx.parameter_environment, DUMMY_SP) { Scalar { value: Pointer, non_zero: non_zero } } else { - let pointee = normalize_associated_type(infcx, pointee); let unsized_part = tcx.struct_tail(pointee); let meta = match unsized_part.sty { ty::TySlice(_) | ty::TyStr => { diff --git a/src/test/run-pass/issue-36036-associated-type-layout.rs b/src/test/run-pass/issue-36036-associated-type-layout.rs new file mode 100644 index 0000000000000..4ee3be0eb7b81 --- /dev/null +++ b/src/test/run-pass/issue-36036-associated-type-layout.rs @@ -0,0 +1,36 @@ +// Copyright 2016 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. + +// Issue 36036: computing the layout of a type composed from another +// trait's associated type caused compiler to ICE when the associated +// type was allowed to be unsized, even though the known instantiated +// type is itself sized. + +#![allow(dead_code)] + +trait Context { + type Container: ?Sized; +} + +impl Context for u16 { + type Container = u8; +} + +struct Wrapper { + container: &'static C::Container +} + +fn foobar(_: Wrapper) {} + +static VALUE: u8 = 0; + +fn main() { + foobar(Wrapper { container: &VALUE }); +} From ca42e0dfd9150f445374fedea397215fa32053e9 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 26 Aug 2016 19:23:42 +0300 Subject: [PATCH 15/43] Make `private_in_public` compatibility lint warn-by-default again --- src/librustc/lint/builtin.rs | 2 +- src/librustc_privacy/diagnostics.rs | 4 ++++ src/test/compile-fail/issue-28514.rs | 2 ++ src/test/compile-fail/issue-30079.rs | 1 + src/test/compile-fail/private-in-public-warn.rs | 4 ++-- src/test/compile-fail/private-variant-and-crate-reexport.rs | 1 + 6 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index f0ddcdc07e120..3230a08c27630 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -114,7 +114,7 @@ declare_lint! { declare_lint! { pub PRIVATE_IN_PUBLIC, - Deny, + Warn, "detect private items in public interfaces not caught by the old implementation" } diff --git a/src/librustc_privacy/diagnostics.rs b/src/librustc_privacy/diagnostics.rs index 891b6adea7893..66afe5835bf6f 100644 --- a/src/librustc_privacy/diagnostics.rs +++ b/src/librustc_privacy/diagnostics.rs @@ -17,6 +17,8 @@ A private trait was used on a public type parameter bound. Erroneous code examples: ```compile_fail,E0445 +#![deny(private_in_public)] + trait Foo { fn dummy(&self) { } } @@ -45,6 +47,8 @@ E0446: r##" A private type was used in a public type signature. Erroneous code example: ```compile_fail,E0446 +#![deny(private_in_public)] + mod Foo { struct Bar(u32); diff --git a/src/test/compile-fail/issue-28514.rs b/src/test/compile-fail/issue-28514.rs index 6ee375503c2af..fb25166531dcb 100644 --- a/src/test/compile-fail/issue-28514.rs +++ b/src/test/compile-fail/issue-28514.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![deny(private_in_public)] + pub use inner::C; mod inner { diff --git a/src/test/compile-fail/issue-30079.rs b/src/test/compile-fail/issue-30079.rs index 55c58ed021b27..6a54e53f14638 100644 --- a/src/test/compile-fail/issue-30079.rs +++ b/src/test/compile-fail/issue-30079.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![deny(private_in_public)] #![allow(unused)] struct SemiPriv; diff --git a/src/test/compile-fail/private-in-public-warn.rs b/src/test/compile-fail/private-in-public-warn.rs index 6d6af77be92b0..455de37aee96f 100644 --- a/src/test/compile-fail/private-in-public-warn.rs +++ b/src/test/compile-fail/private-in-public-warn.rs @@ -13,8 +13,8 @@ #![feature(associated_consts)] #![feature(associated_type_defaults)] -#![allow(dead_code)] -#![allow(unused_variables)] +#![deny(private_in_public)] +#![allow(unused)] #![allow(improper_ctypes)] mod types { diff --git a/src/test/compile-fail/private-variant-and-crate-reexport.rs b/src/test/compile-fail/private-variant-and-crate-reexport.rs index ce029e7eff7fc..dce533e73feea 100644 --- a/src/test/compile-fail/private-variant-and-crate-reexport.rs +++ b/src/test/compile-fail/private-variant-and-crate-reexport.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![deny(private_in_public)] #![allow(dead_code)] extern crate core; From faa280ceb9cd440f462349cd5bbaaff83c269213 Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Fri, 16 Sep 2016 01:08:12 +0300 Subject: [PATCH 16/43] Up the LLVM Fixes #36474 --- src/llvm | 2 +- src/rustllvm/llvm-auto-clean-trigger | 2 +- src/test/run-pass/issue-36474.rs | 40 ++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 src/test/run-pass/issue-36474.rs diff --git a/src/llvm b/src/llvm index eee68eafa7e8e..7801978ec1f36 160000 --- a/src/llvm +++ b/src/llvm @@ -1 +1 @@ -Subproject commit eee68eafa7e8e4ce996b49f5551636639a6c331a +Subproject commit 7801978ec1f3637fcda1b564048ebc732bf586af diff --git a/src/rustllvm/llvm-auto-clean-trigger b/src/rustllvm/llvm-auto-clean-trigger index 67f8730c25825..ea8d59290df2e 100644 --- a/src/rustllvm/llvm-auto-clean-trigger +++ b/src/rustllvm/llvm-auto-clean-trigger @@ -1,4 +1,4 @@ # If this file is modified, then llvm will be forcibly cleaned and then rebuilt. # The actual contents of this file do not matter, but to trigger a change on the # build bots then the contents should be changed so git updates the mtime. -2016-08-23 +2016-09-17 diff --git a/src/test/run-pass/issue-36474.rs b/src/test/run-pass/issue-36474.rs new file mode 100644 index 0000000000000..025244ca6648c --- /dev/null +++ b/src/test/run-pass/issue-36474.rs @@ -0,0 +1,40 @@ +// Copyright 2016 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. + +fn main() { + remove_axis(&3, 0); +} + +trait Dimension { + fn slice(&self) -> &[usize]; +} + +impl Dimension for () { + fn slice(&self) -> &[usize] { &[] } +} + +impl Dimension for usize { + fn slice(&self) -> &[usize] { + unsafe { + ::std::slice::from_raw_parts(self, 1) + } + } +} + +fn remove_axis(value: &usize, axis: usize) -> () { + let tup = (); + let mut it = tup.slice().iter(); + for (i, _) in value.slice().iter().enumerate() { + if i == axis { + continue; + } + it.next(); + } +} From 0a268d4bca092eaf5e8a0caf60a95da0c95a90d4 Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Thu, 15 Sep 2016 23:40:48 +0300 Subject: [PATCH 17/43] Default RUST_MIN_STACK to 16MiB for now --- src/librustc_driver/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 6f57ae2941838..f9a5331926424 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -1049,7 +1049,8 @@ fn parse_crate_attrs<'a>(sess: &'a Session, input: &Input) -> PResult<'a, Vec(f: F) { - const STACK_SIZE: usize = 8 * 1024 * 1024; // 8MB + // Temporarily have stack size set to 16MB to deal with nom-using crates failing + const STACK_SIZE: usize = 16 * 1024 * 1024; // 16MB struct Sink(Arc>>); impl Write for Sink { From d18dc0134daee44074e9fd4ed9c3ff2c8ccad769 Mon Sep 17 00:00:00 2001 From: Ulrik Sverdrup Date: Thu, 15 Sep 2016 09:59:55 +0200 Subject: [PATCH 18/43] Remove data structure specialization for .zip() iterator Go back on half the specialization, the part that changed the Zip struct's fields themselves depending on the types of the iterators. This means that the Zip iterator will always carry two usize fields, which are unused. If a whole for loop using a .zip() iterator is inlined, these are simply removed and have no effect. The same improvement for Zip of for example slice iterators remain, and they still optimize well. However, like when the specialization of zip was merged, the compiler is still very sensistive to the exact context. For example this code only autovectorizes if the function is used, not if the code in zip_sum_i32 is inserted inline it was called: ``` fn zip_sum_i32(xs: &[i32], ys: &[i32]) -> i32 { let mut s = 0; for (&x, &y) in xs.iter().zip(ys) { s += x * y; } s } fn zipdot_i32_default_zip(b: &mut test::Bencher) { let xs = vec![1; 1024]; let ys = vec![1; 1024]; b.iter(|| { zip_sum_i32(&xs, &ys) }) } ``` Include a test that checks that Zip is covariant w.r.t. T and U. --- src/libcore/iter/mod.rs | 52 +++++-------------- .../run-pass/variance-iterators-in-libcore.rs | 17 ++++++ 2 files changed, 31 insertions(+), 38 deletions(-) create mode 100644 src/test/run-pass/variance-iterators-in-libcore.rs diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index d2de0d46d746b..58222496e7249 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -626,7 +626,9 @@ impl DoubleEndedIterator for Chain where pub struct Zip { a: A, b: B, - spec: <(A, B) as ZipImplData>::Data, + // index and len are only used by the specialized version of zip + index: usize, + len: usize, } #[stable(feature = "rust1", since = "1.0.0")] @@ -668,17 +670,6 @@ trait ZipImpl { B: DoubleEndedIterator + ExactSizeIterator; } -// Zip specialization data members -#[doc(hidden)] -trait ZipImplData { - type Data: 'static + Clone + Default + fmt::Debug; -} - -#[doc(hidden)] -impl ZipImplData for T { - default type Data = (); -} - // General Zip impl #[doc(hidden)] impl ZipImpl for Zip @@ -689,7 +680,8 @@ impl ZipImpl for Zip Zip { a: a, b: b, - spec: Default::default(), // unused + index: 0, // unused + len: 0, // unused } } @@ -742,20 +734,6 @@ impl ZipImpl for Zip } } -#[doc(hidden)] -#[derive(Default, Debug, Clone)] -struct ZipImplFields { - index: usize, - len: usize, -} - -#[doc(hidden)] -impl ZipImplData for (A, B) - where A: TrustedRandomAccess, B: TrustedRandomAccess -{ - type Data = ZipImplFields; -} - #[doc(hidden)] impl ZipImpl for Zip where A: TrustedRandomAccess, B: TrustedRandomAccess @@ -765,18 +743,16 @@ impl ZipImpl for Zip Zip { a: a, b: b, - spec: ZipImplFields { - index: 0, - len: len, - } + index: 0, + len: len, } } #[inline] fn next(&mut self) -> Option<(A::Item, B::Item)> { - if self.spec.index < self.spec.len { - let i = self.spec.index; - self.spec.index += 1; + if self.index < self.len { + let i = self.index; + self.index += 1; unsafe { Some((self.a.get_unchecked(i), self.b.get_unchecked(i))) } @@ -787,7 +763,7 @@ impl ZipImpl for Zip #[inline] fn size_hint(&self) -> (usize, Option) { - let len = self.spec.len - self.spec.index; + let len = self.len - self.index; (len, Some(len)) } @@ -796,9 +772,9 @@ impl ZipImpl for Zip where A: DoubleEndedIterator + ExactSizeIterator, B: DoubleEndedIterator + ExactSizeIterator { - if self.spec.index < self.spec.len { - self.spec.len -= 1; - let i = self.spec.len; + if self.index < self.len { + self.len -= 1; + let i = self.len; unsafe { Some((self.a.get_unchecked(i), self.b.get_unchecked(i))) } diff --git a/src/test/run-pass/variance-iterators-in-libcore.rs b/src/test/run-pass/variance-iterators-in-libcore.rs new file mode 100644 index 0000000000000..b9677d5ba8598 --- /dev/null +++ b/src/test/run-pass/variance-iterators-in-libcore.rs @@ -0,0 +1,17 @@ +// Copyright 2015 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. + +#![allow(warnings)] + +use std::iter::Zip; + +fn zip_covariant<'a, A, B>(iter: Zip<&'static A, &'static B>) -> Zip<&'a A, &'a B> { iter } + +fn main() { } From 9c0e1327709cf884aceaaf5e4d883b26c437e632 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Tue, 20 Sep 2016 11:10:26 -0700 Subject: [PATCH 19/43] Bump to beta.4 --- mk/main.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mk/main.mk b/mk/main.mk index 13afff45d3f6c..a68d6cbbd391c 100644 --- a/mk/main.mk +++ b/mk/main.mk @@ -18,7 +18,7 @@ CFG_RELEASE_NUM=1.12.0 # An optional number to put after the label, e.g. '.2' -> '-beta.2' # NB Make sure it starts with a dot to conform to semver pre-release # versions (section 9) -CFG_PRERELEASE_VERSION=.3 +CFG_PRERELEASE_VERSION=.4 ifeq ($(CFG_RELEASE_CHANNEL),stable) # This is the normal semver version string, e.g. "0.12.0", "0.12.0-nightly" From 9ebf0471f6cfe25ea818e386c6282984c05c7c3c Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Tue, 20 Sep 2016 22:04:29 +0000 Subject: [PATCH 20/43] Fix build error --- src/libcore/iter/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index 58222496e7249..37baa0c40434a 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -301,7 +301,6 @@ use clone::Clone; use cmp; -use default::Default; use fmt; use iter_private::TrustedRandomAccess; use ops::FnMut; From 6436a6ec4c9b1099a93984d7d0c6f1ab39672ff1 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Tue, 23 Aug 2016 00:38:26 +0000 Subject: [PATCH 21/43] Update rust-installer. Fixes #35840 --- src/rust-installer | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rust-installer b/src/rust-installer index c37d3747da75c..755bc3db4ff79 160000 --- a/src/rust-installer +++ b/src/rust-installer @@ -1 +1 @@ -Subproject commit c37d3747da75c280237dc2d6b925078e69555499 +Subproject commit 755bc3db4ff795865ea31b5b4f38ac920d8acacb From 9e543219c133b1dc9bd4335a080559b9453d5f81 Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Mon, 12 Sep 2016 01:53:43 +0300 Subject: [PATCH 22/43] use `adt::trans_const` when translating constant closures and tuples Fixes #36401 --- src/librustc_trans/mir/constant.rs | 86 ++++++++++++++++++++---------- src/test/run-pass/issue-36401.rs | 25 +++++++++ 2 files changed, 83 insertions(+), 28 deletions(-) create mode 100644 src/test/run-pass/issue-36401.rs diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs index 31fee560fe369..2c83b7d07cc54 100644 --- a/src/librustc_trans/mir/constant.rs +++ b/src/librustc_trans/mir/constant.rs @@ -36,6 +36,7 @@ use value::Value; use syntax_pos::{Span, DUMMY_SP}; +use std::fmt; use std::ptr; use super::operand::{OperandRef, OperandValue}; @@ -147,6 +148,12 @@ impl<'tcx> Const<'tcx> { } } +impl<'tcx> fmt::Debug for Const<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "Const({:?}: {:?})", Value(self.llval), self.ty) + } +} + #[derive(Copy, Clone)] enum Base { /// A constant value without an unique address. @@ -466,7 +473,8 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { fn const_operand(&self, operand: &mir::Operand<'tcx>, span: Span) -> Result, ConstEvalFailure> { - match *operand { + debug!("const_operand({:?} @ {:?})", operand, span); + let result = match *operand { mir::Operand::Consume(ref lvalue) => { Ok(self.const_lvalue(lvalue, span)?.to_const(span)) } @@ -495,13 +503,33 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { } } } - } + }; + debug!("const_operand({:?} @ {:?}) = {:?}", operand, span, + result.as_ref().ok()); + result + } + + fn const_array(&self, array_ty: Ty<'tcx>, fields: &[ValueRef]) + -> Const<'tcx> + { + let elem_ty = array_ty.builtin_index().unwrap_or_else(|| { + bug!("bad array type {:?}", array_ty) + }); + let llunitty = type_of::type_of(self.ccx, elem_ty); + // If the array contains enums, an LLVM array won't work. + let val = if fields.iter().all(|&f| val_ty(f) == llunitty) { + C_array(llunitty, fields) + } else { + C_struct(self.ccx, fields, false) + }; + Const::new(val, array_ty) } fn const_rvalue(&self, rvalue: &mir::Rvalue<'tcx>, dest_ty: Ty<'tcx>, span: Span) -> Result, ConstEvalFailure> { let tcx = self.ccx.tcx(); + debug!("const_rvalue({:?}: {:?} @ {:?})", rvalue, dest_ty, span); let val = match *rvalue { mir::Rvalue::Use(ref operand) => self.const_operand(operand, span)?, @@ -509,15 +537,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { let elem = self.const_operand(elem, span)?; let size = count.value.as_u64(tcx.sess.target.uint_type); let fields = vec![elem.llval; size as usize]; - - let llunitty = type_of::type_of(self.ccx, elem.ty); - // If the array contains enums, an LLVM array won't work. - let val = if val_ty(elem.llval) == llunitty { - C_array(llunitty, &fields) - } else { - C_struct(self.ccx, &fields, false) - }; - Const::new(val, dest_ty) + self.const_array(dest_ty, &fields) } mir::Rvalue::Aggregate(ref kind, ref operands) => { @@ -541,22 +561,26 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { self.monomorphize(&substs)); } - let val = if let mir::AggregateKind::Adt(adt_def, index, _) = *kind { - let repr = adt::represent_type(self.ccx, dest_ty); - let disr = Disr::from(adt_def.variants[index].disr_val); - adt::trans_const(self.ccx, &repr, disr, &fields) - } else if let ty::TyArray(elem_ty, _) = dest_ty.sty { - let llunitty = type_of::type_of(self.ccx, elem_ty); - // If the array contains enums, an LLVM array won't work. - if fields.iter().all(|&f| val_ty(f) == llunitty) { - C_array(llunitty, &fields) - } else { - C_struct(self.ccx, &fields, false) + match *kind { + mir::AggregateKind::Vec => { + self.const_array(dest_ty, &fields) } - } else { - C_struct(self.ccx, &fields, false) - }; - Const::new(val, dest_ty) + mir::AggregateKind::Adt(..) | + mir::AggregateKind::Closure(..) | + mir::AggregateKind::Tuple => { + let disr = match *kind { + mir::AggregateKind::Adt(adt_def, index, _) => { + Disr::from(adt_def.variants[index].disr_val) + } + _ => Disr(0) + }; + let repr = adt::represent_type(self.ccx, dest_ty); + Const::new( + adt::trans_const(self.ccx, &repr, disr, &fields), + dest_ty + ) + } + } } mir::Rvalue::Cast(ref kind, ref source, cast_ty) => { @@ -780,6 +804,8 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { _ => span_bug!(span, "{:?} in constant", rvalue) }; + debug!("const_rvalue({:?}: {:?} @ {:?}) = {:?}", rvalue, dest_ty, span, val); + Ok(val) } @@ -881,6 +907,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { constant: &mir::Constant<'tcx>) -> Const<'tcx> { + debug!("trans_constant({:?})", constant); let ty = bcx.monomorphize(&constant.ty); let result = match constant.literal.clone() { mir::Literal::Item { def_id, substs } => { @@ -905,7 +932,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { } }; - match result { + let result = match result { Ok(v) => v, Err(ConstEvalFailure::Compiletime(_)) => { // We've errored, so we don't have to produce working code. @@ -917,7 +944,10 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { "MIR constant {:?} results in runtime panic: {:?}", constant, err.description()) } - } + }; + + debug!("trans_constant({:?}) = {:?}", constant, result); + result } } diff --git a/src/test/run-pass/issue-36401.rs b/src/test/run-pass/issue-36401.rs new file mode 100644 index 0000000000000..7b08eba9e4988 --- /dev/null +++ b/src/test/run-pass/issue-36401.rs @@ -0,0 +1,25 @@ +// Copyright 2016 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. + +#[derive(Debug)] +pub enum Event { + Key(u8), + Resize, + Unknown(u16), +} + +static XTERM_SINGLE_BYTES : [(u8, Event); 1] = [(1, Event::Resize)]; + +fn main() { + match XTERM_SINGLE_BYTES[0] { + (1, Event::Resize) => {}, + ref bad => panic!("unexpected {:?}", bad) + } +} From 0129358ffc9ad7a60b0f983eebac1383db4f6268 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 13 Sep 2016 16:04:27 -0400 Subject: [PATCH 23/43] invoke drop glue with a ptr to (data, meta) This is done by creating a little space on the stack. Hokey, but it's the simplest fix I can see. --- src/librustc_trans/mir/block.rs | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs index 56d02fa1fac4f..fbd2191ea7183 100644 --- a/src/librustc_trans/mir/block.rs +++ b/src/librustc_trans/mir/block.rs @@ -242,10 +242,28 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { let lvalue = self.trans_lvalue(&bcx, location); let drop_fn = glue::get_drop_glue(bcx.ccx(), ty); let drop_ty = glue::get_drop_glue_type(bcx.tcx(), ty); - let llvalue = if drop_ty != ty { - bcx.pointercast(lvalue.llval, type_of::type_of(bcx.ccx(), drop_ty).ptr_to()) + let is_sized = common::type_is_sized(bcx.tcx(), ty); + let llvalue = if is_sized { + if drop_ty != ty { + bcx.pointercast(lvalue.llval, type_of::type_of(bcx.ccx(), drop_ty).ptr_to()) + } else { + lvalue.llval + } } else { - lvalue.llval + // FIXME(#36457) Currently drop glue takes sized + // values as a `*(data, meta)`, but elsewhere in + // MIR we pass `(data, meta)` as two separate + // arguments. It would be better to fix drop glue, + // but I am shooting for a quick fix to #35546 + // here that can be cleanly backported to beta, so + // I want to avoid touching all of trans. + bcx.with_block(|bcx| { + let scratch = base::alloc_ty(bcx, ty, "drop"); + base::call_lifetime_start(bcx, scratch); + build::Store(bcx, lvalue.llval, base::get_dataptr(bcx, scratch)); + build::Store(bcx, lvalue.llextra, base::get_meta(bcx, scratch)); + scratch + }) }; if let Some(unwind) = unwind { bcx.invoke(drop_fn, From b31e845d57eb99d3f2f6bbe6f071794533004996 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 13 Sep 2016 18:33:35 -0400 Subject: [PATCH 24/43] add missing test --- src/test/run-pass/issue-35546.rs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/test/run-pass/issue-35546.rs diff --git a/src/test/run-pass/issue-35546.rs b/src/test/run-pass/issue-35546.rs new file mode 100644 index 0000000000000..e8d14f1d42146 --- /dev/null +++ b/src/test/run-pass/issue-35546.rs @@ -0,0 +1,28 @@ +// Copyright 2016 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. + +// Regression test for #35546. Check that we are able to codegen +// this. Before we had problems because of the drop glue signature +// around dropping a trait object (specifically, when dropping the +// `value` field of `Node`). + +struct Node { + next: Option>>, + value: T, +} + +fn clear(head: &mut Option>>) { + match head.take() { + Some(node) => *head = node.next, + None => (), + } +} + +fn main() {} From f0d4add18232d16fabf2e01a6eb0d60a4c7293a4 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 21 Sep 2016 15:15:39 +0200 Subject: [PATCH 25/43] fix PR 36459 post backport to beta. --- src/librustc_trans/mir/block.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs index fbd2191ea7183..6d03b44744b43 100644 --- a/src/librustc_trans/mir/block.rs +++ b/src/librustc_trans/mir/block.rs @@ -23,6 +23,7 @@ use common::{C_bool, C_str_slice, C_struct, C_u32, C_undef}; use consts; use debuginfo::DebugLoc; use Disr; +use expr; use machine::{llalign_of_min, llbitsize_of_real}; use meth; use type_of; @@ -260,8 +261,8 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { bcx.with_block(|bcx| { let scratch = base::alloc_ty(bcx, ty, "drop"); base::call_lifetime_start(bcx, scratch); - build::Store(bcx, lvalue.llval, base::get_dataptr(bcx, scratch)); - build::Store(bcx, lvalue.llextra, base::get_meta(bcx, scratch)); + build::Store(bcx, lvalue.llval, expr::get_dataptr(bcx, scratch)); + build::Store(bcx, lvalue.llextra, expr::get_meta(bcx, scratch)); scratch }) }; From 3264a86a8772ac8f38438a95ef46652dac8e9297 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Thu, 15 Sep 2016 19:02:10 +0200 Subject: [PATCH 26/43] Workaround #34427 by using memset of 0 on ARM to set the discriminant. Conflicts: src/librustc_trans/adt.rs --- src/librustc_trans/adt.rs | 26 +++++++++++++++++++++----- src/test/run-pass/issue-34427.rs | 26 ++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 5 deletions(-) create mode 100644 src/test/run-pass/issue-34427.rs diff --git a/src/librustc_trans/adt.rs b/src/librustc_trans/adt.rs index 23c4258caf7bd..5a88385a4635e 100644 --- a/src/librustc_trans/adt.rs +++ b/src/librustc_trans/adt.rs @@ -55,7 +55,7 @@ use syntax::attr; use syntax::attr::IntType; use _match; use abi::FAT_PTR_ADDR; -use base::InitAlloca; +use base::{self, InitAlloca}; use build::*; use cleanup; use cleanup::CleanupMethods; @@ -1023,16 +1023,32 @@ pub fn trans_set_discr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, r: &Repr<'tcx>, Store(bcx, C_null(llptrty), val); } } - StructWrappedNullablePointer { nndiscr, ref discrfield, .. } => { + StructWrappedNullablePointer { nndiscr, ref discrfield, ref nonnull, .. } => { if discr != nndiscr { - let llptrptr = GEPi(bcx, val, &discrfield[..]); - let llptrty = val_ty(llptrptr).element_type(); - Store(bcx, C_null(llptrty), llptrptr); + if target_sets_discr_via_memset(bcx) { + // Issue #34427: As workaround for LLVM bug on + // ARM, use memset of 0 on whole struct rather + // than storing null to single target field. + let b = B(bcx); + let llptr = b.pointercast(val, Type::i8(b.ccx).ptr_to()); + let fill_byte = C_u8(b.ccx, 0); + let size = C_uint(b.ccx, nonnull.size); + let align = C_i32(b.ccx, nonnull.align as i32); + base::call_memset(&b, llptr, fill_byte, size, align, false); + } else { + let llptrptr = GEPi(bcx, val, &discrfield[..]); + let llptrty = val_ty(llptrptr).element_type(); + Store(bcx, C_null(llptrty), llptrptr); + } } } } } +fn target_sets_discr_via_memset<'blk, 'tcx>(bcx: Block<'blk, 'tcx>) -> bool { + bcx.sess().target.target.arch == "arm" || bcx.sess().target.target.arch == "aarch64" +} + fn assert_discr_in_range(ity: IntType, min: Disr, max: Disr, discr: Disr) { match ity { attr::UnsignedInt(_) => { diff --git a/src/test/run-pass/issue-34427.rs b/src/test/run-pass/issue-34427.rs new file mode 100644 index 0000000000000..6bf8a2ac6a72d --- /dev/null +++ b/src/test/run-pass/issue-34427.rs @@ -0,0 +1,26 @@ +// Copyright 2016 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. + +// Issue #34427: On ARM, the code in `foo` at one time was generating +// a machine code instruction of the form: `str r0, [r0, rN]!` (for +// some N), which is not legal because the source register and base +// register cannot be identical in the preindexed form signalled by +// the `!`. +// +// See LLVM bug: https://llvm.org/bugs/show_bug.cgi?id=28809 + +#[inline(never)] +fn foo(n: usize) -> Vec> { + (0..n).map(|_| None).collect() +} + +fn main() { + let _ = (foo(10), foo(32)); +} From 27c7782ad665e830b58d0adc236204acb2befa18 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Wed, 21 Sep 2016 10:51:17 -0700 Subject: [PATCH 27/43] Bump to 1.12.0-beta.5 --- mk/main.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mk/main.mk b/mk/main.mk index a68d6cbbd391c..b85c7a5c581f2 100644 --- a/mk/main.mk +++ b/mk/main.mk @@ -18,7 +18,7 @@ CFG_RELEASE_NUM=1.12.0 # An optional number to put after the label, e.g. '.2' -> '-beta.2' # NB Make sure it starts with a dot to conform to semver pre-release # versions (section 9) -CFG_PRERELEASE_VERSION=.4 +CFG_PRERELEASE_VERSION=.5 ifeq ($(CFG_RELEASE_CHANNEL),stable) # This is the normal semver version string, e.g. "0.12.0", "0.12.0-nightly" From 30884cd92db37ed524d97b0527fb56aa40e3e5c6 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Tue, 20 Sep 2016 18:38:26 -0700 Subject: [PATCH 28/43] Add changelog for 1.12 --- RELEASES.md | 261 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 261 insertions(+) diff --git a/RELEASES.md b/RELEASES.md index 8817d7f88a738..368a54ab9222a 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,264 @@ +Version 1.12.0 (2016-09-29) +=========================== + +Highlights +---------- + +* [`rustc` translates code to LLVM IR via its own "middle" IR (MIR)] + (https://github.com/rust-lang/rust/pull/34096). + This translation pass is far simpler than the previous AST->LLVM pass, and + creates opportunities to perform new optimizations directly on the MIR. It + was previously described [on the Rust blog] + (https://blog.rust-lang.org/2016/04/19/MIR.html). +* [`rustc` presents a new, more readable error format, along with + machine-readable JSON error output for use by IDEs] + (https://github.com/rust-lang/rust/pull/35401). + Most common editors supporting Rust have been updated to work with it. It was + previously described [on the Rust blog] + (https://blog.rust-lang.org/2016/08/10/Shape-of-errors-to-come.html). + +Compiler +-------- + +* [`rustc` translates code to LLVM IR via its own "middle" IR (MIR)] + (https://github.com/rust-lang/rust/pull/34096). + This translation pass is far simpler than the previous AST->LLVM pass, and + creates opportunities to perform new optimizations directly on the MIR. It + was previously described [on the Rust blog] + (https://blog.rust-lang.org/2016/04/19/MIR.html). +* [Print the Rust target name, not the LLVM target name, with + `--print-target-list`] + (https://github.com/rust-lang/rust/pull/35489) +* [The computation of `TypeId` is correct in some cases where it was previously + producing inconsistent results] + (https://github.com/rust-lang/rust/pull/35267) +* [The `mips-unknown-linux-gnu` target uses hardware floating point by default] + (https://github.com/rust-lang/rust/pull/34910) +* [The `rustc` arguments, `--print target-cpus`, `--print target-features`, + `--print relocation-models`, and `--print code-models` print the available + options to the `-C target-cpu`, `-C target-feature`, `-C relocation-model` and + `-C code-model` code generation arguments] + (https://github.com/rust-lang/rust/pull/34845) +* [`rustc` supports three new MUSL targets on ARM: `arm-unknown-linux-musleabi`, + `arm-unknown-linux-musleabihf`, and `armv7-unknown-linux-musleabihf`] + (https://github.com/rust-lang/rust/pull/35060). + These targets produce statically-linked binaries. There are no binary release + builds yet though. + +Diagnostics +----------- + +* [`rustc` presents a new, more readable error format, along with + machine-readable JSON error output for use by IDEs] + (https://github.com/rust-lang/rust/pull/35401). + Most common editors supporting Rust have been updated to work with it. It was + previously described [on the Rust blog] + (https://blog.rust-lang.org/2016/08/10/Shape-of-errors-to-come.html). +* [In error descriptions, references are now described in plain english, + instead of as "&-ptr"] + (https://github.com/rust-lang/rust/pull/35611) +* [In error type descriptions, unknown numeric types are named `{integer}` or + `{float}` instead of `_`] + (https://github.com/rust-lang/rust/pull/35080) +* [`rustc` emits a clearer error when inner attributes follow a doc comment] + (https://github.com/rust-lang/rust/pull/34676) + +Language +-------- + +* [`macro_rules!` invocations can be made within `macro_rules!` invocations] + (https://github.com/rust-lang/rust/pull/34925) +* [`macro_rules!` meta-variables are hygienic] + (https://github.com/rust-lang/rust/pull/35453) +* [`macro_rules!` `tt` matchers can be reparsed correctly, making them much more + useful] + (https://github.com/rust-lang/rust/pull/34908) +* [`macro_rules!` `stmt` matchers correctly consume the entire contents when + insider non-braces invocations] + (https://github.com/rust-lang/rust/pull/34886) +* [Semicolons are properly required as statement delimeters inside + `macro_rules!` invocations] + (https://github.com/rust-lang/rust/pull/34660) +* [`cfg_attr` works on `path` attributes] + (https://github.com/rust-lang/rust/pull/34546) + +Stabilized APIs +--------------- + +* [`Cell::as_ptr`] + (https://doc.rust-lang.org/std/cell/struct.Cell.html#method.as_ptr) +* [`RefCell::as_ptr`] + (https://doc.rust-lang.org/std/cell/struct.RefCell.html#method.as_ptr) +* [`IpAddr::is_unspecified`] + (https://doc.rust-lang.org/std/net/enum.IpAddr.html#method.is_unspecified) +* [`IpAddr::is_loopback`] + (https://doc.rust-lang.org/std/net/enum.IpAddr.html#method.is_loopback) +* [`IpAddr::is_multicast`] + (https://doc.rust-lang.org/std/net/enum.IpAddr.html#method.is_multicast) +* [`Ipv4Addr::is_unspecified`] + (https://doc.rust-lang.org/std/net/struct.Ipv4Addr.html#method.is_unspecified) +* [`Ipv6Addr::octets`] + (https://doc.rust-lang.org/std/net/struct.Ipv6Addr.html#method.octets) +* [`LinkedList::contains`] + (https://doc.rust-lang.org/std/collections/linked_list/struct.LinkedList.html#method.contains) +* [`VecDeque::contains`] + (https://doc.rust-lang.org/std/collections/vec_deque/struct.VecDeque.html#method.contains) +* [`ExitStatusExt::from_raw`] + (https://doc.rust-lang.org/std/os/unix/process/trait.ExitStatusExt.html#tymethod.from_raw). + Both on Unix and Windows. +* [`Receiver::recv_timeout`] + (https://doc.rust-lang.org/std/sync/mpsc/struct.Receiver.html#method.recv_timeout) +* [`RecvTimeoutError`] + (https://doc.rust-lang.org/std/sync/mpsc/enum.RecvTimeoutError.html) +* [`BinaryHeap::peek_mut`] + (https://doc.rust-lang.org/std/collections/binary_heap/struct.BinaryHeap.html#method.peek_mut) +* [`PeekMut`] + (https://doc.rust-lang.org/std/collections/binary_heap/struct.PeekMut.html) +* [`iter::Product`] + (https://doc.rust-lang.org/std/iter/trait.Product.html) +* [`iter::Sum`] + (https://doc.rust-lang.org/std/iter/trait.Sum.html) +* [`OccupiedEntry::remove_entry`] + (https://doc.rust-lang.org/std/collections/btree_map/struct.OccupiedEntry.html#method.remove_entry) +* [`VacantEntry::into_key`] + (https://doc.rust-lang.org/std/collections/btree_map/struct.VacantEntry.html#method.into_key) + +Libraries +--------- + +* [The `format!` macro and friends now allow a single argument to be formatted + in multiple styles] + (https://github.com/rust-lang/rust/pull/33642) +* [The lifetime bounds on `[T]::binary_search_by` and + `[T]::binary_search_by_key` have been adjusted to be more flexible] + (https://github.com/rust-lang/rust/pull/34762) +* [`Option` implements `From` for its contained type] + (https://github.com/rust-lang/rust/pull/34828) +* [`Cell`, `RefCell` and `UnsafeCell` implement `From` for their contained type] + (https://github.com/rust-lang/rust/pull/35392) +* [`RwLock` panics if the reader count overflows] + (https://github.com/rust-lang/rust/pull/35378) +* [`vec_deque::Drain`, `hash_map::Drain` and `hash_set::Drain` are covariant] + (https://github.com/rust-lang/rust/pull/35354) +* [`vec::Drain` and `binary_heap::Drain` are covariant] + (https://github.com/rust-lang/rust/pull/34951) +* [`Cow` implements `FromIterator` for `char`, `&str` and `String`] + (https://github.com/rust-lang/rust/pull/35064) +* [`String` implements `From>` and `From<&[char]>`] + (https://github.com/rust-lang/rust/pull/35054) +* [Sockets on Linux are correctly closed in subprocesses via `SOCK_CLOEXEC`] + (https://github.com/rust-lang/rust/pull/34946) +* [`hash_map::Entry`, `hash_map::VacantEntry` and `hash_map::OccupiedEntry` + implement `Debug`] + (https://github.com/rust-lang/rust/pull/34946) +* [`btree_map::Entry`, `btree_map::VacantEntry` and `btree_map::OccupiedEntry` + implement `Debug`] + (https://github.com/rust-lang/rust/pull/34885) +* [`String` implements `AddAssign`] + (https://github.com/rust-lang/rust/pull/34890) +* [Variadic `extern fn` pointers implement the `Clone`, `PartialEq`, `Eq`, + `PartialOrd`, `Ord`, `Hash`, `fmt::Pointer`, and `fmt::Debug` traits] + (https://github.com/rust-lang/rust/pull/34879) +* [`FileType` implements `Debug`] + (https://github.com/rust-lang/rust/pull/34757) +* [References to `Mutex` and `RwLock` are unwind-safe] + (https://github.com/rust-lang/rust/pull/34756) +* [`mpsc::sync_channel` `Receiver`s return any available message before + reporting a disconnect] + (https://github.com/rust-lang/rust/pull/34731) +* [Unicode definitions have been updated to 9.0] + (https://github.com/rust-lang/rust/pull/34599) +* [`env` iterators implement `DoubleEndedIterator`] + (https://github.com/rust-lang/rust/pull/33312) + +Cargo +----- + +* [Support local mirrors of registries] + (https://github.com/rust-lang/cargo/pull/2857) +* [Add support for command aliases] + (https://github.com/rust-lang/cargo/pull/2679) +* [Allow `opt-level="s"` / `opt-level="z"` in profile overrides] + (https://github.com/rust-lang/cargo/pull/3007) +* [Make `cargo doc --open --target` work as expected] + (https://github.com/rust-lang/cargo/pull/2988) +* [Speed up noop registry updates] + (https://github.com/rust-lang/cargo/pull/2974) +* [Update OpenSSL] + (https://github.com/rust-lang/cargo/pull/2971) +* [Fix `--panic=abort` with plugins] + (https://github.com/rust-lang/cargo/pull/2954) +* [Always pass `-C metadata` to the compiler] + (https://github.com/rust-lang/cargo/pull/2946) +* [Fix depending on git repos with workspaces] + (https://github.com/rust-lang/cargo/pull/2938) +* [Add a `--lib` flag to `cargo new`] + (https://github.com/rust-lang/cargo/pull/2921) +* [Add `http.cainfo` for custom certs] + (https://github.com/rust-lang/cargo/pull/2917) +* [Indicate the compilation profile after compiling] + (https://github.com/rust-lang/cargo/pull/2909) +* [Allow enabling features for dependencies with `--features`] + (https://github.com/rust-lang/cargo/pull/2876) +* [Add `--jobs` flag to `cargo package`] + (https://github.com/rust-lang/cargo/pull/2867) +* [Add `--dry-run` to `cargo publish`] + (https://github.com/rust-lang/cargo/pull/2849) +* [Add support for `RUSTDOCFLAGS`] + (https://github.com/rust-lang/cargo/pull/2794) + +Performance +----------- + +* [`rustc` produces more compact code by more precisely identifying the live + ranges of variables] + (https://github.com/rust-lang/rust/pull/35409) +* [`panic::catch_unwind` is more optimized] + (https://github.com/rust-lang/rust/pull/35444) +* [`panic::catch_unwind` no longer accesses thread-local storage on entry] + (https://github.com/rust-lang/rust/pull/34866) + +Tooling +------- + +* [Test binaries now support a `--test-threads` argument to specify the number + of threads used to run tests, and which acts the same as the + `RUST_TEST_THREADS` environment variable] + (https://github.com/rust-lang/rust/pull/35414) +* [The test runner now emits a warning when tests run over 60 seconds] + (https://github.com/rust-lang/rust/pull/35405) +* [rustdoc: Fix methods in search results] + (https://github.com/rust-lang/rust/pull/34752) +* [`rust-lldb` warns about unsupported versions of LLDB] + (https://github.com/rust-lang/rust/pull/34646) +* [Rust releases now come with source packages that can be installed by rustup + via `rustup component add rust-src`] + (https://github.com/rust-lang/rust/pull/34366). + The resulting source code can be used by tools and IDES, located in the + sysroot under `lib/rustlib/src`. + +Misc +---- + +* [The compiler can now be built against LLVM 3.9] + (https://github.com/rust-lang/rust/pull/35594) +* Many minor improvements to the documentation. +* [The Rust exception handling "personality" routine is now written in Rust] + (https://github.com/rust-lang/rust/pull/34832) + +Compatibility Notes +------------------- + +* [When printing Windows `OsStr`s, unpaired surrogate codepoints are escaped + with the lowercase format instead of the uppercase] + (https://github.com/rust-lang/rust/pull/35084) +* [When formatting strings, if "precision" is specified, the "fill", + "align" and "width" specifiers are no longer ignored] + (https://github.com/rust-lang/rust/pull/34544) +* [The `Debug` impl for strings no longer escapes all non-ASCII characters] + (https://github.com/rust-lang/rust/pull/34485) + + Version 1.11.0 (2016-08-18) =========================== From 56b1a0792dba0bf39911ee3c314f57ec900846c6 Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Thu, 1 Sep 2016 00:27:03 +0300 Subject: [PATCH 29/43] Fix optimization regressions for operations on [x; n]-initialized arrays. --- src/librustc_trans/tvec.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_trans/tvec.rs b/src/librustc_trans/tvec.rs index 92a2d3787bfd6..11fe9c98d90aa 100644 --- a/src/librustc_trans/tvec.rs +++ b/src/librustc_trans/tvec.rs @@ -349,7 +349,7 @@ fn iter_vec_loop<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>, let plusone = Add(bcx, loop_counter, C_uint(bcx.ccx(), 1usize), DebugLoc::None); AddIncomingToPhi(loop_counter, plusone, bcx.llbb); - let cond_val = ICmp(bcx, llvm::IntULT, plusone, count, DebugLoc::None); + let cond_val = ICmp(bcx, llvm::IntNE, plusone, count, DebugLoc::None); CondBr(bcx, cond_val, loop_bcx.llbb, next_bcx.llbb, DebugLoc::None); next_bcx @@ -381,7 +381,7 @@ pub fn iter_vec_raw<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>, let data_ptr = Phi(header_bcx, val_ty(data_ptr), &[data_ptr], &[bcx.llbb]); let not_yet_at_end = - ICmp(header_bcx, llvm::IntULT, data_ptr, data_end_ptr, DebugLoc::None); + ICmp(header_bcx, llvm::IntNE, data_ptr, data_end_ptr, DebugLoc::None); let body_bcx = fcx.new_temp_block("iter_vec_loop_body"); let next_bcx = fcx.new_temp_block("iter_vec_next"); CondBr(header_bcx, not_yet_at_end, body_bcx.llbb, next_bcx.llbb, DebugLoc::None); From cfb29db52fc47f4ff317abade9869351b72bf010 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Fri, 23 Sep 2016 17:25:26 +0000 Subject: [PATCH 30/43] Revert "implement `From>` and `From<&'a [char]>` for `String`" This reverts commit ac73335f2f5421c914fa3900567696cc6dc73d8d. --- src/libcollections/string.rs | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index 788c838cd3fc8..1ba0319f2d7d9 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -1901,26 +1901,6 @@ impl Into> for String { } } -#[stable(feature = "stringfromchars", since = "1.12.0")] -impl<'a> From<&'a [char]> for String { - #[inline] - fn from(v: &'a [char]) -> String { - let mut s = String::with_capacity(v.len()); - for c in v { - s.push(*c); - } - s - } -} - -#[stable(feature = "stringfromchars", since = "1.12.0")] -impl From> for String { - #[inline] - fn from(v: Vec) -> String { - String::from(v.as_slice()) - } -} - #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Write for String { #[inline] From aaf78d886b0281d602943d37277a5e23289c6fab Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Fri, 23 Sep 2016 23:02:14 +0000 Subject: [PATCH 31/43] Bump beta to .6 --- mk/main.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mk/main.mk b/mk/main.mk index b85c7a5c581f2..90d3563240cd3 100644 --- a/mk/main.mk +++ b/mk/main.mk @@ -18,7 +18,7 @@ CFG_RELEASE_NUM=1.12.0 # An optional number to put after the label, e.g. '.2' -> '-beta.2' # NB Make sure it starts with a dot to conform to semver pre-release # versions (section 9) -CFG_PRERELEASE_VERSION=.5 +CFG_PRERELEASE_VERSION=.6 ifeq ($(CFG_RELEASE_CHANNEL),stable) # This is the normal semver version string, e.g. "0.12.0", "0.12.0-nightly" From f5b4a55c3a61298e7a9646b5835e9a84b370c73f Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Fri, 23 Sep 2016 23:20:46 +0000 Subject: [PATCH 32/43] Remove reverted feature from relnotes --- RELEASES.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index 368a54ab9222a..57aacd8c5ecc4 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -144,8 +144,6 @@ Libraries (https://github.com/rust-lang/rust/pull/34951) * [`Cow` implements `FromIterator` for `char`, `&str` and `String`] (https://github.com/rust-lang/rust/pull/35064) -* [`String` implements `From>` and `From<&[char]>`] - (https://github.com/rust-lang/rust/pull/35054) * [Sockets on Linux are correctly closed in subprocesses via `SOCK_CLOEXEC`] (https://github.com/rust-lang/rust/pull/34946) * [`hash_map::Entry`, `hash_map::VacantEntry` and `hash_map::OccupiedEntry` From f2235379bf5f205cef71baa4ba84b27035c3624b Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 30 Sep 2016 18:15:11 -0400 Subject: [PATCH 33/43] loosen assertion against proj in collector The collector was asserting a total absence of projections, but some projections are expected, even in trans: in particular, projections containing higher-ranked regions, which we don't currently normalize. --- src/librustc/ty/flags.rs | 5 +++++ src/librustc/ty/fold.rs | 2 +- src/librustc/ty/mod.rs | 4 ++++ src/librustc_trans/collector.rs | 4 +++- src/test/run-pass/issue-36381.rs | 34 ++++++++++++++++++++++++++++++++ 5 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 src/test/run-pass/issue-36381.rs diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs index 0997d6c1a7562..a428c99119a38 100644 --- a/src/librustc/ty/flags.rs +++ b/src/librustc/ty/flags.rs @@ -107,6 +107,11 @@ impl FlagComputation { } &ty::TyProjection(ref data) => { + // currently we can't normalize projections that + // include bound regions, so track those separately. + if !data.has_escaping_regions() { + self.add_flags(TypeFlags::HAS_NORMALIZABLE_PROJECTION); + } self.add_flags(TypeFlags::HAS_PROJECTION); self.add_projection_ty(data); } diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs index 3eeff6ee5792f..a8826f0b23ba6 100644 --- a/src/librustc/ty/fold.rs +++ b/src/librustc/ty/fold.rs @@ -105,7 +105,7 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone { TypeFlags::HAS_FREE_REGIONS | TypeFlags::HAS_TY_INFER | TypeFlags::HAS_PARAMS | - TypeFlags::HAS_PROJECTION | + TypeFlags::HAS_NORMALIZABLE_PROJECTION | TypeFlags::HAS_TY_ERR | TypeFlags::HAS_SELF) } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index cfc2e89f9d5a1..02be1573bf176 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -527,6 +527,10 @@ bitflags! { // Only set for TyInfer other than Fresh. const KEEP_IN_LOCAL_TCX = 1 << 11, + // Is there a projection that does not involve a bound region? + // Currently we can't normalize projections w/ bound regions. + const HAS_NORMALIZABLE_PROJECTION = 1 << 12, + const NEEDS_SUBST = TypeFlags::HAS_PARAMS.bits | TypeFlags::HAS_SELF.bits | TypeFlags::HAS_RE_EARLY_BOUND.bits, diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs index acc302430aee6..fdd1ee1fba1d9 100644 --- a/src/librustc_trans/collector.rs +++ b/src/librustc_trans/collector.rs @@ -1042,7 +1042,9 @@ fn create_fn_trans_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let concrete_substs = monomorphize::apply_param_substs(tcx, param_substs, &fn_substs); - assert!(concrete_substs.is_normalized_for_trans()); + assert!(concrete_substs.is_normalized_for_trans(), + "concrete_substs not normalized for trans: {:?}", + concrete_substs); TransItem::Fn(Instance::new(def_id, concrete_substs)) } diff --git a/src/test/run-pass/issue-36381.rs b/src/test/run-pass/issue-36381.rs new file mode 100644 index 0000000000000..6cd991bd942df --- /dev/null +++ b/src/test/run-pass/issue-36381.rs @@ -0,0 +1,34 @@ +// Copyright 2014 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. + +// Regression test for #36381. The trans collector was asserting that +// there are no projection types, but the `<&str as +// StreamOnce>::Position` projection contained a late-bound region, +// and we don't currently normalize in that case until the function is +// actually invoked. + +pub trait StreamOnce { + type Position; +} + +impl<'a> StreamOnce for &'a str { + type Position = usize; +} + +pub fn parser(_: F) { +} + +fn follow(_: &str) -> <&str as StreamOnce>::Position { + panic!() +} + +fn main() { + parser(follow); +} From ca1b124cb8d6d30b2dbe516dc7e97e4818acee34 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 4 Oct 2016 05:55:45 -0400 Subject: [PATCH 34/43] force `i1` booleans to `i8` when comparing Work around LLVM bug. cc #36856 --- src/librustc_trans/base.rs | 11 ++++++++++- src/test/run-pass/issue-36856.rs | 24 ++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 src/test/run-pass/issue-36856.rs diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index c78cda75e820e..479a6a2cac3ed 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -320,7 +320,16 @@ pub fn compare_scalar_types<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, _ => bug!("compare_scalar_types: must be a comparison operator"), } } - ty::TyFnDef(..) | ty::TyFnPtr(_) | ty::TyBool | ty::TyUint(_) | ty::TyChar => { + ty::TyBool => { + // FIXME(#36856) -- using `from_immediate` forces these booleans into `i8`, + // which works around some LLVM bugs + ICmp(bcx, + bin_op_to_icmp_predicate(op, false), + from_immediate(bcx, lhs), + from_immediate(bcx, rhs), + debug_loc) + } + ty::TyFnDef(..) | ty::TyFnPtr(_) | ty::TyUint(_) | ty::TyChar => { ICmp(bcx, bin_op_to_icmp_predicate(op, false), lhs, diff --git a/src/test/run-pass/issue-36856.rs b/src/test/run-pass/issue-36856.rs new file mode 100644 index 0000000000000..91a0dadd65328 --- /dev/null +++ b/src/test/run-pass/issue-36856.rs @@ -0,0 +1,24 @@ +// Copyright 2012 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. + +// Regression test for #36856. + +// compile-flags:-g + +fn g() -> bool { + false +} + +pub fn main() { + let a = !g(); + if a != !g() { + panic!(); + } +} From 566df6ca4b3dd9ff2bb0ae556941bd9085abb912 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Mon, 10 Oct 2016 11:12:29 -0400 Subject: [PATCH 35/43] LLVM: Backport "[SimplifyCFG] Correctly test for unconditional branches in GetCaseResults" --- src/llvm | 2 +- src/rustllvm/llvm-auto-clean-trigger | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/llvm b/src/llvm index 7801978ec1f36..ac1c94226e9fa 160000 --- a/src/llvm +++ b/src/llvm @@ -1 +1 @@ -Subproject commit 7801978ec1f3637fcda1b564048ebc732bf586af +Subproject commit ac1c94226e9fa17005ce7e2dd52dd6d1875f3137 diff --git a/src/rustllvm/llvm-auto-clean-trigger b/src/rustllvm/llvm-auto-clean-trigger index ea8d59290df2e..b12e25bba694f 100644 --- a/src/rustllvm/llvm-auto-clean-trigger +++ b/src/rustllvm/llvm-auto-clean-trigger @@ -1,4 +1,4 @@ # If this file is modified, then llvm will be forcibly cleaned and then rebuilt. # The actual contents of this file do not matter, but to trigger a change on the # build bots then the contents should be changed so git updates the mtime. -2016-09-17 +2016-10-10 From 580cbd889f4a9e2baae3efda8589c6721da3f0f2 Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Tue, 4 Oct 2016 01:13:36 +0300 Subject: [PATCH 36/43] stop having identity casts be lexprs that made no sense (see test), and was incompatible with borrowck. Fixes #36936. --- src/librustc_mir/build/expr/as_lvalue.rs | 1 + src/librustc_mir/build/expr/as_rvalue.rs | 4 +++ src/librustc_mir/build/expr/category.rs | 1 + src/librustc_mir/build/expr/into.rs | 1 + src/librustc_mir/hair/cx/expr.rs | 4 +-- src/librustc_mir/hair/mod.rs | 3 ++ src/test/run-pass/issue-36936.rs | 35 ++++++++++++++++++++++++ 7 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 src/test/run-pass/issue-36936.rs diff --git a/src/librustc_mir/build/expr/as_lvalue.rs b/src/librustc_mir/build/expr/as_lvalue.rs index ae5ccbfd82099..78330f0b9753b 100644 --- a/src/librustc_mir/build/expr/as_lvalue.rs +++ b/src/librustc_mir/build/expr/as_lvalue.rs @@ -96,6 +96,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { ExprKind::LogicalOp { .. } | ExprKind::Box { .. } | ExprKind::Cast { .. } | + ExprKind::Use { .. } | ExprKind::NeverToAny { .. } | ExprKind::ReifyFnPointer { .. } | ExprKind::UnsafeFnPointer { .. } | diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs index dafc53d3c1542..3cd79ee1c5aa1 100644 --- a/src/librustc_mir/build/expr/as_rvalue.rs +++ b/src/librustc_mir/build/expr/as_rvalue.rs @@ -115,6 +115,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let source = unpack!(block = this.as_operand(block, source)); block.and(Rvalue::Cast(CastKind::Misc, source, expr.ty)) } + ExprKind::Use { source } => { + let source = unpack!(block = this.as_operand(block, source)); + block.and(Rvalue::Use(source)) + } ExprKind::ReifyFnPointer { source } => { let source = unpack!(block = this.as_operand(block, source)); block.and(Rvalue::Cast(CastKind::ReifyFnPointer, source, expr.ty)) diff --git a/src/librustc_mir/build/expr/category.rs b/src/librustc_mir/build/expr/category.rs index c19ea0f445ac0..9671f80f48ba7 100644 --- a/src/librustc_mir/build/expr/category.rs +++ b/src/librustc_mir/build/expr/category.rs @@ -68,6 +68,7 @@ impl Category { ExprKind::Binary { .. } | ExprKind::Box { .. } | ExprKind::Cast { .. } | + ExprKind::Use { .. } | ExprKind::ReifyFnPointer { .. } | ExprKind::UnsafeFnPointer { .. } | ExprKind::Unsize { .. } | diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs index e5930f5a62df6..58265b5b0d36b 100644 --- a/src/librustc_mir/build/expr/into.rs +++ b/src/librustc_mir/build/expr/into.rs @@ -249,6 +249,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { ExprKind::Binary { .. } | ExprKind::Box { .. } | ExprKind::Cast { .. } | + ExprKind::Use { .. } | ExprKind::ReifyFnPointer { .. } | ExprKind::UnsafeFnPointer { .. } | ExprKind::Unsize { .. } | diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index a61fdb79df822..605798ad44ce1 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -602,8 +602,8 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, // Check to see if this cast is a "coercion cast", where the cast is actually done // using a coercion (or is a no-op). if let Some(&TyCastKind::CoercionCast) = cx.tcx.cast_kinds.borrow().get(&source.id) { - // Skip the actual cast itexpr, as it's now a no-op. - return source.make_mirror(cx); + // Convert the lexpr to a vexpr. + ExprKind::Use { source: source.to_ref() } } else { ExprKind::Cast { source: source.to_ref() } } diff --git a/src/librustc_mir/hair/mod.rs b/src/librustc_mir/hair/mod.rs index 2a5b7d0fb2902..cc59346487e39 100644 --- a/src/librustc_mir/hair/mod.rs +++ b/src/librustc_mir/hair/mod.rs @@ -139,6 +139,9 @@ pub enum ExprKind<'tcx> { Cast { source: ExprRef<'tcx>, }, + Use { + source: ExprRef<'tcx>, + }, // Use a lexpr to get a vexpr. NeverToAny { source: ExprRef<'tcx>, }, diff --git a/src/test/run-pass/issue-36936.rs b/src/test/run-pass/issue-36936.rs new file mode 100644 index 0000000000000..4216e2bb4fe6c --- /dev/null +++ b/src/test/run-pass/issue-36936.rs @@ -0,0 +1,35 @@ +// Copyright 2016 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. + +// check that casts are not being treated as lexprs. + +fn main() { + let mut a = 0i32; + let b = &(a as i32); + a = 1; + assert!((&a as *const i32) != (b as *const i32)); + assert_eq!(*b, 0); + + assert_eq!(issue_36936(), 1); +} + + +struct A(u32); + +impl Drop for A { + fn drop(&mut self) { + self.0 = 0; + } +} + +fn issue_36936() -> u32 { + let a = &(A(1) as A); + a.0 +} From d0374d0475150281359debe1355c10e1d0e51cfa Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 15 Sep 2016 00:51:46 +0300 Subject: [PATCH 37/43] Temporary fix for metadata decoding for struct constructors --- src/librustc/ty/item_path.rs | 2 +- src/librustc_typeck/check/_match.rs | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index 8ddd8bef36a6f..5e4e7b342d631 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -305,7 +305,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// Returns the def-id of `def_id`'s parent in the def tree. If /// this returns `None`, then `def_id` represents a crate root or /// inlined root. - fn parent_def_id(&self, def_id: DefId) -> Option { + pub fn parent_def_id(&self, def_id: DefId) -> Option { let key = self.def_key(def_id); key.parent.map(|index| DefId { krate: def_id.krate, index: index }) } diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 04f22b195110f..c2fba80385784 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -535,13 +535,21 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { report_unexpected_def(); return; } - Def::Variant(..) | Def::Struct(..) => { + Def::Variant(..) => { let variant = tcx.expect_variant_def(def); if variant.kind != VariantKind::Unit { report_unexpected_def(); return; } } + Def::Struct(ctor_did) => { + let did = tcx.parent_def_id(ctor_did).expect("struct ctor has no parent"); + let variant = tcx.lookup_adt_def(did).struct_variant(); + if variant.kind != VariantKind::Unit { + report_unexpected_def(); + return; + } + } Def::Const(..) | Def::AssociatedConst(..) => {} // OK _ => bug!("unexpected pattern definition {:?}", def) } @@ -592,9 +600,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { report_unexpected_def(false); return; } - Def::Variant(..) | Def::Struct(..) => { + Def::Variant(..) => { tcx.expect_variant_def(def) } + Def::Struct(ctor_did) => { + let did = tcx.parent_def_id(ctor_did).expect("struct ctor has no parent"); + tcx.lookup_adt_def(did).struct_variant() + } _ => bug!("unexpected pattern definition {:?}", def) }; if variant.kind == VariantKind::Unit && subpats.is_empty() && ddpos.is_some() { From 70107c8a7a75f26b59ac73b735492ef213c0b436 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Fri, 14 Oct 2016 12:04:54 -0700 Subject: [PATCH 38/43] Bump version to 1.12.1 --- mk/main.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mk/main.mk b/mk/main.mk index 90d3563240cd3..171ded4230370 100644 --- a/mk/main.mk +++ b/mk/main.mk @@ -13,7 +13,7 @@ ###################################################################### # The version number -CFG_RELEASE_NUM=1.12.0 +CFG_RELEASE_NUM=1.12.1 # An optional number to put after the label, e.g. '.2' -> '-beta.2' # NB Make sure it starts with a dot to conform to semver pre-release From 3361f1335024816cf4418cbf93eb47a5c38d970d Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 12 Oct 2016 17:36:04 +0200 Subject: [PATCH 39/43] Fix ICE by injecting bitcasts if types mismatch when building invokes or calls. --- src/librustc_trans/builder.rs | 49 +++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/src/librustc_trans/builder.rs b/src/librustc_trans/builder.rs index 90f96af549691..7e72b977de458 100644 --- a/src/librustc_trans/builder.rs +++ b/src/librustc_trans/builder.rs @@ -22,6 +22,7 @@ use value::Value; use util::nodemap::FnvHashMap; use libc::{c_uint, c_char}; +use std::borrow::Cow; use std::ffi::CString; use std::ptr; use syntax_pos::Span; @@ -175,8 +176,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { .collect::>() .join(", ")); - check_call("invoke", llfn, args); - + let args = self.check_call("invoke", llfn, args); let bundle = bundle.as_ref().map(|b| b.raw()).unwrap_or(ptr::null_mut()); unsafe { @@ -857,8 +857,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { .collect::>() .join(", ")); - check_call("call", llfn, args); - + let args = self.check_call("call", llfn, args); let bundle = bundle.as_ref().map(|b| b.raw()).unwrap_or(ptr::null_mut()); unsafe { @@ -1100,10 +1099,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { llvm::LLVMRustBuildAtomicFence(self.llbuilder, order, scope); } } -} -fn check_call(typ: &str, llfn: ValueRef, args: &[ValueRef]) { - if cfg!(debug_assertions) { + fn check_call<'b>(&self, + typ: &str, + llfn: ValueRef, + args: &'b [ValueRef]) -> Cow<'b, [ValueRef]> { let mut fn_ty = val_ty(llfn); // Strip off pointers while fn_ty.kind() == llvm::TypeKind::Pointer { @@ -1115,16 +1115,31 @@ fn check_call(typ: &str, llfn: ValueRef, args: &[ValueRef]) { let param_tys = fn_ty.func_params(); - let iter = param_tys.into_iter() - .zip(args.iter().map(|&v| val_ty(v))); - for (i, (expected_ty, actual_ty)) in iter.enumerate() { - if expected_ty != actual_ty { - bug!("Type mismatch in function call of {:?}. \ - Expected {:?} for param {}, got {:?}", - Value(llfn), - expected_ty, i, actual_ty); + let all_args_match = param_tys.iter() + .zip(args.iter().map(|&v| val_ty(v))) + .all(|(expected_ty, actual_ty)| *expected_ty == actual_ty); + + if all_args_match { + return Cow::Borrowed(args); + } + + let casted_args: Vec<_> = param_tys.into_iter() + .zip(args.iter()) + .enumerate() + .map(|(i, (expected_ty, &actual_val))| { + let actual_ty = val_ty(actual_val); + if expected_ty != actual_ty { + debug!("Type mismatch in function call of {:?}. \ + Expected {:?} for param {}, got {:?}; injecting bitcast", + Value(llfn), + expected_ty, i, actual_ty); + self.bitcast(actual_val, expected_ty) + } else { + actual_val + } + }) + .collect(); - } - } + return Cow::Owned(casted_args); } } From 45d365ae253c0b0cc3f88b8dce8722e9e7fb06c1 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 12 Oct 2016 19:26:06 +0200 Subject: [PATCH 40/43] Inject bitcast if types mismatch when building a store instruction. --- src/librustc_trans/builder.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/librustc_trans/builder.rs b/src/librustc_trans/builder.rs index 7e72b977de458..8556e95903c18 100644 --- a/src/librustc_trans/builder.rs +++ b/src/librustc_trans/builder.rs @@ -543,6 +543,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { debug!("Store {:?} -> {:?}", Value(val), Value(ptr)); assert!(!self.llbuilder.is_null()); self.count_insn("store"); + let ptr = self.check_store(val, ptr); unsafe { llvm::LLVMBuildStore(self.llbuilder, val, ptr) } @@ -552,6 +553,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { debug!("Store {:?} -> {:?}", Value(val), Value(ptr)); assert!(!self.llbuilder.is_null()); self.count_insn("store.volatile"); + let ptr = self.check_store(val, ptr); unsafe { let insn = llvm::LLVMBuildStore(self.llbuilder, val, ptr); llvm::LLVMSetVolatile(insn, llvm::True); @@ -562,6 +564,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { pub fn atomic_store(&self, val: ValueRef, ptr: ValueRef, order: AtomicOrdering) { debug!("Store {:?} -> {:?}", Value(val), Value(ptr)); self.count_insn("store.atomic"); + let ptr = self.check_store(val, ptr); unsafe { let ty = Type::from_ref(llvm::LLVMTypeOf(ptr)); let align = llalign_of_pref(self.ccx, ty.element_type()); @@ -1100,6 +1103,27 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } + /// Returns the ptr value that should be used for storing `val`. + fn check_store<'b>(&self, + val: ValueRef, + ptr: ValueRef) -> ValueRef { + let dest_ptr_ty = val_ty(ptr); + let stored_ty = val_ty(val); + let stored_ptr_ty = stored_ty.ptr_to(); + + assert_eq!(dest_ptr_ty.kind(), llvm::TypeKind::Pointer); + + if dest_ptr_ty == stored_ptr_ty { + ptr + } else { + debug!("Type mismatch in store. \ + Expected {:?}, got {:?}; inserting bitcast", + dest_ptr_ty, stored_ptr_ty); + self.bitcast(ptr, stored_ptr_ty) + } + } + + /// Returns the args that should be used for a call to `llfn`. fn check_call<'b>(&self, typ: &str, llfn: ValueRef, From f6859b07967e51de2620566340cfa8c4b1a7c4ab Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 12 Oct 2016 19:29:50 +0200 Subject: [PATCH 41/43] Some tests to check that lifetime parametric fn's do not trip up LLVM. --- .../issue-36744-bitcast-args-if-needed.rs | 32 +++++++++++++++++++ .../run-pass/issue-36744-without-calls.rs | 22 +++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 src/test/run-pass/issue-36744-bitcast-args-if-needed.rs create mode 100644 src/test/run-pass/issue-36744-without-calls.rs diff --git a/src/test/run-pass/issue-36744-bitcast-args-if-needed.rs b/src/test/run-pass/issue-36744-bitcast-args-if-needed.rs new file mode 100644 index 0000000000000..1859cc9ca00b5 --- /dev/null +++ b/src/test/run-pass/issue-36744-bitcast-args-if-needed.rs @@ -0,0 +1,32 @@ +// Copyright 2016 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. + +// This tests for an ICE (and, if ignored, subsequent LLVM abort) when +// a lifetime-parametric fn is passed into a context whose expected +// type has a differing lifetime parameterization. + +struct A<'a> { + _a: &'a i32, +} + +fn call(s: T, functions: &Vec fn(&'n T)>) { + for function in functions { + function(&s); + } +} + +fn f(a: &A) { println!("a holds {}", a._a); } + +fn main() { + let a = A { _a: &10 }; + + let vec: Vec fn(&'u A<'v>)> = vec![f]; + call(a, &vec); +} diff --git a/src/test/run-pass/issue-36744-without-calls.rs b/src/test/run-pass/issue-36744-without-calls.rs new file mode 100644 index 0000000000000..1766edb06b481 --- /dev/null +++ b/src/test/run-pass/issue-36744-without-calls.rs @@ -0,0 +1,22 @@ +// Copyright 2016 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. + +// Tests for an LLVM abort when storing a lifetime-parametric fn into +// context that is expecting one that is not lifetime-parametric +// (i.e. has no `for <'_>`). + +pub struct A<'a>(&'a ()); +pub struct S(T); + +pub fn bad<'s>(v: &mut S)>, y: S fn(A<'b>)>) { + *v = y; +} + +fn main() {} From 2d493421cacc42d04e7626259cc08a51ef6c24cb Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 13 Oct 2016 14:55:31 -0400 Subject: [PATCH 42/43] debuginfo: Create debuginfo for re-aggregated spread_arg instead of for the individual pieces. --- src/librustc_trans/mir/mod.rs | 35 +++++++++++++---------------------- 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/src/librustc_trans/mir/mod.rs b/src/librustc_trans/mir/mod.rs index 727b680541dd7..3b2059cd7ed18 100644 --- a/src/librustc_trans/mir/mod.rs +++ b/src/librustc_trans/mir/mod.rs @@ -22,7 +22,6 @@ use machine; use type_of; use syntax_pos::DUMMY_SP; -use syntax::parse::token::keywords; use std::ops::Deref; use std::rc::Rc; @@ -301,7 +300,6 @@ fn arg_local_refs<'bcx, 'tcx>(bcx: &BlockAndBuilder<'bcx, 'tcx>, _ => bug!("spread argument isn't a tuple?!") }; - let lltuplety = type_of::type_of(bcx.ccx(), arg_ty); let lltemp = bcx.with_block(|bcx| { base::alloc_ty(bcx, arg_ty, &format!("arg{}", arg_index)) }); @@ -319,27 +317,20 @@ fn arg_local_refs<'bcx, 'tcx>(bcx: &BlockAndBuilder<'bcx, 'tcx>, } else { arg.store_fn_arg(bcx, &mut llarg_idx, dst); } - - bcx.with_block(|bcx| arg_scope.map(|scope| { - let byte_offset_of_var_in_tuple = - machine::llelement_offset(bcx.ccx(), lltuplety, i); - - let ops = unsafe { - [llvm::LLVMRustDIBuilderCreateOpDeref(), - llvm::LLVMRustDIBuilderCreateOpPlus(), - byte_offset_of_var_in_tuple as i64] - }; - - let variable_access = VariableAccess::IndirectVariable { - alloca: lltemp, - address_operations: &ops - }; - declare_local(bcx, keywords::Invalid.name(), - tupled_arg_ty, scope, variable_access, - VariableKind::ArgumentVariable(arg_index + i + 1), - bcx.fcx().span.unwrap_or(DUMMY_SP)); - })); } + + // Now that we have one alloca that contains the aggregate value, + // we can create one debuginfo entry for the argument. + bcx.with_block(|bcx| arg_scope.map(|scope| { + let variable_access = VariableAccess::DirectVariable { + alloca: lltemp + }; + declare_local(bcx, arg_decl.debug_name, + arg_ty, scope, variable_access, + VariableKind::ArgumentVariable(arg_index + 1), + bcx.fcx().span.unwrap_or(DUMMY_SP)); + })); + return LocalRef::Lvalue(LvalueRef::new_sized(lltemp, LvalueTy::from_ty(arg_ty))); } From 405f146f20c254e91b5328e97013fe3811cba39a Mon Sep 17 00:00:00 2001 From: Ximin Luo Date: Fri, 28 Oct 2016 17:31:21 +0200 Subject: [PATCH 43/43] Delete stuff that should have been deleted in 1.12.1 Otherwise 1.12.1 FTBFS on Debian when trying to bootstrap from 1.12.0. --- src/libpanic_unwind/gcc.rs | 24 ------------------------ src/libpanic_unwind/seh64_gnu.rs | 15 --------------- 2 files changed, 39 deletions(-) diff --git a/src/libpanic_unwind/gcc.rs b/src/libpanic_unwind/gcc.rs index fdae8f69a9c0e..bd0c2f5126d13 100644 --- a/src/libpanic_unwind/gcc.rs +++ b/src/libpanic_unwind/gcc.rs @@ -264,30 +264,6 @@ unsafe fn find_eh_action(context: *mut uw::_Unwind_Context) -> EHAction { eh::find_eh_action(lsda, &eh_context) } -// *** Delete after a new snapshot *** -#[cfg(all(stage0, any(target_os = "ios", not(target_arch = "arm"))))] -#[lang = "eh_personality_catch"] -#[no_mangle] -pub unsafe extern "C" fn rust_eh_personality_catch(version: c_int, - actions: uw::_Unwind_Action, - exception_class: uw::_Unwind_Exception_Class, - ue_header: *mut uw::_Unwind_Exception, - context: *mut uw::_Unwind_Context) - -> uw::_Unwind_Reason_Code { - rust_eh_personality(version, actions, exception_class, ue_header, context) -} - -// *** Delete after a new snapshot *** -#[cfg(all(stage0, target_arch = "arm", not(target_os = "ios")))] -#[lang = "eh_personality_catch"] -#[no_mangle] -pub unsafe extern "C" fn rust_eh_personality_catch(state: uw::_Unwind_State, - ue_header: *mut uw::_Unwind_Exception, - context: *mut uw::_Unwind_Context) - -> uw::_Unwind_Reason_Code { - rust_eh_personality(state, ue_header, context) -} - // See docs in the `unwind` module. #[cfg(all(target_os="windows", target_arch = "x86", target_env="gnu"))] #[lang = "eh_unwind_resume"] diff --git a/src/libpanic_unwind/seh64_gnu.rs b/src/libpanic_unwind/seh64_gnu.rs index 3642e2488958e..e6d3920b29cb0 100644 --- a/src/libpanic_unwind/seh64_gnu.rs +++ b/src/libpanic_unwind/seh64_gnu.rs @@ -81,21 +81,6 @@ pub unsafe fn cleanup(ptr: *mut u8) -> Box { // This is considered acceptable, because the behavior of throwing exceptions // through a C ABI boundary is undefined. -// *** Delete after a new snapshot *** -#[cfg(stage0)] -#[lang = "eh_personality_catch"] -#[cfg(not(test))] -unsafe extern "C" fn rust_eh_personality_catch(exceptionRecord: *mut c::EXCEPTION_RECORD, - establisherFrame: c::LPVOID, - contextRecord: *mut c::CONTEXT, - dispatcherContext: *mut c::DISPATCHER_CONTEXT) - -> c::EXCEPTION_DISPOSITION { - rust_eh_personality(exceptionRecord, - establisherFrame, - contextRecord, - dispatcherContext) -} - #[lang = "eh_personality"] #[cfg(not(test))] unsafe extern "C" fn rust_eh_personality(exceptionRecord: *mut c::EXCEPTION_RECORD,