about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-05-04 23:15:00 +0000
committerbors <bors@rust-lang.org>2018-05-04 23:15:00 +0000
commit1d168261a1bc0031ef27de735992a4842fd62553 (patch)
treec53c956b4e906922c9de96ec644394b5c1114815 /src
parent91db9dcf3730207f63b3dfc33b2c438a769b7517 (diff)
parent6f2d023028bbd666be2c211b923b32faf10a41da (diff)
Auto merge of #50084 - killercup:compiletest-rustfix, r=Manishearth
First step towards rustfix compiletest mode

This is the first small step towards testing auto-fixable compiler
suggestions using compiletest. Currently, it only checks if next to a
UI test there also happens to a `*.rs.fixed` file, and then uses rustfix
(added as external crate) on the original file, and asserts that it
produces the fixed version.

To show that this works, I've included one such test. I picked this test
case at random (and because it was simple) -- It is not relevant to the
2018 edition. Indeed, in the near future, we want to be able to restrict
rustfix to edition-lints, so this test cast might go away soon.

In case you still think this is somewhat feature-complete, here's a
quick list of things currently missing that I want to add before telling
people they can use this:

- [x] Make this an actual compiletest mode, with `test [fix] …` output
  and everything
- [x] Assert that fixed files still compile
- [x] Assert that fixed files produce no (or a known set of) diagnostics
  output
- [x] Update `update-references.sh` to support rustfix
- [x] Use a published version of rustfix (i.e.: publish a new version
  rustfix that exposes a useful API for this)
Diffstat (limited to 'src')
-rw-r--r--src/Cargo.lock13
-rw-r--r--src/test/rustfix/closure-immutable-outer-variable.fixed20
-rw-r--r--src/test/rustfix/closure-immutable-outer-variable.rs20
-rw-r--r--src/test/rustfix/empty-no-fixes.fixed11
-rw-r--r--src/test/rustfix/empty-no-fixes.rs11
-rw-r--r--src/test/rustfix/empty-no-fixes.rs.fixed12
-rw-r--r--src/test/rustfix/issue-45562.fixed13
-rw-r--r--src/test/rustfix/issue-45562.rs13
-rw-r--r--src/test/rustfix/issue-45799-bad-extern-crate-rename-suggestion-formatting.fixed12
-rw-r--r--src/test/rustfix/issue-45799-bad-extern-crate-rename-suggestion-formatting.rs12
-rw-r--r--src/test/rustfix/issue-46756-consider-borrowing-cast-or-binexpr.fixed22
-rw-r--r--src/test/rustfix/issue-46756-consider-borrowing-cast-or-binexpr.rs22
-rw-r--r--src/test/rustfix/main-no-fixes.fixed11
-rw-r--r--src/test/rustfix/main-no-fixes.rs11
-rw-r--r--src/test/rustfix/main-no-fixes.rs.fixed11
-rw-r--r--src/test/rustfix/missing-comma-in-match.fixed17
-rw-r--r--src/test/rustfix/missing-comma-in-match.rs17
-rw-r--r--src/test/rustfix/str-as-char.fixed13
-rw-r--r--src/test/rustfix/str-as-char.rs13
-rw-r--r--src/test/rustfix/tuple-float-index.fixed15
-rw-r--r--src/test/rustfix/tuple-float-index.rs15
-rwxr-xr-xsrc/test/rustfix/update-all-references.sh31
-rwxr-xr-xsrc/test/rustfix/update-references.sh45
-rw-r--r--src/test/ui/suggestions/closure-immutable-outer-variable.fixed22
-rw-r--r--src/test/ui/suggestions/closure-immutable-outer-variable.nll.fixed22
-rw-r--r--src/test/ui/suggestions/closure-immutable-outer-variable.nll.stderr2
-rw-r--r--src/test/ui/suggestions/closure-immutable-outer-variable.rs2
-rw-r--r--src/test/ui/suggestions/closure-immutable-outer-variable.rs.fixed20
-rw-r--r--src/test/ui/suggestions/closure-immutable-outer-variable.stderr2
-rw-r--r--src/test/ui/suggestions/issue-45562.fixed16
-rw-r--r--src/test/ui/suggestions/issue-45562.rs2
-rw-r--r--src/test/ui/suggestions/issue-45562.stderr2
-rw-r--r--src/test/ui/suggestions/issue-45799-bad-extern-crate-rename-suggestion-formatting.fixed15
-rw-r--r--src/test/ui/suggestions/issue-45799-bad-extern-crate-rename-suggestion-formatting.rs2
-rw-r--r--src/test/ui/suggestions/issue-45799-bad-extern-crate-rename-suggestion-formatting.stderr2
-rw-r--r--src/test/ui/suggestions/issue-46756-consider-borrowing-cast-or-binexpr.fixed26
-rw-r--r--src/test/ui/suggestions/issue-46756-consider-borrowing-cast-or-binexpr.rs2
-rw-r--r--src/test/ui/suggestions/issue-46756-consider-borrowing-cast-or-binexpr.stderr4
-rw-r--r--src/test/ui/suggestions/missing-comma-in-match.fixed21
-rw-r--r--src/test/ui/suggestions/missing-comma-in-match.rs2
-rw-r--r--src/test/ui/suggestions/missing-comma-in-match.stderr2
-rw-r--r--src/test/ui/suggestions/str-as-char.fixed16
-rw-r--r--src/test/ui/suggestions/str-as-char.rs2
-rw-r--r--src/test/ui/suggestions/str-as-char.stderr2
-rw-r--r--src/test/ui/suggestions/tuple-float-index.fixed16
-rw-r--r--src/test/ui/suggestions/tuple-float-index.rs1
-rw-r--r--src/test/ui/suggestions/tuple-float-index.stderr2
-rwxr-xr-xsrc/test/ui/update-references.sh4
-rw-r--r--src/tools/compiletest/Cargo.toml1
-rw-r--r--src/tools/compiletest/src/common.rs43
-rw-r--r--src/tools/compiletest/src/header.rs10
-rw-r--r--src/tools/compiletest/src/main.rs1
-rw-r--r--src/tools/compiletest/src/runtest.rs36
53 files changed, 647 insertions, 33 deletions
diff --git a/src/Cargo.lock b/src/Cargo.lock
index ccdb24d7375..0f08eaf596a 100644
--- a/src/Cargo.lock
+++ b/src/Cargo.lock
@@ -394,6 +394,7 @@ dependencies = [
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "miow 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustfix 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2235,6 +2236,17 @@ dependencies = [
 ]
 
 [[package]]
+name = "rustfix"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "rustfmt-nightly"
 version = "0.6.1"
 dependencies = [
@@ -3146,6 +3158,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum rustc-ap-syntax_pos 113.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "55793c2a775230c42661194c48d44b35d4c8439d79ad8528e56651e854c48c63"
 "checksum rustc-demangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11fb43a206a04116ffd7cfcf9bcb941f8eb6cc7ff667272246b0a1c74259a3cb"
 "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
+"checksum rustfix 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "165a212dd11124d7070892da20f71d82970ef1d1dd41cd804b70f39740a21c85"
 "checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7"
 "checksum same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cfb6eded0b06a0b512c8ddbcf04089138c9b4362c2f696f3c3d76039d68f3637"
 "checksum schannel 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "85fd9df495640643ad2d00443b3d78aae69802ad488debab4f1dd52fc1806ade"
diff --git a/src/test/rustfix/closure-immutable-outer-variable.fixed b/src/test/rustfix/closure-immutable-outer-variable.fixed
new file mode 100644
index 00000000000..bddc2eab16d
--- /dev/null
+++ b/src/test/rustfix/closure-immutable-outer-variable.fixed
@@ -0,0 +1,20 @@
+// Copyright 2017 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.
+
+// Point at the captured immutable outer variable
+
+fn foo(mut f: Box<FnMut()>) {
+    f();
+}
+
+fn main() {
+    let mut y = true;
+    foo(Box::new(move || y = false) as Box<_>);
+}
diff --git a/src/test/rustfix/closure-immutable-outer-variable.rs b/src/test/rustfix/closure-immutable-outer-variable.rs
new file mode 100644
index 00000000000..fe8e2bc6c8e
--- /dev/null
+++ b/src/test/rustfix/closure-immutable-outer-variable.rs
@@ -0,0 +1,20 @@
+// Copyright 2017 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.
+
+// Point at the captured immutable outer variable
+
+fn foo(mut f: Box<FnMut()>) {
+    f();
+}
+
+fn main() {
+    let y = true;
+    foo(Box::new(move || y = false) as Box<_>);
+}
diff --git a/src/test/rustfix/empty-no-fixes.fixed b/src/test/rustfix/empty-no-fixes.fixed
new file mode 100644
index 00000000000..39e19566d76
--- /dev/null
+++ b/src/test/rustfix/empty-no-fixes.fixed
@@ -0,0 +1,11 @@
+// Copyright 2018 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:--crate-type lib
diff --git a/src/test/rustfix/empty-no-fixes.rs b/src/test/rustfix/empty-no-fixes.rs
new file mode 100644
index 00000000000..39e19566d76
--- /dev/null
+++ b/src/test/rustfix/empty-no-fixes.rs
@@ -0,0 +1,11 @@
+// Copyright 2018 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:--crate-type lib
diff --git a/src/test/rustfix/empty-no-fixes.rs.fixed b/src/test/rustfix/empty-no-fixes.rs.fixed
new file mode 100644
index 00000000000..ee58e778253
--- /dev/null
+++ b/src/test/rustfix/empty-no-fixes.rs.fixed
@@ -0,0 +1,12 @@
+// Copyright 2018 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:--crate-type lib
+fn foo() {}
diff --git a/src/test/rustfix/issue-45562.fixed b/src/test/rustfix/issue-45562.fixed
new file mode 100644
index 00000000000..d7a27a11fc0
--- /dev/null
+++ b/src/test/rustfix/issue-45562.fixed
@@ -0,0 +1,13 @@
+// Copyright 2018 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.
+
+#[no_mangle] pub static RAH: usize = 5;
+
+fn main() {}
diff --git a/src/test/rustfix/issue-45562.rs b/src/test/rustfix/issue-45562.rs
new file mode 100644
index 00000000000..39576e9c845
--- /dev/null
+++ b/src/test/rustfix/issue-45562.rs
@@ -0,0 +1,13 @@
+// Copyright 2018 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.
+
+#[no_mangle] pub const RAH: usize = 5;
+
+fn main() {}
diff --git a/src/test/rustfix/issue-45799-bad-extern-crate-rename-suggestion-formatting.fixed b/src/test/rustfix/issue-45799-bad-extern-crate-rename-suggestion-formatting.fixed
new file mode 100644
index 00000000000..d931f90cd04
--- /dev/null
+++ b/src/test/rustfix/issue-45799-bad-extern-crate-rename-suggestion-formatting.fixed
@@ -0,0 +1,12 @@
+// Copyright 2017 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.
+
+extern crate std as other_std;
+fn main() {}
diff --git a/src/test/rustfix/issue-45799-bad-extern-crate-rename-suggestion-formatting.rs b/src/test/rustfix/issue-45799-bad-extern-crate-rename-suggestion-formatting.rs
new file mode 100644
index 00000000000..7c55f9c4eb9
--- /dev/null
+++ b/src/test/rustfix/issue-45799-bad-extern-crate-rename-suggestion-formatting.rs
@@ -0,0 +1,12 @@
+// Copyright 2017 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.
+
+extern crate std;
+fn main() {}
diff --git a/src/test/rustfix/issue-46756-consider-borrowing-cast-or-binexpr.fixed b/src/test/rustfix/issue-46756-consider-borrowing-cast-or-binexpr.fixed
new file mode 100644
index 00000000000..aaa04ef4004
--- /dev/null
+++ b/src/test/rustfix/issue-46756-consider-borrowing-cast-or-binexpr.fixed
@@ -0,0 +1,22 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(unused)]
+
+fn light_flows_our_war_of_mocking_words(and_yet: &usize) -> usize {
+    and_yet + 1
+}
+
+fn main() {
+    let behold: isize = 2;
+    let with_tears: usize = 3;
+    light_flows_our_war_of_mocking_words(&(behold as usize));
+    light_flows_our_war_of_mocking_words(&(with_tears + 4));
+}
diff --git a/src/test/rustfix/issue-46756-consider-borrowing-cast-or-binexpr.rs b/src/test/rustfix/issue-46756-consider-borrowing-cast-or-binexpr.rs
new file mode 100644
index 00000000000..d21681747e9
--- /dev/null
+++ b/src/test/rustfix/issue-46756-consider-borrowing-cast-or-binexpr.rs
@@ -0,0 +1,22 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(unused)]
+
+fn light_flows_our_war_of_mocking_words(and_yet: &usize) -> usize {
+    and_yet + 1
+}
+
+fn main() {
+    let behold: isize = 2;
+    let with_tears: usize = 3;
+    light_flows_our_war_of_mocking_words(behold as usize);
+    light_flows_our_war_of_mocking_words(with_tears + 4);
+}
diff --git a/src/test/rustfix/main-no-fixes.fixed b/src/test/rustfix/main-no-fixes.fixed
new file mode 100644
index 00000000000..3f07b46791d
--- /dev/null
+++ b/src/test/rustfix/main-no-fixes.fixed
@@ -0,0 +1,11 @@
+// Copyright 2018 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() {}
diff --git a/src/test/rustfix/main-no-fixes.rs b/src/test/rustfix/main-no-fixes.rs
new file mode 100644
index 00000000000..3f07b46791d
--- /dev/null
+++ b/src/test/rustfix/main-no-fixes.rs
@@ -0,0 +1,11 @@
+// Copyright 2018 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() {}
diff --git a/src/test/rustfix/main-no-fixes.rs.fixed b/src/test/rustfix/main-no-fixes.rs.fixed
new file mode 100644
index 00000000000..3f07b46791d
--- /dev/null
+++ b/src/test/rustfix/main-no-fixes.rs.fixed
@@ -0,0 +1,11 @@
+// Copyright 2018 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() {}
diff --git a/src/test/rustfix/missing-comma-in-match.fixed b/src/test/rustfix/missing-comma-in-match.fixed
new file mode 100644
index 00000000000..621a4127bc2
--- /dev/null
+++ b/src/test/rustfix/missing-comma-in-match.fixed
@@ -0,0 +1,17 @@
+// Copyright 2018 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 &Some(3) {
+        &None => 1,
+        &Some(2) => { 3 }
+        _ => 2
+    };
+}
diff --git a/src/test/rustfix/missing-comma-in-match.rs b/src/test/rustfix/missing-comma-in-match.rs
new file mode 100644
index 00000000000..8ccad7b9c94
--- /dev/null
+++ b/src/test/rustfix/missing-comma-in-match.rs
@@ -0,0 +1,17 @@
+// Copyright 2018 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 &Some(3) {
+        &None => 1
+        &Some(2) => { 3 }
+        _ => 2
+    };
+}
diff --git a/src/test/rustfix/str-as-char.fixed b/src/test/rustfix/str-as-char.fixed
new file mode 100644
index 00000000000..0ace6d96613
--- /dev/null
+++ b/src/test/rustfix/str-as-char.fixed
@@ -0,0 +1,13 @@
+// Copyright 2017 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() {
+    println!("●●");
+}
diff --git a/src/test/rustfix/str-as-char.rs b/src/test/rustfix/str-as-char.rs
new file mode 100644
index 00000000000..fa0e474fc7f
--- /dev/null
+++ b/src/test/rustfix/str-as-char.rs
@@ -0,0 +1,13 @@
+// Copyright 2017 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() {
+    println!('●●');
+}
diff --git a/src/test/rustfix/tuple-float-index.fixed b/src/test/rustfix/tuple-float-index.fixed
new file mode 100644
index 00000000000..9cb7537b428
--- /dev/null
+++ b/src/test/rustfix/tuple-float-index.fixed
@@ -0,0 +1,15 @@
+// Copyright 2012 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: -Z parse-only
+
+fn main () {
+    ((1, (2, 3)).1).1;
+}
diff --git a/src/test/rustfix/tuple-float-index.rs b/src/test/rustfix/tuple-float-index.rs
new file mode 100644
index 00000000000..8bfbd0e74db
--- /dev/null
+++ b/src/test/rustfix/tuple-float-index.rs
@@ -0,0 +1,15 @@
+// Copyright 2012 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: -Z parse-only
+
+fn main () {
+    (1, (2, 3)).1.1;
+}
diff --git a/src/test/rustfix/update-all-references.sh b/src/test/rustfix/update-all-references.sh
new file mode 100755
index 00000000000..c3f615066bb
--- /dev/null
+++ b/src/test/rustfix/update-all-references.sh
@@ -0,0 +1,31 @@
+#!/usr/bin/env bash
+#
+# 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.
+
+# A script to update the references for all tests. The idea is that
+# you do a run, which will generate files in the build directory
+# containing the (normalized) actual output of the compiler. You then
+# run this script, which will copy those files over. If you find
+# yourself manually editing a foo.stderr file, you're doing it wrong.
+#
+# See all `update-references.sh`, if you just want to update a single test.
+
+if [[ "$1" == "--help" || "$1" == "-h" || "$1" == "" || "$2" != "" ]]; then
+    echo "usage: $0 <build-directory>"
+    echo ""
+    echo "For example:"
+    echo "   $0 ../../../build/x86_64-apple-darwin/test/rustfix"
+fi
+
+BUILD_DIR=$PWD/$1
+MY_DIR=$(dirname $0)
+cd $MY_DIR
+find . -name '*.rs' | xargs ./update-references.sh $BUILD_DIR
diff --git a/src/test/rustfix/update-references.sh b/src/test/rustfix/update-references.sh
new file mode 100755
index 00000000000..bcca2fec10d
--- /dev/null
+++ b/src/test/rustfix/update-references.sh
@@ -0,0 +1,45 @@
+#!/usr/bin/env bash
+#
+# 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.
+
+# A script to update the references for particular tests. The idea is
+# that you do a run, which will generate files in the build directory
+# containing the (normalized) actual output of the compiler. This
+# script will then copy that output and replace the "expected output"
+# files. You can then commit the changes.
+#
+# If you find yourself manually editing a foo.stderr file, you're
+# doing it wrong.
+
+if [[ "$1" == "--help" || "$1" == "-h" || "$1" == "" || "$2" == "" ]]; then
+    echo "usage: $0 <build-directory> <relative-path-to-rs-files>"
+    echo ""
+    echo "For example:"
+    echo "   $0 ../../../build/x86_64-apple-darwin/test/rustfix *.rs */*.rs"
+fi
+
+MYDIR=$(dirname $0)
+
+BUILD_DIR="$1"
+shift
+
+shopt -s nullglob
+
+while [[ "$1" != "" ]]; do
+    for OUT_NAME in $BUILD_DIR/${1%.rs}.*fixed; do
+        OUT_BASE=`basename "$OUT_NAME"`
+        if ! (diff $OUT_NAME $MYDIR/$OUT_BASE >& /dev/null); then
+            echo updating $MYDIR/$OUT_BASE
+            cp $OUT_NAME $MYDIR
+        fi
+    done
+    shift
+done
diff --git a/src/test/ui/suggestions/closure-immutable-outer-variable.fixed b/src/test/ui/suggestions/closure-immutable-outer-variable.fixed
new file mode 100644
index 00000000000..b3a0d592f76
--- /dev/null
+++ b/src/test/ui/suggestions/closure-immutable-outer-variable.fixed
@@ -0,0 +1,22 @@
+// Copyright 2017 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.
+
+// run-rustfix
+
+// Point at the captured immutable outer variable
+
+fn foo(mut f: Box<FnMut()>) {
+    f();
+}
+
+fn main() {
+    let mut y = true;
+    foo(Box::new(move || y = false) as Box<_>); //~ ERROR cannot assign to captured outer variable
+}
diff --git a/src/test/ui/suggestions/closure-immutable-outer-variable.nll.fixed b/src/test/ui/suggestions/closure-immutable-outer-variable.nll.fixed
new file mode 100644
index 00000000000..e162678460c
--- /dev/null
+++ b/src/test/ui/suggestions/closure-immutable-outer-variable.nll.fixed
@@ -0,0 +1,22 @@
+// Copyright 2017 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.
+
+// run-rustfix
+
+// Point at the captured immutable outer variable
+
+fn foo(mut f: Box<FnMut()>) {
+    f();
+}
+
+fn main() {
+    let y = true;
+    foo(Box::new(move || y = false) as Box<_>); //~ ERROR cannot assign to captured outer variable
+}
diff --git a/src/test/ui/suggestions/closure-immutable-outer-variable.nll.stderr b/src/test/ui/suggestions/closure-immutable-outer-variable.nll.stderr
index e4e93ecac8e..bc655114c2b 100644
--- a/src/test/ui/suggestions/closure-immutable-outer-variable.nll.stderr
+++ b/src/test/ui/suggestions/closure-immutable-outer-variable.nll.stderr
@@ -1,5 +1,5 @@
 error[E0594]: cannot assign to immutable item `y`
-  --> $DIR/closure-immutable-outer-variable.rs:19:26
+  --> $DIR/closure-immutable-outer-variable.rs:21:26
    |
 LL |     foo(Box::new(move || y = false) as Box<_>); //~ ERROR cannot assign to captured outer variable
    |                          ^^^^^^^^^ cannot mutate
diff --git a/src/test/ui/suggestions/closure-immutable-outer-variable.rs b/src/test/ui/suggestions/closure-immutable-outer-variable.rs
index 1d14afd6a01..e162678460c 100644
--- a/src/test/ui/suggestions/closure-immutable-outer-variable.rs
+++ b/src/test/ui/suggestions/closure-immutable-outer-variable.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// run-rustfix
+
 // Point at the captured immutable outer variable
 
 fn foo(mut f: Box<FnMut()>) {
diff --git a/src/test/ui/suggestions/closure-immutable-outer-variable.rs.fixed b/src/test/ui/suggestions/closure-immutable-outer-variable.rs.fixed
new file mode 100644
index 00000000000..80a5a45a305
--- /dev/null
+++ b/src/test/ui/suggestions/closure-immutable-outer-variable.rs.fixed
@@ -0,0 +1,20 @@
+// Copyright 2017 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.
+
+// Point at the captured immutable outer variable
+
+fn foo(mut f: Box<FnMut()>) {
+    f();
+}
+
+fn main() {
+    let mut y = true;
+    foo(Box::new(move || y = false) as Box<_>); //~ ERROR cannot assign to captured outer variable
+}
diff --git a/src/test/ui/suggestions/closure-immutable-outer-variable.stderr b/src/test/ui/suggestions/closure-immutable-outer-variable.stderr
index 3353e2c7291..0ee11d8cf15 100644
--- a/src/test/ui/suggestions/closure-immutable-outer-variable.stderr
+++ b/src/test/ui/suggestions/closure-immutable-outer-variable.stderr
@@ -1,5 +1,5 @@
 error[E0594]: cannot assign to captured outer variable in an `FnMut` closure
-  --> $DIR/closure-immutable-outer-variable.rs:19:26
+  --> $DIR/closure-immutable-outer-variable.rs:21:26
    |
 LL |     let y = true;
    |         - help: consider making `y` mutable: `mut y`
diff --git a/src/test/ui/suggestions/issue-45562.fixed b/src/test/ui/suggestions/issue-45562.fixed
new file mode 100644
index 00000000000..7c01f0d1ee5
--- /dev/null
+++ b/src/test/ui/suggestions/issue-45562.fixed
@@ -0,0 +1,16 @@
+// Copyright 2018 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.
+
+// run-rustfix
+
+#[no_mangle] pub static RAH: usize = 5;
+//~^ ERROR const items should never be #[no_mangle]
+
+fn main() {}
diff --git a/src/test/ui/suggestions/issue-45562.rs b/src/test/ui/suggestions/issue-45562.rs
index f493df56f94..c27d52fcdd3 100644
--- a/src/test/ui/suggestions/issue-45562.rs
+++ b/src/test/ui/suggestions/issue-45562.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// run-rustfix
+
 #[no_mangle] pub const RAH: usize = 5;
 //~^ ERROR const items should never be #[no_mangle]
 
diff --git a/src/test/ui/suggestions/issue-45562.stderr b/src/test/ui/suggestions/issue-45562.stderr
index d6960dca054..d9e624cadc7 100644
--- a/src/test/ui/suggestions/issue-45562.stderr
+++ b/src/test/ui/suggestions/issue-45562.stderr
@@ -1,5 +1,5 @@
 error: const items should never be #[no_mangle]
-  --> $DIR/issue-45562.rs:11:14
+  --> $DIR/issue-45562.rs:13:14
    |
 LL | #[no_mangle] pub const RAH: usize = 5;
    |              ---------^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/suggestions/issue-45799-bad-extern-crate-rename-suggestion-formatting.fixed b/src/test/ui/suggestions/issue-45799-bad-extern-crate-rename-suggestion-formatting.fixed
new file mode 100644
index 00000000000..e3287030408
--- /dev/null
+++ b/src/test/ui/suggestions/issue-45799-bad-extern-crate-rename-suggestion-formatting.fixed
@@ -0,0 +1,15 @@
+// Copyright 2017 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.
+
+// run-rustfix
+
+extern crate std as other_std;
+fn main() {}
+//~^^ ERROR the name `std` is defined multiple times [E0259]
diff --git a/src/test/ui/suggestions/issue-45799-bad-extern-crate-rename-suggestion-formatting.rs b/src/test/ui/suggestions/issue-45799-bad-extern-crate-rename-suggestion-formatting.rs
index 4d75127b645..f47ea474d51 100644
--- a/src/test/ui/suggestions/issue-45799-bad-extern-crate-rename-suggestion-formatting.rs
+++ b/src/test/ui/suggestions/issue-45799-bad-extern-crate-rename-suggestion-formatting.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// run-rustfix
+
 extern crate std;
 fn main() {}
 //~^^ ERROR the name `std` is defined multiple times [E0259]
diff --git a/src/test/ui/suggestions/issue-45799-bad-extern-crate-rename-suggestion-formatting.stderr b/src/test/ui/suggestions/issue-45799-bad-extern-crate-rename-suggestion-formatting.stderr
index 8e2b2d845e9..ecdfec2b3bf 100644
--- a/src/test/ui/suggestions/issue-45799-bad-extern-crate-rename-suggestion-formatting.stderr
+++ b/src/test/ui/suggestions/issue-45799-bad-extern-crate-rename-suggestion-formatting.stderr
@@ -1,5 +1,5 @@
 error[E0259]: the name `std` is defined multiple times
-  --> $DIR/issue-45799-bad-extern-crate-rename-suggestion-formatting.rs:11:1
+  --> $DIR/issue-45799-bad-extern-crate-rename-suggestion-formatting.rs:13:1
    |
 LL | extern crate std;
    | ^^^^^^^^^^^^^^^^^ `std` reimported here
diff --git a/src/test/ui/suggestions/issue-46756-consider-borrowing-cast-or-binexpr.fixed b/src/test/ui/suggestions/issue-46756-consider-borrowing-cast-or-binexpr.fixed
new file mode 100644
index 00000000000..77171cad6e7
--- /dev/null
+++ b/src/test/ui/suggestions/issue-46756-consider-borrowing-cast-or-binexpr.fixed
@@ -0,0 +1,26 @@
+// Copyright 2017 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.
+
+// run-rustfix
+
+#![allow(unused)]
+
+fn light_flows_our_war_of_mocking_words(and_yet: &usize) -> usize {
+    and_yet + 1
+}
+
+fn main() {
+    let behold: isize = 2;
+    let with_tears: usize = 3;
+    light_flows_our_war_of_mocking_words(&(behold as usize));
+    //~^ ERROR mismatched types [E0308]
+    light_flows_our_war_of_mocking_words(&(with_tears + 4));
+    //~^ ERROR mismatched types [E0308]
+}
diff --git a/src/test/ui/suggestions/issue-46756-consider-borrowing-cast-or-binexpr.rs b/src/test/ui/suggestions/issue-46756-consider-borrowing-cast-or-binexpr.rs
index 5617c46afa9..e5ea9b5ed09 100644
--- a/src/test/ui/suggestions/issue-46756-consider-borrowing-cast-or-binexpr.rs
+++ b/src/test/ui/suggestions/issue-46756-consider-borrowing-cast-or-binexpr.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// run-rustfix
+
 #![allow(unused)]
 
 fn light_flows_our_war_of_mocking_words(and_yet: &usize) -> usize {
diff --git a/src/test/ui/suggestions/issue-46756-consider-borrowing-cast-or-binexpr.stderr b/src/test/ui/suggestions/issue-46756-consider-borrowing-cast-or-binexpr.stderr
index e89e9dce94d..9c492751ca1 100644
--- a/src/test/ui/suggestions/issue-46756-consider-borrowing-cast-or-binexpr.stderr
+++ b/src/test/ui/suggestions/issue-46756-consider-borrowing-cast-or-binexpr.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/issue-46756-consider-borrowing-cast-or-binexpr.rs:20:42
+  --> $DIR/issue-46756-consider-borrowing-cast-or-binexpr.rs:22:42
    |
 LL |     light_flows_our_war_of_mocking_words(behold as usize);
    |                                          ^^^^^^^^^^^^^^^
@@ -11,7 +11,7 @@ LL |     light_flows_our_war_of_mocking_words(behold as usize);
               found type `usize`
 
 error[E0308]: mismatched types
-  --> $DIR/issue-46756-consider-borrowing-cast-or-binexpr.rs:22:42
+  --> $DIR/issue-46756-consider-borrowing-cast-or-binexpr.rs:24:42
    |
 LL |     light_flows_our_war_of_mocking_words(with_tears + 4);
    |                                          ^^^^^^^^^^^^^^
diff --git a/src/test/ui/suggestions/missing-comma-in-match.fixed b/src/test/ui/suggestions/missing-comma-in-match.fixed
new file mode 100644
index 00000000000..4832f35f42d
--- /dev/null
+++ b/src/test/ui/suggestions/missing-comma-in-match.fixed
@@ -0,0 +1,21 @@
+// Copyright 2018 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.
+
+// run-rustfix
+
+fn main() {
+    match &Some(3) {
+        &None => 1,
+        &Some(2) => { 3 }
+        //~^ ERROR expected one of `,`, `.`, `?`, `}`, or an operator, found `=>`
+        //~| NOTE expected one of `,`, `.`, `?`, `}`, or an operator here
+        _ => 2
+    };
+}
diff --git a/src/test/ui/suggestions/missing-comma-in-match.rs b/src/test/ui/suggestions/missing-comma-in-match.rs
index 6f86cdea3cf..e39b20e77ea 100644
--- a/src/test/ui/suggestions/missing-comma-in-match.rs
+++ b/src/test/ui/suggestions/missing-comma-in-match.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// run-rustfix
+
 fn main() {
     match &Some(3) {
         &None => 1
diff --git a/src/test/ui/suggestions/missing-comma-in-match.stderr b/src/test/ui/suggestions/missing-comma-in-match.stderr
index b71a50b6631..77935934107 100644
--- a/src/test/ui/suggestions/missing-comma-in-match.stderr
+++ b/src/test/ui/suggestions/missing-comma-in-match.stderr
@@ -1,5 +1,5 @@
 error: expected one of `,`, `.`, `?`, `}`, or an operator, found `=>`
-  --> $DIR/missing-comma-in-match.rs:14:18
+  --> $DIR/missing-comma-in-match.rs:16:18
    |
 LL |         &None => 1
    |                   - help: missing a comma here to end this `match` arm
diff --git a/src/test/ui/suggestions/str-as-char.fixed b/src/test/ui/suggestions/str-as-char.fixed
new file mode 100644
index 00000000000..c0dad38e436
--- /dev/null
+++ b/src/test/ui/suggestions/str-as-char.fixed
@@ -0,0 +1,16 @@
+// Copyright 2017 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.
+
+// run-rustfix
+
+fn main() {
+    println!("●●");
+    //~^ ERROR character literal may only contain one codepoint
+}
diff --git a/src/test/ui/suggestions/str-as-char.rs b/src/test/ui/suggestions/str-as-char.rs
index 09aca61147d..b5a5df0af7f 100644
--- a/src/test/ui/suggestions/str-as-char.rs
+++ b/src/test/ui/suggestions/str-as-char.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// run-rustfix
+
 fn main() {
     println!('●●');
     //~^ ERROR character literal may only contain one codepoint
diff --git a/src/test/ui/suggestions/str-as-char.stderr b/src/test/ui/suggestions/str-as-char.stderr
index d881becf00c..60eb182adf1 100644
--- a/src/test/ui/suggestions/str-as-char.stderr
+++ b/src/test/ui/suggestions/str-as-char.stderr
@@ -1,5 +1,5 @@
 error: character literal may only contain one codepoint
-  --> $DIR/str-as-char.rs:12:14
+  --> $DIR/str-as-char.rs:14:14
    |
 LL |     println!('●●');
    |              ^^^^
diff --git a/src/test/ui/suggestions/tuple-float-index.fixed b/src/test/ui/suggestions/tuple-float-index.fixed
new file mode 100644
index 00000000000..55bc2f77dad
--- /dev/null
+++ b/src/test/ui/suggestions/tuple-float-index.fixed
@@ -0,0 +1,16 @@
+// Copyright 2012 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.
+
+// run-rustfix
+// compile-flags: -Z parse-only
+
+fn main () {
+    ((1, (2, 3)).1).1; //~ ERROR unexpected token: `1.1`
+}
diff --git a/src/test/ui/suggestions/tuple-float-index.rs b/src/test/ui/suggestions/tuple-float-index.rs
index 0a188305a92..d569ca4cb86 100644
--- a/src/test/ui/suggestions/tuple-float-index.rs
+++ b/src/test/ui/suggestions/tuple-float-index.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// run-rustfix
 // compile-flags: -Z parse-only
 
 fn main () {
diff --git a/src/test/ui/suggestions/tuple-float-index.stderr b/src/test/ui/suggestions/tuple-float-index.stderr
index 4a1e34890f4..15af0834f03 100644
--- a/src/test/ui/suggestions/tuple-float-index.stderr
+++ b/src/test/ui/suggestions/tuple-float-index.stderr
@@ -1,5 +1,5 @@
 error: unexpected token: `1.1`
-  --> $DIR/tuple-float-index.rs:14:17
+  --> $DIR/tuple-float-index.rs:15:17
    |
 LL |     (1, (2, 3)).1.1; //~ ERROR unexpected token: `1.1`
    |     ------------^^^
diff --git a/src/test/ui/update-references.sh b/src/test/ui/update-references.sh
index 4fc11daaa3a..47a85352b00 100755
--- a/src/test/ui/update-references.sh
+++ b/src/test/ui/update-references.sh
@@ -26,7 +26,6 @@ if [[ "$1" == "--help" || "$1" == "-h" || "$1" == "" || "$2" == "" ]]; then
     echo "   $0 ../../../build/x86_64-apple-darwin/test/ui *.rs */*.rs"
 fi
 
-MYDIR=$(dirname $0)
 
 BUILD_DIR="$1"
 shift
@@ -34,7 +33,8 @@ shift
 shopt -s nullglob
 
 while [[ "$1" != "" ]]; do
-    for EXT in "stderr" "stdout"; do
+    MYDIR=$(dirname $1)
+    for EXT in "stderr" "stdout" "fixed"; do
         for OUT_NAME in $BUILD_DIR/${1%.rs}.*$EXT; do
             OUT_BASE=`basename "$OUT_NAME"`
             if ! (diff $OUT_NAME $MYDIR/$OUT_BASE >& /dev/null); then
diff --git a/src/tools/compiletest/Cargo.toml b/src/tools/compiletest/Cargo.toml
index 7d02f0b746d..77554f244c8 100644
--- a/src/tools/compiletest/Cargo.toml
+++ b/src/tools/compiletest/Cargo.toml
@@ -13,6 +13,7 @@ regex = "0.2"
 serde = "1.0"
 serde_json = "1.0"
 serde_derive = "1.0"
+rustfix = "0.2"
 
 [target.'cfg(unix)'.dependencies]
 libc = "0.2"
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index 365b47447f2..2df52816599 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -74,30 +74,30 @@ impl FromStr for Mode {
 
 impl fmt::Display for Mode {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        fmt::Display::fmt(match *self {
-                              CompileFail => "compile-fail",
-                              ParseFail => "parse-fail",
-                              RunFail => "run-fail",
-                              RunPass => "run-pass",
-                              RunPassValgrind => "run-pass-valgrind",
-                              Pretty => "pretty",
-                              DebugInfoGdb => "debuginfo-gdb",
-                              DebugInfoLldb => "debuginfo-lldb",
-                              Codegen => "codegen",
-                              Rustdoc => "rustdoc",
-                              CodegenUnits => "codegen-units",
-                              Incremental => "incremental",
-                              RunMake => "run-make",
-                              Ui => "ui",
-                              MirOpt => "mir-opt",
-                          },
-                          f)
+        let s = match *self {
+            CompileFail => "compile-fail",
+            ParseFail => "parse-fail",
+            RunFail => "run-fail",
+            RunPass => "run-pass",
+            RunPassValgrind => "run-pass-valgrind",
+            Pretty => "pretty",
+            DebugInfoGdb => "debuginfo-gdb",
+            DebugInfoLldb => "debuginfo-lldb",
+            Codegen => "codegen",
+            Rustdoc => "rustdoc",
+            CodegenUnits => "codegen-units",
+            Incremental => "incremental",
+            RunMake => "run-make",
+            Ui => "ui",
+            MirOpt => "mir-opt",
+        };
+        fmt::Display::fmt(s, f)
     }
 }
 
-#[derive(Clone)]
+#[derive(Clone, PartialEq)]
 pub enum CompareMode {
-    Nll
+    Nll,
 }
 
 impl CompareMode {
@@ -269,6 +269,7 @@ pub fn expected_output_path(testpaths: &TestPaths,
     testpaths.file.with_extension(extension)
 }
 
-pub const UI_EXTENSIONS: &[&str] = &[UI_STDERR, UI_STDOUT];
+pub const UI_EXTENSIONS: &[&str] = &[UI_STDERR, UI_STDOUT, UI_FIXED];
 pub const UI_STDERR: &str = "stderr";
 pub const UI_STDOUT: &str = "stdout";
+pub const UI_FIXED: &str = "fixed";
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 73dd079cf0c..7ac3f5b5b25 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -236,6 +236,7 @@ pub struct TestProps {
     pub normalize_stdout: Vec<(String, String)>,
     pub normalize_stderr: Vec<(String, String)>,
     pub failure_status: i32,
+    pub run_rustfix: bool,
 }
 
 impl TestProps {
@@ -267,6 +268,7 @@ impl TestProps {
             normalize_stdout: vec![],
             normalize_stderr: vec![],
             failure_status: 101,
+            run_rustfix: false,
         }
     }
 
@@ -403,6 +405,10 @@ impl TestProps {
             if let Some(code) = config.parse_failure_status(ln) {
                 self.failure_status = code;
             }
+
+            if !self.run_rustfix {
+                self.run_rustfix = config.parse_run_rustfix(ln);
+            }
         });
 
         for key in &["RUST_TEST_NOCAPTURE", "RUST_TEST_THREADS"] {
@@ -642,6 +648,10 @@ impl Config {
 
         None
     }
+
+    fn parse_run_rustfix(&self, line: &str) -> bool {
+        self.parse_name_directive(line, "run-rustfix")
+    }
 }
 
 pub fn lldb_version_to_int(version_string: &str) -> isize {
diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index 37f7af0abe8..a7849d53c3d 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -26,6 +26,7 @@ extern crate regex;
 extern crate serde_derive;
 extern crate serde_json;
 extern crate test;
+extern crate rustfix;
 
 use std::env;
 use std::ffi::OsString;
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 01d9f52424d..fae75c352da 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -12,7 +12,7 @@ use common::{Config, TestPaths};
 use common::{CompileFail, ParseFail, Pretty, RunFail, RunPass, RunPassValgrind};
 use common::{Codegen, CodegenUnits, DebugInfoGdb, DebugInfoLldb, Rustdoc};
 use common::{Incremental, MirOpt, RunMake, Ui};
-use common::{expected_output_path, UI_STDERR, UI_STDOUT};
+use common::{expected_output_path, UI_STDERR, UI_STDOUT, UI_FIXED};
 use common::CompareMode;
 use diff;
 use errors::{self, Error, ErrorKind};
@@ -21,6 +21,7 @@ use json;
 use header::TestProps;
 use util::logv;
 use regex::Regex;
+use rustfix::{apply_suggestions, get_suggestions_from_json};
 
 use std::collections::VecDeque;
 use std::collections::HashMap;
@@ -2552,6 +2553,7 @@ impl<'test> TestCx<'test> {
 
         let expected_stderr = self.load_expected_output(UI_STDERR);
         let expected_stdout = self.load_expected_output(UI_STDOUT);
+        let expected_fixed = self.load_expected_output(UI_FIXED);
 
         let normalized_stdout =
             self.normalize_output(&proc_res.stdout, &self.props.normalize_stdout);
@@ -2568,6 +2570,21 @@ impl<'test> TestCx<'test> {
         errors += self.compare_output("stdout", &normalized_stdout, &expected_stdout);
         errors += self.compare_output("stderr", &normalized_stderr, &expected_stderr);
 
+        if self.config.compare_mode.is_some() {
+            // don't test rustfix with nll right now
+        } else if self.props.run_rustfix {
+            // Apply suggestions from rustc to the code itself
+            let unfixed_code = self.load_expected_output_from_path(&self.testpaths.file)
+                .unwrap();
+            let suggestions = get_suggestions_from_json(&proc_res.stderr, &HashSet::new()).unwrap();
+            let fixed_code = apply_suggestions(&unfixed_code, &suggestions);
+
+            errors += self.compare_output("fixed", &fixed_code, &expected_fixed);
+        } else if !expected_fixed.is_empty() {
+            panic!("the `// run-rustfix` directive wasn't found but a `*.fixed` \
+                    file was found");
+        }
+
         if errors > 0 {
             println!("To update references, run this command from build directory:");
             let relative_path_to_file = self.testpaths
@@ -2603,6 +2620,23 @@ impl<'test> TestCx<'test> {
                 self.check_error_patterns(&proc_res.stderr, &proc_res);
             }
         }
+
+        if self.props.run_rustfix && self.config.compare_mode.is_none() {
+            // And finally, compile the fixed code and make sure it both
+            // succeeds and has no diagnostics.
+            let mut rustc = self.make_compile_args(
+                &self.testpaths.file.with_extension(UI_FIXED),
+                TargetLocation::ThisFile(self.make_exe_name()),
+            );
+            rustc.arg("-L").arg(&self.aux_output_dir_name());
+            let res = self.compose_and_run_compiler(rustc, None);
+            if !res.status.success() {
+                self.fatal_proc_rec("failed to compile fixed code", &res);
+            }
+            if !res.stderr.is_empty() {
+                self.fatal_proc_rec("fixed code is still producing diagnostics", &res);
+            }
+        }
     }
 
     fn run_mir_opt_test(&self) {