From 29938fff3802243bdfe9a12860384d8eade20a7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Krasnoborski?= Date: Wed, 4 Mar 2015 22:24:38 +0100 Subject: [PATCH 01/37] Fix struct stat on arm linux --- src/liblibc/lib.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/liblibc/lib.rs b/src/liblibc/lib.rs index 42143b06ca0..04898d90ad0 100644 --- a/src/liblibc/lib.rs +++ b/src/liblibc/lib.rs @@ -386,7 +386,8 @@ pub mod types { target_arch = "mips", target_arch = "mipsel", target_arch = "powerpc", - target_arch = "le32"))] + target_arch = "le32", + all(target_arch = "arm", not(target_os = "android"))))] pub mod posix88 { pub type off_t = i32; pub type dev_t = u64; @@ -398,7 +399,7 @@ pub mod types { pub type mode_t = u32; pub type ssize_t = i32; } - #[cfg(target_arch = "arm")] + #[cfg(all(target_arch = "arm", target_os = "android"))] pub mod posix88 { pub type off_t = i32; pub type dev_t = u32; @@ -412,7 +413,8 @@ pub mod types { } #[cfg(any(target_arch = "x86", target_arch = "le32", - target_arch = "powerpc"))] + target_arch = "powerpc", + all(target_arch = "arm", not(target_os = "android"))))] pub mod posix01 { use types::os::arch::c95::{c_short, c_long, time_t}; use types::os::arch::posix88::{dev_t, gid_t, ino_t}; @@ -458,7 +460,7 @@ pub mod types { pub __size: [u32; 9] } } - #[cfg(target_arch = "arm")] + #[cfg(all(target_arch = "arm", target_os = "android"))] pub mod posix01 { use types::os::arch::c95::{c_uchar, c_uint, c_ulong, time_t}; use types::os::arch::c99::{c_longlong, c_ulonglong}; From 61a2766136536f9993ae095075ec766cfc729f8b Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Wed, 4 Mar 2015 16:27:18 -0500 Subject: [PATCH 02/37] Note the alternate form of vec in trpl --- src/doc/trpl/arrays-vectors-and-slices.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/doc/trpl/arrays-vectors-and-slices.md b/src/doc/trpl/arrays-vectors-and-slices.md index d4e2ad5cd5f..f1b5ecf4ff0 100644 --- a/src/doc/trpl/arrays-vectors-and-slices.md +++ b/src/doc/trpl/arrays-vectors-and-slices.md @@ -60,6 +60,12 @@ let v = vec![1, 2, 3]; // v: Vec brackets `[]` with `vec!`. Rust allows you to use either in either situation, this is just convention.) +There's an alternate form of `vec!` for repeating an initial value: + +``` +let v = vec![0; 10]; // ten zeroes +``` + You can get the length of, iterate over, and subscript vectors just like arrays. In addition, (mutable) vectors can grow automatically: From b1e0dfb25c5a3878a27eb3cc15606306f2d3a7bd Mon Sep 17 00:00:00 2001 From: Camille TJHOA Date: Wed, 4 Mar 2015 23:09:03 +0100 Subject: [PATCH 03/37] docs(path.rs): fix ends_with method --- src/libstd/path.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/path.rs b/src/libstd/path.rs index b85a0dcec81..4fd263f96c4 100755 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -1193,7 +1193,7 @@ impl Path { iter_after(self.components(), base.as_path().components()).is_some() } - /// Determines whether `base` is a suffix of `self`. + /// Determines whether `child` is a suffix of `self`. pub fn ends_with(&self, child: &P) -> bool where P: AsPath { iter_after(self.components().rev(), child.as_path().components().rev()).is_some() } From a037cdfcf159a6db80ddd95acd99a61b8441bbe6 Mon Sep 17 00:00:00 2001 From: David King Date: Wed, 4 Mar 2015 23:18:24 +0000 Subject: [PATCH 04/37] Fix broken link in old rust guide Having come back to rust recently after > 6months I was looking for docs on tasks and stumbled upon this broken link. --- src/doc/guide-tasks.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/guide-tasks.md b/src/doc/guide-tasks.md index 197559bef04..21217bf54d7 100644 --- a/src/doc/guide-tasks.md +++ b/src/doc/guide-tasks.md @@ -1,4 +1,4 @@ % The (old) Rust Threads and Communication Guide This content has moved into -[the Rust Programming Language book](book/tasks.html). +[the Rust Programming Language book](book/concurrency.html). From 0dfa9978cc57efc8eb51485fc3a333eafd1aa392 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 3 Mar 2015 14:49:03 -0800 Subject: [PATCH 05/37] std: Stabilize portions of the `io` module The new `io` module has had some time to bake and this commit stabilizes some of the utilities associated with it. This commit also deprecates a number of `std::old_io::util` functions and structures. These items are now `#[stable]` * `Cursor` * `Cursor::{new, into_inner, get_ref, get_mut, position, set_position}` * Implementations of I/O traits for `Cursor` * Delegating implementations of I/O traits for references and `Box` pointers * Implementations of I/O traits for primitives like slices and `Vec` * `ReadExt::bytes` * `Bytes` (and impls) * `ReadExt::chain` * `Chain` (and impls) * `ReadExt::take` (and impls) * `BufReadExt::lines` * `Lines` (and impls) * `io::copy` * `io::{empty, Empty}` (and impls) * `io::{sink, Sink}` (and impls) * `io::{repeat, Repeat}` (and impls) These items remain `#[unstable]` * Core I/O traits. These may want a little bit more time to bake along with the commonly used methods like `read_to_end`. * `BufReadExt::split` - this function may be renamed to not conflict with `SliceExt::split`. * `Error` - there are a number of questions about its representation, `ErrorKind`, and usability. These items are now `#[deprecated]` in `old_io` * `LimitReader` - use `take` instead * `NullWriter` - use `io::sink` instead * `ZeroReader` - use `io::repeat` instead * `NullReader` - use `io::empty` instead * `MultiWriter` - use `broadcast` instead * `ChainedReader` - use `chain` instead * `TeeReader` - use `tee` instead * `copy` - use `io::copy` instead [breaking-change] --- src/librustc_driver/lib.rs | 1 + src/librustdoc/test.rs | 1 + src/libstd/io/cursor.rs | 20 ++++++++++-- src/libstd/io/impls.rs | 64 +++++++++++++++++++++++++++++--------- src/libstd/io/mod.rs | 32 +++++++++++++++++++ src/libstd/io/util.rs | 17 +++++++++- src/libstd/old_io/util.rs | 50 +++++++++++++++++++++++++++++ 7 files changed, 167 insertions(+), 18 deletions(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 15fae351ddb..29489992784 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -769,6 +769,7 @@ fn parse_crate_attrs(sess: &Session, input: &Input) -> /// /// The diagnostic emitter yielded to the procedure should be used for reporting /// errors of the compiler. +#[allow(deprecated)] pub fn monitor(f: F) { const STACK_SIZE: uint = 8 * 1024 * 1024; // 8MB diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 43e8f44244e..afe117961ff 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -106,6 +106,7 @@ pub fn run(input: &str, 0 } +#[allow(deprecated)] fn runtest(test: &str, cratename: &str, libs: SearchPaths, externs: core::Externs, should_fail: bool, no_run: bool, as_test_harness: bool) { diff --git a/src/libstd/io/cursor.rs b/src/libstd/io/cursor.rs index b1779587528..78f9222bde7 100644 --- a/src/libstd/io/cursor.rs +++ b/src/libstd/io/cursor.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![allow(missing_copy_implementations)] - use prelude::v1::*; use io::prelude::*; @@ -32,6 +30,7 @@ use slice; /// Implementations of the I/O traits for `Cursor` are not currently generic /// over `T` itself. Instead, specific implementations are provided for various /// in-memory buffer types like `Vec` and `&[u8]`. +#[stable(feature = "rust1", since = "1.0.0")] pub struct Cursor { inner: T, pos: u64, @@ -39,26 +38,32 @@ pub struct Cursor { impl Cursor { /// Create a new cursor wrapping the provided underlying I/O object. + #[stable(feature = "rust1", since = "1.0.0")] pub fn new(inner: T) -> Cursor { Cursor { pos: 0, inner: inner } } /// Consume this cursor, returning the underlying value. + #[stable(feature = "rust1", since = "1.0.0")] pub fn into_inner(self) -> T { self.inner } /// Get a reference to the underlying value in this cursor. + #[stable(feature = "rust1", since = "1.0.0")] pub fn get_ref(&self) -> &T { &self.inner } /// Get a mutable reference to the underlying value in this cursor. /// /// Care should be taken to avoid modifying the internal I/O state of the /// underlying value as it may corrupt this cursor's position. + #[stable(feature = "rust1", since = "1.0.0")] pub fn get_mut(&mut self) -> &mut T { &mut self.inner } /// Returns the current value of this cursor + #[stable(feature = "rust1", since = "1.0.0")] pub fn position(&self) -> u64 { self.pos } /// Sets the value of this cursor + #[stable(feature = "rust1", since = "1.0.0")] pub fn set_position(&mut self, pos: u64) { self.pos = pos; } } @@ -83,8 +88,11 @@ macro_rules! seek { } } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> io::Seek for Cursor<&'a [u8]> { seek!(); } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> io::Seek for Cursor<&'a mut [u8]> { seek!(); } +#[stable(feature = "rust1", since = "1.0.0")] impl io::Seek for Cursor> { seek!(); } macro_rules! read { @@ -97,8 +105,11 @@ macro_rules! read { } } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> Read for Cursor<&'a [u8]> { read!(); } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> Read for Cursor<&'a mut [u8]> { read!(); } +#[stable(feature = "rust1", since = "1.0.0")] impl Read for Cursor> { read!(); } macro_rules! buffer { @@ -111,10 +122,14 @@ macro_rules! buffer { } } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> BufRead for Cursor<&'a [u8]> { buffer!(); } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> BufRead for Cursor<&'a mut [u8]> { buffer!(); } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> BufRead for Cursor> { buffer!(); } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> Write for Cursor<&'a mut [u8]> { fn write(&mut self, data: &[u8]) -> io::Result { let pos = cmp::min(self.pos, self.inner.len() as u64); @@ -125,6 +140,7 @@ impl<'a> Write for Cursor<&'a mut [u8]> { fn flush(&mut self) -> io::Result<()> { Ok(()) } } +#[stable(feature = "rust1", since = "1.0.0")] impl Write for Cursor> { fn write(&mut self, buf: &[u8]) -> io::Result { // Make sure the internal buffer is as least as big as where we diff --git a/src/libstd/io/impls.rs b/src/libstd/io/impls.rs index 82b69ddebff..c968415d3ef 100644 --- a/src/libstd/io/impls.rs +++ b/src/libstd/io/impls.rs @@ -22,57 +22,88 @@ use vec::Vec; // ============================================================================= // Forwarding implementations +#[stable(feature = "rust1", since = "1.0.0")] impl<'a, R: Read + ?Sized> Read for &'a mut R { - fn read(&mut self, buf: &mut [u8]) -> io::Result { (**self).read(buf) } - - fn read_to_end(&mut self, buf: &mut Vec) -> io::Result<()> { (**self).read_to_end(buf) } - + fn read(&mut self, buf: &mut [u8]) -> io::Result { + (**self).read(buf) + } + fn read_to_end(&mut self, buf: &mut Vec) -> io::Result<()> { + (**self).read_to_end(buf) + } fn read_to_string(&mut self, buf: &mut String) -> io::Result<()> { (**self).read_to_string(buf) } } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a, W: Write + ?Sized> Write for &'a mut W { fn write(&mut self, buf: &[u8]) -> io::Result { (**self).write(buf) } - - fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { (**self).write_all(buf) } - - fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> { (**self).write_fmt(fmt) } - fn flush(&mut self) -> io::Result<()> { (**self).flush() } + fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { + (**self).write_all(buf) + } + fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> { + (**self).write_fmt(fmt) + } } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a, S: Seek + ?Sized> Seek for &'a mut S { fn seek(&mut self, pos: SeekFrom) -> io::Result { (**self).seek(pos) } } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a, B: BufRead + ?Sized> BufRead for &'a mut B { fn fill_buf(&mut self) -> io::Result<&[u8]> { (**self).fill_buf() } - fn consume(&mut self, amt: usize) { (**self).consume(amt) } - fn read_until(&mut self, byte: u8, buf: &mut Vec) -> io::Result<()> { (**self).read_until(byte, buf) } - - fn read_line(&mut self, buf: &mut String) -> io::Result<()> { (**self).read_line(buf) } + fn read_line(&mut self, buf: &mut String) -> io::Result<()> { + (**self).read_line(buf) + } } +#[stable(feature = "rust1", since = "1.0.0")] impl Read for Box { - fn read(&mut self, buf: &mut [u8]) -> io::Result { (**self).read(buf) } + fn read(&mut self, buf: &mut [u8]) -> io::Result { + (**self).read(buf) + } + fn read_to_end(&mut self, buf: &mut Vec) -> io::Result<()> { + (**self).read_to_end(buf) + } + fn read_to_string(&mut self, buf: &mut String) -> io::Result<()> { + (**self).read_to_string(buf) + } } +#[stable(feature = "rust1", since = "1.0.0")] impl Write for Box { fn write(&mut self, buf: &[u8]) -> io::Result { (**self).write(buf) } fn flush(&mut self) -> io::Result<()> { (**self).flush() } + fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { + (**self).write_all(buf) + } + fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> { + (**self).write_fmt(fmt) + } } +#[stable(feature = "rust1", since = "1.0.0")] impl Seek for Box { fn seek(&mut self, pos: SeekFrom) -> io::Result { (**self).seek(pos) } } +#[stable(feature = "rust1", since = "1.0.0")] impl BufRead for Box { fn fill_buf(&mut self) -> io::Result<&[u8]> { (**self).fill_buf() } fn consume(&mut self, amt: usize) { (**self).consume(amt) } + fn read_until(&mut self, byte: u8, buf: &mut Vec) -> io::Result<()> { + (**self).read_until(byte, buf) + } + fn read_line(&mut self, buf: &mut String) -> io::Result<()> { + (**self).read_line(buf) + } } // ============================================================================= // In-memory buffer implementations +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> Read for &'a [u8] { fn read(&mut self, buf: &mut [u8]) -> io::Result { let amt = cmp::min(buf.len(), self.len()); @@ -83,11 +114,13 @@ impl<'a> Read for &'a [u8] { } } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> BufRead for &'a [u8] { fn fill_buf(&mut self) -> io::Result<&[u8]> { Ok(*self) } fn consume(&mut self, amt: usize) { *self = &self[amt..]; } } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> Write for &'a mut [u8] { fn write(&mut self, data: &[u8]) -> io::Result { let amt = cmp::min(data.len(), self.len()); @@ -108,6 +141,7 @@ impl<'a> Write for &'a mut [u8] { fn flush(&mut self) -> io::Result<()> { Ok(()) } } +#[stable(feature = "rust1", since = "1.0.0")] impl Write for Vec { fn write(&mut self, buf: &[u8]) -> io::Result { self.push_all(buf); @@ -115,7 +149,7 @@ impl Write for Vec { } fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { - try!(self.write(buf)); + self.push_all(buf); Ok(()) } diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 5510c0203e6..a91ab57c7e9 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -237,11 +237,13 @@ pub trait Read { /// Extension methods for all instances of `Read`, typically imported through /// `std::io::prelude::*`. +#[unstable(feature = "io", reason = "may merge into the Read trait")] pub trait ReadExt: Read + Sized { /// Create a "by reference" adaptor for this instance of `Read`. /// /// The returned adaptor also implements `Read` and will simply borrow this /// current reader. + #[stable(feature = "rust1", since = "1.0.0")] fn by_ref(&mut self) -> &mut Self { self } /// Transform this `Read` instance to an `Iterator` over its bytes. @@ -250,6 +252,7 @@ pub trait ReadExt: Read + Sized { /// R::Err>`. The yielded item is `Ok` if a byte was successfully read and /// `Err` otherwise for I/O errors. EOF is mapped to returning `None` from /// this iterator. + #[stable(feature = "rust1", since = "1.0.0")] fn bytes(self) -> Bytes { Bytes { inner: self } } @@ -264,6 +267,9 @@ pub trait ReadExt: Read + Sized { /// /// Currently this adaptor will discard intermediate data read, and should /// be avoided if this is not desired. + #[unstable(feature = "io", reason = "the semantics of a partial read/write \ + of where errors happen is currently \ + unclear and may change")] fn chars(self) -> Chars { Chars { inner: self } } @@ -273,6 +279,7 @@ pub trait ReadExt: Read + Sized { /// The returned `Read` instance will first read all bytes from this object /// until EOF is encountered. Afterwards the output is equivalent to the /// output of `next`. + #[stable(feature = "rust1", since = "1.0.0")] fn chain(self, next: R) -> Chain { Chain { first: self, second: next, done_first: false } } @@ -283,6 +290,7 @@ pub trait ReadExt: Read + Sized { /// `limit` bytes, after which it will always return EOF (`Ok(0)`). Any /// read errors will not count towards the number of bytes read and future /// calls to `read` may succeed. + #[stable(feature = "rust1", since = "1.0.0")] fn take(self, limit: u64) -> Take { Take { inner: self, limit: limit } } @@ -293,6 +301,9 @@ pub trait ReadExt: Read + Sized { /// Whenever the returned `Read` instance is read it will write the read /// data to `out`. The current semantics of this implementation imply that /// a `write` error will not report how much data was initially read. + #[unstable(feature = "io", reason = "the semantics of a partial read/write \ + of where errors happen is currently \ + unclear and may change")] fn tee(self, out: W) -> Tee { Tee { reader: self, writer: out } } @@ -415,11 +426,13 @@ pub trait Write { /// Extension methods for all instances of `Write`, typically imported through /// `std::io::prelude::*`. +#[unstable(feature = "io", reason = "may merge into the Read trait")] pub trait WriteExt: Write + Sized { /// Create a "by reference" adaptor for this instance of `Write`. /// /// The returned adaptor also implements `Write` and will simply borrow this /// current writer. + #[stable(feature = "rust1", since = "1.0.0")] fn by_ref(&mut self) -> &mut Self { self } /// Creates a new writer which will write all data to both this writer and @@ -430,11 +443,15 @@ pub trait WriteExt: Write + Sized { /// implementation do not precisely track where errors happen. For example /// an error on the second call to `write` will not report that the first /// call to `write` succeeded. + #[unstable(feature = "io", reason = "the semantics of a partial read/write \ + of where errors happen is currently \ + unclear and may change")] fn broadcast(self, other: W) -> Broadcast { Broadcast { first: self, second: other } } } +#[stable(feature = "rust1", since = "1.0.0")] impl WriteExt for T {} /// An object implementing `Seek` internally has some form of cursor which can @@ -592,6 +609,8 @@ pub trait BufReadExt: BufRead + Sized { /// /// This function will yield errors whenever `read_until` would have also /// yielded an error. + #[unstable(feature = "io", reason = "may be renamed to not conflict with \ + SliceExt::split")] fn split(self, byte: u8) -> Split { Split { buf: self, delim: byte } } @@ -604,11 +623,13 @@ pub trait BufReadExt: BufRead + Sized { /// /// This function will yield errors whenever `read_string` would have also /// yielded an error. + #[stable(feature = "rust1", since = "1.0.0")] fn lines(self) -> Lines { Lines { buf: self } } } +#[stable(feature = "rust1", since = "1.0.0")] impl BufReadExt for T {} /// A `Write` adaptor which will write data to multiple locations. @@ -635,12 +656,14 @@ impl Write for Broadcast { /// Adaptor to chain together two instances of `Read`. /// /// For more information, see `ReadExt::chain`. +#[stable(feature = "rust1", since = "1.0.0")] pub struct Chain { first: T, second: U, done_first: bool, } +#[stable(feature = "rust1", since = "1.0.0")] impl Read for Chain { fn read(&mut self, buf: &mut [u8]) -> Result { if !self.done_first { @@ -656,11 +679,13 @@ impl Read for Chain { /// Reader adaptor which limits the bytes read from an underlying reader. /// /// For more information, see `ReadExt::take`. +#[stable(feature = "rust1", since = "1.0.0")] pub struct Take { inner: T, limit: u64, } +#[stable(feature = "rust1", since = "1.0.0")] impl Take { /// Returns the number of bytes that can be read before this instance will /// return EOF. @@ -669,9 +694,11 @@ impl Take { /// /// This instance may reach EOF after reading fewer bytes than indicated by /// this method if the underlying `Read` instance reaches EOF. + #[stable(feature = "rust1", since = "1.0.0")] pub fn limit(&self) -> u64 { self.limit } } +#[stable(feature = "rust1", since = "1.0.0")] impl Read for Take { fn read(&mut self, buf: &mut [u8]) -> Result { // Don't call into inner reader at all at EOF because it may still block @@ -686,6 +713,7 @@ impl Read for Take { } } +#[stable(feature = "rust1", since = "1.0.0")] impl BufRead for Take { fn fill_buf(&mut self) -> Result<&[u8]> { let buf = try!(self.inner.fill_buf()); @@ -721,10 +749,12 @@ impl Read for Tee { /// A bridge from implementations of `Read` to an `Iterator` of `u8`. /// /// See `ReadExt::bytes` for more information. +#[stable(feature = "rust1", since = "1.0.0")] pub struct Bytes { inner: R, } +#[stable(feature = "rust1", since = "1.0.0")] impl Iterator for Bytes { type Item = Result; @@ -845,10 +875,12 @@ impl Iterator for Split { /// byte. /// /// See `BufReadExt::lines` for more information. +#[stable(feature = "rust1", since = "1.0.0")] pub struct Lines { buf: B, } +#[stable(feature = "rust1", since = "1.0.0")] impl Iterator for Lines { type Item = Result; diff --git a/src/libstd/io/util.rs b/src/libstd/io/util.rs index 3d342137c62..20426025257 100644 --- a/src/libstd/io/util.rs +++ b/src/libstd/io/util.rs @@ -12,7 +12,7 @@ use prelude::v1::*; -use io::{self, Read, Write, ErrorKind}; +use io::{self, Read, Write, ErrorKind, BufRead}; /// Copies the entire contents of a reader into a writer. /// @@ -27,6 +27,7 @@ use io::{self, Read, Write, ErrorKind}; /// This function will return an error immediately if any call to `read` or /// `write` returns an error. All instances of `ErrorKind::Interrupted` are /// handled by this function and the underlying operation is retried. +#[stable(feature = "rust1", since = "1.0.0")] pub fn copy(r: &mut R, w: &mut W) -> io::Result { let mut buf = [0; super::DEFAULT_BUF_SIZE]; let mut written = 0; @@ -43,26 +44,37 @@ pub fn copy(r: &mut R, w: &mut W) -> io::Result { } /// A reader which is always at EOF. +#[stable(feature = "rust1", since = "1.0.0")] pub struct Empty { _priv: () } /// Creates an instance of an empty reader. /// /// All reads from the returned reader will return `Ok(0)`. +#[stable(feature = "rust1", since = "1.0.0")] pub fn empty() -> Empty { Empty { _priv: () } } +#[stable(feature = "rust1", since = "1.0.0")] impl Read for Empty { fn read(&mut self, _buf: &mut [u8]) -> io::Result { Ok(0) } } +#[stable(feature = "rust1", since = "1.0.0")] +impl BufRead for Empty { + fn fill_buf(&mut self) -> io::Result<&[u8]> { Ok(&[]) } + fn consume(&mut self, _n: usize) {} +} /// A reader which infinitely yields one byte. +#[stable(feature = "rust1", since = "1.0.0")] pub struct Repeat { byte: u8 } /// Creates an instance of a reader that infinitely repeats one byte. /// /// All reads from this reader will succeed by filling the specified buffer with /// the given byte. +#[stable(feature = "rust1", since = "1.0.0")] pub fn repeat(byte: u8) -> Repeat { Repeat { byte: byte } } +#[stable(feature = "rust1", since = "1.0.0")] impl Read for Repeat { fn read(&mut self, buf: &mut [u8]) -> io::Result { for slot in buf.iter_mut() { @@ -73,14 +85,17 @@ impl Read for Repeat { } /// A writer which will move data into the void. +#[stable(feature = "rust1", since = "1.0.0")] pub struct Sink { _priv: () } /// Creates an instance of a writer which will successfully consume all data. /// /// All calls to `write` on the returned instance will return `Ok(buf.len())` /// and the contents of the buffer will not be inspected. +#[stable(feature = "rust1", since = "1.0.0")] pub fn sink() -> Sink { Sink { _priv: () } } +#[stable(feature = "rust1", since = "1.0.0")] impl Write for Sink { fn write(&mut self, buf: &[u8]) -> io::Result { Ok(buf.len()) } fn flush(&mut self) -> io::Result<()> { Ok(()) } diff --git a/src/libstd/old_io/util.rs b/src/libstd/old_io/util.rs index 8e49335ed54..839d2e7057b 100644 --- a/src/libstd/old_io/util.rs +++ b/src/libstd/old_io/util.rs @@ -10,6 +10,8 @@ //! Utility implementations of Reader and Writer +#![allow(deprecated)] + use prelude::v1::*; use cmp; use old_io; @@ -17,13 +19,19 @@ use slice::bytes::MutableByteVector; /// Wraps a `Reader`, limiting the number of bytes that can be read from it. #[derive(Debug)] +#[deprecated(since = "1.0.0", reason = "use std::io::Take")] +#[unstable(feature = "old_io")] pub struct LimitReader { limit: uint, inner: R } +#[deprecated(since = "1.0.0", reason = "use std::io::Take")] +#[unstable(feature = "old_io")] impl LimitReader { /// Creates a new `LimitReader` + #[deprecated(since = "1.0.0", reason = "use std::io's take method instead")] + #[unstable(feature = "old_io")] pub fn new(r: R, limit: uint) -> LimitReader { LimitReader { limit: limit, inner: r } } @@ -41,6 +49,8 @@ impl LimitReader { pub fn limit(&self) -> uint { self.limit } } +#[deprecated(since = "1.0.0", reason = "use std::io's take method instead")] +#[unstable(feature = "old_io")] impl Reader for LimitReader { fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult { if self.limit == 0 { @@ -57,6 +67,8 @@ impl Reader for LimitReader { } } +#[deprecated(since = "1.0.0", reason = "use std::io's take method instead")] +#[unstable(feature = "old_io")] impl Buffer for LimitReader { fn fill_buf<'a>(&'a mut self) -> old_io::IoResult<&'a [u8]> { let amt = try!(self.inner.fill_buf()); @@ -79,8 +91,12 @@ impl Buffer for LimitReader { /// A `Writer` which ignores bytes written to it, like /dev/null. #[derive(Copy, Debug)] +#[deprecated(since = "1.0.0", reason = "use std::io::sink() instead")] +#[unstable(feature = "old_io")] pub struct NullWriter; +#[deprecated(since = "1.0.0", reason = "use std::io::sink() instead")] +#[unstable(feature = "old_io")] impl Writer for NullWriter { #[inline] fn write_all(&mut self, _buf: &[u8]) -> old_io::IoResult<()> { Ok(()) } @@ -88,8 +104,12 @@ impl Writer for NullWriter { /// A `Reader` which returns an infinite stream of 0 bytes, like /dev/zero. #[derive(Copy, Debug)] +#[deprecated(since = "1.0.0", reason = "use std::io::repeat(0) instead")] +#[unstable(feature = "old_io")] pub struct ZeroReader; +#[deprecated(since = "1.0.0", reason = "use std::io::repeat(0) instead")] +#[unstable(feature = "old_io")] impl Reader for ZeroReader { #[inline] fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult { @@ -98,6 +118,8 @@ impl Reader for ZeroReader { } } +#[deprecated(since = "1.0.0", reason = "use std::io::repeat(0) instead")] +#[unstable(feature = "old_io")] impl Buffer for ZeroReader { fn fill_buf<'a>(&'a mut self) -> old_io::IoResult<&'a [u8]> { static DATA: [u8; 64] = [0; 64]; @@ -109,8 +131,12 @@ impl Buffer for ZeroReader { /// A `Reader` which is always at EOF, like /dev/null. #[derive(Copy, Debug)] +#[deprecated(since = "1.0.0", reason = "use std::io::empty() instead")] +#[unstable(feature = "old_io")] pub struct NullReader; +#[deprecated(since = "1.0.0", reason = "use std::io::empty() instead")] +#[unstable(feature = "old_io")] impl Reader for NullReader { #[inline] fn read(&mut self, _buf: &mut [u8]) -> old_io::IoResult { @@ -118,6 +144,8 @@ impl Reader for NullReader { } } +#[deprecated(since = "1.0.0", reason = "use std::io::empty() instead")] +#[unstable(feature = "old_io")] impl Buffer for NullReader { fn fill_buf<'a>(&'a mut self) -> old_io::IoResult<&'a [u8]> { Err(old_io::standard_error(old_io::EndOfFile)) @@ -130,17 +158,23 @@ impl Buffer for NullReader { /// The `Writer`s are delegated to in order. If any `Writer` returns an error, /// that error is returned immediately and remaining `Writer`s are not called. #[derive(Debug)] +#[deprecated(since = "1.0.0", reason = "use std::io::Broadcast instead")] +#[unstable(feature = "old_io")] pub struct MultiWriter { writers: Vec } impl MultiWriter where W: Writer { /// Creates a new `MultiWriter` + #[deprecated(since = "1.0.0", reason = "use std::io's broadcast method instead")] + #[unstable(feature = "old_io")] pub fn new(writers: Vec) -> MultiWriter { MultiWriter { writers: writers } } } +#[deprecated(since = "1.0.0", reason = "use std::io::Broadcast instead")] +#[unstable(feature = "old_io")] impl Writer for MultiWriter where W: Writer { #[inline] fn write_all(&mut self, buf: &[u8]) -> old_io::IoResult<()> { @@ -162,6 +196,8 @@ impl Writer for MultiWriter where W: Writer { /// A `Reader` which chains input from multiple `Reader`s, reading each to /// completion before moving onto the next. #[derive(Clone, Debug)] +#[deprecated(since = "1.0.0", reason = "use std::io::Chain instead")] +#[unstable(feature = "old_io")] pub struct ChainedReader { readers: I, cur_reader: Option, @@ -169,12 +205,16 @@ pub struct ChainedReader { impl> ChainedReader { /// Creates a new `ChainedReader` + #[deprecated(since = "1.0.0", reason = "use std::io's chain method instead")] + #[unstable(feature = "old_io")] pub fn new(mut readers: I) -> ChainedReader { let r = readers.next(); ChainedReader { readers: readers, cur_reader: r } } } +#[deprecated(since = "1.0.0", reason = "use std::io::Chain instead")] +#[unstable(feature = "old_io")] impl> Reader for ChainedReader { fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult { loop { @@ -201,13 +241,19 @@ impl> Reader for ChainedReader { /// A `Reader` which forwards input from another `Reader`, passing it along to /// a `Writer` as well. Similar to the `tee(1)` command. #[derive(Debug)] +#[deprecated(since = "1.0.0", reason = "use std::io::Tee instead")] +#[unstable(feature = "old_io")] pub struct TeeReader { reader: R, writer: W, } +#[deprecated(since = "1.0.0", reason = "use std::io::Tee instead")] +#[unstable(feature = "old_io")] impl TeeReader { /// Creates a new `TeeReader` + #[deprecated(since = "1.0.0", reason = "use std::io's tee method instead")] + #[unstable(feature = "old_io")] pub fn new(r: R, w: W) -> TeeReader { TeeReader { reader: r, writer: w } } @@ -220,6 +266,8 @@ impl TeeReader { } } +#[deprecated(since = "1.0.0", reason = "use std::io::Tee instead")] +#[unstable(feature = "old_io")] impl Reader for TeeReader { fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult { self.reader.read(buf).and_then(|len| { @@ -229,6 +277,8 @@ impl Reader for TeeReader { } /// Copies all data from a `Reader` to a `Writer`. +#[deprecated(since = "1.0.0", reason = "use std::io's copy function instead")] +#[unstable(feature = "old_io")] pub fn copy(r: &mut R, w: &mut W) -> old_io::IoResult<()> { let mut buf = [0; super::DEFAULT_BUF_SIZE]; loop { From 9e28156551c1a2af3c47a0937290176ccc457703 Mon Sep 17 00:00:00 2001 From: Kang Seonghoon Date: Thu, 5 Mar 2015 16:35:43 +0900 Subject: [PATCH 06/37] rustdoc: Move sidebar items into shared JavaScript. It had been a source of huge bloat in rustdoc outputs. Of course, we can simply disable compiler docs (as `rustc` generates over 90M of HTML) but this approach fares better even after such decision. Each directory now has `sidebar-items.js`, which immediately calls `initSidebarItems` with a JSON sidebar data. This file is shared throughout every item in the sidebar. The current item is highlighted via a separate JS snippet (`window.sidebarCurrent`). The JS file is designed to be loaded asynchronously, as the sidebar is rendered before the content and slow sidebar loading blocks the entire rendering. For the minimal accessibility without JS, links to the parent items are left in HTML. In the future, it might also be possible to integrate crates data with the same fashion: `sidebar-items.js` at the root path will do that. (Currently rustdoc skips writing JS in that case.) This has a huge impact on the size of rustdoc outputs. Originally it was 326MB uncompressed (37.7MB gzipped, 6.1MB xz compressed); it is 169MB uncompressed (11.9MB gzipped, 5.9MB xz compressed) now. The sidebar JS only takes 10MB uncompressed & 0.3MB gzipped. --- src/librustdoc/html/render.rs | 85 ++++++++++++----------------- src/librustdoc/html/static/main.js | 86 ++++++++++++++++++++++-------- 2 files changed, 99 insertions(+), 72 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 735487611dc..a9a9d0f7694 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -65,12 +65,10 @@ use html::item_type::ItemType; use html::layout; use html::markdown::Markdown; use html::markdown; -use html::escape::Escape; use stability_summary; /// A pair of name and its optional document. -#[derive(Clone, Eq, Ord, PartialEq, PartialOrd)] -pub struct NameDoc(String, Option); +pub type NameDoc = (String, Option); /// Major driving force in all rustdoc rendering. This contains information /// about where in the tree-like hierarchy rendering is occurring and controls @@ -96,12 +94,6 @@ pub struct Context { /// This describes the layout of each page, and is not modified after /// creation of the context (contains info like the favicon and added html). pub layout: layout::Layout, - /// This map is a list of what should be displayed on the sidebar of the - /// current page. The key is the section header (traits, modules, - /// functions), and the value is the list of containers belonging to this - /// header. This map will change depending on the surrounding context of the - /// page. - pub sidebar: HashMap>, /// This flag indicates whether [src] links should be generated or not. If /// the source files are present in the html rendering, then this will be /// `true`. @@ -265,7 +257,6 @@ pub fn run(mut krate: clean::Crate, passes: passes, current: Vec::new(), root_path: String::new(), - sidebar: HashMap::new(), layout: layout::Layout { logo: "".to_string(), favicon: "".to_string(), @@ -1227,7 +1218,16 @@ impl Context { clean::ModuleItem(m) => m, _ => unreachable!() }; - this.sidebar = this.build_sidebar(&m); + + // render sidebar-items.js used throughout this module + { + let items = this.build_sidebar_items(&m); + let js_dst = this.dst.join("sidebar-items.js"); + let mut js_out = BufferedWriter::new(try!(File::create(&js_dst))); + try!(write!(&mut js_out, "initSidebarItems({});", + json::as_json(&items))); + } + for item in m.items { f(this,item); } @@ -1247,15 +1247,11 @@ impl Context { } } - fn build_sidebar(&self, m: &clean::Module) -> HashMap> { + fn build_sidebar_items(&self, m: &clean::Module) -> HashMap> { let mut map = HashMap::new(); for item in &m.items { if self.ignore_private_item(item) { continue } - // avoid putting foreign items to the sidebar. - if let &clean::ForeignFunctionItem(..) = &item.inner { continue } - if let &clean::ForeignStaticItem(..) = &item.inner { continue } - let short = shortty(item).to_static_str(); let myname = match item.name { None => continue, @@ -1264,7 +1260,7 @@ impl Context { let short = short.to_string(); let v = map.entry(short).get().unwrap_or_else( |vacant_entry| vacant_entry.insert(Vec::with_capacity(1))); - v.push(NameDoc(myname, Some(shorter_line(item.doc_value())))); + v.push((myname, Some(shorter_line(item.doc_value())))); } for (_, items) in &mut map { @@ -2211,9 +2207,11 @@ impl<'a> fmt::Display for Sidebar<'a> { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { let cx = self.cx; let it = self.item; + let parentlen = cx.current.len() - if it.is_mod() {1} else {0}; + + // this is not rendered via JS, as that would hamper the accessibility try!(write!(fmt, "

")); - let len = cx.current.len() - if it.is_mod() {1} else {0}; - for (i, name) in cx.current.iter().take(len).enumerate() { + for (i, name) in cx.current.iter().take(parentlen).enumerate() { if i > 0 { try!(write!(fmt, "::")); } @@ -2223,40 +2221,25 @@ impl<'a> fmt::Display for Sidebar<'a> { } try!(write!(fmt, "

")); - fn block(w: &mut fmt::Formatter, short: &str, longty: &str, - cur: &clean::Item, cx: &Context) -> fmt::Result { - let items = match cx.sidebar.get(short) { - Some(items) => items, - None => return Ok(()) - }; - try!(write!(w, "

{}

", short, longty)); - for &NameDoc(ref name, ref doc) in items { - let curty = shortty(cur).to_static_str(); - let class = if cur.name.as_ref().unwrap() == name && - short == curty { "current" } else { "" }; - try!(write!(w, "{name}", - ty = short, - class = class, - href = if curty == "mod" {"../"} else {""}, - path = if short == "mod" { - format!("{}/index.html", name) - } else { - format!("{}.{}.html", short, name) - }, - title = Escape(doc.as_ref().unwrap()), - name = name)); - } - try!(write!(w, "
")); - Ok(()) + // sidebar refers to the enclosing module, not this module + let relpath = if shortty(it) == ItemType::Module { "../" } else { "" }; + try!(write!(fmt, + "", + name = it.name.as_ref().map(|x| &x[..]).unwrap_or(""), + ty = shortty(it).to_static_str(), + path = relpath)); + if parentlen == 0 { + // there is no sidebar-items.js beyond the crate root path + // FIXME maybe dynamic crate loading can be merged here + } else { + try!(write!(fmt, "", + path = relpath)); } - try!(block(fmt, "mod", "Modules", it, cx)); - try!(block(fmt, "struct", "Structs", it, cx)); - try!(block(fmt, "enum", "Enums", it, cx)); - try!(block(fmt, "trait", "Traits", it, cx)); - try!(block(fmt, "fn", "Functions", it, cx)); - try!(block(fmt, "macro", "Macros", it, cx)); Ok(()) } } diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index aac3985f0cc..a9b233dd128 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -15,6 +15,27 @@ "use strict"; var resizeTimeout, interval; + // This mapping table should match the discriminants of + // `rustdoc::html::item_type::ItemType` type in Rust. + var itemTypes = ["mod", + "externcrate", + "import", + "struct", + "enum", + "fn", + "type", + "static", + "trait", + "impl", + "tymethod", + "method", + "structfield", + "variant", + "macro", + "primitive", + "associatedtype", + "constant"]; + $('.js-only').removeClass('js-only'); function getQueryStringParams() { @@ -552,27 +573,6 @@ showResults(results); } - // This mapping table should match the discriminants of - // `rustdoc::html::item_type::ItemType` type in Rust. - var itemTypes = ["mod", - "externcrate", - "import", - "struct", - "enum", - "fn", - "type", - "static", - "trait", - "impl", - "tymethod", - "method", - "structfield", - "variant", - "macro", - "primitive", - "associatedtype", - "constant"]; - function itemTypeFromName(typename) { for (var i = 0; i < itemTypes.length; ++i) { if (itemTypes[i] === typename) return i; @@ -708,6 +708,50 @@ window.initSearch = initSearch; + // delayed sidebar rendering. + function initSidebarItems(items) { + var sidebar = $('.sidebar'); + var current = window.sidebarCurrent; + + function block(shortty, longty) { + var filtered = items[shortty]; + if (!filtered) return; + + var div = $('
').attr('class', 'block ' + shortty); + div.append($('

').text(longty)); + + for (var i = 0; i < filtered.length; ++i) { + var item = filtered[i]; + var name = item[0]; + var desc = item[1]; // can be null + + var klass = shortty; + if (name === current.name && shortty == current.ty) { + klass += ' current'; + } + var path; + if (shortty === 'mod') { + path = name + '/index.html'; + } else { + path = shortty + '.' + name + '.html'; + } + div.append($('', {'href': current.relpath + path, + 'title': desc, + 'class': klass}).text(name)); + } + sidebar.append(div); + } + + block("mod", "Modules"); + block("struct", "Structs"); + block("enum", "Enums"); + block("trait", "Traits"); + block("fn", "Functions"); + block("macro", "Macros"); + } + + window.initSidebarItems = initSidebarItems; + window.register_implementors = function(imp) { var list = $('#implementors-list'); var libs = Object.getOwnPropertyNames(imp); From 3f4181a6e5c41a8d9d8ee434e6b75e7bef315998 Mon Sep 17 00:00:00 2001 From: Valerii Hiora Date: Thu, 26 Feb 2015 20:26:36 +0200 Subject: [PATCH 07/37] iOS: open file on aarch64 breaks permissions According to Apple arm64 calling convention varargs always are passed through stack. Since `open` is actually a vararg function on Darwin's, it means that older declaration caused permissions to be taken from stack, while passed through register => it set file permissions to garbage and it was simply impossible to read/delete files after they were created. They way this commit handles it is to preserve compatibility with existing code - it simply creates a shim unsafe function so all existing callers continue work as nothing happened. --- src/liblibc/lib.rs | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/src/liblibc/lib.rs b/src/liblibc/lib.rs index 74a95b3aba0..1a500016175 100644 --- a/src/liblibc/lib.rs +++ b/src/liblibc/lib.rs @@ -5003,9 +5003,36 @@ pub mod funcs { use types::os::arch::c95::{c_char, c_int}; use types::os::arch::posix88::mode_t; + mod open_shim { + extern { + #[cfg(any(target_os = "macos", + target_os = "ios"))] + pub fn open(path: *const ::c_char, oflag: ::c_int, ...) + -> ::c_int; + + #[cfg(not(any(target_os = "macos", + target_os = "ios")))] + pub fn open(path: *const ::c_char, oflag: ::c_int, mode: ::mode_t) + -> ::c_int; + } + } + + #[cfg(any(target_os = "macos", + target_os = "ios"))] + #[inline] + pub unsafe extern fn open(path: *const c_char, oflag: c_int, mode: mode_t) -> c_int { + use types::os::arch::c95::c_uint; + open_shim::open(path, oflag, mode as c_uint) + } + + #[cfg(not(any(target_os = "macos", + target_os = "ios")))] + #[inline] + pub unsafe extern fn open(path: *const c_char, oflag: c_int, mode: mode_t) -> c_int { + open_shim::open(path, oflag, mode) + } + extern { - pub fn open(path: *const c_char, oflag: c_int, mode: mode_t) - -> c_int; pub fn creat(path: *const c_char, mode: mode_t) -> c_int; pub fn fcntl(fd: c_int, cmd: c_int, ...) -> c_int; } From 7bcf7fb5009b5dbdfa1a611fe464ca0de43c5a49 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Wed, 4 Mar 2015 21:32:33 +1100 Subject: [PATCH 08/37] Use more associated types in core::iter. This concretely improves type inference of some cases (see included test). I assume the compiler struggles to reason about multiple layers of generic type parameters (even with associated-type equalities) but *can* understand pure associated types, since they are always directly computable from the input types. --- src/libcore/iter.rs | 94 ++++++++++--------- .../run-pass/iter-cloned-type-inference.rs | 25 +++++ 2 files changed, 73 insertions(+), 46 deletions(-) create mode 100644 src/test/run-pass/iter-cloned-type-inference.rs diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 9495bc2e19d..07203ad7d19 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -1279,14 +1279,14 @@ pub struct Cloned { } #[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for Cloned where - T: Clone, - D: Deref, - I: Iterator, +impl Iterator for Cloned where + I: Iterator, + I::Item: Deref, + ::Target: Clone { - type Item = T; + type Item = ::Target; - fn next(&mut self) -> Option { + fn next(&mut self) -> Option<::Item> { self.it.next().cloned() } @@ -1296,28 +1296,28 @@ impl Iterator for Cloned where } #[stable(feature = "rust1", since = "1.0.0")] -impl DoubleEndedIterator for Cloned where - T: Clone, - D: Deref, - I: DoubleEndedIterator, +impl DoubleEndedIterator for Cloned where + I: DoubleEndedIterator, + I::Item: Deref, + ::Target: Clone { - fn next_back(&mut self) -> Option { + fn next_back(&mut self) -> Option<::Item> { self.it.next_back().cloned() } } #[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for Cloned where - T: Clone, - D: Deref, - I: ExactSizeIterator, +impl ExactSizeIterator for Cloned where + I: ExactSizeIterator, + I::Item: Deref, + ::Target: Clone {} #[unstable(feature = "core", reason = "trait is experimental")] -impl RandomAccessIterator for Cloned where - T: Clone, - D: Deref, - I: RandomAccessIterator +impl RandomAccessIterator for Cloned where + I: RandomAccessIterator, + I::Item: Deref, + ::Target: Clone { #[inline] fn indexable(&self) -> usize { @@ -1325,7 +1325,7 @@ impl RandomAccessIterator for Cloned where } #[inline] - fn idx(&mut self, index: usize) -> Option { + fn idx(&mut self, index: usize) -> Option<::Item> { self.it.idx(index).cloned() } } @@ -1400,11 +1400,14 @@ pub struct Chain { } #[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for Chain where A: Iterator, B: Iterator { - type Item = T; +impl Iterator for Chain where + A: Iterator, + B: Iterator +{ + type Item = A::Item; #[inline] - fn next(&mut self) -> Option { + fn next(&mut self) -> Option { if self.flag { self.b.next() } else { @@ -1434,12 +1437,12 @@ impl Iterator for Chain where A: Iterator, B: Iterator DoubleEndedIterator for Chain where - A: DoubleEndedIterator, - B: DoubleEndedIterator, +impl DoubleEndedIterator for Chain where + A: DoubleEndedIterator, + B: DoubleEndedIterator, { #[inline] - fn next_back(&mut self) -> Option { + fn next_back(&mut self) -> Option { match self.b.next_back() { Some(x) => Some(x), None => self.a.next_back() @@ -1448,9 +1451,9 @@ impl DoubleEndedIterator for Chain where } #[unstable(feature = "core", reason = "trait is experimental")] -impl RandomAccessIterator for Chain where - A: RandomAccessIterator, - B: RandomAccessIterator, +impl RandomAccessIterator for Chain where + A: RandomAccessIterator, + B: RandomAccessIterator, { #[inline] fn indexable(&self) -> usize { @@ -1459,7 +1462,7 @@ impl RandomAccessIterator for Chain where } #[inline] - fn idx(&mut self, index: usize) -> Option { + fn idx(&mut self, index: usize) -> Option { let len = self.a.indexable(); if index < len { self.a.idx(index) @@ -1479,14 +1482,12 @@ pub struct Zip { } #[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for Zip where - A: Iterator, - B: Iterator, +impl Iterator for Zip where A: Iterator, B: Iterator { - type Item = (T, U); + type Item = (A::Item, B::Item); #[inline] - fn next(&mut self) -> Option<(T, U)> { + fn next(&mut self) -> Option<(A::Item, B::Item)> { match self.a.next() { None => None, Some(x) => match self.b.next() { @@ -1515,12 +1516,12 @@ impl Iterator for Zip where } #[stable(feature = "rust1", since = "1.0.0")] -impl DoubleEndedIterator for Zip where - A: DoubleEndedIterator + ExactSizeIterator, - B: DoubleEndedIterator + ExactSizeIterator, +impl DoubleEndedIterator for Zip where + A: DoubleEndedIterator + ExactSizeIterator, + B: DoubleEndedIterator + ExactSizeIterator, { #[inline] - fn next_back(&mut self) -> Option<(T, U)> { + fn next_back(&mut self) -> Option<(A::Item, B::Item)> { let a_sz = self.a.len(); let b_sz = self.b.len(); if a_sz != b_sz { @@ -1540,9 +1541,9 @@ impl DoubleEndedIterator for Zip where } #[unstable(feature = "core", reason = "trait is experimental")] -impl RandomAccessIterator for Zip where - A: RandomAccessIterator, - B: RandomAccessIterator, +impl RandomAccessIterator for Zip where + A: RandomAccessIterator, + B: RandomAccessIterator { #[inline] fn indexable(&self) -> usize { @@ -1550,7 +1551,7 @@ impl RandomAccessIterator for Zip where } #[inline] - fn idx(&mut self, index: usize) -> Option<(T, U)> { + fn idx(&mut self, index: usize) -> Option<(A::Item, B::Item)> { match self.a.idx(index) { None => None, Some(x) => match self.b.idx(index) { @@ -2071,8 +2072,9 @@ pub struct Scan { } #[stable(feature = "rust1", since = "1.0.0")] -impl, St, F> Iterator for Scan where - F: FnMut(&mut St, A) -> Option, +impl Iterator for Scan where + I: Iterator, + F: FnMut(&mut St, I::Item) -> Option, { type Item = B; diff --git a/src/test/run-pass/iter-cloned-type-inference.rs b/src/test/run-pass/iter-cloned-type-inference.rs new file mode 100644 index 00000000000..6ce226bbeca --- /dev/null +++ b/src/test/run-pass/iter-cloned-type-inference.rs @@ -0,0 +1,25 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test to see that the element type of .cloned() can be inferred +// properly. Previously this would fail to deduce the type of `sum`. + +#![feature(core)] + +use std::iter::AdditiveIterator; + +fn square_sum(v: &[i64]) -> i64 { + let sum = v.iter().cloned().sum(); + sum * sum +} + +fn main() { + assert_eq!(36, square_sum(&[1,2,3])); +} From 18f1e40eaaf7ccde1333fbdfc9f15c4cf462a2a4 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Thu, 5 Mar 2015 13:30:30 +0100 Subject: [PATCH 09/37] doc example does nothing --- src/libcollections/str.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index 599b92d05dd..f37f93a3e51 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -1083,7 +1083,7 @@ pub trait StrExt: Index { /// /// let s = "中华Việt Nam"; /// let mut i = s.len(); - /// while i < 0 { + /// while i > 0 { /// let CharRange {ch, next} = s.char_range_at_reverse(i); /// println!("{}: {}", i, ch); /// i = next; From e316c662f8ac029704922baa53a0831da031aea5 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 5 Mar 2015 15:00:25 +0100 Subject: [PATCH 10/37] debuginfo: Add `debuginfo::with_source_location_override()` function... ... and use it to fix a debug-location issue with constants. --- src/librustc_trans/trans/consts.rs | 2 +- src/librustc_trans/trans/debuginfo.rs | 37 +++++++++++++ src/librustc_trans/trans/expr.rs | 10 +++- src/test/debuginfo/constant-debug-locs.rs | 67 +++++++++++++++++++++++ 4 files changed, 113 insertions(+), 3 deletions(-) create mode 100644 src/test/debuginfo/constant-debug-locs.rs diff --git a/src/librustc_trans/trans/consts.rs b/src/librustc_trans/trans/consts.rs index a39f5d42b55..39b430b7ad5 100644 --- a/src/librustc_trans/trans/consts.rs +++ b/src/librustc_trans/trans/consts.rs @@ -173,7 +173,7 @@ pub fn get_const_expr<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, &**expr } else { ccx.sess().span_bug(ref_expr.span, - &format!("get_const_val given non-constant item {}", + &format!("get_const_expr given non-constant item {}", item.repr(ccx.tcx()))); } } diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs index f3b7058336b..ab35a33cfdd 100644 --- a/src/librustc_trans/trans/debuginfo.rs +++ b/src/librustc_trans/trans/debuginfo.rs @@ -695,6 +695,7 @@ struct FunctionDebugContextData { fn_metadata: DISubprogram, argument_counter: Cell, source_locations_enabled: Cell, + source_location_override: Cell, } enum VariableAccess<'a> { @@ -1174,6 +1175,12 @@ pub fn set_source_location(fcx: &FunctionContext, return; } FunctionDebugContext::RegularContext(box ref function_debug_context) => { + if function_debug_context.source_location_override.get() { + // Just ignore any attempts to set a new debug location while + // the override is active. + return; + } + let cx = fcx.ccx; debug!("set_source_location: {}", cx.sess().codemap().span_to_string(span)); @@ -1192,6 +1199,35 @@ pub fn set_source_location(fcx: &FunctionContext, } } +/// This function makes sure that all debug locations emitted while executing +/// `wrapped_function` are set to the given `debug_loc`. +pub fn with_source_location_override(fcx: &FunctionContext, + debug_loc: DebugLoc, + wrapped_function: F) -> R + where F: FnOnce() -> R +{ + match fcx.debug_context { + FunctionDebugContext::DebugInfoDisabled => { + wrapped_function() + } + FunctionDebugContext::FunctionWithoutDebugInfo => { + set_debug_location(fcx.ccx, UnknownLocation); + wrapped_function() + } + FunctionDebugContext::RegularContext(box ref function_debug_context) => { + if function_debug_context.source_location_override.get() { + wrapped_function() + } else { + debug_loc.apply(fcx); + function_debug_context.source_location_override.set(true); + let result = wrapped_function(); + function_debug_context.source_location_override.set(false); + result + } + } + } +} + /// Clears the current debug location. /// /// Instructions generated hereafter won't be assigned a source location. @@ -1412,6 +1448,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, fn_metadata: fn_metadata, argument_counter: Cell::new(1), source_locations_enabled: Cell::new(false), + source_location_override: Cell::new(false), }; diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index 60455119d58..96d3e16d253 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -147,7 +147,7 @@ pub fn trans_into<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ast::ExprPath(..) => { match bcx.def(expr.id) { def::DefConst(did) => { - let expr = consts::get_const_expr(bcx.ccx(), did, expr); + let const_expr = consts::get_const_expr(bcx.ccx(), did, expr); // Temporarily get cleanup scopes out of the way, // as they require sub-expressions to be contained // inside the current AST scope. @@ -155,7 +155,13 @@ pub fn trans_into<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, // can't have destructors. let scopes = mem::replace(&mut *bcx.fcx.scopes.borrow_mut(), vec![]); - bcx = trans_into(bcx, expr, dest); + // Lock emitted debug locations to the location of + // the constant reference expression. + debuginfo::with_source_location_override(bcx.fcx, + expr.debug_loc(), + || { + bcx = trans_into(bcx, const_expr, dest) + }); let scopes = mem::replace(&mut *bcx.fcx.scopes.borrow_mut(), scopes); assert!(scopes.is_empty()); diff --git a/src/test/debuginfo/constant-debug-locs.rs b/src/test/debuginfo/constant-debug-locs.rs new file mode 100644 index 00000000000..24332e31775 --- /dev/null +++ b/src/test/debuginfo/constant-debug-locs.rs @@ -0,0 +1,67 @@ +// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// ignore-android: FIXME(#10381) +// min-lldb-version: 310 + +// compile-flags:-g + +#![allow(unused_variables)] +#![allow(dead_code)] +#![omit_gdb_pretty_printer_section] + +// This test makes sure that the compiler doesn't crash when trying to assign +// debug locations to const-expressions. + +use std::sync::MUTEX_INIT; +use std::cell::UnsafeCell; + +const CONSTANT: u64 = 3 + 4; + +struct Struct { + a: isize, + b: usize, +} +const STRUCT: Struct = Struct { a: 1, b: 2 }; + +struct TupleStruct(u32); +const TUPLE_STRUCT: TupleStruct = TupleStruct(4); + +enum Enum { + Variant1(char), + Variant2 { a: u8 }, + Variant3 +} + +const VARIANT1: Enum = Enum::Variant1('v'); +const VARIANT2: Enum = Enum::Variant2 { a: 2 }; +const VARIANT3: Enum = Enum::Variant3; + +const STRING: &'static str = "String"; + +const VEC: [u32; 8] = [0; 8]; + +const NESTED: (Struct, TupleStruct) = (STRUCT, TUPLE_STRUCT); + +const UNSAFE_CELL: UnsafeCell = UnsafeCell { value: false }; + +fn main() { + let mut _constant = CONSTANT; + let mut _struct = STRUCT; + let mut _tuple_struct = TUPLE_STRUCT; + let mut _variant1 = VARIANT1; + let mut _variant2 = VARIANT2; + let mut _variant3 = VARIANT3; + let mut _string = STRING; + let mut _vec = VEC; + let mut _nested = NESTED; + let mut _extern = MUTEX_INIT; + let mut _unsafe_cell = UNSAFE_CELL; +} From 4a6fb45ee1c51a67d75d99244446868b36f22cc6 Mon Sep 17 00:00:00 2001 From: Kang Seonghoon Date: Thu, 5 Mar 2015 23:10:15 +0900 Subject: [PATCH 11/37] rustdoc: Reworded comments to give the rationale for JS. --- src/librustdoc/html/render.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index a9a9d0f7694..0edeff71364 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2209,7 +2209,14 @@ impl<'a> fmt::Display for Sidebar<'a> { let it = self.item; let parentlen = cx.current.len() - if it.is_mod() {1} else {0}; - // this is not rendered via JS, as that would hamper the accessibility + // the sidebar is designed to display sibling functions, modules and + // other miscellaneous informations. since there are lots of sibling + // items (and that causes quadratic growth in large modules), + // we refactor common parts into a shared JavaScript file per module. + // still, we don't move everything into JS because we want to preserve + // as much HTML as possible in order to allow non-JS-enabled browsers + // to navigate the documentation (though slightly inefficiently). + try!(write!(fmt, "
' panicked at 'arithmetic operation overflowed' +// compile-flags: -C debug-assertions // (Work around constant-evaluation) fn value() -> u8 { 200 } diff --git a/src/test/run-fail/overflowing-mul.rs b/src/test/run-fail/overflowing-mul.rs index b18d99cd232..5d2f5396240 100644 --- a/src/test/run-fail/overflowing-mul.rs +++ b/src/test/run-fail/overflowing-mul.rs @@ -9,6 +9,7 @@ // except according to those terms. // error-pattern:thread '
' panicked at 'arithmetic operation overflowed' +// compile-flags: -C debug-assertions // (Work around constant-evaluation) fn value() -> u8 { 200 } diff --git a/src/test/run-fail/overflowing-sub.rs b/src/test/run-fail/overflowing-sub.rs index ee32291eca6..b089dccbaa5 100644 --- a/src/test/run-fail/overflowing-sub.rs +++ b/src/test/run-fail/overflowing-sub.rs @@ -9,6 +9,7 @@ // except according to those terms. // error-pattern:thread '
' panicked at 'arithmetic operation overflowed' +// compile-flags: -C debug-assertions // (Work around constant-evaluation) fn value() -> u8 { 42 } diff --git a/src/test/run-make/debug-assertions/Makefile b/src/test/run-make/debug-assertions/Makefile new file mode 100644 index 00000000000..71297562768 --- /dev/null +++ b/src/test/run-make/debug-assertions/Makefile @@ -0,0 +1,21 @@ +-include ../tools.mk + +all: + $(RUSTC) debug.rs -C debug-assertions=no + $(call RUN,debug) good + $(RUSTC) debug.rs -C opt-level=0 + $(call RUN,debug) bad + $(RUSTC) debug.rs -C opt-level=1 + $(call RUN,debug) good + $(RUSTC) debug.rs -C opt-level=2 + $(call RUN,debug) good + $(RUSTC) debug.rs -C opt-level=3 + $(call RUN,debug) good + $(RUSTC) debug.rs -O + $(call RUN,debug) good + $(RUSTC) debug.rs + $(call RUN,debug) bad + $(RUSTC) debug.rs -C debug-assertions=yes -O + $(call RUN,debug) bad + $(RUSTC) debug.rs -C debug-assertions=yes -C opt-level=1 + $(call RUN,debug) bad diff --git a/src/test/run-make/debug-assertions/debug.rs b/src/test/run-make/debug-assertions/debug.rs new file mode 100644 index 00000000000..a0ccc75afd0 --- /dev/null +++ b/src/test/run-make/debug-assertions/debug.rs @@ -0,0 +1,42 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![deny(warnings)] + +use std::env; +use std::thread; + +fn main() { + let should_fail = env::args().nth(1) == Some("bad".to_string()); + + assert_eq!(thread::spawn(debug_assert_eq).join().is_err(), should_fail); + assert_eq!(thread::spawn(debug_assert).join().is_err(), should_fail); + assert_eq!(thread::spawn(overflow).join().is_err(), should_fail); +} + +fn debug_assert_eq() { + let mut hit1 = false; + let mut hit2 = false; + debug_assert_eq!({ hit1 = true; 1 }, { hit2 = true; 2 }); + assert!(!hit1); + assert!(!hit2); +} + +fn debug_assert() { + let mut hit = false; + debug_assert!({ hit = true; false }); + assert!(!hit); +} + +fn overflow() { + fn add(a: u8, b: u8) -> u8 { a + b } + + add(200u8, 200u8); +} diff --git a/src/test/run-pass/conditional-debug-macro-off.rs b/src/test/run-pass/conditional-debug-macro-off.rs index b5a5f57d07a..90142350772 100644 --- a/src/test/run-pass/conditional-debug-macro-off.rs +++ b/src/test/run-pass/conditional-debug-macro-off.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags: --cfg ndebug +// compile-flags: -C debug-assertions=no // exec-env:RUST_LOG=conditional-debug-macro-off=4 #[macro_use] diff --git a/src/test/run-pass/logging-enabled-debug.rs b/src/test/run-pass/logging-enabled-debug.rs index 262d9b21eb4..dfc92728270 100644 --- a/src/test/run-pass/logging-enabled-debug.rs +++ b/src/test/run-pass/logging-enabled-debug.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags:--cfg ndebug +// compile-flags:-C debug-assertions=no // exec-env:RUST_LOG=logging-enabled-debug=debug #[macro_use] diff --git a/src/test/run-pass/logging-separate-lines.rs b/src/test/run-pass/logging-separate-lines.rs index 8526dfe72da..82a155b1173 100644 --- a/src/test/run-pass/logging-separate-lines.rs +++ b/src/test/run-pass/logging-separate-lines.rs @@ -10,6 +10,7 @@ // ignore-windows // exec-env:RUST_LOG=debug +// compile-flags:-C debug-assertions=y #[macro_use] extern crate log; From 628f5d29c3b93bbd590e08dc2c69f842a18d1231 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 2 Mar 2015 10:46:05 -0800 Subject: [PATCH 19/37] std: Stabilize the `ffi` module The two main sub-modules, `c_str` and `os_str`, have now had some time to bake in the standard library. This commits performs a sweep over the modules adding various stability tags. The following APIs are now marked `#[stable]` * `OsString` * `OsStr` * `OsString::from_string` * `OsString::from_str` * `OsString::new` * `OsString::into_string` * `OsString::push` (renamed from `push_os_str`, added an `AsOsStr` bound) * various trait implementations for `OsString` * `OsStr::from_str` * `OsStr::to_str` * `OsStr::to_string_lossy` * `OsStr::to_os_string` * various trait implementations for `OsStr` * `CString` * `CStr` * `NulError` * `CString::new` - this API's implementation may change as a result of rust-lang/rfcs#912 but the usage of `CString::new(thing)` looks like it is unlikely to change. Additionally, the `IntoBytes` bound is also likely to change but the set of implementors for the trait will not change (despite the trait perhaps being renamed). * `CString::from_vec_unchecked` * `CString::as_bytes` * `CString::as_bytes_with_nul` * `NulError::nul_position` * `NulError::into_vec` * `CStr::from_ptr` * `CStr::as_ptr` * `CStr::to_bytes` * `CStr::to_bytes_with_nul` * various trait implementations for `CStr` The following APIs remain `#[unstable]` * `OsStr*Ext` traits remain unstable as the organization of `os::platform` is uncertain still and the traits may change location. * `AsOsStr` remains unstable as generic conversion traits are likely to be rethought soon. The following APIs were deprecated * `OsString::push_os_str` is now called `push` and takes `T: AsOsStr` instead (a superset of the previous functionality). --- src/compiletest/compiletest.rs | 1 - src/compiletest/runtest.rs | 9 +++---- src/librustc/lib.rs | 1 - src/librustc_driver/lib.rs | 1 - src/librustc_trans/back/link.rs | 8 +++--- src/librustc_trans/lib.rs | 2 -- src/librustdoc/html/render.rs | 3 +-- src/libstd/ffi/c_str.rs | 28 ++++++++++++++++++++ src/libstd/ffi/mod.rs | 11 +++++--- src/libstd/ffi/os_str.rs | 46 +++++++++++++++++++++++++++++---- src/libstd/path.rs | 8 +++--- 11 files changed, 89 insertions(+), 29 deletions(-) diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs index b9e6f1842ee..a5d087b6dd2 100644 --- a/src/compiletest/compiletest.rs +++ b/src/compiletest/compiletest.rs @@ -22,7 +22,6 @@ #![feature(unicode)] #![feature(core)] #![feature(path)] -#![feature(os)] #![feature(io)] #![feature(fs)] #![feature(net)] diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 7fb1a436ba3..04714b50fc0 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -20,7 +20,6 @@ use procsrv; use util::logv; use std::env; -use std::ffi::OsStr; use std::fmt; use std::fs::{self, File}; use std::io::BufReader; @@ -1323,7 +1322,7 @@ fn make_exe_name(config: &Config, testfile: &Path) -> PathBuf { let mut f = output_base_name(config, testfile); if !env::consts::EXE_SUFFIX.is_empty() { let mut fname = f.file_name().unwrap().to_os_string(); - fname.push_os_str(OsStr::from_str(env::consts::EXE_SUFFIX)); + fname.push(env::consts::EXE_SUFFIX); f.set_file_name(&fname); } f @@ -1433,7 +1432,7 @@ fn make_out_name(config: &Config, testfile: &Path, extension: &str) -> PathBuf { fn aux_output_dir_name(config: &Config, testfile: &Path) -> PathBuf { let f = output_base_name(config, testfile); let mut fname = f.file_name().unwrap().to_os_string(); - fname.push_os_str(OsStr::from_str("libaux")); + fname.push("libaux"); f.with_file_name(&fname) } @@ -1647,8 +1646,8 @@ fn append_suffix_to_stem(p: &Path, suffix: &str) -> PathBuf { p.to_path_buf() } else { let mut stem = p.file_stem().unwrap().to_os_string(); - stem.push_os_str(OsStr::from_str("-")); - stem.push_os_str(OsStr::from_str(suffix)); + stem.push("-"); + stem.push(suffix); p.with_file_name(&stem) } } diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 2d542eafbe1..2c426a3e7fe 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -38,7 +38,6 @@ #![feature(unsafe_destructor)] #![feature(staged_api)] #![feature(std_misc)] -#![feature(os)] #![feature(path)] #![feature(fs)] #![feature(io)] diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index aa8b7c7785d..6fa8cca23e1 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -29,7 +29,6 @@ #![feature(int_uint)] #![feature(old_io)] #![feature(libc)] -#![feature(os)] #![feature(quote)] #![feature(rustc_diagnostic_macros)] #![feature(rustc_private)] diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 1e84bc4b8e0..21c738aa4a7 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -27,7 +27,7 @@ use util::common::time; use util::ppaux; use util::sha2::{Digest, Sha256}; -use std::ffi::{AsOsStr, OsString}; +use std::ffi::OsString; use std::fs::{self, TempDir, PathExt}; use std::io::{self, Read, Write}; use std::mem; @@ -882,7 +882,7 @@ fn link_args(cmd: &mut Command, let morestack = lib_path.join("libmorestack.a"); let mut v = OsString::from_str("-Wl,-force_load,"); - v.push_os_str(morestack.as_os_str()); + v.push(&morestack); cmd.arg(&v); } else { cmd.args(&["-Wl,--whole-archive", "-lmorestack", "-Wl,--no-whole-archive"]); @@ -1007,7 +1007,7 @@ fn link_args(cmd: &mut Command, if sess.opts.cg.rpath { let mut v = OsString::from_str("-Wl,-install_name,@rpath/"); - v.push_os_str(out_filename.file_name().unwrap()); + v.push(out_filename.file_name().unwrap()); cmd.arg(&v); } } else { @@ -1107,7 +1107,7 @@ fn add_local_native_libraries(cmd: &mut Command, sess: &Session) { &search_path[..], &sess.diagnostic().handler); let mut v = OsString::from_str("-Wl,-force_load,"); - v.push_os_str(lib.as_os_str()); + v.push(&lib); cmd.arg(&v); } } diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index dcc79e90cc5..88293afa53f 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -35,12 +35,10 @@ #![feature(rustc_private)] #![feature(unsafe_destructor)] #![feature(staged_api)] -#![feature(std_misc)] #![feature(unicode)] #![feature(io)] #![feature(fs)] #![feature(path)] -#![feature(os)] #![feature(tempdir)] extern crate arena; diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index add44769bab..b00d61c0303 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -38,7 +38,6 @@ use std::cell::RefCell; use std::cmp::Ordering; use std::collections::{HashMap, HashSet}; use std::default::Default; -use std::ffi::OsStr; use std::fmt; use std::fs::{self, File}; use std::io::prelude::*; @@ -770,7 +769,7 @@ impl<'a> SourceCollector<'a> { let mut fname = p.file_name().expect("source has no filename") .to_os_string(); - fname.push_os_str(OsStr::from_str(".html")); + fname.push(".html"); cur.push(&fname); let mut w = BufWriter::new(try!(File::create(&cur))); diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index c94edb9d2a1..ec9f90723be 100644 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![unstable(feature = "std_misc")] + use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering}; use error::{Error, FromError}; use fmt; @@ -59,6 +61,7 @@ use vec::Vec; /// # } /// ``` #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash)] +#[stable(feature = "rust1", since = "1.0.0")] pub struct CString { inner: Vec, } @@ -110,13 +113,19 @@ pub struct CString { /// } /// ``` #[derive(Hash)] +#[stable(feature = "rust1", since = "1.0.0")] pub struct CStr { + // FIXME: this should not be represented with a DST slice but rather with + // just a raw `libc::c_char` along with some form of marker to make + // this an unsized type. Essentially `sizeof(&CStr)` should be the + // same as `sizeof(&c_char)` but `CStr` should be an unsized type. inner: [libc::c_char] } /// An error returned from `CString::new` to indicate that a nul byte was found /// in the vector provided. #[derive(Clone, PartialEq, Debug)] +#[stable(feature = "rust1", since = "1.0.0")] pub struct NulError(usize, Vec); /// A conversion trait used by the constructor of `CString` for types that can @@ -153,6 +162,7 @@ impl CString { /// This function will return an error if the bytes yielded contain an /// internal 0 byte. The error returned will contain the bytes as well as /// the position of the nul byte. + #[stable(feature = "rust1", since = "1.0.0")] pub fn new(t: T) -> Result { let bytes = t.into_bytes(); match bytes.iter().position(|x| *x == 0) { @@ -216,6 +226,7 @@ impl CString { /// /// This method is equivalent to `from_vec` except that no runtime assertion /// is made that `v` contains no 0 bytes. + #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn from_vec_unchecked(mut v: Vec) -> CString { v.push(0); CString { inner: v } @@ -225,17 +236,20 @@ impl CString { /// /// The returned slice does **not** contain the trailing nul separator and /// it is guaranteed to not have any interior nul bytes. + #[stable(feature = "rust1", since = "1.0.0")] pub fn as_bytes(&self) -> &[u8] { &self.inner[..self.inner.len() - 1] } /// Equivalent to the `as_bytes` function except that the returned slice /// includes the trailing nul byte. + #[stable(feature = "rust1", since = "1.0.0")] pub fn as_bytes_with_nul(&self) -> &[u8] { &self.inner } } +#[stable(feature = "rust1", since = "1.0.0")] impl Deref for CString { type Target = CStr; @@ -254,23 +268,28 @@ impl fmt::Debug for CString { impl NulError { /// Returns the position of the nul byte in the slice that was provided to /// `CString::from_vec`. + #[stable(feature = "rust1", since = "1.0.0")] pub fn nul_position(&self) -> usize { self.0 } /// Consumes this error, returning the underlying vector of bytes which /// generated the error in the first place. + #[stable(feature = "rust1", since = "1.0.0")] pub fn into_vec(self) -> Vec { self.1 } } +#[stable(feature = "rust1", since = "1.0.0")] impl Error for NulError { fn description(&self) -> &str { "nul byte found in data" } } +#[stable(feature = "rust1", since = "1.0.0")] impl fmt::Display for NulError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "nul byte found in provided data at position: {}", self.0) } } +#[stable(feature = "rust1", since = "1.0.0")] impl FromError for io::Error { fn from_error(_: NulError) -> io::Error { io::Error::new(io::ErrorKind::InvalidInput, @@ -278,6 +297,7 @@ impl FromError for io::Error { } } +#[stable(feature = "rust1", since = "1.0.0")] impl FromError for old_io::IoError { fn from_error(_: NulError) -> old_io::IoError { old_io::IoError { @@ -325,6 +345,7 @@ impl CStr { /// } /// # } /// ``` + #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn from_ptr<'a>(ptr: *const libc::c_char) -> &'a CStr { let len = libc::strlen(ptr); mem::transmute(slice::from_raw_parts(ptr, len as usize + 1)) @@ -335,6 +356,7 @@ impl CStr { /// The returned pointer will be valid for as long as `self` is and points /// to a contiguous region of memory terminated with a 0 byte to represent /// the end of the string. + #[stable(feature = "rust1", since = "1.0.0")] pub fn as_ptr(&self) -> *const libc::c_char { self.inner.as_ptr() } @@ -351,6 +373,7 @@ impl CStr { /// > **Note**: This method is currently implemented as a 0-cost cast, but /// > it is planned to alter its definition in the future to perform the /// > length calculation whenever this method is called. + #[stable(feature = "rust1", since = "1.0.0")] pub fn to_bytes(&self) -> &[u8] { let bytes = self.to_bytes_with_nul(); &bytes[..bytes.len() - 1] @@ -364,22 +387,27 @@ impl CStr { /// > **Note**: This method is currently implemented as a 0-cost cast, but /// > it is planned to alter its definition in the future to perform the /// > length calculation whenever this method is called. + #[stable(feature = "rust1", since = "1.0.0")] pub fn to_bytes_with_nul(&self) -> &[u8] { unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.inner) } } } +#[stable(feature = "rust1", since = "1.0.0")] impl PartialEq for CStr { fn eq(&self, other: &CStr) -> bool { self.to_bytes().eq(other.to_bytes()) } } +#[stable(feature = "rust1", since = "1.0.0")] impl Eq for CStr {} +#[stable(feature = "rust1", since = "1.0.0")] impl PartialOrd for CStr { fn partial_cmp(&self, other: &CStr) -> Option { self.to_bytes().partial_cmp(&other.to_bytes()) } } +#[stable(feature = "rust1", since = "1.0.0")] impl Ord for CStr { fn cmp(&self, other: &CStr) -> Ordering { self.to_bytes().cmp(&other.to_bytes()) diff --git a/src/libstd/ffi/mod.rs b/src/libstd/ffi/mod.rs index 1bff6afb776..f17dc654249 100644 --- a/src/libstd/ffi/mod.rs +++ b/src/libstd/ffi/mod.rs @@ -10,17 +10,19 @@ //! Utilities related to FFI bindings. -#![unstable(feature = "std_misc", - reason = "module just underwent fairly large reorganization and the dust \ - still needs to settle")] +#![stable(feature = "rust1", since = "1.0.0")] -pub use self::c_str::{CString, CStr, NulError, IntoBytes}; +#[stable(feature = "rust1", since = "1.0.0")] +pub use self::c_str::{CString, CStr}; +pub use self::c_str::{NulError, IntoBytes}; #[allow(deprecated)] pub use self::c_str::c_str_to_bytes; #[allow(deprecated)] pub use self::c_str::c_str_to_bytes_with_nul; +#[stable(feature = "rust1", since = "1.0.0")] pub use self::os_str::OsString; +#[stable(feature = "rust1", since = "1.0.0")] pub use self::os_str::OsStr; mod c_str; @@ -28,6 +30,7 @@ mod os_str; // FIXME (#21670): these should be defined in the os_str module /// Freely convertible to an `&OsStr` slice. +#[unstable(feature = "std_misc")] pub trait AsOsStr { /// Convert to an `&OsStr` slice. fn as_os_str(&self) -> &OsStr; diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs index 926d8e03f2c..77df831bbfe 100644 --- a/src/libstd/ffi/os_str.rs +++ b/src/libstd/ffi/os_str.rs @@ -49,17 +49,20 @@ use super::AsOsStr; /// Owned, mutable OS strings. #[derive(Clone)] +#[stable(feature = "rust1", since = "1.0.0")] pub struct OsString { inner: Buf } /// Slices into OS strings. +#[stable(feature = "rust1", since = "1.0.0")] pub struct OsStr { inner: Slice } impl OsString { /// Constructs an `OsString` at no cost by consuming a `String`. + #[stable(feature = "rust1", since = "1.0.0")] pub fn from_string(s: String) -> OsString { OsString { inner: Buf::from_string(s) } } @@ -67,11 +70,13 @@ impl OsString { /// Constructs an `OsString` by copying from a `&str` slice. /// /// Equivalent to: `OsString::from_string(String::from_str(s))`. + #[stable(feature = "rust1", since = "1.0.0")] pub fn from_str(s: &str) -> OsString { OsString { inner: Buf::from_str(s) } } /// Constructs a new empty `OsString`. + #[stable(feature = "rust1", since = "1.0.0")] pub fn new() -> OsString { OsString { inner: Buf::from_string(String::new()) } } @@ -79,16 +84,26 @@ impl OsString { /// Convert the `OsString` into a `String` if it contains valid Unicode data. /// /// On failure, ownership of the original `OsString` is returned. + #[stable(feature = "rust1", since = "1.0.0")] pub fn into_string(self) -> Result { self.inner.into_string().map_err(|buf| OsString { inner: buf} ) } /// Extend the string with the given `&OsStr` slice. + #[deprecated(since = "1.0.0", reason = "renamed to `push`")] + #[unstable(feature = "os")] pub fn push_os_str(&mut self, s: &OsStr) { self.inner.push_slice(&s.inner) } + + /// Extend the string with the given `&OsStr` slice. + #[stable(feature = "rust1", since = "1.0.0")] + pub fn push(&mut self, s: &T) { + self.inner.push_slice(&s.as_os_str().inner) + } } +#[stable(feature = "rust1", since = "1.0.0")] impl ops::Index for OsString { type Output = OsStr; @@ -98,6 +113,7 @@ impl ops::Index for OsString { } } +#[stable(feature = "rust1", since = "1.0.0")] impl ops::Deref for OsString { type Target = OsStr; @@ -107,32 +123,38 @@ impl ops::Deref for OsString { } } +#[stable(feature = "rust1", since = "1.0.0")] impl Debug for OsString { fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { fmt::Debug::fmt(&**self, formatter) } } +#[stable(feature = "rust1", since = "1.0.0")] impl PartialEq for OsString { fn eq(&self, other: &OsString) -> bool { &**self == &**other } } +#[stable(feature = "rust1", since = "1.0.0")] impl PartialEq for OsString { fn eq(&self, other: &str) -> bool { &**self == other } } +#[stable(feature = "rust1", since = "1.0.0")] impl PartialEq for str { fn eq(&self, other: &OsString) -> bool { &**other == self } } +#[stable(feature = "rust1", since = "1.0.0")] impl Eq for OsString {} +#[stable(feature = "rust1", since = "1.0.0")] impl PartialOrd for OsString { #[inline] fn partial_cmp(&self, other: &OsString) -> Option { @@ -148,6 +170,7 @@ impl PartialOrd for OsString { fn ge(&self, other: &OsString) -> bool { &**self >= &**other } } +#[stable(feature = "rust1", since = "1.0.0")] impl PartialOrd for OsString { #[inline] fn partial_cmp(&self, other: &str) -> Option { @@ -155,6 +178,7 @@ impl PartialOrd for OsString { } } +#[stable(feature = "rust1", since = "1.0.0")] impl Ord for OsString { #[inline] fn cmp(&self, other: &OsString) -> cmp::Ordering { @@ -172,6 +196,7 @@ impl Hash for OsString { impl OsStr { /// Coerce directly from a `&str` slice to a `&OsStr` slice. + #[stable(feature = "rust1", since = "1.0.0")] pub fn from_str(s: &str) -> &OsStr { unsafe { mem::transmute(Slice::from_str(s)) } } @@ -179,6 +204,7 @@ impl OsStr { /// Yield a `&str` slice if the `OsStr` is valid unicode. /// /// This conversion may entail doing a check for UTF-8 validity. + #[stable(feature = "rust1", since = "1.0.0")] pub fn to_str(&self) -> Option<&str> { self.inner.to_str() } @@ -186,11 +212,13 @@ impl OsStr { /// Convert an `OsStr` to a `Cow`. /// /// Any non-Unicode sequences are replaced with U+FFFD REPLACEMENT CHARACTER. + #[stable(feature = "rust1", since = "1.0.0")] pub fn to_string_lossy(&self) -> Cow { self.inner.to_string_lossy() } /// Copy the slice into an owned `OsString`. + #[stable(feature = "rust1", since = "1.0.0")] pub fn to_os_string(&self) -> OsString { OsString { inner: self.inner.to_owned() } } @@ -204,26 +232,31 @@ impl OsStr { } } +#[stable(feature = "rust1", since = "1.0.0")] impl PartialEq for OsStr { fn eq(&self, other: &OsStr) -> bool { self.bytes().eq(other.bytes()) } } +#[stable(feature = "rust1", since = "1.0.0")] impl PartialEq for OsStr { fn eq(&self, other: &str) -> bool { *self == *OsStr::from_str(other) } } +#[stable(feature = "rust1", since = "1.0.0")] impl PartialEq for str { fn eq(&self, other: &OsStr) -> bool { *other == *OsStr::from_str(self) } } +#[stable(feature = "rust1", since = "1.0.0")] impl Eq for OsStr {} +#[stable(feature = "rust1", since = "1.0.0")] impl PartialOrd for OsStr { #[inline] fn partial_cmp(&self, other: &OsStr) -> Option { @@ -239,6 +272,7 @@ impl PartialOrd for OsStr { fn ge(&self, other: &OsStr) -> bool { self.bytes().ge(other.bytes()) } } +#[stable(feature = "rust1", since = "1.0.0")] impl PartialOrd for OsStr { #[inline] fn partial_cmp(&self, other: &str) -> Option { @@ -249,6 +283,7 @@ impl PartialOrd for OsStr { // FIXME (#19470): cannot provide PartialOrd for str until we // have more flexible coherence rules. +#[stable(feature = "rust1", since = "1.0.0")] impl Ord for OsStr { #[inline] fn cmp(&self, other: &OsStr) -> cmp::Ordering { self.bytes().cmp(other.bytes()) } @@ -262,21 +297,25 @@ impl Hash for OsStr { } } +#[stable(feature = "rust1", since = "1.0.0")] impl Debug for OsStr { fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { self.inner.fmt(formatter) } } +#[stable(feature = "rust1", since = "1.0.0")] impl Borrow for OsString { fn borrow(&self) -> &OsStr { &self[..] } } +#[stable(feature = "rust1", since = "1.0.0")] impl ToOwned for OsStr { type Owned = OsString; fn to_owned(&self) -> OsString { self.to_os_string() } } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a, T: AsOsStr + ?Sized> AsOsStr for &'a T { fn as_os_str(&self) -> &OsStr { (*self).as_os_str() @@ -307,15 +346,12 @@ impl AsOsStr for String { } } -#[cfg(unix)] impl AsOsStr for Path { + #[cfg(unix)] fn as_os_str(&self) -> &OsStr { unsafe { mem::transmute(self.as_vec()) } } -} - -#[cfg(windows)] -impl AsOsStr for Path { + #[cfg(windows)] fn as_os_str(&self) -> &OsStr { // currently .as_str() is actually infallible on windows OsStr::from_str(self.as_str().unwrap()) diff --git a/src/libstd/path.rs b/src/libstd/path.rs index b85a0dcec81..18720ecddd9 100755 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -872,10 +872,10 @@ impl PathBuf { // `path` is a pure relative path } else if need_sep { - self.inner.push_os_str(OsStr::from_str(MAIN_SEP_STR)); + self.inner.push(MAIN_SEP_STR); } - self.inner.push_os_str(path.as_os_str()); + self.inner.push(path); } /// Truncate `self` to `self.parent()`. @@ -937,8 +937,8 @@ impl PathBuf { let extension = extension.as_os_str(); if os_str_as_u8_slice(extension).len() > 0 { - stem.push_os_str(OsStr::from_str(".")); - stem.push_os_str(extension.as_os_str()); + stem.push("."); + stem.push(extension); } self.set_file_name(&stem); From 614853734e1e3553f9f10a5bd72bb31cbd0b1e13 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Thu, 5 Mar 2015 15:27:19 -0800 Subject: [PATCH 20/37] mk: Once again rename the beta channel artifacts as 'beta' No more alphas, please. --- mk/main.mk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mk/main.mk b/mk/main.mk index 9752ee233b6..c00494be47c 100644 --- a/mk/main.mk +++ b/mk/main.mk @@ -18,7 +18,7 @@ CFG_RELEASE_NUM=1.0.0 # An optional number to put after the label, e.g. '.2' -> '-beta.2' # NB Make sure it starts with a dot to conform to semver pre-release # versions (section 9) -CFG_PRERELEASE_VERSION=.2 +CFG_PRERELEASE_VERSION= CFG_FILENAME_EXTRA=4e7c5e5c @@ -30,8 +30,8 @@ CFG_PACKAGE_VERS=$(CFG_RELEASE_NUM) CFG_DISABLE_UNSTABLE_FEATURES=1 endif ifeq ($(CFG_RELEASE_CHANNEL),beta) -CFG_RELEASE=$(CFG_RELEASE_NUM)-alpha$(CFG_PRERELEASE_VERSION) -CFG_PACKAGE_VERS=$(CFG_RELEASE_NUM)-alpha$(CFG_PRERELEASE_VERSION) +CFG_RELEASE=$(CFG_RELEASE_NUM)-beta(CFG_PRERELEASE_VERSION) +CFG_PACKAGE_VERS=$(CFG_RELEASE_NUM)-beta(CFG_PRERELEASE_VERSION) CFG_DISABLE_UNSTABLE_FEATURES=1 endif ifeq ($(CFG_RELEASE_CHANNEL),nightly) From d3e7700de45d6f6cb6acd7f598f9e635fd4de6fb Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Fri, 6 Mar 2015 02:33:24 +0300 Subject: [PATCH 21/37] std: net: enable bind_error test on all platforms Bind on non-local IP address is essentially the same test, and it works same way on all platforms. Fixes #11530 --- src/libstd/net/tcp.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libstd/net/tcp.rs b/src/libstd/net/tcp.rs index 6ce3a939c6a..fd723ea13e9 100644 --- a/src/libstd/net/tcp.rs +++ b/src/libstd/net/tcp.rs @@ -233,13 +233,13 @@ mod tests { } } - // FIXME #11530 this fails on android because tests are run as root - #[cfg_attr(any(windows, target_os = "android"), ignore)] #[test] fn bind_error() { - match TcpListener::bind("0.0.0.0:1") { + match TcpListener::bind("1.1.1.1:9999") { Ok(..) => panic!(), - Err(e) => assert_eq!(e.kind(), ErrorKind::PermissionDenied), + Err(e) => + // EADDRNOTAVAIL is mapped to ConnectionRefused + assert_eq!(e.kind(), ErrorKind::ConnectionRefused), } } From 73b0b25e326687aba319df99aee4b0c4124d4498 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 3 Mar 2015 19:18:29 -0800 Subject: [PATCH 22/37] std: Stabilize the `fs` module This commit performs a stabilization pass over the `std::fs` module now that it's had some time to bake. The change was largely just adding `#[stable]` tags, but there are a few APIs that remain `#[unstable]`. The following apis are now marked `#[stable]`: * `std::fs` (the name) * `File` * `Metadata` * `ReadDir` * `DirEntry` * `OpenOptions` * `Permissions` * `File::{open, create}` * `File::{sync_all, sync_data}` * `File::set_len` * `File::metadata` * Trait implementations for `File` and `&File` * `OpenOptions::new` * `OpenOptions::{read, write, append, truncate, create}` * `OpenOptions::open` - this function was modified, however, to not attempt to reject cross-platform openings of directories. This means that some platforms will succeed in opening a directory and others will fail. * `Metadata::{is_dir, is_file, len, permissions}` * `Permissions::{readonly, set_readonly}` * `Iterator for ReadDir` * `DirEntry::path` * `remove_file` - like with `OpenOptions::open`, the extra windows code to remove a readonly file has been removed. This means that removing a readonly file will succeed on some platforms but fail on others. * `metadata` * `rename` * `copy` * `hard_link` * `soft_link` * `read_link` * `create_dir` * `create_dir_all` * `remove_dir` * `remove_dir_all` * `read_dir` The following apis remain `#[unstable]`. * `WalkDir` and `walk` - there are many methods by which a directory walk can be constructed, and it's unclear whether the current semantics are the right ones. For example symlinks are not handled super well currently. This is now behind a new `fs_walk` feature. * `File::path` - this is an extra abstraction which the standard library provides on top of what the system offers and it's unclear whether we should be doing so. This is now behind a new `file_path` feature. * `Metadata::{accessed, modified}` - we do not currently have a good abstraction for a moment in time which is what these APIs should likely be returning, so these remain `#[unstable]` for now. These are now behind a new `fs_time` feature * `set_file_times` - like with `Metadata::accessed`, we do not currently have the appropriate abstraction for the arguments here so this API remains unstable behind the `fs_time` feature gate. * `PathExt` - the precise set of methods on this trait may change over time and some methods may be removed. This API remains unstable behind the `path_ext` feature gate. * `set_permissions` - we may wish to expose a more granular ability to set the permissions on a file instead of just a blanket "set all permissions" method. This function remains behind the `fs` feature. The following apis are now `#[deprecated]` * The `TempDir` type is now entirely deprecated and is [located on crates.io][tempdir] as the `tempdir` crate with [its source][github] at rust-lang/tempdir. [tempdir]: https://crates.io/crates/tempdir [github]: https://github.com/rust-lang/tempdir The stability of some of these APIs has been questioned over the past few weeks in using these APIs, and it is intentional that the majority of APIs here are marked `#[stable]`. The `std::fs` module has a lot of room to grow and the material is [being tracked in a RFC issue][rfc-issue]. [rfc-issue]: https://github.com/rust-lang/rfcs/issues/939 [breaking-change] --- src/compiletest/compiletest.rs | 2 +- src/libgetopts/lib.rs | 2 +- src/librustc/lib.rs | 2 +- src/librustc_back/archive.rs | 4 +- src/librustc_back/lib.rs | 5 +- src/librustc_back/tempdir.rs | 121 ++++++++++++++++++++++++++++++++ src/librustc_driver/lib.rs | 1 - src/librustc_trans/back/link.rs | 3 +- src/librustc_trans/lib.rs | 4 +- src/librustdoc/lib.rs | 4 +- src/librustdoc/test.rs | 2 +- src/libstd/fs/mod.rs | 120 +++++++++++++++++++++---------- src/libstd/fs/tempdir.rs | 3 + src/libsyntax/lib.rs | 2 +- src/libterm/lib.rs | 2 +- src/libtest/lib.rs | 1 - src/rustbook/build.rs | 3 +- src/rustbook/main.rs | 4 +- 18 files changed, 229 insertions(+), 56 deletions(-) create mode 100644 src/librustc_back/tempdir.rs diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs index b9e6f1842ee..a7531152a84 100644 --- a/src/compiletest/compiletest.rs +++ b/src/compiletest/compiletest.rs @@ -24,8 +24,8 @@ #![feature(path)] #![feature(os)] #![feature(io)] -#![feature(fs)] #![feature(net)] +#![feature(path_ext)] #![deny(warnings)] diff --git a/src/libgetopts/lib.rs b/src/libgetopts/lib.rs index 6b9d6cb0000..49a062ca3e4 100644 --- a/src/libgetopts/lib.rs +++ b/src/libgetopts/lib.rs @@ -92,8 +92,8 @@ #![feature(collections)] #![feature(int_uint)] #![feature(staged_api)] -#![feature(str_words)] #![feature(core)] +#![feature(str_words)] #![cfg_attr(test, feature(rustc_private))] #[cfg(test)] #[macro_use] extern crate log; diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 2d542eafbe1..027360b31ad 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -40,8 +40,8 @@ #![feature(std_misc)] #![feature(os)] #![feature(path)] -#![feature(fs)] #![feature(io)] +#![feature(path_ext)] #![cfg_attr(test, feature(test))] extern crate arena; diff --git a/src/librustc_back/archive.rs b/src/librustc_back/archive.rs index a6994387f8d..ed44bf89529 100644 --- a/src/librustc_back/archive.rs +++ b/src/librustc_back/archive.rs @@ -11,7 +11,7 @@ //! A helper class for dealing with static archives use std::env; -use std::fs::{self, TempDir}; +use std::fs; use std::io::prelude::*; use std::io; use std::path::{Path, PathBuf}; @@ -19,6 +19,8 @@ use std::process::{Command, Output, Stdio}; use std::str; use syntax::diagnostic::Handler as ErrorHandler; +use tempdir::TempDir; + pub const METADATA_FILENAME: &'static str = "rust.metadata.bin"; pub struct ArchiveConfig<'a> { diff --git a/src/librustc_back/lib.rs b/src/librustc_back/lib.rs index 2b028a5c626..a7ae9661c3d 100644 --- a/src/librustc_back/lib.rs +++ b/src/librustc_back/lib.rs @@ -34,7 +34,6 @@ #![feature(collections)] #![feature(core)] #![feature(old_fs)] -#![feature(fs)] #![feature(hash)] #![feature(int_uint)] #![feature(io)] @@ -44,7 +43,8 @@ #![feature(path)] #![feature(rustc_private)] #![feature(staged_api)] -#![feature(tempdir)] +#![feature(rand)] +#![feature(path_ext)] extern crate syntax; extern crate serialize; @@ -52,6 +52,7 @@ extern crate serialize; pub mod abi; pub mod archive; +pub mod tempdir; pub mod arm; pub mod fs; pub mod mips; diff --git a/src/librustc_back/tempdir.rs b/src/librustc_back/tempdir.rs new file mode 100644 index 00000000000..4d8619a8121 --- /dev/null +++ b/src/librustc_back/tempdir.rs @@ -0,0 +1,121 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::env; +use std::io::{self, Error, ErrorKind}; +use std::fs; +use std::path::{self, PathBuf, AsPath}; +use std::rand::{thread_rng, Rng}; + +/// A wrapper for a path to temporary directory implementing automatic +/// scope-based deletion. +pub struct TempDir { + path: Option, +} + +// How many times should we (re)try finding an unused random name? It should be +// enough that an attacker will run out of luck before we run out of patience. +const NUM_RETRIES: u32 = 1 << 31; +// How many characters should we include in a random file name? It needs to +// be enough to dissuade an attacker from trying to preemptively create names +// of that length, but not so huge that we unnecessarily drain the random number +// generator of entropy. +const NUM_RAND_CHARS: uint = 12; + +impl TempDir { + /// Attempts to make a temporary directory inside of `tmpdir` whose name + /// will have the prefix `prefix`. The directory will be automatically + /// deleted once the returned wrapper is destroyed. + /// + /// If no directory can be created, `Err` is returned. + #[allow(deprecated)] // rand usage + pub fn new_in(tmpdir: &P, prefix: &str) + -> io::Result { + let storage; + let mut tmpdir = tmpdir.as_path(); + if !tmpdir.is_absolute() { + let cur_dir = try!(env::current_dir()); + storage = cur_dir.join(tmpdir); + tmpdir = &storage; + // return TempDir::new_in(&cur_dir.join(tmpdir), prefix); + } + + let mut rng = thread_rng(); + for _ in 0..NUM_RETRIES { + let suffix: String = rng.gen_ascii_chars().take(NUM_RAND_CHARS).collect(); + let leaf = if prefix.len() > 0 { + format!("{}.{}", prefix, suffix) + } else { + // If we're given an empty string for a prefix, then creating a + // directory starting with "." would lead to it being + // semi-invisible on some systems. + suffix + }; + let path = tmpdir.join(&leaf); + match fs::create_dir(&path) { + Ok(_) => return Ok(TempDir { path: Some(path) }), + Err(ref e) if e.kind() == ErrorKind::PathAlreadyExists => {} + Err(e) => return Err(e) + } + } + + Err(Error::new(ErrorKind::PathAlreadyExists, + "too many temporary directories already exist", + None)) + } + + /// Attempts to make a temporary directory inside of `env::temp_dir()` whose + /// name will have the prefix `prefix`. The directory will be automatically + /// deleted once the returned wrapper is destroyed. + /// + /// If no directory can be created, `Err` is returned. + #[allow(deprecated)] + pub fn new(prefix: &str) -> io::Result { + TempDir::new_in(&env::temp_dir(), prefix) + } + + /// Unwrap the wrapped `std::path::Path` from the `TempDir` wrapper. + /// This discards the wrapper so that the automatic deletion of the + /// temporary directory is prevented. + pub fn into_path(mut self) -> PathBuf { + self.path.take().unwrap() + } + + /// Access the wrapped `std::path::Path` to the temporary directory. + pub fn path(&self) -> &path::Path { + self.path.as_ref().unwrap() + } + + /// Close and remove the temporary directory + /// + /// Although `TempDir` removes the directory on drop, in the destructor + /// any errors are ignored. To detect errors cleaning up the temporary + /// directory, call `close` instead. + pub fn close(mut self) -> io::Result<()> { + self.cleanup_dir() + } + + fn cleanup_dir(&mut self) -> io::Result<()> { + match self.path { + Some(ref p) => fs::remove_dir_all(p), + None => Ok(()) + } + } +} + +impl Drop for TempDir { + fn drop(&mut self) { + let _ = self.cleanup_dir(); + } +} + +// the tests for this module need to change the path using change_dir, +// and this doesn't play nicely with other tests so these unit tests are located +// in src/test/run-pass/tempfile.rs diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index aa8b7c7785d..b8e84e57a78 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -39,7 +39,6 @@ #![feature(exit_status)] #![feature(path)] #![feature(io)] -#![feature(fs)] extern crate arena; extern crate flate; diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 1e84bc4b8e0..f353c69eca2 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -26,9 +26,10 @@ use middle::ty::{self, Ty}; use util::common::time; use util::ppaux; use util::sha2::{Digest, Sha256}; +use rustc_back::tempdir::TempDir; use std::ffi::{AsOsStr, OsString}; -use std::fs::{self, TempDir, PathExt}; +use std::fs::{self, PathExt}; use std::io::{self, Read, Write}; use std::mem; use std::path::{Path, PathBuf}; diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index dcc79e90cc5..7cdd1d0a456 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -38,10 +38,10 @@ #![feature(std_misc)] #![feature(unicode)] #![feature(io)] -#![feature(fs)] #![feature(path)] #![feature(os)] -#![feature(tempdir)] +#![feature(path_ext)] +#![feature(fs)] extern crate arena; extern crate flate; diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index b4522ad680b..712168ae706 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -35,9 +35,8 @@ #![feature(unicode)] #![feature(str_words)] #![feature(io)] -#![feature(fs)] #![feature(path)] -#![feature(tempdir)] +#![feature(path_ext)] extern crate arena; extern crate getopts; @@ -47,6 +46,7 @@ extern crate rustc_trans; extern crate rustc_driver; extern crate rustc_resolve; extern crate rustc_lint; +extern crate rustc_back; extern crate serialize; extern crate syntax; extern crate "test" as testing; diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 9fd38ecb136..80b0177021e 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -13,7 +13,6 @@ use std::collections::{HashSet, HashMap}; use std::dynamic_lib::DynamicLibrary; use std::env; use std::ffi::OsString; -use std::fs::TempDir; use std::old_io; use std::io; use std::path::PathBuf; @@ -28,6 +27,7 @@ use rustc_lint; use rustc::session::{self, config}; use rustc::session::config::get_unstable_features_setting; use rustc::session::search_paths::{SearchPaths, PathKind}; +use rustc_back::tempdir::TempDir; use rustc_driver::{driver, Compilation}; use syntax::codemap::CodeMap; use syntax::diagnostic; diff --git a/src/libstd/fs/mod.rs b/src/libstd/fs/mod.rs index 64ec025a5c4..706a51c6c9a 100644 --- a/src/libstd/fs/mod.rs +++ b/src/libstd/fs/mod.rs @@ -15,7 +15,7 @@ //! operations. Extra platform-specific functionality can be found in the //! extension traits of `std::os::$platform`. -#![unstable(feature = "fs")] +#![stable(feature = "rust1", since = "1.0.0")] use core::prelude::*; @@ -25,6 +25,7 @@ use sys::fs2 as fs_imp; use sys_common::{AsInnerMut, FromInner, AsInner}; use vec::Vec; +#[allow(deprecated)] pub use self::tempdir::TempDir; mod tempdir; @@ -52,6 +53,7 @@ mod tempdir; /// # Ok(()) /// # } /// ``` +#[stable(feature = "rust1", since = "1.0.0")] pub struct File { inner: fs_imp::File, path: PathBuf, @@ -62,6 +64,7 @@ pub struct File { /// 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. +#[stable(feature = "rust1", since = "1.0.0")] pub struct Metadata(fs_imp::FileAttr); /// Iterator over the entries in a directory. @@ -70,6 +73,7 @@ pub struct Metadata(fs_imp::FileAttr); /// will yield instances of `io::Result`. Through a `DirEntry` /// information like the entry's path and possibly other metadata can be /// learned. +#[stable(feature = "rust1", since = "1.0.0")] pub struct ReadDir(fs_imp::ReadDir); /// Entries returned by the `ReadDir` iterator. @@ -77,9 +81,14 @@ pub struct ReadDir(fs_imp::ReadDir); /// 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 /// path or possibly other metadata through per-platform extension traits. +#[stable(feature = "rust1", since = "1.0.0")] pub struct DirEntry(fs_imp::DirEntry); /// An iterator that recursively walks over the contents of a directory. +#[unstable(feature = "fs_walk", + reason = "the precise semantics and defaults for a recursive walk \ + may change and this may end up accounting for files such \ + as symlinks differently")] pub struct WalkDir { cur: Option, stack: Vec>, @@ -92,6 +101,7 @@ pub struct WalkDir { /// `File::create` methods are aliases for commonly used options using this /// builder. #[derive(Clone)] +#[stable(feature = "rust1", since = "1.0.0")] pub struct OpenOptions(fs_imp::OpenOptions); /// Representation of the various permissions on a file. @@ -101,6 +111,7 @@ pub struct OpenOptions(fs_imp::OpenOptions); /// functionality, such as mode bits, is available through the /// `os::unix::PermissionsExt` trait. #[derive(Clone, PartialEq, Eq, Debug)] +#[stable(feature = "rust1", since = "1.0.0")] pub struct Permissions(fs_imp::FilePermissions); impl File { @@ -112,6 +123,7 @@ impl File { /// /// This function will return an error if `path` does not already exist. /// Other errors may also be returned according to `OpenOptions::open`. + #[stable(feature = "rust1", since = "1.0.0")] pub fn open(path: &P) -> io::Result { OpenOptions::new().read(true).open(path) } @@ -122,11 +134,15 @@ impl File { /// and will truncate it if it does. /// /// See the `OpenOptions::open` function for more details. + #[stable(feature = "rust1", since = "1.0.0")] pub fn create(path: &P) -> io::Result { OpenOptions::new().write(true).create(true).truncate(true).open(path) } /// Returns the original path that was used to open this file. + #[unstable(feature = "file_path", + reason = "this abstraction is imposed by this library instead \ + of the underlying OS and may be removed")] pub fn path(&self) -> Option<&Path> { Some(&self.path) } @@ -135,6 +151,7 @@ impl File { /// /// This function will attempt to ensure that all in-core data reaches the /// filesystem before returning. + #[stable(feature = "rust1", since = "1.0.0")] pub fn sync_all(&self) -> io::Result<()> { self.inner.fsync() } @@ -148,6 +165,7 @@ impl File { /// /// Note that some platforms may simply implement this in terms of /// `sync_all`. + #[stable(feature = "rust1", since = "1.0.0")] pub fn sync_data(&self) -> io::Result<()> { self.inner.datasync() } @@ -159,11 +177,13 @@ impl File { /// be shrunk. If it is greater than the current file's size, then the file /// will be extended to `size` and have all of the intermediate data filled /// in with 0s. + #[stable(feature = "rust1", since = "1.0.0")] pub fn set_len(&self, size: u64) -> io::Result<()> { self.inner.truncate(size) } - /// Queries information about the underlying file. + /// Queries metadata about the underlying file. + #[stable(feature = "rust1", since = "1.0.0")] pub fn metadata(&self) -> io::Result { self.inner.file_attr().map(Metadata) } @@ -172,33 +192,39 @@ impl File { impl AsInner for File { fn as_inner(&self) -> &fs_imp::File { &self.inner } } +#[stable(feature = "rust1", since = "1.0.0")] impl Read for File { fn read(&mut self, buf: &mut [u8]) -> io::Result { self.inner.read(buf) } } +#[stable(feature = "rust1", since = "1.0.0")] impl Write for File { fn write(&mut self, buf: &[u8]) -> io::Result { self.inner.write(buf) } fn flush(&mut self) -> io::Result<()> { self.inner.flush() } } +#[stable(feature = "rust1", since = "1.0.0")] impl Seek for File { fn seek(&mut self, pos: SeekFrom) -> io::Result { self.inner.seek(pos) } } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> Read for &'a File { fn read(&mut self, buf: &mut [u8]) -> io::Result { self.inner.read(buf) } } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> Write for &'a File { fn write(&mut self, buf: &[u8]) -> io::Result { self.inner.write(buf) } fn flush(&mut self) -> io::Result<()> { self.inner.flush() } } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> Seek for &'a File { fn seek(&mut self, pos: SeekFrom) -> io::Result { self.inner.seek(pos) @@ -209,6 +235,7 @@ impl OpenOptions { /// Creates a blank net set of options ready for configuration. /// /// All options are initially set to `false`. + #[stable(feature = "rust1", since = "1.0.0")] pub fn new() -> OpenOptions { OpenOptions(fs_imp::OpenOptions::new()) } @@ -217,6 +244,7 @@ impl OpenOptions { /// /// This option, when true, will indicate that the file should be /// `read`-able if opened. + #[stable(feature = "rust1", since = "1.0.0")] pub fn read(&mut self, read: bool) -> &mut OpenOptions { self.0.read(read); self } @@ -225,6 +253,7 @@ impl OpenOptions { /// /// This option, when true, will indicate that the file should be /// `write`-able if opened. + #[stable(feature = "rust1", since = "1.0.0")] pub fn write(&mut self, write: bool) -> &mut OpenOptions { self.0.write(write); self } @@ -233,6 +262,7 @@ impl OpenOptions { /// /// This option, when true, means that writes will append to a file instead /// of overwriting previous contents. + #[stable(feature = "rust1", since = "1.0.0")] pub fn append(&mut self, append: bool) -> &mut OpenOptions { self.0.append(append); self } @@ -241,6 +271,7 @@ impl OpenOptions { /// /// If a file is successfully opened with this option set it will truncate /// the file to 0 length if it already exists. + #[stable(feature = "rust1", since = "1.0.0")] pub fn truncate(&mut self, truncate: bool) -> &mut OpenOptions { self.0.truncate(truncate); self } @@ -249,6 +280,7 @@ impl OpenOptions { /// /// This option indicates whether a new file will be created if the file /// does not yet already exist. + #[stable(feature = "rust1", since = "1.0.0")] pub fn create(&mut self, create: bool) -> &mut OpenOptions { self.0.create(create); self } @@ -264,37 +296,33 @@ impl OpenOptions { /// * Attempting to open a file with access that the user lacks /// permissions for /// * Filesystem-level errors (full disk, etc) + #[stable(feature = "rust1", since = "1.0.0")] pub fn open(&self, path: &P) -> io::Result { let path = path.as_path(); let inner = try!(fs_imp::File::open(path, &self.0)); - - // On *BSD systems, we can open a directory as a file and read from - // it: fd=open("/tmp", O_RDONLY); read(fd, buf, N); due to an old - // tradition before the introduction of opendir(3). We explicitly - // reject it because there are few use cases. - if cfg!(not(any(target_os = "linux", target_os = "android"))) && - try!(inner.file_attr()).is_dir() { - Err(Error::new(ErrorKind::InvalidInput, "is a directory", None)) - } else { - Ok(File { path: path.to_path_buf(), inner: inner }) - } + Ok(File { path: path.to_path_buf(), inner: inner }) } } + impl AsInnerMut for OpenOptions { fn as_inner_mut(&mut self) -> &mut fs_imp::OpenOptions { &mut self.0 } } impl Metadata { /// Returns whether this metadata is for a directory. + #[stable(feature = "rust1", since = "1.0.0")] pub fn is_dir(&self) -> bool { self.0.is_dir() } /// Returns whether this metadata is for a regular file. + #[stable(feature = "rust1", since = "1.0.0")] pub fn is_file(&self) -> bool { self.0.is_file() } /// Returns the size of the file, in bytes, this metadata is for. + #[stable(feature = "rust1", since = "1.0.0")] pub fn len(&self) -> u64 { self.0.size() } /// Returns the permissions of the file this metadata is for. + #[stable(feature = "rust1", since = "1.0.0")] pub fn permissions(&self) -> Permissions { Permissions(self.0.perm()) } @@ -302,22 +330,32 @@ impl Metadata { /// Returns the most recent access time for a file. /// /// The return value is in milliseconds since the epoch. + #[unstable(feature = "fs_time", + reason = "the return type of u64 is not quite appropriate for \ + this method and may change if the standard library \ + gains a type to represent a moment in time")] pub fn accessed(&self) -> u64 { self.0.accessed() } /// Returns the most recent modification time for a file. /// /// The return value is in milliseconds since the epoch. + #[unstable(feature = "fs_time", + reason = "the return type of u64 is not quite appropriate for \ + this method and may change if the standard library \ + gains a type to represent a moment in time")] pub fn modified(&self) -> u64 { self.0.modified() } } impl Permissions { /// Returns whether these permissions describe a readonly file. + #[stable(feature = "rust1", since = "1.0.0")] pub fn readonly(&self) -> bool { self.0.readonly() } /// Modify the readonly flag for this set of permissions. /// /// This operation does **not** modify the filesystem. To modify the /// filesystem use the `fs::set_permissions` function. + #[stable(feature = "rust1", since = "1.0.0")] pub fn set_readonly(&mut self, readonly: bool) { self.0.set_readonly(readonly) } @@ -333,6 +371,7 @@ impl AsInner for Permissions { fn as_inner(&self) -> &fs_imp::FilePermissions { &self.0 } } +#[stable(feature = "rust1", since = "1.0.0")] impl Iterator for ReadDir { type Item = io::Result; @@ -341,11 +380,13 @@ impl Iterator for ReadDir { } } +#[stable(feature = "rust1", since = "1.0.0")] 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. + #[stable(feature = "rust1", since = "1.0.0")] pub fn path(&self) -> PathBuf { self.0.path() } } @@ -368,31 +409,9 @@ impl DirEntry { /// This function will return an error if `path` points to a directory, if the /// user lacks permissions to remove the file, or if some other filesystem-level /// error occurs. +#[stable(feature = "rust1", since = "1.0.0")] pub fn remove_file(path: &P) -> io::Result<()> { - let path = path.as_path(); - let e = match fs_imp::unlink(path) { - Ok(()) => return Ok(()), - Err(e) => e, - }; - if !cfg!(windows) { return Err(e) } - - // On unix, a readonly file can be successfully removed. On windows, - // however, it cannot. To keep the two platforms in line with - // respect to their behavior, catch this case on windows, attempt to - // change it to read-write, and then remove the file. - if e.kind() != ErrorKind::PermissionDenied { return Err(e) } - - let attr = match metadata(path) { Ok(a) => a, Err(..) => return Err(e) }; - let mut perms = attr.permissions(); - if !perms.readonly() { return Err(e) } - perms.set_readonly(false); - - if set_permissions(path, perms).is_err() { return Err(e) } - if fs_imp::unlink(path).is_ok() { return Ok(()) } - - // Oops, try to put things back the way we found it - let _ = set_permissions(path, attr.permissions()); - Err(e) + fs_imp::unlink(path.as_path()) } /// Given a path, query the file system to get information about a file, @@ -418,6 +437,7 @@ pub fn remove_file(path: &P) -> io::Result<()> { /// This function will return an error if the user lacks the requisite /// permissions to perform a `metadata` call on the given `path` or if there /// is no entry in the filesystem at the provided path. +#[stable(feature = "rust1", since = "1.0.0")] pub fn metadata(path: &P) -> io::Result { fs_imp::stat(path.as_path()).map(Metadata) } @@ -438,6 +458,7 @@ pub fn metadata(path: &P) -> io::Result { /// the process lacks permissions to view the contents, if `from` and `to` /// reside on separate filesystems, or if some other intermittent I/O error /// occurs. +#[stable(feature = "rust1", since = "1.0.0")] pub fn rename(from: &P, to: &Q) -> io::Result<()> { fs_imp::rename(from.as_path(), to.as_path()) @@ -468,6 +489,7 @@ pub fn rename(from: &P, to: &Q) /// * The `from` file does not exist /// * The current process does not have the permission rights to access /// `from` or write `to` +#[stable(feature = "rust1", since = "1.0.0")] pub fn copy(from: &P, to: &Q) -> io::Result { let from = from.as_path(); @@ -490,6 +512,7 @@ pub fn copy(from: &P, to: &Q) /// /// The `dst` path will be a link pointing to the `src` path. Note that systems /// often require these two paths to both be located on the same filesystem. +#[stable(feature = "rust1", since = "1.0.0")] pub fn hard_link(src: &P, dst: &Q) -> io::Result<()> { fs_imp::link(src.as_path(), dst.as_path()) @@ -498,6 +521,7 @@ pub fn hard_link(src: &P, dst: &Q) /// Creates a new soft link on the filesystem. /// /// The `dst` path will be a soft link pointing to the `src` path. +#[stable(feature = "rust1", since = "1.0.0")] pub fn soft_link(src: &P, dst: &Q) -> io::Result<()> { fs_imp::symlink(src.as_path(), dst.as_path()) @@ -510,6 +534,7 @@ pub fn soft_link(src: &P, dst: &Q) /// This function will return an error on failure. Failure conditions include /// reading a file that does not exist or reading a file that is not a soft /// link. +#[stable(feature = "rust1", since = "1.0.0")] pub fn read_link(path: &P) -> io::Result { fs_imp::readlink(path.as_path()) } @@ -528,6 +553,7 @@ pub fn read_link(path: &P) -> io::Result { /// /// This function will return an error if the user lacks permissions to make a /// new directory at the provided `path`, or if the directory already exists. +#[stable(feature = "rust1", since = "1.0.0")] pub fn create_dir(path: &P) -> io::Result<()> { fs_imp::mkdir(path.as_path()) } @@ -541,6 +567,7 @@ pub fn create_dir(path: &P) -> io::Result<()> { /// does not already exist and it could not be created otherwise. The specific /// error conditions for when a directory is being created (after it is /// determined to not exist) are outlined by `fs::create_dir`. +#[stable(feature = "rust1", since = "1.0.0")] pub fn create_dir_all(path: &P) -> io::Result<()> { let path = path.as_path(); if path.is_dir() { return Ok(()) } @@ -572,6 +599,7 @@ pub fn create_dir_all(path: &P) -> io::Result<()> { /// /// This function will return an error if the user lacks permissions to remove /// the directory at the provided `path`, or if the directory isn't empty. +#[stable(feature = "rust1", since = "1.0.0")] pub fn remove_dir(path: &P) -> io::Result<()> { fs_imp::rmdir(path.as_path()) } @@ -585,6 +613,7 @@ pub fn remove_dir(path: &P) -> io::Result<()> { /// # Errors /// /// See `file::remove_file` and `fs::remove_dir` +#[stable(feature = "rust1", since = "1.0.0")] pub fn remove_dir_all(path: &P) -> io::Result<()> { let path = path.as_path(); for child in try!(read_dir(path)) { @@ -637,6 +666,7 @@ pub fn remove_dir_all(path: &P) -> io::Result<()> { /// This function will return an error if the provided `path` doesn't exist, if /// the process lacks permissions to view the contents or if the `path` points /// at a non-directory file +#[stable(feature = "rust1", since = "1.0.0")] pub fn read_dir(path: &P) -> io::Result { fs_imp::readdir(path.as_path()).map(ReadDir) } @@ -649,11 +679,16 @@ pub fn read_dir(path: &P) -> io::Result { /// /// The iterator will yield instances of `io::Result`. New errors may /// be encountered after an iterator is initially constructed. +#[unstable(feature = "fs_walk", + reason = "the precise semantics and defaults for a recursive walk \ + may change and this may end up accounting for files such \ + as symlinks differently")] pub fn walk_dir(path: &P) -> io::Result { let start = try!(read_dir(path)); Ok(WalkDir { cur: Some(start), stack: Vec::new() }) } +#[unstable(feature = "fs_walk")] impl Iterator for WalkDir { type Item = io::Result; @@ -683,6 +718,9 @@ impl Iterator for WalkDir { } /// Utility methods for paths. +#[unstable(feature = "path_ext", + reason = "the precise set of methods exposed on this trait may \ + change and some methods may be removed")] pub trait PathExt { /// Get information on the file, directory, etc at this path. /// @@ -727,6 +765,10 @@ impl PathExt for Path { /// The file at the path specified will have its last access time set to /// `atime` and its modification time set to `mtime`. The times specified should /// be in milliseconds. +#[unstable(feature = "fs_time", + reason = "the argument type of u64 is not quite appropriate for \ + this function and may change if the standard library \ + gains a type to represent a moment in time")] pub fn set_file_times(path: &P, accessed: u64, modified: u64) -> io::Result<()> { fs_imp::utimes(path.as_path(), accessed, modified) @@ -752,6 +794,10 @@ pub fn set_file_times(path: &P, accessed: u64, /// This function will return an error if the provided `path` doesn't exist, if /// the process lacks permissions to change the attributes of the file, or if /// some other I/O error is encountered. +#[unstable(feature = "fs", + reason = "a more granual ability to set specific permissions may \ + be exposed on the Permissions structure itself and this \ + method may not always exist")] pub fn set_permissions(path: &P, perm: Permissions) -> io::Result<()> { fs_imp::set_perm(path.as_path(), perm.0) diff --git a/src/libstd/fs/tempdir.rs b/src/libstd/fs/tempdir.rs index 79bdb35dd48..c1da77a6668 100644 --- a/src/libstd/fs/tempdir.rs +++ b/src/libstd/fs/tempdir.rs @@ -9,6 +9,9 @@ // except according to those terms. #![unstable(feature = "tempdir", reason = "needs an RFC before stabilization")] +#![deprecated(since = "1.0.0", + reason = "use the `tempdir` crate from crates.io instead")] +#![allow(deprecated)] use prelude::v1::*; diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 7bd9cc3b855..c0977508112 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -37,8 +37,8 @@ #![feature(std_misc)] #![feature(unicode)] #![feature(path)] -#![feature(fs)] #![feature(io)] +#![feature(path_ext)] extern crate arena; extern crate fmt_macros; diff --git a/src/libterm/lib.rs b/src/libterm/lib.rs index ba9860ee31f..d4e22c72e16 100644 --- a/src/libterm/lib.rs +++ b/src/libterm/lib.rs @@ -52,7 +52,6 @@ #![feature(box_syntax)] #![feature(collections)] -#![feature(fs)] #![feature(int_uint)] #![feature(io)] #![feature(old_io)] @@ -61,6 +60,7 @@ #![feature(staged_api)] #![feature(std_misc)] #![feature(unicode)] +#![feature(path_ext)] #![cfg_attr(windows, feature(libc))] #[macro_use] extern crate log; diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index e309e7a6c22..60dd91f8c71 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -39,7 +39,6 @@ #![feature(int_uint)] #![feature(old_io)] #![feature(path)] -#![feature(fs)] #![feature(rustc_private)] #![feature(staged_api)] #![feature(std_misc)] diff --git a/src/rustbook/build.rs b/src/rustbook/build.rs index 1fb30e15400..731773917e0 100644 --- a/src/rustbook/build.rs +++ b/src/rustbook/build.rs @@ -11,10 +11,11 @@ //! Implementation of the `build` subcommand, used to compile a book. use std::env; -use std::fs::{self, File, TempDir}; +use std::fs::{self, File}; use std::io::prelude::*; use std::io::{self, BufWriter}; use std::path::{Path, PathBuf}; +use rustc_back::tempdir::TempDir; use subcommand::Subcommand; use term::Term; diff --git a/src/rustbook/main.rs b/src/rustbook/main.rs index 848f960839e..8df622b0b5d 100644 --- a/src/rustbook/main.rs +++ b/src/rustbook/main.rs @@ -12,14 +12,14 @@ #![feature(core)] #![feature(exit_status)] -#![feature(fs)] #![feature(io)] #![feature(old_io)] #![feature(path)] #![feature(rustdoc)] -#![feature(tempdir)] +#![feature(rustc_private)] extern crate rustdoc; +extern crate rustc_back; use std::env; use std::error::Error; From a08f12954c0cfdc0864aea9b1b958ff0b4ee222d Mon Sep 17 00:00:00 2001 From: Paul Osborne Date: Thu, 5 Mar 2015 19:11:59 -0600 Subject: [PATCH 23/37] fix minor grammar mistake in paths documentation --- src/libstd/path.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/path.rs b/src/libstd/path.rs index b85a0dcec81..af3cf57082d 100755 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -90,7 +90,7 @@ //! * Repeated separators are ignored: `a/b` and `a//b` both have components `a` //! and `b`. //! -//! * Paths ending in a separator are treated as if they has a current directory +//! * Paths ending in a separator are treated as if they have a current directory //! component at the end (or, in verbatim paths, an empty component). For //! example, while `a/b` has components `a` and `b`, the paths `a/b/` and //! `a/b/.` both have components `a`, `b`, and `.` (current directory). The From 65b4eda5a6f270f5c30beec66c59825aba0524b9 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 5 Mar 2015 17:20:16 -0800 Subject: [PATCH 24/37] std: Fix peeling ports from addresses The `rsplitn` call was called with 2 instead of 1 so the iterator would yield 3 items in some cases, not the 2 that it should have. Closes #23076 --- src/libstd/net/addr.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs index f16f501c46a..e767ebfa2d9 100644 --- a/src/libstd/net/addr.rs +++ b/src/libstd/net/addr.rs @@ -293,7 +293,7 @@ impl ToSocketAddrs for str { } // split the string by ':' and convert the second part to u16 - let mut parts_iter = self.rsplitn(2, ':'); + let mut parts_iter = self.rsplitn(1, ':'); let port_str = try_opt!(parts_iter.next(), "invalid socket address"); let host = try_opt!(parts_iter.next(), "invalid socket address"); let port: u16 = try_opt!(port_str.parse().ok(), "invalid port value"); @@ -590,4 +590,9 @@ mod tests { let a = SocketAddr::new(IpAddr::new_v4(127, 0, 0, 1), 23924); assert!(tsa("localhost:23924").unwrap().contains(&a)); } + + #[test] + fn to_socket_addr_str_bad() { + assert!(tsa("1200::AB00:1234::2552:7777:1313:34300").is_err()); + } } From 8655e94abf530b3e9cb10e6acc5e39e21d3c19a3 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Thu, 5 Mar 2015 17:29:38 -0800 Subject: [PATCH 25/37] 'ignore-fast' directives do nothing --- src/test/compile-fail/privacy5.rs | 1 - src/test/run-pass/c-stack-returning-int64.rs | 1 - src/test/run-pass/foreign-fn-linkname.rs | 1 - src/test/run-pass/foreign-mod-unused-const.rs | 1 - src/test/run-pass/foreign2.rs | 1 - src/test/run-pass/issue-4735.rs | 1 - src/test/run-pass/newtype-struct-with-dtor.rs | 1 - src/test/run-pass/variadic-ffi.rs | 1 - 8 files changed, 8 deletions(-) diff --git a/src/test/compile-fail/privacy5.rs b/src/test/compile-fail/privacy5.rs index df570fd4647..a7f6a514b96 100644 --- a/src/test/compile-fail/privacy5.rs +++ b/src/test/compile-fail/privacy5.rs @@ -9,7 +9,6 @@ // except according to those terms. // aux-build:privacy-tuple-struct.rs -// ignore-fast extern crate "privacy-tuple-struct" as other; diff --git a/src/test/run-pass/c-stack-returning-int64.rs b/src/test/run-pass/c-stack-returning-int64.rs index 6246ee9c6c4..1de7520d2b1 100644 --- a/src/test/run-pass/c-stack-returning-int64.rs +++ b/src/test/run-pass/c-stack-returning-int64.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-fast doesn't like extern crate extern crate libc; diff --git a/src/test/run-pass/foreign-fn-linkname.rs b/src/test/run-pass/foreign-fn-linkname.rs index 24b711328a1..0adb3942e50 100644 --- a/src/test/run-pass/foreign-fn-linkname.rs +++ b/src/test/run-pass/foreign-fn-linkname.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-fast doesn't like extern crate extern crate libc; use std::ffi::CString; diff --git a/src/test/run-pass/foreign-mod-unused-const.rs b/src/test/run-pass/foreign-mod-unused-const.rs index e1ed0b8ea3b..03023f03233 100644 --- a/src/test/run-pass/foreign-mod-unused-const.rs +++ b/src/test/run-pass/foreign-mod-unused-const.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-fast doesn't like extern crate extern crate libc; diff --git a/src/test/run-pass/foreign2.rs b/src/test/run-pass/foreign2.rs index ce2f8955664..5ebc4effb37 100644 --- a/src/test/run-pass/foreign2.rs +++ b/src/test/run-pass/foreign2.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-fast doesn't like extern crate extern crate libc; diff --git a/src/test/run-pass/issue-4735.rs b/src/test/run-pass/issue-4735.rs index bf422bd0405..196e9748b10 100644 --- a/src/test/run-pass/issue-4735.rs +++ b/src/test/run-pass/issue-4735.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-fast doesn't like extern crate #![allow(unknown_features)] #![feature(box_syntax)] diff --git a/src/test/run-pass/newtype-struct-with-dtor.rs b/src/test/run-pass/newtype-struct-with-dtor.rs index 8631755f37f..15c4e8b0453 100644 --- a/src/test/run-pass/newtype-struct-with-dtor.rs +++ b/src/test/run-pass/newtype-struct-with-dtor.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-fast doesn't like extern crate extern crate libc; use libc::c_int; diff --git a/src/test/run-pass/variadic-ffi.rs b/src/test/run-pass/variadic-ffi.rs index 5a476ed9ee2..b3fff6977a5 100644 --- a/src/test/run-pass/variadic-ffi.rs +++ b/src/test/run-pass/variadic-ffi.rs @@ -13,7 +13,6 @@ extern crate libc; use std::ffi::{self, CString}; use libc::{c_char, c_int}; -// ignore-fast doesn't like extern crate extern { fn sprintf(s: *mut c_char, format: *const c_char, ...) -> c_int; From 1552f672d40c8765bc35136463831503473b2e91 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Thu, 5 Mar 2015 17:38:18 -0800 Subject: [PATCH 26/37] Remove run-pass/lint-cstack.rs. No longer testing anything. --- src/test/run-pass/lint-cstack.rs | 26 -------------------------- 1 file changed, 26 deletions(-) delete mode 100644 src/test/run-pass/lint-cstack.rs diff --git a/src/test/run-pass/lint-cstack.rs b/src/test/run-pass/lint-cstack.rs deleted file mode 100644 index f180ffcd4e8..00000000000 --- a/src/test/run-pass/lint-cstack.rs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2013 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. - -extern crate libc; - -extern { - fn rust_get_test_int() -> libc::intptr_t; -} - -trait A { - fn foo(&self) { - unsafe { - rust_get_test_int(); - } - } -} - -pub fn main() { -} From 96b1f0c0be849d785cb4597ea9a8d088c3a2adf4 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Thu, 5 Mar 2015 20:45:54 -0500 Subject: [PATCH 27/37] Fix reference to 'librlibc' in libcore docs Fixes #23059 --- src/libcore/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 94d37cee5b3..b1cfdbf69c3 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -35,8 +35,7 @@ //! often generated by LLVM. Additionally, this library can make explicit //! calls to these functions. Their signatures are the same as found in C. //! These functions are often provided by the system libc, but can also be -//! provided by `librlibc` which is distributed with the standard rust -//! distribution. +//! provided by the [rlibc crate](https://crates.io/crates/rlibc). //! //! * `rust_begin_unwind` - This function takes three arguments, a //! `fmt::Arguments`, a `&str`, and a `usize`. These three arguments dictate From ccd83daa418310f2a48af29b1e6545577e579e65 Mon Sep 17 00:00:00 2001 From: Lai Jiangshan Date: Fri, 6 Mar 2015 10:03:00 +0800 Subject: [PATCH 28/37] file permission: remove executable bit from *.rs Signed-off-by: Lai Jiangshan --- src/libstd/path.rs | 0 src/test/auxiliary/lint_output_format.rs | 0 src/test/compile-fail/send-is-not-static-ensures-scoping.rs | 0 src/test/run-make/mismatching-target-triples/bar.rs | 0 src/test/run-make/mismatching-target-triples/foo.rs | 0 src/test/run-make/pretty-expanded-hygiene/input.pp.rs | 0 src/test/run-make/pretty-expanded-hygiene/input.rs | 0 src/test/run-make/simd-ffi/simd.rs | 0 src/test/run-pass/send-is-not-static-par-for.rs | 0 9 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 src/libstd/path.rs mode change 100755 => 100644 src/test/auxiliary/lint_output_format.rs mode change 100755 => 100644 src/test/compile-fail/send-is-not-static-ensures-scoping.rs mode change 100755 => 100644 src/test/run-make/mismatching-target-triples/bar.rs mode change 100755 => 100644 src/test/run-make/mismatching-target-triples/foo.rs mode change 100755 => 100644 src/test/run-make/pretty-expanded-hygiene/input.pp.rs mode change 100755 => 100644 src/test/run-make/pretty-expanded-hygiene/input.rs mode change 100755 => 100644 src/test/run-make/simd-ffi/simd.rs mode change 100755 => 100644 src/test/run-pass/send-is-not-static-par-for.rs diff --git a/src/libstd/path.rs b/src/libstd/path.rs old mode 100755 new mode 100644 diff --git a/src/test/auxiliary/lint_output_format.rs b/src/test/auxiliary/lint_output_format.rs old mode 100755 new mode 100644 diff --git a/src/test/compile-fail/send-is-not-static-ensures-scoping.rs b/src/test/compile-fail/send-is-not-static-ensures-scoping.rs old mode 100755 new mode 100644 diff --git a/src/test/run-make/mismatching-target-triples/bar.rs b/src/test/run-make/mismatching-target-triples/bar.rs old mode 100755 new mode 100644 diff --git a/src/test/run-make/mismatching-target-triples/foo.rs b/src/test/run-make/mismatching-target-triples/foo.rs old mode 100755 new mode 100644 diff --git a/src/test/run-make/pretty-expanded-hygiene/input.pp.rs b/src/test/run-make/pretty-expanded-hygiene/input.pp.rs old mode 100755 new mode 100644 diff --git a/src/test/run-make/pretty-expanded-hygiene/input.rs b/src/test/run-make/pretty-expanded-hygiene/input.rs old mode 100755 new mode 100644 diff --git a/src/test/run-make/simd-ffi/simd.rs b/src/test/run-make/simd-ffi/simd.rs old mode 100755 new mode 100644 diff --git a/src/test/run-pass/send-is-not-static-par-for.rs b/src/test/run-pass/send-is-not-static-par-for.rs old mode 100755 new mode 100644 From 3f94260b0fb2639ba81a5458ec54329e4b860afd Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Thu, 5 Mar 2015 23:03:30 +0200 Subject: [PATCH 29/37] Fix an easy to trigger deadlock in std::io::stdio Being a person who somehow has taken a liking to premature optimisation, my knee-jerk reaction to locking in std handles was preamble resembling following snippet: let stdout = stdout(); let lstdout = stdout.lock(); let stdin = stdin(); let lstdin = stdin.lock(); and then reading from the locked handle like this: let mut letter = [0; 1]; lstdin.read(&mut letter).unwrap(); As it is now this code will deadlock because the `read` method attempts to lock stdout as well! --- src/libstd/io/stdio.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index 61ad9905771..4027f741654 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -157,9 +157,6 @@ impl Read for Stdin { impl<'a> Read for StdinLock<'a> { fn read(&mut self, buf: &mut [u8]) -> io::Result { - // Flush stdout so that weird issues like a print!'d prompt not being - // shown until after the user hits enter. - drop(stdout().flush()); self.inner.read(buf) } } From 707f7a1617013f7684fe81a1bba2dd77acbaaa73 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 6 Mar 2015 08:07:50 -0500 Subject: [PATCH 30/37] Check that traits with default impls have no methods fixes #23080 --- src/librustc_typeck/check/mod.rs | 28 +++++++++++++++++++++++++++ src/test/compile-fail/issue-23080.rs | 29 ++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 src/test/compile-fail/issue-23080.rs diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 595a2295674..57469d94ce8 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -465,6 +465,29 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> { } } +// Check that trait with default impls (`impl Trait for ..`) contain no methods +struct DefaultedTraitVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> } + +impl<'a, 'tcx> Visitor<'tcx> for DefaultedTraitVisitor<'a, 'tcx> { + fn visit_item(&mut self, item: &ast::Item) { + let tcx = self.ccx.tcx; + + match item.node { + ast::ItemTrait(_, _, _, ref trait_methods) => { + if ty::trait_has_default_impl(tcx, local_def(item.id)) && + !trait_methods.is_empty() + { + tcx.sess.span_err( + item.span, + "traits with default impls (`e.g. impl Trait for ..`) must have no \ + methods") + } + }, + _ => {}, + } + } +} + pub fn check_item_types(ccx: &CrateCtxt) { let krate = ccx.tcx.map.krate(); let mut visit = wf::CheckTypeWellFormedVisitor::new(ccx); @@ -478,6 +501,11 @@ pub fn check_item_types(ccx: &CrateCtxt) { visit::walk_crate(&mut visit, krate); ccx.tcx.sess.abort_if_errors(); + + let mut visit = DefaultedTraitVisitor { ccx: ccx }; + visit::walk_crate(&mut visit, krate); + + ccx.tcx.sess.abort_if_errors(); } fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, diff --git a/src/test/compile-fail/issue-23080.rs b/src/test/compile-fail/issue-23080.rs new file mode 100644 index 00000000000..61b9a1a14e0 --- /dev/null +++ b/src/test/compile-fail/issue-23080.rs @@ -0,0 +1,29 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(optin_builtin_traits)] + +unsafe trait Trait { +//~^ error: traits with default impls (`e.g. impl Trait for ..`) must have no methods + fn method(&self) { + println!("Hello"); + } +} + +unsafe impl Trait for .. {} + +fn call_method(x: T) { + x.method(); +} + +fn main() { + // ICE + call_method(()); +} From 61c6b199bcc23fe931f3fda2f968442256e07dab Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Fri, 6 Mar 2015 11:03:51 +0530 Subject: [PATCH 31/37] BufferedWriter -> BufWriter (fixup #23060) --- src/librustdoc/html/render.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 4af6a6d229f..2578912127e 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1228,7 +1228,7 @@ impl Context { { let items = this.build_sidebar_items(&m); let js_dst = this.dst.join("sidebar-items.js"); - let mut js_out = BufferedWriter::new(try!(File::create(&js_dst))); + let mut js_out = BufWriter::new(try!(File::create(&js_dst))); try!(write!(&mut js_out, "initSidebarItems({});", json::as_json(&items))); } From 8a391dd8cf2ff938a392cbd177dc0a21d644d627 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 6 Mar 2015 12:14:38 -0500 Subject: [PATCH 32/37] move check into wf pass, add a test for assoc types --- src/librustc_typeck/check/mod.rs | 28 ------------------------- src/librustc_typeck/check/wf.rs | 10 ++++++++- src/test/compile-fail/issue-23080-2.rs | 29 ++++++++++++++++++++++++++ src/test/compile-fail/issue-23080.rs | 4 +++- 4 files changed, 41 insertions(+), 30 deletions(-) create mode 100644 src/test/compile-fail/issue-23080-2.rs diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 57469d94ce8..595a2295674 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -465,29 +465,6 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> { } } -// Check that trait with default impls (`impl Trait for ..`) contain no methods -struct DefaultedTraitVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> } - -impl<'a, 'tcx> Visitor<'tcx> for DefaultedTraitVisitor<'a, 'tcx> { - fn visit_item(&mut self, item: &ast::Item) { - let tcx = self.ccx.tcx; - - match item.node { - ast::ItemTrait(_, _, _, ref trait_methods) => { - if ty::trait_has_default_impl(tcx, local_def(item.id)) && - !trait_methods.is_empty() - { - tcx.sess.span_err( - item.span, - "traits with default impls (`e.g. impl Trait for ..`) must have no \ - methods") - } - }, - _ => {}, - } - } -} - pub fn check_item_types(ccx: &CrateCtxt) { let krate = ccx.tcx.map.krate(); let mut visit = wf::CheckTypeWellFormedVisitor::new(ccx); @@ -501,11 +478,6 @@ pub fn check_item_types(ccx: &CrateCtxt) { visit::walk_crate(&mut visit, krate); ccx.tcx.sess.abort_if_errors(); - - let mut visit = DefaultedTraitVisitor { ccx: ccx }; - visit::walk_crate(&mut visit, krate); - - ccx.tcx.sess.abort_if_errors(); } fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs index aa7e2b6dcce..8185f48cb8c 100644 --- a/src/librustc_typeck/check/wf.rs +++ b/src/librustc_typeck/check/wf.rs @@ -118,7 +118,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { self.check_variances_for_type_defn(item, ast_generics); } - ast::ItemTrait(_, ref ast_generics, _, _) => { + ast::ItemTrait(_, ref ast_generics, _, ref items) => { let trait_predicates = ty::lookup_predicates(ccx.tcx, local_def(item.id)); reject_non_type_param_bounds( @@ -127,6 +127,14 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { &trait_predicates); self.check_variances(item, ast_generics, &trait_predicates, self.tcx().lang_items.phantom_fn()); + if ty::trait_has_default_impl(ccx.tcx, local_def(item.id)) { + if !items.is_empty() { + ccx.tcx.sess.span_err( + item.span, + "traits with default impls (`e.g. unsafe impl Trait for ..`) must \ + have no methods or associated items") + } + } } _ => {} } diff --git a/src/test/compile-fail/issue-23080-2.rs b/src/test/compile-fail/issue-23080-2.rs new file mode 100644 index 00000000000..ff5ac9de8d9 --- /dev/null +++ b/src/test/compile-fail/issue-23080-2.rs @@ -0,0 +1,29 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// ignore-tidy-linelength + +#![feature(optin_builtin_traits)] + +use std::marker::MarkerTrait; + +unsafe trait Trait: MarkerTrait { +//~^ error: traits with default impls (`e.g. unsafe impl Trait for ..`) must have no methods or associated items + type Output; +} + +unsafe impl Trait for .. {} + +fn call_method(x: T) {} + +fn main() { + // ICE + call_method(()); +} diff --git a/src/test/compile-fail/issue-23080.rs b/src/test/compile-fail/issue-23080.rs index 61b9a1a14e0..99373a69697 100644 --- a/src/test/compile-fail/issue-23080.rs +++ b/src/test/compile-fail/issue-23080.rs @@ -8,10 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// ignore-tidy-linelength + #![feature(optin_builtin_traits)] unsafe trait Trait { -//~^ error: traits with default impls (`e.g. impl Trait for ..`) must have no methods +//~^ error: traits with default impls (`e.g. unsafe impl Trait for ..`) must have no methods or associated items fn method(&self) { println!("Hello"); } From f7594e14b8bf291c7312332947f17f4411a02b3a Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Fri, 6 Mar 2015 10:10:47 -0800 Subject: [PATCH 33/37] Remove two green threading tests --- src/test/run-pass/extern-stress.rs | 49 ------------------------------ src/test/run-pass/extern-yield.rs | 48 ----------------------------- 2 files changed, 97 deletions(-) delete mode 100644 src/test/run-pass/extern-stress.rs delete mode 100644 src/test/run-pass/extern-yield.rs diff --git a/src/test/run-pass/extern-stress.rs b/src/test/run-pass/extern-stress.rs deleted file mode 100644 index b9e08e47b37..00000000000 --- a/src/test/run-pass/extern-stress.rs +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// This creates a bunch of descheduling tasks that run concurrently -// while holding onto C stacks - -extern crate libc; -use std::thread::Thread; - -mod rustrt { - extern crate libc; - - #[link(name = "rust_test_helpers")] - extern { - pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t, - data: libc::uintptr_t) - -> libc::uintptr_t; - } -} - -extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t { - if data == 1 { - data - } else { - Thread::yield_now(); - count(data - 1) + count(data - 1) - } -} - -fn count(n: libc::uintptr_t) -> libc::uintptr_t { - unsafe { - rustrt::rust_dbg_call(cb, n) - } -} - -pub fn main() { - (0_usize..100).map(|_| { - Thread::scoped(move|| { - assert_eq!(count(5), 16); - }) - }).collect::>(); -} diff --git a/src/test/run-pass/extern-yield.rs b/src/test/run-pass/extern-yield.rs deleted file mode 100644 index 80428d787f2..00000000000 --- a/src/test/run-pass/extern-yield.rs +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -extern crate libc; -use std::thread::Thread; - -mod rustrt { - extern crate libc; - - #[link(name = "rust_test_helpers")] - extern { - pub fn rust_dbg_call(cb: extern "C" fn (libc::uintptr_t) -> libc::uintptr_t, - data: libc::uintptr_t) - -> libc::uintptr_t; - } -} - -extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t { - if data == 1 { - data - } else { - count(data - 1) + count(data - 1) - } -} - -fn count(n: libc::uintptr_t) -> libc::uintptr_t { - unsafe { - Thread::yield_now(); - rustrt::rust_dbg_call(cb, n) - } -} - -pub fn main() { - (0..10_usize).map(|i| { - Thread::scoped(move|| { - let result = count(5); - println!("result = {}", result); - assert_eq!(result, 16); - }) - }).collect::>(); -} From 9aea749b835a6fdcad6f2840a00adac996cc0339 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 25 Feb 2015 13:08:51 -0800 Subject: [PATCH 34/37] std: Deprecate the std::old_io::net primitives The `std::net` primitives should be ready for use now and as a result the old ones are now deprecated and slated for removal. Most TCP/UDP functionality is now available through `std::net` but the `std::old_io::net::pipe` module is removed entirely from the standard library. Unix socket funtionality can be found in sfackler's [`unix_socket`][unix] crate and there is currently no replacement for named pipes on Windows. [unix]: https://crates.io/crates/unix_socket [breaking-change] --- src/libstd/old_io/net/mod.rs | 4 ++++ src/libstd/old_io/net/pipe.rs | 6 ++++++ src/libstd/sys/common/net.rs | 2 ++ src/libstd/sys/unix/ext.rs | 7 +++++++ src/libstd/sys/unix/tcp.rs | 2 ++ src/libstd/sys/windows/ext.rs | 7 +++++++ src/libstd/sys/windows/tcp.rs | 2 ++ 7 files changed, 30 insertions(+) diff --git a/src/libstd/old_io/net/mod.rs b/src/libstd/old_io/net/mod.rs index bbe3a71dcc0..a3567290b0e 100644 --- a/src/libstd/old_io/net/mod.rs +++ b/src/libstd/old_io/net/mod.rs @@ -10,6 +10,10 @@ //! Networking I/O +#![deprecated(since = "1.0.0", + reason = "replaced with new I/O primitives in `std::net`")] +#![unstable(feature = "old_io")] + use old_io::{IoError, IoResult, InvalidInput}; use ops::FnMut; use option::Option::None; diff --git a/src/libstd/old_io/net/pipe.rs b/src/libstd/old_io/net/pipe.rs index d05669d32b8..2ecaf515f08 100644 --- a/src/libstd/old_io/net/pipe.rs +++ b/src/libstd/old_io/net/pipe.rs @@ -19,6 +19,12 @@ //! instances as clients. #![allow(missing_docs)] +#![deprecated(since = "1.0.0", + reason = "will be removed to be reintroduced at a later date; \ + in the meantime consider using the `unix_socket` crate \ + for unix sockets; there is currently no replacement \ + for named pipes")] +#![unstable(feature = "old_io")] use prelude::v1::*; diff --git a/src/libstd/sys/common/net.rs b/src/libstd/sys/common/net.rs index 228362e3d62..344645dfc1a 100644 --- a/src/libstd/sys/common/net.rs +++ b/src/libstd/sys/common/net.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![allow(deprecated)] + use prelude::v1::*; use self::SocketStatus::*; use self::InAddr::*; diff --git a/src/libstd/sys/unix/ext.rs b/src/libstd/sys/unix/ext.rs index 45042d6f032..ca7f7c4c0ca 100644 --- a/src/libstd/sys/unix/ext.rs +++ b/src/libstd/sys/unix/ext.rs @@ -73,42 +73,49 @@ impl AsRawFd for old_io::pipe::PipeStream { } } +#[allow(deprecated)] impl AsRawFd for old_io::net::pipe::UnixStream { fn as_raw_fd(&self) -> Fd { self.as_inner().fd() } } +#[allow(deprecated)] impl AsRawFd for old_io::net::pipe::UnixListener { fn as_raw_fd(&self) -> Fd { self.as_inner().fd() } } +#[allow(deprecated)] impl AsRawFd for old_io::net::pipe::UnixAcceptor { fn as_raw_fd(&self) -> Fd { self.as_inner().fd() } } +#[allow(deprecated)] impl AsRawFd for old_io::net::tcp::TcpStream { fn as_raw_fd(&self) -> Fd { self.as_inner().fd() } } +#[allow(deprecated)] impl AsRawFd for old_io::net::tcp::TcpListener { fn as_raw_fd(&self) -> Fd { self.as_inner().fd() } } +#[allow(deprecated)] impl AsRawFd for old_io::net::tcp::TcpAcceptor { fn as_raw_fd(&self) -> Fd { self.as_inner().fd() } } +#[allow(deprecated)] impl AsRawFd for old_io::net::udp::UdpSocket { fn as_raw_fd(&self) -> Fd { self.as_inner().fd() diff --git a/src/libstd/sys/unix/tcp.rs b/src/libstd/sys/unix/tcp.rs index b08f6ef9b90..4fcaf504c3d 100644 --- a/src/libstd/sys/unix/tcp.rs +++ b/src/libstd/sys/unix/tcp.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![allow(deprecated)] + use prelude::v1::*; use old_io::net::ip; diff --git a/src/libstd/sys/windows/ext.rs b/src/libstd/sys/windows/ext.rs index df18b404f5f..b30aec08439 100644 --- a/src/libstd/sys/windows/ext.rs +++ b/src/libstd/sys/windows/ext.rs @@ -58,18 +58,21 @@ impl AsRawHandle for old_io::pipe::PipeStream { } } +#[allow(deprecated)] impl AsRawHandle for old_io::net::pipe::UnixStream { fn as_raw_handle(&self) -> Handle { self.as_inner().handle() } } +#[allow(deprecated)] impl AsRawHandle for old_io::net::pipe::UnixListener { fn as_raw_handle(&self) -> Handle { self.as_inner().handle() } } +#[allow(deprecated)] impl AsRawHandle for old_io::net::pipe::UnixAcceptor { fn as_raw_handle(&self) -> Handle { self.as_inner().handle() @@ -81,24 +84,28 @@ pub trait AsRawSocket { fn as_raw_socket(&self) -> Socket; } +#[allow(deprecated)] impl AsRawSocket for old_io::net::tcp::TcpStream { fn as_raw_socket(&self) -> Socket { self.as_inner().fd() } } +#[allow(deprecated)] impl AsRawSocket for old_io::net::tcp::TcpListener { fn as_raw_socket(&self) -> Socket { self.as_inner().socket() } } +#[allow(deprecated)] impl AsRawSocket for old_io::net::tcp::TcpAcceptor { fn as_raw_socket(&self) -> Socket { self.as_inner().socket() } } +#[allow(deprecated)] impl AsRawSocket for old_io::net::udp::UdpSocket { fn as_raw_socket(&self) -> Socket { self.as_inner().fd() diff --git a/src/libstd/sys/windows/tcp.rs b/src/libstd/sys/windows/tcp.rs index 25b70918591..8547de145f8 100644 --- a/src/libstd/sys/windows/tcp.rs +++ b/src/libstd/sys/windows/tcp.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![allow(deprecated)] + use old_io::net::ip; use old_io::IoResult; use libc; From 16ff1401d8fb11b9c0f5fab8052b2a993ff93916 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 6 Mar 2015 13:54:42 -0800 Subject: [PATCH 35/37] std: Ignore a test on windows This test is known to fail on windows. --- src/libstd/fs/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libstd/fs/mod.rs b/src/libstd/fs/mod.rs index ef2dd65a816..42bc636d4bd 100644 --- a/src/libstd/fs/mod.rs +++ b/src/libstd/fs/mod.rs @@ -1552,6 +1552,7 @@ mod tests { } #[test] + #[cfg(not(windows))] fn unlink_readonly() { let tmpdir = tmpdir(); let path = tmpdir.join("file"); From 1a30412ebf4363acf92f1edafa2c007617c94d02 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 6 Mar 2015 15:11:59 -0800 Subject: [PATCH 36/37] Suppress some warnings about features --- src/librustc/lib.rs | 2 ++ src/librustc_trans/lib.rs | 1 + src/librustdoc/lib.rs | 1 + 3 files changed, 4 insertions(+) diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index be625affc2e..d39b14e6fee 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -44,7 +44,9 @@ #![feature(path)] #![feature(io)] #![feature(path_ext)] +#![feature(str_words)] #![cfg_attr(test, feature(test))] + extern crate arena; extern crate flate; extern crate fmt_macros; diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 5f97709dd33..01076a4afa2 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -44,6 +44,7 @@ #![feature(os)] #![feature(path_ext)] #![feature(fs)] +#![feature(hash)] extern crate arena; extern crate flate; diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 80584da265c..c203dc0e719 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -38,6 +38,7 @@ #![feature(str_words)] #![feature(io)] #![feature(path)] +#![feature(file_path)] #![feature(path_ext)] extern crate arena; From aed31ee08e9adff815e8a5df2499f2e4c6e7916b Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 6 Mar 2015 15:53:32 -0800 Subject: [PATCH 37/37] Test fixes and rebase conflicts --- src/librustc_llvm/lib.rs | 2 +- src/librustc_trans/lib.rs | 2 -- src/libstd/fs/mod.rs | 9 +++++++-- src/libstd/net/addr.rs | 1 + 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index 5bf872b3a1d..0ff96784e58 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -31,8 +31,8 @@ #![feature(libc)] #![feature(link_args)] #![feature(staged_api)] -#![feature(std_misc)] #![feature(path)] +#![cfg_attr(unix, feature(std_misc))] extern crate libc; #[macro_use] #[no_link] extern crate rustc_bitflags; diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 08e31a6b339..b74f85aa866 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -40,11 +40,9 @@ #![feature(unicode)] #![feature(io)] #![feature(path)] -#![feature(os)] #![feature(path_ext)] #![feature(fs)] #![feature(hash)] -#![feature(tempdir)] extern crate arena; extern crate flate; diff --git a/src/libstd/fs/mod.rs b/src/libstd/fs/mod.rs index 42bc636d4bd..80ec9909824 100644 --- a/src/libstd/fs/mod.rs +++ b/src/libstd/fs/mod.rs @@ -1313,6 +1313,8 @@ mod tests { check!(fs::set_permissions(&input, p)); check!(fs::copy(&input, &out)); assert!(check!(out.metadata()).permissions().readonly()); + check!(fs::set_permissions(&input, attr.permissions())); + check!(fs::set_permissions(&out, attr.permissions())); } #[cfg(not(windows))] // FIXME(#10264) operation not permitted? @@ -1396,10 +1398,13 @@ mod tests { let attr = check!(fs::metadata(&file)); assert!(attr.permissions().readonly()); - match fs::set_permissions(&tmpdir.join("foo"), p) { - Ok(..) => panic!("wanted a panic"), + match fs::set_permissions(&tmpdir.join("foo"), p.clone()) { + Ok(..) => panic!("wanted an error"), Err(..) => {} } + + p.set_readonly(false); + check!(fs::set_permissions(&file, p)); } #[test] diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs index d975369af49..101aae3eb24 100644 --- a/src/libstd/net/addr.rs +++ b/src/libstd/net/addr.rs @@ -592,6 +592,7 @@ mod tests { } #[test] + #[cfg(not(windows))] fn to_socket_addr_str_bad() { assert!(tsa("1200::AB00:1234::2552:7777:1313:34300").is_err()); }

")); for (i, name) in cx.current.iter().take(parentlen).enumerate() { if i > 0 { From 215d287982b0ea678312892fb2f8db58acebd3b8 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 5 Mar 2015 15:03:14 +0100 Subject: [PATCH 12/37] debuginfo: Add test case for `extern "C"` functions. --- src/test/debuginfo/extern-c-fn.rs | 68 +++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 src/test/debuginfo/extern-c-fn.rs diff --git a/src/test/debuginfo/extern-c-fn.rs b/src/test/debuginfo/extern-c-fn.rs new file mode 100644 index 00000000000..9e73417e7de --- /dev/null +++ b/src/test/debuginfo/extern-c-fn.rs @@ -0,0 +1,68 @@ +// Copyright 2013-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. + +// min-lldb-version: 310 + +// compile-flags:-g + +// === GDB TESTS =================================================================================== +// gdb-command:run + +// gdb-command:print s +// gdb-check:$1 = [...]"abcd" +// gdb-command:print len +// gdb-check:$2 = 20 +// gdb-command:print local0 +// gdb-check:$3 = 19 +// gdb-command:print local1 +// gdb-check:$4 = true +// gdb-command:print local2 +// gdb-check:$5 = 20.5 + +// gdb-command:continue + +// === LLDB TESTS ================================================================================== +// lldb-command:run + +// lldb-command:print len +// lldb-check:[...]$0 = 20 +// lldb-command:print local0 +// lldb-check:[...]$1 = 19 +// lldb-command:print local1 +// lldb-check:[...]$2 = true +// lldb-command:print local2 +// lldb-check:[...]$3 = 20.5 + +// lldb-command:continue + +#![allow(unused_variables)] +#![allow(dead_code)] +#![omit_gdb_pretty_printer_section] + + +#[no_mangle] +pub unsafe extern "C" fn fn_with_c_abi(s: *const u8, len: i32) -> i32 { + let local0 = len - 1; + let local1 = len > 2; + let local2 = (len as f64) + 0.5; + + zzz(); // #break + + return 0; +} + +fn main() { + unsafe { + fn_with_c_abi(b"abcd\0".as_ptr(), 20); + } +} + +#[inline(never)] +fn zzz() {()} From 951ef9d1f105984383b9795c56f7ab8fdd681b63 Mon Sep 17 00:00:00 2001 From: awlnx Date: Thu, 5 Mar 2015 11:53:51 -0500 Subject: [PATCH 13/37] fix for new attributes failing. issue #22964 --- src/liballoc/lib.rs | 2 ++ src/libarena/lib.rs | 2 ++ src/libcollections/lib.rs | 3 ++- src/libcore/lib.rs | 2 ++ src/libcoretest/lib.rs | 2 ++ src/libflate/lib.rs | 2 ++ src/libfmt_macros/lib.rs | 2 ++ src/libgetopts/lib.rs | 3 +++ src/libgraphviz/lib.rs | 2 ++ src/liblibc/lib.rs | 2 ++ src/liblog/lib.rs | 2 ++ src/librand/lib.rs | 2 ++ src/librbml/lib.rs | 2 ++ src/librustc/lib.rs | 3 ++- src/librustc_back/lib.rs | 2 ++ src/librustc_bitflags/lib.rs | 3 +++ src/librustc_borrowck/lib.rs | 2 ++ src/librustc_driver/lib.rs | 2 ++ src/librustc_lint/lib.rs | 2 ++ src/librustc_llvm/lib.rs | 2 ++ src/librustc_privacy/lib.rs | 2 ++ src/librustc_resolve/lib.rs | 2 ++ src/librustc_trans/lib.rs | 2 ++ src/librustc_typeck/lib.rs | 3 ++- src/librustdoc/lib.rs | 2 ++ src/libserialize/lib.rs | 2 ++ src/libstd/lib.rs | 3 ++- src/libsyntax/lib.rs | 2 ++ src/libterm/lib.rs | 2 ++ src/libtest/lib.rs | 2 ++ src/libunicode/lib.rs | 2 ++ 31 files changed, 64 insertions(+), 4 deletions(-) diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 82bd13475c7..828e6b8dd76 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -56,6 +56,8 @@ //! The [`heap`](heap/index.html) module defines the low-level interface to the //! default global allocator. It is not compatible with the libc allocator API. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "alloc"] #![unstable(feature = "alloc")] #![feature(staged_api)] diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index b43f9adfb26..b2ac9a34b02 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -19,6 +19,8 @@ //! arena but can only hold objects of a single type, and `Arena`, which is a //! more complex, slower arena which can hold objects of any type. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "arena"] #![unstable(feature = "rustc_private")] #![staged_api] diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index 7b66bfee34f..9c1c2cc5906 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -12,7 +12,8 @@ //! //! See [std::collections](../std/collections) for a detailed discussion of collections in Rust. - +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "collections"] #![unstable(feature = "collections")] #![staged_api] diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 7cc963bed35..ea39ab3da5e 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -47,6 +47,8 @@ // Since libcore defines many fundamental lang items, all tests live in a // separate crate, libcoretest, to avoid bizarre issues. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "core"] #![unstable(feature = "core")] #![staged_api] diff --git a/src/libcoretest/lib.rs b/src/libcoretest/lib.rs index 03924910e04..1dbbb845d46 100644 --- a/src/libcoretest/lib.rs +++ b/src/libcoretest/lib.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![feature(box_syntax)] #![feature(int_uint)] #![feature(unboxed_closures)] diff --git a/src/libflate/lib.rs b/src/libflate/lib.rs index 2ce52cdec25..ec75c102224 100644 --- a/src/libflate/lib.rs +++ b/src/libflate/lib.rs @@ -14,6 +14,8 @@ //! [def]: https://en.wikipedia.org/wiki/DEFLATE //! [mz]: https://code.google.com/p/miniz/ +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "flate"] #![unstable(feature = "rustc_private")] #![staged_api] diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs index 4e25e51e9a4..9b220409ef5 100644 --- a/src/libfmt_macros/lib.rs +++ b/src/libfmt_macros/lib.rs @@ -14,6 +14,8 @@ //! Parsing does not happen at runtime: structures of `std::fmt::rt` are //! generated instead. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "fmt_macros"] #![unstable(feature = "rustc_private")] #![staged_api] diff --git a/src/libgetopts/lib.rs b/src/libgetopts/lib.rs index 6240b0e6afd..c33c48476d5 100644 --- a/src/libgetopts/lib.rs +++ b/src/libgetopts/lib.rs @@ -77,6 +77,9 @@ //! } //! ``` + +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "getopts"] #![unstable(feature = "rustc_private", reason = "use the crates.io `getopts` library instead")] diff --git a/src/libgraphviz/lib.rs b/src/libgraphviz/lib.rs index 09fbf4935e4..751cbe688d1 100644 --- a/src/libgraphviz/lib.rs +++ b/src/libgraphviz/lib.rs @@ -264,6 +264,8 @@ //! //! * [DOT language](http://www.graphviz.org/doc/info/lang.html) +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "graphviz"] #![unstable(feature = "rustc_private")] #![feature(staged_api)] diff --git a/src/liblibc/lib.rs b/src/liblibc/lib.rs index 42143b06ca0..4051ae9d33a 100644 --- a/src/liblibc/lib.rs +++ b/src/liblibc/lib.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "libc"] #![crate_type = "rlib"] #![cfg_attr(not(feature = "cargo-build"), diff --git a/src/liblog/lib.rs b/src/liblog/lib.rs index d0105bb6577..3b6e1d04691 100644 --- a/src/liblog/lib.rs +++ b/src/liblog/lib.rs @@ -155,6 +155,8 @@ //! they're turned off (just a load and an integer comparison). This also means that //! if logging is disabled, none of the components of the log will be executed. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "log"] #![unstable(feature = "rustc_private", reason = "use the crates.io `log` library instead")] diff --git a/src/librand/lib.rs b/src/librand/lib.rs index 583c658dfe0..7acd6cda044 100644 --- a/src/librand/lib.rs +++ b/src/librand/lib.rs @@ -16,6 +16,8 @@ //! is not recommended to use this library directly, but rather the official //! interface through `std::rand`. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "rand"] #![crate_type = "rlib"] #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk.png", diff --git a/src/librbml/lib.rs b/src/librbml/lib.rs index 05cd24de736..c247e3a3dec 100644 --- a/src/librbml/lib.rs +++ b/src/librbml/lib.rs @@ -15,6 +15,8 @@ //! It is loosely based on the Extensible Binary Markup Language (ebml): //! http://www.matroska.org/technical/specs/rfc/index.html +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "rbml"] #![unstable(feature = "rustc_private")] #![staged_api] diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index aa51320ee7f..53f44c0eb1b 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -14,6 +14,8 @@ //! //! This API is completely unstable and subject to change. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "rustc"] #![unstable(feature = "rustc_private")] #![staged_api] @@ -40,7 +42,6 @@ #![feature(std_misc)] #![feature(os)] #![cfg_attr(test, feature(test))] - extern crate arena; extern crate flate; extern crate fmt_macros; diff --git a/src/librustc_back/lib.rs b/src/librustc_back/lib.rs index 9005c666afb..f5fab17006c 100644 --- a/src/librustc_back/lib.rs +++ b/src/librustc_back/lib.rs @@ -21,6 +21,8 @@ //! one that doesn't; the one that doesn't might get decent parallel //! build speedups. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "rustc_back"] #![unstable(feature = "rustc_private")] #![staged_api] diff --git a/src/librustc_bitflags/lib.rs b/src/librustc_bitflags/lib.rs index 370a5d48dec..5115e9a4a20 100644 --- a/src/librustc_bitflags/lib.rs +++ b/src/librustc_bitflags/lib.rs @@ -8,6 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. + +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "rustc_bitflags"] #![feature(staged_api)] #![staged_api] diff --git a/src/librustc_borrowck/lib.rs b/src/librustc_borrowck/lib.rs index b7cfda28092..e09457970e1 100644 --- a/src/librustc_borrowck/lib.rs +++ b/src/librustc_borrowck/lib.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "rustc_borrowck"] #![unstable(feature = "rustc_private")] #![staged_api] diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index d08fb2b313e..3292b2e026b 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -14,6 +14,8 @@ //! //! This API is completely unstable and subject to change. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "rustc_driver"] #![unstable(feature = "rustc_private")] #![staged_api] diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 9eef0f1cf8b..9781e9944f6 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -19,6 +19,8 @@ //! //! This API is completely unstable and subject to change. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "rustc_lint"] #![unstable(feature = "rustc_private")] #![staged_api] diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index 09a187befb2..8f6ad343317 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![allow(non_upper_case_globals)] #![allow(non_camel_case_types)] #![allow(non_snake_case)] diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 46729988bb6..859e4ab2858 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "rustc_privacy"] #![unstable(feature = "rustc_private")] #![staged_api] diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 78ce9abe07d..7724f4253b7 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "rustc_resolve"] #![unstable(feature = "rustc_private")] #![staged_api] diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 71317d5875b..5ccd7f61e01 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -14,6 +14,8 @@ //! //! This API is completely unstable and subject to change. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "rustc_trans"] #![unstable(feature = "rustc_private")] #![staged_api] diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 78dd66c8e7d..bbc64a54013 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -62,7 +62,8 @@ independently: This API is completely unstable and subject to change. */ - +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "rustc_typeck"] #![unstable(feature = "rustc_private")] #![staged_api] diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index e58239a82c6..cbf7adcbe9a 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "rustdoc"] #![unstable(feature = "rustdoc")] #![staged_api] diff --git a/src/libserialize/lib.rs b/src/libserialize/lib.rs index d476fd72abc..8d58ba99e13 100644 --- a/src/libserialize/lib.rs +++ b/src/libserialize/lib.rs @@ -14,6 +14,8 @@ Core encoding and decoding interfaces. */ +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "serialize"] #![unstable(feature = "rustc_private", reason = "deprecated in favor of rustc-serialize on crates.io")] diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 7957bc35b76..73848a51c1e 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -94,7 +94,8 @@ //! to all code by default. [`macros`](macros/index.html) contains //! all the standard macros, such as `assert!`, `panic!`, `println!`, //! and `format!`, also available to all Rust code. - +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "std"] #![stable(feature = "rust1", since = "1.0.0")] #![staged_api] diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 7acbd10ef03..091f3be631e 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -14,6 +14,8 @@ //! //! This API is completely unstable and subject to change. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "syntax"] #![unstable(feature = "rustc_private")] #![staged_api] diff --git a/src/libterm/lib.rs b/src/libterm/lib.rs index 756d67b5db1..ed42c16f19a 100644 --- a/src/libterm/lib.rs +++ b/src/libterm/lib.rs @@ -38,6 +38,8 @@ //! [win]: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682010%28v=vs.85%29.aspx //! [ti]: https://en.wikipedia.org/wiki/Terminfo +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "term"] #![unstable(feature = "rustc_private", reason = "use the crates.io `term` library instead")] diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index a144904903e..538c96cd63c 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -23,6 +23,8 @@ // running tests while providing a base that other test frameworks may // build off of. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "test"] #![unstable(feature = "test")] #![staged_api] diff --git a/src/libunicode/lib.rs b/src/libunicode/lib.rs index 791886be1ce..2095b6921c8 100644 --- a/src/libunicode/lib.rs +++ b/src/libunicode/lib.rs @@ -20,6 +20,8 @@ //! provide for basic string-related manipulations. This crate does not //! (yet) aim to provide a full set of Unicode tables. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "unicode"] #![unstable(feature = "unicode")] #![feature(staged_api)] From 7ed418c3b4ede0364bf419b2c12b27f89b706dcf Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 5 Mar 2015 10:41:42 -0800 Subject: [PATCH 14/37] std: Deprecate the old_io::process module This module is now superseded by the `std::process` module. This module still has some room to expand to get quite back up to parity with the `old_io` version, and there is a [tracking issue][issue] for feature requests as well as known room for expansion. [issue]: https://github.com/rust-lang/rfcs/issues/941 [breaking-change] --- src/librustc_back/target/apple_ios_base.rs | 16 ++++++++-------- src/libstd/old_io/process.rs | 3 +++ src/libstd/sys/unix/process.rs | 2 ++ src/libstd/sys/windows/process.rs | 2 ++ 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/librustc_back/target/apple_ios_base.rs b/src/librustc_back/target/apple_ios_base.rs index 904b337c03f..2fbbe7d1f7c 100644 --- a/src/librustc_back/target/apple_ios_base.rs +++ b/src/librustc_back/target/apple_ios_base.rs @@ -8,7 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::old_io::{Command, IoError, OtherIoError}; +use std::io; +use std::process::Command; use target::TargetOptions; use self::Arch::*; @@ -40,16 +41,15 @@ pub fn get_sdk_root(sdk_name: &str) -> String { .arg("--show-sdk-path") .arg("-sdk") .arg(sdk_name) - .spawn() - .and_then(|c| c.wait_with_output()) + .output() .and_then(|output| { if output.status.success() { - Ok(String::from_utf8(output.output).unwrap()) + Ok(String::from_utf8(output.stdout).unwrap()) } else { - Err(IoError { - kind: OtherIoError, - desc: "process exit with error", - detail: String::from_utf8(output.error).ok()}) + let error = String::from_utf8(output.stderr); + Err(io::Error::new(io::ErrorKind::Other, + "process exit with error", + error.ok())) } }); diff --git a/src/libstd/old_io/process.rs b/src/libstd/old_io/process.rs index a13295b1ccb..e02e863516a 100644 --- a/src/libstd/old_io/process.rs +++ b/src/libstd/old_io/process.rs @@ -11,6 +11,9 @@ //! Bindings for executing child processes #![allow(non_upper_case_globals)] +#![unstable(feature = "old_io")] +#![deprecated(since = "1.0.0", + reason = "replaced with the std::process module")] pub use self::StdioContainer::*; pub use self::ProcessExit::*; diff --git a/src/libstd/sys/unix/process.rs b/src/libstd/sys/unix/process.rs index 68c5c65e7cd..62a1799de94 100644 --- a/src/libstd/sys/unix/process.rs +++ b/src/libstd/sys/unix/process.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![allow(deprecated)] + use prelude::v1::*; use self::Req::*; diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs index 53a037ef07e..ca3ed54eb03 100644 --- a/src/libstd/sys/windows/process.rs +++ b/src/libstd/sys/windows/process.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![allow(deprecated)] + use prelude::v1::*; use collections; From 1eb37bf4573e6fc28c6595a60dd3868d6c7daea7 Mon Sep 17 00:00:00 2001 From: Pascal Hertleif Date: Thu, 5 Mar 2015 20:53:53 +0100 Subject: [PATCH 15/37] Fix Playpen Links Containing Multiple Examples Fixes #22615. --- src/librustdoc/html/static/playpen.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/html/static/playpen.js b/src/librustdoc/html/static/playpen.js index 687f764f020..8fb979875cd 100644 --- a/src/librustdoc/html/static/playpen.js +++ b/src/librustdoc/html/static/playpen.js @@ -15,7 +15,7 @@ if (window.playgroundUrl) { $('pre.rust').hover(function() { var a = $('').text('⇱').attr('class', 'test-arrow'); - var code = $(this).siblings(".rusttest").text(); + var code = $(this).prev(".rusttest").text(); a.attr('href', window.playgroundUrl + '?code=' + encodeURIComponent(code)); a.attr('target', '_blank'); From f0897aa17f98ff41f1eb6a3af40d84123d3d89d5 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Thu, 5 Mar 2015 16:20:02 -0500 Subject: [PATCH 16/37] OIBIT: for `PhantomData` check `T` rather than the struct itself --- src/librustc/middle/traits/select.rs | 7 +++++ src/test/compile-fail/phantom-oibit.rs | 41 ++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 src/test/compile-fail/phantom-oibit.rs diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index 470315c78f8..5de67cfd38e 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -1700,6 +1700,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } } + // for `PhantomData`, we pass `T` + ty::ty_struct(def_id, substs) + if Some(def_id) == self.tcx().lang_items.phantom_data() => + { + Some(substs.types.get_slice(TypeSpace).to_vec()) + } + ty::ty_struct(def_id, substs) => { Some(ty::struct_fields(self.tcx(), def_id, substs).iter() .map(|f| f.mt.ty) diff --git a/src/test/compile-fail/phantom-oibit.rs b/src/test/compile-fail/phantom-oibit.rs new file mode 100644 index 00000000000..c912d084daa --- /dev/null +++ b/src/test/compile-fail/phantom-oibit.rs @@ -0,0 +1,41 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Ensure that OIBIT checks `T` when it encounters a `PhantomData` field, instead of checking +// the `PhantomData` type itself (which almost always implements a "default" trait +// (`impl Trait for ..`)) + +#![feature(optin_builtin_traits)] + +use std::marker::{MarkerTrait, PhantomData}; + +unsafe trait Zen: MarkerTrait {} + +unsafe impl Zen for .. {} + +unsafe impl<'a, T: 'a> Zen for &'a T where T: Sync {} + +struct Guard<'a, T: 'a> { + _marker: PhantomData<&'a T>, +} + +struct Nested(T); + +fn is_zen(_: T) {} + +fn not_sync(x: Guard) { + is_zen(x) //~ error: the trait `core::marker::Sync` is not implemented for the type `T` +} + +fn nested_not_sync(x: Nested>) { + is_zen(x) //~ error: the trait `core::marker::Sync` is not implemented for the type `T` +} + +fn main() {} From 93192524fb4e9411bd4163fdd5031b7fbc370eca Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 5 Mar 2015 14:49:58 -0800 Subject: [PATCH 17/37] rustc: Don't emit dep-info for imported files Closes #23089 --- src/librustc_driver/driver.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 73682faf1a7..10be1810c21 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -797,7 +797,9 @@ fn write_out_deps(sess: &Session, // Build a list of files used to compile the output and // write Makefile-compatible dependency rules let files: Vec = sess.codemap().files.borrow() - .iter().filter(|fmap| fmap.is_real_file()) + .iter() + .filter(|fmap| fmap.is_real_file()) + .filter(|fmap| !fmap.is_imported()) .map(|fmap| escape_dep_filename(&fmap.name)) .collect(); let mut file = try!(fs::File::create(&deps_filename)); From d5d834551cd5a7e7d89ac9f2ae642a93409ed989 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 2 Mar 2015 14:51:24 -0800 Subject: [PATCH 18/37] rustc: Add a debug_assertions #[cfg] directive This commit is an implementation of [RFC 563][rfc] which adds a new `cfg(debug_assertions)` directive which is specially recognized and calculated by the compiler. The flag is turned off at any optimization level greater than 1 and may also be explicitly controlled through the `-C debug-assertions` flag. [rfc]: https://github.com/rust-lang/rfcs/pull/563 The `debug_assert!` and `debug_assert_eq!` macros now respect this instead of the `ndebug` variable and `ndebug` no longer holds any meaning to the standard library. Code which was previously relying on `not(ndebug)` to gate expensive code should be updated to rely on `debug_assertions` instead. Closes #22492 [breaking-change] --- mk/tests.mk | 2 +- src/libcore/macros.rs | 24 ++++++----- src/liblog/macros.rs | 4 +- src/librustc/session/config.rs | 16 +++++-- src/librustc_trans/trans/base.rs | 2 +- src/test/run-fail/overflowing-add.rs | 1 + src/test/run-fail/overflowing-mul.rs | 1 + src/test/run-fail/overflowing-sub.rs | 1 + src/test/run-make/debug-assertions/Makefile | 21 ++++++++++ src/test/run-make/debug-assertions/debug.rs | 42 +++++++++++++++++++ .../run-pass/conditional-debug-macro-off.rs | 2 +- src/test/run-pass/logging-enabled-debug.rs | 2 +- src/test/run-pass/logging-separate-lines.rs | 1 + 13 files changed, 100 insertions(+), 19 deletions(-) create mode 100644 src/test/run-make/debug-assertions/Makefile create mode 100644 src/test/run-make/debug-assertions/debug.rs diff --git a/mk/tests.mk b/mk/tests.mk index 838ed0dccfc..ef38abcab65 100644 --- a/mk/tests.mk +++ b/mk/tests.mk @@ -590,7 +590,7 @@ TEST_SREQ$(1)_T_$(2)_H_$(3) = \ # The tests select when to use debug configuration on their own; # remove directive, if present, from CFG_RUSTC_FLAGS (issue #7898). -CTEST_RUSTC_FLAGS := $$(subst --cfg ndebug,,$$(CFG_RUSTC_FLAGS)) +CTEST_RUSTC_FLAGS := $$(subst -C debug-assertions,,$$(CFG_RUSTC_FLAGS)) # The tests cannot be optimized while the rest of the compiler is optimized, so # filter out the optimization (if any) from rustc and then figure out if we need diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index 94ca9ec37b4..96c9beece1c 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -100,10 +100,12 @@ macro_rules! assert_eq { /// This will invoke the `panic!` macro if the provided expression cannot be /// evaluated to `true` at runtime. /// -/// Unlike `assert!`, `debug_assert!` statements can be disabled by passing -/// `--cfg ndebug` to the compiler. This makes `debug_assert!` useful for -/// checks that are too expensive to be present in a release build but may be -/// helpful during development. +/// Unlike `assert!`, `debug_assert!` statements are only enabled in non +/// optimized builds by default. An optimized build will omit all +/// `debug_assert!` statements unless `-C debug-assertions` is passed to the +/// compiler. This makes `debug_assert!` useful for checks that are too +/// expensive to be present in a release build but may be helpful during +/// development. /// /// # Example /// @@ -125,7 +127,7 @@ macro_rules! assert_eq { #[macro_export] #[stable(feature = "rust1", since = "1.0.0")] macro_rules! debug_assert { - ($($arg:tt)*) => (if cfg!(not(ndebug)) { assert!($($arg)*); }) + ($($arg:tt)*) => (if cfg!(debug_assertions) { assert!($($arg)*); }) } /// Asserts that two expressions are equal to each other, testing equality in @@ -133,10 +135,12 @@ macro_rules! debug_assert { /// /// On panic, this macro will print the values of the expressions. /// -/// Unlike `assert_eq!`, `debug_assert_eq!` statements can be disabled by -/// passing `--cfg ndebug` to the compiler. This makes `debug_assert_eq!` -/// useful for checks that are too expensive to be present in a release build -/// but may be helpful during development. +/// Unlike `assert_eq!`, `debug_assert_eq!` statements are only enabled in non +/// optimized builds by default. An optimized build will omit all +/// `debug_assert_eq!` statements unless `-C debug-assertions` is passed to the +/// compiler. This makes `debug_assert_eq!` useful for checks that are too +/// expensive to be present in a release build but may be helpful during +/// development. /// /// # Example /// @@ -147,7 +151,7 @@ macro_rules! debug_assert { /// ``` #[macro_export] macro_rules! debug_assert_eq { - ($($arg:tt)*) => (if cfg!(not(ndebug)) { assert_eq!($($arg)*); }) + ($($arg:tt)*) => (if cfg!(debug_assertions) { assert_eq!($($arg)*); }) } /// Short circuiting evaluation on Err diff --git a/src/liblog/macros.rs b/src/liblog/macros.rs index 4a9a9bd4060..f0f861a3831 100644 --- a/src/liblog/macros.rs +++ b/src/liblog/macros.rs @@ -157,7 +157,7 @@ macro_rules! info { /// ``` #[macro_export] macro_rules! debug { - ($($arg:tt)*) => (if cfg!(not(ndebug)) { log!(::log::DEBUG, $($arg)*) }) + ($($arg:tt)*) => (if cfg!(debug_assertions) { log!(::log::DEBUG, $($arg)*) }) } /// A macro to test whether a log level is enabled for the current module. @@ -192,7 +192,7 @@ macro_rules! debug { macro_rules! log_enabled { ($lvl:expr) => ({ let lvl = $lvl; - (lvl != ::log::DEBUG || cfg!(not(ndebug))) && + (lvl != ::log::DEBUG || cfg!(debug_assertions)) && lvl <= ::log::log_level() && ::log::mod_enabled(lvl, module_path!()) }) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index a4355803f4a..1b09be05020 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -81,6 +81,7 @@ pub struct Options { pub gc: bool, pub optimize: OptLevel, + pub debug_assertions: bool, pub debuginfo: DebugInfoLevel, pub lint_opts: Vec<(String, lint::Level)>, pub describe_lints: bool, @@ -238,7 +239,8 @@ pub fn basic_options() -> Options { crate_name: None, alt_std_name: None, libs: Vec::new(), - unstable_features: UnstableFeatures::Disallow + unstable_features: UnstableFeatures::Disallow, + debug_assertions: true, } } @@ -528,6 +530,8 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options, 2 = full debug info with variable and type information"), opt_level: Option = (None, parse_opt_uint, "Optimize with possible levels 0-3"), + debug_assertions: Option = (None, parse_opt_bool, + "explicitly enable the cfg(debug_assertions) directive"), } @@ -621,7 +625,7 @@ pub fn default_configuration(sess: &Session) -> ast::CrateConfig { }; let mk = attr::mk_name_value_item_str; - return vec!(// Target bindings. + let mut ret = vec![ // Target bindings. attr::mk_word_item(fam.clone()), mk(InternedString::new("target_os"), intern(os)), mk(InternedString::new("target_family"), fam), @@ -629,7 +633,11 @@ pub fn default_configuration(sess: &Session) -> ast::CrateConfig { mk(InternedString::new("target_endian"), intern(end)), mk(InternedString::new("target_pointer_width"), intern(wordsz)) - ); + ]; + if sess.opts.debug_assertions { + ret.push(attr::mk_word_item(InternedString::new("debug_assertions"))); + } + return ret; } pub fn append_configuration(cfg: &mut ast::CrateConfig, @@ -923,6 +931,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { } } }; + let debug_assertions = cg.debug_assertions.unwrap_or(opt_level == No); let gc = debugging_opts.gc; let debuginfo = if matches.opt_present("g") { if cg.debuginfo.is_some() { @@ -1064,6 +1073,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { alt_std_name: None, libs: libs, unstable_features: get_unstable_features_setting(), + debug_assertions: debug_assertions, } } diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 13f882bc363..cf4d0e543e3 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -3089,7 +3089,7 @@ pub fn trans_crate<'tcx>(analysis: ty::CrateAnalysis<'tcx>) let check_overflow = if let Some(v) = tcx.sess.opts.debugging_opts.force_overflow_checks { v } else { - !attr::contains_name(&krate.config, "ndebug") + tcx.sess.opts.debug_assertions }; // Before we touch LLVM, make sure that multithreading is enabled. diff --git a/src/test/run-fail/overflowing-add.rs b/src/test/run-fail/overflowing-add.rs index 34a03e5f008..cd13b817c2b 100644 --- a/src/test/run-fail/overflowing-add.rs +++ b/src/test/run-fail/overflowing-add.rs @@ -9,6 +9,7 @@ // except according to those terms. // error-pattern:thread '