about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPhilipp Hansch <dev@phansch.net>2019-02-24 14:11:05 +0100
committerPhilipp Hansch <dev@phansch.net>2019-02-24 14:11:05 +0100
commit7d883cddbc7d8e73a1b9e638b33f00a2ce4001a8 (patch)
treee2845ba1e56606e8ba74b785b8dc3e0b4e477dce
parentff1b1a7c9f5bf5a30368ec9f746933ced5ae76d0 (diff)
downloadrust-7d883cddbc7d8e73a1b9e638b33f00a2ce4001a8.tar.gz
rust-7d883cddbc7d8e73a1b9e638b33f00a2ce4001a8.zip
Extract diagnostics module and document some functions
This moves the lint building functions from `utils/mod.rs` to their own
`utils/diagnostics.rs` file. Also adds documentation for three of them.
-rw-r--r--clippy_lints/src/utils/diagnostics.rs205
-rw-r--r--clippy_lints/src/utils/mod.rs202
2 files changed, 208 insertions, 199 deletions
diff --git a/clippy_lints/src/utils/diagnostics.rs b/clippy_lints/src/utils/diagnostics.rs
new file mode 100644
index 00000000000..e676a28fe65
--- /dev/null
+++ b/clippy_lints/src/utils/diagnostics.rs
@@ -0,0 +1,205 @@
+//! Clippy wrappers around rustc's diagnostic functions.
+
+use crate::reexport::*;
+use rustc::lint::{LateContext, Lint, LintContext};
+use rustc_errors::{Applicability, CodeSuggestion, Substitution, SubstitutionPart, SuggestionStyle};
+use std::env;
+use syntax::errors::DiagnosticBuilder;
+use syntax::source_map::Span;
+
+/// Wrapper around `DiagnosticBuilder` that adds a link to Clippy documentation for the emitted lint
+pub struct DiagnosticWrapper<'a>(pub DiagnosticBuilder<'a>);
+
+impl<'a> Drop for DiagnosticWrapper<'a> {
+    fn drop(&mut self) {
+        self.0.emit();
+    }
+}
+
+impl<'a> DiagnosticWrapper<'a> {
+    fn docs_link(&mut self, lint: &'static Lint) {
+        if env::var("CLIPPY_DISABLE_DOCS_LINKS").is_err() {
+            self.0.help(&format!(
+                "for further information visit https://rust-lang.github.io/rust-clippy/{}/index.html#{}",
+                &option_env!("RUST_RELEASE_NUM").map_or("master".to_string(), |n| {
+                    // extract just major + minor version and ignore patch versions
+                    format!("rust-{}", n.rsplitn(2, '.').nth(1).unwrap())
+                }),
+                lint.name_lower().replacen("clippy::", "", 1)
+            ));
+        }
+    }
+}
+
+/// Emit a basic lint message with a `msg` and a `span`.
+///
+/// This is the most primitive of our lint emission methods and can
+/// be a good way to get a new lint started.
+///
+/// Usually it's nicer to provide more context for lint messages.
+/// Be sure the output is understandable when you use this method.
+///
+/// # Example
+///
+/// ```ignore
+/// error: usage of mem::forget on Drop type
+///   --> $DIR/mem_forget.rs:17:5
+///    |
+/// 17 |     std::mem::forget(seven);
+///    |     ^^^^^^^^^^^^^^^^^^^^^^^
+/// ```
+pub fn span_lint<'a, T: LintContext<'a>>(cx: &T, lint: &'static Lint, sp: Span, msg: &str) {
+    DiagnosticWrapper(cx.struct_span_lint(lint, sp, msg)).docs_link(lint);
+}
+
+/// Same as `span_lint` but with an extra `help` message.
+///
+/// Use this if you want to provide some general help but
+/// can't provide a specific machine applicable suggestion.
+///
+/// The `help` message is not attached to any `Span`.
+///
+/// # Example
+///
+/// ```ignore
+/// error: constant division of 0.0 with 0.0 will always result in NaN
+///   --> $DIR/zero_div_zero.rs:6:25
+///    |
+/// 6  |     let other_f64_nan = 0.0f64 / 0.0;
+///    |                         ^^^^^^^^^^^^
+///    |
+///    = help: Consider using `std::f64::NAN` if you would like a constant representing NaN
+/// ```
+pub fn span_help_and_lint<'a, 'tcx: 'a, T: LintContext<'tcx>>(
+    cx: &'a T,
+    lint: &'static Lint,
+    span: Span,
+    msg: &str,
+    help: &str,
+) {
+    let mut db = DiagnosticWrapper(cx.struct_span_lint(lint, span, msg));
+    db.0.help(help);
+    db.docs_link(lint);
+}
+
+/// Like `span_lint` but with a `note` section instead of a `help` message.
+///
+/// The `note` message is presented separately from the main lint message
+/// and is attached to a specific span:
+///
+/// # Example
+///
+/// ```ignore
+/// error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing.
+///   --> $DIR/drop_forget_ref.rs:10:5
+///    |
+/// 10 |     forget(&SomeStruct);
+///    |     ^^^^^^^^^^^^^^^^^^^
+///    |
+///    = note: `-D clippy::forget-ref` implied by `-D warnings`
+/// note: argument has type &SomeStruct
+///   --> $DIR/drop_forget_ref.rs:10:12
+///    |
+/// 10 |     forget(&SomeStruct);
+///    |            ^^^^^^^^^^^
+/// ```
+pub fn span_note_and_lint<'a, 'tcx: 'a, T: LintContext<'tcx>>(
+    cx: &'a T,
+    lint: &'static Lint,
+    span: Span,
+    msg: &str,
+    note_span: Span,
+    note: &str,
+) {
+    let mut db = DiagnosticWrapper(cx.struct_span_lint(lint, span, msg));
+    if note_span == span {
+        db.0.note(note);
+    } else {
+        db.0.span_note(note_span, note);
+    }
+    db.docs_link(lint);
+}
+
+pub fn span_lint_and_then<'a, 'tcx: 'a, T: LintContext<'tcx>, F>(
+    cx: &'a T,
+    lint: &'static Lint,
+    sp: Span,
+    msg: &str,
+    f: F,
+) where
+    F: for<'b> FnOnce(&mut DiagnosticBuilder<'b>),
+{
+    let mut db = DiagnosticWrapper(cx.struct_span_lint(lint, sp, msg));
+    f(&mut db.0);
+    db.docs_link(lint);
+}
+
+pub fn span_lint_node(cx: &LateContext<'_, '_>, lint: &'static Lint, node: NodeId, sp: Span, msg: &str) {
+    DiagnosticWrapper(cx.tcx.struct_span_lint_node(lint, node, sp, msg)).docs_link(lint);
+}
+
+pub fn span_lint_node_and_then(
+    cx: &LateContext<'_, '_>,
+    lint: &'static Lint,
+    node: NodeId,
+    sp: Span,
+    msg: &str,
+    f: impl FnOnce(&mut DiagnosticBuilder<'_>),
+) {
+    let mut db = DiagnosticWrapper(cx.tcx.struct_span_lint_node(lint, node, sp, msg));
+    f(&mut db.0);
+    db.docs_link(lint);
+}
+
+/// Add a span lint with a suggestion on how to fix it.
+///
+/// These suggestions can be parsed by rustfix to allow it to automatically fix your code.
+/// In the example below, `help` is `"try"` and `sugg` is the suggested replacement `".any(|x| x >
+/// 2)"`.
+///
+/// ```ignore
+/// error: This `.fold` can be more succinctly expressed as `.any`
+/// --> $DIR/methods.rs:390:13
+///     |
+/// 390 |     let _ = (0..3).fold(false, |acc, x| acc || x > 2);
+///     |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `.any(|x| x > 2)`
+///     |
+///     = note: `-D fold-any` implied by `-D warnings`
+/// ```
+pub fn span_lint_and_sugg<'a, 'tcx: 'a, T: LintContext<'tcx>>(
+    cx: &'a T,
+    lint: &'static Lint,
+    sp: Span,
+    msg: &str,
+    help: &str,
+    sugg: String,
+    applicability: Applicability,
+) {
+    span_lint_and_then(cx, lint, sp, msg, |db| {
+        db.span_suggestion(sp, help, sugg, applicability);
+    });
+}
+
+/// Create a suggestion made from several `span → replacement`.
+///
+/// Note: in the JSON format (used by `compiletest_rs`), the help message will
+/// appear once per
+/// replacement. In human-readable format though, it only appears once before
+/// the whole suggestion.
+pub fn multispan_sugg<I>(db: &mut DiagnosticBuilder<'_>, help_msg: String, sugg: I)
+where
+    I: IntoIterator<Item = (Span, String)>,
+{
+    let sugg = CodeSuggestion {
+        substitutions: vec![Substitution {
+            parts: sugg
+                .into_iter()
+                .map(|(span, snippet)| SubstitutionPart { snippet, span })
+                .collect(),
+        }],
+        msg: help_msg,
+        style: SuggestionStyle::ShowCode,
+        applicability: Applicability::Unspecified,
+    };
+    db.suggestions.push(sugg);
+}
diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs
index 4c9a3327eda..c5af70cae96 100644
--- a/clippy_lints/src/utils/mod.rs
+++ b/clippy_lints/src/utils/mod.rs
@@ -17,14 +17,12 @@ use rustc::ty::{
     Binder, Ty, TyCtxt,
 };
 use rustc_data_structures::sync::Lrc;
-use rustc_errors::{Applicability, CodeSuggestion, Substitution, SubstitutionPart, SuggestionStyle};
+use rustc_errors::Applicability;
 use std::borrow::Cow;
-use std::env;
 use std::mem;
 use std::str::FromStr;
 use syntax::ast::{self, LitKind};
 use syntax::attr;
-use syntax::errors::DiagnosticBuilder;
 use syntax::source_map::{Span, DUMMY_SP};
 use syntax::symbol;
 use syntax::symbol::{keywords, Symbol};
@@ -35,6 +33,7 @@ pub mod author;
 pub mod comparisons;
 pub mod conf;
 pub mod constants;
+mod diagnostics;
 mod hir_utils;
 pub mod inspector;
 pub mod internal_lints;
@@ -42,6 +41,7 @@ pub mod paths;
 pub mod ptr;
 pub mod sugg;
 pub mod usage;
+pub use self::diagnostics::*;
 pub use self::hir_utils::{SpanlessEq, SpanlessHash};
 
 pub mod higher;
@@ -611,202 +611,6 @@ pub fn get_enclosing_block<'a, 'tcx: 'a>(cx: &LateContext<'a, 'tcx>, node: NodeI
     }
 }
 
-pub struct DiagnosticWrapper<'a>(pub DiagnosticBuilder<'a>);
-
-impl<'a> Drop for DiagnosticWrapper<'a> {
-    fn drop(&mut self) {
-        self.0.emit();
-    }
-}
-
-impl<'a> DiagnosticWrapper<'a> {
-    fn docs_link(&mut self, lint: &'static Lint) {
-        if env::var("CLIPPY_DISABLE_DOCS_LINKS").is_err() {
-            self.0.help(&format!(
-                "for further information visit https://rust-lang.github.io/rust-clippy/{}/index.html#{}",
-                &option_env!("RUST_RELEASE_NUM").map_or("master".to_string(), |n| {
-                    // extract just major + minor version and ignore patch versions
-                    format!("rust-{}", n.rsplitn(2, '.').nth(1).unwrap())
-                }),
-                lint.name_lower().replacen("clippy::", "", 1)
-            ));
-        }
-    }
-}
-
-/// Emit a basic lint message with a `msg` and a `span`.
-///
-/// This is the most primitive of our lint emission methods and can
-/// be a good way to get a new lint started.
-///
-/// Usually it's nicer to provide more context for lint messages.
-/// Be sure the output is understandable when you use this method.
-///
-/// # Example
-///
-/// ```ignore
-/// error: usage of mem::forget on Drop type
-///   --> $DIR/mem_forget.rs:17:5
-///    |
-/// 17 |     std::mem::forget(seven);
-///    |     ^^^^^^^^^^^^^^^^^^^^^^^
-/// ```
-pub fn span_lint<'a, T: LintContext<'a>>(cx: &T, lint: &'static Lint, sp: Span, msg: &str) {
-    DiagnosticWrapper(cx.struct_span_lint(lint, sp, msg)).docs_link(lint);
-}
-
-/// Same as `span_lint` but with an extra `help` message.
-///
-/// Use this if you want to provide some general help but
-/// can't provide a specific machine applicable suggestion.
-///
-/// The `help` message is not attached to any `Span`.
-///
-/// # Example
-///
-/// ```ignore
-/// error: constant division of 0.0 with 0.0 will always result in NaN
-///   --> $DIR/zero_div_zero.rs:6:25
-///    |
-/// 6  |     let other_f64_nan = 0.0f64 / 0.0;
-///    |                         ^^^^^^^^^^^^
-///    |
-///    = help: Consider using `std::f64::NAN` if you would like a constant representing NaN
-/// ```
-pub fn span_help_and_lint<'a, 'tcx: 'a, T: LintContext<'tcx>>(
-    cx: &'a T,
-    lint: &'static Lint,
-    span: Span,
-    msg: &str,
-    help: &str,
-) {
-    let mut db = DiagnosticWrapper(cx.struct_span_lint(lint, span, msg));
-    db.0.help(help);
-    db.docs_link(lint);
-}
-
-/// Like `span_lint` but with a `note` section instead of a `help` message.
-///
-/// The `note` message is presented separately from the main lint message
-/// and is attached to a specific span:
-///
-/// # Example
-///
-/// ```ignore
-/// error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing.
-///   --> $DIR/drop_forget_ref.rs:10:5
-///    |
-/// 10 |     forget(&SomeStruct);
-///    |     ^^^^^^^^^^^^^^^^^^^
-///    |
-///    = note: `-D clippy::forget-ref` implied by `-D warnings`
-/// note: argument has type &SomeStruct
-///   --> $DIR/drop_forget_ref.rs:10:12
-///    |
-/// 10 |     forget(&SomeStruct);
-///    |            ^^^^^^^^^^^
-/// ```
-pub fn span_note_and_lint<'a, 'tcx: 'a, T: LintContext<'tcx>>(
-    cx: &'a T,
-    lint: &'static Lint,
-    span: Span,
-    msg: &str,
-    note_span: Span,
-    note: &str,
-) {
-    let mut db = DiagnosticWrapper(cx.struct_span_lint(lint, span, msg));
-    if note_span == span {
-        db.0.note(note);
-    } else {
-        db.0.span_note(note_span, note);
-    }
-    db.docs_link(lint);
-}
-
-pub fn span_lint_and_then<'a, 'tcx: 'a, T: LintContext<'tcx>, F>(
-    cx: &'a T,
-    lint: &'static Lint,
-    sp: Span,
-    msg: &str,
-    f: F,
-) where
-    F: for<'b> FnOnce(&mut DiagnosticBuilder<'b>),
-{
-    let mut db = DiagnosticWrapper(cx.struct_span_lint(lint, sp, msg));
-    f(&mut db.0);
-    db.docs_link(lint);
-}
-
-pub fn span_lint_node(cx: &LateContext<'_, '_>, lint: &'static Lint, node: NodeId, sp: Span, msg: &str) {
-    DiagnosticWrapper(cx.tcx.struct_span_lint_node(lint, node, sp, msg)).docs_link(lint);
-}
-
-pub fn span_lint_node_and_then(
-    cx: &LateContext<'_, '_>,
-    lint: &'static Lint,
-    node: NodeId,
-    sp: Span,
-    msg: &str,
-    f: impl FnOnce(&mut DiagnosticBuilder<'_>),
-) {
-    let mut db = DiagnosticWrapper(cx.tcx.struct_span_lint_node(lint, node, sp, msg));
-    f(&mut db.0);
-    db.docs_link(lint);
-}
-
-/// Add a span lint with a suggestion on how to fix it.
-///
-/// These suggestions can be parsed by rustfix to allow it to automatically fix your code.
-/// In the example below, `help` is `"try"` and `sugg` is the suggested replacement `".any(|x| x >
-/// 2)"`.
-///
-/// ```ignore
-/// error: This `.fold` can be more succinctly expressed as `.any`
-/// --> $DIR/methods.rs:390:13
-///     |
-/// 390 |     let _ = (0..3).fold(false, |acc, x| acc || x > 2);
-///     |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `.any(|x| x > 2)`
-///     |
-///     = note: `-D fold-any` implied by `-D warnings`
-/// ```
-pub fn span_lint_and_sugg<'a, 'tcx: 'a, T: LintContext<'tcx>>(
-    cx: &'a T,
-    lint: &'static Lint,
-    sp: Span,
-    msg: &str,
-    help: &str,
-    sugg: String,
-    applicability: Applicability,
-) {
-    span_lint_and_then(cx, lint, sp, msg, |db| {
-        db.span_suggestion(sp, help, sugg, applicability);
-    });
-}
-
-/// Create a suggestion made from several `span → replacement`.
-///
-/// Note: in the JSON format (used by `compiletest_rs`), the help message will
-/// appear once per
-/// replacement. In human-readable format though, it only appears once before
-/// the whole suggestion.
-pub fn multispan_sugg<I>(db: &mut DiagnosticBuilder<'_>, help_msg: String, sugg: I)
-where
-    I: IntoIterator<Item = (Span, String)>,
-{
-    let sugg = CodeSuggestion {
-        substitutions: vec![Substitution {
-            parts: sugg
-                .into_iter()
-                .map(|(span, snippet)| SubstitutionPart { snippet, span })
-                .collect(),
-        }],
-        msg: help_msg,
-        style: SuggestionStyle::ShowCode,
-        applicability: Applicability::Unspecified,
-    };
-    db.suggestions.push(sugg);
-}
-
 /// Return the base type for HIR references and pointers.
 pub fn walk_ptrs_hir_ty(ty: &hir::Ty) -> &hir::Ty {
     match ty.node {