about summary refs log tree commit diff
diff options
context:
space:
mode:
authorZack M. Davis <code@zackmdavis.net>2017-11-24 10:26:42 -0800
committerZack M. Davis <code@zackmdavis.net>2017-12-09 16:33:32 -0800
commit883f5e5e657e714650d34cfb271abd8015210d08 (patch)
tree0cb7a4bc852809787b3c31b13ed579295868f718
parent6fa53b00e7450060a3af9b1ef63169db37e589c2 (diff)
one-time diagnostics: span_suggestion, generalize methods for non-lints
304c8b1edabcd made the Session's one-time-diagnostics set take a
special-purpose `DiagnosticMessageId` enum rather than a LintID so that
it could support more than just lints, but the `diag_span_note_once` and
`diag_note_once` methods continued to take references to lints: for API
consistency, we now make these methods take a `DiagnosticMessageId`
while we add support for one-time span-suggestions.
-rw-r--r--src/librustc/lint/mod.rs13
-rw-r--r--src/librustc/session/mod.rs40
2 files changed, 39 insertions, 14 deletions
diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs
index 906cae53710..f0761ce6178 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -37,7 +37,7 @@ use errors::{DiagnosticBuilder, DiagnosticId};
 use hir::def_id::{CrateNum, LOCAL_CRATE};
 use hir::intravisit::{self, FnKind};
 use hir;
-use session::Session;
+use session::{Session, DiagnosticMessageId};
 use std::hash;
 use syntax::ast;
 use syntax::codemap::MultiSpan;
@@ -423,7 +423,7 @@ pub fn struct_lint_level<'a>(sess: &'a Session,
         LintSource::Default => {
             sess.diag_note_once(
                 &mut err,
-                lint,
+                DiagnosticMessageId::from(lint),
                 &format!("#[{}({})] on by default", level.as_str(), name));
         }
         LintSource::CommandLine(lint_flag_val) => {
@@ -437,24 +437,25 @@ pub fn struct_lint_level<'a>(sess: &'a Session,
             if lint_flag_val.as_str() == name {
                 sess.diag_note_once(
                     &mut err,
-                    lint,
+                    DiagnosticMessageId::from(lint),
                     &format!("requested on the command line with `{} {}`",
                              flag, hyphen_case_lint_name));
             } else {
                 let hyphen_case_flag_val = lint_flag_val.as_str().replace("_", "-");
                 sess.diag_note_once(
                     &mut err,
-                    lint,
+                    DiagnosticMessageId::from(lint),
                     &format!("`{} {}` implied by `{} {}`",
                              flag, hyphen_case_lint_name, flag,
                              hyphen_case_flag_val));
             }
         }
         LintSource::Node(lint_attr_name, src) => {
-            sess.diag_span_note_once(&mut err, lint, src, "lint level defined here");
+            sess.diag_span_note_once(&mut err, DiagnosticMessageId::from(lint),
+                                     src, "lint level defined here");
             if lint_attr_name.as_str() != name {
                 let level_str = level.as_str();
-                sess.diag_note_once(&mut err, lint,
+                sess.diag_note_once(&mut err, DiagnosticMessageId::from(lint),
                                     &format!("#[{}({})] implied by #[{}({})]",
                                              level_str, name, level_str, lint_attr_name));
             }
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index df5805bacd4..36c1966bdc8 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -161,6 +161,7 @@ pub struct PerfStats {
 enum DiagnosticBuilderMethod {
     Note,
     SpanNote,
+    SpanSuggestion(String), // suggestion
     // add more variants as needed to support one-time diagnostics
 }
 
@@ -173,6 +174,12 @@ pub enum DiagnosticMessageId {
     StabilityId(u32) // issue number
 }
 
+impl From<&'static lint::Lint> for DiagnosticMessageId {
+    fn from(lint: &'static lint::Lint) -> Self {
+        DiagnosticMessageId::LintId(lint::LintId::of(lint))
+    }
+}
+
 impl Session {
     pub fn local_crate_disambiguator(&self) -> CrateDisambiguator {
         match *self.crate_disambiguator.borrow() {
@@ -358,10 +365,11 @@ impl Session {
     fn diag_once<'a, 'b>(&'a self,
                          diag_builder: &'b mut DiagnosticBuilder<'a>,
                          method: DiagnosticBuilderMethod,
-                         lint: &'static lint::Lint, message: &str, span: Option<Span>) {
+                         msg_id: DiagnosticMessageId,
+                         message: &str,
+                         span_maybe: Option<Span>) {
 
-        let lint_id = DiagnosticMessageId::LintId(lint::LintId::of(lint));
-        let id_span_message = (lint_id, span, message.to_owned());
+        let id_span_message = (msg_id, span_maybe, message.to_owned());
         let fresh = self.one_time_diagnostics.borrow_mut().insert(id_span_message);
         if fresh {
             match method {
@@ -369,7 +377,12 @@ impl Session {
                     diag_builder.note(message);
                 },
                 DiagnosticBuilderMethod::SpanNote => {
-                    diag_builder.span_note(span.expect("span_note expects a span"), message);
+                    let span = span_maybe.expect("span_note needs a span");
+                    diag_builder.span_note(span, message);
+                },
+                DiagnosticBuilderMethod::SpanSuggestion(suggestion) => {
+                    let span = span_maybe.expect("span_suggestion needs a span");
+                    diag_builder.span_suggestion(span, message, suggestion);
                 }
             }
         }
@@ -377,14 +390,25 @@ impl Session {
 
     pub fn diag_span_note_once<'a, 'b>(&'a self,
                                        diag_builder: &'b mut DiagnosticBuilder<'a>,
-                                       lint: &'static lint::Lint, span: Span, message: &str) {
-        self.diag_once(diag_builder, DiagnosticBuilderMethod::SpanNote, lint, message, Some(span));
+                                       msg_id: DiagnosticMessageId, span: Span, message: &str) {
+        self.diag_once(diag_builder, DiagnosticBuilderMethod::SpanNote,
+                       msg_id, message, Some(span));
     }
 
     pub fn diag_note_once<'a, 'b>(&'a self,
                                   diag_builder: &'b mut DiagnosticBuilder<'a>,
-                                  lint: &'static lint::Lint, message: &str) {
-        self.diag_once(diag_builder, DiagnosticBuilderMethod::Note, lint, message, None);
+                                  msg_id: DiagnosticMessageId, message: &str) {
+        self.diag_once(diag_builder, DiagnosticBuilderMethod::Note, msg_id, message, None);
+    }
+
+    pub fn diag_span_suggestion_once<'a, 'b>(&'a self,
+                                             diag_builder: &'b mut DiagnosticBuilder<'a>,
+                                             msg_id: DiagnosticMessageId,
+                                             span: Span,
+                                             message: &str,
+                                             suggestion: String) {
+        self.diag_once(diag_builder, DiagnosticBuilderMethod::SpanSuggestion(suggestion),
+                       msg_id, message, Some(span));
     }
 
     pub fn codemap<'a>(&'a self) -> &'a codemap::CodeMap {