Skip to content

Commit

Permalink
Add approximate suggestions for rustfix
Browse files Browse the repository at this point in the history
This adds `span_approximate_suggestion()` that lets you emit a
suggestion marked as "approximate" in the JSON output. UI
users see no difference. This is for when rustc and clippy wish to
 emit suggestions which will make sense to the reader (e.g. they may
have placeholders like `<type>`) but are not source-applicable, so that
rustfix/etc can ignore these.

fixes rust-lang#39254
  • Loading branch information
Manishearth committed Jan 29, 2018
1 parent 385ef15 commit 937bc2e
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 7 deletions.
37 changes: 37 additions & 0 deletions src/librustc_errors/diagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ impl Diagnostic {
}],
msg: msg.to_owned(),
show_code_when_inline: false,
approximate: false,
});
self
}
Expand Down Expand Up @@ -252,6 +253,7 @@ impl Diagnostic {
}],
msg: msg.to_owned(),
show_code_when_inline: true,
approximate: false,
});
self
}
Expand All @@ -267,6 +269,41 @@ impl Diagnostic {
}).collect(),
msg: msg.to_owned(),
show_code_when_inline: true,
approximate: false,
});
self
}

/// This is a suggestion that may contain mistakes or fillers and should
/// be read and understood by a human.
pub fn span_approximate_suggestion(&mut self, sp: Span, msg: &str,
suggestion: String) -> &mut Self {
self.suggestions.push(CodeSuggestion {
substitutions: vec![Substitution {
parts: vec![SubstitutionPart {
snippet: suggestion,
span: sp,
}],
}],
msg: msg.to_owned(),
show_code_when_inline: true,
approximate: true,
});
self
}

pub fn span_approximate_suggestions(&mut self, sp: Span, msg: &str,
suggestions: Vec<String>) -> &mut Self {
self.suggestions.push(CodeSuggestion {
substitutions: suggestions.into_iter().map(|snippet| Substitution {
parts: vec![SubstitutionPart {
snippet,
span: sp,
}],
}).collect(),
msg: msg.to_owned(),
show_code_when_inline: true,
approximate: true,
});
self
}
Expand Down
10 changes: 10 additions & 0 deletions src/librustc_errors/diagnostic_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,16 @@ impl<'a> DiagnosticBuilder<'a> {
msg: &str,
suggestions: Vec<String>)
-> &mut Self);
forward!(pub fn span_approximate_suggestion(&mut self,
sp: Span,
msg: &str,
suggestion: String)
-> &mut Self);
forward!(pub fn span_approximate_suggestions(&mut self,
sp: Span,
msg: &str,
suggestions: Vec<String>)
-> &mut Self);
forward!(pub fn set_span<S: Into<MultiSpan>>(&mut self, sp: S) -> &mut Self);
forward!(pub fn code(&mut self, s: DiagnosticId) -> &mut Self);

Expand Down
6 changes: 6 additions & 0 deletions src/librustc_errors/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ pub struct CodeSuggestion {
pub substitutions: Vec<Substitution>,
pub msg: String,
pub show_code_when_inline: bool,
/// Whether or not the suggestion is approximate
///
/// Sometimes we may show suggestions with placeholders,
/// which are useful for users but not useful for
/// tools like rustfix
pub approximate: bool,
}

#[derive(Clone, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)]
Expand Down
18 changes: 11 additions & 7 deletions src/libsyntax/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ struct DiagnosticSpan {
/// If we are suggesting a replacement, this will contain text
/// that should be sliced in atop this span.
suggested_replacement: Option<String>,
/// If the suggestion is approximate
suggestion_approximate: Option<bool>,
/// Macro invocations that created the code at this span, if any.
expansion: Option<Box<DiagnosticSpanMacroExpansion>>,
}
Expand Down Expand Up @@ -220,7 +222,7 @@ impl Diagnostic {

impl DiagnosticSpan {
fn from_span_label(span: SpanLabel,
suggestion: Option<&String>,
suggestion: Option<(&String, bool)>,
je: &JsonEmitter)
-> DiagnosticSpan {
Self::from_span_etc(span.span,
Expand All @@ -233,7 +235,7 @@ impl DiagnosticSpan {
fn from_span_etc(span: Span,
is_primary: bool,
label: Option<String>,
suggestion: Option<&String>,
suggestion: Option<(&String, bool)>,
je: &JsonEmitter)
-> DiagnosticSpan {
// obtain the full backtrace from the `macro_backtrace`
Expand All @@ -253,7 +255,7 @@ impl DiagnosticSpan {
fn from_span_full(span: Span,
is_primary: bool,
label: Option<String>,
suggestion: Option<&String>,
suggestion: Option<(&String, bool)>,
mut backtrace: vec::IntoIter<MacroBacktrace>,
je: &JsonEmitter)
-> DiagnosticSpan {
Expand Down Expand Up @@ -291,7 +293,8 @@ impl DiagnosticSpan {
column_end: end.col.0 + 1,
is_primary,
text: DiagnosticSpanLine::from_span(span, je),
suggested_replacement: suggestion.cloned(),
suggested_replacement: suggestion.map(|x| x.0.clone()),
suggestion_approximate: suggestion.map(|x| x.1),
expansion: backtrace_step,
label,
}
Expand All @@ -309,14 +312,15 @@ impl DiagnosticSpan {
suggestion.substitutions
.iter()
.flat_map(|substitution| {
substitution.parts.iter().map(move |suggestion| {
substitution.parts.iter().map(move |suggestion_inner| {
let span_label = SpanLabel {
span: suggestion.span,
span: suggestion_inner.span,
is_primary: true,
label: None,
};
DiagnosticSpan::from_span_label(span_label,
Some(&suggestion.snippet),
Some((&suggestion_inner.snippet,
suggestion.approximate)),
je)
})
})
Expand Down

0 comments on commit 937bc2e

Please sign in to comment.