When investigating #22518, this chapter is really the only part that has `rand`, and the rest still works without it. We should have some examples like this, but for now, it's more important to be right than perfect.
# 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:
#
\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
// 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 {
// 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 */ }
}
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() {
When this occurs, we must use Rust's destructors to provide safety and guarantee
the release of these resources (especially in the case of panic).
+For more about destructors, see the [Drop trait](../std/ops/trait.Drop.html).
+
# Callbacks from C code to Rust functions
Some external libraries require the usage of callbacks to report back their
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
- 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
/// 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 {
/// 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 {
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 {
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))
}
/// 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 {
// 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("../");
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 {
#![feature(test)]
#![feature(unicode)]
#![feature(str_words)]
-#![feature(io)]
#![feature(file_path)]
#![feature(path_ext)]
#![feature(path_relative_from)]
#![feature(collections)]
#![feature(core)]
#![feature(int_uint)]
-#![feature(io)]
#![feature(old_path)]
#![feature(rustc_private)]
#![feature(staged_api)]
/// 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);
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))
}
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]
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))
}
}
/// 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)`.
/// 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 {
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 {
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
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;
}
}
+#[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(());
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),
}
}
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()),
}
}
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());
}
}
/// 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,
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);
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,
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);
/// ```
#[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:
///
#[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!()
}
}
use usize;
// Reexport some of our utilities which are expected by other crates.
-pub use self::util::{default_sched_threads, min_stack, running_on_valgrind};
+pub use self::util::{min_stack, running_on_valgrind};
pub use self::unwind::{begin_unwind, begin_unwind_fmt};
// Reexport some functionality from liballoc.
return amt;
}
-/// Get's the number of scheduler threads requested by the environment
-/// either `RUST_THREADS` or `num_cpus`.
-#[allow(deprecated)]
-pub fn default_sched_threads() -> uint {
- use os;
- match env::var("RUST_THREADS") {
- Ok(nstr) => {
- let opt_n: Option<uint> = nstr.parse().ok();
- match opt_n {
- Some(n) if n > 0 => n,
- _ => panic!("`RUST_THREADS` is `{}`, should be a positive integer", nstr)
- }
- }
- Err(..) => {
- if limit_thread_creation_due_to_osx_and_valgrind() {
- 1
- } else {
- os::num_cpus()
- }
- }
- }
-}
-
// Indicates whether we should perform expensive sanity checks, including rtassert!
//
// FIXME: Once the runtime matures remove the `true` below to turn off rtassert,
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,
}
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,
}
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 }
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>] }
$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))
}
#![feature(std_misc)]
#![feature(libc)]
#![feature(set_stdio)]
+#![feature(os)]
extern crate getopts;
extern crate serialize;
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
Ok(())
}
+#[allow(deprecated)]
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(..) => {
- rt::default_sched_threads()
+ if std::rt::util::limit_thread_creation_due_to_osx_and_valgrind() {
+ 1
+ } else {
+ std::os::num_cpus()
+ }
}
}
}
}
/// 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>);
}
/// 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>);
--- /dev/null
+// 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));
+}
--- /dev/null
+// 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
+ })
+}
// 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]
--- /dev/null
+-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
--- /dev/null
+// 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() { }
--- /dev/null
+// 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() { }
--- /dev/null
+// 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);
+}
// 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