Skip to content

Commit 937bc2e

Browse files
committed
Add approximate suggestions for rustfix
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 #39254
1 parent 385ef15 commit 937bc2e

File tree

4 files changed

+64
-7
lines changed

4 files changed

+64
-7
lines changed

src/librustc_errors/diagnostic.rs

+37
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ impl Diagnostic {
222222
}],
223223
msg: msg.to_owned(),
224224
show_code_when_inline: false,
225+
approximate: false,
225226
});
226227
self
227228
}
@@ -252,6 +253,7 @@ impl Diagnostic {
252253
}],
253254
msg: msg.to_owned(),
254255
show_code_when_inline: true,
256+
approximate: false,
255257
});
256258
self
257259
}
@@ -267,6 +269,41 @@ impl Diagnostic {
267269
}).collect(),
268270
msg: msg.to_owned(),
269271
show_code_when_inline: true,
272+
approximate: false,
273+
});
274+
self
275+
}
276+
277+
/// This is a suggestion that may contain mistakes or fillers and should
278+
/// be read and understood by a human.
279+
pub fn span_approximate_suggestion(&mut self, sp: Span, msg: &str,
280+
suggestion: String) -> &mut Self {
281+
self.suggestions.push(CodeSuggestion {
282+
substitutions: vec![Substitution {
283+
parts: vec![SubstitutionPart {
284+
snippet: suggestion,
285+
span: sp,
286+
}],
287+
}],
288+
msg: msg.to_owned(),
289+
show_code_when_inline: true,
290+
approximate: true,
291+
});
292+
self
293+
}
294+
295+
pub fn span_approximate_suggestions(&mut self, sp: Span, msg: &str,
296+
suggestions: Vec<String>) -> &mut Self {
297+
self.suggestions.push(CodeSuggestion {
298+
substitutions: suggestions.into_iter().map(|snippet| Substitution {
299+
parts: vec![SubstitutionPart {
300+
snippet,
301+
span: sp,
302+
}],
303+
}).collect(),
304+
msg: msg.to_owned(),
305+
show_code_when_inline: true,
306+
approximate: true,
270307
});
271308
self
272309
}

src/librustc_errors/diagnostic_builder.rs

+10
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,16 @@ impl<'a> DiagnosticBuilder<'a> {
186186
msg: &str,
187187
suggestions: Vec<String>)
188188
-> &mut Self);
189+
forward!(pub fn span_approximate_suggestion(&mut self,
190+
sp: Span,
191+
msg: &str,
192+
suggestion: String)
193+
-> &mut Self);
194+
forward!(pub fn span_approximate_suggestions(&mut self,
195+
sp: Span,
196+
msg: &str,
197+
suggestions: Vec<String>)
198+
-> &mut Self);
189199
forward!(pub fn set_span<S: Into<MultiSpan>>(&mut self, sp: S) -> &mut Self);
190200
forward!(pub fn code(&mut self, s: DiagnosticId) -> &mut Self);
191201

src/librustc_errors/lib.rs

+6
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,12 @@ pub struct CodeSuggestion {
8383
pub substitutions: Vec<Substitution>,
8484
pub msg: String,
8585
pub show_code_when_inline: bool,
86+
/// Whether or not the suggestion is approximate
87+
///
88+
/// Sometimes we may show suggestions with placeholders,
89+
/// which are useful for users but not useful for
90+
/// tools like rustfix
91+
pub approximate: bool,
8692
}
8793

8894
#[derive(Clone, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)]

src/libsyntax/json.rs

+11-7
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@ struct DiagnosticSpan {
121121
/// If we are suggesting a replacement, this will contain text
122122
/// that should be sliced in atop this span.
123123
suggested_replacement: Option<String>,
124+
/// If the suggestion is approximate
125+
suggestion_approximate: Option<bool>,
124126
/// Macro invocations that created the code at this span, if any.
125127
expansion: Option<Box<DiagnosticSpanMacroExpansion>>,
126128
}
@@ -220,7 +222,7 @@ impl Diagnostic {
220222

221223
impl DiagnosticSpan {
222224
fn from_span_label(span: SpanLabel,
223-
suggestion: Option<&String>,
225+
suggestion: Option<(&String, bool)>,
224226
je: &JsonEmitter)
225227
-> DiagnosticSpan {
226228
Self::from_span_etc(span.span,
@@ -233,7 +235,7 @@ impl DiagnosticSpan {
233235
fn from_span_etc(span: Span,
234236
is_primary: bool,
235237
label: Option<String>,
236-
suggestion: Option<&String>,
238+
suggestion: Option<(&String, bool)>,
237239
je: &JsonEmitter)
238240
-> DiagnosticSpan {
239241
// obtain the full backtrace from the `macro_backtrace`
@@ -253,7 +255,7 @@ impl DiagnosticSpan {
253255
fn from_span_full(span: Span,
254256
is_primary: bool,
255257
label: Option<String>,
256-
suggestion: Option<&String>,
258+
suggestion: Option<(&String, bool)>,
257259
mut backtrace: vec::IntoIter<MacroBacktrace>,
258260
je: &JsonEmitter)
259261
-> DiagnosticSpan {
@@ -291,7 +293,8 @@ impl DiagnosticSpan {
291293
column_end: end.col.0 + 1,
292294
is_primary,
293295
text: DiagnosticSpanLine::from_span(span, je),
294-
suggested_replacement: suggestion.cloned(),
296+
suggested_replacement: suggestion.map(|x| x.0.clone()),
297+
suggestion_approximate: suggestion.map(|x| x.1),
295298
expansion: backtrace_step,
296299
label,
297300
}
@@ -309,14 +312,15 @@ impl DiagnosticSpan {
309312
suggestion.substitutions
310313
.iter()
311314
.flat_map(|substitution| {
312-
substitution.parts.iter().map(move |suggestion| {
315+
substitution.parts.iter().map(move |suggestion_inner| {
313316
let span_label = SpanLabel {
314-
span: suggestion.span,
317+
span: suggestion_inner.span,
315318
is_primary: true,
316319
label: None,
317320
};
318321
DiagnosticSpan::from_span_label(span_label,
319-
Some(&suggestion.snippet),
322+
Some((&suggestion_inner.snippet,
323+
suggestion.approximate)),
320324
je)
321325
})
322326
})

0 commit comments

Comments
 (0)