]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #34216 - jseyfried:nested_cfg_attr, r=nrc
authorbors <bors@rust-lang.org>
Thu, 16 Jun 2016 10:49:55 +0000 (03:49 -0700)
committerGitHub <noreply@github.com>
Thu, 16 Jun 2016 10:49:55 +0000 (03:49 -0700)
Support nested `cfg_attr` attributes

Support arbitrarily deeply nested `cfg_attr` attributes (e.g. `#[cfg_attr(foo, cfg_attr(bar, baz))]`).
This makes configuration idempotent.

Currently, the nighties do not support any `cfg_attr` nesting. Stable and beta support just one level of `cfg_attr` nesting (expect for attributes on macro-expanded nodes, where no nesting is supported).

This is a [breaking-change]. For example, the following would break:
```rust
macro_rules! m { () => {
    #[cfg_attr(all(), cfg_attr(all(), cfg(foo)))]
    fn f() {}
} }
m!();

fn main() { f() } //~ ERROR unresolved name `f`
```
r? @nrc

109 files changed:
README.md
configure
mk/tests.mk
src/doc/book/error-handling.md
src/doc/book/loops.md
src/doc/book/no-stdlib.md
src/doc/book/primitive-types.md
src/doc/book/references-and-borrowing.md
src/doc/reference.md
src/liballoc_jemalloc/build.rs
src/liballoc_jemalloc/lib.rs
src/libcollections/btree/map.rs
src/libcollections/btree/set.rs
src/libcollectionstest/str.rs
src/libcore/any.rs
src/libcore/ops.rs
src/libcore/sync/atomic.rs
src/libflate/lib.rs
src/librustc/diagnostics.rs
src/librustc/hir/lowering.rs
src/librustc/hir/mod.rs
src/librustc/hir/print.rs
src/librustc/infer/error_reporting.rs
src/librustc/middle/dead.rs
src/librustc/middle/resolve_lifetime.rs
src/librustc_bitflags/lib.rs
src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs
src/librustc_borrowck/borrowck/mir/elaborate_drops.rs
src/librustc_borrowck/diagnostics.rs
src/librustc_const_eval/check_match.rs
src/librustc_const_eval/eval.rs
src/librustc_const_math/is.rs
src/librustc_const_math/us.rs
src/librustc_data_structures/bitvec.rs
src/librustc_data_structures/tuple_slice.rs
src/librustc_driver/driver.rs
src/librustc_lint/builtin.rs
src/librustc_llvm/lib.rs
src/librustc_metadata/creader.rs
src/librustc_mir/build/expr/as_rvalue.rs
src/librustc_trans/back/archive.rs
src/librustc_trans/back/link.rs
src/librustc_trans/base.rs
src/librustc_trans/context.rs
src/librustc_trans/debuginfo/create_scope_map.rs
src/librustc_trans/debuginfo/metadata.rs
src/librustc_trans/monomorphize.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/diagnostics.rs
src/librustc_unicode/char.rs
src/librustdoc/clean/mod.rs
src/librustdoc/html/render.rs
src/librustdoc/html/static/rustdoc.css
src/librustdoc/visit_ast.rs
src/libstd/collections/hash/map.rs
src/libstd/collections/hash/table.rs
src/libstd/fs.rs
src/libstd/net/ip.rs
src/libstd/process.rs
src/libstd/sys/windows/c.rs
src/libstd/sys/windows/mod.rs
src/libsyntax/ast.rs
src/libsyntax/config.rs
src/libsyntax/ext/base.rs
src/libsyntax/ext/expand.rs
src/libsyntax/parse/parser.rs
src/libsyntax/print/pprust.rs
src/libsyntax/test.rs
src/libsyntax/util/interner.rs
src/libsyntax/visit.rs
src/rustllvm/ArchiveWrapper.cpp
src/rustllvm/ExecutionEngineWrapper.cpp
src/rustllvm/PassWrapper.cpp
src/rustllvm/RustWrapper.cpp
src/test/codegen-units/item-collection/generic-impl.rs
src/test/codegen/issue-32031.rs [new file with mode: 0644]
src/test/codegen/issue-32364.rs [new file with mode: 0644]
src/test/compile-fail/bad-format-args.rs [new file with mode: 0644]
src/test/compile-fail/cfg-non-opt-expr.rs
src/test/compile-fail/custom_attribute.rs
src/test/compile-fail/ifmt-bad-arg.rs
src/test/compile-fail/issue-18819.rs
src/test/compile-fail/issue-25579.rs [new file with mode: 0644]
src/test/compile-fail/issue-3044.rs
src/test/compile-fail/issue-33293.rs [new file with mode: 0644]
src/test/compile-fail/issue-34171.rs [new file with mode: 0644]
src/test/compile-fail/issue-4935.rs
src/test/compile-fail/macro-backtrace-println.rs
src/test/compile-fail/macros-nonfatal-errors.rs
src/test/compile-fail/method-call-err-msg.rs
src/test/compile-fail/not-enough-arguments.rs
src/test/compile-fail/overloaded-calls-bad.rs
src/test/compile-fail/range_traits-1.rs [new file with mode: 0644]
src/test/compile-fail/range_traits-2.rs [new file with mode: 0644]
src/test/compile-fail/range_traits-3.rs [new file with mode: 0644]
src/test/compile-fail/range_traits-4.rs [new file with mode: 0644]
src/test/compile-fail/range_traits-5.rs [new file with mode: 0644]
src/test/compile-fail/range_traits-6.rs [new file with mode: 0644]
src/test/compile-fail/range_traits-7.rs [new file with mode: 0644]
src/test/compile-fail/trace_macros-gate.rs
src/test/compile-fail/variadic-ffi-3.rs
src/test/debuginfo/function-arg-initialization.rs
src/test/run-pass/issue-23477.rs [new file with mode: 0644]
src/test/rustdoc/inline_cross/hidden-use.rs [new file with mode: 0644]
src/test/rustdoc/inline_local/hidden-use.rs [new file with mode: 0644]
src/test/rustdoc/issue-34025.rs [new file with mode: 0644]
src/test/rustdoc/redirect-rename.rs [new file with mode: 0644]
src/tools/cargotest/main.rs
src/tools/linkchecker/main.rs

index 4e476b4f357ec945f44747f8526cde2f4032088a..bc41e62b36a0094e233e6b0e8baaf23aa888e535 100644 (file)
--- a/README.md
+++ b/README.md
@@ -75,13 +75,13 @@ build.
    $ pacman -Sy pacman-mirrors
    ```
 
-Download [MinGW from
-here](http://mingw-w64.org/doku.php/download/mingw-builds), and choose the
-`version=4.9.x,threads=win32,exceptions=dwarf/seh` flavor when installing. Also, make sure to install to a path without spaces in it. After installing,
-add its `bin` directory to your `PATH`. This is due to [#28260](https://github.com/rust-lang/rust/issues/28260), in the future,
-installing from pacman should be just fine.
+   Download [MinGW from
+   here](http://mingw-w64.org/doku.php/download/mingw-builds), and choose the
+   `version=4.9.x,threads=win32,exceptions=dwarf/seh` flavor when installing. Also, make sure to install to a path without spaces in it. After installing,
+   add its `bin` directory to your `PATH`. This is due to [#28260](https://github.com/rust-lang/rust/issues/28260), in the future,
+   installing from pacman should be just fine.
 
-   ```
+   ```sh
    # Make git available in MSYS2 (if not already available on path)
    $ pacman -S git
 
@@ -90,6 +90,8 @@ installing from pacman should be just fine.
 
 3. Run `mingw32_shell.bat` or `mingw64_shell.bat` from wherever you installed
    MSYS2 (i.e. `C:\msys`), depending on whether you want 32-bit or 64-bit Rust.
+   (As of the latest version of MSYS2 you have to run `msys2_shell.cmd -mingw32`
+   or `msys2_shell.cmd -mingw64` from the command line instead)
 
 4. Navigate to Rust's source code, configure and build it:
 
index 5edfd0ed5a1c88088e1783249914083fdfee7eef..49950d2840dff9126a5152679b9a6a07d7e66f18 100755 (executable)
--- a/configure
+++ b/configure
@@ -594,7 +594,7 @@ opt docs     1 "build standard library documentation"
 opt compiler-docs     0 "build compiler documentation"
 opt optimize-tests 1 "build tests with optimizations"
 opt debuginfo-tests 0 "build tests with debugger metadata"
-opt libcpp 1 "build with llvm with libc++ instead of libstdc++ when using clang"
+opt libcpp 1 "build llvm with libc++ instead of libstdc++ when using clang"
 opt llvm-assertions 0 "build LLVM with assertions"
 opt debug-assertions 0 "build with debugging assertions"
 opt fast-make 0 "use .gitmodules as timestamp for submodule deps"
index f9ab84e3f8ccf4f2c45624cb6f737c675bc45e26..ed443147d466e3734bf5a209ff23aed0a7e166f8 100644 (file)
@@ -276,6 +276,7 @@ check-stage$(1)-T-$(2)-H-$(3)-exec: \
        check-stage$(1)-T-$(2)-H-$(3)-incremental-exec \
        check-stage$(1)-T-$(2)-H-$(3)-ui-exec \
        check-stage$(1)-T-$(2)-H-$(3)-doc-exec \
+       check-stage$(1)-T-$(2)-H-$(3)-doc-error-index-exec \
        check-stage$(1)-T-$(2)-H-$(3)-pretty-exec
 
 ifndef CFG_DISABLE_CODEGEN_TESTS
index d94eeaebf4021447c8428906371c500bf3d33f05..544f837d69b264171df652134267d1f5f1551491 100644 (file)
@@ -1829,7 +1829,7 @@ use std::error::Error;
 
 fn search<P: AsRef<Path>>
          (file_path: P, city: &str)
-         -> Result<Vec<PopulationCount>, Box<Error+Send+Sync>> {
+         -> Result<Vec<PopulationCount>, Box<Error>> {
     let mut found = vec![];
     let file = try!(File::open(file_path));
     let mut rdr = csv::Reader::from_reader(file);
@@ -1858,20 +1858,17 @@ Instead of `x.unwrap()`, we now have `try!(x)`. Since our function returns a
 `Result<T, E>`, the `try!` macro will return early from the function if an
 error occurs.
 
-There is one big gotcha in this code: we used `Box<Error + Send + Sync>`
-instead of `Box<Error>`. We did this so we could convert a plain string to an
-error type. We need these extra bounds so that we can use the
-[corresponding `From`
-impls](../std/convert/trait.From.html):
+At the end of `search` we also convert a plain string to an error type 
+by using the [corresponding `From` impls](../std/convert/trait.From.html):
 
 ```rust,ignore
 // We are making use of this impl in the code above, since we call `From::from`
 // on a `&'static str`.
-impl<'a, 'b> From<&'b str> for Box<Error + Send + Sync + 'a>
+impl<'a> From<&'a str> for Box<Error>
 
 // But this is also useful when you need to allocate a new string for an
 // error message, usually with `format!`.
-impl From<String> for Box<Error + Send + Sync>
+impl From<String> for Box<Error>
 ```
 
 Since `search` now returns a `Result<T, E>`, `main` should use case analysis
@@ -1964,7 +1961,7 @@ use std::io;
 
 fn search<P: AsRef<Path>>
          (file_path: &Option<P>, city: &str)
-         -> Result<Vec<PopulationCount>, Box<Error+Send+Sync>> {
+         -> Result<Vec<PopulationCount>, Box<Error>> {
     let mut found = vec![];
     let input: Box<io::Read> = match *file_path {
         None => Box::new(io::stdin()),
@@ -2175,9 +2172,8 @@ heuristics!
   `unwrap`. Be warned: if it winds up in someone else's hands, don't be
   surprised if they are agitated by poor error messages!
 * If you're writing a quick 'n' dirty program and feel ashamed about panicking
-  anyway, then use either a `String` or a `Box<Error + Send + Sync>` for your
-  error type (the `Box<Error + Send + Sync>` type is because of the
-  [available `From` impls](../std/convert/trait.From.html)).
+  anyway, then use either a `String` or a `Box<Error>` for your
+  error type.
 * Otherwise, in a program, define your own error types with appropriate
   [`From`](../std/convert/trait.From.html)
   and
index 97ca2e3e702f6cf926e54e88679beb1eff7dfe1a..e23e6f3a786a5c0e816edb6f27370f3aaf20caf7 100644 (file)
@@ -178,7 +178,7 @@ loop {
 
 We now loop forever with `loop` and use `break` to break out early. Issuing an explicit `return` statement will also serve to terminate the loop early.
 
-`continue` is similar, but instead of ending the loop, goes to the next
+`continue` is similar, but instead of ending the loop, it goes to the next
 iteration. This will only print the odd numbers:
 
 ```rust
index 9823a0b6d6355b7d5d3509549514f060fbad54d5..c5c139e6580b015b91d49bd6d90a66d037b04f41 100644 (file)
@@ -12,9 +12,26 @@ don’t want to use the standard library via an attribute: `#![no_std]`.
 > `#![no_std]`](using-rust-without-the-standard-library.html)
 
 Obviously there's more to life than just libraries: one can use
-`#[no_std]` with an executable, controlling the entry point is
-possible in two ways: the `#[start]` attribute, or overriding the
-default shim for the C `main` function with your own.
+`#[no_std]` with an executable.
+
+### Using libc
+
+In order to build a `#[no_std]` executable we will need libc as a dependency. We can specify
+this using our `Cargo.toml` file:
+
+```toml
+[dependencies]
+libc = { version = "0.2.11", default-features = false }
+```
+
+Note that the default features have been disabled. This is a critical step -
+**the default features of libc include the standard library and so must be
+disabled.**
+
+### Writing an executable without stdlib
+
+Controlling the entry point is possible in two ways: the `#[start]` attribute,
+or overriding the default shim for the C `main` function with your own.
 
 The function marked `#[start]` is passed the command line parameters
 in the same format as C:
@@ -72,7 +89,6 @@ pub extern fn main(argc: i32, argv: *const *const u8) -> i32 {
 # // fn main() {} tricked you, rustdoc!
 ```
 
-
 The compiler currently makes a few assumptions about symbols which are available
 in the executable to call. Normally these functions are provided by the standard
 library, but without it you must define your own.
index b6a123bb3674c9adb0728b002a6cd9d4df94bf8b..ea0bdf29fcc41d7a34be7da8e72d4fb38c934180 100644 (file)
@@ -163,7 +163,7 @@ A ‘slice’ is a reference to (or “view” into) another data structure. The
 useful for allowing safe, efficient access to a portion of an array without
 copying. For example, you might want to reference only one line of a file read
 into memory. By nature, a slice is not created directly, but from an existing
-variable binding. Slices have a defined length, can be mutable or immutable.
+variable binding. Slices have a defined length, and can be mutable or immutable.
 
 Internally, slices are represented as a pointer to the beginning of the data
 and a length.
index a28f450c942af04cf36302c15483bb13df3a0a1c..ef339a14309898fecfef64adecbe686d922d6b04 100644 (file)
@@ -85,7 +85,7 @@ fn main() {
     fn sum_vec(v: &Vec<i32>) -> i32 {
         return v.iter().fold(0, |a, &b| a + b);
     }
-    // Borrow two vectors and and sum them.
+    // Borrow two vectors and sum them.
     // This kind of borrowing does not allow mutation to the borrowed.
     fn foo(v1: &Vec<i32>, v2: &Vec<i32>) -> i32 {
         // do stuff with v1 and v2
index fac9cfadd976e750a66fc98d614d133347d070c5..fb8ea0f5661d3f404df50c0c06c68e9625a48765 100644 (file)
@@ -1628,7 +1628,7 @@ Functions within external blocks may be called by Rust code, just like
 functions defined in Rust. The Rust compiler automatically translates between
 the Rust ABI and the foreign ABI.
 
-A number of [attributes](#attributes) control the behavior of external blocks.
+A number of [attributes](#ffi-attributes) control the behavior of external blocks.
 
 By default external blocks assume that the library they are calling uses the
 standard C "cdecl" ABI. Other ABIs may be specified using an `abi` string, as
index 33a675331ab9dbb91e471e2a9b9d2ffde3e223fc..e43b9a9df1b84f19af23ee5643f6ae2f1629c828 100644 (file)
@@ -33,18 +33,26 @@ fn main() {
                  jemalloc.parent().unwrap().display());
         let stem = jemalloc.file_stem().unwrap().to_str().unwrap();
         let name = jemalloc.file_name().unwrap().to_str().unwrap();
-        let kind = if name.ends_with(".a") {"static"} else {"dylib"};
+        let kind = if name.ends_with(".a") {
+            "static"
+        } else {
+            "dylib"
+        };
         println!("cargo:rustc-link-lib={}={}", kind, &stem[3..]);
-        return
+        return;
     }
 
     let compiler = gcc::Config::new().get_compiler();
     let ar = build_helper::cc2ar(compiler.path(), &target);
-    let cflags = compiler.args().iter().map(|s| s.to_str().unwrap())
-                         .collect::<Vec<_>>().join(" ");
+    let cflags = compiler.args()
+                         .iter()
+                         .map(|s| s.to_str().unwrap())
+                         .collect::<Vec<_>>()
+                         .join(" ");
 
     let mut stack = src_dir.join("../jemalloc")
-                           .read_dir().unwrap()
+                           .read_dir()
+                           .unwrap()
                            .map(|e| e.unwrap())
                            .collect::<Vec<_>>();
     while let Some(entry) = stack.pop() {
@@ -57,7 +65,9 @@ fn main() {
     }
 
     let mut cmd = Command::new("sh");
-    cmd.arg(src_dir.join("../jemalloc/configure").to_str().unwrap()
+    cmd.arg(src_dir.join("../jemalloc/configure")
+                   .to_str()
+                   .unwrap()
                    .replace("C:\\", "/c/")
                    .replace("\\", "/"))
        .current_dir(&build_dir)
@@ -117,9 +127,10 @@ fn main() {
 
     run(&mut cmd);
     run(Command::new("make")
-                .current_dir(&build_dir)
-                .arg("build_lib_static")
-                .arg("-j").arg(env::var("NUM_JOBS").unwrap()));
+            .current_dir(&build_dir)
+            .arg("build_lib_static")
+            .arg("-j")
+            .arg(env::var("NUM_JOBS").unwrap()));
 
     if target.contains("windows") {
         println!("cargo:rustc-link-lib=static=jemalloc");
index 7651d91c06d6bb55d2368cd247a011e483d50c56..347e97e6ffc0a8ddd84e25b3a0637bf499d0ab8a 100644 (file)
                not(target_env = "musl")),
            link(name = "pthread"))]
 #[cfg(not(cargobuild))]
-extern {}
+extern "C" {}
 
 // Note that the symbols here are prefixed by default on OSX and Windows (we
 // don't explicitly request it), and on Android and DragonFly we explicitly
 // request it as unprefixing cause segfaults (mismatches in allocators).
-extern {
+extern "C" {
     #[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios",
                    target_os = "dragonfly", target_os = "windows"),
                link_name = "je_mallocx")]
@@ -136,8 +136,9 @@ pub extern "C" fn __rust_usable_size(size: usize, align: usize) -> usize {
 // are available.
 #[no_mangle]
 #[cfg(target_os = "android")]
-pub extern fn pthread_atfork(_prefork: *mut u8,
-                             _postfork_parent: *mut u8,
-                             _postfork_child: *mut u8) -> i32 {
+pub extern "C" fn pthread_atfork(_prefork: *mut u8,
+                                 _postfork_parent: *mut u8,
+                                 _postfork_child: *mut u8)
+                                 -> i32 {
     0
 }
index 29f3e4b1b6159cd4a02d23baf4468d653180af39..3b775dc2865eea0b2cb9ba1ea83731592098c600 100644 (file)
@@ -17,9 +17,9 @@
 use core::{fmt, intrinsics, mem, ptr};
 
 use borrow::Borrow;
-use Bound::{self, Included, Excluded, Unbounded};
+use Bound::{self, Excluded, Included, Unbounded};
 
-use super::node::{self, NodeRef, Handle, marker};
+use super::node::{self, Handle, NodeRef, marker};
 use super::search;
 
 use super::node::InsertResult::*;
@@ -68,7 +68,7 @@
 /// // would be `BTreeMap<&str, &str>` in this example).
 /// let mut movie_reviews = BTreeMap::new();
 ///
-/// // review some books.
+/// // review some movies.
 /// movie_reviews.insert("Office Space",       "Deals with real issues in the workplace.");
 /// movie_reviews.insert("Pulp Fiction",       "Masterpiece.");
 /// movie_reviews.insert("The Godfather",      "Very enjoyable.");
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct BTreeMap<K, V> {
     root: node::Root<K, V>,
-    length: usize
+    length: usize,
 }
 
 impl<K, V> Drop for BTreeMap<K, V> {
     #[unsafe_destructor_blind_to_params]
     fn drop(&mut self) {
         unsafe {
-            for _ in ptr::read(self).into_iter() { }
+            for _ in ptr::read(self).into_iter() {
+            }
         }
     }
 }
 
 impl<K: Clone, V: Clone> Clone for BTreeMap<K, V> {
     fn clone(&self) -> BTreeMap<K, V> {
-        fn clone_subtree<K: Clone, V: Clone>(
-                node: node::NodeRef<marker::Immut, K, V, marker::LeafOrInternal>)
-                -> BTreeMap<K, V> {
+        fn clone_subtree<K: Clone, V: Clone>(node: node::NodeRef<marker::Immut,
+                                                                 K,
+                                                                 V,
+                                                                 marker::LeafOrInternal>)
+                                             -> BTreeMap<K, V> {
 
             match node.force() {
                 Leaf(leaf) => {
                     let mut out_tree = BTreeMap {
                         root: node::Root::new_leaf(),
-                        length: 0
+                        length: 0,
                     };
 
                     {
                         let mut out_node = match out_tree.root.as_mut().force() {
                             Leaf(leaf) => leaf,
-                            Internal(_) => unreachable!()
+                            Internal(_) => unreachable!(),
                         };
 
                         let mut in_edge = leaf.first_edge();
@@ -171,7 +174,7 @@ fn clone_subtree<K: Clone, V: Clone>(
                     }
 
                     out_tree
-                },
+                }
                 Internal(internal) => {
                     let mut out_tree = clone_subtree(internal.first_edge().descend());
 
@@ -218,7 +221,7 @@ impl<K, Q: ?Sized> super::Recover<Q> for BTreeMap<K, ()>
     fn get(&self, key: &Q) -> Option<&K> {
         match search::search_tree(self.root.as_ref(), key) {
             Found(handle) => Some(handle.into_kv().0),
-            GoDown(_) => None
+            GoDown(_) => None,
         }
     }
 
@@ -226,12 +229,14 @@ fn take(&mut self, key: &Q) -> Option<K> {
         match search::search_tree(self.root.as_mut(), key) {
             Found(handle) => {
                 Some(OccupiedEntry {
-                    handle: handle,
-                    length: &mut self.length,
-                    _marker: PhantomData,
-                }.remove_kv().0)
-            },
-            GoDown(_) => None
+                         handle: handle,
+                         length: &mut self.length,
+                         _marker: PhantomData,
+                     }
+                     .remove_kv()
+                     .0)
+            }
+            GoDown(_) => None,
         }
     }
 
@@ -244,7 +249,8 @@ fn replace(&mut self, key: K) -> Option<K> {
                     handle: handle,
                     length: &mut self.length,
                     _marker: PhantomData,
-                }.insert(());
+                }
+                .insert(());
                 None
             }
         }
@@ -255,14 +261,14 @@ fn replace(&mut self, key: K) -> Option<K> {
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Iter<'a, K: 'a, V: 'a> {
     range: Range<'a, K, V>,
-    length: usize
+    length: usize,
 }
 
 /// A mutable iterator over a BTreeMap's entries.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct IterMut<'a, K: 'a, V: 'a> {
     range: RangeMut<'a, K, V>,
-    length: usize
+    length: usize,
 }
 
 /// An owning iterator over a BTreeMap's entries.
@@ -270,7 +276,7 @@ pub struct IterMut<'a, K: 'a, V: 'a> {
 pub struct IntoIter<K, V> {
     front: Handle<NodeRef<marker::Owned, K, V, marker::Leaf>, marker::Edge>,
     back: Handle<NodeRef<marker::Owned, K, V, marker::Leaf>, marker::Edge>,
-    length: usize
+    length: usize,
 }
 
 /// An iterator over a BTreeMap's keys.
@@ -294,7 +300,7 @@ pub struct ValuesMut<'a, K: 'a, V: 'a> {
 /// An iterator over a sub-range of BTreeMap's entries.
 pub struct Range<'a, K: 'a, V: 'a> {
     front: Handle<NodeRef<marker::Immut<'a>, K, V, marker::Leaf>, marker::Edge>,
-    back: Handle<NodeRef<marker::Immut<'a>, K, V, marker::Leaf>, marker::Edge>
+    back: Handle<NodeRef<marker::Immut<'a>, K, V, marker::Leaf>, marker::Edge>,
 }
 
 /// A mutable iterator over a sub-range of BTreeMap's entries.
@@ -311,15 +317,13 @@ pub struct RangeMut<'a, K: 'a, V: 'a> {
 pub enum Entry<'a, K: 'a, V: 'a> {
     /// A vacant Entry
     #[stable(feature = "rust1", since = "1.0.0")]
-    Vacant(
-        #[stable(feature = "rust1", since = "1.0.0")] VacantEntry<'a, K, V>
-    ),
+    Vacant(#[stable(feature = "rust1", since = "1.0.0")]
+           VacantEntry<'a, K, V>),
 
     /// An occupied Entry
     #[stable(feature = "rust1", since = "1.0.0")]
-    Occupied(
-        #[stable(feature = "rust1", since = "1.0.0")] OccupiedEntry<'a, K, V>
-    ),
+    Occupied(#[stable(feature = "rust1", since = "1.0.0")]
+             OccupiedEntry<'a, K, V>),
 }
 
 /// A vacant Entry.
@@ -336,11 +340,7 @@ pub struct VacantEntry<'a, K: 'a, V: 'a> {
 /// An occupied Entry.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct OccupiedEntry<'a, K: 'a, V: 'a> {
-    handle: Handle<NodeRef<
-        marker::Mut<'a>,
-        K, V,
-        marker::LeafOrInternal
-    >, marker::KV>,
+    handle: Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>, marker::KV>,
 
     length: &'a mut usize,
 
@@ -349,7 +349,7 @@ pub struct OccupiedEntry<'a, K: 'a, V: 'a> {
 }
 
 // An iterator for merging two sorted sequences into one
-struct MergeIter<K, V, I: Iterator<Item=(K, V)>> {
+struct MergeIter<K, V, I: Iterator<Item = (K, V)>> {
     left: Peekable<I>,
     right: Peekable<I>,
 }
@@ -373,7 +373,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
     pub fn new() -> BTreeMap<K, V> {
         BTreeMap {
             root: node::Root::new_leaf(),
-            length: 0
+            length: 0,
         }
     }
 
@@ -415,10 +415,13 @@ pub fn clear(&mut self) {
     /// assert_eq!(map.get(&2), None);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn get<Q: ?Sized>(&self, key: &Q) -> Option<&V> where K: Borrow<Q>, Q: Ord {
+    pub fn get<Q: ?Sized>(&self, key: &Q) -> Option<&V>
+        where K: Borrow<Q>,
+              Q: Ord
+    {
         match search::search_tree(self.root.as_ref(), key) {
             Found(handle) => Some(handle.into_kv().1),
-            GoDown(_) => None
+            GoDown(_) => None,
         }
     }
 
@@ -440,7 +443,10 @@ pub fn get<Q: ?Sized>(&self, key: &Q) -> Option<&V> where K: Borrow<Q>, Q: Ord {
     /// assert_eq!(map.contains_key(&2), false);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn contains_key<Q: ?Sized>(&self, key: &Q) -> bool where K: Borrow<Q>, Q: Ord {
+    pub fn contains_key<Q: ?Sized>(&self, key: &Q) -> bool
+        where K: Borrow<Q>,
+              Q: Ord
+    {
         self.get(key).is_some()
     }
 
@@ -465,10 +471,13 @@ pub fn contains_key<Q: ?Sized>(&self, key: &Q) -> bool where K: Borrow<Q>, Q: Or
     /// ```
     // See `get` for implementation notes, this is basically a copy-paste with mut's added
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn get_mut<Q: ?Sized>(&mut self, key: &Q) -> Option<&mut V> where K: Borrow<Q>, Q: Ord {
+    pub fn get_mut<Q: ?Sized>(&mut self, key: &Q) -> Option<&mut V>
+        where K: Borrow<Q>,
+              Q: Ord
+    {
         match search::search_tree(self.root.as_mut(), key) {
             Found(handle) => Some(handle.into_kv_mut().1),
-            GoDown(_) => None
+            GoDown(_) => None,
         }
     }
 
@@ -528,16 +537,20 @@ pub fn insert(&mut self, key: K, value: V) -> Option<V> {
     /// assert_eq!(map.remove(&1), None);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn remove<Q: ?Sized>(&mut self, key: &Q) -> Option<V> where K: Borrow<Q>, Q: Ord {
+    pub fn remove<Q: ?Sized>(&mut self, key: &Q) -> Option<V>
+        where K: Borrow<Q>,
+              Q: Ord
+    {
         match search::search_tree(self.root.as_mut(), key) {
             Found(handle) => {
                 Some(OccupiedEntry {
-                    handle: handle,
-                    length: &mut self.length,
-                    _marker: PhantomData,
-                }.remove())
-            },
-            GoDown(_) => None
+                         handle: handle,
+                         length: &mut self.length,
+                         _marker: PhantomData,
+                     }
+                     .remove())
+            }
+            GoDown(_) => None,
         }
     }
 
@@ -571,7 +584,7 @@ pub fn remove<Q: ?Sized>(&mut self, key: &Q) -> Option<V> where K: Borrow<Q>, Q:
     /// assert_eq!(a[&5], "f");
     /// ```
     #[unstable(feature = "btree_append", reason = "recently added as part of collections reform 2",
-               issue = "19986")]
+               issue = "34152")]
     pub fn append(&mut self, other: &mut Self) {
         // Do we have to append anything at all?
         if other.len() == 0 {
@@ -628,47 +641,63 @@ pub fn range<Min: ?Sized + Ord, Max: ?Sized + Ord>(&self,
                                                        min: Bound<&Min>,
                                                        max: Bound<&Max>)
                                                        -> Range<K, V>
-        where K: Borrow<Min> + Borrow<Max>,
+        where K: Borrow<Min> + Borrow<Max>
     {
         let front = match min {
-            Included(key) => match search::search_tree(self.root.as_ref(), key) {
-                Found(kv_handle) => match kv_handle.left_edge().force() {
-                    Leaf(bottom) => bottom,
-                    Internal(internal) => last_leaf_edge(internal.descend())
-                },
-                GoDown(bottom) => bottom
-            },
-            Excluded(key) => match search::search_tree(self.root.as_ref(), key) {
-                Found(kv_handle) => match kv_handle.right_edge().force() {
-                    Leaf(bottom) => bottom,
-                    Internal(internal) => first_leaf_edge(internal.descend())
-                },
-                GoDown(bottom) => bottom
-            },
-            Unbounded => first_leaf_edge(self.root.as_ref())
+            Included(key) => {
+                match search::search_tree(self.root.as_ref(), key) {
+                    Found(kv_handle) => {
+                        match kv_handle.left_edge().force() {
+                            Leaf(bottom) => bottom,
+                            Internal(internal) => last_leaf_edge(internal.descend()),
+                        }
+                    }
+                    GoDown(bottom) => bottom,
+                }
+            }
+            Excluded(key) => {
+                match search::search_tree(self.root.as_ref(), key) {
+                    Found(kv_handle) => {
+                        match kv_handle.right_edge().force() {
+                            Leaf(bottom) => bottom,
+                            Internal(internal) => first_leaf_edge(internal.descend()),
+                        }
+                    }
+                    GoDown(bottom) => bottom,
+                }
+            }
+            Unbounded => first_leaf_edge(self.root.as_ref()),
         };
 
         let back = match max {
-            Included(key) => match search::search_tree(self.root.as_ref(), key) {
-                Found(kv_handle) => match kv_handle.right_edge().force() {
-                    Leaf(bottom) => bottom,
-                    Internal(internal) => first_leaf_edge(internal.descend())
-                },
-                GoDown(bottom) => bottom
-            },
-            Excluded(key) => match search::search_tree(self.root.as_ref(), key) {
-                Found(kv_handle) => match kv_handle.left_edge().force() {
-                    Leaf(bottom) => bottom,
-                    Internal(internal) => last_leaf_edge(internal.descend())
-                },
-                GoDown(bottom) => bottom
-            },
-            Unbounded => last_leaf_edge(self.root.as_ref())
+            Included(key) => {
+                match search::search_tree(self.root.as_ref(), key) {
+                    Found(kv_handle) => {
+                        match kv_handle.right_edge().force() {
+                            Leaf(bottom) => bottom,
+                            Internal(internal) => first_leaf_edge(internal.descend()),
+                        }
+                    }
+                    GoDown(bottom) => bottom,
+                }
+            }
+            Excluded(key) => {
+                match search::search_tree(self.root.as_ref(), key) {
+                    Found(kv_handle) => {
+                        match kv_handle.left_edge().force() {
+                            Leaf(bottom) => bottom,
+                            Internal(internal) => last_leaf_edge(internal.descend()),
+                        }
+                    }
+                    GoDown(bottom) => bottom,
+                }
+            }
+            Unbounded => last_leaf_edge(self.root.as_ref()),
         };
 
         Range {
             front: front,
-            back: back
+            back: back,
         }
     }
 
@@ -704,51 +733,67 @@ pub fn range_mut<Min: ?Sized + Ord, Max: ?Sized + Ord>(&mut self,
                                                            min: Bound<&Min>,
                                                            max: Bound<&Max>)
                                                            -> RangeMut<K, V>
-        where K: Borrow<Min> + Borrow<Max>,
+        where K: Borrow<Min> + Borrow<Max>
     {
         let root1 = self.root.as_mut();
         let root2 = unsafe { ptr::read(&root1) };
 
         let front = match min {
-            Included(key) => match search::search_tree(root1, key) {
-                Found(kv_handle) => match kv_handle.left_edge().force() {
-                    Leaf(bottom) => bottom,
-                    Internal(internal) => last_leaf_edge(internal.descend())
-                },
-                GoDown(bottom) => bottom
-            },
-            Excluded(key) => match search::search_tree(root1, key) {
-                Found(kv_handle) => match kv_handle.right_edge().force() {
-                    Leaf(bottom) => bottom,
-                    Internal(internal) => first_leaf_edge(internal.descend())
-                },
-                GoDown(bottom) => bottom
-            },
-            Unbounded => first_leaf_edge(root1)
+            Included(key) => {
+                match search::search_tree(root1, key) {
+                    Found(kv_handle) => {
+                        match kv_handle.left_edge().force() {
+                            Leaf(bottom) => bottom,
+                            Internal(internal) => last_leaf_edge(internal.descend()),
+                        }
+                    }
+                    GoDown(bottom) => bottom,
+                }
+            }
+            Excluded(key) => {
+                match search::search_tree(root1, key) {
+                    Found(kv_handle) => {
+                        match kv_handle.right_edge().force() {
+                            Leaf(bottom) => bottom,
+                            Internal(internal) => first_leaf_edge(internal.descend()),
+                        }
+                    }
+                    GoDown(bottom) => bottom,
+                }
+            }
+            Unbounded => first_leaf_edge(root1),
         };
 
         let back = match max {
-            Included(key) => match search::search_tree(root2, key) {
-                Found(kv_handle) => match kv_handle.right_edge().force() {
-                    Leaf(bottom) => bottom,
-                    Internal(internal) => first_leaf_edge(internal.descend())
-                },
-                GoDown(bottom) => bottom
-            },
-            Excluded(key) => match search::search_tree(root2, key) {
-                Found(kv_handle) => match kv_handle.left_edge().force() {
-                    Leaf(bottom) => bottom,
-                    Internal(internal) => last_leaf_edge(internal.descend())
-                },
-                GoDown(bottom) => bottom
-            },
-            Unbounded => last_leaf_edge(root2)
+            Included(key) => {
+                match search::search_tree(root2, key) {
+                    Found(kv_handle) => {
+                        match kv_handle.right_edge().force() {
+                            Leaf(bottom) => bottom,
+                            Internal(internal) => first_leaf_edge(internal.descend()),
+                        }
+                    }
+                    GoDown(bottom) => bottom,
+                }
+            }
+            Excluded(key) => {
+                match search::search_tree(root2, key) {
+                    Found(kv_handle) => {
+                        match kv_handle.left_edge().force() {
+                            Leaf(bottom) => bottom,
+                            Internal(internal) => last_leaf_edge(internal.descend()),
+                        }
+                    }
+                    GoDown(bottom) => bottom,
+                }
+            }
+            Unbounded => last_leaf_edge(root2),
         };
 
         RangeMut {
             front: front,
             back: back,
-            _marker: PhantomData
+            _marker: PhantomData,
         }
     }
 
@@ -773,21 +818,25 @@ pub fn range_mut<Min: ?Sized + Ord, Max: ?Sized + Ord>(&mut self,
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn entry(&mut self, key: K) -> Entry<K, V> {
         match search::search_tree(self.root.as_mut(), &key) {
-            Found(handle) => Occupied(OccupiedEntry {
-                handle: handle,
-                length: &mut self.length,
-                _marker: PhantomData,
-            }),
-            GoDown(handle) => Vacant(VacantEntry {
-                key: key,
-                handle: handle,
-                length: &mut self.length,
-                _marker: PhantomData,
-            })
+            Found(handle) => {
+                Occupied(OccupiedEntry {
+                    handle: handle,
+                    length: &mut self.length,
+                    _marker: PhantomData,
+                })
+            }
+            GoDown(handle) => {
+                Vacant(VacantEntry {
+                    key: key,
+                    handle: handle,
+                    length: &mut self.length,
+                    _marker: PhantomData,
+                })
+            }
         }
     }
 
-    fn from_sorted_iter<I: Iterator<Item=(K, V)>>(&mut self, iter: I) {
+    fn from_sorted_iter<I: Iterator<Item = (K, V)>>(&mut self, iter: I) {
         let mut cur_node = last_leaf_edge(self.root.as_mut()).into_node();
         // Iterate through all key-value pairs, pushing them into nodes at the right level.
         for (key, value) in iter {
@@ -810,12 +859,12 @@ fn from_sorted_iter<I: Iterator<Item=(K, V)>>(&mut self, iter: I) {
                                 // Go up again.
                                 test_node = parent.forget_type();
                             }
-                        },
+                        }
                         Err(node) => {
                             // We are at the top, create a new root node and push there.
                             open_node = node.into_root_mut().push_level();
                             break;
-                        },
+                        }
                     }
                 }
 
@@ -889,8 +938,10 @@ fn fix_right_edge(&mut self) {
     /// ```
     #[unstable(feature = "btree_split_off",
                reason = "recently added as part of collections reform 2",
-               issue = "19986")]
-    pub fn split_off<Q: ?Sized + Ord>(&mut self, key: &Q) -> Self where K: Borrow<Q> {
+               issue = "34152")]
+    pub fn split_off<Q: ?Sized + Ord>(&mut self, key: &Q) -> Self
+        where K: Borrow<Q>
+    {
         if self.is_empty() {
             return Self::new();
         }
@@ -910,7 +961,7 @@ pub fn split_off<Q: ?Sized + Ord>(&mut self, key: &Q) -> Self where K: Borrow<Q>
                 let mut split_edge = match search::search_node(left_node, key) {
                     // key is going to the right tree
                     Found(handle) => handle.left_edge(),
-                    GoDown(handle) => handle
+                    GoDown(handle) => handle,
                 };
 
                 split_edge.move_suffix(&mut right_node);
@@ -920,8 +971,12 @@ pub fn split_off<Q: ?Sized + Ord>(&mut self, key: &Q) -> Self where K: Borrow<Q>
                         left_node = edge.descend();
                         right_node = node.first_edge().descend();
                     }
-                    (Leaf(_), Leaf(_)) => { break; },
-                    _ => { unreachable!(); }
+                    (Leaf(_), Leaf(_)) => {
+                        break;
+                    }
+                    _ => {
+                        unreachable!();
+                    }
                 }
             }
         }
@@ -950,8 +1005,12 @@ fn dfs<K, V>(node: NodeRef<marker::Immut, K, V, marker::LeafOrInternal>) -> usiz
                 loop {
                     res += dfs(edge.reborrow().descend());
                     match edge.right_kv() {
-                        Ok(right_kv) => { edge = right_kv.right_edge(); },
-                        Err(_) => { break; }
+                        Ok(right_kv) => {
+                            edge = right_kv.right_edge();
+                        }
+                        Err(_) => {
+                            break;
+                        }
                     }
                 }
             }
@@ -1064,14 +1123,16 @@ fn next_back(&mut self) -> Option<(&'a K, &'a V)> {
 }
 
 impl<'a, K: 'a, V: 'a> ExactSizeIterator for Iter<'a, K, V> {
-    fn len(&self) -> usize { self.length }
+    fn len(&self) -> usize {
+        self.length
+    }
 }
 
 impl<'a, K, V> Clone for Iter<'a, K, V> {
     fn clone(&self) -> Iter<'a, K, V> {
         Iter {
             range: self.range.clone(),
-            length: self.length
+            length: self.length,
         }
     }
 }
@@ -1114,7 +1175,9 @@ fn next_back(&mut self) -> Option<(&'a K, &'a mut V)> {
 }
 
 impl<'a, K: 'a, V: 'a> ExactSizeIterator for IterMut<'a, K, V> {
-    fn len(&self) -> usize { self.length }
+    fn len(&self) -> usize {
+        self.length
+    }
 }
 
 impl<K, V> IntoIterator for BTreeMap<K, V> {
@@ -1130,14 +1193,15 @@ fn into_iter(self) -> IntoIter<K, V> {
         IntoIter {
             front: first_leaf_edge(root1),
             back: last_leaf_edge(root2),
-            length: len
+            length: len,
         }
     }
 }
 
 impl<K, V> Drop for IntoIter<K, V> {
     fn drop(&mut self) {
-        for _ in &mut *self { }
+        for _ in &mut *self {
+        }
         unsafe {
             let leaf_node = ptr::read(&self.front).into_node();
             if let Some(first_parent) = leaf_node.deallocate_and_ascend() {
@@ -1168,10 +1232,10 @@ fn next(&mut self) -> Option<(K, V)> {
                 let v = unsafe { ptr::read(kv.reborrow().into_kv().1) };
                 self.front = kv.right_edge();
                 return Some((k, v));
-            },
+            }
             Err(last_edge) => unsafe {
                 unwrap_unchecked(last_edge.into_node().deallocate_and_ascend())
-            }
+            },
         };
 
         loop {
@@ -1181,10 +1245,10 @@ fn next(&mut self) -> Option<(K, V)> {
                     let v = unsafe { ptr::read(kv.reborrow().into_kv().1) };
                     self.front = first_leaf_edge(kv.right_edge().descend());
                     return Some((k, v));
-                },
+                }
                 Err(last_edge) => unsafe {
                     cur_handle = unwrap_unchecked(last_edge.into_node().deallocate_and_ascend());
-                }
+                },
             }
         }
     }
@@ -1210,10 +1274,10 @@ fn next_back(&mut self) -> Option<(K, V)> {
                 let v = unsafe { ptr::read(kv.reborrow().into_kv().1) };
                 self.back = kv.left_edge();
                 return Some((k, v));
-            },
+            }
             Err(last_edge) => unsafe {
                 unwrap_unchecked(last_edge.into_node().deallocate_and_ascend())
-            }
+            },
         };
 
         loop {
@@ -1223,17 +1287,19 @@ fn next_back(&mut self) -> Option<(K, V)> {
                     let v = unsafe { ptr::read(kv.reborrow().into_kv().1) };
                     self.back = last_leaf_edge(kv.left_edge().descend());
                     return Some((k, v));
-                },
+                }
                 Err(last_edge) => unsafe {
                     cur_handle = unwrap_unchecked(last_edge.into_node().deallocate_and_ascend());
-                }
+                },
             }
         }
     }
 }
 
 impl<K, V> ExactSizeIterator for IntoIter<K, V> {
-    fn len(&self) -> usize { self.length }
+    fn len(&self) -> usize {
+        self.length
+    }
 }
 
 impl<'a, K, V> Iterator for Keys<'a, K, V> {
@@ -1262,9 +1328,7 @@ fn len(&self) -> usize {
 
 impl<'a, K, V> Clone for Keys<'a, K, V> {
     fn clone(&self) -> Keys<'a, K, V> {
-        Keys {
-            inner: self.inner.clone()
-        }
+        Keys { inner: self.inner.clone() }
     }
 }
 
@@ -1294,9 +1358,7 @@ fn len(&self) -> usize {
 
 impl<'a, K, V> Clone for Values<'a, K, V> {
     fn clone(&self) -> Values<'a, K, V> {
-        Values {
-            inner: self.inner.clone()
-        }
+        Values { inner: self.inner.clone() }
     }
 }
 
@@ -1348,7 +1410,7 @@ unsafe fn next_unchecked(&mut self) -> (&'a K, &'a V) {
                 let ret = kv.into_kv();
                 self.front = kv.right_edge();
                 return ret;
-            },
+            }
             Err(last_edge) => {
                 let next_level = last_edge.into_node().ascend().ok();
                 unwrap_unchecked(next_level)
@@ -1361,7 +1423,7 @@ unsafe fn next_unchecked(&mut self) -> (&'a K, &'a V) {
                     let ret = kv.into_kv();
                     self.front = first_leaf_edge(kv.right_edge().descend());
                     return ret;
-                },
+                }
                 Err(last_edge) => {
                     let next_level = last_edge.into_node().ascend().ok();
                     cur_handle = unwrap_unchecked(next_level);
@@ -1390,7 +1452,7 @@ unsafe fn next_back_unchecked(&mut self) -> (&'a K, &'a V) {
                 let ret = kv.into_kv();
                 self.back = kv.left_edge();
                 return ret;
-            },
+            }
             Err(last_edge) => {
                 let next_level = last_edge.into_node().ascend().ok();
                 unwrap_unchecked(next_level)
@@ -1403,7 +1465,7 @@ unsafe fn next_back_unchecked(&mut self) -> (&'a K, &'a V) {
                     let ret = kv.into_kv();
                     self.back = last_leaf_edge(kv.left_edge().descend());
                     return ret;
-                },
+                }
                 Err(last_edge) => {
                     let next_level = last_edge.into_node().ascend().ok();
                     cur_handle = unwrap_unchecked(next_level);
@@ -1417,7 +1479,7 @@ impl<'a, K, V> Clone for Range<'a, K, V> {
     fn clone(&self) -> Range<'a, K, V> {
         Range {
             front: self.front,
-            back: self.back
+            back: self.back,
         }
     }
 }
@@ -1429,7 +1491,7 @@ fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
         if self.front == self.back {
             None
         } else {
-            unsafe { Some (self.next_unchecked()) }
+            unsafe { Some(self.next_unchecked()) }
         }
     }
 }
@@ -1443,7 +1505,7 @@ unsafe fn next_unchecked(&mut self) -> (&'a K, &'a mut V) {
                 let (k, v) = ptr::read(&kv).into_kv_mut();
                 self.front = kv.right_edge();
                 return (k, v);
-            },
+            }
             Err(last_edge) => {
                 let next_level = last_edge.into_node().ascend().ok();
                 unwrap_unchecked(next_level)
@@ -1456,7 +1518,7 @@ unsafe fn next_unchecked(&mut self) -> (&'a K, &'a mut V) {
                     let (k, v) = ptr::read(&kv).into_kv_mut();
                     self.front = first_leaf_edge(kv.right_edge().descend());
                     return (k, v);
-                },
+                }
                 Err(last_edge) => {
                     let next_level = last_edge.into_node().ascend().ok();
                     cur_handle = unwrap_unchecked(next_level);
@@ -1485,7 +1547,7 @@ unsafe fn next_back_unchecked(&mut self) -> (&'a K, &'a mut V) {
                 let (k, v) = ptr::read(&kv).into_kv_mut();
                 self.back = kv.left_edge();
                 return (k, v);
-            },
+            }
             Err(last_edge) => {
                 let next_level = last_edge.into_node().ascend().ok();
                 unwrap_unchecked(next_level)
@@ -1498,7 +1560,7 @@ unsafe fn next_back_unchecked(&mut self) -> (&'a K, &'a mut V) {
                     let (k, v) = ptr::read(&kv).into_kv_mut();
                     self.back = last_leaf_edge(kv.left_edge().descend());
                     return (k, v);
-                },
+                }
                 Err(last_edge) => {
                     let next_level = last_edge.into_node().ascend().ok();
                     cur_handle = unwrap_unchecked(next_level);
@@ -1509,7 +1571,7 @@ unsafe fn next_back_unchecked(&mut self) -> (&'a K, &'a mut V) {
 }
 
 impl<K: Ord, V> FromIterator<(K, V)> for BTreeMap<K, V> {
-    fn from_iter<T: IntoIterator<Item=(K, V)>>(iter: T) -> BTreeMap<K, V> {
+    fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> BTreeMap<K, V> {
         let mut map = BTreeMap::new();
         map.extend(iter);
         map
@@ -1518,7 +1580,7 @@ fn from_iter<T: IntoIterator<Item=(K, V)>>(iter: T) -> BTreeMap<K, V> {
 
 impl<K: Ord, V> Extend<(K, V)> for BTreeMap<K, V> {
     #[inline]
-    fn extend<T: IntoIterator<Item=(K, V)>>(&mut self, iter: T) {
+    fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
         for (k, v) in iter {
             self.insert(k, v);
         }
@@ -1526,7 +1588,7 @@ fn extend<T: IntoIterator<Item=(K, V)>>(&mut self, iter: T) {
 }
 
 impl<'a, K: Ord + Copy, V: Copy> Extend<(&'a K, &'a V)> for BTreeMap<K, V> {
-    fn extend<I: IntoIterator<Item=(&'a K, &'a V)>>(&mut self, iter: I) {
+    fn extend<I: IntoIterator<Item = (&'a K, &'a V)>>(&mut self, iter: I) {
         self.extend(iter.into_iter().map(|(&key, &value)| (key, value)));
     }
 }
@@ -1547,8 +1609,7 @@ fn default() -> BTreeMap<K, V> {
 
 impl<K: PartialEq, V: PartialEq> PartialEq for BTreeMap<K, V> {
     fn eq(&self, other: &BTreeMap<K, V>) -> bool {
-        self.len() == other.len() &&
-            self.iter().zip(other).all(|(a, b)| a == b)
+        self.len() == other.len() && self.iter().zip(other).all(|(a, b)| a == b)
     }
 }
 
@@ -1575,7 +1636,8 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 }
 
 impl<'a, K: Ord, Q: ?Sized, V> Index<&'a Q> for BTreeMap<K, V>
-    where K: Borrow<Q>, Q: Ord
+    where K: Borrow<Q>,
+          Q: Ord
 {
     type Output = V;
 
@@ -1585,11 +1647,9 @@ fn index(&self, key: &Q) -> &V {
     }
 }
 
-fn first_leaf_edge<BorrowType, K, V>(
-        mut node: NodeRef<BorrowType,
-                          K, V,
-                          marker::LeafOrInternal>
-        ) -> Handle<NodeRef<BorrowType, K, V, marker::Leaf>, marker::Edge> {
+fn first_leaf_edge<BorrowType, K, V>
+    (mut node: NodeRef<BorrowType, K, V, marker::LeafOrInternal>)
+     -> Handle<NodeRef<BorrowType, K, V, marker::Leaf>, marker::Edge> {
     loop {
         match node.force() {
             Leaf(leaf) => return leaf.first_edge(),
@@ -1600,11 +1660,9 @@ fn first_leaf_edge<BorrowType, K, V>(
     }
 }
 
-fn last_leaf_edge<BorrowType, K, V>(
-        mut node: NodeRef<BorrowType,
-                          K, V,
-                          marker::LeafOrInternal>
-        ) -> Handle<NodeRef<BorrowType, K, V, marker::Leaf>, marker::Edge> {
+fn last_leaf_edge<BorrowType, K, V>
+    (mut node: NodeRef<BorrowType, K, V, marker::LeafOrInternal>)
+     -> Handle<NodeRef<BorrowType, K, V, marker::Leaf>, marker::Edge> {
     loop {
         match node.force() {
             Leaf(leaf) => return leaf.last_edge(),
@@ -1653,9 +1711,9 @@ pub fn iter(&self) -> Iter<K, V> {
         Iter {
             range: Range {
                 front: first_leaf_edge(self.root.as_ref()),
-                back: last_leaf_edge(self.root.as_ref())
+                back: last_leaf_edge(self.root.as_ref()),
             },
-            length: self.length
+            length: self.length,
         }
     }
 
@@ -1690,7 +1748,7 @@ pub fn iter_mut(&mut self) -> IterMut<K, V> {
                 back: last_leaf_edge(root2),
                 _marker: PhantomData,
             },
-            length: self.length
+            length: self.length,
         }
     }
 
@@ -1840,6 +1898,12 @@ pub fn key(&self) -> &K {
         &self.key
     }
 
+    /// Take ownership of the key.
+    #[unstable(feature = "map_entry_recover_keys", issue = "34285")]
+    pub fn into_key(self) -> K {
+        self.key
+    }
+
     /// Sets the value of the entry with the VacantEntry's key,
     /// and returns a mutable reference to it.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -1865,15 +1929,17 @@ pub fn insert(self, value: V) -> &'a mut V {
 
         loop {
             match cur_parent {
-                Ok(parent) => match parent.insert(ins_k, ins_v, ins_edge) {
-                    Fit(_) => return unsafe { &mut *out_ptr },
-                    Split(left, k, v, right) => {
-                        ins_k = k;
-                        ins_v = v;
-                        ins_edge = right;
-                        cur_parent = left.ascend().map_err(|n| n.into_root_mut());
+                Ok(parent) => {
+                    match parent.insert(ins_k, ins_v, ins_edge) {
+                        Fit(_) => return unsafe { &mut *out_ptr },
+                        Split(left, k, v, right) => {
+                            ins_k = k;
+                            ins_v = v;
+                            ins_edge = right;
+                            cur_parent = left.ascend().map_err(|n| n.into_root_mut());
+                        }
                     }
-                },
+                }
                 Err(root) => {
                     root.push_level().push(ins_k, ins_v, ins_edge);
                     return unsafe { &mut *out_ptr };
@@ -1890,6 +1956,12 @@ pub fn key(&self) -> &K {
         self.handle.reborrow().into_kv().0
     }
 
+    /// Take ownership of the key and value from the map.
+    #[unstable(feature = "map_entry_recover_keys", issue = "34285")]
+    pub fn remove_pair(self) -> (K, V) {
+        self.remove_kv()
+    }
+
     /// Gets a reference to the value in the entry.
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get(&self) -> &V {
@@ -1928,7 +2000,7 @@ fn remove_kv(self) -> (K, V) {
             Leaf(leaf) => {
                 let (hole, old_key, old_val) = leaf.remove();
                 (hole.into_node(), old_key, old_val)
-            },
+            }
             Internal(mut internal) => {
                 let key_loc = internal.kv_mut().0 as *mut K;
                 let val_loc = internal.kv_mut().1 as *mut V;
@@ -1938,12 +2010,8 @@ fn remove_kv(self) -> (K, V) {
 
                 let (hole, key, val) = to_remove.remove();
 
-                let old_key = unsafe {
-                    mem::replace(&mut *key_loc, key)
-                };
-                let old_val = unsafe {
-                    mem::replace(&mut *val_loc, val)
-                };
+                let old_key = unsafe { mem::replace(&mut *key_loc, key) };
+                let old_val = unsafe { mem::replace(&mut *val_loc, val) };
 
                 (hole.into_node(), old_key, old_val)
             }
@@ -1955,14 +2023,16 @@ fn remove_kv(self) -> (K, V) {
             match handle_underfull_node(cur_node) {
                 AtRoot => break,
                 EmptyParent(_) => unreachable!(),
-                Merged(parent) => if parent.len() == 0 {
-                    // We must be at the root
-                    parent.into_root_mut().pop_level();
-                    break;
-                } else {
-                    cur_node = parent.forget_type();
-                },
-                Stole(_) => break
+                Merged(parent) => {
+                    if parent.len() == 0 {
+                        // We must be at the root
+                        parent.into_root_mut().pop_level();
+                        break;
+                    } else {
+                        cur_node = parent.forget_type();
+                    }
+                }
+                Stole(_) => break,
             }
         }
 
@@ -1974,13 +2044,11 @@ enum UnderflowResult<'a, K, V> {
     AtRoot,
     EmptyParent(NodeRef<marker::Mut<'a>, K, V, marker::Internal>),
     Merged(NodeRef<marker::Mut<'a>, K, V, marker::Internal>),
-    Stole(NodeRef<marker::Mut<'a>, K, V, marker::Internal>)
+    Stole(NodeRef<marker::Mut<'a>, K, V, marker::Internal>),
 }
 
-fn handle_underfull_node<'a, K, V>(node: NodeRef<marker::Mut<'a>,
-                                                 K, V,
-                                                 marker::LeafOrInternal>)
-                                                 -> UnderflowResult<'a, K, V> {
+fn handle_underfull_node<'a, K, V>(node: NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>)
+                                   -> UnderflowResult<'a, K, V> {
     let parent = if let Ok(parent) = node.ascend() {
         parent
     } else {
@@ -1989,10 +2057,12 @@ fn handle_underfull_node<'a, K, V>(node: NodeRef<marker::Mut<'a>,
 
     let (is_left, mut handle) = match parent.left_kv() {
         Ok(left) => (true, left),
-        Err(parent) => match parent.right_kv() {
-            Ok(right) => (false, right),
-            Err(parent) => {
-                return EmptyParent(parent.into_node());
+        Err(parent) => {
+            match parent.right_kv() {
+                Ok(right) => (false, right),
+                Err(parent) => {
+                    return EmptyParent(parent.into_node());
+                }
             }
         }
     };
@@ -2009,7 +2079,7 @@ fn handle_underfull_node<'a, K, V>(node: NodeRef<marker::Mut<'a>,
     }
 }
 
-impl<K: Ord, V, I: Iterator<Item=(K, V)>> Iterator for MergeIter<K, V, I> {
+impl<K: Ord, V, I: Iterator<Item = (K, V)>> Iterator for MergeIter<K, V, I> {
     type Item = (K, V);
 
     fn next(&mut self) -> Option<(K, V)> {
@@ -2023,16 +2093,12 @@ fn next(&mut self) -> Option<(K, V)> {
         // Check which elements comes first and only advance the corresponding iterator.
         // If two keys are equal, take the value from `right`.
         match res {
-            Ordering::Less => {
-                self.left.next()
-            },
-            Ordering::Greater => {
-                self.right.next()
-            },
+            Ordering::Less => self.left.next(),
+            Ordering::Greater => self.right.next(),
             Ordering::Equal => {
                 self.left.next();
                 self.right.next()
-            },
+            }
         }
     }
 }
index 765595be317c117b705aaa8c90933d383cd1019d..c47eb0b3fad457afed6967f39df3afc43ebbcd3c 100644 (file)
@@ -576,7 +576,7 @@ pub fn take<Q: ?Sized>(&mut self, value: &Q) -> Option<T>
     /// assert!(a.contains(&5));
     /// ```
     #[unstable(feature = "btree_append", reason = "recently added as part of collections reform 2",
-               issue = "19986")]
+               issue = "34152")]
     pub fn append(&mut self, other: &mut Self) {
         self.map.append(&mut other.map);
     }
@@ -613,7 +613,7 @@ pub fn append(&mut self, other: &mut Self) {
     /// ```
     #[unstable(feature = "btree_split_off",
                reason = "recently added as part of collections reform 2",
-               issue = "19986")]
+               issue = "34152")]
     pub fn split_off<Q: ?Sized + Ord>(&mut self, key: &Q) -> Self where T: Borrow<Q> {
         BTreeSet { map: self.map.split_off(key) }
     }
index 124b85bfca872bbfb15f26ca9897dee61ba72806..07428f3f8b2d89a3cdbb61384b8de63dcb2bd072 100644 (file)
@@ -123,8 +123,6 @@ macro_rules! test_concat {
 fn test_concat_for_different_types() {
     test_concat!("ab", vec![s("a"), s("b")]);
     test_concat!("ab", vec!["a", "b"]);
-    test_concat!("ab", vec!["a", "b"]);
-    test_concat!("ab", vec![s("a"), s("b")]);
 }
 
 #[test]
@@ -194,24 +192,24 @@ fn half_a_million_letter_a() -> String {
 
 #[test]
 fn test_starts_with() {
-    assert!(("".starts_with("")));
-    assert!(("abc".starts_with("")));
-    assert!(("abc".starts_with("a")));
-    assert!((!"a".starts_with("abc")));
-    assert!((!"".starts_with("abc")));
-    assert!((!"ödd".starts_with("-")));
-    assert!(("ödd".starts_with("öd")));
+    assert!("".starts_with(""));
+    assert!("abc".starts_with(""));
+    assert!("abc".starts_with("a"));
+    assert!(!"a".starts_with("abc"));
+    assert!(!"".starts_with("abc"));
+    assert!(!"ödd".starts_with("-"));
+    assert!("ödd".starts_with("öd"));
 }
 
 #[test]
 fn test_ends_with() {
-    assert!(("".ends_with("")));
-    assert!(("abc".ends_with("")));
-    assert!(("abc".ends_with("c")));
-    assert!((!"a".ends_with("abc")));
-    assert!((!"".ends_with("abc")));
-    assert!((!"ddö".ends_with("-")));
-    assert!(("ddö".ends_with("dö")));
+    assert!("".ends_with(""));
+    assert!("abc".ends_with(""));
+    assert!("abc".ends_with("c"));
+    assert!(!"a".ends_with("abc"));
+    assert!(!"".ends_with("abc"));
+    assert!(!"ddö".ends_with("-"));
+    assert!("ddö".ends_with("dö"));
 }
 
 #[test]
index dfd2ba9154d53eceb71ec17fbb6ddf46c84a55f6..49304b1f3bfa17d23e632189bfbf942419658292 100644 (file)
@@ -85,7 +85,7 @@
 
 /// A type to emulate dynamic typing.
 ///
-/// Every type with no non-`'static` references implements `Any`.
+/// Most types implement `Any`. However, any type which contains a non-`'static` reference does not.
 /// See the [module-level documentation][mod] for more details.
 ///
 /// [mod]: index.html
index 50c4dc697c2062f7de9c2f9e3661cc228749c27d..5e1210b2ff9bd3a6cb4fa9887127e36756731354 100644 (file)
@@ -1475,7 +1475,7 @@ pub trait IndexMut<Idx: ?Sized>: Index<Idx> {
 ///     assert_eq!(arr[1..3], [  1,2  ]);
 /// }
 /// ```
-#[derive(Copy, Clone, PartialEq, Eq)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct RangeFull;
 
@@ -1506,7 +1506,7 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
 ///     assert_eq!(arr[1..3], [  1,2  ]);  // Range
 /// }
 /// ```
-#[derive(Clone, PartialEq, Eq)]
+#[derive(Clone, PartialEq, Eq, Hash)]  // not Copy -- see #27186
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Range<Idx> {
     /// The lower bound of the range (inclusive).
@@ -1570,7 +1570,7 @@ pub fn contains(&self, item: Idx) -> bool {
 ///     assert_eq!(arr[1..3], [  1,2  ]);
 /// }
 /// ```
-#[derive(Clone, PartialEq, Eq)]
+#[derive(Clone, PartialEq, Eq, Hash)]  // not Copy -- see #27186
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct RangeFrom<Idx> {
     /// The lower bound of the range (inclusive).
@@ -1619,7 +1619,7 @@ pub fn contains(&self, item: Idx) -> bool {
 ///     assert_eq!(arr[1..3], [  1,2  ]);
 /// }
 /// ```
-#[derive(Copy, Clone, PartialEq, Eq)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct RangeTo<Idx> {
     /// The upper bound of the range (exclusive).
@@ -1669,7 +1669,7 @@ pub fn contains(&self, item: Idx) -> bool {
 ///     assert_eq!(arr[1...2], [  1,2  ]);  // RangeInclusive
 /// }
 /// ```
-#[derive(Copy, Clone, PartialEq, Eq)]
+#[derive(Clone, PartialEq, Eq, Hash)]  // not Copy -- see #27186
 #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
 pub enum RangeInclusive<Idx> {
     /// Empty range (iteration has finished)
@@ -1774,7 +1774,7 @@ pub fn contains(&self, item: Idx) -> bool {
 ///     assert_eq!(arr[1...2], [  1,2  ]);
 /// }
 /// ```
-#[derive(Copy, Clone, PartialEq, Eq)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash)]
 #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
 pub struct RangeToInclusive<Idx> {
     /// The upper bound of the range (inclusive)
index 658b1312c496d8b580b6efef49800e49efe1185d..47d9deb62ff6556501c8588981dc621b4282ca1f 100644 (file)
@@ -289,7 +289,7 @@ pub fn compare_and_swap(&self, current: bool, new: bool, order: Ordering) -> boo
     /// Stores a value into the `bool` if the current value is the same as the `current` value.
     ///
     /// The return value is a result indicating whether the new value was written and containing
-    /// the previous value. On success this value is guaranteed to be equal to `new`.
+    /// the previous value. On success this value is guaranteed to be equal to `current`.
     ///
     /// `compare_exchange` takes two `Ordering` arguments to describe the memory ordering of this
     /// operation. The first describes the required ordering if the operation succeeds while the
@@ -633,7 +633,7 @@ pub fn compare_and_swap(&self, current: *mut T, new: *mut T, order: Ordering) ->
     /// Stores a value into the pointer if the current value is the same as the `current` value.
     ///
     /// The return value is a result indicating whether the new value was written and containing
-    /// the previous value. On success this value is guaranteed to be equal to `new`.
+    /// the previous value. On success this value is guaranteed to be equal to `current`.
     ///
     /// `compare_exchange` takes two `Ordering` arguments to describe the memory ordering of this
     /// operation. The first describes the required ordering if the operation succeeds while the
@@ -886,7 +886,7 @@ pub fn compare_and_swap(&self,
             ///
             /// The return value is a result indicating whether the new value was written and
             /// containing the previous value. On success this value is guaranteed to be equal to
-            /// `new`.
+            /// `current`.
             ///
             /// `compare_exchange` takes two `Ordering` arguments to describe the memory ordering of
             /// this operation. The first describes the required ordering if the operation succeeds
index b578b064d67caece89816bdecee93c709041b2a7..63913f2878c20f07b0dc7d6e4fe720260e0cc747 100644 (file)
@@ -31,7 +31,7 @@
 
 extern crate libc;
 
-use libc::{c_void, size_t, c_int};
+use libc::{c_int, c_void, size_t};
 use std::fmt;
 use std::ops::Deref;
 use std::ptr::Unique;
@@ -76,9 +76,9 @@ fn drop(&mut self) {
 
 #[link(name = "miniz", kind = "static")]
 #[cfg(not(cargobuild))]
-extern {}
+extern "C" {}
 
-extern {
+extern "C" {
     /// Raw miniz compression function.
     fn tdefl_compress_mem_to_heap(psrc_buf: *const c_void,
                                   src_buf_len: size_t,
@@ -154,8 +154,8 @@ pub fn inflate_bytes_zlib(bytes: &[u8]) -> Result<Bytes, Error> {
 #[cfg(test)]
 mod tests {
     #![allow(deprecated)]
-    use super::{inflate_bytes, deflate_bytes};
-    use std::__rand::{thread_rng, Rng};
+    use super::{deflate_bytes, inflate_bytes};
+    use std::__rand::{Rng, thread_rng};
 
     #[test]
     fn test_flate_round_trip() {
index 1ba722b6baee76e79594b9d21d47b412a83f254a..eb51043fcd025268a275127e36085711ba580699 100644 (file)
@@ -1112,6 +1112,7 @@ fn main() {
 ```
 
 Or in a generic context, an erroneous code example would look like:
+
 ```compile_fail
 fn some_func<T>(foo: T) {
     println!("{:?}", foo); // error: the trait `core::fmt::Debug` is not
@@ -1130,6 +1131,7 @@ fn main() {
 still rejects the function: It must work with all possible input types. In
 order to make this example compile, we need to restrict the generic type we're
 accepting:
+
 ```
 use std::fmt;
 
@@ -1146,11 +1148,10 @@ fn main() {
     // struct WithoutDebug;
     // some_func(WithoutDebug);
 }
+```
 
 Rust only looks at the signature of the called function, as such it must
 already specify all requirements that will be used for every type parameter.
-```
-
 "##,
 
 E0281: r##"
@@ -1381,6 +1382,7 @@ struct Foo<'a, T: 'a> {
 struct Foo<T> {
     foo: &'static T
 }
+```
 
 This will compile, because it has the constraint on the type parameter:
 
@@ -1442,6 +1444,51 @@ fn foo<'a>(arg: &Box<SomeTrait+'a>) { ... }
 ```
 "##,
 
+E0453: r##"
+A lint check attribute was overruled by a `forbid` directive set as an
+attribute on an enclosing scope, or on the command line with the `-F` option.
+
+Example of erroneous code:
+
+```compile_fail
+#![forbid(non_snake_case)]
+
+#[allow(non_snake_case)]
+fn main() {
+    let MyNumber = 2; // error: allow(non_snake_case) overruled by outer
+                      //        forbid(non_snake_case)
+}
+```
+
+The `forbid` lint setting, like `deny`, turns the corresponding compiler
+warning into a hard error. Unlike `deny`, `forbid` prevents itself from being
+overridden by inner attributes.
+
+If you're sure you want to override the lint check, you can change `forbid` to
+`deny` (or use `-D` instead of `-F` if the `forbid` setting was given as a
+command-line option) to allow the inner lint check attribute:
+
+```
+#![deny(non_snake_case)]
+
+#[allow(non_snake_case)]
+fn main() {
+    let MyNumber = 2; // ok!
+}
+```
+
+Otherwise, edit the code to pass the lint check, and remove the overruled
+attribute:
+
+```
+#![forbid(non_snake_case)]
+
+fn main() {
+    let my_number = 2;
+}
+```
+"##,
+
 E0496: r##"
 A lifetime name is shadowing another lifetime name. Erroneous code example:
 
@@ -1626,7 +1673,6 @@ fn cookie() -> ! { // error: definition of an unknown language item: `cookie`
     E0314, // closure outlives stack frame
     E0315, // cannot invoke closure outside of its lifetime
     E0316, // nested quantification of lifetimes
-    E0453, // overruled by outer forbid
     E0473, // dereference of reference outside its lifetime
     E0474, // captured variable `..` does not outlive the enclosing closure
     E0475, // index of slice outside its lifetime
index 69cf5baa26fecc5d7013fb94f01f67e2e2363e9a..393045bf93efbd81e64c3836057e6d3eb1ed69a2 100644 (file)
 use std::iter;
 use syntax::ast::*;
 use syntax::attr::{ThinAttributes, ThinAttributesExt};
-use syntax::ext::mtwt;
 use syntax::ptr::P;
 use syntax::codemap::{respan, Spanned, Span};
-use syntax::parse::token::{self, keywords};
+use syntax::parse::token;
 use syntax::std_inject;
 use syntax::visit::{self, Visitor};
 
@@ -184,16 +183,8 @@ fn with_parent_def<T, F>(&mut self, parent_id: NodeId, f: F) -> T
         result
     }
 
-    fn lower_ident(&mut self, ident: Ident) -> Name {
-        if ident.name != keywords::Invalid.name() {
-            mtwt::resolve(ident)
-        } else {
-            ident.name
-        }
-    }
-
     fn lower_opt_sp_ident(&mut self, o_id: Option<Spanned<Ident>>) -> Option<Spanned<Name>> {
-        o_id.map(|sp_ident| respan(sp_ident.span, self.lower_ident(sp_ident.node)))
+        o_id.map(|sp_ident| respan(sp_ident.span, sp_ident.node.name))
     }
 
     fn lower_attrs(&mut self, attrs: &Vec<Attribute>) -> hir::HirVec<Attribute> {
@@ -338,18 +329,14 @@ fn lower_variant(&mut self, v: &Variant) -> hir::Variant {
         }
     }
 
-    fn lower_path_full(&mut self, p: &Path, rename: bool) -> hir::Path {
+    fn lower_path(&mut self, p: &Path) -> hir::Path {
         hir::Path {
             global: p.global,
             segments: p.segments
                        .iter()
                        .map(|&PathSegment { identifier, ref parameters }| {
                            hir::PathSegment {
-                               name: if rename {
-                                   self.lower_ident(identifier)
-                               } else {
-                                   identifier.name
-                               },
+                               name: identifier.name,
                                parameters: self.lower_path_parameters(parameters),
                            }
                        })
@@ -358,10 +345,6 @@ fn lower_path_full(&mut self, p: &Path, rename: bool) -> hir::Path {
         }
     }
 
-    fn lower_path(&mut self, p: &Path) -> hir::Path {
-        self.lower_path_full(p, false)
-    }
-
     fn lower_path_parameters(&mut self, path_parameters: &PathParameters) -> hir::PathParameters {
         match *path_parameters {
             PathParameters::AngleBracketed(ref data) =>
@@ -870,8 +853,7 @@ fn lower_pat(&mut self, p: &Pat) -> P<hir::Pat> {
                             // `None` can occur in body-less function signatures
                             None | Some(Def::Local(..)) => {
                                 hir::PatKind::Binding(this.lower_binding_mode(binding_mode),
-                                                      respan(pth1.span,
-                                                             this.lower_ident(pth1.node)),
+                                                      respan(pth1.span, pth1.node.name),
                                                       sub.as_ref().map(|x| this.lower_pat(x)))
                             }
                             _ => hir::PatKind::Path(hir::Path::from_name(pth1.span, pth1.node.name))
@@ -1238,12 +1220,7 @@ fn make_struct(this: &mut LoweringContext,
                             position: position,
                         }
                     });
-                    // Only local variables are renamed
-                    let rename = match self.resolver.get_resolution(e.id).map(|d| d.base_def) {
-                        Some(Def::Local(..)) | Some(Def::Upvar(..)) => true,
-                        _ => false,
-                    };
-                    hir::ExprPath(hir_qself, self.lower_path_full(path, rename))
+                    hir::ExprPath(hir_qself, self.lower_path(path))
                 }
                 ExprKind::Break(opt_ident) => hir::ExprBreak(self.lower_opt_sp_ident(opt_ident)),
                 ExprKind::Again(opt_ident) => hir::ExprAgain(self.lower_opt_sp_ident(opt_ident)),
index c36c88c7990d30abfb1746b70a59a7c3f120ef53..8faa1cc1174e8568cb8b100232648b11ebb72541 100644 (file)
@@ -1138,7 +1138,7 @@ pub enum SelfKind {
 impl Arg {
     pub fn to_self(&self) -> Option<ExplicitSelf> {
         if let PatKind::Binding(BindByValue(mutbl), name, _) = self.pat.node {
-            if name.node.unhygienize() == keywords::SelfValue.name() {
+            if name.node == keywords::SelfValue.name() {
                 return match self.ty.node {
                     TyInfer => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
                     TyRptr(lt, MutTy{ref ty, mutbl}) if ty.node == TyInfer => {
@@ -1154,7 +1154,7 @@ pub fn to_self(&self) -> Option<ExplicitSelf> {
 
     pub fn is_self(&self) -> bool {
         if let PatKind::Binding(_, name, _) = self.pat.node {
-            name.node.unhygienize() == keywords::SelfValue.name()
+            name.node == keywords::SelfValue.name()
         } else {
             false
         }
index ceaf348117e1711b5c8d5bef3c7ca049daa60969..b6b7aa6ce7de73b069aac995375723f034f9ffe1 100644 (file)
@@ -1728,12 +1728,9 @@ pub fn print_pat(&mut self, pat: &hir::Pat) -> io::Result<()> {
                     }
                 }
                 self.print_name(path1.node)?;
-                match *sub {
-                    Some(ref p) => {
-                        word(&mut self.s, "@")?;
-                        self.print_pat(&p)?;
-                    }
-                    None => (),
+                if let Some(ref p) = *sub {
+                    word(&mut self.s, "@")?;
+                    self.print_pat(&p)?;
                 }
             }
             PatKind::TupleStruct(ref path, ref elts, ddpos) => {
@@ -2246,25 +2243,21 @@ pub fn maybe_print_trailing_comment(&mut self,
             Some(cm) => cm,
             _ => return Ok(()),
         };
-        match self.next_comment() {
-            Some(ref cmnt) => {
-                if (*cmnt).style != comments::Trailing {
-                    return Ok(());
-                }
-                let span_line = cm.lookup_char_pos(span.hi);
-                let comment_line = cm.lookup_char_pos((*cmnt).pos);
-                let mut next = (*cmnt).pos + BytePos(1);
-                match next_pos {
-                    None => (),
-                    Some(p) => next = p,
-                }
-                if span.hi < (*cmnt).pos && (*cmnt).pos < next &&
-                   span_line.line == comment_line.line {
-                    self.print_comment(cmnt)?;
-                    self.cur_cmnt_and_lit.cur_cmnt += 1;
-                }
+        if let Some(ref cmnt) = self.next_comment() {
+            if (*cmnt).style != comments::Trailing {
+                return Ok(());
+            }
+            let span_line = cm.lookup_char_pos(span.hi);
+            let comment_line = cm.lookup_char_pos((*cmnt).pos);
+            let mut next = (*cmnt).pos + BytePos(1);
+            if let Some(p) = next_pos {
+                next = p;
+            }
+            if span.hi < (*cmnt).pos && (*cmnt).pos < next &&
+               span_line.line == comment_line.line {
+                self.print_comment(cmnt)?;
+                self.cur_cmnt_and_lit.cur_cmnt += 1;
             }
-            _ => (),
         }
         Ok(())
     }
index 27896b09981210d91ba2cbc32beb802a60b6bd18..86bc4355b2d3c37ad57ab710a4374332907c7b7e 100644 (file)
@@ -1856,11 +1856,10 @@ fn lifetimes_in_scope<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
         },
         None => None
     };
-    if method_id_opt.is_some() {
-        let method_id = method_id_opt.unwrap();
+    if let Some(method_id) = method_id_opt {
         let parent = tcx.map.get_parent(method_id);
-        match tcx.map.find(parent) {
-            Some(node) => match node {
+        if let Some(node) = tcx.map.find(parent) {
+            match node {
                 ast_map::NodeItem(item) => match item.node {
                     hir::ItemImpl(_, _, ref gen, _, _, _) => {
                         taken.extend_from_slice(&gen.lifetimes);
@@ -1868,8 +1867,7 @@ fn lifetimes_in_scope<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
                     _ => ()
                 },
                 _ => ()
-            },
-            None => ()
+            }
         }
     }
     return taken;
@@ -1938,4 +1936,3 @@ fn name_to_dummy_lifetime(name: ast::Name) -> hir::Lifetime {
                     span: codemap::DUMMY_SP,
                     name: name }
 }
-
index e65074a4f07b3b64e8480b4a249af5cf1f4e6873..17da8ddbbc30c85f355c688556a04d510d649d0f 100644 (file)
@@ -160,12 +160,9 @@ fn mark_live_symbols(&mut self) {
             }
             scanned.insert(id);
 
-            match self.tcx.map.find(id) {
-                Some(ref node) => {
-                    self.live_symbols.insert(id);
-                    self.visit_node(node);
-                }
-                None => (),
+            if let Some(ref node) = self.tcx.map.find(id) {
+                self.live_symbols.insert(id);
+                self.visit_node(node);
             }
         }
     }
@@ -372,9 +369,8 @@ fn create_and_seed_worklist<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     }
 
     // Seed entry point
-    match *tcx.sess.entry_fn.borrow() {
-        Some((id, _)) => worklist.push(id),
-        None => ()
+    if let Some((id, _)) = *tcx.sess.entry_fn.borrow() {
+        worklist.push(id);
     }
 
     // Seed implemented trait items
@@ -464,16 +460,14 @@ fn symbol_is_live(&mut self,
         // method of a private type is used, but the type itself is never
         // called directly.
         let impl_items = self.tcx.impl_items.borrow();
-        match self.tcx.inherent_impls.borrow().get(&self.tcx.map.local_def_id(id)) {
-            None => (),
-            Some(impl_list) => {
-                for impl_did in impl_list.iter() {
-                    for item_did in impl_items.get(impl_did).unwrap().iter() {
-                        if let Some(item_node_id) =
-                                self.tcx.map.as_local_node_id(item_did.def_id()) {
-                            if self.live_symbols.contains(&item_node_id) {
-                                return true;
-                            }
+        if let Some(impl_list) =
+                self.tcx.inherent_impls.borrow().get(&self.tcx.map.local_def_id(id)) {
+            for impl_did in impl_list.iter() {
+                for item_did in impl_items.get(impl_did).unwrap().iter() {
+                    if let Some(item_node_id) =
+                            self.tcx.map.as_local_node_id(item_did.def_id()) {
+                        if self.live_symbols.contains(&item_node_id) {
+                            return true;
                         }
                     }
                 }
index dcc84fb04399fa5ed812a5e9ca1735b468ed2185..78d9f5c9b7c2975d65326ebfb325a9c210e09ffd 100644 (file)
@@ -456,8 +456,7 @@ fn visit_item(&mut self, _: &hir::Item) {
     fn expression_label(ex: &hir::Expr) -> Option<(ast::Name, Span)> {
         match ex.node {
             hir::ExprWhile(_, _, Some(label)) |
-            hir::ExprLoop(_, Some(label)) => Some((label.node.unhygienize(),
-                                                   label.span)),
+            hir::ExprLoop(_, Some(label)) => Some((label.node, label.span)),
             _ => None,
         }
     }
index e2025eaa8ee06d6537c264631f4b59c213066a2e..afc2e04d446a1140b4724f3192cfb6f0e21dbde5 100644 (file)
@@ -291,8 +291,8 @@ fn not(self) -> $BitFlags {
 #[cfg(test)]
 #[allow(non_upper_case_globals)]
 mod tests {
-    use std::hash::{Hasher, Hash, SipHasher};
-    use std::option::Option::{Some, None};
+    use std::hash::{Hash, Hasher, SipHasher};
+    use std::option::Option::{None, Some};
 
     bitflags! {
         #[doc = "> The first principle is that you must not fool yourself — and"]
index 8682661d35a849053f5982581dd7b6f933c82bc8..64f35aed23f5c05ef4aef758393ee3d0708b6162 100644 (file)
@@ -122,15 +122,12 @@ fn gather_move<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
 
     let potentially_illegal_move =
                 check_and_get_illegal_move_origin(bccx, &move_info.cmt);
-    match potentially_illegal_move {
-        Some(illegal_move_origin) => {
-            debug!("illegal_move_origin={:?}", illegal_move_origin);
-            let error = MoveError::with_move_info(illegal_move_origin,
-                                                  move_info.span_path_opt);
-            move_error_collector.add_error(error);
-            return
-        }
-        None => ()
+    if let Some(illegal_move_origin) = potentially_illegal_move {
+        debug!("illegal_move_origin={:?}", illegal_move_origin);
+        let error = MoveError::with_move_info(illegal_move_origin,
+                                              move_info.span_path_opt);
+        move_error_collector.add_error(error);
+        return;
     }
 
     match opt_loan_path(&move_info.cmt) {
index 74ebad107eb8a9580bace011ecc639af35849f29..065cbbf76b3845f17f3045b27d2b7e9e1d7605bc 100644 (file)
@@ -548,17 +548,26 @@ fn drop_halfladder<'a>(&mut self,
     ///     ELAB(drop location.2 [target=`c.unwind])
     fn drop_ladder<'a>(&mut self,
                        c: &DropCtxt<'a, 'tcx>,
-                       fields: &[(Lvalue<'tcx>, Option<MovePathIndex>)])
+                       fields: Vec<(Lvalue<'tcx>, Option<MovePathIndex>)>)
                        -> BasicBlock
     {
         debug!("drop_ladder({:?}, {:?})", c, fields);
+
+        let mut fields = fields;
+        fields.retain(|&(ref lvalue, _)| {
+            let ty = self.mir.lvalue_ty(self.tcx, lvalue).to_ty(self.tcx);
+            self.tcx.type_needs_drop_given_env(ty, self.param_env())
+        });
+
+        debug!("drop_ladder - fields needing drop: {:?}", fields);
+
         let unwind_ladder = if c.is_cleanup {
             None
         } else {
             Some(self.drop_halfladder(c, None, c.unwind.unwrap(), &fields, true))
         };
 
-        self.drop_halfladder(c, unwind_ladder, c.succ, fields, c.is_cleanup)
+        self.drop_halfladder(c, unwind_ladder, c.succ, &fields, c.is_cleanup)
             .last().cloned().unwrap_or(c.succ)
     }
 
@@ -567,7 +576,7 @@ fn open_drop_for_tuple<'a>(&mut self, c: &DropCtxt<'a, 'tcx>, tys: &[Ty<'tcx>])
     {
         debug!("open_drop_for_tuple({:?}, {:?})", c, tys);
 
-        let fields: Vec<_> = tys.iter().enumerate().map(|(i, &ty)| {
+        let fields = tys.iter().enumerate().map(|(i, &ty)| {
             (c.lvalue.clone().field(Field::new(i), ty),
              super::move_path_children_matching(
                  &self.move_data().move_paths, c.path, |proj| match proj {
@@ -579,7 +588,7 @@ fn open_drop_for_tuple<'a>(&mut self, c: &DropCtxt<'a, 'tcx>, tys: &[Ty<'tcx>])
             ))
         }).collect();
 
-        self.drop_ladder(c, &fields)
+        self.drop_ladder(c, fields)
     }
 
     fn open_drop_for_box<'a>(&mut self, c: &DropCtxt<'a, 'tcx>, ty: Ty<'tcx>)
@@ -634,7 +643,7 @@ fn open_drop_for_variant<'a>(&mut self,
                 variant_path,
                 &adt.variants[variant_index],
                 substs);
-            self.drop_ladder(c, &fields)
+            self.drop_ladder(c, fields)
         } else {
             // variant not found - drop the entire enum
             if let None = *drop_block {
@@ -659,7 +668,7 @@ fn open_drop_for_adt<'a>(&mut self, c: &DropCtxt<'a, 'tcx>,
                     &adt.variants[0],
                     substs
                 );
-                self.drop_ladder(c, &fields)
+                self.drop_ladder(c, fields)
             }
             _ => {
                 let variant_drops : Vec<BasicBlock> =
index 0624d72dd59939295a1aaaf3c4710ccf3abc6c16..400ae186010e3fb15d594615c6b5dc4705e9b395 100644 (file)
@@ -516,8 +516,10 @@ fn foo(a: &mut i32) {
             //        as immutable
 }
 ```
+
 To fix this error, ensure that you don't have any other references to the
 variable before trying to access it mutably:
+
 ```
 fn bar(x: &mut i32) {}
 fn foo(a: &mut i32) {
@@ -525,10 +527,67 @@ fn foo(a: &mut i32) {
     let ref y = a; // ok!
 }
 ```
+
 For more information on the rust ownership system, take a look at
 https://doc.rust-lang.org/stable/book/references-and-borrowing.html.
 "##,
 
+E0503: r##"
+A value was used after it was mutably borrowed.
+
+Example of erroneous code:
+
+```compile_fail
+fn main() {
+    let mut value = 3;
+    // Create a mutable borrow of `value`. This borrow
+    // lives until the end of this function.
+    let _borrow = &mut value;
+    let _sum = value + 1; // error: cannot use `value` because
+                          //        it was mutably borrowed
+}
+```
+
+In this example, `value` is mutably borrowed by `borrow` and cannot be
+used to calculate `sum`. This is not possible because this would violate
+Rust's mutability rules.
+
+You can fix this error by limiting the scope of the borrow:
+
+```
+fn main() {
+    let mut value = 3;
+    // By creating a new block, you can limit the scope
+    // of the reference.
+    {
+        let _borrow = &mut value; // Use `_borrow` inside this block.
+    }
+    // The block has ended and with it the borrow.
+    // You can now use `value` again.
+    let _sum = value + 1;
+}
+```
+
+Or by cloning `value` before borrowing it:
+
+```
+fn main() {
+    let mut value = 3;
+    // We clone `value`, creating a copy.
+    let value_cloned = value.clone();
+    // The mutable borrow is a reference to `value` and
+    // not to `value_cloned`...
+    let _borrow = &mut value;
+    // ... which means we can still use `value_cloned`,
+    let _sum = value_cloned + 1;
+    // even though the borrow only ends here.
+}
+```
+
+You can find more information about borrowing in the rust-book:
+http://doc.rust-lang.org/stable/book/references-and-borrowing.html
+"##,
+
 E0504: r##"
 This error occurs when an attempt is made to move a borrowed variable into a
 closure.
@@ -911,6 +970,50 @@ fn main() {
 http://doc.rust-lang.org/stable/book/references-and-borrowing.html
 "##,
 
+E0508: r##"
+A value was moved out of a non-copy fixed-size array.
+
+Example of erroneous code:
+
+```compile_fail
+struct NonCopy;
+
+fn main() {
+    let array = [NonCopy; 1];
+    let _value = array[0]; // error: cannot move out of type `[NonCopy; 1]`,
+                           //        a non-copy fixed-size array
+}
+```
+
+The first element was moved out of the array, but this is not
+possible because `NonCopy` does not implement the `Copy` trait.
+
+Consider borrowing the element instead of moving it:
+
+```
+struct NonCopy;
+
+fn main() {
+    let array = [NonCopy; 1];
+    let _value = &array[0]; // Borrowing is allowed, unlike moving.
+}
+```
+
+Alternatively, if your type implements `Clone` and you need to own the value,
+consider borrowing and then cloning:
+
+```
+#[derive(Clone)]
+struct NonCopy;
+
+fn main() {
+    let array = [NonCopy; 1];
+    // Now you can clone the array element.
+    let _value = array[0].clone();
+}
+```
+"##,
+
 E0509: r##"
 This error occurs when an attempt is made to move out of a value whose type
 implements the `Drop` trait.
@@ -1011,7 +1114,5 @@ fn main() {
 register_diagnostics! {
     E0385, // {} in an aliasable location
     E0388, // {} in a static location
-    E0503, // cannot use `..` because it was mutably borrowed
-    E0508, // cannot move out of type `..`, a non-copy fixed-size array
     E0524, // two closures require unique access to `..` at the same time
 }
index f183736b9ed577ad562d3143bdb06b7f5bf58c6e..dbca15ffd34b962e8ead9f0d6ff246855596184c 100644 (file)
@@ -247,8 +247,7 @@ fn check_for_bindings_named_the_same_as_variants(cx: &MatchCheckCtxt, pat: &Pat)
             if let ty::TyEnum(edef, _) = pat_ty.sty {
                 if let Def::Local(..) = cx.tcx.expect_def(p.id) {
                     if edef.variants.iter().any(|variant|
-                        variant.name == name.node.unhygienize()
-                            && variant.kind() == VariantKind::Unit
+                        variant.name == name.node && variant.kind() == VariantKind::Unit
                     ) {
                         let ty_path = cx.tcx.item_path_str(edef.did);
                         let mut err = struct_span_warn!(cx.tcx.sess, p.span, E0170,
index c3db252584cce28f864e4a5693d9f384d66080f5..7551bc5c234ef3096bce47dfdbbae0de496603c0 100644 (file)
@@ -945,10 +945,7 @@ fn infer<'a, 'tcx>(i: ConstInt,
         (&ty::TyInt(IntTy::I32), Infer(i)) => Ok(I32(i as i64 as i32)),
         (&ty::TyInt(IntTy::I64), Infer(i)) => Ok(I64(i as i64)),
         (&ty::TyInt(IntTy::Is), Infer(i)) => {
-            match ConstIsize::new(i as i64, tcx.sess.target.int_type) {
-                Ok(val) => Ok(Isize(val)),
-                Err(_) => Ok(Isize(ConstIsize::Is32(i as i64 as i32))),
-            }
+            Ok(Isize(ConstIsize::new_truncating(i as i64, tcx.sess.target.int_type)))
         },
 
         (&ty::TyInt(IntTy::I8), InferSigned(i)) => Ok(I8(i as i8)),
@@ -956,10 +953,7 @@ fn infer<'a, 'tcx>(i: ConstInt,
         (&ty::TyInt(IntTy::I32), InferSigned(i)) => Ok(I32(i as i32)),
         (&ty::TyInt(IntTy::I64), InferSigned(i)) => Ok(I64(i)),
         (&ty::TyInt(IntTy::Is), InferSigned(i)) => {
-            match ConstIsize::new(i, tcx.sess.target.int_type) {
-                Ok(val) => Ok(Isize(val)),
-                Err(_) => Ok(Isize(ConstIsize::Is32(i as i32))),
-            }
+            Ok(Isize(ConstIsize::new_truncating(i, tcx.sess.target.int_type)))
         },
 
         (&ty::TyUint(UintTy::U8), Infer(i)) => Ok(U8(i as u8)),
@@ -967,10 +961,7 @@ fn infer<'a, 'tcx>(i: ConstInt,
         (&ty::TyUint(UintTy::U32), Infer(i)) => Ok(U32(i as u32)),
         (&ty::TyUint(UintTy::U64), Infer(i)) => Ok(U64(i)),
         (&ty::TyUint(UintTy::Us), Infer(i)) => {
-            match ConstUsize::new(i, tcx.sess.target.uint_type) {
-                Ok(val) => Ok(Usize(val)),
-                Err(_) => Ok(Usize(ConstUsize::Us32(i as u32))),
-            }
+            Ok(Usize(ConstUsize::new_truncating(i, tcx.sess.target.uint_type)))
         },
         (&ty::TyUint(_), InferSigned(_)) => Err(IntermediateUnsignedNegative),
 
@@ -1052,20 +1043,14 @@ fn cast_const_int<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, val: ConstInt, ty: ty::
         ty::TyInt(ast::IntTy::I32) => Ok(Integral(I32(v as i64 as i32))),
         ty::TyInt(ast::IntTy::I64) => Ok(Integral(I64(v as i64))),
         ty::TyInt(ast::IntTy::Is) => {
-            match ConstIsize::new(v as i64, tcx.sess.target.int_type) {
-                Ok(val) => Ok(Integral(Isize(val))),
-                Err(_) => Ok(Integral(Isize(ConstIsize::Is32(v as i64 as i32)))),
-            }
+            Ok(Integral(Isize(ConstIsize::new_truncating(v as i64, tcx.sess.target.int_type))))
         },
         ty::TyUint(ast::UintTy::U8) => Ok(Integral(U8(v as u8))),
         ty::TyUint(ast::UintTy::U16) => Ok(Integral(U16(v as u16))),
         ty::TyUint(ast::UintTy::U32) => Ok(Integral(U32(v as u32))),
         ty::TyUint(ast::UintTy::U64) => Ok(Integral(U64(v))),
         ty::TyUint(ast::UintTy::Us) => {
-            match ConstUsize::new(v, tcx.sess.target.uint_type) {
-                Ok(val) => Ok(Integral(Usize(val))),
-                Err(_) => Ok(Integral(Usize(ConstUsize::Us32(v as u32)))),
-            }
+            Ok(Integral(Usize(ConstUsize::new_truncating(v, tcx.sess.target.uint_type))))
         },
         ty::TyFloat(ast::FloatTy::F64) => match val.erase_type() {
             Infer(u) => Ok(Float(F64(u as f64))),
index 4d2db355eb0258ec9b328c57a5c85afa1a4311f3..ef92b628523e7b278c0fdba2372bbcb6d166eb96 100644 (file)
@@ -27,7 +27,8 @@ pub fn as_i64(self, target_int_ty: ast::IntTy) -> i64 {
             (Is16(i), ast::IntTy::I16) => i as i64,
             (Is32(i), ast::IntTy::I32) => i as i64,
             (Is64(i), ast::IntTy::I64) => i,
-            _ => panic!("got invalid isize size for target"),
+            _ => panic!("unable to convert self ({:?}) to target isize ({:?})",
+                        self, target_int_ty),
         }
     }
     pub fn new(i: i64, target_int_ty: ast::IntTy) -> Result<Self, ConstMathErr> {
@@ -40,4 +41,12 @@ pub fn new(i: i64, target_int_ty: ast::IntTy) -> Result<Self, ConstMathErr> {
             _ => unreachable!(),
         }
     }
+    pub fn new_truncating(i: i64, target_int_ty: ast::IntTy) -> Self {
+        match target_int_ty {
+            ast::IntTy::I16 => Is16(i as i16),
+            ast::IntTy::I32 => Is32(i as i32),
+            ast::IntTy::I64 => Is64(i),
+            _ => unreachable!(),
+        }
+    }
 }
index 2b224d0646616c0f0d6ac23db4e9c5173d3c446f..bf73ff03c98959e025fe3ae04fb6f8065f5464b1 100644 (file)
@@ -27,7 +27,8 @@ pub fn as_u64(self, target_uint_ty: ast::UintTy) -> u64 {
             (Us16(i), ast::UintTy::U16) => i as u64,
             (Us32(i), ast::UintTy::U32) => i as u64,
             (Us64(i), ast::UintTy::U64) => i,
-            _ => panic!("got invalid usize size for target"),
+            _ => panic!("unable to convert self ({:?}) to target usize ({:?})",
+                        self, target_uint_ty),
         }
     }
     pub fn new(i: u64, target_uint_ty: ast::UintTy) -> Result<Self, ConstMathErr> {
@@ -40,4 +41,12 @@ pub fn new(i: u64, target_uint_ty: ast::UintTy) -> Result<Self, ConstMathErr> {
             _ => unreachable!(),
         }
     }
+    pub fn new_truncating(i: u64, target_uint_ty: ast::UintTy) -> Self {
+        match target_uint_ty {
+            ast::UintTy::U16 => Us16(i as u16),
+            ast::UintTy::U32 => Us32(i as u32),
+            ast::UintTy::U64 => Us64(i),
+            _ => unreachable!(),
+        }
+    }
 }
index 79d3f0cf688465cf222ac99e4aec9d2046e5fe4b..2c3a2e8ef6c3b97c9514bdf0cca99b850e3fdedd 100644 (file)
@@ -237,23 +237,9 @@ fn bitvec_iter_works() {
                [1, 10, 19, 62, 63, 64, 65, 66, 99]);
 }
 
-#[test]
-fn bitvec_iter_works_2() {
-    let mut bitvec = BitVector::new(300);
-    bitvec.insert(1);
-    bitvec.insert(10);
-    bitvec.insert(19);
-    bitvec.insert(62);
-    bitvec.insert(66);
-    bitvec.insert(99);
-    bitvec.insert(299);
-    assert_eq!(bitvec.iter().collect::<Vec<_>>(),
-               [1, 10, 19, 62, 66, 99, 299]);
-
-}
 
 #[test]
-fn bitvec_iter_works_3() {
+fn bitvec_iter_works_2() {
     let mut bitvec = BitVector::new(319);
     bitvec.insert(0);
     bitvec.insert(127);
index 9a90ab8c09d44c58499da17b571a5388886980ac..b7c71dd366469eceaac01605efdafd1bfe33935e 100644 (file)
@@ -46,15 +46,25 @@ fn as_mut_slice(&mut self) -> &mut [T] {
 
 #[test]
 fn test_sliced_tuples() {
-    let t2 = (100i32, 101i32);
-    assert_eq!(t2.as_slice(), &[100i32, 101i32]);
+    let t2 = (100, 101);
+    assert_eq!(t2.as_slice(), &[100, 101]);
 
-    let t3 = (102i32, 103i32, 104i32);
-    assert_eq!(t3.as_slice(), &[102i32, 103i32, 104i32]);
+    let t3 = (102, 103, 104);
+    assert_eq!(t3.as_slice(), &[102, 103, 104]);
 
-    let t4 = (105i32, 106i32, 107i32, 108i32);
-    assert_eq!(t4.as_slice(), &[105i32, 106i32, 107i32, 108i32]);
+    let t4 = (105, 106, 107, 108);
+    assert_eq!(t4.as_slice(), &[105, 106, 107, 108]);
+
+    let t5 = (109, 110, 111, 112, 113);
+    assert_eq!(t5.as_slice(), &[109, 110, 111, 112, 113]);
+
+    let t6 = (114, 115, 116, 117, 118, 119);
+    assert_eq!(t6.as_slice(), &[114, 115, 116, 117, 118, 119]);
+
+    let t7 = (120, 121, 122, 123, 124, 125, 126);
+    assert_eq!(t7.as_slice(), &[120, 121, 122, 123, 124, 125, 126]);
+
+    let t8 = (127, 128, 129, 130, 131, 132, 133, 134);
+    assert_eq!(t8.as_slice(), &[127, 128, 129, 130, 131, 132, 133, 134]);
 
-    let t5 = (109i32, 110i32, 111i32, 112i32, 113i32);
-    assert_eq!(t5.as_slice(), &[109i32, 110i32, 111i32, 112i32, 113i32]);
 }
index 06d8a6c9ac86135cec0aca16c89ea2e4576d9138..af68b7632dd18a9c5b8d4286cf68fb851a76ccdd 100644 (file)
@@ -582,6 +582,7 @@ pub fn phase_2_configure_and_expand<'a>(sess: &Session,
         sess.track_errors(|| {
             syntax::config::strip_unconfigured_items(sess.diagnostic(),
                                                      krate,
+                                                     sess.opts.test,
                                                      &mut feature_gated_cfgs)
         })
     })?;
@@ -692,6 +693,7 @@ pub fn phase_2_configure_and_expand<'a>(sess: &Session,
             features: Some(&features),
             recursion_limit: sess.recursion_limit.get(),
             trace_mac: sess.opts.debugging_opts.trace_macros,
+            should_test: sess.opts.test,
         };
         let mut loader = macro_import::MacroLoader::new(sess, &cstore, crate_name);
         let mut ecx = syntax::ext::base::ExtCtxt::new(&sess.parse_sess,
index 2bd2997566e0dcf81b1fd38f4cc06be7908a54d4..3ceca9218bdf5379acda9c219f07cc1b26346f7c 100644 (file)
@@ -163,7 +163,7 @@ fn check_pat(&mut self, cx: &LateContext, pat: &hir::Pat) {
                     continue;
                 }
                 if let PatKind::Binding(_, ident, None) = fieldpat.node.pat.node {
-                    if ident.node.unhygienize() == fieldpat.node.name {
+                    if ident.node == fieldpat.node.name {
                         cx.span_lint(NON_SHORTHAND_FIELD_PATTERNS, fieldpat.span,
                                      &format!("the `{}:` in this pattern is redundant and can \
                                               be removed", ident.node))
index ea0d8eae75d750c39cc5ea4872147aad5780fcd5..e757201c8863383a5065420713c7f847dc6770a3 100644 (file)
@@ -54,6 +54,7 @@
 pub use self::Linkage::*;
 pub use self::DLLStorageClassTypes::*;
 
+use std::str::FromStr;
 use std::ffi::{CString, CStr};
 use std::cell::RefCell;
 use std::slice;
@@ -426,6 +427,20 @@ pub enum ArchiveKind {
     K_COFF,
 }
 
+impl FromStr for ArchiveKind {
+    type Err = ();
+
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
+        match s {
+            "gnu" => Ok(ArchiveKind::K_GNU),
+            "mips64" => Ok(ArchiveKind::K_MIPS64),
+            "bsd" => Ok(ArchiveKind::K_BSD),
+            "coff" => Ok(ArchiveKind::K_COFF),
+            _ => Err(()),
+        }
+    }
+}
+
 /// Represents the different LLVM passes Rust supports
 #[derive(Copy, Clone, PartialEq, Debug)]
 #[repr(C)]
index 2025045cc8f56f3ac6aced9424af50d3aa9da472..8bf057095ac56d6ab7c75fc89288dcbd7d9c53c4 100644 (file)
@@ -929,29 +929,26 @@ fn process_item(&mut self, i: &ast::Item) {
                     return;
                 }
 
-                match self.creader.extract_crate_info(i) {
-                    Some(info) => {
-                        let (cnum, _, _) = self.creader.resolve_crate(&None,
-                                                                      &info.ident,
-                                                                      &info.name,
-                                                                      None,
-                                                                      i.span,
-                                                                      PathKind::Crate,
-                                                                      true);
-
-                        let def_id = self.definitions.opt_local_def_id(i.id).unwrap();
-                        let len = self.definitions.def_path(def_id.index).data.len();
-
-                        self.creader.update_extern_crate(cnum,
-                                                         ExternCrate {
-                                                             def_id: def_id,
-                                                             span: i.span,
-                                                             direct: true,
-                                                             path_len: len,
-                                                         });
-                        self.cstore.add_extern_mod_stmt_cnum(info.id, cnum);
-                    }
-                    None => ()
+                if let Some(info) = self.creader.extract_crate_info(i) {
+                    let (cnum, _, _) = self.creader.resolve_crate(&None,
+                                                                  &info.ident,
+                                                                  &info.name,
+                                                                  None,
+                                                                  i.span,
+                                                                  PathKind::Crate,
+                                                                  true);
+
+                    let def_id = self.definitions.opt_local_def_id(i.id).unwrap();
+                    let len = self.definitions.def_path(def_id.index).data.len();
+
+                    self.creader.update_extern_crate(cnum,
+                                                     ExternCrate {
+                                                         def_id: def_id,
+                                                         span: i.span,
+                                                         direct: true,
+                                                         path_len: len,
+                                                     });
+                    self.cstore.add_extern_mod_stmt_cnum(info.id, cnum);
                 }
             }
             ast::ItemKind::ForeignMod(ref fm) => self.process_foreign_mod(i, fm),
index c0c27ac5943aadc5d8b9e5bff696052600584ceb..ab7bc4eec91cc99d86f03ef61ffbbfcf468fa25b 100644 (file)
@@ -368,6 +368,7 @@ fn minval_literal(&mut self, span: Span, ty: ty::Ty<'tcx>) -> Operand<'tcx> {
                     ast::IntTy::Is => {
                         let int_ty = self.hir.tcx().sess.target.int_type;
                         let min = match int_ty {
+                            ast::IntTy::I16 => std::i16::MIN as i64,
                             ast::IntTy::I32 => std::i32::MIN as i64,
                             ast::IntTy::I64 => std::i64::MIN,
                             _ => unreachable!()
index aea61da18a0a1c59a67721b43670c6fc147e442b..29019f3683dead592681278afbbce89fcf349461 100644 (file)
 
 //! A helper class for dealing with static archives
 
-use std::env;
 use std::ffi::{CString, CStr, OsString};
-use std::fs::{self, File};
-use std::io::prelude::*;
 use std::io;
 use std::mem;
 use std::path::{Path, PathBuf};
-use std::process::{Command, Output, Stdio};
 use std::ptr;
 use std::str;
 
@@ -25,7 +21,6 @@
 use llvm::archive_ro::{ArchiveRO, Child};
 use llvm::{self, ArchiveKind};
 use rustc::session::Session;
-use rustc_back::tempdir::TempDir;
 
 pub struct ArchiveConfig<'a> {
     pub sess: &'a Session,
@@ -41,7 +36,6 @@ pub struct ArchiveConfig<'a> {
 #[must_use = "must call build() to finish building the archive"]
 pub struct ArchiveBuilder<'a> {
     config: ArchiveConfig<'a>,
-    work_dir: TempDir,
     removals: Vec<String>,
     additions: Vec<Addition>,
     should_update_symbols: bool,
@@ -55,17 +49,10 @@ enum Addition {
     },
     Archive {
         archive: ArchiveRO,
-        archive_name: String,
         skip: Box<FnMut(&str) -> bool>,
     },
 }
 
-enum Action<'a> {
-    Remove(&'a [String]),
-    AddObjects(&'a [&'a PathBuf], bool),
-    UpdateSymbols,
-}
-
 pub fn find_library(name: &str, search_paths: &[PathBuf], sess: &Session)
                     -> PathBuf {
     // On Windows, static libraries sometimes show up as libfoo.a and other
@@ -102,7 +89,6 @@ impl<'a> ArchiveBuilder<'a> {
     pub fn new(config: ArchiveConfig<'a>) -> ArchiveBuilder<'a> {
         ArchiveBuilder {
             config: config,
-            work_dir: TempDir::new("rsar").unwrap(),
             removals: Vec::new(),
             additions: Vec::new(),
             should_update_symbols: false,
@@ -148,7 +134,7 @@ fn src_archive(&mut self) -> Option<&ArchiveRO> {
     pub fn add_native_library(&mut self, name: &str) {
         let location = find_library(name, &self.config.lib_search_paths,
                                     self.config.sess);
-        self.add_archive(&location, name, |_| false).unwrap_or_else(|e| {
+        self.add_archive(&location, |_| false).unwrap_or_else(|e| {
             self.config.sess.fatal(&format!("failed to add native library {}: {}",
                                             location.to_string_lossy(), e));
         });
@@ -172,14 +158,14 @@ pub fn add_rlib(&mut self, rlib: &Path, name: &str, lto: bool)
         let metadata_filename =
             self.config.sess.cstore.metadata_filename().to_owned();
 
-        self.add_archive(rlib, &name[..], move |fname: &str| {
+        self.add_archive(rlib, move |fname: &str| {
             let skip_obj = lto && fname.starts_with(&obj_start)
                 && fname.ends_with(".o");
             skip_obj || fname.ends_with(bc_ext) || fname == metadata_filename
         })
     }
 
-    fn add_archive<F>(&mut self, archive: &Path, name: &str, skip: F)
+    fn add_archive<F>(&mut self, archive: &Path, skip: F)
                       -> io::Result<()>
         where F: FnMut(&str) -> bool + 'static
     {
@@ -190,7 +176,6 @@ fn add_archive<F>(&mut self, archive: &Path, name: &str, skip: F)
         };
         self.additions.push(Addition::Archive {
             archive: archive,
-            archive_name: name.to_string(),
             skip: Box::new(skip),
         });
         Ok(())
@@ -214,234 +199,23 @@ pub fn update_symbols(&mut self) {
     /// Combine the provided files, rlibs, and native libraries into a single
     /// `Archive`.
     pub fn build(&mut self) {
-        let res = match self.llvm_archive_kind() {
-            Some(kind) => self.build_with_llvm(kind),
-            None => self.build_with_ar_cmd(),
-        };
-        if let Err(e) = res {
-            self.config.sess.fatal(&format!("failed to build archive: {}", e));
-        }
-    }
-
-    pub fn llvm_archive_kind(&self) -> Option<ArchiveKind> {
-        if unsafe { llvm::LLVMVersionMinor() < 7 } {
-            return None
-        }
-
-        // Currently LLVM only supports writing archives in the 'gnu' format.
-        match &self.config.sess.target.target.options.archive_format[..] {
-            "gnu" => Some(ArchiveKind::K_GNU),
-            "mips64" => Some(ArchiveKind::K_MIPS64),
-            "bsd" => Some(ArchiveKind::K_BSD),
-            "coff" => Some(ArchiveKind::K_COFF),
-            _ => None,
-        }
-    }
-
-    pub fn using_llvm(&self) -> bool {
-        self.llvm_archive_kind().is_some()
-    }
-
-    fn build_with_ar_cmd(&mut self) -> io::Result<()> {
-        let removals = mem::replace(&mut self.removals, Vec::new());
-        let additions = mem::replace(&mut self.additions, Vec::new());
-        let should_update_symbols = mem::replace(&mut self.should_update_symbols,
-                                                 false);
-
-        // Don't use fs::copy because libs may be installed as read-only and we
-        // want to modify this archive, so we use `io::copy` to not preserve
-        // permission bits.
-        if let Some(ref s) = self.config.src {
-            io::copy(&mut File::open(s)?,
-                     &mut File::create(&self.config.dst)?)?;
-        }
-
-        if removals.len() > 0 {
-            self.run(None, Action::Remove(&removals));
-        }
-
-        let mut members = Vec::new();
-        for addition in additions {
-            match addition {
-                Addition::File { path, name_in_archive } => {
-                    let dst = self.work_dir.path().join(&name_in_archive);
-                    fs::copy(&path, &dst)?;
-                    members.push(PathBuf::from(name_in_archive));
-                }
-                Addition::Archive { archive, archive_name, mut skip } => {
-                    self.add_archive_members(&mut members, archive,
-                                             &archive_name, &mut *skip)?;
-                }
-            }
-        }
-
-        // Get an absolute path to the destination, so `ar` will work even
-        // though we run it from `self.work_dir`.
-        let mut objects = Vec::new();
-        let mut total_len = self.config.dst.to_string_lossy().len();
-
-        if members.is_empty() {
-            if should_update_symbols {
-                self.run(Some(self.work_dir.path()), Action::UpdateSymbols);
-            }
-            return Ok(())
-        }
-
-        // Don't allow the total size of `args` to grow beyond 32,000 bytes.
-        // Windows will raise an error if the argument string is longer than
-        // 32,768, and we leave a bit of extra space for the program name.
-        const ARG_LENGTH_LIMIT: usize = 32_000;
-
-        for member_name in &members {
-            let len = member_name.to_string_lossy().len();
-
-            // `len + 1` to account for the space that's inserted before each
-            // argument.  (Windows passes command-line arguments as a single
-            // string, not an array of strings.)
-            if total_len + len + 1 > ARG_LENGTH_LIMIT {
-                // Add the archive members seen so far, without updating the
-                // symbol table.
-                self.run(Some(self.work_dir.path()),
-                         Action::AddObjects(&objects, false));
-
-                objects.clear();
-                total_len = self.config.dst.to_string_lossy().len();
-            }
-
-            objects.push(member_name);
-            total_len += len + 1;
-        }
-
-        // Add the remaining archive members, and update the symbol table if
-        // necessary.
-        self.run(Some(self.work_dir.path()),
-                         Action::AddObjects(&objects, should_update_symbols));
-        Ok(())
-    }
-
-    fn add_archive_members(&mut self, members: &mut Vec<PathBuf>,
-                           archive: ArchiveRO, name: &str,
-                           skip: &mut FnMut(&str) -> bool) -> io::Result<()> {
-        // Next, we must rename all of the inputs to "guaranteed unique names".
-        // We write each file into `self.work_dir` under its new unique name.
-        // The reason for this renaming is that archives are keyed off the name
-        // of the files, so if two files have the same name they will override
-        // one another in the archive (bad).
-        //
-        // We skip any files explicitly desired for skipping, and we also skip
-        // all SYMDEF files as these are just magical placeholders which get
-        // re-created when we make a new archive anyway.
-        for file in archive.iter() {
-            let file = file.map_err(string_to_io_error)?;
-            if !is_relevant_child(&file) {
-                continue
-            }
-            let filename = file.name().unwrap();
-            if skip(filename) {
-                continue
+        let kind = match self.llvm_archive_kind() {
+            Ok(kind) => kind,
+            Err(kind) => {
+                self.config.sess.fatal(&format!("Don't know how to build archive of type: {}",
+                                                kind));
             }
-            let filename = Path::new(filename).file_name().unwrap()
-                                              .to_str().unwrap();
-
-            // Archives on unix systems typically do not have slashes in
-            // filenames as the `ar` utility generally only uses the last
-            // component of a path for the filename list in the archive. On
-            // Windows, however, archives assembled with `lib.exe` will preserve
-            // the full path to the file that was placed in the archive,
-            // including path separators.
-            //
-            // The code below is munging paths so it'll go wrong pretty quickly
-            // if there's some unexpected slashes in the filename, so here we
-            // just chop off everything but the filename component. Note that
-            // this can cause duplicate filenames, but that's also handled below
-            // as well.
-            let filename = Path::new(filename).file_name().unwrap()
-                                              .to_str().unwrap();
-
-            // An archive can contain files of the same name multiple times, so
-            // we need to be sure to not have them overwrite one another when we
-            // extract them. Consequently we need to find a truly unique file
-            // name for us!
-            let mut new_filename = String::new();
-            for n in 0.. {
-                let n = if n == 0 {String::new()} else {format!("-{}", n)};
-                new_filename = format!("r{}-{}-{}", n, name, filename);
-
-                // LLDB (as mentioned in back::link) crashes on filenames of
-                // exactly
-                // 16 bytes in length. If we're including an object file with
-                //    exactly 16-bytes of characters, give it some prefix so
-                //    that it's not 16 bytes.
-                new_filename = if new_filename.len() == 16 {
-                    format!("lldb-fix-{}", new_filename)
-                } else {
-                    new_filename
-                };
-
-                let present = members.iter().filter_map(|p| {
-                    p.file_name().and_then(|f| f.to_str())
-                }).any(|s| s == new_filename);
-                if !present {
-                    break
-                }
-            }
-            let dst = self.work_dir.path().join(&new_filename);
-            File::create(&dst)?.write_all(file.data())?;
-            members.push(PathBuf::from(new_filename));
-        }
-        Ok(())
-    }
-
-    fn run(&self, cwd: Option<&Path>, action: Action) -> Output {
-        let abs_dst = env::current_dir().unwrap().join(&self.config.dst);
-        let ar = &self.config.ar_prog;
-        let mut cmd = Command::new(ar);
-        cmd.env("PATH", &self.config.command_path);
-        cmd.stdout(Stdio::piped()).stderr(Stdio::piped());
-        self.prepare_ar_action(&mut cmd, &abs_dst, action);
-        info!("{:?}", cmd);
+        };
 
-        if let Some(p) = cwd {
-            cmd.current_dir(p);
-            info!("inside {:?}", p.display());
+        if let Err(e) = self.build_with_llvm(kind) {
+            self.config.sess.fatal(&format!("failed to build archive: {}", e));
         }
 
-        let sess = &self.config.sess;
-        match cmd.spawn() {
-            Ok(prog) => {
-                let o = prog.wait_with_output().unwrap();
-                if !o.status.success() {
-                    sess.struct_err(&format!("{:?} failed with: {}", cmd, o.status))
-                        .note(&format!("stdout ---\n{}",
-                                       str::from_utf8(&o.stdout).unwrap()))
-                        .note(&format!("stderr ---\n{}",
-                                       str::from_utf8(&o.stderr).unwrap()))
-                        .emit();
-                    sess.abort_if_errors();
-                }
-                o
-            },
-            Err(e) => {
-                sess.fatal(&format!("could not exec `{}`: {}",
-                                    self.config.ar_prog, e));
-            }
-        }
     }
 
-    fn prepare_ar_action(&self, cmd: &mut Command, dst: &Path, action: Action) {
-        match action {
-            Action::Remove(files) => {
-                cmd.arg("d").arg(dst).args(files);
-            }
-            Action::AddObjects(objs, update_symbols) => {
-                cmd.arg(if update_symbols {"crs"} else {"crS"})
-                   .arg(dst)
-                   .args(objs);
-            }
-            Action::UpdateSymbols => {
-                cmd.arg("s").arg(dst);
-            }
-        }
+    fn llvm_archive_kind(&self) -> Result<ArchiveKind, &str> {
+        let kind = &self.config.sess.target.target.options.archive_format[..];
+        kind.parse().map_err(|_| kind)
     }
 
     fn build_with_llvm(&mut self, kind: ArchiveKind) -> io::Result<()> {
@@ -480,7 +254,7 @@ fn build_with_llvm(&mut self, kind: ArchiveKind) -> io::Result<()> {
                         strings.push(path);
                         strings.push(name);
                     }
-                    Addition::Archive { archive, archive_name: _, mut skip } => {
+                    Addition::Archive { archive, mut skip } => {
                         for child in archive.iter() {
                             let child = child.map_err(string_to_io_error)?;
                             if !is_relevant_child(&child) {
index 6e5964d83c064a9eef4299fd5bccc5c4896c2840..4676b0a67e4ae6fa226cda62c82636a68ee05751 100644 (file)
@@ -412,13 +412,6 @@ fn link_rlib<'a>(sess: &'a Session,
     // symbol table of the archive.
     ab.update_symbols();
 
-    // For OSX/iOS, we must be careful to update symbols only when adding
-    // object files.  We're about to start adding non-object files, so run
-    // `ar` now to process the object files.
-    if sess.target.target.options.is_like_osx && !ab.using_llvm() {
-        ab.build();
-    }
-
     // Note that it is important that we add all of our non-object "magical
     // files" *after* all of the object files in the archive. The reason for
     // this is as follows:
@@ -515,7 +508,7 @@ fn link_rlib<'a>(sess: &'a Session,
             // After adding all files to the archive, we need to update the
             // symbol table of the archive. This currently dies on OSX (see
             // #11162), and isn't necessary there anyway
-            if !sess.target.target.options.is_like_osx || ab.using_llvm() {
+            if !sess.target.target.options.is_like_osx {
                 ab.update_symbols();
             }
         }
@@ -575,9 +568,6 @@ fn write_rlib_bytecode_object_v1(writer: &mut Write,
 fn link_staticlib(sess: &Session, objects: &[PathBuf], out_filename: &Path,
                   tempdir: &Path) {
     let mut ab = link_rlib(sess, None, objects, out_filename, tempdir);
-    if sess.target.target.options.is_like_osx && !ab.using_llvm() {
-        ab.build();
-    }
     if !sess.target.target.options.no_compiler_rt {
         ab.add_native_library("compiler-rt");
     }
index 381bd24d9a4ae59f19938000e53e6d925df5199d..5250361cd17aede9221bfd65880e6d4c213917ba 100644 (file)
@@ -2252,17 +2252,14 @@ pub fn update_linkage(ccx: &CrateContext,
 }
 
 fn set_global_section(ccx: &CrateContext, llval: ValueRef, i: &hir::Item) {
-    match attr::first_attr_value_str_by_name(&i.attrs, "link_section") {
-        Some(sect) => {
-            if contains_null(&sect) {
-                ccx.sess().fatal(&format!("Illegal null byte in link_section value: `{}`", &sect));
-            }
-            unsafe {
-                let buf = CString::new(sect.as_bytes()).unwrap();
-                llvm::LLVMSetSection(llval, buf.as_ptr());
-            }
-        },
-        None => ()
+    if let Some(sect) = attr::first_attr_value_str_by_name(&i.attrs, "link_section") {
+        if contains_null(&sect) {
+            ccx.sess().fatal(&format!("Illegal null byte in link_section value: `{}`", &sect));
+        }
+        unsafe {
+            let buf = CString::new(sect.as_bytes()).unwrap();
+            llvm::LLVMSetSection(llval, buf.as_ptr());
+        }
     }
 }
 
index 550455a7fb7a2306a4f800f2cacdcf6b427136b5..bfcb1ae33b3019f000314b4e25005f23f1a839aa 100644 (file)
@@ -1097,45 +1097,7 @@ macro_rules! mk_struct {
     ifn!("llvm.localrecover", fn(i8p, i8p, t_i32) -> i8p);
     ifn!("llvm.x86.seh.recoverfp", fn(i8p, i8p) -> i8p);
 
-    // Some intrinsics were introduced in later versions of LLVM, but they have
-    // fallbacks in libc or libm and such.
-    macro_rules! compatible_ifn {
-        ($name:expr, noop($cname:ident ($($arg:expr),*) -> void), $llvm_version:expr) => (
-            if unsafe { llvm::LLVMVersionMinor() >= $llvm_version } {
-                // The `if key == $name` is already in ifn!
-                ifn!($name, fn($($arg),*) -> void);
-            } else if key == $name {
-                let f = declare::declare_cfn(ccx, stringify!($cname),
-                                             Type::func(&[$($arg),*], &void));
-                llvm::SetLinkage(f, llvm::InternalLinkage);
-
-                let bld = ccx.builder();
-                let llbb = unsafe {
-                    llvm::LLVMAppendBasicBlockInContext(ccx.llcx(), f,
-                                                        "entry-block\0".as_ptr() as *const _)
-                };
-
-                bld.position_at_end(llbb);
-                bld.ret_void();
-
-                ccx.intrinsics().borrow_mut().insert($name, f.clone());
-                return Some(f);
-            }
-        );
-        ($name:expr, $cname:ident ($($arg:expr),*) -> $ret:expr, $llvm_version:expr) => (
-            if unsafe { llvm::LLVMVersionMinor() >= $llvm_version } {
-                // The `if key == $name` is already in ifn!
-                ifn!($name, fn($($arg),*) -> $ret);
-            } else if key == $name {
-                let f = declare::declare_cfn(ccx, stringify!($cname),
-                                             Type::func(&[$($arg),*], &$ret));
-                ccx.intrinsics().borrow_mut().insert($name, f.clone());
-                return Some(f);
-            }
-        )
-    }
-
-    compatible_ifn!("llvm.assume", noop(llvmcompat_assume(i1) -> void), 6);
+    ifn!("llvm.assume", fn(i1) -> void);
 
     if ccx.sess().opts.debuginfo != NoDebugInfo {
         ifn!("llvm.dbg.declare", fn(Type::metadata(ccx), Type::metadata(ccx)) -> void);
index f1d9e2c5a571052f3d1fed4cabbb8aeb91b52f3b..33bdccbf067285c03e266467c2bea52b89d83ac2 100644 (file)
@@ -51,7 +51,7 @@ pub fn create_scope_map(cx: &CrateContext,
     for arg in args {
         pat_util::pat_bindings(&arg.pat, |_, node_id, _, path1| {
             scope_stack.push(ScopeStackEntry { scope_metadata: fn_metadata,
-                                               name: Some(path1.node.unhygienize()) });
+                                               name: Some(path1.node) });
             scope_map.insert(node_id, fn_metadata);
         })
     }
@@ -260,7 +260,7 @@ fn walk_pattern(cx: &CrateContext,
             // N.B.: this comparison must be UNhygienic... because
             // gdb knows nothing about the context, so any two
             // variables with the same name will cause the problem.
-            let name = path1.node.unhygienize();
+            let name = path1.node;
             let need_new_scope = scope_stack
                 .iter()
                 .any(|entry| entry.name == Some(name));
index ab4860dff1510ce414e376be32cccfd9f677c20b..0d13a1377b831c86136289a54ecdd6659d37fcfd 100644 (file)
@@ -874,9 +874,8 @@ pub fn unknown_file_metadata(cx: &CrateContext) -> DIFile {
 }
 
 fn file_metadata_(cx: &CrateContext, key: &str, file_name: &str, work_dir: &str) -> DIFile {
-    match debug_context(cx).created_files.borrow().get(key) {
-        Some(file_metadata) => return *file_metadata,
-        None => ()
+    if let Some(file_metadata) = debug_context(cx).created_files.borrow().get(key) {
+        return *file_metadata;
     }
 
     debug!("file_metadata: file_name: {}, work_dir: {}", file_name, work_dir);
index a0355dcc66e618c773b1bd0a1efcf970be13a61b..dad82167a76b32a589fae4922ff2e08166af4380 100644 (file)
@@ -50,12 +50,9 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
     let mono_ty = apply_param_substs(ccx.tcx(), psubsts, &item_ty);
     debug!("mono_ty = {:?} (post-substitution)", mono_ty);
 
-    match ccx.instances().borrow().get(&instance) {
-        Some(&val) => {
-            debug!("leaving monomorphic fn {:?}", instance);
-            return (val, mono_ty);
-        }
-        None => ()
+    if let Some(&val) = ccx.instances().borrow().get(&instance) {
+        debug!("leaving monomorphic fn {:?}", instance);
+        return (val, mono_ty);
     }
 
     debug!("monomorphic_fn({:?})", instance);
index d9dd122d07376e49b7ecf28c176d98b35ba3df42..6f7f33fe24d16fc0f2da61f97fde9af971264419 100644 (file)
@@ -2402,29 +2402,45 @@ fn check_argument_types(&self,
 
         let mut expected_arg_tys = expected_arg_tys;
         let expected_arg_count = fn_inputs.len();
+
+        fn parameter_count_error<'tcx>(sess: &Session, sp: Span, fn_inputs: &[Ty<'tcx>],
+                                       expected_count: usize, arg_count: usize, error_code: &str,
+                                       variadic: bool) {
+            let mut err = sess.struct_span_err_with_code(sp,
+                &format!("this function takes {}{} parameter{} but {} parameter{} supplied",
+                    if variadic {"at least "} else {""},
+                    expected_count,
+                    if expected_count == 1 {""} else {"s"},
+                    arg_count,
+                    if arg_count == 1 {" was"} else {"s were"}),
+                error_code);
+            let input_types = fn_inputs.iter().map(|i| format!("{:?}", i)).collect::<Vec<String>>();
+            if input_types.len() > 0 {
+                err.note(&format!("the following parameter type{} expected: {}",
+                        if expected_count == 1 {" was"} else {"s were"},
+                        input_types.join(", ")));
+            }
+            err.emit();
+        }
+
         let formal_tys = if tuple_arguments == TupleArguments {
             let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
             match tuple_type.sty {
+                ty::TyTuple(arg_types) if arg_types.len() != args.len() => {
+                    parameter_count_error(tcx.sess, sp, fn_inputs, arg_types.len(), args.len(),
+                                          "E0057", false);
+                    expected_arg_tys = &[];
+                    self.err_args(args.len())
+                }
                 ty::TyTuple(arg_types) => {
-                    if arg_types.len() != args.len() {
-                        span_err!(tcx.sess, sp, E0057,
-                            "this function takes {} parameter{} but {} parameter{} supplied",
-                            arg_types.len(),
-                            if arg_types.len() == 1 {""} else {"s"},
-                            args.len(),
-                            if args.len() == 1 {" was"} else {"s were"});
-                        expected_arg_tys = &[];
-                        self.err_args(args.len())
-                    } else {
-                        expected_arg_tys = match expected_arg_tys.get(0) {
-                            Some(&ty) => match ty.sty {
-                                ty::TyTuple(ref tys) => &tys,
-                                _ => &[]
-                            },
-                            None => &[]
-                        };
-                        arg_types.to_vec()
-                    }
+                    expected_arg_tys = match expected_arg_tys.get(0) {
+                        Some(&ty) => match ty.sty {
+                            ty::TyTuple(ref tys) => &tys,
+                            _ => &[]
+                        },
+                        None => &[]
+                    };
+                    arg_types.to_vec()
                 }
                 _ => {
                     span_err!(tcx.sess, sp, E0059,
@@ -2440,23 +2456,14 @@ fn check_argument_types(&self,
             if supplied_arg_count >= expected_arg_count {
                 fn_inputs.to_vec()
             } else {
-                span_err!(tcx.sess, sp, E0060,
-                    "this function takes at least {} parameter{} \
-                     but {} parameter{} supplied",
-                    expected_arg_count,
-                    if expected_arg_count == 1 {""} else {"s"},
-                    supplied_arg_count,
-                    if supplied_arg_count == 1 {" was"} else {"s were"});
+                parameter_count_error(tcx.sess, sp, fn_inputs, expected_arg_count,
+                                      supplied_arg_count, "E0060", true);
                 expected_arg_tys = &[];
                 self.err_args(supplied_arg_count)
             }
         } else {
-            span_err!(tcx.sess, sp, E0061,
-                "this function takes {} parameter{} but {} parameter{} supplied",
-                expected_arg_count,
-                if expected_arg_count == 1 {""} else {"s"},
-                supplied_arg_count,
-                if supplied_arg_count == 1 {" was"} else {"s were"});
+            parameter_count_error(tcx.sess, sp, fn_inputs, expected_arg_count, supplied_arg_count,
+                                  "E0061", false);
             expected_arg_tys = &[];
             self.err_args(supplied_arg_count)
         };
index 7017cb9f6a22b0b61b27e5f371616edd6523b0f9..c0cca08b6760282445e255309108c8ca33d61616 100644 (file)
@@ -1174,7 +1174,7 @@ enum DependsOnPointerSize {
 
 ```compile_fail
 #[repr(i32)]
-enum NightWatch {} // error: unsupported representation for zero-variant enum
+enum NightsWatch {} // error: unsupported representation for zero-variant enum
 ```
 
 It is impossible to define an integer type to be used to represent zero-variant
@@ -1184,8 +1184,8 @@ enum values because there are no zero-variant enum values. There is no way to
 
 ```
 #[repr(i32)]
-enum NightWatch {
-    JohnSnow,
+enum NightsWatch {
+    JonSnow,
     Commander,
 }
 ```
@@ -1193,7 +1193,7 @@ enum NightWatch {
 or you remove the integer represention of your enum:
 
 ```
-enum NightWatch {}
+enum NightsWatch {}
 ```
 "##,
 
index 77de51b32e2269841691e3dc3df3498b562d757d..f570375de5ea156ed8828fc75d78880b7031dfb0 100644 (file)
@@ -668,10 +668,13 @@ pub fn is_numeric(self) -> bool {
     /// Basic usage:
     ///
     /// ```
-    /// assert_eq!('C'.to_lowercase().next(), Some('c'));
+    /// assert_eq!('C'.to_lowercase().collect::<String>(), "c");
+    ///
+    /// // Sometimes the result is more than one character:
+    /// assert_eq!('İ'.to_lowercase().collect::<String>(), "i\u{307}");
     ///
     /// // Japanese scripts do not have case, and so:
-    /// assert_eq!('山'.to_lowercase().next(), Some('山'));
+    /// assert_eq!('山'.to_lowercase().collect::<String>(), "山");
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
@@ -702,10 +705,13 @@ pub fn to_lowercase(self) -> ToLowercase {
     /// Basic usage:
     ///
     /// ```
-    /// assert_eq!('c'.to_uppercase().next(), Some('C'));
+    /// assert_eq!('c'.to_uppercase().collect::<String>(), "C");
+    ///
+    /// // Sometimes the result is more than one character:
+    /// assert_eq!('ß'.to_uppercase().collect::<String>(), "SS");
     ///
     /// // Japanese does not have case, and so:
-    /// assert_eq!('山'.to_uppercase().next(), Some('山'));
+    /// assert_eq!('山'.to_uppercase().collect::<String>(), "山");
     /// ```
     ///
     /// In Turkish, the equivalent of 'i' in Latin has five forms instead of two:
@@ -716,17 +722,17 @@ pub fn to_lowercase(self) -> ToLowercase {
     /// Note that the lowercase dotted 'i' is the same as the Latin. Therefore:
     ///
     /// ```
-    /// let upper_i = 'i'.to_uppercase().next();
+    /// let upper_i: String = 'i'.to_uppercase().collect();
     /// ```
     ///
     /// The value of `upper_i` here relies on the language of the text: if we're
-    /// in `en-US`, it should be `Some('I')`, but if we're in `tr_TR`, it should
-    /// be `Some('İ')`. `to_uppercase()` does not take this into account, and so:
+    /// in `en-US`, it should be `"I"`, but if we're in `tr_TR`, it should
+    /// be `"İ"`. `to_uppercase()` does not take this into account, and so:
     ///
     /// ```
-    /// let upper_i = 'i'.to_uppercase().next();
+    /// let upper_i: String = 'i'.to_uppercase().collect();
     ///
-    /// assert_eq!(Some('I'), upper_i);
+    /// assert_eq!(upper_i, "I");
     /// ```
     ///
     /// holds across languages.
index 14ca63403163c85c0fb258dc875a6ad47c0e3560..0801da19c822effb233e22b121f381a3ab16eb2b 100644 (file)
@@ -2389,9 +2389,11 @@ fn clean(&self, cx: &DocContext) -> Vec<Item> {
         // We consider inlining the documentation of `pub use` statements, but we
         // forcefully don't inline if this is not public or if the
         // #[doc(no_inline)] attribute is present.
+        // Don't inline doc(hidden) imports so they can be stripped at a later stage.
         let denied = self.vis != hir::Public || self.attrs.iter().any(|a| {
             &a.name()[..] == "doc" && match a.meta_item_list() {
-                Some(l) => attr::contains_name(l, "no_inline"),
+                Some(l) => attr::contains_name(l, "no_inline") ||
+                           attr::contains_name(l, "hidden"),
                 None => false,
             }
         });
index dc1ef5d94a4aee7136c9580a10931ec941c81273..f7cc45a93b297dc465395bc02a7b6e3247639732 100644 (file)
@@ -1257,7 +1257,6 @@ fn recurse<T, F>(&mut self, s: String, f: F) -> T where
 
         info!("Recursing into {}", self.dst.display());
 
-        mkdir(&self.dst).unwrap();
         let ret = f(self);
 
         info!("Recursed; leaving {}", self.dst.display());
@@ -1301,7 +1300,7 @@ fn krate(self, mut krate: clean::Crate) -> Result<(), Error> {
     fn item<F>(&mut self, item: clean::Item, mut f: F) -> Result<(), Error> where
         F: FnMut(&mut Context, clean::Item),
     {
-        fn render(w: File, cx: &Context, it: &clean::Item,
+        fn render(writer: &mut io::Write, cx: &Context, it: &clean::Item,
                   pushname: bool) -> io::Result<()> {
             // A little unfortunate that this is done like this, but it sure
             // does make formatting *a lot* nicer.
@@ -1336,28 +1335,24 @@ fn render(w: File, cx: &Context, it: &clean::Item,
 
             reset_ids(true);
 
-            // We have a huge number of calls to write, so try to alleviate some
-            // of the pain by using a buffered writer instead of invoking the
-            // write syscall all the time.
-            let mut writer = BufWriter::new(w);
             if !cx.render_redirect_pages {
-                layout::render(&mut writer, &cx.shared.layout, &page,
+                layout::render(writer, &cx.shared.layout, &page,
                                &Sidebar{ cx: cx, item: it },
                                &Item{ cx: cx, item: it },
                                cx.shared.css_file_extension.is_some())?;
             } else {
                 let mut url = repeat("../").take(cx.current.len())
                                            .collect::<String>();
-                if let Some(&(ref names, _)) = cache().paths.get(&it.def_id) {
+                if let Some(&(ref names, ty)) = cache().paths.get(&it.def_id) {
                     for name in &names[..names.len() - 1] {
                         url.push_str(name);
                         url.push_str("/");
                     }
-                    url.push_str(&item_path(it));
-                    layout::redirect(&mut writer, &url)?;
+                    url.push_str(&item_path(ty, names.last().unwrap()));
+                    layout::redirect(writer, &url)?;
                 }
             }
-            writer.flush()
+            Ok(())
         }
 
         // Stripped modules survive the rustdoc passes (i.e. `strip-private`)
@@ -1378,9 +1373,16 @@ fn render(w: File, cx: &Context, it: &clean::Item,
             let mut item = Some(item);
             self.recurse(name, |this| {
                 let item = item.take().unwrap();
-                let joint_dst = this.dst.join("index.html");
-                let dst = try_err!(File::create(&joint_dst), &joint_dst);
-                try_err!(render(dst, this, &item, false), &joint_dst);
+
+                let mut buf = Vec::new();
+                render(&mut buf, this, &item, false).unwrap();
+                // buf will be empty if the module is stripped and there is no redirect for it
+                if !buf.is_empty() {
+                    let joint_dst = this.dst.join("index.html");
+                    try_err!(fs::create_dir_all(&this.dst), &this.dst);
+                    let mut dst = try_err!(File::create(&joint_dst), &joint_dst);
+                    try_err!(dst.write_all(&buf), &joint_dst);
+                }
 
                 let m = match item.inner {
                     clean::StrippedItem(box clean::ModuleItem(m)) |
@@ -1389,7 +1391,7 @@ fn render(w: File, cx: &Context, it: &clean::Item,
                 };
 
                 // render sidebar-items.js used throughout this module
-                {
+                if !this.render_redirect_pages {
                     let items = this.build_sidebar_items(&m);
                     let js_dst = this.dst.join("sidebar-items.js");
                     let mut js_out = BufWriter::new(try_err!(File::create(&js_dst), &js_dst));
@@ -1403,10 +1405,16 @@ fn render(w: File, cx: &Context, it: &clean::Item,
                 Ok(())
             })
         } else if item.name.is_some() {
-            let joint_dst = self.dst.join(&item_path(&item));
-
-            let dst = try_err!(File::create(&joint_dst), &joint_dst);
-            try_err!(render(dst, self, &item, true), &joint_dst);
+            let mut buf = Vec::new();
+            render(&mut buf, self, &item, true).unwrap();
+            // buf will be empty if the item is stripped and there is no redirect for it
+            if !buf.is_empty() {
+                let joint_dst = self.dst.join(&item_path(shortty(&item),
+                                                         item.name.as_ref().unwrap()));
+                try_err!(fs::create_dir_all(&self.dst), &self.dst);
+                let mut dst = try_err!(File::create(&joint_dst), &joint_dst);
+                try_err!(dst.write_all(&buf), &joint_dst);
+            }
             Ok(())
         } else {
             Ok(())
@@ -1524,7 +1532,7 @@ fn href(&self) -> Option<String> {
             Some(format!("{root}{path}/{file}?gotosrc={goto}",
                          root = root,
                          path = path[..path.len() - 1].join("/"),
-                         file = item_path(self.item),
+                         file = item_path(shortty(self.item), self.item.name.as_ref().unwrap()),
                          goto = self.item.def_id.index.as_usize()))
         }
     }
@@ -1616,13 +1624,10 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-fn item_path(item: &clean::Item) -> String {
-    if item.is_mod() {
-        format!("{}/index.html", item.name.as_ref().unwrap())
-    } else {
-        format!("{}.{}.html",
-                shortty(item).to_static_str(),
-                *item.name.as_ref().unwrap())
+fn item_path(ty: ItemType, name: &str) -> String {
+    match ty {
+        ItemType::Module => format!("{}/index.html", name),
+        _ => format!("{}.{}.html", ty.to_static_str(), name),
     }
 }
 
@@ -1814,7 +1819,7 @@ fn cmp(i1: &clean::Item, i2: &clean::Item, idx1: usize, idx2: usize) -> Ordering
                        docs = shorter(Some(&Markdown(doc_value).to_string())),
                        class = shortty(myitem),
                        stab = myitem.stability_class(),
-                       href = item_path(myitem),
+                       href = item_path(shortty(myitem), myitem.name.as_ref().unwrap()),
                        title = full_path(cx, myitem))?;
             }
         }
@@ -2258,8 +2263,8 @@ fn item_struct(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
         if fields.peek().is_some() {
             write!(w, "<h2 class='fields'>Fields</h2>")?;
             for (field, ty) in fields {
-                write!(w, "<span id='{shortty}.{name}'><code>{name}: {ty}</code></span>
-                           <span class='stab {stab}'></span>",
+                write!(w, "<span id='{shortty}.{name}' class='{shortty}'><code>{name}: {ty}</code>
+                           </span><span class='stab {stab}'></span>",
                        shortty = ItemType::StructField,
                        stab = field.stability_class(),
                        name = field.name.as_ref().unwrap(),
index da04f26a70b804ff9b117b12135e0764e314d66e..6d2b315502e260222c3511f5c41b4d6af4f98274 100644 (file)
@@ -659,6 +659,10 @@ span.since {
     margin-bottom: 25px;
 }
 
+.variant, .structfield {
+    display: block;
+}
+
 :target > code {
    background: #FDFFD3;
 }
index c7b571c2d1911438e3b33b647dceb0b6cf8b50d9..b0b55a76e266e96babe7c4a715ea4349c5994bdf 100644 (file)
@@ -245,7 +245,9 @@ fn inherits_doc_hidden(cx: &core::DocContext, mut node: ast::NodeId) -> bool {
         let def_did = def.def_id();
 
         let use_attrs = tcx.map.attrs(id).clean(self.cx);
-        let is_no_inline = use_attrs.list("doc").has_word("no_inline");
+        // Don't inline doc(hidden) imports so they can be stripped at a later stage.
+        let is_no_inline = use_attrs.list("doc").has_word("no_inline") ||
+                           use_attrs.list("doc").has_word("hidden");
 
         // For cross-crate impl inlining we need to know whether items are
         // reachable in documentation - a previously nonreachable item can be
index 37045822d47ec01d6c3b2f28d5167e71b786b2e7..536f168e4010843216c6bc07044ae6a57c78e1e4 100644 (file)
@@ -1552,6 +1552,12 @@ pub fn key(&self) -> &K {
         self.elem.read().0
     }
 
+    /// Take the ownership of the key and value from the map.
+    #[unstable(feature = "map_entry_recover_keys", issue = "34285")]
+    pub fn remove_pair(self) -> (K, V) {
+        pop_internal(self.elem)
+    }
+
     /// Gets a reference to the value in the entry.
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get(&self) -> &V {
@@ -1584,6 +1590,7 @@ pub fn insert(&mut self, mut value: V) -> V {
     pub fn remove(self) -> V {
         pop_internal(self.elem).1
     }
+
     /// Returns a key that was used for search.
     ///
     /// The key was retained for further use.
@@ -1600,6 +1607,12 @@ pub fn key(&self) -> &K {
         &self.key
     }
 
+    /// Take ownership of the key.
+    #[unstable(feature = "map_entry_recover_keys", issue = "34285")]
+    pub fn into_key(self) -> K {
+        self.key
+    }
+
     /// Sets the value of the entry with the VacantEntry's key,
     /// and returns a mutable reference to it
     #[stable(feature = "rust1", since = "1.0.0")]
index cf64e5d333639c5f11d88b854bcfa418cc81029b..c4c4cb453134f5e6fc15a58a12068041de7c7931 100644 (file)
@@ -8,10 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use alloc::heap::{allocate, deallocate, EMPTY};
+use alloc::heap::{EMPTY, allocate, deallocate};
 
 use cmp;
-use hash::{Hash, Hasher, BuildHasher};
+use hash::{BuildHasher, Hash, Hasher};
 use intrinsics::needs_drop;
 use marker;
 use mem::{align_of, size_of};
 #[unsafe_no_drop_flag]
 pub struct RawTable<K, V> {
     capacity: usize,
-    size:     usize,
-    hashes:   Unique<u64>,
+    size: usize,
+    hashes: Unique<u64>,
 
     // Because K/V do not appear directly in any of the types in the struct,
     // inform rustc that in fact instances of K and V are reachable from here.
-    marker:   marker::PhantomData<(K,V)>,
+    marker: marker::PhantomData<(K, V)>,
 }
 
 unsafe impl<K: Send, V: Send> Send for RawTable<K, V> {}
@@ -77,44 +77,48 @@ struct RawBucket<K, V> {
     hash: *mut u64,
 
     // We use *const to ensure covariance with respect to K and V
-    key:  *const K,
-    val:  *const V,
-    _marker: marker::PhantomData<(K,V)>,
+    key: *const K,
+    val: *const V,
+    _marker: marker::PhantomData<(K, V)>,
 }
 
-impl<K,V> Copy for RawBucket<K,V> {}
-impl<K,V> Clone for RawBucket<K,V> {
-    fn clone(&self) -> RawBucket<K, V> { *self }
+impl<K, V> Copy for RawBucket<K, V> {}
+impl<K, V> Clone for RawBucket<K, V> {
+    fn clone(&self) -> RawBucket<K, V> {
+        *self
+    }
 }
 
 pub struct Bucket<K, V, M> {
-    raw:   RawBucket<K, V>,
-    idx:   usize,
-    table: M
+    raw: RawBucket<K, V>,
+    idx: usize,
+    table: M,
 }
 
-impl<K,V,M:Copy> Copy for Bucket<K,V,M> {}
-impl<K,V,M:Copy> Clone for Bucket<K,V,M> {
-    fn clone(&self) -> Bucket<K,V,M> { *self }
+impl<K, V, M: Copy> Copy for Bucket<K, V, M> {}
+impl<K, V, M: Copy> Clone for Bucket<K, V, M> {
+    fn clone(&self) -> Bucket<K, V, M> {
+        *self
+    }
 }
 
 pub struct EmptyBucket<K, V, M> {
-    raw:   RawBucket<K, V>,
-    idx:   usize,
-    table: M
+    raw: RawBucket<K, V>,
+    idx: usize,
+    table: M,
 }
 
 pub struct FullBucket<K, V, M> {
-    raw:   RawBucket<K, V>,
-    idx:   usize,
-    table: M
+    raw: RawBucket<K, V>,
+    idx: usize,
+    table: M,
 }
 
 pub type EmptyBucketImm<'table, K, V> = EmptyBucket<K, V, &'table RawTable<K, V>>;
-pub type  FullBucketImm<'table, K, V> =  FullBucket<K, V, &'table RawTable<K, V>>;
+pub type FullBucketImm<'table, K, V> = FullBucket<K, V, &'table RawTable<K, V>>;
 
 pub type EmptyBucketMut<'table, K, V> = EmptyBucket<K, V, &'table mut RawTable<K, V>>;
-pub type  FullBucketMut<'table, K, V> =  FullBucket<K, V, &'table mut RawTable<K, V>>;
+pub type FullBucketMut<'table, K, V> = FullBucket<K, V, &'table mut RawTable<K, V>>;
 
 pub enum BucketState<K, V, M> {
     Empty(EmptyBucket<K, V, M>),
@@ -139,14 +143,17 @@ pub struct SafeHash {
 impl SafeHash {
     /// Peek at the hash value, which is guaranteed to be non-zero.
     #[inline(always)]
-    pub fn inspect(&self) -> u64 { self.hash }
+    pub fn inspect(&self) -> u64 {
+        self.hash
+    }
 }
 
 /// We need to remove hashes of 0. That's reserved for empty buckets.
 /// This function wraps up `hash_keyed` to be the only way outside this
 /// module to generate a SafeHash.
 pub fn make_hash<T: ?Sized, S>(hash_state: &S, t: &T) -> SafeHash
-    where T: Hash, S: BuildHasher
+    where T: Hash,
+          S: BuildHasher
 {
     let mut state = hash_state.build_hasher();
     t.hash(&mut state);
@@ -175,8 +182,8 @@ impl<K, V> RawBucket<K, V> {
     unsafe fn offset(self, count: isize) -> RawBucket<K, V> {
         RawBucket {
             hash: self.hash.offset(count),
-            key:  self.key.offset(count),
-            val:  self.val.offset(count),
+            key: self.key.offset(count),
+            val: self.val.offset(count),
             _marker: marker::PhantomData,
         }
     }
@@ -212,7 +219,9 @@ pub fn index(&self) -> usize {
     }
 }
 
-impl<K, V, M> Deref for FullBucket<K, V, M> where M: Deref<Target=RawTable<K, V>> {
+impl<K, V, M> Deref for FullBucket<K, V, M>
+    where M: Deref<Target = RawTable<K, V>>
+{
     type Target = RawTable<K, V>;
     fn deref(&self) -> &RawTable<K, V> {
         &self.table
@@ -232,19 +241,23 @@ unsafe fn borrow_table_mut(&mut self) -> &mut RawTable<K, V> {
     }
 }
 
-impl<K, V, M> Put<K, V> for Bucket<K, V, M> where M: Put<K, V> {
+impl<K, V, M> Put<K, V> for Bucket<K, V, M>
+    where M: Put<K, V>
+{
     unsafe fn borrow_table_mut(&mut self) -> &mut RawTable<K, V> {
         self.table.borrow_table_mut()
     }
 }
 
-impl<K, V, M> Put<K, V> for FullBucket<K, V, M> where M: Put<K, V> {
+impl<K, V, M> Put<K, V> for FullBucket<K, V, M>
+    where M: Put<K, V>
+{
     unsafe fn borrow_table_mut(&mut self) -> &mut RawTable<K, V> {
         self.table.borrow_table_mut()
     }
 }
 
-impl<K, V, M: Deref<Target=RawTable<K, V>>> Bucket<K, V, M> {
+impl<K, V, M: Deref<Target = RawTable<K, V>>> Bucket<K, V, M> {
     pub fn new(table: M, hash: SafeHash) -> Bucket<K, V, M> {
         Bucket::at_index(table, hash.inspect() as usize)
     }
@@ -252,14 +265,13 @@ pub fn new(table: M, hash: SafeHash) -> Bucket<K, V, M> {
     pub fn at_index(table: M, ib_index: usize) -> Bucket<K, V, M> {
         // if capacity is 0, then the RawBucket will be populated with bogus pointers.
         // This is an uncommon case though, so avoid it in release builds.
-        debug_assert!(table.capacity() > 0, "Table should have capacity at this point");
+        debug_assert!(table.capacity() > 0,
+                      "Table should have capacity at this point");
         let ib_index = ib_index & (table.capacity() - 1);
         Bucket {
-            raw: unsafe {
-               table.first_bucket_raw().offset(ib_index as isize)
-            },
+            raw: unsafe { table.first_bucket_raw().offset(ib_index as isize) },
             idx: ib_index,
-            table: table
+            table: table,
         }
     }
 
@@ -267,7 +279,7 @@ pub fn first(table: M) -> Bucket<K, V, M> {
         Bucket {
             raw: table.first_bucket_raw(),
             idx: 0,
-            table: table
+            table: table,
         }
     }
 
@@ -277,18 +289,20 @@ pub fn first(table: M) -> Bucket<K, V, M> {
     /// this module.
     pub fn peek(self) -> BucketState<K, V, M> {
         match unsafe { *self.raw.hash } {
-            EMPTY_BUCKET =>
+            EMPTY_BUCKET => {
                 Empty(EmptyBucket {
                     raw: self.raw,
                     idx: self.idx,
-                    table: self.table
-                }),
-            _ =>
+                    table: self.table,
+                })
+            }
+            _ => {
                 Full(FullBucket {
                     raw: self.raw,
                     idx: self.idx,
-                    table: self.table
+                    table: self.table,
                 })
+            }
         }
     }
 
@@ -308,7 +322,7 @@ pub fn next(&mut self) {
     }
 }
 
-impl<K, V, M: Deref<Target=RawTable<K, V>>> EmptyBucket<K, V, M> {
+impl<K, V, M: Deref<Target = RawTable<K, V>>> EmptyBucket<K, V, M> {
     #[inline]
     pub fn next(self) -> Bucket<K, V, M> {
         let mut bucket = self.into_bucket();
@@ -321,7 +335,7 @@ pub fn into_bucket(self) -> Bucket<K, V, M> {
         Bucket {
             raw: self.raw,
             idx: self.idx,
-            table: self.table
+            table: self.table,
         }
     }
 
@@ -329,22 +343,24 @@ pub fn gap_peek(self) -> Option<GapThenFull<K, V, M>> {
         let gap = EmptyBucket {
             raw: self.raw,
             idx: self.idx,
-            table: ()
+            table: (),
         };
 
         match self.next().peek() {
             Full(bucket) => {
                 Some(GapThenFull {
                     gap: gap,
-                    full: bucket
+                    full: bucket,
                 })
             }
-            Empty(..) => None
+            Empty(..) => None,
         }
     }
 }
 
-impl<K, V, M> EmptyBucket<K, V, M> where M: Put<K, V> {
+impl<K, V, M> EmptyBucket<K, V, M>
+    where M: Put<K, V>
+{
     /// Puts given key and value pair, along with the key's hash,
     /// into this bucket in the hashtable. Note how `self` is 'moved' into
     /// this function, because this slot will no longer be empty when
@@ -352,8 +368,7 @@ impl<K, V, M> EmptyBucket<K, V, M> where M: Put<K, V> {
     /// the newly-filled slot in the hashtable.
     ///
     /// Use `make_hash` to construct a `SafeHash` to pass to this function.
-    pub fn put(mut self, hash: SafeHash, key: K, value: V)
-               -> FullBucket<K, V, M> {
+    pub fn put(mut self, hash: SafeHash, key: K, value: V) -> FullBucket<K, V, M> {
         unsafe {
             *self.raw.hash = hash.inspect();
             ptr::write(self.raw.key as *mut K, key);
@@ -362,11 +377,15 @@ pub fn put(mut self, hash: SafeHash, key: K, value: V)
             self.table.borrow_table_mut().size += 1;
         }
 
-        FullBucket { raw: self.raw, idx: self.idx, table: self.table }
+        FullBucket {
+            raw: self.raw,
+            idx: self.idx,
+            table: self.table,
+        }
     }
 }
 
-impl<K, V, M: Deref<Target=RawTable<K, V>>> FullBucket<K, V, M> {
+impl<K, V, M: Deref<Target = RawTable<K, V>>> FullBucket<K, V, M> {
     #[inline]
     pub fn next(self) -> Bucket<K, V, M> {
         let mut bucket = self.into_bucket();
@@ -379,7 +398,7 @@ pub fn into_bucket(self) -> Bucket<K, V, M> {
         Bucket {
             raw: self.raw,
             idx: self.idx,
-            table: self.table
+            table: self.table,
         }
     }
 
@@ -407,19 +426,12 @@ pub fn displacement(&self) -> usize {
 
     #[inline]
     pub fn hash(&self) -> SafeHash {
-        unsafe {
-            SafeHash {
-                hash: *self.raw.hash
-            }
-        }
+        unsafe { SafeHash { hash: *self.raw.hash } }
     }
 
     /// Gets references to the key and value at a given index.
     pub fn read(&self) -> (&K, &V) {
-        unsafe {
-            (&*self.raw.key,
-             &*self.raw.val)
-        }
+        unsafe { (&*self.raw.key, &*self.raw.val) }
     }
 }
 
@@ -436,69 +448,68 @@ pub fn take(mut self) -> (EmptyBucket<K, V, &'t mut RawTable<K, V>>, K, V) {
 
         unsafe {
             *self.raw.hash = EMPTY_BUCKET;
-            (
-                EmptyBucket {
-                    raw: self.raw,
-                    idx: self.idx,
-                    table: self.table
-                },
-                ptr::read(self.raw.key),
-                ptr::read(self.raw.val)
-            )
+            (EmptyBucket {
+                raw: self.raw,
+                idx: self.idx,
+                table: self.table,
+            },
+             ptr::read(self.raw.key),
+             ptr::read(self.raw.val))
         }
     }
 }
 
 // This use of `Put` is misleading and restrictive, but safe and sufficient for our use cases
 // where `M` is a full bucket or table reference type with mutable access to the table.
-impl<K, V, M> FullBucket<K, V, M> where M: Put<K, V> {
+impl<K, V, M> FullBucket<K, V, M>
+    where M: Put<K, V>
+{
     pub fn replace(&mut self, h: SafeHash, k: K, v: V) -> (SafeHash, K, V) {
         unsafe {
             let old_hash = ptr::replace(self.raw.hash as *mut SafeHash, h);
-            let old_key  = ptr::replace(self.raw.key as *mut K,  k);
-            let old_val  = ptr::replace(self.raw.val as *mut V,  v);
+            let old_key = ptr::replace(self.raw.key as *mut K, k);
+            let old_val = ptr::replace(self.raw.val as *mut V, v);
 
             (old_hash, old_key, old_val)
         }
     }
 }
 
-impl<K, V, M> FullBucket<K, V, M> where M: Deref<Target=RawTable<K, V>> + DerefMut {
+impl<K, V, M> FullBucket<K, V, M>
+    where M: Deref<Target = RawTable<K, V>> + DerefMut
+{
     /// Gets mutable references to the key and value at a given index.
     pub fn read_mut(&mut self) -> (&mut K, &mut V) {
-        unsafe {
-            (&mut *(self.raw.key as *mut K),
-             &mut *(self.raw.val as *mut V))
-        }
+        unsafe { (&mut *(self.raw.key as *mut K), &mut *(self.raw.val as *mut V)) }
     }
 }
 
-impl<'t, K, V, M> FullBucket<K, V, M> where M: Deref<Target=RawTable<K, V>> + 't {
+impl<'t, K, V, M> FullBucket<K, V, M>
+    where M: Deref<Target = RawTable<K, V>> + 't
+{
     /// Exchange a bucket state for immutable references into the table.
     /// Because the underlying reference to the table is also consumed,
     /// no further changes to the structure of the table are possible;
     /// in exchange for this, the returned references have a longer lifetime
     /// than the references returned by `read()`.
     pub fn into_refs(self) -> (&'t K, &'t V) {
-        unsafe {
-            (&*self.raw.key,
-             &*self.raw.val)
-        }
+        unsafe { (&*self.raw.key, &*self.raw.val) }
     }
 }
 
-impl<'t, K, V, M> FullBucket<K, V, M> where M: Deref<Target=RawTable<K, V>> + DerefMut + 't {
+impl<'t, K, V, M> FullBucket<K, V, M>
+    where M: Deref<Target = RawTable<K, V>> + DerefMut + 't
+{
     /// This works similarly to `into_refs`, exchanging a bucket state
     /// for mutable references into the table.
     pub fn into_mut_refs(self) -> (&'t mut K, &'t mut V) {
-        unsafe {
-            (&mut *(self.raw.key as *mut K),
-             &mut *(self.raw.val as *mut V))
-        }
+        unsafe { (&mut *(self.raw.key as *mut K), &mut *(self.raw.val as *mut V)) }
     }
 }
 
-impl<K, V, M> GapThenFull<K, V, M> where M: Deref<Target=RawTable<K, V>> {
+impl<K, V, M> GapThenFull<K, V, M>
+    where M: Deref<Target = RawTable<K, V>>
+{
     #[inline]
     pub fn full(&self) -> &FullBucket<K, V, M> {
         &self.full
@@ -522,7 +533,7 @@ pub fn shift(mut self) -> Option<GapThenFull<K, V, M>> {
 
                 Some(self)
             }
-            Empty(..) => None
+            Empty(..) => None,
         }
     }
 }
@@ -554,7 +565,8 @@ fn test_rounding() {
 // from the start of a mallocated array.
 #[inline]
 fn calculate_offsets(hashes_size: usize,
-                     keys_size: usize, keys_align: usize,
+                     keys_size: usize,
+                     keys_align: usize,
                      vals_align: usize)
                      -> (usize, usize, bool) {
     let keys_offset = round_up_to_next(hashes_size, keys_align);
@@ -567,14 +579,15 @@ fn calculate_offsets(hashes_size: usize,
 
 // Returns a tuple of (minimum required malloc alignment, hash_offset,
 // array_size), from the start of a mallocated array.
-fn calculate_allocation(hash_size: usize, hash_align: usize,
-                        keys_size: usize, keys_align: usize,
-                        vals_size: usize, vals_align: usize)
+fn calculate_allocation(hash_size: usize,
+                        hash_align: usize,
+                        keys_size: usize,
+                        keys_align: usize,
+                        vals_size: usize,
+                        vals_align: usize)
                         -> (usize, usize, usize, bool) {
     let hash_offset = 0;
-    let (_, vals_offset, oflo) = calculate_offsets(hash_size,
-                                                   keys_size, keys_align,
-                                                              vals_align);
+    let (_, vals_offset, oflo) = calculate_offsets(hash_size, keys_size, keys_align, vals_align);
     let (end_of_vals, oflo2) = vals_offset.overflowing_add(vals_size);
 
     let align = cmp::max(hash_align, cmp::max(keys_align, vals_align));
@@ -584,12 +597,13 @@ fn calculate_allocation(hash_size: usize, hash_align: usize,
 
 #[test]
 fn test_offset_calculation() {
-    assert_eq!(calculate_allocation(128, 8, 15, 1, 4,  4), (8, 0, 148, false));
-    assert_eq!(calculate_allocation(3,   1, 2,  1, 1,  1), (1, 0, 6, false));
-    assert_eq!(calculate_allocation(6,   2, 12, 4, 24, 8), (8, 0, 48, false));
+    assert_eq!(calculate_allocation(128, 8, 15, 1, 4, 4),
+               (8, 0, 148, false));
+    assert_eq!(calculate_allocation(3, 1, 2, 1, 1, 1), (1, 0, 6, false));
+    assert_eq!(calculate_allocation(6, 2, 12, 4, 24, 8), (8, 0, 48, false));
     assert_eq!(calculate_offsets(128, 15, 1, 4), (128, 144, false));
-    assert_eq!(calculate_offsets(3,   2,  1, 1), (3,   5, false));
-    assert_eq!(calculate_offsets(6,   12, 4, 8), (8,   24, false));
+    assert_eq!(calculate_offsets(3, 2, 1, 1), (3, 5, false));
+    assert_eq!(calculate_offsets(6, 12, 4, 8), (8, 24, false));
 }
 
 impl<K, V> RawTable<K, V> {
@@ -608,8 +622,8 @@ unsafe fn new_uninitialized(capacity: usize) -> RawTable<K, V> {
         // No need for `checked_mul` before a more restrictive check performed
         // later in this method.
         let hashes_size = capacity * size_of::<u64>();
-        let keys_size   = capacity * size_of::< K >();
-        let vals_size   = capacity * size_of::< V >();
+        let keys_size = capacity * size_of::<K>();
+        let vals_size = capacity * size_of::<V>();
 
         // Allocating hashmaps is a little tricky. We need to allocate three
         // arrays, but since we know their sizes and alignments up front,
@@ -619,31 +633,38 @@ unsafe fn new_uninitialized(capacity: usize) -> RawTable<K, V> {
         // This is great in theory, but in practice getting the alignment
         // right is a little subtle. Therefore, calculating offsets has been
         // factored out into a different function.
-        let (malloc_alignment, hash_offset, size, oflo) =
-            calculate_allocation(
-                hashes_size, align_of::<u64>(),
-                keys_size,   align_of::< K >(),
-                vals_size,   align_of::< V >());
+        let (malloc_alignment, hash_offset, size, oflo) = calculate_allocation(hashes_size,
+                                                                               align_of::<u64>(),
+                                                                               keys_size,
+                                                                               align_of::<K>(),
+                                                                               vals_size,
+                                                                               align_of::<V>());
 
         assert!(!oflo, "capacity overflow");
 
         // One check for overflow that covers calculation and rounding of size.
-        let size_of_bucket = size_of::<u64>().checked_add(size_of::<K>()).unwrap()
-                                             .checked_add(size_of::<V>()).unwrap();
-        assert!(size >= capacity.checked_mul(size_of_bucket)
-                                .expect("capacity overflow"),
+        let size_of_bucket = size_of::<u64>()
+                                 .checked_add(size_of::<K>())
+                                 .unwrap()
+                                 .checked_add(size_of::<V>())
+                                 .unwrap();
+        assert!(size >=
+                capacity.checked_mul(size_of_bucket)
+                        .expect("capacity overflow"),
                 "capacity overflow");
 
         let buffer = allocate(size, malloc_alignment);
-        if buffer.is_null() { ::alloc::oom() }
+        if buffer.is_null() {
+            ::alloc::oom()
+        }
 
         let hashes = buffer.offset(hash_offset as isize) as *mut u64;
 
         RawTable {
             capacity: capacity,
-            size:     0,
-            hashes:   Unique::new(hashes),
-            marker:   marker::PhantomData,
+            size: 0,
+            hashes: Unique::new(hashes),
+            marker: marker::PhantomData,
         }
     }
 
@@ -652,16 +673,16 @@ fn first_bucket_raw(&self) -> RawBucket<K, V> {
         let keys_size = self.capacity * size_of::<K>();
 
         let buffer = *self.hashes as *const u8;
-        let (keys_offset, vals_offset, oflo) =
-            calculate_offsets(hashes_size,
-                              keys_size, align_of::<K>(),
-                              align_of::<V>());
+        let (keys_offset, vals_offset, oflo) = calculate_offsets(hashes_size,
+                                                                 keys_size,
+                                                                 align_of::<K>(),
+                                                                 align_of::<V>());
         debug_assert!(!oflo, "capacity overflow");
         unsafe {
             RawBucket {
                 hash: *self.hashes,
-                key:  buffer.offset(keys_offset as isize) as *const K,
-                val:  buffer.offset(vals_offset as isize) as *const V,
+                key: buffer.offset(keys_offset as isize) as *const K,
+                val: buffer.offset(vals_offset as isize) as *const V,
                 _marker: marker::PhantomData,
             }
         }
@@ -691,9 +712,7 @@ pub fn size(&self) -> usize {
     fn raw_buckets(&self) -> RawBuckets<K, V> {
         RawBuckets {
             raw: self.first_bucket_raw(),
-            hashes_end: unsafe {
-                self.hashes.offset(self.capacity as isize)
-            },
+            hashes_end: unsafe { self.hashes.offset(self.capacity as isize) },
             marker: marker::PhantomData,
         }
     }
@@ -747,7 +766,7 @@ unsafe fn rev_move_buckets(&mut self) -> RevMoveBuckets<K, V> {
             raw: raw_bucket.offset(self.capacity as isize),
             hashes_end: raw_bucket.hash,
             elems_left: self.size,
-            marker:     marker::PhantomData,
+            marker: marker::PhantomData,
         }
     }
 }
@@ -827,10 +846,7 @@ fn next(&mut self) -> Option<(K, V)> {
 
                 if *self.raw.hash != EMPTY_BUCKET {
                     self.elems_left -= 1;
-                    return Some((
-                        ptr::read(self.raw.key),
-                        ptr::read(self.raw.val)
-                    ));
+                    return Some((ptr::read(self.raw.key), ptr::read(self.raw.val)));
                 }
             }
         }
@@ -851,7 +867,7 @@ impl<'a, K, V> Clone for Iter<'a, K, V> {
     fn clone(&self) -> Iter<'a, K, V> {
         Iter {
             iter: self.iter.clone(),
-            elems_left: self.elems_left
+            elems_left: self.elems_left,
         }
     }
 }
@@ -873,7 +889,7 @@ unsafe impl<'a, K: Send, V: Send> Send for IterMut<'a, K, V> {}
 /// Iterator over the entries in a table, consuming the table.
 pub struct IntoIter<K, V> {
     table: RawTable<K, V>,
-    iter: RawBuckets<'static, K, V>
+    iter: RawBuckets<'static, K, V>,
 }
 
 unsafe impl<K: Sync, V: Sync> Sync for IntoIter<K, V> {}
@@ -894,10 +910,7 @@ impl<'a, K, V> Iterator for Iter<'a, K, V> {
     fn next(&mut self) -> Option<(&'a K, &'a V)> {
         self.iter.next().map(|bucket| {
             self.elems_left -= 1;
-            unsafe {
-                (&*bucket.key,
-                 &*bucket.val)
-            }
+            unsafe { (&*bucket.key, &*bucket.val) }
         })
     }
 
@@ -906,7 +919,9 @@ fn size_hint(&self) -> (usize, Option<usize>) {
     }
 }
 impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> {
-    fn len(&self) -> usize { self.elems_left }
+    fn len(&self) -> usize {
+        self.elems_left
+    }
 }
 
 impl<'a, K, V> Iterator for IterMut<'a, K, V> {
@@ -915,10 +930,7 @@ impl<'a, K, V> Iterator for IterMut<'a, K, V> {
     fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
         self.iter.next().map(|bucket| {
             self.elems_left -= 1;
-            unsafe {
-                (&*bucket.key,
-                 &mut *(bucket.val as *mut V))
-            }
+            unsafe { (&*bucket.key, &mut *(bucket.val as *mut V)) }
         })
     }
 
@@ -927,7 +939,9 @@ fn size_hint(&self) -> (usize, Option<usize>) {
     }
 }
 impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> {
-    fn len(&self) -> usize { self.elems_left }
+    fn len(&self) -> usize {
+        self.elems_left
+    }
 }
 
 impl<K, V> Iterator for IntoIter<K, V> {
@@ -937,13 +951,7 @@ fn next(&mut self) -> Option<(SafeHash, K, V)> {
         self.iter.next().map(|bucket| {
             self.table.size -= 1;
             unsafe {
-                (
-                    SafeHash {
-                        hash: *bucket.hash,
-                    },
-                    ptr::read(bucket.key),
-                    ptr::read(bucket.val)
-                )
+                (SafeHash { hash: *bucket.hash }, ptr::read(bucket.key), ptr::read(bucket.val))
             }
         })
     }
@@ -954,7 +962,9 @@ fn size_hint(&self) -> (usize, Option<usize>) {
     }
 }
 impl<K, V> ExactSizeIterator for IntoIter<K, V> {
-    fn len(&self) -> usize { self.table.size() }
+    fn len(&self) -> usize {
+        self.table.size()
+    }
 }
 
 impl<'a, K, V> Iterator for Drain<'a, K, V> {
@@ -965,13 +975,9 @@ fn next(&mut self) -> Option<(SafeHash, K, V)> {
         self.iter.next().map(|bucket| {
             self.table.size -= 1;
             unsafe {
-                (
-                    SafeHash {
-                        hash: ptr::replace(bucket.hash, EMPTY_BUCKET),
-                    },
-                    ptr::read(bucket.key),
-                    ptr::read(bucket.val)
-                )
+                (SafeHash { hash: ptr::replace(bucket.hash, EMPTY_BUCKET) },
+                 ptr::read(bucket.key),
+                 ptr::read(bucket.val))
             }
         })
     }
@@ -982,7 +988,9 @@ fn size_hint(&self) -> (usize, Option<usize>) {
     }
 }
 impl<'a, K, V> ExactSizeIterator for Drain<'a, K, V> {
-    fn len(&self) -> usize { self.table.size() }
+    fn len(&self) -> usize {
+        self.table.size()
+    }
 }
 
 impl<'a, K: 'a, V: 'a> Drop for Drain<'a, K, V> {
@@ -1040,7 +1048,8 @@ fn drop(&mut self) {
         // dropping empty tables such as on resize.
         // Also avoid double drop of elements that have been already moved out.
         unsafe {
-            if needs_drop::<(K, V)>() { // avoid linear runtime for types that don't need drop
+            if needs_drop::<(K, V)>() {
+                // avoid linear runtime for types that don't need drop
                 for _ in self.rev_move_buckets() {}
             }
         }
@@ -1048,10 +1057,12 @@ fn drop(&mut self) {
         let hashes_size = self.capacity * size_of::<u64>();
         let keys_size = self.capacity * size_of::<K>();
         let vals_size = self.capacity * size_of::<V>();
-        let (align, _, size, oflo) =
-            calculate_allocation(hashes_size, align_of::<u64>(),
-                                 keys_size, align_of::<K>(),
-                                 vals_size, align_of::<V>());
+        let (align, _, size, oflo) = calculate_allocation(hashes_size,
+                                                          align_of::<u64>(),
+                                                          keys_size,
+                                                          align_of::<K>(),
+                                                          vals_size,
+                                                          align_of::<V>());
 
         debug_assert!(!oflo, "should be impossible");
 
index 0180c3118a586f41c813e65b5ddfa207e3b945f6..668fa1fb303601cefa74c819c7a9d2cf974fb5f0 100644 (file)
@@ -512,7 +512,7 @@ pub fn create(&mut self, create: bool) -> &mut OpenOptions {
     /// No file is allowed to exist at the target location, also no (dangling)
     /// symlink.
     ///
-    /// This option is useful because it as atomic. Otherwise between checking
+    /// This option is useful because it is atomic. Otherwise between checking
     /// whether a file exists and creating a new one, the file may have been
     /// created by another process (a TOCTOU race condition / attack).
     ///
@@ -1770,6 +1770,15 @@ fn file_test_directoryinfo_readdir() {
         check!(fs::remove_dir(dir));
     }
 
+    #[test]
+    fn file_create_new_already_exists_error() {
+        let tmpdir = tmpdir();
+        let file = &tmpdir.join("file_create_new_error_exists");
+        check!(fs::File::create(file));
+        let e = fs::OpenOptions::new().write(true).create_new(true).open(file).unwrap_err();
+        assert_eq!(e.kind(), ErrorKind::AlreadyExists);
+    }
+
     #[test]
     fn mkdir_path_already_exists_error() {
         let tmpdir = tmpdir();
index ba485f819f880c70eefd73c7902fa7cbe6268256..57d75441bff3dd50991b0192d8eb2ce8c36d76b9 100644 (file)
@@ -82,14 +82,15 @@ pub fn new(a: u8, b: u8, c: u8, d: u8) -> Ipv4Addr {
         [(bits >> 24) as u8, (bits >> 16) as u8, (bits >> 8) as u8, bits as u8]
     }
 
-    /// Returns true for the special 'unspecified' address 0.0.0.0.
+    /// Returns true for the special 'unspecified' address (0.0.0.0).
     pub fn is_unspecified(&self) -> bool {
         self.inner.s_addr == 0
     }
 
     /// Returns true if this is a loopback address (127.0.0.0/8).
     ///
-    /// This property is defined by RFC 6890.
+    /// This property is defined by [RFC 1122].
+    /// [RFC 1122]: https://tools.ietf.org/html/rfc1122
     #[stable(since = "1.7.0", feature = "ip_17")]
     pub fn is_loopback(&self) -> bool {
         self.octets()[0] == 127
@@ -97,7 +98,8 @@ pub fn is_loopback(&self) -> bool {
 
     /// Returns true if this is a private address.
     ///
-    /// The private address ranges are defined in RFC 1918 and include:
+    /// The private address ranges are defined in [RFC 1918] and include:
+    /// [RFC 1918]: https://tools.ietf.org/html/rfc1918
     ///
     ///  - 10.0.0.0/8
     ///  - 172.16.0.0/12
@@ -114,7 +116,8 @@ pub fn is_private(&self) -> bool {
 
     /// Returns true if the address is link-local (169.254.0.0/16).
     ///
-    /// This property is defined by RFC 6890.
+    /// This property is defined by [RFC 3927].
+    /// [RFC 3927]: https://tools.ietf.org/html/rfc3927
     #[stable(since = "1.7.0", feature = "ip_17")]
     pub fn is_link_local(&self) -> bool {
         self.octets()[0] == 169 && self.octets()[1] == 254
@@ -137,18 +140,20 @@ pub fn is_global(&self) -> bool {
         !self.is_broadcast() && !self.is_documentation() && !self.is_unspecified()
     }
 
-    /// Returns true if this is a multicast address.
+    /// Returns true if this is a multicast address (224.0.0.0/4).
     ///
     /// Multicast addresses have a most significant octet between 224 and 239,
-    /// and is defined by RFC 5771.
+    /// and is defined by [RFC 5771].
+    /// [RFC 5771]: https://tools.ietf.org/html/rfc5771
     #[stable(since = "1.7.0", feature = "ip_17")]
     pub fn is_multicast(&self) -> bool {
         self.octets()[0] >= 224 && self.octets()[0] <= 239
     }
 
-    /// Returns true if this is a broadcast address.
+    /// Returns true if this is a broadcast address (255.255.255.255).
     ///
-    /// A broadcast address has all octets set to 255 as defined in RFC 919.
+    /// A broadcast address has all octets set to 255 as defined in [RFC 919].
+    /// [RFC 919]: https://tools.ietf.org/html/rfc919
     #[stable(since = "1.7.0", feature = "ip_17")]
     pub fn is_broadcast(&self) -> bool {
         self.octets()[0] == 255 && self.octets()[1] == 255 &&
@@ -157,7 +162,8 @@ pub fn is_broadcast(&self) -> bool {
 
     /// Returns true if this address is in a range designated for documentation.
     ///
-    /// This is defined in RFC 5737:
+    /// This is defined in [RFC 5737]:
+    /// [RFC 5737]: https://tools.ietf.org/html/rfc5737
     ///
     /// - 192.0.2.0/24 (TEST-NET-1)
     /// - 198.51.100.0/24 (TEST-NET-2)
@@ -321,9 +327,10 @@ pub fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16,
         ]
     }
 
-    /// Returns true for the special 'unspecified' address ::.
+    /// Returns true for the special 'unspecified' address (::).
     ///
-    /// This property is defined in RFC 6890.
+    /// This property is defined in [RFC 4291].
+    /// [RFC 4291]: https://tools.ietf.org/html/rfc4291
     #[stable(since = "1.7.0", feature = "ip_17")]
     pub fn is_unspecified(&self) -> bool {
         self.segments() == [0, 0, 0, 0, 0, 0, 0, 0]
@@ -331,7 +338,8 @@ pub fn is_unspecified(&self) -> bool {
 
     /// Returns true if this is a loopback address (::1).
     ///
-    /// This property is defined in RFC 6890.
+    /// This property is defined in [RFC 4291].
+    /// [RFC 4291]: https://tools.ietf.org/html/rfc4291
     #[stable(since = "1.7.0", feature = "ip_17")]
     pub fn is_loopback(&self) -> bool {
         self.segments() == [0, 0, 0, 0, 0, 0, 0, 1]
@@ -352,26 +360,33 @@ pub fn is_global(&self) -> bool {
         }
     }
 
-    /// Returns true if this is a unique local address (IPv6).
+    /// Returns true if this is a unique local address (fc00::/7).
     ///
-    /// Unique local addresses are defined in RFC 4193 and have the form fc00::/7.
+    /// This property is defined in [RFC 4193].
+    /// [RFC 4193]: https://tools.ietf.org/html/rfc4193
     pub fn is_unique_local(&self) -> bool {
         (self.segments()[0] & 0xfe00) == 0xfc00
     }
 
     /// Returns true if the address is unicast and link-local (fe80::/10).
+    ///
+    /// This property is defined in [RFC 4291].
+    /// [RFC 4291]: https://tools.ietf.org/html/rfc4291
     pub fn is_unicast_link_local(&self) -> bool {
         (self.segments()[0] & 0xffc0) == 0xfe80
     }
 
-    /// Returns true if this is a deprecated unicast site-local address (IPv6
-    /// fec0::/10).
+    /// Returns true if this is a deprecated unicast site-local address
+    /// (fec0::/10).
     pub fn is_unicast_site_local(&self) -> bool {
         (self.segments()[0] & 0xffc0) == 0xfec0
     }
 
     /// Returns true if this is an address reserved for documentation
-    /// This is defined to be 2001:db8::/32 in RFC 3849.
+    /// (2001:db8::/32).
+    ///
+    /// This property is defined in [RFC 3849].
+    /// [RFC 3849]: https://tools.ietf.org/html/rfc3849
     pub fn is_documentation(&self) -> bool {
         (self.segments()[0] == 0x2001) && (self.segments()[1] == 0xdb8)
     }
@@ -411,10 +426,10 @@ pub fn multicast_scope(&self) -> Option<Ipv6MulticastScope> {
         }
     }
 
-    /// Returns true if this is a multicast address.
+    /// Returns true if this is a multicast address (ff00::/8).
     ///
-    /// Multicast addresses have the form ff00::/8, and this property is defined
-    /// by RFC 3956.
+    /// This property is defined by [RFC 4291].
+    /// [RFC 4291]: https://tools.ietf.org/html/rfc4291
     #[stable(since = "1.7.0", feature = "ip_17")]
     pub fn is_multicast(&self) -> bool {
         (self.segments()[0] & 0xff00) == 0xff00
index 3ce9bcc79f24ad8dfdedceb315286d0deba49188..96ddda32ae456f33ba3ba8eae1fabd0e047445b8 100644 (file)
@@ -182,8 +182,10 @@ fn from_inner(pipe: AnonPipe) -> ChildStderr {
     }
 }
 
-/// The `Command` type acts as a process builder, providing fine-grained control
-/// over how a new process should be spawned. A default configuration can be
+/// A process builder, providing fine-grained control
+/// over how a new process should be spawned.
+///
+/// A default configuration can be
 /// generated using `Command::new(program)`, where `program` gives a path to the
 /// program to be executed. Additional builder methods allow the configuration
 /// to be changed (for example, by adding arguments) prior to spawning:
index 2acf6485eb3dad6bf9252a609020ede0945706fb..ce563dc7b16d3e4fe31c3b6ab343bd82dfc0d484 100644 (file)
@@ -181,6 +181,7 @@ fn clone(&self) -> Self { *self }
 pub const ERROR_INVALID_HANDLE: DWORD = 6;
 pub const ERROR_NO_MORE_FILES: DWORD = 18;
 pub const ERROR_HANDLE_EOF: DWORD = 38;
+pub const ERROR_FILE_EXISTS: DWORD = 80;
 pub const ERROR_BROKEN_PIPE: DWORD = 109;
 pub const ERROR_CALL_NOT_IMPLEMENTED: DWORD = 120;
 pub const ERROR_INSUFFICIENT_BUFFER: DWORD = 122;
index 384940e4dc446edbe0f0101378000b60a431727b..6dd4f4c3e750e8b2df17d3e5941c9f97bce901f7 100644 (file)
@@ -68,6 +68,7 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind {
     match errno as c::DWORD {
         c::ERROR_ACCESS_DENIED => return ErrorKind::PermissionDenied,
         c::ERROR_ALREADY_EXISTS => return ErrorKind::AlreadyExists,
+        c::ERROR_FILE_EXISTS => return ErrorKind::AlreadyExists,
         c::ERROR_BROKEN_PIPE => return ErrorKind::BrokenPipe,
         c::ERROR_FILE_NOT_FOUND => return ErrorKind::NotFound,
         c::ERROR_PATH_NOT_FOUND => return ErrorKind::NotFound,
index 40c98206c16e9f9e0cc0fe95f76e5841133160c6..8537fcc221c956bc7b34ef425710515b04bc4e4c 100644 (file)
@@ -60,10 +60,6 @@ impl Name {
     pub fn as_str(self) -> token::InternedString {
         token::InternedString::new_from_name(self)
     }
-
-    pub fn unhygienize(self) -> Name {
-        token::intern(&self.as_str())
-    }
 }
 
 impl fmt::Debug for Name {
index 207289de34707d81a765c8628b642f90b8934738..efd92ab3240267a33d3dcf00b0cc1f73c94a6c55 100644 (file)
 use fold::Folder;
 use {ast, fold, attr};
 use codemap::{Spanned, respan};
+use parse::token;
 use ptr::P;
 
 use util::small_vector::SmallVector;
 
-pub trait CfgFolder: fold::Folder {
-    // Check if a node with the given attributes is in this configuration.
-    fn in_cfg(&mut self, attrs: &[ast::Attribute]) -> bool;
-
-    // Update a node before checking if it is in this configuration (used to implement `cfg_attr`).
-    fn process_attrs<T: HasAttrs>(&mut self, node: T) -> T { node }
-
-    // Visit attributes on expression and statements (but not attributes on items in blocks).
-    fn visit_stmt_or_expr_attrs(&mut self, _attrs: &[ast::Attribute]) {}
-
-    // Visit unremovable (non-optional) expressions -- c.f. `fold_expr` vs `fold_opt_expr`.
-    fn visit_unremovable_expr(&mut self, _expr: &ast::Expr) {}
-
-    fn configure<T: HasAttrs>(&mut self, node: T) -> Option<T> {
-        let node = self.process_attrs(node);
-        if self.in_cfg(node.attrs()) { Some(node) } else { None }
-    }
-}
-
-/// A folder that strips out items that do not belong in the current
-/// configuration.
+/// A folder that strips out items that do not belong in the current configuration.
 pub struct StripUnconfigured<'a> {
     diag: CfgDiagReal<'a, 'a>,
+    should_test: bool,
     config: &'a ast::CrateConfig,
 }
 
 impl<'a> StripUnconfigured<'a> {
     pub fn new(config: &'a ast::CrateConfig,
+               should_test: bool,
                diagnostic: &'a Handler,
                feature_gated_cfgs: &'a mut Vec<GatedCfgAttr>)
                -> Self {
         StripUnconfigured {
             config: config,
+            should_test: should_test,
             diag: CfgDiagReal { diag: diagnostic, feature_gated_cfgs: feature_gated_cfgs },
         }
     }
 
+    fn configure<T: HasAttrs>(&mut self, node: T) -> Option<T> {
+        let node = self.process_cfg_attrs(node);
+        if self.in_cfg(node.attrs()) { Some(node) } else { None }
+    }
+
+    fn process_cfg_attrs<T: HasAttrs>(&mut self, node: T) -> T {
+        node.map_attrs(|attrs| {
+            attrs.into_iter().filter_map(|attr| self.process_cfg_attr(attr)).collect()
+        })
+    }
+
     fn process_cfg_attr(&mut self, attr: ast::Attribute) -> Option<ast::Attribute> {
         if !attr.check_name("cfg_attr") {
             return Some(attr);
@@ -88,13 +83,15 @@ fn process_cfg_attr(&mut self, attr: ast::Attribute) -> Option<ast::Attribute> {
             None
         }
     }
-}
 
-impl<'a> CfgFolder for StripUnconfigured<'a> {
-    // Determine if an item should be translated in the current crate
-    // configuration based on the item's attributes
+    // Determine if a node with the given attributes should be included in this configuation.
     fn in_cfg(&mut self, attrs: &[ast::Attribute]) -> bool {
         attrs.iter().all(|attr| {
+            // When not compiling with --test we should not compile the #[test] functions
+            if !self.should_test && is_test_or_bench(attr) {
+                return false;
+            }
+
             let mis = match attr.node.value.node {
                 ast::MetaItemKind::List(_, ref mis) if is_cfg(&attr) => mis,
                 _ => return true
@@ -111,12 +108,7 @@ fn in_cfg(&mut self, attrs: &[ast::Attribute]) -> bool {
         })
     }
 
-    fn process_attrs<T: HasAttrs>(&mut self, node: T) -> T {
-        node.map_attrs(|attrs| {
-            attrs.into_iter().filter_map(|attr| self.process_cfg_attr(attr)).collect()
-        })
-    }
-
+    // Visit attributes on expression and statements (but not attributes on items in blocks).
     fn visit_stmt_or_expr_attrs(&mut self, attrs: &[ast::Attribute]) {
         // flag the offending attributes
         for attr in attrs.iter() {
@@ -124,8 +116,9 @@ fn visit_stmt_or_expr_attrs(&mut self, attrs: &[ast::Attribute]) {
         }
     }
 
+    // Visit unremovable (non-optional) expressions -- c.f. `fold_expr` vs `fold_opt_expr`.
     fn visit_unremovable_expr(&mut self, expr: &ast::Expr) {
-        if let Some(attr) = expr.attrs().iter().find(|a| is_cfg(a)) {
+        if let Some(attr) = expr.attrs().iter().find(|a| is_cfg(a) || is_test_or_bench(a)) {
             let msg = "removing an expression is not supported in this position";
             self.diag.diag.span_err(attr.span, msg);
         }
@@ -134,15 +127,15 @@ fn visit_unremovable_expr(&mut self, expr: &ast::Expr) {
 
 // Support conditional compilation by transforming the AST, stripping out
 // any items that do not belong in the current configuration
-pub fn strip_unconfigured_items(diagnostic: &Handler, krate: ast::Crate,
+pub fn strip_unconfigured_items(diagnostic: &Handler, krate: ast::Crate, should_test: bool,
                                 feature_gated_cfgs: &mut Vec<GatedCfgAttr>)
                                 -> ast::Crate
 {
     let config = &krate.config.clone();
-    StripUnconfigured::new(config, diagnostic, feature_gated_cfgs).fold_crate(krate)
+    StripUnconfigured::new(config, should_test, diagnostic, feature_gated_cfgs).fold_crate(krate)
 }
 
-impl<T: CfgFolder> fold::Folder for T {
+impl<'a> fold::Folder for StripUnconfigured<'a> {
     fn fold_foreign_mod(&mut self, foreign_mod: ast::ForeignMod) -> ast::ForeignMod {
         ast::ForeignMod {
             abi: foreign_mod.abi,
@@ -203,7 +196,7 @@ fn fold_expr(&mut self, expr: P<ast::Expr>) -> P<ast::Expr> {
         // NB: This is intentionally not part of the fold_expr() function
         //     in order for fold_opt_expr() to be able to avoid this check
         self.visit_unremovable_expr(&expr);
-        let expr = self.process_attrs(expr);
+        let expr = self.process_cfg_attrs(expr);
         fold_expr(self, expr)
     }
 
@@ -247,9 +240,15 @@ fn fold_trait_item(&mut self, item: ast::TraitItem) -> SmallVector<ast::TraitIte
         self.configure(item).map(|item| fold::noop_fold_trait_item(item, self))
                             .unwrap_or(SmallVector::zero())
     }
+
+    fn fold_interpolated(&mut self, nt: token::Nonterminal) -> token::Nonterminal {
+        // Don't configure interpolated AST (c.f. #34171).
+        // Interpolated AST will get configured once the surrounding tokens are parsed.
+        nt
+    }
 }
 
-fn fold_expr<F: CfgFolder>(folder: &mut F, expr: P<ast::Expr>) -> P<ast::Expr> {
+fn fold_expr(folder: &mut StripUnconfigured, expr: P<ast::Expr>) -> P<ast::Expr> {
     expr.map(|ast::Expr {id, span, node, attrs}| {
         fold::noop_fold_expr(ast::Expr {
             id: id,
@@ -271,6 +270,10 @@ fn is_cfg(attr: &ast::Attribute) -> bool {
     attr.check_name("cfg")
 }
 
+fn is_test_or_bench(attr: &ast::Attribute) -> bool {
+    attr.check_name("test") || attr.check_name("bench")
+}
+
 pub trait CfgDiag {
     fn emit_error<F>(&mut self, f: F) where F: FnMut(&Handler);
     fn flag_gated<F>(&mut self, f: F) where F: FnMut(&mut Vec<GatedCfgAttr>);
index 95624a433730a96d3b931f62edd92334b0b014e2..b5e4dc63e847e575c9cbff8980bcdbe890ef40fc 100644 (file)
@@ -617,22 +617,6 @@ pub fn call_site(&self) -> Span {
     }
     pub fn backtrace(&self) -> ExpnId { self.backtrace }
 
-    /// Original span that caused the current exapnsion to happen.
-    pub fn original_span(&self) -> Span {
-        let mut expn_id = self.backtrace;
-        let mut call_site = None;
-        loop {
-            match self.codemap().with_expn_info(expn_id, |ei| ei.map(|ei| ei.call_site)) {
-                None => break,
-                Some(cs) => {
-                    call_site = Some(cs);
-                    expn_id = cs.expn_id;
-                }
-            }
-        }
-        call_site.expect("missing expansion backtrace")
-    }
-
     /// Returns span for the macro which originally caused the current expansion to happen.
     ///
     /// Stops backtracing at include! boundary.
index 15d192b59b81ea5cb8abce588abaeb4c93818f3d..83ddc79af84747ce9b71c2471aa2d957a3e416b9 100644 (file)
@@ -236,14 +236,8 @@ fn mac_result<'a>(path: &ast::Path, ident: Option<Ident>, tts: Vec<TokenTree>, m
                     },
                 });
 
-                // The span that we pass to the expanders we want to
-                // be the root of the call stack. That's the most
-                // relevant span and it's the actual invocation of
-                // the macro.
-                let mac_span = fld.cx.original_span();
-
                 let marked_tts = mark_tts(&tts[..], mark);
-                Some(expandfun.expand(fld.cx, mac_span, &marked_tts))
+                Some(expandfun.expand(fld.cx, call_site, &marked_tts))
             }
 
             IdentTT(ref expander, tt_span, allow_internal_unstable) => {
@@ -1001,6 +995,7 @@ pub fn new(cx: &'a mut ExtCtxt<'b>) -> MacroExpander<'a, 'b> {
 
     fn strip_unconfigured(&mut self) -> StripUnconfigured {
         StripUnconfigured::new(&self.cx.cfg,
+                               self.cx.ecfg.should_test,
                                &self.cx.parse_sess.span_diagnostic,
                                self.cx.feature_gated_cfgs)
     }
@@ -1106,6 +1101,7 @@ pub struct ExpansionConfig<'feat> {
     pub features: Option<&'feat Features>,
     pub recursion_limit: usize,
     pub trace_mac: bool,
+    pub should_test: bool, // If false, strip `#[test]` nodes
 }
 
 macro_rules! feature_tests {
@@ -1128,6 +1124,7 @@ pub fn default(crate_name: String) -> ExpansionConfig<'static> {
             features: None,
             recursion_limit: 64,
             trace_mac: false,
+            should_test: false,
         }
     }
 
index 22cc20b8f8c44cc5f26cc36fd4824935a3b3f3a5..341b076e7cf30389ddcfed84f1475f101ce7863d 100644 (file)
@@ -5430,18 +5430,15 @@ fn eval_src_mod_from_path(&mut self,
                               name: String,
                               id_sp: Span) -> PResult<'a, (ast::ItemKind, Vec<ast::Attribute> )> {
         let mut included_mod_stack = self.sess.included_mod_stack.borrow_mut();
-        match included_mod_stack.iter().position(|p| *p == path) {
-            Some(i) => {
-                let mut err = String::from("circular modules: ");
-                let len = included_mod_stack.len();
-                for p in &included_mod_stack[i.. len] {
-                    err.push_str(&p.to_string_lossy());
-                    err.push_str(" -> ");
-                }
-                err.push_str(&path.to_string_lossy());
-                return Err(self.span_fatal(id_sp, &err[..]));
-            }
-            None => ()
+        if let Some(i) = included_mod_stack.iter().position(|p| *p == path) {
+            let mut err = String::from("circular modules: ");
+            let len = included_mod_stack.len();
+            for p in &included_mod_stack[i.. len] {
+                err.push_str(&p.to_string_lossy());
+                err.push_str(" -> ");
+            }
+            err.push_str(&path.to_string_lossy());
+            return Err(self.span_fatal(id_sp, &err[..]));
         }
         included_mod_stack.push(path.clone());
         drop(included_mod_stack);
index 5b9ec924de953528e5ea4c0bfd476f2c69e44543..8818acf9aeff0967b0fc10c2c7070cfefa308962 100644 (file)
@@ -2459,12 +2459,9 @@ pub fn print_pat(&mut self, pat: &ast::Pat) -> io::Result<()> {
                     }
                 }
                 self.print_ident(path1.node)?;
-                match *sub {
-                    Some(ref p) => {
-                        word(&mut self.s, "@")?;
-                        self.print_pat(&p)?;
-                    }
-                    None => ()
+                if let Some(ref p) = *sub {
+                    word(&mut self.s, "@")?;
+                    self.print_pat(&p)?;
                 }
             }
             PatKind::TupleStruct(ref path, ref elts, ddpos) => {
@@ -3008,20 +3005,19 @@ pub fn maybe_print_trailing_comment(&mut self, span: codemap::Span,
             Some(cm) => cm,
             _ => return Ok(())
         };
-        match self.next_comment() {
-            Some(ref cmnt) => {
-                if (*cmnt).style != comments::Trailing { return Ok(()) }
-                let span_line = cm.lookup_char_pos(span.hi);
-                let comment_line = cm.lookup_char_pos((*cmnt).pos);
-                let mut next = (*cmnt).pos + BytePos(1);
-                match next_pos { None => (), Some(p) => next = p }
-                if span.hi < (*cmnt).pos && (*cmnt).pos < next &&
-                    span_line.line == comment_line.line {
-                        self.print_comment(cmnt)?;
-                        self.cur_cmnt_and_lit.cur_cmnt += 1;
-                    }
+        if let Some(ref cmnt) = self.next_comment() {
+            if (*cmnt).style != comments::Trailing { return Ok(()) }
+            let span_line = cm.lookup_char_pos(span.hi);
+            let comment_line = cm.lookup_char_pos((*cmnt).pos);
+            let mut next = (*cmnt).pos + BytePos(1);
+            if let Some(p) = next_pos {
+                next = p;
+            }
+            if span.hi < (*cmnt).pos && (*cmnt).pos < next &&
+               span_line.line == comment_line.line {
+                self.print_comment(cmnt)?;
+                self.cur_cmnt_and_lit.cur_cmnt += 1;
             }
-            _ => ()
         }
         Ok(())
     }
index 2ac4aac65debe4ecfcd3f0f2fc9bfde2b7a3cd10..6e29505f00aaddd9de120ca945d9a6948da62ed3 100644 (file)
@@ -81,7 +81,7 @@ pub fn modify_for_testing(sess: &ParseSess,
     if should_test {
         generate_test_harness(sess, reexport_test_harness_main, krate, span_diagnostic)
     } else {
-        strip_test_functions(krate)
+        krate
     }
 }
 
@@ -306,19 +306,6 @@ fn generate_test_harness(sess: &ParseSess,
     return res;
 }
 
-fn strip_test_functions(krate: ast::Crate) -> ast::Crate {
-    // When not compiling with --test we should not compile the
-    // #[test] functions
-    struct StripTests;
-    impl config::CfgFolder for StripTests {
-        fn in_cfg(&mut self, attrs: &[ast::Attribute]) -> bool {
-            !attr::contains_name(attrs, "test") && !attr::contains_name(attrs, "bench")
-        }
-    }
-
-    StripTests.fold_crate(krate)
-}
-
 /// Craft a span that will be ignored by the stability lint's
 /// call to codemap's is_internal check.
 /// The expanded code calls some unstable functions in the test crate.
index 8e20358027b228c2b28bfaa751ac0536d9806608..7295b36af0fe9f983ff452b27c8983bd7e1d52a4 100644 (file)
@@ -47,9 +47,8 @@ pub fn prefill(init: &[T]) -> Interner<T> {
 
     pub fn intern(&self, val: T) -> Name {
         let mut map = self.map.borrow_mut();
-        match (*map).get(&val) {
-            Some(&idx) => return idx,
-            None => (),
+        if let Some(&idx) = (*map).get(&val) {
+            return idx;
         }
 
         let mut vect = self.vect.borrow_mut();
@@ -161,9 +160,8 @@ pub fn prefill(init: &[&str]) -> StrInterner {
 
     pub fn intern(&self, val: &str) -> Name {
         let mut map = self.map.borrow_mut();
-        match map.get(val) {
-            Some(&idx) => return idx,
-            None => (),
+        if let Some(&idx) = map.get(val) {
+            return idx;
         }
 
         let new_idx = Name(self.len() as u32);
index a1d8e056b0257d3a1a0fc80c9694e196b77e487a..07a6317706b84d96b912c9f4fb8eaa4b558f1bb3 100644 (file)
@@ -185,6 +185,9 @@ pub fn walk_mod<'v, V: Visitor<'v>>(visitor: &mut V, module: &'v Mod) {
 }
 
 pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v Local) {
+    for attr in local.attrs.as_attr_slice() {
+        visitor.visit_attribute(attr);
+    }
     visitor.visit_pat(&local.pat);
     walk_list!(visitor, visit_ty, &local.ty);
     walk_list!(visitor, visit_expr, &local.init);
@@ -635,6 +638,9 @@ pub fn walk_mac<'v, V: Visitor<'v>>(_: &mut V, _: &'v Mac) {
 }
 
 pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
+    for attr in expression.attrs.as_attr_slice() {
+        visitor.visit_attribute(attr);
+    }
     match expression.node {
         ExprKind::Box(ref subexpression) => {
             visitor.visit_expr(subexpression)
index d3f2907bfc31cbb1e7c076f649794d5859663ff3..1e7b04c814cee2ae3f85d19d6a88f93dbcaf933b 100644 (file)
 #include "rustllvm.h"
 
 #include "llvm/Object/Archive.h"
-
-#if LLVM_VERSION_MINOR >= 7
 #include "llvm/Object/ArchiveWriter.h"
-#endif
 
 using namespace llvm;
 using namespace llvm::object;
@@ -34,13 +31,7 @@ struct LLVMRustArchiveMember {
   ~LLVMRustArchiveMember() {}
 };
 
-#if LLVM_VERSION_MINOR >= 6
 typedef OwningBinary<Archive> RustArchive;
-#define GET_ARCHIVE(a) ((a)->getBinary())
-#else
-typedef Archive RustArchive;
-#define GET_ARCHIVE(a) (a)
-#endif
 
 extern "C" void*
 LLVMRustOpenArchive(char *path) {
@@ -52,7 +43,6 @@ LLVMRustOpenArchive(char *path) {
         return nullptr;
     }
 
-#if LLVM_VERSION_MINOR >= 6
     ErrorOr<std::unique_ptr<Archive>> archive_or =
         Archive::create(buf_or.get()->getMemBufferRef());
 
@@ -63,14 +53,6 @@ LLVMRustOpenArchive(char *path) {
 
     OwningBinary<Archive> *ret = new OwningBinary<Archive>(
             std::move(archive_or.get()), std::move(buf_or.get()));
-#else
-    std::error_code err;
-    Archive *ret = new Archive(std::move(buf_or.get()), err);
-    if (err) {
-        LLVMRustSetLastError(err.message().c_str());
-        return nullptr;
-    }
-#endif
 
     return ret;
 }
@@ -87,7 +69,7 @@ struct RustArchiveIterator {
 
 extern "C" RustArchiveIterator*
 LLVMRustArchiveIteratorNew(RustArchive *ra) {
-    Archive *ar = GET_ARCHIVE(ra);
+    Archive *ar = ra->getBinary();
     RustArchiveIterator *rai = new RustArchiveIterator();
     rai->cur = ar->child_begin();
     rai->end = ar->child_end();
@@ -137,16 +119,12 @@ LLVMRustArchiveChildName(const Archive::Child *child, size_t *size) {
 extern "C" const char*
 LLVMRustArchiveChildData(Archive::Child *child, size_t *size) {
     StringRef buf;
-#if LLVM_VERSION_MINOR >= 7
     ErrorOr<StringRef> buf_or_err = child->getBuffer();
     if (buf_or_err.getError()) {
       LLVMRustSetLastError(buf_or_err.getError().message().c_str());
       return NULL;
     }
     buf = buf_or_err.get();
-#else
-    buf = child->getBuffer();
-#endif
     *size = buf.size();
     return buf.data();
 }
@@ -172,7 +150,6 @@ LLVMRustWriteArchive(char *Dst,
                      const LLVMRustArchiveMember **NewMembers,
                      bool WriteSymbtab,
                      Archive::Kind Kind) {
-#if LLVM_VERSION_MINOR >= 7
   std::vector<NewArchiveIterator> Members;
 
   for (size_t i = 0; i < NumMembers; i++) {
@@ -196,8 +173,5 @@ LLVMRustWriteArchive(char *Dst,
   if (!pair.second)
     return 0;
   LLVMRustSetLastError(pair.second.message().c_str());
-#else
-  LLVMRustSetLastError("writing archives not supported with this LLVM version");
-#endif
   return -1;
 }
index 8b01cac820ed08e07b846f5aafeb37360fb706e7..b26ab44601998d9dd89d81d92eae1ac0b7d70760 100644 (file)
@@ -90,13 +90,8 @@ extern "C" LLVMExecutionEngineRef LLVMBuildExecutionEngine(LLVMModuleRef mod)
     RustJITMemoryManager *mm = new RustJITMemoryManager;
 
     ExecutionEngine *ee =
-    #if LLVM_VERSION_MINOR >= 6
         EngineBuilder(std::unique_ptr<Module>(unwrap(mod)))
             .setMCJITMemoryManager(std::unique_ptr<RustJITMemoryManager>(mm))
-    #else
-        EngineBuilder(unwrap(mod))
-            .setMCJITMemoryManager(mm)
-    #endif
             .setEngineKind(EngineKind::JIT)
             .setErrorStr(&error_str)
             .setTargetOptions(options)
index b3d4e35d7b09c75560a9bba4f2c069dda4be76c7..3564f338a029f6bb9e25c90894a785f27afa4da9 100644 (file)
 #include "llvm/Support/CBindingWrapping.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Host.h"
-#if LLVM_VERSION_MINOR >= 7
 #include "llvm/Analysis/TargetLibraryInfo.h"
 #include "llvm/Analysis/TargetTransformInfo.h"
-#else
-#include "llvm/Target/TargetLibraryInfo.h"
-#endif
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/TargetSubtargetInfo.h"
 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
@@ -49,7 +45,7 @@ LLVMInitializePasses() {
   initializeVectorization(Registry);
   initializeIPO(Registry);
   initializeAnalysis(Registry);
-#if LLVM_VERSION_MINOR <= 7
+#if LLVM_VERSION_MINOR == 7
   initializeIPA(Registry);
 #endif
   initializeTransformUtils(Registry);
@@ -223,17 +219,8 @@ LLVMRustAddAnalysisPasses(LLVMTargetMachineRef TM,
                           LLVMPassManagerRef PMR,
                           LLVMModuleRef M) {
     PassManagerBase *PM = unwrap(PMR);
-#if LLVM_VERSION_MINOR >= 7
     PM->add(createTargetTransformInfoWrapperPass(
           unwrap(TM)->getTargetIRAnalysis()));
-#else
-#if LLVM_VERSION_MINOR == 6
-    PM->add(new DataLayoutPass());
-#else
-    PM->add(new DataLayoutPass(unwrap(M)));
-#endif
-    unwrap(TM)->addAnalysisPasses(*PM);
-#endif
 }
 
 extern "C" void
@@ -242,10 +229,8 @@ LLVMRustConfigurePassManagerBuilder(LLVMPassManagerBuilderRef PMB,
                                     bool MergeFunctions,
                                     bool SLPVectorize,
                                     bool LoopVectorize) {
-#if LLVM_VERSION_MINOR >= 6
     // Ignore mergefunc for now as enabling it causes crashes.
     //unwrap(PMB)->MergeFunctions = MergeFunctions;
-#endif
     unwrap(PMB)->SLPVectorize = SLPVectorize;
     unwrap(PMB)->OptLevel = OptLevel;
     unwrap(PMB)->LoopVectorize = LoopVectorize;
@@ -258,11 +243,7 @@ LLVMRustAddBuilderLibraryInfo(LLVMPassManagerBuilderRef PMB,
                               LLVMModuleRef M,
                               bool DisableSimplifyLibCalls) {
     Triple TargetTriple(unwrap(M)->getTargetTriple());
-#if LLVM_VERSION_MINOR >= 7
     TargetLibraryInfoImpl *TLI = new TargetLibraryInfoImpl(TargetTriple);
-#else
-    TargetLibraryInfo *TLI = new TargetLibraryInfo(TargetTriple);
-#endif
     if (DisableSimplifyLibCalls)
       TLI->disableAllFunctions();
     unwrap(PMB)->LibraryInfo = TLI;
@@ -275,17 +256,10 @@ LLVMRustAddLibraryInfo(LLVMPassManagerRef PMB,
                        LLVMModuleRef M,
                        bool DisableSimplifyLibCalls) {
     Triple TargetTriple(unwrap(M)->getTargetTriple());
-#if LLVM_VERSION_MINOR >= 7
     TargetLibraryInfoImpl TLII(TargetTriple);
     if (DisableSimplifyLibCalls)
       TLII.disableAllFunctions();
     unwrap(PMB)->add(new TargetLibraryInfoWrapperPass(TLII));
-#else
-    TargetLibraryInfo *TLI = new TargetLibraryInfo(TargetTriple);
-    if (DisableSimplifyLibCalls)
-      TLI->disableAllFunctions();
-    unwrap(PMB)->add(TLI);
-#endif
 }
 
 // Unfortunately, the LLVM C API doesn't provide an easy way of iterating over
@@ -323,25 +297,16 @@ LLVMRustWriteOutputFile(LLVMTargetMachineRef Target,
   PassManager *PM = unwrap<PassManager>(PMR);
 
   std::string ErrorInfo;
-#if LLVM_VERSION_MINOR >= 6
   std::error_code EC;
   raw_fd_ostream OS(path, EC, sys::fs::F_None);
   if (EC)
     ErrorInfo = EC.message();
-#else
-  raw_fd_ostream OS(path, ErrorInfo, sys::fs::F_None);
-#endif
   if (ErrorInfo != "") {
     LLVMRustSetLastError(ErrorInfo.c_str());
     return false;
   }
 
-#if LLVM_VERSION_MINOR >= 7
   unwrap(Target)->addPassesToEmitFile(*PM, OS, FileType, false);
-#else
-  formatted_raw_ostream FOS(OS);
-  unwrap(Target)->addPassesToEmitFile(*PM, FOS, FileType, false);
-#endif
   PM->run(*unwrap(M));
 
   // Apparently `addPassesToEmitFile` adds a pointer to our on-the-stack output
@@ -358,14 +323,10 @@ LLVMRustPrintModule(LLVMPassManagerRef PMR,
   PassManager *PM = unwrap<PassManager>(PMR);
   std::string ErrorInfo;
 
-#if LLVM_VERSION_MINOR >= 6
   std::error_code EC;
   raw_fd_ostream OS(path, EC, sys::fs::F_None);
   if (EC)
     ErrorInfo = EC.message();
-#else
-  raw_fd_ostream OS(path, ErrorInfo, sys::fs::F_None);
-#endif
 
   formatted_raw_ostream FOS(OS);
 
@@ -428,22 +389,10 @@ extern "C" void
 LLVMRustSetDataLayoutFromTargetMachine(LLVMModuleRef Module,
                                        LLVMTargetMachineRef TMR) {
     TargetMachine *Target = unwrap(TMR);
-#if LLVM_VERSION_MINOR >= 7
     unwrap(Module)->setDataLayout(Target->createDataLayout());
-#elif LLVM_VERSION_MINOR >= 6
-    if (const DataLayout *DL = Target->getSubtargetImpl()->getDataLayout())
-        unwrap(Module)->setDataLayout(DL);
-#else
-    if (const DataLayout *DL = Target->getDataLayout())
-        unwrap(Module)->setDataLayout(DL);
-#endif
 }
 
 extern "C" LLVMTargetDataRef
 LLVMRustGetModuleDataLayout(LLVMModuleRef M) {
-#if LLVM_VERSION_MINOR >= 7
     return wrap(&unwrap(M)->getDataLayout());
-#else
-    return wrap(unwrap(M)->getDataLayout());
-#endif
 }
index 697b2d3f539651533a613685e4f0b321a28d3d60..fadd95c9a72459fce25a9810baf5213eb090d4ec 100644 (file)
@@ -243,7 +243,6 @@ extern "C" LLVMValueRef LLVMInlineAsm(LLVMTypeRef Ty,
 
 typedef DIBuilder* DIBuilderRef;
 
-#if LLVM_VERSION_MINOR >= 6
 typedef struct LLVMOpaqueMetadata *LLVMMetadataRef;
 
 namespace llvm {
@@ -253,29 +252,15 @@ inline Metadata **unwrap(LLVMMetadataRef *Vals) {
   return reinterpret_cast<Metadata**>(Vals);
 }
 }
-#else
-typedef LLVMValueRef LLVMMetadataRef;
-#endif
 
 template<typename DIT>
 DIT* unwrapDIptr(LLVMMetadataRef ref) {
     return (DIT*) (ref ? unwrap<MDNode>(ref) : NULL);
 }
 
-#if LLVM_VERSION_MINOR <= 6
-template<typename DIT>
-DIT unwrapDI(LLVMMetadataRef ref) {
-    return DIT(ref ? unwrap<MDNode>(ref) : NULL);
-}
-#else
 #define DIDescriptor DIScope
 #define DIArray DINodeArray
 #define unwrapDI unwrapDIptr
-#endif
-
-#if LLVM_VERSION_MINOR <= 5
-#define DISubroutineType DICompositeType
-#endif
 
 extern "C" uint32_t LLVMRustDebugMetadataVersion() {
     return DEBUG_METADATA_VERSION;
@@ -339,16 +324,10 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateSubroutineType(
     LLVMMetadataRef File,
     LLVMMetadataRef ParameterTypes) {
     return wrap(Builder->createSubroutineType(
-#if LLVM_VERSION_MINOR <= 7
+#if LLVM_VERSION_MINOR == 7
         unwrapDI<DIFile>(File),
 #endif
-#if LLVM_VERSION_MINOR >= 7
         DITypeRefArray(unwrap<MDTuple>(ParameterTypes))));
-#elif LLVM_VERSION_MINOR >= 6
-        unwrapDI<DITypeArray>(ParameterTypes)));
-#else
-        unwrapDI<DIArray>(ParameterTypes)));
-#endif
 }
 
 extern "C" LLVMMetadataRef LLVMDIBuilderCreateFunction(
@@ -435,11 +414,7 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateStructType(
         AlignInBits,
         Flags,
         unwrapDI<DIType>(DerivedFrom),
-#if LLVM_VERSION_MINOR >= 7
         DINodeArray(unwrapDI<MDTuple>(Elements)),
-#else
-        unwrapDI<DIArray>(Elements),
-#endif
         RunTimeLang,
         unwrapDI<DIType>(VTableHolder),
         UniqueId
@@ -473,9 +448,6 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateLexicalBlock(
     return wrap(Builder->createLexicalBlock(
         unwrapDI<DIDescriptor>(Scope),
         unwrapDI<DIFile>(File), Line, Col
-#if LLVM_VERSION_MINOR == 5
-        , 0
-#endif
         ));
 }
 
@@ -490,11 +462,7 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateStaticVariable(
     bool isLocalToUnit,
     LLVMValueRef Val,
     LLVMMetadataRef Decl = NULL) {
-#if LLVM_VERSION_MINOR >= 6
     return wrap(Builder->createGlobalVariable(unwrapDI<DIDescriptor>(Context),
-#else
-    return wrap(Builder->createStaticVariable(unwrapDI<DIDescriptor>(Context),
-#endif
         Name,
         LinkageName,
         unwrapDI<DIFile>(File),
@@ -518,25 +486,6 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateVariable(
     int64_t* AddrOps,
     unsigned AddrOpsCount,
     unsigned ArgNo) {
-#if LLVM_VERSION_MINOR == 5
-    if (AddrOpsCount > 0) {
-        SmallVector<llvm::Value *, 16> addr_ops;
-        llvm::Type *Int64Ty = Type::getInt64Ty(unwrap<MDNode>(Scope)->getContext());
-        for (unsigned i = 0; i < AddrOpsCount; ++i)
-            addr_ops.push_back(ConstantInt::get(Int64Ty, AddrOps[i]));
-
-        return wrap(Builder->createComplexVariable(
-            Tag,
-            unwrapDI<DIDescriptor>(Scope),
-            Name,
-            unwrapDI<DIFile>(File),
-            LineNo,
-            unwrapDI<DIType>(Ty),
-            addr_ops,
-            ArgNo
-        ));
-    }
-#endif
 #if LLVM_VERSION_MINOR >= 8
     if (Tag == 0x100) { // DW_TAG_auto_variable
         return wrap(Builder->createAutoVariable(
@@ -568,11 +517,7 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateArrayType(
     LLVMMetadataRef Subscripts) {
     return wrap(Builder->createArrayType(Size, AlignInBits,
         unwrapDI<DIType>(Ty),
-#if LLVM_VERSION_MINOR >= 7
         DINodeArray(unwrapDI<MDTuple>(Subscripts))
-#else
-        unwrapDI<DIArray>(Subscripts)
-#endif
     ));
 }
 
@@ -584,11 +529,7 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateVectorType(
     LLVMMetadataRef Subscripts) {
     return wrap(Builder->createVectorType(Size, AlignInBits,
         unwrapDI<DIType>(Ty),
-#if LLVM_VERSION_MINOR >= 7
         DINodeArray(unwrapDI<MDTuple>(Subscripts))
-#else
-        unwrapDI<DIArray>(Subscripts)
-#endif
     ));
 }
 
@@ -603,18 +544,9 @@ extern "C" LLVMMetadataRef LLVMDIBuilderGetOrCreateArray(
     DIBuilderRef Builder,
     LLVMMetadataRef* Ptr,
     unsigned Count) {
-#if LLVM_VERSION_MINOR >= 7
     Metadata **DataValue = unwrap(Ptr);
     return wrap(Builder->getOrCreateArray(
         ArrayRef<Metadata*>(DataValue, Count)).get());
-#else
-    return wrap(Builder->getOrCreateArray(
-#if LLVM_VERSION_MINOR >= 6
-        ArrayRef<Metadata*>(unwrap(Ptr), Count)));
-#else
-        ArrayRef<Value*>(reinterpret_cast<Value**>(Ptr), Count)));
-#endif
-#endif
 }
 
 extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd(
@@ -627,18 +559,10 @@ extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd(
     LLVMBasicBlockRef InsertAtEnd) {
     return wrap(Builder->insertDeclare(
         unwrap(Val),
-#if LLVM_VERSION_MINOR >= 7
         unwrap<DILocalVariable>(VarInfo),
-#else
-        unwrapDI<DIVariable>(VarInfo),
-#endif
-#if LLVM_VERSION_MINOR >= 6
         Builder->createExpression(
           llvm::ArrayRef<int64_t>(AddrOps, AddrOpsCount)),
-#endif
-#if LLVM_VERSION_MINOR >= 7
         DebugLoc(cast<MDNode>(unwrap<MetadataAsValue>(DL)->getMetadata())),
-#endif
         unwrap(InsertAtEnd)));
 }
 
@@ -650,22 +574,12 @@ extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareBefore(
     unsigned AddrOpsCount,
     LLVMValueRef DL,
     LLVMValueRef InsertBefore) {
-#if LLVM_VERSION_MINOR >= 6
-#endif
     return wrap(Builder->insertDeclare(
         unwrap(Val),
-#if LLVM_VERSION_MINOR >= 7
         unwrap<DILocalVariable>(VarInfo),
-#else
-        unwrapDI<DIVariable>(VarInfo),
-#endif
-#if LLVM_VERSION_MINOR >= 6
         Builder->createExpression(
           llvm::ArrayRef<int64_t>(AddrOps, AddrOpsCount)),
-#endif
-#if LLVM_VERSION_MINOR >= 7
         DebugLoc(cast<MDNode>(unwrap<MetadataAsValue>(DL)->getMetadata())),
-#endif
         unwrap<Instruction>(InsertBefore)));
 }
 
@@ -695,11 +609,7 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateEnumerationType(
         LineNumber,
         SizeInBits,
         AlignInBits,
-#if LLVM_VERSION_MINOR >= 7
         DINodeArray(unwrapDI<MDTuple>(Elements)),
-#else
-        unwrapDI<DIArray>(Elements),
-#endif
         unwrapDI<DIType>(ClassType)));
 }
 
@@ -724,11 +634,7 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateUnionType(
         SizeInBits,
         AlignInBits,
         Flags,
-#if LLVM_VERSION_MINOR >= 7
         DINodeArray(unwrapDI<MDTuple>(Elements)),
-#else
-        unwrapDI<DIArray>(Elements),
-#endif
         RunTimeLang,
         UniqueId
         ));
@@ -747,12 +653,6 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateTemplateTypeParameter(
       unwrapDI<DIDescriptor>(Scope),
       Name,
       unwrapDI<DIType>(Ty)
-#if LLVM_VERSION_MINOR <= 6
-      ,
-      unwrapDI<MDNode*>(File),
-      LineNo,
-      ColumnNo
-#endif
       ));
 }
 
@@ -785,15 +685,8 @@ extern "C" void LLVMDICompositeTypeSetTypeArray(
     LLVMMetadataRef CompositeType,
     LLVMMetadataRef TypeArray)
 {
-#if LLVM_VERSION_MINOR >= 7
     DICompositeType *tmp = unwrapDI<DICompositeType>(CompositeType);
     Builder->replaceArrays(tmp, DINodeArray(unwrap<MDTuple>(TypeArray)));
-#elif LLVM_VERSION_MINOR >= 6
-    DICompositeType tmp = unwrapDI<DICompositeType>(CompositeType);
-    Builder->replaceArrays(tmp, unwrapDI<DIArray>(TypeArray));
-#else
-    unwrapDI<DICompositeType>(CompositeType).setTypeArray(unwrapDI<DIArray>(TypeArray));
-#endif
 }
 
 extern "C" LLVMValueRef LLVMDIBuilderCreateDebugLocation(
@@ -810,15 +703,7 @@ extern "C" LLVMValueRef LLVMDIBuilderCreateDebugLocation(
                                        unwrapDIptr<MDNode>(Scope),
                                        unwrapDIptr<MDNode>(InlinedAt));
 
-#if LLVM_VERSION_MINOR >= 6
-    return wrap(MetadataAsValue::get(context, debug_loc.getAsMDNode(
-#if LLVM_VERSION_MINOR <= 6
-            context
-#endif
-        )));
-#else
-    return wrap(debug_loc.getAsMDNode(context));
-#endif
+    return wrap(MetadataAsValue::get(context, debug_loc.getAsMDNode()));
 }
 
 extern "C" void LLVMWriteTypeToString(LLVMTypeRef Type, RustStringRef str) {
@@ -838,40 +723,22 @@ extern "C" void LLVMWriteValueToString(LLVMValueRef Value, RustStringRef str) {
 extern "C" bool
 LLVMRustLinkInExternalBitcode(LLVMModuleRef dst, char *bc, size_t len) {
     Module *Dst = unwrap(dst);
-#if LLVM_VERSION_MINOR >= 6
     std::unique_ptr<MemoryBuffer> buf = MemoryBuffer::getMemBufferCopy(StringRef(bc, len));
-#if LLVM_VERSION_MINOR >= 7
     ErrorOr<std::unique_ptr<Module>> Src =
         llvm::getLazyBitcodeModule(std::move(buf), Dst->getContext());
-#else
-    ErrorOr<Module *> Src = llvm::getLazyBitcodeModule(std::move(buf), Dst->getContext());
-#endif
-#else
-    MemoryBuffer* buf = MemoryBuffer::getMemBufferCopy(StringRef(bc, len));
-    ErrorOr<Module *> Src = llvm::getLazyBitcodeModule(buf, Dst->getContext());
-#endif
     if (!Src) {
         LLVMRustSetLastError(Src.getError().message().c_str());
-#if LLVM_VERSION_MINOR == 5
-        delete buf;
-#endif
         return false;
     }
 
     std::string Err;
 
-#if LLVM_VERSION_MINOR >= 6
     raw_string_ostream Stream(Err);
     DiagnosticPrinterRawOStream DP(Stream);
 #if LLVM_VERSION_MINOR >= 8
     if (Linker::linkModules(*Dst, std::move(Src.get()))) {
-#elif LLVM_VERSION_MINOR >= 7
-    if (Linker::LinkModules(Dst, Src->get(), [&](const DiagnosticInfo &DI) { DI.print(DP); })) {
-#else
-    if (Linker::LinkModules(Dst, *Src, [&](const DiagnosticInfo &DI) { DI.print(DP); })) {
-#endif
 #else
-    if (Linker::LinkModules(Dst, *Src, Linker::DestroySource, &Err)) {
+    if (Linker::LinkModules(Dst, Src->get(), [&](const DiagnosticInfo &DI) { DI.print(DP); })) {
 #endif
         LLVMRustSetLastError(Err.c_str());
         return false;
@@ -975,11 +842,7 @@ extern "C" void LLVMWriteDebugLocToString(
     RustStringRef str)
 {
     raw_rust_string_ostream os(str);
-#if LLVM_VERSION_MINOR >= 7
     unwrap(dl)->print(os);
-#else
-    unwrap(dl)->print(*unwrap(C), os);
-#endif
 }
 
 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef)
index a27515fd39b701dd99b8328f320c0a858bfdf26c..14316a557328b69d1dd264b0fb33932922e43764 100644 (file)
@@ -77,5 +77,3 @@ fn main() {
     //~ TRANS_ITEM fn generic_impl::id[0]<generic_impl::Struct[0]<&str>>
     let _ = (Struct::new(Struct::new("str")).f)(Struct::new("str"));
 }
-
-//~ TRANS_ITEM drop-glue i8
diff --git a/src/test/codegen/issue-32031.rs b/src/test/codegen/issue-32031.rs
new file mode 100644 (file)
index 0000000..5d3ccbf
--- /dev/null
@@ -0,0 +1,33 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-flags: -C no-prepopulate-passes
+
+#![crate_type = "lib"]
+
+#[no_mangle]
+pub struct F32(f32);
+
+// CHECK: define float @add_newtype_f32(float, float)
+#[inline(never)]
+#[no_mangle]
+pub fn add_newtype_f32(a: F32, b: F32) -> F32 {
+    F32(a.0 + b.0)
+}
+
+#[no_mangle]
+pub struct F64(f64);
+
+// CHECK: define double @add_newtype_f64(double, double)
+#[inline(never)]
+#[no_mangle]
+pub fn add_newtype_f64(a: F64, b: F64) -> F64 {
+    F64(a.0 + b.0)
+}
diff --git a/src/test/codegen/issue-32364.rs b/src/test/codegen/issue-32364.rs
new file mode 100644 (file)
index 0000000..926987b
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-flags: -C no-prepopulate-passes
+
+struct Foo;
+
+impl Foo {
+// CHECK: define internal x86_stdcallcc void @{{.*}}foo{{.*}}()
+    #[inline(never)]
+    pub extern "stdcall" fn foo<T>() {
+    }
+}
+
+fn main() {
+    Foo::foo::<Foo>();
+}
diff --git a/src/test/compile-fail/bad-format-args.rs b/src/test/compile-fail/bad-format-args.rs
new file mode 100644 (file)
index 0000000..816c696
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright 2016 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.
+
+// error-pattern: requires at least a format string argument
+// error-pattern: bad-format-args.rs:19:5: 19:15 note: in this expansion
+
+// error-pattern: expected token: `,`
+// error-pattern: bad-format-args.rs:20:5: 20:19 note: in this expansion
+// error-pattern: bad-format-args.rs:21:5: 21:22 note: in this expansion
+
+fn main() {
+    format!();
+    format!("" 1);
+    format!("", 1 1);
+}
index b3ef3d72ca3bf77a99f9a3f8205a40b77bdaa344..a4b24fa8b4bf6e04decef823fee7a34b08966a62 100644 (file)
@@ -17,4 +17,6 @@ fn main() {
     //~^ ERROR removing an expression is not supported in this position
     let _ = [1, 2, 3][#[cfg(unset)] 1];
     //~^ ERROR removing an expression is not supported in this position
+    let _ = #[test] ();
+    //~^ ERROR removing an expression is not supported in this position
 }
index 4e089a4e59c427e41e66f2886997531de8e47119..eff734230ee238e011a72bb35f579c9fb3ded34a 100644 (file)
@@ -8,7 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(stmt_expr_attributes)]
+
 #[foo] //~ ERROR The attribute `foo`
 fn main() {
-
+    #[foo] //~ ERROR The attribute `foo`
+    let x = ();
+    #[foo] //~ ERROR The attribute `foo`
+    x
 }
index 7c929d2db16e73f044b9bc17198bcac098484334..1368702b160bff5e399b5e41e7666241ade260d5 100644 (file)
@@ -50,8 +50,4 @@ fn main() {
 
     format!("foo } bar"); //~ ERROR: unmatched `}` found
     format!("foo }"); //~ ERROR: unmatched `}` found
-
-    format!();          //~ ERROR: requires at least a format string argument
-    format!("" 1);      //~ ERROR: expected token: `,`
-    format!("", 1 1);   //~ ERROR: expected token: `,`
 }
index d89b2c6ce8cb0221e9a64a922e4e8f683909da57..3591b9824145bbdd2d114d457727baf2e6143425 100644 (file)
@@ -24,4 +24,5 @@ fn print_x(_: &Foo<Item=bool>, extra: &str) {
 
 fn main() {
     print_x(X);  //~error this function takes 2 parameters but 1 parameter was supplied
+    //~^ NOTE the following parameter types were expected: &Foo<Item=bool>, &str
 }
diff --git a/src/test/compile-fail/issue-25579.rs b/src/test/compile-fail/issue-25579.rs
new file mode 100644 (file)
index 0000000..849c9aa
--- /dev/null
@@ -0,0 +1,27 @@
+// 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.
+
+enum Sexpression {
+    Num(()),
+    Cons(&'static mut Sexpression)
+}
+
+fn causes_ice(mut l: &mut Sexpression) {
+    loop { match l {
+        &mut Sexpression::Num(ref mut n) => {},
+        &mut Sexpression::Cons(ref mut expr) => { //~ ERROR cannot borrow `l.0`
+            //~| ERROR cannot borrow `l.0`
+            l = &mut **expr; //~ ERROR cannot assign to `l`
+        }
+    }}
+}
+
+fn main() {
+}
index 0f7cc2cb72b8e2b05b73dcb6456119e3ade48d33..68046056fb3156eebb5691b80a0f82c6e06eabd7 100644 (file)
@@ -14,6 +14,7 @@ fn main() {
     needlesArr.iter().fold(|x, y| {
     });
     //~^^ ERROR this function takes 2 parameters but 1 parameter was supplied
+    //~^^^ NOTE the following parameter types were expected
     //
     // the first error is, um, non-ideal.
 }
diff --git a/src/test/compile-fail/issue-33293.rs b/src/test/compile-fail/issue-33293.rs
new file mode 100644 (file)
index 0000000..bed577b
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2016 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.
+
+fn main() {
+    match 0 {
+        aaa::bbb(_) => ()
+        //~^ ERROR failed to resolve. Use of undeclared type or module `aaa`
+    };
+}
diff --git a/src/test/compile-fail/issue-34171.rs b/src/test/compile-fail/issue-34171.rs
new file mode 100644 (file)
index 0000000..30dd34a
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2016 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.
+
+#![feature(rustc_attrs)]
+
+macro_rules! null { ($i:tt) => {} }
+macro_rules! apply_null {
+    ($i:item) => { null! { $i } }
+}
+
+#[rustc_error]
+fn main() { //~ ERROR compilation successful
+    apply_null!(#[cfg(all())] fn f() {});
+}
index b37b8e237edda12eadef63d2e68acdf2313df46b..438d238b6fe6288c8c7202c6208dd42b2114ae30 100644 (file)
@@ -12,3 +12,4 @@
 
 fn foo(a: usize) {}
 fn main() { foo(5, 6) } //~ ERROR this function takes 1 parameter but 2 parameters were supplied
+//~^ NOTE the following parameter type was expected
index c2277c3e6d8cdaba024839c618c0d1a59d2cf4ac..9d6da2a53a2227c16b3b9792a3744405b14f27c1 100644 (file)
@@ -21,11 +21,11 @@ macro_rules! myprint {
 }
 
 macro_rules! myprintln {
-    ($fmt:expr) => (myprint!(concat!($fmt, "\n"))); //~ NOTE in this expansion of myprint!
-                                                    //~^ NOTE in this expansion of concat!
+    ($fmt:expr) => (myprint!(concat!($fmt, "\n"))); //~ ERROR invalid reference to argument `0`
+                                                    //~| NOTE in this expansion of concat!
+                                                    //~| NOTE in this expansion of myprint!
 }
 
 fn main() {
-    myprintln!("{}"); //~ ERROR invalid reference to argument `0`
-                      //~^ NOTE in this expansion of
+    myprintln!("{}"); //~ NOTE in this expansion of
 }
index 42a0f41dd97c3921ffdc50b02e8e461eac9fae46..723e936212a5b76efa3a82765c1ba03df7b906c8 100644 (file)
@@ -32,7 +32,6 @@ fn main() {
 
     foo::blah!(); //~ ERROR
 
-    format!(); //~ ERROR
     format!(invalid); //~ ERROR
 
     include!(invalid); //~ ERROR
index 3434cf96fce9463c15822e240ff5fd61a73d1a88..212c09364cf4c027c711e40e4f51f277052772bc 100644 (file)
@@ -21,10 +21,13 @@ fn main() {
     let x = Foo;
     x.zero(0)   //~ ERROR this function takes 0 parameters but 1 parameter was supplied
      .one()     //~ ERROR this function takes 1 parameter but 0 parameters were supplied
+     //~^ NOTE the following parameter type was expected
      .two(0);   //~ ERROR this function takes 2 parameters but 1 parameter was supplied
+     //~^ NOTE the following parameter types were expected
 
     let y = Foo;
     y.zero()
      .take()    //~ ERROR no method named `take` found for type `Foo` in the current scope
+     //~^ NOTE the method `take` exists but the following trait bounds were not satisfied
      .one(0);
 }
index c952906e5e89ae2d41fb5d8854288858dfc015a5..1f5a54477dd6d0fa83f4597179b819deec94c5db 100644 (file)
@@ -19,4 +19,5 @@ fn foo(a: isize, b: isize, c: isize, d:isize) {
 fn main() {
   foo(1, 2, 3);
   //~^ ERROR this function takes 4 parameters but 3
+  //~^^ NOTE the following parameter types were expected
 }
index 77ac97bc8b89951427bf7aaa9d69d0e45675f55a..8763fb0913a87287ef21d84b391dc7be7bc6bf68 100644 (file)
@@ -36,7 +36,13 @@ fn main() {
         y: 3,
     };
     let ans = s("what");    //~ ERROR mismatched types
-    let ans = s();  //~ ERROR this function takes 1 parameter but 0 parameters were supplied
+    //~^ NOTE expected isize, found &-ptr
+    //~| NOTE expected type
+    //~| NOTE found type
+    let ans = s();
+    //~^ ERROR this function takes 1 parameter but 0 parameters were supplied
+    //~| NOTE the following parameter type was expected
     let ans = s("burma", "shave");
     //~^ ERROR this function takes 1 parameter but 2 parameters were supplied
+    //~| NOTE the following parameter type was expected
 }
diff --git a/src/test/compile-fail/range_traits-1.rs b/src/test/compile-fail/range_traits-1.rs
new file mode 100644 (file)
index 0000000..8521971
--- /dev/null
@@ -0,0 +1,93 @@
+// Copyright 2016 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.
+
+#![feature(inclusive_range)]
+
+use std::ops::*;
+
+// FIXME #34229 duplicated errors
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+struct AllTheRanges {
+    a: Range<usize>,
+    //~^ ERROR PartialOrd
+    //~^^ ERROR PartialOrd
+    //~^^^ ERROR Ord
+    //~^^^^ ERROR binary operation
+    //~^^^^^ ERROR binary operation
+    //~^^^^^^ ERROR binary operation
+    //~^^^^^^^ ERROR binary operation
+    //~^^^^^^^^ ERROR binary operation
+    //~^^^^^^^^^ ERROR binary operation
+    //~^^^^^^^^^^ ERROR binary operation
+    //~^^^^^^^^^^^ ERROR binary operation
+    b: RangeTo<usize>,
+    //~^ ERROR PartialOrd
+    //~^^ ERROR PartialOrd
+    //~^^^ ERROR Ord
+    //~^^^^ ERROR binary operation
+    //~^^^^^ ERROR binary operation
+    //~^^^^^^ ERROR binary operation
+    //~^^^^^^^ ERROR binary operation
+    //~^^^^^^^^ ERROR binary operation
+    //~^^^^^^^^^ ERROR binary operation
+    //~^^^^^^^^^^ ERROR binary operation
+    //~^^^^^^^^^^^ ERROR binary operation
+    c: RangeFrom<usize>,
+    //~^ ERROR PartialOrd
+    //~^^ ERROR PartialOrd
+    //~^^^ ERROR Ord
+    //~^^^^ ERROR binary operation
+    //~^^^^^ ERROR binary operation
+    //~^^^^^^ ERROR binary operation
+    //~^^^^^^^ ERROR binary operation
+    //~^^^^^^^^ ERROR binary operation
+    //~^^^^^^^^^ ERROR binary operation
+    //~^^^^^^^^^^ ERROR binary operation
+    //~^^^^^^^^^^^ ERROR binary operation
+    d: RangeFull,
+    //~^ ERROR PartialOrd
+    //~^^ ERROR PartialOrd
+    //~^^^ ERROR Ord
+    //~^^^^ ERROR binary operation
+    //~^^^^^ ERROR binary operation
+    //~^^^^^^ ERROR binary operation
+    //~^^^^^^^ ERROR binary operation
+    //~^^^^^^^^ ERROR binary operation
+    //~^^^^^^^^^ ERROR binary operation
+    //~^^^^^^^^^^ ERROR binary operation
+    //~^^^^^^^^^^^ ERROR binary operation
+    e: RangeInclusive<usize>,
+    //~^ ERROR PartialOrd
+    //~^^ ERROR PartialOrd
+    //~^^^ ERROR Ord
+    //~^^^^ ERROR binary operation
+    //~^^^^^ ERROR binary operation
+    //~^^^^^^ ERROR binary operation
+    //~^^^^^^^ ERROR binary operation
+    //~^^^^^^^^ ERROR binary operation
+    //~^^^^^^^^^ ERROR binary operation
+    //~^^^^^^^^^^ ERROR binary operation
+    //~^^^^^^^^^^^ ERROR binary operation
+    f: RangeToInclusive<usize>,
+    //~^ ERROR PartialOrd
+    //~^^ ERROR PartialOrd
+    //~^^^ ERROR Ord
+    //~^^^^ ERROR binary operation
+    //~^^^^^ ERROR binary operation
+    //~^^^^^^ ERROR binary operation
+    //~^^^^^^^ ERROR binary operation
+    //~^^^^^^^^ ERROR binary operation
+    //~^^^^^^^^^ ERROR binary operation
+    //~^^^^^^^^^^ ERROR binary operation
+    //~^^^^^^^^^^^ ERROR binary operation
+}
+
+fn main() {}
+
diff --git a/src/test/compile-fail/range_traits-2.rs b/src/test/compile-fail/range_traits-2.rs
new file mode 100644 (file)
index 0000000..64fcd25
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2016 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 std::ops::*;
+
+#[derive(Copy, Clone)] //~ ERROR Copy
+struct R(Range<usize>);
+
+fn main() {}
+
diff --git a/src/test/compile-fail/range_traits-3.rs b/src/test/compile-fail/range_traits-3.rs
new file mode 100644 (file)
index 0000000..d26b795
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2016 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 std::ops::*;
+
+#[derive(Copy, Clone)] //~ ERROR Copy
+struct R(RangeFrom<usize>);
+
+fn main() {}
+
diff --git a/src/test/compile-fail/range_traits-4.rs b/src/test/compile-fail/range_traits-4.rs
new file mode 100644 (file)
index 0000000..630969b
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2016 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.
+
+#![feature(rustc_attrs)]
+
+use std::ops::*;
+
+#[derive(Copy, Clone)]
+struct R(RangeTo<usize>);
+
+#[rustc_error]
+fn main() {} //~ ERROR success
+
diff --git a/src/test/compile-fail/range_traits-5.rs b/src/test/compile-fail/range_traits-5.rs
new file mode 100644 (file)
index 0000000..5963c4a
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2016 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.
+
+#![feature(rustc_attrs)]
+
+use std::ops::*;
+
+#[derive(Copy, Clone)]
+struct R(RangeFull);
+
+#[rustc_error]
+fn main() {} //~ ERROR success
+
diff --git a/src/test/compile-fail/range_traits-6.rs b/src/test/compile-fail/range_traits-6.rs
new file mode 100644 (file)
index 0000000..7c62711
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2016 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.
+
+#![feature(inclusive_range)]
+
+use std::ops::*;
+
+#[derive(Copy, Clone)] //~ ERROR Copy
+struct R(RangeInclusive<usize>);
+
+fn main() {}
+
diff --git a/src/test/compile-fail/range_traits-7.rs b/src/test/compile-fail/range_traits-7.rs
new file mode 100644 (file)
index 0000000..b6fec77
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2016 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.
+
+#![feature(rustc_attrs, inclusive_range)]
+
+use std::ops::*;
+
+#[derive(Copy, Clone)]
+struct R(RangeToInclusive<usize>);
+
+#[rustc_error]
+fn main() {} //~ ERROR success
+
index d627de24d679451b66a8d9778720593479bc886b..e9b7ddf6d1c6cd96928f6523573e3f5d6274081a 100644 (file)
@@ -23,8 +23,9 @@ fn main() {
     // of the below being caught.
 
     macro_rules! expando {
-        ($x: ident) => { trace_macros!($x) }
+        ($x: ident) => { trace_macros!($x) } //~ ERROR `trace_macros` is not stable
     }
 
-    expando!(true); //~ ERROR `trace_macros` is not stable
+    expando!(true); //~ NOTE in this expansion
+                    //~^ NOTE in this expansion
 }
index b43159b0d96b042fbd51c2494632730897602223..d8620ead836397d8a290c961cfb38c939913f047 100644 (file)
@@ -17,7 +17,9 @@ extern "C" fn bar(f: isize, x: u8) {}
 fn main() {
     unsafe {
         foo(); //~ ERROR: this function takes at least 2 parameters but 0 parameters were supplied
+        //~^ NOTE the following parameter types were expected
         foo(1); //~ ERROR: this function takes at least 2 parameters but 1 parameter was supplied
+        //~^ NOTE the following parameter types were expected
 
         let x: unsafe extern "C" fn(f: isize, x: u8) = foo;
         //~^ ERROR: mismatched types
index d007b507556188f4f5bc6c6dec1c7f89b9bf70a0..add0938409405d6b9cf0523c6d731e6edef51ce9 100644 (file)
 #![omit_gdb_pretty_printer_section]
 
 fn immediate_args(a: isize, b: bool, c: f64) {
-    println!("") // #break
+    zzz(); // #break
 }
 
 struct BigStruct {
@@ -243,7 +243,7 @@ struct BigStruct {
 }
 
 fn non_immediate_args(a: BigStruct, b: BigStruct) {
-    println!("") // #break
+    zzz(); // #break
 }
 
 fn binding(a: i64, b: u64, c: f64) {
@@ -257,7 +257,7 @@ fn assignment(mut a: u64, b: u64, c: f64) {
 }
 
 fn function_call(x: u64, y: u64, z: f64) {
-    println!("Hi!") // #break
+    zzz(); // #break
 }
 
 fn identifier(x: u64, y: u64, z: f64) -> u64 {
@@ -333,3 +333,5 @@ fn main() {
     while_expr(40, 41, 42);
     loop_expr(43, 44, 45);
 }
+
+fn zzz() {()}
diff --git a/src/test/run-pass/issue-23477.rs b/src/test/run-pass/issue-23477.rs
new file mode 100644 (file)
index 0000000..d4671c9
--- /dev/null
@@ -0,0 +1,23 @@
+// Copyright 2016 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.
+// compiler-flags: -g
+
+pub struct Dst {
+    pub a: (),
+    pub b: (),
+    pub data: [u8],
+}
+
+pub unsafe fn borrow(bytes: &[u8]) -> &Dst {
+    let dst: &Dst = std::mem::transmute((bytes.as_ptr(), bytes.len()));
+    dst
+}
+
+fn main() {}
diff --git a/src/test/rustdoc/inline_cross/hidden-use.rs b/src/test/rustdoc/inline_cross/hidden-use.rs
new file mode 100644 (file)
index 0000000..dd668c2
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:rustdoc-hidden.rs
+// build-aux-docs
+// ignore-cross-compile
+
+extern crate rustdoc_hidden;
+
+// @has hidden_use/index.html
+// @!has - 'rustdoc_hidden'
+// @!has - 'Bar'
+// @!has hidden_use/struct.Bar.html
+#[doc(hidden)]
+pub use rustdoc_hidden::Bar;
diff --git a/src/test/rustdoc/inline_local/hidden-use.rs b/src/test/rustdoc/inline_local/hidden-use.rs
new file mode 100644 (file)
index 0000000..1b1dafc
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2016 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.
+
+mod private {
+    pub struct Foo {}
+}
+
+// @has hidden_use/index.html
+// @!has - 'private'
+// @!has - 'Foo'
+// @!has hidden_use/struct.Foo.html
+#[doc(hidden)]
+pub use private::Foo;
diff --git a/src/test/rustdoc/issue-34025.rs b/src/test/rustdoc/issue-34025.rs
new file mode 100644 (file)
index 0000000..8c0a770
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_name = "foo"]
+
+// @!has 'foo/sys/index.html'
+// @!has 'foo/sys/sidebar-items.js'
+#[doc(hidden)]
+pub mod sys {
+    extern "C" {
+        // @!has 'foo/sys/fn.foo.html'
+        #[doc(hidden)]
+        pub fn foo();
+    }
+}
diff --git a/src/test/rustdoc/redirect-rename.rs b/src/test/rustdoc/redirect-rename.rs
new file mode 100644 (file)
index 0000000..b7c702d
--- /dev/null
@@ -0,0 +1,32 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_name = "foo"]
+
+mod hidden {
+    // @has foo/hidden/struct.Foo.html
+    // @has - '//p/a' '../../foo/struct.FooBar.html'
+    pub struct Foo {}
+
+    // @has foo/hidden/bar/index.html
+    // @has - '//p/a' '../../foo/baz/index.html'
+    pub mod bar {
+        // @has foo/hidden/bar/struct.Thing.html
+        // @has - '//p/a' '../../foo/baz/struct.Thing.html'
+        pub struct Thing {}
+    }
+}
+
+// @has foo/struct.FooBar.html
+pub use hidden::Foo as FooBar;
+
+// @has foo/baz/index.html
+// @has foo/baz/struct.Thing.html
+pub use hidden::bar as baz;
index 9332a8e5f6c06eb4e4da7aa5ad2851bd72cd4b8a..8b7164819a7907390d3105335ae38039d47b9d65 100644 (file)
@@ -21,20 +21,18 @@ struct Test {
     lock: Option<&'static str>,
 }
 
-const TEST_REPOS: &'static [Test] = &[
-    Test {
-        name: "cargo",
-        repo: "https://github.com/rust-lang/cargo",
-        sha: "7d79da08238e3d47e0bc4406155bdcc45ccb8c82",
-        lock: None,
-    },
-    Test {
-        name: "iron",
-        repo: "https://github.com/iron/iron",
-        sha: "16c858ec2901e2992fe5e529780f59fa8ed12903",
-        lock: Some(include_str!("lockfiles/iron-Cargo.lock")),
-    },
-];
+const TEST_REPOS: &'static [Test] = &[Test {
+                                          name: "cargo",
+                                          repo: "https://github.com/rust-lang/cargo",
+                                          sha: "7d79da08238e3d47e0bc4406155bdcc45ccb8c82",
+                                          lock: None,
+                                      },
+                                      Test {
+                                          name: "iron",
+                                          repo: "https://github.com/iron/iron",
+                                          sha: "16c858ec2901e2992fe5e529780f59fa8ed12903",
+                                          lock: Some(include_str!("lockfiles/iron-Cargo.lock")),
+                                      }];
 
 
 fn main() {
@@ -52,8 +50,10 @@ fn test_repo(cargo: &Path, out_dir: &Path, test: &Test) {
     println!("testing {}", test.repo);
     let dir = clone_repo(test, out_dir);
     if let Some(lockfile) = test.lock {
-        File::create(&dir.join("Cargo.lock")).expect("")
-            .write_all(lockfile.as_bytes()).expect("");
+        File::create(&dir.join("Cargo.lock"))
+            .expect("")
+            .write_all(lockfile.as_bytes())
+            .expect("");
     }
     if !run_cargo_test(cargo, &dir) {
         panic!("tests failed for {}", test.repo);
@@ -65,10 +65,10 @@ fn clone_repo(test: &Test, out_dir: &Path) -> PathBuf {
 
     if !out_dir.join(".git").is_dir() {
         let status = Command::new("git")
-            .arg("init")
-            .arg(&out_dir)
-            .status()
-            .expect("");
+                         .arg("init")
+                         .arg(&out_dir)
+                         .status()
+                         .expect("");
         assert!(status.success());
     }
 
@@ -77,23 +77,23 @@ fn clone_repo(test: &Test, out_dir: &Path) -> PathBuf {
     for depth in &[0, 1, 10, 100, 1000, 100000] {
         if *depth > 0 {
             let status = Command::new("git")
-                .arg("fetch")
-                .arg(test.repo)
-                .arg("master")
-                .arg(&format!("--depth={}", depth))
-                .current_dir(&out_dir)
-                .status()
-                .expect("");
+                             .arg("fetch")
+                             .arg(test.repo)
+                             .arg("master")
+                             .arg(&format!("--depth={}", depth))
+                             .current_dir(&out_dir)
+                             .status()
+                             .expect("");
             assert!(status.success());
         }
 
         let status = Command::new("git")
-            .arg("reset")
-            .arg(test.sha)
-            .arg("--hard")
-            .current_dir(&out_dir)
-            .status()
-            .expect("");
+                         .arg("reset")
+                         .arg(test.sha)
+                         .arg("--hard")
+                         .current_dir(&out_dir)
+                         .status()
+                         .expect("");
 
         if status.success() {
             found = true;
@@ -105,11 +105,11 @@ fn clone_repo(test: &Test, out_dir: &Path) -> PathBuf {
         panic!("unable to find commit {}", test.sha)
     }
     let status = Command::new("git")
-        .arg("clean")
-        .arg("-fdx")
-        .current_dir(&out_dir)
-        .status()
-        .unwrap();
+                     .arg("clean")
+                     .arg("-fdx")
+                     .current_dir(&out_dir)
+                     .status()
+                     .unwrap();
     assert!(status.success());
 
     out_dir
index c02fc8a3f918cdcfb18f068b6693b9bb08592912..4b74833eaf79794ad1f5f7256a335c661cd1c5db 100644 (file)
@@ -75,30 +75,20 @@ struct FileEntry {
 type Cache = HashMap<PathBuf, FileEntry>;
 
 impl FileEntry {
-    fn parse_ids(&mut self,
-                file: &Path,
-                contents: &str,
-                errors: &mut bool)
-{
+    fn parse_ids(&mut self, file: &Path, contents: &str, errors: &mut bool) {
         if self.ids.is_empty() {
             with_attrs_in_source(contents, " id", |fragment, i| {
                 let frag = fragment.trim_left_matches("#").to_owned();
                 if !self.ids.insert(frag) {
                     *errors = true;
-                    println!("{}:{}: id is not unique: `{}`",
-                             file.display(), i, fragment);
+                    println!("{}:{}: id is not unique: `{}`", file.display(), i, fragment);
                 }
             });
         }
     }
 }
 
-fn walk(cache: &mut Cache,
-        root: &Path,
-        dir: &Path,
-        url: &mut Url,
-        errors: &mut bool)
-{
+fn walk(cache: &mut Cache, root: &Path, dir: &Path, url: &mut Url, errors: &mut bool) {
     for entry in t!(dir.read_dir()).map(|e| t!(e)) {
         let path = entry.path();
         let kind = t!(entry.file_type());
@@ -122,8 +112,8 @@ fn check(cache: &mut Cache,
          root: &Path,
          file: &Path,
          base: &Url,
-         errors: &mut bool) -> Option<PathBuf>
-{
+         errors: &mut bool)
+         -> Option<PathBuf> {
     // ignore js files as they are not prone to errors as the rest of the
     // documentation is and they otherwise bring up false positives.
     if file.extension().and_then(|s| s.to_str()) == Some("js") {
@@ -173,8 +163,9 @@ fn check(cache: &mut Cache,
         Err(_) => return None,
     };
     {
-        cache.get_mut(&pretty_file).unwrap()
-                                   .parse_ids(&pretty_file, &contents, errors);
+        cache.get_mut(&pretty_file)
+             .unwrap()
+             .parse_ids(&pretty_file, &contents, errors);
     }
 
     // Search for anything that's the regex 'href[ ]*=[ ]*".*?"'
@@ -195,8 +186,10 @@ fn check(cache: &mut Cache,
                 // the docs offline so it's best to avoid them.
                 *errors = true;
                 let pretty_path = path.strip_prefix(root).unwrap_or(&path);
-                println!("{}:{}: directory link - {}", pretty_file.display(),
-                         i + 1, pretty_path.display());
+                println!("{}:{}: directory link - {}",
+                         pretty_file.display(),
+                         i + 1,
+                         pretty_path.display());
                 return;
             }
             let res = load_file(cache, root, path.clone(), FromRedirect(false));
@@ -205,7 +198,9 @@ fn check(cache: &mut Cache,
                 Err(LoadError::IOError(err)) => panic!(format!("{}", err)),
                 Err(LoadError::BrokenRedirect(target, _)) => {
                     print!("{}:{}: broken redirect to {}",
-                           pretty_file.display(), i + 1, target.display());
+                           pretty_file.display(),
+                           i + 1,
+                           target.display());
                     return;
                 }
                 Err(LoadError::IsRedirect) => unreachable!(),
@@ -225,9 +220,9 @@ fn check(cache: &mut Cache,
                 if !entry.ids.contains(fragment) {
                     *errors = true;
                     print!("{}:{}: broken link fragment  ",
-                           pretty_file.display(), i + 1);
-                    println!("`#{}` pointing to `{}`",
-                             fragment, pretty_path.display());
+                           pretty_file.display(),
+                           i + 1);
+                    println!("`#{}` pointing to `{}`", fragment, pretty_path.display());
                 };
             }
         } else {
@@ -243,7 +238,8 @@ fn check(cache: &mut Cache,
 fn load_file(cache: &mut Cache,
              root: &Path,
              file: PathBuf,
-             redirect: Redirect) -> Result<(PathBuf, String), LoadError> {
+             redirect: Redirect)
+             -> Result<(PathBuf, String), LoadError> {
     let mut contents = String::new();
     let pretty_file = PathBuf::from(file.strip_prefix(root).unwrap_or(&file));
 
@@ -251,7 +247,7 @@ fn load_file(cache: &mut Cache,
         Entry::Occupied(entry) => {
             contents = entry.get().source.clone();
             None
-        },
+        }
         Entry::Vacant(entry) => {
             let mut fp = try!(File::open(file.clone()).map_err(|err| {
                 if let FromRedirect(true) = redirect {
@@ -275,7 +271,7 @@ fn load_file(cache: &mut Cache,
                 });
             }
             maybe
-        },
+        }
     };
     let base = Url::from_file_path(&file).unwrap();
     let mut parser = UrlParser::new();
@@ -286,7 +282,7 @@ fn load_file(cache: &mut Cache,
             let path = PathBuf::from(redirect_file);
             load_file(cache, root, path, FromRedirect(true))
         }
-        None => Ok((pretty_file, contents))
+        None => Ok((pretty_file, contents)),
     }
 }
 
@@ -307,25 +303,22 @@ fn maybe_redirect(source: &str) -> Option<String> {
 }
 
 fn url_to_file_path(parser: &UrlParser, url: &str) -> Option<(Url, PathBuf)> {
-    parser.parse(url).ok().and_then(|parsed_url| {
-        parsed_url.to_file_path().ok().map(|f| (parsed_url, f))
-    })
+    parser.parse(url)
+          .ok()
+          .and_then(|parsed_url| parsed_url.to_file_path().ok().map(|f| (parsed_url, f)))
 }
 
-fn with_attrs_in_source<F: FnMut(&str, usize)>(contents: &str,
-                                               attr: &str,
-                                               mut f: F)
-{
+fn with_attrs_in_source<F: FnMut(&str, usize)>(contents: &str, attr: &str, mut f: F) {
     for (i, mut line) in contents.lines().enumerate() {
         while let Some(j) = line.find(attr) {
-            let rest = &line[j + attr.len() ..];
+            let rest = &line[j + attr.len()..];
             line = rest;
             let pos_equals = match rest.find("=") {
                 Some(i) => i,
                 None => continue,
             };
             if rest[..pos_equals].trim_left_matches(" ") != "" {
-                continue
+                continue;
             }
 
             let rest = &rest[pos_equals + 1..];
@@ -337,7 +330,7 @@ fn with_attrs_in_source<F: FnMut(&str, usize)>(contents: &str,
             let quote_delim = rest.as_bytes()[pos_quote] as char;
 
             if rest[..pos_quote].trim_left_matches(" ") != "" {
-                continue
+                continue;
             }
             let rest = &rest[pos_quote + 1..];
             let url = match rest.find(quote_delim) {