From e15a07ad64516b8b865ec1d0a499e360a33ace3c Mon Sep 17 00:00:00 2001 From: Chris Stankus Date: Fri, 18 Aug 2017 12:20:04 -0500 Subject: [PATCH 01/40] Remove Borrow bound from SliceExt::binary_search --- src/libcore/slice/mod.rs | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 31d8266510a1e..dacc014955a90 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -35,7 +35,6 @@ // * The `raw` and `bytes` submodules. // * Boilerplate trait implementations. -use borrow::Borrow; use cmp::Ordering::{self, Less, Equal, Greater}; use cmp; use fmt; @@ -122,19 +121,17 @@ pub trait SliceExt { fn as_ptr(&self) -> *const Self::Item; #[stable(feature = "core", since = "1.6.0")] - fn binary_search(&self, x: &Q) -> Result - where Self::Item: Borrow, - Q: Ord; + fn binary_search(&self, x: &Self::Item) -> Result + where Self::Item: Ord; #[stable(feature = "core", since = "1.6.0")] fn binary_search_by<'a, F>(&'a self, f: F) -> Result where F: FnMut(&'a Self::Item) -> Ordering; #[stable(feature = "slice_binary_search_by_key", since = "1.10.0")] - fn binary_search_by_key<'a, B, F, Q: ?Sized>(&'a self, b: &Q, f: F) -> Result + fn binary_search_by_key<'a, B, F>(&'a self, b: &B, f: F) -> Result where F: FnMut(&'a Self::Item) -> B, - B: Borrow, - Q: Ord; + B: Ord; #[stable(feature = "core", since = "1.6.0")] fn len(&self) -> usize; @@ -635,11 +632,10 @@ impl SliceExt for [T] { m >= n && needle == &self[m-n..] } - fn binary_search(&self, x: &Q) -> Result - where T: Borrow, - Q: Ord + fn binary_search(&self, x: &T) -> Result + where T: Ord { - self.binary_search_by(|p| p.borrow().cmp(x)) + self.binary_search_by(|p| p.cmp(x)) } fn rotate(&mut self, mid: usize) { @@ -687,12 +683,11 @@ impl SliceExt for [T] { } #[inline] - fn binary_search_by_key<'a, B, F, Q: ?Sized>(&'a self, b: &Q, mut f: F) -> Result + fn binary_search_by_key<'a, B, F>(&'a self, b: &B, mut f: F) -> Result where F: FnMut(&'a Self::Item) -> B, - B: Borrow, - Q: Ord + B: Ord { - self.binary_search_by(|k| f(k).borrow().cmp(b)) + self.binary_search_by(|k| f(k).cmp(b)) } #[inline] From 758a0ce934510b4e77586d02bc30a3d1d5d63cae Mon Sep 17 00:00:00 2001 From: Ulrik Sverdrup Date: Sat, 2 Sep 2017 16:28:48 +0200 Subject: [PATCH 02/40] alloc: Implement downcast Rc -> Rc Implement downcast the like it exists for Box. The implementation avoids using into_raw/from_raw, because the pointer arithmetic which should cancel does not seem to optimize out at the moment. Since Rc is never Send, only Rc and not Rc implements downcast. --- src/liballoc/rc.rs | 61 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 47f537caf31c4..814be059da7c0 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -244,6 +244,7 @@ use boxed::Box; #[cfg(test)] use std::boxed::Box; +use core::any::Any; use core::borrow; use core::cell::Cell; use core::cmp::Ordering; @@ -608,6 +609,46 @@ impl Rc { } } +impl Rc { + #[inline] + #[unstable(feature = "rc_downcast", issue = "0")] + /// Attempt to downcast the `Rc` to a concrete type. + /// + /// # Examples + /// + /// ``` + /// #![feature(rc_downcast)] + /// use std::any::Any; + /// use std::rc::Rc; + /// + /// fn print_if_string(value: Rc) { + /// if let Ok(string) = value.downcast::() { + /// println!("String ({}): {}", string.len(), string); + /// } + /// } + /// + /// fn main() { + /// let my_string = "Hello World".to_string(); + /// print_if_string(Rc::new(my_string)); + /// print_if_string(Rc::new(0i8)); + /// } + /// ``` + pub fn downcast(self) -> Result, Rc> { + if (*self).is::() { + // avoid the pointer arithmetic in from_raw + unsafe { + let raw: *const RcBox = self.ptr.as_ptr(); + forget(self); + Ok(Rc { + ptr: Shared::new_unchecked(raw as *const RcBox as *mut _), + }) + } + } else { + Err(self) + } + } +} + impl Rc { // Allocates an `RcBox` with sufficient space for an unsized value unsafe fn allocate_for_ptr(ptr: *const T) -> *mut RcBox { @@ -1696,6 +1737,26 @@ mod tests { assert_eq!(&r[..], [1, 2, 3]); } + + #[test] + fn test_downcast() { + use std::any::Any; + + let r1: Rc = Rc::new(i32::max_value()); + let r2: Rc = Rc::new("abc"); + + assert!(r1.clone().downcast::().is_err()); + + let r1i32 = r1.downcast::(); + assert!(r1i32.is_ok()); + assert_eq!(r1i32.unwrap(), Rc::new(i32::max_value())); + + assert!(r2.clone().downcast::().is_err()); + + let r2str = r2.downcast::<&'static str>(); + assert!(r2str.is_ok()); + assert_eq!(r2str.unwrap(), Rc::new("abc")); + } } #[stable(feature = "rust1", since = "1.0.0")] From c22db3db6d18141e21ea79cd6e0118177850b1b9 Mon Sep 17 00:00:00 2001 From: "J. Cliff Dyer" Date: Thu, 7 Sep 2017 14:08:58 -0400 Subject: [PATCH 03/40] IP address convenience constructors --- src/libstd/net/ip.rs | 68 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs index 0abf8179cc971..d6387fdd659a8 100644 --- a/src/libstd/net/ip.rs +++ b/src/libstd/net/ip.rs @@ -342,6 +342,32 @@ impl Ipv4Addr { } } + /// Creates a new IPv4 address with the address pointing to localhost: 127.0.0.1. + /// + /// # Examples + /// + /// ``` + /// use std::net::Ipv4Addr; + /// + /// let addr = Ipv4Addr::localhost(); + /// assert_eq!(addr, Ipv4Addr::new(127, 0, 0, 1)); + pub fn localhost() -> Ipv4Addr { + Ipv4Addr::new(127, 0, 0, 1) + } + + /// Creates a new IPv4 address representing an unspecified address: 0.0.0.0 + /// + /// # Examples + /// + /// ``` + /// use std::net::Ipv4Addr; + /// + /// let addr = Ipv4Addr::unspecified(); + /// assert_eq!(addr, Ipv4Addr::new(0, 0, 0, 0)); + pub fn unspecified() -> Ipv4Addr { + Ipv4Addr::new(0, 0, 0, 0) + } + /// Returns the four eight-bit integers that make up this address. /// /// # Examples @@ -788,6 +814,32 @@ impl Ipv6Addr { Ipv6Addr { inner: addr } } + /// Creates a new IPv6 address representing localhost: `::1`. + /// + /// # Examples + /// + /// ``` + /// use std::net::Ipv6Addr; + /// + /// let addr = Ipv6Addr::localhost(); + /// assert_eq!(addr, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)); + pub fn localhost() -> Ipv6Addr { + Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1) + } + + /// Creates a new IPv6 address representing the unspecified address: `::` + /// + /// # Examples + /// + /// ``` + /// use std::net::Ipv6Addr; + /// + /// let addr = Ipv6Addr::unspecified(); + /// assert_eq!(addr, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)); + pub fn unspecified() -> Ipv6Addr { + Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0) + } + /// Returns the eight 16-bit segments that make up this address. /// /// # Examples @@ -1681,6 +1733,22 @@ mod tests { assert_eq!(Ipv6Addr::from(0x112233445566778899aabbccddeeff11u128), a); } + #[test] + fn ipv4_from_constructors() { + assert_eq!(Ipv4Addr::localhost(), Ipv4Addr::new(127, 0, 0, 1)); + assert!(Ipv4Addr::localhost().is_loopback()); + assert_eq!(Ipv4Addr::unspecified(), Ipv4Addr::new(0, 0, 0, 0)); + assert!(Ipv4Addr::unspecified().is_unspecified()); + } + + #[test] + fn ipv6_from_contructors() { + assert_eq!(Ipv6Addr::localhost(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)); + assert!(Ipv6Addr::localhost().is_loopback()); + assert_eq!(Ipv6Addr::unspecified(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)); + assert!(Ipv6Addr::unspecified().is_unspecified()); + } + #[test] fn ipv4_from_octets() { assert_eq!(Ipv4Addr::from([127, 0, 0, 1]), Ipv4Addr::new(127, 0, 0, 1)) From ad170f23397f9da8d2180c4a48981808bf5535c9 Mon Sep 17 00:00:00 2001 From: "J. Cliff Dyer" Date: Thu, 7 Sep 2017 19:06:57 -0400 Subject: [PATCH 04/40] Close doc examples and trim whitespace. --- src/libstd/net/ip.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs index d6387fdd659a8..a3775d30aa8b2 100644 --- a/src/libstd/net/ip.rs +++ b/src/libstd/net/ip.rs @@ -351,6 +351,7 @@ impl Ipv4Addr { /// /// let addr = Ipv4Addr::localhost(); /// assert_eq!(addr, Ipv4Addr::new(127, 0, 0, 1)); + /// ``` pub fn localhost() -> Ipv4Addr { Ipv4Addr::new(127, 0, 0, 1) } @@ -364,6 +365,7 @@ impl Ipv4Addr { /// /// let addr = Ipv4Addr::unspecified(); /// assert_eq!(addr, Ipv4Addr::new(0, 0, 0, 0)); + /// ``` pub fn unspecified() -> Ipv4Addr { Ipv4Addr::new(0, 0, 0, 0) } @@ -823,6 +825,7 @@ impl Ipv6Addr { /// /// let addr = Ipv6Addr::localhost(); /// assert_eq!(addr, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)); + /// ``` pub fn localhost() -> Ipv6Addr { Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1) } @@ -836,6 +839,7 @@ impl Ipv6Addr { /// /// let addr = Ipv6Addr::unspecified(); /// assert_eq!(addr, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)); + /// ``` pub fn unspecified() -> Ipv6Addr { Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0) } @@ -1748,7 +1752,7 @@ mod tests { assert_eq!(Ipv6Addr::unspecified(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)); assert!(Ipv6Addr::unspecified().is_unspecified()); } - + #[test] fn ipv4_from_octets() { assert_eq!(Ipv4Addr::from([127, 0, 0, 1]), Ipv4Addr::new(127, 0, 0, 1)) From 8b6122f8b8001de80fce59a5896566b31c6a69ff Mon Sep 17 00:00:00 2001 From: "J. Cliff Dyer" Date: Fri, 8 Sep 2017 17:20:31 -0400 Subject: [PATCH 05/40] Add feature gate to doctests. --- src/libstd/net/ip.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs index a3775d30aa8b2..d3ea3845f1207 100644 --- a/src/libstd/net/ip.rs +++ b/src/libstd/net/ip.rs @@ -347,6 +347,7 @@ impl Ipv4Addr { /// # Examples /// /// ``` + /// #![feature(ip)] /// use std::net::Ipv4Addr; /// /// let addr = Ipv4Addr::localhost(); @@ -361,6 +362,7 @@ impl Ipv4Addr { /// # Examples /// /// ``` + /// #![feature(ip)] /// use std::net::Ipv4Addr; /// /// let addr = Ipv4Addr::unspecified(); @@ -821,6 +823,7 @@ impl Ipv6Addr { /// # Examples /// /// ``` + /// #![feature(ip)] /// use std::net::Ipv6Addr; /// /// let addr = Ipv6Addr::localhost(); @@ -835,6 +838,7 @@ impl Ipv6Addr { /// # Examples /// /// ``` + /// #![feature(ip)] /// use std::net::Ipv6Addr; /// /// let addr = Ipv6Addr::unspecified(); From 4f245073b2551f99ba9826274f0e656ef6a40664 Mon Sep 17 00:00:00 2001 From: Alexis Beingessner Date: Thu, 17 Aug 2017 17:45:01 -0400 Subject: [PATCH 06/40] implement unsafe pointer methods --- src/libcore/ptr.rs | 1186 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 1174 insertions(+), 12 deletions(-) diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 2e42e0dfd550d..3c597e68e2e9a 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -51,7 +51,7 @@ pub use intrinsics::write_bytes; /// as the compiler doesn't need to prove that it's sound to elide the /// copy. /// -/// # Undefined Behavior +/// # Safety /// /// This has all the same safety problems as `ptr::read` with respect to /// invalid pointers, types, and double drops. @@ -525,15 +525,41 @@ impl *const T { } } - /// Calculates the offset from a pointer. `count` is in units of T; e.g. a - /// `count` of 3 represents a pointer offset of `3 * size_of::()` bytes. + /// Calculates the offset from a pointer. + /// + /// `count` is in units of T; e.g. a `count` of 3 represents a pointer + /// offset of `3 * size_of::()` bytes. /// /// # Safety /// - /// Both the starting and resulting pointer must be either in bounds or one - /// byte past the end of an allocated object. If either pointer is out of - /// bounds or arithmetic overflow occurs then - /// any further use of the returned value will result in undefined behavior. + /// If any of the following conditions are violated, the result is Undefined + /// Behavior: + /// + /// * Both the starting and resulting pointer must be either in bounds or one + /// byte past the end of an allocated object. + /// + /// * The computed offset, **in bytes**, cannot overflow or underflow an + /// `isize`. + /// + /// * The offset being in bounds cannot rely on "wrapping around" the address + /// space. That is, the infinite-precision sum, **in bytes** must fit in a usize. + /// + /// The compiler and standard library generally tries to ensure allocations + /// never reach a size where an offset is a concern. For instance, `Vec` + /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so + /// `vec.as_ptr().offset(vec.len() as isize)` is always safe. + /// + /// Most platforms fundamentally can't even construct such an allocation. + /// For instance, no known 64-bit platform can ever serve a request + /// for 2^63 bytes due to page-table limitations or splitting the address space. + /// However, some 32-bit and 16-bit platforms may successfully serve a request for + /// more than `isize::MAX` bytes with things like Physical Address + /// Extension. As such, memory acquired directly from allocators or memory + /// mapped files *may* be too large to handle with this function. + /// + /// Consider using `wrapping_offset` instead if these constraints are + /// difficult to satisfy. The only advantage of this method is that it + /// enables more aggressive compiler optimizations. /// /// # Examples /// @@ -555,6 +581,7 @@ impl *const T { } /// Calculates the offset from a pointer using wrapping arithmetic. + /// /// `count` is in units of T; e.g. a `count` of 3 represents a pointer /// offset of `3 * size_of::()` bytes. /// @@ -630,6 +657,412 @@ impl *const T { Some(diff / size as isize) } } + + /// Calculates the offset from a pointer (convenience for `.offset(count as isize)`). + /// + /// `count` is in units of T; e.g. a `count` of 3 represents a pointer + /// offset of `3 * size_of::()` bytes. + /// + /// # Safety + /// + /// If any of the following conditions are violated, the result is Undefined + /// Behavior: + /// + /// * Both the starting and resulting pointer must be either in bounds or one + /// byte past the end of an allocated object. + /// + /// * The computed offset, **in bytes**, cannot overflow or underflow an + /// `isize`. + /// + /// * The offset being in bounds cannot rely on "wrapping around" the address + /// space. That is, the infinite-precision sum must fit in a `usize`. + /// + /// The compiler and standard library generally tries to ensure allocations + /// never reach a size where an offset is a concern. For instance, `Vec` + /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so + /// `vec.as_ptr().add(vec.len())` is always safe. + /// + /// Most platforms fundamentally can't even construct such an allocation. + /// For instance, no known 64-bit platform can ever serve a request + /// for 2^63 bytes due to page-table limitations or splitting the address space. + /// However, some 32-bit and 16-bit platforms may successfully serve a request for + /// more than `isize::MAX` bytes with things like Physical Address + /// Extension. As such, memory acquired directly from allocators or memory + /// mapped files *may* be too large to handle with this function. + /// + /// Consider using `wrapping_offset` instead if these constraints are + /// difficult to satisfy. The only advantage of this method is that it + /// enables more aggressive compiler optimizations. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(pointer_methods)] + /// + /// let s: &str = "123"; + /// let ptr: *const u8 = s.as_ptr(); + /// + /// unsafe { + /// println!("{}", *ptr.add(1) as char); + /// println!("{}", *ptr.add(2) as char); + /// } + /// ``` + #[unstable(feature = "pointer_methods", issue = "43941")] + #[inline] + pub unsafe fn add(self, count: usize) -> Self + where T: Sized, + { + self.offset(count as isize) + } + + /// Calculates the offset from a pointer (convenience for + /// `.offset((count as isize).wrapping_neg())`). + /// + /// `count` is in units of T; e.g. a `count` of 3 represents a pointer + /// offset of `3 * size_of::()` bytes. + /// + /// # Safety + /// + /// If any of the following conditions are violated, the result is Undefined + /// Behavior: + /// + /// * Both the starting and resulting pointer must be either in bounds or one + /// byte past the end of an allocated object. + /// + /// * The computed offset cannot exceed `isize::MAX` **bytes**. + /// + /// * The offset being in bounds cannot rely on "wrapping around" the address + /// space. That is, the infinite-precision sum must fit in a usize. + /// + /// The compiler and standard library generally tries to ensure allocations + /// never reach a size where an offset is a concern. For instance, `Vec` + /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so + /// `vec.as_ptr().add(vec.len()).sub(vec.len())` is always safe. + /// + /// Most platforms fundamentally can't even construct such an allocation. + /// For instance, no known 64-bit platform can ever serve a request + /// for 2^63 bytes due to page-table limitations or splitting the address space. + /// However, some 32-bit and 16-bit platforms may successfully serve a request for + /// more than `isize::MAX` bytes with things like Physical Address + /// Extension. As such, memory acquired directly from allocators or memory + /// mapped files *may* be too large to handle with this function. + /// + /// Consider using `wrapping_offset` instead if these constraints are + /// difficult to satisfy. The only advantage of this method is that it + /// enables more aggressive compiler optimizations. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(pointer_methods)] + /// + /// let s: &str = "123"; + /// + /// unsafe { + /// let end: *const u8 = s.as_ptr().add(3); + /// println!("{}", *end.sub(1) as char); + /// println!("{}", *end.sub(2) as char); + /// } + /// ``` + #[unstable(feature = "pointer_methods", issue = "43941")] + #[inline] + pub unsafe fn sub(self, count: usize) -> Self + where T: Sized, + { + self.offset((count as isize).wrapping_neg()) + } + + /// Calculates the offset from a pointer using wrapping arithmetic. + /// (convenience for `.wrapping_offset(count as isize)`) + /// + /// `count` is in units of T; e.g. a `count` of 3 represents a pointer + /// offset of `3 * size_of::()` bytes. + /// + /// # Safety + /// + /// The resulting pointer does not need to be in bounds, but it is + /// potentially hazardous to dereference (which requires `unsafe`). + /// + /// Always use `.add(count)` instead when possible, because `add` + /// allows the compiler to optimize better. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(pointer_methods)] + /// + /// // Iterate using a raw pointer in increments of two elements + /// let data = [1u8, 2, 3, 4, 5]; + /// let mut ptr: *const u8 = data.as_ptr(); + /// let step = 2; + /// let end_rounded_up = ptr.wrapping_add(6); + /// + /// // This loop prints "1, 3, 5, " + /// while ptr != end_rounded_up { + /// unsafe { + /// print!("{}, ", *ptr); + /// } + /// ptr = ptr.wrapping_add(step); + /// } + /// ``` + #[unstable(feature = "pointer_methods", issue = "43941")] + #[inline] + pub fn wrapping_add(self, count: usize) -> Self + where T: Sized, + { + self.wrapping_offset(count as isize) + } + + /// Calculates the offset from a pointer using wrapping arithmetic. + /// (convenience for `.wrapping_offset((count as isize).wrapping_sub())`) + /// + /// `count` is in units of T; e.g. a `count` of 3 represents a pointer + /// offset of `3 * size_of::()` bytes. + /// + /// # Safety + /// + /// The resulting pointer does not need to be in bounds, but it is + /// potentially hazardous to dereference (which requires `unsafe`). + /// + /// Always use `.sub(count)` instead when possible, because `sub` + /// allows the compiler to optimize better. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(pointer_methods)] + /// + /// // Iterate using a raw pointer in increments of two elements (backwards) + /// let data = [1u8, 2, 3, 4, 5]; + /// let mut ptr: *const u8 = data.as_ptr(); + /// let start_rounded_down = ptr.wrapping_sub(2); + /// ptr = ptr.wrapping_add(4); + /// let step = 2; + /// // This loop prints "5, 3, 1, " + /// while ptr != start_rounded_down { + /// unsafe { + /// print!("{}, ", *ptr); + /// } + /// ptr = ptr.wrapping_sub(step); + /// } + /// ``` + #[unstable(feature = "pointer_methods", issue = "43941")] + #[inline] + pub fn wrapping_sub(self, count: usize) -> Self + where T: Sized, + { + self.wrapping_offset((count as isize).wrapping_neg()) + } + + /// Reads the value from `self` without moving it. This leaves the + /// memory in `self` unchanged. + /// + /// # Safety + /// + /// Beyond accepting a raw pointer, this is unsafe because it semantically + /// moves the value out of `self` without preventing further usage of `self`. + /// If `T` is not `Copy`, then care must be taken to ensure that the value at + /// `self` is not used before the data is overwritten again (e.g. with `write`, + /// `zero_memory`, or `copy_memory`). Note that `*self = foo` counts as a use + /// because it will attempt to drop the value previously at `*self`. + /// + /// The pointer must be aligned; use `read_unaligned` if that is not the case. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(pointer_methods)] + /// + /// let x = 12; + /// let y = &x as *const i32; + /// + /// unsafe { + /// assert_eq!(y.read(), 12); + /// } + /// ``` + #[unstable(feature = "pointer_methods", issue = "43941")] + #[inline] + pub unsafe fn read(self) -> T + where T: Sized, + { + read(self) + } + + /// Performs a volatile read of the value from `self` without moving it. This + /// leaves the memory in `self` unchanged. + /// + /// Volatile operations are intended to act on I/O memory, and are guaranteed + /// to not be elided or reordered by the compiler across other volatile + /// operations. + /// + /// # Notes + /// + /// Rust does not currently have a rigorously and formally defined memory model, + /// so the precise semantics of what "volatile" means here is subject to change + /// over time. That being said, the semantics will almost always end up pretty + /// similar to [C11's definition of volatile][c11]. + /// + /// The compiler shouldn't change the relative order or number of volatile + /// memory operations. However, volatile memory operations on zero-sized types + /// (e.g. if a zero-sized type is passed to `read_volatile`) are no-ops + /// and may be ignored. + /// + /// [c11]: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf + /// + /// # Safety + /// + /// Beyond accepting a raw pointer, this is unsafe because it semantically + /// moves the value out of `self` without preventing further usage of `self`. + /// If `T` is not `Copy`, then care must be taken to ensure that the value at + /// `self` is not used before the data is overwritten again (e.g. with `write`, + /// `zero_memory`, or `copy_memory`). Note that `*self = foo` counts as a use + /// because it will attempt to drop the value previously at `*self`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(pointer_methods)] + /// + /// let x = 12; + /// let y = &x as *const i32; + /// + /// unsafe { + /// assert_eq!(y.read_volatile(), 12); + /// } + /// ``` + #[unstable(feature = "pointer_methods", issue = "43941")] + #[inline] + pub unsafe fn read_volatile(self) -> T + where T: Sized, + { + read_volatile(self) + } + + /// Reads the value from `self` without moving it. This leaves the + /// memory in `self` unchanged. + /// + /// Unlike `read`, the pointer may be unaligned. + /// + /// # Safety + /// + /// Beyond accepting a raw pointer, this is unsafe because it semantically + /// moves the value out of `self` without preventing further usage of `self`. + /// If `T` is not `Copy`, then care must be taken to ensure that the value at + /// `self` is not used before the data is overwritten again (e.g. with `write`, + /// `zero_memory`, or `copy_memory`). Note that `*self = foo` counts as a use + /// because it will attempt to drop the value previously at `*self`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(pointer_methods)] + /// + /// let x = 12; + /// let y = &x as *const i32; + /// + /// unsafe { + /// assert_eq!(y.read_unaligned(), 12); + /// } + /// ``` + #[unstable(feature = "pointer_methods", issue = "43941")] + #[inline] + pub unsafe fn read_unaligned(self) -> T + where T: Sized, + { + read_unaligned(self) + } + + /// Copies `count * size_of` bytes from `self` to `dest`. The source + /// and destination may overlap. + /// + /// NOTE: this has the *same* argument order as `ptr::copy`. + /// + /// This is semantically equivalent to C's `memmove`. + /// + /// # Safety + /// + /// Care must be taken with the ownership of `self` and `dest`. + /// This method semantically moves the values of `self` into `dest`. + /// However it does not drop the contents of `self`, or prevent the contents + /// of `dest` from being dropped or used. + /// + /// # Examples + /// + /// Efficiently create a Rust vector from an unsafe buffer: + /// + /// ``` + /// #![feature(pointer_methods)] + /// + /// # #[allow(dead_code)] + /// unsafe fn from_buf_raw(ptr: *const T, elts: usize) -> Vec { + /// let mut dst = Vec::with_capacity(elts); + /// dst.set_len(elts); + /// ptr.copy_to(dst.as_mut_ptr(), elts); + /// dst + /// } + /// ``` + #[unstable(feature = "pointer_methods", issue = "43941")] + #[inline] + pub unsafe fn copy_to(self, dest: *mut T, count: usize) + where T: Sized, + { + copy(self, dest, count) + } + + /// Copies `count * size_of` bytes from `self` to `dest`. The source + /// and destination may *not* overlap. + /// + /// NOTE: this has the *same* argument order as `ptr::copy_nonoverlapping`. + /// + /// `copy_nonoverlapping` is semantically equivalent to C's `memcpy`. + /// + /// # Safety + /// + /// Beyond requiring that the program must be allowed to access both regions + /// of memory, it is Undefined Behavior for source and destination to + /// overlap. Care must also be taken with the ownership of `self` and + /// `self`. This method semantically moves the values of `self` into `dest`. + /// However it does not drop the contents of `dest`, or prevent the contents + /// of `self` from being dropped or used. + /// + /// # Examples + /// + /// Efficiently create a Rust vector from an unsafe buffer: + /// + /// ``` + /// #![feature(pointer_methods)] + /// + /// # #[allow(dead_code)] + /// unsafe fn from_buf_raw(ptr: *const T, elts: usize) -> Vec { + /// let mut dst = Vec::with_capacity(elts); + /// dst.set_len(elts); + /// ptr.copy_to_nonoverlapping(dst.as_mut_ptr(), elts); + /// dst + /// } + /// ``` + #[unstable(feature = "pointer_methods", issue = "43941")] + #[inline] + pub unsafe fn copy_to_nonoverlapping(self, dest: *mut T, count: usize) + where T: Sized, + { + copy_nonoverlapping(self, dest, count) + } + + } #[lang = "mut_ptr"] @@ -687,14 +1120,41 @@ impl *mut T { } } - /// Calculates the offset from a pointer. `count` is in units of T; e.g. a - /// `count` of 3 represents a pointer offset of `3 * size_of::()` bytes. + /// Calculates the offset from a pointer. + /// + /// `count` is in units of T; e.g. a `count` of 3 represents a pointer + /// offset of `3 * size_of::()` bytes. /// /// # Safety /// - /// The offset must be in-bounds of the object, or one-byte-past-the-end. - /// Otherwise `offset` invokes Undefined Behavior, regardless of whether - /// the pointer is used. + /// If any of the following conditions are violated, the result is Undefined + /// Behavior: + /// + /// * Both the starting and resulting pointer must be either in bounds or one + /// byte past the end of an allocated object. + /// + /// * The computed offset, **in bytes**, cannot overflow or underflow an + /// `isize`. + /// + /// * The offset being in bounds cannot rely on "wrapping around" the address + /// space. That is, the infinite-precision sum, **in bytes** must fit in a usize. + /// + /// The compiler and standard library generally tries to ensure allocations + /// never reach a size where an offset is a concern. For instance, `Vec` + /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so + /// `vec.as_ptr().offset(vec.len() as isize)` is always safe. + /// + /// Most platforms fundamentally can't even construct such an allocation. + /// For instance, no known 64-bit platform can ever serve a request + /// for 2^63 bytes due to page-table limitations or splitting the address space. + /// However, some 32-bit and 16-bit platforms may successfully serve a request for + /// more than `isize::MAX` bytes with things like Physical Address + /// Extension. As such, memory acquired directly from allocators or memory + /// mapped files *may* be too large to handle with this function. + /// + /// Consider using `wrapping_offset` instead if these constraints are + /// difficult to satisfy. The only advantage of this method is that it + /// enables more aggressive compiler optimizations. /// /// # Examples /// @@ -821,6 +1281,708 @@ impl *mut T { Some(diff / size as isize) } } + + + /// Calculates the offset from a pointer (convenience for `.offset(count as isize)`). + /// + /// `count` is in units of T; e.g. a `count` of 3 represents a pointer + /// offset of `3 * size_of::()` bytes. + /// + /// # Safety + /// + /// If any of the following conditions are violated, the result is Undefined + /// Behavior: + /// + /// * Both the starting and resulting pointer must be either in bounds or one + /// byte past the end of an allocated object. + /// + /// * The computed offset, **in bytes**, cannot overflow or underflow an + /// `isize`. + /// + /// * The offset being in bounds cannot rely on "wrapping around" the address + /// space. That is, the infinite-precision sum must fit in a `usize`. + /// + /// The compiler and standard library generally tries to ensure allocations + /// never reach a size where an offset is a concern. For instance, `Vec` + /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so + /// `vec.as_ptr().add(vec.len())` is always safe. + /// + /// Most platforms fundamentally can't even construct such an allocation. + /// For instance, no known 64-bit platform can ever serve a request + /// for 2^63 bytes due to page-table limitations or splitting the address space. + /// However, some 32-bit and 16-bit platforms may successfully serve a request for + /// more than `isize::MAX` bytes with things like Physical Address + /// Extension. As such, memory acquired directly from allocators or memory + /// mapped files *may* be too large to handle with this function. + /// + /// Consider using `wrapping_offset` instead if these constraints are + /// difficult to satisfy. The only advantage of this method is that it + /// enables more aggressive compiler optimizations. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(pointer_methods)] + /// + /// let s: &str = "123"; + /// let ptr: *const u8 = s.as_ptr(); + /// + /// unsafe { + /// println!("{}", *ptr.add(1) as char); + /// println!("{}", *ptr.add(2) as char); + /// } + /// ``` + #[unstable(feature = "pointer_methods", issue = "43941")] + #[inline] + pub unsafe fn add(self, count: usize) -> Self + where T: Sized, + { + self.offset(count as isize) + } + + /// Calculates the offset from a pointer (convenience for + /// `.offset((count as isize).wrapping_neg())`). + /// + /// `count` is in units of T; e.g. a `count` of 3 represents a pointer + /// offset of `3 * size_of::()` bytes. + /// + /// # Safety + /// + /// If any of the following conditions are violated, the result is Undefined + /// Behavior: + /// + /// * Both the starting and resulting pointer must be either in bounds or one + /// byte past the end of an allocated object. + /// + /// * The computed offset cannot exceed `isize::MAX` **bytes**. + /// + /// * The offset being in bounds cannot rely on "wrapping around" the address + /// space. That is, the infinite-precision sum must fit in a usize. + /// + /// The compiler and standard library generally tries to ensure allocations + /// never reach a size where an offset is a concern. For instance, `Vec` + /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so + /// `vec.as_ptr().add(vec.len()).sub(vec.len())` is always safe. + /// + /// Most platforms fundamentally can't even construct such an allocation. + /// For instance, no known 64-bit platform can ever serve a request + /// for 2^63 bytes due to page-table limitations or splitting the address space. + /// However, some 32-bit and 16-bit platforms may successfully serve a request for + /// more than `isize::MAX` bytes with things like Physical Address + /// Extension. As such, memory acquired directly from allocators or memory + /// mapped files *may* be too large to handle with this function. + /// + /// Consider using `wrapping_offset` instead if these constraints are + /// difficult to satisfy. The only advantage of this method is that it + /// enables more aggressive compiler optimizations. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(pointer_methods)] + /// + /// let s: &str = "123"; + /// + /// unsafe { + /// let end: *const u8 = s.as_ptr().add(3); + /// println!("{}", *end.sub(1) as char); + /// println!("{}", *end.sub(2) as char); + /// } + /// ``` + #[unstable(feature = "pointer_methods", issue = "43941")] + #[inline] + pub unsafe fn sub(self, count: usize) -> Self + where T: Sized, + { + self.offset((count as isize).wrapping_neg()) + } + + /// Calculates the offset from a pointer using wrapping arithmetic. + /// (convenience for `.wrapping_offset(count as isize)`) + /// + /// `count` is in units of T; e.g. a `count` of 3 represents a pointer + /// offset of `3 * size_of::()` bytes. + /// + /// # Safety + /// + /// The resulting pointer does not need to be in bounds, but it is + /// potentially hazardous to dereference (which requires `unsafe`). + /// + /// Always use `.add(count)` instead when possible, because `add` + /// allows the compiler to optimize better. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(pointer_methods)] + /// + /// // Iterate using a raw pointer in increments of two elements + /// let data = [1u8, 2, 3, 4, 5]; + /// let mut ptr: *const u8 = data.as_ptr(); + /// let step = 2; + /// let end_rounded_up = ptr.wrapping_add(6); + /// + /// // This loop prints "1, 3, 5, " + /// while ptr != end_rounded_up { + /// unsafe { + /// print!("{}, ", *ptr); + /// } + /// ptr = ptr.wrapping_add(step); + /// } + /// ``` + #[unstable(feature = "pointer_methods", issue = "43941")] + #[inline] + pub fn wrapping_add(self, count: usize) -> Self + where T: Sized, + { + self.wrapping_offset(count as isize) + } + + /// Calculates the offset from a pointer using wrapping arithmetic. + /// (convenience for `.wrapping_offset((count as isize).wrapping_sub())`) + /// + /// `count` is in units of T; e.g. a `count` of 3 represents a pointer + /// offset of `3 * size_of::()` bytes. + /// + /// # Safety + /// + /// The resulting pointer does not need to be in bounds, but it is + /// potentially hazardous to dereference (which requires `unsafe`). + /// + /// Always use `.sub(count)` instead when possible, because `sub` + /// allows the compiler to optimize better. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(pointer_methods)] + /// + /// // Iterate using a raw pointer in increments of two elements (backwards) + /// let data = [1u8, 2, 3, 4, 5]; + /// let mut ptr: *const u8 = data.as_ptr(); + /// let start_rounded_down = ptr.wrapping_sub(2); + /// ptr = ptr.wrapping_add(4); + /// let step = 2; + /// // This loop prints "5, 3, 1, " + /// while ptr != start_rounded_down { + /// unsafe { + /// print!("{}, ", *ptr); + /// } + /// ptr = ptr.wrapping_sub(step); + /// } + /// ``` + #[unstable(feature = "pointer_methods", issue = "43941")] + #[inline] + pub fn wrapping_sub(self, count: usize) -> Self + where T: Sized, + { + self.wrapping_offset((count as isize).wrapping_neg()) + } + + /// Reads the value from `self` without moving it. This leaves the + /// memory in `self` unchanged. + /// + /// # Safety + /// + /// Beyond accepting a raw pointer, this is unsafe because it semantically + /// moves the value out of `self` without preventing further usage of `self`. + /// If `T` is not `Copy`, then care must be taken to ensure that the value at + /// `self` is not used before the data is overwritten again (e.g. with `write`, + /// `zero_memory`, or `copy_memory`). Note that `*self = foo` counts as a use + /// because it will attempt to drop the value previously at `*self`. + /// + /// The pointer must be aligned; use `read_unaligned` if that is not the case. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(pointer_methods)] + /// + /// let x = 12; + /// let y = &x as *const i32; + /// + /// unsafe { + /// assert_eq!(y.read(), 12); + /// } + /// ``` + #[unstable(feature = "pointer_methods", issue = "43941")] + #[inline] + pub unsafe fn read(self) -> T + where T: Sized, + { + read(self) + } + + /// Performs a volatile read of the value from `self` without moving it. This + /// leaves the memory in `self` unchanged. + /// + /// Volatile operations are intended to act on I/O memory, and are guaranteed + /// to not be elided or reordered by the compiler across other volatile + /// operations. + /// + /// # Notes + /// + /// Rust does not currently have a rigorously and formally defined memory model, + /// so the precise semantics of what "volatile" means here is subject to change + /// over time. That being said, the semantics will almost always end up pretty + /// similar to [C11's definition of volatile][c11]. + /// + /// The compiler shouldn't change the relative order or number of volatile + /// memory operations. However, volatile memory operations on zero-sized types + /// (e.g. if a zero-sized type is passed to `read_volatile`) are no-ops + /// and may be ignored. + /// + /// [c11]: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf + /// + /// # Safety + /// + /// Beyond accepting a raw pointer, this is unsafe because it semantically + /// moves the value out of `self` without preventing further usage of `self`. + /// If `T` is not `Copy`, then care must be taken to ensure that the value at + /// `src` is not used before the data is overwritten again (e.g. with `write`, + /// `zero_memory`, or `copy_memory`). Note that `*self = foo` counts as a use + /// because it will attempt to drop the value previously at `*self`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(pointer_methods)] + /// + /// let x = 12; + /// let y = &x as *const i32; + /// + /// unsafe { + /// assert_eq!(y.read_volatile(), 12); + /// } + /// ``` + #[unstable(feature = "pointer_methods", issue = "43941")] + #[inline] + pub unsafe fn read_volatile(self) -> T + where T: Sized, + { + read_volatile(self) + } + + /// Reads the value from `self` without moving it. This leaves the + /// memory in `self` unchanged. + /// + /// Unlike `read`, the pointer may be unaligned. + /// + /// # Safety + /// + /// Beyond accepting a raw pointer, this is unsafe because it semantically + /// moves the value out of `self` without preventing further usage of `self`. + /// If `T` is not `Copy`, then care must be taken to ensure that the value at + /// `self` is not used before the data is overwritten again (e.g. with `write`, + /// `zero_memory`, or `copy_memory`). Note that `*self = foo` counts as a use + /// because it will attempt to drop the value previously at `*self`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(pointer_methods)] + /// + /// let x = 12; + /// let y = &x as *const i32; + /// + /// unsafe { + /// assert_eq!(y.read_unaligned(), 12); + /// } + /// ``` + #[unstable(feature = "pointer_methods", issue = "43941")] + #[inline] + pub unsafe fn read_unaligned(self) -> T + where T: Sized, + { + read_unaligned(self) + } + + /// Copies `count * size_of` bytes from `self` to `dest`. The source + /// and destination may overlap. + /// + /// NOTE: this has the *same* argument order as `ptr::copy`. + /// + /// This is semantically equivalent to C's `memmove`. + /// + /// # Safety + /// + /// Care must be taken with the ownership of `self` and `dest`. + /// This method semantically moves the values of `self` into `dest`. + /// However it does not drop the contents of `self`, or prevent the contents + /// of `dest` from being dropped or used. + /// + /// # Examples + /// + /// Efficiently create a Rust vector from an unsafe buffer: + /// + /// ``` + /// #![feature(pointer_methods)] + /// + /// # #[allow(dead_code)] + /// unsafe fn from_buf_raw(ptr: *const T, elts: usize) -> Vec { + /// let mut dst = Vec::with_capacity(elts); + /// dst.set_len(elts); + /// ptr.copy_to(dst.as_mut_ptr(), elts); + /// dst + /// } + /// ``` + #[unstable(feature = "pointer_methods", issue = "43941")] + #[inline] + pub unsafe fn copy_to(self, dest: *mut T, count: usize) + where T: Sized, + { + copy(self, dest, count) + } + + /// Copies `count * size_of` bytes from `self` to `dest`. The source + /// and destination may *not* overlap. + /// + /// NOTE: this has the *same* argument order as `ptr::copy_nonoverlapping`. + /// + /// `copy_nonoverlapping` is semantically equivalent to C's `memcpy`. + /// + /// # Safety + /// + /// Beyond requiring that the program must be allowed to access both regions + /// of memory, it is Undefined Behavior for source and destination to + /// overlap. Care must also be taken with the ownership of `self` and + /// `self`. This method semantically moves the values of `self` into `dest`. + /// However it does not drop the contents of `dest`, or prevent the contents + /// of `self` from being dropped or used. + /// + /// # Examples + /// + /// Efficiently create a Rust vector from an unsafe buffer: + /// + /// ``` + /// #![feature(pointer_methods)] + /// + /// # #[allow(dead_code)] + /// unsafe fn from_buf_raw(ptr: *const T, elts: usize) -> Vec { + /// let mut dst = Vec::with_capacity(elts); + /// dst.set_len(elts); + /// ptr.copy_to_nonoverlapping(dst.as_mut_ptr(), elts); + /// dst + /// } + /// ``` + #[unstable(feature = "pointer_methods", issue = "43941")] + #[inline] + pub unsafe fn copy_to_nonoverlapping(self, dest: *mut T, count: usize) + where T: Sized, + { + copy_nonoverlapping(self, dest, count) + } + + /// Copies `count * size_of` bytes from `src` to `self`. The source + /// and destination may overlap. + /// + /// NOTE: this has the *opposite* argument order of `ptr::copy`. + /// + /// This is semantically equivalent to C's `memmove`. + /// + /// # Safety + /// + /// Care must be taken with the ownership of `src` and `self`. + /// This method semantically moves the values of `src` into `self`. + /// However it does not drop the contents of `self`, or prevent the contents + /// of `src` from being dropped or used. + /// + /// # Examples + /// + /// Efficiently create a Rust vector from an unsafe buffer: + /// + /// ``` + /// #![feature(pointer_methods)] + /// + /// # #[allow(dead_code)] + /// unsafe fn from_buf_raw(ptr: *const T, elts: usize) -> Vec { + /// let mut dst = Vec::with_capacity(elts); + /// dst.set_len(elts); + /// dst.as_mut_ptr().copy_from(ptr, elts); + /// dst + /// } + /// ``` + #[unstable(feature = "pointer_methods", issue = "43941")] + #[inline] + pub unsafe fn copy_from(self, src: *const T, count: usize) + where T: Sized, + { + copy(src, self, count) + } + + /// Copies `count * size_of` bytes from `src` to `self`. The source + /// and destination may *not* overlap. + /// + /// NOTE: this has the *opposite* argument order of `ptr::copy_nonoverlapping`. + /// + /// `copy_nonoverlapping` is semantically equivalent to C's `memcpy`. + /// + /// # Safety + /// + /// Beyond requiring that the program must be allowed to access both regions + /// of memory, it is Undefined Behavior for source and destination to + /// overlap. Care must also be taken with the ownership of `src` and + /// `self`. This method semantically moves the values of `src` into `self`. + /// However it does not drop the contents of `self`, or prevent the contents + /// of `src` from being dropped or used. + /// + /// # Examples + /// + /// Efficiently create a Rust vector from an unsafe buffer: + /// + /// ``` + /// #![feature(pointer_methods)] + /// + /// # #[allow(dead_code)] + /// unsafe fn from_buf_raw(ptr: *const T, elts: usize) -> Vec { + /// let mut dst = Vec::with_capacity(elts); + /// dst.set_len(elts); + /// dst.as_mut_ptr().copy_from_nonoverlapping(ptr, elts); + /// dst + /// } + /// ``` + #[unstable(feature = "pointer_methods", issue = "43941")] + #[inline] + pub unsafe fn copy_from_nonoverlapping(self, src: *const T, count: usize) + where T: Sized, + { + copy_nonoverlapping(src, self, count) + } + + /// Executes the destructor (if any) of the pointed-to value. + /// + /// This has two use cases: + /// + /// * It is *required* to use `drop_in_place` to drop unsized types like + /// trait objects, because they can't be read out onto the stack and + /// dropped normally. + /// + /// * It is friendlier to the optimizer to do this over `ptr::read` when + /// dropping manually allocated memory (e.g. when writing Box/Rc/Vec), + /// as the compiler doesn't need to prove that it's sound to elide the + /// copy. + /// + /// # Safety + /// + /// This has all the same safety problems as `ptr::read` with respect to + /// invalid pointers, types, and double drops. + #[unstable(feature = "pointer_methods", issue = "43941")] + #[inline] + pub unsafe fn drop_in_place(self) { + drop_in_place(self) + } + + /// Overwrites a memory location with the given value without reading or + /// dropping the old value. + /// + /// # Safety + /// + /// This operation is marked unsafe because it writes through a raw pointer. + /// + /// It does not drop the contents of `self`. This is safe, but it could leak + /// allocations or resources, so care must be taken not to overwrite an object + /// that should be dropped. + /// + /// Additionally, it does not drop `val`. Semantically, `val` is moved into the + /// location pointed to by `self`. + /// + /// This is appropriate for initializing uninitialized memory, or overwriting + /// memory that has previously been `read` from. + /// + /// The pointer must be aligned; use `write_unaligned` if that is not the case. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(pointer_methods)] + /// + /// let mut x = 0; + /// let y = &mut x as *mut i32; + /// let z = 12; + /// + /// unsafe { + /// y.write(z); + /// assert_eq!(y.read(), 12); + /// } + /// ``` + #[unstable(feature = "pointer_methods", issue = "43941")] + #[inline] + pub unsafe fn write(self, val: T) + where T: Sized, + { + write(self, val) + } + + /// Invokes memset on the specified pointer, setting `count * size_of::()` + /// bytes of memory starting at `self` to `val`. + /// + /// # Examples + /// + /// ``` + /// #![feature(pointer_methods)] + /// + /// let mut vec = vec![0; 4]; + /// unsafe { + /// let vec_ptr = vec.as_mut_ptr(); + /// vec_ptr.write_bytes(b'a', 2); + /// } + /// assert_eq!(vec, [b'a', b'a', 0, 0]); + /// ``` + #[unstable(feature = "pointer_methods", issue = "43941")] + #[inline] + pub unsafe fn write_bytes(self, val: u8, count: usize) + where T: Sized, + { + write_bytes(self, val, count) + } + + /// Performs a volatile write of a memory location with the given value without + /// reading or dropping the old value. + /// + /// Volatile operations are intended to act on I/O memory, and are guaranteed + /// to not be elided or reordered by the compiler across other volatile + /// operations. + /// + /// # Notes + /// + /// Rust does not currently have a rigorously and formally defined memory model, + /// so the precise semantics of what "volatile" means here is subject to change + /// over time. That being said, the semantics will almost always end up pretty + /// similar to [C11's definition of volatile][c11]. + /// + /// The compiler shouldn't change the relative order or number of volatile + /// memory operations. However, volatile memory operations on zero-sized types + /// (e.g. if a zero-sized type is passed to `write_volatile`) are no-ops + /// and may be ignored. + /// + /// [c11]: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf + /// + /// # Safety + /// + /// This operation is marked unsafe because it accepts a raw pointer. + /// + /// It does not drop the contents of `self`. This is safe, but it could leak + /// allocations or resources, so care must be taken not to overwrite an object + /// that should be dropped. + /// + /// This is appropriate for initializing uninitialized memory, or overwriting + /// memory that has previously been `read` from. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(pointer_methods)] + /// + /// let mut x = 0; + /// let y = &mut x as *mut i32; + /// let z = 12; + /// + /// unsafe { + /// y.write_volatile(z); + /// assert_eq!(y.read_volatile(), 12); + /// } + /// ``` + #[unstable(feature = "pointer_methods", issue = "43941")] + #[inline] + pub unsafe fn write_volatile(self, val: T) + where T: Sized, + { + write_volatile(self, val) + } + + /// Overwrites a memory location with the given value without reading or + /// dropping the old value. + /// + /// Unlike `write`, the pointer may be unaligned. + /// + /// # Safety + /// + /// This operation is marked unsafe because it writes through a raw pointer. + /// + /// It does not drop the contents of `self`. This is safe, but it could leak + /// allocations or resources, so care must be taken not to overwrite an object + /// that should be dropped. + /// + /// Additionally, it does not drop `src`. Semantically, `src` is moved into the + /// location pointed to by `dst`. + /// + /// This is appropriate for initializing uninitialized memory, or overwriting + /// memory that has previously been `read` from. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(pointer_methods)] + /// + /// let mut x = 0; + /// let y = &mut x as *mut i32; + /// let z = 12; + /// + /// unsafe { + /// y.write_unaligned(z); + /// assert_eq!(y.read_unaligned(), 12); + /// } + /// ``` + #[unstable(feature = "pointer_methods", issue = "43941")] + #[inline] + pub unsafe fn write_unaligned(self, val: T) + where T: Sized, + { + write_unaligned(self, val) + } + + /// Replaces the value at `self` with `src`, returning the old + /// value, without dropping either. + /// + /// # Safety + /// + /// This is only unsafe because it accepts a raw pointer. + /// Otherwise, this operation is identical to `mem::replace`. + #[unstable(feature = "pointer_methods", issue = "43941")] + #[inline] + pub unsafe fn replace(self, src: T) -> T + where T: Sized, + { + replace(self, src) + } + + /// Swaps the values at two mutable locations of the same type, without + /// deinitializing either. They may overlap, unlike `mem::swap` which is + /// otherwise equivalent. + /// + /// # Safety + /// + /// This function copies the memory through the raw pointers passed to it + /// as arguments. + /// + /// Ensure that these pointers are valid before calling `swap`. + #[unstable(feature = "pointer_methods", issue = "43941")] + #[inline] + pub unsafe fn swap(self, with: *mut T) + where T: Sized, + { + swap(self, with) + } } // Equality for pointers From a095ee48d5d2287efa663ec196a017c69952b0b3 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 7 Sep 2017 00:08:39 +0200 Subject: [PATCH 07/40] Add class for codeblocks --- src/librustdoc/html/highlight.rs | 17 ++++++- src/librustdoc/html/markdown.rs | 59 +++++++++++++++++++--- src/librustdoc/html/render.rs | 4 +- src/librustdoc/html/static/styles/main.css | 8 +++ 4 files changed, 79 insertions(+), 9 deletions(-) diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index e6b236deac4ee..cc1da35a99757 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -22,6 +22,7 @@ use html::escape::Escape; +use std::collections::HashMap; use std::fmt::Display; use std::io; use std::io::prelude::*; @@ -34,12 +35,18 @@ use syntax_pos::Span; /// Highlights `src`, returning the HTML output. pub fn render_with_highlighting(src: &str, class: Option<&str>, id: Option<&str>, - extension: Option<&str>) -> String { + extension: Option<&str>, + extras: Option>) -> String { debug!("highlighting: ================\n{}\n==============", src); let sess = parse::ParseSess::new(FilePathMapping::empty()); let fm = sess.codemap().new_filemap("".to_string(), src.to_string()); let mut out = Vec::new(); + if let Some((tooltip, class)) = tooltip { + write!(out, "
{}
", + class, tooltip).unwrap(); + } write_header(class, id, &mut out).unwrap(); let mut classifier = Classifier::new(lexer::StringReader::new(&sess, fm), sess.codemap()); @@ -389,12 +396,18 @@ impl Class { fn write_header(class: Option<&str>, id: Option<&str>, - out: &mut Write) + out: &mut Write, + extras: Option>) -> io::Result<()> { write!(out, "
\n", class.unwrap_or(""))
 }
 
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 2d14c02bf8a59..d9fb35c4c269b 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -158,10 +158,15 @@ impl<'a, I: Iterator>> Iterator for CodeBlocks<'a, I> {
 
     fn next(&mut self) -> Option {
         let event = self.inner.next();
+        let compile_fail;
+        let ignore;
         if let Some(Event::Start(Tag::CodeBlock(lang))) = event {
-            if !LangString::parse(&lang).rust {
+            let parse_result = LangString::parse(&lang);
+            if !parse_result.rust {
                 return Some(Event::Start(Tag::CodeBlock(lang)));
             }
+            compile_fail = parse_result.compile_fail;
+            ignore = parse_result.ignore;
         } else {
             return event;
         }
@@ -220,11 +225,28 @@ impl<'a, I: Iterator>> Iterator for CodeBlocks<'a, I> {
                     url, test_escaped, channel
                 ))
             });
+            let title = if ignore {
+                let mut tmp = HashMap::new();
+                tmp.insert("title".to_owned(),
+                           "Be careful when using this code, it's not being tested!".to_owned());
+                Some(tmp)
+            } else if compile_fail {
+                let mut tmp = HashMap::new();
+                tmp.insert("title".to_owned(),
+                           "This code doesn't compile so be extra careful!".to_owned());
+                Some(tmp)
+            } else {
+                None
+            };
             s.push_str(&highlight::render_with_highlighting(
                         &text,
-                        Some("rust-example-rendered"),
+                        Some(&format!("rust-example-rendered{}",
+                                      if ignore { " ignore" }
+                                      else if compile_fail { " compile_fail" }
+                                      else { "" })),
                         None,
-                        playground_button.as_ref().map(String::as_str)));
+                        playground_button.as_ref().map(String::as_str),
+                        title));
             Some(Event::Html(s.into()))
         })
     }
@@ -554,12 +576,18 @@ pub fn render(w: &mut fmt::Formatter,
             let origtext = str::from_utf8(text).unwrap();
             let origtext = origtext.trim_left();
             debug!("docblock: ==============\n{:?}\n=======", text);
+            let mut compile_fail = false;
+            let mut ignore = false;
+
             let rendered = if lang.is_null() || origtext.is_empty() {
                 false
             } else {
                 let rlang = (*lang).as_bytes();
                 let rlang = str::from_utf8(rlang).unwrap();
-                if !LangString::parse(rlang).rust {
+                let parse_result = LangString::parse(rlang);
+                compile_fail = parse_result.compile_fail;
+                ignore = parse_result.ignore;
+                if !parse_result.rust {
                     (my_opaque.dfltblk)(ob, orig_text, lang,
                                         opaque as *const hoedown_renderer_data,
                                         line);
@@ -614,11 +642,30 @@ pub fn render(w: &mut fmt::Formatter,
                         url, test_escaped, channel
                     ))
                 });
+                let title = if ignore {
+                    let mut tmp = HashMap::new();
+                    tmp.insert("title".to_owned(),
+                               "Be careful when using this code, it's not being \
+                                tested!".to_owned());
+                    Some(tmp)
+                } else if compile_fail {
+                    let mut tmp = HashMap::new();
+                    tmp.insert("title".to_owned(),
+                               "This code doesn't compile so be extra \
+                                careful!".to_owned());
+                    Some(tmp)
+                } else {
+                    None
+                };
                 s.push_str(&highlight::render_with_highlighting(
                                &text,
-                               Some("rust-example-rendered"),
+                               Some(&format!("rust-example-rendered{}",
+                                             if ignore { " ignore" }
+                                             else if compile_fail { " compile_fail" }
+                                             else { "" })),
                                None,
-                               playground_button.as_ref().map(String::as_str)));
+                               playground_button.as_ref().map(String::as_str),
+                               title));
                 hoedown_buffer_put(ob, s.as_ptr(), s.len());
             })
         }
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 46bb119cf9c9d..f911ddb4d4f55 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -1839,6 +1839,7 @@ fn render_assoc_const_value(item: &clean::Item) -> String {
                 None,
                 None,
                 None,
+                None,
             )
         }
         _ => String::new(),
@@ -3678,7 +3679,7 @@ impl<'a> fmt::Display for Source<'a> {
             write!(fmt, "{0:1$}\n", i, cols)?;
         }
         write!(fmt, "
")?; - write!(fmt, "{}", highlight::render_with_highlighting(s, None, None, None))?; + write!(fmt, "{}", highlight::render_with_highlighting(s, None, None, None, None))?; Ok(()) } } @@ -3688,6 +3689,7 @@ fn item_macro(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, w.write_str(&highlight::render_with_highlighting(&t.source, Some("macro"), None, + None, None))?; document(w, cx, it) } diff --git a/src/librustdoc/html/static/styles/main.css b/src/librustdoc/html/static/styles/main.css index c5f4272b932fc..18b40b3d60c17 100644 --- a/src/librustdoc/html/static/styles/main.css +++ b/src/librustdoc/html/static/styles/main.css @@ -202,4 +202,12 @@ a.test-arrow:hover{ :target > code { background: #FDFFD3; +} + +pre.compile_fail { + box-shadow: -6px 0 5px -3px #f00; +} + +pre.ignore { + box-shadow: -6px 0 5px -3px #ff9200; } \ No newline at end of file From 9c12e5d4e8c1211783e2c9e6f6cc1fd0091b8724 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 7 Sep 2017 22:06:40 +0200 Subject: [PATCH 08/40] add test --- src/test/rustdoc/codeblock-title.rs | 31 +++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 src/test/rustdoc/codeblock-title.rs diff --git a/src/test/rustdoc/codeblock-title.rs b/src/test/rustdoc/codeblock-title.rs new file mode 100644 index 0000000000000..accefd6b65f28 --- /dev/null +++ b/src/test/rustdoc/codeblock-title.rs @@ -0,0 +1,31 @@ +// 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. + +#![crate_name = "foo"] + +// ignore-tidy-linelength + +// @has foo/fn.bar.html '//*[@class="tooltip compile_fail"]/span' "This code doesn't compile so be extra careful!" +// @has foo/fn.bar.html '//*[@class="tooltip ignore"]/span' "Be careful when using this code, it's not being tested!" + +/// foo +/// +/// ```compile_fail +/// foo(); +/// ``` +/// +/// ```ignore (tidy) +/// goo(); +/// ``` +/// +/// ``` +/// let x = 0; +/// ``` +pub fn bar() -> usize { 2 } From 79f888da6810e9e38918f524b0882b8eaf40e5a1 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 9 Sep 2017 15:33:57 +0200 Subject: [PATCH 09/40] Add arrow and improve display --- src/librustdoc/html/highlight.rs | 11 ++---- src/librustdoc/html/markdown.rs | 30 +++++----------- src/librustdoc/html/render.rs | 3 +- src/librustdoc/html/static/main.js | 18 ++++++++++ src/librustdoc/html/static/rustdoc.css | 42 +++++++++++++++++++++- src/librustdoc/html/static/styles/main.css | 30 ++++++++++++++-- 6 files changed, 98 insertions(+), 36 deletions(-) diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index cc1da35a99757..081f950e40db2 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -22,7 +22,6 @@ use html::escape::Escape; -use std::collections::HashMap; use std::fmt::Display; use std::io; use std::io::prelude::*; @@ -36,7 +35,7 @@ use syntax_pos::Span; /// Highlights `src`, returning the HTML output. pub fn render_with_highlighting(src: &str, class: Option<&str>, id: Option<&str>, extension: Option<&str>, - extras: Option>) -> String { + tooltip: Option<(&str, &str)>) -> String { debug!("highlighting: ================\n{}\n==============", src); let sess = parse::ParseSess::new(FilePathMapping::empty()); let fm = sess.codemap().new_filemap("".to_string(), src.to_string()); @@ -396,18 +395,12 @@ impl Class { fn write_header(class: Option<&str>, id: Option<&str>, - out: &mut Write, - extras: Option>) + out: &mut Write) -> io::Result<()> { write!(out, "
\n", class.unwrap_or(""))
 }
 
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index d9fb35c4c269b..3b03acf99081c 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -225,16 +225,10 @@ impl<'a, I: Iterator>> Iterator for CodeBlocks<'a, I> {
                     url, test_escaped, channel
                 ))
             });
-            let title = if ignore {
-                let mut tmp = HashMap::new();
-                tmp.insert("title".to_owned(),
-                           "Be careful when using this code, it's not being tested!".to_owned());
-                Some(tmp)
+            let tooltip = if ignore {
+                Some(("Be careful when using this code, it's not being tested!", "ignore"))
             } else if compile_fail {
-                let mut tmp = HashMap::new();
-                tmp.insert("title".to_owned(),
-                           "This code doesn't compile so be extra careful!".to_owned());
-                Some(tmp)
+                Some(("This code doesn't compile so be extra careful!", "compile_fail"))
             } else {
                 None
             };
@@ -246,7 +240,7 @@ impl<'a, I: Iterator>> Iterator for CodeBlocks<'a, I> {
                                       else { "" })),
                         None,
                         playground_button.as_ref().map(String::as_str),
-                        title));
+                        tooltip));
             Some(Event::Html(s.into()))
         })
     }
@@ -642,18 +636,10 @@ pub fn render(w: &mut fmt::Formatter,
                         url, test_escaped, channel
                     ))
                 });
-                let title = if ignore {
-                    let mut tmp = HashMap::new();
-                    tmp.insert("title".to_owned(),
-                               "Be careful when using this code, it's not being \
-                                tested!".to_owned());
-                    Some(tmp)
+                let tooltip = if ignore {
+                    Some(("Be careful when using this code, it's not being tested!", "ignore"))
                 } else if compile_fail {
-                    let mut tmp = HashMap::new();
-                    tmp.insert("title".to_owned(),
-                               "This code doesn't compile so be extra \
-                                careful!".to_owned());
-                    Some(tmp)
+                    Some(("This code doesn't compile so be extra careful!", "compile_fail"))
                 } else {
                     None
                 };
@@ -665,7 +651,7 @@ pub fn render(w: &mut fmt::Formatter,
                                              else { "" })),
                                None,
                                playground_button.as_ref().map(String::as_str),
-                               title));
+                               tooltip));
                 hoedown_buffer_put(ob, s.as_ptr(), s.len());
             })
         }
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index f911ddb4d4f55..993462a8d444a 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -3679,7 +3679,8 @@ impl<'a> fmt::Display for Source<'a> {
             write!(fmt, "{0:1$}\n", i, cols)?;
         }
         write!(fmt, "
")?; - write!(fmt, "{}", highlight::render_with_highlighting(s, None, None, None, None))?; + write!(fmt, "{}", + highlight::render_with_highlighting(s, None, None, None, None))?; Ok(()) } } diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 8ec9cd8660a80..da4430d8a1539 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -1296,6 +1296,24 @@ collapseDocs(i_e.previousSibling.childNodes[0]); }); }); + + onEach(document.getElementsByClassName('rust-example-rendered'), function(e) { + if (hasClass(e, 'compile_fail')) { + e.addEventListener("mouseover", function(event) { + e.previousElementSibling.childNodes[0].style.color = '#f00'; + }); + e.addEventListener("mouseout", function(event) { + e.previousElementSibling.childNodes[0].style.color = ''; + }); + } else if (hasClass(e, 'ignore')) { + e.addEventListener("mouseover", function(event) { + e.previousElementSibling.childNodes[0].style.color = '#ff9200'; + }); + e.addEventListener("mouseout", function(event) { + e.previousElementSibling.childNodes[0].style.color = ''; + }); + } + }); }()); // Sets the focus on the search bar at the top of the page diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index ca55d0e5d2a8e..c15051376bf27 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -612,7 +612,6 @@ pre.rust .question-mark { font-weight: bold; } -pre.rust { position: relative; } a.test-arrow { display: inline-block; position: absolute; @@ -813,3 +812,44 @@ span.since { display: none; } } + +.information { + position: absolute; + left: -1px; + margin-top: 7px; +} + +.tooltip { + position: relative; + display: inline-block; + cursor: pointer; +} + +.tooltip .tooltiptext { + width: 120px; + display: none; + background-color: black; + color: #fff; + text-align: center; + padding: 5px 3px; + border-radius: 6px; + margin-left: 5px; + top: -5px; + left: 105%; + z-index: 1; +} + +.tooltip:hover .tooltiptext { + display: inline; +} + +.tooltip .tooltiptext::after { + content: " "; + position: absolute; + top: 50%; + left: 11px; + margin-top: -5px; + border-width: 5px; + border-style: solid; + border-color: transparent black transparent transparent; +} diff --git a/src/librustdoc/html/static/styles/main.css b/src/librustdoc/html/static/styles/main.css index 18b40b3d60c17..42d0ec704f45f 100644 --- a/src/librustdoc/html/static/styles/main.css +++ b/src/librustdoc/html/static/styles/main.css @@ -205,9 +205,33 @@ a.test-arrow:hover{ } pre.compile_fail { - box-shadow: -6px 0 5px -3px #f00; + border-left: 2px solid rgba(255,0,0,.4); +} + +pre.compile_fail:hover, .information:hover + pre.compile_fail { + border-left: 2px solid #f00; } pre.ignore { - box-shadow: -6px 0 5px -3px #ff9200; -} \ No newline at end of file + border-left: 2px solid rgba(255,142,0,.4); +} + +pre.ignore:hover, .information:hover + pre.ignore { + border-left: 2px solid #ff9200; +} + +.tooltip.compile_fail { + color: rgba(255,0,0,.3); +} + +.information > .compile_fail:hover { + color: #f00; +} + +.tooltip.ignore { + color: rgba(255,142,0,.3); +} + +.information > .ignore:hover { + color: rgba(255,142,0,1); +} From 81ebab6fca423973aebda9fa311c7e9b8e1c2e13 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Tue, 12 Sep 2017 18:09:26 -0500 Subject: [PATCH 10/40] bump gcc for bootstrap On Windows, the gcc crate would send /Wall to msvc, which would cause builds to get flooded with warnings, exploding compile times from one hour to more than 72! The gcc crate version 0.3.54 changes this behavior to send /W4 instead, which greatly cuts down on cl.exe flooding the command prompt window with warnings. --- src/Cargo.lock | 36 ++++++++++++++++++------------------ src/bootstrap/Cargo.toml | 2 +- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index 47ef0a7d8ca13..18a01cca8bdfd 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -47,7 +47,7 @@ dependencies = [ "alloc_system 0.0.0", "build_helper 0.1.0", "core 0.0.0", - "gcc 0.3.53 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.0.0", ] @@ -103,7 +103,7 @@ name = "backtrace-sys" version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.3.53 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.30 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -137,7 +137,7 @@ dependencies = [ "build_helper 0.1.0", "cmake 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", "filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "gcc 0.3.53 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.30 (registry+https://github.com/rust-lang/crates.io-index)", @@ -270,7 +270,7 @@ name = "cmake" version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.3.53 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -286,7 +286,7 @@ name = "compiler_builtins" version = "0.0.0" dependencies = [ "core 0.0.0", - "gcc 0.3.53 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -402,7 +402,7 @@ name = "curl-sys" version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.3.53 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.30 (registry+https://github.com/rust-lang/crates.io-index)", "libz-sys 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-sys 0.9.17 (registry+https://github.com/rust-lang/crates.io-index)", @@ -574,7 +574,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "gcc" -version = "0.3.53" +version = "0.3.54" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -834,7 +834,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cmake 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", "curl-sys 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", - "gcc 0.3.53 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.30 (registry+https://github.com/rust-lang/crates.io-index)", "libssh2-sys 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "libz-sys 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", @@ -859,7 +859,7 @@ name = "libz-sys" version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.3.53 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.30 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -880,7 +880,7 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "gcc 0.3.53 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.30 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -962,7 +962,7 @@ name = "miniz-sys" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.3.53 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.30 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1098,7 +1098,7 @@ name = "openssl-sys" version = "0.9.17" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.3.53 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.30 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1203,7 +1203,7 @@ name = "profiler_builtins" version = "0.0.0" dependencies = [ "core 0.0.0", - "gcc 0.3.53 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1599,7 +1599,7 @@ name = "rustc_llvm" version = "0.0.0" dependencies = [ "build_helper 0.1.0", - "gcc 0.3.53 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_bitflags 0.0.0", ] @@ -1729,7 +1729,7 @@ name = "rustc_trans" version = "0.0.0" dependencies = [ "flate2 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)", - "gcc 0.3.53 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", "jobserver 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.6.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1794,7 +1794,7 @@ version = "0.0.0" dependencies = [ "build_helper 0.1.0", "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "gcc 0.3.53 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", "html-diff 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "pulldown-cmark 0.0.14 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1967,7 +1967,7 @@ dependencies = [ "collections 0.0.0", "compiler_builtins 0.0.0", "core 0.0.0", - "gcc 0.3.53 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.0.0", "panic_abort 0.0.0", "panic_unwind 0.0.0", @@ -2471,7 +2471,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum fs2 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9ab76cfd2aaa59b7bf6688ad9ba15bbae64bff97f04ea02144cfd3443e5c2866" "checksum futf 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "51f93f3de6ba1794dcd5810b3546d004600a59a98266487c8407bc4b24e398f3" "checksum futures 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "a82bdc62350ca9d7974c760e9665102fc9d740992a528c2254aa930e53b783c4" -"checksum gcc 0.3.53 (registry+https://github.com/rust-lang/crates.io-index)" = "e8310f7e9c890398b0e80e301c4f474e9918d2b27fca8f48486ca775fa9ffc5a" +"checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb" "checksum getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9047cfbd08a437050b363d35ef160452c5fe8ea5187ae0a624708c91581d685" "checksum git2 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "0c1c0203d653f4140241da0c1375a404f0a397249ec818cd2076c6280c50f6fa" "checksum git2-curl 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "68676bc784bf0bef83278898929bf64a251e87c0340723d0b93fa096c9c5bf8e" diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index daa2a3d0a0ff4..85e3b65c1953c 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -34,7 +34,7 @@ cmake = "0.1.23" filetime = "0.1" num_cpus = "1.0" getopts = "0.2" -gcc = "0.3.50" +gcc = "0.3.54" libc = "0.2" serde = "1.0.8" serde_derive = "1.0.8" From 5cad39163132de69512c770ed06e5432641f2c2d Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 13 Sep 2017 07:41:58 -0700 Subject: [PATCH 11/40] rustc: Spawn `cmd /c emcc.bat` explicitly In #42436 the behavior for spawning processes on Windows was tweaked slightly to fix various bugs, but this caused #42791 as a regression, namely that to spawn batch scripts they need to be manually spawned with `cmd /c` instead now. This updates the compiler to handle this case explicitly for Emscripten. Closes #42791 --- src/librustc_trans/back/link.rs | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index efb56ab5a6cac..08266e86f9793 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -107,14 +107,32 @@ pub fn build_link_meta(incremental_hashes_map: &IncrementalHashesMap) -> LinkMet pub fn get_linker(sess: &Session) -> (String, Command, Vec<(OsString, OsString)>) { let envs = vec![("PATH".into(), command_path(sess))]; + // If our linker looks like a batch script on Windows then to execute this + // we'll need to spawn `cmd` explicitly. This is primarily done to handle + // emscripten where the linker is `emcc.bat` and needs to be spawned as + // `cmd /c emcc.bat ...`. + // + // This worked historically but is needed manually since #42436 (regression + // was tagged as #42791) and some more info can be found on #44443 for + // emscripten itself. + let cmd = |linker: &str| { + if cfg!(windows) && linker.ends_with(".bat") { + let mut cmd = Command::new("cmd"); + cmd.arg("/c").arg(linker); + cmd + } else { + Command::new(linker) + } + }; + if let Some(ref linker) = sess.opts.cg.linker { - (linker.clone(), Command::new(linker), envs) + (linker.clone(), cmd(linker), envs) } else if sess.target.target.options.is_like_msvc { let (cmd, envs) = msvc_link_exe_cmd(sess); ("link.exe".to_string(), cmd, envs) } else { let linker = &sess.target.target.options.linker; - (linker.clone(), Command::new(&linker), envs) + (linker.clone(), cmd(linker), envs) } } From d3bbce79d0c0b3b4525f65e3bc75a8fa2863634a Mon Sep 17 00:00:00 2001 From: Douglas Campos Date: Thu, 7 Sep 2017 22:22:08 -0400 Subject: [PATCH 12/40] bring TyCtxt into scope --- src/librustc/ty/instance.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index 7d543f689c24d..d9c6843fad73a 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -9,7 +9,7 @@ // except according to those terms. use hir::def_id::DefId; -use ty::{self, Ty, TypeFoldable, Substs}; +use ty::{self, Ty, TypeFoldable, Substs, TyCtxt}; use util::ppaux; use std::fmt; @@ -57,12 +57,12 @@ impl<'tcx> InstanceDef<'tcx> { } #[inline] - pub fn def_ty<'a>(&self, tcx: ty::TyCtxt<'a, 'tcx, 'tcx>) -> Ty<'tcx> { + pub fn def_ty<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Ty<'tcx> { tcx.type_of(self.def_id()) } #[inline] - pub fn attrs<'a>(&self, tcx: ty::TyCtxt<'a, 'tcx, 'tcx>) -> ty::Attributes<'tcx> { + pub fn attrs<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> ty::Attributes<'tcx> { tcx.get_attrs(self.def_id()) } } @@ -103,7 +103,7 @@ impl<'a, 'b, 'tcx> Instance<'tcx> { Instance { def: InstanceDef::Item(def_id), substs: substs } } - pub fn mono(tcx: ty::TyCtxt<'a, 'tcx, 'b>, def_id: DefId) -> Instance<'tcx> { + pub fn mono(tcx: TyCtxt<'a, 'tcx, 'b>, def_id: DefId) -> Instance<'tcx> { Instance::new(def_id, tcx.global_tcx().empty_substs_for_def_id(def_id)) } From d3c2386434fa7a7881bbb123cb96c2da158edc4c Mon Sep 17 00:00:00 2001 From: gaurikholkar Date: Thu, 14 Sep 2017 01:04:47 +0530 Subject: [PATCH 13/40] extend E0623 for earlybound and latebound for structs --- .../error_reporting/different_lifetimes.rs | 44 ++++++++++++++----- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/src/librustc/infer/error_reporting/different_lifetimes.rs b/src/librustc/infer/error_reporting/different_lifetimes.rs index 051263dfb53ef..bf1428cabd63c 100644 --- a/src/librustc/infer/error_reporting/different_lifetimes.rs +++ b/src/librustc/infer/error_reporting/different_lifetimes.rs @@ -321,24 +321,46 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for TyPathVisitor<'a, 'gcx, 'tcx> { } fn visit_lifetime(&mut self, lifetime: &hir::Lifetime) { - let br_index = match self.bound_region { - ty::BrAnon(index) => index, - _ => return, - }; let hir_id = self.infcx.tcx.hir.node_to_hir_id(lifetime.id); - match self.infcx.tcx.named_region(hir_id) { + match (self.infcx.tcx.named_region(hir_id), self.bound_region) { // the lifetime of the TyPath! - Some(rl::Region::LateBoundAnon(debruijn_index, anon_index)) => { + (Some(rl::Region::LateBoundAnon(debruijn_index, anon_index)), ty::BrAnon(br_index)) => { if debruijn_index.depth == 1 && anon_index == br_index { self.found_it = true; + return; + } + } + + (Some(rl::Region::EarlyBound(_, id)), ty::BrNamed(def_id, _)) => { + debug!("EarlyBound self.infcx.tcx.hir.local_def_id(id)={:?} \ + def_id={:?}", + self.infcx.tcx.hir.local_def_id(id), + def_id); + if self.infcx.tcx.hir.local_def_id(id) == def_id { + self.found_it = true; + return; // we can stop visiting now } } - Some(rl::Region::Static) | - Some(rl::Region::EarlyBound(_, _)) | - Some(rl::Region::LateBound(_, _)) | - Some(rl::Region::Free(_, _)) | - None => { + + (Some(rl::Region::LateBound(debruijn_index, id)), ty::BrNamed(def_id, _)) => { + debug!("FindNestedTypeVisitor::visit_ty: LateBound depth = {:?}", + debruijn_index.depth); + debug!("self.infcx.tcx.hir.local_def_id(id)={:?}", + self.infcx.tcx.hir.local_def_id(id)); + debug!("def_id={:?}", def_id); + if debruijn_index.depth == 1 && self.infcx.tcx.hir.local_def_id(id) == def_id { + self.found_it = true; + return; // we can stop visiting now + } + } + + (Some(rl::Region::Static), _) | + (Some(rl::Region::EarlyBound(_, _)), _) | + (Some(rl::Region::LateBound(_, _)), _) | + (Some(rl::Region::LateBoundAnon(_, _)), _) | + (Some(rl::Region::Free(_, _)), _) | + (None, _) => { debug!("no arg found"); } } From f8df89a5cbf868677c342e3fa06dc6ca9a784e59 Mon Sep 17 00:00:00 2001 From: gaurikholkar Date: Thu, 14 Sep 2017 01:28:43 +0530 Subject: [PATCH 14/40] adding ui tests --- ...gions-both-are-structs-latebound-regions.rs | 18 ++++++++++++++++++ ...s-both-are-structs-latebound-regions.stderr | 10 ++++++++++ 2 files changed, 28 insertions(+) create mode 100644 src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.rs create mode 100644 src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.stderr diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.rs b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.rs new file mode 100644 index 0000000000000..a91d0b55dc7ab --- /dev/null +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.rs @@ -0,0 +1,18 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. +struct Ref<'a> { + x: &'a u32, +} + +fn foo<'a, 'b>(mut x: Vec>, y: Ref<'b>) { + x.push(y); +} + +fn main() {} diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.stderr new file mode 100644 index 0000000000000..878351210681b --- /dev/null +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.stderr @@ -0,0 +1,10 @@ +error[E0623]: lifetime mismatch + --> $DIR/ex3-both-anon-regions-both-are-structs-latebound-regions.rs:15:12 + | +14 | fn foo<'a, 'b>(mut x: Vec>, y: Ref<'b>) { + | ------- ------- these two types are declared with different lifetimes... +15 | x.push(y); + | ^ ...but data from `y` flows into `x` here + +error: aborting due to previous error + From 696a26882278ac631e11dee457dfe8e6dfbd0891 Mon Sep 17 00:00:00 2001 From: gaurikholkar Date: Thu, 14 Sep 2017 10:01:12 +0530 Subject: [PATCH 15/40] fix depth for structs --- src/librustc/infer/error_reporting/different_lifetimes.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/librustc/infer/error_reporting/different_lifetimes.rs b/src/librustc/infer/error_reporting/different_lifetimes.rs index bf1428cabd63c..536715ffadb15 100644 --- a/src/librustc/infer/error_reporting/different_lifetimes.rs +++ b/src/librustc/infer/error_reporting/different_lifetimes.rs @@ -287,6 +287,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindNestedTypeVisitor<'a, 'gcx, 'tcx> { found_it: false, bound_region: self.bound_region, hir_map: self.hir_map, + depth: self.depth, }; intravisit::walk_ty(subvisitor, arg); // call walk_ty; as visit_ty is empty, // this will visit only outermost type @@ -313,6 +314,7 @@ struct TyPathVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { hir_map: &'a hir::map::Map<'gcx>, found_it: bool, bound_region: ty::BoundRegion, + depth: u32, } impl<'a, 'gcx, 'tcx> Visitor<'gcx> for TyPathVisitor<'a, 'gcx, 'tcx> { @@ -326,7 +328,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for TyPathVisitor<'a, 'gcx, 'tcx> { match (self.infcx.tcx.named_region(hir_id), self.bound_region) { // the lifetime of the TyPath! (Some(rl::Region::LateBoundAnon(debruijn_index, anon_index)), ty::BrAnon(br_index)) => { - if debruijn_index.depth == 1 && anon_index == br_index { + if debruijn_index.depth == self.depth && anon_index == br_index { self.found_it = true; return; } @@ -349,7 +351,8 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for TyPathVisitor<'a, 'gcx, 'tcx> { debug!("self.infcx.tcx.hir.local_def_id(id)={:?}", self.infcx.tcx.hir.local_def_id(id)); debug!("def_id={:?}", def_id); - if debruijn_index.depth == 1 && self.infcx.tcx.hir.local_def_id(id) == def_id { + if debruijn_index.depth == self.depth && + self.infcx.tcx.hir.local_def_id(id) == def_id { self.found_it = true; return; // we can stop visiting now } From 39c9a3d7961df049d77660131033c003e24364a3 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Wed, 6 Sep 2017 08:28:15 +1200 Subject: [PATCH 16/40] Attempt to fix the component manifest problem for rls-preview cc #44270 --- src/bootstrap/dist.rs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 9180c7d165a37..7bca088dbd5a8 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -1098,8 +1098,14 @@ impl Step for Rls { .arg("--output-dir").arg(&distdir(build)) .arg("--non-installed-overlay").arg(&overlay) .arg(format!("--package-name={}-{}", name, target)) - .arg("--component-name=rls") .arg("--legacy-manifest-dirs=rustlib,cargo"); + + if build.config.channel == "nightly" { + cmd.arg("--component-name=rls"); + } else { + cmd.arg("--component-name=rls-preview"); + } + build.run(&mut cmd); distdir(build).join(format!("{}-{}.tar.gz", name, target)) } @@ -1302,9 +1308,12 @@ impl Step for Extended { cp_r(&work.join(&format!("{}-{}", pkgname(build, "rust-std"), target)) .join(format!("rust-std-{}", target)), &exe.join("rust-std")); - cp_r(&work.join(&format!("{}-{}", pkgname(build, "rls"), target)) - .join("rls"), - &exe.join("rls")); + let rls_path = if build.config.channel == "nightly" { + work.join(&format!("{}-{}", pkgname(build, "rls"), target)).join("rls") + } else { + work.join(&format!("{}-{}", pkgname(build, "rls"), target)).join("rls-preview") + }; + cp_r(&rls_path, &exe.join("rls")); cp_r(&work.join(&format!("{}-{}", pkgname(build, "rust-analysis"), target)) .join(format!("rust-analysis-{}", target)), &exe.join("rust-analysis")); From 9240454a3f5c8677e82c8e8ba68333b3e10d6953 Mon Sep 17 00:00:00 2001 From: gaurikholkar Date: Thu, 14 Sep 2017 10:27:41 +0530 Subject: [PATCH 17/40] add ui tests for EBR --- ...ons-both-are-structs-earlybound-regions.rs | 21 +++++++++++++++++++ ...both-are-structs-earlybound-regions.stderr | 11 ++++++++++ 2 files changed, 32 insertions(+) create mode 100644 src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.rs create mode 100644 src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.stderr diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.rs b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.rs new file mode 100644 index 0000000000000..0fef709ae5363 --- /dev/null +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.rs @@ -0,0 +1,21 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. +struct Ref<'a> { + x: &'a u32, +} + +fn foo<'a, 'b>(mut x: Vec>, y: Ref<'b>) + where &'a (): Sized, + &'b u32: Sized +{ + x.push(y); +} + +fn main() {} diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.stderr new file mode 100644 index 0000000000000..59bf5d17222b7 --- /dev/null +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.stderr @@ -0,0 +1,11 @@ +error[E0623]: lifetime mismatch + --> $DIR/ex3-both-anon-regions-both-are-structs-earlybound-regions.rs:18:12 + | +14 | fn foo<'a, 'b>(mut x: Vec>, y: Ref<'b>) + | ------- ------- these two types are declared with different lifetimes... +... +18 | x.push(y); + | ^ ...but data from `y` flows into `x` here + +error: aborting due to previous error + From 06478d12ac9a64b4bc4741ee75b575df4ecb54e2 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Thu, 14 Sep 2017 09:45:07 +0300 Subject: [PATCH 18/40] rustdoc: pretty-print Unevaluated expressions in types. --- src/librustdoc/clean/inline.rs | 2 +- src/librustdoc/clean/mod.rs | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 70563b3d26713..7f5d11ba5de28 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -473,7 +473,7 @@ impl hir::print::PpAnn for InlinedConst { } } -fn print_inlined_const(cx: &DocContext, did: DefId) -> String { +pub fn print_inlined_const(cx: &DocContext, did: DefId) -> String { let body = cx.tcx.extern_const_body(did); let inlined = InlinedConst { nested_bodies: cx.tcx.item_body_nested_bodies(did) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index ce3bf896256ec..7531458d9f9d6 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1793,6 +1793,12 @@ impl Clean for hir::Ty { let n = cx.tcx.const_eval(param_env.and((def_id, substs))).unwrap(); let n = if let ConstVal::Integral(ConstInt::Usize(n)) = n.val { n.to_string() + } else if let ConstVal::Unevaluated(def_id, _) = n.val { + if let Some(node_id) = cx.tcx.hir.as_local_node_id(def_id) { + print_const_expr(cx, cx.tcx.hir.body_owned_by(node_id)) + } else { + inline::print_inlined_const(cx, def_id) + } } else { format!("{:?}", n) }; @@ -1909,6 +1915,12 @@ impl<'tcx> Clean for ty::Ty<'tcx> { ty::TyArray(ty, n) => { let n = if let ConstVal::Integral(ConstInt::Usize(n)) = n.val { n.to_string() + } else if let ConstVal::Unevaluated(def_id, _) = n.val { + if let Some(node_id) = cx.tcx.hir.as_local_node_id(def_id) { + print_const_expr(cx, cx.tcx.hir.body_owned_by(node_id)) + } else { + inline::print_inlined_const(cx, def_id) + } } else { format!("{:?}", n) }; From 52294434b0c8b8f792cf81c6e1816006358e64b2 Mon Sep 17 00:00:00 2001 From: Gauri Kholkar Date: Thu, 14 Sep 2017 17:36:57 +0530 Subject: [PATCH 19/40] Delete fn.rs Removing unwanted file merged in a previous commit --- fn.rs | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 fn.rs diff --git a/fn.rs b/fn.rs deleted file mode 100644 index 186eda95fecbd..0000000000000 --- a/fn.rs +++ /dev/null @@ -1,8 +0,0 @@ - -fn foo(x: fn(&u8, &u8), y: Vec<&u8>, z: &u8) { -// Debruijn 1 1 1 1 -// Anon-Index 0 1 0 1 -// ------ -// debruijn indices are shifted by 1 in here - y.push(z); // index will be zero or one -} From 4253a41473037c769e7c456e2ade079ca350f150 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Mon, 11 Sep 2017 20:15:10 -0400 Subject: [PATCH 20/40] Trim and document compiler-builtins shim --- src/rustc/compiler_builtins_shim/Cargo.toml | 19 +++++++++++++++++-- src/rustc/compiler_builtins_shim/build.rs | 18 ------------------ 2 files changed, 17 insertions(+), 20 deletions(-) delete mode 100644 src/rustc/compiler_builtins_shim/build.rs diff --git a/src/rustc/compiler_builtins_shim/Cargo.toml b/src/rustc/compiler_builtins_shim/Cargo.toml index e0026078a5d72..8ee363b5517e7 100644 --- a/src/rustc/compiler_builtins_shim/Cargo.toml +++ b/src/rustc/compiler_builtins_shim/Cargo.toml @@ -1,5 +1,3 @@ -# See libc_shim/Cargo.toml for why this exists - [package] name = "compiler_builtins" authors = ["The Rust Project Developers"] @@ -12,6 +10,23 @@ test = false doctest = false [dependencies] +# Specify the path to libcore; at the time of writing, removing this shim in +# favor of using compiler-builtins from git results in a compilation failure: +# +# Building stage0 std artifacts (x86_64-apple-darwin -> x86_64-apple-darwin) +# Compiling compiler_builtins v0.1.0 (https://github.com/rust-lang-nursery/compiler-builtins.git#23f14d3f) +# error[E0463]: can't find crate for `core` +# +# error: aborting due to previous error +# +# error: Could not compile `compiler_builtins`. +# +# Caused by: +# process didn't exit successfully: `/Users/tamird/src/rust/build/bootstrap/debug/rustc --crate-name compiler_builtins /Users/tamird/.cargo/git/checkouts/compiler-builtins-ec094dc45a0179c8/23f14d3/src/lib.rs --error-format json --crate-type lib --emit=dep-info,link -C opt-level=2 --cfg feature="c" --cfg feature="compiler-builtins" --cfg feature="default" --cfg feature="gcc" -C metadata=876d429e8d7eae1f -C extra-filename=-876d429e8d7eae1f --out-dir /Users/tamird/src/rust/build/x86_64-apple-darwin/stage0-std/x86_64-apple-darwin/release/deps --target x86_64-apple-darwin -L dependency=/Users/tamird/src/rust/build/x86_64-apple-darwin/stage0-std/x86_64-apple-darwin/release/deps -L dependency=/Users/tamird/src/rust/build/x86_64-apple-darwin/stage0-std/release/deps --cap-lints allow -L native=/Users/tamird/src/rust/build/x86_64-apple-darwin/stage0-std/x86_64-apple-darwin/release/build/compiler_builtins-f18fab55928102ad/out -l static=compiler-rt` (exit code: 101) +# thread 'main' panicked at 'command did not execute successfully: "/Users/tamird/src/rust/build/x86_64-apple-darwin/stage0/bin/cargo" "build" "-j" "4" "--target" "x86_64-apple-darwin" "--release" "--features" "panic-unwind jemalloc backtrace" "--manifest-path" "/Users/tamird/src/rust/src/libstd/Cargo.toml" "--message-format" "json" +# expected success, got: exit code: 101', src/bootstrap/compile.rs:883:8 +# +# See https://github.com/rust-lang/rfcs/pull/1133. core = { path = "../../libcore" } [build-dependencies] diff --git a/src/rustc/compiler_builtins_shim/build.rs b/src/rustc/compiler_builtins_shim/build.rs deleted file mode 100644 index 546f60482e7bc..0000000000000 --- a/src/rustc/compiler_builtins_shim/build.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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. - -#![deny(warnings)] - -// See comments in Cargo.toml for why this exists - -fn main() { - println!("cargo:rustc-cfg=stdbuild"); - println!("cargo:rerun-if-changed=build.rs"); -} From 509982ce532bd3b5f5d3cae16ab6299b4c68b181 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Mon, 11 Sep 2017 21:09:26 -0400 Subject: [PATCH 21/40] Trim and document libc shim --- src/liblibc | 2 +- src/rustc/libc_shim/Cargo.toml | 32 +++++++++++++++++++++++--------- src/rustc/libc_shim/build.rs | 18 ------------------ 3 files changed, 24 insertions(+), 28 deletions(-) delete mode 100644 src/rustc/libc_shim/build.rs diff --git a/src/liblibc b/src/liblibc index 95848f9622dec..703ae4ff93aa6 160000 --- a/src/liblibc +++ b/src/liblibc @@ -1 +1 @@ -Subproject commit 95848f9622deccc9cbadcd5d3a4faef01a90ead4 +Subproject commit 703ae4ff93aa6c91869a509dbb77111266de7242 diff --git a/src/rustc/libc_shim/Cargo.toml b/src/rustc/libc_shim/Cargo.toml index 39df3528be369..0c04402124a2d 100644 --- a/src/rustc/libc_shim/Cargo.toml +++ b/src/rustc/libc_shim/Cargo.toml @@ -1,16 +1,7 @@ -# This is a shim Cargo.toml over the "real Cargo.toml" found in the libc -# repository itself. The purpose for this is to add a build script which prints -# out `--cfg stdbuild` to mirror the makefiles' build system. -# -# Note that other than that this isn't actually needed, and we should probably -# remove this shim in favor of just working with cargo features directly with -# libc. That should make everything nicer! - [package] name = "libc" version = "0.0.0" authors = ["The Rust Project Developers"] -build = "build.rs" [lib] name = "libc" @@ -20,4 +11,27 @@ bench = false doc = false [dependencies] +# Specify the path to libcore; at the time of writing, removing this shim in +# favor of using libc from git results in a compilation failure: +# +# Building stage0 std artifacts (x86_64-apple-darwin -> x86_64-apple-darwin) +# Compiling libc v0.0.0 (file:///Users/tamird/src/rust/src/rustc/libc_shim) +# error[E0463]: can't find crate for `core` +# +# error: aborting due to previous error +# +# error: Could not compile `libc`. +# +# Caused by: +# process didn't exit successfully: `/Users/tamird/src/rust/build/bootstrap/debug/rustc --crate-name libc src/rustc/libc_shim/../../liblibc/src/lib.rs --error-format json --crate-type lib --emit=dep-info,link -C opt-level=2 --cfg feature="default" --cfg feature="no_std" --cfg feature="stdbuild" -C metadata=d758f87058112d7d -C extra-filename=-d758f87058112d7d --out-dir /Users/tamird/src/rust/build/x86_64-apple-darwin/stage0-std/x86_64-apple-darwin/release/deps --target x86_64-apple-darwin -L dependency=/Users/tamird/src/rust/build/x86_64-apple-darwin/stage0-std/x86_64-apple-darwin/release/deps -L dependency=/Users/tamird/src/rust/build/x86_64-apple-darwin/stage0-std/release/deps` (exit code: 101) +# thread 'main' panicked at 'command did not execute successfully: "/Users/tamird/src/rust/build/x86_64-apple-darwin/stage0/bin/cargo" "build" "-j" "4" "--target" "x86_64-apple-darwin" "--release" "--features" "panic-unwind jemalloc backtrace" "--manifest-path" "/Users/tamird/src/rust/src/libstd/Cargo.toml" "--message-format" "json" +# expected success, got: exit code: 101', src/bootstrap/compile.rs:883:8 +# +# See https://github.com/rust-lang/rfcs/pull/1133. core = { path = "../../libcore" } + +[features] +# Certain parts of libc are conditionally compiled differently than when used +# outside rustc. See https://github.com/rust-lang/libc/search?l=Rust&q=stdbuild&type=&utf8=%E2%9C%93. +stdbuild = [] +default = ["stdbuild"] diff --git a/src/rustc/libc_shim/build.rs b/src/rustc/libc_shim/build.rs deleted file mode 100644 index 546f60482e7bc..0000000000000 --- a/src/rustc/libc_shim/build.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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. - -#![deny(warnings)] - -// See comments in Cargo.toml for why this exists - -fn main() { - println!("cargo:rustc-cfg=stdbuild"); - println!("cargo:rerun-if-changed=build.rs"); -} From ddd321df91fc67715cb583f52e68cd41a4549aec Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 14 Sep 2017 13:17:25 -0700 Subject: [PATCH 22/40] travis: Move sccache to the us-west-1 region Most of the other rust-lang buckets are in us-west-1 and I think the original bucket was just accidentally created in the us-east-1 region. Let's consolidate by moving it to the same location as the rest of our buckets. --- .travis.yml | 3 ++- appveyor.yml | 3 ++- src/ci/docker/run.sh | 13 +++++++------ 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 23bae6d9f1721..e24afe5d2c354 100644 --- a/.travis.yml +++ b/.travis.yml @@ -124,7 +124,8 @@ matrix: env: global: - - SCCACHE_BUCKET=rust-lang-ci-sccache + - SCCACHE_BUCKET=rust-lang-ci-sccache2 + - SCCACHE_REGION=us-west-1 - AWS_ACCESS_KEY_ID=AKIAJAMV3QAMMA6AXHFQ # AWS_SECRET_ACCESS_KEY=... - secure: "j96XxTVOSUf4s4r4htIxn/fvIa5DWbMgLqWl7r8z2QfgUwscmkMXAwXuFNc7s7bGTpV/+CgDiMFFM6BAFLGKutytIF6oA02s9b+usQYnM0th7YQ2AIgm9GtMTJCJp4AoyfFmh8F2faUICBZlfVLUJ34udHEe35vOklix+0k4WDo=" diff --git a/appveyor.yml b/appveyor.yml index 62b62ae7c42e9..e922b930675eb 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,5 +1,6 @@ environment: - SCCACHE_BUCKET: rust-lang-ci-sccache + SCCACHE_BUCKET: rust-lang-ci-sccache2 + SCCACHE_REGION: us-west-1 AWS_ACCESS_KEY_ID: AKIAJAMV3QAMMA6AXHFQ AWS_SECRET_ACCESS_KEY: secure: 7Y+JiquYedOAgnUU26uL0DPzrxmTtR+qIwG6rNKSuWDffqU3vVZxbGXim9QpTO80 diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh index 5eba81ff60a22..7087033e117a2 100755 --- a/src/ci/docker/run.sh +++ b/src/ci/docker/run.sh @@ -57,9 +57,10 @@ mkdir -p $objdir/tmp args= if [ "$SCCACHE_BUCKET" != "" ]; then - args="$args --env SCCACHE_BUCKET=$SCCACHE_BUCKET" - args="$args --env AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID" - args="$args --env AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY" + args="$args --env SCCACHE_BUCKET" + args="$args --env SCCACHE_REGION" + args="$args --env AWS_ACCESS_KEY_ID" + args="$args --env AWS_SECRET_ACCESS_KEY" args="$args --env SCCACHE_ERROR_LOG=/tmp/sccache/sccache.log" args="$args --volume $objdir/tmp:/tmp/sccache" else @@ -82,10 +83,10 @@ exec docker \ --env SRC=/checkout \ $args \ --env CARGO_HOME=/cargo \ - --env DEPLOY=$DEPLOY \ - --env DEPLOY_ALT=$DEPLOY_ALT \ + --env DEPLOY \ + --env DEPLOY_ALT \ --env LOCAL_USER_ID=`id -u` \ - --env TRAVIS=${TRAVIS-false} \ + --env TRAVIS \ --env TRAVIS_BRANCH \ --volume "$HOME/.cargo:/cargo" \ --volume "$HOME/rustsrc:$HOME/rustsrc" \ From 61a7703e5575795e837d16d3a0ec46551cc6b69b Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Thu, 14 Sep 2017 13:51:32 -0700 Subject: [PATCH 23/40] Customize `::fold` `FlatMap` can use internal iteration for its `fold`, which shows a performance advantage in the new benchmarks: test iter::bench_flat_map_chain_ref_sum ... bench: 4,354,111 ns/iter (+/- 108,871) test iter::bench_flat_map_chain_sum ... bench: 468,167 ns/iter (+/- 2,274) test iter::bench_flat_map_ref_sum ... bench: 449,616 ns/iter (+/- 6,257) test iter::bench_flat_map_sum ... bench: 348,010 ns/iter (+/- 1,227) ... where the "ref" benches are using `by_ref()` that isn't optimized. So this change shows a decent advantage on its own, but much more when combined with a `chain` iterator that also optimizes `fold`. --- src/libcore/benches/iter.rs | 38 +++++++++++++++++++++++++++++++++++++ src/libcore/iter/mod.rs | 10 ++++++++++ 2 files changed, 48 insertions(+) diff --git a/src/libcore/benches/iter.rs b/src/libcore/benches/iter.rs index 5b06229c21f23..827c6354c60ba 100644 --- a/src/libcore/benches/iter.rs +++ b/src/libcore/benches/iter.rs @@ -146,3 +146,41 @@ fn bench_for_each_chain_ref_fold(b: &mut Bencher) { acc }); } + +#[bench] +fn bench_flat_map_sum(b: &mut Bencher) { + b.iter(|| -> i64 { + (0i64..1000).flat_map(|x| x..x+1000) + .map(black_box) + .sum() + }); +} + +#[bench] +fn bench_flat_map_ref_sum(b: &mut Bencher) { + b.iter(|| -> i64 { + (0i64..1000).flat_map(|x| x..x+1000) + .map(black_box) + .by_ref() + .sum() + }); +} + +#[bench] +fn bench_flat_map_chain_sum(b: &mut Bencher) { + b.iter(|| -> i64 { + (0i64..1000000).flat_map(|x| once(x).chain(once(x))) + .map(black_box) + .sum() + }); +} + +#[bench] +fn bench_flat_map_chain_ref_sum(b: &mut Bencher) { + b.iter(|| -> i64 { + (0i64..1000000).flat_map(|x| once(x).chain(once(x))) + .map(black_box) + .by_ref() + .sum() + }); +} diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index ebedfe1d743bb..a596ffd6ae8fc 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -1902,6 +1902,16 @@ impl Iterator for FlatMap _ => (lo, None) } } + + #[inline] + fn fold(self, init: Acc, mut fold: Fold) -> Acc + where Fold: FnMut(Acc, Self::Item) -> Acc, + { + self.frontiter.into_iter() + .chain(self.iter.map(self.f).map(U::into_iter)) + .chain(self.backiter) + .fold(init, |acc, iter| iter.fold(acc, &mut fold)) + } } #[stable(feature = "rust1", since = "1.0.0")] From 2bde6949f955f59dacd72de3732c48f1c6d5b673 Mon Sep 17 00:00:00 2001 From: Douglas Campos Date: Thu, 14 Sep 2017 21:13:36 -0400 Subject: [PATCH 24/40] bring TyCtxt into scope --- src/librustc/ich/hcx.rs | 8 ++++---- src/librustc/middle/lang_items.rs | 2 +- src/librustc/mir/mod.rs | 6 +++--- src/librustc/ty/layout.rs | 2 +- src/librustc_metadata/astencode.rs | 4 ++-- src/librustc_mir/build/cfg.rs | 4 ++-- src/librustc_mir/shim.rs | 18 +++++++++--------- src/librustc_mir/transform/elaborate_drops.rs | 2 +- src/librustc_mir/util/elaborate_drops.rs | 6 +++--- src/librustc_typeck/check/upvar.rs | 4 ++-- src/librustc_typeck/constrained_type_params.rs | 6 +++--- 11 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs index 81cf20cfc77f0..5c011042deeee 100644 --- a/src/librustc/ich/hcx.rs +++ b/src/librustc/ich/hcx.rs @@ -13,7 +13,7 @@ use hir::def_id::DefId; use hir::map::DefPathHash; use ich::{self, CachingCodemapView}; use session::config::DebugInfoLevel::NoDebugInfo; -use ty; +use ty::TyCtxt; use util::nodemap::{NodeMap, ItemLocalMap}; use std::hash as std_hash; @@ -34,7 +34,7 @@ use rustc_data_structures::accumulate_vec::AccumulateVec; /// a reference to the TyCtxt) and it holds a few caches for speeding up various /// things (e.g. each DefId/DefPath is only hashed once). pub struct StableHashingContext<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { - tcx: ty::TyCtxt<'a, 'gcx, 'tcx>, + tcx: TyCtxt<'a, 'gcx, 'tcx>, codemap: CachingCodemapView<'gcx>, hash_spans: bool, hash_bodies: bool, @@ -53,7 +53,7 @@ pub enum NodeIdHashingMode { impl<'a, 'gcx, 'tcx> StableHashingContext<'a, 'gcx, 'tcx> { - pub fn new(tcx: ty::TyCtxt<'a, 'gcx, 'tcx>) -> Self { + pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Self { let hash_spans_initial = tcx.sess.opts.debuginfo != NoDebugInfo; let check_overflow_initial = tcx.sess.overflow_checks(); @@ -111,7 +111,7 @@ impl<'a, 'gcx, 'tcx> StableHashingContext<'a, 'gcx, 'tcx> { } #[inline] - pub fn tcx(&self) -> ty::TyCtxt<'a, 'gcx, 'tcx> { + pub fn tcx(&self) -> TyCtxt<'a, 'gcx, 'tcx> { self.tcx } diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index cb59d9870faac..b645a49949eec 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -340,7 +340,7 @@ language_item_table! { DebugTraitLangItem, "debug_trait", debug_trait; } -impl<'a, 'tcx, 'gcx> ty::TyCtxt<'a, 'tcx, 'gcx> { +impl<'a, 'tcx, 'gcx> TyCtxt<'a, 'tcx, 'gcx> { pub fn require_lang_item(&self, lang_item: LangItem) -> DefId { self.lang_items().require(lang_item).unwrap_or_else(|msg| { self.sess.fatal(&msg) diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 38dfe010c153c..d43504b77ba0c 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -21,7 +21,7 @@ use rustc_data_structures::control_flow_graph::ControlFlowGraph; use hir::def::CtorKind; use hir::def_id::DefId; use ty::subst::{Subst, Substs}; -use ty::{self, AdtDef, ClosureSubsts, Region, Ty, GeneratorInterior}; +use ty::{self, AdtDef, ClosureSubsts, Region, Ty, TyCtxt, GeneratorInterior}; use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use util::ppaux; use rustc_back::slice; @@ -644,7 +644,7 @@ impl<'tcx> Terminator<'tcx> { } impl<'tcx> TerminatorKind<'tcx> { - pub fn if_<'a, 'gcx>(tcx: ty::TyCtxt<'a, 'gcx, 'tcx>, cond: Operand<'tcx>, + pub fn if_<'a, 'gcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, cond: Operand<'tcx>, t: BasicBlock, f: BasicBlock) -> TerminatorKind<'tcx> { static BOOL_SWITCH_FALSE: &'static [ConstInt] = &[ConstInt::U8(0)]; TerminatorKind::SwitchInt { @@ -1182,7 +1182,7 @@ impl<'tcx> Debug for Operand<'tcx> { impl<'tcx> Operand<'tcx> { pub fn function_handle<'a>( - tcx: ty::TyCtxt<'a, 'tcx, 'tcx>, + tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId, substs: &'tcx Substs<'tcx>, span: Span, diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 0106d98b64130..84d7745a64f0a 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -386,7 +386,7 @@ impl Integer { } } - pub fn to_ty<'a, 'tcx>(&self, tcx: &ty::TyCtxt<'a, 'tcx, 'tcx>, + pub fn to_ty<'a, 'tcx>(&self, tcx: &TyCtxt<'a, 'tcx, 'tcx>, signed: bool) -> Ty<'tcx> { match (*self, signed) { (I1, false) => tcx.types.u8, diff --git a/src/librustc_metadata/astencode.rs b/src/librustc_metadata/astencode.rs index b1b3e92347a21..ade2612855e02 100644 --- a/src/librustc_metadata/astencode.rs +++ b/src/librustc_metadata/astencode.rs @@ -14,7 +14,7 @@ use isolated_encoder::IsolatedEncoder; use schema::*; use rustc::hir; -use rustc::ty; +use rustc::ty::{self, TyCtxt}; #[derive(RustcEncodable, RustcDecodable)] pub struct Ast<'tcx> { @@ -59,7 +59,7 @@ impl<'a, 'b, 'tcx> IsolatedEncoder<'a, 'b, 'tcx> { } struct NestedBodyCollector<'a, 'tcx: 'a> { - tcx: ty::TyCtxt<'a, 'tcx, 'tcx>, + tcx: TyCtxt<'a, 'tcx, 'tcx>, bodies_found: Vec<&'tcx hir::Body>, } diff --git a/src/librustc_mir/build/cfg.rs b/src/librustc_mir/build/cfg.rs index a6e31bcddd242..dfddbfe485dd9 100644 --- a/src/librustc_mir/build/cfg.rs +++ b/src/librustc_mir/build/cfg.rs @@ -16,7 +16,7 @@ use build::CFG; use rustc::middle::region; use rustc::mir::*; -use rustc::ty; +use rustc::ty::TyCtxt; impl<'tcx> CFG<'tcx> { pub fn block_data(&self, blk: BasicBlock) -> &BasicBlockData<'tcx> { @@ -46,7 +46,7 @@ impl<'tcx> CFG<'tcx> { } pub fn push_end_region<'a, 'gcx:'a+'tcx>(&mut self, - tcx: ty::TyCtxt<'a, 'gcx, 'tcx>, + tcx: TyCtxt<'a, 'gcx, 'tcx>, block: BasicBlock, source_info: SourceInfo, region_scope: region::Scope) { diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index 00ee417e02b55..a141ff3153fd1 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -14,7 +14,7 @@ use rustc::infer; use rustc::middle::const_val::ConstVal; use rustc::mir::*; use rustc::mir::transform::MirSource; -use rustc::ty::{self, Ty}; +use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::subst::{Kind, Subst, Substs}; use rustc::ty::maps::Providers; use rustc_const_math::{ConstInt, ConstUsize}; @@ -36,7 +36,7 @@ pub fn provide(providers: &mut Providers) { providers.mir_shims = make_shim; } -fn make_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>, +fn make_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx Mir<'tcx> { @@ -154,7 +154,7 @@ fn local_decls_for_sig<'tcx>(sig: &ty::FnSig<'tcx>, span: Span) .collect() } -fn build_drop_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>, +fn build_drop_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId, ty: Option>) -> Mir<'tcx> @@ -235,7 +235,7 @@ fn build_drop_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>, pub struct DropShimElaborator<'a, 'tcx: 'a> { pub mir: &'a Mir<'tcx>, pub patch: MirPatch<'tcx>, - pub tcx: ty::TyCtxt<'a, 'tcx, 'tcx>, + pub tcx: TyCtxt<'a, 'tcx, 'tcx>, pub param_env: ty::ParamEnv<'tcx>, } @@ -250,7 +250,7 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for DropShimElaborator<'a, 'tcx> { fn patch(&mut self) -> &mut MirPatch<'tcx> { &mut self.patch } fn mir(&self) -> &'a Mir<'tcx> { self.mir } - fn tcx(&self) -> ty::TyCtxt<'a, 'tcx, 'tcx> { self.tcx } + fn tcx(&self) -> TyCtxt<'a, 'tcx, 'tcx> { self.tcx } fn param_env(&self) -> ty::ParamEnv<'tcx> { self.param_env } fn drop_style(&self, _path: Self::Path, mode: DropFlagMode) -> DropStyle { @@ -280,7 +280,7 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for DropShimElaborator<'a, 'tcx> { } /// Build a `Clone::clone` shim for `self_ty`. Here, `def_id` is `Clone::clone`. -fn build_clone_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>, +fn build_clone_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId, self_ty: ty::Ty<'tcx>) -> Mir<'tcx> @@ -306,7 +306,7 @@ fn build_clone_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>, } struct CloneShimBuilder<'a, 'tcx: 'a> { - tcx: ty::TyCtxt<'a, 'tcx, 'tcx>, + tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId, local_decls: IndexVec>, blocks: IndexVec>, @@ -315,7 +315,7 @@ struct CloneShimBuilder<'a, 'tcx: 'a> { } impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> { - fn new(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Self { + fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Self { let sig = tcx.fn_sig(def_id); let sig = tcx.erase_late_bound_regions(&sig); let span = tcx.def_span(def_id); @@ -666,7 +666,7 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> { /// /// If `untuple_args` is a vec of types, the second argument of the /// function will be untupled as these types. -fn build_call_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>, +fn build_call_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId, rcvr_adjustment: Adjustment, call_kind: CallKind, diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/src/librustc_mir/transform/elaborate_drops.rs index 1077f3b014616..c833904adbaea 100644 --- a/src/librustc_mir/transform/elaborate_drops.rs +++ b/src/librustc_mir/transform/elaborate_drops.rs @@ -192,7 +192,7 @@ impl<'a, 'b, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, 'b, 'tcx> { self.ctxt.mir } - fn tcx(&self) -> ty::TyCtxt<'a, 'tcx, 'tcx> { + fn tcx(&self) -> TyCtxt<'a, 'tcx, 'tcx> { self.ctxt.tcx } diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs index 4a11ac1168090..3b9772079adb9 100644 --- a/src/librustc_mir/util/elaborate_drops.rs +++ b/src/librustc_mir/util/elaborate_drops.rs @@ -13,7 +13,7 @@ use rustc::hir; use rustc::mir::*; use rustc::middle::const_val::{ConstInt, ConstVal}; use rustc::middle::lang_items; -use rustc::ty::{self, Ty}; +use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::subst::{Kind, Substs}; use rustc::ty::util::IntTypeExt; use rustc_data_structures::indexed_vec::Idx; @@ -84,7 +84,7 @@ pub trait DropElaborator<'a, 'tcx: 'a> : fmt::Debug { fn patch(&mut self) -> &mut MirPatch<'tcx>; fn mir(&self) -> &'a Mir<'tcx>; - fn tcx(&self) -> ty::TyCtxt<'a, 'tcx, 'tcx>; + fn tcx(&self) -> TyCtxt<'a, 'tcx, 'tcx>; fn param_env(&self) -> ty::ParamEnv<'tcx>; fn drop_style(&self, path: Self::Path, mode: DropFlagMode) -> DropStyle; @@ -133,7 +133,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> lvalue.ty(self.elaborator.mir(), self.tcx()).to_ty(self.tcx()) } - fn tcx(&self) -> ty::TyCtxt<'b, 'tcx, 'tcx> { + fn tcx(&self) -> TyCtxt<'b, 'tcx, 'tcx> { self.elaborator.tcx() } diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs index acdd58f4ecfe4..d179b390a2918 100644 --- a/src/librustc_typeck/check/upvar.rs +++ b/src/librustc_typeck/check/upvar.rs @@ -45,7 +45,7 @@ use super::FnCtxt; use middle::expr_use_visitor as euv; use middle::mem_categorization as mc; use middle::mem_categorization::Categorization; -use rustc::ty::{self, Ty}; +use rustc::ty::{self, Ty, TyCtxt}; use rustc::infer::UpvarRegion; use syntax::ast; use syntax_pos::Span; @@ -586,7 +586,7 @@ impl<'a, 'gcx, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'gcx, 'tcx> { } } -fn var_name(tcx: ty::TyCtxt, var_hir_id: hir::HirId) -> ast::Name { +fn var_name(tcx: TyCtxt, var_hir_id: hir::HirId) -> ast::Name { let var_node_id = tcx.hir.hir_to_node_id(var_hir_id); tcx.hir.name(var_node_id) } diff --git a/src/librustc_typeck/constrained_type_params.rs b/src/librustc_typeck/constrained_type_params.rs index 09c7487e63560..5f55b9b06ef1b 100644 --- a/src/librustc_typeck/constrained_type_params.rs +++ b/src/librustc_typeck/constrained_type_params.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use rustc::ty::{self, Ty}; +use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::fold::{TypeFoldable, TypeVisitor}; use rustc::util::nodemap::FxHashSet; @@ -86,7 +86,7 @@ impl<'tcx> TypeVisitor<'tcx> for ParameterCollector { } } -pub fn identify_constrained_type_params<'tcx>(tcx: ty::TyCtxt, +pub fn identify_constrained_type_params<'tcx>(tcx: TyCtxt, predicates: &[ty::Predicate<'tcx>], impl_trait_ref: Option>, input_parameters: &mut FxHashSet) @@ -136,7 +136,7 @@ pub fn identify_constrained_type_params<'tcx>(tcx: ty::TyCtxt, /// which is determined by 1, which requires `U`, that is determined /// by 0. I should probably pick a less tangled example, but I can't /// think of any. -pub fn setup_constraining_predicates<'tcx>(tcx: ty::TyCtxt, +pub fn setup_constraining_predicates<'tcx>(tcx: TyCtxt, predicates: &mut [ty::Predicate<'tcx>], impl_trait_ref: Option>, input_parameters: &mut FxHashSet) From 9d5b0e1ff54198543233f418fbc43921b5f7201b Mon Sep 17 00:00:00 2001 From: "J. Cliff Dyer" Date: Thu, 14 Sep 2017 21:30:36 -0400 Subject: [PATCH 25/40] Add unstable attributes for Ipv?Addr constructors. --- src/libstd/net/ip.rs | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs index d3ea3845f1207..eea604943af8b 100644 --- a/src/libstd/net/ip.rs +++ b/src/libstd/net/ip.rs @@ -10,7 +10,7 @@ #![unstable(feature = "ip", reason = "extra functionality has not been \ scrutinized to the level that it should \ - be stable", + be to be stable", issue = "27709")] use cmp::Ordering; @@ -347,12 +347,15 @@ impl Ipv4Addr { /// # Examples /// /// ``` - /// #![feature(ip)] + /// #![feature(ip_constructors)] /// use std::net::Ipv4Addr; /// /// let addr = Ipv4Addr::localhost(); /// assert_eq!(addr, Ipv4Addr::new(127, 0, 0, 1)); /// ``` + #[unstable(feature = "ip_constructors", + reason = "requires greater scrutiny before stabilization", + issue = "44582")] pub fn localhost() -> Ipv4Addr { Ipv4Addr::new(127, 0, 0, 1) } @@ -362,12 +365,15 @@ impl Ipv4Addr { /// # Examples /// /// ``` - /// #![feature(ip)] + /// #![feature(ip_constructors)] /// use std::net::Ipv4Addr; /// /// let addr = Ipv4Addr::unspecified(); /// assert_eq!(addr, Ipv4Addr::new(0, 0, 0, 0)); /// ``` + #[unstable(feature = "ip_constructors", + reason = "requires greater scrutiny before stabilization", + issue = "44582")] pub fn unspecified() -> Ipv4Addr { Ipv4Addr::new(0, 0, 0, 0) } @@ -823,12 +829,15 @@ impl Ipv6Addr { /// # Examples /// /// ``` - /// #![feature(ip)] + /// #![feature(ip_constructors)] /// use std::net::Ipv6Addr; /// /// let addr = Ipv6Addr::localhost(); /// assert_eq!(addr, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)); /// ``` + #[unstable(feature = "ip_constructors", + reason = "requires greater scrutiny before stabilization", + issue = "44582")] pub fn localhost() -> Ipv6Addr { Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1) } @@ -838,12 +847,15 @@ impl Ipv6Addr { /// # Examples /// /// ``` - /// #![feature(ip)] + /// #![feature(ip_constructors)] /// use std::net::Ipv6Addr; /// /// let addr = Ipv6Addr::unspecified(); /// assert_eq!(addr, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)); /// ``` + #[unstable(feature = "ip_constructors", + reason = "requires greater scrutiny before stabilization", + issue = "44582")] pub fn unspecified() -> Ipv6Addr { Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0) } From 3fe4612d140abb20c750b1844ff7f49c4f6910c7 Mon Sep 17 00:00:00 2001 From: Douglas Campos Date: Thu, 14 Sep 2017 21:44:23 -0400 Subject: [PATCH 26/40] bring Ty into scope --- src/librustc/infer/error_reporting/mod.rs | 10 +++++----- src/librustc/infer/error_reporting/util.rs | 4 ++-- src/librustc/infer/mod.rs | 2 +- src/librustc/traits/mod.rs | 2 +- src/librustc_borrowck/borrowck/mod.rs | 8 ++++---- src/librustc_mir/build/expr/as_rvalue.rs | 8 ++++---- src/librustc_mir/hair/mod.rs | 4 ++-- src/librustc_mir/shim.rs | 10 +++++----- src/librustc_trans/collector.rs | 18 +++++++++--------- src/librustc_trans/context.rs | 4 ++-- src/librustc_trans/declare.rs | 8 ++++---- src/librustc_trans/meth.rs | 4 ++-- src/librustc_trans/mir/block.rs | 4 ++-- src/librustc_typeck/check/dropck.rs | 2 +- src/librustc_typeck/check/intrinsic.rs | 4 ++-- src/librustc_typeck/check/method/mod.rs | 14 +++++++------- src/librustc_typeck/check/wfcheck.rs | 2 +- src/librustc_typeck/collect.rs | 4 ++-- src/librustdoc/clean/mod.rs | 6 +++--- 19 files changed, 59 insertions(+), 59 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 6fc76a1d09037..a88e90caee307 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -66,7 +66,7 @@ use hir::map as hir_map; use hir::def_id::DefId; use middle::region; use traits::{ObligationCause, ObligationCauseCode}; -use ty::{self, Region, TyCtxt, TypeFoldable}; +use ty::{self, Region, Ty, TyCtxt, TypeFoldable}; use ty::error::TypeError; use syntax::ast::DUMMY_NODE_ID; use syntax_pos::{Pos, Span}; @@ -418,7 +418,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { name: String, sub: &ty::subst::Substs<'tcx>, pos: usize, - other_ty: &ty::Ty<'tcx>) { + other_ty: &Ty<'tcx>) { // `value` and `other_value` hold two incomplete type representation for display. // `name` is the path of both types being compared. `sub` value.push_highlighted(name); @@ -491,7 +491,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { path: String, sub: &ty::subst::Substs<'tcx>, other_path: String, - other_ty: &ty::Ty<'tcx>) -> Option<()> { + other_ty: &Ty<'tcx>) -> Option<()> { for (i, ta) in sub.types().enumerate() { if &ta == other_ty { self.highlight_outer(&mut t1_out, &mut t2_out, path, sub, i, &other_ty); @@ -522,7 +522,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { /// Compare two given types, eliding parts that are the same between them and highlighting /// relevant differences, and return two representation of those types for highlighted printing. - fn cmp(&self, t1: ty::Ty<'tcx>, t2: ty::Ty<'tcx>) + fn cmp(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) -> (DiagnosticStyledString, DiagnosticStyledString) { match (&t1.sty, &t2.sty) { @@ -743,7 +743,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } fn expected_found_str_ty(&self, - exp_found: &ty::error::ExpectedFound>) + exp_found: &ty::error::ExpectedFound>) -> Option<(DiagnosticStyledString, DiagnosticStyledString)> { let exp_found = self.resolve_type_vars_if_possible(exp_found); if exp_found.references_error() { diff --git a/src/librustc/infer/error_reporting/util.rs b/src/librustc/infer/error_reporting/util.rs index b58fa6b0e7cbd..94faec464b244 100644 --- a/src/librustc/infer/error_reporting/util.rs +++ b/src/librustc/infer/error_reporting/util.rs @@ -12,7 +12,7 @@ //! anonymous regions. use hir; use infer::InferCtxt; -use ty::{self, Region}; +use ty::{self, Region, Ty}; use hir::def_id::DefId; use hir::map as hir_map; @@ -35,7 +35,7 @@ pub struct AnonymousArgInfo<'tcx> { // the argument corresponding to the anonymous region pub arg: &'tcx hir::Arg, // the type corresponding to the anonymopus region argument - pub arg_ty: ty::Ty<'tcx>, + pub arg_ty: Ty<'tcx>, // the ty::BoundRegion corresponding to the anonymous region pub bound_region: ty::BoundRegion, // corresponds to id the argument is the first parameter diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 6ccf7e42fd5fd..39bcd7035742e 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -644,7 +644,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } } - pub fn unsolved_variables(&self) -> Vec> { + pub fn unsolved_variables(&self) -> Vec> { let mut variables = Vec::new(); let unbound_ty_vars = self.type_variables diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index fb71d9cc49b9e..a1817f181066c 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -381,7 +381,7 @@ pub struct VtableObjectData<'tcx, N> { #[derive(Clone, PartialEq, Eq)] pub struct VtableFnPointerData<'tcx, N> { - pub fn_ty: ty::Ty<'tcx>, + pub fn_ty: Ty<'tcx>, pub nested: Vec } diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 6527ac0e92721..6fb49a0908ff4 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -34,7 +34,7 @@ use rustc::middle::mem_categorization::Categorization; use rustc::middle::mem_categorization::ImmutabilityBlame; use rustc::middle::region; use rustc::middle::free_region::RegionRelations; -use rustc::ty::{self, TyCtxt}; +use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::maps::Providers; use rustc_mir::util::borrowck_errors::{BorrowckErrors, Origin}; @@ -275,7 +275,7 @@ impl<'tcx> Loan<'tcx> { #[derive(Eq)] pub struct LoanPath<'tcx> { kind: LoanPathKind<'tcx>, - ty: ty::Ty<'tcx>, + ty: Ty<'tcx>, } impl<'tcx> PartialEq for LoanPath<'tcx> { @@ -299,11 +299,11 @@ pub enum LoanPathKind<'tcx> { } impl<'tcx> LoanPath<'tcx> { - fn new(kind: LoanPathKind<'tcx>, ty: ty::Ty<'tcx>) -> LoanPath<'tcx> { + fn new(kind: LoanPathKind<'tcx>, ty: Ty<'tcx>) -> LoanPath<'tcx> { LoanPath { kind: kind, ty: ty } } - fn to_type(&self) -> ty::Ty<'tcx> { self.ty } + fn to_type(&self) -> Ty<'tcx> { self.ty } } // FIXME (pnkfelix): See discussion here diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs index eeae4bce335ca..f0b6a4fcfd9d7 100644 --- a/src/librustc_mir/build/expr/as_rvalue.rs +++ b/src/librustc_mir/build/expr/as_rvalue.rs @@ -22,7 +22,7 @@ use hair::*; use rustc_const_math::{ConstInt, ConstIsize}; use rustc::middle::const_val::ConstVal; use rustc::middle::region; -use rustc::ty; +use rustc::ty::{self, Ty}; use rustc::mir::*; use syntax::ast; use syntax_pos::Span; @@ -291,7 +291,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { } pub fn build_binary_op(&mut self, mut block: BasicBlock, - op: BinOp, span: Span, ty: ty::Ty<'tcx>, + op: BinOp, span: Span, ty: Ty<'tcx>, lhs: Operand<'tcx>, rhs: Operand<'tcx>) -> BlockAnd> { let source_info = self.source_info(span); let bool_ty = self.hir.bool_ty(); @@ -378,7 +378,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { } // Helper to get a `-1` value of the appropriate type - fn neg_1_literal(&mut self, span: Span, ty: ty::Ty<'tcx>) -> Operand<'tcx> { + fn neg_1_literal(&mut self, span: Span, ty: Ty<'tcx>) -> Operand<'tcx> { let literal = match ty.sty { ty::TyInt(ity) => { let val = match ity { @@ -410,7 +410,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { } // Helper to get the minimum value of the appropriate type - fn minval_literal(&mut self, span: Span, ty: ty::Ty<'tcx>) -> Operand<'tcx> { + fn minval_literal(&mut self, span: Span, ty: Ty<'tcx>) -> Operand<'tcx> { let literal = match ty.sty { ty::TyInt(ity) => { let val = match ity { diff --git a/src/librustc_mir/hair/mod.rs b/src/librustc_mir/hair/mod.rs index 067bd458d97dd..3162242de66c5 100644 --- a/src/librustc_mir/hair/mod.rs +++ b/src/librustc_mir/hair/mod.rs @@ -19,7 +19,7 @@ use rustc::mir::{BinOp, BorrowKind, Field, Literal, UnOp}; use rustc::hir::def_id::DefId; use rustc::middle::region; use rustc::ty::subst::Substs; -use rustc::ty::{self, AdtDef, ClosureSubsts, Region, Ty, GeneratorInterior}; +use rustc::ty::{AdtDef, ClosureSubsts, Region, Ty, GeneratorInterior}; use rustc::hir; use syntax::ast; use syntax_pos::Span; @@ -117,7 +117,7 @@ pub enum ExprKind<'tcx> { value: ExprRef<'tcx>, }, Call { - ty: ty::Ty<'tcx>, + ty: Ty<'tcx>, fun: ExprRef<'tcx>, args: Vec>, }, diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index a141ff3153fd1..3c9d95ca21574 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -282,7 +282,7 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for DropShimElaborator<'a, 'tcx> { /// Build a `Clone::clone` shim for `self_ty`. Here, `def_id` is `Clone::clone`. fn build_clone_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId, - self_ty: ty::Ty<'tcx>) + self_ty: Ty<'tcx>) -> Mir<'tcx> { debug!("build_clone_shim(def_id={:?})", def_id); @@ -382,7 +382,7 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> { self.block(vec![ret_statement], TerminatorKind::Return, false); } - fn make_lvalue(&mut self, mutability: Mutability, ty: ty::Ty<'tcx>) -> Lvalue<'tcx> { + fn make_lvalue(&mut self, mutability: Mutability, ty: Ty<'tcx>) -> Lvalue<'tcx> { let span = self.span; Lvalue::Local( self.local_decls.push(temp_decl(mutability, ty, span)) @@ -391,7 +391,7 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> { fn make_clone_call( &mut self, - ty: ty::Ty<'tcx>, + ty: Ty<'tcx>, rcvr_field: Lvalue<'tcx>, next: BasicBlock, cleanup: BasicBlock @@ -487,7 +487,7 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> { } } - fn array_shim(&mut self, ty: ty::Ty<'tcx>, len: u64) { + fn array_shim(&mut self, ty: Ty<'tcx>, len: u64) { let tcx = self.tcx; let span = self.span; let rcvr = Lvalue::Local(Local::new(1+0)).deref(); @@ -613,7 +613,7 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> { self.block(vec![], TerminatorKind::Resume, true); } - fn tuple_shim(&mut self, tys: &ty::Slice>) { + fn tuple_shim(&mut self, tys: &ty::Slice>) { let rcvr = Lvalue::Local(Local::new(1+0)).deref(); let mut returns = Vec::new(); diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs index 3bf709ff7ba9d..f0d8c7e9bfbca 100644 --- a/src/librustc_trans/collector.rs +++ b/src/librustc_trans/collector.rs @@ -197,7 +197,7 @@ use rustc::middle::const_val::ConstVal; use rustc::middle::lang_items::{ExchangeMallocFnLangItem}; use rustc::traits; use rustc::ty::subst::Substs; -use rustc::ty::{self, TypeFoldable, TyCtxt}; +use rustc::ty::{self, TypeFoldable, Ty, TyCtxt}; use rustc::ty::adjustment::CustomCoerceUnsized; use rustc::mir::{self, Location}; use rustc::mir::visit::Visitor as MirVisitor; @@ -648,7 +648,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { } fn visit_drop_use<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, - ty: ty::Ty<'tcx>, + ty: Ty<'tcx>, is_direct_call: bool, output: &mut Vec>) { @@ -657,7 +657,7 @@ fn visit_drop_use<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, } fn visit_fn_use<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, - ty: ty::Ty<'tcx>, + ty: Ty<'tcx>, is_direct_call: bool, output: &mut Vec>) { @@ -776,10 +776,10 @@ fn should_trans_locally<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: &Instan /// Finally, there is also the case of custom unsizing coercions, e.g. for /// smart pointers such as `Rc` and `Arc`. fn find_vtable_types_for_unsizing<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, - source_ty: ty::Ty<'tcx>, - target_ty: ty::Ty<'tcx>) - -> (ty::Ty<'tcx>, ty::Ty<'tcx>) { - let ptr_vtable = |inner_source: ty::Ty<'tcx>, inner_target: ty::Ty<'tcx>| { + source_ty: Ty<'tcx>, + target_ty: Ty<'tcx>) + -> (Ty<'tcx>, Ty<'tcx>) { + let ptr_vtable = |inner_source: Ty<'tcx>, inner_target: Ty<'tcx>| { if !scx.type_is_sized(inner_source) { (inner_source, inner_target) } else { @@ -836,8 +836,8 @@ fn create_fn_trans_item<'a, 'tcx>(instance: Instance<'tcx>) -> TransItem<'tcx> { /// Creates a `TransItem` for each method that is referenced by the vtable for /// the given trait/impl pair. fn create_trans_items_for_vtable_methods<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, - trait_ty: ty::Ty<'tcx>, - impl_ty: ty::Ty<'tcx>, + trait_ty: Ty<'tcx>, + impl_ty: Ty<'tcx>, output: &mut Vec>) { assert!(!trait_ty.needs_subst() && !trait_ty.has_escaping_regions() && !impl_ty.needs_subst() && !impl_ty.has_escaping_regions()); diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index 77bddc7731b5b..4211be362ef19 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -104,7 +104,7 @@ pub struct LocalCrateContext<'a, 'tcx: 'a> { /// Cache instances of monomorphic and polymorphic items instances: RefCell, ValueRef>>, /// Cache generated vtables - vtables: RefCell, + vtables: RefCell, Option>), ValueRef>>, /// Cache of constant strings, const_cstr_cache: RefCell>, @@ -512,7 +512,7 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> { } pub fn vtables<'a>(&'a self) - -> &'a RefCell, + -> &'a RefCell, Option>), ValueRef>> { &self.local().vtables } diff --git a/src/librustc_trans/declare.rs b/src/librustc_trans/declare.rs index 8f9146283effe..3c8ff45499780 100644 --- a/src/librustc_trans/declare.rs +++ b/src/librustc_trans/declare.rs @@ -22,7 +22,7 @@ use llvm::{self, ValueRef}; use llvm::AttributePlace::Function; -use rustc::ty; +use rustc::ty::Ty; use rustc::session::config::Sanitizer; use abi::{Abi, FnType}; use attributes; @@ -119,7 +119,7 @@ pub fn declare_cfn(ccx: &CrateContext, name: &str, fn_type: Type) -> ValueRef { /// If there’s a value with the same name already declared, the function will /// update the declaration and return existing ValueRef instead. pub fn declare_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, name: &str, - fn_type: ty::Ty<'tcx>) -> ValueRef { + fn_type: Ty<'tcx>) -> ValueRef { debug!("declare_rust_fn(name={:?}, fn_type={:?})", name, fn_type); let sig = common::ty_fn_sig(ccx, fn_type); let sig = ccx.tcx().erase_late_bound_regions_and_normalize(&sig); @@ -164,7 +164,7 @@ pub fn define_global(ccx: &CrateContext, name: &str, ty: Type) -> Option(ccx: &CrateContext<'a, 'tcx>, name: &str, - fn_type: ty::Ty<'tcx>) -> ValueRef { + fn_type: Ty<'tcx>) -> ValueRef { if get_defined_value(ccx, name).is_some() { ccx.sess().fatal(&format!("symbol `{}` already defined", name)) } else { @@ -179,7 +179,7 @@ pub fn define_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, /// can happen with #[no_mangle] or #[export_name], for example. pub fn define_internal_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, name: &str, - fn_type: ty::Ty<'tcx>) -> ValueRef { + fn_type: Ty<'tcx>) -> ValueRef { let llfn = define_fn(ccx, name, fn_type); unsafe { llvm::LLVMRustSetLinkage(llfn, llvm::Linkage::InternalLinkage) }; llfn diff --git a/src/librustc_trans/meth.rs b/src/librustc_trans/meth.rs index 6eedd53974e70..9abfbb3279ce0 100644 --- a/src/librustc_trans/meth.rs +++ b/src/librustc_trans/meth.rs @@ -18,7 +18,7 @@ use machine; use monomorphize; use type_::Type; use value::Value; -use rustc::ty; +use rustc::ty::{self, Ty}; #[derive(Copy, Clone, Debug)] pub struct VirtualIndex(usize); @@ -63,7 +63,7 @@ impl<'a, 'tcx> VirtualIndex { /// making an object `Foo` from a value of type `Foo`, then /// `trait_ref` would map `T:Trait`. pub fn get_vtable<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, - ty: ty::Ty<'tcx>, + ty: Ty<'tcx>, trait_ref: Option>) -> ValueRef { diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs index 3e802c8be5bf4..1105da436189f 100644 --- a/src/librustc_trans/mir/block.rs +++ b/src/librustc_trans/mir/block.rs @@ -11,7 +11,7 @@ use llvm::{self, ValueRef, BasicBlockRef}; use rustc::middle::lang_items; use rustc::middle::const_val::{ConstEvalErr, ConstInt, ErrKind}; -use rustc::ty::{self, TypeFoldable}; +use rustc::ty::{self, Ty, TypeFoldable}; use rustc::ty::layout::{self, LayoutTyper}; use rustc::mir; use abi::{Abi, FnType, ArgType}; @@ -119,7 +119,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { fn_ty: FnType<'tcx>, fn_ptr: ValueRef, llargs: &[ValueRef], - destination: Option<(ReturnDest, ty::Ty<'tcx>, mir::BasicBlock)>, + destination: Option<(ReturnDest, Ty<'tcx>, mir::BasicBlock)>, cleanup: Option | { if let Some(cleanup) = cleanup { diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index 9bee26a52c0d7..610d07efa359d 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -268,7 +268,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'a, 'tcx>( /// pub fn check_safety_of_destructor_if_necessary<'a, 'gcx, 'tcx>( rcx: &mut RegionCtxt<'a, 'gcx, 'tcx>, - ty: ty::Ty<'tcx>, + ty: Ty<'tcx>, span: Span, scope: region::Scope) -> Result<(), ErrorReported> diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index fa8d3b9bcc1cb..3861a358b23e0 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -423,8 +423,8 @@ fn match_intrinsic_type_to_type<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, position: &str, span: Span, - structural_to_nominal: &mut FxHashMap<&'a intrinsics::Type, ty::Ty<'tcx>>, - expected: &'a intrinsics::Type, t: ty::Ty<'tcx>) + structural_to_nominal: &mut FxHashMap<&'a intrinsics::Type, Ty<'tcx>>, + expected: &'a intrinsics::Type, t: Ty<'tcx>) { use intrinsics::Type::*; diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index 31ceed5b965bf..0afc482cb79db 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -15,7 +15,7 @@ use hir::def::Def; use hir::def_id::DefId; use rustc::ty::subst::Substs; use rustc::traits; -use rustc::ty::{self, ToPredicate, ToPolyTraitRef, TraitRef, TypeFoldable}; +use rustc::ty::{self, Ty, ToPredicate, ToPolyTraitRef, TraitRef, TypeFoldable}; use rustc::ty::subst::Subst; use rustc::infer::{self, InferOk}; @@ -102,7 +102,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { pub fn method_exists(&self, span: Span, method_name: ast::Name, - self_ty: ty::Ty<'tcx>, + self_ty: Ty<'tcx>, call_expr_id: ast::NodeId, allow_private: bool) -> bool { @@ -136,7 +136,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { /// * `supplied_method_types`: the explicit method type parameters, if any (`T1..Tn`) /// * `self_expr`: the self expression (`foo`) pub fn lookup_method(&self, - self_ty: ty::Ty<'tcx>, + self_ty: Ty<'tcx>, segment: &hir::PathSegment, span: Span, call_expr: &'gcx hir::Expr, @@ -206,7 +206,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { fn lookup_probe(&self, span: Span, method_name: ast::Name, - self_ty: ty::Ty<'tcx>, + self_ty: Ty<'tcx>, call_expr: &'gcx hir::Expr, scope: ProbeScope) -> probe::PickResult<'tcx> { @@ -229,8 +229,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { span: Span, m_name: ast::Name, trait_def_id: DefId, - self_ty: ty::Ty<'tcx>, - opt_input_types: Option<&[ty::Ty<'tcx>]>) + self_ty: Ty<'tcx>, + opt_input_types: Option<&[Ty<'tcx>]>) -> Option>> { debug!("lookup_in_trait_adjusted(self_ty={:?}, \ m_name={}, trait_def_id={:?})", @@ -347,7 +347,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { pub fn resolve_ufcs(&self, span: Span, method_name: ast::Name, - self_ty: ty::Ty<'tcx>, + self_ty: Ty<'tcx>, expr_id: ast::NodeId) -> Result> { let mode = probe::Mode::Path; diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 9c19aef5992e6..f17df8b22f393 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -449,7 +449,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { fcx: &FnCtxt<'fcx, 'gcx, 'tcx>, method_sig: &hir::MethodSig, method: &ty::AssociatedItem, - self_ty: ty::Ty<'tcx>) + self_ty: Ty<'tcx>) { // check that the type of the method's receiver matches the // method's first parameter. diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 1735ec7cc698c..b0f3ff3ef35bf 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1580,7 +1580,7 @@ pub enum SizedByDefault { Yes, No, } /// a region) to ty's notion of ty param bounds, which can either be user-defined traits, or the /// built-in trait (formerly known as kind): Send. pub fn compute_bounds<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>, - param_ty: ty::Ty<'tcx>, + param_ty: Ty<'tcx>, ast_bounds: &[hir::TyParamBound], sized_by_default: SizedByDefault, span: Span) @@ -1673,7 +1673,7 @@ fn compute_sig_of_foreign_fn_decl<'a, 'tcx>( // ABIs are handled at all correctly. if abi != abi::Abi::RustIntrinsic && abi != abi::Abi::PlatformIntrinsic && !tcx.sess.features.borrow().simd_ffi { - let check = |ast_ty: &hir::Ty, ty: ty::Ty| { + let check = |ast_ty: &hir::Ty, ty: Ty| { if ty.is_simd() { tcx.sess.struct_span_err(ast_ty.span, &format!("use of SIMD type `{}` in FFI is highly experimental and \ diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index ce3bf896256ec..658b42da95350 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -35,7 +35,7 @@ use rustc::hir::def::{Def, CtorKind}; use rustc::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc::traits::Reveal; use rustc::ty::subst::Substs; -use rustc::ty::{self, AdtKind}; +use rustc::ty::{self, Ty, AdtKind}; use rustc::middle::stability; use rustc::util::nodemap::{FxHashMap, FxHashSet}; use rustc_typeck::hir_ty_to_ty; @@ -978,7 +978,7 @@ impl<'tcx> Clean for ty::OutlivesPredicate, ty: } } -impl<'tcx> Clean for ty::OutlivesPredicate, ty::Region<'tcx>> { +impl<'tcx> Clean for ty::OutlivesPredicate, ty::Region<'tcx>> { fn clean(&self, cx: &DocContext) -> WherePredicate { let ty::OutlivesPredicate(ref ty, ref lt) = *self; @@ -1895,7 +1895,7 @@ impl Clean for hir::Ty { } } -impl<'tcx> Clean for ty::Ty<'tcx> { +impl<'tcx> Clean for Ty<'tcx> { fn clean(&self, cx: &DocContext) -> Type { match self.sty { ty::TyNever => Never, From a7817dd52cb3f830504cdf702f726a0c0b7685dd Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 14 Sep 2017 21:28:55 -0700 Subject: [PATCH 27/40] rustc: Preallocate when building the dep graph This commit alters the `query` function in the dep graph module to preallocate memory using `with_capacity` instead of relying on automatic growth. Discovered in #44576 it was found that for the syntex_syntax clean incremental benchmark the peak memory usage was found when the dep graph was being saved, particularly the `DepGraphQuery` data structure itself. PRs like #44142 which add more queries end up just making this much larger! I didn't see an immediately obvious way to reduce the size of the `DepGraphQuery` object, but it turns out that `with_capacity` helps quite a bit! Locally 831 MB was used [before] this commit, and 770 MB is in use at the peak of the compiler [after] this commit. That's a nice 7.5% improvement! This won't quite make up for the losses in #44142 but I figured it's a good start. [before]: https://gist.github.com/alexcrichton/2d2b9c7a65503761925c5a0bcfeb0d1e [before]: https://gist.github.com/alexcrichton/6da51f2a6184bfb81694cc44f06deb5b --- src/librustc/dep_graph/query.rs | 5 ++--- src/librustc_data_structures/graph/mod.rs | 7 +++++++ src/librustc_data_structures/snapshot_vec.rs | 7 +++++++ 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/librustc/dep_graph/query.rs b/src/librustc/dep_graph/query.rs index 283da1050aedc..ea83a4f8b3104 100644 --- a/src/librustc/dep_graph/query.rs +++ b/src/librustc/dep_graph/query.rs @@ -22,11 +22,10 @@ impl DepGraphQuery { pub fn new(nodes: &[DepNode], edges: &[(DepNode, DepNode)]) -> DepGraphQuery { - let mut graph = Graph::new(); + let mut graph = Graph::with_capacity(nodes.len(), edges.len()); let mut indices = FxHashMap(); for node in nodes { - indices.insert(node.clone(), graph.next_node_index()); - graph.add_node(node.clone()); + indices.insert(node.clone(), graph.add_node(node.clone())); } for &(ref source, ref target) in edges { diff --git a/src/librustc_data_structures/graph/mod.rs b/src/librustc_data_structures/graph/mod.rs index a5f83ce05f5e5..474622f366913 100644 --- a/src/librustc_data_structures/graph/mod.rs +++ b/src/librustc_data_structures/graph/mod.rs @@ -114,6 +114,13 @@ impl Graph { } } + pub fn with_capacity(nodes: usize, edges: usize) -> Graph { + Graph { + nodes: SnapshotVec::with_capacity(nodes), + edges: SnapshotVec::with_capacity(edges), + } + } + // # Simple accessors #[inline] diff --git a/src/librustc_data_structures/snapshot_vec.rs b/src/librustc_data_structures/snapshot_vec.rs index dac074ab91e1b..2da91918288ba 100644 --- a/src/librustc_data_structures/snapshot_vec.rs +++ b/src/librustc_data_structures/snapshot_vec.rs @@ -66,6 +66,13 @@ impl SnapshotVec { } } + pub fn with_capacity(n: usize) -> SnapshotVec { + SnapshotVec { + values: Vec::with_capacity(n), + undo_log: Vec::new(), + } + } + fn in_snapshot(&self) -> bool { !self.undo_log.is_empty() } From 07494ecf78b3d21e8d67fd3a1a33466e63cae05d Mon Sep 17 00:00:00 2001 From: Makoto Kato Date: Fri, 15 Sep 2017 14:42:03 +0900 Subject: [PATCH 28/40] Require +thumb-mode to generate thumb2 code for Android/armv7-a --- src/librustc_back/target/armv7_linux_androideabi.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_back/target/armv7_linux_androideabi.rs b/src/librustc_back/target/armv7_linux_androideabi.rs index b49b1d1c2138a..45654b0f87020 100644 --- a/src/librustc_back/target/armv7_linux_androideabi.rs +++ b/src/librustc_back/target/armv7_linux_androideabi.rs @@ -16,7 +16,7 @@ use target::{Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { let mut base = super::android_base::opts(); - base.features = "+v7,+thumb2,+vfp3,+d16,-neon".to_string(); + base.features = "+v7,+thumb-mode,+thumb2,+vfp3,+d16,-neon".to_string(); base.max_atomic_width = Some(64); base.pre_link_args .get_mut(&LinkerFlavor::Gcc).unwrap().push("-march=armv7-a".to_string()); From 1b571a0cfcf666c1365c51a2a78be7becf0ce5ba Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Fri, 15 Sep 2017 10:36:14 +0200 Subject: [PATCH 29/40] Get `allow(unused_mut)` to work on `let` bindings fixes #40491 --- src/librustc_lint/unused.rs | 16 ++++------------ .../compile-fail/lint-unused-mut-variables.rs | 8 ++++++++ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 91646ce9f8b96..439cc3a4b844e 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -85,20 +85,12 @@ impl LintPass for UnusedMut { } impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedMut { - fn check_expr(&mut self, cx: &LateContext, e: &hir::Expr) { - if let hir::ExprMatch(_, ref arms, _) = e.node { - for a in arms { - self.check_unused_mut_pat(cx, &a.pats) - } - } + fn check_arm(&mut self, cx: &LateContext, a: &hir::Arm) { + self.check_unused_mut_pat(cx, &a.pats) } - fn check_stmt(&mut self, cx: &LateContext, s: &hir::Stmt) { - if let hir::StmtDecl(ref d, _) = s.node { - if let hir::DeclLocal(ref l) = d.node { - self.check_unused_mut_pat(cx, slice::ref_slice(&l.pat)); - } - } + fn check_local(&mut self, cx: &LateContext, l: &hir::Local) { + self.check_unused_mut_pat(cx, slice::ref_slice(&l.pat)); } fn check_fn(&mut self, diff --git a/src/test/compile-fail/lint-unused-mut-variables.rs b/src/test/compile-fail/lint-unused-mut-variables.rs index 26d00755da33b..3c76740d2b5dd 100644 --- a/src/test/compile-fail/lint-unused-mut-variables.rs +++ b/src/test/compile-fail/lint-unused-mut-variables.rs @@ -110,3 +110,11 @@ fn foo(mut a: isize) { let mut a = 3; let mut b = vec![2]; } + +// make sure the lint attribute can be turned off on let statements +#[deny(unused_mut)] +fn bar() { + #[allow(unused_mut)] + let mut a = 3; + let mut b = vec![2]; //~ ERROR: variable does not need to be mutable +} From 5398e03704a54e62f06b1f1498d89041c9cc4e25 Mon Sep 17 00:00:00 2001 From: Michal Budzynski Date: Fri, 15 Sep 2017 12:54:03 +0200 Subject: [PATCH 30/40] stabilized ord_max_min (fixes #25663) --- src/libcore/cmp.rs | 8 ++------ src/libcore/tests/lib.rs | 1 - 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index ec6525485f7a1..6f86f8caad073 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -453,12 +453,10 @@ pub trait Ord: Eq + PartialOrd { /// # Examples /// /// ``` - /// #![feature(ord_max_min)] - /// /// assert_eq!(2, 1.max(2)); /// assert_eq!(2, 2.max(2)); /// ``` - #[unstable(feature = "ord_max_min", issue = "25663")] + #[stable(feature = "ord_max_min", since = "1.22.0")] fn max(self, other: Self) -> Self where Self: Sized { if other >= self { other } else { self } @@ -471,12 +469,10 @@ pub trait Ord: Eq + PartialOrd { /// # Examples /// /// ``` - /// #![feature(ord_max_min)] - /// /// assert_eq!(1, 1.min(2)); /// assert_eq!(2, 2.min(2)); /// ``` - #[unstable(feature = "ord_max_min", issue = "25663")] + #[stable(feature = "ord_max_min", since = "1.22.0")] fn min(self, other: Self) -> Self where Self: Sized { if self <= other { self } else { other } diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index ab2022b1824ca..1ba9d78f9de89 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -27,7 +27,6 @@ #![feature(inclusive_range_syntax)] #![feature(iter_rfind)] #![feature(nonzero)] -#![feature(ord_max_min)] #![feature(rand)] #![feature(raw)] #![feature(refcell_replace_swap)] From 2819122b44fc7b6069fc09cf7ea6b710019eed72 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 15 Sep 2017 07:18:21 -0700 Subject: [PATCH 31/40] Update cargo submodule Just a routine update --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargo b/src/tools/cargo index 33250c48b4763..8118b02ac5ce4 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 33250c48b4763b01478d780e76206484a1d5b207 +Subproject commit 8118b02ac5ce49b22e049ff03316d5e1574852cf From 9a01dc43fffa34c4c814e3161f5e8246b01c597c Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 15 Sep 2017 16:29:21 +0200 Subject: [PATCH 32/40] update rust-installer --- src/tools/rust-installer | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-installer b/src/tools/rust-installer index adea17e1b2223..0ddd53c4bc2a7 160000 --- a/src/tools/rust-installer +++ b/src/tools/rust-installer @@ -1 +1 @@ -Subproject commit adea17e1b22231a9036a619264b72565e3a3962f +Subproject commit 0ddd53c4bc2a76df565a1c1fc0cc6f19f254b51e From 8772227758ca08f77ff7d1a886b26a3170244d1d Mon Sep 17 00:00:00 2001 From: Michal Budzynski Date: Fri, 15 Sep 2017 17:06:49 +0200 Subject: [PATCH 33/40] stabilized iterator_for_each (closes #42986) updated clippy and rls as it uses the iterator_for_each --- src/Cargo.lock | 6 +++--- .../src/library-features/iterator-for-each.md | 17 ----------------- src/libcore/iter/iterator.rs | 6 +----- src/tools/rls | 2 +- 4 files changed, 5 insertions(+), 26 deletions(-) delete mode 100644 src/doc/unstable-book/src/library-features/iterator-for-each.md diff --git a/src/Cargo.lock b/src/Cargo.lock index 1bbe8ca7575f1..22a546f75d71b 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -1334,7 +1334,7 @@ dependencies = [ "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "racer 2.0.10 (registry+https://github.com/rust-lang/crates.io-index)", - "rls-analysis 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rls-analysis 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", "rls-data 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "rls-rustc 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1348,7 +1348,7 @@ dependencies = [ [[package]] name = "rls-analysis" -version = "0.6.5" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "derive-new 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2542,7 +2542,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1731164734096285ec2a5ec7fea5248ae2f5485b3feeb0115af4fda2183b2d1b" "checksum regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f9ec002c35e86791825ed294b50008eea9ddfc8def4420124fbc6b08db834957" "checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db" -"checksum rls-analysis 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d2cb40c0371765897ae428b5706bb17135705ad4f6d1b8b6afbaabcf8c9b5cff" +"checksum rls-analysis 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "4302cc8291570d7f817945845d8c01756e833dbc93c0a87d4f6c9a0b0b7992f1" "checksum rls-data 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "11d339f1888e33e74d8032de0f83c40b2bdaaaf04a8cfc03b32186c3481fb534" "checksum rls-rustc 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b21ea952e9bf1569929abf1bb920262cde04b7b1b26d8e0260286302807299d2" "checksum rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d7c7046dc6a92f2ae02ed302746db4382e75131b9ce20ce967259f6b5867a6a" diff --git a/src/doc/unstable-book/src/library-features/iterator-for-each.md b/src/doc/unstable-book/src/library-features/iterator-for-each.md deleted file mode 100644 index ebeb5f6a1de51..0000000000000 --- a/src/doc/unstable-book/src/library-features/iterator-for-each.md +++ /dev/null @@ -1,17 +0,0 @@ -# `iterator_for_each` - -The tracking issue for this feature is: [#42986] - -[#42986]: https://github.com/rust-lang/rust/issues/42986 - ------------------------- - -To call a closure on each element of an iterator, you can use `for_each`: - -```rust -#![feature(iterator_for_each)] - -fn main() { - (0..10).for_each(|i| println!("{}", i)); -} -``` diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 7c009114afefb..edafd0ce2c227 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -498,8 +498,6 @@ pub trait Iterator { /// Basic usage: /// /// ``` - /// #![feature(iterator_for_each)] - /// /// use std::sync::mpsc::channel; /// /// let (tx, rx) = channel(); @@ -514,15 +512,13 @@ pub trait Iterator { /// might be preferable to keep a functional style with longer iterators: /// /// ``` - /// #![feature(iterator_for_each)] - /// /// (0..5).flat_map(|x| x * 100 .. x * 110) /// .enumerate() /// .filter(|&(i, x)| (i + x) % 3 == 0) /// .for_each(|(i, x)| println!("{}:{}", i, x)); /// ``` #[inline] - #[unstable(feature = "iterator_for_each", issue = "42986")] + #[stable(feature = "iterator_for_each", since = "1.22.0")] fn for_each(self, mut f: F) where Self: Sized, F: FnMut(Self::Item), { diff --git a/src/tools/rls b/src/tools/rls index 8dd70945fb049..7221e38023c41 160000 --- a/src/tools/rls +++ b/src/tools/rls @@ -1 +1 @@ -Subproject commit 8dd70945fb049df3f9dc7685cdc58d94e05e8ffc +Subproject commit 7221e38023c41ff2532ebbf54a7da296fd488b50 From 61e255a5345751d64e6d2e784d0abc4c2c255715 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 15 Sep 2017 09:34:17 -0700 Subject: [PATCH 34/40] rustbuild: Compile the error-index in stage 2 Right now we comiple rustdoc in stage 2 and the error index in stage 0, which ends up compiling rustdoc twice! To avoid compiling rustdoc twice (which takes awhile) let's just compile it once in stage 2. --- src/bootstrap/tool.rs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index eaa2b1244236f..9b861ae429d37 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -148,15 +148,27 @@ macro_rules! tool { impl<'a> Builder<'a> { pub fn tool_exe(&self, tool: Tool) -> PathBuf { + let stage = self.tool_default_stage(tool); match tool { $(Tool::$name => self.ensure($name { - compiler: self.compiler(0, self.build.build), + compiler: self.compiler(stage, self.build.build), target: self.build.build, }), )+ } } + + pub fn tool_default_stage(&self, tool: Tool) -> u32 { + // Compile the error-index in the top stage as it depends on + // rustdoc, so we want to avoid recompiling rustdoc twice if we + // can. Otherwise compile everything else in stage0 as there's + // no need to rebootstrap everything + match tool { + Tool::ErrorIndex => self.top_stage, + _ => 0, + } + } } $( @@ -436,7 +448,7 @@ impl<'a> Builder<'a> { /// `host`. pub fn tool_cmd(&self, tool: Tool) -> Command { let mut cmd = Command::new(self.tool_exe(tool)); - let compiler = self.compiler(0, self.build.build); + let compiler = self.compiler(self.tool_default_stage(tool), self.build.build); self.prepare_tool_cmd(compiler, &mut cmd); cmd } From 6fdadaaa96908e98c3265cc35af17da1aff1c25f Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 15 Sep 2017 09:37:52 -0700 Subject: [PATCH 35/40] rustbuild: Update `cmake` dependency Should help suppress some warnings from various repos as `cmake` in the newest version disables warnings by default. --- src/Cargo.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index 79822675364cf..69e8595a1414a 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -135,7 +135,7 @@ name = "bootstrap" version = "0.0.0" dependencies = [ "build_helper 0.1.0", - "cmake 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", + "cmake 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "gcc 0.3.53 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", @@ -267,7 +267,7 @@ dependencies = [ [[package]] name = "cmake" -version = "0.1.24" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "gcc 0.3.53 (registry+https://github.com/rust-lang/crates.io-index)", @@ -840,7 +840,7 @@ name = "libgit2-sys" version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cmake 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", + "cmake 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "curl-sys 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "gcc 0.3.53 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.30 (registry+https://github.com/rust-lang/crates.io-index)", @@ -855,7 +855,7 @@ name = "libssh2-sys" version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cmake 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", + "cmake 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.30 (registry+https://github.com/rust-lang/crates.io-index)", "libz-sys 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-sys 0.9.17 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1476,7 +1476,7 @@ dependencies = [ "alloc 0.0.0", "alloc_system 0.0.0", "build_helper 0.1.0", - "cmake 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", + "cmake 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -1622,7 +1622,7 @@ dependencies = [ "alloc 0.0.0", "alloc_system 0.0.0", "build_helper 0.1.0", - "cmake 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", + "cmake 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -1667,7 +1667,7 @@ dependencies = [ "alloc 0.0.0", "alloc_system 0.0.0", "build_helper 0.1.0", - "cmake 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", + "cmake 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -1779,7 +1779,7 @@ dependencies = [ "alloc 0.0.0", "alloc_system 0.0.0", "build_helper 0.1.0", - "cmake 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", + "cmake 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -2455,7 +2455,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum bufstream 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f382711e76b9de6c744cc00d0497baba02fb00a787f088c879f01d09468e32" "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" "checksum clap 2.26.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2267a8fdd4dce6956ba6649e130f62fb279026e5e84b92aa939ac8f85ce3f9f0" -"checksum cmake 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)" = "b8ebbb35d3dc9cd09497168f33de1acb79b265d350ab0ac34133b98f8509af1f" +"checksum cmake 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)" = "0c8a6541a55bcd72d3de4faee2d101a5a66df29790282c7f797082a7228a9b3d" "checksum conv 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "78ff10625fd0ac447827aa30ea8b861fead473bb60aeb73af6c1c58caf0d1299" "checksum core-foundation 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5909502e547762013619f4c4e01cc7393c20fe2d52d7fa471c1210adb2320dc7" "checksum core-foundation-sys 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bc9fb3d6cb663e6fd7cf1c63f9b144ee2b1e4a78595a0451dd34bff85b9a3387" From 3a39d95330623d47bcfcd5cac2d6b3c30e12ae5a Mon Sep 17 00:00:00 2001 From: Ulrik Sverdrup Date: Fri, 15 Sep 2017 19:16:22 +0200 Subject: [PATCH 36/40] alloc: Add tracking issue for rc_downcast --- src/liballoc/rc.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 814be059da7c0..58c589697f41c 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -611,7 +611,7 @@ impl Rc { impl Rc { #[inline] - #[unstable(feature = "rc_downcast", issue = "0")] + #[unstable(feature = "rc_downcast", issue = "44608")] /// Attempt to downcast the `Rc` to a concrete type. /// /// # Examples From 351f56a6034486c38c3b36bfbbd15a81a39ba9aa Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 15 Sep 2017 10:30:56 -0700 Subject: [PATCH 37/40] Add a specific test for `FlatMap::fold` --- src/libcore/tests/iter.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index ed6923929d6b0..59ae30de452c9 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -654,6 +654,22 @@ fn test_iterator_flat_map() { assert_eq!(i, ys.len()); } +/// Test `FlatMap::fold` with items already picked off the front and back, +/// to make sure all parts of the `FlatMap` are folded correctly. +#[test] +fn test_iterator_flat_map_fold() { + let xs = [0, 3, 6]; + let ys = [1, 2, 3, 4, 5, 6, 7]; + let mut it = xs.iter().flat_map(|&x| x..x+3); + it.next(); + it.next_back(); + let i = it.fold(0, |i, x| { + assert_eq!(x, ys[i]); + i + 1 + }); + assert_eq!(i, ys.len()); +} + #[test] fn test_inspect() { let xs = [1, 2, 3, 4]; From f7e974e4322b53cdadddf2ca8c72eaf419d406f2 Mon Sep 17 00:00:00 2001 From: Jon Gjengset Date: Fri, 15 Sep 2017 13:32:45 -0400 Subject: [PATCH 38/40] HashMap::new and HashSet::new do not allocate --- src/libstd/collections/hash/map.rs | 3 +++ src/libstd/collections/hash/set.rs | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index fbb69ca974930..96af227257824 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -588,6 +588,9 @@ impl HashMap impl HashMap { /// Creates an empty `HashMap`. /// + /// The hash map is initially created with a capacity of 0, so it will not allocate until it + /// is first inserted into. + /// /// # Examples /// /// ``` diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index 9771363d545cd..51698ce7c17ca 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -125,6 +125,9 @@ pub struct HashSet { impl HashSet { /// Creates an empty `HashSet`. /// + /// The hash set is initially created with a capacity of 0, so it will not allocate until it + /// is first inserted into. + /// /// # Examples /// /// ``` From 97fee3e94b4943ec8430102bb53e751b8706d872 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 15 Sep 2017 10:34:05 -0700 Subject: [PATCH 39/40] travis: Disable LLVM assertions on OSX Our OSX builders are routinely and significantly over hour 2 hour "soft limit" for testing PRs. I *think* that a big portion of this time comes from the fact that LLVM and debug assertions are enabled. In an effort to speed up these builders and reduce cycle time this commit disables LLVM assertions on OSX for all builders. My thinking is that we'll let this bake for a bit after merged to see what the effect is on timing on Travis. If it doesn't actually help much we can turn them back on, and if it doesn't help enough we can disable Rust debug assertions as well. --- .travis.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.travis.yml b/.travis.yml index 23bae6d9f1721..39853e3585895 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,6 +28,7 @@ matrix: RUSTC_RETRY_LINKER_ON_SEGFAULT=1 SCCACHE_ERROR_LOG=/tmp/sccache.log MACOSX_DEPLOYMENT_TARGET=10.7 + NO_LLVM_ASSERTIONS=1 os: osx osx_image: xcode7 @@ -46,6 +47,7 @@ matrix: SCCACHE_ERROR_LOG=/tmp/sccache.log MACOSX_DEPLOYMENT_TARGET=10.8 MACOSX_STD_DEPLOYMENT_TARGET=10.7 + NO_LLVM_ASSERTIONS=1 os: osx osx_image: xcode8.2 - env: > @@ -56,6 +58,7 @@ matrix: SCCACHE_ERROR_LOG=/tmp/sccache.log MACOSX_DEPLOYMENT_TARGET=10.8 MACOSX_STD_DEPLOYMENT_TARGET=10.7 + NO_LLVM_ASSERTIONS=1 os: osx osx_image: xcode8.2 @@ -73,6 +76,7 @@ matrix: RUSTC_RETRY_LINKER_ON_SEGFAULT=1 SCCACHE_ERROR_LOG=/tmp/sccache.log MACOSX_DEPLOYMENT_TARGET=10.7 + NO_LLVM_ASSERTIONS=1 os: osx osx_image: xcode7 - env: > @@ -83,6 +87,7 @@ matrix: RUSTC_RETRY_LINKER_ON_SEGFAULT=1 SCCACHE_ERROR_LOG=/tmp/sccache.log MACOSX_DEPLOYMENT_TARGET=10.7 + NO_LLVM_ASSERTIONS=1 os: osx osx_image: xcode7 From 3da54fb03613b4fb65f3e43fd8e2d05bc7866c53 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 15 Sep 2017 15:28:59 -0700 Subject: [PATCH 40/40] rustbuild: Fix test "test rustdoc" invocation Previously it would use the librustc output directory which would cause rustdoc to get entirely recompiled, whereas the intention is that it uses the already-compiled artifacts from building rustdoc itself, using the tool output directory --- src/bootstrap/check.rs | 9 +++++---- src/bootstrap/tool.rs | 8 +++++--- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index 0d5c3addd9e74..5853d5ae3204e 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -1118,10 +1118,11 @@ impl Step for Rustdoc { let compiler = builder.compiler(builder.top_stage, self.host); let target = compiler.host; - builder.ensure(RemoteCopyLibs { compiler, target }); - - let mut cargo = builder.cargo(compiler, Mode::Librustc, target, test_kind.subcommand()); - compile::rustc_cargo(build, &compiler, target, &mut cargo); + let mut cargo = tool::prepare_tool_cargo(builder, + compiler, + target, + test_kind.subcommand(), + "src/tools/rustdoc"); let _folder = build.fold_output(|| { format!("{}_stage{}-rustdoc", test_kind.subcommand(), compiler.stage) }); diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index eaa2b1244236f..26ea89b68497c 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -94,20 +94,21 @@ impl Step for ToolBuild { let _folder = build.fold_output(|| format!("stage{}-{}", compiler.stage, tool)); println!("Building stage{} tool {} ({})", compiler.stage, tool, target); - let mut cargo = prepare_tool_cargo(builder, compiler, target, path); + let mut cargo = prepare_tool_cargo(builder, compiler, target, "build", path); build.run(&mut cargo); build.cargo_out(compiler, Mode::Tool, target).join(exe(tool, &compiler.host)) } } -fn prepare_tool_cargo( +pub fn prepare_tool_cargo( builder: &Builder, compiler: Compiler, target: Interned, + command: &'static str, path: &'static str, ) -> Command { let build = builder.build; - let mut cargo = builder.cargo(compiler, Mode::Tool, target, "build"); + let mut cargo = builder.cargo(compiler, Mode::Tool, target, command); let dir = build.src.join(path); cargo.arg("--manifest-path").arg(dir.join("Cargo.toml")); @@ -283,6 +284,7 @@ impl Step for Rustdoc { let mut cargo = prepare_tool_cargo(builder, build_compiler, target, + "build", "src/tools/rustdoc"); build.run(&mut cargo); // Cargo adds a number of paths to the dylib search path on windows, which results in