]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #22911 - djmally:master, r=steveklabnik
authorManish Goregaokar <manishsmail@gmail.com>
Mon, 2 Mar 2015 08:08:50 +0000 (13:38 +0530)
committerManish Goregaokar <manishsmail@gmail.com>
Mon, 2 Mar 2015 20:16:28 +0000 (01:46 +0530)
 ... example that actually does use an Option

68 files changed:
configure
src/doc/intro.md
src/liballoc/arc.rs
src/libcollections/str.rs
src/libcore/fmt/mod.rs
src/libcore/iter.rs
src/libcore/lib.rs
src/libcore/num/int.rs [deleted file]
src/libcore/num/mod.rs
src/libcore/num/uint.rs [deleted file]
src/libcoretest/iter.rs
src/libcoretest/num/int.rs [deleted file]
src/libcoretest/num/int_macros.rs
src/libcoretest/num/mod.rs
src/libcoretest/num/uint.rs [deleted file]
src/libgetopts/lib.rs
src/liblibc/lib.rs
src/librand/rand_impls.rs
src/librbml/lib.rs
src/librustc/lint/context.rs
src/librustc/lint/mod.rs
src/librustc/metadata/decoder.rs
src/librustc/middle/liveness.rs
src/librustc_lint/builtin.rs
src/librustc_trans/back/write.rs
src/librustc_trans/trans/_match.rs
src/librustc_trans/trans/base.rs
src/librustc_trans/trans/callee.rs
src/librustc_trans/trans/meth.rs
src/librustc_typeck/check/dropck.rs
src/librustc_typeck/diagnostics.rs
src/libstd/io/lazy.rs [new file with mode: 0644]
src/libstd/io/mod.rs
src/libstd/io/stdio.rs [new file with mode: 0644]
src/libstd/lib.rs
src/libstd/num/mod.rs
src/libstd/old_io/extensions.rs
src/libstd/old_io/stdio.rs
src/libstd/sys/unix/mod.rs
src/libstd/sys/unix/stdio.rs [new file with mode: 0644]
src/libstd/sys/unix/thread.rs
src/libstd/sys/windows/c.rs
src/libstd/sys/windows/handle.rs
src/libstd/sys/windows/mod.rs
src/libstd/sys/windows/stdio.rs [new file with mode: 0644]
src/libstd/thread.rs
src/libsyntax/attr.rs
src/test/bench/shootout-binarytrees.rs
src/test/bench/shootout-k-nucleotide.rs
src/test/bench/sudoku.rs
src/test/compile-fail/dropck_no_diverge_on_nonregular_1.rs [new file with mode: 0644]
src/test/compile-fail/dropck_no_diverge_on_nonregular_2.rs [new file with mode: 0644]
src/test/compile-fail/dropck_no_diverge_on_nonregular_3.rs [new file with mode: 0644]
src/test/compile-fail/issue-8460-const.rs
src/test/compile-fail/nonbool_static_assert.rs [new file with mode: 0644]
src/test/compile-fail/unnecessary-private.rs
src/test/run-fail/bounds-check-no-overflow.rs
src/test/run-fail/hashmap-capacity-overflow.rs
src/test/run-pass-valgrind/cleanup-stdin.rs
src/test/run-pass/ifmt.rs
src/test/run-pass/issue-13304.rs
src/test/run-pass/issue-14456.rs
src/test/run-pass/issue-16671.rs
src/test/run-pass/issue-17322.rs
src/test/run-pass/issue-22777.rs [new file with mode: 0644]
src/test/run-pass/issue-4333.rs
src/test/run-pass/macro-attributes.rs
src/test/run-pass/process-spawn-with-unicode-params.rs

index e722fe8772a394f21e90280aaf21c5bc727dd4a1..e5333b45525fc3eb0636ad585bacbdba0985f5d1 100755 (executable)
--- a/configure
+++ b/configure
@@ -875,7 +875,7 @@ then
             | cut -d ' ' -f 2)
 
         case $CFG_CLANG_VERSION in
-            (3.0svn | 3.0 | 3.1* | 3.2* | 3.3* | 3.4* | 3.5* | 3.6*)
+            (3.2* | 3.3* | 3.4* | 3.5* | 3.6*)
             step_msg "found ok version of CLANG: $CFG_CLANG_VERSION"
             if [ -z "$CC" ]
             then
index 07a90959deb693b30fbf629a50d950c9c52cc03c..d145eaada2b0e0f1f81c87bfaf2f3a6ba82d3ea3 100644 (file)
@@ -510,10 +510,10 @@ numbers[1] is 3
 numbers[0] is 2
 ```
 
-Each time, we can get a slithtly different output because the threads
-are not quaranteed to run in any set order. If you get the same order
-every time it is because each of these threads are very small and
-complete too fast for their indeterminate behavior to surface.
+Each time, we can get a slightly different output because the threads are not
+guaranteed to run in any set order. If you get the same order every time it is
+because each of these threads are very small and complete too fast for their
+indeterminate behavior to surface.
 
 The important part here is that the Rust compiler was able to use ownership to
 give us assurance _at compile time_ that we weren't doing something incorrect
index 88a3752c88a1d6774b8b288a2a12f2af0e566e61..c95b413b397edb1fd489298ddde673707e4fce7a 100644 (file)
@@ -201,10 +201,11 @@ pub fn downgrade(&self) -> Weak<T> {
 impl<T> Arc<T> {
     #[inline]
     fn inner(&self) -> &ArcInner<T> {
-        // This unsafety is ok because while this arc is alive we're guaranteed that the inner
-        // pointer is valid. Furthermore, we know that the `ArcInner` structure itself is `Sync`
-        // because the inner data is `Sync` as well, so we're ok loaning out an immutable pointer
-        // to these contents.
+        // This unsafety is ok because while this arc is alive we're guaranteed
+        // that the inner pointer is valid. Furthermore, we know that the
+        // `ArcInner` structure itself is `Sync` because the inner data is
+        // `Sync` as well, so we're ok loaning out an immutable pointer to these
+        // contents.
         unsafe { &**self._ptr }
     }
 }
@@ -236,13 +237,15 @@ impl<T> Clone for Arc<T> {
     /// ```
     #[inline]
     fn clone(&self) -> Arc<T> {
-        // Using a relaxed ordering is alright here, as knowledge of the original reference
-        // prevents other threads from erroneously deleting the object.
+        // Using a relaxed ordering is alright here, as knowledge of the
+        // original reference prevents other threads from erroneously deleting
+        // the object.
         //
-        // As explained in the [Boost documentation][1], Increasing the reference counter can
-        // always be done with memory_order_relaxed: New references to an object can only be formed
-        // from an existing reference, and passing an existing reference from one thread to another
-        // must already provide any required synchronization.
+        // As explained in the [Boost documentation][1], Increasing the
+        // reference counter can always be done with memory_order_relaxed: New
+        // references to an object can only be formed from an existing
+        // reference, and passing an existing reference from one thread to
+        // another must already provide any required synchronization.
         //
         // [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html)
         self.inner().strong.fetch_add(1, Relaxed);
index c58cca828d8c39a04c9fc542aa7b0ff3ec54a8ad..86fcac3e4b8a09ca34e98ab499568c3bb83153f4 100644 (file)
@@ -1455,9 +1455,9 @@ fn words(&self) -> Words {
     ///
     /// `is_cjk` determines behavior for characters in the Ambiguous category: if `is_cjk` is
     /// `true`, these are 2 columns wide; otherwise, they are 1. In CJK locales, `is_cjk` should be
-    /// `true`, else it should be `false`. [Unicode Standard Annex
-    /// #11](http://www.unicode.org/reports/tr11/) recommends that these characters be treated as 1
-    /// column (i.e., `is_cjk` = `false`) if the locale is unknown.
+    /// `true`, else it should be `false`.
+    /// [Unicode Standard Annex #11](http://www.unicode.org/reports/tr11/) recommends that these
+    /// characters be treated as 1 column (i.e., `is_cjk = false`) if the locale is unknown.
     #[unstable(feature = "collections",
                reason = "this functionality may only be provided by libunicode")]
     fn width(&self, is_cjk: bool) -> usize {
index 117b829fdff9b5bf79ed6e4d686cfa45239b21b4..9544fbaa55b256b65fd48dd58ee682dc14c1386a 100644 (file)
@@ -700,7 +700,7 @@ fn fmt(&self, f: &mut Formatter) -> Result {
 impl<T> Pointer for *const T {
     fn fmt(&self, f: &mut Formatter) -> Result {
         f.flags |= 1 << (FlagV1::Alternate as u32);
-        let ret = LowerHex::fmt(&(*self as u32), f);
+        let ret = LowerHex::fmt(&(*self as usize), f);
         f.flags &= !(1 << (FlagV1::Alternate as u32));
         ret
     }
index 4c9e8f47d0eb2f04d0279642a405f3345295e6d4..88a729a3db09e92682022b71406d35cd6f483930 100644 (file)
@@ -68,7 +68,7 @@
 use ops::{Add, Deref, FnMut};
 use option::Option;
 use option::Option::{Some, None};
-use marker::{Send, Sized, Sync};
+use marker::Sized;
 use usize;
 
 /// An interface for dealing with "external iterators". These types of iterators
@@ -1783,10 +1783,6 @@ pub struct Peekable<I: Iterator> {
     peeked: Option<I::Item>,
 }
 
-// FIXME: after #22828 being fixed, the following unsafe impl should be removed
-unsafe impl<I: Iterator> Sync for Peekable<I> where I: Sync, I::Item: Sync {}
-unsafe impl<I: Iterator> Send for Peekable<I> where I: Send, I::Item: Send {}
-
 impl<I: Iterator + Clone> Clone for Peekable<I> where I::Item: Clone {
     fn clone(&self) -> Peekable<I> {
         Peekable {
index a9d699735908529c52614531693ecc54adacbed7..7cc963bed358f9aa666ff401bc3f520a3d84109a 100644 (file)
@@ -39,7 +39,7 @@
 //!   distribution.
 //!
 //! * `rust_begin_unwind` - This function takes three arguments, a
-//!   `fmt::Arguments`, a `&str`, and a `uint`. These three arguments dictate
+//!   `fmt::Arguments`, a `&str`, and a `usize`. These three arguments dictate
 //!   the panic message, the file at which panic was invoked, and the line.
 //!   It is up to consumers of this core library to define this panic
 //!   function; it is only required to never return.
 #[macro_use]
 mod uint_macros;
 
-#[path = "num/int.rs"]  pub mod int;
 #[path = "num/isize.rs"]  pub mod isize;
 #[path = "num/i8.rs"]   pub mod i8;
 #[path = "num/i16.rs"]  pub mod i16;
 #[path = "num/i32.rs"]  pub mod i32;
 #[path = "num/i64.rs"]  pub mod i64;
 
-#[path = "num/uint.rs"] pub mod uint;
 #[path = "num/usize.rs"] pub mod usize;
 #[path = "num/u8.rs"]   pub mod u8;
 #[path = "num/u16.rs"]  pub mod u16;
diff --git a/src/libcore/num/int.rs b/src/libcore/num/int.rs
deleted file mode 100644 (file)
index 2132b95..0000000
+++ /dev/null
@@ -1,21 +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.
-
-//! Deprecated: replaced by `isize`.
-//!
-//! The rollout of the new type will gradually take place over the
-//! alpha cycle along with the development of clearer conventions
-//! around integer types.
-
-#![unstable(feature = "core")]
-#![deprecated(since = "1.0.0", reason = "replaced by isize")]
-
-#[cfg(target_pointer_width = "32")] int_module! { int, 32 }
-#[cfg(target_pointer_width = "64")] int_module! { int, 64 }
index b1039f79f23de1989343683d2d4cc99cd528a906..318799f59a8101f48a41e9f02d6aa89f6ddc88ff 100644 (file)
@@ -372,9 +372,10 @@ fn saturating_sub(self, other: Self) -> Self {
     #[unstable(feature = "core",
                reason = "pending integer conventions")]
     #[inline]
-    fn pow(self, mut exp: uint) -> Self {
+    fn pow(self, mut exp: u32) -> Self {
         let mut base = self;
         let mut acc: Self = Int::one();
+
         while exp > 0 {
             if (exp & 1) == 1 {
                 acc = acc * base;
diff --git a/src/libcore/num/uint.rs b/src/libcore/num/uint.rs
deleted file mode 100644 (file)
index f66a0ee..0000000
+++ /dev/null
@@ -1,20 +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.
-
-//! Deprecated: replaced by `usize`.
-//!
-//! The rollout of the new type will gradually take place over the
-//! alpha cycle along with the development of clearer conventions
-//! around integer types.
-
-#![unstable(feature = "core")]
-#![deprecated(since = "1.0.0", reason = "replaced by usize")]
-
-uint_module! { uint, int, ::int::BITS }
index 8a27400389f4ada601d595879b3b0ed651c46ff4..abf88583c03ffac03f1a6a40a0c9c51a86e20060 100644 (file)
@@ -12,7 +12,7 @@
 use core::iter::order::*;
 use core::iter::MinMaxResult::*;
 use core::num::SignedInt;
-use core::uint;
+use core::usize;
 use core::cmp;
 
 use test::Bencher;
@@ -292,7 +292,7 @@ fn count(st: &mut uint) -> Option<uint> {
 fn test_cycle() {
     let cycle_len = 3;
     let it = count(0, 1).take(cycle_len).cycle();
-    assert_eq!(it.size_hint(), (uint::MAX, None));
+    assert_eq!(it.size_hint(), (usize::MAX, None));
     for (i, x) in it.take(100).enumerate() {
         assert_eq!(i % cycle_len, x);
     }
@@ -365,19 +365,19 @@ fn test_iterator_size_hint() {
     let v2 = &[10, 11, 12];
     let vi = v.iter();
 
-    assert_eq!(c.size_hint(), (uint::MAX, None));
+    assert_eq!(c.size_hint(), (usize::MAX, None));
     assert_eq!(vi.clone().size_hint(), (10, Some(10)));
 
     assert_eq!(c.clone().take(5).size_hint(), (5, Some(5)));
     assert_eq!(c.clone().skip(5).size_hint().1, None);
     assert_eq!(c.clone().take_while(|_| false).size_hint(), (0, None));
     assert_eq!(c.clone().skip_while(|_| false).size_hint(), (0, None));
-    assert_eq!(c.clone().enumerate().size_hint(), (uint::MAX, None));
-    assert_eq!(c.clone().chain(vi.clone().cloned()).size_hint(), (uint::MAX, None));
+    assert_eq!(c.clone().enumerate().size_hint(), (usize::MAX, None));
+    assert_eq!(c.clone().chain(vi.clone().cloned()).size_hint(), (usize::MAX, None));
     assert_eq!(c.clone().zip(vi.clone()).size_hint(), (10, Some(10)));
     assert_eq!(c.clone().scan(0, |_,_| Some(0)).size_hint(), (0, None));
     assert_eq!(c.clone().filter(|_| false).size_hint(), (0, None));
-    assert_eq!(c.clone().map(|_| 0).size_hint(), (uint::MAX, None));
+    assert_eq!(c.clone().map(|_| 0).size_hint(), (usize::MAX, None));
     assert_eq!(c.filter_map(|_| Some(0)).size_hint(), (0, None));
 
     assert_eq!(vi.clone().take(5).size_hint(), (5, Some(5)));
@@ -753,7 +753,7 @@ fn test_range() {
 
     assert_eq!((0..100).size_hint(), (100, Some(100)));
     // this test is only meaningful when sizeof uint < sizeof u64
-    assert_eq!((uint::MAX - 1..uint::MAX).size_hint(), (1, Some(1)));
+    assert_eq!((usize::MAX - 1..usize::MAX).size_hint(), (1, Some(1)));
     assert_eq!((-10..-1).size_hint(), (9, Some(9)));
     assert_eq!((-1..-10).size_hint(), (0, Some(0)));
 }
diff --git a/src/libcoretest/num/int.rs b/src/libcoretest/num/int.rs
deleted file mode 100644 (file)
index be8dfd0..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// 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.
-
-int_module!(int, int);
index f5657d939b2afccb1258032a88a37251f1809316..d1bfb475b074b41d2a38faebbccf16cffaf3ab09 100644 (file)
@@ -12,7 +12,7 @@ macro_rules! int_module { ($T:ty, $T_i:ident) => (
 #[cfg(test)]
 mod tests {
     use core::$T_i::*;
-    use core::int;
+    use core::isize;
     use core::num::{FromStrRadix, Int, SignedInt};
     use core::ops::{Shl, Shr, Not, BitXor, BitAnd, BitOr};
     use num;
@@ -153,7 +153,7 @@ fn test_be() {
     fn test_signed_checked_div() {
         assert!(10.checked_div(2) == Some(5));
         assert!(5.checked_div(0) == None);
-        assert!(int::MIN.checked_div(-1) == None);
+        assert!(isize::MIN.checked_div(-1) == None);
     }
 
     #[test]
@@ -201,6 +201,17 @@ fn test_from_str_radix() {
         assert_eq!(FromStrRadix::from_str_radix("Z", 35).ok(), None::<$T>);
         assert_eq!(FromStrRadix::from_str_radix("-9", 2).ok(), None::<$T>);
     }
+
+    #[test]
+    fn test_pow() {
+        let mut r = 2 as $T;
+
+        assert_eq!(r.pow(2u32), 4 as $T);
+        assert_eq!(r.pow(0u32), 1 as $T);
+        r = -2 as $T;
+        assert_eq!(r.pow(2u32), 4 as $T);
+        assert_eq!(r.pow(3u32), -8 as $T);
+    }
 }
 
 )}
index 03f6e51a3498a4c72f1ce88639172695add9b5cc..1cd1989c11dc3e5088cf210b06ff74965677d0e0 100644 (file)
@@ -21,7 +21,6 @@
 mod i16;
 mod i32;
 mod i64;
-mod int;
 
 #[macro_use]
 mod uint_macros;
@@ -30,7 +29,6 @@
 mod u16;
 mod u32;
 mod u64;
-mod uint;
 
 /// Helper function for testing numeric operations
 pub fn test_num<T>(ten: T, two: T) where
diff --git a/src/libcoretest/num/uint.rs b/src/libcoretest/num/uint.rs
deleted file mode 100644 (file)
index 395e55c..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// 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.
-
-uint_module!(uint, uint);
index 4e329897e1ab21958e6dd520aabdaea04b3b34ff..6240b0e6afdd50861f59ced7b8a752cd8dd626b9 100644 (file)
@@ -963,7 +963,7 @@ fn t(s: &str, i: uint, u: &[String]) {
         "little lamb".to_string(),
         "Little lamb".to_string()
     ]);
-    t("\nMary had a little lamb\nLittle lamb\n", ::std::uint::MAX,
+    t("\nMary had a little lamb\nLittle lamb\n", ::std::usize::MAX,
         &["Mary had a little lamb\nLittle lamb".to_string()]);
 }
 
index 74a95b3aba056cdd194a1637b1950d5f5ba5bafa..42143b06ca0e391678583b6e9cfced390ffa897c 100644 (file)
@@ -1115,7 +1115,6 @@ pub mod c99 {
             pub mod posix88 {
                 pub type off_t = i64;
                 pub type dev_t = u32;
-                pub type ino_t = u32;
                 pub type pid_t = i32;
                 pub type uid_t = u32;
                 pub type gid_t = u32;
index d5c5d5004657e7facfdee32003e8ef9440d5a073..74d2c408060cbc2c595cd95678e4bbb409ad0468 100644 (file)
 
 use core::prelude::*;
 use core::char;
-use core::int;
-use core::uint;
+use core::isize;
+use core::usize;
 
 use {Rand,Rng};
 
-impl Rand for int {
+impl Rand for isize {
     #[inline]
-    fn rand<R: Rng>(rng: &mut R) -> int {
-        if int::BITS == 32 {
-            rng.gen::<i32>() as int
+    fn rand<R: Rng>(rng: &mut R) -> isize {
+        if isize::BITS == 32 {
+            rng.gen::<i32>() as isize
         } else {
-            rng.gen::<i64>() as int
+            rng.gen::<i64>() as isize
         }
     }
 }
@@ -56,13 +56,13 @@ fn rand<R: Rng>(rng: &mut R) -> i64 {
     }
 }
 
-impl Rand for uint {
+impl Rand for usize {
     #[inline]
-    fn rand<R: Rng>(rng: &mut R) -> uint {
-        if uint::BITS == 32 {
-            rng.gen::<u32>() as uint
+    fn rand<R: Rng>(rng: &mut R) -> usize {
+        if usize::BITS == 32 {
+            rng.gen::<u32>() as usize
         } else {
-            rng.gen::<u64>() as uint
+            rng.gen::<u64>() as usize
         }
     }
 }
index c48dd7a6ee89406fe26a978264a17ba81dd6c9f3..05cd24de7368c6a831597d8e9aa4e096c916adf8 100644 (file)
@@ -132,11 +132,9 @@ pub mod reader {
     use std::char;
 
     use std::isize;
-    use std::old_io::extensions::u64_from_be_bytes;
     use std::mem::transmute;
     use std::num::Int;
-    use std::option::Option;
-    use std::option::Option::{None, Some};
+    use std::slice::bytes;
 
     use serialize;
 
@@ -199,20 +197,24 @@ pub fn vuint_at(data: &[u8], start: uint) -> DecodeResult<Res> {
             return vuint_at_slow(data, start);
         }
 
-        // Lookup table for parsing EBML Element IDs as per http://ebml.sourceforge.net/specs/
-        // The Element IDs are parsed by reading a big endian u32 positioned at data[start].
-        // Using the four most significant bits of the u32 we lookup in the table below how the
-        // element ID should be derived from it.
+        // Lookup table for parsing EBML Element IDs as per
+        // http://ebml.sourceforge.net/specs/ The Element IDs are parsed by
+        // reading a big endian u32 positioned at data[start].  Using the four
+        // most significant bits of the u32 we lookup in the table below how
+        // the element ID should be derived from it.
         //
-        // The table stores tuples (shift, mask) where shift is the number the u32 should be right
-        // shifted with and mask is the value the right shifted value should be masked with.
-        // If for example the most significant bit is set this means it's a class A ID and the u32
-        // should be right shifted with 24 and masked with 0x7f. Therefore we store (24, 0x7f) at
-        // index 0x8 - 0xF (four bit numbers where the most significant bit is set).
+        // The table stores tuples (shift, mask) where shift is the number the
+        // u32 should be right shifted with and mask is the value the right
+        // shifted value should be masked with.  If for example the most
+        // significant bit is set this means it's a class A ID and the u32
+        // should be right shifted with 24 and masked with 0x7f. Therefore we
+        // store (24, 0x7f) at index 0x8 - 0xF (four bit numbers where the most
+        // significant bit is set).
         //
-        // By storing the number of shifts and masks in a table instead of checking in order if
-        // the most significant bit is set, the second most significant bit is set etc. we can
-        // replace up to three "and+branch" with a single table lookup which gives us a measured
+        // By storing the number of shifts and masks in a table instead of
+        // checking in order if the most significant bit is set, the second
+        // most significant bit is set etc. we can replace up to three
+        // "and+branch" with a single table lookup which gives us a measured
         // speedup of around 2x on x86_64.
         static SHIFT_MASK_TABLE: [(uint, u32); 16] = [
             (0, 0x0), (0, 0x0fffffff),
@@ -318,17 +320,23 @@ pub fn doc_as_u8(d: Doc) -> u8 {
 
     pub fn doc_as_u16(d: Doc) -> u16 {
         assert_eq!(d.end, d.start + 2);
-        u64_from_be_bytes(d.data, d.start, 2) as u16
+        let mut b = [0; 2];
+        bytes::copy_memory(&mut b, &d.data[d.start..d.end]);
+        unsafe { (*(b.as_ptr() as *const u16)).to_be() }
     }
 
     pub fn doc_as_u32(d: Doc) -> u32 {
         assert_eq!(d.end, d.start + 4);
-        u64_from_be_bytes(d.data, d.start, 4) as u32
+        let mut b = [0; 4];
+        bytes::copy_memory(&mut b, &d.data[d.start..d.end]);
+        unsafe { (*(b.as_ptr() as *const u32)).to_be() }
     }
 
     pub fn doc_as_u64(d: Doc) -> u64 {
         assert_eq!(d.end, d.start + 8);
-        u64_from_be_bytes(d.data, d.start, 8)
+        let mut b = [0; 8];
+        bytes::copy_memory(&mut b, &d.data[d.start..d.end]);
+        unsafe { (*(b.as_ptr() as *const u64)).to_be() }
     }
 
     pub fn doc_as_i8(d: Doc) -> i8 { doc_as_u8(d) as i8 }
@@ -689,11 +697,10 @@ fn error(&mut self, err: &str) -> Error {
 }
 
 pub mod writer {
-    use std::clone::Clone;
-    use std::old_io::extensions::u64_to_be_bytes;
+    use std::mem;
+    use std::num::Int;
     use std::old_io::{Writer, Seek};
     use std::old_io;
-    use std::mem;
 
     use super::{ EsVec, EsMap, EsEnum, EsVecLen, EsVecElt, EsMapLen, EsMapKey,
         EsEnumVid, EsU64, EsU32, EsU16, EsU8, EsInt, EsI64, EsI32, EsI16, EsI8,
@@ -794,21 +801,18 @@ pub fn wr_tagged_bytes(&mut self, tag_id: uint, b: &[u8]) -> EncodeResult {
         }
 
         pub fn wr_tagged_u64(&mut self, tag_id: uint, v: u64) -> EncodeResult {
-            u64_to_be_bytes(v, 8, |v| {
-                self.wr_tagged_bytes(tag_id, v)
-            })
+            let bytes: [u8; 8] = unsafe { mem::transmute(v.to_be()) };
+            self.wr_tagged_bytes(tag_id, &bytes)
         }
 
         pub fn wr_tagged_u32(&mut self, tag_id: uint, v: u32)  -> EncodeResult{
-            u64_to_be_bytes(v as u64, 4, |v| {
-                self.wr_tagged_bytes(tag_id, v)
-            })
+            let bytes: [u8; 4] = unsafe { mem::transmute(v.to_be()) };
+            self.wr_tagged_bytes(tag_id, &bytes)
         }
 
         pub fn wr_tagged_u16(&mut self, tag_id: uint, v: u16) -> EncodeResult {
-            u64_to_be_bytes(v as u64, 2, |v| {
-                self.wr_tagged_bytes(tag_id, v)
-            })
+            let bytes: [u8; 2] = unsafe { mem::transmute(v.to_be()) };
+            self.wr_tagged_bytes(tag_id, &bytes)
         }
 
         pub fn wr_tagged_u8(&mut self, tag_id: uint, v: u8) -> EncodeResult {
@@ -816,21 +820,15 @@ pub fn wr_tagged_u8(&mut self, tag_id: uint, v: u8) -> EncodeResult {
         }
 
         pub fn wr_tagged_i64(&mut self, tag_id: uint, v: i64) -> EncodeResult {
-            u64_to_be_bytes(v as u64, 8, |v| {
-                self.wr_tagged_bytes(tag_id, v)
-            })
+            self.wr_tagged_u64(tag_id, v as u64)
         }
 
         pub fn wr_tagged_i32(&mut self, tag_id: uint, v: i32) -> EncodeResult {
-            u64_to_be_bytes(v as u64, 4, |v| {
-                self.wr_tagged_bytes(tag_id, v)
-            })
+            self.wr_tagged_u32(tag_id, v as u32)
         }
 
         pub fn wr_tagged_i16(&mut self, tag_id: uint, v: i16) -> EncodeResult {
-            u64_to_be_bytes(v as u64, 2, |v| {
-                self.wr_tagged_bytes(tag_id, v)
-            })
+            self.wr_tagged_u16(tag_id, v as u16)
         }
 
         pub fn wr_tagged_i8(&mut self, tag_id: uint, v: i8) -> EncodeResult {
index 2b968736ffd9a6240c5bbca23197535fb00d3349..f635c77af9b2a1053bbc5d05f619b81d8ab60ae8 100644 (file)
@@ -612,7 +612,7 @@ fn visit_generics(&mut self, g: &ast::Generics) {
     }
 
     fn visit_trait_item(&mut self, m: &ast::TraitItem) {
-        run_lints!(self, check_trait_method, m);
+        run_lints!(self, check_trait_item, m);
         visit::walk_trait_item(self, m);
     }
 
index f3fa3b8846ca2b6d6d6eb175f68873cff5bed564..506d20133bdc78e8679f1dd8253b7284cedea232 100644 (file)
@@ -144,7 +144,7 @@ fn check_generics(&mut self, _: &Context, _: &ast::Generics) { }
     fn check_fn(&mut self, _: &Context,
         _: FnKind, _: &ast::FnDecl, _: &ast::Block, _: Span, _: ast::NodeId) { }
     fn check_ty_method(&mut self, _: &Context, _: &ast::TypeMethod) { }
-    fn check_trait_method(&mut self, _: &Context, _: &ast::TraitItem) { }
+    fn check_trait_item(&mut self, _: &Context, _: &ast::TraitItem) { }
     fn check_struct_def(&mut self, _: &Context,
         _: &ast::StructDef, _: ast::Ident, _: &ast::Generics, _: ast::NodeId) { }
     fn check_struct_def_post(&mut self, _: &Context,
index 0503045ac6e2d1673027bdf9bf1ede727c0c6f23..251c5e6eac70ebe7df5530dca754089ebb442a0b 100644 (file)
 
 use std::collections::HashMap;
 use std::hash::{self, Hash, SipHasher};
-use std::old_io::extensions::u64_from_be_bytes;
-use std::old_io;
 use std::num::FromPrimitive;
+use std::num::Int;
+use std::old_io;
 use std::rc::Rc;
+use std::slice::bytes;
 use std::str;
 
 use rbml::reader;
 // what crate that's in and give us a def_id that makes sense for the current
 // build.
 
+fn u32_from_be_bytes(bytes: &[u8]) -> u32 {
+    let mut b = [0; 4];
+    bytes::copy_memory(&mut b, &bytes[..4]);
+    unsafe { (*(b.as_ptr() as *const u32)).to_be() }
+}
+
 fn lookup_hash<'a, F>(d: rbml::Doc<'a>, mut eq_fn: F, hash: u64) -> Option<rbml::Doc<'a>> where
     F: FnMut(&[u8]) -> bool,
 {
     let index = reader::get_doc(d, tag_index);
     let table = reader::get_doc(index, tag_index_table);
     let hash_pos = table.start + (hash % 256 * 4) as uint;
-    let pos = u64_from_be_bytes(d.data, hash_pos, 4) as uint;
+    let pos = u32_from_be_bytes(&d.data[hash_pos..]) as uint;
     let tagged_doc = reader::doc_at(d.data, pos).unwrap();
 
     let belt = tag_index_buckets_bucket_elt;
 
     let mut ret = None;
     reader::tagged_docs(tagged_doc.doc, belt, |elt| {
-        let pos = u64_from_be_bytes(elt.data, elt.start, 4) as uint;
+        let pos = u32_from_be_bytes(&elt.data[elt.start..]) as uint;
         if eq_fn(&elt.data[elt.start + 4 .. elt.end]) {
             ret = Some(reader::doc_at(d.data, pos).unwrap().doc);
             false
@@ -87,9 +94,7 @@ fn lookup_hash<'a, F>(d: rbml::Doc<'a>, mut eq_fn: F, hash: u64) -> Option<rbml:
 pub fn maybe_find_item<'a>(item_id: ast::NodeId,
                            items: rbml::Doc<'a>) -> Option<rbml::Doc<'a>> {
     fn eq_item(bytes: &[u8], item_id: ast::NodeId) -> bool {
-        return u64_from_be_bytes(
-            &bytes[0..4], 0, 4) as ast::NodeId
-            == item_id;
+        u32_from_be_bytes(bytes) == item_id
     }
     lookup_hash(items,
                 |a| eq_item(a, item_id),
index 2ac019aa964dc6f1f0f15c9c4a17e917d8085a13..5cb034667cc64ad9ffa982e4f753f37f63b8edc2 100644 (file)
@@ -51,8 +51,8 @@
 //! enclosing function.  On the way down the tree, it identifies those AST
 //! nodes and variable IDs that will be needed for the liveness analysis
 //! and assigns them contiguous IDs.  The liveness id for an AST node is
-//! called a `live_node` (it's a newtype'd uint) and the id for a variable
-//! is called a `variable` (another newtype'd uint).
+//! called a `live_node` (it's a newtype'd usize) and the id for a variable
+//! is called a `variable` (another newtype'd usize).
 //!
 //! On the way back up the tree, as we are about to exit from a function
 //! declaration we allocate a `liveness` instance.  Now that we know
 use lint;
 use util::nodemap::NodeMap;
 
-use std::{fmt, old_io, uint};
+use std::{fmt, old_io, usize};
 use std::rc::Rc;
 use std::iter::repeat;
 use syntax::ast::{self, NodeId, Expr};
@@ -138,17 +138,17 @@ enum LoopKind<'a> {
 }
 
 #[derive(Copy, PartialEq)]
-struct Variable(uint);
+struct Variable(usize);
 
 #[derive(Copy, PartialEq)]
-struct LiveNode(uint);
+struct LiveNode(usize);
 
 impl Variable {
-    fn get(&self) -> uint { let Variable(v) = *self; v }
+    fn get(&self) -> usize { let Variable(v) = *self; v }
 }
 
 impl LiveNode {
-    fn get(&self) -> uint { let LiveNode(v) = *self; v }
+    fn get(&self) -> usize { let LiveNode(v) = *self; v }
 }
 
 impl Clone for LiveNode {
@@ -232,11 +232,11 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 
 impl LiveNode {
     fn is_valid(&self) -> bool {
-        self.get() != uint::MAX
+        self.get() != usize::MAX
     }
 }
 
-fn invalid_node() -> LiveNode { LiveNode(uint::MAX) }
+fn invalid_node() -> LiveNode { LiveNode(usize::MAX) }
 
 struct CaptureInfo {
     ln: LiveNode,
@@ -260,8 +260,8 @@ enum VarKind {
 struct IrMaps<'a, 'tcx: 'a> {
     tcx: &'a ty::ctxt<'tcx>,
 
-    num_live_nodes: uint,
-    num_vars: uint,
+    num_live_nodes: usize,
+    num_vars: usize,
     live_node_map: NodeMap<LiveNode>,
     variable_map: NodeMap<Variable>,
     capture_info_map: NodeMap<Rc<Vec<CaptureInfo>>>,
@@ -540,9 +540,9 @@ struct Specials {
     clean_exit_var: Variable
 }
 
-static ACC_READ: uint = 1;
-static ACC_WRITE: uint = 2;
-static ACC_USE: uint = 4;
+static ACC_READ: u32 = 1;
+static ACC_WRITE: u32 = 2;
+static ACC_USE: u32 = 4;
 
 struct Liveness<'a, 'tcx: 'a> {
     ir: &'a mut IrMaps<'a, 'tcx>,
@@ -631,7 +631,7 @@ fn define_bindings_in_arm_pats(&mut self, pat: Option<&ast::Pat>, succ: LiveNode
         succ
     }
 
-    fn idx(&self, ln: LiveNode, var: Variable) -> uint {
+    fn idx(&self, ln: LiveNode, var: Variable) -> usize {
         ln.get() * self.ir.num_vars + var.get()
     }
 
@@ -670,7 +670,7 @@ fn assigned_on_exit(&self, ln: LiveNode, var: Variable)
     }
 
     fn indices2<F>(&mut self, ln: LiveNode, succ_ln: LiveNode, mut op: F) where
-        F: FnMut(&mut Liveness<'a, 'tcx>, uint, uint),
+        F: FnMut(&mut Liveness<'a, 'tcx>, usize, usize),
     {
         let node_base_idx = self.idx(ln, Variable(0));
         let succ_base_idx = self.idx(succ_ln, Variable(0));
@@ -684,7 +684,7 @@ fn write_vars<F>(&self,
                      ln: LiveNode,
                      mut test: F)
                      -> old_io::IoResult<()> where
-        F: FnMut(uint) -> LiveNode,
+        F: FnMut(usize) -> LiveNode,
     {
         let node_base_idx = self.idx(ln, Variable(0));
         for var_idx in 0..self.ir.num_vars {
@@ -807,7 +807,7 @@ fn define(&mut self, writer: LiveNode, var: Variable) {
     }
 
     // Either read, write, or both depending on the acc bitset
-    fn acc(&mut self, ln: LiveNode, var: Variable, acc: uint) {
+    fn acc(&mut self, ln: LiveNode, var: Variable, acc: u32) {
         debug!("{:?} accesses[{:x}] {:?}: {}",
                ln, acc, var, self.ln_str(ln));
 
@@ -1283,7 +1283,7 @@ fn propagate_through_lvalue_components(&mut self,
     }
 
     // see comment on propagate_through_lvalue()
-    fn write_lvalue(&mut self, expr: &Expr, succ: LiveNode, acc: uint)
+    fn write_lvalue(&mut self, expr: &Expr, succ: LiveNode, acc: u32)
                     -> LiveNode {
         match expr.node {
           ast::ExprPath(..) => {
@@ -1298,7 +1298,7 @@ fn write_lvalue(&mut self, expr: &Expr, succ: LiveNode, acc: uint)
         }
     }
 
-    fn access_path(&mut self, expr: &Expr, succ: LiveNode, acc: uint)
+    fn access_path(&mut self, expr: &Expr, succ: LiveNode, acc: u32)
                    -> LiveNode {
         match self.ir.tcx.def_map.borrow()[expr.id].full_def() {
           DefLocal(nid) => {
index d0fccf6495a0a47d9b83d39ac637cc60819a7308..fe047d2334eecec5650e1fb346339ae2d5a309a0 100644 (file)
@@ -28,8 +28,6 @@
 //! Use the former for unit-like structs and the latter for structs with
 //! a `pub fn new()`.
 
-use self::MethodContext::*;
-
 use metadata::{csearch, decoder};
 use middle::def::*;
 use middle::subst::Substs;
@@ -228,7 +226,9 @@ fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
                             ast::LitInt(v, ast::UnsuffixedIntLit(ast::Plus)) => {
                                 let int_type = if let ast::TyIs(_) = t {
                                     cx.sess().target.int_type
-                                } else { t };
+                                } else {
+                                    t
+                                };
                                 let (min, max) = int_ty_range(int_type);
                                 let negative = self.negated_expr_id == e.id;
 
@@ -245,14 +245,16 @@ fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
                     ty::ty_uint(t) => {
                         let uint_type = if let ast::TyUs(_) = t {
                             cx.sess().target.uint_type
-                        } else { t };
+                        } else {
+                            t
+                        };
                         let (min, max) = uint_ty_range(uint_type);
                         let lit_val: u64 = match lit.node {
                             ast::LitByte(_v) => return,  // _v is u8, within range by definition
                             ast::LitInt(v, _) => v,
                             _ => panic!()
                         };
-                        if  lit_val < min || lit_val > max {
+                        if lit_val < min || lit_val > max {
                             cx.span_lint(OVERFLOWING_LITERALS, e.span,
                                          &*format!("literal out of range for {:?}", t));
                         }
@@ -262,9 +264,9 @@ fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
                         let lit_val: f64 = match lit.node {
                             ast::LitFloat(ref v, _) |
                             ast::LitFloatUnsuffixed(ref v) => {
-                                match v.parse().ok() {
-                                    Some(f) => f,
-                                    None => return
+                                match v.parse() {
+                                    Ok(f) => f,
+                                    Err(_) => return
                                 }
                             }
                             _ => panic!()
@@ -302,52 +304,52 @@ fn rev_binop(binop: ast::BinOp) -> ast::BinOp {
             })
         }
 
-        // for int & uint, be conservative with the warnings, so that the
+        // for isize & usize, be conservative with the warnings, so that the
         // warnings are consistent between 32- and 64-bit platforms
         fn int_ty_range(int_ty: ast::IntTy) -> (i64, i64) {
             match int_ty {
-                ast::TyIs(_) =>    (i64::MIN,        i64::MAX),
-                ast::TyI8 =>   (i8::MIN  as i64, i8::MAX  as i64),
-                ast::TyI16 =>  (i16::MIN as i64, i16::MAX as i64),
-                ast::TyI32 =>  (i32::MIN as i64, i32::MAX as i64),
-                ast::TyI64 =>  (i64::MIN,        i64::MAX)
+                ast::TyIs(_) => (i64::MIN,        i64::MAX),
+                ast::TyI8 =>    (i8::MIN  as i64, i8::MAX  as i64),
+                ast::TyI16 =>   (i16::MIN as i64, i16::MAX as i64),
+                ast::TyI32 =>   (i32::MIN as i64, i32::MAX as i64),
+                ast::TyI64 =>   (i64::MIN,        i64::MAX)
             }
         }
 
         fn uint_ty_range(uint_ty: ast::UintTy) -> (u64, u64) {
             match uint_ty {
-                ast::TyUs(_) =>   (u64::MIN,         u64::MAX),
-                ast::TyU8 =>  (u8::MIN   as u64, u8::MAX   as u64),
-                ast::TyU16 => (u16::MIN  as u64, u16::MAX  as u64),
-                ast::TyU32 => (u32::MIN  as u64, u32::MAX  as u64),
-                ast::TyU64 => (u64::MIN,         u64::MAX)
+                ast::TyUs(_) => (u64::MIN,         u64::MAX),
+                ast::TyU8 =>    (u8::MIN   as u64, u8::MAX   as u64),
+                ast::TyU16 =>   (u16::MIN  as u64, u16::MAX  as u64),
+                ast::TyU32 =>   (u32::MIN  as u64, u32::MAX  as u64),
+                ast::TyU64 =>   (u64::MIN,         u64::MAX)
             }
         }
 
         fn float_ty_range(float_ty: ast::FloatTy) -> (f64, f64) {
             match float_ty {
-                ast::TyF32  => (f32::MIN as f64, f32::MAX as f64),
-                ast::TyF64  => (f64::MIN,        f64::MAX)
+                ast::TyF32 => (f32::MIN as f64, f32::MAX as f64),
+                ast::TyF64 => (f64::MIN,        f64::MAX)
             }
         }
 
         fn int_ty_bits(int_ty: ast::IntTy, target_int_ty: ast::IntTy) -> u64 {
             match int_ty {
-                ast::TyIs(_) =>    int_ty_bits(target_int_ty, target_int_ty),
-                ast::TyI8 =>   i8::BITS  as u64,
-                ast::TyI16 =>  i16::BITS as u64,
-                ast::TyI32 =>  i32::BITS as u64,
-                ast::TyI64 =>  i64::BITS as u64
+                ast::TyIs(_) => int_ty_bits(target_int_ty, target_int_ty),
+                ast::TyI8 =>    i8::BITS  as u64,
+                ast::TyI16 =>   i16::BITS as u64,
+                ast::TyI32 =>   i32::BITS as u64,
+                ast::TyI64 =>   i64::BITS as u64
             }
         }
 
         fn uint_ty_bits(uint_ty: ast::UintTy, target_uint_ty: ast::UintTy) -> u64 {
             match uint_ty {
-                ast::TyUs(_) =>    uint_ty_bits(target_uint_ty, target_uint_ty),
-                ast::TyU8 =>   u8::BITS  as u64,
-                ast::TyU16 =>  u16::BITS as u64,
-                ast::TyU32 =>  u32::BITS as u64,
-                ast::TyU64 =>  u64::BITS as u64
+                ast::TyUs(_) => uint_ty_bits(target_uint_ty, target_uint_ty),
+                ast::TyU8 =>    u8::BITS  as u64,
+                ast::TyU16 =>   u16::BITS as u64,
+                ast::TyU32 =>   u32::BITS as u64,
+                ast::TyU64 =>   u64::BITS as u64
             }
         }
 
@@ -360,7 +362,11 @@ fn check_limits(tcx: &ty::ctxt, binop: ast::BinOp,
             };
             // Normalize the binop so that the literal is always on the RHS in
             // the comparison
-            let norm_binop = if swap { rev_binop(binop) } else { binop };
+            let norm_binop = if swap {
+                rev_binop(binop)
+            } else {
+                binop
+            };
             match ty::expr_ty(tcx, expr).sty {
                 ty::ty_int(int_ty) => {
                     let (min, max) = int_ty_range(int_ty);
@@ -432,9 +438,9 @@ fn check_def(&mut self, sp: Span, id: ast::NodeId) {
 
                 if !ty::is_ffi_safe(self.cx.tcx, tty) {
                     self.cx.span_lint(IMPROPER_CTYPES, sp,
-                                      "found type without foreign-function-safe
-                                      representation annotation in foreign module, consider \
-                                      adding a #[repr(...)] attribute to the type");
+                                      "found type without foreign-function-safe \
+                                       representation annotation in foreign module, consider \
+                                       adding a #[repr(...)] attribute to the type");
                 }
             }
             _ => ()
@@ -595,7 +601,7 @@ fn get_lints(&self) -> LintArray {
 
     fn check_item(&mut self, cx: &Context, item: &ast::Item) {
         if !attr::contains_name(&item.attrs, "automatically_derived") {
-            return
+            return;
         }
         let did = match item.node {
             ast::ItemImpl(_, _, _, ref t_ref_opt, _, _) => {
@@ -603,7 +609,7 @@ fn check_item(&mut self, cx: &Context, item: &ast::Item) {
                 if let &Some(ref trait_ref) = t_ref_opt {
                     let def_id = ty::trait_ref_to_def_id(cx.tcx, trait_ref);
                     if Some(def_id) == cx.tcx.lang_items.copy_trait() {
-                        return
+                        return;
                     }
                 }
 
@@ -615,12 +621,16 @@ fn check_item(&mut self, cx: &Context, item: &ast::Item) {
             }
             _ => return,
         };
-        if !ast_util::is_local(did) { return }
+        if !ast_util::is_local(did) {
+            return;
+        }
         let item = match cx.tcx.map.find(did.node) {
             Some(ast_map::NodeItem(item)) => item,
             _ => return,
         };
-        if !self.checked_raw_pointers.insert(item.id) { return }
+        if !self.checked_raw_pointers.insert(item.id) {
+            return;
+        }
         match item.node {
             ast::ItemStruct(..) | ast::ItemEnum(..) => {
                 let mut visitor = RawPtrDeriveVisitor { cx: cx };
@@ -646,6 +656,7 @@ fn get_lints(&self) -> LintArray {
     }
 
     fn check_attribute(&mut self, cx: &Context, attr: &ast::Attribute) {
+        // Note that check_name() marks the attribute as used if it matches.
         for &(ref name, ty) in KNOWN_ATTRIBUTES {
             match ty {
                 AttributeType::Whitelisted
@@ -730,23 +741,24 @@ fn check_stmt(&mut self, cx: &Context, s: &ast::Stmt) {
         }
 
         let t = ty::expr_ty(cx.tcx, expr);
-        let mut warned = false;
-        match t.sty {
+        let warned = match t.sty {
             ty::ty_tup(ref tys) if tys.is_empty() => return,
             ty::ty_bool => return,
             ty::ty_struct(did, _) |
             ty::ty_enum(did, _) => {
                 if ast_util::is_local(did) {
                     if let ast_map::NodeItem(it) = cx.tcx.map.get(did.node) {
-                        warned |= check_must_use(cx, &it.attrs, s.span);
+                        check_must_use(cx, &it.attrs, s.span)
+                    } else {
+                        false
                     }
                 } else {
                     let attrs = csearch::get_item_attrs(&cx.sess().cstore, did);
-                    warned |= check_must_use(cx, &attrs[..], s.span);
+                    check_must_use(cx, &attrs[..], s.span)
                 }
             }
-            _ => {}
-        }
+            _ => false,
+        };
         if !warned {
             cx.span_lint(UNUSED_RESULTS, s.span, "unused result");
         }
@@ -785,7 +797,9 @@ impl NonCamelCaseTypes {
     fn check_case(&self, cx: &Context, sort: &str, ident: ast::Ident, span: Span) {
         fn is_camel_case(ident: ast::Ident) -> bool {
             let ident = token::get_ident(ident);
-            if ident.is_empty() { return true; }
+            if ident.is_empty() {
+                return true;
+            }
             let ident = ident.trim_matches('_');
 
             // start with a non-lowercase letter rather than non-uppercase
@@ -795,8 +809,11 @@ fn is_camel_case(ident: ast::Ident) -> bool {
 
         fn to_camel_case(s: &str) -> String {
             s.split('_').flat_map(|word| word.chars().enumerate().map(|(i, c)|
-                if i == 0 { c.to_uppercase() }
-                else { c }
+                if i == 0 {
+                    c.to_uppercase()
+                } else {
+                    c
+                }
             )).collect()
         }
 
@@ -820,11 +837,13 @@ fn get_lints(&self) -> LintArray {
     }
 
     fn check_item(&mut self, cx: &Context, it: &ast::Item) {
-        let has_extern_repr = it.attrs.iter().map(|attr| {
+        let has_extern_repr = it.attrs.iter().any(|attr| {
             attr::find_repr_attrs(cx.tcx.sess.diagnostic(), attr).iter()
                 .any(|r| r == &attr::ReprExtern)
-        }).any(|x| x);
-        if has_extern_repr { return }
+        });
+        if has_extern_repr {
+            return;
+        }
 
         match it.node {
             ast::ItemTy(..) | ast::ItemStruct(..) => {
@@ -834,7 +853,9 @@ fn check_item(&mut self, cx: &Context, it: &ast::Item) {
                 self.check_case(cx, "trait", it.ident, it.span)
             }
             ast::ItemEnum(ref enum_definition, _) => {
-                if has_extern_repr { return }
+                if has_extern_repr {
+                    return;
+                }
                 self.check_case(cx, "type", it.ident, it.span);
                 for variant in &enum_definition.variants {
                     self.check_case(cx, "variant", variant.node.name, variant.span);
@@ -866,32 +887,28 @@ fn method_context(cx: &Context, m: &ast::Method) -> MethodContext {
 
     match cx.tcx.impl_or_trait_items.borrow().get(&did).cloned() {
         None => cx.sess().span_bug(m.span, "missing method descriptor?!"),
-        Some(md) => {
-            match md {
-                ty::MethodTraitItem(md) => {
-                    match md.container {
-                        ty::TraitContainer(..) => TraitDefaultImpl,
-                        ty::ImplContainer(cid) => {
-                            match ty::impl_trait_ref(cx.tcx, cid) {
-                                Some(..) => TraitImpl,
-                                None => PlainImpl
-                            }
-                        }
+        Some(ty::MethodTraitItem(md)) => {
+            match md.container {
+                ty::TraitContainer(..) => MethodContext::TraitDefaultImpl,
+                ty::ImplContainer(cid) => {
+                    match ty::impl_trait_ref(cx.tcx, cid) {
+                        Some(..) => MethodContext::TraitImpl,
+                        None => MethodContext::PlainImpl
                     }
                 }
-                ty::TypeTraitItem(typedef) => {
-                    match typedef.container {
-                        ty::TraitContainer(..) => TraitDefaultImpl,
-                        ty::ImplContainer(cid) => {
-                            match ty::impl_trait_ref(cx.tcx, cid) {
-                                Some(..) => TraitImpl,
-                                None => PlainImpl
-                            }
-                        }
+            }
+        },
+        Some(ty::TypeTraitItem(typedef)) => {
+            match typedef.container {
+                ty::TraitContainer(..) => MethodContext::TraitDefaultImpl,
+                ty::ImplContainer(cid) => {
+                    match ty::impl_trait_ref(cx.tcx, cid) {
+                        Some(..) => MethodContext::TraitImpl,
+                        None => MethodContext::PlainImpl
                     }
                 }
             }
-        }
+        },
     }
 }
 
@@ -912,12 +929,16 @@ fn to_snake_case(mut str: &str) -> String {
             if c == '_' {
                 words.push(String::new());
                 true
-            } else { false }
+            } else {
+                false
+            }
         });
         for s in str.split('_') {
             let mut last_upper = false;
             let mut buf = String::new();
-            if s.is_empty() { continue; }
+            if s.is_empty() {
+                continue;
+            }
             for ch in s.chars() {
                 if !buf.is_empty() && buf != "'"
                                    && ch.is_uppercase()
@@ -936,7 +957,9 @@ fn to_snake_case(mut str: &str) -> String {
     fn check_snake_case(&self, cx: &Context, sort: &str, ident: ast::Ident, span: Span) {
         fn is_snake_case(ident: ast::Ident) -> bool {
             let ident = token::get_ident(ident);
-            if ident.is_empty() { return true; }
+            if ident.is_empty() {
+                return true;
+            }
             let ident = ident.trim_left_matches('\'');
             let ident = ident.trim_matches('_');
 
@@ -979,14 +1002,17 @@ fn check_fn(&mut self, cx: &Context,
                 _: &ast::Block, span: Span, _: ast::NodeId) {
         match fk {
             visit::FkMethod(ident, _, m) => match method_context(cx, m) {
-                PlainImpl
-                    => self.check_snake_case(cx, "method", ident, span),
-                TraitDefaultImpl
-                    => self.check_snake_case(cx, "trait method", ident, span),
+                MethodContext::PlainImpl => {
+                    self.check_snake_case(cx, "method", ident, span)
+                },
+                MethodContext::TraitDefaultImpl => {
+                    self.check_snake_case(cx, "trait method", ident, span)
+                },
                 _ => (),
             },
-            visit::FkItemFn(ident, _, _, _)
-                => self.check_snake_case(cx, "function", ident, span),
+            visit::FkItemFn(ident, _, _, _) => {
+                self.check_snake_case(cx, "function", ident, span)
+            },
             _ => (),
         }
     }
@@ -1015,7 +1041,7 @@ fn check_pat(&mut self, cx: &Context, p: &ast::Pat) {
     }
 
     fn check_struct_def(&mut self, cx: &Context, s: &ast::StructDef,
-            _: ast::Ident, _: &ast::Generics, _: ast::NodeId) {
+                        _: ast::Ident, _: &ast::Generics, _: ast::NodeId) {
         for sf in &s.fields {
             if let ast::StructField_ { kind: ast::NamedField(ident, _), .. } = sf.node {
                 self.check_snake_case(cx, "structure field", ident, sf.span);
@@ -1094,13 +1120,12 @@ fn check_pat(&mut self, cx: &Context, p: &ast::Pat) {
 
 impl UnusedParens {
     fn check_unused_parens_core(&self, cx: &Context, value: &ast::Expr, msg: &str,
-                                     struct_lit_needs_parens: bool) {
+                                struct_lit_needs_parens: bool) {
         if let ast::ExprParen(ref inner) = value.node {
             let necessary = struct_lit_needs_parens && contains_exterior_struct_lit(&**inner);
             if !necessary {
                 cx.span_lint(UNUSED_PARENS, value.span,
-                             &format!("unnecessary parentheses around {}",
-                                     msg))
+                             &format!("unnecessary parentheses around {}", msg))
             }
         }
 
@@ -1193,26 +1218,17 @@ fn get_lints(&self) -> LintArray {
     }
 
     fn check_item(&mut self, cx: &Context, item: &ast::Item) {
-        match item.node {
-            ast::ItemUse(ref view_path) => {
-                match view_path.node {
-                    ast::ViewPathList(_, ref items) => {
-                        if items.len() == 1 {
-                            match items[0].node {
-                                ast::PathListIdent {ref name, ..} => {
-                                    let m = format!("braces around {} is unnecessary",
-                                                    &token::get_ident(*name));
-                                    cx.span_lint(UNUSED_IMPORT_BRACES, item.span,
-                                                 &m[..]);
-                                },
-                                _ => ()
-                            }
-                        }
+        if let ast::ItemUse(ref view_path) = item.node {
+            if let ast::ViewPathList(_, ref items) = view_path.node {
+                if items.len() == 1 {
+                    if let ast::PathListIdent {ref name, ..} = items[0].node {
+                        let m = format!("braces around {} is unnecessary",
+                                        &token::get_ident(*name));
+                        cx.span_lint(UNUSED_IMPORT_BRACES, item.span,
+                                     &m[..]);
                     }
-                    _ => ()
                 }
-            },
-            _ => ()
+            }
         }
     }
 }
@@ -1234,9 +1250,10 @@ fn get_lints(&self) -> LintArray {
     fn check_pat(&mut self, cx: &Context, pat: &ast::Pat) {
         let def_map = cx.tcx.def_map.borrow();
         if let ast::PatStruct(_, ref v, _) = pat.node {
-            let field_pats = v.iter()
-                              .filter(|fieldpat| !fieldpat.node.is_shorthand)
-                              .filter(|fieldpat| {
+            let field_pats = v.iter().filter(|fieldpat| {
+                if fieldpat.node.is_shorthand {
+                    return false;
+                }
                 let def = def_map.get(&fieldpat.node.pat.id).map(|d| d.full_def());
                 def == Some(def::DefLocal(fieldpat.node.pat.id))
             });
@@ -1482,10 +1499,14 @@ fn check_missing_docs_attrs(&self,
                                desc: &'static str) {
         // If we're building a test harness, then warning about
         // documentation is probably not really relevant right now.
-        if cx.sess().opts.test { return }
+        if cx.sess().opts.test {
+            return;
+        }
 
         // `#[doc(hidden)]` disables missing_docs check.
-        if self.doc_hidden() { return }
+        if self.doc_hidden() {
+            return;
+        }
 
         // Only check publicly-visible items, using the result from the privacy pass.
         // It's an option so the crate root can also use this function (it doesn't
@@ -1504,7 +1525,7 @@ fn check_missing_docs_attrs(&self,
         });
         if !has_doc {
             cx.span_lint(MISSING_DOCS, sp,
-                &format!("missing documentation for {}", desc));
+                         &format!("missing documentation for {}", desc));
         }
     }
 }
@@ -1528,20 +1549,19 @@ fn exit_lint_attrs(&mut self, _: &Context, _: &[ast::Attribute]) {
         self.doc_hidden_stack.pop().expect("empty doc_hidden_stack");
     }
 
-    fn check_struct_def(&mut self, _: &Context,
-        _: &ast::StructDef, _: ast::Ident, _: &ast::Generics, id: ast::NodeId) {
+    fn check_struct_def(&mut self, _: &Context, _: &ast::StructDef,
+                        _: ast::Ident, _: &ast::Generics, id: ast::NodeId) {
         self.struct_def_stack.push(id);
     }
 
-    fn check_struct_def_post(&mut self, _: &Context,
-        _: &ast::StructDef, _: ast::Ident, _: &ast::Generics, id: ast::NodeId) {
+    fn check_struct_def_post(&mut self, _: &Context, _: &ast::StructDef,
+                             _: ast::Ident, _: &ast::Generics, id: ast::NodeId) {
         let popped = self.struct_def_stack.pop().expect("empty struct_def_stack");
         assert!(popped == id);
     }
 
     fn check_crate(&mut self, cx: &Context, krate: &ast::Crate) {
-        self.check_missing_docs_attrs(cx, None, &krate.attrs,
-                                     krate.span, "crate");
+        self.check_missing_docs_attrs(cx, None, &krate.attrs, krate.span, "crate");
     }
 
     fn check_item(&mut self, cx: &Context, it: &ast::Item) {
@@ -1554,30 +1574,28 @@ fn check_item(&mut self, cx: &Context, it: &ast::Item) {
             ast::ItemTy(..) => "a type alias",
             _ => return
         };
-        self.check_missing_docs_attrs(cx, Some(it.id), &it.attrs,
-                                     it.span, desc);
+        self.check_missing_docs_attrs(cx, Some(it.id), &it.attrs, it.span, desc);
     }
 
-    fn check_fn(&mut self, cx: &Context,
-            fk: visit::FnKind, _: &ast::FnDecl,
-            _: &ast::Block, _: Span, _: ast::NodeId) {
+    fn check_fn(&mut self, cx: &Context, fk: visit::FnKind, _: &ast::FnDecl,
+                _: &ast::Block, _: Span, _: ast::NodeId) {
         if let visit::FkMethod(_, _, m) = fk {
             // If the method is an impl for a trait, don't doc.
-            if method_context(cx, m) == TraitImpl { return; }
+            if method_context(cx, m) == MethodContext::TraitImpl {
+                return;
+            }
 
             // Otherwise, doc according to privacy. This will also check
             // doc for default methods defined on traits.
-            self.check_missing_docs_attrs(cx, Some(m.id), &m.attrs,
-                                          m.span, "a method");
+            self.check_missing_docs_attrs(cx, Some(m.id), &m.attrs, m.span, "a method");
         }
     }
 
     fn check_ty_method(&mut self, cx: &Context, tm: &ast::TypeMethod) {
-        self.check_missing_docs_attrs(cx, Some(tm.id), &tm.attrs,
-                                     tm.span, "a type method");
+        self.check_missing_docs_attrs(cx, Some(tm.id), &tm.attrs, tm.span, "a type method");
     }
 
-    fn check_trait_method(&mut self, cx: &Context, it: &ast::TraitItem) {
+    fn check_trait_item(&mut self, cx: &Context, it: &ast::TraitItem) {
         if let ast::TraitItem::TypeTraitItem(ref ty) = *it {
             let assoc_ty = &ty.ty_param;
             self.check_missing_docs_attrs(cx, Some(assoc_ty.id), &ty.attrs,
@@ -1598,8 +1616,7 @@ fn check_struct_field(&mut self, cx: &Context, sf: &ast::StructField) {
     }
 
     fn check_variant(&mut self, cx: &Context, v: &ast::Variant, _: &ast::Generics) {
-        self.check_missing_docs_attrs(cx, Some(v.node.id), &v.node.attrs,
-                                     v.span, "a variant");
+        self.check_missing_docs_attrs(cx, Some(v.node.id), &v.node.attrs, v.span, "a variant");
         assert!(!self.in_variant);
         self.in_variant = true;
     }
@@ -1626,18 +1643,18 @@ fn get_lints(&self) -> LintArray {
 
     fn check_item(&mut self, cx: &Context, item: &ast::Item) {
         if !cx.exported_items.contains(&item.id) {
-            return
+            return;
         }
         if cx.tcx
              .destructor_for_type
              .borrow()
              .contains_key(&ast_util::local_def(item.id)) {
-            return
+            return;
         }
         let ty = match item.node {
             ast::ItemStruct(_, ref ast_generics) => {
                 if ast_generics.is_parameterized() {
-                    return
+                    return;
                 }
                 ty::mk_struct(cx.tcx,
                               ast_util::local_def(item.id),
@@ -1645,7 +1662,7 @@ fn check_item(&mut self, cx: &Context, item: &ast::Item) {
             }
             ast::ItemEnum(_, ref ast_generics) => {
                 if ast_generics.is_parameterized() {
-                    return
+                    return;
                 }
                 ty::mk_enum(cx.tcx,
                             ast_util::local_def(item.id),
@@ -1655,7 +1672,7 @@ fn check_item(&mut self, cx: &Context, item: &ast::Item) {
         };
         let parameter_environment = ty::empty_parameter_environment(cx.tcx);
         if !ty::type_moves_by_default(&parameter_environment, item.span, ty) {
-            return
+            return;
         }
         if ty::can_type_implement_copy(&parameter_environment, item.span, ty).is_ok() {
             cx.span_lint(MISSING_COPY_IMPLEMENTATIONS,
@@ -1709,10 +1726,10 @@ fn check_item(&mut self, cx: &Context, item: &ast::Item) {
             let impls = match impls.get(&debug) {
                 Some(impls) => {
                     impls.borrow().iter()
-                        .filter(|d| d.krate == ast::LOCAL_CRATE)
-                        .filter_map(|d| ty::ty_to_def_id(ty::node_id_to_type(cx.tcx, d.node)))
-                        .map(|d| d.node)
-                        .collect()
+                         .filter(|d| d.krate == ast::LOCAL_CRATE)
+                         .filter_map(|d| ty::ty_to_def_id(ty::node_id_to_type(cx.tcx, d.node)))
+                         .map(|d| d.node)
+                         .collect()
                 }
                 None => NodeSet(),
             };
@@ -1741,8 +1758,7 @@ fn check_item(&mut self, cx: &Context, item: &ast::Item) {
 
 impl Stability {
     fn lint(&self, cx: &Context, _id: ast::DefId, span: Span, stability: &Option<attr::Stability>) {
-
-        // deprecated attributes apply in-crate and cross-crate
+        // Deprecated attributes apply in-crate and cross-crate.
         let (lint, label) = match *stability {
             Some(attr::Stability { deprecated_since: Some(_), .. }) =>
                 (DEPRECATED, "deprecated"),
@@ -1857,25 +1873,27 @@ fn check_fn(&mut self, cx: &Context, fn_kind: visit::FnKind, _: &ast::FnDecl,
         let mut visited = BitSet::new();
 
         while let Some(idx) = work_queue.pop() {
-            let cfg_id = idx.node_id();
             if idx == cfg.exit {
                 // found a path!
                 reached_exit_without_self_call = true;
-                break
-            } else if visited.contains(&cfg_id) {
+                break;
+            }
+
+            let cfg_id = idx.node_id();
+            if visited.contains(&cfg_id) {
                 // already done
-                continue
+                continue;
             }
             visited.insert(cfg_id);
+
             let node_id = cfg.graph.node_data(idx).id();
 
             // is this a recursive call?
             if node_id != ast::DUMMY_NODE_ID && checker(cx.tcx, impl_node_id, id, name, node_id) {
-
                 self_call_spans.push(cx.tcx.map.span(node_id));
                 // this is a self call, so we shouldn't explore past
                 // this node in the CFG.
-                continue
+                continue;
             }
             // add the successors of this node to explore the graph further.
             cfg.graph.each_outgoing_edge(idx, |_, edge| {
@@ -1888,7 +1906,7 @@ fn check_fn(&mut self, cx: &Context, fn_kind: visit::FnKind, _: &ast::FnDecl,
             });
         }
 
-        // check the number of sell calls because a function that
+        // Check the number of self calls because a function that
         // doesn't return (e.g. calls a `-> !` function or `loop { /*
         // no break */ }`) shouldn't be linted unless it actually
         // recurs.
@@ -1920,7 +1938,7 @@ fn id_refers_to_this_fn<'tcx>(tcx: &ty::ctxt<'tcx>,
                                       _: ast::Ident,
                                       id: ast::NodeId) -> bool {
             tcx.def_map.borrow().get(&id)
-                .map_or(false, |def| def.def_id() == ast_util::local_def(fn_id))
+               .map_or(false, |def| def.def_id() == ast_util::local_def(fn_id))
         }
 
         // check if the method call `id` refers to method `method_id`
@@ -1962,7 +1980,7 @@ fn id_refers_to_this_method<'tcx>(tcx: &ty::ctxt<'tcx>,
                                 tcx.map.span(id),
                                 "non-method call expr behaving like a method call?")
                         };
-                        // it matches if it comes from the same impl,
+                        // It matches if it comes from the same impl,
                         // and has the same method name.
                         return ast_util::is_local(impl_def_id)
                             && impl_def_id.node == impl_id
@@ -2013,7 +2031,7 @@ fn check_item(&mut self, cx: &Context, it: &ast::Item) {
 
         if decoder::get_plugin_registrar_fn(md.data()).is_some() {
             cx.span_lint(PLUGIN_AS_LIBRARY, it.span,
-                "compiler plugin used as an ordinary library");
+                         "compiler plugin used as an ordinary library");
         }
     }
 }
@@ -2069,7 +2087,7 @@ fn check_item(&mut self, cx: &Context, it: &ast::Item) {
                     // Const items do not refer to a particular location in memory, and therefore
                     // don't have anything to attach a symbol to
                     let msg = "const items should never be #[no_mangle], consider instead using \
-                        `pub static`";
+                               `pub static`";
                     cx.span_lint(NO_MANGLE_CONST_ITEMS, it.span, msg);
                 }
             }
@@ -2082,15 +2100,17 @@ fn check_item(&mut self, cx: &Context, it: &ast::Item) {
 #[derive(Copy)]
 pub struct UnstableFeatures;
 
-declare_lint!(UNSTABLE_FEATURES, Allow,
-              "enabling unstable features");
+declare_lint! {
+    UNSTABLE_FEATURES,
+    Allow,
+    "enabling unstable features"
+}
 
 impl LintPass for UnstableFeatures {
     fn get_lints(&self) -> LintArray {
         lint_array!(UNSTABLE_FEATURES)
     }
     fn check_attribute(&mut self, ctx: &Context, attr: &ast::Attribute) {
-        use syntax::attr;
         if attr::contains_name(&[attr.node.value.clone()], "feature") {
             ctx.span_lint(UNSTABLE_FEATURES, attr.span, "unstable feature");
         }
index a1fc63778ce8af858a5bda6b5a935b2c7fa81571..cd14fe529b1a7b45453c19a141c7d168116b2b5a 100644 (file)
@@ -851,7 +851,9 @@ pub fn run_passes(sess: &Session,
 
     // FIXME: time_llvm_passes support - does this use a global context or
     // something?
-    //if sess.time_llvm_passes() { llvm::LLVMRustPrintPassTimings(); }
+    if sess.opts.cg.codegen_units == 1 && sess.time_llvm_passes() {
+        unsafe { llvm::LLVMRustPrintPassTimings(); }
+    }
 }
 
 struct WorkItem {
index 48ff4c8332022aac0972c153eade715fbbe7be42..2ab6f5b0f952178b3637b9998fdb3d290b207c55 100644 (file)
@@ -789,7 +789,7 @@ fn pat_score(def_map: &DefMap, pat: &ast::Pat) -> uint {
 
         // Irrefutable columns always go first, they'd only be duplicated in the branches.
         if total_score == 0 {
-            std::uint::MAX
+            std::usize::MAX
         } else {
             total_score
         }
index b18b7b75d32fc1fc65acd2980779716b1d74ec33..1f578ac0bdbab2b8d80d354d73af7934cec02137 100644 (file)
@@ -433,13 +433,13 @@ pub fn set_inline_hint(f: ValueRef) {
 }
 
 pub fn set_llvm_fn_attrs(ccx: &CrateContext, attrs: &[ast::Attribute], llfn: ValueRef) {
-    use syntax::attr::*;
+    use syntax::attr::{find_inline_attr, InlineAttr};
     // Set the inline hint if there is one
     match find_inline_attr(Some(ccx.sess().diagnostic()), attrs) {
-        InlineHint   => set_inline_hint(llfn),
-        InlineAlways => set_always_inline(llfn),
-        InlineNever  => set_no_inline(llfn),
-        InlineNone   => { /* fallthrough */ }
+        InlineAttr::Hint   => set_inline_hint(llfn),
+        InlineAttr::Always => set_always_inline(llfn),
+        InlineAttr::Never  => set_no_inline(llfn),
+        InlineAttr::None   => { /* fallthrough */ }
     }
 
     for attr in attrs {
@@ -2332,6 +2332,11 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
           // Do static_assert checking. It can't really be done much earlier
           // because we need to get the value of the bool out of LLVM
           if attr::contains_name(&item.attrs, "static_assert") {
+              if !ty::type_is_bool(ty::expr_ty(ccx.tcx(), expr)) {
+                  ccx.sess().span_fatal(expr.span,
+                                        "can only have static_assert on a static \
+                                         with type `bool`");
+              }
               if m == ast::MutMutable {
                   ccx.sess().span_fatal(expr.span,
                                         "cannot have static_assert on a mutable \
@@ -2430,21 +2435,19 @@ pub fn get_fn_llvm_attributes<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_ty: Ty<
     use middle::ty::{BrAnon, ReLateBound};
 
     let function_type;
-    let (fn_sig, abi, has_env) = match fn_ty.sty {
-        ty::ty_bare_fn(_, ref f) => (&f.sig, f.abi, false),
+    let (fn_sig, abi, env_ty) = match fn_ty.sty {
+        ty::ty_bare_fn(_, ref f) => (&f.sig, f.abi, None),
         ty::ty_closure(closure_did, _, substs) => {
             let typer = common::NormalizingClosureTyper::new(ccx.tcx());
             function_type = typer.closure_type(closure_did, substs);
-            (&function_type.sig, RustCall, true)
+            let self_type = self_type_for_closure(ccx, closure_did, fn_ty);
+            (&function_type.sig, RustCall, Some(self_type))
         }
         _ => ccx.sess().bug("expected closure or function.")
     };
 
     let fn_sig = ty::erase_late_bound_regions(ccx.tcx(), fn_sig);
 
-    // Since index 0 is the return value of the llvm func, we start
-    // at either 1 or 2 depending on whether there's an env slot or not
-    let mut first_arg_offset = if has_env { 2 } else { 1 };
     let mut attrs = llvm::AttrBuilder::new();
     let ret_ty = fn_sig.output;
 
@@ -2455,7 +2458,11 @@ pub fn get_fn_llvm_attributes<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_ty: Ty<
             assert!(abi == RustCall);
 
             match fn_sig.inputs[0].sty {
-                ty::ty_tup(ref inputs) => inputs.clone(),
+                ty::ty_tup(ref inputs) => {
+                    let mut full_inputs = vec![env_ty.expect("Missing closure environment")];
+                    full_inputs.push_all(inputs);
+                    full_inputs
+                }
                 _ => ccx.sess().bug("expected tuple'd inputs")
             }
         },
@@ -2473,6 +2480,8 @@ pub fn get_fn_llvm_attributes<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_ty: Ty<
         _ => fn_sig.inputs.clone()
     };
 
+    // Index 0 is the return value of the llvm func, so we start at 1
+    let mut first_arg_offset = 1;
     if let ty::FnConverging(ret_ty) = ret_ty {
         // A function pointer is called without the declaration
         // available, so we have to apply any attributes with ABI
index 4f234fac9a4a0e65dba0040513c2e2d83a08c8fb..861233bafdfac01405d6a51f847d5af276bcc7ab 100644 (file)
@@ -603,7 +603,18 @@ pub fn trans_method_call<'a, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let _icx = push_ctxt("trans_method_call");
     debug!("trans_method_call(call_expr={})", call_expr.repr(bcx.tcx()));
     let method_call = MethodCall::expr(call_expr.id);
-    let method_ty = (*bcx.tcx().method_map.borrow())[method_call].ty;
+    let method_ty = match bcx.tcx().method_map.borrow().get(&method_call) {
+        Some(method) => match method.origin {
+            ty::MethodTraitObject(_) => match method.ty.sty {
+                ty::ty_bare_fn(_, ref fty) => {
+                    ty::mk_bare_fn(bcx.tcx(), None, meth::opaque_method_ty(bcx.tcx(), fty))
+                }
+                _ => method.ty
+            },
+            _ => method.ty
+        },
+        None => panic!("method not found in trans_method_call")
+    };
     trans_call_inner(
         bcx,
         call_expr.debug_loc(),
@@ -927,20 +938,21 @@ fn trans_args_under_call_abi<'blk, 'tcx>(
                                                           tuple_expr.id));
             let repr = adt::represent_type(bcx.ccx(), tuple_type);
             let repr_ptr = &*repr;
-            for i in 0..field_types.len() {
+            llargs.extend(field_types.iter().enumerate().map(|(i, field_type)| {
                 let arg_datum = tuple_lvalue_datum.get_element(
                     bcx,
-                    field_types[i],
+                    field_type,
                     |srcval| {
                         adt::trans_field_ptr(bcx, repr_ptr, srcval, 0, i)
-                    });
-                let arg_datum = arg_datum.to_expr_datum();
-                let arg_datum =
-                    unpack_datum!(bcx, arg_datum.to_rvalue_datum(bcx, "arg"));
-                let arg_datum =
-                    unpack_datum!(bcx, arg_datum.to_appropriate_datum(bcx));
-                llargs.push(arg_datum.add_clean(bcx.fcx, arg_cleanup_scope));
-            }
+                    }).to_expr_datum();
+                unpack_result!(bcx, trans_arg_datum(
+                    bcx,
+                    field_type,
+                    arg_datum,
+                    arg_cleanup_scope,
+                    DontAutorefArg)
+                )
+            }));
         }
         _ => {
             bcx.sess().span_bug(tuple_expr.span,
index 4423cd2774446a8df5dea1bb2aa5ebabc706f485..67f1c39c6e094f114d4f2b7a423bc1e6557442cb 100644 (file)
@@ -589,15 +589,16 @@ pub fn trans_object_shim<'a, 'tcx>(
     };
     let fty = monomorphize::apply_param_substs(tcx, &object_substs, &method_ty.fty);
     let fty = tcx.mk_bare_fn(fty);
-    debug!("trans_object_shim: fty={}", fty.repr(tcx));
+    let method_ty = opaque_method_ty(tcx, fty);
+    debug!("trans_object_shim: fty={} method_ty={}", fty.repr(tcx), method_ty.repr(tcx));
 
     //
-    let method_bare_fn_ty =
-        ty::mk_bare_fn(tcx, None, fty);
+    let shim_fn_ty = ty::mk_bare_fn(tcx, None, fty);
+    let method_bare_fn_ty = ty::mk_bare_fn(tcx, None, method_ty);
     let function_name =
-        link::mangle_internal_name_by_type_and_seq(ccx, method_bare_fn_ty, "object_shim");
+        link::mangle_internal_name_by_type_and_seq(ccx, shim_fn_ty, "object_shim");
     let llfn =
-        decl_internal_rust_fn(ccx, method_bare_fn_ty, &function_name);
+        decl_internal_rust_fn(ccx, shim_fn_ty, &function_name);
 
     let sig = ty::erase_late_bound_regions(ccx.tcx(), &fty.sig);
 
@@ -866,3 +867,20 @@ pub fn trans_trait_cast<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
     bcx
 }
+
+/// Replace the self type (&Self or Box<Self>) with an opaque pointer.
+pub fn opaque_method_ty<'tcx>(tcx: &ty::ctxt<'tcx>, method_ty: &ty::BareFnTy<'tcx>)
+        -> &'tcx ty::BareFnTy<'tcx> {
+    let mut inputs = method_ty.sig.0.inputs.clone();
+    inputs[0] = ty::mk_mut_ptr(tcx, ty::mk_mach_int(tcx, ast::TyI8));
+
+    tcx.mk_bare_fn(ty::BareFnTy {
+        unsafety: method_ty.unsafety,
+        abi: method_ty.abi,
+        sig: ty::Binder(ty::FnSig {
+            inputs: inputs,
+            output: method_ty.sig.0.output,
+            variadic: method_ty.sig.0.variadic,
+        }),
+    })
+}
index 083523f7ba92f97fce223becfadf59dccc1003e7..cffd74ccd7218c3da9458131a756bfd3e1578cb6 100644 (file)
@@ -14,8 +14,9 @@
 use middle::region;
 use middle::subst;
 use middle::ty::{self, Ty};
-use util::ppaux::{Repr};
+use util::ppaux::{Repr, UserString};
 
+use syntax::ast;
 use syntax::codemap::Span;
 
 pub fn check_safety_of_destructor_if_necessary<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>,
@@ -28,29 +29,98 @@ pub fn check_safety_of_destructor_if_necessary<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>
     // types that have been traversed so far by `traverse_type_if_unseen`
     let mut breadcrumbs: Vec<Ty<'tcx>> = Vec::new();
 
-    iterate_over_potentially_unsafe_regions_in_type(
+    let result = iterate_over_potentially_unsafe_regions_in_type(
         rcx,
         &mut breadcrumbs,
+        TypeContext::Root,
         typ,
         span,
         scope,
+        0,
         0);
+    match result {
+        Ok(()) => {}
+        Err(Error::Overflow(ref ctxt, ref detected_on_typ)) => {
+            let tcx = rcx.tcx();
+            span_err!(tcx.sess, span, E0320,
+                      "overflow while adding drop-check rules for {}",
+                      typ.user_string(rcx.tcx()));
+            match *ctxt {
+                TypeContext::Root => {
+                    // no need for an additional note if the overflow
+                    // was somehow on the root.
+                }
+                TypeContext::EnumVariant { def_id, variant, arg_index } => {
+                    // FIXME (pnkfelix): eventually lookup arg_name
+                    // for the given index on struct variants.
+                    span_note!(
+                        rcx.tcx().sess,
+                        span,
+                        "overflowed on enum {} variant {} argument {} type: {}",
+                        ty::item_path_str(tcx, def_id),
+                        variant,
+                        arg_index,
+                        detected_on_typ.user_string(rcx.tcx()));
+                }
+                TypeContext::Struct { def_id, field } => {
+                    span_note!(
+                        rcx.tcx().sess,
+                        span,
+                        "overflowed on struct {} field {} type: {}",
+                        ty::item_path_str(tcx, def_id),
+                        field,
+                        detected_on_typ.user_string(rcx.tcx()));
+                }
+            }
+        }
+    }
+}
+
+enum Error<'tcx> {
+    Overflow(TypeContext, ty::Ty<'tcx>),
+}
+
+enum TypeContext {
+    Root,
+    EnumVariant {
+        def_id: ast::DefId,
+        variant: ast::Name,
+        arg_index: usize,
+    },
+    Struct {
+        def_id: ast::DefId,
+        field: ast::Name,
+    }
 }
 
+// The `depth` counts the number of calls to this function;
+// the `xref_depth` counts the subset of such calls that go
+// across a `Box<T>` or `PhantomData<T>`.
 fn iterate_over_potentially_unsafe_regions_in_type<'a, 'tcx>(
     rcx: &mut Rcx<'a, 'tcx>,
     breadcrumbs: &mut Vec<Ty<'tcx>>,
+    context: TypeContext,
     ty_root: ty::Ty<'tcx>,
     span: Span,
     scope: region::CodeExtent,
-    depth: uint)
+    depth: uint,
+    xref_depth: uint) -> Result<(), Error<'tcx>>
 {
+    // Issue #22443: Watch out for overflow. While we are careful to
+    // handle regular types properly, non-regular ones cause problems.
+    let recursion_limit = rcx.tcx().sess.recursion_limit.get();
+    if xref_depth >= recursion_limit {
+        return Err(Error::Overflow(context, ty_root))
+    }
+
     let origin = || infer::SubregionOrigin::SafeDestructor(span);
     let mut walker = ty_root.walk();
     let opt_phantom_data_def_id = rcx.tcx().lang_items.phantom_data();
 
     let destructor_for_type = rcx.tcx().destructor_for_type.borrow();
 
+    let xref_depth_orig = xref_depth;
+
     while let Some(typ) = walker.next() {
         // Avoid recursing forever.
         if breadcrumbs.contains(&typ) {
@@ -61,20 +131,33 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'tcx>(
         // If we encounter `PhantomData<T>`, then we should replace it
         // with `T`, the type it represents as owned by the
         // surrounding context, before doing further analysis.
-        let typ = if let ty::ty_struct(struct_did, substs) = typ.sty {
-            if opt_phantom_data_def_id == Some(struct_did) {
-                let item_type = ty::lookup_item_type(rcx.tcx(), struct_did);
-                let tp_def = item_type.generics.types
-                    .opt_get(subst::TypeSpace, 0).unwrap();
-                let new_typ = substs.type_for_def(tp_def);
-                debug!("replacing phantom {} with {}",
+        let (typ, xref_depth) = match typ.sty {
+            ty::ty_struct(struct_did, substs) => {
+                if opt_phantom_data_def_id == Some(struct_did) {
+                    let item_type = ty::lookup_item_type(rcx.tcx(), struct_did);
+                    let tp_def = item_type.generics.types
+                        .opt_get(subst::TypeSpace, 0).unwrap();
+                    let new_typ = substs.type_for_def(tp_def);
+                    debug!("replacing phantom {} with {}",
+                           typ.repr(rcx.tcx()), new_typ.repr(rcx.tcx()));
+                    (new_typ, xref_depth_orig + 1)
+                } else {
+                    (typ, xref_depth_orig)
+                }
+            }
+
+            // Note: When ty_uniq is removed from compiler, the
+            // definition of `Box<T>` must carry a PhantomData that
+            // puts us into the previous case.
+            ty::ty_uniq(new_typ) => {
+                debug!("replacing ty_uniq {} with {}",
                        typ.repr(rcx.tcx()), new_typ.repr(rcx.tcx()));
-                new_typ
-            } else {
-                typ
+                (new_typ, xref_depth_orig + 1)
+            }
+
+            _ => {
+                (typ, xref_depth_orig)
             }
-        } else {
-            typ
         };
 
         let opt_type_did = match typ.sty {
@@ -87,9 +170,9 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'tcx>(
             opt_type_did.and_then(|did| destructor_for_type.get(&did));
 
         debug!("iterate_over_potentially_unsafe_regions_in_type \
-                {}typ: {} scope: {:?} opt_dtor: {:?}",
+                {}typ: {} scope: {:?} opt_dtor: {:?} xref: {}",
                (0..depth).map(|_| ' ').collect::<String>(),
-               typ.repr(rcx.tcx()), scope, opt_dtor);
+               typ.repr(rcx.tcx()), scope, opt_dtor, xref_depth);
 
         // If `typ` has a destructor, then we must ensure that all
         // borrowed data reachable via `typ` must outlive the parent
@@ -228,6 +311,8 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'tcx>(
 
             match typ.sty {
                 ty::ty_struct(struct_did, substs) => {
+                    debug!("typ: {} is struct; traverse structure and not type-expression",
+                           typ.repr(rcx.tcx()));
                     // Don't recurse; we extract type's substructure,
                     // so do not process subparts of type expression.
                     walker.skip_current_subtree();
@@ -240,17 +325,24 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'tcx>(
                                                   struct_did,
                                                   field.id,
                                                   substs);
-                        iterate_over_potentially_unsafe_regions_in_type(
+                        try!(iterate_over_potentially_unsafe_regions_in_type(
                             rcx,
                             breadcrumbs,
+                            TypeContext::Struct {
+                                def_id: struct_did,
+                                field: field.name,
+                            },
                             field_type,
                             span,
                             scope,
-                            depth+1)
+                            depth+1,
+                            xref_depth))
                     }
                 }
 
                 ty::ty_enum(enum_did, substs) => {
+                    debug!("typ: {} is enum; traverse structure and not type-expression",
+                           typ.repr(rcx.tcx()));
                     // Don't recurse; we extract type's substructure,
                     // so do not process subparts of type expression.
                     walker.skip_current_subtree();
@@ -260,14 +352,20 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'tcx>(
                                                  enum_did,
                                                  substs);
                     for variant_info in all_variant_info.iter() {
-                        for argument_type in variant_info.args.iter() {
-                            iterate_over_potentially_unsafe_regions_in_type(
+                        for (i, arg_type) in variant_info.args.iter().enumerate() {
+                            try!(iterate_over_potentially_unsafe_regions_in_type(
                                 rcx,
                                 breadcrumbs,
-                                *argument_type,
+                                TypeContext::EnumVariant {
+                                    def_id: enum_did,
+                                    variant: variant_info.name,
+                                    arg_index: i,
+                                },
+                                *arg_type,
                                 span,
                                 scope,
-                                depth+1)
+                                depth+1,
+                                xref_depth));
                         }
                     }
                 }
@@ -290,4 +388,6 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'tcx>(
             // is done.
         }
     }
+
+    return Ok(());
 }
index 7b43a9fef06dcd36d604f5b42425fd42b3cecf72..3bd15fbc7dbea774fb55ebad140bd1ab85fed0ff 100644 (file)
     E0249, // expected constant expr for array length
     E0250, // expected constant expr for array length
     E0318, // can't create default impls for traits outside their crates
-    E0319  // trait impls for defaulted traits allowed just for structs/enums
+    E0319, // trait impls for defaulted traits allowed just for structs/enums
+    E0320  // recursive overflow during dropck
 }
 
 __build_diagnostic_array! { DIAGNOSTICS }
diff --git a/src/libstd/io/lazy.rs b/src/libstd/io/lazy.rs
new file mode 100644 (file)
index 0000000..c9b105f
--- /dev/null
@@ -0,0 +1,59 @@
+// 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.
+
+use prelude::v1::*;
+
+use boxed;
+use cell::UnsafeCell;
+use rt;
+use sync::{StaticMutex, Arc};
+
+pub struct Lazy<T> {
+    pub lock: StaticMutex,
+    pub ptr: UnsafeCell<*mut Arc<T>>,
+    pub init: fn() -> Arc<T>,
+}
+
+unsafe impl<T> Sync for Lazy<T> {}
+
+macro_rules! lazy_init {
+    ($init:expr) => (::io::lazy::Lazy {
+        lock: ::sync::MUTEX_INIT,
+        ptr: ::cell::UnsafeCell { value: 0 as *mut _ },
+        init: $init,
+    })
+}
+
+impl<T: Send + Sync + 'static> Lazy<T> {
+    pub fn get(&'static self) -> Option<Arc<T>> {
+        let _g = self.lock.lock();
+        unsafe {
+            let mut ptr = *self.ptr.get();
+            if ptr.is_null() {
+                ptr = boxed::into_raw(self.init());
+                *self.ptr.get() = ptr;
+            } else if ptr as usize == 1 {
+                return None
+            }
+            Some((*ptr).clone())
+        }
+    }
+
+    fn init(&'static self) -> Box<Arc<T>> {
+        rt::at_exit(move || unsafe {
+            let g = self.lock.lock();
+            let ptr = *self.ptr.get();
+            *self.ptr.get() = 1 as *mut _;
+            drop(g);
+            drop(Box::from_raw(ptr))
+        });
+        Box::new((self.init)())
+    }
+}
index 3b4e15953c4613958adfea8d2015625ae32e0017..5510c0203e6cff3c3af5e7c487cf2ad2112ba909 100644 (file)
 pub use self::cursor::Cursor;
 pub use self::error::{Result, Error, ErrorKind};
 pub use self::util::{copy, sink, Sink, empty, Empty, repeat, Repeat};
+pub use self::stdio::{stdin, stdout, stderr, Stdin, Stdout, Stderr};
+pub use self::stdio::{StdoutLock, StderrLock, StdinLock};
+
+#[macro_use] mod lazy;
 
 pub mod prelude;
 mod buffered;
@@ -46,6 +50,7 @@
 mod error;
 mod impls;
 mod util;
+mod stdio;
 
 const DEFAULT_BUF_SIZE: usize = 64 * 1024;
 
diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs
new file mode 100644 (file)
index 0000000..61ad990
--- /dev/null
@@ -0,0 +1,325 @@
+// 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.
+
+use prelude::v1::*;
+use io::prelude::*;
+
+use cmp;
+use fmt;
+use io::lazy::Lazy;
+use io::{self, BufReader, LineWriter};
+use sync::{Arc, Mutex, MutexGuard};
+use sys::stdio;
+
+/// A handle to a raw instance of the standard input stream of this process.
+///
+/// This handle is not synchronized or buffered in any fashion. Constructed via
+/// the `std::io::stdin_raw` function.
+pub struct StdinRaw(stdio::Stdin);
+
+/// A handle to a raw instance of the standard output stream of this process.
+///
+/// This handle is not synchronized or buffered in any fashion. Constructed via
+/// the `std::io::stdout_raw` function.
+pub struct StdoutRaw(stdio::Stdout);
+
+/// A handle to a raw instance of the standard output stream of this process.
+///
+/// This handle is not synchronized or buffered in any fashion. Constructed via
+/// the `std::io::stderr_raw` function.
+pub struct StderrRaw(stdio::Stderr);
+
+/// Construct a new raw handle to the standard input of this process.
+///
+/// The returned handle does not interact with any other handles created nor
+/// handles returned by `std::io::stdin`. Data buffered by the `std::io::stdin`
+/// handles is **not** available to raw handles returned from this function.
+///
+/// The returned handle has no external synchronization or buffering.
+pub fn stdin_raw() -> StdinRaw { StdinRaw(stdio::Stdin::new()) }
+
+/// Construct a new raw handle to the standard input stream of this process.
+///
+/// The returned handle does not interact with any other handles created nor
+/// handles returned by `std::io::stdout`. Note that data is buffered by the
+/// `std::io::stdin` handles so writes which happen via this raw handle may
+/// appear before previous writes.
+///
+/// The returned handle has no external synchronization or buffering layered on
+/// top.
+pub fn stdout_raw() -> StdoutRaw { StdoutRaw(stdio::Stdout::new()) }
+
+/// Construct a new raw handle to the standard input stream of this process.
+///
+/// The returned handle does not interact with any other handles created nor
+/// handles returned by `std::io::stdout`.
+///
+/// The returned handle has no external synchronization or buffering layered on
+/// top.
+pub fn stderr_raw() -> StderrRaw { StderrRaw(stdio::Stderr::new()) }
+
+impl Read for StdinRaw {
+    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.0.read(buf) }
+}
+impl Write for StdoutRaw {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) }
+    fn flush(&mut self) -> io::Result<()> { Ok(()) }
+}
+impl Write for StderrRaw {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) }
+    fn flush(&mut self) -> io::Result<()> { Ok(()) }
+}
+
+/// A handle to the standard input stream of a process.
+///
+/// Each handle is a shared reference to a global buffer of input data to this
+/// process. A handle can be `lock`'d to gain full access to `BufRead` methods
+/// (e.g. `.lines()`). Writes to this handle are otherwise locked with respect
+/// to other writes.
+///
+/// This handle implements the `Read` trait, but beware that concurrent reads
+/// of `Stdin` must be executed with care.
+pub struct Stdin {
+    inner: Arc<Mutex<BufReader<StdinRaw>>>,
+}
+
+/// A locked reference to the a `Stdin` handle.
+///
+/// This handle implements both the `Read` and `BufRead` traits and is
+/// constructed via the `lock` method on `Stdin`.
+pub struct StdinLock<'a> {
+    inner: MutexGuard<'a, BufReader<StdinRaw>>,
+}
+
+/// Create a new handle to the global standard input stream of this process.
+///
+/// The handle returned refers to a globally shared buffer between all threads.
+/// Access is synchronized and can be explicitly controlled with the `lock()`
+/// method.
+///
+/// The `Read` trait is implemented for the returned value but the `BufRead`
+/// trait is not due to the global nature of the standard input stream. The
+/// locked version, `StdinLock`, implements both `Read` and `BufRead`, however.
+///
+/// To avoid locking and buffering altogether, it is recommended to use the
+/// `stdin_raw` constructor.
+pub fn stdin() -> Stdin {
+    static INSTANCE: Lazy<Mutex<BufReader<StdinRaw>>> = lazy_init!(stdin_init);
+    return Stdin {
+        inner: INSTANCE.get().expect("cannot access stdin during shutdown"),
+    };
+
+    fn stdin_init() -> Arc<Mutex<BufReader<StdinRaw>>> {
+        // The default buffer capacity is 64k, but apparently windows
+        // doesn't like 64k reads on stdin. See #13304 for details, but the
+        // idea is that on windows we use a slightly smaller buffer that's
+        // been seen to be acceptable.
+        Arc::new(Mutex::new(if cfg!(windows) {
+            BufReader::with_capacity(8 * 1024, stdin_raw())
+        } else {
+            BufReader::new(stdin_raw())
+        }))
+    }
+}
+
+impl Stdin {
+    /// Lock this handle to the standard input stream, returning a readable
+    /// guard.
+    ///
+    /// The lock is released when the returned lock goes out of scope. The
+    /// returned guard also implements the `Read` and `BufRead` traits for
+    /// accessing the underlying data.
+    pub fn lock(&self) -> StdinLock {
+        StdinLock { inner: self.inner.lock().unwrap() }
+    }
+}
+
+impl Read for Stdin {
+    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+        self.lock().read(buf)
+    }
+
+    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<()> {
+        self.lock().read_to_end(buf)
+    }
+
+    fn read_to_string(&mut self, buf: &mut String) -> io::Result<()> {
+        self.lock().read_to_string(buf)
+    }
+}
+
+impl<'a> Read for StdinLock<'a> {
+    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+        // Flush stdout so that weird issues like a print!'d prompt not being
+        // shown until after the user hits enter.
+        drop(stdout().flush());
+        self.inner.read(buf)
+    }
+}
+impl<'a> BufRead for StdinLock<'a> {
+    fn fill_buf(&mut self) -> io::Result<&[u8]> { self.inner.fill_buf() }
+    fn consume(&mut self, n: usize) { self.inner.consume(n) }
+}
+
+// As with stdin on windows, stdout often can't handle writes of large
+// sizes. For an example, see #14940. For this reason, don't try to
+// write the entire output buffer on windows. On unix we can just
+// write the whole buffer all at once.
+//
+// For some other references, it appears that this problem has been
+// encountered by others [1] [2]. We choose the number 8KB just because
+// libuv does the same.
+//
+// [1]: https://tahoe-lafs.org/trac/tahoe-lafs/ticket/1232
+// [2]: http://www.mail-archive.com/log4net-dev@logging.apache.org/msg00661.html
+#[cfg(windows)]
+const OUT_MAX: usize = 8192;
+#[cfg(unix)]
+const OUT_MAX: usize = ::usize::MAX;
+
+/// A handle to the global standard output stream of the current process.
+///
+/// Each handle shares a global buffer of data to be written to the standard
+/// output stream. Access is also synchronized via a lock and explicit control
+/// over locking is available via the `lock` method.
+pub struct Stdout {
+    // FIXME: this should be LineWriter or BufWriter depending on the state of
+    //        stdout (tty or not). Note that if this is not line buffered it
+    //        should also flush-on-panic or some form of flush-on-abort.
+    inner: Arc<Mutex<LineWriter<StdoutRaw>>>,
+}
+
+/// A locked reference to the a `Stdout` handle.
+///
+/// This handle implements the `Write` trait and is constructed via the `lock`
+/// method on `Stdout`.
+pub struct StdoutLock<'a> {
+    inner: MutexGuard<'a, LineWriter<StdoutRaw>>,
+}
+
+/// Constructs a new reference to the standard output of the current process.
+///
+/// Each handle returned is a reference to a shared global buffer whose access
+/// is synchronized via a mutex. Explicit control over synchronization is
+/// provided via the `lock` method.
+///
+/// The returned handle implements the `Write` trait.
+///
+/// To avoid locking and buffering altogether, it is recommended to use the
+/// `stdout_raw` constructor.
+pub fn stdout() -> Stdout {
+    static INSTANCE: Lazy<Mutex<LineWriter<StdoutRaw>>> = lazy_init!(stdout_init);
+    return Stdout {
+        inner: INSTANCE.get().expect("cannot access stdout during shutdown"),
+    };
+
+    fn stdout_init() -> Arc<Mutex<LineWriter<StdoutRaw>>> {
+        Arc::new(Mutex::new(LineWriter::new(stdout_raw())))
+    }
+}
+
+impl Stdout {
+    /// Lock this handle to the standard output stream, returning a writable
+    /// guard.
+    ///
+    /// The lock is released when the returned lock goes out of scope. The
+    /// returned guard also implements the `Write` trait for writing data.
+    pub fn lock(&self) -> StdoutLock {
+        StdoutLock { inner: self.inner.lock().unwrap() }
+    }
+}
+
+impl Write for Stdout {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        self.lock().write(buf)
+    }
+    fn flush(&mut self) -> io::Result<()> {
+        self.lock().flush()
+    }
+    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
+        self.lock().write_all(buf)
+    }
+    fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> {
+        self.lock().write_fmt(fmt)
+    }
+}
+impl<'a> Write for StdoutLock<'a> {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        self.inner.write(&buf[..cmp::min(buf.len(), OUT_MAX)])
+    }
+    fn flush(&mut self) -> io::Result<()> { self.inner.flush() }
+}
+
+/// A handle to the standard error stream of a process.
+///
+/// For more information, see `stderr`
+pub struct Stderr {
+    inner: Arc<Mutex<StderrRaw>>,
+}
+
+/// A locked reference to the a `Stderr` handle.
+///
+/// This handle implements the `Write` trait and is constructed via the `lock`
+/// method on `Stderr`.
+pub struct StderrLock<'a> {
+    inner: MutexGuard<'a, StderrRaw>,
+}
+
+/// Constructs a new reference to the standard error stream of a process.
+///
+/// Each returned handle is synchronized amongst all other handles created from
+/// this function. No handles are buffered, however.
+///
+/// The returned handle implements the `Write` trait.
+///
+/// To avoid locking altogether, it is recommended to use the `stderr_raw`
+/// constructor.
+pub fn stderr() -> Stderr {
+    static INSTANCE: Lazy<Mutex<StderrRaw>> = lazy_init!(stderr_init);
+    return Stderr {
+        inner: INSTANCE.get().expect("cannot access stderr during shutdown"),
+    };
+
+    fn stderr_init() -> Arc<Mutex<StderrRaw>> {
+        Arc::new(Mutex::new(stderr_raw()))
+    }
+}
+
+impl Stderr {
+    /// Lock this handle to the standard error stream, returning a writable
+    /// guard.
+    ///
+    /// The lock is released when the returned lock goes out of scope. The
+    /// returned guard also implements the `Write` trait for writing data.
+    pub fn lock(&self) -> StderrLock {
+        StderrLock { inner: self.inner.lock().unwrap() }
+    }
+}
+
+impl Write for Stderr {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        self.lock().write(buf)
+    }
+    fn flush(&mut self) -> io::Result<()> {
+        self.lock().flush()
+    }
+    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
+        self.lock().write_all(buf)
+    }
+    fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> {
+        self.lock().write_fmt(fmt)
+    }
+}
+impl<'a> Write for StderrLock<'a> {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        self.inner.write(&buf[..cmp::min(buf.len(), OUT_MAX)])
+    }
+    fn flush(&mut self) -> io::Result<()> { self.inner.flush() }
+}
index b5bdeb7f181b0ddab0bebb3c25491c619d385ddc..7957bc35b76b5c3e90507df79c6b624e9b2c6326 100644 (file)
 #![feature(box_syntax)]
 #![feature(collections)]
 #![feature(core)]
-#![feature(int_uint)]
+#![feature(hash)]
 #![feature(lang_items)]
 #![feature(libc)]
 #![feature(linkage, thread_local, asm)]
 mod uint_macros;
 
 #[path = "num/isize.rs"]  pub mod isize;
-pub use isize as int;
 #[path = "num/i8.rs"]   pub mod i8;
 #[path = "num/i16.rs"]  pub mod i16;
 #[path = "num/i32.rs"]  pub mod i32;
 #[path = "num/i64.rs"]  pub mod i64;
 
 #[path = "num/usize.rs"] pub mod usize;
-pub use usize as uint;
 #[path = "num/u8.rs"]   pub mod u8;
 #[path = "num/u16.rs"]  pub mod u16;
 #[path = "num/u32.rs"]  pub mod u32;
index 15ae8b027e128a20451ebc5c8a408ae008f5b42e..d776079efaeeccd00b8cda8e8a180ba26bf3145c 100644 (file)
@@ -1830,6 +1830,6 @@ mod bench {
     #[bench]
     fn bench_pow_function(b: &mut Bencher) {
         let v = (0..1024).collect::<Vec<_>>();
-        b.iter(|| {v.iter().fold(0, |old, new| old.pow(*new));});
+        b.iter(|| {v.iter().fold(0, |old, new| old.pow(*new as u32));});
     }
 }
index 8bd19f063f0300c51cc9256b70f6c7f0d1aa5fba..45a86a9fde72c4322eb32eddd73f2a1b04e21451 100644 (file)
 //! Utility mixins that apply to all Readers and Writers
 
 #![allow(missing_docs)]
+#![unstable(feature = "old_io")]
+#![deprecated(since = "1.0.0",
+              reason = "functionality will be removed with no immediate \
+                        replacement")]
 
 // FIXME: Not sure how this should be structured
 // FIXME: Iteration should probably be considered separately
index 56a707c24a6c9789c5c8b751e31759d91c7fef5f..a5df21749e22e3023580e1ae8ef4b6a48a130c67 100644 (file)
@@ -224,10 +224,10 @@ pub fn stdin() -> StdinReader {
 
     unsafe {
         ONCE.call_once(|| {
-            // The default buffer capacity is 64k, but apparently windows doesn't like
-            // 64k reads on stdin. See #13304 for details, but the idea is that on
-            // windows we use a slightly smaller buffer that's been seen to be
-            // acceptable.
+            // The default buffer capacity is 64k, but apparently windows
+            // doesn't like 64k reads on stdin. See #13304 for details, but the
+            // idea is that on windows we use a slightly smaller buffer that's
+            // been seen to be acceptable.
             let stdin = if cfg!(windows) {
                 BufferedReader::with_capacity(8 * 1024, stdin_raw())
             } else {
index 632270bc5ccbf250286bc176d1f7c08ce9ea4935..80bfd57e933c42af7cb23da3a33006a8f553c59f 100644 (file)
@@ -63,6 +63,7 @@ macro_rules! helper_init { (static $name:ident: Helper<$m:ty>) => (
 pub mod timer;
 pub mod tty;
 pub mod udp;
+pub mod stdio;
 
 pub mod addrinfo {
     pub use sys_common::net::get_host_addresses;
diff --git a/src/libstd/sys/unix/stdio.rs b/src/libstd/sys/unix/stdio.rs
new file mode 100644 (file)
index 0000000..2f9610f
--- /dev/null
@@ -0,0 +1,52 @@
+// 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.
+
+use prelude::v1::*;
+
+use io;
+use libc;
+use sys::fd::FileDesc;
+
+pub struct Stdin(());
+pub struct Stdout(());
+pub struct Stderr(());
+
+impl Stdin {
+    pub fn new() -> Stdin { Stdin(()) }
+
+    pub fn read(&self, data: &mut [u8]) -> io::Result<usize> {
+        let fd = FileDesc::new(libc::STDIN_FILENO);
+        let ret = fd.read(data);
+        fd.into_raw();
+        return ret;
+    }
+}
+
+impl Stdout {
+    pub fn new() -> Stdout { Stdout(()) }
+
+    pub fn write(&self, data: &[u8]) -> io::Result<usize> {
+        let fd = FileDesc::new(libc::STDOUT_FILENO);
+        let ret = fd.write(data);
+        fd.into_raw();
+        return ret;
+    }
+}
+
+impl Stderr {
+    pub fn new() -> Stderr { Stderr(()) }
+
+    pub fn write(&self, data: &[u8]) -> io::Result<usize> {
+        let fd = FileDesc::new(libc::STDERR_FILENO);
+        let ret = fd.write(data);
+        fd.into_raw();
+        return ret;
+    }
+}
index f4791d39da19055e6925db6d923ed98527eb4097..827e2afdca85c81eaaecd97a50ae4e82fa549359 100644 (file)
@@ -164,7 +164,7 @@ pub unsafe fn current() -> uint {
 
         if pthread_main_np() == 1 {
             // main thread
-            current_stack.ss_sp as uint - current_stack.ss_size as uint + 3 * PAGE_SIZE as uint
+            current_stack.ss_sp as uint - current_stack.ss_size as uint + PAGE_SIZE as uint
 
         } else {
             // new thread
index 2d1a5e10bd63f73a6e815452f8ea9abb41e35cf6..8ed7302b6653f74327da76665a0455137a8abae2 100644 (file)
 pub const ERROR_NO_MORE_FILES: libc::DWORD = 18;
 pub const TOKEN_READ: libc::DWORD = 0x20008;
 
+// Note that these are not actually HANDLEs, just values to pass to GetStdHandle
+pub const STD_INPUT_HANDLE: libc::DWORD = -10;
+pub const STD_OUTPUT_HANDLE: libc::DWORD = -11;
+pub const STD_ERROR_HANDLE: libc::DWORD = -12;
+
 #[repr(C)]
 #[cfg(target_arch = "x86")]
 pub struct WSADATA {
@@ -427,6 +432,7 @@ pub fn OpenProcessToken(ProcessHandle: libc::HANDLE,
                             DesiredAccess: libc::DWORD,
                             TokenHandle: *mut libc::HANDLE) -> libc::BOOL;
     pub fn GetCurrentProcess() -> libc::HANDLE;
+    pub fn GetStdHandle(which: libc::DWORD) -> libc::HANDLE;
 }
 
 #[link(name = "userenv")]
index 99de659be41edf7986b81236f3cea90305bb9fc3..0089dcad455df2f731608871524b6edf803f329a 100644 (file)
 
 use prelude::v1::*;
 
-use libc::{self, HANDLE};
-use io;
 use io::ErrorKind;
+use io;
+use libc::{self, HANDLE};
+use mem;
 use ptr;
 use sys::cvt;
 
@@ -28,6 +29,12 @@ pub fn new(handle: HANDLE) -> Handle {
 
     pub fn raw(&self) -> HANDLE { self.0 }
 
+    pub fn into_raw(self) -> HANDLE {
+        let ret = self.0;
+        unsafe { mem::forget(self) }
+        return ret;
+    }
+
     pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
         read(self.0, buf)
     }
index 5bb2a134533ed0217b7dd9135b51e070e56fd346..3bdadbb9012e04da91a39f5635bfb779614b5e42 100644 (file)
@@ -61,6 +61,7 @@ macro_rules! helper_init { (static $name:ident: Helper<$m:ty>) => (
 pub mod timer;
 pub mod tty;
 pub mod udp;
+pub mod stdio;
 
 pub mod addrinfo {
     pub use sys_common::net::get_host_addresses;
diff --git a/src/libstd/sys/windows/stdio.rs b/src/libstd/sys/windows/stdio.rs
new file mode 100644 (file)
index 0000000..72ce8b7
--- /dev/null
@@ -0,0 +1,155 @@
+// 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.
+
+use prelude::v1::*;
+use io::prelude::*;
+
+use io::{self, Cursor};
+use iter::repeat;
+use libc;
+use ptr;
+use str;
+use sync::Mutex;
+use sys::c;
+use sys::cvt;
+use sys::handle::Handle;
+
+struct NoClose(Option<Handle>);
+
+enum Output {
+    Console(NoClose),
+    Pipe(NoClose),
+}
+
+pub struct Stdin {
+    handle: Output,
+    utf8: Mutex<io::Cursor<Vec<u8>>>,
+}
+pub struct Stdout(Output);
+pub struct Stderr(Output);
+
+fn get(handle: libc::DWORD) -> io::Result<Output> {
+    let handle = unsafe { c::GetStdHandle(handle) };
+    if handle == libc::INVALID_HANDLE_VALUE {
+        Err(io::Error::last_os_error())
+    } else if handle.is_null() {
+        Err(io::Error::new(io::ErrorKind::Other,
+                           "no stdio handle available for this process", None))
+    } else {
+        let ret = NoClose::new(handle);
+        let mut out = 0;
+        match unsafe { c::GetConsoleMode(handle, &mut out) } {
+            0 => Ok(Output::Pipe(ret)),
+            _ => Ok(Output::Console(ret)),
+        }
+    }
+}
+
+fn write(out: &Output, data: &[u8]) -> io::Result<usize> {
+    let handle = match *out {
+        Output::Console(ref c) => c.get().raw(),
+        Output::Pipe(ref p) => return p.get().write(data),
+    };
+    let utf16 = match str::from_utf8(data).ok() {
+        Some(utf8) => utf8.utf16_units().collect::<Vec<u16>>(),
+        None => return Err(invalid_encoding()),
+    };
+    let mut written = 0;
+    try!(cvt(unsafe {
+        c::WriteConsoleW(handle,
+                         utf16.as_ptr() as libc::LPCVOID,
+                         utf16.len() as u32,
+                         &mut written,
+                         ptr::null_mut())
+    }));
+
+    // FIXME if this only partially writes the utf16 buffer then we need to
+    //       figure out how many bytes of `data` were actually written
+    assert_eq!(written as usize, utf16.len());
+    Ok(data.len())
+}
+
+impl Stdin {
+    pub fn new() -> Stdin {
+        Stdin {
+            handle: get(c::STD_INPUT_HANDLE).unwrap(),
+            utf8: Mutex::new(Cursor::new(Vec::new())),
+        }
+    }
+
+    pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
+        let handle = match self.handle {
+            Output::Console(ref c) => c.get().raw(),
+            Output::Pipe(ref p) => return p.get().read(buf),
+        };
+        let mut utf8 = self.utf8.lock().unwrap();
+        // Read more if the buffer is empty
+        if utf8.position() as usize == utf8.get_ref().len() {
+            let mut utf16: Vec<u16> = repeat(0u16).take(0x1000).collect();
+            let mut num = 0;
+            try!(cvt(unsafe {
+                c::ReadConsoleW(handle,
+                                utf16.as_mut_ptr() as libc::LPVOID,
+                                utf16.len() as u32,
+                                &mut num,
+                                ptr::null_mut())
+            }));
+            utf16.truncate(num as usize);
+            // FIXME: what to do about this data that has already been read?
+            let data = match String::from_utf16(&utf16) {
+                Ok(utf8) => utf8.into_bytes(),
+                Err(..) => return Err(invalid_encoding()),
+            };
+            *utf8 = Cursor::new(data);
+        }
+
+        // MemReader shouldn't error here since we just filled it
+        utf8.read(buf)
+    }
+}
+
+impl Stdout {
+    pub fn new() -> Stdout {
+        Stdout(get(c::STD_OUTPUT_HANDLE).unwrap())
+    }
+
+    pub fn write(&self, data: &[u8]) -> io::Result<usize> {
+        write(&self.0, data)
+    }
+}
+
+impl Stderr {
+    pub fn new() -> Stderr {
+        Stderr(get(c::STD_ERROR_HANDLE).unwrap())
+    }
+
+    pub fn write(&self, data: &[u8]) -> io::Result<usize> {
+        write(&self.0, data)
+    }
+}
+
+impl NoClose {
+    fn new(handle: libc::HANDLE) -> NoClose {
+        NoClose(Some(Handle::new(handle)))
+    }
+
+    fn get(&self) -> &Handle { self.0.as_ref().unwrap() }
+}
+
+impl Drop for NoClose {
+    fn drop(&mut self) {
+        self.0.take().unwrap().into_raw();
+    }
+}
+
+fn invalid_encoding() -> io::Error {
+    io::Error::new(io::ErrorKind::InvalidInput, "text was not valid unicode",
+                   None)
+}
index 6aad2bbcc7f08b47ab57f6dbd0f097cedbd2ce08..883c1bbbbe5853e4d31ef903e387488dc129b719 100644 (file)
 //! a thread will unwind the stack, running destructors and freeing
 //! owned resources. Thread panic is unrecoverable from within
 //! the panicking thread (i.e. there is no 'try/catch' in Rust), but
-//! panic may optionally be detected from a different thread. If
-//! the main thread panics the application will exit with a non-zero
+//! the panic may optionally be detected from a different thread. If
+//! the main thread panics, the application will exit with a non-zero
 //! exit code.
 //!
 //! When the main thread of a Rust program terminates, the entire program shuts
 //! down, even if other threads are still running. However, this module provides
 //! convenient facilities for automatically waiting for the termination of a
-//! child thread (i.e., join), described below.
+//! child thread (i.e., join).
 //!
 //! ## The `Thread` type
 //!
-//! Already-running threads are represented via the `Thread` type, which you can
+//! Threads are represented via the `Thread` type, which you can
 //! get in one of two ways:
 //!
-//! * By spawning a new thread, e.g. using the `thread::spawn` constructor;
+//! * By spawning a new thread, e.g. using the `thread::spawn` function.
 //! * By requesting the current thread, using the `thread::current` function.
 //!
 //! Threads can be named, and provide some built-in support for low-level
-//! synchronization described below.
+//! synchronization (described below).
 //!
 //! The `thread::current()` function is available even for threads not spawned
 //! by the APIs of this module.
 //! use std::thread;
 //!
 //! thread::spawn(move || {
-//!     println!("Hello, World!");
-//!     // some computation here
+//!     // some work here
 //! });
 //! ```
 //!
 //! In this example, the spawned thread is "detached" from the current
-//! thread, meaning that it can outlive the thread that spawned
-//! it. (Note, however, that when the main thread terminates all
-//! detached threads are terminated as well.)
+//! thread. This means that it can outlive its parent (the thread that spawned
+//! it), unless this parent is the main thread.
 //!
 //! ## Scoped threads
 //!
 //! Often a parent thread uses a child thread to perform some particular task,
 //! and at some point must wait for the child to complete before continuing.
-//! For this scenario, use the `scoped` constructor:
+//! For this scenario, use the `thread::scoped` function:
 //!
 //! ```rust
 //! use std::thread;
 //!
 //! let guard = thread::scoped(move || {
-//!     println!("Hello, World!");
-//!     // some computation here
+//!     // some work here
 //! });
+//!
 //! // do some other work in the meantime
 //! let output = guard.join();
 //! ```
 //! terminates) when it is dropped. You can join the child thread in
 //! advance by calling the `join` method on the guard, which will also
 //! return the result produced by the thread.  A handle to the thread
-//! itself is available via the `thread` method on the join guard.
-//!
-//! (Note: eventually, the `scoped` constructor will allow the parent and child
-//! threads to data that lives on the parent thread's stack, but some language
-//! changes are needed before this is possible.)
+//! itself is available via the `thread` method of the join guard.
 //!
 //! ## Configuring threads
 //!
 //! use std::thread;
 //!
 //! thread::Builder::new().name("child1".to_string()).spawn(move || {
-//!     println!("Hello, world!")
+//!     println!("Hello, world!");
 //! });
 //! ```
 //!
 //! initially not present:
 //!
 //! * The `thread::park()` function blocks the current thread unless or until
-//!   the token is available for its thread handle, at which point It atomically
+//!   the token is available for its thread handle, at which point it atomically
 //!   consumes the token. It may also return *spuriously*, without consuming the
 //!   token. `thread::park_timeout()` does the same, but allows specifying a
 //!   maximum time to block the thread for.
 //! * It avoids the need to allocate mutexes and condvars when building new
 //!   synchronization primitives; the threads already provide basic blocking/signaling.
 //!
-//! * It can be implemented highly efficiently on many platforms.
+//! * It can be implemented very efficiently on many platforms.
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
@@ -170,7 +164,7 @@ pub struct Builder {
     // A name for the thread-to-be, for identification in panic messages
     name: Option<String>,
     // The size of the stack for the spawned thread
-    stack_size: Option<uint>,
+    stack_size: Option<usize>,
     // Thread-local stdout
     stdout: Option<Box<Writer + Send + 'static>>,
     // Thread-local stderr
@@ -200,7 +194,7 @@ pub fn name(mut self, name: String) -> Builder {
 
     /// Set the size of the stack for the new thread.
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn stack_size(mut self, size: uint) -> Builder {
+    pub fn stack_size(mut self, size: usize) -> Builder {
         self.stack_size = Some(size);
         self
     }
@@ -283,8 +277,8 @@ fn spawn_inner<T: Send>(self, f: Thunk<(), T>) -> io::Result<JoinInner<T>> {
         // address at which our stack started).
         let main = move || {
             let something_around_the_top_of_the_stack = 1;
-            let addr = &something_around_the_top_of_the_stack as *const int;
-            let my_stack_top = addr as uint;
+            let addr = &something_around_the_top_of_the_stack as *const isize;
+            let my_stack_top = addr as usize;
             let my_stack_bottom = my_stack_top - stack_size + 1024;
             unsafe {
                 stack::record_os_managed_stack_bounds(my_stack_bottom, my_stack_top);
@@ -779,7 +773,7 @@ fn test_spawn_sched() {
 
         let (tx, rx) = channel();
 
-        fn f(i: int, tx: Sender<()>) {
+        fn f(i: i32, tx: Sender<()>) {
             let tx = tx.clone();
             thread::spawn(move|| {
                 if i == 0 {
@@ -808,13 +802,13 @@ fn test_spawn_sched_childs_on_default_sched() {
     }
 
     fn avoid_copying_the_body<F>(spawnfn: F) where F: FnOnce(Thunk<'static>) {
-        let (tx, rx) = channel::<uint>();
+        let (tx, rx) = channel::<u32>();
 
         let x = box 1;
-        let x_in_parent = (&*x) as *const int as uint;
+        let x_in_parent = (&*x) as *const isize as u32;
 
         spawnfn(Thunk::new(move|| {
-            let x_in_child = (&*x) as *const int as uint;
+            let x_in_child = (&*x) as *const isize as u32;
             tx.send(x_in_child).unwrap();
         }));
 
@@ -853,8 +847,8 @@ fn test_child_doesnt_ref_parent() {
         // climbing the task tree to dereference each ancestor. (See #1789)
         // (well, it would if the constant were 8000+ - I lowered it to be more
         // valgrind-friendly. try this at home, instead..!)
-        static GENERATIONS: uint = 16;
-        fn child_no(x: uint) -> Thunk<'static> {
+        static GENERATIONS: usize = 16;
+        fn child_no(x: usize) -> Thunk<'static> {
             return Thunk::new(move|| {
                 if x < GENERATIONS {
                     thread::spawn(move|| child_no(x+1).invoke(()));
index 4fc08c0c2b28caaccfcabe40924c848cbcf917ac..1c7930b9bc99288279fe1d91ed8d59a629afe915 100644 (file)
@@ -10,7 +10,6 @@
 
 // Functions dealing with attributes and meta items
 
-pub use self::InlineAttr::*;
 pub use self::StabilityLevel::*;
 pub use self::ReprAttr::*;
 pub use self::IntType::*;
@@ -285,33 +284,33 @@ pub fn find_crate_name(attrs: &[Attribute]) -> Option<InternedString> {
 
 #[derive(Copy, PartialEq)]
 pub enum InlineAttr {
-    InlineNone,
-    InlineHint,
-    InlineAlways,
-    InlineNever,
+    None,
+    Hint,
+    Always,
+    Never,
 }
 
 /// Determine what `#[inline]` attribute is present in `attrs`, if any.
 pub fn find_inline_attr(diagnostic: Option<&SpanHandler>, attrs: &[Attribute]) -> InlineAttr {
     // FIXME (#2809)---validate the usage of #[inline] and #[inline]
-    attrs.iter().fold(InlineNone, |ia,attr| {
+    attrs.iter().fold(InlineAttr::None, |ia,attr| {
         match attr.node.value.node {
             MetaWord(ref n) if *n == "inline" => {
                 mark_used(attr);
-                InlineHint
+                InlineAttr::Hint
             }
             MetaList(ref n, ref items) if *n == "inline" => {
                 mark_used(attr);
                 if items.len() != 1 {
                     diagnostic.map(|d|{ d.span_err(attr.span, "expected one argument"); });
-                    InlineNone
+                    InlineAttr::None
                 } else if contains_name(&items[..], "always") {
-                    InlineAlways
+                    InlineAttr::Always
                 } else if contains_name(&items[..], "never") {
-                    InlineNever
+                    InlineAttr::Never
                 } else {
                     diagnostic.map(|d|{ d.span_err((*items[0]).span, "invalid argument"); });
-                    InlineNone
+                    InlineAttr::None
                 }
             }
             _ => ia
@@ -322,8 +321,8 @@ pub fn find_inline_attr(diagnostic: Option<&SpanHandler>, attrs: &[Attribute]) -
 /// True if `#[inline]` or `#[inline(always)]` is present in `attrs`.
 pub fn requests_inline(attrs: &[Attribute]) -> bool {
     match find_inline_attr(None, attrs) {
-        InlineHint | InlineAlways => true,
-        InlineNone | InlineNever => false,
+        InlineAttr::Hint | InlineAttr::Always => true,
+        InlineAttr::None | InlineAttr::Never => false,
     }
 }
 
index 1e23da3020f277b7262145bab28a0c3216e010a5..38fc53ccd366a104896a9bc5dcd313a66aa215c7 100644 (file)
@@ -109,7 +109,7 @@ fn main() {
 
     let messages = range_step(min_depth, max_depth + 1, 2).map(|depth| {
         use std::num::Int;
-        let iterations = 2.pow((max_depth - depth + min_depth) as usize);
+        let iterations = 2.pow((max_depth - depth + min_depth) as u32);
         thread::scoped(move || inner(depth, iterations))
     }).collect::<Vec<_>>();
 
index fb75c67253c6d057d37e962e80d9e5fe7ad03910..f239a0d78d1ddd9875bb6c873d5f5f07e0aeb6b4 100644 (file)
 #![feature(box_syntax)]
 
 use std::ascii::OwnedAsciiExt;
+use std::env;
+use std::fs::File;
+use std::io::prelude::*;
+use std::io;
 use std::slice;
 use std::sync::Arc;
 use std::thread;
 
 static TABLE: [u8;4] = [ 'A' as u8, 'C' as u8, 'G' as u8, 'T' as u8 ];
-static TABLE_SIZE: uint = 2 << 16;
+static TABLE_SIZE: usize = 2 << 16;
 
 static OCCURRENCES: [&'static str;5] = [
     "GGT",
@@ -73,7 +77,7 @@ fn push_char(&self, c: u8) -> Code {
         Code((self.hash() << 2) + (pack_symbol(c) as u64))
     }
 
-    fn rotate(&self, c: u8, frame: uint) -> Code {
+    fn rotate(&self, c: u8, frame: usize) -> Code {
         Code(self.push_char(c).hash() & ((1u64 << (2 * frame)) - 1))
     }
 
@@ -81,7 +85,7 @@ fn pack(string: &str) -> Code {
         string.bytes().fold(Code(0u64), |a, b| a.push_char(b))
     }
 
-    fn unpack(&self, frame: uint) -> String {
+    fn unpack(&self, frame: usize) -> String {
         let mut key = self.hash();
         let mut result = Vec::new();
         for _ in 0..frame {
@@ -113,13 +117,13 @@ fn f(&self, entry: &mut Entry) {
 impl TableCallback for PrintCallback {
     fn f(&self, entry: &mut Entry) {
         let PrintCallback(s) = *self;
-        println!("{}\t{}", entry.count as int, s);
+        println!("{}\t{}", entry.count, s);
     }
 }
 
 struct Entry {
     code: Code,
-    count: uint,
+    count: usize,
     next: Option<Box<Entry>>,
 }
 
@@ -165,20 +169,20 @@ fn lookup<C:TableCallback>(&mut self, key: Code, c: C) {
         let index = key.hash() % (TABLE_SIZE as u64);
 
         {
-            if self.items[index as uint].is_none() {
+            if self.items[index as usize].is_none() {
                 let mut entry = box Entry {
                     code: key,
                     count: 0,
                     next: None,
                 };
                 c.f(&mut *entry);
-                self.items[index as uint] = Some(entry);
+                self.items[index as usize] = Some(entry);
                 return;
             }
         }
 
         {
-            let entry = self.items[index as uint].as_mut().unwrap();
+            let entry = self.items[index as usize].as_mut().unwrap();
             if entry.code == key {
                 c.f(&mut **entry);
                 return;
@@ -233,10 +237,10 @@ fn pack_symbol(c: u8) -> u8 {
 }
 
 fn unpack_symbol(c: u8) -> u8 {
-    TABLE[c as uint]
+    TABLE[c as usize]
 }
 
-fn generate_frequencies(mut input: &[u8], frame: uint) -> Table {
+fn generate_frequencies(mut input: &[u8], frame: usize) -> Table {
     let mut frequencies = Table::new();
     if input.len() < frame { return frequencies; }
     let mut code = Code(0);
@@ -256,7 +260,7 @@ fn generate_frequencies(mut input: &[u8], frame: uint) -> Table {
     frequencies
 }
 
-fn print_frequencies(frequencies: &Table, frame: uint) {
+fn print_frequencies(frequencies: &Table, frame: usize) {
     let mut vector = Vec::new();
     for entry in frequencies.iter() {
         vector.push((entry.count, entry.code));
@@ -280,9 +284,9 @@ fn print_occurrences(frequencies: &mut Table, occurrence: &'static str) {
     frequencies.lookup(Code::pack(occurrence), PrintCallback(occurrence))
 }
 
-fn get_sequence<R: Buffer>(r: &mut R, key: &str) -> Vec<u8> {
+fn get_sequence<R: BufRead>(r: &mut R, key: &str) -> Vec<u8> {
     let mut res = Vec::new();
-    for l in r.lines().map(|l| l.ok().unwrap())
+    for l in r.lines().map(|l| l.unwrap())
         .skip_while(|l| key != &l[..key.len()]).skip(1)
     {
         res.push_all(l.trim().as_bytes());
@@ -291,13 +295,13 @@ fn get_sequence<R: Buffer>(r: &mut R, key: &str) -> Vec<u8> {
 }
 
 fn main() {
-    let input = if std::env::var_os("RUST_BENCH").is_some() {
-        let fd = std::old_io::File::open(&Path::new("shootout-k-nucleotide.data"));
-        get_sequence(&mut std::old_io::BufferedReader::new(fd), ">THREE")
+    let input = if env::var_os("RUST_BENCH").is_some() {
+        let f = File::open("shootout-k-nucleotide.data").unwrap();
+        get_sequence(&mut io::BufReader::new(f), ">THREE")
     } else {
-        let mut stdin = std::old_io::stdin();
+        let stdin = io::stdin();
         let mut stdin = stdin.lock();
-        get_sequence(&mut *stdin, ">THREE")
+        get_sequence(&mut stdin, ">THREE")
     };
     let input = Arc::new(input);
 
index b45f241e8e5d4291a7d72df40faf1535ac2d3090..40e1e7d2b76b02614a211db532013b8a9a0b1452 100644 (file)
@@ -13,9 +13,8 @@
 #![feature(box_syntax)]
 #![allow(non_snake_case)]
 
-use std::old_io::BufferedReader;
-use std::old_io::stdio::StdReader;
-use std::old_io;
+use std::io::prelude::*;
+use std::io;
 use std::iter::repeat;
 use std::num::Int;
 use std::env;
@@ -37,7 +36,7 @@
 //
 
 // internal type of sudoku grids
-type grid = Vec<Vec<u8> > ;
+type grid = Vec<Vec<u8>>;
 
 struct Sudoku {
     grid: grid
@@ -55,9 +54,11 @@ pub fn new(g: grid) -> Sudoku {
         return Sudoku::new(g)
     }
 
-    pub fn read(mut reader: &mut BufferedReader<StdReader>) -> Sudoku {
+    pub fn read(reader: &mut BufRead) -> Sudoku {
         /* assert first line is exactly "9,9" */
-        assert!(reader.read_line().unwrap() == "9,9".to_string());
+        let mut s = String::new();
+        reader.read_line(&mut s).unwrap();
+        assert_eq!(s, "9,9\n");
 
         let mut g = repeat(vec![0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8])
                           .take(10).collect::<Vec<_>>();
@@ -71,7 +72,7 @@ pub fn read(mut reader: &mut BufferedReader<StdReader>) -> Sudoku {
             if comps.len() == 3 {
                 let row = comps[0].parse::<u8>().unwrap();
                 let col = comps[1].parse::<u8>().unwrap();
-                g[row as uint][col as uint] = comps[2].parse().unwrap();
+                g[row as usize][col as usize] = comps[2].parse().unwrap();
             }
             else {
                 panic!("Invalid sudoku file");
@@ -80,11 +81,11 @@ pub fn read(mut reader: &mut BufferedReader<StdReader>) -> Sudoku {
         return Sudoku::new(g)
     }
 
-    pub fn write(&self, writer: &mut old_io::Writer) {
+    pub fn write(&self, writer: &mut Write) {
         for row in 0u8..9u8 {
-            write!(writer, "{}", self.grid[row as uint][0]);
+            write!(writer, "{}", self.grid[row as usize][0]);
             for col in 1u8..9u8 {
-                write!(writer, " {}", self.grid[row as uint][col as uint]);
+                write!(writer, " {}", self.grid[row as usize][col as usize]);
             }
             write!(writer, "\n");
          }
@@ -95,7 +96,7 @@ pub fn solve(&mut self) {
         let mut work: Vec<(u8, u8)> = Vec::new(); /* queue of uncolored fields */
         for row in 0u8..9u8 {
             for col in 0u8..9u8 {
-                let color = self.grid[row as uint][col as uint];
+                let color = self.grid[row as usize][col as usize];
                 if color == 0u8 {
                     work.push((row, col));
                 }
@@ -107,7 +108,7 @@ pub fn solve(&mut self) {
         while ptr < end {
             let (row, col) = work[ptr];
             // is there another color to try?
-            let the_color = self.grid[row as uint][col as uint] +
+            let the_color = self.grid[row as usize][col as usize] +
                                 (1 as u8);
             if self.next_color(row, col, the_color) {
                 //  yes: advance work list
@@ -130,10 +131,10 @@ fn next_color(&mut self, row: u8, col: u8, start_color: u8) -> bool {
 
             // find first remaining color that is available
             let next = avail.next();
-            self.grid[row as uint][col as uint] = next;
+            self.grid[row as usize][col as usize] = next;
             return 0u8 != next;
         }
-        self.grid[row as uint][col as uint] = 0u8;
+        self.grid[row as usize][col as usize] = 0u8;
         return false;
     }
 
@@ -141,9 +142,9 @@ fn next_color(&mut self, row: u8, col: u8, start_color: u8) -> bool {
     fn drop_colors(&mut self, avail: &mut Colors, row: u8, col: u8) {
         for idx in 0u8..9u8 {
             /* check same column fields */
-            avail.remove(self.grid[idx as uint][col as uint]);
+            avail.remove(self.grid[idx as usize][col as usize]);
             /* check same row fields */
-            avail.remove(self.grid[row as uint][idx as uint]);
+            avail.remove(self.grid[row as usize][idx as usize]);
         }
 
         // check same block fields
@@ -151,7 +152,7 @@ fn drop_colors(&mut self, avail: &mut Colors, row: u8, col: u8) {
         let col0 = (col / 3u8) * 3u8;
         for alt_row in row0..row0 + 3u8 {
             for alt_col in col0..col0 + 3u8 {
-                avail.remove(self.grid[alt_row as uint][alt_col as uint]);
+                avail.remove(self.grid[alt_row as usize][alt_col as usize]);
             }
         }
     }
@@ -165,7 +166,7 @@ fn drop_colors(&mut self, avail: &mut Colors, row: u8, col: u8) {
 impl Colors {
     fn new(start_color: u8) -> Colors {
         // Sets bits 9..start_color
-        let tails = !0u16 << start_color as uint;
+        let tails = !0u16 << start_color as usize;
         return Colors(HEADS & tails);
     }
 
@@ -182,7 +183,7 @@ fn next(&self) -> u8 {
     fn remove(&mut self, color: u8) {
         if color != 0u8 {
             let Colors(val) = *self;
-            let mask = !(1u16 << color as uint);
+            let mask = !(1u16 << color as usize);
             *self    = Colors(val & mask);
         }
     }
@@ -269,15 +270,16 @@ fn check_DEFAULT_SUDOKU_solution() {
 }
 
 fn main() {
-    let args        = env::args();
+    let args = env::args();
     let use_default = args.len() == 1;
     let mut sudoku = if use_default {
         Sudoku::from_vec(&DEFAULT_SUDOKU)
     } else {
-        let mut stdin = old_io::stdin();
-        let mut stdin = stdin.lock();
-        Sudoku::read(&mut *stdin)
+        let stdin = io::stdin();
+        let mut locked = stdin.lock();
+        Sudoku::read(&mut locked)
     };
     sudoku.solve();
-    sudoku.write(&mut old_io::stdout());
+    let out = io::stdout();
+    sudoku.write(&mut out.lock());
 }
diff --git a/src/test/compile-fail/dropck_no_diverge_on_nonregular_1.rs b/src/test/compile-fail/dropck_no_diverge_on_nonregular_1.rs
new file mode 100644 (file)
index 0000000..f096885
--- /dev/null
@@ -0,0 +1,37 @@
+// 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.
+
+// Issue 22443: Reject code using non-regular types that would
+// otherwise cause dropck to loop infinitely.
+
+use std::marker::PhantomData;
+
+struct Digit<T> {
+    elem: T
+}
+
+struct Node<T:'static> { m: PhantomData<&'static T> }
+
+
+enum FingerTree<T:'static> {
+    Single(T),
+    // Bug report said Digit after Box would stack overflow (versus
+    // Digit before Box; see dropck_no_diverge_on_nonregular_2).
+    Deep(
+        Box<FingerTree<Node<T>>>,
+        Digit<T>,
+        )
+}
+
+fn main() {
+    let ft = //~ ERROR overflow while adding drop-check rules for FingerTree
+        FingerTree::Single(1);
+    //~^ ERROR overflow while adding drop-check rules for FingerTree
+}
diff --git a/src/test/compile-fail/dropck_no_diverge_on_nonregular_2.rs b/src/test/compile-fail/dropck_no_diverge_on_nonregular_2.rs
new file mode 100644 (file)
index 0000000..886bd6b
--- /dev/null
@@ -0,0 +1,36 @@
+// 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.
+
+// Issue 22443: Reject code using non-regular types that would
+// otherwise cause dropck to loop infinitely.
+
+use std::marker::PhantomData;
+
+struct Digit<T> {
+    elem: T
+}
+
+struct Node<T:'static> { m: PhantomData<&'static T> }
+
+enum FingerTree<T:'static> {
+    Single(T),
+    // Bug report said Digit before Box would infinite loop (versus
+    // Digit after Box; see dropck_no_diverge_on_nonregular_1).
+    Deep(
+        Digit<T>,
+        Box<FingerTree<Node<T>>>,
+        )
+}
+
+fn main() {
+    let ft = //~ ERROR overflow while adding drop-check rules for FingerTree
+        FingerTree::Single(1);
+    //~^ ERROR overflow while adding drop-check rules for FingerTree
+}
diff --git a/src/test/compile-fail/dropck_no_diverge_on_nonregular_3.rs b/src/test/compile-fail/dropck_no_diverge_on_nonregular_3.rs
new file mode 100644 (file)
index 0000000..f7eb6e1
--- /dev/null
@@ -0,0 +1,46 @@
+// 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.
+
+// Issue 22443: Reject code using non-regular types that would
+// otherwise cause dropck to loop infinitely.
+//
+// This version is just checking that we still sanely handle a trivial
+// wrapper around the non-regular type. (It also demonstrates how the
+// error messages will report different types depending on which type
+// dropck is analyzing.)
+
+use std::marker::PhantomData;
+
+struct Digit<T> {
+    elem: T
+}
+
+struct Node<T:'static> { m: PhantomData<&'static T> }
+
+enum FingerTree<T:'static> {
+    Single(T),
+    // According to the bug report, Digit before Box would infinite loop.
+    Deep(
+        Digit<T>,
+        Box<FingerTree<Node<T>>>,
+        )
+}
+
+enum Wrapper<T:'static> {
+    Simple,
+    Other(FingerTree<T>),
+}
+
+fn main() {
+    let w = //~ ERROR overflow while adding drop-check rules for core::option
+        Some(Wrapper::Simple::<u32>);
+    //~^ ERROR overflow while adding drop-check rules for core::option::Option
+    //~| ERROR overflow while adding drop-check rules for Wrapper
+}
index 954ae8ebc48dd87df4dff656dee302492a309e1c..9c2e8d278ab0b8310db1190bd21c2ee27c824730 100644 (file)
@@ -8,11 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::{int, i8, i16, i32, i64};
+use std::{isize, i8, i16, i32, i64};
 use std::thread;
 
 fn main() {
-    assert!(thread::spawn(move|| { int::MIN / -1; }).join().is_err());
+    assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err());
     //~^ ERROR attempted to divide with overflow in a constant expression
     assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err());
     //~^ ERROR attempted to divide with overflow in a constant expression
@@ -32,7 +32,7 @@ fn main() {
     //~^ ERROR attempted to divide by zero in a constant expression
     assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err());
     //~^ ERROR attempted to divide by zero in a constant expression
-    assert!(thread::spawn(move|| { int::MIN % -1; }).join().is_err());
+    assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err());
     //~^ ERROR attempted remainder with overflow in a constant expression
     assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err());
     //~^ ERROR attempted remainder with overflow in a constant expression
diff --git a/src/test/compile-fail/nonbool_static_assert.rs b/src/test/compile-fail/nonbool_static_assert.rs
new file mode 100644 (file)
index 0000000..d85f58e
--- /dev/null
@@ -0,0 +1,16 @@
+// 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.
+
+#![allow(dead_code)]
+
+#[static_assert]
+static E: i32 = 1; //~ ERROR can only have static_assert on a static with type `bool`
+
+fn main() {}
index 964db6e9a4546bfb8b8ad18cfd80dc5af26110eb..5f3744712ccb4c2b5b2049b70533ec4bdfe8e9c7 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 fn main() {
-    pub use std::uint; //~ ERROR: visibility has no effect
+    pub use std::usize; //~ ERROR: visibility has no effect
     pub struct A; //~ ERROR: visibility has no effect
     pub enum B {} //~ ERROR: visibility has no effect
     pub trait C { //~ ERROR: visibility has no effect
index be4ad0781f272f9ee40110772d5b1b79000ca3e9..c15c4b83828a34bff88dde7f2c43eea5a36535b8 100644 (file)
 
 // error-pattern:index out of bounds: the len is 3 but the index is
 
-use std::uint;
+use std::usize;
 use std::mem::size_of;
 
 fn main() {
     let xs = [1, 2, 3];
-    xs[uint::MAX / size_of::<int>() + 1];
+    xs[usize::MAX / size_of::<isize>() + 1];
 }
index c86f8a38f63c409f32eeb4885a17da54050f398e..2c7c0875227d9baeddb83028f6bf45cf2c6290d8 100644 (file)
 // error-pattern:capacity overflow
 
 use std::collections::hash_map::HashMap;
-use std::uint;
+use std::usize;
 use std::mem::size_of;
 
 fn main() {
-    let threshold = uint::MAX / size_of::<(u64, u64, u64)>();
+    let threshold = usize::MAX / size_of::<(u64, u64, u64)>();
     let mut h = HashMap::<u64, u64>::with_capacity(threshold + 100);
     h.insert(0, 0);
 }
index c16f1f4c842ac1d1afacc0205d28635c7b224d9a..127be1f90d5ff08fc5ed5a5ffa7d625fd0dca84f 100644 (file)
@@ -10,4 +10,5 @@
 
 fn main() {
     let _ = std::old_io::stdin();
+    let _ = std::io::stdin();
 }
index ab83fb90d3f25ab3f47cdea68d77d7f4021a7b4b..62b8ff528a5e2e1395881d72a19a6dba16a8765e 100644 (file)
@@ -17,6 +17,7 @@
 #![feature(box_syntax)]
 
 use std::fmt;
+use std::usize;
 
 struct A;
 struct B;
@@ -137,6 +138,13 @@ pub fn main() {
     t!(format!("{:+10.3e}", 1.2345e6f64),  "  +1.234e6");
     t!(format!("{:+10.3e}", -1.2345e6f64), "  -1.234e6");
 
+    // Test that pointers don't get truncated.
+    {
+        let val = usize::MAX;
+        let exp = format!("{:#x}", val);
+        t!(format!("{:p}", val as *const isize), exp);
+    }
+
     // Escaping
     t!(format!("{{"), "{");
     t!(format!("}}"), "}");
index 4a7d6be55a1625fa4730c38d3d43a8feaaf8e83b..f1c747eca68406c82bcb7b97738feeabf9c9dde8 100644 (file)
@@ -8,10 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-fast
-
 use std::env;
-use std::old_io;
+use std::io::prelude::*;
+use std::io;
+use std::process::{Command, Stdio};
 use std::str;
 
 fn main() {
@@ -25,17 +25,19 @@ fn main() {
 
 fn parent() {
     let args: Vec<String> = env::args().collect();
-    let mut p = old_io::process::Command::new(&args[0])
-                                     .arg("child").spawn().unwrap();
-    p.stdin.as_mut().unwrap().write_str("test1\ntest2\ntest3").unwrap();
+    let mut p = Command::new(&args[0]).arg("child")
+                        .stdout(Stdio::capture())
+                        .stdin(Stdio::capture())
+                        .spawn().unwrap();
+    p.stdin.as_mut().unwrap().write_all(b"test1\ntest2\ntest3").unwrap();
     let out = p.wait_with_output().unwrap();
     assert!(out.status.success());
-    let s = str::from_utf8(&out.output).unwrap();
-    assert_eq!(s, "test1\n\ntest2\n\ntest3\n");
+    let s = str::from_utf8(&out.stdout).unwrap();
+    assert_eq!(s, "test1\ntest2\ntest3\n");
 }
 
 fn child() {
-    let mut stdin = old_io::stdin();
+    let mut stdin = io::stdin();
     for line in stdin.lock().lines() {
         println!("{}", line.unwrap());
     }
index 723db9485ca6ee110b2ced81aad5f69b60f193ae..7e4c464d9aaba7f37c5b650fe07725be6ca85505 100644 (file)
@@ -8,11 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
-use std::old_io::process;
-use std::old_io::Command;
-use std::old_io;
 use std::env;
+use std::io::prelude::*;
+use std::io;
+use std::process::{Command, Stdio};
 
 fn main() {
     let args: Vec<String> = env::args().collect();
@@ -21,22 +20,23 @@ fn main() {
     }
 
     test();
-
 }
 
 fn child() {
-    old_io::stdout().write_line("foo").unwrap();
-    old_io::stderr().write_line("bar").unwrap();
-    let mut stdin = old_io::stdin();
-    assert_eq!(stdin.lock().read_line().err().unwrap().kind, old_io::EndOfFile);
+    writeln!(&mut io::stdout(), "foo").unwrap();
+    writeln!(&mut io::stderr(), "bar").unwrap();
+    let mut stdin = io::stdin();
+    let mut s = String::new();
+    stdin.lock().read_line(&mut s).unwrap();
+    assert_eq!(s.len(), 0);
 }
 
 fn test() {
     let args: Vec<String> = env::args().collect();
     let mut p = Command::new(&args[0]).arg("child")
-                                     .stdin(process::Ignored)
-                                     .stdout(process::Ignored)
-                                     .stderr(process::Ignored)
+                                     .stdin(Stdio::capture())
+                                     .stdout(Stdio::capture())
+                                     .stderr(Stdio::capture())
                                      .spawn().unwrap();
     assert!(p.wait().unwrap().success());
 }
index b06c4923c16c1af370ea3f443e1932d4a3a7d475..1ebe3a7f068acc7184c3e334e70876dc919dcaf8 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// DON'T REENABLE THIS UNLESS YOU'VE ACTUALLY FIXED THE UNDERLYING ISSUE
+// ignore-android seems to block forever
 
 #![forbid(warnings)]
 
 // A var moved into a proc, that has a mutable loan path should
 // not trigger a misleading unused_mut warning.
 
+use std::io::prelude::*;
 use std::thread;
 
 pub fn main() {
-    let mut stdin = std::old_io::stdin();
+    let mut stdin = std::io::stdin();
     thread::spawn(move|| {
-        let _ = stdin.read_to_end();
-    });
+        let mut v = Vec::new();
+        let _ = stdin.read_to_end(&mut v);
+    }).join().ok().unwrap();
 }
index dd1cfb5e342832e9b50f87bae8687cfd0aaeae18..d4c32f42188bb0b4934f073c2c21955d3ecb4c7a 100644 (file)
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-use std::old_io;
+use std::io::{self, Write};
 
-fn f(wr: &mut Writer) {
-    wr.write_str("hello").ok().expect("failed");
+fn f(wr: &mut Write) {
+    wr.write_all(b"hello").ok().expect("failed");
 }
 
 fn main() {
-    let mut wr = box old_io::stdout() as Box<Writer + 'static>;
+    let mut wr = box io::stdout() as Box<Write>;
     f(&mut wr);
 }
diff --git a/src/test/run-pass/issue-22777.rs b/src/test/run-pass/issue-22777.rs
new file mode 100644 (file)
index 0000000..cab33be
--- /dev/null
@@ -0,0 +1,55 @@
+// 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.
+
+// This test is reduced from libsyntax.  It is just checking that we
+// can successfully deal with a "deep" structure, which the drop-check
+// was hitting a recursion limit on at one point.
+
+#![allow(non_camel_case_types)]
+
+pub fn noop_fold_impl_item() -> SmallVector<ImplItem> {
+    loop  { }
+}
+
+pub struct SmallVector<T>(P<T>);
+pub struct ImplItem(P<S01_Method>);
+
+struct P<T>(Box<T>);
+
+struct S01_Method(P<S02_Generics>);
+struct S02_Generics(P<S03_TyParam>);
+struct S03_TyParam(P<S04_TyParamBound>);
+struct S04_TyParamBound(S05_PolyTraitRef);
+struct S05_PolyTraitRef(S06_TraitRef);
+struct S06_TraitRef(S07_Path);
+struct S07_Path(Vec<S08_PathSegment>);
+struct S08_PathSegment(S09_PathParameters);
+struct S09_PathParameters(P<S10_ParenthesizedParameterData>);
+struct S10_ParenthesizedParameterData(Option<P<S11_Ty>>);
+struct S11_Ty(P<S12_Expr>);
+struct S12_Expr(P<S13_Block>);
+struct S13_Block(Vec<P<S14_Stmt>>);
+struct S14_Stmt(P<S15_Decl>);
+struct S15_Decl(P<S16_Local>);
+struct S16_Local(P<S17_Pat>);
+struct S17_Pat(P<S18_Mac>);
+struct S18_Mac(Vec<P<S19_TokenTree>>);
+struct S19_TokenTree(P<S20_Token>);
+struct S20_Token(P<S21_Nonterminal>);
+struct S21_Nonterminal(P<S22_Item>);
+struct S22_Item(P<S23_EnumDef>);
+struct S23_EnumDef(Vec<P<S24_Variant>>);
+struct S24_Variant(P<S25_VariantKind>);
+struct S25_VariantKind(P<S26_StructDef>);
+struct S26_StructDef(Vec<P<S27_StructField>>);
+struct S27_StructField(P<S28_StructFieldKind>);
+struct S28_StructFieldKind;
+
+pub fn main() {}
index 28ab3c3ef12537956feed46fcdfdc587f12bde1b..074bbf270fd7e26f87342ceca320fd7ae71ed3e7 100644 (file)
@@ -8,9 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::old_io;
+use std::io;
 
 pub fn main() {
-    let stdout = &mut old_io::stdout() as &mut old_io::Writer;
+    let stdout = &mut io::stdout() as &mut io::Write;
     stdout.write(b"Hello!");
 }
index 521aef4b5ba5b0b02bebe2e30381d75fc3d8c512..2752fc88b456b2b45c171d1a19bdf4d27d4f768d 100644 (file)
@@ -10,6 +10,8 @@
 
 // ignore-pretty - token trees can't pretty print
 
+#![feature(custom_attribute)]
+
 macro_rules! compiles_fine {
     (#[$at:meta]) => {
         // test that the different types of attributes work
index 017784990f4178ece9fcc4dff70c6cbca120b35e..3e5f84fa26fe075769334e213e478b5acf3234e5 100644 (file)
 // non-ASCII characters.  The child process ensures all the strings are
 // intact.
 
-use std::old_io;
-use std::old_io::fs;
-use std::old_io::Command;
+use std::io::prelude::*;
+use std::io;
+use std::fs;
+use std::process::Command;
 use std::os;
 use std::env;
-use std::old_path::Path;
+use std::path::{Path, PathBuf};
 
 fn main() {
     let my_args = env::args().collect::<Vec<_>>();
-    let my_cwd  = os::getcwd().unwrap();
+    let my_cwd  = PathBuf::new(os::getcwd().unwrap().as_str().unwrap());
     let my_env  = env::vars().collect::<Vec<_>>();
-    let my_path = Path::new(os::self_exe_name().unwrap());
-    let my_dir  = my_path.dir_path();
-    let my_ext  = my_path.extension_str().unwrap_or("");
+    let my_path = PathBuf::new(os::self_exe_name().unwrap().as_str().unwrap());
+    let my_dir  = my_path.parent().unwrap();
+    let my_ext  = my_path.extension().and_then(|s| s.to_str()).unwrap_or("");
 
     // some non-ASCII characters
-    let blah       = "\u03c0\u042f\u97f3\u00e6\u221e";
+    let blah       = "\u{3c0}\u{42f}\u{97f3}\u{e6}\u{221e}";
 
     let child_name = "child";
     let child_dir  = format!("process-spawn-with-unicode-params-{}", blah);
 
     // parameters sent to child / expected to be received from parent
     let arg = blah;
-    let cwd = my_dir.join(Path::new(child_dir.clone()));
+    let cwd = my_dir.join(&child_dir);
     let env = ("RUST_TEST_PROC_SPAWN_UNICODE".to_string(), blah.to_string());
 
     // am I the parent or the child?
@@ -47,24 +48,22 @@ fn main() {
 
         let child_filestem = Path::new(child_name);
         let child_filename = child_filestem.with_extension(my_ext);
-        let child_path     = cwd.join(child_filename);
+        let child_path     = cwd.join(&child_filename);
 
         // make a separate directory for the child
-        drop(fs::mkdir(&cwd, old_io::USER_RWX).is_ok());
-        assert!(fs::copy(&my_path, &child_path).is_ok());
-        let mut my_env = my_env;
-        my_env.push(env);
+        let _ = fs::create_dir(&cwd);
+        fs::copy(&my_path, &child_path).unwrap();
 
         // run child
         let p = Command::new(&child_path)
                         .arg(arg)
-                        .cwd(&cwd)
-                        .env_set_all(&my_env)
+                        .current_dir(&cwd)
+                        .env(&env.0, &env.1)
                         .spawn().unwrap().wait_with_output().unwrap();
 
         // display the output
-        assert!(old_io::stdout().write(&p.output).is_ok());
-        assert!(old_io::stderr().write(&p.error).is_ok());
+        io::stdout().write_all(&p.stdout).unwrap();
+        io::stderr().write_all(&p.stderr).unwrap();
 
         // make sure the child succeeded
         assert!(p.status.success());
@@ -72,7 +71,7 @@ fn main() {
     } else {                            // child
 
         // check working directory (don't try to compare with `cwd` here!)
-        assert!(my_cwd.ends_with_path(&Path::new(child_dir)));
+        assert!(my_cwd.ends_with(&child_dir));
 
         // check arguments
         assert_eq!(&*my_args[1], arg);