]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #23532 - steveklabnik:gh22002, r=alexcrichton
authorManish Goregaokar <manishsmail@gmail.com>
Fri, 20 Mar 2015 00:01:39 +0000 (05:31 +0530)
committerManish Goregaokar <manishsmail@gmail.com>
Fri, 20 Mar 2015 07:13:14 +0000 (12:43 +0530)
 Fixes #22002

37 files changed:
Makefile.in
man/rustc.1
src/compiletest/compiletest.rs
src/compiletest/header.rs
src/doc/trpl/pointers.md
src/doc/trpl/unsafe.md
src/libcore/num/mod.rs
src/librustc/middle/astencode.rs
src/librustc_back/tempdir.rs
src/librustdoc/html/render.rs
src/librustdoc/lib.rs
src/libserialize/lib.rs
src/libstd/fs/mod.rs
src/libstd/fs/tempdir.rs
src/libstd/io/error.rs
src/libstd/io/mod.rs
src/libstd/net/mod.rs
src/libstd/net/parser.rs
src/libstd/net/tcp.rs
src/libstd/num/f32.rs
src/libstd/num/f64.rs
src/libstd/num/mod.rs
src/libstd/process.rs
src/libstd/sys/unix/mod.rs
src/libstd/sys/windows/mod.rs
src/libsyntax/ext/quote.rs
src/libsyntax/print/pprust.rs
src/libtest/lib.rs
src/libunicode/char.rs
src/test/auxiliary/crate_with_invalid_spans.rs [new file with mode: 0644]
src/test/auxiliary/crate_with_invalid_spans_macros.rs [new file with mode: 0644]
src/test/run-fail/test-tasks-invalid-value.rs
src/test/run-make/rustdoc-src-links/Makefile [new file with mode: 0644]
src/test/run-make/rustdoc-src-links/foo.rs [new file with mode: 0644]
src/test/run-make/rustdoc-src-links/qux/mod.rs [new file with mode: 0644]
src/test/run-pass/import-crate-with-invalid-spans.rs [new file with mode: 0644]
src/test/run-pass/tcp-connect-timeouts.rs

index a760155bbd91aeeee3a961599f7a7cf86c4b331a..e7ad2aec7be0af4be5390c40443f5f7c5262fcfa 100644 (file)
 #     make check-stage1-rpass TESTNAME=my-shiny-new-test
 #
 #     // Having trouble figuring out which test is failing? Turn off parallel tests
-#     make check-stage1-std RUST_TEST_TASKS=1
-#
-# This is hardly all there is to know of The Rust Build System's
-# mysteries. The tale continues on the wiki[1].
-#
-# [1]: https://github.com/rust-lang/rust/wiki/Note-testsuite
+#     make check-stage1-std RUST_TEST_THREADS=1
 #
 # If you really feel like getting your hands dirty, then:
 #
index f37e66001909305143f627359a9f392adbbfeb6d..33ef3f9ee4acba4e3078a5a3afb8ac6ccf3849d5 100644 (file)
@@ -242,6 +242,28 @@ full debug info with variable and type information.
 \fBopt\-level\fR=\fIVAL\fR
 Optimize with possible levels 0\[en]3
 
+.SH ENVIRONMENT VARIABLES
+
+Some of these affect the output of the compiler, while others affect programs
+which link to the standard library.
+
+.TP
+\fBRUST_TEST_THREADS\fR
+The test framework Rust provides executes tests in parallel. This variable sets
+the maximum number of threads used for this purpose.
+
+.TP
+\fBRUST_TEST_NOCAPTURE\fR
+A synonym for the --nocapture flag.
+
+.TP
+\fBRUST_MIN_STACK\fR
+Sets the minimum stack size for new threads.
+
+.TP
+\fBRUST_BACKTRACE\fR
+If set, produces a backtrace in the output of a program which panics.
+
 .SH "EXAMPLES"
 To build an executable from a source file with a main function:
     $ rustc \-o hello hello.rs
index 7fbe772b7f5bdd1171971509be08063c3adc86ee..01c4e99b77c70a25daa503a95ac2f1d45a093f0d 100644 (file)
@@ -224,7 +224,7 @@ pub fn run_tests(config: &Config) {
         // android debug-info test uses remote debugger
         // so, we test 1 task at once.
         // also trying to isolate problems with adb_run_wrapper.sh ilooping
-        env::set_var("RUST_TEST_TASKS","1");
+        env::set_var("RUST_TEST_THREADS","1");
     }
 
     match config.mode {
@@ -232,7 +232,7 @@ pub fn run_tests(config: &Config) {
             // Some older versions of LLDB seem to have problems with multiple
             // instances running in parallel, so only run one test task at a
             // time.
-            env::set_var("RUST_TEST_TASKS", "1");
+            env::set_var("RUST_TEST_THREADS", "1");
         }
         _ => { /* proceed */ }
     }
index 21cebc61b3a9d3d4dcc821e15de197b896bdd769..6899fa13974e9e4282bafd0fda4021ec4223765e 100644 (file)
@@ -131,7 +131,7 @@ pub fn load_props(testfile: &Path) -> TestProps {
         true
     });
 
-    for key in vec!["RUST_TEST_NOCAPTURE", "RUST_TEST_TASKS"] {
+    for key in vec!["RUST_TEST_NOCAPTURE", "RUST_TEST_THREADS"] {
         match env::var(key) {
             Ok(val) =>
                 if exec_env.iter().find(|&&(ref x, _)| *x == key.to_string()).is_none() {
index 930a40c5050db4c001f0d306d4aa8e671000fa3d..39106aaf85751c3efeb31b2ce6ebf8357a302879 100644 (file)
@@ -561,38 +561,40 @@ fn main() {
 In this case, Rust knows that `x` is being *borrowed* by the `add_one()`
 function, and since it's only reading the value, allows it.
 
-We can borrow `x` multiple times, as long as it's not simultaneous:
+We can borrow `x` as read-only multiple times, even simultaneously:
 
 ```{rust}
-fn add_one(x: &i32) -> i32 {
-    *x + 1
+fn add(x: &i32, y: &i32) -> i32 {
+    *x + *y
 }
 
 fn main() {
     let x = Box::new(5);
 
-    println!("{}", add_one(&*x));
-    println!("{}", add_one(&*x));
-    println!("{}", add_one(&*x));
+    println!("{}", add(&x, &x));
+    println!("{}", add(&x, &x));
 }
 ```
 
-Or as long as it's not a mutable borrow. This will error:
+We can mutably borrow `x` multiple times, but only if x itself is mutable, and
+it may not be *simultaneously* borrowed: 
 
 ```{rust,ignore}
-fn add_one(x: &mut i32) -> i32 {
-    *x + 1
+fn increment(x: &mut i32) {
+    *x += 1;
 }
 
 fn main() {
-    let x = Box::new(5);
+    // If variable x is not "mut", this will not compile
+    let mut x = Box::new(5);
 
-    println!("{}", add_one(&*x)); // error: cannot borrow immutable dereference
-                                  // of `&`-pointer as mutable
+    increment(&mut x);
+    increment(&mut x);
+    println!("{}", x);
 }
 ```
 
-Notice we changed the signature of `add_one()` to request a mutable reference.
+Notice the signature of `increment()` requests a mutable reference.
 
 ## Best practices
 
index 4e14085599b603d3b640d672748c8f41eebce10f..11f0b8e1ddbf96df73378f4169fae121551fea85 100644 (file)
@@ -93,10 +93,6 @@ offered by the Rust language and libraries. For example, they
 - are plain-old-data, that is, they don't move ownership, again unlike
   `Box`, hence the Rust compiler cannot protect against bugs like
   use-after-free;
-- are considered sendable (if their contents is considered sendable),
-  so the compiler offers no assistance with ensuring their use is
-  thread-safe; for example, one can concurrently access a `*mut i32`
-  from two threads without synchronization.
 - lack any form of lifetimes, unlike `&`, and so the compiler cannot
   reason about dangling pointers; and
 - have no guarantees about aliasing or mutability other than mutation
index 156bc2708fb5f338e46a29e2feca4e9c23dcece7..17ef0ecb1c0da6feb4905230334690661eadd29d 100644 (file)
@@ -345,6 +345,16 @@ fn to_le(self) -> Self {
 
     /// Saturating integer addition. Computes `self + other`, saturating at
     /// the numeric bounds instead of overflowing.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::num::Int;
+    ///
+    /// assert_eq!(5u16.saturating_add(65534), 65535);
+    /// assert_eq!((-5i16).saturating_add(-32767), -32768);
+    /// assert_eq!(100u32.saturating_add(4294967294), 4294967295);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     fn saturating_add(self, other: Self) -> Self {
@@ -357,6 +367,16 @@ fn saturating_add(self, other: Self) -> Self {
 
     /// Saturating integer subtraction. Computes `self - other`, saturating at
     /// the numeric bounds instead of overflowing.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::num::Int;
+    ///
+    /// assert_eq!(5u16.saturating_sub(65534), 0);
+    /// assert_eq!(5i16.saturating_sub(-32767), 32767);
+    /// assert_eq!(100u32.saturating_sub(4294967294), 0);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     fn saturating_sub(self, other: Self) -> Self {
index f7210728bb480099731fad7eb7c999007705179f..8b2a94025f337441a3fa44b86d7e9d4dd549b228 100644 (file)
@@ -235,12 +235,27 @@ pub fn tr_intern_def_id(&self, did: ast::DefId) -> ast::DefId {
     pub fn tr_span(&self, span: Span) -> Span {
         let imported_filemaps = &self.cdata.codemap_import_info[..];
 
+        let span = if span.lo > span.hi {
+            // Currently macro expansion sometimes produces invalid Span values
+            // where lo > hi. In order not to crash the compiler when trying to
+            // translate these values, let's transform them into something we
+            // can handle (and which will produce useful debug locations at
+            // least some of the time).
+            // This workaround is only necessary as long as macro expansion is
+            // not fixed. FIXME(#23480)
+            codemap::mk_sp(span.lo, span.lo)
+        } else {
+            span
+        };
+
         let filemap_index = {
             // Optimize for the case that most spans within a translated item
             // originate from the same filemap.
             let last_filemap_index = self.last_filemap_index.get();
 
             if span.lo >= imported_filemaps[last_filemap_index].original_start_pos &&
+               span.lo <= imported_filemaps[last_filemap_index].original_end_pos &&
+               span.hi >= imported_filemaps[last_filemap_index].original_start_pos &&
                span.hi <= imported_filemaps[last_filemap_index].original_end_pos {
                 last_filemap_index
             } else {
index 4d8619a81216f940c6d14633703836187503fd71..0e87ba278db21f520286843306901c2494beac2f 100644 (file)
@@ -61,12 +61,12 @@ pub fn new_in<P: AsPath + ?Sized>(tmpdir: &P, prefix: &str)
             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(ref e) if e.kind() == ErrorKind::AlreadyExists => {}
                 Err(e) => return Err(e)
             }
         }
 
-        Err(Error::new(ErrorKind::PathAlreadyExists,
+        Err(Error::new(ErrorKind::AlreadyExists,
                        "too many temporary directories already exist",
                        None))
     }
index f97470dbaed758d885165bed8c20e67c334d0c98..81daac7b90f0d018fb86ed71288a9f088ce8fffe 100644 (file)
@@ -692,16 +692,23 @@ fn shortty(item: &clean::Item) -> ItemType {
 
 /// Takes a path to a source file and cleans the path to it. This canonicalizes
 /// things like ".." to components which preserve the "top down" hierarchy of a
-/// static HTML tree.
+/// static HTML tree. Each component in the cleaned path will be passed as an
+/// argument to `f`. The very last component of the path (ie the file name) will
+/// be passed to `f` if `keep_filename` is true, and ignored otherwise.
 // FIXME (#9639): The closure should deal with &[u8] instead of &str
 // FIXME (#9639): This is too conservative, rejecting non-UTF-8 paths
-fn clean_srcpath<F>(src_root: &Path, p: &Path, mut f: F) where
+fn clean_srcpath<F>(src_root: &Path, p: &Path, keep_filename: bool, mut f: F) where
     F: FnMut(&str),
 {
     // make it relative, if possible
     let p = p.relative_from(src_root).unwrap_or(p);
 
-    for c in p.iter().map(|x| x.to_str().unwrap()) {
+    let mut iter = p.iter().map(|x| x.to_str().unwrap()).peekable();
+    while let Some(c) = iter.next() {
+        if !keep_filename && iter.peek().is_none() {
+            break;
+        }
+
         if ".." == c {
             f("up");
         } else {
@@ -803,7 +810,7 @@ fn emit_source(&mut self, filename: &str) -> io::Result<()> {
         // Create the intermediate directories
         let mut cur = self.dst.clone();
         let mut root_path = String::from_str("../../");
-        clean_srcpath(&self.cx.src_root, &p, |component| {
+        clean_srcpath(&self.cx.src_root, &p, false, |component| {
             cur.push(component);
             mkdir(&cur).unwrap();
             root_path.push_str("../");
@@ -1368,7 +1375,7 @@ fn href(&self, cx: &Context) -> Option<String> {
         if ast_util::is_local(self.item.def_id) {
             let mut path = Vec::new();
             clean_srcpath(&cx.src_root, Path::new(&self.item.source.filename),
-                          |component| {
+                          true, |component| {
                 path.push(component.to_string());
             });
             let href = if self.item.source.loline == self.item.source.hiline {
index bd4177861dd42f9d53ee6b3d5861fa8a0bc41ae0..0650b4d515860902ab9409444b96822042a5611c 100644 (file)
@@ -35,7 +35,6 @@
 #![feature(test)]
 #![feature(unicode)]
 #![feature(str_words)]
-#![feature(io)]
 #![feature(file_path)]
 #![feature(path_ext)]
 #![feature(path_relative_from)]
index 31c270dca6bba1fa612d6c18da71362b4cc33916..90cb88046e53d008416577d3934a927888b6dbe9 100644 (file)
@@ -31,7 +31,6 @@
 #![feature(collections)]
 #![feature(core)]
 #![feature(int_uint)]
-#![feature(io)]
 #![feature(old_path)]
 #![feature(rustc_private)]
 #![feature(staged_api)]
index ba89b3a0ea63f8b0e365a07ea6275d0beb258839..c56852cb18a0577b93ca8895a34c44a1d0c44965 100644 (file)
@@ -73,6 +73,11 @@ pub struct File {
 /// will yield instances of `io::Result<DirEntry>`. Through a `DirEntry`
 /// information like the entry's path and possibly other metadata can be
 /// learned.
+///
+/// # Failure
+///
+/// This `io::Result` will be an `Err` if there's some sort of intermittent
+/// IO error during iteration.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct ReadDir(fs_imp::ReadDir);
 
@@ -493,7 +498,7 @@ pub fn copy<P: AsPath, Q: AsPath>(from: P, to: Q) -> io::Result<u64> {
     let from = from.as_path();
     let to = to.as_path();
     if !from.is_file() {
-        return Err(Error::new(ErrorKind::MismatchedFileTypeForOperation,
+        return Err(Error::new(ErrorKind::InvalidInput,
                               "the source path is not an existing file",
                               None))
     }
@@ -1134,7 +1139,7 @@ fn mkdir_path_already_exists_error() {
         let dir = &tmpdir.join("mkdir_error_twice");
         check!(fs::create_dir(dir));
         let e = fs::create_dir(dir).err().unwrap();
-        assert_eq!(e.kind(), ErrorKind::PathAlreadyExists);
+        assert_eq!(e.kind(), ErrorKind::AlreadyExists);
     }
 
     #[test]
index c1da77a6668f51b513ab79d7428a87aa1bcebd3d..8f32d7a586459241324a3a249a6ede228c4bce55 100644 (file)
@@ -68,12 +68,12 @@ pub fn new_in<P: AsPath + ?Sized>(tmpdir: &P, prefix: &str)
             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(ref e) if e.kind() == ErrorKind::AlreadyExists => {}
                 Err(e) => return Err(e)
             }
         }
 
-        Err(Error::new(ErrorKind::PathAlreadyExists,
+        Err(Error::new(ErrorKind::AlreadyExists,
                        "too many temporary directories already exist",
                        None))
     }
index 530c672810723a26ae7c59cfd1c6535a3e6a9105..f445ace081e4ffc9f2b66b4e2317d07f76076bdb 100644 (file)
@@ -51,41 +51,53 @@ struct Custom {
 }
 
 /// A list specifying general categories of I/O error.
+///
+/// This list is intended to grow over time and it is not recommended to
+/// exhaustively match against it.
 #[derive(Copy, PartialEq, Eq, Clone, Debug)]
-#[unstable(feature = "io",
-           reason = "the interaction between OS error codes and how they map to \
-                     these names (as well as the names themselves) has not \
-                     been thoroughly thought out")]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub enum ErrorKind {
-    /// The file was not found.
-    FileNotFound,
-    /// The file permissions disallowed access to this file.
+    /// An entity was not found, often a file.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    NotFound,
+    /// The operation lacked the necessary privileges to complete.
+    #[stable(feature = "rust1", since = "1.0.0")]
     PermissionDenied,
     /// The connection was refused by the remote server.
+    #[stable(feature = "rust1", since = "1.0.0")]
     ConnectionRefused,
     /// The connection was reset by the remote server.
+    #[stable(feature = "rust1", since = "1.0.0")]
     ConnectionReset,
     /// The connection was aborted (terminated) by the remote server.
+    #[stable(feature = "rust1", since = "1.0.0")]
     ConnectionAborted,
     /// The network operation failed because it was not connected yet.
+    #[stable(feature = "rust1", since = "1.0.0")]
     NotConnected,
+    /// A socket address could not be bound because the address is already in
+    /// use elsewhere.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    AddrInUse,
+    /// A nonexistent interface was requested or the requested address was not
+    /// local.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    AddrNotAvailable,
     /// The operation failed because a pipe was closed.
+    #[stable(feature = "rust1", since = "1.0.0")]
     BrokenPipe,
-    /// A file already existed with that name.
-    PathAlreadyExists,
-    /// No file exists at that location.
-    PathDoesntExist,
-    /// The path did not specify the type of file that this operation required.
-    /// For example, attempting to copy a directory with the `fs::copy()`
-    /// operation will fail with this error.
-    MismatchedFileTypeForOperation,
-    /// The operation temporarily failed (for example, because a signal was
-    /// received), and retrying may succeed.
-    ResourceUnavailable,
-    /// A parameter was incorrect in a way that caused an I/O error not part of
-    /// this list.
+    /// An entity already exists, often a file.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    AlreadyExists,
+    /// The operation needs to block to complete, but the blocking operation was
+    /// requested to not occur.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    WouldBlock,
+    /// A parameter was incorrect.
+    #[stable(feature = "rust1", since = "1.0.0")]
     InvalidInput,
     /// The I/O operation's timeout expired, causing it to be canceled.
+    #[stable(feature = "rust1", since = "1.0.0")]
     TimedOut,
     /// An error returned when an operation could not be completed because a
     /// call to `write` returned `Ok(0)`.
@@ -93,11 +105,23 @@ pub enum ErrorKind {
     /// This typically means that an operation could only succeed if it wrote a
     /// particular number of bytes but only a smaller number of bytes could be
     /// written.
+    #[stable(feature = "rust1", since = "1.0.0")]
     WriteZero,
-    /// This operation was interrupted
+    /// This operation was interrupted.
+    ///
+    /// Interrupted operations can typically be retried.
+    #[stable(feature = "rust1", since = "1.0.0")]
     Interrupted,
     /// Any I/O error not part of this list.
+    #[stable(feature = "rust1", since = "1.0.0")]
     Other,
+
+    /// Any I/O error not part of this list.
+    #[unstable(feature = "std_misc",
+               reason = "better expressed through extensible enums that this \
+                         enum cannot be exhaustively matched against")]
+    #[doc(hidden)]
+    __Nonexhaustive,
 }
 
 impl Error {
@@ -134,6 +158,19 @@ pub fn from_os_error(code: i32) -> Error {
         Error { repr: Repr::Os(code) }
     }
 
+    /// Returns the OS error that this error represents (if any).
+    ///
+    /// If this `Error` was constructed via `last_os_error` then this function
+    /// will return `Some`, otherwise it will return `None`.
+    #[unstable(feature = "io", reason = "function was just added and the return \
+                                         type may become an abstract OS error")]
+    pub fn raw_os_error(&self) -> Option<i32> {
+        match self.repr {
+            Repr::Os(i) => Some(i),
+            Repr::Custom(..) => None,
+        }
+    }
+
     /// Return the corresponding `ErrorKind` for this error.
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn kind(&self) -> ErrorKind {
index 8691c84a4622f348b675545aa060740f23d40f06..237435d6dfbfa4c9b8a224c515edc74d122dc20a 100644 (file)
@@ -584,7 +584,8 @@ fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> Result<usize> {
         read_until(self, byte, buf)
     }
 
-    /// Read all bytes until a newline byte (the 0xA byte) is reached.
+    /// Read all bytes until a newline byte (the 0xA byte) is reached, and
+    /// append them to the provided buffer.
     ///
     /// This function will continue to read (and buffer) bytes from the
     /// underlying stream until the newline delimiter (the 0xA byte) or EOF is
index 36f36af73e1480c10bc435e1455e8f8d48c41122..543fdd16f41e307d3b185f7e8f39232ad494e6b0 100644 (file)
@@ -25,6 +25,7 @@
 pub use self::addr::{SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs};
 pub use self::tcp::{TcpStream, TcpListener};
 pub use self::udp::UdpSocket;
+pub use self::parser::AddrParseError;
 
 mod ip;
 mod addr;
index 9843a1527180e356b7f996e69e4aba307e8fd99b..e7509834c7b7866a83b2f52f564c40816c76781a 100644 (file)
@@ -296,35 +296,40 @@ fn read_socket_addr(&mut self) -> Option<SocketAddr> {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl FromStr for Ipv4Addr {
-    type Err = ParseError;
-    fn from_str(s: &str) -> Result<Ipv4Addr, ParseError> {
+    type Err = AddrParseError;
+    fn from_str(s: &str) -> Result<Ipv4Addr, AddrParseError> {
         match Parser::new(s).read_till_eof(|p| p.read_ipv4_addr()) {
             Some(s) => Ok(s),
-            None => Err(ParseError)
+            None => Err(AddrParseError(()))
         }
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl FromStr for Ipv6Addr {
-    type Err = ParseError;
-    fn from_str(s: &str) -> Result<Ipv6Addr, ParseError> {
+    type Err = AddrParseError;
+    fn from_str(s: &str) -> Result<Ipv6Addr, AddrParseError> {
         match Parser::new(s).read_till_eof(|p| p.read_ipv6_addr()) {
             Some(s) => Ok(s),
-            None => Err(ParseError)
+            None => Err(AddrParseError(()))
         }
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl FromStr for SocketAddr {
-    type Err = ParseError;
-    fn from_str(s: &str) -> Result<SocketAddr, ParseError> {
+    type Err = AddrParseError;
+    fn from_str(s: &str) -> Result<SocketAddr, AddrParseError> {
         match Parser::new(s).read_till_eof(|p| p.read_socket_addr()) {
             Some(s) => Ok(s),
-            None => Err(ParseError),
+            None => Err(AddrParseError(())),
         }
     }
 }
 
-#[derive(Debug, Clone, PartialEq, Copy)]
-pub struct ParseError;
+/// An error returned when parsing an IP address or a socket address.
+#[stable(feature = "rust1", since = "1.0.0")]
+#[derive(Debug, Clone, PartialEq)]
+pub struct AddrParseError(());
index 501ba2dc2c178b63ffe7b98597c769043ee112f5..f263d7d72d35d364d5d5d04af0a6c2d78dc83c15 100644 (file)
@@ -273,8 +273,7 @@ fn bind_error() {
         match TcpListener::bind("1.1.1.1:9999") {
             Ok(..) => panic!(),
             Err(e) =>
-                // EADDRNOTAVAIL is mapped to ConnectionRefused
-                assert_eq!(e.kind(), ErrorKind::ConnectionRefused),
+                assert_eq!(e.kind(), ErrorKind::AddrNotAvailable),
         }
     }
 
@@ -282,8 +281,11 @@ fn bind_error() {
     fn connect_error() {
         match TcpStream::connect("0.0.0.0:1") {
             Ok(..) => panic!(),
-            Err(e) => assert!((e.kind() == ErrorKind::ConnectionRefused)
-                              || (e.kind() == ErrorKind::InvalidInput)),
+            Err(e) => assert!(e.kind() == ErrorKind::ConnectionRefused ||
+                              e.kind() == ErrorKind::InvalidInput ||
+                              e.kind() == ErrorKind::AddrInUse ||
+                              e.kind() == ErrorKind::AddrNotAvailable,
+                              "bad error: {} {:?}", e, e.kind()),
         }
     }
 
@@ -535,7 +537,8 @@ fn double_bind() {
                 Ok(..) => panic!(),
                 Err(e) => {
                     assert!(e.kind() == ErrorKind::ConnectionRefused ||
-                            e.kind() == ErrorKind::Other,
+                            e.kind() == ErrorKind::Other ||
+                            e.kind() == ErrorKind::AddrInUse,
                             "unknown error: {} {:?}", e, e.kind());
                 }
             }
index 11e2b8dca1b8082d73c6835326497b4d96185acb..b5513dfd0354d542538360bb947fb510020596d3 100644 (file)
@@ -191,8 +191,8 @@ fn to_radians(self) -> f32 { num::Float::to_radians(self) }
     /// Constructs a floating point number by multiplying `x` by 2 raised to the
     /// power of `exp`
     #[inline]
-    fn ldexp(x: f32, exp: int) -> f32 {
-        unsafe { cmath::ldexpf(x, exp as c_int) }
+    fn ldexp(self, exp: isize) -> f32 {
+        unsafe { cmath::ldexpf(self, exp as c_int) }
     }
 
     /// Breaks the number into a normalized fraction and a base-2 exponent,
@@ -2207,8 +2207,8 @@ fn test_ldexp() {
         let f1: f32 = FromStrRadix::from_str_radix("1p-123", 16).unwrap();
         let f2: f32 = FromStrRadix::from_str_radix("1p-111", 16).unwrap();
         let f3: f32 = FromStrRadix::from_str_radix("1.Cp-12", 16).unwrap();
-        assert_eq!(Float::ldexp(1f32, -123), f1);
-        assert_eq!(Float::ldexp(1f32, -111), f2);
+        assert_eq!(1f32.ldexp(-123), f1);
+        assert_eq!(1f32.ldexp(-111), f2);
         assert_eq!(Float::ldexp(1.75f32, -12), f3);
 
         assert_eq!(Float::ldexp(0f32, -123), 0f32);
index 650f642220fc0c270257226d1912068c9d80738b..61bddc3d18f66310c7210bdd5c7747b9001f0517 100644 (file)
@@ -200,8 +200,8 @@ fn to_degrees(self) -> f64 { num::Float::to_degrees(self) }
     fn to_radians(self) -> f64 { num::Float::to_radians(self) }
 
     #[inline]
-    fn ldexp(x: f64, exp: int) -> f64 {
-        unsafe { cmath::ldexp(x, exp as c_int) }
+    fn ldexp(self, exp: isize) -> f64 {
+        unsafe { cmath::ldexp(self, exp as c_int) }
     }
 
     /// Breaks the number into a normalized fraction and a base-2 exponent,
@@ -2214,8 +2214,8 @@ fn test_ldexp() {
         let f1: f64 = FromStrRadix::from_str_radix("1p-123", 16).unwrap();
         let f2: f64 = FromStrRadix::from_str_radix("1p-111", 16).unwrap();
         let f3: f64 = FromStrRadix::from_str_radix("1.Cp-12", 16).unwrap();
-        assert_eq!(Float::ldexp(1f64, -123), f1);
-        assert_eq!(Float::ldexp(1f64, -111), f2);
+        assert_eq!(1f64.ldexp(-123), f1);
+        assert_eq!(1f64.ldexp(-111), f2);
         assert_eq!(Float::ldexp(1.75f64, -12), f3);
 
         assert_eq!(Float::ldexp(0f64, -123), 0f64);
index 37f1f69177621781729c03e49f0c6d2bcb7fdf6d..082dad613b5561891bd11be67406f354e198fa9b 100644 (file)
@@ -699,7 +699,7 @@ pub trait Float
     /// ```
     #[unstable(feature = "std_misc",
                reason = "pending integer conventions")]
-    fn ldexp(x: Self, exp: isize) -> Self;
+    fn ldexp(self, exp: isize) -> Self;
     /// Breaks the number into a normalized fraction and a base-2 exponent,
     /// satisfying:
     ///
index df8a5d27c7fa0be9767784af1d481af23997beeb..cda37b19c48680b4815e579acb839be6faa891ff 100644 (file)
@@ -668,7 +668,7 @@ fn test_process_status() {
     #[test]
     fn test_process_output_fail_to_start() {
         match Command::new("/no-binary-by-this-name-should-exist").output() {
-            Err(e) => assert_eq!(e.kind(), ErrorKind::FileNotFound),
+            Err(e) => assert_eq!(e.kind(), ErrorKind::NotFound),
             Ok(..) => panic!()
         }
     }
index a8cee74828d3496c433f07bcf73b202a32f9d03c..5555eec4f391876ad7227ba501540bec7dd198df 100644 (file)
@@ -139,22 +139,19 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind {
         libc::EPIPE => ErrorKind::BrokenPipe,
         libc::ENOTCONN => ErrorKind::NotConnected,
         libc::ECONNABORTED => ErrorKind::ConnectionAborted,
-        libc::EADDRNOTAVAIL => ErrorKind::ConnectionRefused,
-        libc::EADDRINUSE => ErrorKind::ConnectionRefused,
-        libc::ENOENT => ErrorKind::FileNotFound,
-        libc::EISDIR => ErrorKind::InvalidInput,
+        libc::EADDRNOTAVAIL => ErrorKind::AddrNotAvailable,
+        libc::EADDRINUSE => ErrorKind::AddrInUse,
+        libc::ENOENT => ErrorKind::NotFound,
         libc::EINTR => ErrorKind::Interrupted,
         libc::EINVAL => ErrorKind::InvalidInput,
-        libc::ENOTTY => ErrorKind::MismatchedFileTypeForOperation,
         libc::ETIMEDOUT => ErrorKind::TimedOut,
-        libc::ECANCELED => ErrorKind::TimedOut,
-        libc::consts::os::posix88::EEXIST => ErrorKind::PathAlreadyExists,
+        libc::consts::os::posix88::EEXIST => ErrorKind::AlreadyExists,
 
         // These two constants can have the same value on some systems,
         // but different values on others, so we can't use a match
         // clause
         x if x == libc::EAGAIN || x == libc::EWOULDBLOCK =>
-            ErrorKind::ResourceUnavailable,
+            ErrorKind::WouldBlock,
 
         _ => ErrorKind::Other,
     }
index d02fe79fcdb1f9ea18f93f22ce599f32f38d1009..eeaf4ced07239e16fe0b5b3b83b08bb45a45fe99 100644 (file)
@@ -149,25 +149,21 @@ pub fn decode_error_detailed(errno: i32) -> IoError {
 pub fn decode_error_kind(errno: i32) -> ErrorKind {
     match errno as libc::c_int {
         libc::ERROR_ACCESS_DENIED => ErrorKind::PermissionDenied,
-        libc::ERROR_ALREADY_EXISTS => ErrorKind::PathAlreadyExists,
+        libc::ERROR_ALREADY_EXISTS => ErrorKind::AlreadyExists,
         libc::ERROR_BROKEN_PIPE => ErrorKind::BrokenPipe,
-        libc::ERROR_FILE_NOT_FOUND => ErrorKind::FileNotFound,
-        libc::ERROR_INVALID_FUNCTION => ErrorKind::InvalidInput,
-        libc::ERROR_INVALID_HANDLE => ErrorKind::MismatchedFileTypeForOperation,
-        libc::ERROR_INVALID_NAME => ErrorKind::InvalidInput,
-        libc::ERROR_NOTHING_TO_TERMINATE => ErrorKind::InvalidInput,
+        libc::ERROR_FILE_NOT_FOUND => ErrorKind::NotFound,
         libc::ERROR_NO_DATA => ErrorKind::BrokenPipe,
         libc::ERROR_OPERATION_ABORTED => ErrorKind::TimedOut,
 
         libc::WSAEACCES => ErrorKind::PermissionDenied,
-        libc::WSAEADDRINUSE => ErrorKind::ConnectionRefused,
-        libc::WSAEADDRNOTAVAIL => ErrorKind::ConnectionRefused,
+        libc::WSAEADDRINUSE => ErrorKind::AddrInUse,
+        libc::WSAEADDRNOTAVAIL => ErrorKind::AddrNotAvailable,
         libc::WSAECONNABORTED => ErrorKind::ConnectionAborted,
         libc::WSAECONNREFUSED => ErrorKind::ConnectionRefused,
         libc::WSAECONNRESET => ErrorKind::ConnectionReset,
         libc::WSAEINVAL => ErrorKind::InvalidInput,
         libc::WSAENOTCONN => ErrorKind::NotConnected,
-        libc::WSAEWOULDBLOCK => ErrorKind::ResourceUnavailable,
+        libc::WSAEWOULDBLOCK => ErrorKind::WouldBlock,
 
         _ => ErrorKind::Other,
     }
index c38556b0782196e3bb51f0d59d985bbb8793aeea..c11ffe66e6c392305450dd13706994e6ba3ed812 100644 (file)
@@ -176,6 +176,8 @@ fn to_source_with_hygiene(&self) -> String {
     impl_to_source! { ast::Arg, arg_to_string }
     impl_to_source! { Generics, generics_to_string }
     impl_to_source! { P<ast::Item>, item_to_string }
+    impl_to_source! { P<ast::ImplItem>, impl_item_to_string }
+    impl_to_source! { P<ast::TraitItem>, trait_item_to_string }
     impl_to_source! { P<ast::Stmt>, stmt_to_string }
     impl_to_source! { P<ast::Expr>, expr_to_string }
     impl_to_source! { P<ast::Pat>, pat_to_string }
@@ -308,6 +310,8 @@ fn to_tokens(&self, cx: &ExtCtxt) -> Vec<TokenTree> {
 
     impl_to_tokens! { ast::Ident }
     impl_to_tokens! { P<ast::Item> }
+    impl_to_tokens! { P<ast::ImplItem> }
+    impl_to_tokens! { P<ast::TraitItem> }
     impl_to_tokens! { P<ast::Pat> }
     impl_to_tokens! { ast::Arm }
     impl_to_tokens_lifetime! { &'a [P<ast::Item>] }
index b58c121c5fd54730df170197ef956b41145b95cc..239fea57d94d2ae795f47dc5ba21543818e8aa8d 100644 (file)
@@ -355,6 +355,14 @@ pub fn item_to_string(i: &ast::Item) -> String {
     $to_string(|s| s.print_item(i))
 }
 
+pub fn impl_item_to_string(i: &ast::ImplItem) -> String {
+    $to_string(|s| s.print_impl_item(i))
+}
+
+pub fn trait_item_to_string(i: &ast::TraitItem) -> String {
+    $to_string(|s| s.print_trait_item(i))
+}
+
 pub fn generics_to_string(generics: &ast::Generics) -> String {
     $to_string(|s| s.print_generics(generics))
 }
index 02ddeea46bfc8ad14fcf5f20a0308fa93b5447cc..e4ccd49e807acfb1f803e25819ccb35c14a653ec 100644 (file)
@@ -338,7 +338,7 @@ fn usage(binary: &str) {
 only those tests that match are run.
 
 By default, all tests are run in parallel. This can be altered with the
-RUST_TEST_TASKS environment variable when running tests (set it to 1).
+RUST_TEST_THRADS environment variable when running tests (set it to 1).
 
 All tests have their standard output and standard error captured by default.
 This can be overridden with the --nocapture flag or the RUST_TEST_NOCAPTURE=1
@@ -843,12 +843,12 @@ fn run_tests<F>(opts: &TestOpts,
 
 fn get_concurrency() -> uint {
     use std::rt;
-    match env::var("RUST_TEST_TASKS") {
+    match env::var("RUST_TEST_THREADS") {
         Ok(s) => {
             let opt_n: Option<uint> = s.parse().ok();
             match opt_n {
                 Some(n) if n > 0 => n,
-                _ => panic!("RUST_TEST_TASKS is `{}`, should be a positive integer.", s)
+                _ => panic!("RUST_TEST_THREADS is `{}`, should be a positive integer.", s)
             }
         }
         Err(..) => {
index e24ade58a5224e36f33d440f00d19038b6ad1020..5e1070c6dc503d1bc1019eab14dff4a90a16288b 100644 (file)
@@ -462,7 +462,8 @@ fn width(self, is_cjk: bool) -> Option<usize> { charwidth::width(self, is_cjk) }
 }
 
 /// An iterator over the lowercase mapping of a given character, returned from
-/// the `lowercase` method on characters.
+/// the [`to_lowercase` method](../primitive.char.html#method.to_lowercase) on
+/// characters.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct ToLowercase(Option<char>);
 
@@ -473,7 +474,8 @@ fn next(&mut self) -> Option<char> { self.0.take() }
 }
 
 /// An iterator over the uppercase mapping of a given character, returned from
-/// the `uppercase` method on characters.
+/// the [`to_uppercase` method](../primitive.char.html#method.to_uppercase) on
+/// characters.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct ToUppercase(Option<char>);
 
diff --git a/src/test/auxiliary/crate_with_invalid_spans.rs b/src/test/auxiliary/crate_with_invalid_spans.rs
new file mode 100644 (file)
index 0000000..b37533d
--- /dev/null
@@ -0,0 +1,30 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_type = "rlib"]
+// no-prefer-dynamic
+
+// compile-flags: -g
+
+#[macro_use]
+mod crate_with_invalid_spans_macros;
+
+pub fn exported_generic<T>(x: T, y: u32) -> (T, u32) {
+    // Using the add1 macro will produce an invalid span, because the `y` passed
+    // to the macro will have a span from this file, but the rest of the code
+    // generated from the macro will have spans from the macro-defining file.
+    // The AST node for the (1 + y) expression generated by the macro will then
+    // take it's `lo` span bound from the `1` literal in the macro-defining file
+    // and it's `hi` bound from `y` in this file, which should be lower than the
+    // `lo` and even lower than the lower bound of the FileMap it is supposedly
+    // contained in because the FileMap for this file was allocated earlier than
+    // the FileMap of the macro-defining file.
+    return (x, add1!(y));
+}
diff --git a/src/test/auxiliary/crate_with_invalid_spans_macros.rs b/src/test/auxiliary/crate_with_invalid_spans_macros.rs
new file mode 100644 (file)
index 0000000..112315a
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+macro_rules! add1 {
+    ($e:expr) => ({
+        let a = 1 + $e;
+        let b = $e + 1;
+        a + b - 1
+    })
+}
index 8c9cd2d63cb4758f4c29f40e3e2435294872a126..94ed641c79c9372cabcf34a107356b5e2bc780cc 100644 (file)
@@ -8,12 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// This checks that RUST_TEST_TASKS not being 1, 2, ... is detected
+// This checks that RUST_TEST_THREADS not being 1, 2, ... is detected
 // properly.
 
 // error-pattern:should be a positive integer
 // compile-flags: --test
-// exec-env:RUST_TEST_TASKS=foo
+// exec-env:RUST_TEST_THREADS=foo
 // ignore-pretty: does not work well with `--test`
 
 #[test]
diff --git a/src/test/run-make/rustdoc-src-links/Makefile b/src/test/run-make/rustdoc-src-links/Makefile
new file mode 100644 (file)
index 0000000..419603e
--- /dev/null
@@ -0,0 +1,5 @@
+-include ../tools.mk
+all:
+       $(HOST_RPATH_ENV) $(RUSTDOC) -w html -o $(TMPDIR)/doc foo.rs
+       $(HTMLDOCCK) $(TMPDIR)/doc foo.rs
+       $(HTMLDOCCK) $(TMPDIR)/doc qux/mod.rs
diff --git a/src/test/run-make/rustdoc-src-links/foo.rs b/src/test/run-make/rustdoc-src-links/foo.rs
new file mode 100644 (file)
index 0000000..9a964f1
--- /dev/null
@@ -0,0 +1,43 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_name = "foo"]
+
+//! Dox
+// @has src/foo/foo.rs.html
+// @has foo/index.html '//a/@href' '../src/foo/foo.rs.html'
+
+pub mod qux;
+
+// @has foo/bar/index.html '//a/@href' '../../src/foo/foo.rs.html'
+pub mod bar {
+
+    /// Dox
+    // @has foo/bar/baz/index.html '//a/@href' '../../../src/foo/foo.rs.html'
+    pub mod baz {
+        /// Dox
+        // @has foo/bar/baz/fn.baz.html '//a/@href' '../../../src/foo/foo.rs.html'
+        pub fn baz() { }
+    }
+
+    /// Dox
+    // @has foo/bar/trait.Foobar.html '//a/@href' '../../src/foo/foo.rs.html'
+    pub trait Foobar { fn dummy(&self) { } }
+
+    // @has foo/bar/struct.Foo.html '//a/@href' '../../src/foo/foo.rs.html'
+    pub struct Foo { x: i32, y: u32 }
+
+    // @has foo/bar/fn.prawns.html '//a/@href' '../../src/foo/foo.rs.html'
+    pub fn prawns((a, b): (i32, u32), Foo { x, y }: Foo) { }
+}
+
+/// Dox
+// @has foo/fn.modfn.html '//a/@href' '../src/foo/foo.rs.html'
+pub fn modfn() { }
diff --git a/src/test/run-make/rustdoc-src-links/qux/mod.rs b/src/test/run-make/rustdoc-src-links/qux/mod.rs
new file mode 100644 (file)
index 0000000..9b1563d
--- /dev/null
@@ -0,0 +1,39 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Dox
+// @has src/foo/qux/mod.rs.html
+// @has foo/qux/index.html '//a/@href' '../../src/foo/qux/mod.rs.html'
+
+// @has foo/qux/bar/index.html '//a/@href' '../../../src/foo/qux/mod.rs.html'
+pub mod bar {
+
+    /// Dox
+    // @has foo/qux/bar/baz/index.html '//a/@href' '../../../../src/foo/qux/mod.rs.html'
+    pub mod baz {
+        /// Dox
+        // @has foo/qux/bar/baz/fn.baz.html '//a/@href' '../../../../src/foo/qux/mod.rs.html'
+        pub fn baz() { }
+    }
+
+    /// Dox
+    // @has foo/qux/bar/trait.Foobar.html '//a/@href' '../../../src/foo/qux/mod.rs.html'
+    pub trait Foobar { fn dummy(&self) { } }
+
+    // @has foo/qux/bar/struct.Foo.html '//a/@href' '../../../src/foo/qux/mod.rs.html'
+    pub struct Foo { x: i32, y: u32 }
+
+    // @has foo/qux/bar/fn.prawns.html '//a/@href' '../../../src/foo/qux/mod.rs.html'
+    pub fn prawns((a, b): (i32, u32), Foo { x, y }: Foo) { }
+}
+
+/// Dox
+// @has foo/qux/fn.modfn.html '//a/@href' '../../src/foo/qux/mod.rs.html'
+pub fn modfn() { }
diff --git a/src/test/run-pass/import-crate-with-invalid-spans.rs b/src/test/run-pass/import-crate-with-invalid-spans.rs
new file mode 100644 (file)
index 0000000..a949f25
--- /dev/null
@@ -0,0 +1,20 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:crate_with_invalid_spans.rs
+
+extern crate crate_with_invalid_spans;
+
+fn main() {
+    // The AST of `exported_generic` stored in crate_with_invalid_spans's
+    // metadata should contain an invalid span where span.lo > span.hi.
+    // Let's make sure the compiler doesn't crash when encountering this.
+    let _ = crate_with_invalid_spans::exported_generic(32u32, 7u32);
+}
index d1a3edcfbc52931cb341ed9bf6c2dc0fae0429ec..5462a996f73d974d071a4ca31b6845cc68228dc1 100644 (file)
@@ -10,7 +10,7 @@
 
 // ignore-pretty
 // compile-flags:--test
-// exec-env:RUST_TEST_TASKS=1
+// exec-env:RUST_TEST_THREADS=1
 
 // Tests for the connect_timeout() function on a TcpStream. This runs with only
 // one test task to ensure that errors are timeouts, not file descriptor