]> git.lizzy.rs Git - rust.git/commitdiff
Minimize single span suggestions into a note
authorOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>
Fri, 24 Mar 2017 16:31:41 +0000 (17:31 +0100)
committerOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>
Tue, 25 Apr 2017 09:04:34 +0000 (11:04 +0200)
src/librustc_errors/diagnostic.rs
src/librustc_errors/diagnostic_builder.rs
src/librustc_errors/emitter.rs
src/librustc_errors/lib.rs
src/librustc_typeck/check/mod.rs
src/libsyntax/json.rs

index 9715ace3e2e2e5a6eb43f32d725c98a68ce15c1e..38fa35ecb126299a7fec1f01638447bf3c510b07 100644 (file)
@@ -11,7 +11,6 @@
 use CodeSuggestion;
 use Level;
 use RenderSpan;
-use RenderSpan::Suggestion;
 use std::fmt;
 use syntax_pos::{MultiSpan, Span};
 use snippet::Style;
@@ -24,6 +23,7 @@ pub struct Diagnostic {
     pub code: Option<String>,
     pub span: MultiSpan,
     pub children: Vec<SubDiagnostic>,
+    pub suggestion: Option<CodeSuggestion>,
 }
 
 /// For example a note attached to an error.
@@ -87,6 +87,7 @@ pub fn new_with_code(level: Level, code: Option<String>, message: &str) -> Self
             code: code,
             span: MultiSpan::new(),
             children: vec![],
+            suggestion: None,
         }
     }
 
@@ -202,19 +203,14 @@ pub fn span_help<S: Into<MultiSpan>>(&mut self,
 
     /// Prints out a message with a suggested edit of the code.
     ///
-    /// See `diagnostic::RenderSpan::Suggestion` for more information.
-    pub fn span_suggestion<S: Into<MultiSpan>>(&mut self,
-                                               sp: S,
-                                               msg: &str,
-                                               suggestion: String)
-                                               -> &mut Self {
-        self.sub(Level::Help,
-                 msg,
-                 MultiSpan::new(),
-                 Some(Suggestion(CodeSuggestion {
-                     msp: sp.into(),
-                     substitutes: vec![suggestion],
-                 })));
+    /// See `diagnostic::CodeSuggestion` for more information.
+    pub fn span_suggestion(&mut self, sp: Span, msg: &str, suggestion: String) -> &mut Self {
+        assert!(self.suggestion.is_none());
+        self.suggestion = Some(CodeSuggestion {
+            msp: sp.into(),
+            substitutes: vec![suggestion],
+            msg: msg.to_owned(),
+        });
         self
     }
 
index 7b27f13951b61b5babf4bc9c32ab37c71f5d8f10..9dfd47b8464d78ed730e51879491f49f4a660133 100644 (file)
@@ -141,11 +141,11 @@ pub fn emit(&mut self) {
                                                   sp: S,
                                                   msg: &str)
                                                   -> &mut Self);
-    forward!(pub fn span_suggestion<S: Into<MultiSpan>>(&mut self,
-                                                        sp: S,
-                                                        msg: &str,
-                                                        suggestion: String)
-                                                        -> &mut Self);
+    forward!(pub fn span_suggestion(&mut self,
+                                    sp: Span,
+                                    msg: &str,
+                                    suggestion: String)
+                                    -> &mut Self);
     forward!(pub fn set_span<S: Into<MultiSpan>>(&mut self, sp: S) -> &mut Self);
     forward!(pub fn code(&mut self, s: String) -> &mut Self);
 
index 64652bb308bdc4952af117da586ff704648c68c6..8855859d7c4ac28498af972948544a67465b0a1c 100644 (file)
@@ -34,6 +34,22 @@ impl Emitter for EmitterWriter {
     fn emit(&mut self, db: &DiagnosticBuilder) {
         let mut primary_span = db.span.clone();
         let mut children = db.children.clone();
+
+        if let Some(sugg) = db.suggestion.clone() {
+            assert_eq!(sugg.msp.primary_spans().len(), sugg.substitutes.len());
+            if sugg.substitutes.len() == 1 {
+                let msg = format!("{} `{}`", sugg.msg, sugg.substitutes[0]);
+                primary_span.push_span_label(sugg.msp.primary_spans()[0], msg);
+            } else {
+                children.push(SubDiagnostic {
+                    level: Level::Help,
+                    message: Vec::new(),
+                    span: MultiSpan::new(),
+                    render_span: Some(Suggestion(sugg)),
+                });
+            }
+        }
+
         self.fix_multispans_in_std_macros(&mut primary_span, &mut children);
         self.emit_messages_default(&db.level,
                                    &db.styled_message(),
@@ -756,7 +772,7 @@ fn fix_multispans_in_std_macros(&mut self,
     /// displayed, keeping the provided highlighting.
     fn msg_to_buffer(&self,
                      buffer: &mut StyledBuffer,
-                     msg: &Vec<(String, Style)>,
+                     msg: &[(String, Style)],
                      padding: usize,
                      label: &str,
                      override_style: Option<Style>) {
@@ -1022,7 +1038,6 @@ fn emit_message_default(&mut self,
     fn emit_suggestion_default(&mut self,
                                suggestion: &CodeSuggestion,
                                level: &Level,
-                               msg: &Vec<(String, Style)>,
                                max_line_num_len: usize)
                                -> io::Result<()> {
         use std::borrow::Borrow;
@@ -1034,7 +1049,7 @@ fn emit_suggestion_default(&mut self,
             buffer.append(0, &level.to_string(), Style::Level(level.clone()));
             buffer.append(0, ": ", Style::HeaderMsg);
             self.msg_to_buffer(&mut buffer,
-                               msg,
+                               &[(suggestion.msg.to_owned(), Style::NoStyle)],
                                max_line_num_len,
                                "suggestion",
                                Some(Style::HeaderMsg));
@@ -1099,7 +1114,6 @@ fn emit_messages_default(&mut self,
                         Some(Suggestion(ref cs)) => {
                             match self.emit_suggestion_default(cs,
                                                                &child.level,
-                                                               &child.styled_message(),
                                                                max_line_num_len) {
                                 Err(e) => panic!("failed to emit error: {}", e),
                                 _ => ()
index da29e354a7014eeae31e26f438f63fac7dad4d74..15e73fa4e7600ea7116d22a8a7d626f05927f4d8 100644 (file)
@@ -67,6 +67,7 @@ pub enum RenderSpan {
 pub struct CodeSuggestion {
     pub msp: MultiSpan,
     pub substitutes: Vec<String>,
+    pub msg: String,
 }
 
 pub trait CodeMapper {
index 098e8c53a52c12c89582022d77d05da0afcaebd4..690fe59f8ce450030fd425259ff6f5bd0c3ec7b3 100644 (file)
@@ -3804,9 +3804,7 @@ fn check_expr_kind(&self,
                                       let snip = tcx.sess.codemap().span_to_snippet(base.span);
                                       if let Ok(snip) = snip {
                                           err.span_suggestion(expr.span,
-                                                              "to access tuple elements, \
-                                                               use tuple indexing syntax \
-                                                               as shown",
+                                                              "to access tuple elements, use",
                                                               format!("{}.{}", snip, i));
                                           needs_note = false;
                                       }
index dec1b7d1d87be4bf09bcec60d3981061682ff962..7d8064a6a450428d61cd90d2013ab2d9dfd6b344 100644 (file)
@@ -22,8 +22,9 @@
 use codemap::CodeMap;
 use syntax_pos::{self, MacroBacktrace, Span, SpanLabel, MultiSpan};
 use errors::registry::Registry;
-use errors::{DiagnosticBuilder, SubDiagnostic, RenderSpan, CodeSuggestion, CodeMapper};
+use errors::{Level, DiagnosticBuilder, SubDiagnostic, RenderSpan, CodeSuggestion, CodeMapper};
 use errors::emitter::Emitter;
+use errors::snippet::Style;
 
 use std::rc::Rc;
 use std::io::{self, Write};
@@ -152,12 +153,21 @@ impl Diagnostic {
     fn from_diagnostic_builder(db: &DiagnosticBuilder,
                                je: &JsonEmitter)
                                -> Diagnostic {
+        let sugg = db.suggestion.as_ref().map(|sugg| {
+            SubDiagnostic {
+                level: Level::Help,
+                message: vec![(sugg.msg.clone(), Style::NoStyle)],
+                span: MultiSpan::new(),
+                render_span: Some(RenderSpan::Suggestion(sugg.clone())),
+            }
+        });
+        let sugg = sugg.as_ref();
         Diagnostic {
             message: db.message(),
             code: DiagnosticCode::map_opt_string(db.code.clone(), je),
             level: db.level.to_str(),
             spans: DiagnosticSpan::from_multispan(&db.span, je),
-            children: db.children.iter().map(|c| {
+            children: db.children.iter().chain(sugg).map(|c| {
                 Diagnostic::from_sub_diagnostic(c, je)
             }).collect(),
             rendered: None,