Skip to content

Commit e30551f

Browse files
authored
Rollup merge of rust-lang#50541 - QuietMisdreavus:rustdoc-errors, r=GuillaumeGomez
rustdoc: replace most (e)println! statements with structured warnings/errors Turns out, the rustc diagnostic handler doesn't need a whole lot of setup that we weren't already doing. For errors that occur outside a "dealing with source code" context, we can just use the format/color config we were already parsing and make up a `Handler` that we can emit structured warnings/errors from. So i did that. This will make it way easier to test things with `rustdoc-ui` tests, since those require the JSON error output. (In fact, this PR is a yak shave for a different one where i was trying to do just that. `>_>`)
2 parents fcea9b1 + c3fd12f commit e30551f

File tree

5 files changed

+144
-122
lines changed

5 files changed

+144
-122
lines changed

Diff for: src/librustdoc/core.rs

+53-32
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,57 @@ impl DocAccessLevels for AccessLevels<DefId> {
117117
}
118118
}
119119

120+
/// Creates a new diagnostic `Handler` that can be used to emit warnings and errors.
121+
///
122+
/// If the given `error_format` is `ErrorOutputType::Json` and no `CodeMap` is given, a new one
123+
/// will be created for the handler.
124+
pub fn new_handler(error_format: ErrorOutputType, codemap: Option<Lrc<codemap::CodeMap>>)
125+
-> errors::Handler
126+
{
127+
// rustdoc doesn't override (or allow to override) anything from this that is relevant here, so
128+
// stick to the defaults
129+
let sessopts = config::basic_options();
130+
let emitter: Box<dyn Emitter + sync::Send> = match error_format {
131+
ErrorOutputType::HumanReadable(color_config) => Box::new(
132+
EmitterWriter::stderr(
133+
color_config,
134+
codemap.map(|cm| cm as _),
135+
false,
136+
sessopts.debugging_opts.teach,
137+
).ui_testing(sessopts.debugging_opts.ui_testing)
138+
),
139+
ErrorOutputType::Json(pretty) => {
140+
let codemap = codemap.unwrap_or_else(
141+
|| Lrc::new(codemap::CodeMap::new(sessopts.file_path_mapping())));
142+
Box::new(
143+
JsonEmitter::stderr(
144+
None,
145+
codemap,
146+
pretty,
147+
sessopts.debugging_opts.suggestion_applicability,
148+
).ui_testing(sessopts.debugging_opts.ui_testing)
149+
)
150+
},
151+
ErrorOutputType::Short(color_config) => Box::new(
152+
EmitterWriter::stderr(
153+
color_config,
154+
codemap.map(|cm| cm as _),
155+
true,
156+
false)
157+
),
158+
};
159+
160+
errors::Handler::with_emitter_and_flags(
161+
emitter,
162+
errors::HandlerFlags {
163+
can_emit_warnings: true,
164+
treat_err_as_bug: false,
165+
external_macro_backtrace: false,
166+
..Default::default()
167+
},
168+
)
169+
}
170+
120171
pub fn run_core(search_paths: SearchPaths,
121172
cfgs: Vec<String>,
122173
externs: config::Externs,
@@ -159,41 +210,11 @@ pub fn run_core(search_paths: SearchPaths,
159210
},
160211
error_format,
161212
edition,
162-
..config::basic_options().clone()
213+
..config::basic_options()
163214
};
164215
driver::spawn_thread_pool(sessopts, move |sessopts| {
165216
let codemap = Lrc::new(codemap::CodeMap::new(sessopts.file_path_mapping()));
166-
let emitter: Box<dyn Emitter + sync::Send> = match error_format {
167-
ErrorOutputType::HumanReadable(color_config) => Box::new(
168-
EmitterWriter::stderr(
169-
color_config,
170-
Some(codemap.clone()),
171-
false,
172-
sessopts.debugging_opts.teach,
173-
).ui_testing(sessopts.debugging_opts.ui_testing)
174-
),
175-
ErrorOutputType::Json(pretty) => Box::new(
176-
JsonEmitter::stderr(
177-
None,
178-
codemap.clone(),
179-
pretty,
180-
sessopts.debugging_opts.suggestion_applicability,
181-
).ui_testing(sessopts.debugging_opts.ui_testing)
182-
),
183-
ErrorOutputType::Short(color_config) => Box::new(
184-
EmitterWriter::stderr(color_config, Some(codemap.clone()), true, false)
185-
),
186-
};
187-
188-
let diagnostic_handler = errors::Handler::with_emitter_and_flags(
189-
emitter,
190-
errors::HandlerFlags {
191-
can_emit_warnings: true,
192-
treat_err_as_bug: false,
193-
external_macro_backtrace: false,
194-
..Default::default()
195-
},
196-
);
217+
let diagnostic_handler = new_handler(error_format, Some(codemap.clone()));
197218

198219
let mut sess = session::build_session_(
199220
sessopts, cpath, diagnostic_handler, codemap,

Diff for: src/librustdoc/externalfiles.rs

+14-11
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use std::fs;
1212
use std::path::Path;
1313
use std::str;
14+
use errors;
1415
use html::markdown::Markdown;
1516

1617
#[derive(Clone)]
@@ -28,23 +29,23 @@ pub struct ExternalHtml {
2829

2930
impl ExternalHtml {
3031
pub fn load(in_header: &[String], before_content: &[String], after_content: &[String],
31-
md_before_content: &[String], md_after_content: &[String])
32+
md_before_content: &[String], md_after_content: &[String], diag: &errors::Handler)
3233
-> Option<ExternalHtml> {
33-
load_external_files(in_header)
34+
load_external_files(in_header, diag)
3435
.and_then(|ih|
35-
load_external_files(before_content)
36+
load_external_files(before_content, diag)
3637
.map(|bc| (ih, bc))
3738
)
3839
.and_then(|(ih, bc)|
39-
load_external_files(md_before_content)
40+
load_external_files(md_before_content, diag)
4041
.map(|m_bc| (ih, format!("{}{}", bc, Markdown(&m_bc, &[]))))
4142
)
4243
.and_then(|(ih, bc)|
43-
load_external_files(after_content)
44+
load_external_files(after_content, diag)
4445
.map(|ac| (ih, bc, ac))
4546
)
4647
.and_then(|(ih, bc, ac)|
47-
load_external_files(md_after_content)
48+
load_external_files(md_after_content, diag)
4849
.map(|m_ac| (ih, bc, format!("{}{}", ac, Markdown(&m_ac, &[]))))
4950
)
5051
.map(|(ih, bc, ac)|
@@ -62,28 +63,30 @@ pub enum LoadStringError {
6263
BadUtf8,
6364
}
6465

65-
pub fn load_string<P: AsRef<Path>>(file_path: P) -> Result<String, LoadStringError> {
66+
pub fn load_string<P: AsRef<Path>>(file_path: P, diag: &errors::Handler)
67+
-> Result<String, LoadStringError>
68+
{
6669
let file_path = file_path.as_ref();
6770
let contents = match fs::read(file_path) {
6871
Ok(bytes) => bytes,
6972
Err(e) => {
70-
eprintln!("error reading `{}`: {}", file_path.display(), e);
73+
diag.struct_err(&format!("error reading `{}`: {}", file_path.display(), e)).emit();
7174
return Err(LoadStringError::ReadFail);
7275
}
7376
};
7477
match str::from_utf8(&contents) {
7578
Ok(s) => Ok(s.to_string()),
7679
Err(_) => {
77-
eprintln!("error reading `{}`: not UTF-8", file_path.display());
80+
diag.struct_err(&format!("error reading `{}`: not UTF-8", file_path.display())).emit();
7881
Err(LoadStringError::BadUtf8)
7982
}
8083
}
8184
}
8285

83-
fn load_external_files(names: &[String]) -> Option<String> {
86+
fn load_external_files(names: &[String], diag: &errors::Handler) -> Option<String> {
8487
let mut out = String::new();
8588
for name in names {
86-
let s = match load_string(name) {
89+
let s = match load_string(name, diag) {
8790
Ok(s) => s,
8891
Err(_) => return None,
8992
};

0 commit comments

Comments
 (0)