-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Minimize single span suggestions into a label #40851
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
Changes from all commits
0e920fd
b857a1a
ca701d7
3a5567b
f4b1e2a
e0655a0
d64af4a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,7 +11,6 @@ | |
use CodeSuggestion; | ||
use Level; | ||
use RenderSpan; | ||
use RenderSpan::Suggestion; | ||
use std::fmt; | ||
use syntax_pos::{MultiSpan, Span}; | ||
use snippet::Style; | ||
|
@@ -24,6 +23,7 @@ pub struct Diagnostic { | |
pub code: Option<String>, | ||
pub span: MultiSpan, | ||
pub children: Vec<SubDiagnostic>, | ||
pub suggestion: Option<CodeSuggestion>, | ||
} | ||
|
||
/// For example a note attached to an error. | ||
|
@@ -87,6 +87,7 @@ impl Diagnostic { | |
code: code, | ||
span: MultiSpan::new(), | ||
children: vec![], | ||
suggestion: None, | ||
} | ||
} | ||
|
||
|
@@ -202,19 +203,14 @@ impl Diagnostic { | |
|
||
/// Prints out a message with a suggested edit of the code. | ||
/// | ||
/// See `diagnostic::RenderSpan::Suggestion` for more information. | ||
pub fn span_suggestion<S: Into<MultiSpan>>(&mut self, | ||
sp: S, | ||
msg: &str, | ||
suggestion: String) | ||
-> &mut Self { | ||
self.sub(Level::Help, | ||
msg, | ||
MultiSpan::new(), | ||
Some(Suggestion(CodeSuggestion { | ||
msp: sp.into(), | ||
substitutes: vec![suggestion], | ||
}))); | ||
/// See `diagnostic::CodeSuggestion` for more information. | ||
pub fn span_suggestion(&mut self, sp: Span, msg: &str, suggestion: String) -> &mut Self { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it is worth keeping the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The reason is that using a multispan will panic in the original emitter code |
||
assert!(self.suggestion.is_none()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It surprises me that we never have multiple suggestions, but I guess part of your plan is to do this properly in the long run? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes |
||
self.suggestion = Some(CodeSuggestion { | ||
msp: sp.into(), | ||
substitutes: vec![suggestion], | ||
msg: msg.to_owned(), | ||
}); | ||
self | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,6 +34,27 @@ impl Emitter for EmitterWriter { | |
fn emit(&mut self, db: &DiagnosticBuilder) { | ||
let mut primary_span = db.span.clone(); | ||
let mut children = db.children.clone(); | ||
|
||
if let Some(sugg) = db.suggestion.clone() { | ||
assert_eq!(sugg.msp.primary_spans().len(), sugg.substitutes.len()); | ||
// don't display multispans as labels | ||
if sugg.substitutes.len() == 1 && | ||
// don't display long messages as labels | ||
sugg.msg.split_whitespace().count() < 10 && | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The rules about message length ate defined here. Currently only single line messages with fewer than 10 words are accepted |
||
// don't display multiline suggestions as labels | ||
sugg.substitutes[0].find('\n').is_none() { | ||
let msg = format!("help: {} `{}`", sugg.msg, sugg.substitutes[0]); | ||
primary_span.push_span_label(sugg.msp.primary_spans()[0], msg); | ||
} else { | ||
children.push(SubDiagnostic { | ||
level: Level::Help, | ||
message: Vec::new(), | ||
span: MultiSpan::new(), | ||
render_span: Some(Suggestion(sugg)), | ||
}); | ||
} | ||
} | ||
|
||
self.fix_multispans_in_std_macros(&mut primary_span, &mut children); | ||
self.emit_messages_default(&db.level, | ||
&db.styled_message(), | ||
|
@@ -756,7 +777,7 @@ impl EmitterWriter { | |
/// displayed, keeping the provided highlighting. | ||
fn msg_to_buffer(&self, | ||
buffer: &mut StyledBuffer, | ||
msg: &Vec<(String, Style)>, | ||
msg: &[(String, Style)], | ||
padding: usize, | ||
label: &str, | ||
override_style: Option<Style>) { | ||
|
@@ -1022,7 +1043,6 @@ impl EmitterWriter { | |
fn emit_suggestion_default(&mut self, | ||
suggestion: &CodeSuggestion, | ||
level: &Level, | ||
msg: &Vec<(String, Style)>, | ||
max_line_num_len: usize) | ||
-> io::Result<()> { | ||
use std::borrow::Borrow; | ||
|
@@ -1034,7 +1054,7 @@ impl EmitterWriter { | |
buffer.append(0, &level.to_string(), Style::Level(level.clone())); | ||
buffer.append(0, ": ", Style::HeaderMsg); | ||
self.msg_to_buffer(&mut buffer, | ||
msg, | ||
&[(suggestion.msg.to_owned(), Style::NoStyle)], | ||
max_line_num_len, | ||
"suggestion", | ||
Some(Style::HeaderMsg)); | ||
|
@@ -1099,7 +1119,6 @@ impl EmitterWriter { | |
Some(Suggestion(ref cs)) => { | ||
match self.emit_suggestion_default(cs, | ||
&child.level, | ||
&child.styled_message(), | ||
max_line_num_len) { | ||
Err(e) => panic!("failed to emit error: {}", e), | ||
_ => () | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
error[E0178]: expected a path on the left-hand side of `+`, not `&'a Foo` | ||
--> $DIR/E0178.rs:14:8 | ||
| | ||
14 | w: &'a Foo + Copy, | ||
| ^^^^^^^^^^^^^^ help: try adding parentheses: `&'a (Foo + Copy)` | ||
|
||
error[E0178]: expected a path on the left-hand side of `+`, not `&'a Foo` | ||
--> $DIR/E0178.rs:15:8 | ||
| | ||
15 | x: &'a Foo + 'a, | ||
| ^^^^^^^^^^^^ help: try adding parentheses: `&'a (Foo + 'a)` | ||
|
||
error[E0178]: expected a path on the left-hand side of `+`, not `&'a mut Foo` | ||
--> $DIR/E0178.rs:16:8 | ||
| | ||
16 | y: &'a mut Foo + 'a, | ||
| ^^^^^^^^^^^^^^^^ help: try adding parentheses: `&'a mut (Foo + 'a)` | ||
|
||
error[E0178]: expected a path on the left-hand side of `+`, not `fn() -> Foo` | ||
--> $DIR/E0178.rs:17:8 | ||
| | ||
17 | z: fn() -> Foo + 'a, | ||
| ^^^^^^^^^^^^^^^^ perhaps you forgot parentheses? | ||
|
||
error: aborting due to 4 previous errors | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we remove RenderSpan::Suggestion now or is it still used elsewhere?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left it in for keeping the diff small. I convert to it in the emitter and json impls. Wanted to get feedback on a readable diff first