Skip to content

Commit

Permalink
Rollup merge of rust-lang#64058 - phansch:refactor_out_method, r=este…
Browse files Browse the repository at this point in the history
…bank

librustc_errors: Extract sugg/subst handling into method

An initial refactoring before working on rust-lang#61809.

This moves the whole block into a method so that it can be reused in the
annotate-snippet emitter. The method is already used in the new emitter, but
there's no UI tests with suggestions included in this PR.

A first look at some UI tests with suggestions showed that there's some
more work to do in [annotate-snippet-rs][annotate-snippet-rs] before the new output is closer to the
current one, so I opted to do that in a second step.

r? @estebank

[annotate-snippet-rs]: https://github.com/rust-lang/annotate-snippets-rs
  • Loading branch information
Centril authored Sep 3, 2019
2 parents ececd71 + 84ccbe2 commit aa63cd9
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 12 deletions.
4 changes: 1 addition & 3 deletions src/librustc_errors/annotate_snippet_emitter_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,8 @@ pub struct AnnotateSnippetEmitterWriter {
impl Emitter for AnnotateSnippetEmitterWriter {
/// The entry point for the diagnostics generation
fn emit_diagnostic(&mut self, db: &DiagnosticBuilder<'_>) {
let primary_span = db.span.clone();
let children = db.children.clone();
// FIXME(#59346): Collect suggestions (see emitter.rs)
let suggestions: &[_] = &[];
let (primary_span, suggestions) = self.primary_span_formatted(&db);

// FIXME(#59346): Add `fix_multispans_in_std_macros` function from emitter.rs

Expand Down
40 changes: 31 additions & 9 deletions src/librustc_errors/emitter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,16 +191,25 @@ pub trait Emitter {
fn should_show_explain(&self) -> bool {
true
}
}

impl Emitter for EmitterWriter {
fn emit_diagnostic(&mut self, db: &DiagnosticBuilder<'_>) {
/// Formats the substitutions of the primary_span
///
/// The are a lot of conditions to this method, but in short:
///
/// * If the current `Diagnostic` has only one visible `CodeSuggestion`,
/// we format the `help` suggestion depending on the content of the
/// substitutions. In that case, we return the modified span only.
///
/// * If the current `Diagnostic` has multiple suggestions,
/// we return the original `primary_span` and the original suggestions.
fn primary_span_formatted<'a>(
&mut self,
db: &'a DiagnosticBuilder<'_>
) -> (MultiSpan, &'a [CodeSuggestion]) {
let mut primary_span = db.span.clone();
let mut children = db.children.clone();
let mut suggestions: &[_] = &[];

if let Some((sugg, rest)) = db.suggestions.split_first() {
if rest.is_empty() &&
// ^ if there is only one suggestion
// don't display multi-suggestions as labels
sugg.substitutions.len() == 1 &&
// don't display multipart suggestions as labels
Expand All @@ -216,21 +225,34 @@ impl Emitter for EmitterWriter {
{
let substitution = &sugg.substitutions[0].parts[0].snippet.trim();
let msg = if substitution.len() == 0 || sugg.style.hide_inline() {
// This substitution is only removal or we explicitly don't want to show the
// code inline, don't show it
// This substitution is only removal OR we explicitly don't want to show the
// code inline (`hide_inline`). Therefore, we don't show the substitution.
format!("help: {}", sugg.msg)
} else {
// Show the default suggestion text with the substitution
format!("help: {}: `{}`", sugg.msg, substitution)
};
primary_span.push_span_label(sugg.substitutions[0].parts[0].span, msg);

// We return only the modified primary_span
(primary_span, &[])
} else {
// if there are multiple suggestions, print them all in full
// to be consistent. We could try to figure out if we can
// make one (or the first one) inline, but that would give
// undue importance to a semi-random suggestion
suggestions = &db.suggestions;
(primary_span, &db.suggestions)
}
} else {
(primary_span, &db.suggestions)
}
}
}

impl Emitter for EmitterWriter {
fn emit_diagnostic(&mut self, db: &DiagnosticBuilder<'_>) {
let mut children = db.children.clone();
let (mut primary_span, suggestions) = self.primary_span_formatted(&db);

self.fix_multispans_in_std_macros(&mut primary_span,
&mut children,
Expand Down

0 comments on commit aa63cd9

Please sign in to comment.