about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2016-12-24 21:14:17 +0000
committerbors <bors@rust-lang.org>2016-12-24 21:14:17 +0000
commite60aa62ffe7462d48cb44ab33f2551b466745e83 (patch)
tree97d19ca2d9cedb110340266922ae30aab94347b3
parent00e61d41859514c906b8b630ea10ececa4f0c2cd (diff)
parentdf63b0ce720a846e8c7983b1b26ed3e3d36ba972 (diff)
downloadrust-e60aa62ffe7462d48cb44ab33f2551b466745e83.tar.gz
rust-e60aa62ffe7462d48cb44ab33f2551b466745e83.zip
Auto merge of #38594 - steveklabnik:rollup, r=steveklabnik
Rollup of 14 pull requests

- Successful merges: #37956, #38013, #38297, #38480, #38497, #38502, #38505, #38513, #38521, #38549, #38554, #38557, #38568, #38572
- Failed merges:
-rw-r--r--src/bootstrap/README.md2
-rw-r--r--src/doc/book/casting-between-types.md18
-rw-r--r--src/doc/book/documentation.md5
-rw-r--r--src/doc/book/testing.md9
-rw-r--r--src/libcollections/linked_list.rs20
-rw-r--r--src/librustc_incremental/calculate_svh/svh_visitor.rs46
-rw-r--r--src/librustc_metadata/diagnostics.rs6
-rw-r--r--src/librustc_trans/README.md1
-rw-r--r--src/librustc_trans/README.txt1
-rw-r--r--src/librustc_typeck/diagnostics.rs4
-rw-r--r--src/librustdoc/html/format.rs2
-rw-r--r--src/librustdoc/html/layout.rs1
-rw-r--r--src/librustdoc/html/static/rustdoc.css2
-rw-r--r--src/libstd/io/mod.rs6
-rw-r--r--src/libstd/sys/unix/process/magenta.rs1
-rw-r--r--src/libstd/thread/mod.rs97
-rw-r--r--src/test/incremental/hashes/inherent_impls.rs410
-rw-r--r--src/test/incremental/hashes/inline_asm.rs265
18 files changed, 848 insertions, 48 deletions
diff --git a/src/bootstrap/README.md b/src/bootstrap/README.md
index ade5bde07d2..ac84edb4038 100644
--- a/src/bootstrap/README.md
+++ b/src/bootstrap/README.md
@@ -142,7 +142,7 @@ incremental builds:
 ```
 
 The `--incremental` flag will store incremental compilation artifacts
-in `build/stage0-incremental`. Note that we only use incremental
+in `build/<host>/stage0-incremental`. Note that we only use incremental
 compilation for the stage0 -> stage1 compilation -- this is because
 the stage1 compiler is changing, and we don't try to cache and reuse
 incremental artifacts across different versions of the compiler. For
diff --git a/src/doc/book/casting-between-types.md b/src/doc/book/casting-between-types.md
index 296384ab6ef..a8f8224c58b 100644
--- a/src/doc/book/casting-between-types.md
+++ b/src/doc/book/casting-between-types.md
@@ -16,18 +16,18 @@ function result.
 
 The most common case of coercion is removing mutability from a reference:
 
- * `&mut T` to `&T`
+* `&mut T` to `&T`
 
 An analogous conversion is to remove mutability from a
 [raw pointer](raw-pointers.md):
 
- * `*mut T` to `*const T`
+* `*mut T` to `*const T`
 
 References can also be coerced to raw pointers:
 
- * `&T` to `*const T`
+* `&T` to `*const T`
 
- * `&mut T` to `*mut T`
+* `&mut T` to `*mut T`
 
 Custom coercions may be defined using [`Deref`](deref-coercions.md).
 
@@ -59,11 +59,11 @@ A cast `e as U` is valid if `e` has type `T` and `T` *coerces* to `U`.
 
 A cast `e as U` is also valid in any of the following cases:
 
- * `e` has type `T` and `T` and `U` are any numeric types; *numeric-cast*
- * `e` is a C-like enum (with no data attached to the variants),
-    and `U` is an integer type; *enum-cast*
- * `e` has type `bool` or `char` and `U` is an integer type; *prim-int-cast*
- * `e` has type `u8` and `U` is `char`; *u8-char-cast*
+* `e` has type `T` and `T` and `U` are any numeric types; *numeric-cast*
+* `e` is a C-like enum (with no data attached to the variants),
+   and `U` is an integer type; *enum-cast*
+* `e` has type `bool` or `char` and `U` is an integer type; *prim-int-cast*
+* `e` has type `u8` and `U` is `char`; *u8-char-cast*
 
 For example
 
diff --git a/src/doc/book/documentation.md b/src/doc/book/documentation.md
index f30a95b4e78..dafcffc39c8 100644
--- a/src/doc/book/documentation.md
+++ b/src/doc/book/documentation.md
@@ -460,8 +460,9 @@ not actually pass as a test.
 ```
 
 The `no_run` attribute will compile your code, but not run it. This is
-important for examples such as "Here's how to start up a network service,"
-which you would want to make sure compile, but might run in an infinite loop!
+important for examples such as "Here's how to retrieve a web page,"
+which you would want to ensure compiles, but might be run in a test
+environment that has no network access.
 
 ### Documenting modules
 
diff --git a/src/doc/book/testing.md b/src/doc/book/testing.md
index ebeb9923197..96cec7295aa 100644
--- a/src/doc/book/testing.md
+++ b/src/doc/book/testing.md
@@ -589,11 +589,10 @@ please see the [Documentation chapter](documentation.html).
 
 # Testing and concurrency
 
-One thing that is important to note when writing tests is that they may be run
-concurrently using threads. For this reason you should take care that your tests
-are written in such a way as to not depend on each-other, or on any shared
-state. "Shared state" can also include the environment, such as the current
-working directory, or environment variables.
+It is important to note that tests are run concurrently using threads. For this
+reason, care should be taken to ensure your tests do not depend on each-other,
+or on any shared state. "Shared state" can also include the environment, such
+as the current working directory, or environment variables.
 
 If this is an issue it is possible to control this concurrency, either by
 setting the environment variable `RUST_TEST_THREADS`, or by passing the argument
diff --git a/src/libcollections/linked_list.rs b/src/libcollections/linked_list.rs
index e8c2e0b5902..31085509088 100644
--- a/src/libcollections/linked_list.rs
+++ b/src/libcollections/linked_list.rs
@@ -10,8 +10,15 @@
 
 //! A doubly-linked list with owned nodes.
 //!
-//! The `LinkedList` allows pushing and popping elements at either end and is thus
-//! efficiently usable as a double-ended queue.
+//! The `LinkedList` allows pushing and popping elements at either end
+//! in constant time.
+//!
+//! Almost always it is better to use `Vec` or [`VecDeque`] instead of
+//! [`LinkedList`]. In general, array-based containers are faster,
+//! more memory efficient and make better use of CPU cache.
+//!
+//! [`LinkedList`]: ../linked_list/struct.LinkedList.html
+//! [`VecDeque`]: ../vec_deque/struct.VecDeque.html
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
@@ -27,7 +34,14 @@ use core::ptr::{self, Shared};
 
 use super::SpecExtend;
 
-/// A doubly-linked list.
+/// A doubly-linked list with owned nodes.
+///
+/// The `LinkedList` allows pushing and popping elements at either end
+/// in constant time.
+///
+/// Almost always it is better to use `Vec` or `VecDeque` instead of
+/// `LinkedList`. In general, array-based containers are faster,
+/// more memory efficient and make better use of CPU cache.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct LinkedList<T> {
     head: Option<Shared<Node<T>>>,
diff --git a/src/librustc_incremental/calculate_svh/svh_visitor.rs b/src/librustc_incremental/calculate_svh/svh_visitor.rs
index bd865d10efc..ccae5f3b003 100644
--- a/src/librustc_incremental/calculate_svh/svh_visitor.rs
+++ b/src/librustc_incremental/calculate_svh/svh_visitor.rs
@@ -28,7 +28,7 @@ use rustc::hir::def_id::DefId;
 use rustc::hir::intravisit as visit;
 use rustc::ty::TyCtxt;
 use rustc_data_structures::fnv;
-use std::hash::Hash;
+use std::hash::{Hash, Hasher};
 
 use super::def_path_hash::DefPathHashes;
 use super::caching_codemap_view::CachingCodemapView;
@@ -264,7 +264,7 @@ enum SawExprComponent<'a> {
     SawExprPath,
     SawExprAddrOf(hir::Mutability),
     SawExprRet,
-    SawExprInlineAsm(&'a hir::InlineAsm),
+    SawExprInlineAsm(StableInlineAsm<'a>),
     SawExprStruct,
     SawExprRepeat,
 }
@@ -340,7 +340,7 @@ fn saw_expr<'a>(node: &'a Expr_,
         ExprBreak(label, _)      => (SawExprBreak(label.map(|l| l.name.as_str())), false),
         ExprAgain(label)         => (SawExprAgain(label.map(|l| l.name.as_str())), false),
         ExprRet(..)              => (SawExprRet, false),
-        ExprInlineAsm(ref a,..)  => (SawExprInlineAsm(a), false),
+        ExprInlineAsm(ref a,..)  => (SawExprInlineAsm(StableInlineAsm(a)), false),
         ExprStruct(..)           => (SawExprStruct, false),
         ExprRepeat(..)           => (SawExprRepeat, false),
     }
@@ -491,6 +491,46 @@ enum SawSpanExpnKind {
     SomeExpansion,
 }
 
+/// A wrapper that provides a stable Hash implementation.
+struct StableInlineAsm<'a>(&'a InlineAsm);
+
+impl<'a> Hash for StableInlineAsm<'a> {
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        let InlineAsm {
+            asm,
+            asm_str_style,
+            ref outputs,
+            ref inputs,
+            ref clobbers,
+            volatile,
+            alignstack,
+            dialect,
+            expn_id: _, // This is used for error reporting
+        } = *self.0;
+
+        asm.as_str().hash(state);
+        asm_str_style.hash(state);
+        outputs.len().hash(state);
+        for output in outputs {
+            let InlineAsmOutput { constraint, is_rw, is_indirect } = *output;
+            constraint.as_str().hash(state);
+            is_rw.hash(state);
+            is_indirect.hash(state);
+        }
+        inputs.len().hash(state);
+        for input in inputs {
+            input.as_str().hash(state);
+        }
+        clobbers.len().hash(state);
+        for clobber in clobbers {
+            clobber.as_str().hash(state);
+        }
+        volatile.hash(state);
+        alignstack.hash(state);
+        dialect.hash(state);
+    }
+}
+
 macro_rules! hash_attrs {
     ($visitor:expr, $attrs:expr) => ({
         let attrs = $attrs;
diff --git a/src/librustc_metadata/diagnostics.rs b/src/librustc_metadata/diagnostics.rs
index 6cf1a9e8a39..d3a2b6f1683 100644
--- a/src/librustc_metadata/diagnostics.rs
+++ b/src/librustc_metadata/diagnostics.rs
@@ -57,9 +57,9 @@ An unknown "kind" was specified for a link attribute. Erroneous code example:
 
 Please specify a valid "kind" value, from one of the following:
 
- * static
- * dylib
- * framework
+* static
+* dylib
+* framework
 
 "##,
 
diff --git a/src/librustc_trans/README.md b/src/librustc_trans/README.md
new file mode 100644
index 00000000000..cd43cbd7052
--- /dev/null
+++ b/src/librustc_trans/README.md
@@ -0,0 +1 @@
+See [librustc/README.md](../librustc/README.md).
diff --git a/src/librustc_trans/README.txt b/src/librustc_trans/README.txt
deleted file mode 100644
index 1f416d5404d..00000000000
--- a/src/librustc_trans/README.txt
+++ /dev/null
@@ -1 +0,0 @@
-See the README.md in ../librustc.
diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs
index 71507063ffc..2b17ac94b22 100644
--- a/src/librustc_typeck/diagnostics.rs
+++ b/src/librustc_typeck/diagnostics.rs
@@ -1378,8 +1378,8 @@ let x = |_| {}; // error: cannot determine a type for this expression
 
 You have two possibilities to solve this situation:
 
- * Give an explicit definition of the expression
- * Infer the expression
+* Give an explicit definition of the expression
+* Infer the expression
 
 Examples:
 
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 6dc6e80dae0..796a3a93068 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -207,7 +207,7 @@ impl<'a> fmt::Display for WhereClause<'a> {
         if !f.alternate() {
             clause.push_str("</span>");
             let plain = format!("{:#}", self);
-            if plain.len() > 80 {
+            if plain.len() + pad > 80 {
                 //break it onto its own line regardless, but make sure method impls and trait
                 //blocks keep their fixed padding (2 and 9, respectively)
                 let padding = if pad > 10 {
diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs
index 5353642e294..06a81641296 100644
--- a/src/librustdoc/html/layout.rs
+++ b/src/librustdoc/html/layout.rs
@@ -46,6 +46,7 @@ r##"<!DOCTYPE html>
 
     <title>{title}</title>
 
+    <link rel="stylesheet" type="text/css" href="{root_path}normalize.css">
     <link rel="stylesheet" type="text/css" href="{root_path}rustdoc.css">
     <link rel="stylesheet" type="text/css" href="{root_path}main.css">
     {css_extension}
diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css
index 15912b41d59..ce7c6acdf47 100644
--- a/src/librustdoc/html/static/rustdoc.css
+++ b/src/librustdoc/html/static/rustdoc.css
@@ -1,5 +1,3 @@
-@import "normalize.css";
-
 /**
  * Copyright 2013 The Rust Project Developers. See the COPYRIGHT
  * file at the top-level directory of this distribution and at
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index 143a85ae321..5450a10c9bd 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -1425,6 +1425,12 @@ pub trait BufRead: Read {
     ///     println!("{}", line.unwrap());
     /// }
     /// ```
+    ///
+    /// # Errors
+    ///
+    /// Each line of the iterator has the same error semantics as [`BufRead::read_line()`].
+    ///
+    /// [`BufRead::read_line()`]: trait.BufRead.html#method.read_line
     #[stable(feature = "rust1", since = "1.0.0")]
     fn lines(self) -> Lines<Self> where Self: Sized {
         Lines { buf: self }
diff --git a/src/libstd/sys/unix/process/magenta.rs b/src/libstd/sys/unix/process/magenta.rs
index 319fbce35cd..2bb005be4ec 100644
--- a/src/libstd/sys/unix/process/magenta.rs
+++ b/src/libstd/sys/unix/process/magenta.rs
@@ -23,7 +23,6 @@ pub type mx_rights_t = u32;
 pub type mx_status_t = i32;
 
 pub type mx_size_t = usize;
-pub type mx_ssize_t = isize;
 
 pub const MX_HANDLE_INVALID: mx_handle_t = 0;
 
diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs
index 2a3fb5ec43f..6d8b3cc93d9 100644
--- a/src/libstd/thread/mod.rs
+++ b/src/libstd/thread/mod.rs
@@ -318,20 +318,38 @@ impl Builder {
 // Free functions
 ////////////////////////////////////////////////////////////////////////////////
 
-/// Spawns a new thread, returning a `JoinHandle` for it.
+/// Spawns a new thread, returning a [`JoinHandle`] for it.
 ///
 /// The join handle will implicitly *detach* the child thread upon being
 /// dropped. In this case, the child thread may outlive the parent (unless
 /// the parent thread is the main thread; the whole process is terminated when
-/// the main thread finishes.) Additionally, the join handle provides a `join`
+/// the main thread finishes). Additionally, the join handle provides a [`join`]
 /// method that can be used to join the child thread. If the child thread
-/// panics, `join` will return an `Err` containing the argument given to
-/// `panic`.
+/// panics, [`join`] will return an [`Err`] containing the argument given to
+/// [`panic`].
 ///
 /// # Panics
 ///
-/// Panics if the OS fails to create a thread; use `Builder::spawn`
+/// Panics if the OS fails to create a thread; use [`Builder::spawn`]
 /// to recover from such errors.
+///
+/// [`JoinHandle`]: ../../std/thread/struct.JoinHandle.html
+/// [`join`]: ../../std/thread/struct.JoinHandle.html#method.join
+/// [`Err`]: ../../std/result/enum.Result.html#variant.Err
+/// [`panic!`]: ../../std/macro.panic.html
+/// [`Builder::spawn`]: ../../std/thread/struct.Builder.html#method.spawn
+///
+/// # Examples
+///
+/// ```
+/// use std::thread;
+///
+/// let handler = thread::spawn(|| {
+///     // thread code
+/// });
+///
+/// handler.join().unwrap();
+/// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn spawn<F, T>(f: F) -> JoinHandle<T> where
     F: FnOnce() -> T, F: Send + 'static, T: Send + 'static
@@ -341,7 +359,7 @@ pub fn spawn<F, T>(f: F) -> JoinHandle<T> where
 
 /// Gets a handle to the thread that invokes it.
 ///
-/// #Examples
+/// # Examples
 ///
 /// Getting a handle to the current thread with `thread::current()`:
 ///
@@ -366,6 +384,14 @@ pub fn current() -> Thread {
 }
 
 /// Cooperatively gives up a timeslice to the OS scheduler.
+///
+/// # Examples
+///
+/// ```
+/// use std::thread;
+///
+/// thread::yield_now();
+/// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn yield_now() {
     imp::Thread::yield_now()
@@ -375,7 +401,7 @@ pub fn yield_now() {
 ///
 /// # Examples
 ///
-/// ```rust,should_panic
+/// ```should_panic
 /// use std::thread;
 ///
 /// struct SomeStruct;
@@ -413,6 +439,15 @@ pub fn panicking() -> bool {
 /// specifics or platform-dependent functionality. Note that on unix platforms
 /// this function will not return early due to a signal being received or a
 /// spurious wakeup.
+///
+/// # Examples
+///
+/// ```no_run
+/// use std::thread;
+///
+/// // Let's sleep for 2 seconds:
+/// thread::sleep_ms(2000);
+/// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_deprecated(since = "1.6.0", reason = "replaced by `std::thread::sleep`")]
 pub fn sleep_ms(ms: u32) {
@@ -433,7 +468,7 @@ pub fn sleep_ms(ms: u32) {
 ///
 /// # Examples
 ///
-/// ```rust,no_run
+/// ```no_run
 /// use std::{thread, time};
 ///
 /// let ten_millis = time::Duration::from_millis(10);
@@ -749,7 +784,7 @@ impl<T> JoinInner<T> {
 ///
 /// A `JoinHandle` *detaches* the child thread when it is dropped.
 ///
-/// Due to platform restrictions, it is not possible to `Clone` this
+/// Due to platform restrictions, it is not possible to [`Clone`] this
 /// handle: the ability to join a child thread is a uniquely-owned
 /// permission.
 ///
@@ -760,7 +795,7 @@ impl<T> JoinInner<T> {
 ///
 /// Creation from [`thread::spawn`]:
 ///
-/// ```rust
+/// ```
 /// use std::thread;
 ///
 /// let join_handle: thread::JoinHandle<_> = thread::spawn(|| {
@@ -770,7 +805,7 @@ impl<T> JoinInner<T> {
 ///
 /// Creation from [`thread::Builder::spawn`]:
 ///
-/// ```rust
+/// ```
 /// use std::thread;
 ///
 /// let builder = thread::Builder::new();
@@ -780,13 +815,31 @@ impl<T> JoinInner<T> {
 /// }).unwrap();
 /// ```
 ///
+/// [`Clone`]: ../../std/clone/trait.Clone.html
 /// [`thread::spawn`]: fn.spawn.html
 /// [`thread::Builder::spawn`]: struct.Builder.html#method.spawn
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct JoinHandle<T>(JoinInner<T>);
 
 impl<T> JoinHandle<T> {
-    /// Extracts a handle to the underlying thread
+    /// Extracts a handle to the underlying thread.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(thread_id)]
+    ///
+    /// use std::thread;
+    ///
+    /// let builder = thread::Builder::new();
+    ///
+    /// let join_handle: thread::JoinHandle<_> = builder.spawn(|| {
+    ///     // some work here
+    /// }).unwrap();
+    ///
+    /// let thread = join_handle.thread();
+    /// println!("thread id: {:?}", thread.id());
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn thread(&self) -> &Thread {
         &self.0.thread
@@ -794,8 +847,24 @@ impl<T> JoinHandle<T> {
 
     /// Waits for the associated thread to finish.
     ///
-    /// If the child thread panics, `Err` is returned with the parameter given
-    /// to `panic`.
+    /// If the child thread panics, [`Err`] is returned with the parameter given
+    /// to [`panic`].
+    ///
+    /// [`Err`]: ../../std/result/enum.Result.html#variant.Err
+    /// [`panic!`]: ../../std/macro.panic.html
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::thread;
+    ///
+    /// let builder = thread::Builder::new();
+    ///
+    /// let join_handle: thread::JoinHandle<_> = builder.spawn(|| {
+    ///     // some work here
+    /// }).unwrap();
+    /// join_handle.join().expect("Couldn't join on the associated thread");
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn join(mut self) -> Result<T> {
         self.0.join()
diff --git a/src/test/incremental/hashes/inherent_impls.rs b/src/test/incremental/hashes/inherent_impls.rs
index f7a390e8745..5c37bc13359 100644
--- a/src/test/incremental/hashes/inherent_impls.rs
+++ b/src/test/incremental/hashes/inherent_impls.rs
@@ -107,7 +107,7 @@ impl Foo {
     pub fn method_selfness(&self) { }
 }
 
-// Change Method Selfmutness -----------------------------------------------------------
+// Change Method Selfmutness ---------------------------------------------------
 #[cfg(cfail1)]
 impl Foo {
     pub fn method_selfmutness(&self) { }
@@ -126,3 +126,411 @@ impl Foo {
     pub fn method_selfmutness(&mut self) { }
 }
 
+
+
+// Add Method To Impl ----------------------------------------------------------
+#[cfg(cfail1)]
+impl Foo {
+    pub fn add_method_to_impl1(&self) { }
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+impl Foo {
+    #[rustc_clean(label="Hir", cfg="cfail2")]
+    #[rustc_clean(label="Hir", cfg="cfail3")]
+    #[rustc_metadata_clean(cfg="cfail2")]
+    #[rustc_metadata_clean(cfg="cfail3")]
+    pub fn add_method_to_impl1(&self) { }
+
+    #[rustc_dirty(label="Hir", cfg="cfail2")]
+    #[rustc_clean(label="Hir", cfg="cfail3")]
+    #[rustc_metadata_dirty(cfg="cfail2")]
+    #[rustc_metadata_clean(cfg="cfail3")]
+    pub fn add_method_to_impl2(&self) { }
+}
+
+
+
+// Add Method Parameter --------------------------------------------------------
+#[cfg(cfail1)]
+impl Foo {
+    pub fn add_method_parameter(&self) { }
+}
+
+#[cfg(not(cfail1))]
+#[rustc_clean(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_clean(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+impl Foo {
+    #[rustc_dirty(label="Hir", cfg="cfail2")]
+    #[rustc_clean(label="Hir", cfg="cfail3")]
+    #[rustc_metadata_dirty(cfg="cfail2")]
+    #[rustc_metadata_clean(cfg="cfail3")]
+    pub fn add_method_parameter(&self, _: i32) { }
+}
+
+
+
+// Change Method Parameter Name ------------------------------------------------
+#[cfg(cfail1)]
+impl Foo {
+    pub fn change_method_parameter_name(&self, a: i64) { }
+}
+
+#[cfg(not(cfail1))]
+#[rustc_clean(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_clean(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+impl Foo {
+    #[rustc_dirty(label="Hir", cfg="cfail2")]
+    #[rustc_clean(label="Hir", cfg="cfail3")]
+    #[rustc_metadata_dirty(cfg="cfail2")]
+    #[rustc_metadata_clean(cfg="cfail3")]
+    pub fn change_method_parameter_name(&self, b: i64) { }
+}
+
+
+
+// Change Method Return Type ---------------------------------------------------
+#[cfg(cfail1)]
+impl Foo {
+    pub fn change_method_return_type(&self) -> u16 { 0 }
+}
+
+#[cfg(not(cfail1))]
+#[rustc_clean(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_clean(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+impl Foo {
+    #[rustc_dirty(label="Hir", cfg="cfail2")]
+    #[rustc_clean(label="Hir", cfg="cfail3")]
+    #[rustc_metadata_dirty(cfg="cfail2")]
+    #[rustc_metadata_clean(cfg="cfail3")]
+    pub fn change_method_return_type(&self) -> u8 { 0 }
+}
+
+
+
+// Make Method #[inline] -------------------------------------------------------
+#[cfg(cfail1)]
+impl Foo {
+    pub fn make_method_inline(&self) -> u8 { 0 }
+}
+
+#[cfg(not(cfail1))]
+#[rustc_clean(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_clean(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+impl Foo {
+    #[rustc_dirty(label="Hir", cfg="cfail2")]
+    #[rustc_clean(label="Hir", cfg="cfail3")]
+    #[rustc_metadata_dirty(cfg="cfail2")]
+    #[rustc_metadata_clean(cfg="cfail3")]
+    #[inline]
+    pub fn make_method_inline(&self) -> u8 { 0 }
+}
+
+
+
+//  Change order of parameters -------------------------------------------------
+#[cfg(cfail1)]
+impl Foo {
+    pub fn change_method_parameter_order(&self, a: i64, b: i64) { }
+}
+
+#[cfg(not(cfail1))]
+#[rustc_clean(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_clean(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+impl Foo {
+    #[rustc_dirty(label="Hir", cfg="cfail2")]
+    #[rustc_clean(label="Hir", cfg="cfail3")]
+    #[rustc_metadata_dirty(cfg="cfail2")]
+    #[rustc_metadata_clean(cfg="cfail3")]
+    pub fn change_method_parameter_order(&self, b: i64, a: i64) { }
+}
+
+
+
+// Make method unsafe ----------------------------------------------------------
+#[cfg(cfail1)]
+impl Foo {
+    pub fn make_method_unsafe(&self) { }
+}
+
+#[cfg(not(cfail1))]
+#[rustc_clean(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_clean(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+impl Foo {
+    #[rustc_dirty(label="Hir", cfg="cfail2")]
+    #[rustc_clean(label="Hir", cfg="cfail3")]
+    #[rustc_metadata_dirty(cfg="cfail2")]
+    #[rustc_metadata_clean(cfg="cfail3")]
+    pub unsafe fn make_method_unsafe(&self) { }
+}
+
+
+
+// Make method extern ----------------------------------------------------------
+#[cfg(cfail1)]
+impl Foo {
+    pub fn make_method_extern(&self) { }
+}
+
+#[cfg(not(cfail1))]
+#[rustc_clean(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_clean(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+impl Foo {
+    #[rustc_dirty(label="Hir", cfg="cfail2")]
+    #[rustc_clean(label="Hir", cfg="cfail3")]
+    #[rustc_metadata_dirty(cfg="cfail2")]
+    #[rustc_metadata_clean(cfg="cfail3")]
+    pub extern fn make_method_extern(&self) { }
+}
+
+
+
+// Change method calling convention --------------------------------------------
+#[cfg(cfail1)]
+impl Foo {
+    pub extern "C" fn change_method_calling_convention(&self) { }
+}
+
+#[cfg(not(cfail1))]
+#[rustc_clean(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_clean(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+impl Foo {
+    #[rustc_dirty(label="Hir", cfg="cfail2")]
+    #[rustc_clean(label="Hir", cfg="cfail3")]
+    #[rustc_metadata_dirty(cfg="cfail2")]
+    #[rustc_metadata_clean(cfg="cfail3")]
+    pub extern "system" fn change_method_calling_convention(&self) { }
+}
+
+
+
+// Add Lifetime Parameter to Method --------------------------------------------
+#[cfg(cfail1)]
+impl Foo {
+    pub fn add_lifetime_parameter_to_method(&self) { }
+}
+
+#[cfg(not(cfail1))]
+#[rustc_clean(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_clean(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+impl Foo {
+    #[rustc_dirty(label="Hir", cfg="cfail2")]
+    #[rustc_clean(label="Hir", cfg="cfail3")]
+    #[rustc_metadata_dirty(cfg="cfail2")]
+    #[rustc_metadata_clean(cfg="cfail3")]
+    pub fn add_lifetime_parameter_to_method<'a>(&self) { }
+}
+
+
+
+// Add Type Parameter To Method ------------------------------------------------
+#[cfg(cfail1)]
+impl Foo {
+    pub fn add_type_parameter_to_method(&self) { }
+}
+
+#[cfg(not(cfail1))]
+#[rustc_clean(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_clean(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+impl Foo {
+    #[rustc_dirty(label="Hir", cfg="cfail2")]
+    #[rustc_clean(label="Hir", cfg="cfail3")]
+    #[rustc_metadata_dirty(cfg="cfail2")]
+    #[rustc_metadata_clean(cfg="cfail3")]
+    pub fn add_type_parameter_to_method<T>(&self) { }
+}
+
+
+
+// Add Lifetime Bound to Lifetime Parameter of Method --------------------------
+#[cfg(cfail1)]
+impl Foo {
+    pub fn add_lifetime_bound_to_lifetime_param_of_method<'a, 'b>(&self) { }
+}
+
+#[cfg(not(cfail1))]
+#[rustc_clean(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_clean(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+impl Foo {
+    #[rustc_dirty(label="Hir", cfg="cfail2")]
+    #[rustc_clean(label="Hir", cfg="cfail3")]
+    #[rustc_metadata_dirty(cfg="cfail2")]
+    #[rustc_metadata_clean(cfg="cfail3")]
+    pub fn add_lifetime_bound_to_lifetime_param_of_method<'a, 'b: 'a>(&self) { }
+}
+
+
+
+// Add Lifetime Bound to Type Parameter of Method ------------------------------
+#[cfg(cfail1)]
+impl Foo {
+    pub fn add_lifetime_bound_to_type_param_of_method<'a, T>(&self) { }
+}
+
+#[cfg(not(cfail1))]
+#[rustc_clean(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_clean(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+impl Foo {
+    #[rustc_dirty(label="Hir", cfg="cfail2")]
+    #[rustc_clean(label="Hir", cfg="cfail3")]
+    #[rustc_metadata_dirty(cfg="cfail2")]
+    #[rustc_metadata_clean(cfg="cfail3")]
+    pub fn add_lifetime_bound_to_type_param_of_method<'a, T: 'a>(&self) { }
+}
+
+
+
+// Add Trait Bound to Type Parameter of Method ------------------------------
+#[cfg(cfail1)]
+impl Foo {
+    pub fn add_trait_bound_to_type_param_of_method<T>(&self) { }
+}
+
+#[cfg(not(cfail1))]
+#[rustc_clean(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_clean(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+impl Foo {
+    #[rustc_dirty(label="Hir", cfg="cfail2")]
+    #[rustc_clean(label="Hir", cfg="cfail3")]
+    #[rustc_metadata_dirty(cfg="cfail2")]
+    #[rustc_metadata_clean(cfg="cfail3")]
+    pub fn add_trait_bound_to_type_param_of_method<T: Clone>(&self) { }
+}
+
+
+
+// Add #[no_mangle] to Method --------------------------------------------------
+#[cfg(cfail1)]
+impl Foo {
+    pub fn add_no_mangle_to_method(&self) { }
+}
+
+#[cfg(not(cfail1))]
+#[rustc_clean(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_clean(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+impl Foo {
+    #[rustc_dirty(label="Hir", cfg="cfail2")]
+    #[rustc_clean(label="Hir", cfg="cfail3")]
+    #[rustc_metadata_dirty(cfg="cfail2")]
+    #[rustc_metadata_clean(cfg="cfail3")]
+    #[no_mangle]
+    pub fn add_no_mangle_to_method(&self) { }
+}
+
+
+
+struct Bar<T>(T);
+
+// Add Type Parameter To Impl --------------------------------------------------
+#[cfg(cfail1)]
+impl Bar<u32> {
+    pub fn add_type_parameter_to_impl(&self) { }
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+impl<T> Bar<T> {
+    #[rustc_dirty(label="Hir", cfg="cfail2")]
+    #[rustc_clean(label="Hir", cfg="cfail3")]
+    #[rustc_metadata_dirty(cfg="cfail2")]
+    #[rustc_metadata_clean(cfg="cfail3")]
+    pub fn add_type_parameter_to_impl(&self) { }
+}
+
+
+
+// Change Self Type of Impl ----------------------------------------------------
+#[cfg(cfail1)]
+impl Bar<u32> {
+    pub fn change_impl_self_type(&self) { }
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+impl Bar<u64> {
+    #[rustc_dirty(label="Hir", cfg="cfail2")]
+    #[rustc_clean(label="Hir", cfg="cfail3")]
+    #[rustc_metadata_dirty(cfg="cfail2")]
+    #[rustc_metadata_clean(cfg="cfail3")]
+    pub fn change_impl_self_type(&self) { }
+}
+
+
+
+// Add Lifetime Bound to Impl --------------------------------------------------
+#[cfg(cfail1)]
+impl<T> Bar<T> {
+    pub fn add_lifetime_bound_to_impl_parameter(&self) { }
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+impl<T: 'static> Bar<T> {
+    #[rustc_dirty(label="Hir", cfg="cfail2")]
+    #[rustc_clean(label="Hir", cfg="cfail3")]
+    #[rustc_metadata_dirty(cfg="cfail2")]
+    #[rustc_metadata_clean(cfg="cfail3")]
+    pub fn add_lifetime_bound_to_impl_parameter(&self) { }
+}
+
+
+
+// Add Trait Bound to Impl Parameter -------------------------------------------
+#[cfg(cfail1)]
+impl<T> Bar<T> {
+    pub fn add_trait_bound_to_impl_parameter(&self) { }
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+impl<T: Clone> Bar<T> {
+    #[rustc_dirty(label="Hir", cfg="cfail2")]
+    #[rustc_clean(label="Hir", cfg="cfail3")]
+    #[rustc_metadata_dirty(cfg="cfail2")]
+    #[rustc_metadata_clean(cfg="cfail3")]
+    pub fn add_trait_bound_to_impl_parameter(&self) { }
+}
diff --git a/src/test/incremental/hashes/inline_asm.rs b/src/test/incremental/hashes/inline_asm.rs
new file mode 100644
index 00000000000..a1057c036d6
--- /dev/null
+++ b/src/test/incremental/hashes/inline_asm.rs
@@ -0,0 +1,265 @@
+// 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.
+
+
+// This test case tests the incremental compilation hash (ICH) implementation
+// for inline asm.
+
+// The general pattern followed here is: Change one thing between rev1 and rev2
+// and make sure that the hash has changed, then change nothing between rev2 and
+// rev3 and make sure that the hash has not changed.
+
+// must-compile-successfully
+// revisions: cfail1 cfail2 cfail3
+// compile-flags: -Z query-dep-graph
+
+#![allow(warnings)]
+#![feature(rustc_attrs)]
+#![feature(asm)]
+#![crate_type="rlib"]
+
+
+
+// Change template -------------------------------------------------------------
+#[cfg(cfail1)]
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+fn change_template(a: i32) -> i32 {
+    let c: i32;
+    unsafe {
+        asm!("add 1, $0"
+             : "=r"(c)
+             : "0"(a)
+             :
+             :
+             );
+    }
+    c
+}
+
+#[cfg(not(cfail1))]
+#[rustc_clean(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_dirty(label="HirBody", cfg="cfail2")]
+#[rustc_clean(label="HirBody", cfg="cfail3")]
+#[rustc_metadata_clean(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+fn change_template(a: i32) -> i32 {
+    let c: i32;
+    unsafe {
+        asm!("add 2, $0"
+             : "=r"(c)
+             : "0"(a)
+             :
+             :
+             );
+    }
+    c
+}
+
+
+
+// Change output -------------------------------------------------------------
+#[cfg(cfail1)]
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+fn change_output(a: i32) -> i32 {
+    let mut _out1: i32 = 0;
+    let mut _out2: i32 = 0;
+    unsafe {
+        asm!("add 1, $0"
+             : "=r"(_out1)
+             : "0"(a)
+             :
+             :
+             );
+    }
+    _out1
+}
+
+#[cfg(not(cfail1))]
+#[rustc_clean(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_dirty(label="HirBody", cfg="cfail2")]
+#[rustc_clean(label="HirBody", cfg="cfail3")]
+#[rustc_metadata_clean(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+fn change_output(a: i32) -> i32 {
+    let mut _out1: i32 = 0;
+    let mut _out2: i32 = 0;
+    unsafe {
+        asm!("add 1, $0"
+             : "=r"(_out2)
+             : "0"(a)
+             :
+             :
+             );
+    }
+    _out1
+}
+
+
+
+// Change input -------------------------------------------------------------
+#[cfg(cfail1)]
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+fn change_input(_a: i32, _b: i32) -> i32 {
+    let _out;
+    unsafe {
+        asm!("add 1, $0"
+             : "=r"(_out)
+             : "0"(_a)
+             :
+             :
+             );
+    }
+    _out
+}
+
+#[cfg(not(cfail1))]
+#[rustc_clean(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_dirty(label="HirBody", cfg="cfail2")]
+#[rustc_clean(label="HirBody", cfg="cfail3")]
+#[rustc_metadata_clean(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+fn change_input(_a: i32, _b: i32) -> i32 {
+    let _out;
+    unsafe {
+        asm!("add 1, $0"
+             : "=r"(_out)
+             : "0"(_b)
+             :
+             :
+             );
+    }
+    _out
+}
+
+
+
+// Change input constraint -----------------------------------------------------
+#[cfg(cfail1)]
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+fn change_input_constraint(_a: i32, _b: i32) -> i32 {
+    let _out;
+    unsafe {
+        asm!("add 1, $0"
+             : "=r"(_out)
+             : "0"(_a), "r"(_b)
+             :
+             :
+             );
+    }
+    _out
+}
+
+#[cfg(not(cfail1))]
+#[rustc_clean(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_dirty(label="HirBody", cfg="cfail2")]
+#[rustc_clean(label="HirBody", cfg="cfail3")]
+#[rustc_metadata_clean(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+fn change_input_constraint(_a: i32, _b: i32) -> i32 {
+    let _out;
+    unsafe {
+        asm!("add 1, $0"
+             : "=r"(_out)
+             : "r"(_a), "0"(_b)
+             :
+             :
+             );
+    }
+    _out
+}
+
+
+
+// Change clobber --------------------------------------------------------------
+#[cfg(cfail1)]
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+fn change_clobber(_a: i32) -> i32 {
+    let _out;
+    unsafe {
+        asm!("add 1, $0"
+             : "=r"(_out)
+             : "0"(_a)
+             :
+             :
+             );
+    }
+    _out
+}
+
+#[cfg(not(cfail1))]
+#[rustc_clean(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_dirty(label="HirBody", cfg="cfail2")]
+#[rustc_clean(label="HirBody", cfg="cfail3")]
+#[rustc_metadata_clean(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+fn change_clobber(_a: i32) -> i32 {
+    let _out;
+    unsafe {
+        asm!("add 1, $0"
+             : "=r"(_out)
+             : "0"(_a)
+             : "eax"
+             :
+             );
+    }
+    _out
+}
+
+
+
+// Change options --------------------------------------------------------------
+#[cfg(cfail1)]
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+fn change_options(_a: i32) -> i32 {
+    let _out;
+    unsafe {
+        asm!("add 1, $0"
+             : "=r"(_out)
+             : "0"(_a)
+             :
+             :
+             );
+    }
+    _out
+}
+
+#[cfg(not(cfail1))]
+#[rustc_clean(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_dirty(label="HirBody", cfg="cfail2")]
+#[rustc_clean(label="HirBody", cfg="cfail3")]
+#[rustc_metadata_clean(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+fn change_options(_a: i32) -> i32 {
+    let _out;
+    unsafe {
+        asm!("add 1, $0"
+             : "=r"(_out)
+             : "0"(_a)
+             :
+             : "volatile"
+             );
+    }
+    _out
+}
+
+
+