about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-09-07 20:01:44 +0200
committerGitHub <noreply@github.com>2019-09-07 20:01:44 +0200
commit89a69fd76d275ddd2c81fdbae02a966d24658aaa (patch)
treeb191b0475521f0d20bf4aaad612c28a4d9a8d952
parent3c4a58622128887778c6fd7c35de66f3fa463708 (diff)
parent5153db136e8419beb217340500a97db553ddabbe (diff)
downloadrust-89a69fd76d275ddd2c81fdbae02a966d24658aaa.tar.gz
rust-89a69fd76d275ddd2c81fdbae02a966d24658aaa.zip
Rollup merge of #64139 - Mark-Simulacrum:strip-legacy-proc-macro, r=petrochenkov
Migrate internal diagnostic registration to macro_rules

Review is best done commit-by-commit.

Fixes #64132.
-rw-r--r--Cargo.lock4
-rw-r--r--src/bootstrap/test.rs5
-rw-r--r--src/librustc/error_codes.rs24
-rw-r--r--src/librustc/lib.rs6
-rw-r--r--src/librustc_codegen_llvm/Cargo.toml4
-rw-r--r--src/librustc_codegen_llvm/error_codes.rs2
-rw-r--r--src/librustc_codegen_llvm/lib.rs5
-rw-r--r--src/librustc_codegen_ssa/error_codes.rs2
-rw-r--r--src/librustc_codegen_ssa/lib.rs5
-rw-r--r--src/librustc_codegen_utils/lib.rs1
-rw-r--r--src/librustc_driver/lib.rs1
-rw-r--r--src/librustc_interface/passes.rs17
-rw-r--r--src/librustc_interface/util.rs18
-rw-r--r--src/librustc_lint/error_codes.rs5
-rw-r--r--src/librustc_lint/lib.rs1
-rw-r--r--src/librustc_metadata/error_codes.rs12
-rw-r--r--src/librustc_metadata/lib.rs5
-rw-r--r--src/librustc_mir/error_codes.rs6
-rw-r--r--src/librustc_mir/lib.rs5
-rw-r--r--src/librustc_passes/error_codes.rs10
-rw-r--r--src/librustc_passes/lib.rs5
-rw-r--r--src/librustc_plugin/error_codes.rs11
-rw-r--r--src/librustc_plugin/lib.rs5
-rw-r--r--src/librustc_privacy/error_codes.rs5
-rw-r--r--src/librustc_privacy/lib.rs5
-rw-r--r--src/librustc_resolve/error_codes.rs9
-rw-r--r--src/librustc_resolve/late.rs24
-rw-r--r--src/librustc_resolve/late/diagnostics.rs4
-rw-r--r--src/librustc_resolve/lib.rs7
-rw-r--r--src/librustc_typeck/error_codes.rs16
-rw-r--r--src/librustc_typeck/lib.rs7
-rw-r--r--src/librustc_typeck/structured_errors.rs4
-rw-r--r--src/libsyntax/diagnostics/macros.rs55
-rw-r--r--src/libsyntax/diagnostics/plugin.rs185
-rw-r--r--src/libsyntax/error_codes.rs20
-rw-r--r--src/libsyntax/feature_gate/active.rs6
-rw-r--r--src/libsyntax/feature_gate/removed.rs5
-rw-r--r--src/libsyntax/lib.rs6
-rw-r--r--src/libsyntax/parse/mod.rs4
-rw-r--r--src/libsyntax_ext/error_codes.rs9
-rw-r--r--src/libsyntax_ext/lib.rs1
-rw-r--r--src/test/ui/feature-gate/allow-features-empty.rs2
-rw-r--r--src/test/ui/feature-gate/allow-features-empty.stderr14
-rw-r--r--src/test/ui/feature-gate/allow-features.rs4
-rw-r--r--src/test/ui/feature-gate/allow-features.stderr4
-rw-r--r--src/test/ui/feature-gates/feature-gate-rustc-diagnostic-macros.rs13
-rw-r--r--src/test/ui/feature-gates/feature-gate-rustc-diagnostic-macros.stderr20
-rw-r--r--src/tools/error_index_generator/build.rs51
-rw-r--r--src/tools/tidy/src/style.rs26
49 files changed, 176 insertions, 489 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 313fef1c086..2236cdb3f04 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3129,11 +3129,7 @@ dependencies = [
 name = "rustc_codegen_llvm"
 version = "0.0.0"
 dependencies = [
- "cc",
- "memmap",
- "num_cpus",
  "rustc_llvm",
- "tempfile",
 ]
 
 [[package]]
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index 97b28ed9e96..00d87f3841c 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -1327,7 +1327,10 @@ impl Step for Compiletest {
             cmd.env("RUSTC_PROFILER_SUPPORT", "1");
         }
 
-        cmd.env("RUST_TEST_TMPDIR", builder.out.join("tmp"));
+        let tmp = builder.out.join("tmp");
+        std::fs::create_dir_all(&tmp).unwrap();
+        cmd.env("RUST_TEST_TMPDIR", tmp);
+
 
         cmd.arg("--adb-path").arg("adb");
         cmd.arg("--adb-test-dir").arg(ADB_TEST_DIR);
diff --git a/src/librustc/error_codes.rs b/src/librustc/error_codes.rs
index 937a9ea6c1b..eee33846139 100644
--- a/src/librustc/error_codes.rs
+++ b/src/librustc/error_codes.rs
@@ -1,7 +1,8 @@
 // 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! {
+// 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.
+syntax::register_diagnostics! {
 E0038: r##"
 Trait objects like `Box<Trait>` can only be constructed when certain
 requirements are satisfied by the trait in question.
@@ -2183,11 +2184,7 @@ Examples of erroneous code:
 static X: u32 = 42;
 ```
 "##,
-
-}
-
-
-register_diagnostics! {
+;
 //  E0006, // merged with E0005
 //  E0101, // replaced with E0282
 //  E0102, // replaced with E0282
@@ -2206,7 +2203,8 @@ register_diagnostics! {
 //  E0305, // expected constant
     E0311, // thing may not live long enough
     E0312, // lifetime of reference outlives lifetime of borrowed content
-    E0313, // lifetime of borrowed pointer outlives lifetime of captured variable
+    E0313, // lifetime of borrowed pointer outlives lifetime of captured
+           // variable
     E0314, // closure outlives stack frame
     E0315, // cannot invoke closure outside of its lifetime
     E0316, // nested quantification of lifetimes
@@ -2223,12 +2221,13 @@ register_diagnostics! {
     E0483, // lifetime of operand does not outlive the operation
     E0484, // reference is not valid at the time of borrow
     E0485, // automatically reference is not valid at the time of borrow
-    E0486, // type of expression contains references that are not valid during...
+    E0486, // type of expression contains references that are not valid during..
     E0487, // unsafe use of destructor: destructor might be called while...
     E0488, // lifetime of variable does not enclose its declaration
     E0489, // type/lifetime parameter not in scope here
     E0490, // a value of type `..` is borrowed for too long
-    E0495, // cannot infer an appropriate lifetime due to conflicting requirements
+    E0495, // cannot infer an appropriate lifetime due to conflicting
+           // requirements
     E0566, // conflicting representation hints
     E0623, // lifetime mismatch where both parameters are anonymous regions
     E0628, // generators cannot have explicit parameters
@@ -2239,7 +2238,8 @@ register_diagnostics! {
     E0688, // in-band lifetimes cannot be mixed with explicit lifetime binders
     E0697, // closures cannot be static
     E0707, // multiple elided lifetimes used in arguments of `async fn`
-    E0708, // `async` non-`move` closures with parameters are not currently supported
+    E0708, // `async` non-`move` closures with parameters are not currently
+           // supported
     E0709, // multiple different lifetimes used in arguments of `async fn`
     E0710, // an unknown tool name found in scoped lint
     E0711, // a feature has been declared with conflicting stability attributes
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index bf4330a29a7..63ef82a7401 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -45,7 +45,6 @@
 #![feature(non_exhaustive)]
 #![feature(optin_builtin_traits)]
 #![feature(range_is_empty)]
-#![feature(rustc_diagnostic_macros)]
 #![feature(slice_patterns)]
 #![feature(specialization)]
 #![feature(unboxed_closures)]
@@ -88,8 +87,6 @@ mod tests;
 #[macro_use]
 mod macros;
 
-// N.B., this module needs to be declared first so diagnostics are
-// registered before they are used.
 pub mod error_codes;
 
 #[macro_use]
@@ -142,6 +139,3 @@ pub mod util {
 
 // Allows macros to refer to this crate as `::rustc`
 extern crate self as rustc;
-
-// Build the diagnostics array at the end so that the metadata includes error use sites.
-__build_diagnostic_array! { librustc, DIAGNOSTICS }
diff --git a/src/librustc_codegen_llvm/Cargo.toml b/src/librustc_codegen_llvm/Cargo.toml
index 5e1b0eafdec..98efa6a5804 100644
--- a/src/librustc_codegen_llvm/Cargo.toml
+++ b/src/librustc_codegen_llvm/Cargo.toml
@@ -11,11 +11,7 @@ crate-type = ["dylib"]
 test = false
 
 [dependencies]
-cc = "1.0.1" # Used to locate MSVC
-num_cpus = "1.0"
-tempfile = "3.0"
 rustc_llvm = { path = "../librustc_llvm" }
-memmap = "0.6"
 
 [features]
 # This is used to convince Cargo to separately cache builds of `rustc_codegen_llvm`
diff --git a/src/librustc_codegen_llvm/error_codes.rs b/src/librustc_codegen_llvm/error_codes.rs
index c6b5dc03a6f..042e51ed2ba 100644
--- a/src/librustc_codegen_llvm/error_codes.rs
+++ b/src/librustc_codegen_llvm/error_codes.rs
@@ -1,4 +1,4 @@
-register_long_diagnostics! {
+register_diagnostics! {
 
 E0511: r##"
 Invalid monomorphization of an intrinsic function was used. Erroneous code
diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs
index 2fd78885bd0..9f2c303145d 100644
--- a/src/librustc_codegen_llvm/lib.rs
+++ b/src/librustc_codegen_llvm/lib.rs
@@ -14,7 +14,6 @@
 #![feature(in_band_lifetimes)]
 #![feature(libc)]
 #![feature(nll)]
-#![feature(rustc_diagnostic_macros)]
 #![feature(optin_builtin_traits)]
 #![feature(concat_idents)]
 #![feature(link_args)]
@@ -256,7 +255,7 @@ impl CodegenBackend for LlvmCodegenBackend {
     }
 
     fn diagnostics(&self) -> &[(&'static str, &'static str)] {
-        &DIAGNOSTICS
+        &error_codes::DIAGNOSTICS
     }
 
     fn target_features(&self, sess: &Session) -> Vec<Symbol> {
@@ -425,5 +424,3 @@ impl Drop for ModuleLlvm {
         }
     }
 }
-
-__build_diagnostic_array! { librustc_codegen_llvm, DIAGNOSTICS }
diff --git a/src/librustc_codegen_ssa/error_codes.rs b/src/librustc_codegen_ssa/error_codes.rs
index 8d46dcb7c09..8ff41c275a8 100644
--- a/src/librustc_codegen_ssa/error_codes.rs
+++ b/src/librustc_codegen_ssa/error_codes.rs
@@ -1,4 +1,4 @@
-register_long_diagnostics! {
+syntax::register_diagnostics! {
 
 E0668: r##"
 Malformed inline assembly rejected by LLVM.
diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs
index 68640abb043..90bf964ceaa 100644
--- a/src/librustc_codegen_ssa/lib.rs
+++ b/src/librustc_codegen_ssa/lib.rs
@@ -4,7 +4,6 @@
 #![feature(box_syntax)]
 #![feature(core_intrinsics)]
 #![feature(libc)]
-#![feature(rustc_diagnostic_macros)]
 #![feature(stmt_expr_attributes)]
 #![feature(try_blocks)]
 #![feature(in_band_lifetimes)]
@@ -35,8 +34,6 @@ use rustc_data_structures::svh::Svh;
 use rustc::middle::cstore::{LibSource, CrateSource, NativeLibrary};
 use syntax_pos::symbol::Symbol;
 
-// N.B., this module needs to be declared first so diagnostics are
-// registered before they are used.
 mod error_codes;
 
 pub mod common;
@@ -158,5 +155,3 @@ pub struct CodegenResults {
     pub linker_info: back::linker::LinkerInfo,
     pub crate_info: CrateInfo,
 }
-
-__build_diagnostic_array! { librustc_codegen_ssa, DIAGNOSTICS }
diff --git a/src/librustc_codegen_utils/lib.rs b/src/librustc_codegen_utils/lib.rs
index 4ea375b59b2..1201446afb5 100644
--- a/src/librustc_codegen_utils/lib.rs
+++ b/src/librustc_codegen_utils/lib.rs
@@ -10,7 +10,6 @@
 #![feature(core_intrinsics)]
 #![feature(never_type)]
 #![feature(nll)]
-#![feature(rustc_diagnostic_macros)]
 #![feature(in_band_lifetimes)]
 
 #![recursion_limit="256"]
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 9a6a12e261c..a912ea3c358 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -9,7 +9,6 @@
 #![feature(box_syntax)]
 #![cfg_attr(unix, feature(libc))]
 #![feature(nll)]
-#![feature(rustc_diagnostic_macros)]
 #![feature(set_stdio)]
 #![feature(no_debug)]
 #![feature(integer_atomics)]
diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs
index 7fcad4d79c2..3cfae1686df 100644
--- a/src/librustc_interface/passes.rs
+++ b/src/librustc_interface/passes.rs
@@ -34,7 +34,7 @@ use rustc_privacy;
 use rustc_resolve::{Resolver, ResolverArenas};
 use rustc_traits;
 use rustc_typeck as typeck;
-use syntax::{self, ast, diagnostics, visit};
+use syntax::{self, ast, visit};
 use syntax::early_buffered_lints::BufferedEarlyLint;
 use syntax::ext::base::{NamedSyntaxExtension, ExtCtxt};
 use syntax::mut_visit::MutVisitor;
@@ -283,21 +283,6 @@ pub fn register_plugins<'a>(
     let mut registry = Registry::new(sess, krate.span);
 
     time(sess, "plugin registration", || {
-        if sess.features_untracked().rustc_diagnostic_macros {
-            registry.register_macro(
-                "__diagnostic_used",
-                diagnostics::plugin::expand_diagnostic_used,
-            );
-            registry.register_macro(
-                "__register_diagnostic",
-                diagnostics::plugin::expand_register_diagnostic,
-            );
-            registry.register_macro(
-                "__build_diagnostic_array",
-                diagnostics::plugin::expand_build_diagnostic_array,
-            );
-        }
-
         for registrar in registrars {
             registry.args_hidden = Some(registrar.args);
             (registrar.fun)(&mut registry);
diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs
index f007a0cf2ab..9eaf7b77716 100644
--- a/src/librustc_interface/util.rs
+++ b/src/librustc_interface/util.rs
@@ -43,17 +43,17 @@ use std::{thread, panic};
 
 pub fn diagnostics_registry() -> Registry {
     let mut all_errors = Vec::new();
-    all_errors.extend_from_slice(&rustc::DIAGNOSTICS);
-    all_errors.extend_from_slice(&rustc_typeck::DIAGNOSTICS);
-    all_errors.extend_from_slice(&rustc_resolve::DIAGNOSTICS);
-    all_errors.extend_from_slice(&rustc_privacy::DIAGNOSTICS);
+    all_errors.extend_from_slice(&rustc::error_codes::DIAGNOSTICS);
+    all_errors.extend_from_slice(&rustc_typeck::error_codes::DIAGNOSTICS);
+    all_errors.extend_from_slice(&rustc_resolve::error_codes::DIAGNOSTICS);
+    all_errors.extend_from_slice(&rustc_privacy::error_codes::DIAGNOSTICS);
     // FIXME: need to figure out a way to get these back in here
     // all_errors.extend_from_slice(get_codegen_backend(sess).diagnostics());
-    all_errors.extend_from_slice(&rustc_metadata::DIAGNOSTICS);
-    all_errors.extend_from_slice(&rustc_passes::DIAGNOSTICS);
-    all_errors.extend_from_slice(&rustc_plugin::DIAGNOSTICS);
-    all_errors.extend_from_slice(&rustc_mir::DIAGNOSTICS);
-    all_errors.extend_from_slice(&syntax::DIAGNOSTICS);
+    all_errors.extend_from_slice(&rustc_metadata::error_codes::DIAGNOSTICS);
+    all_errors.extend_from_slice(&rustc_passes::error_codes::DIAGNOSTICS);
+    all_errors.extend_from_slice(&rustc_plugin::error_codes::DIAGNOSTICS);
+    all_errors.extend_from_slice(&rustc_mir::error_codes::DIAGNOSTICS);
+    all_errors.extend_from_slice(&syntax::error_codes::DIAGNOSTICS);
 
     Registry::new(&all_errors)
 }
diff --git a/src/librustc_lint/error_codes.rs b/src/librustc_lint/error_codes.rs
index d7c39b780bf..ea2e1d9ecc5 100644
--- a/src/librustc_lint/error_codes.rs
+++ b/src/librustc_lint/error_codes.rs
@@ -1,5 +1,4 @@
-use syntax::register_diagnostics;
-
-register_diagnostics! {
+syntax::register_diagnostics! {
+;
     E0721, // `await` keyword
 }
diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs
index 27833161ef2..4ee6551f787 100644
--- a/src/librustc_lint/lib.rs
+++ b/src/librustc_lint/lib.rs
@@ -15,7 +15,6 @@
 #![feature(box_patterns)]
 #![feature(box_syntax)]
 #![feature(nll)]
-#![feature(rustc_diagnostic_macros)]
 
 #![recursion_limit="256"]
 
diff --git a/src/librustc_metadata/error_codes.rs b/src/librustc_metadata/error_codes.rs
index 0708a6243bf..cd8e95e6c3a 100644
--- a/src/librustc_metadata/error_codes.rs
+++ b/src/librustc_metadata/error_codes.rs
@@ -1,6 +1,4 @@
-use syntax::{register_diagnostics, register_long_diagnostics};
-
-register_long_diagnostics! {
+syntax::register_diagnostics! {
 E0454: r##"
 A link name was given with an empty name. Erroneous code example:
 
@@ -84,10 +82,7 @@ You need to link your code to the relevant crate in order to be able to use it
 (through Cargo or the `-L` option of rustc example). Plugins are crates as
 well, and you link to them the same way.
 "##,
-
-}
-
-register_diagnostics! {
+;
     E0456, // plugin `..` is not available for triple `..`
     E0457, // plugin `..` only found in rlib format, but must be available...
     E0514, // metadata version mismatch
@@ -97,5 +92,6 @@ register_diagnostics! {
     E0464, // multiple matching crates for `..`
     E0465, // multiple .. candidates for `..` found
     E0519, // local crate and dependency have same (crate-name, disambiguator)
-    E0523, // two dependencies have same (crate-name, disambiguator) but different SVH
+    // two dependencies have same (crate-name, disambiguator) but different SVH
+    E0523,
 }
diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs
index c96d02d9b37..e6104e629e9 100644
--- a/src/librustc_metadata/lib.rs
+++ b/src/librustc_metadata/lib.rs
@@ -8,7 +8,6 @@
 #![feature(nll)]
 #![feature(proc_macro_internals)]
 #![feature(proc_macro_quote)]
-#![feature(rustc_diagnostic_macros)]
 #![feature(rustc_private)]
 #![feature(slice_patterns)]
 #![feature(specialization)]
@@ -23,7 +22,7 @@ extern crate rustc;
 #[macro_use]
 extern crate rustc_data_structures;
 
-mod error_codes;
+pub mod error_codes;
 
 mod index;
 mod encoder;
@@ -68,5 +67,3 @@ pub fn validate_crate_name(
         sess.unwrap().abort_if_errors();
     }
 }
-
-__build_diagnostic_array! { librustc_metadata, DIAGNOSTICS }
diff --git a/src/librustc_mir/error_codes.rs b/src/librustc_mir/error_codes.rs
index 22432db8190..d80449ac237 100644
--- a/src/librustc_mir/error_codes.rs
+++ b/src/librustc_mir/error_codes.rs
@@ -1,4 +1,4 @@
-register_long_diagnostics! {
+syntax::register_diagnostics! {
 
 
 E0001: r##"
@@ -2448,9 +2448,9 @@ information.
 
 There are some known bugs that trigger this message.
 "##,
-}
 
-register_diagnostics! {
+;
+
 //  E0298, // cannot compare constants
 //  E0299, // mismatched types between arms
 //  E0471, // constant evaluation error (in pattern)
diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs
index cccf7b9545b..f27db351b74 100644
--- a/src/librustc_mir/lib.rs
+++ b/src/librustc_mir/lib.rs
@@ -14,7 +14,6 @@ Rust MIR: a lowered representation of Rust. Also: an experiment!
 #![feature(const_fn)]
 #![feature(decl_macro)]
 #![feature(exhaustive_patterns)]
-#![feature(rustc_diagnostic_macros)]
 #![feature(never_type)]
 #![feature(specialization)]
 #![feature(try_trait)]
@@ -32,7 +31,7 @@ Rust MIR: a lowered representation of Rust. Also: an experiment!
 #[macro_use] extern crate rustc_data_structures;
 #[macro_use] extern crate syntax;
 
-mod error_codes;
+pub mod error_codes;
 
 mod borrow_check;
 mod build;
@@ -62,5 +61,3 @@ pub fn provide(providers: &mut Providers<'_>) {
     };
     providers.type_name = interpret::type_name;
 }
-
-__build_diagnostic_array! { librustc_mir, DIAGNOSTICS }
diff --git a/src/librustc_passes/error_codes.rs b/src/librustc_passes/error_codes.rs
index a30cd8a627f..af07c790e2a 100644
--- a/src/librustc_passes/error_codes.rs
+++ b/src/librustc_passes/error_codes.rs
@@ -1,6 +1,4 @@
-use syntax::{register_diagnostics, register_long_diagnostics};
-
-register_long_diagnostics! {
+syntax::register_diagnostics! {
 /*
 E0014: r##"
 Constants can only be initialized by a constant value or, in a future
@@ -320,10 +318,8 @@ async fn foo() {}
 ```
 
 Switch to the Rust 2018 edition to use `async fn`.
-"##
-}
-
-register_diagnostics! {
+"##,
+;
     E0226, // only a single explicit lifetime bound is permitted
     E0472, // asm! is unsupported on this target
     E0561, // patterns aren't allowed in function pointer types
diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs
index 5614b570b92..cf2da4ffa2a 100644
--- a/src/librustc_passes/lib.rs
+++ b/src/librustc_passes/lib.rs
@@ -9,7 +9,6 @@
 #![feature(in_band_lifetimes)]
 #![feature(nll)]
 #![feature(bind_by_move_pattern_guards)]
-#![feature(rustc_diagnostic_macros)]
 
 #![recursion_limit="256"]
 
@@ -18,7 +17,7 @@ extern crate rustc;
 
 use rustc::ty::query::Providers;
 
-mod error_codes;
+pub mod error_codes;
 
 pub mod ast_validation;
 pub mod rvalue_promotion;
@@ -26,8 +25,6 @@ pub mod hir_stats;
 pub mod layout_test;
 pub mod loops;
 
-__build_diagnostic_array! { librustc_passes, DIAGNOSTICS }
-
 pub fn provide(providers: &mut Providers<'_>) {
     rvalue_promotion::provide(providers);
     loops::provide(providers);
diff --git a/src/librustc_plugin/error_codes.rs b/src/librustc_plugin/error_codes.rs
index b5f6a8d905d..7b3f01c0ee1 100644
--- a/src/librustc_plugin/error_codes.rs
+++ b/src/librustc_plugin/error_codes.rs
@@ -1,9 +1,4 @@
-use syntax::{register_diagnostics, register_long_diagnostics};
-
-register_long_diagnostics! {
-
-}
-
-register_diagnostics! {
-    E0498  // malformed plugin attribute
+syntax::register_diagnostics! {
+;
+    E0498,  // malformed plugin attribute
 }
diff --git a/src/librustc_plugin/lib.rs b/src/librustc_plugin/lib.rs
index 952bc9fff6a..4e1a47c503e 100644
--- a/src/librustc_plugin/lib.rs
+++ b/src/librustc_plugin/lib.rs
@@ -54,15 +54,12 @@
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
 
 #![feature(nll)]
-#![feature(rustc_diagnostic_macros)]
 
 #![recursion_limit="256"]
 
 pub use registry::Registry;
 
-mod error_codes;
+pub mod error_codes;
 pub mod registry;
 pub mod load;
 pub mod build;
-
-__build_diagnostic_array! { librustc_plugin, DIAGNOSTICS }
diff --git a/src/librustc_privacy/error_codes.rs b/src/librustc_privacy/error_codes.rs
index 70a799d426a..67066466f1d 100644
--- a/src/librustc_privacy/error_codes.rs
+++ b/src/librustc_privacy/error_codes.rs
@@ -1,4 +1,4 @@
-register_long_diagnostics! {
+syntax::register_diagnostics! {
 
 E0445: r##"
 A private trait was used on a public type parameter bound. Erroneous code
@@ -154,8 +154,5 @@ let f = Bar::Foo::new(); // ok!
 ```
 "##,
 
-}
-
-register_diagnostics! {
 //  E0450, moved into resolve
 }
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index 146058963b6..1e61f78c357 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -2,7 +2,6 @@
 
 #![feature(in_band_lifetimes)]
 #![feature(nll)]
-#![feature(rustc_diagnostic_macros)]
 
 #![recursion_limit="256"]
 
@@ -31,7 +30,7 @@ use syntax_pos::Span;
 use std::{cmp, fmt, mem};
 use std::marker::PhantomData;
 
-mod error_codes;
+pub mod error_codes;
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Generic infrastructure used to implement specific visitors below.
@@ -2035,5 +2034,3 @@ fn check_private_in_public(tcx: TyCtxt<'_>, krate: CrateNum) {
     };
     krate.visit_all_item_likes(&mut DeepVisitor::new(&mut visitor));
 }
-
-__build_diagnostic_array! { librustc_privacy, DIAGNOSTICS }
diff --git a/src/librustc_resolve/error_codes.rs b/src/librustc_resolve/error_codes.rs
index 1faaf97e981..adbff67cc8d 100644
--- a/src/librustc_resolve/error_codes.rs
+++ b/src/librustc_resolve/error_codes.rs
@@ -1,9 +1,7 @@
-use syntax::{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! {
+syntax::register_diagnostics! {
 
 E0128: r##"
 Type parameter defaults can only use parameters that occur before them.
@@ -1662,10 +1660,7 @@ fn const_id<T, const N: T>() -> T { // error: const parameter
 }
 ```
 "##,
-
-}
-
-register_diagnostics! {
+;
 //  E0153, unused error code
 //  E0157, unused error code
 //  E0257,
diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs
index 3ddaf2d94f9..aae283b7452 100644
--- a/src/librustc_resolve/late.rs
+++ b/src/librustc_resolve/late.rs
@@ -298,18 +298,18 @@ impl<'a> PathSource<'a> {
     }
 
     fn error_code(self, has_unexpected_resolution: bool) -> &'static str {
-        __diagnostic_used!(E0404);
-        __diagnostic_used!(E0405);
-        __diagnostic_used!(E0412);
-        __diagnostic_used!(E0422);
-        __diagnostic_used!(E0423);
-        __diagnostic_used!(E0425);
-        __diagnostic_used!(E0531);
-        __diagnostic_used!(E0532);
-        __diagnostic_used!(E0573);
-        __diagnostic_used!(E0574);
-        __diagnostic_used!(E0575);
-        __diagnostic_used!(E0576);
+        syntax::diagnostic_used!(E0404);
+        syntax::diagnostic_used!(E0405);
+        syntax::diagnostic_used!(E0412);
+        syntax::diagnostic_used!(E0422);
+        syntax::diagnostic_used!(E0423);
+        syntax::diagnostic_used!(E0425);
+        syntax::diagnostic_used!(E0531);
+        syntax::diagnostic_used!(E0532);
+        syntax::diagnostic_used!(E0573);
+        syntax::diagnostic_used!(E0574);
+        syntax::diagnostic_used!(E0575);
+        syntax::diagnostic_used!(E0576);
         match (self, has_unexpected_resolution) {
             (PathSource::Trait(_), true) => "E0404",
             (PathSource::Trait(_), false) => "E0405",
diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs
index a822fa049ca..0c86d8494fd 100644
--- a/src/librustc_resolve/late/diagnostics.rs
+++ b/src/librustc_resolve/late/diagnostics.rs
@@ -113,7 +113,7 @@ impl<'a> LateResolutionVisitor<'a, '_> {
 
         // Emit special messages for unresolved `Self` and `self`.
         if is_self_type(path, ns) {
-            __diagnostic_used!(E0411);
+            syntax::diagnostic_used!(E0411);
             err.code(DiagnosticId::Error("E0411".into()));
             err.span_label(span, format!("`Self` is only available in impls, traits, \
                                           and type definitions"));
@@ -122,7 +122,7 @@ impl<'a> LateResolutionVisitor<'a, '_> {
         if is_self_value(path, ns) {
             debug!("smart_resolve_path_fragment: E0424, source={:?}", source);
 
-            __diagnostic_used!(E0424);
+            syntax::diagnostic_used!(E0424);
             err.code(DiagnosticId::Error("E0424".into()));
             err.span_label(span, match source {
                 PathSource::Pat => {
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 7f65e5dfaa2..e980b8d01f7 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -14,7 +14,6 @@
 #![feature(label_break_value)]
 #![feature(mem_take)]
 #![feature(nll)]
-#![feature(rustc_diagnostic_macros)]
 
 #![recursion_limit="256"]
 
@@ -68,9 +67,7 @@ use macros::{LegacyBinding, LegacyScope};
 
 type Res = def::Res<NodeId>;
 
-// N.B., this module needs to be declared first so diagnostics are
-// registered before they are used.
-mod error_codes;
+pub mod error_codes;
 mod diagnostics;
 mod late;
 mod macros;
@@ -2840,5 +2837,3 @@ impl CrateLint {
         }
     }
 }
-
-__build_diagnostic_array! { librustc_resolve, DIAGNOSTICS }
diff --git a/src/librustc_typeck/error_codes.rs b/src/librustc_typeck/error_codes.rs
index 093446d2853..e11dcfafb8f 100644
--- a/src/librustc_typeck/error_codes.rs
+++ b/src/librustc_typeck/error_codes.rs
@@ -1,6 +1,6 @@
 // ignore-tidy-filelength
 
-register_long_diagnostics! {
+syntax::register_diagnostics! {
 
 E0023: r##"
 A pattern used to match against an enum variant must provide a sub-pattern for
@@ -4870,10 +4870,7 @@ fn foo_recursive(n: usize) -> Pin<Box<dyn Future<Output = ()>>> {
 The `Box<...>` ensures that the result is of known size,
 and the pin is required to keep it in the same place in memory.
 "##,
-
-}  // (end of detailed error messages)
-
-register_diagnostics! {
+;
 //  E0035, merged into E0087/E0089
 //  E0036, merged into E0087/E0089
 //  E0068,
@@ -4930,7 +4927,8 @@ register_diagnostics! {
 //  E0245, // not a trait
 //  E0246, // invalid recursive type
 //  E0247,
-//  E0248, // value used as a type, now reported earlier during resolution as E0412
+//  E0248, // value used as a type, now reported earlier during resolution
+           // as E0412
 //  E0249,
 //  E0319, // trait impls for defaulted traits allowed just for structs/enums
 //  E0372, // coherence not object safe
@@ -4938,7 +4936,7 @@ register_diagnostics! {
            // between structures with the same definition
 //  E0558, // replaced with a generic attribute input check
     E0533, // `{}` does not name a unit variant, unit struct or a constant
-//  E0563, // cannot determine a type for this `impl Trait`: {} // removed in 6383de15
+//  E0563, // cannot determine a type for this `impl Trait` removed in 6383de15
     E0564, // only named lifetimes are allowed in `impl Trait`,
            // but `{}` was found in the type `{}`
     E0587, // type has conflicting packed and align representation hints
@@ -4947,8 +4945,8 @@ register_diagnostics! {
 //  E0612, // merged into E0609
 //  E0613, // Removed (merged with E0609)
     E0627, // yield statement outside of generator literal
-    E0632, // cannot provide explicit type parameters when `impl Trait` is used in
-           // argument position.
+    E0632, // cannot provide explicit type parameters when `impl Trait` is used
+           // in argument position.
     E0634, // type has conflicting packed representaton hints
     E0640, // infer outlives requirements
     E0641, // cannot cast to/from a pointer with an unknown kind
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index 9d9a9d9b559..959483e4439 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -65,7 +65,6 @@ This API is completely unstable and subject to change.
 #![feature(exhaustive_patterns)]
 #![feature(in_band_lifetimes)]
 #![feature(nll)]
-#![feature(rustc_diagnostic_macros)]
 #![feature(slice_patterns)]
 #![feature(never_type)]
 #![feature(inner_deref)]
@@ -78,9 +77,7 @@ This API is completely unstable and subject to change.
 
 #[macro_use] extern crate rustc;
 
-// N.B., this module needs to be declared first so diagnostics are
-// registered before they are used.
-mod error_codes;
+pub mod error_codes;
 
 mod astconv;
 mod check;
@@ -389,5 +386,3 @@ pub fn hir_trait_to_predicates<'tcx>(
 
     bounds
 }
-
-__build_diagnostic_array! { librustc_typeck, DIAGNOSTICS }
diff --git a/src/librustc_typeck/structured_errors.rs b/src/librustc_typeck/structured_errors.rs
index 3e3eab8cf4c..273a36edc56 100644
--- a/src/librustc_typeck/structured_errors.rs
+++ b/src/librustc_typeck/structured_errors.rs
@@ -48,7 +48,7 @@ impl<'tcx> StructuredDiagnostic<'tcx> for VariadicError<'tcx> {
     fn session(&self) -> &Session { self.sess }
 
     fn code(&self) -> DiagnosticId {
-        __diagnostic_used!(E0617);
+        syntax::diagnostic_used!(E0617);
         DiagnosticId::Error("E0617".to_owned())
     }
 
@@ -104,7 +104,7 @@ impl<'tcx> StructuredDiagnostic<'tcx> for SizedUnsizedCastError<'tcx> {
     fn session(&self) -> &Session { self.sess }
 
     fn code(&self) -> DiagnosticId {
-        __diagnostic_used!(E0607);
+        syntax::diagnostic_used!(E0607);
         DiagnosticId::Error("E0607".to_owned())
     }
 
diff --git a/src/libsyntax/diagnostics/macros.rs b/src/libsyntax/diagnostics/macros.rs
index b754d083376..c95c5bd5d02 100644
--- a/src/libsyntax/diagnostics/macros.rs
+++ b/src/libsyntax/diagnostics/macros.rs
@@ -1,13 +1,14 @@
 #[macro_export]
-macro_rules! register_diagnostic {
-    ($code:tt, $description:tt) => (__register_diagnostic! { $code, $description });
-    ($code:tt) => (__register_diagnostic! { $code })
+macro_rules! diagnostic_used {
+    ($code:ident) => (
+        let _ = crate::error_codes::$code;
+    )
 }
 
 #[macro_export]
 macro_rules! span_fatal {
     ($session:expr, $span:expr, $code:ident, $($message:tt)*) => ({
-        __diagnostic_used!($code);
+        $crate::diagnostic_used!($code);
         $session.span_fatal_with_code(
             $span,
             &format!($($message)*),
@@ -19,7 +20,7 @@ macro_rules! span_fatal {
 #[macro_export]
 macro_rules! span_err {
     ($session:expr, $span:expr, $code:ident, $($message:tt)*) => ({
-        __diagnostic_used!($code);
+        $crate::diagnostic_used!($code);
         $session.span_err_with_code(
             $span,
             &format!($($message)*),
@@ -31,7 +32,7 @@ macro_rules! span_err {
 #[macro_export]
 macro_rules! span_warn {
     ($session:expr, $span:expr, $code:ident, $($message:tt)*) => ({
-        __diagnostic_used!($code);
+        $crate::diagnostic_used!($code);
         $session.span_warn_with_code(
             $span,
             &format!($($message)*),
@@ -43,7 +44,7 @@ macro_rules! span_warn {
 #[macro_export]
 macro_rules! struct_err {
     ($session:expr, $code:ident, $($message:tt)*) => ({
-        __diagnostic_used!($code);
+        $crate::diagnostic_used!($code);
         $session.struct_err_with_code(
             &format!($($message)*),
             $crate::errors::DiagnosticId::Error(stringify!($code).to_owned()),
@@ -54,7 +55,7 @@ macro_rules! struct_err {
 #[macro_export]
 macro_rules! span_err_or_warn {
     ($is_warning:expr, $session:expr, $span:expr, $code:ident, $($message:tt)*) => ({
-        __diagnostic_used!($code);
+        $crate::diagnostic_used!($code);
         if $is_warning {
             $session.span_warn_with_code(
                 $span,
@@ -74,7 +75,7 @@ macro_rules! span_err_or_warn {
 #[macro_export]
 macro_rules! struct_span_fatal {
     ($session:expr, $span:expr, $code:ident, $($message:tt)*) => ({
-        __diagnostic_used!($code);
+        $crate::diagnostic_used!($code);
         $session.struct_span_fatal_with_code(
             $span,
             &format!($($message)*),
@@ -86,7 +87,7 @@ macro_rules! struct_span_fatal {
 #[macro_export]
 macro_rules! struct_span_err {
     ($session:expr, $span:expr, $code:ident, $($message:tt)*) => ({
-        __diagnostic_used!($code);
+        $crate::diagnostic_used!($code);
         $session.struct_span_err_with_code(
             $span,
             &format!($($message)*),
@@ -98,7 +99,7 @@ macro_rules! struct_span_err {
 #[macro_export]
 macro_rules! stringify_error_code {
     ($code:ident) => ({
-        __diagnostic_used!($code);
+        $crate::diagnostic_used!($code);
         $crate::errors::DiagnosticId::Error(stringify!($code).to_owned())
     })
 }
@@ -117,7 +118,7 @@ macro_rules! type_error_struct {
 #[macro_export]
 macro_rules! struct_span_warn {
     ($session:expr, $span:expr, $code:ident, $($message:tt)*) => ({
-        __diagnostic_used!($code);
+        $crate::diagnostic_used!($code);
         $session.struct_span_warn_with_code(
             $span,
             &format!($($message)*),
@@ -129,7 +130,7 @@ macro_rules! struct_span_warn {
 #[macro_export]
 macro_rules! struct_span_err_or_warn {
     ($is_warning:expr, $session:expr, $span:expr, $code:ident, $($message:tt)*) => ({
-        __diagnostic_used!($code);
+        $crate::diagnostic_used!($code);
         if $is_warning {
             $session.struct_span_warn_with_code(
                 $span,
@@ -169,20 +170,22 @@ macro_rules! help {
 
 #[macro_export]
 macro_rules! register_diagnostics {
-    ($($code:tt),*) => (
-        $($crate::register_diagnostic! { $code })*
+    ($($ecode:ident: $message:expr,)*) => (
+        $crate::register_diagnostics!{$($ecode:$message,)* ;}
     );
-    ($($code:tt),*,) => (
-        $($crate::register_diagnostic! { $code })*
-    )
-}
 
-#[macro_export]
-macro_rules! register_long_diagnostics {
-    ($($code:tt: $description:tt),*) => (
-        $($crate::register_diagnostic! { $code, $description })*
-    );
-    ($($code:tt: $description:tt),*,) => (
-        $($crate::register_diagnostic! { $code, $description })*
+    ($($ecode:ident: $message:expr,)* ; $($code:ident,)*) => (
+        pub static DIAGNOSTICS: &[(&str, &str)] = &[
+            $( (stringify!($ecode), $message), )*
+        ];
+
+        $(
+            #[deny(unused)]
+            pub(crate) const $ecode: &str = $message;
+        )*
+        $(
+            #[deny(unused)]
+            pub(crate) const $code: () = ();
+        )*
     )
 }
diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs
deleted file mode 100644
index 5de39c8d14d..00000000000
--- a/src/libsyntax/diagnostics/plugin.rs
+++ /dev/null
@@ -1,185 +0,0 @@
-use std::collections::BTreeMap;
-
-use crate::ast::{self, Ident, Name};
-use crate::source_map;
-use crate::ext::base::{ExtCtxt, MacEager, MacResult};
-use crate::parse::token::{self, Token};
-use crate::ptr::P;
-use crate::symbol::kw;
-use crate::tokenstream::{TokenTree, TokenStream};
-
-use smallvec::smallvec;
-use syntax_pos::Span;
-
-pub use errors::*;
-
-// Maximum width of any line in an extended error description (inclusive).
-const MAX_DESCRIPTION_WIDTH: usize = 80;
-
-/// Error information type.
-pub struct ErrorInfo {
-    pub description: Option<Name>,
-    pub use_site: Option<Span>
-}
-
-/// Mapping from error codes to metadata.
-pub type ErrorMap = BTreeMap<Name, ErrorInfo>;
-
-pub fn expand_diagnostic_used<'cx>(ecx: &'cx mut ExtCtxt<'_>,
-                                   span: Span,
-                                   tts: TokenStream)
-                                   -> Box<dyn MacResult+'cx> {
-    assert_eq!(tts.len(), 1);
-    let code = match tts.into_trees().next() {
-        Some(TokenTree::Token(Token { kind: token::Ident(code, _), .. })) => code,
-        _ => unreachable!()
-    };
-
-    ecx.parse_sess.registered_diagnostics.with_lock(|diagnostics| {
-        match diagnostics.get_mut(&code) {
-            // Previously used errors.
-            Some(&mut ErrorInfo { description: _, use_site: Some(previous_span) }) => {
-                ecx.struct_span_warn(span, &format!(
-                    "diagnostic code {} already used", code
-                )).span_note(previous_span, "previous invocation")
-                  .emit();
-            }
-            // Newly used errors.
-            Some(ref mut info) => {
-                info.use_site = Some(span);
-            }
-            // Unregistered errors.
-            None => {
-                ecx.span_err(span, &format!(
-                    "used diagnostic code {} not registered", code
-                ));
-            }
-        }
-    });
-    MacEager::expr(ecx.expr_tuple(span, Vec::new()))
-}
-
-pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt<'_>,
-                                       span: Span,
-                                       tts: TokenStream)
-                                       -> Box<dyn MacResult+'cx> {
-    assert!(tts.len() == 1 || tts.len() == 3);
-    let mut cursor = tts.into_trees();
-    let code = match cursor.next() {
-        Some(TokenTree::Token(Token { kind: token::Ident(code, _), .. })) => code,
-        _ => unreachable!()
-    };
-    let description = match  (cursor.next(), cursor.next()) {
-        (None, None) => None,
-        (
-            Some(TokenTree::Token(Token { kind: token::Comma, .. })),
-            Some(TokenTree::Token(Token { kind: token::Literal(token::Lit { symbol, .. }), ..}))
-        ) => {
-            Some(symbol)
-        },
-        _ => unreachable!()
-    };
-
-    // Check that the description starts and ends with a newline and doesn't
-    // overflow the maximum line width.
-    description.map(|raw_msg| {
-        let msg = raw_msg.as_str();
-        if !msg.starts_with("\n") || !msg.ends_with("\n") {
-            ecx.span_err(span, &format!(
-                "description for error code {} doesn't start and end with a newline",
-                code
-            ));
-        }
-
-        // URLs can be unavoidably longer than the line limit, so we allow them.
-        // Allowed format is: `[name]: https://www.rust-lang.org/`
-        let is_url = |l: &str| l.starts_with("[") && l.contains("]:") && l.contains("http");
-
-        if msg.lines().any(|line| line.len() > MAX_DESCRIPTION_WIDTH && !is_url(line)) {
-            ecx.span_err(span, &format!(
-                "description for error code {} contains a line longer than {} characters.\n\
-                 if you're inserting a long URL use the footnote style to bypass this check.",
-                code, MAX_DESCRIPTION_WIDTH
-            ));
-        }
-    });
-    // Add the error to the map.
-    ecx.parse_sess.registered_diagnostics.with_lock(|diagnostics| {
-        let info = ErrorInfo {
-            description,
-            use_site: None
-        };
-        if diagnostics.insert(code, info).is_some() {
-            ecx.span_err(span, &format!(
-                "diagnostic code {} already registered", code
-            ));
-        }
-    });
-
-    MacEager::items(smallvec![])
-}
-
-pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt<'_>,
-                                          span: Span,
-                                          tts: TokenStream)
-                                          -> Box<dyn MacResult+'cx> {
-    assert_eq!(tts.len(), 3);
-    let ident = match tts.into_trees().nth(2) {
-        // DIAGNOSTICS ident.
-        Some(TokenTree::Token(Token { kind: token::Ident(name, _), span }))
-        => Ident::new(name, span),
-        _ => unreachable!()
-    };
-
-    // Construct the output expression.
-    let (count, expr) =
-        ecx.parse_sess.registered_diagnostics.with_lock(|diagnostics| {
-            let descriptions: Vec<P<ast::Expr>> =
-                diagnostics.iter().filter_map(|(&code, info)| {
-                    info.description.map(|description| {
-                        ecx.expr_tuple(span, vec![
-                            ecx.expr_str(span, code),
-                            ecx.expr_str(span, description)
-                        ])
-                    })
-                }).collect();
-            (descriptions.len(), ecx.expr_vec(span, descriptions))
-        });
-
-    let static_ = ecx.lifetime(span, Ident::with_dummy_span(kw::StaticLifetime));
-    let ty_str = ecx.ty_rptr(
-        span,
-        ecx.ty_ident(span, ecx.ident_of("str")),
-        Some(static_),
-        ast::Mutability::Immutable,
-    );
-
-    let ty = ecx.ty(
-        span,
-        ast::TyKind::Array(
-            ecx.ty(
-                span,
-                ast::TyKind::Tup(vec![ty_str.clone(), ty_str])
-            ),
-            ast::AnonConst {
-                id: ast::DUMMY_NODE_ID,
-                value: ecx.expr_usize(span, count),
-            },
-        ),
-    );
-
-    MacEager::items(smallvec![
-        P(ast::Item {
-            ident,
-            attrs: Vec::new(),
-            id: ast::DUMMY_NODE_ID,
-            node: ast::ItemKind::Const(
-                ty,
-                expr,
-            ),
-            vis: source_map::respan(span.shrink_to_lo(), ast::VisibilityKind::Public),
-            span,
-            tokens: None,
-        })
-    ])
-}
diff --git a/src/libsyntax/error_codes.rs b/src/libsyntax/error_codes.rs
index 1ba29011f75..9925dd8ada0 100644
--- a/src/libsyntax/error_codes.rs
+++ b/src/libsyntax/error_codes.rs
@@ -1,7 +1,8 @@
 // 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! {
+// 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_diagnostics! {
 
 E0178: r##"
 In types, the `+` type operator has low precedence, so it is often necessary
@@ -420,9 +421,8 @@ Delete the offending feature attribute, or add it to the list of allowed
 features in the `-Z allow_features` flag.
 "##,
 
-}
+;
 
-register_diagnostics! {
     E0539, // incorrect meta item
     E0540, // multiple rustc_deprecated attributes
     E0542, // missing 'since'
@@ -432,7 +432,9 @@ register_diagnostics! {
     E0546, // missing 'feature'
     E0547, // missing 'issue'
 //  E0548, // replaced with a generic attribute input check
-    E0549, // rustc_deprecated attribute must be paired with either stable or unstable attribute
+    // rustc_deprecated attribute must be paired with either stable or unstable
+    // attribute
+    E0549,
     E0550, // multiple deprecated attributes
     E0551, // incorrect meta item
     E0553, // multiple rustc_const_unstable attributes
@@ -440,9 +442,11 @@ register_diagnostics! {
     E0556, // malformed feature, expected just one word
     E0584, // file for module `..` found at both .. and ..
     E0629, // missing 'feature' (rustc_const_unstable)
-    E0630, // rustc_const_unstable attribute must be paired with stable/unstable attribute
+    // rustc_const_unstable attribute must be paired with stable/unstable
+    // attribute
+    E0630,
     E0693, // incorrect `repr(align)` attribute format
-    E0694, // an unknown tool name found in scoped attributes
+//  E0694, // an unknown tool name found in scoped attributes
     E0703, // invalid ABI
     E0717, // rustc_promotable without stability attribute
 }
diff --git a/src/libsyntax/feature_gate/active.rs b/src/libsyntax/feature_gate/active.rs
index c947b09fdcb..86979bdb1fb 100644
--- a/src/libsyntax/feature_gate/active.rs
+++ b/src/libsyntax/feature_gate/active.rs
@@ -120,12 +120,6 @@ declare_features! (
     /// macros disappear).
     (active, allow_internal_unsafe, "1.0.0", None, None),
 
-    /// Allows using the macros:
-    /// + `__diagnostic_used`
-    /// + `__register_diagnostic`
-    /// +`__build_diagnostic_array`
-    (active, rustc_diagnostic_macros, "1.0.0", None, None),
-
     /// Allows using `#[rustc_const_unstable(feature = "foo", ..)]` which
     /// lets a function to be `const` when opted into with `#![feature(foo)]`.
     (active, rustc_const_unstable, "1.0.0", None, None),
diff --git a/src/libsyntax/feature_gate/removed.rs b/src/libsyntax/feature_gate/removed.rs
index ad7d69b3e73..2c29e1ebf14 100644
--- a/src/libsyntax/feature_gate/removed.rs
+++ b/src/libsyntax/feature_gate/removed.rs
@@ -94,6 +94,11 @@ declare_features! (
     /// Allows defining `existential type`s.
     (removed, existential_type, "1.38.0", Some(63063), None,
      Some("removed in favor of `#![feature(type_alias_impl_trait)]`")),
+    /// Allows using the macros:
+    /// + `__diagnostic_used`
+    /// + `__register_diagnostic`
+    /// +`__build_diagnostic_array`
+    (removed, rustc_diagnostic_macros, "1.38.0", None, None, None),
 
     // -------------------------------------------------------------------------
     // feature-group-end: removed features
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index 1741932c1b8..49efbce482f 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -18,7 +18,6 @@
 #![feature(proc_macro_diagnostic)]
 #![feature(proc_macro_internals)]
 #![feature(proc_macro_span)]
-#![feature(rustc_diagnostic_macros)]
 #![feature(try_trait)]
 #![feature(unicode_internals)]
 
@@ -123,11 +122,8 @@ scoped_tls::scoped_thread_local!(pub static GLOBALS: Globals);
 pub mod diagnostics {
     #[macro_use]
     pub mod macros;
-    pub mod plugin;
 }
 
-// N.B., this module needs to be declared first so diagnostics are
-// registered before they are used.
 pub mod error_codes;
 
 pub mod util {
@@ -182,5 +178,3 @@ pub mod ext {
 }
 
 pub mod early_buffered_lints;
-
-__build_diagnostic_array! { libsyntax, DIAGNOSTICS }
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index b1af4806e2d..981f5f1f7b0 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -8,7 +8,6 @@ use crate::parse::parser::Parser;
 use crate::parse::parser::emit_unclosed_delims;
 use crate::parse::token::TokenKind;
 use crate::tokenstream::{TokenStream, TokenTree};
-use crate::diagnostics::plugin::ErrorMap;
 use crate::print::pprust;
 use crate::symbol::Symbol;
 
@@ -64,8 +63,6 @@ pub struct ParseSess {
     pub missing_fragment_specifiers: Lock<FxHashSet<Span>>,
     /// Places where raw identifiers were used. This is used for feature-gating raw identifiers.
     pub raw_identifier_spans: Lock<Vec<Span>>,
-    /// The registered diagnostics codes.
-    crate registered_diagnostics: Lock<ErrorMap>,
     /// Used to determine and report recursive module inclusions.
     included_mod_stack: Lock<Vec<PathBuf>>,
     source_map: Lrc<SourceMap>,
@@ -95,7 +92,6 @@ impl ParseSess {
             config: FxHashSet::default(),
             missing_fragment_specifiers: Lock::new(FxHashSet::default()),
             raw_identifier_spans: Lock::new(Vec::new()),
-            registered_diagnostics: Lock::new(ErrorMap::new()),
             included_mod_stack: Lock::new(vec![]),
             source_map,
             buffered_lints: Lock::new(vec![]),
diff --git a/src/libsyntax_ext/error_codes.rs b/src/libsyntax_ext/error_codes.rs
index 5982a4df226..2bc990574f7 100644
--- a/src/libsyntax_ext/error_codes.rs
+++ b/src/libsyntax_ext/error_codes.rs
@@ -1,9 +1,8 @@
-use syntax::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! {
+// 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.
+syntax::register_diagnostics! {
 E0660: r##"
 The argument to the `asm` macro is not well-formed.
 
diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs
index 5c0a63ebbe7..631ab7a3310 100644
--- a/src/libsyntax_ext/lib.rs
+++ b/src/libsyntax_ext/lib.rs
@@ -9,7 +9,6 @@
 #![feature(nll)]
 #![feature(proc_macro_internals)]
 #![feature(proc_macro_quote)]
-#![feature(rustc_diagnostic_macros)]
 
 extern crate proc_macro;
 
diff --git a/src/test/ui/feature-gate/allow-features-empty.rs b/src/test/ui/feature-gate/allow-features-empty.rs
index 784a1d2697d..641e4b852e7 100644
--- a/src/test/ui/feature-gate/allow-features-empty.rs
+++ b/src/test/ui/feature-gate/allow-features-empty.rs
@@ -1,8 +1,6 @@
 // compile-flags: -Z allow_features=
 // Note: This test uses rustc internal flags because they will never stabilize.
 
-#![feature(rustc_diagnostic_macros)] //~ ERROR
-
 #![feature(rustc_const_unstable)] //~ ERROR
 
 #![feature(lang_items)] //~ ERROR
diff --git a/src/test/ui/feature-gate/allow-features-empty.stderr b/src/test/ui/feature-gate/allow-features-empty.stderr
index ab41422ed05..a87d1058503 100644
--- a/src/test/ui/feature-gate/allow-features-empty.stderr
+++ b/src/test/ui/feature-gate/allow-features-empty.stderr
@@ -1,27 +1,21 @@
-error[E0725]: the feature `rustc_diagnostic_macros` is not in the list of allowed features
-  --> $DIR/allow-features-empty.rs:4:12
-   |
-LL | #![feature(rustc_diagnostic_macros)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-
 error[E0725]: the feature `rustc_const_unstable` is not in the list of allowed features
-  --> $DIR/allow-features-empty.rs:6:12
+  --> $DIR/allow-features-empty.rs:4:12
    |
 LL | #![feature(rustc_const_unstable)]
    |            ^^^^^^^^^^^^^^^^^^^^
 
 error[E0725]: the feature `lang_items` is not in the list of allowed features
-  --> $DIR/allow-features-empty.rs:8:12
+  --> $DIR/allow-features-empty.rs:6:12
    |
 LL | #![feature(lang_items)]
    |            ^^^^^^^^^^
 
 error[E0725]: the feature `unknown_stdlib_feature` is not in the list of allowed features
-  --> $DIR/allow-features-empty.rs:10:12
+  --> $DIR/allow-features-empty.rs:8:12
    |
 LL | #![feature(unknown_stdlib_feature)]
    |            ^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0725`.
diff --git a/src/test/ui/feature-gate/allow-features.rs b/src/test/ui/feature-gate/allow-features.rs
index de3439a5b62..de69e48a65f 100644
--- a/src/test/ui/feature-gate/allow-features.rs
+++ b/src/test/ui/feature-gate/allow-features.rs
@@ -1,8 +1,6 @@
-// compile-flags: -Z allow_features=rustc_diagnostic_macros,lang_items
+// compile-flags: -Z allow_features=lang_items
 // Note: This test uses rustc internal flags because they will never stabilize.
 
-#![feature(rustc_diagnostic_macros)]
-
 #![feature(rustc_const_unstable)] //~ ERROR
 
 #![feature(lang_items)]
diff --git a/src/test/ui/feature-gate/allow-features.stderr b/src/test/ui/feature-gate/allow-features.stderr
index 5b39a6f053b..157dddf06ad 100644
--- a/src/test/ui/feature-gate/allow-features.stderr
+++ b/src/test/ui/feature-gate/allow-features.stderr
@@ -1,11 +1,11 @@
 error[E0725]: the feature `rustc_const_unstable` is not in the list of allowed features
-  --> $DIR/allow-features.rs:6:12
+  --> $DIR/allow-features.rs:4:12
    |
 LL | #![feature(rustc_const_unstable)]
    |            ^^^^^^^^^^^^^^^^^^^^
 
 error[E0725]: the feature `unknown_stdlib_feature` is not in the list of allowed features
-  --> $DIR/allow-features.rs:10:12
+  --> $DIR/allow-features.rs:8:12
    |
 LL | #![feature(unknown_stdlib_feature)]
    |            ^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/feature-gates/feature-gate-rustc-diagnostic-macros.rs b/src/test/ui/feature-gates/feature-gate-rustc-diagnostic-macros.rs
deleted file mode 100644
index 63c2c31fd30..00000000000
--- a/src/test/ui/feature-gates/feature-gate-rustc-diagnostic-macros.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-// Test that diagnostic macros are gated by `rustc_diagnostic_macros` feature
-// gate
-
-__register_diagnostic!(E0001);
-//~^ ERROR cannot find macro `__register_diagnostic!` in this scope
-
-fn main() {
-    __diagnostic_used!(E0001);
-    //~^ ERROR cannot find macro `__diagnostic_used!` in this scope
-}
-
-__build_diagnostic_array!(DIAGNOSTICS);
-//~^ ERROR cannot find macro `__build_diagnostic_array!` in this scope
diff --git a/src/test/ui/feature-gates/feature-gate-rustc-diagnostic-macros.stderr b/src/test/ui/feature-gates/feature-gate-rustc-diagnostic-macros.stderr
deleted file mode 100644
index 676b8b9f056..00000000000
--- a/src/test/ui/feature-gates/feature-gate-rustc-diagnostic-macros.stderr
+++ /dev/null
@@ -1,20 +0,0 @@
-error: cannot find macro `__build_diagnostic_array!` in this scope
-  --> $DIR/feature-gate-rustc-diagnostic-macros.rs:12:1
-   |
-LL | __build_diagnostic_array!(DIAGNOSTICS);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: cannot find macro `__diagnostic_used!` in this scope
-  --> $DIR/feature-gate-rustc-diagnostic-macros.rs:8:5
-   |
-LL |     __diagnostic_used!(E0001);
-   |     ^^^^^^^^^^^^^^^^^
-
-error: cannot find macro `__register_diagnostic!` in this scope
-  --> $DIR/feature-gate-rustc-diagnostic-macros.rs:4:1
-   |
-LL | __register_diagnostic!(E0001);
-   | ^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 3 previous errors
-
diff --git a/src/tools/error_index_generator/build.rs b/src/tools/error_index_generator/build.rs
index 2ac7351fce4..832aa3b1c8d 100644
--- a/src/tools/error_index_generator/build.rs
+++ b/src/tools/error_index_generator/build.rs
@@ -14,9 +14,7 @@ fn main() {
         if entry.file_name() == "error_codes.rs" {
             println!("cargo:rerun-if-changed={}", entry.path().to_str().unwrap());
             let file = fs::read_to_string(entry.path()).unwrap()
-                .replace("use syntax::{register_diagnostics, register_long_diagnostics};", "")
-                .replace("use syntax::register_diagnostics;", "")
-                .replace("use syntax::register_long_diagnostics;", "");
+                .replace("syntax::register_diagnostics!", "register_diagnostics!");
             let contents = format!("(|| {{\n{}\n}})();", file);
 
             fs::write(&out_dir.join(&format!("error_{}.rs", idx)), &contents).unwrap();
@@ -26,36 +24,31 @@ fn main() {
     }
 
     let mut all = String::new();
-    all.push_str("fn register_all() -> Vec<(&'static str, Option<&'static str>)> {\n");
-    all.push_str("let mut long_codes: Vec<(&'static str, Option<&'static str>)> = Vec::new();\n");
-    all.push_str(r#"
-macro_rules! register_diagnostics {
-    ($($code:tt),*) => {{
-        long_codes.extend([$(
-            stringify!($code),
-        )*].iter().cloned().map(|s| (s, None)).collect::<Vec<_>>());
-    }};
-    ($($code:tt),*,) => {{
-        long_codes.extend([$(
-            stringify!($code),
-        )*].iter().cloned().map(|s| (s, None)));
-    }}
-}
+    all.push_str(r###"
+fn register_all() -> Vec<(&'static str, Option<&'static str>)> {
+    let mut long_codes: Vec<(&'static str, Option<&'static str>)> = Vec::new();
+    macro_rules! register_diagnostics {
+        ($($ecode:ident: $message:expr,)*) => (
+            register_diagnostics!{$($ecode:$message,)* ;}
+        );
 
-macro_rules! register_long_diagnostics {
-    ($($code:tt: $description:tt),*) => {
-        {long_codes.extend([$(
-            (stringify!($code), Some(stringify!($description))),
-        )*].iter());}
-    };
-    ($($code:tt: $description:tt),*,) => {
-        {long_codes.extend([$(
-            (stringify!($code), Some(stringify!($description))),
-        )*].iter());}
+        ($($ecode:ident: $message:expr,)* ; $($code:ident,)*) => (
+            $(
+                {long_codes.extend([
+                    (stringify!($ecode), Some(stringify!($message))),
+                ].iter());}
+            )*
+            $(
+                {long_codes.extend([
+                    stringify!($code),
+                ].iter().cloned().map(|s| (s, None)).collect::<Vec<_>>());}
+            )*
+        )
     }
-}"#);
+"###);
     for idx in 0..idx {
         all.push_str(&format!(r#"include!(concat!(env!("OUT_DIR"), "/error_{}.rs"));"#, idx));
+        all.push_str("\n");
     }
     all.push_str("\nlong_codes\n");
     all.push_str("}\n");
diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs
index 6a0d530e236..93029099686 100644
--- a/src/tools/tidy/src/style.rs
+++ b/src/tools/tidy/src/style.rs
@@ -15,6 +15,7 @@
 
 use std::path::Path;
 
+const ERROR_CODE_COLS: usize = 80;
 const COLS: usize = 100;
 
 const LINES: usize = 3000;
@@ -51,7 +52,13 @@ enum LIUState {
 /// Lines of this form are allowed to be overlength, because Markdown
 /// offers no way to split a line in the middle of a URL, and the lengths
 /// of URLs to external references are beyond our control.
-fn line_is_url(line: &str) -> bool {
+fn line_is_url(columns: usize, line: &str) -> bool {
+    // more basic check for error_codes.rs, to avoid complexity in implementing two state machines
+    if columns == ERROR_CODE_COLS {
+        return line.starts_with("[") &&
+            line.contains("]:") && line.contains("http");
+    }
+
     use self::LIUState::*;
     let mut state: LIUState = EXP_COMMENT_START;
     let is_url = |w: &str| w.starts_with("http://") || w.starts_with("https://");
@@ -75,7 +82,7 @@ fn line_is_url(line: &str) -> bool {
                 => state = EXP_END,
 
             (_, w)
-                if w.len() > COLS && is_url(w)
+                if w.len() > columns && is_url(w)
                 => state = EXP_END,
 
             (_, _) => {}
@@ -88,8 +95,8 @@ fn line_is_url(line: &str) -> bool {
 /// Returns `true` if `line` is allowed to be longer than the normal limit.
 /// Currently there is only one exception, for long URLs, but more
 /// may be added in the future.
-fn long_line_is_ok(line: &str) -> bool {
-    if line_is_url(line) {
+fn long_line_is_ok(max_columns: usize, line: &str) -> bool {
+    if line_is_url(max_columns, line) {
         return true;
     }
 
@@ -144,6 +151,12 @@ pub fn check(path: &Path, bad: &mut bool) {
             tidy_error!(bad, "{}: empty file", file.display());
         }
 
+        let max_columns = if filename == "error_codes.rs" {
+            ERROR_CODE_COLS
+        } else {
+            COLS
+        };
+
         let can_contain = contents.contains("// ignore-tidy-") ||
             contents.contains("# ignore-tidy-");
         let mut skip_cr = contains_ignore_directive(can_contain, &contents, "cr");
@@ -162,11 +175,12 @@ pub fn check(path: &Path, bad: &mut bool) {
             let mut err = |msg: &str| {
                 tidy_error!(bad, "{}:{}: {}", file.display(), i + 1, msg);
             };
-            if line.chars().count() > COLS && !long_line_is_ok(line) {
+            if line.chars().count() > max_columns &&
+                !long_line_is_ok(max_columns, line) {
                 suppressible_tidy_err!(
                     err,
                     skip_line_length,
-                    &format!("line longer than {} chars", COLS)
+                    &format!("line longer than {} chars", max_columns)
                 );
             }
             if line.contains('\t') {