about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-01-05 10:57:24 -0500
committerGitHub <noreply@github.com>2024-01-05 10:57:24 -0500
commitda700b39dfea54849f5ceaf3553bd7866a0906e7 (patch)
treee97c15ebde4b63e6552fee09cda42c84e5d98799
parent3087b36eacb5de5a371b753f6fcd7994eb33137c (diff)
parent884322389759a9a9563e492d8bbd96b83c27c2de (diff)
downloadrust-da700b39dfea54849f5ceaf3553bd7866a0906e7.tar.gz
rust-da700b39dfea54849f5ceaf3553bd7866a0906e7.zip
Rollup merge of #119601 - nnethercote:Emitter-cleanups, r=oli-obk
`Emitter` cleanups

Some improvements I found while looking at this code.

r? `@oli-obk`
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs2
-rw-r--r--compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs8
-rw-r--r--compiler/rustc_errors/src/emitter.rs28
-rw-r--r--compiler/rustc_errors/src/lib.rs4
-rw-r--r--compiler/rustc_expand/src/tests.rs4
-rw-r--r--compiler/rustc_session/src/config.rs13
-rw-r--r--compiler/rustc_session/src/session.rs10
-rw-r--r--src/librustdoc/core.rs4
-rw-r--r--src/librustdoc/doctest.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs4
-rw-r--r--src/tools/rustfmt/src/parse/session.rs4
-rw-r--r--tests/ui/lint/use_suggestion_json.rs2
-rw-r--r--tests/ui/lint/use_suggestion_json.stderr424
13 files changed, 465 insertions, 52 deletions
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index 2041ffefe77..fd925b62702 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -1393,7 +1393,7 @@ fn report_ice(
 ) {
     let fallback_bundle =
         rustc_errors::fallback_fluent_bundle(crate::DEFAULT_LOCALE_RESOURCES.to_vec(), false);
-    let emitter = Box::new(rustc_errors::emitter::EmitterWriter::stderr(
+    let emitter = Box::new(rustc_errors::emitter::HumanEmitter::stderr(
         rustc_errors::ColorConfig::Auto,
         fallback_bundle,
     ));
diff --git a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
index 0390829b33b..5c0e210f147 100644
--- a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
+++ b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
@@ -20,7 +20,7 @@ use rustc_span::source_map::SourceMap;
 use rustc_span::SourceFile;
 
 /// Generates diagnostics using annotate-snippet
-pub struct AnnotateSnippetEmitterWriter {
+pub struct AnnotateSnippetEmitter {
     source_map: Option<Lrc<SourceMap>>,
     fluent_bundle: Option<Lrc<FluentBundle>>,
     fallback_bundle: LazyFallbackBundle,
@@ -33,7 +33,7 @@ pub struct AnnotateSnippetEmitterWriter {
     macro_backtrace: bool,
 }
 
-impl Translate for AnnotateSnippetEmitterWriter {
+impl Translate for AnnotateSnippetEmitter {
     fn fluent_bundle(&self) -> Option<&Lrc<FluentBundle>> {
         self.fluent_bundle.as_ref()
     }
@@ -43,7 +43,7 @@ impl Translate for AnnotateSnippetEmitterWriter {
     }
 }
 
-impl Emitter for AnnotateSnippetEmitterWriter {
+impl Emitter for AnnotateSnippetEmitter {
     /// The entry point for the diagnostics generation
     fn emit_diagnostic(&mut self, diag: &Diagnostic) {
         let fluent_args = to_fluent_args(diag.args());
@@ -97,7 +97,7 @@ fn annotation_type_for_level(level: Level) -> AnnotationType {
     }
 }
 
-impl AnnotateSnippetEmitterWriter {
+impl AnnotateSnippetEmitter {
     pub fn new(
         source_map: Option<Lrc<SourceMap>>,
         fluent_bundle: Option<Lrc<FluentBundle>>,
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index 546159c9d13..987832e6937 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -61,13 +61,13 @@ impl HumanReadableErrorType {
         self,
         mut dst: Box<dyn WriteColor + Send>,
         fallback_bundle: LazyFallbackBundle,
-    ) -> EmitterWriter {
+    ) -> HumanEmitter {
         let (short, color_config) = self.unzip();
         let color = color_config.suggests_using_colors();
         if !dst.supports_color() && color {
             dst = Box::new(Ansi::new(dst));
         }
-        EmitterWriter::new(dst, fallback_bundle).short_message(short)
+        HumanEmitter::new(dst, fallback_bundle).short_message(short)
     }
 }
 
@@ -196,13 +196,15 @@ pub trait Emitter: Translate {
     fn emit_diagnostic(&mut self, diag: &Diagnostic);
 
     /// Emit a notification that an artifact has been output.
-    /// This is currently only supported for the JSON format,
-    /// other formats can, and will, simply ignore it.
+    /// Currently only supported for the JSON format.
     fn emit_artifact_notification(&mut self, _path: &Path, _artifact_type: &str) {}
 
+    /// Emit a report about future breakage.
+    /// Currently only supported for the JSON format.
     fn emit_future_breakage_report(&mut self, _diags: Vec<Diagnostic>) {}
 
-    /// Emit list of unused externs
+    /// Emit list of unused externs.
+    /// Currently only supported for the JSON format.
     fn emit_unused_externs(
         &mut self,
         _lint_level: rustc_lint_defs::Level,
@@ -501,7 +503,7 @@ pub trait Emitter: Translate {
     }
 }
 
-impl Translate for EmitterWriter {
+impl Translate for HumanEmitter {
     fn fluent_bundle(&self) -> Option<&Lrc<FluentBundle>> {
         self.fluent_bundle.as_ref()
     }
@@ -511,7 +513,7 @@ impl Translate for EmitterWriter {
     }
 }
 
-impl Emitter for EmitterWriter {
+impl Emitter for HumanEmitter {
     fn source_map(&self) -> Option<&Lrc<SourceMap>> {
         self.sm.as_ref()
     }
@@ -622,7 +624,7 @@ impl ColorConfig {
 
 /// Handles the writing of `HumanReadableErrorType::Default` and `HumanReadableErrorType::Short`
 #[derive(Setters)]
-pub struct EmitterWriter {
+pub struct HumanEmitter {
     #[setters(skip)]
     dst: IntoDynSyncSend<Destination>,
     sm: Option<Lrc<SourceMap>>,
@@ -647,14 +649,14 @@ pub struct FileWithAnnotatedLines {
     multiline_depth: usize,
 }
 
-impl EmitterWriter {
-    pub fn stderr(color_config: ColorConfig, fallback_bundle: LazyFallbackBundle) -> EmitterWriter {
+impl HumanEmitter {
+    pub fn stderr(color_config: ColorConfig, fallback_bundle: LazyFallbackBundle) -> HumanEmitter {
         let dst = from_stderr(color_config);
         Self::create(dst, fallback_bundle)
     }
 
-    fn create(dst: Destination, fallback_bundle: LazyFallbackBundle) -> EmitterWriter {
-        EmitterWriter {
+    fn create(dst: Destination, fallback_bundle: LazyFallbackBundle) -> HumanEmitter {
+        HumanEmitter {
             dst: IntoDynSyncSend(dst),
             sm: None,
             fluent_bundle: None,
@@ -673,7 +675,7 @@ impl EmitterWriter {
     pub fn new(
         dst: Box<dyn WriteColor + Send>,
         fallback_bundle: LazyFallbackBundle,
-    ) -> EmitterWriter {
+    ) -> HumanEmitter {
         Self::create(dst, fallback_bundle)
     }
 
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index a0ded2ae158..25bec9f766b 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -53,7 +53,7 @@ pub use snippet::Style;
 pub use termcolor::{Color, ColorSpec, WriteColor};
 
 use crate::diagnostic_impls::{DelayedAtWithNewline, DelayedAtWithoutNewline};
-use emitter::{is_case_difference, DynEmitter, Emitter, EmitterWriter};
+use emitter::{is_case_difference, DynEmitter, Emitter, HumanEmitter};
 use registry::Registry;
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
 use rustc_data_structures::stable_hasher::{Hash128, StableHasher};
@@ -571,7 +571,7 @@ impl DiagCtxt {
         sm: Option<Lrc<SourceMap>>,
         fallback_bundle: LazyFallbackBundle,
     ) -> Self {
-        let emitter = Box::new(EmitterWriter::stderr(ColorConfig::Auto, fallback_bundle).sm(sm));
+        let emitter = Box::new(HumanEmitter::stderr(ColorConfig::Auto, fallback_bundle).sm(sm));
         Self::with_emitter(emitter)
     }
     pub fn disable_warnings(mut self) -> Self {
diff --git a/compiler/rustc_expand/src/tests.rs b/compiler/rustc_expand/src/tests.rs
index 0b859841828..3c14ad5e7b8 100644
--- a/compiler/rustc_expand/src/tests.rs
+++ b/compiler/rustc_expand/src/tests.rs
@@ -7,7 +7,7 @@ use rustc_span::source_map::{FilePathMapping, SourceMap};
 use rustc_span::{BytePos, Span};
 
 use rustc_data_structures::sync::Lrc;
-use rustc_errors::emitter::EmitterWriter;
+use rustc_errors::emitter::HumanEmitter;
 use rustc_errors::{DiagCtxt, MultiSpan, PResult};
 use termcolor::WriteColor;
 
@@ -30,7 +30,7 @@ fn create_test_handler() -> (DiagCtxt, Lrc<SourceMap>, Arc<Mutex<Vec<u8>>>) {
         vec![crate::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE],
         false,
     );
-    let emitter = EmitterWriter::new(Box::new(Shared { data: output.clone() }), fallback_bundle)
+    let emitter = HumanEmitter::new(Box::new(Shared { data: output.clone() }), fallback_bundle)
         .sm(Some(source_map.clone()))
         .diagnostic_width(Some(140));
     let dcx = DiagCtxt::with_emitter(Box::new(emitter));
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index bff4f027a87..12d8293ecd2 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -2035,23 +2035,14 @@ fn check_error_format_stability(
     early_dcx: &mut EarlyDiagCtxt,
     unstable_opts: &UnstableOptions,
     error_format: ErrorOutputType,
-    json_rendered: HumanReadableErrorType,
 ) {
     if !unstable_opts.unstable_options {
-        if let ErrorOutputType::Json { pretty: true, json_rendered } = error_format {
-            early_dcx.abort_if_error_and_set_error_format(ErrorOutputType::Json {
-                pretty: false,
-                json_rendered,
-            });
+        if let ErrorOutputType::Json { pretty: true, .. } = error_format {
             early_dcx.early_fatal("`--error-format=pretty-json` is unstable");
         }
         if let ErrorOutputType::HumanReadable(HumanReadableErrorType::AnnotateSnippet(_)) =
             error_format
         {
-            early_dcx.abort_if_error_and_set_error_format(ErrorOutputType::Json {
-                pretty: false,
-                json_rendered,
-            });
             early_dcx.early_fatal("`--error-format=human-annotate-rs` is unstable");
         }
     }
@@ -2649,7 +2640,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
     let mut unstable_opts = UnstableOptions::build(early_dcx, matches);
     let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(early_dcx, matches);
 
-    check_error_format_stability(early_dcx, &unstable_opts, error_format, json_rendered);
+    check_error_format_stability(early_dcx, &unstable_opts, error_format);
 
     if !unstable_opts.unstable_options && json_unused_externs.is_enabled() {
         early_dcx.early_fatal(
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index c80990402a9..ce166ae352f 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -17,8 +17,8 @@ use rustc_data_structures::profiling::{SelfProfiler, SelfProfilerRef};
 use rustc_data_structures::sync::{
     AtomicU64, DynSend, DynSync, Lock, Lrc, OneThread, Ordering::SeqCst,
 };
-use rustc_errors::annotate_snippet_emitter_writer::AnnotateSnippetEmitterWriter;
-use rustc_errors::emitter::{DynEmitter, EmitterWriter, HumanReadableErrorType};
+use rustc_errors::annotate_snippet_emitter_writer::AnnotateSnippetEmitter;
+use rustc_errors::emitter::{DynEmitter, HumanEmitter, HumanReadableErrorType};
 use rustc_errors::json::JsonEmitter;
 use rustc_errors::registry::Registry;
 use rustc_errors::{
@@ -1000,7 +1000,7 @@ fn default_emitter(
             let (short, color_config) = kind.unzip();
 
             if let HumanReadableErrorType::AnnotateSnippet(_) = kind {
-                let emitter = AnnotateSnippetEmitterWriter::new(
+                let emitter = AnnotateSnippetEmitter::new(
                     Some(source_map),
                     bundle,
                     fallback_bundle,
@@ -1009,7 +1009,7 @@ fn default_emitter(
                 );
                 Box::new(emitter.ui_testing(sopts.unstable_opts.ui_testing))
             } else {
-                let emitter = EmitterWriter::stderr(color_config, fallback_bundle)
+                let emitter = HumanEmitter::stderr(color_config, fallback_bundle)
                     .fluent_bundle(bundle)
                     .sm(Some(source_map))
                     .short_message(short)
@@ -1504,7 +1504,7 @@ fn mk_emitter(output: ErrorOutputType) -> Box<DynEmitter> {
     let emitter: Box<DynEmitter> = match output {
         config::ErrorOutputType::HumanReadable(kind) => {
             let (short, color_config) = kind.unzip();
-            Box::new(EmitterWriter::stderr(color_config, fallback_bundle).short_message(short))
+            Box::new(HumanEmitter::stderr(color_config, fallback_bundle).short_message(short))
         }
         config::ErrorOutputType::Json { pretty, json_rendered } => Box::new(JsonEmitter::basic(
             pretty,
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 11a035ad3e3..359d5ec485e 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -1,7 +1,7 @@
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::sync::Lrc;
 use rustc_data_structures::unord::UnordSet;
-use rustc_errors::emitter::{DynEmitter, EmitterWriter};
+use rustc_errors::emitter::{DynEmitter, HumanEmitter};
 use rustc_errors::json::JsonEmitter;
 use rustc_errors::TerminalUrl;
 use rustc_feature::UnstableFeatures;
@@ -138,7 +138,7 @@ pub(crate) fn new_dcx(
         ErrorOutputType::HumanReadable(kind) => {
             let (short, color_config) = kind.unzip();
             Box::new(
-                EmitterWriter::stderr(color_config, fallback_bundle)
+                HumanEmitter::stderr(color_config, fallback_bundle)
                     .sm(source_map.map(|sm| sm as _))
                     .short_message(short)
                     .teach(unstable_opts.teach)
diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs
index c74f2ecb018..9a900625268 100644
--- a/src/librustdoc/doctest.rs
+++ b/src/librustdoc/doctest.rs
@@ -557,7 +557,7 @@ pub(crate) fn make_test(
     // crate already is included.
     let result = rustc_driver::catch_fatal_errors(|| {
         rustc_span::create_session_if_not_set_then(edition, |_| {
-            use rustc_errors::emitter::{Emitter, EmitterWriter};
+            use rustc_errors::emitter::{Emitter, HumanEmitter};
             use rustc_errors::DiagCtxt;
             use rustc_parse::parser::ForceCollect;
             use rustc_span::source_map::FilePathMapping;
@@ -572,11 +572,11 @@ pub(crate) fn make_test(
                 rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(),
                 false,
             );
-            supports_color = EmitterWriter::stderr(ColorConfig::Auto, fallback_bundle.clone())
+            supports_color = HumanEmitter::stderr(ColorConfig::Auto, fallback_bundle.clone())
                 .diagnostic_width(Some(80))
                 .supports_color();
 
-            let emitter = EmitterWriter::new(Box::new(io::sink()), fallback_bundle);
+            let emitter = HumanEmitter::new(Box::new(io::sink()), fallback_bundle);
 
             // FIXME(misdreavus): pass `-Z treat-err-as-bug` to the doctest parser
             let dcx = DiagCtxt::with_emitter(Box::new(emitter)).disable_warnings();
@@ -739,7 +739,7 @@ fn check_if_attr_is_complete(source: &str, edition: Edition) -> bool {
     }
     rustc_driver::catch_fatal_errors(|| {
         rustc_span::create_session_if_not_set_then(edition, |_| {
-            use rustc_errors::emitter::EmitterWriter;
+            use rustc_errors::emitter::HumanEmitter;
             use rustc_errors::DiagCtxt;
             use rustc_span::source_map::FilePathMapping;
 
@@ -752,7 +752,7 @@ fn check_if_attr_is_complete(source: &str, edition: Edition) -> bool {
                 false,
             );
 
-            let emitter = EmitterWriter::new(Box::new(io::sink()), fallback_bundle);
+            let emitter = HumanEmitter::new(Box::new(io::sink()), fallback_bundle);
 
             let dcx = DiagCtxt::with_emitter(Box::new(emitter)).disable_warnings();
             let sess = ParseSess::with_dcx(dcx, sm);
diff --git a/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs b/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs
index c639813a3f9..a744b69ecb4 100644
--- a/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs
@@ -5,7 +5,7 @@ use crate::doc::{NEEDLESS_DOCTEST_MAIN, TEST_ATTR_IN_DOCTEST};
 use clippy_utils::diagnostics::span_lint;
 use rustc_ast::{CoroutineKind, Fn, FnRetTy, Item, ItemKind};
 use rustc_data_structures::sync::Lrc;
-use rustc_errors::emitter::EmitterWriter;
+use rustc_errors::emitter::HumanEmitter;
 use rustc_errors::DiagCtxt;
 use rustc_lint::LateContext;
 use rustc_parse::maybe_new_parser_from_source_str;
@@ -44,7 +44,7 @@ pub fn check(
 
                 let fallback_bundle =
                     rustc_errors::fallback_fluent_bundle(rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), false);
-                let emitter = EmitterWriter::new(Box::new(io::sink()), fallback_bundle);
+                let emitter = HumanEmitter::new(Box::new(io::sink()), fallback_bundle);
                 let dcx = DiagCtxt::with_emitter(Box::new(emitter)).disable_warnings();
                 #[expect(clippy::arc_with_non_send_sync)] // `Lrc` is expected by with_dcx
                 let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
diff --git a/src/tools/rustfmt/src/parse/session.rs b/src/tools/rustfmt/src/parse/session.rs
index 8303c03e1eb..2663f16b8e8 100644
--- a/src/tools/rustfmt/src/parse/session.rs
+++ b/src/tools/rustfmt/src/parse/session.rs
@@ -2,7 +2,7 @@ use std::path::Path;
 use std::sync::atomic::{AtomicBool, Ordering};
 
 use rustc_data_structures::sync::{IntoDynSyncSend, Lrc};
-use rustc_errors::emitter::{DynEmitter, Emitter, EmitterWriter};
+use rustc_errors::emitter::{DynEmitter, Emitter, HumanEmitter};
 use rustc_errors::translation::Translate;
 use rustc_errors::{ColorConfig, DiagCtxt, Diagnostic, Level as DiagnosticLevel};
 use rustc_session::parse::ParseSess as RawParseSess;
@@ -139,7 +139,7 @@ fn default_dcx(
             rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(),
             false,
         );
-        Box::new(EmitterWriter::stderr(emit_color, fallback_bundle).sm(Some(source_map.clone())))
+        Box::new(HumanEmitter::stderr(emit_color, fallback_bundle).sm(Some(source_map.clone())))
     };
     DiagCtxt::with_emitter(Box::new(SilentOnIgnoredFilesEmitter {
         has_non_ignorable_parser_errors: false,
diff --git a/tests/ui/lint/use_suggestion_json.rs b/tests/ui/lint/use_suggestion_json.rs
index 7d641e08bf0..6a947f14302 100644
--- a/tests/ui/lint/use_suggestion_json.rs
+++ b/tests/ui/lint/use_suggestion_json.rs
@@ -1,6 +1,6 @@
 // ignore-windows
 // ignore-sgx std::os::fortanix_sgx::usercalls::alloc::Iter changes compiler suggestions
-// compile-flags: --error-format pretty-json --json=diagnostic-rendered-ansi
+// compile-flags: --error-format pretty-json --json=diagnostic-rendered-ansi -Z unstable-options
 
 // The output for humans should just highlight the whole span without showing
 // the suggested replacement, but we also want to test that suggested
diff --git a/tests/ui/lint/use_suggestion_json.stderr b/tests/ui/lint/use_suggestion_json.stderr
index 7dfd269a4e2..b3c973680b7 100644
--- a/tests/ui/lint/use_suggestion_json.stderr
+++ b/tests/ui/lint/use_suggestion_json.stderr
@@ -1,3 +1,423 @@
-{"$message_type":"diagnostic","message":"`--error-format=pretty-json` is unstable","code":null,"level":"error","spans":[],"children":[],"rendered":"\u001b[0m\u001b[1m\u001b[38;5;9merror\u001b[0m\u001b[0m\u001b[1m: `--error-format=pretty-json` is unstable\u001b[0m
+{
+  "$message_type": "diagnostic",
+  "message": "cannot find type `Iter` in this scope",
+  "code": {
+    "code": "E0412",
+    "explanation": "A used type name is not in scope.
 
-"}
+Erroneous code examples:
+
+```compile_fail,E0412
+impl Something {} // error: type name `Something` is not in scope
+
+// or:
+
+trait Foo {
+    fn bar(N); // error: type name `N` is not in scope
+}
+
+// or:
+
+fn foo(x: T) {} // type name `T` is not in scope
+```
+
+To fix this error, please verify you didn't misspell the type name, you did
+declare it or imported it into the scope. Examples:
+
+```
+struct Something;
+
+impl Something {} // ok!
+
+// or:
+
+trait Foo {
+    type N;
+
+    fn bar(_: Self::N); // ok!
+}
+
+// or:
+
+fn foo<T>(x: T) {} // ok!
+```
+
+Another case that causes this error is when a type is imported into a parent
+module. To fix this, you can follow the suggestion and use File directly or
+`use super::File;` which will import the types from the parent namespace. An
+example that causes this error is below:
+
+```compile_fail,E0412
+use std::fs::File;
+
+mod foo {
+    fn some_function(f: File) {}
+}
+```
+
+```
+use std::fs::File;
+
+mod foo {
+    // either
+    use super::File;
+    // or
+    // use std::fs::File;
+    fn foo(f: File) {}
+}
+# fn main() {} // don't insert it for us; that'll break imports
+```
+"
+  },
+  "level": "error",
+  "spans": [
+    {
+      "file_name": "$DIR/use_suggestion_json.rs",
+      "byte_start": 561,
+      "byte_end": 565,
+      "line_start": 12,
+      "line_end": 12,
+      "column_start": 12,
+      "column_end": 16,
+      "is_primary": true,
+      "text": [
+        {
+          "text": "    let x: Iter;",
+          "highlight_start": 12,
+          "highlight_end": 16
+        }
+      ],
+      "label": "not found in this scope",
+      "suggested_replacement": null,
+      "suggestion_applicability": null,
+      "expansion": null
+    }
+  ],
+  "children": [
+    {
+      "message": "consider importing one of these items",
+      "code": null,
+      "level": "help",
+      "spans": [
+        {
+          "file_name": "$DIR/use_suggestion_json.rs",
+          "byte_start": 538,
+          "byte_end": 538,
+          "line_start": 11,
+          "line_end": 11,
+          "column_start": 1,
+          "column_end": 1,
+          "is_primary": true,
+          "text": [
+            {
+              "text": "fn main() {",
+              "highlight_start": 1,
+              "highlight_end": 1
+            }
+          ],
+          "label": null,
+          "suggested_replacement": "use std::collections::binary_heap::Iter;
+
+",
+          "suggestion_applicability": "MaybeIncorrect",
+          "expansion": null
+        },
+        {
+          "file_name": "$DIR/use_suggestion_json.rs",
+          "byte_start": 538,
+          "byte_end": 538,
+          "line_start": 11,
+          "line_end": 11,
+          "column_start": 1,
+          "column_end": 1,
+          "is_primary": true,
+          "text": [
+            {
+              "text": "fn main() {",
+              "highlight_start": 1,
+              "highlight_end": 1
+            }
+          ],
+          "label": null,
+          "suggested_replacement": "use std::collections::btree_map::Iter;
+
+",
+          "suggestion_applicability": "MaybeIncorrect",
+          "expansion": null
+        },
+        {
+          "file_name": "$DIR/use_suggestion_json.rs",
+          "byte_start": 538,
+          "byte_end": 538,
+          "line_start": 11,
+          "line_end": 11,
+          "column_start": 1,
+          "column_end": 1,
+          "is_primary": true,
+          "text": [
+            {
+              "text": "fn main() {",
+              "highlight_start": 1,
+              "highlight_end": 1
+            }
+          ],
+          "label": null,
+          "suggested_replacement": "use std::collections::btree_set::Iter;
+
+",
+          "suggestion_applicability": "MaybeIncorrect",
+          "expansion": null
+        },
+        {
+          "file_name": "$DIR/use_suggestion_json.rs",
+          "byte_start": 538,
+          "byte_end": 538,
+          "line_start": 11,
+          "line_end": 11,
+          "column_start": 1,
+          "column_end": 1,
+          "is_primary": true,
+          "text": [
+            {
+              "text": "fn main() {",
+              "highlight_start": 1,
+              "highlight_end": 1
+            }
+          ],
+          "label": null,
+          "suggested_replacement": "use std::collections::hash_map::Iter;
+
+",
+          "suggestion_applicability": "MaybeIncorrect",
+          "expansion": null
+        },
+        {
+          "file_name": "$DIR/use_suggestion_json.rs",
+          "byte_start": 538,
+          "byte_end": 538,
+          "line_start": 11,
+          "line_end": 11,
+          "column_start": 1,
+          "column_end": 1,
+          "is_primary": true,
+          "text": [
+            {
+              "text": "fn main() {",
+              "highlight_start": 1,
+              "highlight_end": 1
+            }
+          ],
+          "label": null,
+          "suggested_replacement": "use std::collections::hash_set::Iter;
+
+",
+          "suggestion_applicability": "MaybeIncorrect",
+          "expansion": null
+        },
+        {
+          "file_name": "$DIR/use_suggestion_json.rs",
+          "byte_start": 538,
+          "byte_end": 538,
+          "line_start": 11,
+          "line_end": 11,
+          "column_start": 1,
+          "column_end": 1,
+          "is_primary": true,
+          "text": [
+            {
+              "text": "fn main() {",
+              "highlight_start": 1,
+              "highlight_end": 1
+            }
+          ],
+          "label": null,
+          "suggested_replacement": "use std::collections::linked_list::Iter;
+
+",
+          "suggestion_applicability": "MaybeIncorrect",
+          "expansion": null
+        },
+        {
+          "file_name": "$DIR/use_suggestion_json.rs",
+          "byte_start": 538,
+          "byte_end": 538,
+          "line_start": 11,
+          "line_end": 11,
+          "column_start": 1,
+          "column_end": 1,
+          "is_primary": true,
+          "text": [
+            {
+              "text": "fn main() {",
+              "highlight_start": 1,
+              "highlight_end": 1
+            }
+          ],
+          "label": null,
+          "suggested_replacement": "use std::collections::vec_deque::Iter;
+
+",
+          "suggestion_applicability": "MaybeIncorrect",
+          "expansion": null
+        },
+        {
+          "file_name": "$DIR/use_suggestion_json.rs",
+          "byte_start": 538,
+          "byte_end": 538,
+          "line_start": 11,
+          "line_end": 11,
+          "column_start": 1,
+          "column_end": 1,
+          "is_primary": true,
+          "text": [
+            {
+              "text": "fn main() {",
+              "highlight_start": 1,
+              "highlight_end": 1
+            }
+          ],
+          "label": null,
+          "suggested_replacement": "use std::option::Iter;
+
+",
+          "suggestion_applicability": "MaybeIncorrect",
+          "expansion": null
+        },
+        {
+          "file_name": "$DIR/use_suggestion_json.rs",
+          "byte_start": 538,
+          "byte_end": 538,
+          "line_start": 11,
+          "line_end": 11,
+          "column_start": 1,
+          "column_end": 1,
+          "is_primary": true,
+          "text": [
+            {
+              "text": "fn main() {",
+              "highlight_start": 1,
+              "highlight_end": 1
+            }
+          ],
+          "label": null,
+          "suggested_replacement": "use std::path::Iter;
+
+",
+          "suggestion_applicability": "MaybeIncorrect",
+          "expansion": null
+        },
+        {
+          "file_name": "$DIR/use_suggestion_json.rs",
+          "byte_start": 538,
+          "byte_end": 538,
+          "line_start": 11,
+          "line_end": 11,
+          "column_start": 1,
+          "column_end": 1,
+          "is_primary": true,
+          "text": [
+            {
+              "text": "fn main() {",
+              "highlight_start": 1,
+              "highlight_end": 1
+            }
+          ],
+          "label": null,
+          "suggested_replacement": "use std::result::Iter;
+
+",
+          "suggestion_applicability": "MaybeIncorrect",
+          "expansion": null
+        },
+        {
+          "file_name": "$DIR/use_suggestion_json.rs",
+          "byte_start": 538,
+          "byte_end": 538,
+          "line_start": 11,
+          "line_end": 11,
+          "column_start": 1,
+          "column_end": 1,
+          "is_primary": true,
+          "text": [
+            {
+              "text": "fn main() {",
+              "highlight_start": 1,
+              "highlight_end": 1
+            }
+          ],
+          "label": null,
+          "suggested_replacement": "use std::slice::Iter;
+
+",
+          "suggestion_applicability": "MaybeIncorrect",
+          "expansion": null
+        },
+        {
+          "file_name": "$DIR/use_suggestion_json.rs",
+          "byte_start": 538,
+          "byte_end": 538,
+          "line_start": 11,
+          "line_end": 11,
+          "column_start": 1,
+          "column_end": 1,
+          "is_primary": true,
+          "text": [
+            {
+              "text": "fn main() {",
+              "highlight_start": 1,
+              "highlight_end": 1
+            }
+          ],
+          "label": null,
+          "suggested_replacement": "use std::sync::mpsc::Iter;
+
+",
+          "suggestion_applicability": "MaybeIncorrect",
+          "expansion": null
+        }
+      ],
+      "children": [],
+      "rendered": null
+    }
+  ],
+  "rendered": "\u001b[0m\u001b[1m\u001b[38;5;9merror[E0412]\u001b[0m\u001b[0m\u001b[1m: cannot find type `Iter` in this scope\u001b[0m
+\u001b[0m  \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m--> \u001b[0m\u001b[0m$DIR/use_suggestion_json.rs:12:12\u001b[0m
+\u001b[0m   \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m
+\u001b[0m\u001b[1m\u001b[38;5;12mLL\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m    let x: Iter;\u001b[0m
+\u001b[0m   \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m| \u001b[0m\u001b[0m           \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;9m^^^^\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;9mnot found in this scope\u001b[0m
+\u001b[0m   \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m
+\u001b[0m\u001b[1m\u001b[38;5;14mhelp\u001b[0m\u001b[0m: consider importing one of these items\u001b[0m
+\u001b[0m   \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m
+\u001b[0m\u001b[1m\u001b[38;5;12mLL\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[38;5;10m+ use std::collections::binary_heap::Iter;\u001b[0m
+\u001b[0m   \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m
+\u001b[0m\u001b[1m\u001b[38;5;12mLL\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[38;5;10m+ use std::collections::btree_map::Iter;\u001b[0m
+\u001b[0m   \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m
+\u001b[0m\u001b[1m\u001b[38;5;12mLL\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[38;5;10m+ use std::collections::btree_set::Iter;\u001b[0m
+\u001b[0m   \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m
+\u001b[0m\u001b[1m\u001b[38;5;12mLL\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[38;5;10m+ use std::collections::hash_map::Iter;\u001b[0m
+\u001b[0m   \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m
+\u001b[0m     and 8 other candidates\u001b[0m
+
+"
+}
+{
+  "$message_type": "diagnostic",
+  "message": "aborting due to 1 previous error",
+  "code": null,
+  "level": "error",
+  "spans": [],
+  "children": [],
+  "rendered": "\u001b[0m\u001b[1m\u001b[38;5;9merror\u001b[0m\u001b[0m\u001b[1m: aborting due to 1 previous error\u001b[0m
+
+"
+}
+{
+  "$message_type": "diagnostic",
+  "message": "For more information about this error, try `rustc --explain E0412`.",
+  "code": null,
+  "level": "failure-note",
+  "spans": [],
+  "children": [],
+  "rendered": "\u001b[0m\u001b[1mFor more information about this error, try `rustc --explain E0412`.\u001b[0m
+"
+}