diff --git a/examples/rustc-driver-getting-diagnostics.rs b/examples/rustc-driver-getting-diagnostics.rs index 6708b4985..fd9448277 100644 --- a/examples/rustc-driver-getting-diagnostics.rs +++ b/examples/rustc-driver-getting-diagnostics.rs @@ -9,12 +9,41 @@ extern crate rustc_interface; extern crate rustc_session; extern crate rustc_span; -use rustc_errors::registry; +use rustc_errors::{ + emitter::Emitter, registry, translation::Translate, DiagCtxt, Diagnostic, FluentBundle, +}; use rustc_session::config; -use std::path; -use std::process; -use std::str; -use std::sync; +use rustc_span::source_map::SourceMap; + +use std::{ + path, process, str, + sync::{Arc, Mutex}, +}; + +struct DebugEmitter { + source_map: Arc, + diagnostics: Arc>>, +} + +impl Translate for DebugEmitter { + fn fluent_bundle(&self) -> Option<&Arc> { + None + } + + fn fallback_fluent_bundle(&self) -> &FluentBundle { + panic!("this emitter should not translate message") + } +} + +impl Emitter for DebugEmitter { + fn emit_diagnostic(&mut self, diag: &Diagnostic) { + self.diagnostics.lock().unwrap().push(diag.clone()); + } + + fn source_map(&self) -> Option<&Arc> { + Some(&self.source_map) + } +} fn main() { let out = process::Command::new("rustc") @@ -23,17 +52,11 @@ fn main() { .output() .unwrap(); let sysroot = str::from_utf8(&out.stdout).unwrap().trim(); - let buffer = sync::Arc::new(sync::Mutex::new(Vec::new())); + let buffer: Arc>> = Arc::default(); + let diagnostics = buffer.clone(); let config = rustc_interface::Config { opts: config::Options { maybe_sysroot: Some(path::PathBuf::from(sysroot)), - // Configure the compiler to emit diagnostics in compact JSON format. - error_format: config::ErrorOutputType::Json { - pretty: false, - json_rendered: rustc_errors::emitter::HumanReadableErrorType::Default( - rustc_errors::emitter::ColorConfig::Never, - ), - }, ..config::Options::default() }, // This program contains a type error. @@ -53,7 +76,12 @@ fn main() { file_loader: None, locale_resources: rustc_driver::DEFAULT_LOCALE_RESOURCES, lint_caps: rustc_hash::FxHashMap::default(), - parse_sess_created: None, + parse_sess_created: Some(Box::new(|parse_sess| { + parse_sess.dcx = DiagCtxt::with_emitter(Box::new(DebugEmitter { + source_map: parse_sess.clone_source_map(), + diagnostics, + })) + })), register_lints: None, override_queries: None, registry: registry::Registry::new(rustc_error_codes::DIAGNOSTICS), @@ -61,7 +89,7 @@ fn main() { expanded_args: Vec::new(), ice_file: None, hash_untracked_state: None, - using_internal_features: sync::Arc::default(), + using_internal_features: Arc::default(), }; rustc_interface::run_compiler(config, |compiler| { compiler.enter(|queries| { @@ -72,6 +100,7 @@ fn main() { }); }); // Read buffered diagnostics. - let diagnostics = String::from_utf8(buffer.lock().unwrap().clone()).unwrap(); - println!("{diagnostics}"); + buffer.lock().unwrap().iter().for_each(|diagnostic| { + println!("{diagnostic:#?}"); + }); }