]> git.lizzy.rs Git - rust.git/commitdiff
auto merge of #16326 : pnkfelix/rust/fsk-add-path-suffix-lookup, r=huonw
authorbors <bors@rust-lang.org>
Sat, 9 Aug 2014 09:51:23 +0000 (09:51 +0000)
committerbors <bors@rust-lang.org>
Sat, 9 Aug 2014 09:51:23 +0000 (09:51 +0000)
Extended `ast_map::Map` with an iterator over all node id's that match a path suffix.

Extended pretty printer to let users choose particular items to pretty print, either by indicating an integer node-id, or by providing a path suffix.

 * Example 1: the suffix `typeck::check::check_struct` matches the item with the path `rustc::middle::typeck::check::check_struct` when compiling the `rustc` crate.

 * Example 2: the suffix `and` matches `core::option::Option::and` and `core::result::Result::and` when compiling the `core` crate.

Refactored `pprust` slightly to support the pretty printer changes.

(See individual commits for more description.)

38 files changed:
configure
src/doc/guide.md
src/libcollections/ringbuf.rs
src/libcollections/vec.rs
src/libcore/char.rs
src/libcore/failure.rs
src/libcore/fmt/float.rs
src/libcore/fmt/num.rs
src/libcore/ops.rs
src/libcore/ptr.rs
src/libcore/str.rs
src/liblibc/lib.rs
src/libnative/io/c_win32.rs
src/libnative/io/file_win32.rs
src/libnative/io/pipe_win32.rs
src/libnative/io/process.rs
src/libnative/io/util.rs
src/librustc/front/test.rs
src/librustdoc/flock.rs
src/librustdoc/html/render.rs
src/librustdoc/html/static/main.css
src/librustrt/unwind.rs
src/librustuv/lib.rs
src/libstd/io/fs.rs
src/libstd/io/tempfile.rs
src/libstd/lib.rs
src/libstd/macros.rs
src/libstd/sync/mod.rs
src/libunicode/normalize.rs
src/rt/rust_builtin.c
src/snapshots.txt
src/test/compile-fail/inaccessible-test-modules.rs [new file with mode: 0644]
src/test/run-make/test-harness/Makefile [new file with mode: 0644]
src/test/run-make/test-harness/test-ignore-cfg.rs [new file with mode: 0644]
src/test/run-pass/core-run-destroy.rs
src/test/run-pass/reexport-test-harness-main.rs [new file with mode: 0644]
src/test/run-pass/tcp-connect-timeouts.rs
src/test/run-pass/test-ignore-cfg.rs [deleted file]

index e08e28e0aece0eecae3c97da8ca41244d511418e..636d50276ff543baf97facc4896ec0100d6d6a1e 100755 (executable)
--- a/configure
+++ b/configure
@@ -557,13 +557,21 @@ fi
 
 if [ ! -z "$CFG_ENABLE_LOCAL_RUST" ]
 then
-    if [ ! -f ${CFG_LOCAL_RUST_ROOT}/bin/rustc${BIN_SUF} ]
+    system_rustc=$(which rustc)
+    if [ -f ${CFG_LOCAL_RUST_ROOT}/bin/rustc${BIN_SUF} ]
     then
-        err "no local rust to use"
+        : # everything already configured
+    elif [ -n "$system_rustc" ]
+    then
+        # we assume that rustc is in a /bin directory
+        CFG_LOCAL_RUST_ROOT=${system_rustc%/bin/rustc}
     else
-        LRV=`${CFG_LOCAL_RUST_ROOT}/bin/rustc${BIN_SUF} --version`
-        step_msg "using rustc at: ${CFG_LOCAL_RUST_ROOT} with version: $LRV"
+        err "no local rust to use"
     fi
+
+    LRV=`${CFG_LOCAL_RUST_ROOT}/bin/rustc${BIN_SUF} --version`
+    step_msg "using rustc at: ${CFG_LOCAL_RUST_ROOT} with version: $LRV"
+    putvar CFG_LOCAL_RUST_ROOT
 fi
 
 # Force freebsd to build with clang; gcc doesn't like us there
index a2b3f22c1554bb34d94552b0c04dfdaaf443e6af..a5091f41974b43949e1bb34164f04b0a83a3f4f3 100644 (file)
@@ -1432,6 +1432,86 @@ building our guessing game, but we need to know how to do one last thing first:
 get input from the keyboard. You can't have a guessing game without the ability
 to guess!
 
+# Strings
+
+Strings are an important concept for any programmer to master. Rust's string
+handling system is a bit different than in other languages, due to its systems
+focus. Any time you have a data structure of variable size, things can get
+tricky, and strings are a re-sizable data structure. That said, Rust's strings
+also work differently than in some other systems languages, such as C.
+
+Let's dig into the details. A **string** is a sequence of unicode scalar values
+encoded as a stream of UTF-8 bytes. All strings are guaranteed to be
+validly-encoded UTF-8 sequences. Additionally, strings are not null-terminated
+and can contain null bytes.
+
+Rust has two main types of strings: `&str` and `String`.
+
+The first kind is a `&str`. This is pronounced a 'string slice.' String literals
+are of the type `&str`:
+
+```{rust}
+let string = "Hello there.";
+```
+
+This string is statically allocated, meaning that it's saved inside our
+compiled program, and exists for the entire duration it runs. The `string`
+binding is a reference to this statically allocated string. String slices
+have a fixed size, and cannot be mutated.
+
+A `String`, on the other hand, is an in-memory string.  This string is
+growable, and is also guaranteed to be UTF-8.
+
+```{rust}
+let mut s = "Hello".to_string();
+println!("{}", s);
+
+s.push_str(", world.");
+println!("{}", s);
+```
+
+You can coerce a `String` into a `&str` with the `as_slice()` method:
+
+```{rust}
+fn takes_slice(slice: &str) {
+    println!("Got: {}", slice);
+}
+
+fn main() {
+    let s = "Hello".to_string();
+    takes_slice(s.as_slice());
+}
+```
+
+To compare a String to a constant string, prefer `as_slice()`...
+
+```{rust}
+fn compare(string: String) {
+    if string.as_slice() == "Hello" {
+        println!("yes");
+    }
+}
+```
+
+... over `to_string()`:
+
+```{rust}
+fn compare(string: String) {
+    if string == "Hello".to_string() {
+        println!("yes");
+    }
+}
+```
+
+Converting a `String` to a `&str` is cheap, but converting the `&str` to a
+`String` involves allocating memory. No reason to do that unless you have to!
+
+That's the basics of strings in Rust! They're probably a bit more complicated
+than you are used to, if you come from a scripting language, but when the
+low-level details matter, they really matter. Just remember that `String`s
+allocate memory and control their data, while `&str`s are a reference to
+another string, and you'll be all set.
+
 # Standard Input
 
 Getting input from the keyboard is pretty easy, but uses some things
@@ -3614,6 +3694,94 @@ guide](http://doc.rust-lang.org/guide-pointers.html#rc-and-arc).
 
 # Patterns
 
+# Method Syntax
+
+Functions are great, but if you want to call a bunch of them on some data, it
+can be awkward. Consider this code:
+
+```{rust,ignore}
+baz(bar(foo(x)));
+```
+
+We would read this left-to right, and so we see 'baz bar foo.' But this isn't the
+order that the functions would get called in, that's inside-out: 'foo bar baz.'
+Wouldn't it be nice if we could do this instead?
+
+```{rust,ignore}
+x.foo().bar().baz();
+```
+
+Luckily, as you may have guessed with the leading question, you can! Rust provides
+the ability to use this **method call syntax** via the `impl` keyword.
+
+Here's how it works:
+
+```
+struct Circle {
+    x: f64,
+    y: f64,
+    radius: f64,
+}
+
+impl Circle {
+    fn area(&self) -> f64 {
+        std::f64::consts::PI * (self.radius * self.radius)
+    }
+}
+
+fn main() {
+    let c = Circle { x: 0.0, y: 0.0, radius: 2.0 };
+    println!("{}", c.area());
+}
+```
+
+This will print `12.566371`.
+
+We've made a struct that represents a circle. We then write an `impl` block,
+and inside it, define a method, `area`. Methods take a  special first
+parameter, `&self`. There are three variants: `self`, `&self`, and `&mut self`.
+You can think of this first parameter as being the `x` in `x.foo()`. The three
+variants correspond to the three kinds of thing `x` could be: `self` if it's
+just a value on the stack, `&self` if it's a reference, and `&mut self` if it's
+a mutable reference. We should default to using `&self`, as it's the most
+common.
+
+Finally, as you may remember, the value of the area of a circle is `π*r²`.
+Because we took the `&self` parameter to `area`, we can use it just like any
+other parameter. Because we know it's a `Circle`, we can access the `radius`
+just like we would with any other struct. An import of π and some
+multiplications later, and we have our area.
+
+You can also define methods that do not take a `self` parameter. Here's a
+pattern that's very common in Rust code:
+
+```
+struct Circle {
+    x: f64,
+    y: f64,
+    radius: f64,
+}
+
+impl Circle {
+    fn new(x: f64, y: f64, radius: f64) -> Circle {
+        Circle {
+            x: x,
+            y: y,
+            radius: radius,
+        }
+    }
+}
+
+fn main() {
+    let c = Circle::new(0.0, 0.0, 2.0);
+}
+```
+
+This **static method** builds a new `Circle` for us. Note that static methods
+are called with the `Struct::method()` syntax, rather than the `ref.method()`
+syntax.
+
+
 # Closures
 
 So far, we've made lots of functions in Rust. But we've given them all names.
@@ -4318,6 +4486,152 @@ the same function, so our binary is a little bit larger.
 
 # Tasks
 
+Concurrency and parallelism are topics that are of increasing interest to a
+broad subsection of software developers. Modern computers are often multi-core,
+to the point that even embedded devices like cell phones have more than one
+processor. Rust's semantics lend themselves very nicely to solving a number of
+issues that programmers have with concurrency. Many concurrency errors that are
+runtime errors in other languages are compile-time errors in Rust.
+
+Rust's concurrency primitive is called a **task**. Tasks are lightweight, and
+do not share memory in an unsafe manner, preferring message passing to
+communicate.  It's worth noting that tasks are implemented as a library, and
+not part of the language.  This means that in the future, other concurrency
+libraries can be written for Rust to help in specific scenarios.  Here's an
+example of creating a task:
+
+```{rust}
+spawn(proc() {
+    println!("Hello from a task!");
+});
+```
+
+The `spawn` function takes a proc as an argument, and runs that proc in a new
+task. A proc takes ownership of its entire environment, and so any variables
+that you use inside the proc will not be usable afterward:
+
+```{rust,ignore}
+let mut x = vec![1i, 2i, 3i];
+
+spawn(proc() {
+    println!("The value of x[0] is: {}", x[0]);
+});
+
+println!("The value of x[0] is: {}", x[0]); // error: use of moved value: `x`
+```
+
+`x` is now owned by the proc, and so we can't use it anymore. Many other
+languages would let us do this, but it's not safe to do so. Rust's type system
+catches the error.
+
+If tasks were only able to capture these values, they wouldn't be very useful.
+Luckily, tasks can communicate with each other through **channel**s. Channels
+work like this:
+
+```{rust}
+let (tx, rx) = channel();
+
+spawn(proc() {
+    tx.send("Hello from a task!".to_string());
+});
+
+let message = rx.recv();
+println!("{}", message);
+```
+
+The `channel()` function returns two endpoints: a `Receiver<T>` and a
+`Sender<T>`. You can use the `.send()` method on the `Sender<T>` end, and
+receive the message on the `Receiver<T>` side with the `recv()` method.  This
+method blocks until it gets a message. There's a similar method, `.try_recv()`,
+which returns an `Option<T>` and does not block.
+
+If you want to send messages to the task as well, create two channels!
+
+```{rust}
+let (tx1, rx1) = channel();
+let (tx2, rx2) = channel();
+
+spawn(proc() {
+    tx1.send("Hello from a task!".to_string());
+    let message = rx2.recv();
+    println!("{}", message);
+});
+
+let message = rx1.recv();
+println!("{}", message);
+
+tx2.send("Goodbye from main!".to_string());
+```
+
+The proc has one sending end and one receiving end, and the main task has one
+of each as well. Now they can talk back and forth in whatever way they wish.
+
+Notice as well that because `Sender` and `Receiver` are generic, while you can
+pass any kind of information through the channel, the ends are strongly typed.
+If you try to pass a string, and then an integer, Rust will complain.
+
+## Futures
+
+With these basic primitives, many different concurrency patterns can be
+developed. Rust includes some of these types in its standard library. For
+example, if you wish to compute some value in the background, `Future` is
+a useful thing to use:
+
+```{rust}
+use std::sync::Future;
+
+let mut delayed_value = Future::spawn(proc() {
+    // just return anything for examples' sake
+
+    12345i
+});
+println!("value = {}", delayed_value.get());
+```
+
+Calling `Future::spawn` works just like `spawn()`: it takes a proc. In this
+case, though, you don't need to mess with the channel: just have the proc
+return the value.
+
+`Future::spawn` will return a value which we can bind with `let`. It needs
+to be mutable, because once the value is computed, it saves a copy of the
+value, and if it were immutable, it couldn't update itself.
+
+The proc will go on processing in the background, and when we need the final
+value, we can call `get()` on it. This will block until the result is done,
+but if it's finished computing in the background, we'll just get the value
+immediately.
+
+## Success and failure
+
+Tasks don't always succeed, they can also fail. A task that wishes to fail
+can call the `fail!` macro, passing a message:
+
+```{rust}
+spawn(proc() {
+    fail!("Nope.");
+});
+```
+
+If a task fails, it is not possible for it to recover. However, it can
+notify other tasks that it has failed. We can do this with `task::try`:
+
+```{rust}
+use std::task;
+use std::rand;
+
+let result = task::try(proc() {
+    if rand::random() {
+        println!("OK");
+    } else {
+        fail!("oops!");
+    }
+});
+```
+
+This task will randomly fail or succeed. `task::try` returns a `Result`
+type, so we can handle the response like any other computation that may
+fail.
+
 # Macros
 
 # Unsafe
index 0cde7a90e9c89a546ae38bbe12d0902be2e5bb44..84b5c5bb9985bf94fcb37f82403bf2d8c21e071a 100644 (file)
@@ -403,11 +403,11 @@ impl<'a, T> ExactSize<&'a mut T> for MutItems<'a, T> {}
 fn grow<T>(nelts: uint, loptr: &mut uint, elts: &mut Vec<Option<T>>) {
     assert_eq!(nelts, elts.len());
     let lo = *loptr;
-    let newlen = nelts * 2;
-    elts.reserve(newlen);
+    elts.reserve(nelts * 2);
+    let newlen = elts.capacity();
 
     /* fill with None */
-    for _ in range(elts.len(), elts.capacity()) {
+    for _ in range(elts.len(), newlen) {
         elts.push(None);
     }
 
@@ -750,6 +750,47 @@ fn test_with_capacity() {
         assert_eq!(d.len(), 1);
     }
 
+    #[test]
+    fn test_with_capacity_non_power_two() {
+        let mut d3 = RingBuf::with_capacity(3);
+        d3.push(1i);
+
+        // X = None, | = lo
+        // [|1, X, X]
+        assert_eq!(d3.pop_front(), Some(1));
+        // [X, |X, X]
+        assert_eq!(d3.front(), None);
+
+        // [X, |3, X]
+        d3.push(3);
+        // [X, |3, 6]
+        d3.push(6);
+        // [X, X, |6]
+        assert_eq!(d3.pop_front(), Some(3));
+
+        // Pushing the lo past half way point to trigger
+        // the 'B' scenario for growth
+        // [9, X, |6]
+        d3.push(9);
+        // [9, 12, |6]
+        d3.push(12);
+
+        d3.push(15);
+        // There used to be a bug here about how the
+        // RingBuf made growth assumptions about the
+        // underlying Vec which didn't hold and lead
+        // to corruption.
+        // (Vec grows to next power of two)
+        //good- [9, 12, 15, X, X, X, X, |6]
+        //bug-  [15, 12, X, X, X, |6, X, X]
+        assert_eq!(d3.pop_front(), Some(6));
+
+        // Which leads us to the following state which
+        // would be a failure case.
+        //bug-  [15, 12, X, X, X, X, |X, X]
+        assert_eq!(d3.front(), Some(&9));
+    }
+
     #[test]
     fn test_reserve_exact() {
         let mut d = RingBuf::new();
index 6618906cf69dee18e8c1b7cac37a68f56ed88d8a..39fe57038b0b2f4b98fa77e2f0a476b9b3408c1b 100644 (file)
@@ -1318,7 +1318,7 @@ pub fn as_mut_ptr(&mut self) -> *mut T {
     /// Retains only the elements specified by the predicate.
     ///
     /// In other words, remove all elements `e` such that `f(&e)` returns false.
-    /// This method operates in place and preserves the order the retained elements.
+    /// This method operates in place and preserves the order of the retained elements.
     ///
     /// # Example
     ///
index 71144095f478bb02a89cc3b3306abcea9dc2b89d..63ffc4a046f68af72e17e1afac4a559042c73d34 100644 (file)
@@ -19,9 +19,6 @@
 use option::{None, Option, Some};
 use iter::range_step;
 
-#[cfg(stage0)]
-use iter::Iterator; // NOTE(stage0): Remove after snapshot.
-
 // UTF-8 ranges and tags for encoding characters
 static TAG_CONT: u8    = 0b1000_0000u8;
 static TAG_TWO_B: u8   = 0b1100_0000u8;
index f5cfa2611d5e66ef260a07d4be8a7aca05714bc4..e764ae17500b6898792ba94c78316046b9768d34 100644 (file)
 use fmt;
 use intrinsics;
 
-#[cfg(stage0)]
-#[cold] #[inline(never)] // this is the slow path, always
-#[lang="fail_"]
-fn fail_(expr: &'static str, file: &'static str, line: uint) -> ! {
-    format_args!(|args| -> () {
-        begin_unwind(args, &(file, line));
-    }, "{}", expr);
-
-    unsafe { intrinsics::abort() }
-}
-
-#[cfg(stage0)]
-#[cold]
-#[lang="fail_bounds_check"]
-fn fail_bounds_check(file: &'static str, line: uint,
-                     index: uint, len: uint) -> ! {
-    format_args!(|args| -> () {
-        begin_unwind(args, &(file, line));
-    }, "index out of bounds: the len is {} but the index is {}", len, index);
-    unsafe { intrinsics::abort() }
-}
-
-#[cfg(not(stage0))]
 #[cold] #[inline(never)] // this is the slow path, always
 #[lang="fail_"]
 fn fail_(expr_file_line: &(&'static str, &'static str, uint)) -> ! {
@@ -68,7 +45,6 @@ fn fail_(expr_file_line: &(&'static str, &'static str, uint)) -> ! {
     unsafe { intrinsics::abort() }
 }
 
-#[cfg(not(stage0))]
 #[cold] #[inline(never)]
 #[lang="fail_bounds_check"]
 fn fail_bounds_check(file_line: &(&'static str, uint),
index 88702e59e30d165833278b3a5851930aa6f2e0ec..1bfa5168cf7960adf8d63eb15cc975509129ec1c 100644 (file)
 use slice;
 use str::StrSlice;
 
-#[cfg(stage0)]
-use iter::Iterator;         // NOTE(stage0): Remove after snapshot.
-#[cfg(stage0)]
-use option::{Some, None};   // NOTE(stage0): Remove after snapshot.
-
 /// A flag that specifies whether to use exponential (scientific) notation.
 pub enum ExponentFormat {
     /// Do not use exponential notation.
index 99920dc7881901cc2a0eb7324b544337ef235f98..bba3e4cb9afccdef116e3419940e091cea6d4c34 100644 (file)
 use num::{Int, cast, zero};
 use slice::{ImmutableVector, MutableVector};
 
-#[cfg(stage0)]
-use iter::Iterator;         // NOTE(stage0): Remove after snapshot.
-#[cfg(stage0)]
-use option::{Some, None};   // NOTE(stage0): Remove after snapshot.
-
 /// A type that represents a specific radix
 #[doc(hidden)]
 trait GenericRadix {
index 839243970ac673ed40080d84c55212b76aa3b50d..23577dd29e0af0c75ee24a463e9ae5ba16e458e2 100644 (file)
@@ -771,7 +771,6 @@ pub trait FnOnce<Args,Result> {
 
 macro_rules! def_fn_mut(
     ($($args:ident)*) => (
-        #[cfg(not(stage0))]
         impl<Result$(,$args)*>
         FnMut<($($args,)*),Result>
         for extern "Rust" fn($($args: $args,)*) -> Result {
index 4921802ba732eea4022f0ff63e42cbfd7d4f6800..eb9bede85d8b25cc95d8b1534c64aab526c7b2fa 100644 (file)
@@ -95,9 +95,6 @@
 
 use cmp::{PartialEq, Eq, PartialOrd, Equiv, Ordering, Less, Equal, Greater};
 
-#[cfg(stage0)]
-use iter::Iterator; // NOTE(stage0): Remove after snapshot.
-
 pub use intrinsics::copy_memory;
 pub use intrinsics::copy_nonoverlapping_memory;
 pub use intrinsics::set_memory;
index 5eb463687904c41b34119f3b0b85ca5daeba3324..c1166a7621e193e6515c1745248d0f67c5125737 100644 (file)
@@ -1030,9 +1030,6 @@ pub mod traits {
     use option::{Option, Some};
     use str::{Str, StrSlice, eq_slice};
 
-    #[cfg(stage0)]
-    use option::None;   // NOTE(stage0): Remove after snapshot.
-
     impl<'a> Ord for &'a str {
         #[inline]
         fn cmp(&self, other: & &'a str) -> Ordering {
index 1bc64ffcc92ae8f05a26f3e72ae30607d0b56b38..e368a5644159c7126b27386e07385a75c4ae28c0 100644 (file)
@@ -1142,18 +1142,16 @@ pub mod extra {
     pub mod os {
         pub mod common {
             pub mod posix01 {
-                use types::os::arch::c95::{c_short, time_t, suseconds_t,
-                                                 c_long};
+                use types::os::arch::c95::{c_short, time_t, c_long};
                 use types::os::arch::extra::{int64, time64_t};
                 use types::os::arch::posix88::{dev_t, ino_t};
-                use types::os::arch::posix88::mode_t;
 
                 // pub Note: this is the struct called stat64 in win32. Not stat,
                 // nor stati64.
                 pub struct stat {
                     pub st_dev: dev_t,
                     pub st_ino: ino_t,
-                    pub st_mode: mode_t,
+                    pub st_mode: u16,
                     pub st_nlink: c_short,
                     pub st_uid: c_short,
                     pub st_gid: c_short,
@@ -1171,8 +1169,8 @@ pub struct utimbuf {
                 }
 
                 pub struct timeval {
-                    pub tv_sec: time_t,
-                    pub tv_usec: suseconds_t,
+                    pub tv_sec: c_long,
+                    pub tv_usec: c_long,
                 }
 
                 pub struct timespec {
@@ -1186,7 +1184,7 @@ pub enum timezone {}
             pub mod bsd44 {
                 use types::os::arch::c95::{c_char, c_int, c_uint, size_t};
 
-                pub type SOCKET = c_uint;
+                pub type SOCKET = uint;
                 pub type socklen_t = c_int;
                 pub type sa_family_t = u16;
                 pub type in_port_t = u16;
@@ -1197,6 +1195,7 @@ pub struct sockaddr {
                 }
                 pub struct sockaddr_storage {
                     pub ss_family: sa_family_t,
+                    pub __ss_pad1: [u8, ..6],
                     pub __ss_align: i64,
                     pub __ss_pad2: [u8, ..112],
                 }
@@ -1293,12 +1292,9 @@ pub mod c99 {
             pub mod posix88 {
                 pub type off_t = i32;
                 pub type dev_t = u32;
-                pub type ino_t = i16;
+                pub type ino_t = u16;
 
-                #[cfg(target_arch = "x86")]
-                pub type pid_t = i32;
-                #[cfg(target_arch = "x86_64")]
-                pub type pid_t = i64;
+                pub type pid_t = u32;
 
                 pub type useconds_t = u32;
                 pub type mode_t = u16;
@@ -1415,7 +1411,7 @@ pub struct SYSTEM_INFO {
                     pub dwPageSize: DWORD,
                     pub lpMinimumApplicationAddress: LPVOID,
                     pub lpMaximumApplicationAddress: LPVOID,
-                    pub dwActiveProcessorMask: DWORD,
+                    pub dwActiveProcessorMask: uint,
                     pub dwNumberOfProcessors: DWORD,
                     pub dwProcessorType: DWORD,
                     pub dwAllocationGranularity: DWORD,
@@ -1950,7 +1946,7 @@ pub mod bsd44 {
         }
         pub mod extra {
             use types::os::arch::c95::c_int;
-            use types::os::arch::extra::{WORD, DWORD, BOOL};
+            use types::os::arch::extra::{WORD, DWORD, BOOL, HANDLE};
 
             pub static TRUE : BOOL = 1;
             pub static FALSE : BOOL = 0;
@@ -1979,7 +1975,7 @@ pub mod extra {
             pub static ERROR_IO_PENDING: c_int = 997;
             pub static ERROR_FILE_INVALID : c_int = 1006;
             pub static ERROR_NOT_FOUND: c_int = 1168;
-            pub static INVALID_HANDLE_VALUE : c_int = -1;
+            pub static INVALID_HANDLE_VALUE: HANDLE = -1 as HANDLE;
 
             pub static DELETE : DWORD = 0x00010000;
             pub static READ_CONTROL : DWORD = 0x00020000;
index 482155c339c9b5e0b7f6b0973d725b69287a4c87..80c9e91b48f7a5e24e3ba6db156d142c94090133 100644 (file)
@@ -28,6 +28,7 @@
 pub static ENABLE_QUICK_EDIT_MODE: libc::DWORD = 0x40;
 
 #[repr(C)]
+#[cfg(target_arch = "x86")]
 pub struct WSADATA {
     pub wVersion: libc::WORD,
     pub wHighVersion: libc::WORD,
@@ -37,6 +38,17 @@ pub struct WSADATA {
     pub iMaxUdpDg: u16,
     pub lpVendorInfo: *mut u8,
 }
+#[repr(C)]
+#[cfg(target_arch = "x86_64")]
+pub struct WSADATA {
+    pub wVersion: libc::WORD,
+    pub wHighVersion: libc::WORD,
+    pub iMaxSockets: u16,
+    pub iMaxUdpDg: u16,
+    pub lpVendorInfo: *mut u8,
+    pub szDescription: [u8, ..WSADESCRIPTION_LEN + 1],
+    pub szSystemStatus: [u8, ..WSASYS_STATUS_LEN + 1],
+}
 
 pub type LPWSADATA = *mut WSADATA;
 
index a024d498ef341f6fd313656eba61fed7c5840034..fe29c0245297cd34709e4d189ac1aa02d49710cc 100644 (file)
@@ -320,7 +320,7 @@ pub fn open(path: &CString, fm: rtio::FileMode, fa: rtio::FileAccess)
                           dwFlagsAndAttributes,
                           ptr::mut_null())
     };
-    if handle == libc::INVALID_HANDLE_VALUE as libc::HANDLE {
+    if handle == libc::INVALID_HANDLE_VALUE {
         Err(super::last_error())
     } else {
         let fd = unsafe {
@@ -368,7 +368,7 @@ fn prune(root: &CString, dirs: Vec<Path>) -> Vec<CString> {
         let wfd_ptr = malloc_raw(rust_list_dir_wfd_size() as uint);
         let find_handle = libc::FindFirstFileW(path.as_ptr(),
                                                wfd_ptr as libc::HANDLE);
-        if find_handle as libc::c_int != libc::INVALID_HANDLE_VALUE {
+        if find_handle != libc::INVALID_HANDLE_VALUE {
             let mut paths = vec!();
             let mut more_files = 1 as libc::c_int;
             while more_files != 0 {
@@ -440,7 +440,7 @@ pub fn readlink(p: &CString) -> IoResult<CString> {
                           libc::FILE_ATTRIBUTE_NORMAL,
                           ptr::mut_null())
     };
-    if handle as int == libc::INVALID_HANDLE_VALUE as int {
+    if handle == libc::INVALID_HANDLE_VALUE {
         return Err(super::last_error())
     }
     // Specify (sz - 1) because the documentation states that it's the size
index 87129bba845bf513e88aa0470a8991bbdc3679b8..717915e5d23bde51c181ace0c4768f436dec4738 100644 (file)
@@ -223,7 +223,7 @@ fn try_connect(p: *const u16) -> Option<libc::HANDLE> {
                 libc::FILE_FLAG_OVERLAPPED,
                 ptr::mut_null())
         };
-        if result != libc::INVALID_HANDLE_VALUE as libc::HANDLE {
+        if result != libc::INVALID_HANDLE_VALUE {
             return Some(result)
         }
 
@@ -238,7 +238,7 @@ fn try_connect(p: *const u16) -> Option<libc::HANDLE> {
                     libc::FILE_FLAG_OVERLAPPED,
                     ptr::mut_null())
             };
-            if result != libc::INVALID_HANDLE_VALUE as libc::HANDLE {
+            if result != libc::INVALID_HANDLE_VALUE {
                 return Some(result)
             }
         }
@@ -253,7 +253,7 @@ fn try_connect(p: *const u16) -> Option<libc::HANDLE> {
                     libc::FILE_FLAG_OVERLAPPED,
                     ptr::mut_null())
             };
-            if result != libc::INVALID_HANDLE_VALUE as libc::HANDLE {
+            if result != libc::INVALID_HANDLE_VALUE {
                 return Some(result)
             }
         }
@@ -565,7 +565,7 @@ pub fn bind(addr: &CString) -> IoResult<UnixListener> {
         // and such.
         let addr_v = try!(to_utf16(addr));
         let ret = unsafe { pipe(addr_v.as_ptr(), true) };
-        if ret == libc::INVALID_HANDLE_VALUE as libc::HANDLE {
+        if ret == libc::INVALID_HANDLE_VALUE {
             Err(super::last_error())
         } else {
             Ok(UnixListener { handle: ret, name: addr.clone() })
@@ -680,7 +680,7 @@ pub fn native_accept(&mut self) -> IoResult<UnixStream> {
         // create a second server pipe. If this fails, we disconnect the
         // connected client and return an error (see comments above).
         let new_handle = unsafe { pipe(name.as_ptr(), false) };
-        if new_handle == libc::INVALID_HANDLE_VALUE as libc::HANDLE {
+        if new_handle == libc::INVALID_HANDLE_VALUE {
             let ret = Err(super::last_error());
             // If our disconnection fails, then there's not really a whole lot
             // that we can do, so fail the task.
index c89a40d65135144f880d0904619392942793a434..d83e36a5e2a9c6e0835e8683ab642f10acedc894 100644 (file)
@@ -359,13 +359,13 @@ fn spawn_process_os(cfg: ProcessConfig,
                                               libc::OPEN_EXISTING,
                                               0,
                                               ptr::mut_null());
-                    if *slot == INVALID_HANDLE_VALUE as libc::HANDLE {
+                    if *slot == INVALID_HANDLE_VALUE {
                         return Err(super::last_error())
                     }
                 }
                 Some(ref fd) => {
                     let orig = get_osfhandle(fd.fd()) as HANDLE;
-                    if orig == INVALID_HANDLE_VALUE as HANDLE {
+                    if orig == INVALID_HANDLE_VALUE {
                         return Err(super::last_error())
                     }
                     if DuplicateHandle(cur_proc, orig, cur_proc, slot,
@@ -450,9 +450,9 @@ fn zeroed_startupinfo() -> libc::types::os::arch::extra::STARTUPINFO {
         wShowWindow: 0,
         cbReserved2: 0,
         lpReserved2: ptr::mut_null(),
-        hStdInput: libc::INVALID_HANDLE_VALUE as libc::HANDLE,
-        hStdOutput: libc::INVALID_HANDLE_VALUE as libc::HANDLE,
-        hStdError: libc::INVALID_HANDLE_VALUE as libc::HANDLE,
+        hStdInput: libc::INVALID_HANDLE_VALUE,
+        hStdOutput: libc::INVALID_HANDLE_VALUE,
+        hStdError: libc::INVALID_HANDLE_VALUE,
     }
 }
 
index 06046cc74cfd85d7828d92b2f0688756764bf57a..97518bbf1999587fa027df320b3f454b30e34a12 100644 (file)
@@ -52,6 +52,14 @@ pub fn eof() -> IoError {
     }
 }
 
+#[cfg(windows)]
+pub fn ms_to_timeval(ms: u64) -> libc::timeval {
+    libc::timeval {
+        tv_sec: (ms / 1000) as libc::c_long,
+        tv_usec: ((ms % 1000) * 1000) as libc::c_long,
+    }
+}
+#[cfg(not(windows))]
 pub fn ms_to_timeval(ms: u64) -> libc::timeval {
     libc::timeval {
         tv_sec: (ms / 1000) as libc::time_t,
index 0fce75c8369bc24c4f6b1791d0bba9bc2e61c21a..14cda7d62c35def4dc62053e12af7a95184c1f61 100644 (file)
@@ -51,6 +51,7 @@ struct TestCtxt<'a> {
     ext_cx: ExtCtxt<'a>,
     testfns: Vec<Test>,
     reexport_mod_ident: ast::Ident,
+    reexport_test_harness_main: Option<InternedString>,
     is_test_crate: bool,
     config: ast::CrateConfig,
 }
@@ -64,8 +65,16 @@ pub fn modify_for_testing(sess: &Session,
     // command line options.
     let should_test = attr::contains_name(krate.config.as_slice(), "test");
 
+    // Check for #[reexport_test_harness_main = "some_name"] which
+    // creates a `use some_name = __test::main;`. This needs to be
+    // unconditional, so that the attribute is still marked as used in
+    // non-test builds.
+    let reexport_test_harness_main =
+        attr::first_attr_value_str_by_name(krate.attrs.as_slice(),
+                                           "reexport_test_harness_main");
+
     if should_test {
-        generate_test_harness(sess, krate)
+        generate_test_harness(sess, reexport_test_harness_main, krate)
     } else {
         strip_test_functions(krate)
     }
@@ -79,14 +88,17 @@ struct TestHarnessGenerator<'a> {
 
 impl<'a> fold::Folder for TestHarnessGenerator<'a> {
     fn fold_crate(&mut self, c: ast::Crate) -> ast::Crate {
-        let folded = fold::noop_fold_crate(c, self);
+        let mut folded = fold::noop_fold_crate(c, self);
 
         // Add a special __test module to the crate that will contain code
         // generated for the test harness
-        ast::Crate {
-            module: add_test_module(&self.cx, &folded.module),
-            .. folded
+        let (mod_, reexport) = mk_test_module(&self.cx, &self.cx.reexport_test_harness_main);
+        folded.module.items.push(mod_);
+        match reexport {
+            Some(re) => folded.module.view_items.push(re),
+            None => {}
         }
+        folded
     }
 
     fn fold_item(&mut self, i: Gc<ast::Item>) -> SmallVector<Gc<ast::Item>> {
@@ -196,7 +208,9 @@ fn mk_reexport_mod(cx: &mut TestCtxt, tests: Vec<ast::Ident>,
     }
 }
 
-fn generate_test_harness(sess: &Session, krate: ast::Crate) -> ast::Crate {
+fn generate_test_harness(sess: &Session,
+                         reexport_test_harness_main: Option<InternedString>,
+                         krate: ast::Crate) -> ast::Crate {
     let mut cx: TestCtxt = TestCtxt {
         sess: sess,
         ext_cx: ExtCtxt::new(&sess.parse_sess, sess.opts.cfg.clone(),
@@ -206,7 +220,8 @@ fn generate_test_harness(sess: &Session, krate: ast::Crate) -> ast::Crate {
                              }),
         path: Vec::new(),
         testfns: Vec::new(),
-        reexport_mod_ident: token::str_to_ident("__test_reexports"),
+        reexport_mod_ident: token::gensym_ident("__test_reexports"),
+        reexport_test_harness_main: reexport_test_harness_main,
         is_test_crate: is_test_crate(&krate),
         config: krate.config.clone(),
     };
@@ -314,14 +329,6 @@ fn should_fail(i: Gc<ast::Item>) -> bool {
     attr::contains_name(i.attrs.as_slice(), "should_fail")
 }
 
-fn add_test_module(cx: &TestCtxt, m: &ast::Mod) -> ast::Mod {
-    let testmod = mk_test_module(cx);
-    ast::Mod {
-        items: m.items.clone().append_one(testmod),
-        ..(*m).clone()
-    }
-}
-
 /*
 
 We're going to be building a module that looks more or less like:
@@ -359,7 +366,8 @@ fn mk_std(cx: &TestCtxt) -> ast::ViewItem {
     }
 }
 
-fn mk_test_module(cx: &TestCtxt) -> Gc<ast::Item> {
+fn mk_test_module(cx: &TestCtxt, reexport_test_harness_main: &Option<InternedString>)
+                  -> (Gc<ast::Item>, Option<ast::ViewItem>) {
     // Link to test crate
     let view_items = vec!(mk_std(cx));
 
@@ -383,18 +391,35 @@ pub fn main() {
     };
     let item_ = ast::ItemMod(testmod);
 
+    let mod_ident = token::gensym_ident("__test");
     let item = ast::Item {
-        ident: token::str_to_ident("__test"),
+        ident: mod_ident,
         attrs: Vec::new(),
         id: ast::DUMMY_NODE_ID,
         node: item_,
         vis: ast::Public,
         span: DUMMY_SP,
-     };
+    };
+    let reexport = reexport_test_harness_main.as_ref().map(|s| {
+        // building `use <ident> = __test::main`
+        let reexport_ident = token::str_to_ident(s.get());
+
+        let use_path =
+            nospan(ast::ViewPathSimple(reexport_ident,
+                                       path_node(vec![mod_ident, token::str_to_ident("main")]),
+                                       ast::DUMMY_NODE_ID));
+
+        ast::ViewItem {
+            node: ast::ViewItemUse(box(GC) use_path),
+            attrs: vec![],
+            vis: ast::Inherited,
+            span: DUMMY_SP
+        }
+    });
 
     debug!("Synthetic test module:\n{}\n", pprust::item_to_string(&item));
 
-    box(GC) item
+    (box(GC) item, reexport)
 }
 
 fn nospan<T>(t: T) -> codemap::Spanned<T> {
@@ -417,11 +442,27 @@ fn mk_tests(cx: &TestCtxt) -> Gc<ast::Item> {
     // The vector of test_descs for this crate
     let test_descs = mk_test_descs(cx);
 
-    (quote_item!(&cx.ext_cx,
-        pub static TESTS : &'static [self::test::TestDescAndFn] =
-            $test_descs
-        ;
-    )).unwrap()
+    // FIXME #15962: should be using quote_item, but that stringifies
+    // __test_reexports, causing it to be reinterned, losing the
+    // gensym information.
+    let sp = DUMMY_SP;
+    let ecx = &cx.ext_cx;
+    let struct_type = ecx.ty_path(ecx.path(sp, vec![ecx.ident_of("self"),
+                                                    ecx.ident_of("test"),
+                                                    ecx.ident_of("TestDescAndFn")]),
+                                  None);
+    let static_lt = ecx.lifetime(sp, token::special_idents::static_lifetime.name);
+    // &'static [self::test::TestDescAndFn]
+    let static_type = ecx.ty_rptr(sp,
+                                  ecx.ty(sp, ast::TyVec(struct_type)),
+                                  Some(static_lt),
+                                  ast::MutImmutable);
+    // static TESTS: $static_type = &[...];
+    ecx.item_static(sp,
+                    ecx.ident_of("TESTS"),
+                    static_type,
+                    ast::MutImmutable,
+                    test_descs)
 }
 
 fn is_test_crate(krate: &ast::Crate) -> bool {
@@ -448,59 +489,58 @@ fn mk_test_descs(cx: &TestCtxt) -> Gc<ast::Expr> {
 }
 
 fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> Gc<ast::Expr> {
+    // FIXME #15962: should be using quote_expr, but that stringifies
+    // __test_reexports, causing it to be reinterned, losing the
+    // gensym information.
+
     let span = test.span;
     let path = test.path.clone();
+    let ecx = &cx.ext_cx;
+    let self_id = ecx.ident_of("self");
+    let test_id = ecx.ident_of("test");
+
+    // creates self::test::$name
+    let test_path = |name| {
+        ecx.path(span, vec![self_id, test_id, ecx.ident_of(name)])
+    };
+    // creates $name: $expr
+    let field = |name, expr| ecx.field_imm(span, ecx.ident_of(name), expr);
 
     debug!("encoding {}", ast_util::path_name_i(path.as_slice()));
 
-    let name_lit: ast::Lit =
-        nospan(ast::LitStr(token::intern_and_get_ident(
-                    ast_util::path_name_i(path.as_slice()).as_slice()),
-                    ast::CookedStr));
+    // path to the #[test] function: "foo::bar::baz"
+    let path_string = ast_util::path_name_i(path.as_slice());
+    let name_expr = ecx.expr_str(span, token::intern_and_get_ident(path_string.as_slice()));
 
-    let name_expr = box(GC) ast::Expr {
-          id: ast::DUMMY_NODE_ID,
-          node: ast::ExprLit(box(GC) name_lit),
-          span: span
-    };
+    // self::test::StaticTestName($name_expr)
+    let name_expr = ecx.expr_call(span,
+                                  ecx.expr_path(test_path("StaticTestName")),
+                                  vec![name_expr]);
 
-    let mut visible_path = vec![cx.reexport_mod_ident.clone()];
-    visible_path.extend(path.move_iter());
-    let fn_path = cx.ext_cx.path_global(DUMMY_SP, visible_path);
+    let ignore_expr = ecx.expr_bool(span, test.ignore);
+    let fail_expr = ecx.expr_bool(span, test.should_fail);
 
-    let fn_expr = box(GC) ast::Expr {
-        id: ast::DUMMY_NODE_ID,
-        node: ast::ExprPath(fn_path),
-        span: span,
-    };
+    // self::test::TestDesc { ... }
+    let desc_expr = ecx.expr_struct(
+        span,
+        test_path("TestDesc"),
+        vec![field("name", name_expr),
+             field("ignore", ignore_expr),
+             field("should_fail", fail_expr)]);
 
-    let t_expr = if test.bench {
-        quote_expr!(&cx.ext_cx, self::test::StaticBenchFn($fn_expr) )
-    } else {
-        quote_expr!(&cx.ext_cx, self::test::StaticTestFn($fn_expr) )
-    };
 
-    let ignore_expr = if test.ignore {
-        quote_expr!(&cx.ext_cx, true )
-    } else {
-        quote_expr!(&cx.ext_cx, false )
-    };
+    let mut visible_path = vec![cx.reexport_mod_ident.clone()];
+    visible_path.extend(path.move_iter());
 
-    let fail_expr = if test.should_fail {
-        quote_expr!(&cx.ext_cx, true )
-    } else {
-        quote_expr!(&cx.ext_cx, false )
-    };
+    let fn_expr = ecx.expr_path(ecx.path_global(span, visible_path));
 
-    let e = quote_expr!(&cx.ext_cx,
-        self::test::TestDescAndFn {
-            desc: self::test::TestDesc {
-                name: self::test::StaticTestName($name_expr),
-                ignore: $ignore_expr,
-                should_fail: $fail_expr
-            },
-            testfn: $t_expr,
-        }
-    );
-    e
+    let variant_name = if test.bench { "StaticBenchFn" } else { "StaticTestFn" };
+    // self::test::$variant_name($fn_expr)
+    let testfn_expr = ecx.expr_call(span, ecx.expr_path(test_path(variant_name)), vec![fn_expr]);
+
+    // self::test::TestDescAndFn { ... }
+    ecx.expr_struct(span,
+                    test_path("TestDescAndFn"),
+                    vec![field("desc", desc_expr),
+                         field("testfn", testfn_expr)])
 }
index f22950e7a299e235c8922a1d7edeec6d513c514e..cb8be9c899757d4c24a97f6cc3393100c34cba5a 100644 (file)
@@ -197,7 +197,7 @@ pub fn new(p: &Path) -> Lock {
                                   libc::FILE_ATTRIBUTE_NORMAL,
                                   ptr::mut_null())
             };
-            if handle as uint == libc::INVALID_HANDLE_VALUE as uint {
+            if handle == libc::INVALID_HANDLE_VALUE {
                 fail!("create file error: {}", os::last_os_error());
             }
             let mut overlapped: libc::OVERLAPPED = unsafe { mem::zeroed() };
index 76e18d5258c49902377be20e4b2128d229c5390c..eea594550398b36e4a7a0b46fb969181c3a1df53 100644 (file)
@@ -1294,7 +1294,7 @@ fn href(&self) -> Option<String> {
 impl<'a> fmt::Show for Item<'a> {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         // Write the breadcrumb trail header for the top
-        try!(write!(fmt, "\n<h1 class='fqn'>"));
+        try!(write!(fmt, "\n<h1 class='fqn'><div class='in-band'>"));
         match self.item.inner {
             clean::ModuleItem(ref m) => if m.is_crate {
                     try!(write!(fmt, "Crate "));
@@ -1316,7 +1316,7 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
             let cur = self.cx.current.as_slice();
             let amt = if self.ismodule() { cur.len() - 1 } else { cur.len() };
             for (i, component) in cur.iter().enumerate().take(amt) {
-                try!(write!(fmt, "<a href='{}index.html'>{}</a>::",
+                try!(write!(fmt, "<a href='{}index.html'>{}</a>&#8203;::",
                             "../".repeat(cur.len() - i - 1),
                             component.as_slice()));
             }
@@ -1325,10 +1325,10 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
                     shortty(self.item), self.item.name.get_ref().as_slice()));
 
         // Write stability level
-        try!(write!(fmt, "{}", Stability(&self.item.stability)));
+        try!(write!(fmt, "&#8203;{}", Stability(&self.item.stability)));
 
         // Links to out-of-band information, i.e. src and stability dashboard
-        try!(write!(fmt, "<span class='out-of-band'>"));
+        try!(write!(fmt, "</div><div class='out-of-band'>"));
 
         // Write stability dashboard link
         match self.item.inner {
@@ -1340,8 +1340,8 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
 
         try!(write!(fmt,
         r##"<span id='render-detail'>
-            <a id="collapse-all" href="#">[collapse all]</a>
-            <a id="expand-all" href="#">[expand all]</a>
+            <a id="collapse-all" href="#">[-]
+            </a>&nbsp;<a id="expand-all" href="#">[+]</a>
         </span>"##));
 
         // Write `src` tag
@@ -1360,7 +1360,7 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
             }
         }
 
-        try!(write!(fmt, "</span>"));
+        try!(write!(fmt, "</div>"));
 
         try!(write!(fmt, "</h1>\n"));
 
index f579123fc462b8e913bdb6e5edbe2e9a34b08a02..e41566e07fd811b9deba0de81fc934d49e1e7347 100644 (file)
@@ -252,8 +252,19 @@ nav.sub {
 .docblock h3, .docblock h4, .docblock h5 { font-size: 1em; }
 
 .content .out-of-band {
-    float: right;
     font-size: 23px;
+    width: 40%;
+    margin: 0px;
+    padding: 0px;
+    text-align: right;
+    display: inline-block;
+}
+
+.content .in-band {
+    width: 60%;
+    margin: 0px;
+    padding: 0px;
+    display: inline-block;
 }
 
 .content table {
@@ -282,8 +293,8 @@ nav.sub {
 }
 .content .multi-column li { width: 100%; display: inline-block; }
 
-.content .method { 
-    font-size: 1em; 
+.content .method {
+    font-size: 1em;
     position: relative;
 }
 .content .methods .docblock { margin-left: 40px; }
@@ -455,8 +466,8 @@ pre.rust { position: relative; }
     top: 0;
     right: 10px;
     font-size: 150%;
-    -webkit-transform: scaleX(-1); 
-    transform: scaleX(-1); 
+    -webkit-transform: scaleX(-1);
+    transform: scaleX(-1);
 }
 
 .methods .section-header {
@@ -470,22 +481,6 @@ pre.rust { position: relative; }
     content: '\2002\00a7\2002';
 }
 
-/* Media Queries */
-
-@media (max-width: 700px) {
-    .sidebar {
-        display: none;
-    }
-
-    .content {
-        margin-left: 0px;
-    }
-
-    nav.sub {
-        margin: 0 auto;
-    }
-}
-
 .collapse-toggle {
     font-weight: 100;
     position: absolute;
@@ -518,3 +513,59 @@ pre.rust { position: relative; }
     color: #999;
     font-style: italic;
 }
+
+
+
+/* Media Queries */
+
+@media (max-width: 700px) {
+    body {
+        padding-top: 0px;
+    }
+
+    .sidebar {
+        height: 40px;
+        min-height: 40px;
+        width: 100%;
+        margin: 0px;
+        padding: 0px;
+        position: static;
+    }
+
+    .sidebar .location {
+        float: left;
+        margin: 0px;
+        padding: 5px;
+        width: 60%;
+        background: inherit;
+        text-align: left;
+        font-size: 24px;
+    }
+
+    .sidebar img {
+        width: 35px;
+        margin-top: 5px;
+        margin-bottom: 0px;
+        float: left;
+    }
+
+    nav.sub {
+        margin: 0 auto;
+    }
+
+    .sidebar .block {
+        display: none;
+    }
+
+    .content {
+        margin-left: 0px;
+    }
+
+    .toggle-wrapper > .collapse-toggle {
+        left: 0px;
+    }
+
+    .toggle-wrapper {
+        height: 1.5em;
+    }
+}
index 117f680011e5bac64ace4dbeb5391e89eb4d9d5f..79f83df5be8097257760f145eef89a2a0538cf3f 100644 (file)
@@ -523,22 +523,6 @@ fn write(&mut self, buf: &[u8]) -> fmt::Result {
 }
 
 /// This is the entry point of unwinding for fail!() and assert!().
-#[cfg(stage0)]
-#[inline(never)] #[cold] // avoid code bloat at the call sites as much as possible
-pub fn begin_unwind<M: Any + Send>(msg: M, file: &'static str, line: uint) -> ! {
-    // Note that this should be the only allocation performed in this code path.
-    // Currently this means that fail!() on OOM will invoke this code path,
-    // but then again we're not really ready for failing on OOM anyway. If
-    // we do start doing this, then we should propagate this allocation to
-    // be performed in the parent of this task instead of the task that's
-    // failing.
-
-    // see below for why we do the `Any` coercion here.
-    begin_unwind_inner(box msg, &(file, line))
-}
-
-/// This is the entry point of unwinding for fail!() and assert!().
-#[cfg(not(stage0))]
 #[inline(never)] #[cold] // avoid code bloat at the call sites as much as possible
 pub fn begin_unwind<M: Any + Send>(msg: M, file_line: &(&'static str, uint)) -> ! {
     // Note that this should be the only allocation performed in this code path.
index 24b8c29785804920ccd43c49cfd854bf220f0afb..dd80ab3ee78a15f23545e908c094b2c5224ba05e 100644 (file)
@@ -48,6 +48,8 @@
 #![deny(unused_result, unused_must_use)]
 #![allow(visible_private_types)]
 
+#![reexport_test_harness_main = "test_main"]
+
 #[cfg(test)] extern crate green;
 #[cfg(test)] extern crate debug;
 #[cfg(test)] extern crate realrustuv = "rustuv";
 pub use self::tty::TtyWatcher;
 
 // Run tests with libgreen instead of libnative.
-//
-// FIXME: This egregiously hacks around starting the test runner in a different
-//        threading mode than the default by reaching into the auto-generated
-//        '__test' module.
 #[cfg(test)] #[start]
 fn start(argc: int, argv: *const *const u8) -> int {
-    green::start(argc, argv, event_loop, __test::main)
+    green::start(argc, argv, event_loop, test_main)
 }
 
 mod macros;
index 6a4172d5c3526fd195ecafb4292bda2d15bdc39d..7335511ed857e42781339027bf7a530b7ddd06bd 100644 (file)
@@ -1592,10 +1592,11 @@ pub fn tmpdir() -> TempDir {
         let tmpdir = tmpdir();
         let path = tmpdir.join("a");
         check!(File::create(&path));
-
-        check!(change_file_times(&path, 1000, 2000));
-        assert_eq!(check!(path.stat()).accessed, 1000);
-        assert_eq!(check!(path.stat()).modified, 2000);
+        // These numbers have to be bigger than the time in the day to account for timezones
+        // Windows in particular will fail in certain timezones with small enough values
+        check!(change_file_times(&path, 100000, 200000));
+        assert_eq!(check!(path.stat()).accessed, 100000);
+        assert_eq!(check!(path.stat()).modified, 200000);
     })
 
     iotest!(fn utime_noexist() {
index 1d53ed814377e605b197e30966ef68ed088a2688..2faa23a6aa0a5feb008bd9d79a312a0d26d83f98 100644 (file)
@@ -21,9 +21,6 @@
 use result::{Ok, Err};
 use sync::atomic;
 
-#[cfg(stage0)]
-use iter::Iterator; // NOTE(stage0): Remove after snapshot.
-
 /// A wrapper for a path to temporary directory implementing automatic
 /// scope-based deletion.
 pub struct TempDir {
index 125c3fdf5d90c02b0f2dfc6614d0bb33c5038c7f..20fc7efeb574f15d4a7a0884286e082dc1504d8e 100644 (file)
 #![allow(deprecated)]
 #![deny(missing_doc)]
 
+#![reexport_test_harness_main = "test_main"]
+
 // When testing libstd, bring in libuv as the I/O backend so tests can print
 // things and all of the std::io tests have an I/O interface to run on top
 // of
 pub use core_sync::comm;
 
 // Run tests with libgreen instead of libnative.
-//
-// FIXME: This egregiously hacks around starting the test runner in a different
-//        threading mode than the default by reaching into the auto-generated
-//        '__test' module.
 #[cfg(test)] #[start]
 fn start(argc: int, argv: *const *const u8) -> int {
-    green::start(argc, argv, rustuv::event_loop, __test::main)
+    green::start(argc, argv, rustuv::event_loop, test_main)
 }
 
 /* Exported macros */
index 3184c151bd2c74e9c138344a5da481862f133d6a..f2d7fb0cea68acb5fa63736da196a069c6fbe4f2 100644 (file)
@@ -37,7 +37,6 @@
 /// fail!("this is a {} {message}", "fancy", message = "message");
 /// ```
 #[macro_export]
-#[cfg(not(stage0))]
 macro_rules! fail(
     () => ({
         fail!("explicit failure")
@@ -68,39 +67,6 @@ fn run_fmt(fmt: &::std::fmt::Arguments) -> ! {
     });
 )
 
-#[macro_export]
-#[cfg(stage0)]
-macro_rules! fail(
-    () => ({
-        fail!("explicit failure")
-    });
-    ($msg:expr) => ({
-        // static requires less code at runtime, more constant data
-        static FILE_LINE: (&'static str, uint) = (file!(), line!());
-        let (file, line) = FILE_LINE;
-        ::std::rt::begin_unwind($msg, file, line)
-    });
-    ($fmt:expr, $($arg:tt)*) => ({
-        // a closure can't have return type !, so we need a full
-        // function to pass to format_args!, *and* we need the
-        // file and line numbers right here; so an inner bare fn
-        // is our only choice.
-        //
-        // LLVM doesn't tend to inline this, presumably because begin_unwind_fmt
-        // is #[cold] and #[inline(never)] and because this is flagged as cold
-        // as returning !. We really do want this to be inlined, however,
-        // because it's just a tiny wrapper. Small wins (156K to 149K in size)
-        // were seen when forcing this to be inlined, and that number just goes
-        // up with the number of calls to fail!()
-        #[inline(always)]
-        fn run_fmt(fmt: &::std::fmt::Arguments) -> ! {
-            static FILE_LINE: (&'static str, uint) = (file!(), line!());
-            ::std::rt::begin_unwind_fmt(fmt, &FILE_LINE)
-        }
-        format_args!(run_fmt, $fmt, $($arg)*)
-    });
-)
-
 /// Ensure that a boolean expression is `true` at runtime.
 ///
 /// This will invoke the `fail!` macro if the provided expression cannot be
index 1d189f8d4bcbd023ab66489df67de95892b37411..c9526a64f46d08775c30bbc44a9c6f782aeff9db 100644 (file)
@@ -10,7 +10,7 @@
 
 //! Useful synchronization primitives
 //!
-//! This modules contains useful safe and unsafe synchronization primitives.
+//! This module contains useful safe and unsafe synchronization primitives.
 //! Most of the primitives in this module do not provide any sort of locking
 //! and/or blocking at all, but rather provide the necessary tools to build
 //! other types of concurrent primitives.
index df0be09aea1f7f058c4baddd11ee1abd1d62447f..ec31181e8a7483f93ce1219b0fafde67ba39aeb4 100644 (file)
@@ -39,9 +39,6 @@ fn bsearch_table<T>(c: char, r: &'static [(char, &'static [T])]) -> Option<&'sta
 pub fn decompose_compatible(c: char, i: |char|) { d(c, i, true); }
 
 fn d(c: char, i: |char|, k: bool) {
-    #[cfg(stage0)]
-    use core::iter::Iterator;
-
     // 7-bit ASCII never decomposes
     if c <= '\x7f' { i(c); return; }
 
index 89cb27c1f1ae1473aa32a8b166f9df88c7586d46..ba20f2c6f27f9fca7b9404cb90564be862331cdd 100644 (file)
@@ -8,10 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-/* Foreign builtins. */
-
-#include "valgrind/valgrind.h"
-
 #include <stdint.h>
 #include <time.h>
 #include <string.h>
 #endif
 #endif
 
+/* Foreign builtins. */
+//include valgrind.h after stdint.h so that uintptr_t is defined for msys2 w64
+#include "valgrind/valgrind.h"
+
 #ifdef __ANDROID__
 time_t
 timegm(struct tm *tm)
index 623f8f8bcc00d3097c4f4f02bba9cad9a6ba489c..a07be82d58ef91f0cae09074ac8a5c4513e4088d 100644 (file)
@@ -1,3 +1,11 @@
+S 2014-08-07 12e0f72
+  freebsd-x86_64 e55055a876ebbde0d3ed3bcb97579afab9264def
+  linux-i386 2665e45879f2ef77ce0c9015f971642fe424ac33
+  linux-x86_64 51ed1f4cf0707585a136bb149a443394067c074c
+  macos-i386 78f1996954a6e0718d684a3756b4870a6f8771ee
+  macos-x86_64 216f46f65866207a9f41c3ed654f5c1e085cb7f3
+  winnt-i386 95a9b8a8bf587761ae954392aee2ccee3758a533
+
 S 2014-07-17 9fc8394
   freebsd-x86_64 5a4b645e2b42ae06224cc679d4a43b3d89be1482
   linux-i386 a5e1bb723020ac35173d49600e76b0935e257a6a
diff --git a/src/test/compile-fail/inaccessible-test-modules.rs b/src/test/compile-fail/inaccessible-test-modules.rs
new file mode 100644 (file)
index 0000000..b646f80
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <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.
+
+// compile-flags:--test
+
+// the `--test` harness creates modules with these textual names, but
+// they should be inaccessible from normal code.
+use x = __test; //~ ERROR unresolved import `__test`
+use y = __test_reexports; //~ ERROR unresolved import `__test_reexports`
+
+#[test]
+fn baz() {}
diff --git a/src/test/run-make/test-harness/Makefile b/src/test/run-make/test-harness/Makefile
new file mode 100644 (file)
index 0000000..4517af8
--- /dev/null
@@ -0,0 +1,7 @@
+-include ../tools.mk
+
+all:
+       # check that #[ignore(cfg(...))] does the right thing.
+       $(RUSTC) --test test-ignore-cfg.rs --cfg ignorecfg
+       $(call RUN,test-ignore-cfg) | grep 'shouldnotignore ... ok'
+       $(call RUN,test-ignore-cfg) | grep 'shouldignore ... ignored'
diff --git a/src/test/run-make/test-harness/test-ignore-cfg.rs b/src/test/run-make/test-harness/test-ignore-cfg.rs
new file mode 100644 (file)
index 0000000..a8f88cc
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <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.
+
+#[test]
+#[ignore(cfg(ignorecfg))]
+fn shouldignore() {
+}
+
+#[test]
+#[ignore(cfg(noignorecfg))]
+fn shouldnotignore() {
+}
index 8e84278c10e02ab235ba2fd039df06dbb6a99766..d187a6a8afebb17346fd0763a7ca07a2a97bc6ad 100644 (file)
@@ -16,6 +16,8 @@
 // instead of in std.
 
 #![feature(macro_rules)]
+#![reexport_test_harness_main = "test_main"]
+
 extern crate libc;
 
 extern crate native;
@@ -55,7 +57,7 @@ fn f() $b
 
 #[cfg(test)] #[start]
 fn start(argc: int, argv: *const *const u8) -> int {
-    green::start(argc, argv, rustuv::event_loop, __test::main)
+    green::start(argc, argv, rustuv::event_loop, test_main)
 }
 
 iotest!(fn test_destroy_once() {
diff --git a/src/test/run-pass/reexport-test-harness-main.rs b/src/test/run-pass/reexport-test-harness-main.rs
new file mode 100644 (file)
index 0000000..309ae1b
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <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.
+
+// ignore-pretty
+// compile-flags:--test
+
+#![reexport_test_harness_main = "test_main"]
+
+#[cfg(test)]
+fn _unused() {
+    // should resolve to the entry point function the --test harness
+    // creates.
+    test_main();
+}
index d2408509fc5820c0105e083a149060d1ea67333d..6f6fff15814d556f8865acac9353475f5bb09718 100644 (file)
@@ -18,6 +18,7 @@
 
 #![feature(macro_rules, globs)]
 #![allow(experimental)]
+#![reexport_test_harness_main = "test_main"]
 
 extern crate native;
 extern crate green;
@@ -25,7 +26,7 @@
 
 #[cfg(test)] #[start]
 fn start(argc: int, argv: *const *const u8) -> int {
-    green::start(argc, argv, rustuv::event_loop, __test::main)
+    green::start(argc, argv, rustuv::event_loop, test_main)
 }
 
 macro_rules! iotest (
diff --git a/src/test/run-pass/test-ignore-cfg.rs b/src/test/run-pass/test-ignore-cfg.rs
deleted file mode 100644 (file)
index b36fbca..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2012-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 <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.
-
-// compile-flags: --test --cfg ignorecfg
-// ignore-pretty: does not work well with `--test`
-
-#[test]
-#[ignore(cfg(ignorecfg))]
-fn shouldignore() {
-}
-
-#[test]
-#[ignore(cfg(noignorecfg))]
-fn shouldnotignore() {
-}
-
-#[test]
-fn checktests() {
-    // Pull the tests out of the secreturn test module
-    let tests = __test::TESTS;
-
-    assert!(
-        tests.iter().any(|t| t.desc.name.to_string().as_slice() == "shouldignore" &&
-                         t.desc.ignore));
-
-    assert!(
-        tests.iter().any(|t| t.desc.name.to_string().as_slice() == "shouldnotignore" &&
-                         !t.desc.ignore));
-}