]> git.lizzy.rs Git - rust.git/commitdiff
Teach diagnostics to have correctly padded lists
authorEsteban Küber <esteban@kuber.com.ar>
Sun, 8 Jan 2017 05:12:33 +0000 (21:12 -0800)
committerEsteban Küber <esteban@kuber.com.ar>
Sun, 8 Jan 2017 07:34:37 +0000 (23:34 -0800)
Make the suggestion list have a correct padding:

```
error[E0308]: mismatched types
 --> file.rs:3:20
  |
3 |     let x: usize = "";
  |                    ^^ expected usize, found reference
  |
  = note: expected type `usize`
  = note:    found type `&'static str`
  = help: here are some functions which might fulfill your needs:
          - .len()
          - .foo()
          - .bar()
```

src/librustc_errors/diagnostic.rs
src/librustc_errors/diagnostic_builder.rs
src/librustc_errors/emitter.rs
src/librustc_typeck/check/demand.rs
src/test/ui/resolve/token-error-correct-3.stderr
src/test/ui/span/coerce-suggestions.stderr

index 730ca8f9e2e4474e97735ffd13ad6a553f51183c..73a8343eafc45218af566604006b19c7e72c5c5b 100644 (file)
@@ -32,6 +32,7 @@ pub struct SubDiagnostic {
     pub message: String,
     pub span: MultiSpan,
     pub render_span: Option<RenderSpan>,
+    pub list: Vec<String>,
 }
 
 impl Diagnostic {
@@ -132,6 +133,11 @@ 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)
@@ -191,11 +197,23 @@ 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 7dfea6b8951b05f2aebd649e338124e57af9fbf6..24f1b86739da6fa36f05454c23242e1a9c1b908a 100644 (file)
@@ -135,6 +135,7 @@ 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 808fe504b95cdc241f231604587e50d2125e8795..015997211bb3f07d03a617a8a782b9b962d32662 100644 (file)
@@ -699,6 +699,7 @@ fn fix_multispans_in_std_macros(&mut self,
                     .to_string(),
                 span: MultiSpan::new(),
                 render_span: None,
+                list: vec![],
             });
         }
     }
@@ -923,14 +924,28 @@ fn emit_messages_default(&mut self,
                             }
                         },
                         None => {
+                            let msg = if child.list.len() == 0 {
+                                child.message.to_owned()
+                            } else {
+                                format!("{}\n{}",
+                                        &child.message,
+                                        &child.list.iter().map(|item| {
+                                            format!("{}         - {}",
+                                                    (0..max_line_num_len)
+                                                          .map(|_| " ")
+                                                          .collect::<String>(),
+                                                    item)
+                                        }).collect::<Vec<String>>()
+                                        .join("\n"))
+                            };
                             match self.emit_message_default(&child.span,
-                                                            &child.message,
+                                                            &msg,
                                                             &None,
                                                             &child.level,
                                                             max_line_num_len,
                                                             true) {
                                 Err(e) => panic!("failed to emit error: {}", e),
-                                _ => ()
+                                _ => (),
                             }
                         }
                     }
index 393d9341a08432151876eb73941c90d3e5d50964..06d629c173256d4c4cd9fb77318d040e9f5372d1 100644 (file)
@@ -70,9 +70,8 @@ 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(&format!("here are some functions which \
-                                   might fulfill your needs:\n - {}",
-                                  self.get_best_match(&suggestions)));
+                err.help_with_list("here are some functions which might fulfill your needs:",
+                                   self.get_best_match(&suggestions));
             };
             err.emit();
         }
@@ -88,15 +87,14 @@ fn format_method_suggestion(&self, method: &AssociatedItem) -> String {
                 })
     }
 
-    fn display_suggested_methods(&self, methods: &[AssociatedItem]) -> String {
+    fn display_suggested_methods(&self, methods: &[AssociatedItem]) -> Vec<String> {
         methods.iter()
                .take(5)
                .map(|method| self.format_method_suggestion(&*method))
                .collect::<Vec<String>>()
-               .join("\n - ")
     }
 
-    fn get_best_match(&self, methods: &[AssociatedItem]) -> String {
+    fn get_best_match(&self, methods: &[AssociatedItem]) -> Vec<String> {
         let no_argument_methods: Vec<_> =
             methods.iter()
                    .filter(|ref x| self.has_no_input_arg(&*x))
index 0b15c23909ca65cf3bed29f124762b7fcdaaee50..bb6f310fec81387c3c1003078f303f9c5251641f 100644 (file)
@@ -37,9 +37,9 @@ error[E0308]: mismatched types
    = note: expected type `()`
    = note:    found type `std::result::Result<bool, std::io::Error>`
    = help: here are some functions which might fulfill your needs:
- - .unwrap()
- - .unwrap_err()
- - .unwrap_or_default()
          - .unwrap()
          - .unwrap_err()
          - .unwrap_or_default()
 
 error: aborting due to previous error
 
index e316466150703c3dbf66ca61c049ab74a2d1c463..ed1bcd318a4f69f280b1d6e86ee46c9b547b71a5 100644 (file)
@@ -7,8 +7,8 @@ error[E0308]: mismatched types
    = note: expected type `usize`
    = note:    found type `std::string::String`
    = help: here are some functions which might fulfill your needs:
- - .capacity()
- - .len()
          - .capacity()
          - .len()
 
 error[E0308]: mismatched types
   --> $DIR/coerce-suggestions.rs:23:19
@@ -19,10 +19,10 @@ error[E0308]: mismatched types
    = note: expected type `&str`
    = note:    found type `std::string::String`
    = help: here are some functions which might fulfill your needs:
- - .as_str()
- - .trim()
- - .trim_left()
- - .trim_right()
          - .as_str()
          - .trim()
          - .trim_left()
          - .trim_right()
 
 error[E0308]: mismatched types
   --> $DIR/coerce-suggestions.rs:30:10