Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get diagnostics directly in rustc-driver-getting-diagnostics example #1857

Merged
merged 1 commit into from
Jan 21, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 46 additions & 17 deletions examples/rustc-driver-getting-diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<SourceMap>,
diagnostics: Arc<Mutex<Vec<Diagnostic>>>,
}

impl Translate for DebugEmitter {
fn fluent_bundle(&self) -> Option<&Arc<FluentBundle>> {
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<SourceMap>> {
Some(&self.source_map)
}
}

fn main() {
let out = process::Command::new("rustc")
Expand All @@ -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<Mutex<Vec<Diagnostic>>> = 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.
Expand All @@ -53,15 +76,20 @@ 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),
make_codegen_backend: None,
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| {
Expand All @@ -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:#?}");
});
}