From 8478d48dad949b3b1374569a5391089a49094eeb Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 9 May 2016 19:45:12 -0400 Subject: Add some warnings to std::env::current_exe /cc #21889 --- src/libstd/env.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'src/libstd') diff --git a/src/libstd/env.rs b/src/libstd/env.rs index 9dc6a26cdee..369594e2b8f 100644 --- a/src/libstd/env.rs +++ b/src/libstd/env.rs @@ -493,6 +493,21 @@ pub fn temp_dir() -> PathBuf { /// that can fail for a good number of reasons. Some errors can include, but not /// be limited to, filesystem operations failing or general syscall failures. /// +/// # Security +/// +/// This function should be used with care, as its incorrect usage can cause +/// security problems. Specifically, as with many operations invovling files and +/// paths, you can introduce a race condition. It goes like this: +/// +/// 1. You get the path to the current executable using `current_exe()`, and +/// store it in a variable binding. +/// 2. Time passes. A malicious actor removes the current executable, and +/// replaces it with a malicious one. +/// 3. You then use the binding to try to open that file. +/// +/// You expected to be opening the current executable, but you're now opening +/// something completely different. +/// /// # Examples /// /// ``` -- cgit 1.4.1-3-g733a5 From e7d423a3bf599b8e235d25511e807e6bf981c020 Mon Sep 17 00:00:00 2001 From: Aaron Gallagher Date: Mon, 30 May 2016 19:10:16 -0700 Subject: Retry on EINTR in Bytes and Chars. Since Bytes and Chars called directly into Read::read, they didn't use any of the retrying wrappers. This allows both iterator types to retry. --- src/libstd/io/mod.rs | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) (limited to 'src/libstd') diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index a058337a50a..d5b255ee573 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -1522,6 +1522,18 @@ impl BufRead for Take { } } +fn read_one_byte(reader: &mut Read) -> Option> { + let mut buf = [0]; + loop { + return match reader.read(&mut buf) { + Ok(0) => None, + Ok(..) => Some(Ok(buf[0])), + Err(ref e) if e.kind() == ErrorKind::Interrupted => continue, + Err(e) => Some(Err(e)), + }; + } +} + /// An iterator over `u8` values of a reader. /// /// This struct is generally created by calling [`bytes()`][bytes] on a reader. @@ -1538,12 +1550,7 @@ impl Iterator for Bytes { type Item = Result; fn next(&mut self) -> Option> { - let mut buf = [0]; - match self.inner.read(&mut buf) { - Ok(0) => None, - Ok(..) => Some(Ok(buf[0])), - Err(e) => Some(Err(e)), - } + read_one_byte(&mut self.inner) } } @@ -1579,11 +1586,10 @@ impl Iterator for Chars { type Item = result::Result; fn next(&mut self) -> Option> { - let mut buf = [0]; - let first_byte = match self.inner.read(&mut buf) { - Ok(0) => return None, - Ok(..) => buf[0], - Err(e) => return Some(Err(CharsError::Other(e))), + let first_byte = match read_one_byte(&mut self.inner) { + None => return None, + Some(Ok(b)) => b, + Some(Err(e)) => return Some(Err(CharsError::Other(e))), }; let width = core_str::utf8_char_width(first_byte); if width == 1 { return Some(Ok(first_byte as char)) } @@ -1595,6 +1601,7 @@ impl Iterator for Chars { match self.inner.read(&mut buf[start..width]) { Ok(0) => return Some(Err(CharsError::NotUtf8)), Ok(n) => start += n, + Err(ref e) if e.kind() == ErrorKind::Interrupted => continue, Err(e) => return Some(Err(CharsError::Other(e))), } } -- cgit 1.4.1-3-g733a5 From b8141049da7507bdbf2b037847945e5bb299ccad Mon Sep 17 00:00:00 2001 From: Matt Horn Date: Wed, 6 Jul 2016 16:59:32 -0600 Subject: Add IpAddr common methods --- src/libstd/net/ip.rs | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) (limited to 'src/libstd') diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs index 57d75441bff..b9a57579b5c 100644 --- a/src/libstd/net/ip.rs +++ b/src/libstd/net/ip.rs @@ -59,6 +59,48 @@ pub enum Ipv6MulticastScope { Global } +impl IpAddr { + /// Returns true for the special 'unspecified' address (0.0.0.0 in IPv4, :: in IPv6). + pub fn is_unspecified(&self) -> bool { + match *self { + IpAddr::V4(ref a) => a.is_unspecified(), + IpAddr::V6(ref a) => a.is_unspecified(), + } + } + + /// Returns true if this is a loopback address (127.0.0.0/8 in IPv4, ::1 in IPv6). + pub fn is_loopback(&self) -> bool { + match *self { + IpAddr::V4(ref a) => a.is_loopback(), + IpAddr::V6(ref a) => a.is_loopback(), + } + } + + /// Returns true if the address appears to be globally routable. + pub fn is_global(&self) -> bool { + match *self { + IpAddr::V4(ref a) => a.is_global(), + IpAddr::V6(ref a) => a.is_global(), + } + } + + /// Returns true if this is a multicast address (224.0.0.0/4 in IPv4, ff00::/8 in IPv6) + pub fn is_multicast(&self) -> bool { + match *self { + IpAddr::V4(ref a) => a.is_multicast(), + IpAddr::V6(ref a) => a.is_multicast(), + } + } + + /// Returns true if this address is in a range designated for documentation. + pub fn is_documentation(&self) -> bool { + match *self { + IpAddr::V4(ref a) => a.is_documentation(), + IpAddr::V6(ref a) => a.is_documentation(), + } + } +} + impl Ipv4Addr { /// Creates a new IPv4 address from four eight-bit octets. /// @@ -756,6 +798,67 @@ mod tests { None); } + #[test] + fn ip_properties() { + fn check4(octets: &[u8; 4], unspec: bool, loopback: bool, + global: bool, multicast: bool, documentation: bool) { + let ip = IpAddr::V4(Ipv4Addr::new(octets[0], octets[1], octets[2], octets[3])); + assert_eq!(ip.is_unspecified(), unspec); + assert_eq!(ip.is_loopback(), loopback); + assert_eq!(ip.is_global(), global); + assert_eq!(ip.is_multicast(), multicast); + assert_eq!(ip.is_documentation(), documentation); + } + + fn check6(str_addr: &str, unspec: bool, loopback: bool, + global: bool, u_doc: bool, mcast: bool) { + let ip = IpAddr::V6(str_addr.parse().unwrap()); + assert_eq!(ip.is_unspecified(), unspec); + assert_eq!(ip.is_loopback(), loopback); + assert_eq!(ip.is_global(), global); + assert_eq!(ip.is_documentation(), u_doc); + assert_eq!(ip.is_multicast(), mcast); + } + + // address unspec loopbk global multicast doc + check4(&[0, 0, 0, 0], true, false, false, false, false); + check4(&[0, 0, 0, 1], false, false, true, false, false); + check4(&[0, 1, 0, 0], false, false, true, false, false); + check4(&[10, 9, 8, 7], false, false, false, false, false); + check4(&[127, 1, 2, 3], false, true, false, false, false); + check4(&[172, 31, 254, 253], false, false, false, false, false); + check4(&[169, 254, 253, 242], false, false, false, false, false); + check4(&[192, 0, 2, 183], false, false, false, false, true); + check4(&[192, 1, 2, 183], false, false, true, false, false); + check4(&[192, 168, 254, 253], false, false, false, false, false); + check4(&[198, 51, 100, 0], false, false, false, false, true); + check4(&[203, 0, 113, 0], false, false, false, false, true); + check4(&[203, 2, 113, 0], false, false, true, false, false); + check4(&[224, 0, 0, 0], false, false, true, true, false); + check4(&[239, 255, 255, 255], false, false, true, true, false); + check4(&[255, 255, 255, 255], false, false, false, false, false); + + // address unspec loopbk global doc mcast + check6("::", true, false, false, false, false); + check6("::1", false, true, false, false, false); + check6("::0.0.0.2", false, false, true, false, false); + check6("1::", false, false, true, false, false); + check6("fc00::", false, false, false, false, false); + check6("fdff:ffff::", false, false, false, false, false); + check6("fe80:ffff::", false, false, false, false, false); + check6("febf:ffff::", false, false, false, false, false); + check6("fec0::", false, false, false, false, false); + check6("ff01::", false, false, false, false, true); + check6("ff02::", false, false, false, false, true); + check6("ff03::", false, false, false, false, true); + check6("ff04::", false, false, false, false, true); + check6("ff05::", false, false, false, false, true); + check6("ff08::", false, false, false, false, true); + check6("ff0e::", false, false, true, false, true); + check6("2001:db8:85a3::8a2e:370:7334", false, false, false, true, false); + check6("102:304:506:708:90a:b0c:d0e:f10", false, false, true, false, false); + } + #[test] fn ipv4_properties() { fn check(octets: &[u8; 4], unspec: bool, loopback: bool, -- cgit 1.4.1-3-g733a5 From 211c655c97d35a511e27b30480e196ea04e4e13f Mon Sep 17 00:00:00 2001 From: Matt Horn Date: Wed, 6 Jul 2016 20:47:47 -0600 Subject: Mark new methods as unstable --- src/libstd/net/ip.rs | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/libstd') diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs index b9a57579b5c..6bbba7ffb20 100644 --- a/src/libstd/net/ip.rs +++ b/src/libstd/net/ip.rs @@ -61,6 +61,7 @@ pub enum Ipv6MulticastScope { impl IpAddr { /// Returns true for the special 'unspecified' address (0.0.0.0 in IPv4, :: in IPv6). + #[unstable(feature="ipaddr_common", reason="recently added and depends on unstable Ipv4Addr.is_unspecified()", issue="27709")] pub fn is_unspecified(&self) -> bool { match *self { IpAddr::V4(ref a) => a.is_unspecified(), @@ -69,6 +70,7 @@ impl IpAddr { } /// Returns true if this is a loopback address (127.0.0.0/8 in IPv4, ::1 in IPv6). + #[unstable(feature="ipaddr_common", reason="recently added", issue="27709")] pub fn is_loopback(&self) -> bool { match *self { IpAddr::V4(ref a) => a.is_loopback(), @@ -77,6 +79,7 @@ impl IpAddr { } /// Returns true if the address appears to be globally routable. + #[unstable(feature="ipaddr_common", reason="recently added and depends on unstable Ipv4Addr.is_global() and Ipv6Addr.is_global()", issue="27709")] pub fn is_global(&self) -> bool { match *self { IpAddr::V4(ref a) => a.is_global(), @@ -85,6 +88,7 @@ impl IpAddr { } /// Returns true if this is a multicast address (224.0.0.0/4 in IPv4, ff00::/8 in IPv6) + #[unstable(feature="ipaddr_common", reason="recently added", issue="27709")] pub fn is_multicast(&self) -> bool { match *self { IpAddr::V4(ref a) => a.is_multicast(), @@ -93,6 +97,7 @@ impl IpAddr { } /// Returns true if this address is in a range designated for documentation. + #[unstable(feature="ipaddr_common", reason="recently added and depends on unstable Ipv6Addr.is_documentation()", issue="27709")] pub fn is_documentation(&self) -> bool { match *self { IpAddr::V4(ref a) => a.is_documentation(), -- cgit 1.4.1-3-g733a5 From fee5b492fecd321b5ce507d732948943a74fbf4c Mon Sep 17 00:00:00 2001 From: Matt Horn Date: Wed, 6 Jul 2016 22:10:12 -0600 Subject: Properly mark new methods as unstable --- src/libstd/net/ip.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'src/libstd') diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs index 6bbba7ffb20..2bf063099e4 100644 --- a/src/libstd/net/ip.rs +++ b/src/libstd/net/ip.rs @@ -61,7 +61,8 @@ pub enum Ipv6MulticastScope { impl IpAddr { /// Returns true for the special 'unspecified' address (0.0.0.0 in IPv4, :: in IPv6). - #[unstable(feature="ipaddr_common", reason="recently added and depends on unstable Ipv4Addr.is_unspecified()", issue="27709")] + #[unstable(feature="ip", issue="27709", + reason="recently added and depends on unstable Ipv4Addr.is_unspecified()")] pub fn is_unspecified(&self) -> bool { match *self { IpAddr::V4(ref a) => a.is_unspecified(), @@ -70,7 +71,7 @@ impl IpAddr { } /// Returns true if this is a loopback address (127.0.0.0/8 in IPv4, ::1 in IPv6). - #[unstable(feature="ipaddr_common", reason="recently added", issue="27709")] + #[unstable(feature="ip", reason="recently added", issue="27709")] pub fn is_loopback(&self) -> bool { match *self { IpAddr::V4(ref a) => a.is_loopback(), @@ -79,7 +80,8 @@ impl IpAddr { } /// Returns true if the address appears to be globally routable. - #[unstable(feature="ipaddr_common", reason="recently added and depends on unstable Ipv4Addr.is_global() and Ipv6Addr.is_global()", issue="27709")] + #[unstable(feature="ip", issue="27709", + reason="recently added and depends on unstable Ip{v4,v6}Addr.is_global()")] pub fn is_global(&self) -> bool { match *self { IpAddr::V4(ref a) => a.is_global(), @@ -88,7 +90,7 @@ impl IpAddr { } /// Returns true if this is a multicast address (224.0.0.0/4 in IPv4, ff00::/8 in IPv6) - #[unstable(feature="ipaddr_common", reason="recently added", issue="27709")] + #[unstable(feature="ip", reason="recently added", issue="27709")] pub fn is_multicast(&self) -> bool { match *self { IpAddr::V4(ref a) => a.is_multicast(), @@ -97,7 +99,8 @@ impl IpAddr { } /// Returns true if this address is in a range designated for documentation. - #[unstable(feature="ipaddr_common", reason="recently added and depends on unstable Ipv6Addr.is_documentation()", issue="27709")] + #[unstable(feature="ip", issue="27709", + reason="recently added and depends on unstable Ipv6Addr.is_documentation()")] pub fn is_documentation(&self) -> bool { match *self { IpAddr::V4(ref a) => a.is_documentation(), -- cgit 1.4.1-3-g733a5 From 58da5dd51eebe700a2ac8cf4f0b10dec6d1b6ca9 Mon Sep 17 00:00:00 2001 From: Matt Horn Date: Thu, 7 Jul 2016 11:15:25 -0600 Subject: Add links to Ipv*Addr methods in docs per https://github.com/rust-lang/rust/pull/34694#issuecomment-231126489 --- src/libstd/net/ip.rs | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'src/libstd') diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs index 2bf063099e4..fddb237dd5f 100644 --- a/src/libstd/net/ip.rs +++ b/src/libstd/net/ip.rs @@ -60,7 +60,9 @@ pub enum Ipv6MulticastScope { } impl IpAddr { - /// Returns true for the special 'unspecified' address (0.0.0.0 in IPv4, :: in IPv6). + /// Returns true for the special 'unspecified' address ([IPv4], [IPv6]). + /// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_unspecified + /// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_unspecified #[unstable(feature="ip", issue="27709", reason="recently added and depends on unstable Ipv4Addr.is_unspecified()")] pub fn is_unspecified(&self) -> bool { @@ -70,7 +72,9 @@ impl IpAddr { } } - /// Returns true if this is a loopback address (127.0.0.0/8 in IPv4, ::1 in IPv6). + /// Returns true if this is a loopback address ([IPv4], [IPv6]). + /// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_loopback + /// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_loopback #[unstable(feature="ip", reason="recently added", issue="27709")] pub fn is_loopback(&self) -> bool { match *self { @@ -79,7 +83,9 @@ impl IpAddr { } } - /// Returns true if the address appears to be globally routable. + /// Returns true if the address appears to be globally routable ([IPv4], [IPv6]). + /// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_global + /// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_global #[unstable(feature="ip", issue="27709", reason="recently added and depends on unstable Ip{v4,v6}Addr.is_global()")] pub fn is_global(&self) -> bool { @@ -89,7 +95,9 @@ impl IpAddr { } } - /// Returns true if this is a multicast address (224.0.0.0/4 in IPv4, ff00::/8 in IPv6) + /// Returns true if this is a multicast address ([IPv4], [IPv6]). + /// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_multicast + /// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_multicast #[unstable(feature="ip", reason="recently added", issue="27709")] pub fn is_multicast(&self) -> bool { match *self { @@ -98,7 +106,9 @@ impl IpAddr { } } - /// Returns true if this address is in a range designated for documentation. + /// Returns true if this address is in a range designated for documentation ([IPv4], [IPv6]). + /// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_documentation + /// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_documentation #[unstable(feature="ip", issue="27709", reason="recently added and depends on unstable Ipv6Addr.is_documentation()")] pub fn is_documentation(&self) -> bool { -- cgit 1.4.1-3-g733a5 From 8aeb9303e954502f67f4af7c5c7e79f6d4f706eb Mon Sep 17 00:00:00 2001 From: mitchmindtree Date: Fri, 8 Jul 2016 22:12:36 +1000 Subject: add a non blocking iterator for the mpsc::Receiver Currently, the `mpsc::Receiver` offers methods for receiving values in both blocking (`recv`) and non-blocking (`try_recv`) flavours. However only blocking iteration over values is supported. This commit adds a non-blocking iterator to complement the `try_recv` method, just as the blocking iterator complements the `recv` method. --- src/libstd/sync/mpsc/mod.rs | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'src/libstd') diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs index 34bc210b3c8..30ce9c3f382 100644 --- a/src/libstd/sync/mpsc/mod.rs +++ b/src/libstd/sync/mpsc/mod.rs @@ -311,6 +311,16 @@ pub struct Iter<'a, T: 'a> { rx: &'a Receiver } +/// An iterator that attempts to yield all pending values for a receiver. +/// `None` will be returned when there are no pending values remaining or +/// if the corresponding channel has hung up. +/// +/// This Iterator will never block the caller in order to wait for data to +/// become available. Instead, it will return `None`. +pub struct TryIter<'a, T: 'a> { + rx: &'a Receiver +} + /// An owning iterator over messages on a receiver, this iterator will block /// whenever `next` is called, waiting for a new message, and `None` will be /// returned when the corresponding channel has hung up. @@ -982,6 +992,15 @@ impl Receiver { pub fn iter(&self) -> Iter { Iter { rx: self } } + + /// Returns an iterator that will attempt to yield all pending values. + /// It will return `None` if there are no more pending values or if the + /// channel has hung up. The iterator will never `panic!` or block the + /// user by waiting for values. + pub fn try_iter(&self) -> TryIter { + TryIter { rx: self } + } + } impl select::Packet for Receiver { @@ -1077,6 +1096,12 @@ impl<'a, T> Iterator for Iter<'a, T> { fn next(&mut self) -> Option { self.rx.recv().ok() } } +impl<'a, T> Iterator for TryIter<'a, T> { + type Item = T; + + fn next(&mut self) -> Option { self.rx.try_recv().ok() } +} + #[stable(feature = "receiver_into_iter", since = "1.1.0")] impl<'a, T> IntoIterator for &'a Receiver { type Item = T; -- cgit 1.4.1-3-g733a5 From b354887180b665441dd6e3ea51b2651085de88f9 Mon Sep 17 00:00:00 2001 From: mitchmindtree Date: Sat, 9 Jul 2016 00:21:26 +1000 Subject: Add a test for Receiver::try_iter --- src/libstd/sync/mpsc/mod.rs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'src/libstd') diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs index 30ce9c3f382..51a820b2e91 100644 --- a/src/libstd/sync/mpsc/mod.rs +++ b/src/libstd/sync/mpsc/mod.rs @@ -1839,6 +1839,34 @@ mod tests { assert_eq!(count_rx.recv().unwrap(), 4); } + #[test] + fn test_recv_try_iter() { + let (request_tx, request_rx) = channel(); + let (response_tx, response_rx) = channel(); + + // Request `x`s until we have `6`. + let t = thread::spawn(move|| { + let mut count = 0; + loop { + for x in response_rx.try_iter() { + count += x; + if count == 6 { + drop(response_rx); + drop(request_tx); + return count; + } + } + request_tx.send(()).unwrap(); + } + }); + + for _ in request_rx.iter() { + response_tx.send(2).unwrap(); + } + + assert_eq!(t.join().unwrap(), 6); + } + #[test] fn test_recv_into_iter_owned() { let mut iter = { -- cgit 1.4.1-3-g733a5 From b02b38e1c4f7c8075c92d41e9e08bf2a20982f66 Mon Sep 17 00:00:00 2001 From: mitchmindtree Date: Sat, 9 Jul 2016 00:35:08 +1000 Subject: Add the unstable attribute to the new mpsc::Receiver::try_iter API --- src/libstd/sync/mpsc/mod.rs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/libstd') diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs index 51a820b2e91..2d2bded9f60 100644 --- a/src/libstd/sync/mpsc/mod.rs +++ b/src/libstd/sync/mpsc/mod.rs @@ -317,6 +317,7 @@ pub struct Iter<'a, T: 'a> { /// /// This Iterator will never block the caller in order to wait for data to /// become available. Instead, it will return `None`. +#[unstable(feature = "receiver_try_iter")] pub struct TryIter<'a, T: 'a> { rx: &'a Receiver } @@ -997,6 +998,7 @@ impl Receiver { /// It will return `None` if there are no more pending values or if the /// channel has hung up. The iterator will never `panic!` or block the /// user by waiting for values. + #[unstable(feature = "receiver_try_iter")] pub fn try_iter(&self) -> TryIter { TryIter { rx: self } } @@ -1096,6 +1098,7 @@ impl<'a, T> Iterator for Iter<'a, T> { fn next(&mut self) -> Option { self.rx.recv().ok() } } +#[unstable(feature = "receiver_try_iter")] impl<'a, T> Iterator for TryIter<'a, T> { type Item = T; -- cgit 1.4.1-3-g733a5 From ce442b4f5195ff6af27ae3335c7bb372015c1407 Mon Sep 17 00:00:00 2001 From: ggomez Date: Wed, 20 Jul 2016 15:02:33 +0200 Subject: Add debug for hash_map::{Entry, VacantEntry, OccupiedEntry} --- src/libstd/collections/hash/map.rs | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'src/libstd') diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 60d7e01d988..a03249e0063 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -1351,6 +1351,20 @@ pub enum Entry<'a, K: 'a, V: 'a> { ), } +#[stable(feature= "debug_hash_map", since = "1.12.0")] +impl<'a, K: 'a + Debug, V: 'a + Debug> Debug for Entry<'a, K, V> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + Vacant(ref v) => f.debug_tuple("Entry") + .field(v) + .finish(), + Occupied(ref o) => f.debug_tuple("Entry") + .field(o) + .finish(), + } + } +} + /// A view into a single occupied location in a HashMap. #[stable(feature = "rust1", since = "1.0.0")] pub struct OccupiedEntry<'a, K: 'a, V: 'a> { @@ -1358,6 +1372,16 @@ pub struct OccupiedEntry<'a, K: 'a, V: 'a> { elem: FullBucket>, } +#[stable(feature= "debug_hash_map", since = "1.12.0")] +impl<'a, K: 'a + Debug, V: 'a + Debug> Debug for OccupiedEntry<'a, K, V> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("OccupiedEntry") + .field("key", self.key()) + .field("value", self.get()) + .finish() + } +} + /// A view into a single empty location in a HashMap. #[stable(feature = "rust1", since = "1.0.0")] pub struct VacantEntry<'a, K: 'a, V: 'a> { @@ -1366,6 +1390,15 @@ pub struct VacantEntry<'a, K: 'a, V: 'a> { elem: VacantEntryState>, } +#[stable(feature= "debug_hash_map", since = "1.12.0")] +impl<'a, K: 'a + Debug, V: 'a> Debug for VacantEntry<'a, K, V> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_tuple("VacantEntry") + .field(self.key()) + .finish() + } +} + /// Possible states of a VacantEntry. enum VacantEntryState { /// The index is occupied, but the key to insert has precedence, -- cgit 1.4.1-3-g733a5 From d820fcba122771742f8bdeed4c8619292f3450f6 Mon Sep 17 00:00:00 2001 From: Mark Buer Date: Mon, 18 Jul 2016 17:54:15 +0930 Subject: Remove rustdoc reference to `walk_dir` --- src/libstd/fs.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/libstd') diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index 83439b3f132..c28f70b8692 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -791,8 +791,8 @@ impl Iterator for ReadDir { impl DirEntry { /// Returns the full path to the file that this entry represents. /// - /// The full path is created by joining the original path to `read_dir` or - /// `walk_dir` with the filename of this entry. + /// The full path is created by joining the original path to `read_dir` + /// with the filename of this entry. /// /// # Examples /// -- cgit 1.4.1-3-g733a5 From c4730daf450bafe51e76d430f94d2c59c814e53c Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 19 Jul 2016 12:32:56 -0400 Subject: re-work example --- src/libstd/env.rs | 47 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 12 deletions(-) (limited to 'src/libstd') diff --git a/src/libstd/env.rs b/src/libstd/env.rs index 369594e2b8f..5a3899eca3f 100644 --- a/src/libstd/env.rs +++ b/src/libstd/env.rs @@ -495,18 +495,41 @@ pub fn temp_dir() -> PathBuf { /// /// # Security /// -/// This function should be used with care, as its incorrect usage can cause -/// security problems. Specifically, as with many operations invovling files and -/// paths, you can introduce a race condition. It goes like this: -/// -/// 1. You get the path to the current executable using `current_exe()`, and -/// store it in a variable binding. -/// 2. Time passes. A malicious actor removes the current executable, and -/// replaces it with a malicious one. -/// 3. You then use the binding to try to open that file. -/// -/// You expected to be opening the current executable, but you're now opening -/// something completely different. +/// The output of this function should not be used in anything that might have +/// security implications. For example: +/// +/// ``` +/// fn main() { +/// println!("{:?}", std::env::current_exe()); +/// } +/// ``` +/// +/// On Linux systems, if this is compiled as `foo`: +/// +/// ```bash +/// $ rustc foo.rs +/// $ ./foo +/// Ok("/home/alex/foo") +/// ``` +/// +/// And you make a symbolic link of the program: +/// +/// ```bash +/// $ ln foo bar +/// ``` +/// +/// When you run it, you won't get the original executable, you'll get the +/// symlink: +/// +/// ```bash +/// $ ./bar +/// Ok("/home/alex/bar") +/// ``` +/// +/// This sort of behavior has been known to [lead to privledge escalation] when +/// used incorrectly, for example. +/// +/// [lead to privledge escalation]: http://securityvulns.com/Wdocument183.html /// /// # Examples /// -- cgit 1.4.1-3-g733a5 From aed2e5c1e5d1774fba671ba60ee6347a1d524f2e Mon Sep 17 00:00:00 2001 From: mitchmindtree Date: Wed, 20 Jul 2016 14:49:40 +1000 Subject: Add the missing tracking issue field for #34931 to the receiver_try_iter stability attributes --- src/libstd/sync/mpsc/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/libstd') diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs index 2d2bded9f60..b862a594ed2 100644 --- a/src/libstd/sync/mpsc/mod.rs +++ b/src/libstd/sync/mpsc/mod.rs @@ -317,7 +317,7 @@ pub struct Iter<'a, T: 'a> { /// /// This Iterator will never block the caller in order to wait for data to /// become available. Instead, it will return `None`. -#[unstable(feature = "receiver_try_iter")] +#[unstable(feature = "receiver_try_iter", issue = "34931")] pub struct TryIter<'a, T: 'a> { rx: &'a Receiver } @@ -998,7 +998,7 @@ impl Receiver { /// It will return `None` if there are no more pending values or if the /// channel has hung up. The iterator will never `panic!` or block the /// user by waiting for values. - #[unstable(feature = "receiver_try_iter")] + #[unstable(feature = "receiver_try_iter", issue = "34931")] pub fn try_iter(&self) -> TryIter { TryIter { rx: self } } @@ -1098,7 +1098,7 @@ impl<'a, T> Iterator for Iter<'a, T> { fn next(&mut self) -> Option { self.rx.recv().ok() } } -#[unstable(feature = "receiver_try_iter")] +#[unstable(feature = "receiver_try_iter", issue = "34931")] impl<'a, T> Iterator for TryIter<'a, T> { type Item = T; -- cgit 1.4.1-3-g733a5 From 15cd5a18a656252e32e7320fde3072be7b59db18 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 20 Jul 2016 17:26:12 -0700 Subject: std: Fix usage of SOCK_CLOEXEC This code path was intended to only get executed on Linux, but unfortunately the `cfg!` was malformed so it actually never got executed. --- src/libstd/sys/unix/net.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/libstd') diff --git a/src/libstd/sys/unix/net.rs b/src/libstd/sys/unix/net.rs index a784741c88c..6f1b70acb60 100644 --- a/src/libstd/sys/unix/net.rs +++ b/src/libstd/sys/unix/net.rs @@ -67,7 +67,7 @@ impl Socket { // this option, however, was added in 2.6.27, and we still support // 2.6.18 as a kernel, so if the returned error is EINVAL we // fallthrough to the fallback. - if cfg!(linux) { + if cfg!(target_os = "linux") { match cvt(libc::socket(fam, ty | SOCK_CLOEXEC, 0)) { Ok(fd) => return Ok(Socket(FileDesc::new(fd))), Err(ref e) if e.raw_os_error() == Some(libc::EINVAL) => {} @@ -87,7 +87,7 @@ impl Socket { let mut fds = [0, 0]; // Like above, see if we can set cloexec atomically - if cfg!(linux) { + if cfg!(target_os = "linux") { match cvt(libc::socketpair(fam, ty | SOCK_CLOEXEC, 0, fds.as_mut_ptr())) { Ok(_) => { return Ok((Socket(FileDesc::new(fds[0])), Socket(FileDesc::new(fds[1])))); -- cgit 1.4.1-3-g733a5 From 05af033b7fec63638497a9780e6b323d327d1e17 Mon Sep 17 00:00:00 2001 From: mitchmindtree Date: Thu, 21 Jul 2016 19:32:24 +1000 Subject: Fix issue in receiver_try_iter test where response sender would panic instead of break from the loop --- src/libstd/sync/mpsc/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/libstd') diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs index b862a594ed2..6fe1b2a3b47 100644 --- a/src/libstd/sync/mpsc/mod.rs +++ b/src/libstd/sync/mpsc/mod.rs @@ -1854,8 +1854,6 @@ mod tests { for x in response_rx.try_iter() { count += x; if count == 6 { - drop(response_rx); - drop(request_tx); return count; } } @@ -1864,7 +1862,9 @@ mod tests { }); for _ in request_rx.iter() { - response_tx.send(2).unwrap(); + if response_tx.send(2).is_err() { + break; + } } assert_eq!(t.join().unwrap(), 6); -- cgit 1.4.1-3-g733a5 From ec33dab062aba12ff248a4fd3cb04c7c8d0dfd27 Mon Sep 17 00:00:00 2001 From: ggomez Date: Wed, 20 Jul 2016 14:44:15 +0200 Subject: Add HashMap Entry enums examples --- src/libstd/collections/hash/map.rs | 203 ++++++++++++++++++++++++++++++++++++- 1 file changed, 198 insertions(+), 5 deletions(-) (limited to 'src/libstd') diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 60d7e01d988..a4aa434d6c4 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -1336,6 +1336,10 @@ impl<'a, K, V> InternalEntry> { } /// A view into a single location in a map, which may be vacant or occupied. +/// This enum is constructed from the [`entry`] method on [`HashMap`]. +/// +/// [`HashMap`]: struct.HashMap.html +/// [`entry`]: struct.HashMap.html#method.entry #[stable(feature = "rust1", since = "1.0.0")] pub enum Entry<'a, K: 'a, V: 'a> { /// An occupied Entry. @@ -1352,6 +1356,9 @@ pub enum Entry<'a, K: 'a, V: 'a> { } /// A view into a single occupied location in a HashMap. +/// It is part of the [`Entry`] enum. +/// +/// [`Entry`]: enum.Entry.html #[stable(feature = "rust1", since = "1.0.0")] pub struct OccupiedEntry<'a, K: 'a, V: 'a> { key: Option, @@ -1359,6 +1366,9 @@ pub struct OccupiedEntry<'a, K: 'a, V: 'a> { } /// A view into a single empty location in a HashMap. +/// It is part of the [`Entry`] enum. +/// +/// [`Entry`]: enum.Entry.html #[stable(feature = "rust1", since = "1.0.0")] pub struct VacantEntry<'a, K: 'a, V: 'a> { hash: SafeHash, @@ -1518,6 +1528,20 @@ impl<'a, K, V> Entry<'a, K, V> { #[stable(feature = "rust1", since = "1.0.0")] /// Ensures a value is in the entry by inserting the default if empty, and returns /// a mutable reference to the value in the entry. + /// + /// # Examples + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut map: HashMap<&str, u32> = HashMap::new(); + /// map.entry("poneyland").or_insert(12); + /// + /// assert_eq!(map["poneyland"], 12); + /// + /// *map.entry("poneyland").or_insert(12) += 10; + /// assert_eq!(map["poneyland"], 22); + /// ``` pub fn or_insert(self, default: V) -> &'a mut V { match self { Occupied(entry) => entry.into_mut(), @@ -1528,6 +1552,19 @@ impl<'a, K, V> Entry<'a, K, V> { #[stable(feature = "rust1", since = "1.0.0")] /// Ensures a value is in the entry by inserting the result of the default function if empty, /// and returns a mutable reference to the value in the entry. + /// + /// # Examples + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut map: HashMap<&str, String> = HashMap::new(); + /// let s = "hoho".to_owned(); + /// + /// map.entry("poneyland").or_insert_with(|| s); + /// + /// assert_eq!(map["poneyland"], "hoho".to_owned()); + /// ``` pub fn or_insert_with V>(self, default: F) -> &'a mut V { match self { Occupied(entry) => entry.into_mut(), @@ -1536,6 +1573,15 @@ impl<'a, K, V> Entry<'a, K, V> { } /// Returns a reference to this entry's key. + /// + /// # Examples + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut map: HashMap<&str, u32> = HashMap::new(); + /// assert_eq!(map.entry("poneyland").key(), &"poneyland"); + /// ``` #[stable(feature = "map_entry_keys", since = "1.10.0")] pub fn key(&self) -> &K { match *self { @@ -1547,37 +1593,130 @@ impl<'a, K, V> Entry<'a, K, V> { impl<'a, K, V> OccupiedEntry<'a, K, V> { /// Gets a reference to the key in the entry. + /// + /// # Examples + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut map: HashMap<&str, u32> = HashMap::new(); + /// map.entry("poneyland").or_insert(12); + /// assert_eq!(map.entry("poneyland").key(), &"poneyland"); + /// ``` #[stable(feature = "map_entry_keys", since = "1.10.0")] pub fn key(&self) -> &K { self.elem.read().0 } /// Take the ownership of the key and value from the map. + /// + /// # Examples + /// + /// ``` + /// #![feature(map_entry_recover_keys)] + /// + /// use std::collections::HashMap; + /// use std::collections::hash_map::Entry; + /// + /// let mut map: HashMap<&str, u32> = HashMap::new(); + /// map.entry("poneyland").or_insert(12); + /// + /// if let Entry::Occupied(o) = map.entry("poneyland") { + /// // We delete the entry from the map. + /// o.remove_pair(); + /// } + /// + /// assert_eq!(map.contains_key("poneyland"), false); + /// ``` #[unstable(feature = "map_entry_recover_keys", issue = "34285")] pub fn remove_pair(self) -> (K, V) { pop_internal(self.elem) } /// Gets a reference to the value in the entry. + /// + /// # Examples + /// + /// ``` + /// use std::collections::HashMap; + /// use std::collections::hash_map::Entry; + /// + /// let mut map: HashMap<&str, u32> = HashMap::new(); + /// map.entry("poneyland").or_insert(12); + /// + /// if let Entry::Occupied(o) = map.entry("poneyland") { + /// assert_eq!(o.get(), &12); + /// } + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn get(&self) -> &V { self.elem.read().1 } /// Gets a mutable reference to the value in the entry. + /// + /// # Examples + /// + /// ``` + /// use std::collections::HashMap; + /// use std::collections::hash_map::Entry; + /// + /// let mut map: HashMap<&str, u32> = HashMap::new(); + /// map.entry("poneyland").or_insert(12); + /// + /// assert_eq!(map["poneyland"], 12); + /// if let Entry::Occupied(mut o) = map.entry("poneyland") { + /// *o.get_mut() += 10; + /// } + /// + /// assert_eq!(map["poneyland"], 22); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn get_mut(&mut self) -> &mut V { self.elem.read_mut().1 } /// Converts the OccupiedEntry into a mutable reference to the value in the entry - /// with a lifetime bound to the map itself + /// with a lifetime bound to the map itself. + /// + /// # Examples + /// + /// ``` + /// use std::collections::HashMap; + /// use std::collections::hash_map::Entry; + /// + /// let mut map: HashMap<&str, u32> = HashMap::new(); + /// map.entry("poneyland").or_insert(12); + /// + /// assert_eq!(map["poneyland"], 12); + /// if let Entry::Occupied(o) = map.entry("poneyland") { + /// *o.into_mut() += 10; + /// } + /// + /// assert_eq!(map["poneyland"], 22); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn into_mut(self) -> &'a mut V { self.elem.into_mut_refs().1 } - /// Sets the value of the entry, and returns the entry's old value + /// Sets the value of the entry, and returns the entry's old value. + /// + /// # Examples + /// + /// ``` + /// use std::collections::HashMap; + /// use std::collections::hash_map::Entry; + /// + /// let mut map: HashMap<&str, u32> = HashMap::new(); + /// map.entry("poneyland").or_insert(12); + /// + /// if let Entry::Occupied(mut o) = map.entry("poneyland") { + /// assert_eq!(o.insert(15), 12); + /// } + /// + /// assert_eq!(map["poneyland"], 15); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn insert(&mut self, mut value: V) -> V { let old_value = self.get_mut(); @@ -1585,7 +1724,23 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> { value } - /// Takes the value out of the entry, and returns it + /// Takes the value out of the entry, and returns it. + /// + /// # Examples + /// + /// ``` + /// use std::collections::HashMap; + /// use std::collections::hash_map::Entry; + /// + /// let mut map: HashMap<&str, u32> = HashMap::new(); + /// map.entry("poneyland").or_insert(12); + /// + /// if let Entry::Occupied(o) = map.entry("poneyland") { + /// assert_eq!(o.remove(), 12); + /// } + /// + /// assert_eq!(map.contains_key("poneyland"), false); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn remove(self) -> V { pop_internal(self.elem).1 @@ -1601,20 +1756,58 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> { impl<'a, K: 'a, V: 'a> VacantEntry<'a, K, V> { /// Gets a reference to the key that would be used when inserting a value - /// through the VacantEntry. + /// through the `VacantEntry`. + /// + /// # Examples + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut map: HashMap<&str, u32> = HashMap::new(); + /// assert_eq!(map.entry("poneyland").key(), &"poneyland"); + /// ``` #[stable(feature = "map_entry_keys", since = "1.10.0")] pub fn key(&self) -> &K { &self.key } /// Take ownership of the key. + /// + /// # Examples + /// + /// ``` + /// #![feature(map_entry_recover_keys)] + /// + /// use std::collections::HashMap; + /// use std::collections::hash_map::Entry; + /// + /// let mut map: HashMap<&str, u32> = HashMap::new(); + /// + /// if let Entry::Vacant(v) = map.entry("poneyland") { + /// v.into_key(); + /// } + /// ``` #[unstable(feature = "map_entry_recover_keys", issue = "34285")] pub fn into_key(self) -> K { self.key } /// Sets the value of the entry with the VacantEntry's key, - /// and returns a mutable reference to it + /// and returns a mutable reference to it. + /// + /// # Examples + /// + /// ``` + /// use std::collections::HashMap; + /// use std::collections::hash_map::Entry; + /// + /// let mut map: HashMap<&str, u32> = HashMap::new(); + /// + /// if let Entry::Vacant(o) = map.entry("poneyland") { + /// o.insert(37); + /// } + /// assert_eq!(map["poneyland"], 37); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn insert(self, value: V) -> &'a mut V { match self.elem { -- cgit 1.4.1-3-g733a5 From 3c8fae369f54649fe90dc85f284e897974aeb1ca Mon Sep 17 00:00:00 2001 From: ggomez Date: Fri, 22 Jul 2016 14:57:52 +0200 Subject: Add Random state doc --- src/libstd/collections/hash/map.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'src/libstd') diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 60d7e01d988..d4b09807e74 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -1666,6 +1666,17 @@ impl<'a, K, V, S> Extend<(&'a K, &'a V)> for HashMap /// A particular instance `RandomState` will create the same instances of /// `Hasher`, but the hashers created by two different `RandomState` /// instances are unlikely to produce the same result for the same values. +/// +/// # Examples +/// +/// ``` +/// use std::collections::HashMap; +/// use std::collections::hash_map::RandomState; +/// +/// let s = RandomState::new(); +/// let mut map = HashMap::with_hasher(s); +/// map.insert(1, 2); +/// ``` #[derive(Clone)] #[stable(feature = "hashmap_build_hasher", since = "1.7.0")] pub struct RandomState { @@ -1675,6 +1686,14 @@ pub struct RandomState { impl RandomState { /// Constructs a new `RandomState` that is initialized with random keys. + /// + /// # Examples + /// + /// ``` + /// use std::collections::hash_map::RandomState; + /// + /// let s = RandomState::new(); + /// ``` #[inline] #[allow(deprecated)] // rand #[stable(feature = "hashmap_build_hasher", since = "1.7.0")] -- cgit 1.4.1-3-g733a5 From 90bb8d469c495f48cf0da67c7811fd887a8b0655 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 23 Jul 2016 01:57:21 +0200 Subject: Add DirBuilder doc examples --- src/libstd/fs.rs | 19 ++++++++++++++++++- src/libstd/sys/unix/ext/fs.rs | 10 ++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) (limited to 'src/libstd') diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index c28f70b8692..c74e508a69b 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -1397,6 +1397,14 @@ pub fn set_permissions>(path: P, perm: Permissions) impl DirBuilder { /// Creates a new set of options with default mode/security settings for all /// platforms and also non-recursive. + /// + /// # Examples + /// + /// ``` + /// use std::fs::DirBuilder; + /// + /// let builder = DirBuilder::new(); + /// ``` #[stable(feature = "dir_builder", since = "1.6.0")] pub fn new() -> DirBuilder { DirBuilder { @@ -1409,7 +1417,16 @@ impl DirBuilder { /// all parent directories if they do not exist with the same security and /// permissions settings. /// - /// This option defaults to `false` + /// This option defaults to `false`. + /// + /// # Examples + /// + /// ``` + /// use std::fs::DirBuilder; + /// + /// let mut builder = DirBuilder::new(); + /// builder.recursive(true); + /// ``` #[stable(feature = "dir_builder", since = "1.6.0")] pub fn recursive(&mut self, recursive: bool) -> &mut Self { self.recursive = recursive; diff --git a/src/libstd/sys/unix/ext/fs.rs b/src/libstd/sys/unix/ext/fs.rs index bb90a977433..d1f26fec249 100644 --- a/src/libstd/sys/unix/ext/fs.rs +++ b/src/libstd/sys/unix/ext/fs.rs @@ -239,6 +239,16 @@ pub fn symlink, Q: AsRef>(src: P, dst: Q) -> io::Result<()> pub trait DirBuilderExt { /// Sets the mode to create new directories with. This option defaults to /// 0o777. + /// + /// # Examples + /// + /// ```ignore + /// use std::fs::DirBuilder; + /// use std::os::unix::fs::DirBuilderExt; + /// + /// let mut builder = DirBuilder::new(); + /// builder.mode(0o755); + /// ``` #[stable(feature = "dir_builder", since = "1.6.0")] fn mode(&mut self, mode: u32) -> &mut Self; } -- cgit 1.4.1-3-g733a5 From ccc955c84c3edb1aab58a5e6afe08cc1f57b7697 Mon Sep 17 00:00:00 2001 From: Robert Williamson Date: Sat, 23 Jul 2016 16:13:25 -0600 Subject: Fix HashMap's values_mut example to use println! --- src/libstd/collections/hash/map.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libstd') diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index a03249e0063..97af99030c8 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -877,7 +877,7 @@ impl HashMap /// } /// /// for val in map.values() { - /// print!("{}", val); + /// println!("{}", val); /// } /// ``` #[stable(feature = "map_values_mut", since = "1.10.0")] -- cgit 1.4.1-3-g733a5 From dad29a6d03429874ddf5ce6f53045bae2e0d6fac Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 24 Jul 2016 16:07:06 +0200 Subject: Add missing links --- src/libstd/fs.rs | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) (limited to 'src/libstd') diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index c28f70b8692..d1453b05a79 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -58,28 +58,37 @@ pub struct File { /// Metadata information about a file. /// -/// This structure is returned from the `metadata` function or method and +/// This structure is returned from the [`metadata`] function or method and /// represents known metadata about a file such as its permissions, size, /// modification times, etc. +/// +/// [`metadata`]: fn.metadata.html #[stable(feature = "rust1", since = "1.0.0")] #[derive(Clone)] pub struct Metadata(fs_imp::FileAttr); /// Iterator over the entries in a directory. /// -/// This iterator is returned from the `read_dir` function of this module and -/// will yield instances of `io::Result`. Through a `DirEntry` +/// This iterator is returned from the [`read_dir`] function of this module and +/// will yield instances of `io::Result`. Through a [`DirEntry`] /// information like the entry's path and possibly other metadata can be /// learned. /// +/// [`read_dir`]: fn.read_dir.html +/// [`DirEntry`]: struct.DirEntry.html +/// /// # Errors /// -/// This `io::Result` will be an `Err` if there's some sort of intermittent +/// This [`io::Result`] will be an `Err` if there's some sort of intermittent /// IO error during iteration. +/// +/// [`io::Result`]: ../io/type.Result.html #[stable(feature = "rust1", since = "1.0.0")] pub struct ReadDir(fs_imp::ReadDir); -/// Entries returned by the `ReadDir` iterator. +/// Entries returned by the [`ReadDir`] iterator. +/// +/// [`ReadDir`]: struct.ReadDir.html /// /// An instance of `DirEntry` represents an entry inside of a directory on the /// filesystem. Each entry can be inspected via methods to learn about the full @@ -89,17 +98,23 @@ pub struct DirEntry(fs_imp::DirEntry); /// Options and flags which can be used to configure how a file is opened. /// -/// This builder exposes the ability to configure how a `File` is opened and -/// what operations are permitted on the open file. The `File::open` and -/// `File::create` methods are aliases for commonly used options using this +/// This builder exposes the ability to configure how a [`File`] is opened and +/// what operations are permitted on the open file. The [`File::open`] and +/// [`File::create`] methods are aliases for commonly used options using this /// builder. /// -/// Generally speaking, when using `OpenOptions`, you'll first call `new()`, -/// then chain calls to methods to set each option, then call `open()`, passing -/// the path of the file you're trying to open. This will give you a +/// [`File`]: struct.File.html +/// [`File::open`]: struct.File.html#method.open +/// [`File::create`]: struct.File.html#method.create +/// +/// Generally speaking, when using `OpenOptions`, you'll first call [`new()`], +/// then chain calls to methods to set each option, then call [`open()`], +/// passing the path of the file you're trying to open. This will give you a /// [`io::Result`][result] with a [`File`][file] inside that you can further /// operate on. /// +/// [`new()`]: struct.OpenOptions.html#method.new +/// [`open()`]: struct.OpenOptions.html#method.open /// [result]: ../io/type.Result.html /// [file]: struct.File.html /// @@ -131,10 +146,12 @@ pub struct OpenOptions(fs_imp::OpenOptions); /// Representation of the various permissions on a file. /// -/// This module only currently provides one bit of information, `readonly`, +/// This module only currently provides one bit of information, [`readonly`], /// which is exposed on all currently supported platforms. Unix-specific /// functionality, such as mode bits, is available through the /// `os::unix::PermissionsExt` trait. +/// +/// [`readonly`]: struct.Permissions.html#method.readonly #[derive(Clone, PartialEq, Eq, Debug)] #[stable(feature = "rust1", since = "1.0.0")] pub struct Permissions(fs_imp::FilePermissions); -- cgit 1.4.1-3-g733a5 From 16699635bc467b0940c11675dd73e7e444088c4e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 24 Jul 2016 16:52:28 +0200 Subject: Add DirEntry doc examples --- src/libstd/fs.rs | 55 +++++++++++++++++++++++++++++++++++++++++++ src/libstd/sys/unix/ext/fs.rs | 16 +++++++++++++ 2 files changed, 71 insertions(+) (limited to 'src/libstd') diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index d1453b05a79..6547cb6acbe 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -846,6 +846,26 @@ impl DirEntry { /// On Windows this function is cheap to call (no extra system calls /// needed), but on Unix platforms this function is the equivalent of /// calling `symlink_metadata` on the path. + /// + /// # Examples + /// + /// ``` + /// use std::fs; + /// + /// if let Ok(entries) = fs::read_dir(".") { + /// for entry in entries { + /// if let Ok(entry) = entry { + /// // Here, `entry` is a `DirEntry`. + /// if let Ok(metadata) = entry.metadata() { + /// // Now let's show our entry's permissions! + /// println!("{:?}: {:?}", entry.path(), metadata.permissions()); + /// } else { + /// println!("Couldn't get metadata for {:?}", entry.path()); + /// } + /// } + /// } + /// } + /// ``` #[stable(feature = "dir_entry_ext", since = "1.1.0")] pub fn metadata(&self) -> io::Result { self.0.metadata().map(Metadata) @@ -861,6 +881,26 @@ impl DirEntry { /// On Windows and most Unix platforms this function is free (no extra /// system calls needed), but some Unix platforms may require the equivalent /// call to `symlink_metadata` to learn about the target file type. + /// + /// # Examples + /// + /// ``` + /// use std::fs; + /// + /// if let Ok(entries) = fs::read_dir(".") { + /// for entry in entries { + /// if let Ok(entry) = entry { + /// // Here, `entry` is a `DirEntry`. + /// if let Ok(file_type) = entry.file_type() { + /// // Now let's show our entry's file type! + /// println!("{:?}: {:?}", entry.path(), file_type); + /// } else { + /// println!("Couldn't get file type for {:?}", entry.path()); + /// } + /// } + /// } + /// } + /// ``` #[stable(feature = "dir_entry_ext", since = "1.1.0")] pub fn file_type(&self) -> io::Result { self.0.file_type().map(FileType) @@ -868,6 +908,21 @@ impl DirEntry { /// Returns the bare file name of this directory entry without any other /// leading path component. + /// + /// # Examples + /// + /// ``` + /// use std::fs; + /// + /// if let Ok(entries) = fs::read_dir(".") { + /// for entry in entries { + /// if let Ok(entry) = entry { + /// // Here, `entry` is a `DirEntry`. + /// println!("{:?}", entry.file_name()); + /// } + /// } + /// } + /// ``` #[stable(feature = "dir_entry_ext", since = "1.1.0")] pub fn file_name(&self) -> OsString { self.0.file_name() diff --git a/src/libstd/sys/unix/ext/fs.rs b/src/libstd/sys/unix/ext/fs.rs index bb90a977433..17c093e6cac 100644 --- a/src/libstd/sys/unix/ext/fs.rs +++ b/src/libstd/sys/unix/ext/fs.rs @@ -196,6 +196,22 @@ impl FileTypeExt for fs::FileType { pub trait DirEntryExt { /// Returns the underlying `d_ino` field in the contained `dirent` /// structure. + /// + /// # Examples + /// + /// ``` + /// use std::fs; + /// use std::os::unix::fs::DirEntryExt; + /// + /// if let Ok(entries) = fs::read_dir(".") { + /// for entry in entries { + /// if let Ok(entry) = entry { + /// // Here, `entry` is a `DirEntry`. + /// println!("{:?}: {}", entry.file_name(), entry.ino()); + /// } + /// } + /// } + /// ``` #[stable(feature = "dir_entry_ext", since = "1.1.0")] fn ino(&self) -> u64; } -- cgit 1.4.1-3-g733a5 From debb2ac76bd8b4ef8de0f470351a2b187afc91df Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 24 Jul 2016 17:00:49 +0200 Subject: Improve Open doc --- src/libstd/fs.rs | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) (limited to 'src/libstd') diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index c28f70b8692..4d4d44bae30 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -156,12 +156,14 @@ pub struct DirBuilder { impl File { /// Attempts to open a file in read-only mode. /// - /// See the `OpenOptions::open` method for more details. + /// See the [`OpenOptions::open`] method for more details. /// /// # Errors /// /// This function will return an error if `path` does not already exist. - /// Other errors may also be returned according to `OpenOptions::open`. + /// Other errors may also be returned according to [`OpenOptions::open`]. + /// + /// [`OpenOptions::open`]: struct.OpenOptions.html#method.open /// /// # Examples /// @@ -183,7 +185,9 @@ impl File { /// This function will create a file if it does not exist, /// and will truncate it if it does. /// - /// See the `OpenOptions::open` function for more details. + /// See the [`OpenOptions::open`] function for more details. + /// + /// [`OpenOptions::open`]: struct.OpenOptions.html#method.open /// /// # Examples /// @@ -224,7 +228,7 @@ impl File { self.inner.fsync() } - /// This function is similar to `sync_all`, except that it may not + /// This function is similar to [`sync_all`], except that it may not /// synchronize file metadata to the filesystem. /// /// This is intended for use cases that must synchronize content, but don't @@ -232,7 +236,9 @@ impl File { /// operations. /// /// Note that some platforms may simply implement this in terms of - /// `sync_all`. + /// [`sync_all`]. + /// + /// [`sync_all`]: struct.File.html#method.sync_all /// /// # Examples /// @@ -304,6 +310,18 @@ impl File { /// The returned `File` is a reference to the same state that this object /// references. Both handles will read and write with the same cursor /// position. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs::File; + /// + /// # fn foo() -> std::io::Result<()> { + /// let mut f = try!(File::open("foo.txt")); + /// let file_copy = try!(f.try_clone()); + /// # Ok(()) + /// # } + /// ``` #[stable(feature = "file_try_clone", since = "1.9.0")] pub fn try_clone(&self) -> io::Result { Ok(File { -- cgit 1.4.1-3-g733a5 From 1aa8dad854155221db7cec19b6105c673e4a871e Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sat, 30 Apr 2016 16:37:44 +0200 Subject: DoubleEndedIterator for Args The number of arguments given to a process is always known, which makes implementing DoubleEndedIterator possible. That way, the Iterator::rev() method becomes usable, among others. Signed-off-by: Sebastian Thiel Tidy for DoubleEndedIterator I chose to not create a new feature for it, even though technically, this makes me lie about the original availability of the implementation. Verify with @alexchrichton Setup feature flag for new std::env::Args iterators Add test for Args reverse iterator It's somewhat depending on the input of the test program, but made in such a way that should be somewhat flexible to changes to the way it is called. Deduplicate windows ArgsOS code for DEI DEI = DoubleEndedIterator Move env::args().rev() test to run-pass It must be controlling it's arguments for full isolation. Remove superfluous feature name Assert all arguments returned by env::args().rev() Let's be very sure it works as we expect, why take chances. Fix rval of os_string_from_ptr A trait cannot be returned, but only the corresponding object. Deref pointers to actually operate on the argument Put unsafe to correct location --- src/libstd/env.rs | 11 +++++++ src/libstd/sys/unix/os.rs | 4 +++ src/libstd/sys/windows/os.rs | 27 ++++++++++------ src/test/run-pass/env-args-reverse-iterator.rs | 44 ++++++++++++++++++++++++++ 4 files changed, 76 insertions(+), 10 deletions(-) create mode 100644 src/test/run-pass/env-args-reverse-iterator.rs (limited to 'src/libstd') diff --git a/src/libstd/env.rs b/src/libstd/env.rs index 6956dc0d901..01bc733d440 100644 --- a/src/libstd/env.rs +++ b/src/libstd/env.rs @@ -587,6 +587,13 @@ impl ExactSizeIterator for Args { fn len(&self) -> usize { self.inner.len() } } +#[stable(feature = "env_iterators", since = "1.11.0")] +impl DoubleEndedIterator for Args { + fn next_back(&mut self) -> Option { + self.inner.next_back().map(|s| s.into_string().unwrap()) + } +} + #[stable(feature = "env", since = "1.0.0")] impl Iterator for ArgsOs { type Item = OsString; @@ -599,6 +606,10 @@ impl ExactSizeIterator for ArgsOs { fn len(&self) -> usize { self.inner.len() } } +#[stable(feature = "env_iterators", since = "1.11.0")] +impl DoubleEndedIterator for ArgsOs { + fn next_back(&mut self) -> Option { self.inner.next_back() } +} /// Constants associated with the current target #[stable(feature = "env", since = "1.0.0")] pub mod consts { diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs index 21ce6b19ceb..a8cb1ce49d2 100644 --- a/src/libstd/sys/unix/os.rs +++ b/src/libstd/sys/unix/os.rs @@ -308,6 +308,10 @@ impl ExactSizeIterator for Args { fn len(&self) -> usize { self.iter.len() } } +impl DoubleEndedIterator for Args { + fn next_back(&mut self) -> Option { self.iter.next_back() } +} + /// Returns the command line arguments /// /// Returns a list of the command line arguments. diff --git a/src/libstd/sys/windows/os.rs b/src/libstd/sys/windows/os.rs index 32ca32e76cb..0cea7f81e36 100644 --- a/src/libstd/sys/windows/os.rs +++ b/src/libstd/sys/windows/os.rs @@ -278,23 +278,30 @@ pub struct Args { cur: *mut *mut u16, } +unsafe fn os_string_from_ptr(ptr: *mut u16) -> OsString { + let mut len = 0; + while *ptr.offset(len) != 0 { len += 1; } + + // Push it onto the list. + let ptr = ptr as *const u16; + let buf = slice::from_raw_parts(ptr, len as usize); + OsStringExt::from_wide(buf) +} + impl Iterator for Args { type Item = OsString; fn next(&mut self) -> Option { - self.range.next().map(|i| unsafe { - let ptr = *self.cur.offset(i); - let mut len = 0; - while *ptr.offset(len) != 0 { len += 1; } - - // Push it onto the list. - let ptr = ptr as *const u16; - let buf = slice::from_raw_parts(ptr, len as usize); - OsStringExt::from_wide(buf) - }) + self.range.next().map(|i| unsafe { os_string_from_ptr(*self.cur.offset(i)) } ) } fn size_hint(&self) -> (usize, Option) { self.range.size_hint() } } +impl DoubleEndedIterator for Args { + fn next_back(&mut self) -> Option { + self.range.next_back().map(|i| unsafe { os_string_from_ptr(*self.cur.offset(i)) } ) + } +} + impl ExactSizeIterator for Args { fn len(&self) -> usize { self.range.len() } } diff --git a/src/test/run-pass/env-args-reverse-iterator.rs b/src/test/run-pass/env-args-reverse-iterator.rs new file mode 100644 index 00000000000..d22fa6494f0 --- /dev/null +++ b/src/test/run-pass/env-args-reverse-iterator.rs @@ -0,0 +1,44 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::env::args; +use std::process::Command; + +fn assert_reverse_iterator_for_program_arguments(program_name: &str) { + let args: Vec<_> = args().rev().collect(); + + assert!(args.len() == 4); + assert_eq!(args[0], "c"); + assert_eq!(args[1], "b"); + assert_eq!(args[2], "a"); + assert_eq!(args[3], program_name); + + println!("passed"); +} + +fn main() { + let mut args = args(); + let me = args.next().unwrap(); + + if let Some(_) = args.next() { + assert_reverse_iterator_for_program_arguments(&me); + return + } + + let output = Command::new(&me) + .arg("a") + .arg("b") + .arg("c") + .output() + .unwrap(); + assert!(output.status.success()); + assert!(output.stderr.is_empty()); + assert_eq!(output.stdout, b"passed\n"); +} -- cgit 1.4.1-3-g733a5 From d464422c0a15b88a7f5791652ce1f881959fcc44 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Tue, 26 Jul 2016 15:21:25 -0500 Subject: rustbuild: make backtraces (RUST_BACKTRACE) optional but keep them enabled by default to maintain the status quo. When disabled shaves ~56KB off every x86_64-unknown-linux-gnu binary. To disable backtraces you have to use a config.toml (see src/bootstrap/config.toml.example for details) when building rustc/std: $ python bootstrap.py --config=config.toml --- src/bootstrap/config.rs | 4 ++++ src/bootstrap/config.toml.example | 3 +++ src/bootstrap/lib.rs | 3 +++ src/libstd/Cargo.toml | 1 + src/libstd/build.rs | 3 ++- src/libstd/panicking.rs | 16 ++++++++++++---- src/libstd/sys/common/mod.rs | 2 ++ src/libstd/sys/unix/mod.rs | 1 + src/rustc/std_shim/Cargo.toml | 1 + 9 files changed, 29 insertions(+), 5 deletions(-) (limited to 'src/libstd') diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index e64d7e5a437..aafbf68d1b7 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -72,6 +72,7 @@ pub struct Config { // libstd features pub debug_jemalloc: bool, pub use_jemalloc: bool, + pub backtrace: bool, // support for RUST_BACKTRACE // misc pub channel: String, @@ -134,6 +135,7 @@ struct Rust { debuginfo: Option, debug_jemalloc: Option, use_jemalloc: Option, + backtrace: Option, default_linker: Option, default_ar: Option, channel: Option, @@ -158,6 +160,7 @@ impl Config { let mut config = Config::default(); config.llvm_optimize = true; config.use_jemalloc = true; + config.backtrace = true; config.rust_optimize = true; config.rust_optimize_tests = true; config.submodules = true; @@ -230,6 +233,7 @@ impl Config { set(&mut config.rust_rpath, rust.rpath); set(&mut config.debug_jemalloc, rust.debug_jemalloc); set(&mut config.use_jemalloc, rust.use_jemalloc); + set(&mut config.backtrace, rust.backtrace); set(&mut config.channel, rust.channel.clone()); config.rustc_default_linker = rust.default_linker.clone(); config.rustc_default_ar = rust.default_ar.clone(); diff --git a/src/bootstrap/config.toml.example b/src/bootstrap/config.toml.example index 6f065842328..2894adafef6 100644 --- a/src/bootstrap/config.toml.example +++ b/src/bootstrap/config.toml.example @@ -99,6 +99,9 @@ # Whether or not jemalloc is built with its debug option set #debug-jemalloc = false +# Whether or not `panic!`s generate backtraces (RUST_BACKTRACE) +#backtrace = true + # The default linker that will be used by the generated compiler. Note that this # is not the linker used to link said compiler. #default-linker = "cc" diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 367322e8816..25356b86221 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -652,6 +652,9 @@ impl Build { if self.config.use_jemalloc { features.push_str(" jemalloc"); } + if self.config.backtrace { + features.push_str(" backtrace"); + } return features } diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml index eded6e24f3e..b442d21b72b 100644 --- a/src/libstd/Cargo.toml +++ b/src/libstd/Cargo.toml @@ -27,5 +27,6 @@ build_helper = { path = "../build_helper" } gcc = "0.3" [features] +backtrace = [] jemalloc = ["alloc_jemalloc"] debug-jemalloc = ["alloc_jemalloc/debug"] diff --git a/src/libstd/build.rs b/src/libstd/build.rs index 9c408366f8b..9018e48d06b 100644 --- a/src/libstd/build.rs +++ b/src/libstd/build.rs @@ -25,7 +25,8 @@ fn main() { let target = env::var("TARGET").unwrap(); let host = env::var("HOST").unwrap(); - if !target.contains("apple") && !target.contains("msvc") && !target.contains("emscripten"){ + if cfg!(feature = "backtrace") && !target.contains("apple") && !target.contains("msvc") && + !target.contains("emscripten") { build_libbacktrace(&host, &target); } diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs index d73e9542d21..319fbdaac55 100644 --- a/src/libstd/panicking.rs +++ b/src/libstd/panicking.rs @@ -28,8 +28,10 @@ use intrinsics; use mem; use raw; use sys_common::rwlock::RWLock; +#[cfg(feature = "backtrace")] use sync::atomic::{AtomicBool, Ordering}; use sys::stdio::Stderr; +#[cfg(feature = "backtrace")] use sys_common::backtrace; use sys_common::thread_info; use sys_common::util; @@ -71,6 +73,7 @@ enum Hook { static HOOK_LOCK: RWLock = RWLock::new(); static mut HOOK: Hook = Hook::Default; +#[cfg(feature = "backtrace")] static FIRST_PANIC: AtomicBool = AtomicBool::new(true); /// Registers a custom panic hook, replacing any that was previously registered. @@ -183,10 +186,12 @@ impl<'a> Location<'a> { } fn default_hook(info: &PanicInfo) { + #[cfg(feature = "backtrace")] let panics = PANIC_COUNT.with(|c| c.get()); // If this is a double panic, make sure that we print a backtrace // for this panic. Otherwise only print it if logging is enabled. + #[cfg(feature = "backtrace")] let log_backtrace = panics >= 2 || backtrace::log_enabled(); let file = info.location.file; @@ -207,10 +212,13 @@ fn default_hook(info: &PanicInfo) { let _ = writeln!(err, "thread '{}' panicked at '{}', {}:{}", name, msg, file, line); - if log_backtrace { - let _ = backtrace::write(err); - } else if FIRST_PANIC.compare_and_swap(true, false, Ordering::SeqCst) { - let _ = writeln!(err, "note: Run with `RUST_BACKTRACE=1` for a backtrace."); + #[cfg(feature = "backtrace")] + { + if log_backtrace { + let _ = backtrace::write(err); + } else if FIRST_PANIC.compare_and_swap(true, false, Ordering::SeqCst) { + let _ = writeln!(err, "note: Run with `RUST_BACKTRACE=1` for a backtrace."); + } } }; diff --git a/src/libstd/sys/common/mod.rs b/src/libstd/sys/common/mod.rs index c9279883ae5..67b19682fc9 100644 --- a/src/libstd/sys/common/mod.rs +++ b/src/libstd/sys/common/mod.rs @@ -28,6 +28,7 @@ macro_rules! rtassert { pub mod args; pub mod at_exit_imp; +#[cfg(feature = "backtrace")] pub mod backtrace; pub mod condvar; pub mod io; @@ -42,6 +43,7 @@ pub mod thread_local; pub mod util; pub mod wtf8; +#[cfg(feature = "backtrace")] #[cfg(any(all(unix, not(any(target_os = "macos", target_os = "ios", target_os = "emscripten"))), all(windows, target_env = "gnu")))] pub mod gnu; diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs index f0fd42fc99b..9aac7be8017 100644 --- a/src/libstd/sys/unix/mod.rs +++ b/src/libstd/sys/unix/mod.rs @@ -30,6 +30,7 @@ use libc; pub mod weak; pub mod android; +#[cfg(feature = "backtrace")] pub mod backtrace; pub mod condvar; pub mod ext; diff --git a/src/rustc/std_shim/Cargo.toml b/src/rustc/std_shim/Cargo.toml index 5602ef866b8..693cbe06ba9 100644 --- a/src/rustc/std_shim/Cargo.toml +++ b/src/rustc/std_shim/Cargo.toml @@ -46,3 +46,4 @@ std = { path = "../../libstd" } [features] jemalloc = ["std/jemalloc"] debug-jemalloc = ["std/debug-jemalloc"] +backtrace = ["std/backtrace"] -- cgit 1.4.1-3-g733a5 From 774fbdf40deb9b257dd6aa166096fed1eeac80c2 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Tue, 26 Jul 2016 22:33:45 -0500 Subject: keep backtraces if using the old build system --- src/libstd/panicking.rs | 24 +++++++++++++----------- src/libstd/sys/common/mod.rs | 4 ++-- src/libstd/sys/unix/mod.rs | 2 +- 3 files changed, 16 insertions(+), 14 deletions(-) (limited to 'src/libstd') diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs index 319fbdaac55..57a4c3df70a 100644 --- a/src/libstd/panicking.rs +++ b/src/libstd/panicking.rs @@ -28,11 +28,7 @@ use intrinsics; use mem; use raw; use sys_common::rwlock::RWLock; -#[cfg(feature = "backtrace")] -use sync::atomic::{AtomicBool, Ordering}; use sys::stdio::Stderr; -#[cfg(feature = "backtrace")] -use sys_common::backtrace; use sys_common::thread_info; use sys_common::util; use thread; @@ -73,8 +69,6 @@ enum Hook { static HOOK_LOCK: RWLock = RWLock::new(); static mut HOOK: Hook = Hook::Default; -#[cfg(feature = "backtrace")] -static FIRST_PANIC: AtomicBool = AtomicBool::new(true); /// Registers a custom panic hook, replacing any that was previously registered. /// @@ -186,13 +180,17 @@ impl<'a> Location<'a> { } fn default_hook(info: &PanicInfo) { - #[cfg(feature = "backtrace")] - let panics = PANIC_COUNT.with(|c| c.get()); + #[cfg(any(not(cargobuild), feature = "backtrace"))] + use sys_common::backtrace; // If this is a double panic, make sure that we print a backtrace // for this panic. Otherwise only print it if logging is enabled. - #[cfg(feature = "backtrace")] - let log_backtrace = panics >= 2 || backtrace::log_enabled(); + #[cfg(any(not(cargobuild), feature = "backtrace"))] + let log_backtrace = { + let panics = PANIC_COUNT.with(|c| c.get()); + + panics >= 2 || backtrace::log_enabled() + }; let file = info.location.file; let line = info.location.line; @@ -212,8 +210,12 @@ fn default_hook(info: &PanicInfo) { let _ = writeln!(err, "thread '{}' panicked at '{}', {}:{}", name, msg, file, line); - #[cfg(feature = "backtrace")] + #[cfg(any(not(cargobuild), feature = "backtrace"))] { + use sync::atomic::{AtomicBool, Ordering}; + + static FIRST_PANIC: AtomicBool = AtomicBool::new(true); + if log_backtrace { let _ = backtrace::write(err); } else if FIRST_PANIC.compare_and_swap(true, false, Ordering::SeqCst) { diff --git a/src/libstd/sys/common/mod.rs b/src/libstd/sys/common/mod.rs index 67b19682fc9..a1f3f477b3a 100644 --- a/src/libstd/sys/common/mod.rs +++ b/src/libstd/sys/common/mod.rs @@ -28,7 +28,7 @@ macro_rules! rtassert { pub mod args; pub mod at_exit_imp; -#[cfg(feature = "backtrace")] +#[cfg(any(not(cargobuild), feature = "backtrace"))] pub mod backtrace; pub mod condvar; pub mod io; @@ -43,7 +43,7 @@ pub mod thread_local; pub mod util; pub mod wtf8; -#[cfg(feature = "backtrace")] +#[cfg(any(not(cargobuild), feature = "backtrace"))] #[cfg(any(all(unix, not(any(target_os = "macos", target_os = "ios", target_os = "emscripten"))), all(windows, target_env = "gnu")))] pub mod gnu; diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs index 9aac7be8017..1c25c8f77c1 100644 --- a/src/libstd/sys/unix/mod.rs +++ b/src/libstd/sys/unix/mod.rs @@ -30,7 +30,7 @@ use libc; pub mod weak; pub mod android; -#[cfg(feature = "backtrace")] +#[cfg(any(not(cargobuild), feature = "backtrace"))] pub mod backtrace; pub mod condvar; pub mod ext; -- cgit 1.4.1-3-g733a5 From 3d09b4a0d58200da84fe19cd3b0003d61e5b1791 Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Wed, 27 Jul 2016 12:10:31 +0200 Subject: Rename `char::escape` to `char::escape_debug` and add tracking issue --- src/libcollections/lib.rs | 2 +- src/libcollections/str.rs | 6 +++--- src/libcollectionstest/str.rs | 22 ++++++++++---------- src/libcore/char.rs | 24 +++++++++++----------- src/libcore/fmt/mod.rs | 4 ++-- src/libcoretest/char.rs | 4 ++-- src/libcoretest/lib.rs | 3 ++- src/librustc_unicode/char.rs | 8 ++++---- src/librustc_unicode/lib.rs | 2 +- src/libstd/lib.rs | 15 +++++++------- src/libstd/sys/common/wtf8.rs | 6 +++--- .../run-pass/sync-send-iterators-in-libcore.rs | 2 +- 12 files changed, 50 insertions(+), 48 deletions(-) (limited to 'src/libstd') diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index 333219bc5e5..7fc6e54d69f 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -33,7 +33,7 @@ #![feature(allow_internal_unstable)] #![feature(box_patterns)] #![feature(box_syntax)] -#![feature(char_escape)] +#![cfg_attr(not(test), feature(char_escape_debug))] #![feature(core_intrinsics)] #![feature(dropck_parametricity)] #![feature(fmt_internals)] diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index a63ea9d3ec7..4c64019de09 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -1697,12 +1697,12 @@ impl str { return s; } - /// Escapes each char in `s` with `char::escape`. + /// Escapes each char in `s` with `char::escape_debug`. #[unstable(feature = "str_escape", reason = "return type may change to be an iterator", issue = "27791")] - pub fn escape(&self) -> String { - self.chars().flat_map(|c| c.escape()).collect() + pub fn escape_debug(&self) -> String { + self.chars().flat_map(|c| c.escape_debug()).collect() } /// Escapes each char in `s` with `char::escape_default`. diff --git a/src/libcollectionstest/str.rs b/src/libcollectionstest/str.rs index 870f8a3a1ec..a61925cd3be 100644 --- a/src/libcollectionstest/str.rs +++ b/src/libcollectionstest/str.rs @@ -704,17 +704,17 @@ fn test_escape_unicode() { } #[test] -fn test_escape() { - assert_eq!("abc".escape_default(), "abc"); - assert_eq!("a c".escape_default(), "a c"); - assert_eq!("éèê".escape_default(), "éèê"); - assert_eq!("\r\n\t".escape_default(), "\\r\\n\\t"); - assert_eq!("'\"\\".escape_default(), "\\'\\\"\\\\"); - assert_eq!("\u{7f}\u{ff}".escape_default(), "\\u{7f}\u{ff}"); - assert_eq!("\u{100}\u{ffff}".escape_default(), "\u{100}\\u{ffff}"); - assert_eq!("\u{10000}\u{10ffff}".escape_default(), "\u{10000}\\u{10ffff}"); - assert_eq!("ab\u{200b}".escape_default(), "ab\\u{200b}"); - assert_eq!("\u{10d4ea}\r".escape_default(), "\\u{10d4ea}\\r"); +fn test_escape_debug() { + assert_eq!("abc".escape_debug(), "abc"); + assert_eq!("a c".escape_debug(), "a c"); + assert_eq!("éèê".escape_debug(), "éèê"); + assert_eq!("\r\n\t".escape_debug(), "\\r\\n\\t"); + assert_eq!("'\"\\".escape_debug(), "\\'\\\"\\\\"); + assert_eq!("\u{7f}\u{ff}".escape_debug(), "\\u{7f}\u{ff}"); + assert_eq!("\u{100}\u{ffff}".escape_debug(), "\u{100}\\u{ffff}"); + assert_eq!("\u{10000}\u{10ffff}".escape_debug(), "\u{10000}\\u{10ffff}"); + assert_eq!("ab\u{200b}".escape_debug(), "ab\\u{200b}"); + assert_eq!("\u{10d4ea}\r".escape_debug(), "\\u{10d4ea}\\r"); } #[test] diff --git a/src/libcore/char.rs b/src/libcore/char.rs index 3e435b47110..a3440fe8aa6 100644 --- a/src/libcore/char.rs +++ b/src/libcore/char.rs @@ -264,8 +264,8 @@ pub trait CharExt { fn escape_unicode(self) -> EscapeUnicode; #[stable(feature = "core", since = "1.6.0")] fn escape_default(self) -> EscapeDefault; - #[unstable(feature = "char_escape", issue = "0")] - fn escape(self) -> Escape; + #[unstable(feature = "char_escape_debug", issue = "35068")] + fn escape_debug(self) -> EscapeDebug; #[stable(feature = "core", since = "1.6.0")] fn len_utf8(self) -> usize; #[stable(feature = "core", since = "1.6.0")] @@ -330,7 +330,7 @@ impl CharExt for char { } #[inline] - fn escape(self) -> Escape { + fn escape_debug(self) -> EscapeDebug { let init_state = match self { '\t' => EscapeDefaultState::Backslash('t'), '\r' => EscapeDefaultState::Backslash('r'), @@ -339,7 +339,7 @@ impl CharExt for char { c if is_printable(c) => EscapeDefaultState::Char(c), c => EscapeDefaultState::Unicode(c.escape_unicode()), }; - Escape(EscapeDefault { state: init_state }) + EscapeDebug(EscapeDefault { state: init_state }) } #[inline] @@ -618,24 +618,24 @@ impl ExactSizeIterator for EscapeDefault { /// An iterator that yields the literal escape code of a `char`. /// -/// This `struct` is created by the [`escape()`] method on [`char`]. See its +/// This `struct` is created by the [`escape_debug()`] method on [`char`]. See its /// documentation for more. /// -/// [`escape()`]: ../../std/primitive.char.html#method.escape +/// [`escape_debug()`]: ../../std/primitive.char.html#method.escape_debug /// [`char`]: ../../std/primitive.char.html -#[unstable(feature = "char_escape", issue = "0")] +#[unstable(feature = "char_escape_debug", issue = "35068")] #[derive(Clone, Debug)] -pub struct Escape(EscapeDefault); +pub struct EscapeDebug(EscapeDefault); -#[unstable(feature = "char_escape", issue = "0")] -impl Iterator for Escape { +#[unstable(feature = "char_escape_debug", issue = "35068")] +impl Iterator for EscapeDebug { type Item = char; fn next(&mut self) -> Option { self.0.next() } fn size_hint(&self) -> (usize, Option) { self.0.size_hint() } } -#[unstable(feature = "char_escape", issue = "0")] -impl ExactSizeIterator for Escape { } +#[unstable(feature = "char_escape_debug", issue = "35068")] +impl ExactSizeIterator for EscapeDebug { } /// An iterator over `u8` entries represending the UTF-8 encoding of a `char` /// value. diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 3bcdce57af0..173c55e35d5 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -1383,7 +1383,7 @@ impl Debug for str { f.write_char('"')?; let mut from = 0; for (i, c) in self.char_indices() { - let esc = c.escape(); + let esc = c.escape_debug(); // If char needs escaping, flush backlog so far and write, else skip if esc.len() != 1 { f.write_str(&self[from..i])?; @@ -1409,7 +1409,7 @@ impl Display for str { impl Debug for char { fn fmt(&self, f: &mut Formatter) -> Result { f.write_char('\'')?; - for c in self.escape() { + for c in self.escape_debug() { f.write_char(c)? } f.write_char('\'') diff --git a/src/libcoretest/char.rs b/src/libcoretest/char.rs index ec757b0b5d3..4632419336d 100644 --- a/src/libcoretest/char.rs +++ b/src/libcoretest/char.rs @@ -124,9 +124,9 @@ fn test_is_digit() { } #[test] -fn test_escape() { +fn test_escape_debug() { fn string(c: char) -> String { - c.escape().collect() + c.escape_debug().collect() } let s = string('\n'); assert_eq!(s, "\\n"); diff --git a/src/libcoretest/lib.rs b/src/libcoretest/lib.rs index 1ef2b58351f..ef0042808f9 100644 --- a/src/libcoretest/lib.rs +++ b/src/libcoretest/lib.rs @@ -14,6 +14,7 @@ #![feature(borrow_state)] #![feature(box_syntax)] #![feature(cell_extras)] +#![feature(char_escape_debug)] #![feature(const_fn)] #![feature(core_private_bignum)] #![feature(core_private_diy_float)] @@ -29,10 +30,10 @@ #![feature(slice_patterns)] #![feature(step_by)] #![feature(test)] +#![feature(try_from)] #![feature(unboxed_closures)] #![feature(unicode)] #![feature(unique)] -#![feature(try_from)] extern crate core; extern crate test; diff --git a/src/librustc_unicode/char.rs b/src/librustc_unicode/char.rs index 683d5289ab5..7e308684a25 100644 --- a/src/librustc_unicode/char.rs +++ b/src/librustc_unicode/char.rs @@ -36,7 +36,7 @@ use tables::{conversions, derived_property, general_category, property}; #[stable(feature = "rust1", since = "1.0.0")] pub use core::char::{MAX, from_digit, from_u32, from_u32_unchecked}; #[stable(feature = "rust1", since = "1.0.0")] -pub use core::char::{EncodeUtf16, EncodeUtf8, Escape, EscapeDefault, EscapeUnicode}; +pub use core::char::{EncodeUtf16, EncodeUtf8, EscapeDebug, EscapeDefault, EscapeUnicode}; // unstable reexports #[unstable(feature = "decode_utf8", issue = "33906")] @@ -296,10 +296,10 @@ impl char { /// /// assert_eq!(quote, "\\n"); /// ``` - #[unstable(feature = "char_escape", issue = "0")] + #[unstable(feature = "char_escape_debug", issue = "35068")] #[inline] - pub fn escape(self) -> Escape { - C::escape(self) + pub fn escape_debug(self) -> EscapeDebug { + C::escape_debug(self) } /// Returns an iterator that yields the literal escape code of a `char`. diff --git a/src/librustc_unicode/lib.rs b/src/librustc_unicode/lib.rs index 8c91d3b6a92..3ae905eba27 100644 --- a/src/librustc_unicode/lib.rs +++ b/src/librustc_unicode/lib.rs @@ -32,7 +32,7 @@ #![cfg_attr(not(stage0), deny(warnings))] #![no_std] -#![feature(char_escape)] +#![feature(char_escape_debug)] #![feature(core_char_ext)] #![feature(decode_utf8)] #![feature(lang_items)] diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index d05a5a09614..865d067cdb6 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -218,8 +218,9 @@ #![feature(associated_consts)] #![feature(borrow_state)] #![feature(box_syntax)] -#![feature(cfg_target_vendor)] #![feature(cfg_target_thread_local)] +#![feature(cfg_target_vendor)] +#![feature(char_escape_debug)] #![feature(char_internals)] #![feature(collections)] #![feature(collections_bound)] @@ -229,10 +230,10 @@ #![feature(dropck_parametricity)] #![feature(float_extras)] #![feature(float_from_str_radix)] -#![feature(fnbox)] #![feature(fn_traits)] -#![feature(heap_api)] +#![feature(fnbox)] #![feature(hashmap_hasher)] +#![feature(heap_api)] #![feature(inclusive_range)] #![feature(int_error_internals)] #![feature(into_cow)] @@ -242,6 +243,7 @@ #![feature(linkage)] #![feature(macro_reexport)] #![cfg_attr(test, feature(map_values_mut))] +#![feature(needs_panic_runtime)] #![feature(num_bits_bytes)] #![feature(old_wrapping)] #![feature(on_unimplemented)] @@ -249,10 +251,11 @@ #![feature(optin_builtin_traits)] #![feature(panic_unwind)] #![feature(placement_in_syntax)] +#![feature(question_mark)] #![feature(rand)] #![feature(raw)] -#![feature(repr_simd)] #![feature(reflect_marker)] +#![feature(repr_simd)] #![feature(rustc_attrs)] #![feature(shared)] #![feature(sip_hash_13)] @@ -266,6 +269,7 @@ #![feature(str_utf16)] #![feature(test, rustc_private)] #![feature(thread_local)] +#![feature(try_from)] #![feature(unboxed_closures)] #![feature(unicode)] #![feature(unique)] @@ -273,9 +277,6 @@ #![feature(unwind_attributes)] #![feature(vec_push_all)] #![feature(zero_one)] -#![feature(question_mark)] -#![feature(try_from)] -#![feature(needs_panic_runtime)] // Issue# 30592: Systematically use alloc_system during stage0 since jemalloc // might be unavailable or disabled diff --git a/src/libstd/sys/common/wtf8.rs b/src/libstd/sys/common/wtf8.rs index 2c1a656290f..c0e6ec46b55 100644 --- a/src/libstd/sys/common/wtf8.rs +++ b/src/libstd/sys/common/wtf8.rs @@ -390,7 +390,7 @@ impl fmt::Debug for Wtf8 { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { fn write_str_escaped(f: &mut fmt::Formatter, s: &str) -> fmt::Result { use fmt::Write; - for c in s.chars().flat_map(|c| c.escape_default()) { + for c in s.chars().flat_map(|c| c.escape_debug()) { f.write_char(c)? } Ok(()) @@ -1064,9 +1064,9 @@ mod tests { #[test] fn wtf8buf_show() { - let mut string = Wtf8Buf::from_str("a\té 💩\r"); + let mut string = Wtf8Buf::from_str("a\té \u{7f}💩\r"); string.push(CodePoint::from_u32(0xD800).unwrap()); - assert_eq!(format!("{:?}", string), r#""a\t\u{e9} \u{1f4a9}\r\u{D800}""#); + assert_eq!(format!("{:?}", string), "\"a\\té \\u{7f}\u{1f4a9}\\r\\u{D800}\""); } #[test] diff --git a/src/test/run-pass/sync-send-iterators-in-libcore.rs b/src/test/run-pass/sync-send-iterators-in-libcore.rs index 93178994815..d12bdf182fa 100644 --- a/src/test/run-pass/sync-send-iterators-in-libcore.rs +++ b/src/test/run-pass/sync-send-iterators-in-libcore.rs @@ -67,7 +67,7 @@ macro_rules! is_sync_send { fn main() { // for char.rs - all_sync_send!("Я", escape_default, escape_unicode); + all_sync_send!("Я", escape_debug, escape_default, escape_unicode); // for iter.rs all_sync_send_mutable_ref!([1], iter); -- cgit 1.4.1-3-g733a5 From 52c50ba276ffbdbe9c1a56e4f0b7d424f6bc22cc Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 28 Jul 2016 02:53:34 +0200 Subject: Add doc examples for std::fs::Metadata --- src/libstd/fs.rs | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'src/libstd') diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index 48753ccf1c3..38fd93501a5 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -694,6 +694,23 @@ impl Metadata { /// /// This field may not be available on all platforms, and will return an /// `Err` on platforms where it is not available. + /// + /// # Examples + /// + /// ``` + /// # fn foo() -> std::io::Result<()> { + /// use std::fs; + /// + /// let metadata = try!(fs::metadata("foo.txt")); + /// + /// if let Ok(time) = metadata.modified() { + /// println!("{:?}", time); + /// } else { + /// println!("Not supported on this platform"); + /// } + /// # Ok(()) + /// # } + /// ``` #[stable(feature = "fs_time", since = "1.10.0")] pub fn modified(&self) -> io::Result { self.0.modified().map(FromInner::from_inner) @@ -712,6 +729,23 @@ impl Metadata { /// /// This field may not be available on all platforms, and will return an /// `Err` on platforms where it is not available. + /// + /// # Examples + /// + /// ``` + /// # fn foo() -> std::io::Result<()> { + /// use std::fs; + /// + /// let metadata = try!(fs::metadata("foo.txt")); + /// + /// if let Ok(time) = metadata.accessed() { + /// println!("{:?}", time); + /// } else { + /// println!("Not supported on this platform"); + /// } + /// # Ok(()) + /// # } + /// ``` #[stable(feature = "fs_time", since = "1.10.0")] pub fn accessed(&self) -> io::Result { self.0.accessed().map(FromInner::from_inner) @@ -726,6 +760,23 @@ impl Metadata { /// /// This field may not be available on all platforms, and will return an /// `Err` on platforms where it is not available. + /// + /// # Examples + /// + /// ``` + /// # fn foo() -> std::io::Result<()> { + /// use std::fs; + /// + /// let metadata = try!(fs::metadata("foo.txt")); + /// + /// if let Ok(time) = metadata.created() { + /// println!("{:?}", time); + /// } else { + /// println!("Not supported on this platform"); + /// } + /// # Ok(()) + /// # } + /// ``` #[stable(feature = "fs_time", since = "1.10.0")] pub fn created(&self) -> io::Result { self.0.created().map(FromInner::from_inner) -- cgit 1.4.1-3-g733a5 From 8d3f20f9061273b215a7d86f8783f1ae66f9b3ae Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 28 Jul 2016 12:55:58 +0200 Subject: Add doc examples for std::fs::unix::OpenOptionsExt --- src/libstd/sys/unix/ext/fs.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src/libstd') diff --git a/src/libstd/sys/unix/ext/fs.rs b/src/libstd/sys/unix/ext/fs.rs index 54340773a42..1e0dc3c833e 100644 --- a/src/libstd/sys/unix/ext/fs.rs +++ b/src/libstd/sys/unix/ext/fs.rs @@ -63,6 +63,18 @@ pub trait OpenOptionsExt { /// If no `mode` is set, the default of `0o666` will be used. /// The operating system masks out bits with the systems `umask`, to produce /// the final permissions. + /// + /// # Examples + /// + /// ```rust,ignore + /// extern crate libc; + /// use std::fs::OpenOptions; + /// use std::os::unix::fs::OpenOptionsExt; + /// + /// let mut options = OpenOptions::new(); + /// options.mode(0o644); // Give read/write for owner and read for others. + /// let file = options.open("foo.txt"); + /// ``` #[stable(feature = "fs_ext", since = "1.1.0")] fn mode(&mut self, mode: u32) -> &mut Self; -- cgit 1.4.1-3-g733a5 From 123bf1e95d05282dc32d9a2403859dd827d84309 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 28 Jul 2016 13:04:24 +0200 Subject: Add OpenOptionsExt doc examples --- src/libstd/sys/unix/ext/fs.rs | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'src/libstd') diff --git a/src/libstd/sys/unix/ext/fs.rs b/src/libstd/sys/unix/ext/fs.rs index 1e0dc3c833e..77587918ac9 100644 --- a/src/libstd/sys/unix/ext/fs.rs +++ b/src/libstd/sys/unix/ext/fs.rs @@ -25,15 +25,53 @@ use sys::platform::fs::MetadataExt as UnixMetadataExt; pub trait PermissionsExt { /// Returns the underlying raw `mode_t` bits that are the standard Unix /// permissions for this file. + /// + /// # Examples + /// + /// ```rust,ignore + /// use std::fs::File; + /// use std::os::unix::fs::PermissionsExt; + /// + /// let f = try!(File::create("foo.txt")); + /// let metadata = try!(f.metadata()); + /// let permissions = metadata.permissions(); + /// + /// println!("permissions: {}", permissions.mode()); + /// ``` #[stable(feature = "fs_ext", since = "1.1.0")] fn mode(&self) -> u32; /// Sets the underlying raw bits for this set of permissions. + /// + /// # Examples + /// + /// ```rust,ignore + /// use std::fs::File; + /// use std::os::unix::fs::PermissionsExt; + /// + /// let f = try!(File::create("foo.txt")); + /// let metadata = try!(f.metadata()); + /// let mut permissions = metadata.permissions(); + /// + /// permissions.set_mode(0o644); // Read/write for owner and read for others. + /// assert_eq!(permissions.mode(), 0o644); + /// ``` #[stable(feature = "fs_ext", since = "1.1.0")] fn set_mode(&mut self, mode: u32); /// Creates a new instance of `Permissions` from the given set of Unix /// permission bits. + /// + /// # Examples + /// + /// ```rust,ignore + /// use std::fs::Permissions; + /// use std::os::unix::fs::PermissionsExt; + /// + /// // Read/write for owner and read for others. + /// let permissions = Permissions::from_mode(0o644); + /// assert_eq!(permissions.mode(), 0o644); + /// ``` #[stable(feature = "fs_ext", since = "1.1.0")] fn from_mode(mode: u32) -> Self; } -- cgit 1.4.1-3-g733a5 From bb6c27e74d08b78709b6fb87f5cb149f4366ccb6 Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Thu, 28 Jul 2016 11:30:38 +0200 Subject: Escape the unmatched surrogates with lower-case hexadecimal numbers It's done the same way for the rest of the codepoint escapes. --- src/libstd/sys/common/wtf8.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/libstd') diff --git a/src/libstd/sys/common/wtf8.rs b/src/libstd/sys/common/wtf8.rs index c0e6ec46b55..c1b4f8a8c88 100644 --- a/src/libstd/sys/common/wtf8.rs +++ b/src/libstd/sys/common/wtf8.rs @@ -408,7 +408,7 @@ impl fmt::Debug for Wtf8 { &self.bytes[pos .. surrogate_pos] )}, )?; - write!(formatter, "\\u{{{:X}}}", surrogate)?; + write!(formatter, "\\u{{{:x}}}", surrogate)?; pos = surrogate_pos + 3; } } @@ -1066,7 +1066,7 @@ mod tests { fn wtf8buf_show() { let mut string = Wtf8Buf::from_str("a\té \u{7f}💩\r"); string.push(CodePoint::from_u32(0xD800).unwrap()); - assert_eq!(format!("{:?}", string), "\"a\\té \\u{7f}\u{1f4a9}\\r\\u{D800}\""); + assert_eq!(format!("{:?}", string), "\"a\\té \\u{7f}\u{1f4a9}\\r\\u{d800}\""); } #[test] -- cgit 1.4.1-3-g733a5 From e805cb6374550190f8b3c4582fe67ae40d5b7a16 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 29 Jul 2016 14:32:35 +0200 Subject: Add io::Error doc examples --- src/libstd/io/error.rs | 145 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) (limited to 'src/libstd') diff --git a/src/libstd/io/error.rs b/src/libstd/io/error.rs index 05ae8ed5b0b..63016a1a795 100644 --- a/src/libstd/io/error.rs +++ b/src/libstd/io/error.rs @@ -208,6 +208,14 @@ impl Error { /// This function reads the value of `errno` for the target platform (e.g. /// `GetLastError` on Windows) and will return a corresponding instance of /// `Error` for the error code. + /// + /// # Examples + /// + /// ``` + /// use std::io::Error; + /// + /// println!("last OS error: {:?}", Error::last_os_error()); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn last_os_error() -> Error { Error::from_raw_os_error(sys::os::errno() as i32) @@ -248,6 +256,27 @@ impl Error { /// If this `Error` was constructed via `last_os_error` or /// `from_raw_os_error`, then this function will return `Some`, otherwise /// it will return `None`. + /// + /// # Examples + /// + /// ``` + /// use std::io::{Error, ErrorKind}; + /// + /// fn print_os_error(err: &Error) { + /// if let Some(raw_os_err) = err.raw_os_error() { + /// println!("raw OS error: {:?}", raw_os_err); + /// } else { + /// println!("Not an OS error"); + /// } + /// } + /// + /// fn main() { + /// // Will print "raw OS error: ...". + /// print_os_error(&Error::last_os_error()); + /// // Will print "Not an OS error". + /// print_os_error(&Error::new(ErrorKind::Other, "oh no!")); + /// } + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn raw_os_error(&self) -> Option { match self.repr { @@ -260,6 +289,27 @@ impl Error { /// /// If this `Error` was constructed via `new` then this function will /// return `Some`, otherwise it will return `None`. + /// + /// # Examples + /// + /// ``` + /// use std::io::{Error, ErrorKind}; + /// + /// fn print_error(err: &Error) { + /// if let Some(inner_err) = err.get_ref() { + /// println!("Inner error: {:?}", inner_err); + /// } else { + /// println!("No inner error"); + /// } + /// } + /// + /// fn main() { + /// // Will print "No inner error". + /// print_error(&Error::last_os_error()); + /// // Will print "Inner error: ...". + /// print_error(&Error::new(ErrorKind::Other, "oh no!")); + /// } + /// ``` #[stable(feature = "io_error_inner", since = "1.3.0")] pub fn get_ref(&self) -> Option<&(error::Error+Send+Sync+'static)> { match self.repr { @@ -273,6 +323,63 @@ impl Error { /// /// If this `Error` was constructed via `new` then this function will /// return `Some`, otherwise it will return `None`. + /// + /// # Examples + /// + /// ``` + /// use std::io::{Error, ErrorKind}; + /// use std::{error, fmt}; + /// use std::fmt::Display; + /// + /// #[derive(Debug)] + /// struct MyError { + /// v: String, + /// } + /// + /// impl MyError { + /// fn new() -> MyError { + /// MyError { + /// v: "oh no!".to_owned() + /// } + /// } + /// + /// fn change_message(&mut self, new_message: &str) { + /// self.v = new_message.to_owned(); + /// } + /// } + /// + /// impl error::Error for MyError { + /// fn description(&self) -> &str { &self.v } + /// } + /// + /// impl Display for MyError { + /// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + /// write!(f, "MyError: {}", &self.v) + /// } + /// } + /// + /// fn change_error(mut err: Error) -> Error { + /// if let Some(inner_err) = err.get_mut() { + /// inner_err.downcast_mut::().unwrap().change_message("I've been changed!"); + /// } + /// err + /// } + /// + /// fn print_error(err: &Error) { + /// if let Some(inner_err) = err.get_ref() { + /// println!("Inner error: {}", inner_err); + /// } else { + /// println!("No inner error"); + /// } + /// } + /// + /// fn main() { + /// // Will print "No inner error". + /// print_error(&change_error(Error::last_os_error())); + /// // Will print "Inner error: ...". + /// print_error(&change_error(Error::new(ErrorKind::Other, MyError::new()))); + /// } + /// ``` #[stable(feature = "io_error_inner", since = "1.3.0")] pub fn get_mut(&mut self) -> Option<&mut (error::Error+Send+Sync+'static)> { match self.repr { @@ -285,6 +392,27 @@ impl Error { /// /// If this `Error` was constructed via `new` then this function will /// return `Some`, otherwise it will return `None`. + /// + /// # Examples + /// + /// ``` + /// use std::io::{Error, ErrorKind}; + /// + /// fn print_error(err: Error) { + /// if let Some(inner_err) = err.into_inner() { + /// println!("Inner error: {}", inner_err); + /// } else { + /// println!("No inner error"); + /// } + /// } + /// + /// fn main() { + /// // Will print "No inner error". + /// print_error(Error::last_os_error()); + /// // Will print "Inner error: ...". + /// print_error(Error::new(ErrorKind::Other, "oh no!")); + /// } + /// ``` #[stable(feature = "io_error_inner", since = "1.3.0")] pub fn into_inner(self) -> Option> { match self.repr { @@ -294,6 +422,23 @@ impl Error { } /// Returns the corresponding `ErrorKind` for this error. + /// + /// # Examples + /// + /// ``` + /// use std::io::{Error, ErrorKind}; + /// + /// fn print_error(err: Error) { + /// println!("{:?}", err.kind()); + /// } + /// + /// fn main() { + /// // Will print "No inner error". + /// print_error(Error::last_os_error()); + /// // Will print "Inner error: ...". + /// print_error(Error::new(ErrorKind::AddrInUse, "oh no!")); + /// } + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn kind(&self) -> ErrorKind { match self.repr { -- cgit 1.4.1-3-g733a5 From aad5f6f912298bd0a4cc1dea698b652f81badd29 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 30 Jul 2016 00:53:18 +0200 Subject: Add doc example for io::Stderr --- src/libstd/io/stdio.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'src/libstd') diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index c4b573db5f2..a25bc038b7b 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -505,6 +505,21 @@ impl Stderr { /// /// The lock is released when the returned lock goes out of scope. The /// returned guard also implements the `Write` trait for writing data. + /// + /// # Examples + /// + /// ``` + /// use std::io::{self, Write}; + /// + /// fn foo() -> io::Result<()> { + /// let stderr = io::stderr(); + /// let mut handle = stderr.lock(); + /// + /// try!(handle.write(b"hello world")); + /// + /// Ok(()) + /// } + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn lock(&self) -> StderrLock { StderrLock { inner: self.inner.lock().unwrap_or_else(|e| e.into_inner()) } -- cgit 1.4.1-3-g733a5 From 451683f0eec360bf4adbec5c19be764b7fac79e4 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 30 Jul 2016 00:56:14 +0200 Subject: Add doc example for Stdin --- src/libstd/io/stdio.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'src/libstd') diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index a25bc038b7b..d7566d5c9a4 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -240,6 +240,21 @@ impl Stdin { /// /// [`Read`]: trait.Read.html /// [`BufRead`]: trait.BufRead.html + /// + /// # Examples + /// + /// ``` + /// use std::io::{self, Read}; + /// + /// # fn foo() -> io::Result { + /// let mut buffer = String::new(); + /// let stdin = io::stdin(); + /// let mut handle = stdin.lock(); + /// + /// try!(handle.read_to_string(&mut buffer)); + /// # Ok(buffer) + /// # } + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn lock(&self) -> StdinLock { StdinLock { inner: self.inner.lock().unwrap_or_else(|e| e.into_inner()) } -- cgit 1.4.1-3-g733a5 From aeb3af898ae426031376a345f91e04bfc7af32f8 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 30 Jul 2016 00:57:20 +0200 Subject: Add doc example for Stdout --- src/libstd/io/stdio.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'src/libstd') diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index d7566d5c9a4..b8b66a58359 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -414,6 +414,21 @@ impl Stdout { /// /// The lock is released when the returned lock goes out of scope. The /// returned guard also implements the `Write` trait for writing data. + /// + /// # Examples + /// + /// ``` + /// use std::io::{self, Write}; + /// + /// # fn foo() -> io::Result<()> { + /// let stdout = io::stdout(); + /// let mut handle = stdout.lock(); + /// + /// try!(handle.write(b"hello world")); + /// + /// # Ok(()) + /// # } + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn lock(&self) -> StdoutLock { StdoutLock { inner: self.inner.lock().unwrap_or_else(|e| e.into_inner()) } -- cgit 1.4.1-3-g733a5 From 2bed205d3be05682b84693edeed4d84d850eb801 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 30 Jul 2016 13:30:41 +0200 Subject: Add io::Take doc example --- src/libstd/io/mod.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'src/libstd') diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index d5b255ee573..3d1ee5b7ae7 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -1482,6 +1482,24 @@ impl Take { /// /// This instance may reach EOF after reading fewer bytes than indicated by /// this method if the underlying `Read` instance reaches EOF. + /// + /// # Examples + /// + /// ``` + /// use std::io; + /// use std::io::prelude::*; + /// use std::fs::File; + /// + /// # fn foo() -> io::Result<()> { + /// let f = try!(File::open("foo.txt")); + /// + /// // read at most five bytes + /// let handle = f.take(5); + /// + /// println!("limit: {}", handle.limit()); + /// # Ok(()) + /// # } + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn limit(&self) -> u64 { self.limit } } -- cgit 1.4.1-3-g733a5 From fda473f00fa07b9a8246b104396f9922e54bff16 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 30 Jul 2016 13:37:52 +0200 Subject: Add urls in std::io types --- src/libstd/io/error.rs | 8 +++++++- src/libstd/io/mod.rs | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) (limited to 'src/libstd') diff --git a/src/libstd/io/error.rs b/src/libstd/io/error.rs index 63016a1a795..5333b0a531e 100644 --- a/src/libstd/io/error.rs +++ b/src/libstd/io/error.rs @@ -55,7 +55,9 @@ pub type Result = result::Result; /// /// Errors mostly originate from the underlying OS, but custom instances of /// `Error` can be created with crafted error messages and a particular value of -/// `ErrorKind`. +/// [`ErrorKind`]. +/// +/// [`ErrorKind`]: enum.ErrorKind.html #[derive(Debug)] #[stable(feature = "rust1", since = "1.0.0")] pub struct Error { @@ -77,6 +79,10 @@ struct Custom { /// /// This list is intended to grow over time and it is not recommended to /// exhaustively match against it. +/// +/// It is used with the [`io::Error`] type. +/// +/// [`io::Error`]: struct.Error.html #[derive(Copy, PartialEq, Eq, Clone, Debug)] #[stable(feature = "rust1", since = "1.0.0")] #[allow(deprecated)] diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 3d1ee5b7ae7..88fd4186e0a 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -1082,16 +1082,22 @@ pub trait Seek { /// /// If the seek operation completed successfully, /// this method returns the new position from the start of the stream. - /// That position can be used later with `SeekFrom::Start`. + /// That position can be used later with [`SeekFrom::Start`]. /// /// # Errors /// /// Seeking to a negative offset is considered an error. + /// + /// [`SeekFrom::Start`]: enum.SeekFrom.html#variant.Start #[stable(feature = "rust1", since = "1.0.0")] fn seek(&mut self, pos: SeekFrom) -> Result; } /// Enumeration of possible methods to seek within an I/O object. +/// +/// It is used by the [`Seek`] trait. +/// +/// [`Seek`]: trait.Seek.html #[derive(Copy, PartialEq, Eq, Clone, Debug)] #[stable(feature = "rust1", since = "1.0.0")] pub enum SeekFrom { -- cgit 1.4.1-3-g733a5 From 57cad5722db3043804bc4c38ec3b456e9ff497be Mon Sep 17 00:00:00 2001 From: Timon Van Overveldt Date: Wed, 27 Apr 2016 18:02:31 -0700 Subject: Update gcc crate dependency to 0.3.27. This is to pull in changes to support ARM MUSL targets. This change also commits a couple of other cargo-generated changes to other dependencies in the various Cargo.toml files. --- src/bootstrap/Cargo.lock | 12 ++++++------ src/liballoc_jemalloc/Cargo.toml | 2 +- src/libflate/Cargo.toml | 2 +- src/librustc_llvm/Cargo.toml | 2 +- src/librustdoc/Cargo.toml | 2 +- src/libstd/Cargo.toml | 2 +- src/rustc/std_shim/Cargo.lock | 6 +++--- 7 files changed, 14 insertions(+), 14 deletions(-) (limited to 'src/libstd') diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock index 1290f2a404b..02698d6f7a1 100644 --- a/src/bootstrap/Cargo.lock +++ b/src/bootstrap/Cargo.lock @@ -7,8 +7,8 @@ dependencies = [ "filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "gcc 0.3.31 (git+https://github.com/alexcrichton/gcc-rs)", "getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "md5 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", @@ -33,7 +33,7 @@ name = "filetime" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -53,7 +53,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "kernel32-sys" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -62,7 +62,7 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -75,7 +75,7 @@ name = "num_cpus" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/src/liballoc_jemalloc/Cargo.toml b/src/liballoc_jemalloc/Cargo.toml index 768a0c2c0a5..25b3c8a3a0a 100644 --- a/src/liballoc_jemalloc/Cargo.toml +++ b/src/liballoc_jemalloc/Cargo.toml @@ -16,7 +16,7 @@ libc = { path = "../rustc/libc_shim" } [build-dependencies] build_helper = { path = "../build_helper" } -gcc = "0.3.17" +gcc = "0.3.27" [features] debug = [] diff --git a/src/libflate/Cargo.toml b/src/libflate/Cargo.toml index 52aa6bb86ef..5423da9c81c 100644 --- a/src/libflate/Cargo.toml +++ b/src/libflate/Cargo.toml @@ -11,4 +11,4 @@ crate-type = ["dylib"] [build-dependencies] build_helper = { path = "../build_helper" } -gcc = "0.3" +gcc = "0.3.27" diff --git a/src/librustc_llvm/Cargo.toml b/src/librustc_llvm/Cargo.toml index 05d20911a5d..f97daa22ff6 100644 --- a/src/librustc_llvm/Cargo.toml +++ b/src/librustc_llvm/Cargo.toml @@ -17,4 +17,4 @@ rustc_bitflags = { path = "../librustc_bitflags" } [build-dependencies] build_helper = { path = "../build_helper" } -gcc = "0.3" +gcc = "0.3.27" diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index a41d3b0253a..3e510bdc900 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -28,4 +28,4 @@ log = { path = "../liblog" } [build-dependencies] build_helper = { path = "../build_helper" } -gcc = "0.3" +gcc = "0.3.27" diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml index b442d21b72b..3ce6841fdd4 100644 --- a/src/libstd/Cargo.toml +++ b/src/libstd/Cargo.toml @@ -24,7 +24,7 @@ unwind = { path = "../libunwind" } [build-dependencies] build_helper = { path = "../build_helper" } -gcc = "0.3" +gcc = "0.3.27" [features] backtrace = [] diff --git a/src/rustc/std_shim/Cargo.lock b/src/rustc/std_shim/Cargo.lock index bad46966ffa..70aef55d799 100644 --- a/src/rustc/std_shim/Cargo.lock +++ b/src/rustc/std_shim/Cargo.lock @@ -18,7 +18,7 @@ version = "0.0.0" dependencies = [ "build_helper 0.1.0", "core 0.0.0", - "gcc 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.0.0", ] @@ -49,7 +49,7 @@ version = "0.0.0" [[package]] name = "gcc" -version = "0.3.26" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -101,7 +101,7 @@ dependencies = [ "build_helper 0.1.0", "collections 0.0.0", "core 0.0.0", - "gcc 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.0.0", "panic_abort 0.0.0", "panic_unwind 0.0.0", -- cgit 1.4.1-3-g733a5 From f7247d1071206db45103c994b0077fcb0d8f75cf Mon Sep 17 00:00:00 2001 From: Timon Van Overveldt Date: Wed, 27 Apr 2016 18:02:31 -0700 Subject: Add ARM MUSL targets. The targets are: - `arm-unknown-linux-musleabi` - `arm-unknown-linux-musleabihf` - `armv7-unknown-linux-musleabihf` These mirror the existing `gnueabi` targets. All of these targets produce fully static binaries, similar to the x86 MUSL targets. For now these targets can only be used with `--rustbuild` builds, as https://github.com/rust-lang/compiler-rt/pull/22 only made the necessary compiler-rt changes in the CMake configs, not the plain GNU Make configs. I've tested these targets GCC 5.3.0 compiled again musl-1.1.12 (downloaded from http://musl.codu.org/). An example `./configure` invocation is: ``` ./configure \ --enable-rustbuild --target=arm-unknown-linux-musleabi \ --musl-root="$MUSL_ROOT" ``` where `MUSL_ROOT` points to the `arm-linux-musleabi` prefix. Usually that path will be of the form `/foobar/arm-linux-musleabi/arm-linux-musleabi`. Usually the cross-compile toolchain will live under `/foobar/arm-linux-musleabi/bin`. That path should either by added to your `PATH` variable, or you should add a section to your `config.toml` as follows: ``` [target.arm-unknown-linux-musleabi] cc = "/foobar/arm-linux-musleabi/bin/arm-linux-musleabi-gcc" cxx = "/foobar/arm-linux-musleabi/bin/arm-linux-musleabi-g++" ``` As a prerequisite you'll also have to put a cross-compiled static `libunwind.a` library in `$MUSL_ROOT/lib`. This is similar to [how the x86_64 MUSL targets are built] (https://doc.rust-lang.org/book/advanced-linking.html). --- configure | 2 +- mk/cfg/arm-unknown-linux-musleabi.mk | 3 + mk/cfg/arm-unknown-linux-musleabihf.mk | 3 + mk/cfg/armv7-unknown-linux-musleabihf.mk | 3 + src/bootstrap/compile.rs | 3 +- src/bootstrap/sanity.rs | 2 +- src/liballoc_jemalloc/build.rs | 11 +++- src/liballoc_jemalloc/lib.rs | 4 +- .../target/arm_unknown_linux_musleabi.rs | 33 ++++++++++ .../target/arm_unknown_linux_musleabihf.rs | 33 ++++++++++ .../target/armv7_unknown_linux_musleabihf.rs | 34 ++++++++++ src/librustc_back/target/mod.rs | 4 ++ src/librustc_back/target/musl_base.rs | 72 ++++++++++++++++++++++ src/libstd/rtdeps.rs | 4 +- src/libstd/sys/unix/thread.rs | 8 ++- 15 files changed, 210 insertions(+), 9 deletions(-) create mode 100644 mk/cfg/arm-unknown-linux-musleabi.mk create mode 100644 mk/cfg/arm-unknown-linux-musleabihf.mk create mode 100644 mk/cfg/armv7-unknown-linux-musleabihf.mk create mode 100644 src/librustc_back/target/arm_unknown_linux_musleabi.rs create mode 100644 src/librustc_back/target/arm_unknown_linux_musleabihf.rs create mode 100644 src/librustc_back/target/armv7_unknown_linux_musleabihf.rs create mode 100644 src/librustc_back/target/musl_base.rs (limited to 'src/libstd') diff --git a/configure b/configure index d2ec457a1c8..a7e24a506fb 100755 --- a/configure +++ b/configure @@ -1192,7 +1192,7 @@ do ;; - x86_64-*-musl) + x86_64-*-musl | arm-*-musleabi) if [ ! -f $CFG_MUSL_ROOT/lib/libc.a ] then err "musl libc $CFG_MUSL_ROOT/lib/libc.a not found" diff --git a/mk/cfg/arm-unknown-linux-musleabi.mk b/mk/cfg/arm-unknown-linux-musleabi.mk new file mode 100644 index 00000000000..8120250150d --- /dev/null +++ b/mk/cfg/arm-unknown-linux-musleabi.mk @@ -0,0 +1,3 @@ +# This file is intentially left empty to indicate that, while this target is +# supported, it's not supported using plain GNU Make builds. Use a --rustbuild +# instead. \ No newline at end of file diff --git a/mk/cfg/arm-unknown-linux-musleabihf.mk b/mk/cfg/arm-unknown-linux-musleabihf.mk new file mode 100644 index 00000000000..8120250150d --- /dev/null +++ b/mk/cfg/arm-unknown-linux-musleabihf.mk @@ -0,0 +1,3 @@ +# This file is intentially left empty to indicate that, while this target is +# supported, it's not supported using plain GNU Make builds. Use a --rustbuild +# instead. \ No newline at end of file diff --git a/mk/cfg/armv7-unknown-linux-musleabihf.mk b/mk/cfg/armv7-unknown-linux-musleabihf.mk new file mode 100644 index 00000000000..8120250150d --- /dev/null +++ b/mk/cfg/armv7-unknown-linux-musleabihf.mk @@ -0,0 +1,3 @@ +# This file is intentially left empty to indicate that, while this target is +# supported, it's not supported using plain GNU Make builds. Use a --rustbuild +# instead. \ No newline at end of file diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 8ec9c7f0109..061192ebd13 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -92,8 +92,7 @@ pub fn std_link(build: &Build, } add_to_sysroot(&out_dir, &libdir); - if target.contains("musl") && - (target.contains("x86_64") || target.contains("i686")) { + if target.contains("musl") && !target.contains("mips") { copy_third_party_objects(build, target, &libdir); } } diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs index 73749246758..09f96782e71 100644 --- a/src/bootstrap/sanity.rs +++ b/src/bootstrap/sanity.rs @@ -109,7 +109,7 @@ pub fn check(build: &mut Build) { } // Make sure musl-root is valid if specified - if target.contains("musl") && (target.contains("x86_64") || target.contains("i686")) { + if target.contains("musl") && !target.contains("mips") { match build.config.musl_root { Some(ref root) => { if fs::metadata(root.join("lib/libc.a")).is_err() { diff --git a/src/liballoc_jemalloc/build.rs b/src/liballoc_jemalloc/build.rs index d1b3583d256..dc1b8d6ea98 100644 --- a/src/liballoc_jemalloc/build.rs +++ b/src/liballoc_jemalloc/build.rs @@ -73,7 +73,16 @@ fn main() { .replace("\\", "/")) .current_dir(&build_dir) .env("CC", compiler.path()) - .env("EXTRA_CFLAGS", cflags) + .env("EXTRA_CFLAGS", cflags.clone()) + // jemalloc generates Makefile deps using GCC's "-MM" flag. This means + // that GCC will run the preprocessor, and only the preprocessor, over + // jemalloc's source files. If we don't specify CPPFLAGS, then at least + // on ARM that step fails with a "Missing implementation for 32-bit + // atomic operations" error. This is because no "-march" flag will be + // passed to GCC, and then GCC won't define the + // "__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4" macro that jemalloc needs to + // select an atomic operation implementation. + .env("CPPFLAGS", cflags.clone()) .env("AR", &ar) .env("RANLIB", format!("{} s", ar.display())); diff --git a/src/liballoc_jemalloc/lib.rs b/src/liballoc_jemalloc/lib.rs index 347e97e6ffc..ccf3d978fe4 100644 --- a/src/liballoc_jemalloc/lib.rs +++ b/src/liballoc_jemalloc/lib.rs @@ -36,7 +36,9 @@ use libc::{c_int, c_void, size_t}; #[cfg_attr(target_os = "android", link(name = "gcc"))] #[cfg_attr(all(not(windows), not(target_os = "android"), - not(target_env = "musl")), + not(target_env = "musl"), + not(target_env = "musleabi"), + not(target_env = "musleabihf")), link(name = "pthread"))] #[cfg(not(cargobuild))] extern "C" {} diff --git a/src/librustc_back/target/arm_unknown_linux_musleabi.rs b/src/librustc_back/target/arm_unknown_linux_musleabi.rs new file mode 100644 index 00000000000..906f60f1c9a --- /dev/null +++ b/src/librustc_back/target/arm_unknown_linux_musleabi.rs @@ -0,0 +1,33 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use target::Target; + +pub fn target() -> Target { + let mut base = super::musl_base::opts(); + + // Most of these settings are copied from the arm_unknown_linux_gnueabi + // target. + base.features = "+v6".to_string(); + Target { + // It's important we use "gnueabi" and not "musleabi" here. LLVM uses it + // to determine the calling convention and float ABI, and it doesn't + // support the "musleabi" value. + llvm_target: "arm-unknown-linux-gnueabi".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "32".to_string(), + data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), + arch: "arm".to_string(), + target_os: "linux".to_string(), + target_env: "musleabi".to_string(), + target_vendor: "unknown".to_string(), + options: base, + } +} diff --git a/src/librustc_back/target/arm_unknown_linux_musleabihf.rs b/src/librustc_back/target/arm_unknown_linux_musleabihf.rs new file mode 100644 index 00000000000..3051721b8c2 --- /dev/null +++ b/src/librustc_back/target/arm_unknown_linux_musleabihf.rs @@ -0,0 +1,33 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use target::Target; + +pub fn target() -> Target { + let mut base = super::musl_base::opts(); + + // Most of these settings are copied from the arm_unknown_linux_gnueabihf + // target. + base.features = "+v6,+vfp2".to_string(); + Target { + // It's important we use "gnueabihf" and not "musleabihf" here. LLVM + // uses it to determine the calling convention and float ABI, and it + // doesn't support the "musleabihf" value. + llvm_target: "arm-unknown-linux-gnueabihf".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "32".to_string(), + data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), + arch: "arm".to_string(), + target_os: "linux".to_string(), + target_env: "musleabi".to_string(), + target_vendor: "unknown".to_string(), + options: base, + } +} diff --git a/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs b/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs new file mode 100644 index 00000000000..8732681fb49 --- /dev/null +++ b/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs @@ -0,0 +1,34 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use target::Target; + +pub fn target() -> Target { + let mut base = super::musl_base::opts(); + + // Most of these settings are copied from the armv7_unknown_linux_gnueabihf + // target. + base.features = "+v7,+vfp3,+neon".to_string(); + base.cpu = "cortex-a8".to_string(); + Target { + // It's important we use "gnueabihf" and not "musleabihf" here. LLVM + // uses it to determine the calling convention and float ABI, and LLVM + // doesn't support the "musleabihf" value. + llvm_target: "armv7-unknown-linux-gnueabihf".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "32".to_string(), + data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), + arch: "arm".to_string(), + target_os: "linux".to_string(), + target_env: "musleabi".to_string(), + target_vendor: "unknown".to_string(), + options: base, + } +} diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs index f5314809228..694b1340bbb 100644 --- a/src/librustc_back/target/mod.rs +++ b/src/librustc_back/target/mod.rs @@ -59,6 +59,7 @@ mod freebsd_base; mod linux_base; mod linux_musl_base; mod openbsd_base; +mod musl_base; mod netbsd_base; mod solaris_base; mod windows_base; @@ -134,7 +135,10 @@ supported_targets! { ("powerpc64le-unknown-linux-gnu", powerpc64le_unknown_linux_gnu), ("arm-unknown-linux-gnueabi", arm_unknown_linux_gnueabi), ("arm-unknown-linux-gnueabihf", arm_unknown_linux_gnueabihf), + ("arm-unknown-linux-musleabi", arm_unknown_linux_musleabi), + ("arm-unknown-linux-musleabihf", arm_unknown_linux_musleabihf), ("armv7-unknown-linux-gnueabihf", armv7_unknown_linux_gnueabihf), + ("armv7-unknown-linux-musleabihf", armv7_unknown_linux_musleabihf), ("aarch64-unknown-linux-gnu", aarch64_unknown_linux_gnu), ("x86_64-unknown-linux-musl", x86_64_unknown_linux_musl), ("i686-unknown-linux-musl", i686_unknown_linux_musl), diff --git a/src/librustc_back/target/musl_base.rs b/src/librustc_back/target/musl_base.rs new file mode 100644 index 00000000000..77cf015e1d9 --- /dev/null +++ b/src/librustc_back/target/musl_base.rs @@ -0,0 +1,72 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use target::TargetOptions; + +pub fn opts() -> TargetOptions { + let mut base = super::linux_base::opts(); + + // Make sure that the linker/gcc really don't pull in anything, including + // default objects, libs, etc. + base.pre_link_args.push("-nostdlib".to_string()); + base.pre_link_args.push("-static".to_string()); + + // At least when this was tested, the linker would not add the + // `GNU_EH_FRAME` program header to executables generated, which is required + // when unwinding to locate the unwinding information. I'm not sure why this + // argument is *not* necessary for normal builds, but it can't hurt! + base.pre_link_args.push("-Wl,--eh-frame-hdr".to_string()); + + // There's a whole bunch of circular dependencies when dealing with MUSL + // unfortunately. To put this in perspective libc is statically linked to + // liblibc and libunwind is statically linked to libstd: + // + // * libcore depends on `fmod` which is in libc (transitively in liblibc). + // liblibc, however, depends on libcore. + // * compiler-rt has personality symbols that depend on libunwind, but + // libunwind is in libstd which depends on compiler-rt. + // + // Recall that linkers discard libraries and object files as much as + // possible, and with all the static linking and archives flying around with + // MUSL the linker is super aggressively stripping out objects. For example + // the first case has fmod stripped from liblibc (it's in its own object + // file) so it's not there when libcore needs it. In the second example all + // the unused symbols from libunwind are stripped (each is in its own object + // file in libstd) before we end up linking compiler-rt which depends on + // those symbols. + // + // To deal with these circular dependencies we just force the compiler to + // link everything as a group, not stripping anything out until everything + // is processed. The linker will still perform a pass to strip out object + // files but it won't do so until all objects/archives have been processed. + base.pre_link_args.push("-Wl,-(".to_string()); + base.post_link_args.push("-Wl,-)".to_string()); + + // When generating a statically linked executable there's generally some + // small setup needed which is listed in these files. These are provided by + // a musl toolchain and are linked by default by the `musl-gcc` script. Note + // that `gcc` also does this by default, it just uses some different files. + // + // Each target directory for musl has these object files included in it so + // they'll be included from there. + base.pre_link_objects_exe.push("crt1.o".to_string()); + base.pre_link_objects_exe.push("crti.o".to_string()); + base.post_link_objects.push("crtn.o".to_string()); + + // MUSL support doesn't currently include dynamic linking, so there's no + // need for dylibs or rpath business. Additionally `-pie` is incompatible + // with `-static`, so we can't pass `-pie`. + base.dynamic_linking = false; + base.has_rpath = false; + base.position_independent_executables = false; + + return base; +} + diff --git a/src/libstd/rtdeps.rs b/src/libstd/rtdeps.rs index a11200873d5..f23ac32f51c 100644 --- a/src/libstd/rtdeps.rs +++ b/src/libstd/rtdeps.rs @@ -19,7 +19,9 @@ // // On Linux, librt and libdl are indirect dependencies via std, // and binutils 2.22+ won't add them automatically -#[cfg(all(target_os = "linux", not(target_env = "musl")))] +#[cfg(all(target_os = "linux", not(any(target_env = "musl", + target_env = "musleabi", + target_env = "musleabihf"))))] #[link(name = "dl")] #[link(name = "pthread")] extern {} diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index 1061ca87f64..7f05aec4e6e 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -171,7 +171,9 @@ impl Drop for Thread { } } -#[cfg(all(not(all(target_os = "linux", not(target_env = "musl"))), +#[cfg(all(not(all(target_os = "linux", not(any(target_env = "musl", + target_env = "musleabi", + target_env = "musleabihf")))), not(target_os = "freebsd"), not(target_os = "macos"), not(target_os = "bitrig"), @@ -185,7 +187,9 @@ pub mod guard { } -#[cfg(any(all(target_os = "linux", not(target_env = "musl")), +#[cfg(any(all(target_os = "linux", not(any(target_env = "musl", + target_env = "musleabi", + target_env = "musleabihf"))), target_os = "freebsd", target_os = "macos", target_os = "bitrig", -- cgit 1.4.1-3-g733a5 From 9ffd0fe5a75b8eb640f0bd94385c7b5f675c7e95 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Tue, 26 Jul 2016 16:17:14 -0500 Subject: arm-musl targets now use cfg(env = "musl") --- .gitmodules | 2 +- src/liballoc_jemalloc/lib.rs | 4 +--- src/liblibc | 2 +- src/librustc_back/target/arm_unknown_linux_musleabi.rs | 2 +- src/librustc_back/target/arm_unknown_linux_musleabihf.rs | 2 +- src/librustc_back/target/armv7_unknown_linux_musleabihf.rs | 2 +- src/libstd/rtdeps.rs | 4 +--- src/libstd/sys/unix/thread.rs | 8 ++------ 8 files changed, 9 insertions(+), 17 deletions(-) (limited to 'src/libstd') diff --git a/.gitmodules b/.gitmodules index 39288a7ae49..61697a37960 100644 --- a/.gitmodules +++ b/.gitmodules @@ -16,4 +16,4 @@ url = https://github.com/rust-lang/rust-installer.git [submodule "src/liblibc"] path = src/liblibc - url = https://github.com/rust-lang/libc.git + url = https://github.com/japaric/libc.git diff --git a/src/liballoc_jemalloc/lib.rs b/src/liballoc_jemalloc/lib.rs index ccf3d978fe4..347e97e6ffc 100644 --- a/src/liballoc_jemalloc/lib.rs +++ b/src/liballoc_jemalloc/lib.rs @@ -36,9 +36,7 @@ use libc::{c_int, c_void, size_t}; #[cfg_attr(target_os = "android", link(name = "gcc"))] #[cfg_attr(all(not(windows), not(target_os = "android"), - not(target_env = "musl"), - not(target_env = "musleabi"), - not(target_env = "musleabihf")), + not(target_env = "musl")), link(name = "pthread"))] #[cfg(not(cargobuild))] extern "C" {} diff --git a/src/liblibc b/src/liblibc index b0d62534d48..23a5092adce 160000 --- a/src/liblibc +++ b/src/liblibc @@ -1 +1 @@ -Subproject commit b0d62534d48b711c8978d1bbe8cca0558ae7b1cb +Subproject commit 23a5092adcecc8c755e7887337e52f357353cad7 diff --git a/src/librustc_back/target/arm_unknown_linux_musleabi.rs b/src/librustc_back/target/arm_unknown_linux_musleabi.rs index 906f60f1c9a..f2dff16a284 100644 --- a/src/librustc_back/target/arm_unknown_linux_musleabi.rs +++ b/src/librustc_back/target/arm_unknown_linux_musleabi.rs @@ -26,7 +26,7 @@ pub fn target() -> Target { data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), target_os: "linux".to_string(), - target_env: "musleabi".to_string(), + target_env: "musl".to_string(), target_vendor: "unknown".to_string(), options: base, } diff --git a/src/librustc_back/target/arm_unknown_linux_musleabihf.rs b/src/librustc_back/target/arm_unknown_linux_musleabihf.rs index 3051721b8c2..89da0213198 100644 --- a/src/librustc_back/target/arm_unknown_linux_musleabihf.rs +++ b/src/librustc_back/target/arm_unknown_linux_musleabihf.rs @@ -26,7 +26,7 @@ pub fn target() -> Target { data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), target_os: "linux".to_string(), - target_env: "musleabi".to_string(), + target_env: "musl".to_string(), target_vendor: "unknown".to_string(), options: base, } diff --git a/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs b/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs index 8732681fb49..3b9ac8e21f2 100644 --- a/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs +++ b/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs @@ -27,7 +27,7 @@ pub fn target() -> Target { data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), target_os: "linux".to_string(), - target_env: "musleabi".to_string(), + target_env: "musl".to_string(), target_vendor: "unknown".to_string(), options: base, } diff --git a/src/libstd/rtdeps.rs b/src/libstd/rtdeps.rs index f23ac32f51c..c2572dfa5e1 100644 --- a/src/libstd/rtdeps.rs +++ b/src/libstd/rtdeps.rs @@ -19,9 +19,7 @@ // // On Linux, librt and libdl are indirect dependencies via std, // and binutils 2.22+ won't add them automatically -#[cfg(all(target_os = "linux", not(any(target_env = "musl", - target_env = "musleabi", - target_env = "musleabihf"))))] +#[cfg(all(target_os = "linux", not(any(target_env = "musl"))))] #[link(name = "dl")] #[link(name = "pthread")] extern {} diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index 7f05aec4e6e..65ebce0baa2 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -171,9 +171,7 @@ impl Drop for Thread { } } -#[cfg(all(not(all(target_os = "linux", not(any(target_env = "musl", - target_env = "musleabi", - target_env = "musleabihf")))), +#[cfg(all(not(all(target_os = "linux", not(any(target_env = "musl")))), not(target_os = "freebsd"), not(target_os = "macos"), not(target_os = "bitrig"), @@ -187,9 +185,7 @@ pub mod guard { } -#[cfg(any(all(target_os = "linux", not(any(target_env = "musl", - target_env = "musleabi", - target_env = "musleabihf"))), +#[cfg(any(all(target_os = "linux", not(any(target_env = "musl"))), target_os = "freebsd", target_os = "macos", target_os = "bitrig", -- cgit 1.4.1-3-g733a5 From ea009939904021aaba59f9ca8038b646a65a27d6 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Wed, 27 Jul 2016 11:37:15 -0500 Subject: remove some `any`s that are no longer necessary --- src/libstd/rtdeps.rs | 2 +- src/libstd/sys/unix/thread.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/libstd') diff --git a/src/libstd/rtdeps.rs b/src/libstd/rtdeps.rs index c2572dfa5e1..a11200873d5 100644 --- a/src/libstd/rtdeps.rs +++ b/src/libstd/rtdeps.rs @@ -19,7 +19,7 @@ // // On Linux, librt and libdl are indirect dependencies via std, // and binutils 2.22+ won't add them automatically -#[cfg(all(target_os = "linux", not(any(target_env = "musl"))))] +#[cfg(all(target_os = "linux", not(target_env = "musl")))] #[link(name = "dl")] #[link(name = "pthread")] extern {} diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index 65ebce0baa2..1061ca87f64 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -171,7 +171,7 @@ impl Drop for Thread { } } -#[cfg(all(not(all(target_os = "linux", not(any(target_env = "musl")))), +#[cfg(all(not(all(target_os = "linux", not(target_env = "musl"))), not(target_os = "freebsd"), not(target_os = "macos"), not(target_os = "bitrig"), @@ -185,7 +185,7 @@ pub mod guard { } -#[cfg(any(all(target_os = "linux", not(any(target_env = "musl"))), +#[cfg(any(all(target_os = "linux", not(target_env = "musl")), target_os = "freebsd", target_os = "macos", target_os = "bitrig", -- cgit 1.4.1-3-g733a5 From 57e3b9eb713f44a9dce97be5840c536bd7a86069 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Mon, 1 Aug 2016 20:16:56 -0400 Subject: Indicate where the `std::net::Incoming` struct is created. --- src/libstd/net/tcp.rs | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/libstd') diff --git a/src/libstd/net/tcp.rs b/src/libstd/net/tcp.rs index 5ab0d5a0877..76617f15970 100644 --- a/src/libstd/net/tcp.rs +++ b/src/libstd/net/tcp.rs @@ -77,6 +77,11 @@ pub struct TcpListener(net_imp::TcpListener); /// /// This iterator will infinitely yield `Some` of the accepted connections. It /// is equivalent to calling `accept` in a loop. +/// +/// This `struct` is created by the [`incoming`] method on [`TcpListener`]. +/// +/// [`incoming`]: struct.TcpListener.html#method.incoming +/// [`TcpListener`]: struct.TcpListener.html #[stable(feature = "rust1", since = "1.0.0")] pub struct Incoming<'a> { listener: &'a TcpListener } -- cgit 1.4.1-3-g733a5 From f2d8db15dfe9b715f0e0a957440d79945270a20f Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Mon, 1 Aug 2016 20:21:08 -0400 Subject: Link to relevant method/struct for `std::net::Shutdown` docs. --- src/libstd/net/mod.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/libstd') diff --git a/src/libstd/net/mod.rs b/src/libstd/net/mod.rs index ac13b23ebee..11a16b27113 100644 --- a/src/libstd/net/mod.rs +++ b/src/libstd/net/mod.rs @@ -35,7 +35,11 @@ mod udp; mod parser; #[cfg(test)] mod test; -/// Possible values which can be passed to the `shutdown` method of `TcpStream`. +/// Possible values which can be passed to the [`shutdown`] method of +/// [`TcpStream`]. +/// +/// [`shutdown`]: struct.TcpStream.html#method.shutdown +/// [`TcpStream`]: struct.TcpStream.html #[derive(Copy, Clone, PartialEq, Debug)] #[stable(feature = "rust1", since = "1.0.0")] pub enum Shutdown { -- cgit 1.4.1-3-g733a5 From 3081dd863718f941e283ec954f36a23bbe58ffeb Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Tue, 2 Aug 2016 08:49:05 -0400 Subject: Add doc example for `std::ffi::NulError::nul_position`. --- src/libstd/ffi/c_str.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src/libstd') diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index 0d3e18f9b96..f800a6e228e 100644 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@ -356,6 +356,18 @@ impl Borrow for CString { impl NulError { /// Returns the position of the nul byte in the slice that was provided to /// `CString::new`. + /// + /// # Examples + /// + /// ``` + /// use std::ffi::CString; + /// + /// let nul_error = CString::new("foo\0bar").unwrap_err(); + /// assert_eq!(nul_error.nul_position(), 3); + /// + /// let nul_error = CString::new("foo bar\0").unwrap_err(); + /// assert_eq!(nul_error.nul_position(), 7); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn nul_position(&self) -> usize { self.0 } -- cgit 1.4.1-3-g733a5 From 3e46c9dfcc60733be20cc8de1361e809669e5096 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 27 Jul 2016 20:55:14 +0200 Subject: Add doc examples for FileType struct --- src/libstd/fs.rs | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) (limited to 'src/libstd') diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index 48753ccf1c3..2b2f21522d4 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -156,7 +156,10 @@ pub struct OpenOptions(fs_imp::OpenOptions); #[stable(feature = "rust1", since = "1.0.0")] pub struct Permissions(fs_imp::FilePermissions); -/// An structure representing a type of file with accessors for each file type. +/// A structure representing a type of file with accessors for each file type. +/// It is returned by [`Metadata::file_type`] method. +/// +/// [`Metadata::file_type`]: struct.Metadata.html#method.file_type #[stable(feature = "file_type", since = "1.1.0")] #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub struct FileType(fs_imp::FileType); @@ -610,6 +613,19 @@ impl AsInnerMut for OpenOptions { impl Metadata { /// Returns the file type for this metadata. + /// + /// # Examples + /// + /// ``` + /// # fn foo() -> std::io::Result<()> { + /// use std::fs; + /// + /// let metadata = try!(fs::metadata("foo.txt")); + /// + /// println!("{:?}", metadata.file_type()); + /// # Ok(()) + /// # } + /// ``` #[stable(feature = "file_type", since = "1.1.0")] pub fn file_type(&self) -> FileType { FileType(self.0.file_type()) @@ -788,14 +804,56 @@ impl Permissions { impl FileType { /// Test whether this file type represents a directory. + /// + /// # Examples + /// + /// ``` + /// # fn foo() -> std::io::Result<()> { + /// use std::fs; + /// + /// let metadata = try!(fs::metadata("foo.txt")); + /// let file_type = metadata.file_type(); + /// + /// assert_eq!(file_type.is_dir(), false); + /// # Ok(()) + /// # } + /// ``` #[stable(feature = "file_type", since = "1.1.0")] pub fn is_dir(&self) -> bool { self.0.is_dir() } /// Test whether this file type represents a regular file. + /// + /// # Examples + /// + /// ``` + /// # fn foo() -> std::io::Result<()> { + /// use std::fs; + /// + /// let metadata = try!(fs::metadata("foo.txt")); + /// let file_type = metadata.file_type(); + /// + /// assert_eq!(file_type.is_file(), true); + /// # Ok(()) + /// # } + /// ``` #[stable(feature = "file_type", since = "1.1.0")] pub fn is_file(&self) -> bool { self.0.is_file() } /// Test whether this file type represents a symbolic link. + /// + /// # Examples + /// + /// ``` + /// # fn foo() -> std::io::Result<()> { + /// use std::fs; + /// + /// let metadata = try!(fs::metadata("foo.txt")); + /// let file_type = metadata.file_type(); + /// + /// assert_eq!(file_type.is_symlink(), false); + /// # Ok(()) + /// # } + /// ``` #[stable(feature = "file_type", since = "1.1.0")] pub fn is_symlink(&self) -> bool { self.0.is_symlink() } } -- cgit 1.4.1-3-g733a5 From 4fc6f5ac264a58ddaaaf3d2ddfbe011eb675edaf Mon Sep 17 00:00:00 2001 From: Stefan Schindler Date: Wed, 3 Aug 2016 13:30:28 +0200 Subject: Add an example to `std::thread::park_timeout` --- src/libstd/thread/mod.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'src/libstd') diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index e9736fea7b3..40d5c700246 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -478,6 +478,25 @@ pub fn park_timeout_ms(ms: u32) { /// /// Platforms which do not support nanosecond precision for sleeping will have /// `dur` rounded up to the nearest granularity of time they can sleep for. +/// +/// # Example +/// +/// Waiting for the complete expiration of the timeout: +/// +/// ```rust,no_run +/// use std::thread::park_timeout; +/// use std::time::{Instant, Duration}; +/// +/// let timeout = Duration::from_secs(2); +/// let beginning_park = Instant::now(); +/// park_timeout(timeout); +/// +/// while beginning_park.elapsed() < timeout { +/// println!("restarting park_timeout after {:?}", beginning_park.elapsed()); +/// let timeout = timeout - beginning_park.elapsed(); +/// park_timeout(timeout); +/// } +/// ``` #[stable(feature = "park_timeout", since = "1.4.0")] pub fn park_timeout(dur: Duration) { let thread = current(); -- cgit 1.4.1-3-g733a5 From 20721a4923db5a8a462d8a8229d1f1a13e56e17c Mon Sep 17 00:00:00 2001 From: Stefan Schindler Date: Wed, 3 Aug 2016 13:34:49 +0200 Subject: Add link to replacement function --- src/libstd/thread/mod.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/libstd') diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 40d5c700246..f06c105d30e 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -447,6 +447,8 @@ pub fn park() { *guard = false; } +/// Use [park_timeout]. +/// /// Blocks unless or until the current thread's token is made available or /// the specified duration has been reached (may wake spuriously). /// @@ -456,7 +458,10 @@ pub fn park() { /// preemption or platform differences that may not cause the maximum /// amount of time waited to be precisely `ms` long. /// -/// See the module doc for more detail. +/// See the [module documentation][thread] for more detail. +/// +/// [thread]: index.html +/// [park_timeout]: fn.park_timeout.html #[stable(feature = "rust1", since = "1.0.0")] #[rustc_deprecated(since = "1.6.0", reason = "replaced by `std::thread::park_timeout`")] pub fn park_timeout_ms(ms: u32) { -- cgit 1.4.1-3-g733a5