Skip to content

Commit 8c75e18

Browse files
test for putting back check on json
1 parent c290857 commit 8c75e18

File tree

5 files changed

+127
-79
lines changed

5 files changed

+127
-79
lines changed

src/librustc_errors/diagnostic_builder.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@ impl<'a> DiagnosticBuilder<'a> {
9292
Level::Bug |
9393
Level::Fatal |
9494
Level::PhaseFatal |
95-
Level::Error => {
95+
Level::Error |
96+
Level::FailureNote => {
9697
true
9798
}
9899

src/librustc_errors/emitter.rs

+35-54
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use atty;
2121
use std::borrow::Cow;
2222
use std::io::prelude::*;
2323
use std::io;
24-
use std::collections::{HashMap, HashSet};
24+
use std::collections::HashMap;
2525
use std::cmp::min;
2626
use termcolor::{StandardStream, ColorChoice, ColorSpec, BufferWriter};
2727
use termcolor::{WriteColor, Color, Buffer};
@@ -33,6 +33,11 @@ const ANONYMIZED_LINE_NUM: &str = "LL";
3333
pub trait Emitter {
3434
/// Emit a structured diagnostic.
3535
fn emit(&mut self, db: &DiagnosticBuilder);
36+
37+
/// Check if should show explanations about "rustc --explain"
38+
fn should_show_explain(&self) -> bool {
39+
true
40+
}
3641
}
3742

3843
impl Emitter for EmitterWriter {
@@ -80,6 +85,10 @@ impl Emitter for EmitterWriter {
8085
&children,
8186
&suggestions);
8287
}
88+
89+
fn should_show_explain(&self) -> bool {
90+
!self.short_message
91+
}
8392
}
8493

8594
/// maximum number of lines we will print for each error; arbitrary.
@@ -114,7 +123,6 @@ pub struct EmitterWriter {
114123
cm: Option<Lrc<CodeMapper>>,
115124
short_message: bool,
116125
teach: bool,
117-
error_codes: HashSet<String>,
118126
ui_testing: bool,
119127
}
120128

@@ -124,34 +132,6 @@ struct FileWithAnnotatedLines {
124132
multiline_depth: usize,
125133
}
126134

127-
impl Drop for EmitterWriter {
128-
fn drop(&mut self) {
129-
if !self.short_message && !self.error_codes.is_empty() {
130-
let mut error_codes = self.error_codes.clone().into_iter().collect::<Vec<_>>();
131-
let mut dst = self.dst.writable();
132-
error_codes.sort();
133-
if error_codes.len() > 1 {
134-
let limit = if error_codes.len() > 9 { 9 } else { error_codes.len() };
135-
writeln!(dst,
136-
"You've got a few errors: {}{}",
137-
error_codes[..limit].join(", "),
138-
if error_codes.len() > 9 { "..." } else { "" }
139-
).expect("failed to give tips...");
140-
writeln!(dst,
141-
"If you want more information on an error, try using \
142-
\"rustc --explain {}\"",
143-
&error_codes[0]).expect("failed to give tips...");
144-
} else {
145-
writeln!(dst,
146-
"If you want more information on this error, try using \
147-
\"rustc --explain {}\"",
148-
&error_codes[0]).expect("failed to give tips...");
149-
}
150-
dst.flush().expect("failed to emit errors");
151-
}
152-
}
153-
}
154-
155135
impl EmitterWriter {
156136
pub fn stderr(color_config: ColorConfig,
157137
code_map: Option<Lrc<CodeMapper>>,
@@ -164,7 +144,6 @@ impl EmitterWriter {
164144
cm: code_map,
165145
short_message,
166146
teach,
167-
error_codes: HashSet::new(),
168147
ui_testing: false,
169148
}
170149
}
@@ -179,7 +158,6 @@ impl EmitterWriter {
179158
cm: code_map,
180159
short_message,
181160
teach,
182-
error_codes: HashSet::new(),
183161
ui_testing: false,
184162
}
185163
}
@@ -993,18 +971,26 @@ impl EmitterWriter {
993971
buffer.prepend(0, " ", Style::NoStyle);
994972
}
995973
draw_note_separator(&mut buffer, 0, max_line_num_len + 1);
996-
buffer.append(0, &level.to_string(), Style::HeaderMsg);
997-
buffer.append(0, ": ", Style::NoStyle);
974+
let level_str = level.to_string();
975+
if !level_str.is_empty() {
976+
buffer.append(0, &level_str, Style::HeaderMsg);
977+
buffer.append(0, ": ", Style::NoStyle);
978+
}
998979
self.msg_to_buffer(&mut buffer, msg, max_line_num_len, "note", None);
999980
} else {
1000-
buffer.append(0, &level.to_string(), Style::Level(level.clone()));
981+
let level_str = level.to_string();
982+
if !level_str.is_empty() {
983+
buffer.append(0, &level_str, Style::Level(level.clone()));
984+
}
1001985
// only render error codes, not lint codes
1002986
if let Some(DiagnosticId::Error(ref code)) = *code {
1003987
buffer.append(0, "[", Style::Level(level.clone()));
1004988
buffer.append(0, &code, Style::Level(level.clone()));
1005989
buffer.append(0, "]", Style::Level(level.clone()));
1006990
}
1007-
buffer.append(0, ": ", Style::HeaderMsg);
991+
if !level_str.is_empty() {
992+
buffer.append(0, ": ", Style::HeaderMsg);
993+
}
1008994
for &(ref text, _) in msg.iter() {
1009995
buffer.append(0, text, Style::HeaderMsg);
1010996
}
@@ -1020,14 +1006,12 @@ impl EmitterWriter {
10201006
if primary_span != &&DUMMY_SP {
10211007
(cm.lookup_char_pos(primary_span.lo()), cm)
10221008
} else {
1023-
emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message,
1024-
&mut self.error_codes)?;
1009+
emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message)?;
10251010
return Ok(());
10261011
}
10271012
} else {
10281013
// If we don't have span information, emit and exit
1029-
emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message,
1030-
&mut self.error_codes)?;
1014+
emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message)?;
10311015
return Ok(());
10321016
};
10331017
if let Ok(pos) =
@@ -1200,8 +1184,7 @@ impl EmitterWriter {
12001184
}
12011185

12021186
// final step: take our styled buffer, render it, then output it
1203-
emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message,
1204-
&mut self.error_codes)?;
1187+
emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message)?;
12051188

12061189
Ok(())
12071190

@@ -1218,8 +1201,11 @@ impl EmitterWriter {
12181201
let mut buffer = StyledBuffer::new();
12191202

12201203
// Render the suggestion message
1221-
buffer.append(0, &level.to_string(), Style::Level(level.clone()));
1222-
buffer.append(0, ": ", Style::HeaderMsg);
1204+
let level_str = level.to_string();
1205+
if !level_str.is_empty() {
1206+
buffer.append(0, &level_str, Style::Level(level.clone()));
1207+
buffer.append(0, ": ", Style::HeaderMsg);
1208+
}
12231209
self.msg_to_buffer(&mut buffer,
12241210
&[(suggestion.msg.to_owned(), Style::NoStyle)],
12251211
max_line_num_len,
@@ -1289,8 +1275,7 @@ impl EmitterWriter {
12891275
let msg = format!("and {} other candidates", suggestions.len() - MAX_SUGGESTIONS);
12901276
buffer.puts(row_num, 0, &msg, Style::NoStyle);
12911277
}
1292-
emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message,
1293-
&mut self.error_codes)?;
1278+
emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message)?;
12941279
}
12951280
Ok(())
12961281
}
@@ -1321,7 +1306,7 @@ impl EmitterWriter {
13211306
draw_col_separator_no_space(&mut buffer, 0, max_line_num_len + 1);
13221307
}
13231308
match emit_to_destination(&buffer.render(), level, &mut self.dst,
1324-
self.short_message, &mut self.error_codes) {
1309+
self.short_message) {
13251310
Ok(()) => (),
13261311
Err(e) => panic!("failed to emit error: {}", e)
13271312
}
@@ -1416,8 +1401,7 @@ fn overlaps(a1: &Annotation, a2: &Annotation, padding: usize) -> bool {
14161401
fn emit_to_destination(rendered_buffer: &Vec<Vec<StyledString>>,
14171402
lvl: &Level,
14181403
dst: &mut Destination,
1419-
short_message: bool,
1420-
error_codes: &mut HashSet<String>)
1404+
short_message: bool)
14211405
-> io::Result<()> {
14221406
use lock;
14231407

@@ -1436,16 +1420,13 @@ fn emit_to_destination(rendered_buffer: &Vec<Vec<StyledString>>,
14361420
// same buffering approach. Instead, we use a global Windows mutex, which we acquire long
14371421
// enough to output the full error message, then we release.
14381422
let _buffer_lock = lock::acquire_global_lock("rustc_errors");
1439-
for line in rendered_buffer {
1423+
for (pos, line) in rendered_buffer.iter().enumerate() {
14401424
for part in line {
14411425
dst.apply_style(lvl.clone(), part.style)?;
14421426
write!(dst, "{}", part.text)?;
1443-
if !short_message && part.text.len() == 12 && part.text.starts_with("error[E") {
1444-
error_codes.insert(part.text[6..11].to_owned());
1445-
}
14461427
dst.reset()?;
14471428
}
1448-
if !short_message {
1429+
if !short_message && (!lvl.is_failure_note() || pos != rendered_buffer.len() - 1) {
14491430
write!(dst, "\n")?;
14501431
}
14511432
}

src/librustc_errors/lib.rs

+47-4
Original file line numberDiff line numberDiff line change
@@ -509,12 +509,14 @@ impl Handler {
509509
pub fn span_unimpl<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> ! {
510510
self.span_bug(sp, &format!("unimplemented {}", msg));
511511
}
512+
pub fn failure(&self, msg: &str) {
513+
DiagnosticBuilder::new(self, FailureNote, msg).emit()
514+
}
512515
pub fn fatal(&self, msg: &str) -> FatalError {
513516
if self.flags.treat_err_as_bug {
514517
self.bug(msg);
515518
}
516-
let mut db = DiagnosticBuilder::new(self, Fatal, msg);
517-
db.emit();
519+
DiagnosticBuilder::new(self, Fatal, msg).emit();
518520
FatalError
519521
}
520522
pub fn err(&self, msg: &str) {
@@ -567,8 +569,39 @@ impl Handler {
567569
s = format!("aborting due to {} previous errors", self.err_count());
568570
}
569571
}
572+
let err = self.fatal(&s);
573+
574+
let can_show_explain = self.emitter.borrow().should_show_explain();
575+
let are_there_diagnostics = !self.tracked_diagnostic_codes.borrow().is_empty();
576+
if can_show_explain && are_there_diagnostics {
577+
let mut error_codes =
578+
self.tracked_diagnostic_codes.borrow()
579+
.clone()
580+
.into_iter()
581+
.filter_map(|x| match x {
582+
DiagnosticId::Error(ref s) => Some(s.clone()),
583+
_ => None,
584+
})
585+
.collect::<Vec<_>>();
586+
if !error_codes.is_empty() {
587+
error_codes.sort();
588+
if error_codes.len() > 1 {
589+
let limit = if error_codes.len() > 9 { 9 } else { error_codes.len() };
590+
self.failure(&format!("Some errors occurred: {}{}",
591+
error_codes[..limit].join(", "),
592+
if error_codes.len() > 9 { "..." } else { "." }));
593+
self.failure(&format!("For more information about an error, try \
594+
`rustc --explain {}`.",
595+
&error_codes[0]));
596+
} else {
597+
self.failure(&format!("For more information about this error, try \
598+
`rustc --explain {}`.",
599+
&error_codes[0]));
600+
}
601+
}
602+
}
570603

571-
self.fatal(&s).raise();
604+
err.raise();
572605
}
573606
pub fn emit(&self, msp: &MultiSpan, msg: &str, lvl: Level) {
574607
if lvl == Warning && !self.flags.can_emit_warnings {
@@ -654,6 +687,7 @@ pub enum Level {
654687
Note,
655688
Help,
656689
Cancelled,
690+
FailureNote,
657691
}
658692

659693
impl fmt::Display for Level {
@@ -682,9 +716,10 @@ impl Level {
682716
spec.set_fg(Some(Color::Cyan))
683717
.set_intense(true);
684718
}
719+
FailureNote => {}
685720
Cancelled => unreachable!(),
686721
}
687-
return spec
722+
spec
688723
}
689724

690725
pub fn to_str(self) -> &'static str {
@@ -694,7 +729,15 @@ impl Level {
694729
Warning => "warning",
695730
Note => "note",
696731
Help => "help",
732+
FailureNote => "",
697733
Cancelled => panic!("Shouldn't call on cancelled error"),
698734
}
699735
}
736+
737+
pub fn is_failure_note(&self) -> bool {
738+
match *self {
739+
FailureNote => true,
740+
_ => false,
741+
}
742+
}
700743
}

src/tools/compiletest/src/json.rs

+20
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ struct Diagnostic {
2424
level: String,
2525
spans: Vec<DiagnosticSpan>,
2626
children: Vec<Diagnostic>,
27+
rendered: Option<String>,
2728
}
2829

2930
#[derive(Deserialize, Clone)]
@@ -56,6 +57,25 @@ struct DiagnosticCode {
5657
explanation: Option<String>,
5758
}
5859

60+
pub fn extract_rendered(output: &str, proc_res: &ProcRes) -> String {
61+
output.lines()
62+
.filter_map(|line| if line.starts_with('{') {
63+
match serde_json::from_str::<Diagnostic>(line) {
64+
Ok(diagnostic) => diagnostic.rendered,
65+
Err(error) => {
66+
proc_res.fatal(Some(&format!("failed to decode compiler output as json: \
67+
`{}`\noutput: {}\nline: {}",
68+
error,
69+
line,
70+
output)));
71+
}
72+
}
73+
} else {
74+
None
75+
})
76+
.collect()
77+
}
78+
5979
pub fn parse_output(file_name: &str, output: &str, proc_res: &ProcRes) -> Vec<Error> {
6080
output.lines()
6181
.flat_map(|line| parse_line(file_name, line, output, proc_res))

0 commit comments

Comments
 (0)