From b650e91cf40500b60475c17ff289e1db761d7836 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= <john.kare.alsaker@gmail.com>
Date: Thu, 9 Jan 2020 03:48:00 +0100
Subject: [PATCH 01/38] Label unmarked time

---
 src/librustc_codegen_ssa/back/link.rs     | 49 +++++++++------
 src/librustc_codegen_ssa/back/write.rs    |  9 ++-
 src/librustc_data_structures/profiling.rs |  6 ++
 src/librustc_driver/lib.rs                |  3 +
 src/librustc_incremental/persist/fs.rs    |  4 ++
 src/librustc_incremental/persist/load.rs  |  2 +
 src/librustc_interface/interface.rs       | 14 +++--
 src/librustc_interface/passes.rs          | 74 +++++++++++++----------
 src/librustc_interface/queries.rs         | 15 ++++-
 9 files changed, 117 insertions(+), 59 deletions(-)

diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs
index 253225f308e88..7436b7b9a4f56 100644
--- a/src/librustc_codegen_ssa/back/link.rs
+++ b/src/librustc_codegen_ssa/back/link.rs
@@ -53,6 +53,7 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>(
     crate_name: &str,
     target_cpu: &str,
 ) {
+    let _timer = sess.timer("link_binary");
     let output_metadata = sess.opts.output_types.contains_key(&OutputType::Metadata);
     for &crate_type in sess.crate_types.borrow().iter() {
         // Ignore executable crates if we have -Z no-codegen, as they will error.
@@ -71,9 +72,11 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>(
             );
         }
 
-        for obj in codegen_results.modules.iter().filter_map(|m| m.object.as_ref()) {
-            check_file_is_writeable(obj, sess);
-        }
+        sess.time("link_binary_check_files_are_writeable", || {
+            for obj in codegen_results.modules.iter().filter_map(|m| m.object.as_ref()) {
+                check_file_is_writeable(obj, sess);
+            }
+        });
 
         let tmpdir = TempFileBuilder::new()
             .prefix("rustc")
@@ -84,6 +87,7 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>(
             let out_filename = out_filename(sess, crate_type, outputs, crate_name);
             match crate_type {
                 config::CrateType::Rlib => {
+                    let _timer = sess.timer("link_rlib");
                     link_rlib::<B>(
                         sess,
                         codegen_results,
@@ -118,29 +122,34 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>(
     }
 
     // Remove the temporary object file and metadata if we aren't saving temps
-    if !sess.opts.cg.save_temps {
-        if sess.opts.output_types.should_codegen() && !preserve_objects_for_their_debuginfo(sess) {
-            for obj in codegen_results.modules.iter().filter_map(|m| m.object.as_ref()) {
-                remove(sess, obj);
+    sess.time("link_binary_remove_temps", || {
+        if !sess.opts.cg.save_temps {
+            if sess.opts.output_types.should_codegen()
+                && !preserve_objects_for_their_debuginfo(sess)
+            {
+                for obj in codegen_results.modules.iter().filter_map(|m| m.object.as_ref()) {
+                    remove(sess, obj);
+                }
             }
-        }
-        for obj in codegen_results.modules.iter().filter_map(|m| m.bytecode_compressed.as_ref()) {
-            remove(sess, obj);
-        }
-        if let Some(ref metadata_module) = codegen_results.metadata_module {
-            if let Some(ref obj) = metadata_module.object {
+            for obj in codegen_results.modules.iter().filter_map(|m| m.bytecode_compressed.as_ref())
+            {
                 remove(sess, obj);
             }
-        }
-        if let Some(ref allocator_module) = codegen_results.allocator_module {
-            if let Some(ref obj) = allocator_module.object {
-                remove(sess, obj);
+            if let Some(ref metadata_module) = codegen_results.metadata_module {
+                if let Some(ref obj) = metadata_module.object {
+                    remove(sess, obj);
+                }
             }
-            if let Some(ref bc) = allocator_module.bytecode_compressed {
-                remove(sess, bc);
+            if let Some(ref allocator_module) = codegen_results.allocator_module {
+                if let Some(ref obj) = allocator_module.object {
+                    remove(sess, obj);
+                }
+                if let Some(ref bc) = allocator_module.bytecode_compressed {
+                    remove(sess, bc);
+                }
             }
         }
-    }
+    });
 }
 
 // The third parameter is for env vars, used on windows to set up the
diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs
index 1ce0a29d55d9d..4d09e23ee7f7a 100644
--- a/src/librustc_codegen_ssa/back/write.rs
+++ b/src/librustc_codegen_ssa/back/write.rs
@@ -479,6 +479,8 @@ fn copy_all_cgu_workproducts_to_incr_comp_cache_dir(
         return work_products;
     }
 
+    let _timer = sess.timer("incr_comp_copy_cgu_workproducts");
+
     for module in compiled_modules.modules.iter().filter(|m| m.kind == ModuleKind::Regular) {
         let mut files = vec![];
 
@@ -1714,8 +1716,11 @@ pub struct OngoingCodegen<B: ExtraBackendMethods> {
 
 impl<B: ExtraBackendMethods> OngoingCodegen<B> {
     pub fn join(self, sess: &Session) -> (CodegenResults, FxHashMap<WorkProductId, WorkProduct>) {
+        let _timer = sess.timer("finish_ongoing_codegen");
+
         self.shared_emitter_main.check(sess, true);
-        let compiled_modules = match self.future.join() {
+        let future = self.future;
+        let compiled_modules = sess.time("join_worker_thread", || match future.join() {
             Ok(Ok(compiled_modules)) => compiled_modules,
             Ok(Err(())) => {
                 sess.abort_if_errors();
@@ -1724,7 +1729,7 @@ impl<B: ExtraBackendMethods> OngoingCodegen<B> {
             Err(_) => {
                 bug!("panic during codegen/LLVM phase");
             }
-        };
+        });
 
         sess.cgu_reuse_tracker.check_expected_reuse(sess.diagnostic());
 
diff --git a/src/librustc_data_structures/profiling.rs b/src/librustc_data_structures/profiling.rs
index a9d3a2668aab1..892509fc2d66f 100644
--- a/src/librustc_data_structures/profiling.rs
+++ b/src/librustc_data_structures/profiling.rs
@@ -347,6 +347,12 @@ impl<'a> TimingGuard<'a> {
     pub fn none() -> TimingGuard<'a> {
         TimingGuard(None)
     }
+
+    #[inline(always)]
+    pub fn run<R>(self, f: impl FnOnce() -> R) -> R {
+        let _timer = self;
+        f()
+    }
 }
 
 #[must_use]
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index a5277bcd120ed..a334124bf7e00 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -389,6 +389,7 @@ pub fn run_compiler(
                 })?;
             } else {
                 // Drop AST after creating GlobalCtxt to free memory
+                let _timer = sess.prof.generic_activity("drop_ast");
                 mem::drop(queries.expansion()?.take());
             }
 
@@ -408,11 +409,13 @@ pub fn run_compiler(
                 sess.code_stats.print_type_sizes();
             }
 
+            let _timer = sess.timer("query_linker");
             let linker = queries.linker()?;
             Ok(Some(linker))
         })?;
 
         if let Some(linker) = linker {
+            let _timer = sess.timer("link");
             linker.link()?
         }
 
diff --git a/src/librustc_incremental/persist/fs.rs b/src/librustc_incremental/persist/fs.rs
index adf8f57f01d08..ba20006d73ccc 100644
--- a/src/librustc_incremental/persist/fs.rs
+++ b/src/librustc_incremental/persist/fs.rs
@@ -190,6 +190,8 @@ pub fn prepare_session_directory(
         return;
     }
 
+    let _timer = sess.timer("incr_comp_prepare_session_directory");
+
     debug!("prepare_session_directory");
 
     // {incr-comp-dir}/{crate-name-and-disambiguator}
@@ -306,6 +308,8 @@ pub fn finalize_session_directory(sess: &Session, svh: Svh) {
         return;
     }
 
+    let _timer = sess.timer("incr_comp_finalize_session_directory");
+
     let incr_comp_session_dir: PathBuf = sess.incr_comp_session_dir().clone();
 
     if sess.has_errors_or_delayed_span_bugs() {
diff --git a/src/librustc_incremental/persist/load.rs b/src/librustc_incremental/persist/load.rs
index 0732ddd3261a4..6c57f79e1a7fb 100644
--- a/src/librustc_incremental/persist/load.rs
+++ b/src/librustc_incremental/persist/load.rs
@@ -102,6 +102,8 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture {
         return MaybeAsync::Sync(LoadResult::Ok { data: Default::default() });
     }
 
+    let _timer = sess.prof.generic_activity("incr_comp_prepare_load_dep_graph");
+
     // Calling `sess.incr_comp_session_dir()` will panic if `sess.opts.incremental.is_none()`.
     // Fortunately, we just checked that this isn't the case.
     let path = dep_graph_path_from(&sess.incr_comp_session_dir());
diff --git a/src/librustc_interface/interface.rs b/src/librustc_interface/interface.rs
index c4449945dd19d..d00875f6fee88 100644
--- a/src/librustc_interface/interface.rs
+++ b/src/librustc_interface/interface.rs
@@ -177,11 +177,17 @@ pub fn run_compiler_in_existing_thread_pool<R>(
         override_queries: config.override_queries,
     };
 
-    let _sess_abort_error = OnDrop(|| {
-        compiler.sess.diagnostic().print_error_count(registry);
-    });
+    let r = {
+        let _sess_abort_error = OnDrop(|| {
+            compiler.sess.diagnostic().print_error_count(registry);
+        });
 
-    f(&compiler)
+        f(&compiler)
+    };
+
+    let prof = compiler.sess.prof.clone();
+    prof.generic_activity("drop_compiler").run(move || drop(compiler));
+    r
 }
 
 pub fn run_compiler<R: Send>(mut config: Config, f: impl FnOnce(&Compiler) -> R + Send) -> R {
diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs
index a7e174f04553c..76ceeabdb728b 100644
--- a/src/librustc_interface/passes.rs
+++ b/src/librustc_interface/passes.rs
@@ -163,19 +163,22 @@ pub fn register_plugins<'a>(
         )
     });
 
-    let (krate, features) = rustc_expand::config::features(
-        krate,
-        &sess.parse_sess,
-        sess.edition(),
-        &sess.opts.debugging_opts.allow_features,
-    );
+    let (krate, features) = sess.time("compute_features", || {
+        rustc_expand::config::features(
+            krate,
+            &sess.parse_sess,
+            sess.edition(),
+            &sess.opts.debugging_opts.allow_features,
+        )
+    });
     // these need to be set "early" so that expansion sees `quote` if enabled.
     sess.init_features(features);
 
     let crate_types = util::collect_crate_types(sess, &krate.attrs);
     sess.crate_types.set(crate_types);
 
-    let disambiguator = util::compute_crate_disambiguator(sess);
+    let disambiguator =
+        sess.time("compute_crate_disambiguator", || util::compute_crate_disambiguator(sess));
     sess.crate_disambiguator.set(disambiguator);
     rustc_incremental::prepare_session_directory(sess, &crate_name, disambiguator);
 
@@ -611,6 +614,8 @@ pub fn prepare_outputs(
     boxed_resolver: &Steal<Rc<RefCell<BoxedResolver>>>,
     crate_name: &str,
 ) -> Result<OutputFilenames> {
+    let _timer = sess.timer("prepare_outputs");
+
     // FIXME: rustdoc passes &[] instead of &krate.attrs here
     let outputs = util::build_output_filenames(
         &compiler.input,
@@ -721,33 +726,40 @@ pub fn create_global_ctxt<'tcx>(
 
     let query_result_on_disk_cache = rustc_incremental::load_query_result_cache(sess);
 
-    let codegen_backend = compiler.codegen_backend();
-    let mut local_providers = ty::query::Providers::default();
-    default_provide(&mut local_providers);
-    codegen_backend.provide(&mut local_providers);
+    let codegen_backend = sess.time("load_codegen_backend", || compiler.codegen_backend());
 
-    let mut extern_providers = local_providers;
-    default_provide_extern(&mut extern_providers);
-    codegen_backend.provide_extern(&mut extern_providers);
+    let (local_providers, extern_providers) = sess.time("load_codegen_backend", || {
+        let mut local_providers = ty::query::Providers::default();
+        default_provide(&mut local_providers);
+        codegen_backend.provide(&mut local_providers);
 
-    if let Some(callback) = compiler.override_queries {
-        callback(sess, &mut local_providers, &mut extern_providers);
-    }
+        let mut extern_providers = local_providers;
+        default_provide_extern(&mut extern_providers);
+        codegen_backend.provide_extern(&mut extern_providers);
 
-    let gcx = global_ctxt.init_locking(|| {
-        TyCtxt::create_global_ctxt(
-            sess,
-            lint_store,
-            local_providers,
-            extern_providers,
-            &all_arenas,
-            arena,
-            resolver_outputs,
-            hir_map,
-            query_result_on_disk_cache,
-            &crate_name,
-            &outputs,
-        )
+        if let Some(callback) = compiler.override_queries {
+            callback(sess, &mut local_providers, &mut extern_providers);
+        }
+
+        (local_providers, extern_providers)
+    });
+
+    let gcx = sess.time("setup_global_ctxt", || {
+        global_ctxt.init_locking(|| {
+            TyCtxt::create_global_ctxt(
+                sess,
+                lint_store,
+                local_providers,
+                extern_providers,
+                &all_arenas,
+                arena,
+                resolver_outputs,
+                hir_map,
+                query_result_on_disk_cache,
+                &crate_name,
+                &outputs,
+            )
+        })
     });
 
     // Do some initialization of the DepGraph that can only be done with the tcx available.
diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs
index 6033569d765b4..3ec043624accb 100644
--- a/src/librustc_interface/queries.rs
+++ b/src/librustc_interface/queries.rs
@@ -158,6 +158,7 @@ impl<'tcx> Queries<'tcx> {
             Ok(match self.compiler.crate_name {
                 Some(ref crate_name) => crate_name.clone(),
                 None => {
+                    let _timer = self.session().timer("crate_name");
                     let parse_result = self.parse()?;
                     let krate = parse_result.peek();
                     rustc_codegen_utils::link::find_crate_name(
@@ -176,6 +177,7 @@ impl<'tcx> Queries<'tcx> {
         self.expansion.compute(|| {
             let crate_name = self.crate_name()?.peek().clone();
             let (krate, lint_store) = self.register_plugins()?.take();
+            let _timer = self.session().timer("configure_and_expand");
             passes::configure_and_expand(
                 self.session().clone(),
                 lint_store.clone(),
@@ -256,6 +258,7 @@ impl<'tcx> Queries<'tcx> {
             let lint_store = self.expansion()?.peek().2.clone();
             let hir = self.lower_to_hir()?.peek();
             let (ref hir_forest, ref resolver_outputs) = &*hir;
+            let _timer = self.session().timer("create_global_ctxt");
             Ok(passes::create_global_ctxt(
                 self.compiler,
                 lint_store,
@@ -312,14 +315,19 @@ pub struct Linker {
 
 impl Linker {
     pub fn link(self) -> Result<()> {
-        self.codegen_backend
+        let r = self
+            .codegen_backend
             .join_codegen_and_link(
                 self.ongoing_codegen,
                 &self.sess,
                 &self.dep_graph,
                 &self.prepare_outputs,
             )
-            .map_err(|_| ErrorReported)
+            .map_err(|_| ErrorReported);
+        let prof = self.sess.prof.clone();
+        let dep_graph = self.dep_graph;
+        prof.generic_activity("drop_dep_graph").run(move || drop(dep_graph));
+        r
     }
 }
 
@@ -328,6 +336,7 @@ impl Compiler {
     where
         F: for<'tcx> FnOnce(&'tcx Queries<'tcx>) -> T,
     {
+        let mut _timer = None;
         let queries = Queries::new(&self);
         let ret = f(&queries);
 
@@ -337,6 +346,8 @@ impl Compiler {
             }
         }
 
+        _timer = Some(self.session().timer("free_global_ctxt"));
+
         ret
     }
 

From 5918c187854e14a9b9c626753a70530a0e6222db Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= <john.kare.alsaker@gmail.com>
Date: Thu, 9 Jan 2020 23:19:20 +0100
Subject: [PATCH 02/38] Tweak timers

---
 src/librustc_ast_lowering/lib.rs  |  2 +-
 src/librustc_driver/lib.rs        |  1 -
 src/librustc_interface/passes.rs  | 42 +++++++++++++------------------
 src/librustc_interface/queries.rs |  1 -
 4 files changed, 18 insertions(+), 28 deletions(-)

diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs
index 385153b62ce82..f0724b4bc0c77 100644
--- a/src/librustc_ast_lowering/lib.rs
+++ b/src/librustc_ast_lowering/lib.rs
@@ -268,7 +268,7 @@ pub fn lower_crate<'a, 'hir>(
     // incr. comp. yet.
     dep_graph.assert_ignored();
 
-    let _prof_timer = sess.prof.generic_activity("hir_lowering");
+    let _prof_timer = sess.prof.verbose_generic_activity("hir_lowering");
 
     LoweringContext {
         crate_root: sess.parse_sess.injected_crate_name.try_get().copied(),
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index a334124bf7e00..0cc74060a7df8 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -409,7 +409,6 @@ pub fn run_compiler(
                 sess.code_stats.print_type_sizes();
             }
 
-            let _timer = sess.timer("query_linker");
             let linker = queries.linker()?;
             Ok(Some(linker))
         })?;
diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs
index 76ceeabdb728b..277bdf914085d 100644
--- a/src/librustc_interface/passes.rs
+++ b/src/librustc_interface/passes.rs
@@ -163,22 +163,19 @@ pub fn register_plugins<'a>(
         )
     });
 
-    let (krate, features) = sess.time("compute_features", || {
-        rustc_expand::config::features(
-            krate,
-            &sess.parse_sess,
-            sess.edition(),
-            &sess.opts.debugging_opts.allow_features,
-        )
-    });
+    let (krate, features) = rustc_expand::config::features(
+        krate,
+        &sess.parse_sess,
+        sess.edition(),
+        &sess.opts.debugging_opts.allow_features,
+    );
     // these need to be set "early" so that expansion sees `quote` if enabled.
     sess.init_features(features);
 
     let crate_types = util::collect_crate_types(sess, &krate.attrs);
     sess.crate_types.set(crate_types);
 
-    let disambiguator =
-        sess.time("compute_crate_disambiguator", || util::compute_crate_disambiguator(sess));
+    let disambiguator = util::compute_crate_disambiguator(sess);
     sess.crate_disambiguator.set(disambiguator);
     rustc_incremental::prepare_session_directory(sess, &crate_name, disambiguator);
 
@@ -726,23 +723,18 @@ pub fn create_global_ctxt<'tcx>(
 
     let query_result_on_disk_cache = rustc_incremental::load_query_result_cache(sess);
 
-    let codegen_backend = sess.time("load_codegen_backend", || compiler.codegen_backend());
+    let codegen_backend = compiler.codegen_backend();
+    let mut local_providers = ty::query::Providers::default();
+    default_provide(&mut local_providers);
+    codegen_backend.provide(&mut local_providers);
 
-    let (local_providers, extern_providers) = sess.time("load_codegen_backend", || {
-        let mut local_providers = ty::query::Providers::default();
-        default_provide(&mut local_providers);
-        codegen_backend.provide(&mut local_providers);
+    let mut extern_providers = local_providers;
+    default_provide_extern(&mut extern_providers);
+    codegen_backend.provide_extern(&mut extern_providers);
 
-        let mut extern_providers = local_providers;
-        default_provide_extern(&mut extern_providers);
-        codegen_backend.provide_extern(&mut extern_providers);
-
-        if let Some(callback) = compiler.override_queries {
-            callback(sess, &mut local_providers, &mut extern_providers);
-        }
-
-        (local_providers, extern_providers)
-    });
+    if let Some(callback) = compiler.override_queries {
+        callback(sess, &mut local_providers, &mut extern_providers);
+    }
 
     let gcx = sess.time("setup_global_ctxt", || {
         global_ctxt.init_locking(|| {
diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs
index 3ec043624accb..7de1c36ce4b2e 100644
--- a/src/librustc_interface/queries.rs
+++ b/src/librustc_interface/queries.rs
@@ -158,7 +158,6 @@ impl<'tcx> Queries<'tcx> {
             Ok(match self.compiler.crate_name {
                 Some(ref crate_name) => crate_name.clone(),
                 None => {
-                    let _timer = self.session().timer("crate_name");
                     let parse_result = self.parse()?;
                     let krate = parse_result.peek();
                     rustc_codegen_utils::link::find_crate_name(

From 1c9f999157e40b770c60518174355273875bf88d Mon Sep 17 00:00:00 2001
From: Matthew Healy <matthew.healy@soundcloud.com>
Date: Thu, 9 Jan 2020 22:19:33 +0100
Subject: [PATCH 03/38] Add llvm-skip-rebuild to opts

---
 src/bootstrap/flags.rs | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs
index ffc24367db6e9..813e89eef38ce 100644
--- a/src/bootstrap/flags.rs
+++ b/src/bootstrap/flags.rs
@@ -150,6 +150,14 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`",
             "VALUE",
         );
         opts.optopt("", "error-format", "rustc error format", "FORMAT");
+        opts.optopt(
+            "",
+            "llvm-skip-rebuild",
+            "whether rebuilding llvm should be skipped \
+             a VALUE of TRUE indicates that llvm will not be rebuilt \
+             VALUE overrides the skip-rebuild option in config.toml.",
+            "VALUE",
+        );
 
         // fn usage()
         let usage =

From 595999962a84892d35c68c621cee86d0f367dafb Mon Sep 17 00:00:00 2001
From: msizanoen1 <qtmlabs@protonmail.com>
Date: Fri, 10 Jan 2020 12:23:42 +0700
Subject: [PATCH 04/38] Distribution CI for RISC-V GNU/Linux

---
 src/ci/docker/dist-various-1/Dockerfile       |  29 +
 .../dist-various-1/build-riscv-toolchain.sh   |  27 +
 src/ci/docker/dist-various-1/crosstool-ng.sh  |  13 +
 .../riscv64-unknown-linux-gnu.config          | 908 ++++++++++++++++++
 4 files changed, 977 insertions(+)
 create mode 100755 src/ci/docker/dist-various-1/build-riscv-toolchain.sh
 create mode 100755 src/ci/docker/dist-various-1/crosstool-ng.sh
 create mode 100644 src/ci/docker/dist-various-1/riscv64-unknown-linux-gnu.config

diff --git a/src/ci/docker/dist-various-1/Dockerfile b/src/ci/docker/dist-various-1/Dockerfile
index 6bbf092878311..61f0fcc6ff741 100644
--- a/src/ci/docker/dist-various-1/Dockerfile
+++ b/src/ci/docker/dist-various-1/Dockerfile
@@ -2,11 +2,24 @@ FROM ubuntu:16.04
 
 RUN apt-get update && apt-get install -y --no-install-recommends \
   g++ \
+  automake \
+  bison \
+  bzip2 \
+  flex \
+  help2man \
+  libtool-bin \
+  texinfo \
+  unzip \
+  wget \
+  xz-utils \
+  libncurses-dev \
+  gawk \
   make \
   file \
   curl \
   ca-certificates \
   python2.7 \
+  python3 \
   git \
   cmake \
   sudo \
@@ -35,6 +48,18 @@ RUN add-apt-repository ppa:team-gcc-arm-embedded/ppa && \
     apt-get update && \
     apt-get install -y --no-install-recommends gcc-arm-embedded
 
+COPY scripts/rustbuild-setup.sh dist-various-1/build-riscv-toolchain.sh dist-various-1/riscv64-unknown-linux-gnu.config dist-various-1/crosstool-ng.sh /build
+RUN ./crosstool-ng.sh
+
+# Crosstool-ng will refuse to build as root
+RUN ./rustbuild-setup.sh
+USER rustbuild
+
+RUN ./build-riscv-toolchain.sh
+
+USER root
+ENV PATH=/x-tools/riscv64-unknown-linux-gnu/bin:$PATH
+
 COPY dist-various-1/build-rumprun.sh /build
 RUN ./build-rumprun.sh
 
@@ -129,6 +154,7 @@ ENV TARGETS=$TARGETS,riscv32imc-unknown-none-elf
 ENV TARGETS=$TARGETS,riscv32imac-unknown-none-elf
 ENV TARGETS=$TARGETS,riscv64imac-unknown-none-elf
 ENV TARGETS=$TARGETS,riscv64gc-unknown-none-elf
+ENV TARGETS=$TARGETS,riscv64gc-unknown-linux-gnu
 ENV TARGETS=$TARGETS,armebv7r-none-eabi
 ENV TARGETS=$TARGETS,armebv7r-none-eabihf
 ENV TARGETS=$TARGETS,armv7r-none-eabi
@@ -147,6 +173,9 @@ ENV CC_mipsel_unknown_linux_musl=mipsel-openwrt-linux-gcc \
     CC_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-gcc \
     AR_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-ar \
     CXX_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-g++ \
+    CC_riscv64gc_unknown_linux_gnu=riscv64-unknown-linux-gnu-gcc \
+    AR_riscv64gc_unknown_linux_gnu=riscv64-unknown-linux-gnu-ar \
+    CXX_riscv64gc_unknown_linux_gnu=riscv64-unknown-linux-gnu-g++ \
     CC_riscv32i_unknown_none_elf=false \
     CC_riscv32imc_unknown_none_elf=false \
     CC_riscv32imac_unknown_none_elf=false \
diff --git a/src/ci/docker/dist-various-1/build-riscv-toolchain.sh b/src/ci/docker/dist-various-1/build-riscv-toolchain.sh
new file mode 100755
index 0000000000000..9cb5700b3b6fb
--- /dev/null
+++ b/src/ci/docker/dist-various-1/build-riscv-toolchain.sh
@@ -0,0 +1,27 @@
+#!/usr/bin/env bash
+
+set -ex
+
+hide_output() {
+  set +x
+  on_err="
+echo ERROR: An error was encountered with the build.
+cat /tmp/build.log
+exit 1
+"
+  trap "$on_err" ERR
+  bash -c "while true; do sleep 30; echo \$(date) - building ...; done" &
+  PING_LOOP_PID=$!
+  $@ &> /tmp/build.log
+  rm /tmp/build.log
+  trap - ERR
+  kill $PING_LOOP_PID
+  set -x
+}
+
+mkdir -p /tmp/build-riscv
+cp riscv64-unknown-linux-gnu.config /tmp/build-riscv/.config
+cd /tmp/build-riscv
+hide_output ct-ng build
+cd ..
+rm -rf build-riscv
diff --git a/src/ci/docker/dist-various-1/crosstool-ng.sh b/src/ci/docker/dist-various-1/crosstool-ng.sh
new file mode 100755
index 0000000000000..b01fdd0bf65e7
--- /dev/null
+++ b/src/ci/docker/dist-various-1/crosstool-ng.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+set -ex
+
+# Mirrored from https://github.com/crosstool-ng/crosstool-ng/archive/crosstool-ng-1.24.0.tar.gz
+url="https://ci-mirrors.rust-lang.org/rustc/crosstool-ng-1.24.0.tar.gz"
+curl -Lf $url | tar xzf -
+cd crosstool-ng-crosstool-ng-1.24.0
+./bootstrap
+./configure --prefix=/usr/local
+make -j$(nproc)
+make install
+cd ..
+rm -rf crosstool-ng-crosstool-ng-1.24.0
diff --git a/src/ci/docker/dist-various-1/riscv64-unknown-linux-gnu.config b/src/ci/docker/dist-various-1/riscv64-unknown-linux-gnu.config
new file mode 100644
index 0000000000000..dd06065b19740
--- /dev/null
+++ b/src/ci/docker/dist-various-1/riscv64-unknown-linux-gnu.config
@@ -0,0 +1,908 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# crosstool-NG  Configuration
+#
+CT_CONFIGURE_has_static_link=y
+CT_CONFIGURE_has_cxx11=y
+CT_CONFIGURE_has_wget=y
+CT_CONFIGURE_has_curl=y
+CT_CONFIGURE_has_make_3_81_or_newer=y
+CT_CONFIGURE_has_make_4_0_or_newer=y
+CT_CONFIGURE_has_libtool_2_4_or_newer=y
+CT_CONFIGURE_has_libtoolize_2_4_or_newer=y
+CT_CONFIGURE_has_autoconf_2_65_or_newer=y
+CT_CONFIGURE_has_autoreconf_2_65_or_newer=y
+CT_CONFIGURE_has_automake_1_15_or_newer=y
+CT_CONFIGURE_has_gnu_m4_1_4_12_or_newer=y
+CT_CONFIGURE_has_python_3_4_or_newer=y
+CT_CONFIGURE_has_bison_2_7_or_newer=y
+CT_CONFIGURE_has_python=y
+CT_CONFIGURE_has_dtc=y
+CT_CONFIGURE_has_svn=y
+CT_CONFIGURE_has_git=y
+CT_CONFIGURE_has_md5sum=y
+CT_CONFIGURE_has_sha1sum=y
+CT_CONFIGURE_has_sha256sum=y
+CT_CONFIGURE_has_sha512sum=y
+CT_CONFIGURE_has_install_with_strip_program=y
+CT_CONFIG_VERSION_CURRENT="3"
+CT_CONFIG_VERSION="3"
+CT_MODULES=y
+
+#
+# Paths and misc options
+#
+
+#
+# crosstool-NG behavior
+#
+# CT_OBSOLETE is not set
+CT_EXPERIMENTAL=y
+# CT_ALLOW_BUILD_AS_ROOT is not set
+# CT_DEBUG_CT is not set
+
+#
+# Paths
+#
+CT_LOCAL_TARBALLS_DIR="${HOME}/src"
+CT_SAVE_TARBALLS=y
+# CT_TARBALLS_BUILDROOT_LAYOUT is not set
+CT_WORK_DIR="${CT_TOP_DIR}/.build"
+CT_BUILD_TOP_DIR="${CT_WORK_DIR:-${CT_TOP_DIR}/.build}/${CT_HOST:+HOST-${CT_HOST}/}${CT_TARGET}"
+CT_PREFIX_DIR="/x-tools/${CT_TARGET}"
+CT_RM_RF_PREFIX_DIR=y
+CT_REMOVE_DOCS=y
+CT_INSTALL_LICENSES=y
+CT_PREFIX_DIR_RO=y
+CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y
+# CT_STRIP_TARGET_TOOLCHAIN_EXECUTABLES is not set
+
+#
+# Downloading
+#
+CT_DOWNLOAD_AGENT_WGET=y
+# CT_DOWNLOAD_AGENT_CURL is not set
+# CT_DOWNLOAD_AGENT_NONE is not set
+# CT_FORBID_DOWNLOAD is not set
+# CT_FORCE_DOWNLOAD is not set
+CT_CONNECT_TIMEOUT=10
+CT_DOWNLOAD_WGET_OPTIONS="--passive-ftp --tries=3 -nc --progress=dot:binary"
+# CT_ONLY_DOWNLOAD is not set
+# CT_USE_MIRROR is not set
+CT_VERIFY_DOWNLOAD_DIGEST=y
+CT_VERIFY_DOWNLOAD_DIGEST_SHA512=y
+# CT_VERIFY_DOWNLOAD_DIGEST_SHA256 is not set
+# CT_VERIFY_DOWNLOAD_DIGEST_SHA1 is not set
+# CT_VERIFY_DOWNLOAD_DIGEST_MD5 is not set
+CT_VERIFY_DOWNLOAD_DIGEST_ALG="sha512"
+# CT_VERIFY_DOWNLOAD_SIGNATURE is not set
+
+#
+# Extracting
+#
+# CT_FORCE_EXTRACT is not set
+CT_OVERRIDE_CONFIG_GUESS_SUB=y
+# CT_ONLY_EXTRACT is not set
+CT_PATCH_BUNDLED=y
+# CT_PATCH_LOCAL is not set
+# CT_PATCH_BUNDLED_LOCAL is not set
+# CT_PATCH_LOCAL_BUNDLED is not set
+# CT_PATCH_NONE is not set
+CT_PATCH_ORDER="bundled"
+
+#
+# Build behavior
+#
+CT_PARALLEL_JOBS=0
+CT_LOAD=""
+CT_USE_PIPES=y
+CT_EXTRA_CFLAGS_FOR_BUILD=""
+CT_EXTRA_LDFLAGS_FOR_BUILD=""
+CT_EXTRA_CFLAGS_FOR_HOST=""
+CT_EXTRA_LDFLAGS_FOR_HOST=""
+# CT_CONFIG_SHELL_SH is not set
+# CT_CONFIG_SHELL_ASH is not set
+CT_CONFIG_SHELL_BASH=y
+# CT_CONFIG_SHELL_CUSTOM is not set
+CT_CONFIG_SHELL="${bash}"
+
+#
+# Logging
+#
+# CT_LOG_ERROR is not set
+# CT_LOG_WARN is not set
+# CT_LOG_INFO is not set
+# CT_LOG_EXTRA is not set
+CT_LOG_ALL=y
+# CT_LOG_DEBUG is not set
+CT_LOG_LEVEL_MAX="ALL"
+# CT_LOG_SEE_TOOLS_WARN is not set
+CT_LOG_TO_FILE=y
+CT_LOG_FILE_COMPRESS=y
+
+#
+# Target options
+#
+# CT_ARCH_ALPHA is not set
+# CT_ARCH_ARC is not set
+# CT_ARCH_ARM is not set
+# CT_ARCH_AVR is not set
+# CT_ARCH_M68K is not set
+# CT_ARCH_MICROBLAZE is not set
+# CT_ARCH_MIPS is not set
+# CT_ARCH_MOXIE is not set
+# CT_ARCH_MSP430 is not set
+# CT_ARCH_NIOS2 is not set
+# CT_ARCH_POWERPC is not set
+CT_ARCH_RISCV=y
+# CT_ARCH_S390 is not set
+# CT_ARCH_SH is not set
+# CT_ARCH_SPARC is not set
+# CT_ARCH_X86 is not set
+# CT_ARCH_XTENSA is not set
+CT_ARCH="riscv"
+CT_ARCH_CHOICE_KSYM="RISCV"
+CT_ARCH_TUNE=""
+CT_ARCH_RISCV_SHOW=y
+
+#
+# Options for riscv
+#
+CT_ARCH_RISCV_PKG_KSYM=""
+CT_ALL_ARCH_CHOICES="ALPHA ARC ARM AVR M68K MICROBLAZE MIPS MOXIE MSP430 NIOS2 POWERPC RISCV S390 SH SPARC X86 XTENSA"
+CT_ARCH_SUFFIX=""
+# CT_OMIT_TARGET_VENDOR is not set
+
+#
+# Generic target options
+#
+# CT_MULTILIB is not set
+# CT_DEMULTILIB is not set
+CT_ARCH_SUPPORTS_BOTH_MMU=y
+CT_ARCH_USE_MMU=y
+CT_ARCH_SUPPORTS_32=y
+CT_ARCH_SUPPORTS_64=y
+CT_ARCH_DEFAULT_32=y
+CT_ARCH_BITNESS=64
+# CT_ARCH_32 is not set
+CT_ARCH_64=y
+
+#
+# Target optimisations
+#
+CT_ARCH_SUPPORTS_WITH_ARCH=y
+CT_ARCH_SUPPORTS_WITH_ABI=y
+CT_ARCH_SUPPORTS_WITH_TUNE=y
+CT_ARCH_ARCH="rv64gc"
+CT_ARCH_ABI=""
+CT_TARGET_CFLAGS=""
+CT_TARGET_LDFLAGS=""
+
+#
+# Toolchain options
+#
+
+#
+# General toolchain options
+#
+CT_FORCE_SYSROOT=y
+CT_USE_SYSROOT=y
+CT_SYSROOT_NAME="sysroot"
+CT_SYSROOT_DIR_PREFIX=""
+CT_WANTS_STATIC_LINK=y
+CT_WANTS_STATIC_LINK_CXX=y
+# CT_STATIC_TOOLCHAIN is not set
+CT_SHOW_CT_VERSION=y
+CT_TOOLCHAIN_PKGVERSION=""
+CT_TOOLCHAIN_BUGURL=""
+
+#
+# Tuple completion and aliasing
+#
+CT_TARGET_VENDOR="unknown"
+CT_TARGET_ALIAS_SED_EXPR=""
+CT_TARGET_ALIAS=""
+
+#
+# Toolchain type
+#
+# CT_NATIVE is not set
+CT_CROSS=y
+# CT_CROSS_NATIVE is not set
+# CT_CANADIAN is not set
+CT_TOOLCHAIN_TYPE="cross"
+
+#
+# Build system
+#
+CT_BUILD=""
+CT_BUILD_PREFIX=""
+CT_BUILD_SUFFIX=""
+
+#
+# Misc options
+#
+# CT_TOOLCHAIN_ENABLE_NLS is not set
+
+#
+# Operating System
+#
+CT_KERNEL_SUPPORTS_SHARED_LIBS=y
+# CT_KERNEL_BARE_METAL is not set
+CT_KERNEL_LINUX=y
+CT_KERNEL="linux"
+CT_KERNEL_CHOICE_KSYM="LINUX"
+CT_KERNEL_LINUX_SHOW=y
+
+#
+# Options for linux
+#
+CT_KERNEL_LINUX_PKG_KSYM="LINUX"
+CT_LINUX_DIR_NAME="linux"
+CT_LINUX_PKG_NAME="linux"
+CT_LINUX_SRC_RELEASE=y
+# CT_LINUX_SRC_DEVEL is not set
+# CT_LINUX_SRC_CUSTOM is not set
+CT_LINUX_PATCH_GLOBAL=y
+# CT_LINUX_PATCH_BUNDLED is not set
+# CT_LINUX_PATCH_LOCAL is not set
+# CT_LINUX_PATCH_BUNDLED_LOCAL is not set
+# CT_LINUX_PATCH_LOCAL_BUNDLED is not set
+# CT_LINUX_PATCH_NONE is not set
+CT_LINUX_PATCH_ORDER="global"
+CT_LINUX_V_4_20=y
+# CT_LINUX_V_4_19 is not set
+# CT_LINUX_V_4_18 is not set
+# CT_LINUX_V_4_17 is not set
+# CT_LINUX_V_4_16 is not set
+# CT_LINUX_V_4_15 is not set
+# CT_LINUX_V_4_14 is not set
+# CT_LINUX_V_4_13 is not set
+# CT_LINUX_V_4_12 is not set
+# CT_LINUX_V_4_11 is not set
+# CT_LINUX_V_4_10 is not set
+# CT_LINUX_V_4_9 is not set
+# CT_LINUX_V_4_4 is not set
+# CT_LINUX_V_4_1 is not set
+# CT_LINUX_V_3_16 is not set
+# CT_LINUX_V_3_13 is not set
+# CT_LINUX_V_3_12 is not set
+# CT_LINUX_V_3_10 is not set
+# CT_LINUX_V_3_4 is not set
+# CT_LINUX_V_3_2 is not set
+# CT_LINUX_NO_VERSIONS is not set
+CT_LINUX_VERSION="4.20.8"
+CT_LINUX_MIRRORS="$(CT_Mirrors kernel.org linux ${CT_LINUX_VERSION})"
+CT_LINUX_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_LINUX_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_LINUX_ARCHIVE_FORMATS=".tar.xz .tar.gz"
+CT_LINUX_SIGNATURE_FORMAT="unpacked/.sign"
+CT_LINUX_later_than_4_8=y
+CT_LINUX_4_8_or_later=y
+CT_LINUX_later_than_3_7=y
+CT_LINUX_3_7_or_later=y
+CT_LINUX_later_than_3_2=y
+CT_LINUX_3_2_or_later=y
+CT_LINUX_REQUIRE_3_2_or_later=y
+CT_KERNEL_LINUX_VERBOSITY_0=y
+# CT_KERNEL_LINUX_VERBOSITY_1 is not set
+# CT_KERNEL_LINUX_VERBOSITY_2 is not set
+CT_KERNEL_LINUX_VERBOSE_LEVEL=0
+CT_KERNEL_LINUX_INSTALL_CHECK=y
+CT_ALL_KERNEL_CHOICES="BARE_METAL LINUX WINDOWS"
+
+#
+# Common kernel options
+#
+CT_SHARED_LIBS=y
+
+#
+# Binary utilities
+#
+CT_ARCH_BINFMT_ELF=y
+CT_BINUTILS_BINUTILS=y
+CT_BINUTILS="binutils"
+CT_BINUTILS_CHOICE_KSYM="BINUTILS"
+CT_BINUTILS_BINUTILS_SHOW=y
+
+#
+# Options for binutils
+#
+CT_BINUTILS_BINUTILS_PKG_KSYM="BINUTILS"
+CT_BINUTILS_DIR_NAME="binutils"
+CT_BINUTILS_USE_GNU=y
+CT_BINUTILS_USE="BINUTILS"
+CT_BINUTILS_PKG_NAME="binutils"
+CT_BINUTILS_SRC_RELEASE=y
+# CT_BINUTILS_SRC_DEVEL is not set
+# CT_BINUTILS_SRC_CUSTOM is not set
+CT_BINUTILS_PATCH_GLOBAL=y
+# CT_BINUTILS_PATCH_BUNDLED is not set
+# CT_BINUTILS_PATCH_LOCAL is not set
+# CT_BINUTILS_PATCH_BUNDLED_LOCAL is not set
+# CT_BINUTILS_PATCH_LOCAL_BUNDLED is not set
+# CT_BINUTILS_PATCH_NONE is not set
+CT_BINUTILS_PATCH_ORDER="global"
+CT_BINUTILS_V_2_32=y
+# CT_BINUTILS_V_2_31 is not set
+# CT_BINUTILS_V_2_30 is not set
+# CT_BINUTILS_V_2_29 is not set
+# CT_BINUTILS_V_2_28 is not set
+# CT_BINUTILS_V_2_27 is not set
+# CT_BINUTILS_V_2_26 is not set
+# CT_BINUTILS_NO_VERSIONS is not set
+CT_BINUTILS_VERSION="2.32"
+CT_BINUTILS_MIRRORS="$(CT_Mirrors GNU binutils) $(CT_Mirrors sourceware binutils/releases)"
+CT_BINUTILS_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_BINUTILS_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_BINUTILS_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz"
+CT_BINUTILS_SIGNATURE_FORMAT="packed/.sig"
+CT_BINUTILS_later_than_2_30=y
+CT_BINUTILS_2_30_or_later=y
+CT_BINUTILS_later_than_2_27=y
+CT_BINUTILS_2_27_or_later=y
+CT_BINUTILS_later_than_2_25=y
+CT_BINUTILS_2_25_or_later=y
+CT_BINUTILS_REQUIRE_2_25_or_later=y
+CT_BINUTILS_later_than_2_23=y
+CT_BINUTILS_2_23_or_later=y
+
+#
+# GNU binutils
+#
+CT_BINUTILS_HAS_HASH_STYLE=y
+CT_BINUTILS_HAS_GOLD=y
+CT_BINUTILS_HAS_PLUGINS=y
+CT_BINUTILS_HAS_PKGVERSION_BUGURL=y
+CT_BINUTILS_FORCE_LD_BFD_DEFAULT=y
+CT_BINUTILS_LINKER_LD=y
+CT_BINUTILS_LINKERS_LIST="ld"
+CT_BINUTILS_LINKER_DEFAULT="bfd"
+# CT_BINUTILS_PLUGINS is not set
+CT_BINUTILS_RELRO=m
+CT_BINUTILS_EXTRA_CONFIG_ARRAY=""
+# CT_BINUTILS_FOR_TARGET is not set
+CT_ALL_BINUTILS_CHOICES="BINUTILS"
+
+#
+# C-library
+#
+CT_LIBC_GLIBC=y
+# CT_LIBC_MUSL is not set
+# CT_LIBC_UCLIBC is not set
+CT_LIBC="glibc"
+CT_LIBC_CHOICE_KSYM="GLIBC"
+CT_THREADS="nptl"
+CT_LIBC_GLIBC_SHOW=y
+
+#
+# Options for glibc
+#
+CT_LIBC_GLIBC_PKG_KSYM="GLIBC"
+CT_GLIBC_DIR_NAME="glibc"
+CT_GLIBC_USE_GNU=y
+CT_GLIBC_USE="GLIBC"
+CT_GLIBC_PKG_NAME="glibc"
+CT_GLIBC_SRC_RELEASE=y
+# CT_GLIBC_SRC_DEVEL is not set
+# CT_GLIBC_SRC_CUSTOM is not set
+CT_GLIBC_PATCH_GLOBAL=y
+# CT_GLIBC_PATCH_BUNDLED is not set
+# CT_GLIBC_PATCH_LOCAL is not set
+# CT_GLIBC_PATCH_BUNDLED_LOCAL is not set
+# CT_GLIBC_PATCH_LOCAL_BUNDLED is not set
+# CT_GLIBC_PATCH_NONE is not set
+CT_GLIBC_PATCH_ORDER="global"
+CT_GLIBC_V_2_29=y
+# CT_GLIBC_NO_VERSIONS is not set
+CT_GLIBC_VERSION="2.29"
+CT_GLIBC_MIRRORS="$(CT_Mirrors GNU glibc)"
+CT_GLIBC_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_GLIBC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_GLIBC_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz"
+CT_GLIBC_SIGNATURE_FORMAT="packed/.sig"
+CT_GLIBC_2_29_or_later=y
+CT_GLIBC_2_29_or_older=y
+CT_GLIBC_REQUIRE_2_29_or_later=y
+CT_GLIBC_later_than_2_27=y
+CT_GLIBC_2_27_or_later=y
+CT_GLIBC_later_than_2_26=y
+CT_GLIBC_2_26_or_later=y
+CT_GLIBC_later_than_2_25=y
+CT_GLIBC_2_25_or_later=y
+CT_GLIBC_later_than_2_24=y
+CT_GLIBC_2_24_or_later=y
+CT_GLIBC_later_than_2_23=y
+CT_GLIBC_2_23_or_later=y
+CT_GLIBC_later_than_2_20=y
+CT_GLIBC_2_20_or_later=y
+CT_GLIBC_later_than_2_17=y
+CT_GLIBC_2_17_or_later=y
+CT_GLIBC_later_than_2_14=y
+CT_GLIBC_2_14_or_later=y
+CT_GLIBC_DEP_KERNEL_HEADERS_VERSION=y
+CT_GLIBC_DEP_BINUTILS=y
+CT_GLIBC_DEP_GCC=y
+CT_GLIBC_DEP_PYTHON=y
+CT_GLIBC_BUILD_SSP=y
+CT_GLIBC_HAS_LIBIDN_ADDON=y
+# CT_GLIBC_USE_LIBIDN_ADDON is not set
+CT_GLIBC_NO_SPARC_V8=y
+CT_GLIBC_HAS_OBSOLETE_RPC=y
+CT_GLIBC_EXTRA_CONFIG_ARRAY=""
+CT_GLIBC_CONFIGPARMS=""
+CT_GLIBC_EXTRA_CFLAGS=""
+CT_GLIBC_ENABLE_OBSOLETE_RPC=y
+# CT_GLIBC_ENABLE_FORTIFIED_BUILD is not set
+# CT_GLIBC_DISABLE_VERSIONING is not set
+CT_GLIBC_OLDEST_ABI=""
+CT_GLIBC_FORCE_UNWIND=y
+# CT_GLIBC_LOCALES is not set
+CT_GLIBC_KERNEL_VERSION_NONE=y
+# CT_GLIBC_KERNEL_VERSION_AS_HEADERS is not set
+# CT_GLIBC_KERNEL_VERSION_CHOSEN is not set
+CT_GLIBC_MIN_KERNEL=""
+CT_GLIBC_SSP_DEFAULT=y
+# CT_GLIBC_SSP_NO is not set
+# CT_GLIBC_SSP_YES is not set
+# CT_GLIBC_SSP_ALL is not set
+# CT_GLIBC_SSP_STRONG is not set
+# CT_GLIBC_ENABLE_WERROR is not set
+CT_ALL_LIBC_CHOICES="AVR_LIBC BIONIC GLIBC MINGW_W64 MOXIEBOX MUSL NEWLIB NONE UCLIBC"
+CT_LIBC_SUPPORT_THREADS_ANY=y
+CT_LIBC_SUPPORT_THREADS_NATIVE=y
+
+#
+# Common C library options
+#
+CT_THREADS_NATIVE=y
+# CT_CREATE_LDSO_CONF is not set
+CT_LIBC_XLDD=y
+
+#
+# C compiler
+#
+CT_CC_CORE_PASSES_NEEDED=y
+CT_CC_CORE_PASS_1_NEEDED=y
+CT_CC_CORE_PASS_2_NEEDED=y
+CT_CC_SUPPORT_CXX=y
+CT_CC_SUPPORT_FORTRAN=y
+CT_CC_SUPPORT_ADA=y
+CT_CC_SUPPORT_OBJC=y
+CT_CC_SUPPORT_OBJCXX=y
+CT_CC_SUPPORT_GOLANG=y
+CT_CC_GCC=y
+CT_CC="gcc"
+CT_CC_CHOICE_KSYM="GCC"
+CT_CC_GCC_SHOW=y
+
+#
+# Options for gcc
+#
+CT_CC_GCC_PKG_KSYM="GCC"
+CT_GCC_DIR_NAME="gcc"
+CT_GCC_USE_GNU=y
+# CT_GCC_USE_LINARO is not set
+CT_GCC_USE="GCC"
+CT_GCC_PKG_NAME="gcc"
+CT_GCC_SRC_RELEASE=y
+# CT_GCC_SRC_DEVEL is not set
+# CT_GCC_SRC_CUSTOM is not set
+CT_GCC_PATCH_GLOBAL=y
+# CT_GCC_PATCH_BUNDLED is not set
+# CT_GCC_PATCH_LOCAL is not set
+# CT_GCC_PATCH_BUNDLED_LOCAL is not set
+# CT_GCC_PATCH_LOCAL_BUNDLED is not set
+# CT_GCC_PATCH_NONE is not set
+CT_GCC_PATCH_ORDER="global"
+CT_GCC_V_8=y
+# CT_GCC_V_7 is not set
+# CT_GCC_NO_VERSIONS is not set
+CT_GCC_VERSION="8.3.0"
+CT_GCC_MIRRORS="$(CT_Mirrors GNU gcc/gcc-${CT_GCC_VERSION}) $(CT_Mirrors sourceware gcc/releases/gcc-${CT_GCC_VERSION})"
+CT_GCC_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_GCC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_GCC_ARCHIVE_FORMATS=".tar.xz .tar.gz"
+CT_GCC_SIGNATURE_FORMAT=""
+CT_GCC_later_than_7=y
+CT_GCC_7_or_later=y
+CT_GCC_REQUIRE_7_or_later=y
+CT_GCC_later_than_6=y
+CT_GCC_6_or_later=y
+CT_GCC_later_than_5=y
+CT_GCC_5_or_later=y
+CT_GCC_REQUIRE_5_or_later=y
+CT_GCC_later_than_4_9=y
+CT_GCC_4_9_or_later=y
+CT_GCC_REQUIRE_4_9_or_later=y
+CT_GCC_later_than_4_8=y
+CT_GCC_4_8_or_later=y
+CT_CC_GCC_HAS_LIBMPX=y
+CT_CC_GCC_ENABLE_CXX_FLAGS=""
+CT_CC_GCC_CORE_EXTRA_CONFIG_ARRAY=""
+CT_CC_GCC_EXTRA_CONFIG_ARRAY=""
+CT_CC_GCC_STATIC_LIBSTDCXX=y
+# CT_CC_GCC_SYSTEM_ZLIB is not set
+CT_CC_GCC_CONFIG_TLS=m
+
+#
+# Optimisation features
+#
+CT_CC_GCC_USE_GRAPHITE=y
+CT_CC_GCC_USE_LTO=y
+
+#
+# Settings for libraries running on target
+#
+CT_CC_GCC_ENABLE_TARGET_OPTSPACE=y
+# CT_CC_GCC_LIBMUDFLAP is not set
+# CT_CC_GCC_LIBGOMP is not set
+# CT_CC_GCC_LIBSSP is not set
+# CT_CC_GCC_LIBQUADMATH is not set
+# CT_CC_GCC_LIBSANITIZER is not set
+
+#
+# Misc. obscure options.
+#
+CT_CC_CXA_ATEXIT=y
+# CT_CC_GCC_DISABLE_PCH is not set
+CT_CC_GCC_SJLJ_EXCEPTIONS=m
+CT_CC_GCC_LDBL_128=m
+# CT_CC_GCC_BUILD_ID is not set
+CT_CC_GCC_LNK_HASH_STYLE_DEFAULT=y
+# CT_CC_GCC_LNK_HASH_STYLE_SYSV is not set
+# CT_CC_GCC_LNK_HASH_STYLE_GNU is not set
+# CT_CC_GCC_LNK_HASH_STYLE_BOTH is not set
+CT_CC_GCC_LNK_HASH_STYLE=""
+CT_CC_GCC_DEC_FLOAT_AUTO=y
+# CT_CC_GCC_DEC_FLOAT_BID is not set
+# CT_CC_GCC_DEC_FLOAT_DPD is not set
+# CT_CC_GCC_DEC_FLOATS_NO is not set
+CT_ALL_CC_CHOICES="GCC"
+
+#
+# Additional supported languages:
+#
+CT_CC_LANG_CXX=y
+# CT_CC_LANG_FORTRAN is not set
+# CT_CC_LANG_ADA is not set
+# CT_CC_LANG_OBJC is not set
+# CT_CC_LANG_OBJCXX is not set
+# CT_CC_LANG_GOLANG is not set
+CT_CC_LANG_OTHERS=""
+
+#
+# Debug facilities
+#
+# CT_DEBUG_DUMA is not set
+CT_DEBUG_GDB=y
+CT_DEBUG_GDB_PKG_KSYM="GDB"
+CT_GDB_DIR_NAME="gdb"
+CT_GDB_USE_GNU=y
+CT_GDB_USE="GDB"
+CT_GDB_PKG_NAME="gdb"
+CT_GDB_SRC_RELEASE=y
+# CT_GDB_SRC_DEVEL is not set
+# CT_GDB_SRC_CUSTOM is not set
+CT_GDB_PATCH_GLOBAL=y
+# CT_GDB_PATCH_BUNDLED is not set
+# CT_GDB_PATCH_LOCAL is not set
+# CT_GDB_PATCH_BUNDLED_LOCAL is not set
+# CT_GDB_PATCH_LOCAL_BUNDLED is not set
+# CT_GDB_PATCH_NONE is not set
+CT_GDB_PATCH_ORDER="global"
+CT_GDB_V_8_2=y
+# CT_GDB_V_8_1 is not set
+# CT_GDB_V_8_0 is not set
+# CT_GDB_NO_VERSIONS is not set
+CT_GDB_VERSION="8.2.1"
+CT_GDB_MIRRORS="$(CT_Mirrors GNU gdb) $(CT_Mirrors sourceware gdb/releases)"
+CT_GDB_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_GDB_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_GDB_ARCHIVE_FORMATS=".tar.xz .tar.gz"
+CT_GDB_SIGNATURE_FORMAT=""
+CT_GDB_later_than_8_0=y
+CT_GDB_8_0_or_later=y
+CT_GDB_REQUIRE_8_0_or_later=y
+CT_GDB_later_than_7_12=y
+CT_GDB_7_12_or_later=y
+CT_GDB_later_than_7_2=y
+CT_GDB_7_2_or_later=y
+CT_GDB_later_than_7_0=y
+CT_GDB_7_0_or_later=y
+CT_GDB_CROSS=y
+# CT_GDB_CROSS_STATIC is not set
+# CT_GDB_CROSS_SIM is not set
+# CT_GDB_CROSS_PYTHON is not set
+CT_GDB_CROSS_EXTRA_CONFIG_ARRAY=""
+# CT_GDB_NATIVE is not set
+# CT_GDB_GDBSERVER is not set
+CT_GDB_HAS_PKGVERSION_BUGURL=y
+CT_GDB_HAS_PYTHON=y
+CT_GDB_INSTALL_GDBINIT=y
+CT_GDB_HAS_IPA_LIB=y
+# CT_DEBUG_LTRACE is not set
+# CT_DEBUG_STRACE is not set
+CT_ALL_DEBUG_CHOICES="DUMA GDB LTRACE STRACE"
+
+#
+# Companion libraries
+#
+# CT_COMPLIBS_CHECK is not set
+# CT_COMP_LIBS_CLOOG is not set
+CT_COMP_LIBS_EXPAT=y
+CT_COMP_LIBS_EXPAT_PKG_KSYM="EXPAT"
+CT_EXPAT_DIR_NAME="expat"
+CT_EXPAT_PKG_NAME="expat"
+CT_EXPAT_SRC_RELEASE=y
+# CT_EXPAT_SRC_DEVEL is not set
+# CT_EXPAT_SRC_CUSTOM is not set
+CT_EXPAT_PATCH_GLOBAL=y
+# CT_EXPAT_PATCH_BUNDLED is not set
+# CT_EXPAT_PATCH_LOCAL is not set
+# CT_EXPAT_PATCH_BUNDLED_LOCAL is not set
+# CT_EXPAT_PATCH_LOCAL_BUNDLED is not set
+# CT_EXPAT_PATCH_NONE is not set
+CT_EXPAT_PATCH_ORDER="global"
+CT_EXPAT_V_2_2=y
+# CT_EXPAT_NO_VERSIONS is not set
+CT_EXPAT_VERSION="2.2.6"
+CT_EXPAT_MIRRORS="http://downloads.sourceforge.net/project/expat/expat/${CT_EXPAT_VERSION}"
+CT_EXPAT_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_EXPAT_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_EXPAT_ARCHIVE_FORMATS=".tar.bz2"
+CT_EXPAT_SIGNATURE_FORMAT=""
+CT_COMP_LIBS_GETTEXT=y
+CT_COMP_LIBS_GETTEXT_PKG_KSYM="GETTEXT"
+CT_GETTEXT_DIR_NAME="gettext"
+CT_GETTEXT_PKG_NAME="gettext"
+CT_GETTEXT_SRC_RELEASE=y
+# CT_GETTEXT_SRC_DEVEL is not set
+# CT_GETTEXT_SRC_CUSTOM is not set
+CT_GETTEXT_PATCH_GLOBAL=y
+# CT_GETTEXT_PATCH_BUNDLED is not set
+# CT_GETTEXT_PATCH_LOCAL is not set
+# CT_GETTEXT_PATCH_BUNDLED_LOCAL is not set
+# CT_GETTEXT_PATCH_LOCAL_BUNDLED is not set
+# CT_GETTEXT_PATCH_NONE is not set
+CT_GETTEXT_PATCH_ORDER="global"
+CT_GETTEXT_V_0_19_8_1=y
+# CT_GETTEXT_NO_VERSIONS is not set
+CT_GETTEXT_VERSION="0.19.8.1"
+CT_GETTEXT_MIRRORS="$(CT_Mirrors GNU gettext)"
+CT_GETTEXT_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_GETTEXT_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_GETTEXT_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.gz"
+CT_GETTEXT_SIGNATURE_FORMAT="packed/.sig"
+CT_COMP_LIBS_GMP=y
+CT_COMP_LIBS_GMP_PKG_KSYM="GMP"
+CT_GMP_DIR_NAME="gmp"
+CT_GMP_PKG_NAME="gmp"
+CT_GMP_SRC_RELEASE=y
+# CT_GMP_SRC_DEVEL is not set
+# CT_GMP_SRC_CUSTOM is not set
+CT_GMP_PATCH_GLOBAL=y
+# CT_GMP_PATCH_BUNDLED is not set
+# CT_GMP_PATCH_LOCAL is not set
+# CT_GMP_PATCH_BUNDLED_LOCAL is not set
+# CT_GMP_PATCH_LOCAL_BUNDLED is not set
+# CT_GMP_PATCH_NONE is not set
+CT_GMP_PATCH_ORDER="global"
+CT_GMP_V_6_1=y
+# CT_GMP_NO_VERSIONS is not set
+CT_GMP_VERSION="6.1.2"
+CT_GMP_MIRRORS="https://gmplib.org/download/gmp https://gmplib.org/download/gmp/archive $(CT_Mirrors GNU gmp)"
+CT_GMP_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_GMP_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_GMP_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.bz2"
+CT_GMP_SIGNATURE_FORMAT="packed/.sig"
+CT_GMP_later_than_5_1_0=y
+CT_GMP_5_1_0_or_later=y
+CT_GMP_later_than_5_0_0=y
+CT_GMP_5_0_0_or_later=y
+CT_GMP_REQUIRE_5_0_0_or_later=y
+CT_COMP_LIBS_ISL=y
+CT_COMP_LIBS_ISL_PKG_KSYM="ISL"
+CT_ISL_DIR_NAME="isl"
+CT_ISL_PKG_NAME="isl"
+CT_ISL_SRC_RELEASE=y
+# CT_ISL_SRC_DEVEL is not set
+# CT_ISL_SRC_CUSTOM is not set
+CT_ISL_PATCH_GLOBAL=y
+# CT_ISL_PATCH_BUNDLED is not set
+# CT_ISL_PATCH_LOCAL is not set
+# CT_ISL_PATCH_BUNDLED_LOCAL is not set
+# CT_ISL_PATCH_LOCAL_BUNDLED is not set
+# CT_ISL_PATCH_NONE is not set
+CT_ISL_PATCH_ORDER="global"
+CT_ISL_V_0_20=y
+# CT_ISL_V_0_19 is not set
+# CT_ISL_V_0_18 is not set
+# CT_ISL_V_0_17 is not set
+# CT_ISL_V_0_16 is not set
+# CT_ISL_V_0_15 is not set
+# CT_ISL_NO_VERSIONS is not set
+CT_ISL_VERSION="0.20"
+CT_ISL_MIRRORS="http://isl.gforge.inria.fr"
+CT_ISL_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_ISL_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_ISL_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz"
+CT_ISL_SIGNATURE_FORMAT=""
+CT_ISL_later_than_0_18=y
+CT_ISL_0_18_or_later=y
+CT_ISL_later_than_0_15=y
+CT_ISL_0_15_or_later=y
+CT_ISL_REQUIRE_0_15_or_later=y
+CT_ISL_later_than_0_14=y
+CT_ISL_0_14_or_later=y
+CT_ISL_REQUIRE_0_14_or_later=y
+CT_ISL_later_than_0_13=y
+CT_ISL_0_13_or_later=y
+CT_ISL_later_than_0_12=y
+CT_ISL_0_12_or_later=y
+CT_ISL_REQUIRE_0_12_or_later=y
+# CT_COMP_LIBS_LIBELF is not set
+CT_COMP_LIBS_LIBICONV=y
+CT_COMP_LIBS_LIBICONV_PKG_KSYM="LIBICONV"
+CT_LIBICONV_DIR_NAME="libiconv"
+CT_LIBICONV_PKG_NAME="libiconv"
+CT_LIBICONV_SRC_RELEASE=y
+# CT_LIBICONV_SRC_DEVEL is not set
+# CT_LIBICONV_SRC_CUSTOM is not set
+CT_LIBICONV_PATCH_GLOBAL=y
+# CT_LIBICONV_PATCH_BUNDLED is not set
+# CT_LIBICONV_PATCH_LOCAL is not set
+# CT_LIBICONV_PATCH_BUNDLED_LOCAL is not set
+# CT_LIBICONV_PATCH_LOCAL_BUNDLED is not set
+# CT_LIBICONV_PATCH_NONE is not set
+CT_LIBICONV_PATCH_ORDER="global"
+CT_LIBICONV_V_1_15=y
+# CT_LIBICONV_NO_VERSIONS is not set
+CT_LIBICONV_VERSION="1.15"
+CT_LIBICONV_MIRRORS="$(CT_Mirrors GNU libiconv)"
+CT_LIBICONV_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_LIBICONV_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_LIBICONV_ARCHIVE_FORMATS=".tar.gz"
+CT_LIBICONV_SIGNATURE_FORMAT="packed/.sig"
+CT_COMP_LIBS_MPC=y
+CT_COMP_LIBS_MPC_PKG_KSYM="MPC"
+CT_MPC_DIR_NAME="mpc"
+CT_MPC_PKG_NAME="mpc"
+CT_MPC_SRC_RELEASE=y
+# CT_MPC_SRC_DEVEL is not set
+# CT_MPC_SRC_CUSTOM is not set
+CT_MPC_PATCH_GLOBAL=y
+# CT_MPC_PATCH_BUNDLED is not set
+# CT_MPC_PATCH_LOCAL is not set
+# CT_MPC_PATCH_BUNDLED_LOCAL is not set
+# CT_MPC_PATCH_LOCAL_BUNDLED is not set
+# CT_MPC_PATCH_NONE is not set
+CT_MPC_PATCH_ORDER="global"
+CT_MPC_V_1_1=y
+# CT_MPC_V_1_0 is not set
+# CT_MPC_NO_VERSIONS is not set
+CT_MPC_VERSION="1.1.0"
+CT_MPC_MIRRORS="http://www.multiprecision.org/downloads $(CT_Mirrors GNU mpc)"
+CT_MPC_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_MPC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_MPC_ARCHIVE_FORMATS=".tar.gz"
+CT_MPC_SIGNATURE_FORMAT="packed/.sig"
+CT_MPC_1_1_0_or_later=y
+CT_MPC_1_1_0_or_older=y
+CT_COMP_LIBS_MPFR=y
+CT_COMP_LIBS_MPFR_PKG_KSYM="MPFR"
+CT_MPFR_DIR_NAME="mpfr"
+CT_MPFR_PKG_NAME="mpfr"
+CT_MPFR_SRC_RELEASE=y
+# CT_MPFR_SRC_DEVEL is not set
+# CT_MPFR_SRC_CUSTOM is not set
+CT_MPFR_PATCH_GLOBAL=y
+# CT_MPFR_PATCH_BUNDLED is not set
+# CT_MPFR_PATCH_LOCAL is not set
+# CT_MPFR_PATCH_BUNDLED_LOCAL is not set
+# CT_MPFR_PATCH_LOCAL_BUNDLED is not set
+# CT_MPFR_PATCH_NONE is not set
+CT_MPFR_PATCH_ORDER="global"
+CT_MPFR_V_4_0=y
+# CT_MPFR_V_3_1 is not set
+# CT_MPFR_NO_VERSIONS is not set
+CT_MPFR_VERSION="4.0.2"
+CT_MPFR_MIRRORS="http://www.mpfr.org/mpfr-${CT_MPFR_VERSION} $(CT_Mirrors GNU mpfr)"
+CT_MPFR_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_MPFR_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_MPFR_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz .zip"
+CT_MPFR_SIGNATURE_FORMAT="packed/.asc"
+CT_MPFR_later_than_4_0_0=y
+CT_MPFR_4_0_0_or_later=y
+CT_MPFR_later_than_3_0_0=y
+CT_MPFR_3_0_0_or_later=y
+CT_MPFR_REQUIRE_3_0_0_or_later=y
+CT_COMP_LIBS_NCURSES=y
+CT_COMP_LIBS_NCURSES_PKG_KSYM="NCURSES"
+CT_NCURSES_DIR_NAME="ncurses"
+CT_NCURSES_PKG_NAME="ncurses"
+CT_NCURSES_SRC_RELEASE=y
+# CT_NCURSES_SRC_DEVEL is not set
+# CT_NCURSES_SRC_CUSTOM is not set
+CT_NCURSES_PATCH_GLOBAL=y
+# CT_NCURSES_PATCH_BUNDLED is not set
+# CT_NCURSES_PATCH_LOCAL is not set
+# CT_NCURSES_PATCH_BUNDLED_LOCAL is not set
+# CT_NCURSES_PATCH_LOCAL_BUNDLED is not set
+# CT_NCURSES_PATCH_NONE is not set
+CT_NCURSES_PATCH_ORDER="global"
+CT_NCURSES_V_6_1=y
+# CT_NCURSES_V_6_0 is not set
+# CT_NCURSES_NO_VERSIONS is not set
+CT_NCURSES_VERSION="6.1"
+CT_NCURSES_MIRRORS="ftp://invisible-island.net/ncurses $(CT_Mirrors GNU ncurses)"
+CT_NCURSES_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_NCURSES_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_NCURSES_ARCHIVE_FORMATS=".tar.gz"
+CT_NCURSES_SIGNATURE_FORMAT="packed/.sig"
+# CT_NCURSES_NEW_ABI is not set
+CT_NCURSES_HOST_CONFIG_ARGS=""
+CT_NCURSES_HOST_DISABLE_DB=y
+CT_NCURSES_HOST_FALLBACKS="linux,xterm,xterm-color,xterm-256color,vt100"
+CT_NCURSES_TARGET_CONFIG_ARGS=""
+# CT_NCURSES_TARGET_DISABLE_DB is not set
+CT_NCURSES_TARGET_FALLBACKS=""
+CT_COMP_LIBS_ZLIB=y
+CT_COMP_LIBS_ZLIB_PKG_KSYM="ZLIB"
+CT_ZLIB_DIR_NAME="zlib"
+CT_ZLIB_PKG_NAME="zlib"
+CT_ZLIB_SRC_RELEASE=y
+# CT_ZLIB_SRC_DEVEL is not set
+# CT_ZLIB_SRC_CUSTOM is not set
+CT_ZLIB_PATCH_GLOBAL=y
+# CT_ZLIB_PATCH_BUNDLED is not set
+# CT_ZLIB_PATCH_LOCAL is not set
+# CT_ZLIB_PATCH_BUNDLED_LOCAL is not set
+# CT_ZLIB_PATCH_LOCAL_BUNDLED is not set
+# CT_ZLIB_PATCH_NONE is not set
+CT_ZLIB_PATCH_ORDER="global"
+CT_ZLIB_V_1_2_11=y
+# CT_ZLIB_NO_VERSIONS is not set
+CT_ZLIB_VERSION="1.2.11"
+CT_ZLIB_MIRRORS="http://downloads.sourceforge.net/project/libpng/zlib/${CT_ZLIB_VERSION}"
+CT_ZLIB_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_ZLIB_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_ZLIB_ARCHIVE_FORMATS=".tar.xz .tar.gz"
+CT_ZLIB_SIGNATURE_FORMAT="packed/.asc"
+CT_ALL_COMP_LIBS_CHOICES="CLOOG EXPAT GETTEXT GMP ISL LIBELF LIBICONV MPC MPFR NCURSES ZLIB"
+CT_LIBICONV_NEEDED=y
+CT_GETTEXT_NEEDED=y
+CT_GMP_NEEDED=y
+CT_MPFR_NEEDED=y
+CT_ISL_NEEDED=y
+CT_MPC_NEEDED=y
+CT_EXPAT_NEEDED=y
+CT_NCURSES_NEEDED=y
+CT_ZLIB_NEEDED=y
+CT_LIBICONV=y
+CT_GETTEXT=y
+CT_GMP=y
+CT_MPFR=y
+CT_ISL=y
+CT_MPC=y
+CT_EXPAT=y
+CT_NCURSES=y
+CT_ZLIB=y
+
+#
+# Companion tools
+#
+# CT_COMP_TOOLS_FOR_HOST is not set
+# CT_COMP_TOOLS_AUTOCONF is not set
+# CT_COMP_TOOLS_AUTOMAKE is not set
+# CT_COMP_TOOLS_BISON is not set
+# CT_COMP_TOOLS_DTC is not set
+# CT_COMP_TOOLS_LIBTOOL is not set
+# CT_COMP_TOOLS_M4 is not set
+# CT_COMP_TOOLS_MAKE is not set
+CT_ALL_COMP_TOOLS_CHOICES="AUTOCONF AUTOMAKE BISON DTC LIBTOOL M4 MAKE"
+
+#
+# Test suite
+#
+# CT_TEST_SUITE_GCC is not set

From fcd850fc5db2501d14b2e0cbfac8aa890d700e55 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Thu, 9 Jan 2020 22:10:18 -0800
Subject: [PATCH 05/38] Do not ICE on unicode next point

Use `shrink_to_hi` instead of `next_point`
Fix #68000.
---
 src/librustc_parse/parser/item.rs               |  2 +-
 ...e-68000-unicode-ident-after-missing-comma.rs |  6 ++++++
 ...000-unicode-ident-after-missing-comma.stderr | 17 +++++++++++++++++
 3 files changed, 24 insertions(+), 1 deletion(-)
 create mode 100644 src/test/ui/issues/issue-68000-unicode-ident-after-missing-comma.rs
 create mode 100644 src/test/ui/issues/issue-68000-unicode-ident-after-missing-comma.stderr

diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs
index 918e826fc26bf..4cd3540ea6807 100644
--- a/src/librustc_parse/parser/item.rs
+++ b/src/librustc_parse/parser/item.rs
@@ -1489,7 +1489,7 @@ impl<'a> Parser<'a> {
                 }
             }
             _ => {
-                let sp = self.sess.source_map().next_point(self.prev_span);
+                let sp = self.prev_span.shrink_to_hi();
                 let mut err = self.struct_span_err(
                     sp,
                     &format!("expected `,`, or `}}`, found {}", super::token_descr(&self.token)),
diff --git a/src/test/ui/issues/issue-68000-unicode-ident-after-missing-comma.rs b/src/test/ui/issues/issue-68000-unicode-ident-after-missing-comma.rs
new file mode 100644
index 0000000000000..3c49a5a975209
--- /dev/null
+++ b/src/test/ui/issues/issue-68000-unicode-ident-after-missing-comma.rs
@@ -0,0 +1,6 @@
+pub struct Foo {
+    pub bar: Vec<i32>ö
+    //~^ ERROR expected `,`, or `}`, found `ö`
+} //~ ERROR expected `:`, found `}`
+
+fn main() {}
diff --git a/src/test/ui/issues/issue-68000-unicode-ident-after-missing-comma.stderr b/src/test/ui/issues/issue-68000-unicode-ident-after-missing-comma.stderr
new file mode 100644
index 0000000000000..ef365a616437b
--- /dev/null
+++ b/src/test/ui/issues/issue-68000-unicode-ident-after-missing-comma.stderr
@@ -0,0 +1,17 @@
+error: expected `,`, or `}`, found `ö`
+  --> $DIR/issue-68000-unicode-ident-after-missing-comma.rs:2:22
+   |
+LL |     pub bar: Vec<i32>ö
+   |                      ^ help: try adding a comma: `,`
+
+error: expected `:`, found `}`
+  --> $DIR/issue-68000-unicode-ident-after-missing-comma.rs:4:1
+   |
+LL |     pub bar: Vec<i32>ö
+   |                       - expected `:`
+LL |
+LL | }
+   | ^ unexpected token
+
+error: aborting due to 2 previous errors
+

From 0bbbd5d418f764146afdde3460c170db205ba0fa Mon Sep 17 00:00:00 2001
From: Matthew Healy <matthew.healy@soundcloud.com>
Date: Thu, 9 Jan 2020 22:51:38 +0100
Subject: [PATCH 06/38] Match llvm-skip-rebuild flag

---
 src/bootstrap/flags.rs | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs
index 813e89eef38ce..1fbdd50a51133 100644
--- a/src/bootstrap/flags.rs
+++ b/src/bootstrap/flags.rs
@@ -38,6 +38,8 @@ pub struct Flags {
     //
     // true => deny, false => warn
     pub deny_warnings: Option<bool>,
+
+    pub llvm_skip_rebuild: Option<bool>,
 }
 
 pub enum Subcommand {
@@ -495,6 +497,9 @@ Arguments:
                 .map(|p| p.into())
                 .collect::<Vec<_>>(),
             deny_warnings: parse_deny_warnings(&matches),
+            llvm_skip_rebuild: matches.opt_str("llvm-skip-rebuild").map(|s| s.to_lowercase()).map(
+                |s| s.parse::<bool>().expect("`llvm-skip-rebuild` should be either true or false"),
+            ),
         }
     }
 }

From 7e50b599bfeb75f7be1d5a1fa855e37ec6d0e65d Mon Sep 17 00:00:00 2001
From: Matthew Healy <matthew.healy@soundcloud.com>
Date: Thu, 9 Jan 2020 23:13:57 +0100
Subject: [PATCH 07/38] Prefer llvm-skip-rebuild flag value over config.toml

---
 src/bootstrap/config.rs | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index 944df66431fe8..110c8b844d54c 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -493,9 +493,13 @@ impl Config {
             config.mandir = install.mandir.clone().map(PathBuf::from);
         }
 
+        // We want the llvm-skip-rebuild flag to take precedence over the
+        // skip-rebuild config.toml option so we store it separately
+        // so that we can infer the right value
+        let mut llvm_skip_rebuild = flags.llvm_skip_rebuild;
+
         // Store off these values as options because if they're not provided
         // we'll infer default values for them later
-        let mut llvm_skip_rebuild = None;
         let mut llvm_assertions = None;
         let mut debug = None;
         let mut debug_assertions = None;
@@ -517,7 +521,7 @@ impl Config {
             }
             set(&mut config.ninja, llvm.ninja);
             llvm_assertions = llvm.assertions;
-            llvm_skip_rebuild = llvm.skip_rebuild;
+            llvm_skip_rebuild = llvm_skip_rebuild.or(llvm.skip_rebuild);
             set(&mut config.llvm_optimize, llvm.optimize);
             set(&mut config.llvm_thin_lto, llvm.thin_lto);
             set(&mut config.llvm_release_debuginfo, llvm.release_debuginfo);

From 8ca55641fd80ac51971997f903358fa579209d71 Mon Sep 17 00:00:00 2001
From: varkor <github@varkor.com>
Date: Fri, 10 Jan 2020 13:31:36 +0000
Subject: [PATCH 08/38] Clarify suggestion for E0013

---
 src/librustc_mir/transform/check_consts/ops.rs       | 12 +++++++-----
 .../ui/consts/const-fn-not-safe-for-const.stderr     |  8 ++++++--
 .../ui/issues/issue-17718-const-bad-values.stderr    |  8 ++++++--
 src/test/ui/issues/issue-17718-references.stderr     | 12 +++++++++---
 src/test/ui/issues/issue-18118-2.rs                  |  3 +--
 src/test/ui/issues/issue-18118-2.stderr              |  4 +++-
 src/test/ui/issues/issue-52060.stderr                |  4 +++-
 7 files changed, 35 insertions(+), 16 deletions(-)

diff --git a/src/librustc_mir/transform/check_consts/ops.rs b/src/librustc_mir/transform/check_consts/ops.rs
index abef008a8eccb..e418809282750 100644
--- a/src/librustc_mir/transform/check_consts/ops.rs
+++ b/src/librustc_mir/transform/check_consts/ops.rs
@@ -350,16 +350,18 @@ impl NonConstOp for StaticAccess {
             item.tcx.sess,
             span,
             E0013,
-            "{}s cannot refer to statics, use \
-                                        a constant instead",
+            "{}s cannot refer to statics",
             item.const_kind()
         );
+        err.help(
+            "consider extracting the value of the `static` to a `const`, and referring to that",
+        );
         if item.tcx.sess.teach(&err.get_code().unwrap()) {
             err.note(
-                "Static and const variables can refer to other const variables. \
-                    But a const variable cannot refer to a static variable.",
+                "`static` and `const` variables can refer to other `const` variables. \
+                    A `const` variable, however, cannot refer to a `static` variable.",
             );
-            err.help("To fix this, the value can be extracted as a const and then used.");
+            err.help("To fix this, the value can be extracted to a `const` and then used.");
         }
         err.emit();
     }
diff --git a/src/test/ui/consts/const-fn-not-safe-for-const.stderr b/src/test/ui/consts/const-fn-not-safe-for-const.stderr
index 2d4175ea8eb7d..df793d7dd7ec9 100644
--- a/src/test/ui/consts/const-fn-not-safe-for-const.stderr
+++ b/src/test/ui/consts/const-fn-not-safe-for-const.stderr
@@ -4,17 +4,21 @@ error[E0015]: calls in constant functions are limited to constant functions, tup
 LL |     random()
    |     ^^^^^^^^
 
-error[E0013]: constant functions cannot refer to statics, use a constant instead
+error[E0013]: constant functions cannot refer to statics
   --> $DIR/const-fn-not-safe-for-const.rs:20:5
    |
 LL |     Y
    |     ^
+   |
+   = help: consider extracting the value of the `static` to a `const`, and referring to that
 
-error[E0013]: constant functions cannot refer to statics, use a constant instead
+error[E0013]: constant functions cannot refer to statics
   --> $DIR/const-fn-not-safe-for-const.rs:25:6
    |
 LL |     &Y
    |      ^
+   |
+   = help: consider extracting the value of the `static` to a `const`, and referring to that
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/issues/issue-17718-const-bad-values.stderr b/src/test/ui/issues/issue-17718-const-bad-values.stderr
index 14bf5dc38b47a..e45d8b6c740e0 100644
--- a/src/test/ui/issues/issue-17718-const-bad-values.stderr
+++ b/src/test/ui/issues/issue-17718-const-bad-values.stderr
@@ -7,17 +7,21 @@ LL | const C1: &'static mut [usize] = &mut [];
    = note: for more information, see https://github.com/rust-lang/rust/issues/57349
    = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
 
-error[E0013]: constants cannot refer to statics, use a constant instead
+error[E0013]: constants cannot refer to statics
   --> $DIR/issue-17718-const-bad-values.rs:5:46
    |
 LL | const C2: &'static mut usize = unsafe { &mut S };
    |                                              ^
+   |
+   = help: consider extracting the value of the `static` to a `const`, and referring to that
 
-error[E0013]: constants cannot refer to statics, use a constant instead
+error[E0013]: constants cannot refer to statics
   --> $DIR/issue-17718-const-bad-values.rs:5:46
    |
 LL | const C2: &'static mut usize = unsafe { &mut S };
    |                                              ^
+   |
+   = help: consider extracting the value of the `static` to a `const`, and referring to that
 
 error[E0658]: references in constants may only refer to immutable values
   --> $DIR/issue-17718-const-bad-values.rs:5:41
diff --git a/src/test/ui/issues/issue-17718-references.stderr b/src/test/ui/issues/issue-17718-references.stderr
index 27aad9c03cebe..e3c3b369ffb32 100644
--- a/src/test/ui/issues/issue-17718-references.stderr
+++ b/src/test/ui/issues/issue-17718-references.stderr
@@ -1,20 +1,26 @@
-error[E0013]: constants cannot refer to statics, use a constant instead
+error[E0013]: constants cannot refer to statics
   --> $DIR/issue-17718-references.rs:9:29
    |
 LL | const T2: &'static usize = &S;
    |                             ^
+   |
+   = help: consider extracting the value of the `static` to a `const`, and referring to that
 
-error[E0013]: constants cannot refer to statics, use a constant instead
+error[E0013]: constants cannot refer to statics
   --> $DIR/issue-17718-references.rs:14:19
    |
 LL | const T6: usize = S;
    |                   ^
+   |
+   = help: consider extracting the value of the `static` to a `const`, and referring to that
 
-error[E0013]: constants cannot refer to statics, use a constant instead
+error[E0013]: constants cannot refer to statics
   --> $DIR/issue-17718-references.rs:19:33
    |
 LL | const T10: Struct = Struct { a: S };
    |                                 ^
+   |
+   = help: consider extracting the value of the `static` to a `const`, and referring to that
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/issues/issue-18118-2.rs b/src/test/ui/issues/issue-18118-2.rs
index 6d52156b3d2de..f712a2eedb7e9 100644
--- a/src/test/ui/issues/issue-18118-2.rs
+++ b/src/test/ui/issues/issue-18118-2.rs
@@ -1,7 +1,6 @@
 pub fn main() {
     const z: &'static isize = {
         static p: isize = 3;
-        &p
-        //~^ ERROR constants cannot refer to statics, use a constant instead
+        &p //~ ERROR constants cannot refer to statics
     };
 }
diff --git a/src/test/ui/issues/issue-18118-2.stderr b/src/test/ui/issues/issue-18118-2.stderr
index d58822f16eb35..4fc3ca78f961c 100644
--- a/src/test/ui/issues/issue-18118-2.stderr
+++ b/src/test/ui/issues/issue-18118-2.stderr
@@ -1,8 +1,10 @@
-error[E0013]: constants cannot refer to statics, use a constant instead
+error[E0013]: constants cannot refer to statics
   --> $DIR/issue-18118-2.rs:4:10
    |
 LL |         &p
    |          ^
+   |
+   = help: consider extracting the value of the `static` to a `const`, and referring to that
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-52060.stderr b/src/test/ui/issues/issue-52060.stderr
index c69145c1fe833..502825e9766e3 100644
--- a/src/test/ui/issues/issue-52060.stderr
+++ b/src/test/ui/issues/issue-52060.stderr
@@ -1,8 +1,10 @@
-error[E0013]: constants cannot refer to statics, use a constant instead
+error[E0013]: constants cannot refer to statics
   --> $DIR/issue-52060.rs:4:26
    |
 LL | static B: [u32; 1] = [0; A.len()];
    |                          ^
+   |
+   = help: consider extracting the value of the `static` to a `const`, and referring to that
 
 error[E0080]: evaluation of constant value failed
   --> $DIR/issue-52060.rs:4:26

From 137a31d6923f229ffb5ed78772d02ecda3c7c53c Mon Sep 17 00:00:00 2001
From: Lzu Tao <taolzu@gmail.com>
Date: Fri, 10 Jan 2020 18:20:40 +0000
Subject: [PATCH 09/38] Inline to make OsStr::is_empty zero cost

---
 src/libstd/ffi/os_str.rs              | 1 +
 src/libstd/sys_common/os_str_bytes.rs | 1 +
 2 files changed, 2 insertions(+)

diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs
index 4c308327b83b7..ec2d07f34ca5f 100644
--- a/src/libstd/ffi/os_str.rs
+++ b/src/libstd/ffi/os_str.rs
@@ -615,6 +615,7 @@ impl OsStr {
     /// assert!(!os_str.is_empty());
     /// ```
     #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
+    #[inline]
     pub fn is_empty(&self) -> bool {
         self.inner.inner.is_empty()
     }
diff --git a/src/libstd/sys_common/os_str_bytes.rs b/src/libstd/sys_common/os_str_bytes.rs
index eb8a881ec8881..e965ea79aa039 100644
--- a/src/libstd/sys_common/os_str_bytes.rs
+++ b/src/libstd/sys_common/os_str_bytes.rs
@@ -104,6 +104,7 @@ impl Buf {
         self.inner.shrink_to(min_capacity)
     }
 
+    #[inline]
     pub fn as_slice(&self) -> &Slice {
         unsafe { mem::transmute(&*self.inner) }
     }

From eca1e8bd9beeaabbc240ad342892f26998ad7f35 Mon Sep 17 00:00:00 2001
From: Lzu Tao <taolzu@gmail.com>
Date: Fri, 10 Jan 2020 18:48:15 +0000
Subject: [PATCH 10/38] Inline PathBuf::deref to make it zero cost

---
 src/libstd/path.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/libstd/path.rs b/src/libstd/path.rs
index fbbdc1ddac297..f00ef26930921 100644
--- a/src/libstd/path.rs
+++ b/src/libstd/path.rs
@@ -1535,7 +1535,7 @@ impl fmt::Debug for PathBuf {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl ops::Deref for PathBuf {
     type Target = Path;
-
+    #[inline]
     fn deref(&self) -> &Path {
         Path::new(&self.inner)
     }

From ea6bb7fe17395545a8f22563ed831ac5d2b4389f Mon Sep 17 00:00:00 2001
From: Lzu Tao <taolzu@gmail.com>
Date: Fri, 10 Jan 2020 18:56:30 +0000
Subject: [PATCH 11/38] Inline `AsRef<Path> for str`

---
 src/libstd/path.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/libstd/path.rs b/src/libstd/path.rs
index f00ef26930921..7ea642942dd74 100644
--- a/src/libstd/path.rs
+++ b/src/libstd/path.rs
@@ -2655,6 +2655,7 @@ impl AsRef<Path> for OsString {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl AsRef<Path> for str {
+    #[inline]
     fn as_ref(&self) -> &Path {
         Path::new(self)
     }

From bf1d20c4b60c20a780e8d98882e24b0e48b1a33d Mon Sep 17 00:00:00 2001
From: Lzu Tao <taolzu@gmail.com>
Date: Fri, 10 Jan 2020 19:02:14 +0000
Subject: [PATCH 12/38] Inline `impl From<OsString> for PathBuf`

---
 src/libstd/path.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/libstd/path.rs b/src/libstd/path.rs
index 7ea642942dd74..a09300ffe956f 100644
--- a/src/libstd/path.rs
+++ b/src/libstd/path.rs
@@ -1475,6 +1475,7 @@ impl From<OsString> for PathBuf {
     /// Converts a `OsString` into a `PathBuf`
     ///
     /// This conversion does not allocate or copy memory.
+    #[inline]
     fn from(s: OsString) -> PathBuf {
         PathBuf { inner: s }
     }

From 3250057da983fa4d5bfd0799adaa41cb038f0e25 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Fri, 10 Jan 2020 11:02:47 -0800
Subject: [PATCH 13/38] Fix `next_point` to be unicode aware

---
 src/librustc_span/source_map.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/librustc_span/source_map.rs b/src/librustc_span/source_map.rs
index ec1f9f3a7bdaf..fb5fcf4a8303b 100644
--- a/src/librustc_span/source_map.rs
+++ b/src/librustc_span/source_map.rs
@@ -710,7 +710,7 @@ impl SourceMap {
     pub fn next_point(&self, sp: Span) -> Span {
         let start_of_next_point = sp.hi().0;
 
-        let width = self.find_width_of_character_at_span(sp, true);
+        let width = self.find_width_of_character_at_span(sp.shrink_to_hi(), true);
         // If the width is 1, then the next span should point to the same `lo` and `hi`. However,
         // in the case of a multibyte character, where the width != 1, the next span should
         // span multiple bytes to include the whole character.

From d558f6a570a782cd1c2e54de790f4f968b0de5f1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Fri, 10 Jan 2020 11:03:26 -0800
Subject: [PATCH 14/38] Fix invalid bounding box

---
 src/librustc_errors/lib.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index 99a6d6f8ec2d4..e24e8719133a9 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -182,7 +182,7 @@ impl CodeSuggestion {
 
                 // Find the bounding span.
                 let lo = substitution.parts.iter().map(|part| part.span.lo()).min().unwrap();
-                let hi = substitution.parts.iter().map(|part| part.span.hi()).min().unwrap();
+                let hi = substitution.parts.iter().map(|part| part.span.hi()).max().unwrap();
                 let bounding_span = Span::with_root_ctxt(lo, hi);
                 let lines = cm.span_to_lines(bounding_span).unwrap();
                 assert!(!lines.lines.is_empty());

From cd5ab974808732a7f1b6923a54cf8a75dff1599e Mon Sep 17 00:00:00 2001
From: Lzu Tao <taolzu@gmail.com>
Date: Fri, 10 Jan 2020 19:06:18 +0000
Subject: [PATCH 15/38] inline `impl AsRef<OsStr> for OsString`

---
 src/libstd/ffi/os_str.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs
index ec2d07f34ca5f..77da97219b147 100644
--- a/src/libstd/ffi/os_str.rs
+++ b/src/libstd/ffi/os_str.rs
@@ -966,6 +966,7 @@ impl AsRef<OsStr> for OsStr {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl AsRef<OsStr> for OsString {
+    #[inline]
     fn as_ref(&self) -> &OsStr {
         self
     }

From 76e698fc56473702ce2db81296b45c5fd267485e Mon Sep 17 00:00:00 2001
From: Lzu Tao <taolzu@gmail.com>
Date: Fri, 10 Jan 2020 19:18:17 +0000
Subject: [PATCH 16/38] inline `impl AsRef<Path> for PathBuf`

---
 src/libstd/path.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/libstd/path.rs b/src/libstd/path.rs
index a09300ffe956f..a703cb748e06b 100644
--- a/src/libstd/path.rs
+++ b/src/libstd/path.rs
@@ -2671,6 +2671,7 @@ impl AsRef<Path> for String {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl AsRef<Path> for PathBuf {
+    #[inline]
     fn as_ref(&self) -> &Path {
         self
     }

From b93ef68245807bac97cd17ea9eaa13169380d815 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Fri, 10 Jan 2020 11:22:33 -0800
Subject: [PATCH 17/38] Change `next_point` when `shrink_to_hi` is more
 appropriate

---
 src/librustc_builtin_macros/assert.rs    |  2 +-
 src/librustc_expand/mbe/macro_parser.rs  |  2 +-
 src/librustc_parse/parser/diagnostics.rs | 11 ++++-------
 src/librustc_parse/parser/expr.rs        |  2 +-
 src/librustc_parse/parser/item.rs        |  4 ++--
 src/librustc_parse/parser/mod.rs         |  2 +-
 src/librustc_typeck/check/callee.rs      |  5 ++---
 src/librustc_typeck/check/mod.rs         |  3 +--
 8 files changed, 13 insertions(+), 18 deletions(-)

diff --git a/src/librustc_builtin_macros/assert.rs b/src/librustc_builtin_macros/assert.rs
index 9043db4742bf7..b76b496666e88 100644
--- a/src/librustc_builtin_macros/assert.rs
+++ b/src/librustc_builtin_macros/assert.rs
@@ -106,7 +106,7 @@ fn parse_assert<'a>(
     let custom_message =
         if let token::Literal(token::Lit { kind: token::Str, .. }) = parser.token.kind {
             let mut err = cx.struct_span_warn(parser.token.span, "unexpected string literal");
-            let comma_span = cx.source_map().next_point(parser.prev_span);
+            let comma_span = parser.prev_span.shrink_to_hi();
             err.span_suggestion_short(
                 comma_span,
                 "try adding a comma",
diff --git a/src/librustc_expand/mbe/macro_parser.rs b/src/librustc_expand/mbe/macro_parser.rs
index c0e34a30c54e9..d0aae300b1c9d 100644
--- a/src/librustc_expand/mbe/macro_parser.rs
+++ b/src/librustc_expand/mbe/macro_parser.rs
@@ -696,7 +696,7 @@ pub(super) fn parse(
                         if parser.token.span.is_dummy() {
                             parser.token.span
                         } else {
-                            sess.source_map().next_point(parser.token.span)
+                            parser.token.span.shrink_to_hi()
                         },
                     ),
                     "missing tokens in macro arguments",
diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs
index 9abfbc698c5cf..b9658b33d0fef 100644
--- a/src/librustc_parse/parser/diagnostics.rs
+++ b/src/librustc_parse/parser/diagnostics.rs
@@ -265,10 +265,7 @@ impl<'a> Parser<'a> {
             };
             (
                 format!("expected one of {}, found {}", expect, actual),
-                (
-                    self.sess.source_map().next_point(self.prev_span),
-                    format!("expected one of {}", short_expect),
-                ),
+                (self.prev_span.shrink_to_hi(), format!("expected one of {}", short_expect)),
             )
         } else if expected.is_empty() {
             (
@@ -278,7 +275,7 @@ impl<'a> Parser<'a> {
         } else {
             (
                 format!("expected {}, found {}", expect, actual),
-                (self.sess.source_map().next_point(self.prev_span), format!("expected {}", expect)),
+                (self.prev_span.shrink_to_hi(), format!("expected {}", expect)),
             )
         };
         self.last_unexpected_token_span = Some(self.token.span);
@@ -809,7 +806,7 @@ impl<'a> Parser<'a> {
             _ if self.prev_span == DUMMY_SP => (self.token.span, self.token.span),
             // EOF, don't want to point at the following char, but rather the last token.
             (token::Eof, None) => (self.prev_span, self.token.span),
-            _ => (self.sess.source_map().next_point(self.prev_span), self.token.span),
+            _ => (self.prev_span.shrink_to_hi(), self.token.span),
         };
         let msg = format!(
             "expected `{}`, found {}",
@@ -1132,7 +1129,7 @@ impl<'a> Parser<'a> {
                     err.span_label(sp, "unclosed delimiter");
                 }
                 err.span_suggestion_short(
-                    self.sess.source_map().next_point(self.prev_span),
+                    self.prev_span.shrink_to_hi(),
                     &format!("{} may belong here", delim.to_string()),
                     delim.to_string(),
                     Applicability::MaybeIncorrect,
diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs
index 90f15375aec42..f02ea117c0646 100644
--- a/src/librustc_parse/parser/expr.rs
+++ b/src/librustc_parse/parser/expr.rs
@@ -1646,7 +1646,7 @@ impl<'a> Parser<'a> {
                             //   |      |
                             //   |      parsed until here as `"y" & X`
                             err.span_suggestion_short(
-                                cm.next_point(arm_start_span),
+                                arm_start_span.shrink_to_hi(),
                                 "missing a comma here to end this `match` arm",
                                 ",".to_owned(),
                                 Applicability::MachineApplicable,
diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs
index 4cd3540ea6807..fdc01dc930d96 100644
--- a/src/librustc_parse/parser/item.rs
+++ b/src/librustc_parse/parser/item.rs
@@ -1628,7 +1628,7 @@ impl<'a> Parser<'a> {
             // it's safe to peel off one character only when it has the close delim
             self.prev_span.with_lo(self.prev_span.hi() - BytePos(1))
         } else {
-            self.sess.source_map().next_point(self.prev_span)
+            self.prev_span.shrink_to_hi()
         };
 
         self.struct_span_err(
@@ -1644,7 +1644,7 @@ impl<'a> Parser<'a> {
             Applicability::MaybeIncorrect,
         )
         .span_suggestion(
-            self.sess.source_map().next_point(self.prev_span),
+            self.prev_span.shrink_to_hi(),
             "add a semicolon",
             ';'.to_string(),
             Applicability::MaybeIncorrect,
diff --git a/src/librustc_parse/parser/mod.rs b/src/librustc_parse/parser/mod.rs
index 8d695eda98d04..a1035d320b31c 100644
--- a/src/librustc_parse/parser/mod.rs
+++ b/src/librustc_parse/parser/mod.rs
@@ -765,7 +765,7 @@ impl<'a> Parser<'a> {
                             break;
                         }
                         Err(mut expect_err) => {
-                            let sp = self.sess.source_map().next_point(self.prev_span);
+                            let sp = self.prev_span.shrink_to_hi();
                             let token_str = pprust::token_kind_to_string(t);
 
                             // Attempt to keep parsing if it was a similar separator.
diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs
index a1915bc025f79..918542e7da5ff 100644
--- a/src/librustc_typeck/check/callee.rs
+++ b/src/librustc_typeck/check/callee.rs
@@ -242,7 +242,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         ) = (parent_node, callee_node)
         {
             let start = sp.shrink_to_lo();
-            let end = self.tcx.sess.source_map().next_point(callee_span);
+            let end = callee_span.shrink_to_hi();
             err.multipart_suggestion(
                 "if you meant to create this closure and immediately call it, surround the \
                 closure with parenthesis",
@@ -319,9 +319,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             let call_is_multiline =
                                 self.tcx.sess.source_map().is_multiline(call_expr.span);
                             if call_is_multiline {
-                                let span = self.tcx.sess.source_map().next_point(callee.span);
                                 err.span_suggestion(
-                                    span,
+                                    callee.span.shrink_to_hi(),
                                     "try adding a semicolon",
                                     ";".to_owned(),
                                     Applicability::MaybeIncorrect,
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index f10edc1a468b4..94c9a704c65df 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -4953,9 +4953,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 | ExprKind::Loop(..)
                 | ExprKind::Match(..)
                 | ExprKind::Block(..) => {
-                    let sp = self.tcx.sess.source_map().next_point(cause_span);
                     err.span_suggestion(
-                        sp,
+                        cause_span.shrink_to_hi(),
                         "try adding a semicolon",
                         ";".to_string(),
                         Applicability::MachineApplicable,

From f6e9fd037a7b55f8f4fe78694b77d9788b18dfeb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Fri, 10 Jan 2020 11:22:57 -0800
Subject: [PATCH 18/38] Add ICE regression tests

---
 .../issue-68091-unicode-ident-after-if.rs      |  9 +++++++++
 .../issue-68091-unicode-ident-after-if.stderr  | 18 ++++++++++++++++++
 ...8092-unicode-ident-after-incomplete-expr.rs |  9 +++++++++
 ...-unicode-ident-after-incomplete-expr.stderr |  8 ++++++++
 4 files changed, 44 insertions(+)
 create mode 100644 src/test/ui/issues/issue-68091-unicode-ident-after-if.rs
 create mode 100644 src/test/ui/issues/issue-68091-unicode-ident-after-if.stderr
 create mode 100644 src/test/ui/issues/issue-68092-unicode-ident-after-incomplete-expr.rs
 create mode 100644 src/test/ui/issues/issue-68092-unicode-ident-after-incomplete-expr.stderr

diff --git a/src/test/ui/issues/issue-68091-unicode-ident-after-if.rs b/src/test/ui/issues/issue-68091-unicode-ident-after-if.rs
new file mode 100644
index 0000000000000..00f90cc73b344
--- /dev/null
+++ b/src/test/ui/issues/issue-68091-unicode-ident-after-if.rs
@@ -0,0 +1,9 @@
+macro_rules! x {
+    ($($c:tt)*) => {
+        $($c)ö* {} //~ ERROR missing condition for `if` expression
+    };             //~| ERROR mismatched types
+}
+
+fn main() {
+    x!(if);
+}
diff --git a/src/test/ui/issues/issue-68091-unicode-ident-after-if.stderr b/src/test/ui/issues/issue-68091-unicode-ident-after-if.stderr
new file mode 100644
index 0000000000000..8d1a03ac207e1
--- /dev/null
+++ b/src/test/ui/issues/issue-68091-unicode-ident-after-if.stderr
@@ -0,0 +1,18 @@
+error: missing condition for `if` expression
+  --> $DIR/issue-68091-unicode-ident-after-if.rs:3:14
+   |
+LL |         $($c)ö* {}
+   |              ^ expected if condition here
+
+error[E0308]: mismatched types
+  --> $DIR/issue-68091-unicode-ident-after-if.rs:3:17
+   |
+LL |         $($c)ö* {}
+   |                 ^^ expected `bool`, found `()`
+...
+LL |     x!(if);
+   |     ------- in this macro invocation
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/issues/issue-68092-unicode-ident-after-incomplete-expr.rs b/src/test/ui/issues/issue-68092-unicode-ident-after-incomplete-expr.rs
new file mode 100644
index 0000000000000..1a90b4724d49d
--- /dev/null
+++ b/src/test/ui/issues/issue-68092-unicode-ident-after-incomplete-expr.rs
@@ -0,0 +1,9 @@
+macro_rules! x {
+    ($($c:tt)*) => {
+        $($c)ö* //~ ERROR macro expansion ends with an incomplete expression: expected expression
+    };
+}
+
+fn main() {
+    x!(!);
+}
diff --git a/src/test/ui/issues/issue-68092-unicode-ident-after-incomplete-expr.stderr b/src/test/ui/issues/issue-68092-unicode-ident-after-incomplete-expr.stderr
new file mode 100644
index 0000000000000..0b9c364f1f1fb
--- /dev/null
+++ b/src/test/ui/issues/issue-68092-unicode-ident-after-incomplete-expr.stderr
@@ -0,0 +1,8 @@
+error: macro expansion ends with an incomplete expression: expected expression
+  --> $DIR/issue-68092-unicode-ident-after-incomplete-expr.rs:3:14
+   |
+LL |         $($c)ö*
+   |              ^ expected expression
+
+error: aborting due to previous error
+

From 5f3f1a3606a5f13177a1634ba80d6386e5132518 Mon Sep 17 00:00:00 2001
From: Lzu Tao <taolzu@gmail.com>
Date: Fri, 10 Jan 2020 19:27:02 +0000
Subject: [PATCH 19/38] inline `impl From<String> for Box<dyn Error + Send +
 Sync>`

---
 src/libstd/error.rs | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/libstd/error.rs b/src/libstd/error.rs
index 1407fe2771553..b480581e21ba9 100644
--- a/src/libstd/error.rs
+++ b/src/libstd/error.rs
@@ -250,6 +250,7 @@ impl From<String> for Box<dyn Error + Send + Sync> {
     /// assert!(
     ///     mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
     /// ```
+    #[inline]
     fn from(err: String) -> Box<dyn Error + Send + Sync> {
         struct StringError(String);
 
@@ -317,6 +318,7 @@ impl<'a> From<&str> for Box<dyn Error + Send + Sync + 'a> {
     /// assert!(
     ///     mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
     /// ```
+    #[inline]
     fn from(err: &str) -> Box<dyn Error + Send + Sync + 'a> {
         From::from(String::from(err))
     }

From 799efd3615f468c1382c61fe73b137fcffcd0a78 Mon Sep 17 00:00:00 2001
From: varkor <github@varkor.com>
Date: Fri, 10 Jan 2020 22:29:57 +0000
Subject: [PATCH 20/38] Fix issue with using `self` module via indirection

---
 src/librustc_privacy/lib.rs       | 3 +++
 src/test/ui/issues/issue-68103.rs | 6 ++++++
 2 files changed, 9 insertions(+)
 create mode 100644 src/test/ui/issues/issue-68103.rs

diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index a96d59340237d..70d4841ec244b 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -652,6 +652,9 @@ impl EmbargoVisitor<'tcx> {
             if let Some(item) = module
                 .res
                 .and_then(|res| res.mod_def_id())
+                // If the module is `self`, i.e. the current crate,
+                // there will be no corresponding item.
+                .filter(|def_id| def_id.index != CRATE_DEF_INDEX || def_id.krate != LOCAL_CRATE)
                 .and_then(|def_id| self.tcx.hir().as_local_hir_id(def_id))
                 .map(|module_hir_id| self.tcx.hir().expect_item(module_hir_id))
             {
diff --git a/src/test/ui/issues/issue-68103.rs b/src/test/ui/issues/issue-68103.rs
new file mode 100644
index 0000000000000..e775678fc6053
--- /dev/null
+++ b/src/test/ui/issues/issue-68103.rs
@@ -0,0 +1,6 @@
+// check-pass
+
+pub extern crate self as name;
+pub use name::name as bug;
+
+fn main() {}

From 6007641d2101e6489aa6b9a3ba84b6a2b9b04fa5 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Thu, 2 Jan 2020 11:41:57 +0100
Subject: [PATCH 21/38] gating diagnostics -> rustc_session::parse

---
 Cargo.lock                          |  1 +
 src/librustc_session/Cargo.toml     |  1 +
 src/librustc_session/parse.rs       | 72 ++++++++++++++++++++++++++--
 src/libsyntax/attr/builtin.rs       |  3 +-
 src/libsyntax/feature_gate/check.rs | 73 ++---------------------------
 src/libsyntax/lib.rs                |  3 +-
 6 files changed, 77 insertions(+), 76 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 339389f8569e0..6116ae033875e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3866,6 +3866,7 @@ dependencies = [
  "log",
  "num_cpus",
  "rustc_data_structures",
+ "rustc_error_codes",
  "rustc_errors",
  "rustc_feature",
  "rustc_fs_util",
diff --git a/src/librustc_session/Cargo.toml b/src/librustc_session/Cargo.toml
index 47c23bc4dcf98..377ea141ed57c 100644
--- a/src/librustc_session/Cargo.toml
+++ b/src/librustc_session/Cargo.toml
@@ -10,6 +10,7 @@ path = "lib.rs"
 
 [dependencies]
 log = "0.4"
+rustc_error_codes = { path = "../librustc_error_codes" }
 rustc_errors = { path = "../librustc_errors" }
 rustc_feature = { path = "../librustc_feature" }
 rustc_target = { path = "../librustc_target" }
diff --git a/src/librustc_session/parse.rs b/src/librustc_session/parse.rs
index 6cc6a1ec276ca..2a5945d2b0595 100644
--- a/src/librustc_session/parse.rs
+++ b/src/librustc_session/parse.rs
@@ -6,10 +6,10 @@ use crate::node_id::NodeId;
 
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::sync::{Lock, Lrc, Once};
-use rustc_errors::{
-    emitter::SilentEmitter, Applicability, ColorConfig, DiagnosticBuilder, Handler,
-};
-use rustc_feature::UnstableFeatures;
+use rustc_error_codes::E0658;
+use rustc_errors::{emitter::SilentEmitter, ColorConfig, Handler};
+use rustc_errors::{error_code, Applicability, DiagnosticBuilder};
+use rustc_feature::{find_feature_issue, GateIssue, UnstableFeatures};
 use rustc_span::edition::Edition;
 use rustc_span::hygiene::ExpnId;
 use rustc_span::source_map::{FilePathMapping, SourceMap};
@@ -62,6 +62,70 @@ impl GatedSpans {
     }
 }
 
+#[derive(Debug, Copy, Clone, PartialEq)]
+pub enum GateStrength {
+    /// A hard error. (Most feature gates should use this.)
+    Hard,
+    /// Only a warning. (Use this only as backwards-compatibility demands.)
+    Soft,
+}
+
+pub fn feature_err<'a>(
+    sess: &'a ParseSess,
+    feature: Symbol,
+    span: impl Into<MultiSpan>,
+    explain: &str,
+) -> DiagnosticBuilder<'a> {
+    feature_err_issue(sess, feature, span, GateIssue::Language, explain)
+}
+
+pub fn feature_err_issue<'a>(
+    sess: &'a ParseSess,
+    feature: Symbol,
+    span: impl Into<MultiSpan>,
+    issue: GateIssue,
+    explain: &str,
+) -> DiagnosticBuilder<'a> {
+    leveled_feature_err(sess, feature, span, issue, explain, GateStrength::Hard)
+}
+
+pub fn leveled_feature_err<'a>(
+    sess: &'a ParseSess,
+    feature: Symbol,
+    span: impl Into<MultiSpan>,
+    issue: GateIssue,
+    explain: &str,
+    level: GateStrength,
+) -> DiagnosticBuilder<'a> {
+    let diag = &sess.span_diagnostic;
+
+    let mut err = match level {
+        GateStrength::Hard => diag.struct_span_err_with_code(span, explain, error_code!(E0658)),
+        GateStrength::Soft => diag.struct_span_warn(span, explain),
+    };
+
+    if let Some(n) = find_feature_issue(feature, issue) {
+        err.note(&format!(
+            "for more information, see https://github.com/rust-lang/rust/issues/{}",
+            n,
+        ));
+    }
+
+    // #23973: do not suggest `#![feature(...)]` if we are in beta/stable
+    if sess.unstable_features.is_nightly_build() {
+        err.help(&format!("add `#![feature({})]` to the crate attributes to enable", feature));
+    }
+
+    // If we're on stable and only emitting a "soft" warning, add a note to
+    // clarify that the feature isn't "on" (rather than being on but
+    // warning-worthy).
+    if !sess.unstable_features.is_nightly_build() && level == GateStrength::Soft {
+        err.help("a nightly build of the compiler is required to enable this feature");
+    }
+
+    err
+}
+
 /// Info about a parsing session.
 pub struct ParseSess {
     pub span_diagnostic: Handler,
diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs
index 958e4373cc0ed..70f4f47621a34 100644
--- a/src/libsyntax/attr/builtin.rs
+++ b/src/libsyntax/attr/builtin.rs
@@ -2,9 +2,8 @@
 
 use super::{mark_used, MetaItemKind};
 use crate::ast::{self, Attribute, MetaItem, NestedMetaItem};
-use crate::feature_gate::feature_err;
 use crate::print::pprust;
-use crate::sess::ParseSess;
+use crate::sess::{feature_err, ParseSess};
 
 use rustc_errors::{struct_span_err, Applicability, Handler};
 use rustc_feature::{find_gated_cfg, is_builtin_attr_name, Features, GatedCfg};
diff --git a/src/libsyntax/feature_gate/check.rs b/src/libsyntax/feature_gate/check.rs
index 4eee4e943c2cd..2b49a296a082a 100644
--- a/src/libsyntax/feature_gate/check.rs
+++ b/src/libsyntax/feature_gate/check.rs
@@ -1,22 +1,21 @@
 use crate::ast::{self, AssocTyConstraint, AssocTyConstraintKind, NodeId};
 use crate::ast::{GenericParam, GenericParamKind, PatKind, RangeEnd, VariantData};
 use crate::attr;
-use crate::sess::ParseSess;
+use crate::sess::{feature_err, leveled_feature_err, GateStrength, ParseSess};
 use crate::visit::{self, FnKind, Visitor};
 
 use rustc_data_structures::fx::FxHashMap;
 use rustc_error_codes::*;
-use rustc_errors::{error_code, struct_span_err, Applicability, DiagnosticBuilder, Handler};
-use rustc_feature::{find_feature_issue, GateIssue};
+use rustc_errors::{error_code, struct_span_err, Applicability, Handler};
 use rustc_feature::{AttributeGate, BUILTIN_ATTRIBUTE_MAP};
-use rustc_feature::{Feature, Features, State as FeatureState, UnstableFeatures};
+use rustc_feature::{Feature, Features, GateIssue, State as FeatureState, UnstableFeatures};
 use rustc_feature::{
     ACCEPTED_FEATURES, ACTIVE_FEATURES, REMOVED_FEATURES, STABLE_REMOVED_FEATURES,
 };
 use rustc_span::edition::{Edition, ALL_EDITIONS};
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::{sym, Symbol};
-use rustc_span::{MultiSpan, Span, DUMMY_SP};
+use rustc_span::{Span, DUMMY_SP};
 
 use log::debug;
 
@@ -53,70 +52,6 @@ pub fn check_attribute(attr: &ast::Attribute, parse_sess: &ParseSess, features:
     PostExpansionVisitor { parse_sess, features }.visit_attribute(attr)
 }
 
-#[derive(Debug, Copy, Clone, PartialEq)]
-pub enum GateStrength {
-    /// A hard error. (Most feature gates should use this.)
-    Hard,
-    /// Only a warning. (Use this only as backwards-compatibility demands.)
-    Soft,
-}
-
-pub fn feature_err<'a>(
-    sess: &'a ParseSess,
-    feature: Symbol,
-    span: impl Into<MultiSpan>,
-    explain: &str,
-) -> DiagnosticBuilder<'a> {
-    feature_err_issue(sess, feature, span, GateIssue::Language, explain)
-}
-
-pub fn feature_err_issue<'a>(
-    sess: &'a ParseSess,
-    feature: Symbol,
-    span: impl Into<MultiSpan>,
-    issue: GateIssue,
-    explain: &str,
-) -> DiagnosticBuilder<'a> {
-    leveled_feature_err(sess, feature, span, issue, explain, GateStrength::Hard)
-}
-
-fn leveled_feature_err<'a>(
-    sess: &'a ParseSess,
-    feature: Symbol,
-    span: impl Into<MultiSpan>,
-    issue: GateIssue,
-    explain: &str,
-    level: GateStrength,
-) -> DiagnosticBuilder<'a> {
-    let diag = &sess.span_diagnostic;
-
-    let mut err = match level {
-        GateStrength::Hard => diag.struct_span_err_with_code(span, explain, error_code!(E0658)),
-        GateStrength::Soft => diag.struct_span_warn(span, explain),
-    };
-
-    if let Some(n) = find_feature_issue(feature, issue) {
-        err.note(&format!(
-            "for more information, see https://github.com/rust-lang/rust/issues/{}",
-            n,
-        ));
-    }
-
-    // #23973: do not suggest `#![feature(...)]` if we are in beta/stable
-    if sess.unstable_features.is_nightly_build() {
-        err.help(&format!("add `#![feature({})]` to the crate attributes to enable", feature));
-    }
-
-    // If we're on stable and only emitting a "soft" warning, add a note to
-    // clarify that the feature isn't "on" (rather than being on but
-    // warning-worthy).
-    if !sess.unstable_features.is_nightly_build() && level == GateStrength::Soft {
-        err.help("a nightly build of the compiler is required to enable this feature");
-    }
-
-    err
-}
-
 struct PostExpansionVisitor<'a> {
     parse_sess: &'a ParseSess,
     features: &'a Features,
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index 7ee4ca4603c9c..ffb0d7e7f9706 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -77,7 +77,8 @@ pub mod entry;
 pub mod expand;
 pub mod feature_gate {
     mod check;
-    pub use check::{check_attribute, check_crate, feature_err, feature_err_issue, get_features};
+    pub use check::{check_attribute, check_crate, get_features};
+    pub use rustc_session::parse::{feature_err, feature_err_issue};
 }
 pub mod mut_visit;
 pub mod ptr;

From c944e6aac197ef37d4554fcc416dcff7ec4085c4 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Thu, 2 Jan 2020 11:55:00 +0100
Subject: [PATCH 22/38] document feature_err et. al

---
 src/librustc_session/parse.rs | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/src/librustc_session/parse.rs b/src/librustc_session/parse.rs
index 2a5945d2b0595..b0c6aefc00ca1 100644
--- a/src/librustc_session/parse.rs
+++ b/src/librustc_session/parse.rs
@@ -62,6 +62,8 @@ impl GatedSpans {
     }
 }
 
+/// The strenght of a feature gate.
+/// Either it is a `Hard` error, or only a `Soft` warning.
 #[derive(Debug, Copy, Clone, PartialEq)]
 pub enum GateStrength {
     /// A hard error. (Most feature gates should use this.)
@@ -70,6 +72,20 @@ pub enum GateStrength {
     Soft,
 }
 
+/// Construct a diagnostic for a language feature error due to the given `span`.
+/// The `feature`'s `Symbol` is the one you used in `active.rs` and `rustc_span::symbols`.
+///
+/// Example usage:
+///
+/// ```ignore
+/// feature_err(
+///     parse_sess,
+///     sym::stmt_expr_attributes,
+///     attr.span,
+///     "attributes on expressions are unstable",
+/// )
+/// .emit();
+/// ```
 pub fn feature_err<'a>(
     sess: &'a ParseSess,
     feature: Symbol,
@@ -79,6 +95,10 @@ pub fn feature_err<'a>(
     feature_err_issue(sess, feature, span, GateIssue::Language, explain)
 }
 
+/// Construct a diagnostic for a feature gate error.
+///
+/// This variant allows you to control whether it is a library or language feature.
+/// Almost always, you want to use this for a language feature. If so, prefer `feature_err`.
 pub fn feature_err_issue<'a>(
     sess: &'a ParseSess,
     feature: Symbol,
@@ -89,6 +109,9 @@ pub fn feature_err_issue<'a>(
     leveled_feature_err(sess, feature, span, issue, explain, GateStrength::Hard)
 }
 
+/// Construct a diagnostic for a feature gate error / warning.
+///
+/// You should typically just use `feature_err` instead.
 pub fn leveled_feature_err<'a>(
     sess: &'a ParseSess,
     feature: Symbol,

From 7c78090690cf78b453cf828babd3dd69eb276779 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Thu, 2 Jan 2020 12:33:56 +0100
Subject: [PATCH 23/38] get_features -> rustc_parse::config

---
 src/librustc_parse/config.rs        | 183 +++++++++++++++++++++++++++-
 src/libsyntax/feature_gate/check.rs | 175 +-------------------------
 src/libsyntax/lib.rs                |   2 +-
 3 files changed, 182 insertions(+), 178 deletions(-)

diff --git a/src/librustc_parse/config.rs b/src/librustc_parse/config.rs
index f2ffd9470ed76..df1e62d04d66d 100644
--- a/src/librustc_parse/config.rs
+++ b/src/librustc_parse/config.rs
@@ -9,15 +9,20 @@
 //! [#64197]: https://github.com/rust-lang/rust/issues/64197
 
 use crate::{parse_in, validate_attr};
-use rustc_errors::Applicability;
-use rustc_feature::Features;
-use rustc_span::edition::Edition;
-use rustc_span::symbol::sym;
-use rustc_span::Span;
+use rustc_data_structures::fx::FxHashMap;
+use rustc_error_codes::*;
+use rustc_errors::{error_code, struct_span_err, Applicability, Handler};
+use rustc_feature::{Feature, Features, State as FeatureState};
+use rustc_feature::{
+    ACCEPTED_FEATURES, ACTIVE_FEATURES, REMOVED_FEATURES, STABLE_REMOVED_FEATURES,
+};
+use rustc_span::edition::{Edition, ALL_EDITIONS};
+use rustc_span::symbol::{sym, Symbol};
+use rustc_span::{Span, DUMMY_SP};
 use syntax::ast::{self, AttrItem, Attribute, MetaItem};
 use syntax::attr;
 use syntax::attr::HasAttrs;
-use syntax::feature_gate::{feature_err, get_features};
+use syntax::feature_gate::feature_err;
 use syntax::mut_visit::*;
 use syntax::ptr::P;
 use syntax::sess::ParseSess;
@@ -31,6 +36,172 @@ pub struct StripUnconfigured<'a> {
     pub features: Option<&'a Features>,
 }
 
+fn get_features(
+    span_handler: &Handler,
+    krate_attrs: &[ast::Attribute],
+    crate_edition: Edition,
+    allow_features: &Option<Vec<String>>,
+) -> Features {
+    fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) {
+        let mut err = struct_span_err!(span_handler, span, E0557, "feature has been removed");
+        err.span_label(span, "feature has been removed");
+        if let Some(reason) = reason {
+            err.note(reason);
+        }
+        err.emit();
+    }
+
+    fn active_features_up_to(edition: Edition) -> impl Iterator<Item = &'static Feature> {
+        ACTIVE_FEATURES.iter().filter(move |feature| {
+            if let Some(feature_edition) = feature.edition {
+                feature_edition <= edition
+            } else {
+                false
+            }
+        })
+    }
+
+    let mut features = Features::default();
+    let mut edition_enabled_features = FxHashMap::default();
+
+    for &edition in ALL_EDITIONS {
+        if edition <= crate_edition {
+            // The `crate_edition` implies its respective umbrella feature-gate
+            // (i.e., `#![feature(rust_20XX_preview)]` isn't needed on edition 20XX).
+            edition_enabled_features.insert(edition.feature_name(), edition);
+        }
+    }
+
+    for feature in active_features_up_to(crate_edition) {
+        feature.set(&mut features, DUMMY_SP);
+        edition_enabled_features.insert(feature.name, crate_edition);
+    }
+
+    // Process the edition umbrella feature-gates first, to ensure
+    // `edition_enabled_features` is completed before it's queried.
+    for attr in krate_attrs {
+        if !attr.check_name(sym::feature) {
+            continue;
+        }
+
+        let list = match attr.meta_item_list() {
+            Some(list) => list,
+            None => continue,
+        };
+
+        for mi in list {
+            if !mi.is_word() {
+                continue;
+            }
+
+            let name = mi.name_or_empty();
+
+            let edition = ALL_EDITIONS.iter().find(|e| name == e.feature_name()).copied();
+            if let Some(edition) = edition {
+                if edition <= crate_edition {
+                    continue;
+                }
+
+                for feature in active_features_up_to(edition) {
+                    // FIXME(Manishearth) there is currently no way to set
+                    // lib features by edition
+                    feature.set(&mut features, DUMMY_SP);
+                    edition_enabled_features.insert(feature.name, edition);
+                }
+            }
+        }
+    }
+
+    for attr in krate_attrs {
+        if !attr.check_name(sym::feature) {
+            continue;
+        }
+
+        let list = match attr.meta_item_list() {
+            Some(list) => list,
+            None => continue,
+        };
+
+        let bad_input = |span| {
+            struct_span_err!(span_handler, span, E0556, "malformed `feature` attribute input")
+        };
+
+        for mi in list {
+            let name = match mi.ident() {
+                Some(ident) if mi.is_word() => ident.name,
+                Some(ident) => {
+                    bad_input(mi.span())
+                        .span_suggestion(
+                            mi.span(),
+                            "expected just one word",
+                            format!("{}", ident.name),
+                            Applicability::MaybeIncorrect,
+                        )
+                        .emit();
+                    continue;
+                }
+                None => {
+                    bad_input(mi.span()).span_label(mi.span(), "expected just one word").emit();
+                    continue;
+                }
+            };
+
+            if let Some(edition) = edition_enabled_features.get(&name) {
+                let msg =
+                    &format!("the feature `{}` is included in the Rust {} edition", name, edition);
+                span_handler.struct_span_warn_with_code(mi.span(), msg, error_code!(E0705)).emit();
+                continue;
+            }
+
+            if ALL_EDITIONS.iter().any(|e| name == e.feature_name()) {
+                // Handled in the separate loop above.
+                continue;
+            }
+
+            let removed = REMOVED_FEATURES.iter().find(|f| name == f.name);
+            let stable_removed = STABLE_REMOVED_FEATURES.iter().find(|f| name == f.name);
+            if let Some(Feature { state, .. }) = removed.or(stable_removed) {
+                if let FeatureState::Removed { reason } | FeatureState::Stabilized { reason } =
+                    state
+                {
+                    feature_removed(span_handler, mi.span(), *reason);
+                    continue;
+                }
+            }
+
+            if let Some(Feature { since, .. }) = ACCEPTED_FEATURES.iter().find(|f| name == f.name) {
+                let since = Some(Symbol::intern(since));
+                features.declared_lang_features.push((name, mi.span(), since));
+                continue;
+            }
+
+            if let Some(allowed) = allow_features.as_ref() {
+                if allowed.iter().find(|&f| name.as_str() == *f).is_none() {
+                    struct_span_err!(
+                        span_handler,
+                        mi.span(),
+                        E0725,
+                        "the feature `{}` is not in the list of allowed features",
+                        name
+                    )
+                    .emit();
+                    continue;
+                }
+            }
+
+            if let Some(f) = ACTIVE_FEATURES.iter().find(|f| name == f.name) {
+                f.set(&mut features, mi.span());
+                features.declared_lang_features.push((name, mi.span(), None));
+                continue;
+            }
+
+            features.declared_lib_features.push((name, mi.span()));
+        }
+    }
+
+    features
+}
+
 // `cfg_attr`-process the crate's attributes and compute the crate's features.
 pub fn features(
     mut krate: ast::Crate,
diff --git a/src/libsyntax/feature_gate/check.rs b/src/libsyntax/feature_gate/check.rs
index 2b49a296a082a..46a22f12678ee 100644
--- a/src/libsyntax/feature_gate/check.rs
+++ b/src/libsyntax/feature_gate/check.rs
@@ -4,18 +4,13 @@ use crate::attr;
 use crate::sess::{feature_err, leveled_feature_err, GateStrength, ParseSess};
 use crate::visit::{self, FnKind, Visitor};
 
-use rustc_data_structures::fx::FxHashMap;
 use rustc_error_codes::*;
-use rustc_errors::{error_code, struct_span_err, Applicability, Handler};
+use rustc_errors::{struct_span_err, Handler};
 use rustc_feature::{AttributeGate, BUILTIN_ATTRIBUTE_MAP};
-use rustc_feature::{Feature, Features, GateIssue, State as FeatureState, UnstableFeatures};
-use rustc_feature::{
-    ACCEPTED_FEATURES, ACTIVE_FEATURES, REMOVED_FEATURES, STABLE_REMOVED_FEATURES,
-};
-use rustc_span::edition::{Edition, ALL_EDITIONS};
+use rustc_feature::{Features, GateIssue, UnstableFeatures};
 use rustc_span::source_map::Spanned;
-use rustc_span::symbol::{sym, Symbol};
-use rustc_span::{Span, DUMMY_SP};
+use rustc_span::symbol::sym;
+use rustc_span::Span;
 
 use log::debug;
 
@@ -659,168 +654,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
     }
 }
 
-pub fn get_features(
-    span_handler: &Handler,
-    krate_attrs: &[ast::Attribute],
-    crate_edition: Edition,
-    allow_features: &Option<Vec<String>>,
-) -> Features {
-    fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) {
-        let mut err = struct_span_err!(span_handler, span, E0557, "feature has been removed");
-        err.span_label(span, "feature has been removed");
-        if let Some(reason) = reason {
-            err.note(reason);
-        }
-        err.emit();
-    }
-
-    let mut features = Features::default();
-    let mut edition_enabled_features = FxHashMap::default();
-
-    for &edition in ALL_EDITIONS {
-        if edition <= crate_edition {
-            // The `crate_edition` implies its respective umbrella feature-gate
-            // (i.e., `#![feature(rust_20XX_preview)]` isn't needed on edition 20XX).
-            edition_enabled_features.insert(edition.feature_name(), edition);
-        }
-    }
-
-    for feature in active_features_up_to(crate_edition) {
-        feature.set(&mut features, DUMMY_SP);
-        edition_enabled_features.insert(feature.name, crate_edition);
-    }
-
-    // Process the edition umbrella feature-gates first, to ensure
-    // `edition_enabled_features` is completed before it's queried.
-    for attr in krate_attrs {
-        if !attr.check_name(sym::feature) {
-            continue;
-        }
-
-        let list = match attr.meta_item_list() {
-            Some(list) => list,
-            None => continue,
-        };
-
-        for mi in list {
-            if !mi.is_word() {
-                continue;
-            }
-
-            let name = mi.name_or_empty();
-
-            let edition = ALL_EDITIONS.iter().find(|e| name == e.feature_name()).copied();
-            if let Some(edition) = edition {
-                if edition <= crate_edition {
-                    continue;
-                }
-
-                for feature in active_features_up_to(edition) {
-                    // FIXME(Manishearth) there is currently no way to set
-                    // lib features by edition
-                    feature.set(&mut features, DUMMY_SP);
-                    edition_enabled_features.insert(feature.name, edition);
-                }
-            }
-        }
-    }
-
-    for attr in krate_attrs {
-        if !attr.check_name(sym::feature) {
-            continue;
-        }
-
-        let list = match attr.meta_item_list() {
-            Some(list) => list,
-            None => continue,
-        };
-
-        let bad_input = |span| {
-            struct_span_err!(span_handler, span, E0556, "malformed `feature` attribute input")
-        };
-
-        for mi in list {
-            let name = match mi.ident() {
-                Some(ident) if mi.is_word() => ident.name,
-                Some(ident) => {
-                    bad_input(mi.span())
-                        .span_suggestion(
-                            mi.span(),
-                            "expected just one word",
-                            format!("{}", ident.name),
-                            Applicability::MaybeIncorrect,
-                        )
-                        .emit();
-                    continue;
-                }
-                None => {
-                    bad_input(mi.span()).span_label(mi.span(), "expected just one word").emit();
-                    continue;
-                }
-            };
-
-            if let Some(edition) = edition_enabled_features.get(&name) {
-                let msg =
-                    &format!("the feature `{}` is included in the Rust {} edition", name, edition);
-                span_handler.struct_span_warn_with_code(mi.span(), msg, error_code!(E0705)).emit();
-                continue;
-            }
-
-            if ALL_EDITIONS.iter().any(|e| name == e.feature_name()) {
-                // Handled in the separate loop above.
-                continue;
-            }
-
-            let removed = REMOVED_FEATURES.iter().find(|f| name == f.name);
-            let stable_removed = STABLE_REMOVED_FEATURES.iter().find(|f| name == f.name);
-            if let Some(Feature { state, .. }) = removed.or(stable_removed) {
-                if let FeatureState::Removed { reason } | FeatureState::Stabilized { reason } =
-                    state
-                {
-                    feature_removed(span_handler, mi.span(), *reason);
-                    continue;
-                }
-            }
-
-            if let Some(Feature { since, .. }) = ACCEPTED_FEATURES.iter().find(|f| name == f.name) {
-                let since = Some(Symbol::intern(since));
-                features.declared_lang_features.push((name, mi.span(), since));
-                continue;
-            }
-
-            if let Some(allowed) = allow_features.as_ref() {
-                if allowed.iter().find(|&f| name.as_str() == *f).is_none() {
-                    struct_span_err!(
-                        span_handler,
-                        mi.span(),
-                        E0725,
-                        "the feature `{}` is not in the list of allowed features",
-                        name
-                    )
-                    .emit();
-                    continue;
-                }
-            }
-
-            if let Some(f) = ACTIVE_FEATURES.iter().find(|f| name == f.name) {
-                f.set(&mut features, mi.span());
-                features.declared_lang_features.push((name, mi.span(), None));
-                continue;
-            }
-
-            features.declared_lib_features.push((name, mi.span()));
-        }
-    }
-
-    features
-}
-
-fn active_features_up_to(edition: Edition) -> impl Iterator<Item = &'static Feature> {
-    ACTIVE_FEATURES.iter().filter(move |feature| {
-        if let Some(feature_edition) = feature.edition { feature_edition <= edition } else { false }
-    })
-}
-
 pub fn check_crate(
     krate: &ast::Crate,
     parse_sess: &ParseSess,
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index ffb0d7e7f9706..d266bf4bde08d 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -77,7 +77,7 @@ pub mod entry;
 pub mod expand;
 pub mod feature_gate {
     mod check;
-    pub use check::{check_attribute, check_crate, get_features};
+    pub use check::{check_attribute, check_crate};
     pub use rustc_session::parse::{feature_err, feature_err_issue};
 }
 pub mod mut_visit;

From 1af8c10bd42570ccbb112f3741fafbe6cf71ac67 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Thu, 2 Jan 2020 12:42:42 +0100
Subject: [PATCH 24/38] simplify feature_err imports

---
 src/librustc/lint/levels.rs                    | 4 ++--
 src/librustc/middle/stability.rs               | 2 +-
 src/librustc_expand/expand.rs                  | 4 ++--
 src/librustc_metadata/native_libs.rs           | 2 +-
 src/librustc_mir/hair/pattern/check_match.rs   | 2 +-
 src/librustc_mir/transform/check_consts/ops.rs | 2 +-
 src/librustc_parse/config.rs                   | 3 +--
 src/librustc_passes/check_const.rs             | 2 +-
 src/librustc_passes/stability.rs               | 2 +-
 src/librustc_resolve/macros.rs                 | 2 +-
 src/librustc_typeck/astconv.rs                 | 2 +-
 src/librustc_typeck/check/coercion.rs          | 7 +++----
 src/librustc_typeck/check/mod.rs               | 2 +-
 src/librustc_typeck/check/wfcheck.rs           | 4 ++--
 src/librustc_typeck/collect.rs                 | 6 +++---
 src/libsyntax/lib.rs                           | 1 -
 16 files changed, 22 insertions(+), 25 deletions(-)

diff --git a/src/librustc/lint/levels.rs b/src/librustc/lint/levels.rs
index 6ca98b44bf80c..e586ad1836c73 100644
--- a/src/librustc/lint/levels.rs
+++ b/src/librustc/lint/levels.rs
@@ -13,8 +13,8 @@ use rustc_span::source_map::MultiSpan;
 use rustc_span::symbol::{sym, Symbol};
 use syntax::ast;
 use syntax::attr;
-use syntax::feature_gate;
 use syntax::print::pprust;
+use syntax::sess::feature_err;
 
 use rustc_error_codes::*;
 
@@ -223,7 +223,7 @@ impl<'a> LintLevelsBuilder<'a> {
                             // don't have any lint names (`#[level(reason = "foo")]`)
                             if let ast::LitKind::Str(rationale, _) = name_value.kind {
                                 if !self.sess.features_untracked().lint_reasons {
-                                    feature_gate::feature_err(
+                                    feature_err(
                                         &self.sess.parse_sess,
                                         sym::lint_reasons,
                                         item.span,
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
index 93c23e40d2e2b..4874d65b2b0db 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc/middle/stability.rs
@@ -18,7 +18,7 @@ use rustc_span::symbol::{sym, Symbol};
 use rustc_span::{MultiSpan, Span};
 use syntax::ast::CRATE_NODE_ID;
 use syntax::attr::{self, ConstStability, Deprecation, RustcDeprecation, Stability};
-use syntax::feature_gate::feature_err_issue;
+use syntax::sess::feature_err_issue;
 
 use std::num::NonZeroU32;
 
diff --git a/src/librustc_expand/expand.rs b/src/librustc_expand/expand.rs
index 8426391a2f389..f20de93bdeb67 100644
--- a/src/librustc_expand/expand.rs
+++ b/src/librustc_expand/expand.rs
@@ -18,11 +18,11 @@ use rustc_span::{FileName, Span, DUMMY_SP};
 use syntax::ast::{self, AttrItem, Block, Ident, LitKind, NodeId, PatKind, Path};
 use syntax::ast::{ItemKind, MacArgs, MacStmtStyle, StmtKind};
 use syntax::attr::{self, is_builtin_attr, HasAttrs};
-use syntax::feature_gate::{self, feature_err};
+use syntax::feature_gate;
 use syntax::mut_visit::*;
 use syntax::print::pprust;
 use syntax::ptr::P;
-use syntax::sess::ParseSess;
+use syntax::sess::{feature_err, ParseSess};
 use syntax::token;
 use syntax::tokenstream::{TokenStream, TokenTree};
 use syntax::util::map_in_place::MapInPlace;
diff --git a/src/librustc_metadata/native_libs.rs b/src/librustc_metadata/native_libs.rs
index ae67efb966c96..9426d5e26f5e5 100644
--- a/src/librustc_metadata/native_libs.rs
+++ b/src/librustc_metadata/native_libs.rs
@@ -1,4 +1,5 @@
 use rustc::middle::cstore::{self, NativeLibrary};
+use rustc::session::parse::feature_err;
 use rustc::session::Session;
 use rustc::ty::TyCtxt;
 use rustc_data_structures::fx::FxHashSet;
@@ -10,7 +11,6 @@ use rustc_span::source_map::Span;
 use rustc_span::symbol::{kw, sym, Symbol};
 use rustc_target::spec::abi::Abi;
 use syntax::attr;
-use syntax::feature_gate::feature_err;
 
 crate fn collect(tcx: TyCtxt<'_>) -> Vec<NativeLibrary> {
     let mut collector = Collector { tcx, libs: Vec::new() };
diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs
index ce0c081bc1608..0e9d16cfa56a8 100644
--- a/src/librustc_mir/hair/pattern/check_match.rs
+++ b/src/librustc_mir/hair/pattern/check_match.rs
@@ -6,6 +6,7 @@ use super::{PatCtxt, PatKind, PatternError};
 
 use rustc::hir::map::Map;
 use rustc::lint;
+use rustc::session::parse::feature_err;
 use rustc::session::Session;
 use rustc::ty::subst::{InternalSubsts, SubstsRef};
 use rustc::ty::{self, Ty, TyCtxt};
@@ -19,7 +20,6 @@ use rustc_hir::{HirId, Pat};
 use rustc_span::symbol::sym;
 use rustc_span::{MultiSpan, Span};
 use syntax::ast::Mutability;
-use syntax::feature_gate::feature_err;
 
 use std::slice;
 
diff --git a/src/librustc_mir/transform/check_consts/ops.rs b/src/librustc_mir/transform/check_consts/ops.rs
index abef008a8eccb..e69b580565e53 100644
--- a/src/librustc_mir/transform/check_consts/ops.rs
+++ b/src/librustc_mir/transform/check_consts/ops.rs
@@ -1,12 +1,12 @@
 //! Concrete error types for all operations which may be invalid in a certain const context.
 
 use rustc::session::config::nightly_options;
+use rustc::session::parse::feature_err;
 use rustc::ty::TyCtxt;
 use rustc_errors::struct_span_err;
 use rustc_hir::def_id::DefId;
 use rustc_span::symbol::sym;
 use rustc_span::{Span, Symbol};
-use syntax::feature_gate::feature_err;
 
 use super::{ConstKind, Item};
 
diff --git a/src/librustc_parse/config.rs b/src/librustc_parse/config.rs
index df1e62d04d66d..8467acc759c2b 100644
--- a/src/librustc_parse/config.rs
+++ b/src/librustc_parse/config.rs
@@ -22,10 +22,9 @@ use rustc_span::{Span, DUMMY_SP};
 use syntax::ast::{self, AttrItem, Attribute, MetaItem};
 use syntax::attr;
 use syntax::attr::HasAttrs;
-use syntax::feature_gate::feature_err;
 use syntax::mut_visit::*;
 use syntax::ptr::P;
-use syntax::sess::ParseSess;
+use syntax::sess::{feature_err, ParseSess};
 use syntax::util::map_in_place::MapInPlace;
 
 use smallvec::SmallVec;
diff --git a/src/librustc_passes/check_const.rs b/src/librustc_passes/check_const.rs
index a2944918a4748..39ba2fbc63b43 100644
--- a/src/librustc_passes/check_const.rs
+++ b/src/librustc_passes/check_const.rs
@@ -9,6 +9,7 @@
 
 use rustc::hir::map::Map;
 use rustc::session::config::nightly_options;
+use rustc::session::parse::feature_err;
 use rustc::ty::query::Providers;
 use rustc::ty::TyCtxt;
 use rustc_error_codes::*;
@@ -18,7 +19,6 @@ use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_span::{sym, Span, Symbol};
 use syntax::ast::Mutability;
-use syntax::feature_gate::feature_err;
 
 use std::fmt;
 
diff --git a/src/librustc_passes/stability.rs b/src/librustc_passes/stability.rs
index 588386e6f8d69..af37d218d68f0 100644
--- a/src/librustc_passes/stability.rs
+++ b/src/librustc_passes/stability.rs
@@ -5,6 +5,7 @@ use rustc::hir::map::Map;
 use rustc::lint;
 use rustc::middle::privacy::AccessLevels;
 use rustc::middle::stability::{DeprecationEntry, Index};
+use rustc::session::parse::feature_err;
 use rustc::session::Session;
 use rustc::traits::misc::can_type_implement_copy;
 use rustc::ty::query::Providers;
@@ -20,7 +21,6 @@ use rustc_span::symbol::{sym, Symbol};
 use rustc_span::Span;
 use syntax::ast::Attribute;
 use syntax::attr::{self, Stability};
-use syntax::feature_gate::feature_err;
 
 use std::cmp::Ordering;
 use std::mem::replace;
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 1103d5b5b7c97..85b5d8ef1cb5d 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -7,6 +7,7 @@ use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, Determinacy};
 use crate::{CrateLint, ParentScope, ResolutionError, Resolver, Scope, ScopeSet, Weak};
 use crate::{ModuleKind, ModuleOrUniformRoot, NameBinding, PathResult, Segment, ToNameBinding};
 use rustc::middle::stability;
+use rustc::session::parse::feature_err;
 use rustc::session::Session;
 use rustc::{lint, span_bug, ty};
 use rustc_data_structures::fx::FxHashSet;
@@ -23,7 +24,6 @@ use rustc_span::symbol::{kw, sym, Symbol};
 use rustc_span::{Span, DUMMY_SP};
 use syntax::ast::{self, Ident, NodeId};
 use syntax::attr::{self, StabilityLevel};
-use syntax::feature_gate::feature_err;
 use syntax::print::pprust;
 
 use rustc_data_structures::sync::Lrc;
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 851c2f76adab7..c15bcd81443d6 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -10,6 +10,7 @@ use crate::namespace::Namespace;
 use crate::require_c_abi_if_c_variadic;
 use crate::util::common::ErrorReported;
 use rustc::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
+use rustc::session::parse::feature_err;
 use rustc::traits;
 use rustc::traits::astconv_object_safety_violations;
 use rustc::traits::error_reporting::report_object_safety_error;
@@ -30,7 +31,6 @@ use rustc_span::{MultiSpan, Span, DUMMY_SP};
 use rustc_target::spec::abi;
 use smallvec::SmallVec;
 use syntax::ast;
-use syntax::feature_gate::feature_err;
 use syntax::util::lev_distance::find_best_match_for_name;
 
 use std::collections::BTreeSet;
diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs
index feab31523f265..1afb703ca1506 100644
--- a/src/librustc_typeck/check/coercion.rs
+++ b/src/librustc_typeck/check/coercion.rs
@@ -53,6 +53,7 @@
 use crate::check::{FnCtxt, Needs};
 use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc::infer::{Coercion, InferOk, InferResult};
+use rustc::session::parse::feature_err;
 use rustc::traits::{self, ObligationCause, ObligationCauseCode};
 use rustc::ty::adjustment::{
     Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCast,
@@ -62,6 +63,7 @@ use rustc::ty::fold::TypeFoldable;
 use rustc::ty::relate::RelateResult;
 use rustc::ty::subst::SubstsRef;
 use rustc::ty::{self, Ty, TypeAndMut};
+use rustc_error_codes::*;
 use rustc_errors::{struct_span_err, DiagnosticBuilder};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
@@ -70,9 +72,6 @@ use rustc_span::symbol::sym;
 use rustc_target::spec::abi::Abi;
 use smallvec::{smallvec, SmallVec};
 use std::ops::Deref;
-use syntax::feature_gate;
-
-use rustc_error_codes::*;
 
 struct Coerce<'a, 'tcx> {
     fcx: &'a FnCtxt<'a, 'tcx>,
@@ -627,7 +626,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
         }
 
         if has_unsized_tuple_coercion && !self.tcx.features().unsized_tuple_coercion {
-            feature_gate::feature_err(
+            feature_err(
                 &self.tcx.sess.parse_sess,
                 sym::unsized_tuple_coercion,
                 self.cause.span,
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 32225cd417f2d..dea1be7641afa 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -99,6 +99,7 @@ use rustc::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
 use rustc::infer::{self, InferCtxt, InferOk, InferResult};
 use rustc::middle::region;
 use rustc::mir::interpret::ConstValue;
+use rustc::session::parse::feature_err;
 use rustc::traits::error_reporting::recursive_type_with_infinite_size_error;
 use rustc::traits::{self, ObligationCause, ObligationCauseCode, TraitEngine};
 use rustc::ty::adjustment::{
@@ -130,7 +131,6 @@ use rustc_span::{self, BytePos, MultiSpan, Span};
 use rustc_target::spec::abi::Abi;
 use syntax::ast;
 use syntax::attr;
-use syntax::feature_gate::feature_err;
 use syntax::util::parser::ExprPrecedence;
 
 use rustc_error_codes::*;
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index df1eecdcfa8c5..a496a6e12ce1a 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -3,6 +3,7 @@ use crate::constrained_generic_params::{identify_constrained_generic_params, Par
 
 use rustc::infer::opaque_types::may_define_opaque_type;
 use rustc::middle::lang_items;
+use rustc::session::parse::feature_err;
 use rustc::traits::{self, ObligationCause, ObligationCauseCode};
 use rustc::ty::subst::{InternalSubsts, Subst};
 use rustc::ty::{self, AdtKind, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable};
@@ -13,7 +14,6 @@ use rustc_hir::ItemKind;
 use rustc_span::symbol::sym;
 use rustc_span::Span;
 use syntax::ast;
-use syntax::feature_gate;
 
 use rustc_hir as hir;
 use rustc_hir::itemlikevisit::ParItemLikeVisitor;
@@ -821,7 +821,7 @@ fn check_method_receiver<'fcx, 'tcx>(
         if !receiver_is_valid(fcx, span, receiver_ty, self_ty, false) {
             if receiver_is_valid(fcx, span, receiver_ty, self_ty, true) {
                 // Report error; would have worked with `arbitrary_self_types`.
-                feature_gate::feature_err(
+                feature_err(
                     &fcx.tcx.sess.parse_sess,
                     sym::arbitrary_self_types,
                     span,
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 64e71cc42e0ca..ad750d5ab8341 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -23,6 +23,7 @@ use crate::middle::weak_lang_items;
 use rustc::hir::map::Map;
 use rustc::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
 use rustc::mir::mono::Linkage;
+use rustc::session::parse::feature_err;
 use rustc::traits;
 use rustc::ty::query::Providers;
 use rustc::ty::subst::GenericArgKind;
@@ -45,7 +46,6 @@ use rustc_target::spec::abi;
 use syntax::ast;
 use syntax::ast::{Ident, MetaItemKind};
 use syntax::attr::{list_contains_name, mark_used, InlineAttr, OptimizeAttr};
-use syntax::feature_gate;
 
 use rustc_error_codes::*;
 
@@ -1537,7 +1537,7 @@ fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
                         _ => None,
                     };
                     if let Some(unsupported_type) = err {
-                        feature_gate::feature_err(
+                        feature_err(
                             &tcx.sess.parse_sess,
                             sym::const_compare_raw_pointers,
                             hir_ty.span,
@@ -2633,7 +2633,7 @@ fn from_target_feature(
                 None => true,
             };
             if !allowed && id.is_local() {
-                feature_gate::feature_err(
+                feature_err(
                     &tcx.sess.parse_sess,
                     feature_gate.unwrap(),
                     item.span(),
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index d266bf4bde08d..c03e848b7a420 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -78,7 +78,6 @@ pub mod expand;
 pub mod feature_gate {
     mod check;
     pub use check::{check_attribute, check_crate};
-    pub use rustc_session::parse::{feature_err, feature_err_issue};
 }
 pub mod mut_visit;
 pub mod ptr;

From fff5ef68b0d5c314569a71c7fae136196b14a6bc Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Thu, 2 Jan 2020 12:54:43 +0100
Subject: [PATCH 25/38] canonicalize rustc::session import

---
 Cargo.lock                            | 1 +
 src/librustc_passes/Cargo.toml        | 1 +
 src/librustc_passes/ast_validation.rs | 2 +-
 3 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/Cargo.lock b/Cargo.lock
index 6116ae033875e..2522eb85a7cad 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3787,6 +3787,7 @@ dependencies = [
  "rustc_hir",
  "rustc_index",
  "rustc_parse",
+ "rustc_session",
  "rustc_span",
  "rustc_target",
  "syntax",
diff --git a/src/librustc_passes/Cargo.toml b/src/librustc_passes/Cargo.toml
index 4adc6dabb9fdb..897581b32b5a1 100644
--- a/src/librustc_passes/Cargo.toml
+++ b/src/librustc_passes/Cargo.toml
@@ -17,6 +17,7 @@ rustc_feature = { path = "../librustc_feature" }
 rustc_hir = { path = "../librustc_hir" }
 rustc_index = { path = "../librustc_index" }
 rustc_parse = { path = "../librustc_parse" }
+rustc_session = { path = "../librustc_session" }
 rustc_target = { path = "../librustc_target" }
 syntax = { path = "../libsyntax" }
 rustc_span = { path = "../librustc_span" }
diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs
index be58a790fa878..9cd7d9a89fd87 100644
--- a/src/librustc_passes/ast_validation.rs
+++ b/src/librustc_passes/ast_validation.rs
@@ -7,10 +7,10 @@
 // or type checking or some other kind of complex analysis.
 
 use rustc::lint;
-use rustc::session::Session;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::{struct_span_err, Applicability, FatalError};
 use rustc_parse::validate_attr;
+use rustc_session::Session;
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::{kw, sym};
 use rustc_span::Span;

From d247ac4c0d64b278d80296a0dab801238fa3c66b Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 5 Jan 2020 07:30:38 +0100
Subject: [PATCH 26/38] Remove unused derives

---
 src/librustc/lint/builtin.rs | 2 +-
 src/librustc/lint/context.rs | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index f5845dcae1288..5dea0dbc8966c 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -516,7 +516,7 @@ declare_lint_pass! {
 
 // this could be a closure, but then implementing derive traits
 // becomes hacky (and it gets allocated)
-#[derive(PartialEq, RustcEncodable, RustcDecodable, Debug)]
+#[derive(PartialEq)]
 pub enum BuiltinLintDiagnostics {
     Normal,
     BareTraitObject(Span, /* is_global */ bool),
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index bd561b41c57f5..492d8f1f8a5f7 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -66,7 +66,7 @@ pub struct LintStore {
 
 /// Lints that are buffered up early on in the `Session` before the
 /// `LintLevels` is calculated
-#[derive(PartialEq, Debug)]
+#[derive(PartialEq)]
 pub struct BufferedEarlyLint {
     pub lint_id: LintId,
     pub ast_id: ast::NodeId,

From 82eeb8573a7caa0b3dc4aaa8236e83fcff9779d3 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 5 Jan 2020 08:54:10 +0100
Subject: [PATCH 27/38] prepare for moving BuiltinLintDiagnostics to
 rustc_session

---
 src/librustc/lint/builtin.rs | 144 +++++++++++++++++------------------
 src/librustc/lint/context.rs |   2 +-
 2 files changed, 71 insertions(+), 75 deletions(-)

diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index 5dea0dbc8966c..de4992d8e706e 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -514,8 +514,10 @@ declare_lint_pass! {
     ]
 }
 
-// this could be a closure, but then implementing derive traits
-// becomes hacky (and it gets allocated)
+impl LateLintPass<'_, '_> for HardwiredLints {}
+
+// This could be a closure, but then implementing derive trait
+// becomes hacky (and it gets allocated).
 #[derive(PartialEq)]
 pub enum BuiltinLintDiagnostics {
     Normal,
@@ -572,86 +574,80 @@ pub fn add_elided_lifetime_in_path_suggestion(
     );
 }
 
-impl BuiltinLintDiagnostics {
-    pub fn run(self, sess: &Session, db: &mut DiagnosticBuilder<'_>) {
-        match self {
-            BuiltinLintDiagnostics::Normal => (),
-            BuiltinLintDiagnostics::BareTraitObject(span, is_global) => {
-                let (sugg, app) = match sess.source_map().span_to_snippet(span) {
-                    Ok(ref s) if is_global => {
-                        (format!("dyn ({})", s), Applicability::MachineApplicable)
-                    }
-                    Ok(s) => (format!("dyn {}", s), Applicability::MachineApplicable),
-                    Err(_) => ("dyn <type>".to_string(), Applicability::HasPlaceholders),
-                };
-                db.span_suggestion(span, "use `dyn`", sugg, app);
-            }
-            BuiltinLintDiagnostics::AbsPathWithModule(span) => {
-                let (sugg, app) = match sess.source_map().span_to_snippet(span) {
-                    Ok(ref s) => {
-                        // FIXME(Manishearth) ideally the emitting code
-                        // can tell us whether or not this is global
-                        let opt_colon = if s.trim_start().starts_with("::") { "" } else { "::" };
-
-                        (format!("crate{}{}", opt_colon, s), Applicability::MachineApplicable)
-                    }
-                    Err(_) => ("crate::<path>".to_string(), Applicability::HasPlaceholders),
-                };
-                db.span_suggestion(span, "use `crate`", sugg, app);
-            }
-            BuiltinLintDiagnostics::ProcMacroDeriveResolutionFallback(span) => {
-                db.span_label(
-                    span,
-                    "names from parent modules are not \
-                                     accessible without an explicit import",
-                );
-            }
-            BuiltinLintDiagnostics::MacroExpandedMacroExportsAccessedByAbsolutePaths(span_def) => {
-                db.span_note(span_def, "the macro is defined here");
-            }
-            BuiltinLintDiagnostics::ElidedLifetimesInPaths(
+pub fn run_builtin_lint_diagnostics(
+    this: BuiltinLintDiagnostics,
+    sess: &Session,
+    db: &mut DiagnosticBuilder<'_>,
+) {
+    match this {
+        BuiltinLintDiagnostics::Normal => (),
+        BuiltinLintDiagnostics::BareTraitObject(span, is_global) => {
+            let (sugg, app) = match sess.source_map().span_to_snippet(span) {
+                Ok(s) if is_global => (format!("dyn ({})", s), Applicability::MachineApplicable),
+                Ok(s) => (format!("dyn {}", s), Applicability::MachineApplicable),
+                Err(_) => ("dyn <type>".to_string(), Applicability::HasPlaceholders),
+            };
+            db.span_suggestion(span, "use `dyn`", sugg, app);
+        }
+        BuiltinLintDiagnostics::AbsPathWithModule(span) => {
+            let (sugg, app) = match sess.source_map().span_to_snippet(span) {
+                Ok(ref s) => {
+                    // FIXME(Manishearth) ideally the emitting code
+                    // can tell us whether or not this is global
+                    let opt_colon = if s.trim_start().starts_with("::") { "" } else { "::" };
+
+                    (format!("crate{}{}", opt_colon, s), Applicability::MachineApplicable)
+                }
+                Err(_) => ("crate::<path>".to_string(), Applicability::HasPlaceholders),
+            };
+            db.span_suggestion(span, "use `crate`", sugg, app);
+        }
+        BuiltinLintDiagnostics::ProcMacroDeriveResolutionFallback(span) => {
+            db.span_label(
+                span,
+                "names from parent modules are not accessible without an explicit import",
+            );
+        }
+        BuiltinLintDiagnostics::MacroExpandedMacroExportsAccessedByAbsolutePaths(span_def) => {
+            db.span_note(span_def, "the macro is defined here");
+        }
+        BuiltinLintDiagnostics::ElidedLifetimesInPaths(
+            n,
+            path_span,
+            incl_angl_brckt,
+            insertion_span,
+            anon_lts,
+        ) => {
+            add_elided_lifetime_in_path_suggestion(
+                sess,
+                db,
                 n,
                 path_span,
                 incl_angl_brckt,
                 insertion_span,
                 anon_lts,
-            ) => {
-                add_elided_lifetime_in_path_suggestion(
-                    sess,
-                    db,
-                    n,
-                    path_span,
-                    incl_angl_brckt,
-                    insertion_span,
-                    anon_lts,
+            );
+        }
+        BuiltinLintDiagnostics::UnknownCrateTypes(span, note, sugg) => {
+            db.span_suggestion(span, &note, sugg, Applicability::MaybeIncorrect);
+        }
+        BuiltinLintDiagnostics::UnusedImports(message, replaces) => {
+            if !replaces.is_empty() {
+                db.tool_only_multipart_suggestion(
+                    &message,
+                    replaces,
+                    Applicability::MachineApplicable,
                 );
             }
-            BuiltinLintDiagnostics::UnknownCrateTypes(span, note, sugg) => {
-                db.span_suggestion(span, &note, sugg, Applicability::MaybeIncorrect);
-            }
-            BuiltinLintDiagnostics::UnusedImports(message, replaces) => {
-                if !replaces.is_empty() {
-                    db.tool_only_multipart_suggestion(
-                        &message,
-                        replaces,
-                        Applicability::MachineApplicable,
-                    );
-                }
-            }
-            BuiltinLintDiagnostics::RedundantImport(spans, ident) => {
-                for (span, is_imported) in spans {
-                    let introduced = if is_imported { "imported" } else { "defined" };
-                    db.span_label(
-                        span,
-                        format!("the item `{}` is already {} here", ident, introduced),
-                    );
-                }
-            }
-            BuiltinLintDiagnostics::DeprecatedMacro(suggestion, span) => {
-                stability::deprecation_suggestion(db, suggestion, span)
+        }
+        BuiltinLintDiagnostics::RedundantImport(spans, ident) => {
+            for (span, is_imported) in spans {
+                let introduced = if is_imported { "imported" } else { "defined" };
+                db.span_label(span, format!("the item `{}` is already {} here", ident, introduced));
             }
         }
+        BuiltinLintDiagnostics::DeprecatedMacro(suggestion, span) => {
+            stability::deprecation_suggestion(db, suggestion, span)
+        }
     }
 }
-
-impl<'a, 'tcx> LateLintPass<'a, 'tcx> for HardwiredLints {}
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index 492d8f1f8a5f7..90575f71ff573 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -495,7 +495,7 @@ pub trait LintContext: Sized {
         diagnostic: BuiltinLintDiagnostics,
     ) {
         let mut db = self.lookup(lint, span, msg);
-        diagnostic.run(self.sess(), &mut db);
+        super::builtin::run_builtin_lint_diagnostics(diagnostic, self.sess(), &mut db);
         db.emit();
     }
 

From 7dbccf5b556ece8e69355ee99d6f9bdcfbd71bbf Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 5 Jan 2020 09:40:16 +0100
Subject: [PATCH 28/38] buffered lint infra -> rustc_session

---
 Cargo.lock                            |  1 +
 src/librustc/lint/builtin.rs          | 19 +-----
 src/librustc/lint/context.rs          | 15 +----
 src/librustc/lint/mod.rs              | 59 +------------------
 src/librustc/middle/stability.rs      |  4 +-
 src/librustc_ast_lowering/lib.rs      |  6 +-
 src/librustc_ast_lowering/path.rs     |  7 ++-
 src/librustc_interface/Cargo.toml     |  1 +
 src/librustc_interface/passes.rs      |  5 +-
 src/librustc_interface/util.rs        | 12 ++--
 src/librustc_lint/early.rs            |  8 +--
 src/librustc_passes/ast_validation.rs |  9 +--
 src/librustc_resolve/check_unused.rs  |  3 +-
 src/librustc_resolve/imports.rs       |  4 +-
 src/librustc_resolve/lib.rs           | 26 +++++----
 src/librustc_session/lint.rs          | 83 +++++++++++++++++++++++++--
 src/librustc_session/parse.rs         | 11 ++--
 17 files changed, 136 insertions(+), 137 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 2522eb85a7cad..5b9db97975001 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3630,6 +3630,7 @@ dependencies = [
  "rustc_plugin_impl",
  "rustc_privacy",
  "rustc_resolve",
+ "rustc_session",
  "rustc_span",
  "rustc_target",
  "rustc_traits",
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index de4992d8e706e..548b3e27ac69f 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -9,10 +9,9 @@ use crate::middle::stability;
 use crate::session::Session;
 use rustc_errors::{pluralize, Applicability, DiagnosticBuilder};
 use rustc_session::declare_lint;
+use rustc_session::lint::BuiltinLintDiagnostics;
 use rustc_span::edition::Edition;
 use rustc_span::source_map::Span;
-use rustc_span::symbol::Symbol;
-use syntax::ast;
 use syntax::early_buffered_lints::{ILL_FORMED_ATTRIBUTE_INPUT, META_VARIABLE_MISUSE};
 
 declare_lint! {
@@ -516,22 +515,6 @@ declare_lint_pass! {
 
 impl LateLintPass<'_, '_> for HardwiredLints {}
 
-// This could be a closure, but then implementing derive trait
-// becomes hacky (and it gets allocated).
-#[derive(PartialEq)]
-pub enum BuiltinLintDiagnostics {
-    Normal,
-    BareTraitObject(Span, /* is_global */ bool),
-    AbsPathWithModule(Span),
-    ProcMacroDeriveResolutionFallback(Span),
-    MacroExpandedMacroExportsAccessedByAbsolutePaths(Span),
-    ElidedLifetimesInPaths(usize, Span, bool, Span, String),
-    UnknownCrateTypes(Span, String, String),
-    UnusedImports(String, Vec<(Span, String)>),
-    RedundantImport(Vec<(Span, bool)>, ast::Ident),
-    DeprecatedMacro(Option<Symbol>, Span),
-}
-
 pub fn add_elided_lifetime_in_path_suggestion(
     sess: &Session,
     db: &mut DiagnosticBuilder<'_>,
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index 90575f71ff573..759ab3749d2a7 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -17,10 +17,8 @@
 use self::TargetLint::*;
 
 use crate::hir::map::{definitions::DisambiguatedDefPathData, DefPathData};
-use crate::lint::builtin::BuiltinLintDiagnostics;
 use crate::lint::levels::{LintLevelSets, LintLevelsBuilder};
 use crate::lint::{EarlyLintPassObject, LateLintPassObject};
-use crate::lint::{FutureIncompatibleInfo, Level, Lint, LintBuffer, LintId};
 use crate::middle::privacy::AccessLevels;
 use crate::session::Session;
 use crate::ty::layout::{LayoutError, LayoutOf, TyLayout};
@@ -31,6 +29,8 @@ use rustc_error_codes::*;
 use rustc_errors::{struct_span_err, DiagnosticBuilder};
 use rustc_hir as hir;
 use rustc_hir::def_id::{CrateNum, DefId};
+use rustc_session::lint::BuiltinLintDiagnostics;
+use rustc_session::lint::{FutureIncompatibleInfo, Level, Lint, LintBuffer, LintId};
 use rustc_span::{symbol::Symbol, MultiSpan, Span, DUMMY_SP};
 use syntax::ast;
 use syntax::util::lev_distance::find_best_match_for_name;
@@ -64,17 +64,6 @@ pub struct LintStore {
     lint_groups: FxHashMap<&'static str, LintGroup>,
 }
 
-/// Lints that are buffered up early on in the `Session` before the
-/// `LintLevels` is calculated
-#[derive(PartialEq)]
-pub struct BufferedEarlyLint {
-    pub lint_id: LintId,
-    pub ast_id: ast::NodeId,
-    pub span: MultiSpan,
-    pub msg: String,
-    pub diagnostic: BuiltinLintDiagnostics,
-}
-
 /// The target of the `by_name` map, which accounts for renaming/deprecation.
 enum TargetLint {
     /// A direct lint target
diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs
index a8c1f9a664f18..e59e8ce1c0a76 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -21,12 +21,10 @@
 pub use self::Level::*;
 pub use self::LintSource::*;
 
-use crate::lint::builtin::BuiltinLintDiagnostics;
 use crate::ty::TyCtxt;
 use rustc_data_structures::sync;
 use rustc_errors::{DiagnosticBuilder, DiagnosticId};
 use rustc_hir as hir;
-use rustc_session::node_id::NodeMap;
 use rustc_session::{DiagnosticMessageId, Session};
 use rustc_span::hygiene::MacroKind;
 use rustc_span::source_map::{DesugaringKind, ExpnKind, MultiSpan};
@@ -35,10 +33,10 @@ use rustc_span::Span;
 use syntax::ast;
 
 pub use crate::lint::context::{
-    BufferedEarlyLint, CheckLintNameResult, EarlyContext, LateContext, LintContext, LintStore,
+    CheckLintNameResult, EarlyContext, LateContext, LintContext, LintStore,
 };
 
-pub use rustc_session::lint::{FutureIncompatibleInfo, Level, Lint, LintId};
+pub use rustc_session::lint::{BufferedEarlyLint, FutureIncompatibleInfo, Level, Lint, LintId};
 
 /// Declares a static `LintArray` and return it as an expression.
 #[macro_export]
@@ -373,59 +371,6 @@ mod levels;
 
 pub use self::levels::{LintLevelMap, LintLevelSets, LintLevelsBuilder};
 
-#[derive(Default)]
-pub struct LintBuffer {
-    pub map: NodeMap<Vec<BufferedEarlyLint>>,
-}
-
-impl LintBuffer {
-    pub fn add_lint(
-        &mut self,
-        lint: &'static Lint,
-        id: ast::NodeId,
-        sp: MultiSpan,
-        msg: &str,
-        diagnostic: BuiltinLintDiagnostics,
-    ) {
-        let early_lint = BufferedEarlyLint {
-            lint_id: LintId::of(lint),
-            ast_id: id,
-            span: sp,
-            msg: msg.to_string(),
-            diagnostic,
-        };
-        let arr = self.map.entry(id).or_default();
-        if !arr.contains(&early_lint) {
-            arr.push(early_lint);
-        }
-    }
-
-    pub fn take(&mut self, id: ast::NodeId) -> Vec<BufferedEarlyLint> {
-        self.map.remove(&id).unwrap_or_default()
-    }
-
-    pub fn buffer_lint<S: Into<MultiSpan>>(
-        &mut self,
-        lint: &'static Lint,
-        id: ast::NodeId,
-        sp: S,
-        msg: &str,
-    ) {
-        self.add_lint(lint, id, sp.into(), msg, BuiltinLintDiagnostics::Normal)
-    }
-
-    pub fn buffer_lint_with_diagnostic<S: Into<MultiSpan>>(
-        &mut self,
-        lint: &'static Lint,
-        id: ast::NodeId,
-        sp: S,
-        msg: &str,
-        diagnostic: BuiltinLintDiagnostics,
-    ) {
-        self.add_lint(lint, id, sp.into(), msg, diagnostic)
-    }
-}
-
 pub fn struct_lint_level<'a>(
     sess: &'a Session,
     lint: &'static Lint,
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
index 4874d65b2b0db..17e84c24881c1 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc/middle/stability.rs
@@ -3,7 +3,6 @@
 
 pub use self::StabilityLevel::*;
 
-use crate::lint::builtin::BuiltinLintDiagnostics;
 use crate::lint::{self, in_derive_expansion, Lint};
 use crate::session::{DiagnosticMessageId, Session};
 use crate::ty::{self, TyCtxt};
@@ -14,6 +13,7 @@ use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX};
 use rustc_hir::{self, HirId};
+use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer};
 use rustc_span::symbol::{sym, Symbol};
 use rustc_span::{MultiSpan, Span};
 use syntax::ast::CRATE_NODE_ID;
@@ -195,7 +195,7 @@ pub fn rustc_deprecation_message(depr: &RustcDeprecation, path: &str) -> (String
 }
 
 pub fn early_report_deprecation(
-    lint_buffer: &'a mut lint::LintBuffer,
+    lint_buffer: &'a mut LintBuffer,
     message: &str,
     suggestion: Option<Symbol>,
     lint: &'static Lint,
diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs
index 527aa6796bc22..77cb9ee35fff7 100644
--- a/src/librustc_ast_lowering/lib.rs
+++ b/src/librustc_ast_lowering/lib.rs
@@ -37,7 +37,6 @@ use rustc::arena::Arena;
 use rustc::dep_graph::DepGraph;
 use rustc::hir::map::definitions::{DefKey, DefPathData, Definitions};
 use rustc::hir::map::Map;
-use rustc::lint;
 use rustc::lint::builtin;
 use rustc::{bug, span_bug};
 use rustc_data_structures::captures::Captures;
@@ -52,6 +51,7 @@ use rustc_hir::intravisit;
 use rustc_hir::{ConstArg, GenericArg, ParamName};
 use rustc_index::vec::IndexVec;
 use rustc_session::config::nightly_options;
+use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer};
 use rustc_session::node_id::NodeMap;
 use rustc_session::Session;
 use rustc_span::hygiene::ExpnId;
@@ -198,7 +198,7 @@ pub trait Resolver {
         ns: Namespace,
     ) -> (ast::Path, Res<NodeId>);
 
-    fn lint_buffer(&mut self) -> &mut lint::LintBuffer;
+    fn lint_buffer(&mut self) -> &mut LintBuffer;
 
     fn next_node_id(&mut self) -> NodeId;
 }
@@ -2617,7 +2617,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 id,
                 span,
                 "trait objects without an explicit `dyn` are deprecated",
-                builtin::BuiltinLintDiagnostics::BareTraitObject(span, is_global),
+                BuiltinLintDiagnostics::BareTraitObject(span, is_global),
             )
         }
     }
diff --git a/src/librustc_ast_lowering/path.rs b/src/librustc_ast_lowering/path.rs
index 9b504704ae06c..b50295ebaae55 100644
--- a/src/librustc_ast_lowering/path.rs
+++ b/src/librustc_ast_lowering/path.rs
@@ -1,7 +1,7 @@
 use super::{AnonymousLifetimeMode, ImplTraitContext, LoweringContext, ParamMode};
 use super::{GenericArgsCtor, ParenthesizedGenericArgs};
 
-use rustc::lint::builtin::{self, ELIDED_LIFETIMES_IN_PATHS};
+use rustc::lint::builtin::ELIDED_LIFETIMES_IN_PATHS;
 use rustc::span_bug;
 use rustc_error_codes::*;
 use rustc_errors::{struct_span_err, Applicability};
@@ -9,6 +9,7 @@ use rustc_hir as hir;
 use rustc_hir::def::{DefKind, PartialRes, Res};
 use rustc_hir::def_id::DefId;
 use rustc_hir::GenericArg;
+use rustc_session::lint::BuiltinLintDiagnostics;
 use rustc_span::Span;
 use syntax::ast::{self, *};
 
@@ -304,7 +305,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             E0726,
                             "implicit elided lifetime not allowed here"
                         );
-                        crate::lint::builtin::add_elided_lifetime_in_path_suggestion(
+                        rustc::lint::builtin::add_elided_lifetime_in_path_suggestion(
                             &self.sess,
                             &mut err,
                             expected_lifetimes,
@@ -321,7 +322,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             CRATE_NODE_ID,
                             path_span,
                             "hidden lifetime parameters in types are deprecated",
-                            builtin::BuiltinLintDiagnostics::ElidedLifetimesInPaths(
+                            BuiltinLintDiagnostics::ElidedLifetimesInPaths(
                                 expected_lifetimes,
                                 path_span,
                                 incl_angl_brckt,
diff --git a/src/librustc_interface/Cargo.toml b/src/librustc_interface/Cargo.toml
index be60b75bc47eb..9bd19fb38e771 100644
--- a/src/librustc_interface/Cargo.toml
+++ b/src/librustc_interface/Cargo.toml
@@ -17,6 +17,7 @@ syntax = { path = "../libsyntax" }
 rustc_builtin_macros = { path = "../librustc_builtin_macros" }
 rustc_expand = { path = "../librustc_expand" }
 rustc_parse = { path = "../librustc_parse" }
+rustc_session = { path = "../librustc_session" }
 rustc_span = { path = "../librustc_span" }
 rustc_serialize = { path = "../libserialize", package = "serialize" }
 rustc = { path = "../librustc" }
diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs
index a7e174f04553c..e8210bfacd3bd 100644
--- a/src/librustc_interface/passes.rs
+++ b/src/librustc_interface/passes.rs
@@ -37,7 +37,6 @@ use rustc_span::symbol::Symbol;
 use rustc_span::FileName;
 use rustc_traits;
 use rustc_typeck as typeck;
-use syntax::early_buffered_lints::BufferedEarlyLint;
 use syntax::mut_visit::MutVisitor;
 use syntax::util::node_count::NodeCounter;
 use syntax::{self, ast, visit};
@@ -411,8 +410,8 @@ fn configure_and_expand_inner<'a>(
     // Add all buffered lints from the `ParseSess` to the `Session`.
     sess.parse_sess.buffered_lints.with_lock(|buffered_lints| {
         info!("{} parse sess buffered_lints", buffered_lints.len());
-        for BufferedEarlyLint { id, span, msg, lint_id } in buffered_lints.drain(..) {
-            resolver.lint_buffer().buffer_lint(lint_id, id, span, &msg);
+        for early_lint in buffered_lints.drain(..) {
+            resolver.lint_buffer().add_early_lint(early_lint);
         }
     });
 
diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs
index 8e381a27b414f..2fafd3af7a5ff 100644
--- a/src/librustc_interface/util.rs
+++ b/src/librustc_interface/util.rs
@@ -1,8 +1,5 @@
 use log::info;
 use rustc::lint;
-use rustc::session::config::{ErrorOutputType, Input, OutputFilenames};
-use rustc::session::CrateDisambiguator;
-use rustc::session::{self, config, early_error, filesearch, DiagnosticOutput, Session};
 use rustc::ty;
 use rustc_codegen_utils::codegen_backend::CodegenBackend;
 use rustc_data_structures::fingerprint::Fingerprint;
@@ -14,6 +11,11 @@ use rustc_data_structures::sync::{Lock, Lrc};
 use rustc_errors::registry::Registry;
 use rustc_metadata::dynamic_lib::DynamicLibrary;
 use rustc_resolve::{self, Resolver};
+use rustc_session as session;
+use rustc_session::config::{ErrorOutputType, Input, OutputFilenames};
+use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer};
+use rustc_session::CrateDisambiguator;
+use rustc_session::{config, early_error, filesearch, DiagnosticOutput, Session};
 use rustc_span::edition::Edition;
 use rustc_span::source_map::{FileLoader, RealFileLoader, SourceMap};
 use rustc_span::symbol::{sym, Symbol};
@@ -420,7 +422,7 @@ pub(crate) fn compute_crate_disambiguator(session: &Session) -> CrateDisambiguat
     CrateDisambiguator::from(hasher.finish::<Fingerprint>())
 }
 
-pub(crate) fn check_attr_crate_type(attrs: &[ast::Attribute], lint_buffer: &mut lint::LintBuffer) {
+pub(crate) fn check_attr_crate_type(attrs: &[ast::Attribute], lint_buffer: &mut LintBuffer) {
     // Unconditionally collect crate types from attributes to make them used
     for a in attrs.iter() {
         if a.check_name(sym::crate_type) {
@@ -442,7 +444,7 @@ pub(crate) fn check_attr_crate_type(attrs: &[ast::Attribute], lint_buffer: &mut
                             ast::CRATE_NODE_ID,
                             span,
                             "invalid `crate_type` value",
-                            lint::builtin::BuiltinLintDiagnostics::UnknownCrateTypes(
+                            BuiltinLintDiagnostics::UnknownCrateTypes(
                                 span,
                                 "did you mean".to_string(),
                                 format!("\"{}\"", candidate),
diff --git a/src/librustc_lint/early.rs b/src/librustc_lint/early.rs
index 67c0c98b20380..9a90171985158 100644
--- a/src/librustc_lint/early.rs
+++ b/src/librustc_lint/early.rs
@@ -16,15 +16,15 @@
 
 use rustc::lint::{EarlyContext, LintStore};
 use rustc::lint::{EarlyLintPass, EarlyLintPassObject};
-use rustc::lint::{LintBuffer, LintContext, LintPass};
-use rustc::session::Session;
-
+use rustc::lint::{LintContext, LintPass};
+use rustc_session::lint::LintBuffer;
+use rustc_session::Session;
 use rustc_span::Span;
-use std::slice;
 use syntax::ast;
 use syntax::visit as ast_visit;
 
 use log::debug;
+use std::slice;
 
 macro_rules! run_early_pass { ($cx:expr, $f:ident, $($args:expr),*) => ({
     $cx.pass.$f(&$cx.context, $($args),*);
diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs
index 9cd7d9a89fd87..bc8d8a414c44d 100644
--- a/src/librustc_passes/ast_validation.rs
+++ b/src/librustc_passes/ast_validation.rs
@@ -6,10 +6,11 @@
 // This pass is supposed to perform only simple checks not requiring name resolution
 // or type checking or some other kind of complex analysis.
 
-use rustc::lint;
+use rustc::lint::builtin::PATTERNS_IN_FNS_WITHOUT_BODY;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::{struct_span_err, Applicability, FatalError};
 use rustc_parse::validate_attr;
+use rustc_session::lint::LintBuffer;
 use rustc_session::Session;
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::{kw, sym};
@@ -65,7 +66,7 @@ struct AstValidator<'a> {
     /// certain positions.
     is_assoc_ty_bound_banned: bool,
 
-    lint_buffer: &'a mut lint::LintBuffer,
+    lint_buffer: &'a mut LintBuffer,
 }
 
 impl<'a> AstValidator<'a> {
@@ -992,7 +993,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                 Self::check_decl_no_pat(&sig.decl, |span, mut_ident| {
                     if mut_ident {
                         self.lint_buffer.buffer_lint(
-                            lint::builtin::PATTERNS_IN_FNS_WITHOUT_BODY,
+                            PATTERNS_IN_FNS_WITHOUT_BODY,
                             ti.id,
                             span,
                             "patterns aren't allowed in methods without bodies",
@@ -1021,7 +1022,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
     }
 }
 
-pub fn check_crate(session: &Session, krate: &Crate, lints: &mut lint::LintBuffer) -> bool {
+pub fn check_crate(session: &Session, krate: &Crate, lints: &mut LintBuffer) -> bool {
     let mut validator = AstValidator {
         session,
         has_proc_macro_decls: false,
diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs
index d6f365fce7929..4a6df92d82260 100644
--- a/src/librustc_resolve/check_unused.rs
+++ b/src/librustc_resolve/check_unused.rs
@@ -29,6 +29,7 @@ use crate::Resolver;
 use rustc::{lint, ty};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::pluralize;
+use rustc_session::lint::BuiltinLintDiagnostics;
 use rustc_session::node_id::NodeMap;
 use rustc_span::{MultiSpan, Span, DUMMY_SP};
 use syntax::ast;
@@ -317,7 +318,7 @@ impl Resolver<'_> {
                 unused.use_tree_id,
                 ms,
                 &msg,
-                lint::builtin::BuiltinLintDiagnostics::UnusedImports(fix_msg.into(), fixes),
+                BuiltinLintDiagnostics::UnusedImports(fix_msg.into(), fixes),
             );
         }
     }
diff --git a/src/librustc_resolve/imports.rs b/src/librustc_resolve/imports.rs
index 813e6ac96911e..ecd51b1ee0519 100644
--- a/src/librustc_resolve/imports.rs
+++ b/src/librustc_resolve/imports.rs
@@ -12,9 +12,9 @@ use crate::{CrateLint, Module, ModuleOrUniformRoot, ParentScope, PerNS, ScopeSet
 use crate::{NameBinding, NameBindingKind, PathResult, PrivacyError, ToNameBinding};
 
 use rustc::hir::exports::Export;
-use rustc::lint::builtin::BuiltinLintDiagnostics;
 use rustc::lint::builtin::{PUB_USE_OF_PRIVATE_EXTERN_CRATE, UNUSED_IMPORTS};
-use rustc::session::DiagnosticMessageId;
+use rustc_session::DiagnosticMessageId;
+use rustc_session::lint::BuiltinLintDiagnostics;
 use rustc::ty;
 use rustc::{bug, span_bug};
 use rustc_data_structures::fx::FxHashSet;
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index e6be9f6d328c0..8e4630cf7d696 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -24,7 +24,6 @@ use rustc::hir::exports::ExportMap;
 use rustc::hir::map::{DefKey, Definitions};
 use rustc::lint;
 use rustc::middle::cstore::{CrateStore, MetadataLoaderDyn};
-use rustc::session::Session;
 use rustc::span_bug;
 use rustc::ty::query::Providers;
 use rustc::ty::{self, DefIdTree, ResolverOutputs};
@@ -39,7 +38,9 @@ use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, CRATE_DEF_INDEX, LOCAL_CRATE}
 use rustc_hir::PrimTy::{self, Bool, Char, Float, Int, Str, Uint};
 use rustc_hir::{GlobMap, TraitMap};
 use rustc_metadata::creader::{CStore, CrateLoader};
+use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer};
 use rustc_session::node_id::{NodeMap, NodeSet};
+use rustc_session::Session;
 use rustc_span::hygiene::{ExpnId, ExpnKind, MacroKind, SyntaxContext, Transparency};
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::{kw, sym};
@@ -960,7 +961,7 @@ pub struct Resolver<'a> {
     /// when visiting the correspondent variants.
     variant_vis: DefIdMap<ty::Visibility>,
 
-    lint_buffer: lint::LintBuffer,
+    lint_buffer: LintBuffer,
 
     next_node_id: NodeId,
 }
@@ -1082,7 +1083,7 @@ impl rustc_ast_lowering::Resolver for Resolver<'_> {
         &mut self.definitions
     }
 
-    fn lint_buffer(&mut self) -> &mut lint::LintBuffer {
+    fn lint_buffer(&mut self) -> &mut LintBuffer {
         &mut self.lint_buffer
     }
 
@@ -1241,7 +1242,7 @@ impl<'a> Resolver<'a> {
                 .chain(features.declared_lang_features.iter().map(|(feat, ..)| *feat))
                 .collect(),
             variant_vis: Default::default(),
-            lint_buffer: lint::LintBuffer::default(),
+            lint_buffer: LintBuffer::default(),
             next_node_id: NodeId::from_u32(1),
         }
     }
@@ -1256,7 +1257,7 @@ impl<'a> Resolver<'a> {
         self.next_node_id
     }
 
-    pub fn lint_buffer(&mut self) -> &mut lint::LintBuffer {
+    pub fn lint_buffer(&mut self) -> &mut LintBuffer {
         &mut self.lint_buffer
     }
 
@@ -1713,10 +1714,10 @@ impl<'a> Resolver<'a> {
                     if let Some(node_id) = poisoned {
                         self.lint_buffer.buffer_lint_with_diagnostic(
                             lint::builtin::PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
-                            node_id, ident.span,
+                            node_id,
+                            ident.span,
                             &format!("cannot find {} `{}` in this scope", ns.descr(), ident),
-                            lint::builtin::BuiltinLintDiagnostics::
-                                ProcMacroDeriveResolutionFallback(ident.span),
+                            BuiltinLintDiagnostics::ProcMacroDeriveResolutionFallback(ident.span),
                         );
                     }
                     return Some(LexicalScopeBinding::Item(binding));
@@ -2267,7 +2268,7 @@ impl<'a> Resolver<'a> {
             }
         }
 
-        let diag = lint::builtin::BuiltinLintDiagnostics::AbsPathWithModule(diag_span);
+        let diag = BuiltinLintDiagnostics::AbsPathWithModule(diag_span);
         self.lint_buffer.buffer_lint_with_diagnostic(
             lint::builtin::ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
             diag_id,
@@ -2562,9 +2563,10 @@ impl<'a> Resolver<'a> {
                        cannot be referred to by absolute paths";
             self.lint_buffer.buffer_lint_with_diagnostic(
                 lint::builtin::MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS,
-                CRATE_NODE_ID, span_use, msg,
-                lint::builtin::BuiltinLintDiagnostics::
-                    MacroExpandedMacroExportsAccessedByAbsolutePaths(span_def),
+                CRATE_NODE_ID,
+                span_use,
+                msg,
+                BuiltinLintDiagnostics::MacroExpandedMacroExportsAccessedByAbsolutePaths(span_def),
             );
         }
 
diff --git a/src/librustc_session/lint.rs b/src/librustc_session/lint.rs
index 0cce7e848fd60..24e42928f638a 100644
--- a/src/librustc_session/lint.rs
+++ b/src/librustc_session/lint.rs
@@ -1,8 +1,8 @@
 pub use self::Level::*;
-use crate::node_id::NodeId;
+use crate::node_id::{NodeId, NodeMap};
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
 use rustc_span::edition::Edition;
-use rustc_span::{sym, MultiSpan, Symbol};
+use rustc_span::{sym, symbol::Ident, MultiSpan, Span, Symbol};
 
 /// Setting for how to handle a lint.
 #[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
@@ -174,7 +174,25 @@ impl<HCX> ToStableHashKey<HCX> for LintId {
     }
 }
 
-/// Stores buffered lint info which can later be passed to `librustc`.
+// This could be a closure, but then implementing derive trait
+// becomes hacky (and it gets allocated).
+#[derive(PartialEq)]
+pub enum BuiltinLintDiagnostics {
+    Normal,
+    BareTraitObject(Span, /* is_global */ bool),
+    AbsPathWithModule(Span),
+    ProcMacroDeriveResolutionFallback(Span),
+    MacroExpandedMacroExportsAccessedByAbsolutePaths(Span),
+    ElidedLifetimesInPaths(usize, Span, bool, Span, String),
+    UnknownCrateTypes(Span, String, String),
+    UnusedImports(String, Vec<(Span, String)>),
+    RedundantImport(Vec<(Span, bool)>, Ident),
+    DeprecatedMacro(Option<Symbol>, Span),
+}
+
+/// Lints that are buffered up early on in the `Session` before the
+/// `LintLevels` is calculated. These are later passed to `librustc`.
+#[derive(PartialEq)]
 pub struct BufferedEarlyLint {
     /// The span of code that we are linting on.
     pub span: MultiSpan,
@@ -183,10 +201,65 @@ pub struct BufferedEarlyLint {
     pub msg: String,
 
     /// The `NodeId` of the AST node that generated the lint.
-    pub id: NodeId,
+    pub node_id: NodeId,
 
     /// A lint Id that can be passed to `rustc::lint::Lint::from_parser_lint_id`.
-    pub lint_id: &'static Lint,
+    pub lint_id: LintId,
+
+    /// Customization of the `DiagnosticBuilder<'_>` for the lint.
+    pub diagnostic: BuiltinLintDiagnostics,
+}
+
+#[derive(Default)]
+pub struct LintBuffer {
+    pub map: NodeMap<Vec<BufferedEarlyLint>>,
+}
+
+impl LintBuffer {
+    pub fn add_early_lint(&mut self, early_lint: BufferedEarlyLint) {
+        let arr = self.map.entry(early_lint.node_id).or_default();
+        if !arr.contains(&early_lint) {
+            arr.push(early_lint);
+        }
+    }
+
+    pub fn add_lint(
+        &mut self,
+        lint: &'static Lint,
+        node_id: NodeId,
+        span: MultiSpan,
+        msg: &str,
+        diagnostic: BuiltinLintDiagnostics,
+    ) {
+        let lint_id = LintId::of(lint);
+        let msg = msg.to_string();
+        self.add_early_lint(BufferedEarlyLint { lint_id, node_id, span, msg, diagnostic });
+    }
+
+    pub fn take(&mut self, id: NodeId) -> Vec<BufferedEarlyLint> {
+        self.map.remove(&id).unwrap_or_default()
+    }
+
+    pub fn buffer_lint(
+        &mut self,
+        lint: &'static Lint,
+        id: NodeId,
+        sp: impl Into<MultiSpan>,
+        msg: &str,
+    ) {
+        self.add_lint(lint, id, sp.into(), msg, BuiltinLintDiagnostics::Normal)
+    }
+
+    pub fn buffer_lint_with_diagnostic(
+        &mut self,
+        lint: &'static Lint,
+        id: NodeId,
+        sp: impl Into<MultiSpan>,
+        msg: &str,
+        diagnostic: BuiltinLintDiagnostics,
+    ) {
+        self.add_lint(lint, id, sp.into(), msg, diagnostic)
+    }
 }
 
 /// Declares a static item of type `&'static Lint`.
diff --git a/src/librustc_session/parse.rs b/src/librustc_session/parse.rs
index b0c6aefc00ca1..0e342939ff1af 100644
--- a/src/librustc_session/parse.rs
+++ b/src/librustc_session/parse.rs
@@ -1,7 +1,7 @@
 //! Contains `ParseSess` which holds state living beyond what one `Parser` might.
 //! It also serves as an input to the parser itself.
 
-use crate::lint::BufferedEarlyLint;
+use crate::lint::{BufferedEarlyLint, BuiltinLintDiagnostics, Lint, LintId};
 use crate::node_id::NodeId;
 
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
@@ -210,17 +210,18 @@ impl ParseSess {
 
     pub fn buffer_lint(
         &self,
-        lint_id: &'static crate::lint::Lint,
+        lint: &'static Lint,
         span: impl Into<MultiSpan>,
-        id: NodeId,
+        node_id: NodeId,
         msg: &str,
     ) {
         self.buffered_lints.with_lock(|buffered_lints| {
             buffered_lints.push(BufferedEarlyLint {
                 span: span.into(),
-                id,
+                node_id,
                 msg: msg.into(),
-                lint_id,
+                lint_id: LintId::of(lint),
+                diagnostic: BuiltinLintDiagnostics::Normal,
             });
         });
     }

From 45f27643db6e25d4377d1b7050e55c07a02a0cec Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 5 Jan 2020 10:07:26 +0100
Subject: [PATCH 29/38] prepare moving HardwiredLints to rustc_session

---
 src/librustc/lint/builtin.rs             | 131 +----------------------
 src/librustc/lint/context.rs             | 125 ++++++++++++++++++++-
 src/librustc/lint/internal.rs            |   6 +-
 src/librustc/lint/mod.rs                 |  45 ++------
 src/librustc_ast_lowering/path.rs        |   2 +-
 src/librustc_lint/array_into_iter.rs     |   3 +-
 src/librustc_lint/builtin.rs             |   9 +-
 src/librustc_lint/late.rs                |   6 +-
 src/librustc_lint/lib.rs                 |   3 +-
 src/librustc_lint/non_ascii_idents.rs    |   2 +-
 src/librustc_lint/nonstandard_style.rs   |   4 +-
 src/librustc_lint/redundant_semicolon.rs |   2 +-
 src/librustc_lint/types.rs               |   6 +-
 src/librustc_lint/unused.rs              |   4 +-
 src/librustc_session/lint.rs             |  38 +++++++
 15 files changed, 187 insertions(+), 199 deletions(-)

diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index 548b3e27ac69f..9783bc36ea542 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -4,14 +4,9 @@
 //! compiler code, rather than using their own custom pass. Those
 //! lints are all available in `rustc_lint::builtin`.
 
-use crate::lint::{FutureIncompatibleInfo, LateLintPass, LintArray, LintPass};
-use crate::middle::stability;
-use crate::session::Session;
-use rustc_errors::{pluralize, Applicability, DiagnosticBuilder};
-use rustc_session::declare_lint;
-use rustc_session::lint::BuiltinLintDiagnostics;
+use rustc_session::lint::FutureIncompatibleInfo;
+use rustc_session::{declare_lint, declare_lint_pass};
 use rustc_span::edition::Edition;
-use rustc_span::source_map::Span;
 use syntax::early_buffered_lints::{ILL_FORMED_ATTRIBUTE_INPUT, META_VARIABLE_MISUSE};
 
 declare_lint! {
@@ -512,125 +507,3 @@ declare_lint_pass! {
         SOFT_UNSTABLE,
     ]
 }
-
-impl LateLintPass<'_, '_> for HardwiredLints {}
-
-pub fn add_elided_lifetime_in_path_suggestion(
-    sess: &Session,
-    db: &mut DiagnosticBuilder<'_>,
-    n: usize,
-    path_span: Span,
-    incl_angl_brckt: bool,
-    insertion_span: Span,
-    anon_lts: String,
-) {
-    let (replace_span, suggestion) = if incl_angl_brckt {
-        (insertion_span, anon_lts)
-    } else {
-        // When possible, prefer a suggestion that replaces the whole
-        // `Path<T>` expression with `Path<'_, T>`, rather than inserting `'_, `
-        // at a point (which makes for an ugly/confusing label)
-        if let Ok(snippet) = sess.source_map().span_to_snippet(path_span) {
-            // But our spans can get out of whack due to macros; if the place we think
-            // we want to insert `'_` isn't even within the path expression's span, we
-            // should bail out of making any suggestion rather than panicking on a
-            // subtract-with-overflow or string-slice-out-out-bounds (!)
-            // FIXME: can we do better?
-            if insertion_span.lo().0 < path_span.lo().0 {
-                return;
-            }
-            let insertion_index = (insertion_span.lo().0 - path_span.lo().0) as usize;
-            if insertion_index > snippet.len() {
-                return;
-            }
-            let (before, after) = snippet.split_at(insertion_index);
-            (path_span, format!("{}{}{}", before, anon_lts, after))
-        } else {
-            (insertion_span, anon_lts)
-        }
-    };
-    db.span_suggestion(
-        replace_span,
-        &format!("indicate the anonymous lifetime{}", pluralize!(n)),
-        suggestion,
-        Applicability::MachineApplicable,
-    );
-}
-
-pub fn run_builtin_lint_diagnostics(
-    this: BuiltinLintDiagnostics,
-    sess: &Session,
-    db: &mut DiagnosticBuilder<'_>,
-) {
-    match this {
-        BuiltinLintDiagnostics::Normal => (),
-        BuiltinLintDiagnostics::BareTraitObject(span, is_global) => {
-            let (sugg, app) = match sess.source_map().span_to_snippet(span) {
-                Ok(s) if is_global => (format!("dyn ({})", s), Applicability::MachineApplicable),
-                Ok(s) => (format!("dyn {}", s), Applicability::MachineApplicable),
-                Err(_) => ("dyn <type>".to_string(), Applicability::HasPlaceholders),
-            };
-            db.span_suggestion(span, "use `dyn`", sugg, app);
-        }
-        BuiltinLintDiagnostics::AbsPathWithModule(span) => {
-            let (sugg, app) = match sess.source_map().span_to_snippet(span) {
-                Ok(ref s) => {
-                    // FIXME(Manishearth) ideally the emitting code
-                    // can tell us whether or not this is global
-                    let opt_colon = if s.trim_start().starts_with("::") { "" } else { "::" };
-
-                    (format!("crate{}{}", opt_colon, s), Applicability::MachineApplicable)
-                }
-                Err(_) => ("crate::<path>".to_string(), Applicability::HasPlaceholders),
-            };
-            db.span_suggestion(span, "use `crate`", sugg, app);
-        }
-        BuiltinLintDiagnostics::ProcMacroDeriveResolutionFallback(span) => {
-            db.span_label(
-                span,
-                "names from parent modules are not accessible without an explicit import",
-            );
-        }
-        BuiltinLintDiagnostics::MacroExpandedMacroExportsAccessedByAbsolutePaths(span_def) => {
-            db.span_note(span_def, "the macro is defined here");
-        }
-        BuiltinLintDiagnostics::ElidedLifetimesInPaths(
-            n,
-            path_span,
-            incl_angl_brckt,
-            insertion_span,
-            anon_lts,
-        ) => {
-            add_elided_lifetime_in_path_suggestion(
-                sess,
-                db,
-                n,
-                path_span,
-                incl_angl_brckt,
-                insertion_span,
-                anon_lts,
-            );
-        }
-        BuiltinLintDiagnostics::UnknownCrateTypes(span, note, sugg) => {
-            db.span_suggestion(span, &note, sugg, Applicability::MaybeIncorrect);
-        }
-        BuiltinLintDiagnostics::UnusedImports(message, replaces) => {
-            if !replaces.is_empty() {
-                db.tool_only_multipart_suggestion(
-                    &message,
-                    replaces,
-                    Applicability::MachineApplicable,
-                );
-            }
-        }
-        BuiltinLintDiagnostics::RedundantImport(spans, ident) => {
-            for (span, is_imported) in spans {
-                let introduced = if is_imported { "imported" } else { "defined" };
-                db.span_label(span, format!("the item `{}` is already {} here", ident, introduced));
-            }
-        }
-        BuiltinLintDiagnostics::DeprecatedMacro(suggestion, span) => {
-            stability::deprecation_suggestion(db, suggestion, span)
-        }
-    }
-}
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index 759ab3749d2a7..3f18f4dbd1fe7 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -20,13 +20,14 @@ use crate::hir::map::{definitions::DisambiguatedDefPathData, DefPathData};
 use crate::lint::levels::{LintLevelSets, LintLevelsBuilder};
 use crate::lint::{EarlyLintPassObject, LateLintPassObject};
 use crate::middle::privacy::AccessLevels;
+use crate::middle::stability;
 use crate::session::Session;
 use crate::ty::layout::{LayoutError, LayoutOf, TyLayout};
 use crate::ty::{self, print::Printer, subst::GenericArg, Ty, TyCtxt};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync;
 use rustc_error_codes::*;
-use rustc_errors::{struct_span_err, DiagnosticBuilder};
+use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder};
 use rustc_hir as hir;
 use rustc_hir::def_id::{CrateNum, DefId};
 use rustc_session::lint::BuiltinLintDiagnostics;
@@ -466,6 +467,48 @@ impl LintPassObject for EarlyLintPassObject {}
 
 impl LintPassObject for LateLintPassObject {}
 
+pub fn add_elided_lifetime_in_path_suggestion(
+    sess: &Session,
+    db: &mut DiagnosticBuilder<'_>,
+    n: usize,
+    path_span: Span,
+    incl_angl_brckt: bool,
+    insertion_span: Span,
+    anon_lts: String,
+) {
+    let (replace_span, suggestion) = if incl_angl_brckt {
+        (insertion_span, anon_lts)
+    } else {
+        // When possible, prefer a suggestion that replaces the whole
+        // `Path<T>` expression with `Path<'_, T>`, rather than inserting `'_, `
+        // at a point (which makes for an ugly/confusing label)
+        if let Ok(snippet) = sess.source_map().span_to_snippet(path_span) {
+            // But our spans can get out of whack due to macros; if the place we think
+            // we want to insert `'_` isn't even within the path expression's span, we
+            // should bail out of making any suggestion rather than panicking on a
+            // subtract-with-overflow or string-slice-out-out-bounds (!)
+            // FIXME: can we do better?
+            if insertion_span.lo().0 < path_span.lo().0 {
+                return;
+            }
+            let insertion_index = (insertion_span.lo().0 - path_span.lo().0) as usize;
+            if insertion_index > snippet.len() {
+                return;
+            }
+            let (before, after) = snippet.split_at(insertion_index);
+            (path_span, format!("{}{}{}", before, anon_lts, after))
+        } else {
+            (insertion_span, anon_lts)
+        }
+    };
+    db.span_suggestion(
+        replace_span,
+        &format!("indicate the anonymous lifetime{}", pluralize!(n)),
+        suggestion,
+        Applicability::MachineApplicable,
+    );
+}
+
 pub trait LintContext: Sized {
     type PassObject: LintPassObject;
 
@@ -484,7 +527,85 @@ pub trait LintContext: Sized {
         diagnostic: BuiltinLintDiagnostics,
     ) {
         let mut db = self.lookup(lint, span, msg);
-        super::builtin::run_builtin_lint_diagnostics(diagnostic, self.sess(), &mut db);
+
+        let sess = self.sess();
+        match diagnostic {
+            BuiltinLintDiagnostics::Normal => (),
+            BuiltinLintDiagnostics::BareTraitObject(span, is_global) => {
+                let (sugg, app) = match sess.source_map().span_to_snippet(span) {
+                    Ok(s) if is_global => {
+                        (format!("dyn ({})", s), Applicability::MachineApplicable)
+                    }
+                    Ok(s) => (format!("dyn {}", s), Applicability::MachineApplicable),
+                    Err(_) => ("dyn <type>".to_string(), Applicability::HasPlaceholders),
+                };
+                db.span_suggestion(span, "use `dyn`", sugg, app);
+            }
+            BuiltinLintDiagnostics::AbsPathWithModule(span) => {
+                let (sugg, app) = match sess.source_map().span_to_snippet(span) {
+                    Ok(ref s) => {
+                        // FIXME(Manishearth) ideally the emitting code
+                        // can tell us whether or not this is global
+                        let opt_colon = if s.trim_start().starts_with("::") { "" } else { "::" };
+
+                        (format!("crate{}{}", opt_colon, s), Applicability::MachineApplicable)
+                    }
+                    Err(_) => ("crate::<path>".to_string(), Applicability::HasPlaceholders),
+                };
+                db.span_suggestion(span, "use `crate`", sugg, app);
+            }
+            BuiltinLintDiagnostics::ProcMacroDeriveResolutionFallback(span) => {
+                db.span_label(
+                    span,
+                    "names from parent modules are not accessible without an explicit import",
+                );
+            }
+            BuiltinLintDiagnostics::MacroExpandedMacroExportsAccessedByAbsolutePaths(span_def) => {
+                db.span_note(span_def, "the macro is defined here");
+            }
+            BuiltinLintDiagnostics::ElidedLifetimesInPaths(
+                n,
+                path_span,
+                incl_angl_brckt,
+                insertion_span,
+                anon_lts,
+            ) => {
+                add_elided_lifetime_in_path_suggestion(
+                    sess,
+                    &mut db,
+                    n,
+                    path_span,
+                    incl_angl_brckt,
+                    insertion_span,
+                    anon_lts,
+                );
+            }
+            BuiltinLintDiagnostics::UnknownCrateTypes(span, note, sugg) => {
+                db.span_suggestion(span, &note, sugg, Applicability::MaybeIncorrect);
+            }
+            BuiltinLintDiagnostics::UnusedImports(message, replaces) => {
+                if !replaces.is_empty() {
+                    db.tool_only_multipart_suggestion(
+                        &message,
+                        replaces,
+                        Applicability::MachineApplicable,
+                    );
+                }
+            }
+            BuiltinLintDiagnostics::RedundantImport(spans, ident) => {
+                for (span, is_imported) in spans {
+                    let introduced = if is_imported { "imported" } else { "defined" };
+                    db.span_label(
+                        span,
+                        format!("the item `{}` is already {} here", ident, introduced),
+                    );
+                }
+            }
+            BuiltinLintDiagnostics::DeprecatedMacro(suggestion, span) => {
+                stability::deprecation_suggestion(&mut db, suggestion, span)
+            }
+        }
+
         db.emit();
     }
 
diff --git a/src/librustc/lint/internal.rs b/src/librustc/lint/internal.rs
index 7b99b4af4f9ab..30679226b9b71 100644
--- a/src/librustc/lint/internal.rs
+++ b/src/librustc/lint/internal.rs
@@ -1,13 +1,11 @@
 //! Some lints that are only useful in the compiler or crates that use compiler internals, such as
 //! Clippy.
 
-use crate::lint::{
-    EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintArray, LintContext, LintPass,
-};
+use crate::lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::Applicability;
 use rustc_hir::{GenericArg, HirId, MutTy, Mutability, Path, PathSegment, QPath, Ty, TyKind};
-use rustc_session::declare_tool_lint;
+use rustc_session::{declare_lint_pass, declare_tool_lint, impl_lint_pass};
 use rustc_span::symbol::{sym, Symbol};
 use syntax::ast::{Ident, Item, ItemKind};
 
diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs
index e59e8ce1c0a76..1aa4a43a2f2e3 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -21,6 +21,7 @@
 pub use self::Level::*;
 pub use self::LintSource::*;
 
+use crate::lint::builtin::HardwiredLints;
 use crate::ty::TyCtxt;
 use rustc_data_structures::sync;
 use rustc_errors::{DiagnosticBuilder, DiagnosticId};
@@ -33,48 +34,12 @@ use rustc_span::Span;
 use syntax::ast;
 
 pub use crate::lint::context::{
-    CheckLintNameResult, EarlyContext, LateContext, LintContext, LintStore,
+    add_elided_lifetime_in_path_suggestion, CheckLintNameResult, EarlyContext, LateContext,
+    LintContext, LintStore,
 };
 
 pub use rustc_session::lint::{BufferedEarlyLint, FutureIncompatibleInfo, Level, Lint, LintId};
-
-/// Declares a static `LintArray` and return it as an expression.
-#[macro_export]
-macro_rules! lint_array {
-    ($( $lint:expr ),* ,) => { lint_array!( $($lint),* ) };
-    ($( $lint:expr ),*) => {{
-        vec![$($lint),*]
-    }}
-}
-
-pub type LintArray = Vec<&'static Lint>;
-
-pub trait LintPass {
-    fn name(&self) -> &'static str;
-}
-
-/// Implements `LintPass for $name` with the given list of `Lint` statics.
-#[macro_export]
-macro_rules! impl_lint_pass {
-    ($name:ident => [$($lint:expr),* $(,)?]) => {
-        impl LintPass for $name {
-            fn name(&self) -> &'static str { stringify!($name) }
-        }
-        impl $name {
-            pub fn get_lints() -> LintArray { $crate::lint_array!($($lint),*) }
-        }
-    };
-}
-
-/// Declares a type named `$name` which implements `LintPass`.
-/// To the right of `=>` a comma separated list of `Lint` statics is given.
-#[macro_export]
-macro_rules! declare_lint_pass {
-    ($(#[$m:meta])* $name:ident => [$($lint:expr),* $(,)?]) => {
-        $(#[$m])* #[derive(Copy, Clone)] pub struct $name;
-        $crate::impl_lint_pass!($name => [$($lint),*]);
-    };
-}
+pub use rustc_session::lint::{LintArray, LintPass};
 
 #[macro_export]
 macro_rules! late_lint_methods {
@@ -166,6 +131,8 @@ macro_rules! declare_late_lint_pass {
 
 late_lint_methods!(declare_late_lint_pass, [], ['tcx]);
 
+impl LateLintPass<'_, '_> for HardwiredLints {}
+
 #[macro_export]
 macro_rules! expand_combined_late_lint_pass_method {
     ([$($passes:ident),*], $self: ident, $name: ident, $params:tt) => ({
diff --git a/src/librustc_ast_lowering/path.rs b/src/librustc_ast_lowering/path.rs
index b50295ebaae55..65347d379bd6a 100644
--- a/src/librustc_ast_lowering/path.rs
+++ b/src/librustc_ast_lowering/path.rs
@@ -305,7 +305,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             E0726,
                             "implicit elided lifetime not allowed here"
                         );
-                        rustc::lint::builtin::add_elided_lifetime_in_path_suggestion(
+                        rustc::lint::add_elided_lifetime_in_path_suggestion(
                             &self.sess,
                             &mut err,
                             expected_lifetimes,
diff --git a/src/librustc_lint/array_into_iter.rs b/src/librustc_lint/array_into_iter.rs
index d8ddf7435b458..19d1052d1b243 100644
--- a/src/librustc_lint/array_into_iter.rs
+++ b/src/librustc_lint/array_into_iter.rs
@@ -1,5 +1,4 @@
-use crate::lint::{LateContext, LateLintPass, LintArray, LintContext, LintPass};
-use rustc::lint::FutureIncompatibleInfo;
+use rustc::lint::{FutureIncompatibleInfo, LateContext, LateLintPass, LintContext};
 use rustc::ty;
 use rustc::ty::adjustment::{Adjust, Adjustment};
 use rustc_errors::Applicability;
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 25f6361e0507d..befeb84e57c9c 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -21,13 +21,8 @@
 //! If you define a new `LateLintPass`, you will also need to add it to the
 //! `late_lint_methods!` invocation in `lib.rs`.
 
-use std::fmt::Write;
-
-use lint::{EarlyContext, EarlyLintPass, LateLintPass, LintPass};
-use lint::{LateContext, LintArray, LintContext};
 use rustc::hir::map::Map;
-use rustc::lint;
-use rustc::lint::FutureIncompatibleInfo;
+use rustc::lint::{self, EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
 use rustc::traits::misc::can_type_implement_copy;
 use rustc::ty::{self, layout::VariantIdx, Ty, TyCtxt};
 use rustc_data_structures::fx::FxHashSet;
@@ -39,6 +34,7 @@ use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_hir::{GenericParamKind, PatKind};
 use rustc_hir::{HirIdSet, Node};
+use rustc_session::lint::FutureIncompatibleInfo;
 use rustc_span::edition::Edition;
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::{kw, sym, Symbol};
@@ -52,6 +48,7 @@ use syntax::visit::FnKind;
 use crate::nonstandard_style::{method_context, MethodLateContext};
 
 use log::debug;
+use std::fmt::Write;
 
 // hardwired lints from librustc
 pub use lint::builtin::*;
diff --git a/src/librustc_lint/late.rs b/src/librustc_lint/late.rs
index 07c3b95d69972..d8e0274cf43b9 100644
--- a/src/librustc_lint/late.rs
+++ b/src/librustc_lint/late.rs
@@ -16,7 +16,6 @@
 
 use rustc::hir::map::Map;
 use rustc::lint::LateContext;
-use rustc::lint::LintPass;
 use rustc::lint::{LateLintPass, LateLintPassObject};
 use rustc::ty::{self, TyCtxt};
 use rustc_data_structures::sync::{join, par_iter, ParallelIterator};
@@ -24,12 +23,13 @@ use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
 use rustc_hir::intravisit as hir_visit;
 use rustc_hir::intravisit::Visitor;
+use rustc_session::lint::LintPass;
 use rustc_span::Span;
-use std::slice;
 use syntax::ast;
+use syntax::walk_list;
 
 use log::debug;
-use syntax::walk_list;
+use std::slice;
 
 macro_rules! lint_callback { ($cx:expr, $f:ident, $($args:expr),*) => ({
     $cx.pass.$f(&$cx.context, $($args),*);
diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs
index e272c3af46824..e708ded603b25 100644
--- a/src/librustc_lint/lib.rs
+++ b/src/librustc_lint/lib.rs
@@ -38,11 +38,12 @@ use rustc::lint::builtin::{
     BARE_TRAIT_OBJECTS, ELIDED_LIFETIMES_IN_PATHS, EXPLICIT_OUTLIVES_REQUIREMENTS,
     INTRA_DOC_LINK_RESOLUTION_FAILURE, MISSING_DOC_CODE_EXAMPLES, PRIVATE_DOC_TESTS,
 };
-use rustc::lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintArray, LintPass};
+use rustc::lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass};
 use rustc::ty::query::Providers;
 use rustc::ty::TyCtxt;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
+use rustc_session::lint::{LintArray, LintPass};
 
 use rustc_span::Span;
 use syntax::ast;
diff --git a/src/librustc_lint/non_ascii_idents.rs b/src/librustc_lint/non_ascii_idents.rs
index f30d0bcbdd53f..522aeb6b14420 100644
--- a/src/librustc_lint/non_ascii_idents.rs
+++ b/src/librustc_lint/non_ascii_idents.rs
@@ -1,4 +1,4 @@
-use crate::lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass};
+use rustc::lint::{EarlyContext, EarlyLintPass, LintContext};
 use syntax::ast;
 
 declare_lint! {
diff --git a/src/librustc_lint/nonstandard_style.rs b/src/librustc_lint/nonstandard_style.rs
index 7e5ad0976989e..f75bb9ba32c3d 100644
--- a/src/librustc_lint/nonstandard_style.rs
+++ b/src/librustc_lint/nonstandard_style.rs
@@ -1,6 +1,4 @@
-use lint::{EarlyContext, LateContext, LintArray, LintContext};
-use lint::{EarlyLintPass, LateLintPass, LintPass};
-use rustc::lint;
+use rustc::lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
 use rustc::ty;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
diff --git a/src/librustc_lint/redundant_semicolon.rs b/src/librustc_lint/redundant_semicolon.rs
index 9fc147f2a0c5a..dc18f15fe40cb 100644
--- a/src/librustc_lint/redundant_semicolon.rs
+++ b/src/librustc_lint/redundant_semicolon.rs
@@ -1,4 +1,4 @@
-use crate::lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass};
+use rustc::lint::{EarlyContext, EarlyLintPass, LintContext};
 use rustc_errors::Applicability;
 use syntax::ast::{ExprKind, Stmt, StmtKind};
 
diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs
index f128e25f35bf2..ab6841c0c09bc 100644
--- a/src/librustc_lint/types.rs
+++ b/src/librustc_lint/types.rs
@@ -1,9 +1,6 @@
 #![allow(non_snake_case)]
 
-use crate::hir::def_id::DefId;
-use lint::{LateContext, LintArray, LintContext};
-use lint::{LateLintPass, LintPass};
-use rustc::lint;
+use rustc::lint::{LateContext, LateLintPass, LintContext};
 use rustc::mir::interpret::{sign_extend, truncate};
 use rustc::ty::layout::{self, IntegerExt, LayoutOf, SizeSkeleton, VariantIdx};
 use rustc::ty::subst::SubstsRef;
@@ -11,6 +8,7 @@ use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
+use rustc_hir::def_id::DefId;
 use rustc_hir::{is_range_literal, ExprKind, Node};
 use rustc_index::vec::Idx;
 use rustc_span::source_map;
diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs
index d57f565d919be..da8a23f041e58 100644
--- a/src/librustc_lint/unused.rs
+++ b/src/librustc_lint/unused.rs
@@ -1,7 +1,5 @@
-use lint::{EarlyContext, LateContext, LintArray, LintContext};
-use lint::{EarlyLintPass, LateLintPass, LintPass};
-use rustc::lint;
 use rustc::lint::builtin::UNUSED_ATTRIBUTES;
+use rustc::lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
 use rustc::ty::adjustment;
 use rustc::ty::{self, Ty};
 use rustc_data_structures::fx::FxHashMap;
diff --git a/src/librustc_session/lint.rs b/src/librustc_session/lint.rs
index 24e42928f638a..40d40ce72114d 100644
--- a/src/librustc_session/lint.rs
+++ b/src/librustc_session/lint.rs
@@ -326,3 +326,41 @@ macro_rules! declare_tool_lint {
         };
     );
 }
+
+/// Declares a static `LintArray` and return it as an expression.
+#[macro_export]
+macro_rules! lint_array {
+    ($( $lint:expr ),* ,) => { lint_array!( $($lint),* ) };
+    ($( $lint:expr ),*) => {{
+        vec![$($lint),*]
+    }}
+}
+
+pub type LintArray = Vec<&'static Lint>;
+
+pub trait LintPass {
+    fn name(&self) -> &'static str;
+}
+
+/// Implements `LintPass for $name` with the given list of `Lint` statics.
+#[macro_export]
+macro_rules! impl_lint_pass {
+    ($name:ident => [$($lint:expr),* $(,)?]) => {
+        impl $crate::lint::LintPass for $name {
+            fn name(&self) -> &'static str { stringify!($name) }
+        }
+        impl $name {
+            pub fn get_lints() -> $crate::lint::LintArray { $crate::lint_array!($($lint),*) }
+        }
+    };
+}
+
+/// Declares a type named `$name` which implements `LintPass`.
+/// To the right of `=>` a comma separated list of `Lint` statics is given.
+#[macro_export]
+macro_rules! declare_lint_pass {
+    ($(#[$m:meta])* $name:ident => [$($lint:expr),* $(,)?]) => {
+        $(#[$m])* #[derive(Copy, Clone)] pub struct $name;
+        $crate::impl_lint_pass!($name => [$($lint),*]);
+    };
+}

From 2b44a6c8f4053cf5f8acf026ffdbc329709e5c3d Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 5 Jan 2020 10:35:40 +0100
Subject: [PATCH 30/38] move {rustc -> rustc_session}::lint::builtin

---
 src/librustc/lint/mod.rs                      |  2 +-
 src/librustc_session/lint.rs                  |  2 ++
 .../lint/builtin.rs                           | 27 ++++++++++++++++---
 src/libsyntax/early_buffered_lints.rs         | 26 ++----------------
 4 files changed, 29 insertions(+), 28 deletions(-)
 rename src/{librustc => librustc_session}/lint/builtin.rs (95%)

diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs
index 1aa4a43a2f2e3..4f35ef673efa1 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -38,6 +38,7 @@ pub use crate::lint::context::{
     LintContext, LintStore,
 };
 
+pub use rustc_session::lint::builtin;
 pub use rustc_session::lint::{BufferedEarlyLint, FutureIncompatibleInfo, Level, Lint, LintId};
 pub use rustc_session::lint::{LintArray, LintPass};
 
@@ -331,7 +332,6 @@ pub enum LintSource {
 
 pub type LevelSource = (Level, LintSource);
 
-pub mod builtin;
 mod context;
 pub mod internal;
 mod levels;
diff --git a/src/librustc_session/lint.rs b/src/librustc_session/lint.rs
index 40d40ce72114d..2ba3932c7d97e 100644
--- a/src/librustc_session/lint.rs
+++ b/src/librustc_session/lint.rs
@@ -4,6 +4,8 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHas
 use rustc_span::edition::Edition;
 use rustc_span::{sym, symbol::Ident, MultiSpan, Span, Symbol};
 
+pub mod builtin;
+
 /// Setting for how to handle a lint.
 #[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
 pub enum Level {
diff --git a/src/librustc/lint/builtin.rs b/src/librustc_session/lint/builtin.rs
similarity index 95%
rename from src/librustc/lint/builtin.rs
rename to src/librustc_session/lint/builtin.rs
index 9783bc36ea542..3e8503ef661f0 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc_session/lint/builtin.rs
@@ -4,10 +4,31 @@
 //! compiler code, rather than using their own custom pass. Those
 //! lints are all available in `rustc_lint::builtin`.
 
-use rustc_session::lint::FutureIncompatibleInfo;
-use rustc_session::{declare_lint, declare_lint_pass};
+use crate::lint::FutureIncompatibleInfo;
+use crate::{declare_lint, declare_lint_pass};
 use rustc_span::edition::Edition;
-use syntax::early_buffered_lints::{ILL_FORMED_ATTRIBUTE_INPUT, META_VARIABLE_MISUSE};
+
+declare_lint! {
+    pub ILL_FORMED_ATTRIBUTE_INPUT,
+    Deny,
+    "ill-formed attribute inputs that were previously accepted and used in practice",
+    @future_incompatible = FutureIncompatibleInfo {
+        reference: "issue #57571 <https://github.com/rust-lang/rust/issues/57571>",
+        edition: None,
+    };
+}
+
+declare_lint! {
+    pub META_VARIABLE_MISUSE,
+    Allow,
+    "possible meta-variable misuse at macro definition"
+}
+
+declare_lint! {
+    pub INCOMPLETE_INCLUDE,
+    Deny,
+    "trailing content in included file"
+}
 
 declare_lint! {
     pub EXCEEDING_BITSHIFTS,
diff --git a/src/libsyntax/early_buffered_lints.rs b/src/libsyntax/early_buffered_lints.rs
index 7724107888ad0..8df4eb6c9ace4 100644
--- a/src/libsyntax/early_buffered_lints.rs
+++ b/src/libsyntax/early_buffered_lints.rs
@@ -3,28 +3,6 @@
 //! Since we cannot have a dependency on `librustc`, we implement some types here that are somewhat
 //! redundant. Later, these types can be converted to types for use by the rest of the compiler.
 
-use rustc_session::declare_lint;
+pub use rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT;
+pub use rustc_session::lint::builtin::{INCOMPLETE_INCLUDE, META_VARIABLE_MISUSE};
 pub use rustc_session::lint::BufferedEarlyLint;
-use rustc_session::lint::FutureIncompatibleInfo;
-
-declare_lint! {
-    pub ILL_FORMED_ATTRIBUTE_INPUT,
-    Deny,
-    "ill-formed attribute inputs that were previously accepted and used in practice",
-    @future_incompatible = FutureIncompatibleInfo {
-        reference: "issue #57571 <https://github.com/rust-lang/rust/issues/57571>",
-        edition: None,
-    };
-}
-
-declare_lint! {
-    pub META_VARIABLE_MISUSE,
-    Allow,
-    "possible meta-variable misuse at macro definition"
-}
-
-declare_lint! {
-    pub INCOMPLETE_INCLUDE,
-    Deny,
-    "trailing content in included file"
-}

From f361b71a7dd5516e40fe77f22d28b9ed6d76e7bf Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 5 Jan 2020 10:47:20 +0100
Subject: [PATCH 31/38] nix syntax::early_buffered_lints

---
 Cargo.lock                                 | 3 +++
 src/librustc/lint/mod.rs                   | 2 +-
 src/librustc_builtin_macros/Cargo.toml     | 1 +
 src/librustc_builtin_macros/source_util.rs | 4 ++--
 src/librustc_expand/Cargo.toml             | 1 +
 src/librustc_expand/mbe/macro_check.rs     | 8 ++++----
 src/librustc_parse/Cargo.toml              | 1 +
 src/librustc_parse/validate_attr.rs        | 4 ++--
 src/libsyntax/early_buffered_lints.rs      | 8 --------
 src/libsyntax/lib.rs                       | 2 --
 10 files changed, 15 insertions(+), 19 deletions(-)
 delete mode 100644 src/libsyntax/early_buffered_lints.rs

diff --git a/Cargo.lock b/Cargo.lock
index 5b9db97975001..b8086c83b8dd3 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3386,6 +3386,7 @@ dependencies = [
  "rustc_expand",
  "rustc_feature",
  "rustc_parse",
+ "rustc_session",
  "rustc_span",
  "rustc_target",
  "smallvec 1.0.0",
@@ -3544,6 +3545,7 @@ dependencies = [
  "rustc_feature",
  "rustc_lexer",
  "rustc_parse",
+ "rustc_session",
  "rustc_span",
  "serialize",
  "smallvec 1.0.0",
@@ -3769,6 +3771,7 @@ dependencies = [
  "rustc_errors",
  "rustc_feature",
  "rustc_lexer",
+ "rustc_session",
  "rustc_span",
  "smallvec 1.0.0",
  "syntax",
diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs
index 4f35ef673efa1..4afeb14494850 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -21,11 +21,11 @@
 pub use self::Level::*;
 pub use self::LintSource::*;
 
-use crate::lint::builtin::HardwiredLints;
 use crate::ty::TyCtxt;
 use rustc_data_structures::sync;
 use rustc_errors::{DiagnosticBuilder, DiagnosticId};
 use rustc_hir as hir;
+use rustc_session::lint::builtin::HardwiredLints;
 use rustc_session::{DiagnosticMessageId, Session};
 use rustc_span::hygiene::MacroKind;
 use rustc_span::source_map::{DesugaringKind, ExpnKind, MultiSpan};
diff --git a/src/librustc_builtin_macros/Cargo.toml b/src/librustc_builtin_macros/Cargo.toml
index ca57068fb9a33..f291eaf93580b 100644
--- a/src/librustc_builtin_macros/Cargo.toml
+++ b/src/librustc_builtin_macros/Cargo.toml
@@ -17,6 +17,7 @@ rustc_errors = { path = "../librustc_errors" }
 rustc_feature = { path = "../librustc_feature" }
 rustc_parse = { path = "../librustc_parse" }
 rustc_target = { path = "../librustc_target" }
+rustc_session = { path = "../librustc_session" }
 smallvec = { version = "1.0", features = ["union", "may_dangle"] }
 syntax = { path = "../libsyntax" }
 rustc_expand = { path = "../librustc_expand" }
diff --git a/src/librustc_builtin_macros/source_util.rs b/src/librustc_builtin_macros/source_util.rs
index 19a766de1f47f..dc85a92d272c4 100644
--- a/src/librustc_builtin_macros/source_util.rs
+++ b/src/librustc_builtin_macros/source_util.rs
@@ -1,15 +1,15 @@
 use rustc_expand::base::{self, *};
 use rustc_expand::panictry;
 use rustc_parse::{self, new_sub_parser_from_file, parser::Parser, DirectoryOwnership};
+use rustc_session::lint::builtin::INCOMPLETE_INCLUDE;
 use rustc_span::symbol::Symbol;
+use rustc_span::{self, Pos, Span};
 use syntax::ast;
-use syntax::early_buffered_lints::INCOMPLETE_INCLUDE;
 use syntax::print::pprust;
 use syntax::ptr::P;
 use syntax::token;
 use syntax::tokenstream::TokenStream;
 
-use rustc_span::{self, Pos, Span};
 use smallvec::SmallVec;
 
 use rustc_data_structures::sync::Lrc;
diff --git a/src/librustc_expand/Cargo.toml b/src/librustc_expand/Cargo.toml
index c23846063c1dc..2aa1f93378a40 100644
--- a/src/librustc_expand/Cargo.toml
+++ b/src/librustc_expand/Cargo.toml
@@ -19,5 +19,6 @@ rustc_errors = { path = "../librustc_errors" }
 rustc_feature = { path = "../librustc_feature" }
 rustc_lexer = { path = "../librustc_lexer" }
 rustc_parse = { path = "../librustc_parse" }
+rustc_session = { path = "../librustc_session" }
 smallvec = { version = "1.0", features = ["union", "may_dangle"] }
 syntax = { path = "../libsyntax" }
diff --git a/src/librustc_expand/mbe/macro_check.rs b/src/librustc_expand/mbe/macro_check.rs
index 992764ab6a41d..47865b2fb9fc3 100644
--- a/src/librustc_expand/mbe/macro_check.rs
+++ b/src/librustc_expand/mbe/macro_check.rs
@@ -106,14 +106,14 @@
 //! bound.
 use crate::mbe::{KleeneToken, TokenTree};
 
+use rustc_data_structures::fx::FxHashMap;
+use rustc_session::lint::builtin::META_VARIABLE_MISUSE;
+use rustc_session::parse::ParseSess;
 use rustc_span::symbol::{kw, sym};
+use rustc_span::{symbol::Ident, MultiSpan, Span};
 use syntax::ast::NodeId;
-use syntax::early_buffered_lints::META_VARIABLE_MISUSE;
-use syntax::sess::ParseSess;
 use syntax::token::{DelimToken, Token, TokenKind};
 
-use rustc_data_structures::fx::FxHashMap;
-use rustc_span::{symbol::Ident, MultiSpan, Span};
 use smallvec::SmallVec;
 
 /// Stack represented as linked list.
diff --git a/src/librustc_parse/Cargo.toml b/src/librustc_parse/Cargo.toml
index d41d89902efcd..aa159c55ff284 100644
--- a/src/librustc_parse/Cargo.toml
+++ b/src/librustc_parse/Cargo.toml
@@ -18,6 +18,7 @@ rustc_lexer = { path = "../librustc_lexer" }
 rustc_errors = { path = "../librustc_errors" }
 rustc_error_codes = { path = "../librustc_error_codes" }
 smallvec = { version = "1.0", features = ["union", "may_dangle"] }
+rustc_session = { path = "../librustc_session" }
 rustc_span = { path = "../librustc_span" }
 syntax = { path = "../libsyntax" }
 unicode-normalization = "0.1.11"
diff --git a/src/librustc_parse/validate_attr.rs b/src/librustc_parse/validate_attr.rs
index f089361220777..84562fbb46ff2 100644
--- a/src/librustc_parse/validate_attr.rs
+++ b/src/librustc_parse/validate_attr.rs
@@ -4,10 +4,10 @@ use crate::parse_in;
 
 use rustc_errors::{Applicability, PResult};
 use rustc_feature::{AttributeTemplate, BUILTIN_ATTRIBUTE_MAP};
+use rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT;
+use rustc_session::parse::ParseSess;
 use rustc_span::{sym, Symbol};
 use syntax::ast::{self, Attribute, MacArgs, MacDelimiter, MetaItem, MetaItemKind};
-use syntax::early_buffered_lints::ILL_FORMED_ATTRIBUTE_INPUT;
-use syntax::sess::ParseSess;
 use syntax::tokenstream::DelimSpan;
 
 pub fn check_meta(sess: &ParseSess, attr: &Attribute) {
diff --git a/src/libsyntax/early_buffered_lints.rs b/src/libsyntax/early_buffered_lints.rs
deleted file mode 100644
index 8df4eb6c9ace4..0000000000000
--- a/src/libsyntax/early_buffered_lints.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-//! Allows the buffering of lints for later.
-//!
-//! Since we cannot have a dependency on `librustc`, we implement some types here that are somewhat
-//! redundant. Later, these types can be converted to types for use by the rest of the compiler.
-
-pub use rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT;
-pub use rustc_session::lint::builtin::{INCOMPLETE_INCLUDE, META_VARIABLE_MISUSE};
-pub use rustc_session::lint::BufferedEarlyLint;
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index c03e848b7a420..75c647f2daa16 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -93,8 +93,6 @@ pub mod print {
     pub mod pprust;
 }
 
-pub mod early_buffered_lints;
-
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 
 /// Requirements for a `StableHashingContext` to be used in this crate.

From ed69fbbc44b6e6ba5c41905835deaaae53e6f867 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 5 Jan 2020 10:58:44 +0100
Subject: [PATCH 32/38] ast_validation -> new crate rustc_ast_passes

---
 Cargo.lock                                     | 14 ++++++++++++++
 src/librustc_ast_passes/Cargo.toml             | 18 ++++++++++++++++++
 .../ast_validation.rs                          |  4 ++--
 src/librustc_ast_passes/lib.rs                 |  7 +++++++
 src/librustc_interface/Cargo.toml              |  1 +
 src/librustc_interface/passes.rs               |  4 ++--
 src/librustc_passes/lib.rs                     |  1 -
 7 files changed, 44 insertions(+), 5 deletions(-)
 create mode 100644 src/librustc_ast_passes/Cargo.toml
 rename src/{librustc_passes => librustc_ast_passes}/ast_validation.rs (99%)
 create mode 100644 src/librustc_ast_passes/lib.rs

diff --git a/Cargo.lock b/Cargo.lock
index b8086c83b8dd3..385863abf678a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3374,6 +3374,19 @@ dependencies = [
  "syntax",
 ]
 
+[[package]]
+name = "rustc_ast_passes"
+version = "0.0.0"
+dependencies = [
+ "rustc_data_structures",
+ "rustc_error_codes",
+ "rustc_errors",
+ "rustc_parse",
+ "rustc_session",
+ "rustc_span",
+ "syntax",
+]
+
 [[package]]
 name = "rustc_builtin_macros"
 version = "0.0.0"
@@ -3615,6 +3628,7 @@ dependencies = [
  "rustc",
  "rustc-rayon",
  "rustc_ast_lowering",
+ "rustc_ast_passes",
  "rustc_builtin_macros",
  "rustc_codegen_llvm",
  "rustc_codegen_ssa",
diff --git a/src/librustc_ast_passes/Cargo.toml b/src/librustc_ast_passes/Cargo.toml
new file mode 100644
index 0000000000000..f658618fe8ac0
--- /dev/null
+++ b/src/librustc_ast_passes/Cargo.toml
@@ -0,0 +1,18 @@
+[package]
+authors = ["The Rust Project Developers"]
+name = "rustc_ast_passes"
+version = "0.0.0"
+edition = "2018"
+
+[lib]
+name = "rustc_ast_passes"
+path = "lib.rs"
+
+[dependencies]
+rustc_data_structures = { path = "../librustc_data_structures" }
+rustc_errors = { path = "../librustc_errors", package = "rustc_errors" }
+rustc_error_codes = { path = "../librustc_error_codes" }
+rustc_parse = { path = "../librustc_parse" }
+rustc_session = { path = "../librustc_session" }
+rustc_span = { path = "../librustc_span" }
+syntax = { path = "../libsyntax" }
diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_ast_passes/ast_validation.rs
similarity index 99%
rename from src/librustc_passes/ast_validation.rs
rename to src/librustc_ast_passes/ast_validation.rs
index bc8d8a414c44d..c915b7ba21692 100644
--- a/src/librustc_passes/ast_validation.rs
+++ b/src/librustc_ast_passes/ast_validation.rs
@@ -6,10 +6,10 @@
 // This pass is supposed to perform only simple checks not requiring name resolution
 // or type checking or some other kind of complex analysis.
 
-use rustc::lint::builtin::PATTERNS_IN_FNS_WITHOUT_BODY;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::{struct_span_err, Applicability, FatalError};
 use rustc_parse::validate_attr;
+use rustc_session::lint::builtin::PATTERNS_IN_FNS_WITHOUT_BODY;
 use rustc_session::lint::LintBuffer;
 use rustc_session::Session;
 use rustc_span::source_map::Spanned;
@@ -907,7 +907,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                     }
                 }
 
-                Some(Constness::Const) => bug!("Parser should reject bare `const` on bounds"),
+                Some(Constness::Const) => panic!("Parser should reject bare `const` on bounds"),
                 None => {}
             }
         }
diff --git a/src/librustc_ast_passes/lib.rs b/src/librustc_ast_passes/lib.rs
new file mode 100644
index 0000000000000..8011478ed2fee
--- /dev/null
+++ b/src/librustc_ast_passes/lib.rs
@@ -0,0 +1,7 @@
+//! The `rustc_ast_passes` crate contains passes which validate the AST in `syntax`
+//! parsed by `rustc_parse` and then lowered, after the passes in this crate,
+//! by `rustc_ast_lowering`.
+
+#![feature(slice_patterns)]
+
+pub mod ast_validation;
diff --git a/src/librustc_interface/Cargo.toml b/src/librustc_interface/Cargo.toml
index 9bd19fb38e771..eb0551c606548 100644
--- a/src/librustc_interface/Cargo.toml
+++ b/src/librustc_interface/Cargo.toml
@@ -22,6 +22,7 @@ rustc_span = { path = "../librustc_span" }
 rustc_serialize = { path = "../libserialize", package = "serialize" }
 rustc = { path = "../librustc" }
 rustc_ast_lowering = { path = "../librustc_ast_lowering" }
+rustc_ast_passes = { path = "../librustc_ast_passes" }
 rustc_incremental = { path = "../librustc_incremental" }
 rustc_traits = { path = "../librustc_traits" }
 rustc_data_structures = { path = "../librustc_data_structures" }
diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs
index e8210bfacd3bd..27bed31b9d673 100644
--- a/src/librustc_interface/passes.rs
+++ b/src/librustc_interface/passes.rs
@@ -29,7 +29,7 @@ use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
 use rustc_incremental;
 use rustc_mir as mir;
 use rustc_parse::{parse_crate_from_file, parse_crate_from_source_str};
-use rustc_passes::{self, ast_validation, hir_stats, layout_test};
+use rustc_passes::{self, hir_stats, layout_test};
 use rustc_plugin_impl as plugin;
 use rustc_privacy;
 use rustc_resolve::{Resolver, ResolverArenas};
@@ -344,7 +344,7 @@ fn configure_and_expand_inner<'a>(
     }
 
     let has_proc_macro_decls = sess.time("AST_validation", || {
-        ast_validation::check_crate(sess, &krate, &mut resolver.lint_buffer())
+        rustc_ast_passes::ast_validation::check_crate(sess, &krate, &mut resolver.lint_buffer())
     });
 
     let crate_types = sess.crate_types.borrow();
diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs
index f128d3891d7b8..65eb07b989d83 100644
--- a/src/librustc_passes/lib.rs
+++ b/src/librustc_passes/lib.rs
@@ -17,7 +17,6 @@ extern crate log;
 
 use rustc::ty::query::Providers;
 
-pub mod ast_validation;
 mod check_const;
 pub mod dead;
 mod diagnostic_items;

From 6cbcb830221a5525f333da95c93bd8622da00765 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 5 Jan 2020 11:11:39 +0100
Subject: [PATCH 33/38] {syntax -> rustc_ast_passes}::feature_gate

---
 Cargo.lock                                            |  3 +++
 src/librustc_ast_passes/Cargo.toml                    |  2 ++
 .../check.rs => librustc_ast_passes/feature_gate.rs}  | 11 +++++------
 src/librustc_ast_passes/lib.rs                        |  1 +
 src/librustc_expand/Cargo.toml                        |  1 +
 src/librustc_expand/expand.rs                         |  3 +--
 src/librustc_interface/passes.rs                      |  2 +-
 src/libsyntax/lib.rs                                  |  4 ----
 8 files changed, 14 insertions(+), 13 deletions(-)
 rename src/{libsyntax/feature_gate/check.rs => librustc_ast_passes/feature_gate.rs} (98%)

diff --git a/Cargo.lock b/Cargo.lock
index 385863abf678a..772470d90c573 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3378,9 +3378,11 @@ dependencies = [
 name = "rustc_ast_passes"
 version = "0.0.0"
 dependencies = [
+ "log",
  "rustc_data_structures",
  "rustc_error_codes",
  "rustc_errors",
+ "rustc_feature",
  "rustc_parse",
  "rustc_session",
  "rustc_span",
@@ -3553,6 +3555,7 @@ name = "rustc_expand"
 version = "0.0.0"
 dependencies = [
  "log",
+ "rustc_ast_passes",
  "rustc_data_structures",
  "rustc_errors",
  "rustc_feature",
diff --git a/src/librustc_ast_passes/Cargo.toml b/src/librustc_ast_passes/Cargo.toml
index f658618fe8ac0..dced4a0d15b0c 100644
--- a/src/librustc_ast_passes/Cargo.toml
+++ b/src/librustc_ast_passes/Cargo.toml
@@ -9,9 +9,11 @@ name = "rustc_ast_passes"
 path = "lib.rs"
 
 [dependencies]
+log = "0.4"
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_errors = { path = "../librustc_errors", package = "rustc_errors" }
 rustc_error_codes = { path = "../librustc_error_codes" }
+rustc_feature = { path = "../librustc_feature" }
 rustc_parse = { path = "../librustc_parse" }
 rustc_session = { path = "../librustc_session" }
 rustc_span = { path = "../librustc_span" }
diff --git a/src/libsyntax/feature_gate/check.rs b/src/librustc_ast_passes/feature_gate.rs
similarity index 98%
rename from src/libsyntax/feature_gate/check.rs
rename to src/librustc_ast_passes/feature_gate.rs
index 46a22f12678ee..1e396d6fe8e47 100644
--- a/src/libsyntax/feature_gate/check.rs
+++ b/src/librustc_ast_passes/feature_gate.rs
@@ -1,9 +1,3 @@
-use crate::ast::{self, AssocTyConstraint, AssocTyConstraintKind, NodeId};
-use crate::ast::{GenericParam, GenericParamKind, PatKind, RangeEnd, VariantData};
-use crate::attr;
-use crate::sess::{feature_err, leveled_feature_err, GateStrength, ParseSess};
-use crate::visit::{self, FnKind, Visitor};
-
 use rustc_error_codes::*;
 use rustc_errors::{struct_span_err, Handler};
 use rustc_feature::{AttributeGate, BUILTIN_ATTRIBUTE_MAP};
@@ -11,6 +5,11 @@ use rustc_feature::{Features, GateIssue, UnstableFeatures};
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::sym;
 use rustc_span::Span;
+use syntax::ast::{self, AssocTyConstraint, AssocTyConstraintKind, NodeId};
+use syntax::ast::{GenericParam, GenericParamKind, PatKind, RangeEnd, VariantData};
+use syntax::attr;
+use syntax::sess::{feature_err, leveled_feature_err, GateStrength, ParseSess};
+use syntax::visit::{self, FnKind, Visitor};
 
 use log::debug;
 
diff --git a/src/librustc_ast_passes/lib.rs b/src/librustc_ast_passes/lib.rs
index 8011478ed2fee..f8771471e0002 100644
--- a/src/librustc_ast_passes/lib.rs
+++ b/src/librustc_ast_passes/lib.rs
@@ -5,3 +5,4 @@
 #![feature(slice_patterns)]
 
 pub mod ast_validation;
+pub mod feature_gate;
diff --git a/src/librustc_expand/Cargo.toml b/src/librustc_expand/Cargo.toml
index 2aa1f93378a40..d04dd079be75d 100644
--- a/src/librustc_expand/Cargo.toml
+++ b/src/librustc_expand/Cargo.toml
@@ -14,6 +14,7 @@ doctest = false
 rustc_serialize = { path = "../libserialize", package = "serialize" }
 log = "0.4"
 rustc_span = { path = "../librustc_span" }
+rustc_ast_passes = { path = "../librustc_ast_passes" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_errors = { path = "../librustc_errors" }
 rustc_feature = { path = "../librustc_feature" }
diff --git a/src/librustc_expand/expand.rs b/src/librustc_expand/expand.rs
index f20de93bdeb67..3254d0c913da3 100644
--- a/src/librustc_expand/expand.rs
+++ b/src/librustc_expand/expand.rs
@@ -18,7 +18,6 @@ use rustc_span::{FileName, Span, DUMMY_SP};
 use syntax::ast::{self, AttrItem, Block, Ident, LitKind, NodeId, PatKind, Path};
 use syntax::ast::{ItemKind, MacArgs, MacStmtStyle, StmtKind};
 use syntax::attr::{self, is_builtin_attr, HasAttrs};
-use syntax::feature_gate;
 use syntax::mut_visit::*;
 use syntax::print::pprust;
 use syntax::ptr::P;
@@ -1062,7 +1061,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
     fn check_attributes(&mut self, attrs: &[ast::Attribute]) {
         let features = self.cx.ecfg.features.unwrap();
         for attr in attrs.iter() {
-            feature_gate::check_attribute(attr, self.cx.parse_sess, features);
+            rustc_ast_passes::feature_gate::check_attribute(attr, self.cx.parse_sess, features);
             validate_attr::check_meta(self.cx.parse_sess, attr);
 
             // macros are expanded before any lint passes so this warning has to be hardcoded
diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs
index 27bed31b9d673..951fc63fe953c 100644
--- a/src/librustc_interface/passes.rs
+++ b/src/librustc_interface/passes.rs
@@ -399,7 +399,7 @@ fn configure_and_expand_inner<'a>(
 
     // Needs to go *after* expansion to be able to check the results of macro expansion.
     sess.time("complete_gated_feature_checking", || {
-        syntax::feature_gate::check_crate(
+        rustc_ast_passes::feature_gate::check_crate(
             &krate,
             &sess.parse_sess,
             &sess.features_untracked(),
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index 75c647f2daa16..fcefe3d2a02e4 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -75,10 +75,6 @@ pub mod ast;
 pub mod attr;
 pub mod entry;
 pub mod expand;
-pub mod feature_gate {
-    mod check;
-    pub use check::{check_attribute, check_crate};
-}
 pub mod mut_visit;
 pub mod ptr;
 pub mod show_span;

From ae213db0f5d9a513cae9624b1a341f516bb8e1e9 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 5 Jan 2020 11:21:26 +0100
Subject: [PATCH 34/38] {syntax -> rustc_ast_passes}::show_span

---
 src/librustc_ast_passes/lib.rs                      | 1 +
 src/{libsyntax => librustc_ast_passes}/show_span.rs | 6 +++---
 src/librustc_interface/passes.rs                    | 2 +-
 src/libsyntax/lib.rs                                | 1 -
 4 files changed, 5 insertions(+), 5 deletions(-)
 rename src/{libsyntax => librustc_ast_passes}/show_span.rs (96%)

diff --git a/src/librustc_ast_passes/lib.rs b/src/librustc_ast_passes/lib.rs
index f8771471e0002..eadbc485296e8 100644
--- a/src/librustc_ast_passes/lib.rs
+++ b/src/librustc_ast_passes/lib.rs
@@ -6,3 +6,4 @@
 
 pub mod ast_validation;
 pub mod feature_gate;
+pub mod show_span;
diff --git a/src/libsyntax/show_span.rs b/src/librustc_ast_passes/show_span.rs
similarity index 96%
rename from src/libsyntax/show_span.rs
rename to src/librustc_ast_passes/show_span.rs
index b70e2ce0d3eb7..4596e8ff53dde 100644
--- a/src/libsyntax/show_span.rs
+++ b/src/librustc_ast_passes/show_span.rs
@@ -5,9 +5,9 @@
 
 use std::str::FromStr;
 
-use crate::ast;
-use crate::visit;
-use crate::visit::Visitor;
+use syntax::ast;
+use syntax::visit;
+use syntax::visit::Visitor;
 
 enum Mode {
     Expression,
diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs
index 951fc63fe953c..6322cc4b9a321 100644
--- a/src/librustc_interface/passes.rs
+++ b/src/librustc_interface/passes.rs
@@ -70,7 +70,7 @@ pub fn parse<'a>(sess: &'a Session, input: &Input) -> PResult<'a, ast::Crate> {
     }
 
     if let Some(ref s) = sess.opts.debugging_opts.show_span {
-        syntax::show_span::run(sess.diagnostic(), s, &krate);
+        rustc_ast_passes::show_span::run(sess.diagnostic(), s, &krate);
     }
 
     if sess.opts.debugging_opts.hir_stats {
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index fcefe3d2a02e4..a96fee0cf8f16 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -77,7 +77,6 @@ pub mod entry;
 pub mod expand;
 pub mod mut_visit;
 pub mod ptr;
-pub mod show_span;
 pub use rustc_session::parse as sess;
 pub mod token;
 pub mod tokenstream;

From 7d6548a14a240d57561df9faaf75c31422137caa Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 5 Jan 2020 12:02:45 +0100
Subject: [PATCH 35/38] rustc_passes: remove unused rustc_parse dep

---
 Cargo.lock                     | 1 -
 src/librustc_passes/Cargo.toml | 1 -
 2 files changed, 2 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 772470d90c573..e96bf84e95b6a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3807,7 +3807,6 @@ dependencies = [
  "rustc_feature",
  "rustc_hir",
  "rustc_index",
- "rustc_parse",
  "rustc_session",
  "rustc_span",
  "rustc_target",
diff --git a/src/librustc_passes/Cargo.toml b/src/librustc_passes/Cargo.toml
index 897581b32b5a1..639d8639c4bb2 100644
--- a/src/librustc_passes/Cargo.toml
+++ b/src/librustc_passes/Cargo.toml
@@ -16,7 +16,6 @@ rustc_errors = { path = "../librustc_errors" }
 rustc_feature = { path = "../librustc_feature" }
 rustc_hir = { path = "../librustc_hir" }
 rustc_index = { path = "../librustc_index" }
-rustc_parse = { path = "../librustc_parse" }
 rustc_session = { path = "../librustc_session" }
 rustc_target = { path = "../librustc_target" }
 syntax = { path = "../libsyntax" }

From b4809d0818121480b96904fcb441cade7a735f18 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 5 Jan 2020 13:05:49 +0100
Subject: [PATCH 36/38] appease rustfmt

---
 src/librustc_resolve/imports.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/librustc_resolve/imports.rs b/src/librustc_resolve/imports.rs
index ecd51b1ee0519..8fe17e89444cd 100644
--- a/src/librustc_resolve/imports.rs
+++ b/src/librustc_resolve/imports.rs
@@ -13,8 +13,6 @@ use crate::{NameBinding, NameBindingKind, PathResult, PrivacyError, ToNameBindin
 
 use rustc::hir::exports::Export;
 use rustc::lint::builtin::{PUB_USE_OF_PRIVATE_EXTERN_CRATE, UNUSED_IMPORTS};
-use rustc_session::DiagnosticMessageId;
-use rustc_session::lint::BuiltinLintDiagnostics;
 use rustc::ty;
 use rustc::{bug, span_bug};
 use rustc_data_structures::fx::FxHashSet;
@@ -22,6 +20,8 @@ use rustc_data_structures::ptr_key::PtrKey;
 use rustc_errors::{pluralize, struct_span_err, Applicability};
 use rustc_hir::def::{self, PartialRes};
 use rustc_hir::def_id::DefId;
+use rustc_session::lint::BuiltinLintDiagnostics;
+use rustc_session::DiagnosticMessageId;
 use rustc_span::hygiene::ExpnId;
 use rustc_span::symbol::kw;
 use rustc_span::{MultiSpan, Span};

From d0d1c60f1e3eb8f8a871dbe7517461fc828ad22f Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 5 Jan 2020 13:30:12 +0100
Subject: [PATCH 37/38] pacify tidy by nixing added docs :(

---
 src/librustc_session/parse.rs | 12 ------------
 1 file changed, 12 deletions(-)

diff --git a/src/librustc_session/parse.rs b/src/librustc_session/parse.rs
index 0e342939ff1af..946e77d35595e 100644
--- a/src/librustc_session/parse.rs
+++ b/src/librustc_session/parse.rs
@@ -74,18 +74,6 @@ pub enum GateStrength {
 
 /// Construct a diagnostic for a language feature error due to the given `span`.
 /// The `feature`'s `Symbol` is the one you used in `active.rs` and `rustc_span::symbols`.
-///
-/// Example usage:
-///
-/// ```ignore
-/// feature_err(
-///     parse_sess,
-///     sym::stmt_expr_attributes,
-///     attr.span,
-///     "attributes on expressions are unstable",
-/// )
-/// .emit();
-/// ```
 pub fn feature_err<'a>(
     sess: &'a ParseSess,
     feature: Symbol,

From 682f500c8f5d54197d8974b5c4371306e2faecc8 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Wed, 8 Jan 2020 22:54:08 +0100
Subject: [PATCH 38/38] fix fallout in ui-fulldeps

---
 .../internal-lints/lint_pass_impl_without_macro.rs           | 5 ++---
 .../internal-lints/lint_pass_impl_without_macro.stderr       | 4 ++--
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs b/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs
index 7ce2a1dd9a62d..8d9cbe45fc696 100644
--- a/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs
+++ b/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs
@@ -6,9 +6,8 @@
 extern crate rustc;
 extern crate rustc_session;
 
-use rustc::lint::{LintArray, LintPass};
-use rustc::{declare_lint_pass, impl_lint_pass};
-use rustc_session::declare_lint;
+use rustc_session::lint::{LintArray, LintPass};
+use rustc_session::{declare_lint, declare_lint_pass, impl_lint_pass};
 
 declare_lint! {
     pub TEST_LINT,
diff --git a/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr b/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr
index ad8670c6c83c8..39ac0019aac23 100644
--- a/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr
+++ b/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr
@@ -1,5 +1,5 @@
 error: implementing `LintPass` by hand
-  --> $DIR/lint_pass_impl_without_macro.rs:21:6
+  --> $DIR/lint_pass_impl_without_macro.rs:20:6
    |
 LL | impl LintPass for Foo {
    |      ^^^^^^^^
@@ -12,7 +12,7 @@ LL | #![deny(rustc::lint_pass_impl_without_macro)]
    = help: try using `declare_lint_pass!` or `impl_lint_pass!` instead
 
 error: implementing `LintPass` by hand
-  --> $DIR/lint_pass_impl_without_macro.rs:31:14
+  --> $DIR/lint_pass_impl_without_macro.rs:30:14
    |
 LL |         impl LintPass for Custom {
    |              ^^^^^^^^