]> git.lizzy.rs Git - rust.git/commitdiff
Teach diagnostics to correct margin on multiline messages
authorEsteban Küber <esteban@kuber.com.ar>
Sun, 8 Jan 2017 22:00:57 +0000 (14:00 -0800)
committerEsteban Küber <esteban@kuber.com.ar>
Mon, 9 Jan 2017 00:07:14 +0000 (16:07 -0800)
Make any diagnostic line to have the correct margin to align with the
first line:

```
error: message
 --> file.rs:3:20
  |
3 |     <CODE>
  |      ^^^^
  |
  = note: this is a multiline
          note with a correct
          margin
  = note: this is a single line note
  = help: here are some functions which might fulfill your needs:
          - .len()
          - .foo()
          - .bar()
  = suggestion: this is a multiline
                suggestion with a
                correct margin
```

src/librustc_errors/diagnostic.rs
src/librustc_errors/diagnostic_builder.rs
src/librustc_errors/emitter.rs
src/librustc_typeck/check/demand.rs

index 73a8343eafc45218af566604006b19c7e72c5c5b..730ca8f9e2e4474e97735ffd13ad6a553f51183c 100644 (file)
@@ -32,7 +32,6 @@ pub struct SubDiagnostic {
     pub message: String,
     pub span: MultiSpan,
     pub render_span: Option<RenderSpan>,
-    pub list: Vec<String>,
 }
 
 impl Diagnostic {
@@ -133,11 +132,6 @@ pub fn help(&mut self , msg: &str) -> &mut Self {
         self
     }
 
-    pub fn help_with_list(&mut self , msg: &str, list: Vec<String>) -> &mut Self {
-        self.sub_with_list(Level::Help, msg, MultiSpan::new(), None, list);
-        self
-    }
-
     pub fn span_help<S: Into<MultiSpan>>(&mut self,
                                          sp: S,
                                          msg: &str)
@@ -197,23 +191,11 @@ fn sub(&mut self,
            message: &str,
            span: MultiSpan,
            render_span: Option<RenderSpan>) {
-        self.sub_with_list(level, message, span, render_span, vec![]);
-    }
-
-    /// Convenience function for internal use, clients should use one of the
-    /// public methods above.
-    fn sub_with_list(&mut self,
-           level: Level,
-           message: &str,
-           span: MultiSpan,
-           render_span: Option<RenderSpan>,
-           list: Vec<String>) {
         let sub = SubDiagnostic {
             level: level,
             message: message.to_owned(),
             span: span,
             render_span: render_span,
-            list: list,
         };
         self.children.push(sub);
     }
index 24f1b86739da6fa36f05454c23242e1a9c1b908a..7dfea6b8951b05f2aebd649e338124e57af9fbf6 100644 (file)
@@ -135,7 +135,6 @@ pub fn emit(&mut self) {
     forward!(pub fn warn(&mut self, msg: &str) -> &mut Self);
     forward!(pub fn span_warn<S: Into<MultiSpan>>(&mut self, sp: S, msg: &str) -> &mut Self);
     forward!(pub fn help(&mut self , msg: &str) -> &mut Self);
-    forward!(pub fn help_with_list(&mut self , msg: &str, list: Vec<String>) -> &mut Self);
     forward!(pub fn span_help<S: Into<MultiSpan>>(&mut self,
                                                   sp: S,
                                                   msg: &str)
index 88373bf988da790369fa2af7b0fbfe48e12cfaf9..dbef287f11337ff43ada1a52c62b4e4b236e2120 100644 (file)
@@ -699,11 +699,25 @@ fn fix_multispans_in_std_macros(&mut self,
                     .to_string(),
                 span: MultiSpan::new(),
                 render_span: None,
-                list: vec![],
             });
         }
     }
 
+    fn msg_with_padding(&self, msg: &str, padding: usize) -> String {
+        let padding = (0..padding)
+            .map(|_| " ")
+            .collect::<String>();
+        msg.split('\n').enumerate().fold("".to_owned(), |mut acc, x| {
+            if x.0 != 0 {
+                acc.push_str("\n");
+                // Align every line with first one.
+                acc.push_str(&padding);
+            }
+            acc.push_str(&x.1);
+            acc
+        })
+    }
+
     fn emit_message_default(&mut self,
                             msp: &MultiSpan,
                             msg: &str,
@@ -722,7 +736,10 @@ fn emit_message_default(&mut self,
             draw_note_separator(&mut buffer, 0, max_line_num_len + 1);
             buffer.append(0, &level.to_string(), Style::HeaderMsg);
             buffer.append(0, ": ", Style::NoStyle);
-            buffer.append(0, msg, Style::NoStyle);
+
+            // The extra 9 ` ` is the padding that's always needed to align to the `note: `.
+            let message = self.msg_with_padding(msg, max_line_num_len + 9);
+            buffer.append(0, &message, Style::NoStyle);
         } else {
             buffer.append(0, &level.to_string(), Style::Level(level.clone()));
             match code {
@@ -855,7 +872,10 @@ fn emit_suggestion_default(&mut self,
 
             buffer.append(0, &level.to_string(), Style::Level(level.clone()));
             buffer.append(0, ": ", Style::HeaderMsg);
-            buffer.append(0, msg, Style::HeaderMsg);
+
+            // The extra 15 ` ` is the padding that's always needed to align to the `suggestion: `.
+            let message = self.msg_with_padding(msg, max_line_num_len + 15);
+            buffer.append(0, &message, Style::HeaderMsg);
 
             let lines = cm.span_to_lines(primary_span).unwrap();
 
@@ -924,51 +944,8 @@ fn emit_messages_default(&mut self,
                             }
                         },
                         None => {
-                            // Diagnostic with lists need to render the list items at the
-                            // appropriate depth and composed into the body of the message.
-                            let msg = if child.list.len() == 0 {
-                                // Diagnostics without lists just need the original message
-                                child.message.to_owned()
-                            } else {
-                                // Diagnostic with a list of items needs to be rendered with the
-                                // appropriate padding at the left to have a consistent margin with
-                                // the `note: ` text.
-
-                                // Add as many ` ` chars at the beggining to align the `- item`
-                                // text to the beggining of the `note: ` text. The extra 9 ` ` is
-                                // the padding that's always needed to align to the `note: `.
-                                let padding = (0..max_line_num_len + 9)
-                                    .map(|_| " ")
-                                    .collect::<String>();
-
-                                // Concatenate the message and all the list items, properly aligned
-                                child.list.iter().fold(child.message.to_owned(), |mut acc, x| {
-                                    acc.push_str("\n");
-                                    acc.push_str(&padding);
-                                    acc.push_str("- ");
-                                    acc.push_str(x);
-                                    acc
-                                })
-                                // msg will now be:
-                                //
-                                //     child.message's content
-                                //              - item 1
-                                //              - item 2
-                                //
-                                // and the diagnostic will look like
-                                //
-                                //     error: message
-                                //      --> file.rs:3:20
-                                //       |
-                                //     3 |     <Code>
-                                //       |      ^^^^ highlight
-                                //       |
-                                //       = help: child.message's content
-                                //               - item 1
-                                //               - item 2
-                            };
                             match self.emit_message_default(&child.span,
-                                                            &msg,
+                                                            &child.message,
                                                             &None,
                                                             &child.level,
                                                             max_line_num_len,
index 06d629c173256d4c4cd9fb77318d040e9f5372d1..3bc3d1a2c970eece32250b1b74fda5b41540d384 100644 (file)
@@ -70,15 +70,16 @@ pub fn demand_coerce(&self, expr: &hir::Expr, checked_ty: Ty<'tcx>, expected: Ty
                                                          ast::DUMMY_NODE_ID);
             let mut err = self.report_mismatched_types(&cause, expected, expr_ty, e);
             if suggestions.len() > 0 {
-                err.help_with_list("here are some functions which might fulfill your needs:",
-                                   self.get_best_match(&suggestions));
+                err.help(&format!("here are some functions which \
+                                   might fulfill your needs:\n{}",
+                                  self.get_best_match(&suggestions).join("\n")));
             };
             err.emit();
         }
     }
 
     fn format_method_suggestion(&self, method: &AssociatedItem) -> String {
-        format!(".{}({})",
+        format!(".{}({})",
                 method.name,
                 if self.has_no_input_arg(method) {
                     ""