Skip to content

Commit 4401e47

Browse files
authored
Get diagnostics directly in rustc-driver-getting-diagnostics example (#1857)
1 parent c2717f6 commit 4401e47

File tree

1 file changed

+46
-17
lines changed

1 file changed

+46
-17
lines changed

examples/rustc-driver-getting-diagnostics.rs

+46-17
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,41 @@ extern crate rustc_interface;
99
extern crate rustc_session;
1010
extern crate rustc_span;
1111

12-
use rustc_errors::registry;
12+
use rustc_errors::{
13+
emitter::Emitter, registry, translation::Translate, DiagCtxt, Diagnostic, FluentBundle,
14+
};
1315
use rustc_session::config;
14-
use std::path;
15-
use std::process;
16-
use std::str;
17-
use std::sync;
16+
use rustc_span::source_map::SourceMap;
17+
18+
use std::{
19+
path, process, str,
20+
sync::{Arc, Mutex},
21+
};
22+
23+
struct DebugEmitter {
24+
source_map: Arc<SourceMap>,
25+
diagnostics: Arc<Mutex<Vec<Diagnostic>>>,
26+
}
27+
28+
impl Translate for DebugEmitter {
29+
fn fluent_bundle(&self) -> Option<&Arc<FluentBundle>> {
30+
None
31+
}
32+
33+
fn fallback_fluent_bundle(&self) -> &FluentBundle {
34+
panic!("this emitter should not translate message")
35+
}
36+
}
37+
38+
impl Emitter for DebugEmitter {
39+
fn emit_diagnostic(&mut self, diag: &Diagnostic) {
40+
self.diagnostics.lock().unwrap().push(diag.clone());
41+
}
42+
43+
fn source_map(&self) -> Option<&Arc<SourceMap>> {
44+
Some(&self.source_map)
45+
}
46+
}
1847

1948
fn main() {
2049
let out = process::Command::new("rustc")
@@ -23,17 +52,11 @@ fn main() {
2352
.output()
2453
.unwrap();
2554
let sysroot = str::from_utf8(&out.stdout).unwrap().trim();
26-
let buffer = sync::Arc::new(sync::Mutex::new(Vec::new()));
55+
let buffer: Arc<Mutex<Vec<Diagnostic>>> = Arc::default();
56+
let diagnostics = buffer.clone();
2757
let config = rustc_interface::Config {
2858
opts: config::Options {
2959
maybe_sysroot: Some(path::PathBuf::from(sysroot)),
30-
// Configure the compiler to emit diagnostics in compact JSON format.
31-
error_format: config::ErrorOutputType::Json {
32-
pretty: false,
33-
json_rendered: rustc_errors::emitter::HumanReadableErrorType::Default(
34-
rustc_errors::emitter::ColorConfig::Never,
35-
),
36-
},
3760
..config::Options::default()
3861
},
3962
// This program contains a type error.
@@ -53,15 +76,20 @@ fn main() {
5376
file_loader: None,
5477
locale_resources: rustc_driver::DEFAULT_LOCALE_RESOURCES,
5578
lint_caps: rustc_hash::FxHashMap::default(),
56-
parse_sess_created: None,
79+
parse_sess_created: Some(Box::new(|parse_sess| {
80+
parse_sess.dcx = DiagCtxt::with_emitter(Box::new(DebugEmitter {
81+
source_map: parse_sess.clone_source_map(),
82+
diagnostics,
83+
}))
84+
})),
5785
register_lints: None,
5886
override_queries: None,
5987
registry: registry::Registry::new(rustc_error_codes::DIAGNOSTICS),
6088
make_codegen_backend: None,
6189
expanded_args: Vec::new(),
6290
ice_file: None,
6391
hash_untracked_state: None,
64-
using_internal_features: sync::Arc::default(),
92+
using_internal_features: Arc::default(),
6593
};
6694
rustc_interface::run_compiler(config, |compiler| {
6795
compiler.enter(|queries| {
@@ -72,6 +100,7 @@ fn main() {
72100
});
73101
});
74102
// Read buffered diagnostics.
75-
let diagnostics = String::from_utf8(buffer.lock().unwrap().clone()).unwrap();
76-
println!("{diagnostics}");
103+
buffer.lock().unwrap().iter().for_each(|diagnostic| {
104+
println!("{diagnostic:#?}");
105+
});
77106
}

0 commit comments

Comments
 (0)