about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorPhilipp Hansch <dev@phansch.net>2019-09-01 12:15:33 +0200
committerPhilipp Hansch <dev@phansch.net>2019-09-01 13:05:47 +0200
commit84ccbe2076cf37bc13c32a89ccc57a57281b8708 (patch)
tree4ea1758f9ea16991df236fe32efdc15f355fe540 /src
parent2d851b33181b1404856cb1d8b20d261adda54ffb (diff)
downloadrust-84ccbe2076cf37bc13c32a89ccc57a57281b8708.tar.gz
rust-84ccbe2076cf37bc13c32a89ccc57a57281b8708.zip
librustc_errors: Extract sugg/subst handling into method
An initial refactoring before working on #61809.

This moves the whole block into a method so that it can be reused in the
annotate-snippet output. It's 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.
Diffstat (limited to 'src')
-rw-r--r--src/librustc_errors/annotate_snippet_emitter_writer.rs4
-rw-r--r--src/librustc_errors/emitter.rs40
2 files changed, 32 insertions, 12 deletions
diff --git a/src/librustc_errors/annotate_snippet_emitter_writer.rs b/src/librustc_errors/annotate_snippet_emitter_writer.rs
index 255af3122e7..3bed5d81dc5 100644
--- a/src/librustc_errors/annotate_snippet_emitter_writer.rs
+++ b/src/librustc_errors/annotate_snippet_emitter_writer.rs
@@ -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
 
diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs
index 77d373e7a8c..0a9c927ef40 100644
--- a/src/librustc_errors/emitter.rs
+++ b/src/librustc_errors/emitter.rs
@@ -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
@@ -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,