about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-04-18 14:52:45 +0000
committerbors <bors@rust-lang.org>2019-04-18 14:52:45 +0000
commitd6f513ec7d1e83c8689f94fb48686dd11f1d1c80 (patch)
treeffac5f0c321b75165397cf045d60ed31c171a0fa
parentbf843eb9c2d48a80a5992a5d60858e27269f9575 (diff)
parenta1d2f7222cf1f5c4344a918251c7f37d252c2434 (diff)
downloadrust-d6f513ec7d1e83c8689f94fb48686dd11f1d1c80.tar.gz
rust-d6f513ec7d1e83c8689f94fb48686dd11f1d1c80.zip
Auto merge of #60025 - JohnTitor:rename-files, r=petrochenkov
Rename files about error codes

fixes #60017

This PR will be failed in tidy.

<details>
<summary>The log is here:</summary>

```
tidy check
tidy error: duplicate error code: 411
tidy error: Documents\GitHub\rust\src\librustc_resolve\diagnostics.rs:83:             __diagnostic_used!(E0411);
tidy error: Documents\GitHub\rust\src\librustc_resolve\diagnostics.rs:84:             err.code(DiagnosticId::Error("E0411".to_owned()));
tidy error: duplicate error code: 424
tidy error: Documents\GitHub\rust\src\librustc_resolve\diagnostics.rs:90:             debug!("smart_resolve_path_fragment: E0424, source={:?}", source);
tidy error: Documents\GitHub\rust\src\librustc_resolve\diagnostics.rs:92:             __diagnostic_used!(E0424);
tidy error: Documents\GitHub\rust\src\librustc_resolve\diagnostics.rs:93:             err.code(DiagnosticId::Error("E0424".to_owned()));
some tidy checks failed
```

</details>

I'd like to fix this but I don't know what to do.
I will work on later. Please let me know if you have any solutions.

r? @petrochenkov
-rw-r--r--src/doc/rustc-ux-guidelines.md22
-rw-r--r--src/librustc/error_codes.rs (renamed from src/librustc/diagnostics.rs)0
-rw-r--r--src/librustc/lib.rs2
-rw-r--r--src/librustc_borrowck/error_codes.rs (renamed from src/librustc_borrowck/diagnostics.rs)0
-rw-r--r--src/librustc_codegen_llvm/error_codes.rs (renamed from src/librustc_codegen_llvm/diagnostics.rs)0
-rw-r--r--src/librustc_codegen_llvm/lib.rs2
-rw-r--r--src/librustc_codegen_ssa/error_codes.rs (renamed from src/librustc_codegen_ssa/diagnostics.rs)0
-rw-r--r--src/librustc_codegen_ssa/lib.rs2
-rw-r--r--src/librustc_lint/error_codes.rs (renamed from src/librustc_lint/diagnostics.rs)0
-rw-r--r--src/librustc_lint/lib.rs2
-rw-r--r--src/librustc_metadata/error_codes.rs (renamed from src/librustc_metadata/diagnostics.rs)0
-rw-r--r--src/librustc_metadata/lib.rs2
-rw-r--r--src/librustc_mir/error_codes.rs (renamed from src/librustc_mir/diagnostics.rs)0
-rw-r--r--src/librustc_mir/lib.rs2
-rw-r--r--src/librustc_passes/error_codes.rs (renamed from src/librustc_passes/diagnostics.rs)0
-rw-r--r--src/librustc_passes/lib.rs2
-rw-r--r--src/librustc_plugin/error_codes.rs (renamed from src/librustc_plugin/diagnostics.rs)0
-rw-r--r--src/librustc_plugin/lib.rs2
-rw-r--r--src/librustc_privacy/error_codes.rs (renamed from src/librustc_privacy/diagnostics.rs)0
-rw-r--r--src/librustc_privacy/lib.rs2
-rw-r--r--src/librustc_resolve/diagnostics.rs2458
-rw-r--r--src/librustc_resolve/error_codes.rs1672
-rw-r--r--src/librustc_resolve/error_reporting.rs856
-rw-r--r--src/librustc_resolve/lib.rs4
-rw-r--r--src/librustc_typeck/error_codes.rs (renamed from src/librustc_typeck/diagnostics.rs)0
-rw-r--r--src/librustc_typeck/lib.rs2
-rw-r--r--src/libsyntax/error_codes.rs (renamed from src/libsyntax/diagnostic_list.rs)0
-rw-r--r--src/libsyntax/lib.rs2
-rw-r--r--src/libsyntax_ext/error_codes.rs (renamed from src/libsyntax_ext/diagnostics.rs)0
-rw-r--r--src/libsyntax_ext/lib.rs2
-rw-r--r--src/tools/tidy/src/errors.rs2
31 files changed, 2519 insertions, 2519 deletions
diff --git a/src/doc/rustc-ux-guidelines.md b/src/doc/rustc-ux-guidelines.md
index 93e94e55863..e3684fc9f32 100644
--- a/src/doc/rustc-ux-guidelines.md
+++ b/src/doc/rustc-ux-guidelines.md
@@ -61,17 +61,17 @@ for details on how to format and write long error codes.
 
 * All of them are accessible [online](http://doc.rust-lang.org/error-index.html),
   which are auto-generated from rustc source code in different places:
-  [librustc](https://github.com/rust-lang/rust/blob/master/src/librustc/diagnostics.rs),
-  [libsyntax](https://github.com/rust-lang/rust/blob/master/src/libsyntax/diagnostics.rs),
-  [librustc_borrowck](https://github.com/rust-lang/rust/blob/master/src/librustc_borrowck/diagnostics.rs),
-  [librustc_metadata](https://github.com/rust-lang/rust/blob/master/src/librustc_metadata/diagnostics.rs),
-  [librustc_mir](https://github.com/rust-lang/rust/blob/master/src/librustc_mir/diagnostics.rs),
-  [librustc_passes](https://github.com/rust-lang/rust/blob/master/src/librustc_passes/diagnostics.rs),
-  [librustc_privacy](https://github.com/rust-lang/rust/blob/master/src/librustc_privacy/diagnostics.rs),
-  [librustc_resolve](https://github.com/rust-lang/rust/blob/master/src/librustc_resolve/diagnostics.rs),
-  [librustc_codegen_llvm](https://github.com/rust-lang/rust/blob/master/src/librustc_codegen_llvm/diagnostics.rs),
-  [librustc_plugin](https://github.com/rust-lang/rust/blob/master/src/librustc_plugin/diagnostics.rs),
-  [librustc_typeck](https://github.com/rust-lang/rust/blob/master/src/librustc_typeck/diagnostics.rs).
+  [librustc](https://github.com/rust-lang/rust/blob/master/src/librustc/error_codes.rs),
+  [libsyntax](https://github.com/rust-lang/rust/blob/master/src/libsyntax/error_codes.rs),
+  [librustc_borrowck](https://github.com/rust-lang/rust/blob/master/src/librustc_borrowck/error_codes.rs),
+  [librustc_metadata](https://github.com/rust-lang/rust/blob/master/src/librustc_metadata/error_codes.rs),
+  [librustc_mir](https://github.com/rust-lang/rust/blob/master/src/librustc_mir/error_codes.rs),
+  [librustc_passes](https://github.com/rust-lang/rust/blob/master/src/librustc_passes/error_codes.rs),
+  [librustc_privacy](https://github.com/rust-lang/rust/blob/master/src/librustc_privacy/error_codes.rs),
+  [librustc_resolve](https://github.com/rust-lang/rust/blob/master/src/librustc_resolve/error_codes.rs),
+  [librustc_codegen_llvm](https://github.com/rust-lang/rust/blob/master/src/librustc_codegen_llvm/error_codes.rs),
+  [librustc_plugin](https://github.com/rust-lang/rust/blob/master/src/librustc_plugin/error_codes.rs),
+  [librustc_typeck](https://github.com/rust-lang/rust/blob/master/src/librustc_typeck/error_codes.rs).
 * Explanations have full markdown support. Use it, especially to highlight
 code with backticks.
 * When talking about the compiler, call it `the compiler`, not `Rust` or
diff --git a/src/librustc/diagnostics.rs b/src/librustc/error_codes.rs
index 00f9fa3a938..00f9fa3a938 100644
--- a/src/librustc/diagnostics.rs
+++ b/src/librustc/error_codes.rs
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index 4cbf8e3ecfc..1bd44b13b66 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -99,7 +99,7 @@ mod macros;
 
 // N.B., this module needs to be declared first so diagnostics are
 // registered before they are used.
-pub mod diagnostics;
+pub mod error_codes;
 
 #[macro_use]
 pub mod query;
diff --git a/src/librustc_borrowck/diagnostics.rs b/src/librustc_borrowck/error_codes.rs
index 44d8a23fcb9..44d8a23fcb9 100644
--- a/src/librustc_borrowck/diagnostics.rs
+++ b/src/librustc_borrowck/error_codes.rs
diff --git a/src/librustc_codegen_llvm/diagnostics.rs b/src/librustc_codegen_llvm/error_codes.rs
index 872fa424e4c..872fa424e4c 100644
--- a/src/librustc_codegen_llvm/diagnostics.rs
+++ b/src/librustc_codegen_llvm/error_codes.rs
diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs
index da91217e95e..c2eee59fbb0 100644
--- a/src/librustc_codegen_llvm/lib.rs
+++ b/src/librustc_codegen_llvm/lib.rs
@@ -70,7 +70,7 @@ use rustc_mir::monomorphize;
 use rustc_codegen_ssa::ModuleCodegen;
 use rustc_codegen_utils::codegen_backend::CodegenBackend;
 
-mod diagnostics;
+mod error_codes;
 
 mod back {
     mod archive;
diff --git a/src/librustc_codegen_ssa/diagnostics.rs b/src/librustc_codegen_ssa/error_codes.rs
index e7ef178cfab..e7ef178cfab 100644
--- a/src/librustc_codegen_ssa/diagnostics.rs
+++ b/src/librustc_codegen_ssa/error_codes.rs
diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs
index c6e689f2e83..49e9f6fe38a 100644
--- a/src/librustc_codegen_ssa/lib.rs
+++ b/src/librustc_codegen_ssa/lib.rs
@@ -41,7 +41,7 @@ use syntax_pos::symbol::Symbol;
 
 // N.B., this module needs to be declared first so diagnostics are
 // registered before they are used.
-mod diagnostics;
+mod error_codes;
 
 pub mod common;
 pub mod traits;
diff --git a/src/librustc_lint/diagnostics.rs b/src/librustc_lint/error_codes.rs
index 3165673111c..3165673111c 100644
--- a/src/librustc_lint/diagnostics.rs
+++ b/src/librustc_lint/error_codes.rs
diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs
index ff5e4f02554..3f6348ec8dd 100644
--- a/src/librustc_lint/lib.rs
+++ b/src/librustc_lint/lib.rs
@@ -25,7 +25,7 @@
 #[macro_use]
 extern crate rustc;
 
-mod diagnostics;
+mod error_codes;
 mod nonstandard_style;
 pub mod builtin;
 mod types;
diff --git a/src/librustc_metadata/diagnostics.rs b/src/librustc_metadata/error_codes.rs
index 9ac582ebc42..9ac582ebc42 100644
--- a/src/librustc_metadata/diagnostics.rs
+++ b/src/librustc_metadata/error_codes.rs
diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs
index d052e13f9c0..4f84ca69b7f 100644
--- a/src/librustc_metadata/lib.rs
+++ b/src/librustc_metadata/lib.rs
@@ -26,7 +26,7 @@ extern crate rustc;
 #[macro_use]
 extern crate rustc_data_structures;
 
-mod diagnostics;
+mod error_codes;
 
 mod index_builder;
 mod index;
diff --git a/src/librustc_mir/diagnostics.rs b/src/librustc_mir/error_codes.rs
index c8836fe5193..c8836fe5193 100644
--- a/src/librustc_mir/diagnostics.rs
+++ b/src/librustc_mir/error_codes.rs
diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs
index a16eaf011c8..d382e53e918 100644
--- a/src/librustc_mir/lib.rs
+++ b/src/librustc_mir/lib.rs
@@ -40,7 +40,7 @@ extern crate serialize as rustc_serialize; // used by deriving
 #[macro_use]
 extern crate syntax;
 
-mod diagnostics;
+mod error_codes;
 
 mod borrow_check;
 mod build;
diff --git a/src/librustc_passes/diagnostics.rs b/src/librustc_passes/error_codes.rs
index e3c6b16703a..e3c6b16703a 100644
--- a/src/librustc_passes/diagnostics.rs
+++ b/src/librustc_passes/error_codes.rs
diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs
index db8fcaa5693..7c48feecb21 100644
--- a/src/librustc_passes/lib.rs
+++ b/src/librustc_passes/lib.rs
@@ -19,7 +19,7 @@ extern crate rustc;
 
 use rustc::ty::query::Providers;
 
-mod diagnostics;
+mod error_codes;
 
 pub mod ast_validation;
 pub mod rvalue_promotion;
diff --git a/src/librustc_plugin/diagnostics.rs b/src/librustc_plugin/error_codes.rs
index 68462bd83ef..68462bd83ef 100644
--- a/src/librustc_plugin/diagnostics.rs
+++ b/src/librustc_plugin/error_codes.rs
diff --git a/src/librustc_plugin/lib.rs b/src/librustc_plugin/lib.rs
index 351ba7f04d3..3775dbb79c6 100644
--- a/src/librustc_plugin/lib.rs
+++ b/src/librustc_plugin/lib.rs
@@ -61,7 +61,7 @@
 
 pub use registry::Registry;
 
-mod diagnostics;
+mod error_codes;
 pub mod registry;
 pub mod load;
 pub mod build;
diff --git a/src/librustc_privacy/diagnostics.rs b/src/librustc_privacy/error_codes.rs
index fa4df53e47b..fa4df53e47b 100644
--- a/src/librustc_privacy/diagnostics.rs
+++ b/src/librustc_privacy/error_codes.rs
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index ef315c5f955..edb3efb78a3 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -33,7 +33,7 @@ use syntax_pos::Span;
 use std::{cmp, fmt, mem};
 use std::marker::PhantomData;
 
-mod diagnostics;
+mod error_codes;
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Generic infrastructure used to implement specific visitors below.
diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs
index 5c095994a1b..9e3894dab0d 100644
--- a/src/librustc_resolve/diagnostics.rs
+++ b/src/librustc_resolve/diagnostics.rs
@@ -1,1672 +1,856 @@
-#![allow(non_snake_case)]
-
-use syntax::{register_diagnostic, register_diagnostics, register_long_diagnostics};
-
-// Error messages for EXXXX errors.  Each message should start and end with a
-// new line, and be wrapped to 80 characters.  In vim you can `:set tw=80` and
-// use `gq` to wrap paragraphs. Use `:set tw=0` to disable.
-register_long_diagnostics! {
-
-E0128: r##"
-Type parameter defaults can only use parameters that occur before them.
-Erroneous code example:
-
-```compile_fail,E0128
-struct Foo<T=U, U=()> {
-    field1: T,
-    filed2: U,
-}
-// error: type parameters with a default cannot use forward declared
-// identifiers
-```
-
-Since type parameters are evaluated in-order, you may be able to fix this issue
-by doing:
-
-```
-struct Foo<U=(), T=U> {
-    field1: T,
-    filed2: U,
-}
-```
-
-Please also verify that this wasn't because of a name-clash and rename the type
-parameter if so.
-"##,
-
-E0154: r##"
-#### Note: this error code is no longer emitted by the compiler.
-
-Imports (`use` statements) are not allowed after non-item statements, such as
-variable declarations and expression statements.
-
-Here is an example that demonstrates the error:
-
-```
-fn f() {
-    // Variable declaration before import
-    let x = 0;
-    use std::io::Read;
-    // ...
-}
-```
-
-The solution is to declare the imports at the top of the block, function, or
-file.
-
-Here is the previous example again, with the correct order:
-
-```
-fn f() {
-    use std::io::Read;
-    let x = 0;
-    // ...
-}
-```
-
-See the Declaration Statements section of the reference for more information
-about what constitutes an Item declaration and what does not:
-
-https://doc.rust-lang.org/reference.html#statements
-"##,
-
-E0251: r##"
-#### Note: this error code is no longer emitted by the compiler.
-
-Two items of the same name cannot be imported without rebinding one of the
-items under a new local name.
-
-An example of this error:
-
-```
-use foo::baz;
-use bar::*; // error, do `use foo::baz as quux` instead on the previous line
-
-fn main() {}
-
-mod foo {
-    pub struct baz;
-}
-
-mod bar {
-    pub mod baz {}
-}
-```
-"##,
-
-E0252: r##"
-Two items of the same name cannot be imported without rebinding one of the
-items under a new local name.
-
-Erroneous code example:
-
-```compile_fail,E0252
-use foo::baz;
-use bar::baz; // error, do `use bar::baz as quux` instead
-
-fn main() {}
-
-mod foo {
-    pub struct baz;
-}
-
-mod bar {
-    pub mod baz {}
-}
-```
-
-You can use aliases in order to fix this error. Example:
-
-```
-use foo::baz as foo_baz;
-use bar::baz; // ok!
-
-fn main() {}
-
-mod foo {
-    pub struct baz;
-}
-
-mod bar {
-    pub mod baz {}
-}
-```
-
-Or you can reference the item with its parent:
-
-```
-use bar::baz;
-
-fn main() {
-    let x = foo::baz; // ok!
-}
-
-mod foo {
-    pub struct baz;
-}
-
-mod bar {
-    pub mod baz {}
-}
-```
-"##,
-
-E0253: r##"
-Attempt was made to import an unimportable value. This can happen when trying
-to import a method from a trait.
-
-Erroneous code example:
-
-```compile_fail,E0253
-mod foo {
-    pub trait MyTrait {
-        fn do_something();
-    }
-}
-
-use foo::MyTrait::do_something;
-// error: `do_something` is not directly importable
-
-fn main() {}
-```
-
-It's invalid to directly import methods belonging to a trait or concrete type.
-"##,
-
-E0254: r##"
-Attempt was made to import an item whereas an extern crate with this name has
-already been imported.
-
-Erroneous code example:
-
-```compile_fail,E0254
-extern crate core;
-
-mod foo {
-    pub trait core {
-        fn do_something();
-    }
-}
-
-use foo::core;  // error: an extern crate named `core` has already
-                //        been imported in this module
-
-fn main() {}
-```
-
-To fix this issue, you have to rename at least one of the two imports.
-Example:
-
-```
-extern crate core as libcore; // ok!
-
-mod foo {
-    pub trait core {
-        fn do_something();
-    }
-}
-
-use foo::core;
-
-fn main() {}
-```
-"##,
-
-E0255: r##"
-You can't import a value whose name is the same as another value defined in the
-module.
-
-Erroneous code example:
-
-```compile_fail,E0255
-use bar::foo; // error: an item named `foo` is already in scope
-
-fn foo() {}
-
-mod bar {
-     pub fn foo() {}
-}
-
-fn main() {}
-```
-
-You can use aliases in order to fix this error. Example:
-
-```
-use bar::foo as bar_foo; // ok!
-
-fn foo() {}
-
-mod bar {
-     pub fn foo() {}
-}
-
-fn main() {}
-```
-
-Or you can reference the item with its parent:
-
-```
-fn foo() {}
-
-mod bar {
-     pub fn foo() {}
-}
-
-fn main() {
-    bar::foo(); // we get the item by referring to its parent
-}
-```
-"##,
-
-E0256: r##"
-#### Note: this error code is no longer emitted by the compiler.
-
-You can't import a type or module when the name of the item being imported is
-the same as another type or submodule defined in the module.
-
-An example of this error:
-
-```compile_fail
-use foo::Bar; // error
-
-type Bar = u32;
-
-mod foo {
-    pub mod Bar { }
-}
-
-fn main() {}
-```
-"##,
-
-E0259: r##"
-The name chosen for an external crate conflicts with another external crate
-that has been imported into the current module.
-
-Erroneous code example:
-
-```compile_fail,E0259
-extern crate core;
-extern crate std as core;
-
-fn main() {}
-```
-
-The solution is to choose a different name that doesn't conflict with any
-external crate imported into the current module.
-
-Correct example:
-
-```
-extern crate core;
-extern crate std as other_name;
-
-fn main() {}
-```
-"##,
-
-E0260: r##"
-The name for an item declaration conflicts with an external crate's name.
-
-Erroneous code example:
-
-```compile_fail,E0260
-extern crate core;
-
-struct core;
-
-fn main() {}
-```
-
-There are two possible solutions:
-
-Solution #1: Rename the item.
-
-```
-extern crate core;
-
-struct xyz;
-```
-
-Solution #2: Import the crate with a different name.
-
-```
-extern crate core as xyz;
-
-struct abc;
-```
-
-See the Declaration Statements section of the reference for more information
-about what constitutes an Item declaration and what does not:
-
-https://doc.rust-lang.org/reference.html#statements
-"##,
-
-E0364: r##"
-Private items cannot be publicly re-exported. This error indicates that you
-attempted to `pub use` a type or value that was not itself public.
-
-Erroneous code example:
-
-```compile_fail
-mod foo {
-    const X: u32 = 1;
-}
-
-pub use foo::X;
-
-fn main() {}
-```
-
-The solution to this problem is to ensure that the items that you are
-re-exporting are themselves marked with `pub`:
-
-```
-mod foo {
-    pub const X: u32 = 1;
-}
-
-pub use foo::X;
-
-fn main() {}
-```
-
-See the 'Use Declarations' section of the reference for more information on
-this topic:
-
-https://doc.rust-lang.org/reference.html#use-declarations
-"##,
-
-E0365: r##"
-Private modules cannot be publicly re-exported. This error indicates that you
-attempted to `pub use` a module that was not itself public.
-
-Erroneous code example:
-
-```compile_fail,E0365
-mod foo {
-    pub const X: u32 = 1;
-}
-
-pub use foo as foo2;
-
-fn main() {}
-```
-
-The solution to this problem is to ensure that the module that you are
-re-exporting is itself marked with `pub`:
-
-```
-pub mod foo {
-    pub const X: u32 = 1;
-}
-
-pub use foo as foo2;
-
-fn main() {}
-```
-
-See the 'Use Declarations' section of the reference for more information
-on this topic:
-
-https://doc.rust-lang.org/reference.html#use-declarations
-"##,
-
-E0401: r##"
-Inner items do not inherit type or const parameters from the functions
-they are embedded in.
-
-Erroneous code example:
-
-```compile_fail,E0401
-fn foo<T>(x: T) {
-    fn bar(y: T) { // T is defined in the "outer" function
-        // ..
-    }
-    bar(x);
-}
-```
-
-Nor will this:
-
-```compile_fail,E0401
-fn foo<T>(x: T) {
-    type MaybeT = Option<T>;
-    // ...
-}
-```
-
-Or this:
-
-```compile_fail,E0401
-fn foo<T>(x: T) {
-    struct Foo {
-        x: T,
-    }
-    // ...
-}
-```
-
-Items inside functions are basically just like top-level items, except
-that they can only be used from the function they are in.
-
-There are a couple of solutions for this.
-
-If the item is a function, you may use a closure:
-
-```
-fn foo<T>(x: T) {
-    let bar = |y: T| { // explicit type annotation may not be necessary
-        // ..
-    };
-    bar(x);
-}
-```
+use std::cmp::Reverse;
+
+use errors::{Applicability, DiagnosticBuilder, DiagnosticId};
+use log::debug;
+use rustc::hir::def::{self, CtorKind, Namespace::*};
+use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
+use rustc::session::{Session, config::nightly_options};
+use syntax::ast::{self, Expr, ExprKind, Ident};
+use syntax::ext::base::MacroKind;
+use syntax::symbol::{Symbol, keywords};
+use syntax_pos::{BytePos, Span};
+
+type Def = def::Def<ast::NodeId>;
+
+use crate::macros::ParentScope;
+use crate::resolve_imports::{ImportDirective, ImportDirectiveSubclass, ImportResolver};
+use crate::{import_candidate_to_enum_paths, is_self_type, is_self_value, path_names_to_string};
+use crate::{AssocSuggestion, CrateLint, ImportSuggestion, ModuleOrUniformRoot, PathResult,
+            PathSource, Resolver, Segment, Suggestion};
+
+impl<'a> Resolver<'a> {
+    /// Handles error reporting for `smart_resolve_path_fragment` function.
+    /// Creates base error and amends it with one short label and possibly some longer helps/notes.
+    pub(crate) fn smart_resolve_report_errors(
+        &mut self,
+        path: &[Segment],
+        span: Span,
+        source: PathSource<'_>,
+        def: Option<Def>,
+    ) -> (DiagnosticBuilder<'a>, Vec<ImportSuggestion>) {
+        let ident_span = path.last().map_or(span, |ident| ident.ident.span);
+        let ns = source.namespace();
+        let is_expected = &|def| source.is_expected(def);
+        let is_enum_variant = &|def| if let Def::Variant(..) = def { true } else { false };
+
+        // Make the base error.
+        let expected = source.descr_expected();
+        let path_str = Segment::names_to_string(path);
+        let item_str = path.last().unwrap().ident;
+        let code = source.error_code(def.is_some());
+        let (base_msg, fallback_label, base_span) = if let Some(def) = def {
+            (format!("expected {}, found {} `{}`", expected, def.kind_name(), path_str),
+                format!("not a {}", expected),
+                span)
+        } else {
+            let item_span = path.last().unwrap().ident.span;
+            let (mod_prefix, mod_str) = if path.len() == 1 {
+                (String::new(), "this scope".to_string())
+            } else if path.len() == 2 && path[0].ident.name == keywords::PathRoot.name() {
+                (String::new(), "the crate root".to_string())
+            } else {
+                let mod_path = &path[..path.len() - 1];
+                let mod_prefix = match self.resolve_path_without_parent_scope(
+                    mod_path, Some(TypeNS), false, span, CrateLint::No
+                ) {
+                    PathResult::Module(ModuleOrUniformRoot::Module(module)) =>
+                        module.def(),
+                    _ => None,
+                }.map_or(String::new(), |def| format!("{} ", def.kind_name()));
+                (mod_prefix, format!("`{}`", Segment::names_to_string(mod_path)))
+            };
+            (format!("cannot find {} `{}` in {}{}", expected, item_str, mod_prefix, mod_str),
+                format!("not found in {}", mod_str),
+                item_span)
+        };
+
+        let code = DiagnosticId::Error(code.into());
+        let mut err = self.session.struct_span_err_with_code(base_span, &base_msg, code);
+
+        // Emit help message for fake-self from other languages (e.g., `this` in Javascript).
+        if ["this", "my"].contains(&&*item_str.as_str())
+            && self.self_value_is_available(path[0].ident.span, span) {
+            err.span_suggestion(
+                span,
+                "did you mean",
+                "self".to_string(),
+                Applicability::MaybeIncorrect,
+            );
+        }
 
-For a generic item, you can copy over the parameters:
+        // Emit special messages for unresolved `Self` and `self`.
+        if is_self_type(path, ns) {
+            __diagnostic_used!(E0411);
+            err.code(DiagnosticId::Error("E0411".into()));
+            err.span_label(span, format!("`Self` is only available in impls, traits, \
+                                          and type definitions"));
+            return (err, Vec::new());
+        }
+        if is_self_value(path, ns) {
+            debug!("smart_resolve_path_fragment: E0424, source={:?}", source);
+
+            __diagnostic_used!(E0424);
+            err.code(DiagnosticId::Error("E0424".into()));
+            err.span_label(span, match source {
+                PathSource::Pat => {
+                    format!("`self` value is a keyword \
+                             and may not be bound to \
+                             variables or shadowed")
+                }
+                _ => {
+                    format!("`self` value is a keyword \
+                             only available in methods \
+                             with `self` parameter")
+                }
+            });
+            return (err, Vec::new());
+        }
 
-```
-fn foo<T>(x: T) {
-    fn bar<T>(y: T) {
-        // ..
-    }
-    bar(x);
-}
-```
+        // Try to lookup name in more relaxed fashion for better error reporting.
+        let ident = path.last().unwrap().ident;
+        let candidates = self.lookup_import_candidates(ident, ns, is_expected)
+            .drain(..)
+            .filter(|ImportSuggestion { did, .. }| {
+                match (did, def.and_then(|def| def.opt_def_id())) {
+                    (Some(suggestion_did), Some(actual_did)) => *suggestion_did != actual_did,
+                    _ => true,
+                }
+            })
+            .collect::<Vec<_>>();
+        if candidates.is_empty() && is_expected(Def::Enum(DefId::local(CRATE_DEF_INDEX))) {
+            let enum_candidates =
+                self.lookup_import_candidates(ident, ns, is_enum_variant);
+            let mut enum_candidates = enum_candidates.iter()
+                .map(|suggestion| {
+                    import_candidate_to_enum_paths(&suggestion)
+                }).collect::<Vec<_>>();
+            enum_candidates.sort();
+
+            if !enum_candidates.is_empty() {
+                // Contextualize for E0412 "cannot find type", but don't belabor the point
+                // (that it's a variant) for E0573 "expected type, found variant".
+                let preamble = if def.is_none() {
+                    let others = match enum_candidates.len() {
+                        1 => String::new(),
+                        2 => " and 1 other".to_owned(),
+                        n => format!(" and {} others", n)
+                    };
+                    format!("there is an enum variant `{}`{}; ",
+                            enum_candidates[0].0, others)
+                } else {
+                    String::new()
+                };
+                let msg = format!("{}try using the variant's enum", preamble);
+
+                err.span_suggestions(
+                    span,
+                    &msg,
+                    enum_candidates.into_iter()
+                        .map(|(_variant_path, enum_ty_path)| enum_ty_path)
+                        // Variants re-exported in prelude doesn't mean `prelude::v1` is the
+                        // type name!
+                        // FIXME: is there a more principled way to do this that
+                        // would work for other re-exports?
+                        .filter(|enum_ty_path| enum_ty_path != "std::prelude::v1")
+                        // Also write `Option` rather than `std::prelude::v1::Option`.
+                        .map(|enum_ty_path| {
+                            // FIXME #56861: DRY-er prelude filtering.
+                            enum_ty_path.trim_start_matches("std::prelude::v1::").to_owned()
+                        }),
+                    Applicability::MachineApplicable,
+                );
+            }
+        }
+        if path.len() == 1 && self.self_type_is_available(span) {
+            if let Some(candidate) = self.lookup_assoc_candidate(ident, ns, is_expected) {
+                let self_is_available = self.self_value_is_available(path[0].ident.span, span);
+                match candidate {
+                    AssocSuggestion::Field => {
+                        err.span_suggestion(
+                            span,
+                            "try",
+                            format!("self.{}", path_str),
+                            Applicability::MachineApplicable,
+                        );
+                        if !self_is_available {
+                            err.span_label(span, format!("`self` value is a keyword \
+                                                         only available in \
+                                                         methods with `self` parameter"));
+                        }
+                    }
+                    AssocSuggestion::MethodWithSelf if self_is_available => {
+                        err.span_suggestion(
+                            span,
+                            "try",
+                            format!("self.{}", path_str),
+                            Applicability::MachineApplicable,
+                        );
+                    }
+                    AssocSuggestion::MethodWithSelf | AssocSuggestion::AssocItem => {
+                        err.span_suggestion(
+                            span,
+                            "try",
+                            format!("Self::{}", path_str),
+                            Applicability::MachineApplicable,
+                        );
+                    }
+                }
+                return (err, candidates);
+            }
+        }
 
-```
-fn foo<T>(x: T) {
-    type MaybeT<T> = Option<T>;
-}
-```
+        let mut levenshtein_worked = false;
+
+        // Try Levenshtein algorithm.
+        let suggestion = self.lookup_typo_candidate(path, ns, is_expected, span);
+        if let Some(suggestion) = suggestion {
+            let msg = format!(
+                "{} {} with a similar name exists",
+                suggestion.article, suggestion.kind
+            );
+            err.span_suggestion(
+                ident_span,
+                &msg,
+                suggestion.candidate.to_string(),
+                Applicability::MaybeIncorrect,
+            );
+
+            levenshtein_worked = true;
+        }
 
-Be sure to copy over any bounds as well:
+        // Try context-dependent help if relaxed lookup didn't work.
+        if let Some(def) = def {
+            if self.smart_resolve_context_dependent_help(&mut err,
+                                                         span,
+                                                         source,
+                                                         def,
+                                                         &path_str,
+                                                         &fallback_label) {
+                return (err, candidates);
+            }
+        }
 
-```
-fn foo<T: Copy>(x: T) {
-    fn bar<T: Copy>(y: T) {
-        // ..
+        // Fallback label.
+        if !levenshtein_worked {
+            err.span_label(base_span, fallback_label);
+            self.type_ascription_suggestion(&mut err, base_span);
+        }
+        (err, candidates)
     }
-    bar(x);
-}
-```
 
-```
-fn foo<T: Copy>(x: T) {
-    struct Foo<T: Copy> {
-        x: T,
+    /// Provides context-dependent help for errors reported by the `smart_resolve_path_fragment`
+    /// function.
+    /// Returns `true` if able to provide context-dependent help.
+    fn smart_resolve_context_dependent_help(
+        &mut self,
+        err: &mut DiagnosticBuilder<'a>,
+        span: Span,
+        source: PathSource<'_>,
+        def: Def,
+        path_str: &str,
+        fallback_label: &str,
+    ) -> bool {
+        let ns = source.namespace();
+        let is_expected = &|def| source.is_expected(def);
+
+        let path_sep = |err: &mut DiagnosticBuilder<'_>, expr: &Expr| match expr.node {
+            ExprKind::Field(_, ident) => {
+                err.span_suggestion(
+                    expr.span,
+                    "use the path separator to refer to an item",
+                    format!("{}::{}", path_str, ident),
+                    Applicability::MaybeIncorrect,
+                );
+                true
+            }
+            ExprKind::MethodCall(ref segment, ..) => {
+                let span = expr.span.with_hi(segment.ident.span.hi());
+                err.span_suggestion(
+                    span,
+                    "use the path separator to refer to an item",
+                    format!("{}::{}", path_str, segment.ident),
+                    Applicability::MaybeIncorrect,
+                );
+                true
+            }
+            _ => false,
+        };
+
+        match (def, source) {
+            (Def::Macro(..), _) => {
+                err.span_suggestion(
+                    span,
+                    "use `!` to invoke the macro",
+                    format!("{}!", path_str),
+                    Applicability::MaybeIncorrect,
+                );
+                if path_str == "try" && span.rust_2015() {
+                    err.note("if you want the `try` keyword, you need to be in the 2018 edition");
+                }
+            }
+            (Def::TyAlias(..), PathSource::Trait(_)) => {
+                err.span_label(span, "type aliases cannot be used as traits");
+                if nightly_options::is_nightly_build() {
+                    err.note("did you mean to use a trait alias?");
+                }
+            }
+            (Def::Mod(..), PathSource::Expr(Some(parent))) => if !path_sep(err, &parent) {
+                return false;
+            },
+            (Def::Enum(..), PathSource::TupleStruct)
+                | (Def::Enum(..), PathSource::Expr(..))  => {
+                if let Some(variants) = self.collect_enum_variants(def) {
+                    if !variants.is_empty() {
+                        let msg = if variants.len() == 1 {
+                            "try using the enum's variant"
+                        } else {
+                            "try using one of the enum's variants"
+                        };
+
+                        err.span_suggestions(
+                            span,
+                            msg,
+                            variants.iter().map(path_names_to_string),
+                            Applicability::MaybeIncorrect,
+                        );
+                    }
+                } else {
+                    err.note("did you mean to use one of the enum's variants?");
+                }
+            },
+            (Def::Struct(def_id), _) if ns == ValueNS => {
+                if let Some((ctor_def, ctor_vis))
+                        = self.struct_constructors.get(&def_id).cloned() {
+                    let accessible_ctor = self.is_accessible(ctor_vis);
+                    if is_expected(ctor_def) && !accessible_ctor {
+                        err.span_label(
+                            span,
+                            format!("constructor is not visible here due to private fields"),
+                        );
+                    }
+                } else {
+                    // HACK(estebank): find a better way to figure out that this was a
+                    // parser issue where a struct literal is being used on an expression
+                    // where a brace being opened means a block is being started. Look
+                    // ahead for the next text to see if `span` is followed by a `{`.
+                    let sm = self.session.source_map();
+                    let mut sp = span;
+                    loop {
+                        sp = sm.next_point(sp);
+                        match sm.span_to_snippet(sp) {
+                            Ok(ref snippet) => {
+                                if snippet.chars().any(|c| { !c.is_whitespace() }) {
+                                    break;
+                                }
+                            }
+                            _ => break,
+                        }
+                    }
+                    let followed_by_brace = match sm.span_to_snippet(sp) {
+                        Ok(ref snippet) if snippet == "{" => true,
+                        _ => false,
+                    };
+                    // In case this could be a struct literal that needs to be surrounded
+                    // by parenthesis, find the appropriate span.
+                    let mut i = 0;
+                    let mut closing_brace = None;
+                    loop {
+                        sp = sm.next_point(sp);
+                        match sm.span_to_snippet(sp) {
+                            Ok(ref snippet) => {
+                                if snippet == "}" {
+                                    let sp = span.to(sp);
+                                    if let Ok(snippet) = sm.span_to_snippet(sp) {
+                                        closing_brace = Some((sp, snippet));
+                                    }
+                                    break;
+                                }
+                            }
+                            _ => break,
+                        }
+                        i += 1;
+                        // The bigger the span, the more likely we're incorrect --
+                        // bound it to 100 chars long.
+                        if i > 100 {
+                            break;
+                        }
+                    }
+                    match source {
+                        PathSource::Expr(Some(parent)) => if !path_sep(err, &parent) {
+                            err.span_label(
+                                span,
+                                format!("did you mean `{} {{ /* fields */ }}`?", path_str),
+                            );
+                        }
+                        PathSource::Expr(None) if followed_by_brace == true => {
+                            if let Some((sp, snippet)) = closing_brace {
+                                err.span_suggestion(
+                                    sp,
+                                    "surround the struct literal with parenthesis",
+                                    format!("({})", snippet),
+                                    Applicability::MaybeIncorrect,
+                                );
+                            } else {
+                                err.span_label(
+                                    span,
+                                    format!("did you mean `({} {{ /* fields */ }})`?", path_str),
+                                );
+                            }
+                        },
+                        _ => {
+                            err.span_label(
+                                span,
+                                format!("did you mean `{} {{ /* fields */ }}`?", path_str),
+                            );
+                        },
+                    }
+                }
+            }
+            (Def::Union(..), _) |
+            (Def::Variant(..), _) |
+            (Def::Ctor(_, _, CtorKind::Fictive), _) if ns == ValueNS => {
+                err.span_label(span, format!("did you mean `{} {{ /* fields */ }}`?", path_str));
+            }
+            (Def::SelfTy(..), _) if ns == ValueNS => {
+                err.span_label(span, fallback_label);
+                err.note("can't use `Self` as a constructor, you must use the implemented struct");
+            }
+            (Def::TyAlias(_), _) | (Def::AssociatedTy(..), _) if ns == ValueNS => {
+                err.note("can't use a type alias as a constructor");
+            }
+            _ => return false,
+        }
+        true
     }
 }
-```
-
-This may require additional type hints in the function body.
-
-In case the item is a function inside an `impl`, defining a private helper
-function might be easier:
 
-```
-# struct Foo<T>(T);
-impl<T> Foo<T> {
-    pub fn foo(&self, x: T) {
-        self.bar(x);
-    }
+impl<'a, 'b:'a> ImportResolver<'a, 'b> {
+    /// Adds suggestions for a path that cannot be resolved.
+    pub(crate) fn make_path_suggestion(
+        &mut self,
+        span: Span,
+        mut path: Vec<Segment>,
+        parent_scope: &ParentScope<'b>,
+    ) -> Option<(Vec<Segment>, Vec<String>)> {
+        debug!("make_path_suggestion: span={:?} path={:?}", span, path);
+
+        match (path.get(0), path.get(1)) {
+            // `{{root}}::ident::...` on both editions.
+            // On 2015 `{{root}}` is usually added implicitly.
+            (Some(fst), Some(snd)) if fst.ident.name == keywords::PathRoot.name() &&
+                                      !snd.ident.is_path_segment_keyword() => {}
+            // `ident::...` on 2018.
+            (Some(fst), _) if fst.ident.span.rust_2018() &&
+                              !fst.ident.is_path_segment_keyword() => {
+                // Insert a placeholder that's later replaced by `self`/`super`/etc.
+                path.insert(0, Segment::from_ident(keywords::Invalid.ident()));
+            }
+            _ => return None,
+        }
 
-    fn bar(&self, y: T) {
-        // ..
+        self.make_missing_self_suggestion(span, path.clone(), parent_scope)
+            .or_else(|| self.make_missing_crate_suggestion(span, path.clone(), parent_scope))
+            .or_else(|| self.make_missing_super_suggestion(span, path.clone(), parent_scope))
+            .or_else(|| self.make_external_crate_suggestion(span, path, parent_scope))
     }
-}
-```
-
-For default impls in traits, the private helper solution won't work, however
-closures or copying the parameters should still work.
-"##,
-
-E0403: r##"
-Some type parameters have the same name.
-
-Erroneous code example:
-
-```compile_fail,E0403
-fn foo<T, T>(s: T, u: T) {} // error: the name `T` is already used for a type
-                            //        parameter in this type parameter list
-```
-
-Please verify that none of the type parameters are misspelled, and rename any
-clashing parameters. Example:
-
-```
-fn foo<T, Y>(s: T, u: Y) {} // ok!
-```
-"##,
-
-E0404: r##"
-You tried to use something which is not a trait in a trait position, such as
-a bound or `impl`.
-
-Erroneous code example:
-
-```compile_fail,E0404
-struct Foo;
-struct Bar;
-
-impl Foo for Bar {} // error: `Foo` is not a trait
-```
-
-Another erroneous code example:
-
-```compile_fail,E0404
-struct Foo;
-
-fn bar<T: Foo>(t: T) {} // error: `Foo` is not a trait
-```
-
-Please verify that you didn't misspell the trait's name or otherwise use the
-wrong identifier. Example:
-
-```
-trait Foo {
-    // some functions
-}
-struct Bar;
-
-impl Foo for Bar { // ok!
-    // functions implementation
-}
-```
-
-or
-
-```
-trait Foo {
-    // some functions
-}
-
-fn bar<T: Foo>(t: T) {} // ok!
-```
-
-"##,
-
-E0405: r##"
-The code refers to a trait that is not in scope.
-
-Erroneous code example:
-
-```compile_fail,E0405
-struct Foo;
-
-impl SomeTrait for Foo {} // error: trait `SomeTrait` is not in scope
-```
-
-Please verify that the name of the trait wasn't misspelled and ensure that it
-was imported. Example:
-
-```
-# #[cfg(for_demonstration_only)]
-// solution 1:
-use some_file::SomeTrait;
-
-// solution 2:
-trait SomeTrait {
-    // some functions
-}
-
-struct Foo;
-
-impl SomeTrait for Foo { // ok!
-    // implements functions
-}
-```
-"##,
-
-E0407: r##"
-A definition of a method not in the implemented trait was given in a trait
-implementation.
-
-Erroneous code example:
-
-```compile_fail,E0407
-trait Foo {
-    fn a();
-}
-
-struct Bar;
-
-impl Foo for Bar {
-    fn a() {}
-    fn b() {} // error: method `b` is not a member of trait `Foo`
-}
-```
-
-Please verify you didn't misspell the method name and you used the correct
-trait. First example:
-
-```
-trait Foo {
-    fn a();
-    fn b();
-}
-
-struct Bar;
-
-impl Foo for Bar {
-    fn a() {}
-    fn b() {} // ok!
-}
-```
-
-Second example:
-
-```
-trait Foo {
-    fn a();
-}
-
-struct Bar;
-
-impl Foo for Bar {
-    fn a() {}
-}
-
-impl Bar {
-    fn b() {}
-}
-```
-"##,
-
-E0408: r##"
-An "or" pattern was used where the variable bindings are not consistently bound
-across patterns.
-
-Erroneous code example:
-
-```compile_fail,E0408
-match x {
-    Some(y) | None => { /* use y */ } // error: variable `y` from pattern #1 is
-                                      //        not bound in pattern #2
-    _ => ()
-}
-```
-
-Here, `y` is bound to the contents of the `Some` and can be used within the
-block corresponding to the match arm. However, in case `x` is `None`, we have
-not specified what `y` is, and the block will use a nonexistent variable.
-
-To fix this error, either split into multiple match arms:
-
-```
-let x = Some(1);
-match x {
-    Some(y) => { /* use y */ }
-    None => { /* ... */ }
-}
-```
-
-or, bind the variable to a field of the same type in all sub-patterns of the
-or pattern:
-
-```
-let x = (0, 2);
-match x {
-    (0, y) | (y, 0) => { /* use y */}
-    _ => {}
-}
-```
-
-In this example, if `x` matches the pattern `(0, _)`, the second field is set
-to `y`. If it matches `(_, 0)`, the first field is set to `y`; so in all
-cases `y` is set to some value.
-"##,
-
-E0409: r##"
-An "or" pattern was used where the variable bindings are not consistently bound
-across patterns.
-
-Erroneous code example:
-
-```compile_fail,E0409
-let x = (0, 2);
-match x {
-    (0, ref y) | (y, 0) => { /* use y */} // error: variable `y` is bound with
-                                          //        different mode in pattern #2
-                                          //        than in pattern #1
-    _ => ()
-}
-```
-
-Here, `y` is bound by-value in one case and by-reference in the other.
-
-To fix this error, just use the same mode in both cases.
-Generally using `ref` or `ref mut` where not already used will fix this:
-
-```
-let x = (0, 2);
-match x {
-    (0, ref y) | (ref y, 0) => { /* use y */}
-    _ => ()
-}
-```
-
-Alternatively, split the pattern:
-
-```
-let x = (0, 2);
-match x {
-    (y, 0) => { /* use y */ }
-    (0, ref y) => { /* use y */}
-    _ => ()
-}
-```
-"##,
-
-E0411: r##"
-The `Self` keyword was used outside an impl, trait, or type definition.
-
-Erroneous code example:
-
-```compile_fail,E0411
-<Self>::foo; // error: use of `Self` outside of an impl, trait, or type
-             // definition
-```
-
-The `Self` keyword represents the current type, which explains why it can only
-be used inside an impl, trait, or type definition. It gives access to the
-associated items of a type:
-
-```
-trait Foo {
-    type Bar;
-}
 
-trait Baz : Foo {
-    fn bar() -> Self::Bar; // like this
-}
-```
-
-However, be careful when two types have a common associated type:
-
-```compile_fail
-trait Foo {
-    type Bar;
-}
-
-trait Foo2 {
-    type Bar;
-}
-
-trait Baz : Foo + Foo2 {
-    fn bar() -> Self::Bar;
-    // error: ambiguous associated type `Bar` in bounds of `Self`
-}
-```
-
-This problem can be solved by specifying from which trait we want to use the
-`Bar` type:
-
-```
-trait Foo {
-    type Bar;
-}
-
-trait Foo2 {
-    type Bar;
-}
-
-trait Baz : Foo + Foo2 {
-    fn bar() -> <Self as Foo>::Bar; // ok!
-}
-```
-"##,
-
-E0412: r##"
-The type name used is not in scope.
-
-Erroneous code examples:
-
-```compile_fail,E0412
-impl Something {} // error: type name `Something` is not in scope
-
-// or:
-
-trait Foo {
-    fn bar(N); // error: type name `N` is not in scope
-}
-
-// or:
-
-fn foo(x: T) {} // type name `T` is not in scope
-```
-
-To fix this error, please verify you didn't misspell the type name, you did
-declare it or imported it into the scope. Examples:
-
-```
-struct Something;
-
-impl Something {} // ok!
-
-// or:
-
-trait Foo {
-    type N;
-
-    fn bar(_: Self::N); // ok!
-}
-
-// or:
-
-fn foo<T>(x: T) {} // ok!
-```
-
-Another case that causes this error is when a type is imported into a parent
-module. To fix this, you can follow the suggestion and use File directly or
-`use super::File;` which will import the types from the parent namespace. An
-example that causes this error is below:
-
-```compile_fail,E0412
-use std::fs::File;
-
-mod foo {
-    fn some_function(f: File) {}
-}
-```
-
-```
-use std::fs::File;
-
-mod foo {
-    // either
-    use super::File;
-    // or
-    // use std::fs::File;
-    fn foo(f: File) {}
-}
-# fn main() {} // don't insert it for us; that'll break imports
-```
-"##,
-
-E0415: r##"
-More than one function parameter have the same name.
-
-Erroneous code example:
-
-```compile_fail,E0415
-fn foo(f: i32, f: i32) {} // error: identifier `f` is bound more than
-                          //        once in this parameter list
-```
-
-Please verify you didn't misspell parameters' name. Example:
-
-```
-fn foo(f: i32, g: i32) {} // ok!
-```
-"##,
-
-E0416: r##"
-An identifier is bound more than once in a pattern.
-
-Erroneous code example:
-
-```compile_fail,E0416
-match (1, 2) {
-    (x, x) => {} // error: identifier `x` is bound more than once in the
-                 //        same pattern
-}
-```
-
-Please verify you didn't misspell identifiers' name. Example:
-
-```
-match (1, 2) {
-    (x, y) => {} // ok!
-}
-```
-
-Or maybe did you mean to unify? Consider using a guard:
-
-```
-# let (A, B, C) = (1, 2, 3);
-match (A, B, C) {
-    (x, x2, see) if x == x2 => { /* A and B are equal, do one thing */ }
-    (y, z, see) => { /* A and B unequal; do another thing */ }
-}
-```
-"##,
-
-E0422: r##"
-You are trying to use an identifier that is either undefined or not a struct.
-Erroneous code example:
-
-```compile_fail,E0422
-fn main () {
-    let x = Foo { x: 1, y: 2 };
-}
-```
-
-In this case, `Foo` is undefined, so it inherently isn't anything, and
-definitely not a struct.
-
-```compile_fail
-fn main () {
-    let foo = 1;
-    let x = foo { x: 1, y: 2 };
-}
-```
-
-In this case, `foo` is defined, but is not a struct, so Rust can't use it as
-one.
-"##,
-
-E0423: r##"
-An identifier was used like a function name or a value was expected and the
-identifier exists but it belongs to a different namespace.
-
-For (an erroneous) example, here a `struct` variant name were used as a
-function:
-
-```compile_fail,E0423
-struct Foo { a: bool };
-
-let f = Foo();
-// error: expected function, found `Foo`
-// `Foo` is a struct name, but this expression uses it like a function name
-```
-
-Please verify you didn't misspell the name of what you actually wanted to use
-here. Example:
-
-```
-fn Foo() -> u32 { 0 }
-
-let f = Foo(); // ok!
-```
-
-It is common to forget the trailing `!` on macro invocations, which would also
-yield this error:
-
-```compile_fail,E0423
-println("");
-// error: expected function, found macro `println`
-// did you mean `println!(...)`? (notice the trailing `!`)
-```
-
-Another case where this error is emitted is when a value is expected, but
-something else is found:
-
-```compile_fail,E0423
-pub mod a {
-    pub const I: i32 = 1;
-}
-
-fn h1() -> i32 {
-    a.I
-    //~^ ERROR expected value, found module `a`
-    // did you mean `a::I`?
-}
-```
-"##,
-
-E0424: r##"
-The `self` keyword was used in a static method.
-
-Erroneous code example:
-
-```compile_fail,E0424
-struct Foo;
-
-impl Foo {
-    fn bar(self) {}
-
-    fn foo() {
-        self.bar(); // error: `self` is not available in a static method.
+    /// Suggest a missing `self::` if that resolves to an correct module.
+    ///
+    /// ```
+    ///    |
+    /// LL | use foo::Bar;
+    ///    |     ^^^ did you mean `self::foo`?
+    /// ```
+    fn make_missing_self_suggestion(
+        &mut self,
+        span: Span,
+        mut path: Vec<Segment>,
+        parent_scope: &ParentScope<'b>,
+    ) -> Option<(Vec<Segment>, Vec<String>)> {
+        // Replace first ident with `self` and check if that is valid.
+        path[0].ident.name = keywords::SelfLower.name();
+        let result = self.resolve_path(&path, None, parent_scope, false, span, CrateLint::No);
+        debug!("make_missing_self_suggestion: path={:?} result={:?}", path, result);
+        if let PathResult::Module(..) = result {
+            Some((path, Vec::new()))
+        } else {
+            None
+        }
     }
-}
-```
-
-Please check if the method's argument list should have contained `self`,
-`&self`, or `&mut self` (in case you didn't want to create a static
-method), and add it if so. Example:
-
-```
-struct Foo;
 
-impl Foo {
-    fn bar(self) {}
-
-    fn foo(self) {
-        self.bar(); // ok!
+    /// Suggests a missing `crate::` if that resolves to an correct module.
+    ///
+    /// ```
+    ///    |
+    /// LL | use foo::Bar;
+    ///    |     ^^^ did you mean `crate::foo`?
+    /// ```
+    fn make_missing_crate_suggestion(
+        &mut self,
+        span: Span,
+        mut path: Vec<Segment>,
+        parent_scope: &ParentScope<'b>,
+    ) -> Option<(Vec<Segment>, Vec<String>)> {
+        // Replace first ident with `crate` and check if that is valid.
+        path[0].ident.name = keywords::Crate.name();
+        let result = self.resolve_path(&path, None, parent_scope, false, span, CrateLint::No);
+        debug!("make_missing_crate_suggestion:  path={:?} result={:?}", path, result);
+        if let PathResult::Module(..) = result {
+            Some((
+                path,
+                vec![
+                    "`use` statements changed in Rust 2018; read more at \
+                     <https://doc.rust-lang.org/edition-guide/rust-2018/module-system/path-\
+                     clarity.html>".to_string()
+                ],
+            ))
+        } else {
+            None
+        }
     }
-}
-```
-"##,
-
-E0425: r##"
-An unresolved name was used.
-
-Erroneous code examples:
 
-```compile_fail,E0425
-something_that_doesnt_exist::foo;
-// error: unresolved name `something_that_doesnt_exist::foo`
-
-// or:
-
-trait Foo {
-    fn bar() {
-        Self; // error: unresolved name `Self`
+    /// Suggests a missing `super::` if that resolves to an correct module.
+    ///
+    /// ```
+    ///    |
+    /// LL | use foo::Bar;
+    ///    |     ^^^ did you mean `super::foo`?
+    /// ```
+    fn make_missing_super_suggestion(
+        &mut self,
+        span: Span,
+        mut path: Vec<Segment>,
+        parent_scope: &ParentScope<'b>,
+    ) -> Option<(Vec<Segment>, Vec<String>)> {
+        // Replace first ident with `crate` and check if that is valid.
+        path[0].ident.name = keywords::Super.name();
+        let result = self.resolve_path(&path, None, parent_scope, false, span, CrateLint::No);
+        debug!("make_missing_super_suggestion:  path={:?} result={:?}", path, result);
+        if let PathResult::Module(..) = result {
+            Some((path, Vec::new()))
+        } else {
+            None
+        }
     }
-}
-
-// or:
-
-let x = unknown_variable;  // error: unresolved name `unknown_variable`
-```
-
-Please verify that the name wasn't misspelled and ensure that the
-identifier being referred to is valid for the given situation. Example:
-
-```
-enum something_that_does_exist {
-    Foo,
-}
-```
-
-Or:
-
-```
-mod something_that_does_exist {
-    pub static foo : i32 = 0i32;
-}
-
-something_that_does_exist::foo; // ok!
-```
-
-Or:
-
-```
-let unknown_variable = 12u32;
-let x = unknown_variable; // ok!
-```
-
-If the item is not defined in the current module, it must be imported using a
-`use` statement, like so:
-
-```
-# mod foo { pub fn bar() {} }
-# fn main() {
-use foo::bar;
-bar();
-# }
-```
-
-If the item you are importing is not defined in some super-module of the
-current module, then it must also be declared as public (e.g., `pub fn`).
-"##,
-
-E0426: r##"
-An undeclared label was used.
-
-Erroneous code example:
-
-```compile_fail,E0426
-loop {
-    break 'a; // error: use of undeclared label `'a`
-}
-```
-
-Please verify you spelt or declare the label correctly. Example:
-
-```
-'a: loop {
-    break 'a; // ok!
-}
-```
-"##,
-
-E0428: r##"
-A type or module has been defined more than once.
-
-Erroneous code example:
-
-```compile_fail,E0428
-struct Bar;
-struct Bar; // error: duplicate definition of value `Bar`
-```
-
-Please verify you didn't misspell the type/module's name or remove/rename the
-duplicated one. Example:
-
-```
-struct Bar;
-struct Bar2; // ok!
-```
-"##,
-
-E0429: r##"
-The `self` keyword cannot appear alone as the last segment in a `use`
-declaration.
-
-Erroneous code example:
-
-```compile_fail,E0429
-use std::fmt::self; // error: `self` imports are only allowed within a { } list
-```
-
-To use a namespace itself in addition to some of its members, `self` may appear
-as part of a brace-enclosed list of imports:
-
-```
-use std::fmt::{self, Debug};
-```
-
-If you only want to import the namespace, do so directly:
-
-```
-use std::fmt;
-```
-"##,
-
-E0430: r##"
-The `self` import appears more than once in the list.
-
-Erroneous code example:
-
-```compile_fail,E0430
-use something::{self, self}; // error: `self` import can only appear once in
-                             //        the list
-```
-
-Please verify you didn't misspell the import name or remove the duplicated
-`self` import. Example:
-
-```
-# mod something {}
-# fn main() {
-use something::{self}; // ok!
-# }
-```
-"##,
-
-E0431: r##"
-An invalid `self` import was made.
-
-Erroneous code example:
-
-```compile_fail,E0431
-use {self}; // error: `self` import can only appear in an import list with a
-            //        non-empty prefix
-```
 
-You cannot import the current module into itself, please remove this import
-or verify you didn't misspell it.
-"##,
-
-E0432: r##"
-An import was unresolved.
-
-Erroneous code example:
-
-```compile_fail,E0432
-use something::Foo; // error: unresolved import `something::Foo`.
-```
-
-Paths in `use` statements are relative to the crate root. To import items
-relative to the current and parent modules, use the `self::` and `super::`
-prefixes, respectively. Also verify that you didn't misspell the import
-name and that the import exists in the module from where you tried to
-import it. Example:
-
-```
-use self::something::Foo; // ok!
-
-mod something {
-    pub struct Foo;
-}
-# fn main() {}
-```
-
-Or, if you tried to use a module from an external crate, you may have missed
-the `extern crate` declaration (which is usually placed in the crate root):
-
-```
-extern crate core; // Required to use the `core` crate
-
-use core::any;
-# fn main() {}
-```
-"##,
-
-E0433: r##"
-An undeclared type or module was used.
-
-Erroneous code example:
-
-```compile_fail,E0433
-let map = HashMap::new();
-// error: failed to resolve: use of undeclared type or module `HashMap`
-```
-
-Please verify you didn't misspell the type/module's name or that you didn't
-forget to import it:
-
-
-```
-use std::collections::HashMap; // HashMap has been imported.
-let map: HashMap<u32, u32> = HashMap::new(); // So it can be used!
-```
-"##,
-
-E0434: r##"
-This error indicates that a variable usage inside an inner function is invalid
-because the variable comes from a dynamic environment. Inner functions do not
-have access to their containing environment.
+    /// Suggests a missing external crate name if that resolves to an correct module.
+    ///
+    /// ```
+    ///    |
+    /// LL | use foobar::Baz;
+    ///    |     ^^^^^^ did you mean `baz::foobar`?
+    /// ```
+    ///
+    /// Used when importing a submodule of an external crate but missing that crate's
+    /// name as the first part of path.
+    fn make_external_crate_suggestion(
+        &mut self,
+        span: Span,
+        mut path: Vec<Segment>,
+        parent_scope: &ParentScope<'b>,
+    ) -> Option<(Vec<Segment>, Vec<String>)> {
+        if path[1].ident.span.rust_2015() {
+            return None;
+        }
 
-Erroneous code example:
+        // Sort extern crate names in reverse order to get
+        // 1) some consistent ordering for emitted dignostics, and
+        // 2) `std` suggestions before `core` suggestions.
+        let mut extern_crate_names =
+            self.resolver.extern_prelude.iter().map(|(ident, _)| ident.name).collect::<Vec<_>>();
+        extern_crate_names.sort_by_key(|name| Reverse(name.as_str()));
+
+        for name in extern_crate_names.into_iter() {
+            // Replace first ident with a crate name and check if that is valid.
+            path[0].ident.name = name;
+            let result = self.resolve_path(&path, None, parent_scope, false, span, CrateLint::No);
+            debug!("make_external_crate_suggestion: name={:?} path={:?} result={:?}",
+                    name, path, result);
+            if let PathResult::Module(..) = result {
+                return Some((path, Vec::new()));
+            }
+        }
 
-```compile_fail,E0434
-fn foo() {
-    let y = 5;
-    fn bar() -> u32 {
-        y // error: can't capture dynamic environment in a fn item; use the
-          //        || { ... } closure form instead.
+        None
     }
-}
-```
 
-Functions do not capture local variables. To fix this error, you can replace the
-function with a closure:
-
-```
-fn foo() {
-    let y = 5;
-    let bar = || {
-        y
-    };
-}
-```
+    /// Suggests importing a macro from the root of the crate rather than a module within
+    /// the crate.
+    ///
+    /// ```
+    /// help: a macro with this name exists at the root of the crate
+    ///    |
+    /// LL | use issue_59764::makro;
+    ///    |     ^^^^^^^^^^^^^^^^^^
+    ///    |
+    ///    = note: this could be because a macro annotated with `#[macro_export]` will be exported
+    ///            at the root of the crate instead of the module where it is defined
+    /// ```
+    pub(crate) fn check_for_module_export_macro(
+        &self,
+        directive: &'b ImportDirective<'b>,
+        module: ModuleOrUniformRoot<'b>,
+        ident: Ident,
+    ) -> Option<(Option<Suggestion>, Vec<String>)> {
+        let mut crate_module = if let ModuleOrUniformRoot::Module(module) = module {
+            module
+        } else {
+            return None;
+        };
+
+        while let Some(parent) = crate_module.parent {
+            crate_module = parent;
+        }
 
-or replace the captured variable with a constant or a static item:
+        if ModuleOrUniformRoot::same_def(ModuleOrUniformRoot::Module(crate_module), module) {
+            // Don't make a suggestion if the import was already from the root of the
+            // crate.
+            return None;
+        }
 
-```
-fn foo() {
-    static mut X: u32 = 4;
-    const Y: u32 = 5;
-    fn bar() -> u32 {
-        unsafe {
-            X = 3;
+        let resolutions = crate_module.resolutions.borrow();
+        let resolution = resolutions.get(&(ident, MacroNS))?;
+        let binding = resolution.borrow().binding()?;
+        if let Def::Macro(_, MacroKind::Bang) = binding.def() {
+            let module_name = crate_module.kind.name().unwrap();
+            let import = match directive.subclass {
+                ImportDirectiveSubclass::SingleImport { source, target, .. } if source != target =>
+                    format!("{} as {}", source, target),
+                _ => format!("{}", ident),
+            };
+
+            let mut corrections: Vec<(Span, String)> = Vec::new();
+            if !directive.is_nested() {
+                // Assume this is the easy case of `use issue_59764::foo::makro;` and just remove
+                // intermediate segments.
+                corrections.push((directive.span, format!("{}::{}", module_name, import)));
+            } else {
+                // Find the binding span (and any trailing commas and spaces).
+                //   ie. `use a::b::{c, d, e};`
+                //                      ^^^
+                let (found_closing_brace, binding_span) = find_span_of_binding_until_next_binding(
+                    self.resolver.session, directive.span, directive.use_span,
+                );
+                debug!("check_for_module_export_macro: found_closing_brace={:?} binding_span={:?}",
+                       found_closing_brace, binding_span);
+
+                let mut removal_span = binding_span;
+                if found_closing_brace {
+                    // If the binding span ended with a closing brace, as in the below example:
+                    //   ie. `use a::b::{c, d};`
+                    //                      ^
+                    // Then expand the span of characters to remove to include the previous
+                    // binding's trailing comma.
+                    //   ie. `use a::b::{c, d};`
+                    //                    ^^^
+                    if let Some(previous_span) = extend_span_to_previous_binding(
+                        self.resolver.session, binding_span,
+                    ) {
+                        debug!("check_for_module_export_macro: previous_span={:?}", previous_span);
+                        removal_span = removal_span.with_lo(previous_span.lo());
+                    }
+                }
+                debug!("check_for_module_export_macro: removal_span={:?}", removal_span);
+
+                // Remove the `removal_span`.
+                corrections.push((removal_span, "".to_string()));
+
+                // Find the span after the crate name and if it has nested imports immediatately
+                // after the crate name already.
+                //   ie. `use a::b::{c, d};`
+                //               ^^^^^^^^^
+                //   or  `use a::{b, c, d}};`
+                //               ^^^^^^^^^^^
+                let (has_nested, after_crate_name) = find_span_immediately_after_crate_name(
+                    self.resolver.session, module_name, directive.use_span,
+                );
+                debug!("check_for_module_export_macro: has_nested={:?} after_crate_name={:?}",
+                       has_nested, after_crate_name);
+
+                let source_map = self.resolver.session.source_map();
+
+                // Add the import to the start, with a `{` if required.
+                let start_point = source_map.start_point(after_crate_name);
+                if let Ok(start_snippet) = source_map.span_to_snippet(start_point) {
+                    corrections.push((
+                        start_point,
+                        if has_nested {
+                            // In this case, `start_snippet` must equal '{'.
+                            format!("{}{}, ", start_snippet, import)
+                        } else {
+                            // In this case, add a `{`, then the moved import, then whatever
+                            // was there before.
+                            format!("{{{}, {}", import, start_snippet)
+                        }
+                    ));
+                }
+
+                // Add a `};` to the end if nested, matching the `{` added at the start.
+                if !has_nested {
+                    corrections.push((source_map.end_point(after_crate_name),
+                                     "};".to_string()));
+                }
+            }
+
+            let suggestion = Some((
+                corrections,
+                String::from("a macro with this name exists at the root of the crate"),
+                Applicability::MaybeIncorrect,
+            ));
+            let note = vec![
+                "this could be because a macro annotated with `#[macro_export]` will be exported \
+                 at the root of the crate instead of the module where it is defined".to_string(),
+            ];
+            Some((suggestion, note))
+        } else {
+            None
         }
-        Y
     }
 }
-```
-"##,
-
-E0435: r##"
-A non-constant value was used in a constant expression.
-
-Erroneous code example:
-
-```compile_fail,E0435
-let foo = 42;
-let a: [u8; foo]; // error: attempt to use a non-constant value in a constant
-```
-
-To fix this error, please replace the value with a constant. Example:
-
-```
-let a: [u8; 42]; // ok!
-```
-
-Or:
-
-```
-const FOO: usize = 42;
-let a: [u8; FOO]; // ok!
-```
-"##,
-
-E0437: r##"
-Trait implementations can only implement associated types that are members of
-the trait in question. This error indicates that you attempted to implement
-an associated type whose name does not match the name of any associated type
-in the trait.
-
-Erroneous code example:
-
-```compile_fail,E0437
-trait Foo {}
-
-impl Foo for i32 {
-    type Bar = bool;
-}
-```
-
-The solution to this problem is to remove the extraneous associated type:
-
-```
-trait Foo {}
-
-impl Foo for i32 {}
-```
-"##,
-
-E0438: r##"
-Trait implementations can only implement associated constants that are
-members of the trait in question. This error indicates that you
-attempted to implement an associated constant whose name does not
-match the name of any associated constant in the trait.
-
-Erroneous code example:
-
-```compile_fail,E0438
-trait Foo {}
-
-impl Foo for i32 {
-    const BAR: bool = true;
-}
-```
-
-The solution to this problem is to remove the extraneous associated constant:
-
-```
-trait Foo {}
-
-impl Foo for i32 {}
-```
-"##,
-
-E0466: r##"
-Macro import declarations were malformed.
-
-Erroneous code examples:
-
-```compile_fail,E0466
-#[macro_use(a_macro(another_macro))] // error: invalid import declaration
-extern crate core as some_crate;
-
-#[macro_use(i_want = "some_macros")] // error: invalid import declaration
-extern crate core as another_crate;
-```
-
-This is a syntax error at the level of attribute declarations. The proper
-syntax for macro imports is the following:
-
-```ignore (cannot-doctest-multicrate-project)
-// In some_crate:
-#[macro_export]
-macro_rules! get_tacos {
-    ...
-}
-
-#[macro_export]
-macro_rules! get_pimientos {
-    ...
-}
-
-// In your crate:
-#[macro_use(get_tacos, get_pimientos)] // It imports `get_tacos` and
-extern crate some_crate;               // `get_pimientos` macros from some_crate
-```
-
-If you would like to import all exported macros, write `macro_use` with no
-arguments.
-"##,
-
-E0468: r##"
-A non-root module attempts to import macros from another crate.
-
-Example of erroneous code:
-
-```compile_fail,E0468
-mod foo {
-    #[macro_use(debug_assert)]  // error: must be at crate root to import
-    extern crate core;          //        macros from another crate
-    fn run_macro() { debug_assert!(true); }
-}
-```
-
-Only `extern crate` imports at the crate root level are allowed to import
-macros.
-
-Either move the macro import to crate root or do without the foreign macros.
-This will work:
-
-```
-#[macro_use(debug_assert)]
-extern crate core;
-
-mod foo {
-    fn run_macro() { debug_assert!(true); }
-}
-# fn main() {}
-```
-"##,
 
-E0469: r##"
-A macro listed for import was not found.
-
-Erroneous code example:
-
-```compile_fail,E0469
-#[macro_use(drink, be_merry)] // error: imported macro not found
-extern crate alloc;
-
-fn main() {
-    // ...
-}
-```
-
-Either the listed macro is not contained in the imported crate, or it is not
-exported from the given crate.
-
-This could be caused by a typo. Did you misspell the macro's name?
-
-Double-check the names of the macros listed for import, and that the crate
-in question exports them.
-
-A working version would be:
-
-```ignore (cannot-doctest-multicrate-project)
-// In some_crate crate:
-#[macro_export]
-macro_rules! eat {
-    ...
-}
-
-#[macro_export]
-macro_rules! drink {
-    ...
-}
-
-// In your crate:
-#[macro_use(eat, drink)]
-extern crate some_crate; //ok!
-```
-"##,
-
-E0530: r##"
-A binding shadowed something it shouldn't.
-
-Erroneous code example:
-
-```compile_fail,E0530
-static TEST: i32 = 0;
-
-let r: (i32, i32) = (0, 0);
-match r {
-    TEST => {} // error: match bindings cannot shadow statics
-}
-```
-
-To fix this error, just change the binding's name in order to avoid shadowing
-one of the following:
-
-* struct name
-* struct/enum variant
-* static
-* const
-* associated const
-
-Fixed example:
-
-```
-static TEST: i32 = 0;
-
-let r: (i32, i32) = (0, 0);
-match r {
-    something => {} // ok!
-}
-```
-"##,
-
-E0532: r##"
-Pattern arm did not match expected kind.
-
-Erroneous code example:
-
-```compile_fail,E0532
-enum State {
-    Succeeded,
-    Failed(String),
-}
-
-fn print_on_failure(state: &State) {
-    match *state {
-        // error: expected unit struct/variant or constant, found tuple
-        //        variant `State::Failed`
-        State::Failed => println!("Failed"),
-        _ => ()
+/// Given a `binding_span` of a binding within a use statement:
+///
+/// ```
+/// use foo::{a, b, c};
+///              ^
+/// ```
+///
+/// then return the span until the next binding or the end of the statement:
+///
+/// ```
+/// use foo::{a, b, c};
+///              ^^^
+/// ```
+pub(crate) fn find_span_of_binding_until_next_binding(
+    sess: &Session,
+    binding_span: Span,
+    use_span: Span,
+) -> (bool, Span) {
+    let source_map = sess.source_map();
+
+    // Find the span of everything after the binding.
+    //   ie. `a, e};` or `a};`
+    let binding_until_end = binding_span.with_hi(use_span.hi());
+
+    // Find everything after the binding but not including the binding.
+    //   ie. `, e};` or `};`
+    let after_binding_until_end = binding_until_end.with_lo(binding_span.hi());
+
+    // Keep characters in the span until we encounter something that isn't a comma or
+    // whitespace.
+    //   ie. `, ` or ``.
+    //
+    // Also note whether a closing brace character was encountered. If there
+    // was, then later go backwards to remove any trailing commas that are left.
+    let mut found_closing_brace = false;
+    let after_binding_until_next_binding = source_map.span_take_while(
+        after_binding_until_end,
+        |&ch| {
+            if ch == '}' { found_closing_brace = true; }
+            ch == ' ' || ch == ','
+        }
+    );
+
+    // Combine the two spans.
+    //   ie. `a, ` or `a`.
+    //
+    // Removing these would leave `issue_52891::{d, e};` or `issue_52891::{d, e, };`
+    let span = binding_span.with_hi(after_binding_until_next_binding.hi());
+
+    (found_closing_brace, span)
+}
+
+/// Given a `binding_span`, return the span through to the comma or opening brace of the previous
+/// binding.
+///
+/// ```
+/// use foo::a::{a, b, c};
+///               ^^--- binding span
+///               |
+///               returned span
+///
+/// use foo::{a, b, c};
+///           --- binding span
+/// ```
+pub(crate) fn extend_span_to_previous_binding(
+    sess: &Session,
+    binding_span: Span,
+) -> Option<Span> {
+    let source_map = sess.source_map();
+
+    // `prev_source` will contain all of the source that came before the span.
+    // Then split based on a command and take the first (ie. closest to our span)
+    // snippet. In the example, this is a space.
+    let prev_source = source_map.span_to_prev_source(binding_span).ok()?;
+
+    let prev_comma = prev_source.rsplit(',').collect::<Vec<_>>();
+    let prev_starting_brace = prev_source.rsplit('{').collect::<Vec<_>>();
+    if prev_comma.len() <= 1 || prev_starting_brace.len() <= 1 {
+        return None;
     }
-}
-```
-
-To fix this error, ensure the match arm kind is the same as the expression
-matched.
 
-Fixed example:
-
-```
-enum State {
-    Succeeded,
-    Failed(String),
-}
+    let prev_comma = prev_comma.first().unwrap();
+    let prev_starting_brace = prev_starting_brace.first().unwrap();
 
-fn print_on_failure(state: &State) {
-    match *state {
-        State::Failed(ref msg) => println!("Failed with {}", msg),
-        _ => ()
+    // If the amount of source code before the comma is greater than
+    // the amount of source code before the starting brace then we've only
+    // got one item in the nested item (eg. `issue_52891::{self}`).
+    if prev_comma.len() > prev_starting_brace.len() {
+        return None;
     }
-}
-```
-"##,
-
-E0603: r##"
-A private item was used outside its scope.
-
-Erroneous code example:
-
-```compile_fail,E0603
-mod SomeModule {
-    const PRIVATE: u32 = 0x_a_bad_1dea_u32; // This const is private, so we
-                                            // can't use it outside of the
-                                            // `SomeModule` module.
-}
-
-println!("const value: {}", SomeModule::PRIVATE); // error: constant `PRIVATE`
-                                                  //        is private
-```
-
-In order to fix this error, you need to make the item public by using the `pub`
-keyword. Example:
-
-```
-mod SomeModule {
-    pub const PRIVATE: u32 = 0x_a_bad_1dea_u32; // We set it public by using the
-                                                // `pub` keyword.
-}
 
-println!("const value: {}", SomeModule::PRIVATE); // ok!
-```
-"##,
-
-E0659: r##"
-An item usage is ambiguous.
-
-Erroneous code example:
-
-```compile_fail,E0659
-pub mod moon {
-    pub fn foo() {}
-}
-
-pub mod earth {
-    pub fn foo() {}
-}
-
-mod collider {
-    pub use moon::*;
-    pub use earth::*;
-}
-
-fn main() {
-    collider::foo(); // ERROR: `foo` is ambiguous
-}
-```
-
-This error generally appears when two items with the same name are imported into
-a module. Here, the `foo` functions are imported and reexported from the
-`collider` module and therefore, when we're using `collider::foo()`, both
-functions collide.
-
-To solve this error, the best solution is generally to keep the path before the
-item when using it. Example:
-
-```
-pub mod moon {
-    pub fn foo() {}
-}
-
-pub mod earth {
-    pub fn foo() {}
-}
-
-mod collider {
-    pub use moon;
-    pub use earth;
-}
-
-fn main() {
-    collider::moon::foo(); // ok!
-    collider::earth::foo(); // ok!
-}
-```
-"##,
-
-}
-
-register_diagnostics! {
-//  E0153, unused error code
-//  E0157, unused error code
-//  E0257,
-//  E0258,
-//  E0402, // cannot use an outer type parameter in this context
-//  E0406, merged into 420
-//  E0410, merged into 408
-//  E0413, merged into 530
-//  E0414, merged into 530
-//  E0417, merged into 532
-//  E0418, merged into 532
-//  E0419, merged into 531
-//  E0420, merged into 532
-//  E0421, merged into 531
-    E0531, // unresolved pattern path kind `name`
-//  E0427, merged into 530
-//  E0467, removed
-//  E0470, removed
-    E0573,
-    E0574,
-    E0575,
-    E0576,
-    E0577,
-    E0578,
+    Some(binding_span.with_lo(BytePos(
+        // Take away the number of bytes for the characters we've found and an
+        // extra for the comma.
+        binding_span.lo().0 - (prev_comma.as_bytes().len() as u32) - 1
+    )))
+}
+
+/// Given a `use_span` of a binding within a use statement, returns the highlighted span and if
+/// it is a nested use tree.
+///
+/// ```
+/// use foo::a::{b, c};
+///          ^^^^^^^^^^ // false
+///
+/// use foo::{a, b, c};
+///          ^^^^^^^^^^ // true
+///
+/// use foo::{a, b::{c, d}};
+///          ^^^^^^^^^^^^^^^ // true
+/// ```
+fn find_span_immediately_after_crate_name(
+    sess: &Session,
+    module_name: Symbol,
+    use_span: Span,
+) -> (bool, Span) {
+    debug!("find_span_immediately_after_crate_name: module_name={:?} use_span={:?}",
+           module_name, use_span);
+    let source_map = sess.source_map();
+
+    // Using `use issue_59764::foo::{baz, makro};` as an example throughout..
+    let mut num_colons = 0;
+    // Find second colon.. `use issue_59764:`
+    let until_second_colon = source_map.span_take_while(use_span, |c| {
+        if *c == ':' { num_colons += 1; }
+        match c {
+            ':' if num_colons == 2 => false,
+            _ => true,
+        }
+    });
+    // Find everything after the second colon.. `foo::{baz, makro};`
+    let from_second_colon = use_span.with_lo(until_second_colon.hi() + BytePos(1));
+
+    let mut found_a_non_whitespace_character = false;
+    // Find the first non-whitespace character in `from_second_colon`.. `f`
+    let after_second_colon = source_map.span_take_while(from_second_colon, |c| {
+        if found_a_non_whitespace_character { return false; }
+        if !c.is_whitespace() { found_a_non_whitespace_character = true; }
+        true
+    });
+
+    // Find the first `{` in from_second_colon.. `foo::{`
+    let next_left_bracket = source_map.span_through_char(from_second_colon, '{');
+
+    (next_left_bracket == after_second_colon, from_second_colon)
 }
diff --git a/src/librustc_resolve/error_codes.rs b/src/librustc_resolve/error_codes.rs
new file mode 100644
index 00000000000..5c095994a1b
--- /dev/null
+++ b/src/librustc_resolve/error_codes.rs
@@ -0,0 +1,1672 @@
+#![allow(non_snake_case)]
+
+use syntax::{register_diagnostic, register_diagnostics, register_long_diagnostics};
+
+// Error messages for EXXXX errors.  Each message should start and end with a
+// new line, and be wrapped to 80 characters.  In vim you can `:set tw=80` and
+// use `gq` to wrap paragraphs. Use `:set tw=0` to disable.
+register_long_diagnostics! {
+
+E0128: r##"
+Type parameter defaults can only use parameters that occur before them.
+Erroneous code example:
+
+```compile_fail,E0128
+struct Foo<T=U, U=()> {
+    field1: T,
+    filed2: U,
+}
+// error: type parameters with a default cannot use forward declared
+// identifiers
+```
+
+Since type parameters are evaluated in-order, you may be able to fix this issue
+by doing:
+
+```
+struct Foo<U=(), T=U> {
+    field1: T,
+    filed2: U,
+}
+```
+
+Please also verify that this wasn't because of a name-clash and rename the type
+parameter if so.
+"##,
+
+E0154: r##"
+#### Note: this error code is no longer emitted by the compiler.
+
+Imports (`use` statements) are not allowed after non-item statements, such as
+variable declarations and expression statements.
+
+Here is an example that demonstrates the error:
+
+```
+fn f() {
+    // Variable declaration before import
+    let x = 0;
+    use std::io::Read;
+    // ...
+}
+```
+
+The solution is to declare the imports at the top of the block, function, or
+file.
+
+Here is the previous example again, with the correct order:
+
+```
+fn f() {
+    use std::io::Read;
+    let x = 0;
+    // ...
+}
+```
+
+See the Declaration Statements section of the reference for more information
+about what constitutes an Item declaration and what does not:
+
+https://doc.rust-lang.org/reference.html#statements
+"##,
+
+E0251: r##"
+#### Note: this error code is no longer emitted by the compiler.
+
+Two items of the same name cannot be imported without rebinding one of the
+items under a new local name.
+
+An example of this error:
+
+```
+use foo::baz;
+use bar::*; // error, do `use foo::baz as quux` instead on the previous line
+
+fn main() {}
+
+mod foo {
+    pub struct baz;
+}
+
+mod bar {
+    pub mod baz {}
+}
+```
+"##,
+
+E0252: r##"
+Two items of the same name cannot be imported without rebinding one of the
+items under a new local name.
+
+Erroneous code example:
+
+```compile_fail,E0252
+use foo::baz;
+use bar::baz; // error, do `use bar::baz as quux` instead
+
+fn main() {}
+
+mod foo {
+    pub struct baz;
+}
+
+mod bar {
+    pub mod baz {}
+}
+```
+
+You can use aliases in order to fix this error. Example:
+
+```
+use foo::baz as foo_baz;
+use bar::baz; // ok!
+
+fn main() {}
+
+mod foo {
+    pub struct baz;
+}
+
+mod bar {
+    pub mod baz {}
+}
+```
+
+Or you can reference the item with its parent:
+
+```
+use bar::baz;
+
+fn main() {
+    let x = foo::baz; // ok!
+}
+
+mod foo {
+    pub struct baz;
+}
+
+mod bar {
+    pub mod baz {}
+}
+```
+"##,
+
+E0253: r##"
+Attempt was made to import an unimportable value. This can happen when trying
+to import a method from a trait.
+
+Erroneous code example:
+
+```compile_fail,E0253
+mod foo {
+    pub trait MyTrait {
+        fn do_something();
+    }
+}
+
+use foo::MyTrait::do_something;
+// error: `do_something` is not directly importable
+
+fn main() {}
+```
+
+It's invalid to directly import methods belonging to a trait or concrete type.
+"##,
+
+E0254: r##"
+Attempt was made to import an item whereas an extern crate with this name has
+already been imported.
+
+Erroneous code example:
+
+```compile_fail,E0254
+extern crate core;
+
+mod foo {
+    pub trait core {
+        fn do_something();
+    }
+}
+
+use foo::core;  // error: an extern crate named `core` has already
+                //        been imported in this module
+
+fn main() {}
+```
+
+To fix this issue, you have to rename at least one of the two imports.
+Example:
+
+```
+extern crate core as libcore; // ok!
+
+mod foo {
+    pub trait core {
+        fn do_something();
+    }
+}
+
+use foo::core;
+
+fn main() {}
+```
+"##,
+
+E0255: r##"
+You can't import a value whose name is the same as another value defined in the
+module.
+
+Erroneous code example:
+
+```compile_fail,E0255
+use bar::foo; // error: an item named `foo` is already in scope
+
+fn foo() {}
+
+mod bar {
+     pub fn foo() {}
+}
+
+fn main() {}
+```
+
+You can use aliases in order to fix this error. Example:
+
+```
+use bar::foo as bar_foo; // ok!
+
+fn foo() {}
+
+mod bar {
+     pub fn foo() {}
+}
+
+fn main() {}
+```
+
+Or you can reference the item with its parent:
+
+```
+fn foo() {}
+
+mod bar {
+     pub fn foo() {}
+}
+
+fn main() {
+    bar::foo(); // we get the item by referring to its parent
+}
+```
+"##,
+
+E0256: r##"
+#### Note: this error code is no longer emitted by the compiler.
+
+You can't import a type or module when the name of the item being imported is
+the same as another type or submodule defined in the module.
+
+An example of this error:
+
+```compile_fail
+use foo::Bar; // error
+
+type Bar = u32;
+
+mod foo {
+    pub mod Bar { }
+}
+
+fn main() {}
+```
+"##,
+
+E0259: r##"
+The name chosen for an external crate conflicts with another external crate
+that has been imported into the current module.
+
+Erroneous code example:
+
+```compile_fail,E0259
+extern crate core;
+extern crate std as core;
+
+fn main() {}
+```
+
+The solution is to choose a different name that doesn't conflict with any
+external crate imported into the current module.
+
+Correct example:
+
+```
+extern crate core;
+extern crate std as other_name;
+
+fn main() {}
+```
+"##,
+
+E0260: r##"
+The name for an item declaration conflicts with an external crate's name.
+
+Erroneous code example:
+
+```compile_fail,E0260
+extern crate core;
+
+struct core;
+
+fn main() {}
+```
+
+There are two possible solutions:
+
+Solution #1: Rename the item.
+
+```
+extern crate core;
+
+struct xyz;
+```
+
+Solution #2: Import the crate with a different name.
+
+```
+extern crate core as xyz;
+
+struct abc;
+```
+
+See the Declaration Statements section of the reference for more information
+about what constitutes an Item declaration and what does not:
+
+https://doc.rust-lang.org/reference.html#statements
+"##,
+
+E0364: r##"
+Private items cannot be publicly re-exported. This error indicates that you
+attempted to `pub use` a type or value that was not itself public.
+
+Erroneous code example:
+
+```compile_fail
+mod foo {
+    const X: u32 = 1;
+}
+
+pub use foo::X;
+
+fn main() {}
+```
+
+The solution to this problem is to ensure that the items that you are
+re-exporting are themselves marked with `pub`:
+
+```
+mod foo {
+    pub const X: u32 = 1;
+}
+
+pub use foo::X;
+
+fn main() {}
+```
+
+See the 'Use Declarations' section of the reference for more information on
+this topic:
+
+https://doc.rust-lang.org/reference.html#use-declarations
+"##,
+
+E0365: r##"
+Private modules cannot be publicly re-exported. This error indicates that you
+attempted to `pub use` a module that was not itself public.
+
+Erroneous code example:
+
+```compile_fail,E0365
+mod foo {
+    pub const X: u32 = 1;
+}
+
+pub use foo as foo2;
+
+fn main() {}
+```
+
+The solution to this problem is to ensure that the module that you are
+re-exporting is itself marked with `pub`:
+
+```
+pub mod foo {
+    pub const X: u32 = 1;
+}
+
+pub use foo as foo2;
+
+fn main() {}
+```
+
+See the 'Use Declarations' section of the reference for more information
+on this topic:
+
+https://doc.rust-lang.org/reference.html#use-declarations
+"##,
+
+E0401: r##"
+Inner items do not inherit type or const parameters from the functions
+they are embedded in.
+
+Erroneous code example:
+
+```compile_fail,E0401
+fn foo<T>(x: T) {
+    fn bar(y: T) { // T is defined in the "outer" function
+        // ..
+    }
+    bar(x);
+}
+```
+
+Nor will this:
+
+```compile_fail,E0401
+fn foo<T>(x: T) {
+    type MaybeT = Option<T>;
+    // ...
+}
+```
+
+Or this:
+
+```compile_fail,E0401
+fn foo<T>(x: T) {
+    struct Foo {
+        x: T,
+    }
+    // ...
+}
+```
+
+Items inside functions are basically just like top-level items, except
+that they can only be used from the function they are in.
+
+There are a couple of solutions for this.
+
+If the item is a function, you may use a closure:
+
+```
+fn foo<T>(x: T) {
+    let bar = |y: T| { // explicit type annotation may not be necessary
+        // ..
+    };
+    bar(x);
+}
+```
+
+For a generic item, you can copy over the parameters:
+
+```
+fn foo<T>(x: T) {
+    fn bar<T>(y: T) {
+        // ..
+    }
+    bar(x);
+}
+```
+
+```
+fn foo<T>(x: T) {
+    type MaybeT<T> = Option<T>;
+}
+```
+
+Be sure to copy over any bounds as well:
+
+```
+fn foo<T: Copy>(x: T) {
+    fn bar<T: Copy>(y: T) {
+        // ..
+    }
+    bar(x);
+}
+```
+
+```
+fn foo<T: Copy>(x: T) {
+    struct Foo<T: Copy> {
+        x: T,
+    }
+}
+```
+
+This may require additional type hints in the function body.
+
+In case the item is a function inside an `impl`, defining a private helper
+function might be easier:
+
+```
+# struct Foo<T>(T);
+impl<T> Foo<T> {
+    pub fn foo(&self, x: T) {
+        self.bar(x);
+    }
+
+    fn bar(&self, y: T) {
+        // ..
+    }
+}
+```
+
+For default impls in traits, the private helper solution won't work, however
+closures or copying the parameters should still work.
+"##,
+
+E0403: r##"
+Some type parameters have the same name.
+
+Erroneous code example:
+
+```compile_fail,E0403
+fn foo<T, T>(s: T, u: T) {} // error: the name `T` is already used for a type
+                            //        parameter in this type parameter list
+```
+
+Please verify that none of the type parameters are misspelled, and rename any
+clashing parameters. Example:
+
+```
+fn foo<T, Y>(s: T, u: Y) {} // ok!
+```
+"##,
+
+E0404: r##"
+You tried to use something which is not a trait in a trait position, such as
+a bound or `impl`.
+
+Erroneous code example:
+
+```compile_fail,E0404
+struct Foo;
+struct Bar;
+
+impl Foo for Bar {} // error: `Foo` is not a trait
+```
+
+Another erroneous code example:
+
+```compile_fail,E0404
+struct Foo;
+
+fn bar<T: Foo>(t: T) {} // error: `Foo` is not a trait
+```
+
+Please verify that you didn't misspell the trait's name or otherwise use the
+wrong identifier. Example:
+
+```
+trait Foo {
+    // some functions
+}
+struct Bar;
+
+impl Foo for Bar { // ok!
+    // functions implementation
+}
+```
+
+or
+
+```
+trait Foo {
+    // some functions
+}
+
+fn bar<T: Foo>(t: T) {} // ok!
+```
+
+"##,
+
+E0405: r##"
+The code refers to a trait that is not in scope.
+
+Erroneous code example:
+
+```compile_fail,E0405
+struct Foo;
+
+impl SomeTrait for Foo {} // error: trait `SomeTrait` is not in scope
+```
+
+Please verify that the name of the trait wasn't misspelled and ensure that it
+was imported. Example:
+
+```
+# #[cfg(for_demonstration_only)]
+// solution 1:
+use some_file::SomeTrait;
+
+// solution 2:
+trait SomeTrait {
+    // some functions
+}
+
+struct Foo;
+
+impl SomeTrait for Foo { // ok!
+    // implements functions
+}
+```
+"##,
+
+E0407: r##"
+A definition of a method not in the implemented trait was given in a trait
+implementation.
+
+Erroneous code example:
+
+```compile_fail,E0407
+trait Foo {
+    fn a();
+}
+
+struct Bar;
+
+impl Foo for Bar {
+    fn a() {}
+    fn b() {} // error: method `b` is not a member of trait `Foo`
+}
+```
+
+Please verify you didn't misspell the method name and you used the correct
+trait. First example:
+
+```
+trait Foo {
+    fn a();
+    fn b();
+}
+
+struct Bar;
+
+impl Foo for Bar {
+    fn a() {}
+    fn b() {} // ok!
+}
+```
+
+Second example:
+
+```
+trait Foo {
+    fn a();
+}
+
+struct Bar;
+
+impl Foo for Bar {
+    fn a() {}
+}
+
+impl Bar {
+    fn b() {}
+}
+```
+"##,
+
+E0408: r##"
+An "or" pattern was used where the variable bindings are not consistently bound
+across patterns.
+
+Erroneous code example:
+
+```compile_fail,E0408
+match x {
+    Some(y) | None => { /* use y */ } // error: variable `y` from pattern #1 is
+                                      //        not bound in pattern #2
+    _ => ()
+}
+```
+
+Here, `y` is bound to the contents of the `Some` and can be used within the
+block corresponding to the match arm. However, in case `x` is `None`, we have
+not specified what `y` is, and the block will use a nonexistent variable.
+
+To fix this error, either split into multiple match arms:
+
+```
+let x = Some(1);
+match x {
+    Some(y) => { /* use y */ }
+    None => { /* ... */ }
+}
+```
+
+or, bind the variable to a field of the same type in all sub-patterns of the
+or pattern:
+
+```
+let x = (0, 2);
+match x {
+    (0, y) | (y, 0) => { /* use y */}
+    _ => {}
+}
+```
+
+In this example, if `x` matches the pattern `(0, _)`, the second field is set
+to `y`. If it matches `(_, 0)`, the first field is set to `y`; so in all
+cases `y` is set to some value.
+"##,
+
+E0409: r##"
+An "or" pattern was used where the variable bindings are not consistently bound
+across patterns.
+
+Erroneous code example:
+
+```compile_fail,E0409
+let x = (0, 2);
+match x {
+    (0, ref y) | (y, 0) => { /* use y */} // error: variable `y` is bound with
+                                          //        different mode in pattern #2
+                                          //        than in pattern #1
+    _ => ()
+}
+```
+
+Here, `y` is bound by-value in one case and by-reference in the other.
+
+To fix this error, just use the same mode in both cases.
+Generally using `ref` or `ref mut` where not already used will fix this:
+
+```
+let x = (0, 2);
+match x {
+    (0, ref y) | (ref y, 0) => { /* use y */}
+    _ => ()
+}
+```
+
+Alternatively, split the pattern:
+
+```
+let x = (0, 2);
+match x {
+    (y, 0) => { /* use y */ }
+    (0, ref y) => { /* use y */}
+    _ => ()
+}
+```
+"##,
+
+E0411: r##"
+The `Self` keyword was used outside an impl, trait, or type definition.
+
+Erroneous code example:
+
+```compile_fail,E0411
+<Self>::foo; // error: use of `Self` outside of an impl, trait, or type
+             // definition
+```
+
+The `Self` keyword represents the current type, which explains why it can only
+be used inside an impl, trait, or type definition. It gives access to the
+associated items of a type:
+
+```
+trait Foo {
+    type Bar;
+}
+
+trait Baz : Foo {
+    fn bar() -> Self::Bar; // like this
+}
+```
+
+However, be careful when two types have a common associated type:
+
+```compile_fail
+trait Foo {
+    type Bar;
+}
+
+trait Foo2 {
+    type Bar;
+}
+
+trait Baz : Foo + Foo2 {
+    fn bar() -> Self::Bar;
+    // error: ambiguous associated type `Bar` in bounds of `Self`
+}
+```
+
+This problem can be solved by specifying from which trait we want to use the
+`Bar` type:
+
+```
+trait Foo {
+    type Bar;
+}
+
+trait Foo2 {
+    type Bar;
+}
+
+trait Baz : Foo + Foo2 {
+    fn bar() -> <Self as Foo>::Bar; // ok!
+}
+```
+"##,
+
+E0412: r##"
+The type name used is not in scope.
+
+Erroneous code examples:
+
+```compile_fail,E0412
+impl Something {} // error: type name `Something` is not in scope
+
+// or:
+
+trait Foo {
+    fn bar(N); // error: type name `N` is not in scope
+}
+
+// or:
+
+fn foo(x: T) {} // type name `T` is not in scope
+```
+
+To fix this error, please verify you didn't misspell the type name, you did
+declare it or imported it into the scope. Examples:
+
+```
+struct Something;
+
+impl Something {} // ok!
+
+// or:
+
+trait Foo {
+    type N;
+
+    fn bar(_: Self::N); // ok!
+}
+
+// or:
+
+fn foo<T>(x: T) {} // ok!
+```
+
+Another case that causes this error is when a type is imported into a parent
+module. To fix this, you can follow the suggestion and use File directly or
+`use super::File;` which will import the types from the parent namespace. An
+example that causes this error is below:
+
+```compile_fail,E0412
+use std::fs::File;
+
+mod foo {
+    fn some_function(f: File) {}
+}
+```
+
+```
+use std::fs::File;
+
+mod foo {
+    // either
+    use super::File;
+    // or
+    // use std::fs::File;
+    fn foo(f: File) {}
+}
+# fn main() {} // don't insert it for us; that'll break imports
+```
+"##,
+
+E0415: r##"
+More than one function parameter have the same name.
+
+Erroneous code example:
+
+```compile_fail,E0415
+fn foo(f: i32, f: i32) {} // error: identifier `f` is bound more than
+                          //        once in this parameter list
+```
+
+Please verify you didn't misspell parameters' name. Example:
+
+```
+fn foo(f: i32, g: i32) {} // ok!
+```
+"##,
+
+E0416: r##"
+An identifier is bound more than once in a pattern.
+
+Erroneous code example:
+
+```compile_fail,E0416
+match (1, 2) {
+    (x, x) => {} // error: identifier `x` is bound more than once in the
+                 //        same pattern
+}
+```
+
+Please verify you didn't misspell identifiers' name. Example:
+
+```
+match (1, 2) {
+    (x, y) => {} // ok!
+}
+```
+
+Or maybe did you mean to unify? Consider using a guard:
+
+```
+# let (A, B, C) = (1, 2, 3);
+match (A, B, C) {
+    (x, x2, see) if x == x2 => { /* A and B are equal, do one thing */ }
+    (y, z, see) => { /* A and B unequal; do another thing */ }
+}
+```
+"##,
+
+E0422: r##"
+You are trying to use an identifier that is either undefined or not a struct.
+Erroneous code example:
+
+```compile_fail,E0422
+fn main () {
+    let x = Foo { x: 1, y: 2 };
+}
+```
+
+In this case, `Foo` is undefined, so it inherently isn't anything, and
+definitely not a struct.
+
+```compile_fail
+fn main () {
+    let foo = 1;
+    let x = foo { x: 1, y: 2 };
+}
+```
+
+In this case, `foo` is defined, but is not a struct, so Rust can't use it as
+one.
+"##,
+
+E0423: r##"
+An identifier was used like a function name or a value was expected and the
+identifier exists but it belongs to a different namespace.
+
+For (an erroneous) example, here a `struct` variant name were used as a
+function:
+
+```compile_fail,E0423
+struct Foo { a: bool };
+
+let f = Foo();
+// error: expected function, found `Foo`
+// `Foo` is a struct name, but this expression uses it like a function name
+```
+
+Please verify you didn't misspell the name of what you actually wanted to use
+here. Example:
+
+```
+fn Foo() -> u32 { 0 }
+
+let f = Foo(); // ok!
+```
+
+It is common to forget the trailing `!` on macro invocations, which would also
+yield this error:
+
+```compile_fail,E0423
+println("");
+// error: expected function, found macro `println`
+// did you mean `println!(...)`? (notice the trailing `!`)
+```
+
+Another case where this error is emitted is when a value is expected, but
+something else is found:
+
+```compile_fail,E0423
+pub mod a {
+    pub const I: i32 = 1;
+}
+
+fn h1() -> i32 {
+    a.I
+    //~^ ERROR expected value, found module `a`
+    // did you mean `a::I`?
+}
+```
+"##,
+
+E0424: r##"
+The `self` keyword was used in a static method.
+
+Erroneous code example:
+
+```compile_fail,E0424
+struct Foo;
+
+impl Foo {
+    fn bar(self) {}
+
+    fn foo() {
+        self.bar(); // error: `self` is not available in a static method.
+    }
+}
+```
+
+Please check if the method's argument list should have contained `self`,
+`&self`, or `&mut self` (in case you didn't want to create a static
+method), and add it if so. Example:
+
+```
+struct Foo;
+
+impl Foo {
+    fn bar(self) {}
+
+    fn foo(self) {
+        self.bar(); // ok!
+    }
+}
+```
+"##,
+
+E0425: r##"
+An unresolved name was used.
+
+Erroneous code examples:
+
+```compile_fail,E0425
+something_that_doesnt_exist::foo;
+// error: unresolved name `something_that_doesnt_exist::foo`
+
+// or:
+
+trait Foo {
+    fn bar() {
+        Self; // error: unresolved name `Self`
+    }
+}
+
+// or:
+
+let x = unknown_variable;  // error: unresolved name `unknown_variable`
+```
+
+Please verify that the name wasn't misspelled and ensure that the
+identifier being referred to is valid for the given situation. Example:
+
+```
+enum something_that_does_exist {
+    Foo,
+}
+```
+
+Or:
+
+```
+mod something_that_does_exist {
+    pub static foo : i32 = 0i32;
+}
+
+something_that_does_exist::foo; // ok!
+```
+
+Or:
+
+```
+let unknown_variable = 12u32;
+let x = unknown_variable; // ok!
+```
+
+If the item is not defined in the current module, it must be imported using a
+`use` statement, like so:
+
+```
+# mod foo { pub fn bar() {} }
+# fn main() {
+use foo::bar;
+bar();
+# }
+```
+
+If the item you are importing is not defined in some super-module of the
+current module, then it must also be declared as public (e.g., `pub fn`).
+"##,
+
+E0426: r##"
+An undeclared label was used.
+
+Erroneous code example:
+
+```compile_fail,E0426
+loop {
+    break 'a; // error: use of undeclared label `'a`
+}
+```
+
+Please verify you spelt or declare the label correctly. Example:
+
+```
+'a: loop {
+    break 'a; // ok!
+}
+```
+"##,
+
+E0428: r##"
+A type or module has been defined more than once.
+
+Erroneous code example:
+
+```compile_fail,E0428
+struct Bar;
+struct Bar; // error: duplicate definition of value `Bar`
+```
+
+Please verify you didn't misspell the type/module's name or remove/rename the
+duplicated one. Example:
+
+```
+struct Bar;
+struct Bar2; // ok!
+```
+"##,
+
+E0429: r##"
+The `self` keyword cannot appear alone as the last segment in a `use`
+declaration.
+
+Erroneous code example:
+
+```compile_fail,E0429
+use std::fmt::self; // error: `self` imports are only allowed within a { } list
+```
+
+To use a namespace itself in addition to some of its members, `self` may appear
+as part of a brace-enclosed list of imports:
+
+```
+use std::fmt::{self, Debug};
+```
+
+If you only want to import the namespace, do so directly:
+
+```
+use std::fmt;
+```
+"##,
+
+E0430: r##"
+The `self` import appears more than once in the list.
+
+Erroneous code example:
+
+```compile_fail,E0430
+use something::{self, self}; // error: `self` import can only appear once in
+                             //        the list
+```
+
+Please verify you didn't misspell the import name or remove the duplicated
+`self` import. Example:
+
+```
+# mod something {}
+# fn main() {
+use something::{self}; // ok!
+# }
+```
+"##,
+
+E0431: r##"
+An invalid `self` import was made.
+
+Erroneous code example:
+
+```compile_fail,E0431
+use {self}; // error: `self` import can only appear in an import list with a
+            //        non-empty prefix
+```
+
+You cannot import the current module into itself, please remove this import
+or verify you didn't misspell it.
+"##,
+
+E0432: r##"
+An import was unresolved.
+
+Erroneous code example:
+
+```compile_fail,E0432
+use something::Foo; // error: unresolved import `something::Foo`.
+```
+
+Paths in `use` statements are relative to the crate root. To import items
+relative to the current and parent modules, use the `self::` and `super::`
+prefixes, respectively. Also verify that you didn't misspell the import
+name and that the import exists in the module from where you tried to
+import it. Example:
+
+```
+use self::something::Foo; // ok!
+
+mod something {
+    pub struct Foo;
+}
+# fn main() {}
+```
+
+Or, if you tried to use a module from an external crate, you may have missed
+the `extern crate` declaration (which is usually placed in the crate root):
+
+```
+extern crate core; // Required to use the `core` crate
+
+use core::any;
+# fn main() {}
+```
+"##,
+
+E0433: r##"
+An undeclared type or module was used.
+
+Erroneous code example:
+
+```compile_fail,E0433
+let map = HashMap::new();
+// error: failed to resolve: use of undeclared type or module `HashMap`
+```
+
+Please verify you didn't misspell the type/module's name or that you didn't
+forget to import it:
+
+
+```
+use std::collections::HashMap; // HashMap has been imported.
+let map: HashMap<u32, u32> = HashMap::new(); // So it can be used!
+```
+"##,
+
+E0434: r##"
+This error indicates that a variable usage inside an inner function is invalid
+because the variable comes from a dynamic environment. Inner functions do not
+have access to their containing environment.
+
+Erroneous code example:
+
+```compile_fail,E0434
+fn foo() {
+    let y = 5;
+    fn bar() -> u32 {
+        y // error: can't capture dynamic environment in a fn item; use the
+          //        || { ... } closure form instead.
+    }
+}
+```
+
+Functions do not capture local variables. To fix this error, you can replace the
+function with a closure:
+
+```
+fn foo() {
+    let y = 5;
+    let bar = || {
+        y
+    };
+}
+```
+
+or replace the captured variable with a constant or a static item:
+
+```
+fn foo() {
+    static mut X: u32 = 4;
+    const Y: u32 = 5;
+    fn bar() -> u32 {
+        unsafe {
+            X = 3;
+        }
+        Y
+    }
+}
+```
+"##,
+
+E0435: r##"
+A non-constant value was used in a constant expression.
+
+Erroneous code example:
+
+```compile_fail,E0435
+let foo = 42;
+let a: [u8; foo]; // error: attempt to use a non-constant value in a constant
+```
+
+To fix this error, please replace the value with a constant. Example:
+
+```
+let a: [u8; 42]; // ok!
+```
+
+Or:
+
+```
+const FOO: usize = 42;
+let a: [u8; FOO]; // ok!
+```
+"##,
+
+E0437: r##"
+Trait implementations can only implement associated types that are members of
+the trait in question. This error indicates that you attempted to implement
+an associated type whose name does not match the name of any associated type
+in the trait.
+
+Erroneous code example:
+
+```compile_fail,E0437
+trait Foo {}
+
+impl Foo for i32 {
+    type Bar = bool;
+}
+```
+
+The solution to this problem is to remove the extraneous associated type:
+
+```
+trait Foo {}
+
+impl Foo for i32 {}
+```
+"##,
+
+E0438: r##"
+Trait implementations can only implement associated constants that are
+members of the trait in question. This error indicates that you
+attempted to implement an associated constant whose name does not
+match the name of any associated constant in the trait.
+
+Erroneous code example:
+
+```compile_fail,E0438
+trait Foo {}
+
+impl Foo for i32 {
+    const BAR: bool = true;
+}
+```
+
+The solution to this problem is to remove the extraneous associated constant:
+
+```
+trait Foo {}
+
+impl Foo for i32 {}
+```
+"##,
+
+E0466: r##"
+Macro import declarations were malformed.
+
+Erroneous code examples:
+
+```compile_fail,E0466
+#[macro_use(a_macro(another_macro))] // error: invalid import declaration
+extern crate core as some_crate;
+
+#[macro_use(i_want = "some_macros")] // error: invalid import declaration
+extern crate core as another_crate;
+```
+
+This is a syntax error at the level of attribute declarations. The proper
+syntax for macro imports is the following:
+
+```ignore (cannot-doctest-multicrate-project)
+// In some_crate:
+#[macro_export]
+macro_rules! get_tacos {
+    ...
+}
+
+#[macro_export]
+macro_rules! get_pimientos {
+    ...
+}
+
+// In your crate:
+#[macro_use(get_tacos, get_pimientos)] // It imports `get_tacos` and
+extern crate some_crate;               // `get_pimientos` macros from some_crate
+```
+
+If you would like to import all exported macros, write `macro_use` with no
+arguments.
+"##,
+
+E0468: r##"
+A non-root module attempts to import macros from another crate.
+
+Example of erroneous code:
+
+```compile_fail,E0468
+mod foo {
+    #[macro_use(debug_assert)]  // error: must be at crate root to import
+    extern crate core;          //        macros from another crate
+    fn run_macro() { debug_assert!(true); }
+}
+```
+
+Only `extern crate` imports at the crate root level are allowed to import
+macros.
+
+Either move the macro import to crate root or do without the foreign macros.
+This will work:
+
+```
+#[macro_use(debug_assert)]
+extern crate core;
+
+mod foo {
+    fn run_macro() { debug_assert!(true); }
+}
+# fn main() {}
+```
+"##,
+
+E0469: r##"
+A macro listed for import was not found.
+
+Erroneous code example:
+
+```compile_fail,E0469
+#[macro_use(drink, be_merry)] // error: imported macro not found
+extern crate alloc;
+
+fn main() {
+    // ...
+}
+```
+
+Either the listed macro is not contained in the imported crate, or it is not
+exported from the given crate.
+
+This could be caused by a typo. Did you misspell the macro's name?
+
+Double-check the names of the macros listed for import, and that the crate
+in question exports them.
+
+A working version would be:
+
+```ignore (cannot-doctest-multicrate-project)
+// In some_crate crate:
+#[macro_export]
+macro_rules! eat {
+    ...
+}
+
+#[macro_export]
+macro_rules! drink {
+    ...
+}
+
+// In your crate:
+#[macro_use(eat, drink)]
+extern crate some_crate; //ok!
+```
+"##,
+
+E0530: r##"
+A binding shadowed something it shouldn't.
+
+Erroneous code example:
+
+```compile_fail,E0530
+static TEST: i32 = 0;
+
+let r: (i32, i32) = (0, 0);
+match r {
+    TEST => {} // error: match bindings cannot shadow statics
+}
+```
+
+To fix this error, just change the binding's name in order to avoid shadowing
+one of the following:
+
+* struct name
+* struct/enum variant
+* static
+* const
+* associated const
+
+Fixed example:
+
+```
+static TEST: i32 = 0;
+
+let r: (i32, i32) = (0, 0);
+match r {
+    something => {} // ok!
+}
+```
+"##,
+
+E0532: r##"
+Pattern arm did not match expected kind.
+
+Erroneous code example:
+
+```compile_fail,E0532
+enum State {
+    Succeeded,
+    Failed(String),
+}
+
+fn print_on_failure(state: &State) {
+    match *state {
+        // error: expected unit struct/variant or constant, found tuple
+        //        variant `State::Failed`
+        State::Failed => println!("Failed"),
+        _ => ()
+    }
+}
+```
+
+To fix this error, ensure the match arm kind is the same as the expression
+matched.
+
+Fixed example:
+
+```
+enum State {
+    Succeeded,
+    Failed(String),
+}
+
+fn print_on_failure(state: &State) {
+    match *state {
+        State::Failed(ref msg) => println!("Failed with {}", msg),
+        _ => ()
+    }
+}
+```
+"##,
+
+E0603: r##"
+A private item was used outside its scope.
+
+Erroneous code example:
+
+```compile_fail,E0603
+mod SomeModule {
+    const PRIVATE: u32 = 0x_a_bad_1dea_u32; // This const is private, so we
+                                            // can't use it outside of the
+                                            // `SomeModule` module.
+}
+
+println!("const value: {}", SomeModule::PRIVATE); // error: constant `PRIVATE`
+                                                  //        is private
+```
+
+In order to fix this error, you need to make the item public by using the `pub`
+keyword. Example:
+
+```
+mod SomeModule {
+    pub const PRIVATE: u32 = 0x_a_bad_1dea_u32; // We set it public by using the
+                                                // `pub` keyword.
+}
+
+println!("const value: {}", SomeModule::PRIVATE); // ok!
+```
+"##,
+
+E0659: r##"
+An item usage is ambiguous.
+
+Erroneous code example:
+
+```compile_fail,E0659
+pub mod moon {
+    pub fn foo() {}
+}
+
+pub mod earth {
+    pub fn foo() {}
+}
+
+mod collider {
+    pub use moon::*;
+    pub use earth::*;
+}
+
+fn main() {
+    collider::foo(); // ERROR: `foo` is ambiguous
+}
+```
+
+This error generally appears when two items with the same name are imported into
+a module. Here, the `foo` functions are imported and reexported from the
+`collider` module and therefore, when we're using `collider::foo()`, both
+functions collide.
+
+To solve this error, the best solution is generally to keep the path before the
+item when using it. Example:
+
+```
+pub mod moon {
+    pub fn foo() {}
+}
+
+pub mod earth {
+    pub fn foo() {}
+}
+
+mod collider {
+    pub use moon;
+    pub use earth;
+}
+
+fn main() {
+    collider::moon::foo(); // ok!
+    collider::earth::foo(); // ok!
+}
+```
+"##,
+
+}
+
+register_diagnostics! {
+//  E0153, unused error code
+//  E0157, unused error code
+//  E0257,
+//  E0258,
+//  E0402, // cannot use an outer type parameter in this context
+//  E0406, merged into 420
+//  E0410, merged into 408
+//  E0413, merged into 530
+//  E0414, merged into 530
+//  E0417, merged into 532
+//  E0418, merged into 532
+//  E0419, merged into 531
+//  E0420, merged into 532
+//  E0421, merged into 531
+    E0531, // unresolved pattern path kind `name`
+//  E0427, merged into 530
+//  E0467, removed
+//  E0470, removed
+    E0573,
+    E0574,
+    E0575,
+    E0576,
+    E0577,
+    E0578,
+}
diff --git a/src/librustc_resolve/error_reporting.rs b/src/librustc_resolve/error_reporting.rs
deleted file mode 100644
index 9e3894dab0d..00000000000
--- a/src/librustc_resolve/error_reporting.rs
+++ /dev/null
@@ -1,856 +0,0 @@
-use std::cmp::Reverse;
-
-use errors::{Applicability, DiagnosticBuilder, DiagnosticId};
-use log::debug;
-use rustc::hir::def::{self, CtorKind, Namespace::*};
-use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
-use rustc::session::{Session, config::nightly_options};
-use syntax::ast::{self, Expr, ExprKind, Ident};
-use syntax::ext::base::MacroKind;
-use syntax::symbol::{Symbol, keywords};
-use syntax_pos::{BytePos, Span};
-
-type Def = def::Def<ast::NodeId>;
-
-use crate::macros::ParentScope;
-use crate::resolve_imports::{ImportDirective, ImportDirectiveSubclass, ImportResolver};
-use crate::{import_candidate_to_enum_paths, is_self_type, is_self_value, path_names_to_string};
-use crate::{AssocSuggestion, CrateLint, ImportSuggestion, ModuleOrUniformRoot, PathResult,
-            PathSource, Resolver, Segment, Suggestion};
-
-impl<'a> Resolver<'a> {
-    /// Handles error reporting for `smart_resolve_path_fragment` function.
-    /// Creates base error and amends it with one short label and possibly some longer helps/notes.
-    pub(crate) fn smart_resolve_report_errors(
-        &mut self,
-        path: &[Segment],
-        span: Span,
-        source: PathSource<'_>,
-        def: Option<Def>,
-    ) -> (DiagnosticBuilder<'a>, Vec<ImportSuggestion>) {
-        let ident_span = path.last().map_or(span, |ident| ident.ident.span);
-        let ns = source.namespace();
-        let is_expected = &|def| source.is_expected(def);
-        let is_enum_variant = &|def| if let Def::Variant(..) = def { true } else { false };
-
-        // Make the base error.
-        let expected = source.descr_expected();
-        let path_str = Segment::names_to_string(path);
-        let item_str = path.last().unwrap().ident;
-        let code = source.error_code(def.is_some());
-        let (base_msg, fallback_label, base_span) = if let Some(def) = def {
-            (format!("expected {}, found {} `{}`", expected, def.kind_name(), path_str),
-                format!("not a {}", expected),
-                span)
-        } else {
-            let item_span = path.last().unwrap().ident.span;
-            let (mod_prefix, mod_str) = if path.len() == 1 {
-                (String::new(), "this scope".to_string())
-            } else if path.len() == 2 && path[0].ident.name == keywords::PathRoot.name() {
-                (String::new(), "the crate root".to_string())
-            } else {
-                let mod_path = &path[..path.len() - 1];
-                let mod_prefix = match self.resolve_path_without_parent_scope(
-                    mod_path, Some(TypeNS), false, span, CrateLint::No
-                ) {
-                    PathResult::Module(ModuleOrUniformRoot::Module(module)) =>
-                        module.def(),
-                    _ => None,
-                }.map_or(String::new(), |def| format!("{} ", def.kind_name()));
-                (mod_prefix, format!("`{}`", Segment::names_to_string(mod_path)))
-            };
-            (format!("cannot find {} `{}` in {}{}", expected, item_str, mod_prefix, mod_str),
-                format!("not found in {}", mod_str),
-                item_span)
-        };
-
-        let code = DiagnosticId::Error(code.into());
-        let mut err = self.session.struct_span_err_with_code(base_span, &base_msg, code);
-
-        // Emit help message for fake-self from other languages (e.g., `this` in Javascript).
-        if ["this", "my"].contains(&&*item_str.as_str())
-            && self.self_value_is_available(path[0].ident.span, span) {
-            err.span_suggestion(
-                span,
-                "did you mean",
-                "self".to_string(),
-                Applicability::MaybeIncorrect,
-            );
-        }
-
-        // Emit special messages for unresolved `Self` and `self`.
-        if is_self_type(path, ns) {
-            __diagnostic_used!(E0411);
-            err.code(DiagnosticId::Error("E0411".into()));
-            err.span_label(span, format!("`Self` is only available in impls, traits, \
-                                          and type definitions"));
-            return (err, Vec::new());
-        }
-        if is_self_value(path, ns) {
-            debug!("smart_resolve_path_fragment: E0424, source={:?}", source);
-
-            __diagnostic_used!(E0424);
-            err.code(DiagnosticId::Error("E0424".into()));
-            err.span_label(span, match source {
-                PathSource::Pat => {
-                    format!("`self` value is a keyword \
-                             and may not be bound to \
-                             variables or shadowed")
-                }
-                _ => {
-                    format!("`self` value is a keyword \
-                             only available in methods \
-                             with `self` parameter")
-                }
-            });
-            return (err, Vec::new());
-        }
-
-        // Try to lookup name in more relaxed fashion for better error reporting.
-        let ident = path.last().unwrap().ident;
-        let candidates = self.lookup_import_candidates(ident, ns, is_expected)
-            .drain(..)
-            .filter(|ImportSuggestion { did, .. }| {
-                match (did, def.and_then(|def| def.opt_def_id())) {
-                    (Some(suggestion_did), Some(actual_did)) => *suggestion_did != actual_did,
-                    _ => true,
-                }
-            })
-            .collect::<Vec<_>>();
-        if candidates.is_empty() && is_expected(Def::Enum(DefId::local(CRATE_DEF_INDEX))) {
-            let enum_candidates =
-                self.lookup_import_candidates(ident, ns, is_enum_variant);
-            let mut enum_candidates = enum_candidates.iter()
-                .map(|suggestion| {
-                    import_candidate_to_enum_paths(&suggestion)
-                }).collect::<Vec<_>>();
-            enum_candidates.sort();
-
-            if !enum_candidates.is_empty() {
-                // Contextualize for E0412 "cannot find type", but don't belabor the point
-                // (that it's a variant) for E0573 "expected type, found variant".
-                let preamble = if def.is_none() {
-                    let others = match enum_candidates.len() {
-                        1 => String::new(),
-                        2 => " and 1 other".to_owned(),
-                        n => format!(" and {} others", n)
-                    };
-                    format!("there is an enum variant `{}`{}; ",
-                            enum_candidates[0].0, others)
-                } else {
-                    String::new()
-                };
-                let msg = format!("{}try using the variant's enum", preamble);
-
-                err.span_suggestions(
-                    span,
-                    &msg,
-                    enum_candidates.into_iter()
-                        .map(|(_variant_path, enum_ty_path)| enum_ty_path)
-                        // Variants re-exported in prelude doesn't mean `prelude::v1` is the
-                        // type name!
-                        // FIXME: is there a more principled way to do this that
-                        // would work for other re-exports?
-                        .filter(|enum_ty_path| enum_ty_path != "std::prelude::v1")
-                        // Also write `Option` rather than `std::prelude::v1::Option`.
-                        .map(|enum_ty_path| {
-                            // FIXME #56861: DRY-er prelude filtering.
-                            enum_ty_path.trim_start_matches("std::prelude::v1::").to_owned()
-                        }),
-                    Applicability::MachineApplicable,
-                );
-            }
-        }
-        if path.len() == 1 && self.self_type_is_available(span) {
-            if let Some(candidate) = self.lookup_assoc_candidate(ident, ns, is_expected) {
-                let self_is_available = self.self_value_is_available(path[0].ident.span, span);
-                match candidate {
-                    AssocSuggestion::Field => {
-                        err.span_suggestion(
-                            span,
-                            "try",
-                            format!("self.{}", path_str),
-                            Applicability::MachineApplicable,
-                        );
-                        if !self_is_available {
-                            err.span_label(span, format!("`self` value is a keyword \
-                                                         only available in \
-                                                         methods with `self` parameter"));
-                        }
-                    }
-                    AssocSuggestion::MethodWithSelf if self_is_available => {
-                        err.span_suggestion(
-                            span,
-                            "try",
-                            format!("self.{}", path_str),
-                            Applicability::MachineApplicable,
-                        );
-                    }
-                    AssocSuggestion::MethodWithSelf | AssocSuggestion::AssocItem => {
-                        err.span_suggestion(
-                            span,
-                            "try",
-                            format!("Self::{}", path_str),
-                            Applicability::MachineApplicable,
-                        );
-                    }
-                }
-                return (err, candidates);
-            }
-        }
-
-        let mut levenshtein_worked = false;
-
-        // Try Levenshtein algorithm.
-        let suggestion = self.lookup_typo_candidate(path, ns, is_expected, span);
-        if let Some(suggestion) = suggestion {
-            let msg = format!(
-                "{} {} with a similar name exists",
-                suggestion.article, suggestion.kind
-            );
-            err.span_suggestion(
-                ident_span,
-                &msg,
-                suggestion.candidate.to_string(),
-                Applicability::MaybeIncorrect,
-            );
-
-            levenshtein_worked = true;
-        }
-
-        // Try context-dependent help if relaxed lookup didn't work.
-        if let Some(def) = def {
-            if self.smart_resolve_context_dependent_help(&mut err,
-                                                         span,
-                                                         source,
-                                                         def,
-                                                         &path_str,
-                                                         &fallback_label) {
-                return (err, candidates);
-            }
-        }
-
-        // Fallback label.
-        if !levenshtein_worked {
-            err.span_label(base_span, fallback_label);
-            self.type_ascription_suggestion(&mut err, base_span);
-        }
-        (err, candidates)
-    }
-
-    /// Provides context-dependent help for errors reported by the `smart_resolve_path_fragment`
-    /// function.
-    /// Returns `true` if able to provide context-dependent help.
-    fn smart_resolve_context_dependent_help(
-        &mut self,
-        err: &mut DiagnosticBuilder<'a>,
-        span: Span,
-        source: PathSource<'_>,
-        def: Def,
-        path_str: &str,
-        fallback_label: &str,
-    ) -> bool {
-        let ns = source.namespace();
-        let is_expected = &|def| source.is_expected(def);
-
-        let path_sep = |err: &mut DiagnosticBuilder<'_>, expr: &Expr| match expr.node {
-            ExprKind::Field(_, ident) => {
-                err.span_suggestion(
-                    expr.span,
-                    "use the path separator to refer to an item",
-                    format!("{}::{}", path_str, ident),
-                    Applicability::MaybeIncorrect,
-                );
-                true
-            }
-            ExprKind::MethodCall(ref segment, ..) => {
-                let span = expr.span.with_hi(segment.ident.span.hi());
-                err.span_suggestion(
-                    span,
-                    "use the path separator to refer to an item",
-                    format!("{}::{}", path_str, segment.ident),
-                    Applicability::MaybeIncorrect,
-                );
-                true
-            }
-            _ => false,
-        };
-
-        match (def, source) {
-            (Def::Macro(..), _) => {
-                err.span_suggestion(
-                    span,
-                    "use `!` to invoke the macro",
-                    format!("{}!", path_str),
-                    Applicability::MaybeIncorrect,
-                );
-                if path_str == "try" && span.rust_2015() {
-                    err.note("if you want the `try` keyword, you need to be in the 2018 edition");
-                }
-            }
-            (Def::TyAlias(..), PathSource::Trait(_)) => {
-                err.span_label(span, "type aliases cannot be used as traits");
-                if nightly_options::is_nightly_build() {
-                    err.note("did you mean to use a trait alias?");
-                }
-            }
-            (Def::Mod(..), PathSource::Expr(Some(parent))) => if !path_sep(err, &parent) {
-                return false;
-            },
-            (Def::Enum(..), PathSource::TupleStruct)
-                | (Def::Enum(..), PathSource::Expr(..))  => {
-                if let Some(variants) = self.collect_enum_variants(def) {
-                    if !variants.is_empty() {
-                        let msg = if variants.len() == 1 {
-                            "try using the enum's variant"
-                        } else {
-                            "try using one of the enum's variants"
-                        };
-
-                        err.span_suggestions(
-                            span,
-                            msg,
-                            variants.iter().map(path_names_to_string),
-                            Applicability::MaybeIncorrect,
-                        );
-                    }
-                } else {
-                    err.note("did you mean to use one of the enum's variants?");
-                }
-            },
-            (Def::Struct(def_id), _) if ns == ValueNS => {
-                if let Some((ctor_def, ctor_vis))
-                        = self.struct_constructors.get(&def_id).cloned() {
-                    let accessible_ctor = self.is_accessible(ctor_vis);
-                    if is_expected(ctor_def) && !accessible_ctor {
-                        err.span_label(
-                            span,
-                            format!("constructor is not visible here due to private fields"),
-                        );
-                    }
-                } else {
-                    // HACK(estebank): find a better way to figure out that this was a
-                    // parser issue where a struct literal is being used on an expression
-                    // where a brace being opened means a block is being started. Look
-                    // ahead for the next text to see if `span` is followed by a `{`.
-                    let sm = self.session.source_map();
-                    let mut sp = span;
-                    loop {
-                        sp = sm.next_point(sp);
-                        match sm.span_to_snippet(sp) {
-                            Ok(ref snippet) => {
-                                if snippet.chars().any(|c| { !c.is_whitespace() }) {
-                                    break;
-                                }
-                            }
-                            _ => break,
-                        }
-                    }
-                    let followed_by_brace = match sm.span_to_snippet(sp) {
-                        Ok(ref snippet) if snippet == "{" => true,
-                        _ => false,
-                    };
-                    // In case this could be a struct literal that needs to be surrounded
-                    // by parenthesis, find the appropriate span.
-                    let mut i = 0;
-                    let mut closing_brace = None;
-                    loop {
-                        sp = sm.next_point(sp);
-                        match sm.span_to_snippet(sp) {
-                            Ok(ref snippet) => {
-                                if snippet == "}" {
-                                    let sp = span.to(sp);
-                                    if let Ok(snippet) = sm.span_to_snippet(sp) {
-                                        closing_brace = Some((sp, snippet));
-                                    }
-                                    break;
-                                }
-                            }
-                            _ => break,
-                        }
-                        i += 1;
-                        // The bigger the span, the more likely we're incorrect --
-                        // bound it to 100 chars long.
-                        if i > 100 {
-                            break;
-                        }
-                    }
-                    match source {
-                        PathSource::Expr(Some(parent)) => if !path_sep(err, &parent) {
-                            err.span_label(
-                                span,
-                                format!("did you mean `{} {{ /* fields */ }}`?", path_str),
-                            );
-                        }
-                        PathSource::Expr(None) if followed_by_brace == true => {
-                            if let Some((sp, snippet)) = closing_brace {
-                                err.span_suggestion(
-                                    sp,
-                                    "surround the struct literal with parenthesis",
-                                    format!("({})", snippet),
-                                    Applicability::MaybeIncorrect,
-                                );
-                            } else {
-                                err.span_label(
-                                    span,
-                                    format!("did you mean `({} {{ /* fields */ }})`?", path_str),
-                                );
-                            }
-                        },
-                        _ => {
-                            err.span_label(
-                                span,
-                                format!("did you mean `{} {{ /* fields */ }}`?", path_str),
-                            );
-                        },
-                    }
-                }
-            }
-            (Def::Union(..), _) |
-            (Def::Variant(..), _) |
-            (Def::Ctor(_, _, CtorKind::Fictive), _) if ns == ValueNS => {
-                err.span_label(span, format!("did you mean `{} {{ /* fields */ }}`?", path_str));
-            }
-            (Def::SelfTy(..), _) if ns == ValueNS => {
-                err.span_label(span, fallback_label);
-                err.note("can't use `Self` as a constructor, you must use the implemented struct");
-            }
-            (Def::TyAlias(_), _) | (Def::AssociatedTy(..), _) if ns == ValueNS => {
-                err.note("can't use a type alias as a constructor");
-            }
-            _ => return false,
-        }
-        true
-    }
-}
-
-impl<'a, 'b:'a> ImportResolver<'a, 'b> {
-    /// Adds suggestions for a path that cannot be resolved.
-    pub(crate) fn make_path_suggestion(
-        &mut self,
-        span: Span,
-        mut path: Vec<Segment>,
-        parent_scope: &ParentScope<'b>,
-    ) -> Option<(Vec<Segment>, Vec<String>)> {
-        debug!("make_path_suggestion: span={:?} path={:?}", span, path);
-
-        match (path.get(0), path.get(1)) {
-            // `{{root}}::ident::...` on both editions.
-            // On 2015 `{{root}}` is usually added implicitly.
-            (Some(fst), Some(snd)) if fst.ident.name == keywords::PathRoot.name() &&
-                                      !snd.ident.is_path_segment_keyword() => {}
-            // `ident::...` on 2018.
-            (Some(fst), _) if fst.ident.span.rust_2018() &&
-                              !fst.ident.is_path_segment_keyword() => {
-                // Insert a placeholder that's later replaced by `self`/`super`/etc.
-                path.insert(0, Segment::from_ident(keywords::Invalid.ident()));
-            }
-            _ => return None,
-        }
-
-        self.make_missing_self_suggestion(span, path.clone(), parent_scope)
-            .or_else(|| self.make_missing_crate_suggestion(span, path.clone(), parent_scope))
-            .or_else(|| self.make_missing_super_suggestion(span, path.clone(), parent_scope))
-            .or_else(|| self.make_external_crate_suggestion(span, path, parent_scope))
-    }
-
-    /// Suggest a missing `self::` if that resolves to an correct module.
-    ///
-    /// ```
-    ///    |
-    /// LL | use foo::Bar;
-    ///    |     ^^^ did you mean `self::foo`?
-    /// ```
-    fn make_missing_self_suggestion(
-        &mut self,
-        span: Span,
-        mut path: Vec<Segment>,
-        parent_scope: &ParentScope<'b>,
-    ) -> Option<(Vec<Segment>, Vec<String>)> {
-        // Replace first ident with `self` and check if that is valid.
-        path[0].ident.name = keywords::SelfLower.name();
-        let result = self.resolve_path(&path, None, parent_scope, false, span, CrateLint::No);
-        debug!("make_missing_self_suggestion: path={:?} result={:?}", path, result);
-        if let PathResult::Module(..) = result {
-            Some((path, Vec::new()))
-        } else {
-            None
-        }
-    }
-
-    /// Suggests a missing `crate::` if that resolves to an correct module.
-    ///
-    /// ```
-    ///    |
-    /// LL | use foo::Bar;
-    ///    |     ^^^ did you mean `crate::foo`?
-    /// ```
-    fn make_missing_crate_suggestion(
-        &mut self,
-        span: Span,
-        mut path: Vec<Segment>,
-        parent_scope: &ParentScope<'b>,
-    ) -> Option<(Vec<Segment>, Vec<String>)> {
-        // Replace first ident with `crate` and check if that is valid.
-        path[0].ident.name = keywords::Crate.name();
-        let result = self.resolve_path(&path, None, parent_scope, false, span, CrateLint::No);
-        debug!("make_missing_crate_suggestion:  path={:?} result={:?}", path, result);
-        if let PathResult::Module(..) = result {
-            Some((
-                path,
-                vec![
-                    "`use` statements changed in Rust 2018; read more at \
-                     <https://doc.rust-lang.org/edition-guide/rust-2018/module-system/path-\
-                     clarity.html>".to_string()
-                ],
-            ))
-        } else {
-            None
-        }
-    }
-
-    /// Suggests a missing `super::` if that resolves to an correct module.
-    ///
-    /// ```
-    ///    |
-    /// LL | use foo::Bar;
-    ///    |     ^^^ did you mean `super::foo`?
-    /// ```
-    fn make_missing_super_suggestion(
-        &mut self,
-        span: Span,
-        mut path: Vec<Segment>,
-        parent_scope: &ParentScope<'b>,
-    ) -> Option<(Vec<Segment>, Vec<String>)> {
-        // Replace first ident with `crate` and check if that is valid.
-        path[0].ident.name = keywords::Super.name();
-        let result = self.resolve_path(&path, None, parent_scope, false, span, CrateLint::No);
-        debug!("make_missing_super_suggestion:  path={:?} result={:?}", path, result);
-        if let PathResult::Module(..) = result {
-            Some((path, Vec::new()))
-        } else {
-            None
-        }
-    }
-
-    /// Suggests a missing external crate name if that resolves to an correct module.
-    ///
-    /// ```
-    ///    |
-    /// LL | use foobar::Baz;
-    ///    |     ^^^^^^ did you mean `baz::foobar`?
-    /// ```
-    ///
-    /// Used when importing a submodule of an external crate but missing that crate's
-    /// name as the first part of path.
-    fn make_external_crate_suggestion(
-        &mut self,
-        span: Span,
-        mut path: Vec<Segment>,
-        parent_scope: &ParentScope<'b>,
-    ) -> Option<(Vec<Segment>, Vec<String>)> {
-        if path[1].ident.span.rust_2015() {
-            return None;
-        }
-
-        // Sort extern crate names in reverse order to get
-        // 1) some consistent ordering for emitted dignostics, and
-        // 2) `std` suggestions before `core` suggestions.
-        let mut extern_crate_names =
-            self.resolver.extern_prelude.iter().map(|(ident, _)| ident.name).collect::<Vec<_>>();
-        extern_crate_names.sort_by_key(|name| Reverse(name.as_str()));
-
-        for name in extern_crate_names.into_iter() {
-            // Replace first ident with a crate name and check if that is valid.
-            path[0].ident.name = name;
-            let result = self.resolve_path(&path, None, parent_scope, false, span, CrateLint::No);
-            debug!("make_external_crate_suggestion: name={:?} path={:?} result={:?}",
-                    name, path, result);
-            if let PathResult::Module(..) = result {
-                return Some((path, Vec::new()));
-            }
-        }
-
-        None
-    }
-
-    /// Suggests importing a macro from the root of the crate rather than a module within
-    /// the crate.
-    ///
-    /// ```
-    /// help: a macro with this name exists at the root of the crate
-    ///    |
-    /// LL | use issue_59764::makro;
-    ///    |     ^^^^^^^^^^^^^^^^^^
-    ///    |
-    ///    = note: this could be because a macro annotated with `#[macro_export]` will be exported
-    ///            at the root of the crate instead of the module where it is defined
-    /// ```
-    pub(crate) fn check_for_module_export_macro(
-        &self,
-        directive: &'b ImportDirective<'b>,
-        module: ModuleOrUniformRoot<'b>,
-        ident: Ident,
-    ) -> Option<(Option<Suggestion>, Vec<String>)> {
-        let mut crate_module = if let ModuleOrUniformRoot::Module(module) = module {
-            module
-        } else {
-            return None;
-        };
-
-        while let Some(parent) = crate_module.parent {
-            crate_module = parent;
-        }
-
-        if ModuleOrUniformRoot::same_def(ModuleOrUniformRoot::Module(crate_module), module) {
-            // Don't make a suggestion if the import was already from the root of the
-            // crate.
-            return None;
-        }
-
-        let resolutions = crate_module.resolutions.borrow();
-        let resolution = resolutions.get(&(ident, MacroNS))?;
-        let binding = resolution.borrow().binding()?;
-        if let Def::Macro(_, MacroKind::Bang) = binding.def() {
-            let module_name = crate_module.kind.name().unwrap();
-            let import = match directive.subclass {
-                ImportDirectiveSubclass::SingleImport { source, target, .. } if source != target =>
-                    format!("{} as {}", source, target),
-                _ => format!("{}", ident),
-            };
-
-            let mut corrections: Vec<(Span, String)> = Vec::new();
-            if !directive.is_nested() {
-                // Assume this is the easy case of `use issue_59764::foo::makro;` and just remove
-                // intermediate segments.
-                corrections.push((directive.span, format!("{}::{}", module_name, import)));
-            } else {
-                // Find the binding span (and any trailing commas and spaces).
-                //   ie. `use a::b::{c, d, e};`
-                //                      ^^^
-                let (found_closing_brace, binding_span) = find_span_of_binding_until_next_binding(
-                    self.resolver.session, directive.span, directive.use_span,
-                );
-                debug!("check_for_module_export_macro: found_closing_brace={:?} binding_span={:?}",
-                       found_closing_brace, binding_span);
-
-                let mut removal_span = binding_span;
-                if found_closing_brace {
-                    // If the binding span ended with a closing brace, as in the below example:
-                    //   ie. `use a::b::{c, d};`
-                    //                      ^
-                    // Then expand the span of characters to remove to include the previous
-                    // binding's trailing comma.
-                    //   ie. `use a::b::{c, d};`
-                    //                    ^^^
-                    if let Some(previous_span) = extend_span_to_previous_binding(
-                        self.resolver.session, binding_span,
-                    ) {
-                        debug!("check_for_module_export_macro: previous_span={:?}", previous_span);
-                        removal_span = removal_span.with_lo(previous_span.lo());
-                    }
-                }
-                debug!("check_for_module_export_macro: removal_span={:?}", removal_span);
-
-                // Remove the `removal_span`.
-                corrections.push((removal_span, "".to_string()));
-
-                // Find the span after the crate name and if it has nested imports immediatately
-                // after the crate name already.
-                //   ie. `use a::b::{c, d};`
-                //               ^^^^^^^^^
-                //   or  `use a::{b, c, d}};`
-                //               ^^^^^^^^^^^
-                let (has_nested, after_crate_name) = find_span_immediately_after_crate_name(
-                    self.resolver.session, module_name, directive.use_span,
-                );
-                debug!("check_for_module_export_macro: has_nested={:?} after_crate_name={:?}",
-                       has_nested, after_crate_name);
-
-                let source_map = self.resolver.session.source_map();
-
-                // Add the import to the start, with a `{` if required.
-                let start_point = source_map.start_point(after_crate_name);
-                if let Ok(start_snippet) = source_map.span_to_snippet(start_point) {
-                    corrections.push((
-                        start_point,
-                        if has_nested {
-                            // In this case, `start_snippet` must equal '{'.
-                            format!("{}{}, ", start_snippet, import)
-                        } else {
-                            // In this case, add a `{`, then the moved import, then whatever
-                            // was there before.
-                            format!("{{{}, {}", import, start_snippet)
-                        }
-                    ));
-                }
-
-                // Add a `};` to the end if nested, matching the `{` added at the start.
-                if !has_nested {
-                    corrections.push((source_map.end_point(after_crate_name),
-                                     "};".to_string()));
-                }
-            }
-
-            let suggestion = Some((
-                corrections,
-                String::from("a macro with this name exists at the root of the crate"),
-                Applicability::MaybeIncorrect,
-            ));
-            let note = vec![
-                "this could be because a macro annotated with `#[macro_export]` will be exported \
-                 at the root of the crate instead of the module where it is defined".to_string(),
-            ];
-            Some((suggestion, note))
-        } else {
-            None
-        }
-    }
-}
-
-/// Given a `binding_span` of a binding within a use statement:
-///
-/// ```
-/// use foo::{a, b, c};
-///              ^
-/// ```
-///
-/// then return the span until the next binding or the end of the statement:
-///
-/// ```
-/// use foo::{a, b, c};
-///              ^^^
-/// ```
-pub(crate) fn find_span_of_binding_until_next_binding(
-    sess: &Session,
-    binding_span: Span,
-    use_span: Span,
-) -> (bool, Span) {
-    let source_map = sess.source_map();
-
-    // Find the span of everything after the binding.
-    //   ie. `a, e};` or `a};`
-    let binding_until_end = binding_span.with_hi(use_span.hi());
-
-    // Find everything after the binding but not including the binding.
-    //   ie. `, e};` or `};`
-    let after_binding_until_end = binding_until_end.with_lo(binding_span.hi());
-
-    // Keep characters in the span until we encounter something that isn't a comma or
-    // whitespace.
-    //   ie. `, ` or ``.
-    //
-    // Also note whether a closing brace character was encountered. If there
-    // was, then later go backwards to remove any trailing commas that are left.
-    let mut found_closing_brace = false;
-    let after_binding_until_next_binding = source_map.span_take_while(
-        after_binding_until_end,
-        |&ch| {
-            if ch == '}' { found_closing_brace = true; }
-            ch == ' ' || ch == ','
-        }
-    );
-
-    // Combine the two spans.
-    //   ie. `a, ` or `a`.
-    //
-    // Removing these would leave `issue_52891::{d, e};` or `issue_52891::{d, e, };`
-    let span = binding_span.with_hi(after_binding_until_next_binding.hi());
-
-    (found_closing_brace, span)
-}
-
-/// Given a `binding_span`, return the span through to the comma or opening brace of the previous
-/// binding.
-///
-/// ```
-/// use foo::a::{a, b, c};
-///               ^^--- binding span
-///               |
-///               returned span
-///
-/// use foo::{a, b, c};
-///           --- binding span
-/// ```
-pub(crate) fn extend_span_to_previous_binding(
-    sess: &Session,
-    binding_span: Span,
-) -> Option<Span> {
-    let source_map = sess.source_map();
-
-    // `prev_source` will contain all of the source that came before the span.
-    // Then split based on a command and take the first (ie. closest to our span)
-    // snippet. In the example, this is a space.
-    let prev_source = source_map.span_to_prev_source(binding_span).ok()?;
-
-    let prev_comma = prev_source.rsplit(',').collect::<Vec<_>>();
-    let prev_starting_brace = prev_source.rsplit('{').collect::<Vec<_>>();
-    if prev_comma.len() <= 1 || prev_starting_brace.len() <= 1 {
-        return None;
-    }
-
-    let prev_comma = prev_comma.first().unwrap();
-    let prev_starting_brace = prev_starting_brace.first().unwrap();
-
-    // If the amount of source code before the comma is greater than
-    // the amount of source code before the starting brace then we've only
-    // got one item in the nested item (eg. `issue_52891::{self}`).
-    if prev_comma.len() > prev_starting_brace.len() {
-        return None;
-    }
-
-    Some(binding_span.with_lo(BytePos(
-        // Take away the number of bytes for the characters we've found and an
-        // extra for the comma.
-        binding_span.lo().0 - (prev_comma.as_bytes().len() as u32) - 1
-    )))
-}
-
-/// Given a `use_span` of a binding within a use statement, returns the highlighted span and if
-/// it is a nested use tree.
-///
-/// ```
-/// use foo::a::{b, c};
-///          ^^^^^^^^^^ // false
-///
-/// use foo::{a, b, c};
-///          ^^^^^^^^^^ // true
-///
-/// use foo::{a, b::{c, d}};
-///          ^^^^^^^^^^^^^^^ // true
-/// ```
-fn find_span_immediately_after_crate_name(
-    sess: &Session,
-    module_name: Symbol,
-    use_span: Span,
-) -> (bool, Span) {
-    debug!("find_span_immediately_after_crate_name: module_name={:?} use_span={:?}",
-           module_name, use_span);
-    let source_map = sess.source_map();
-
-    // Using `use issue_59764::foo::{baz, makro};` as an example throughout..
-    let mut num_colons = 0;
-    // Find second colon.. `use issue_59764:`
-    let until_second_colon = source_map.span_take_while(use_span, |c| {
-        if *c == ':' { num_colons += 1; }
-        match c {
-            ':' if num_colons == 2 => false,
-            _ => true,
-        }
-    });
-    // Find everything after the second colon.. `foo::{baz, makro};`
-    let from_second_colon = use_span.with_lo(until_second_colon.hi() + BytePos(1));
-
-    let mut found_a_non_whitespace_character = false;
-    // Find the first non-whitespace character in `from_second_colon`.. `f`
-    let after_second_colon = source_map.span_take_while(from_second_colon, |c| {
-        if found_a_non_whitespace_character { return false; }
-        if !c.is_whitespace() { found_a_non_whitespace_character = true; }
-        true
-    });
-
-    // Find the first `{` in from_second_colon.. `foo::{`
-    let next_left_bracket = source_map.span_through_char(from_second_colon, '{');
-
-    (next_left_bracket == after_second_colon, from_second_colon)
-}
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 83416eaa062..08b2f1a0f16 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -65,7 +65,7 @@ use std::mem::replace;
 use rustc_data_structures::ptr_key::PtrKey;
 use rustc_data_structures::sync::Lrc;
 
-use error_reporting::{find_span_of_binding_until_next_binding, extend_span_to_previous_binding};
+use diagnostics::{find_span_of_binding_until_next_binding, extend_span_to_previous_binding};
 use resolve_imports::{ImportDirective, ImportDirectiveSubclass, NameResolution, ImportResolver};
 use macros::{InvocationData, LegacyBinding, ParentScope};
 
@@ -73,8 +73,8 @@ type Def = def::Def<NodeId>;
 
 // N.B., this module needs to be declared first so diagnostics are
 // registered before they are used.
+mod error_codes;
 mod diagnostics;
-mod error_reporting;
 mod macros;
 mod check_unused;
 mod build_reduced_graph;
diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/error_codes.rs
index 22f24df450f..22f24df450f 100644
--- a/src/librustc_typeck/diagnostics.rs
+++ b/src/librustc_typeck/error_codes.rs
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index 4320e28d676..9bc221fac1b 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -81,7 +81,7 @@ This API is completely unstable and subject to change.
 
 // N.B., this module needs to be declared first so diagnostics are
 // registered before they are used.
-mod diagnostics;
+mod error_codes;
 
 mod astconv;
 mod check;
diff --git a/src/libsyntax/diagnostic_list.rs b/src/libsyntax/error_codes.rs
index ac24475cab8..ac24475cab8 100644
--- a/src/libsyntax/diagnostic_list.rs
+++ b/src/libsyntax/error_codes.rs
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index 1486909b276..db10ab7af5a 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -114,7 +114,7 @@ pub mod diagnostics {
 
 // N.B., this module needs to be declared first so diagnostics are
 // registered before they are used.
-pub mod diagnostic_list;
+pub mod error_codes;
 
 pub mod util {
     pub mod lev_distance;
diff --git a/src/libsyntax_ext/diagnostics.rs b/src/libsyntax_ext/error_codes.rs
index 9bbd9fdec17..9bbd9fdec17 100644
--- a/src/libsyntax_ext/diagnostics.rs
+++ b/src/libsyntax_ext/error_codes.rs
diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs
index 8371d272075..508f740cac9 100644
--- a/src/libsyntax_ext/lib.rs
+++ b/src/libsyntax_ext/lib.rs
@@ -17,7 +17,7 @@
 
 extern crate proc_macro;
 
-mod diagnostics;
+mod error_codes;
 
 mod asm;
 mod assert;
diff --git a/src/tools/tidy/src/errors.rs b/src/tools/tidy/src/errors.rs
index 76ebc9b6010..ef1000ee506 100644
--- a/src/tools/tidy/src/errors.rs
+++ b/src/tools/tidy/src/errors.rs
@@ -15,7 +15,7 @@ pub fn check(path: &Path, bad: &mut bool) {
                 &mut |path| super::filter_dirs(path) || path.ends_with("src/test"),
                 &mut |file| {
         let filename = file.file_name().unwrap().to_string_lossy();
-        if filename != "diagnostics.rs" && filename != "diagnostic_list.rs" {
+        if filename != "error_codes.rs" {
             return
         }