From fe96ffeac98481433c33e3e9f49a56f70f8ec134 Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Tue, 5 Mar 2019 11:50:33 -0500 Subject: [PATCH] move lint documentation into macro invocations --- clippy_dev/src/lib.rs | 8 +- clippy_lints/src/approx_const.rs | 42 +- clippy_lints/src/arithmetic.rs | 46 +- clippy_lints/src/assertions_on_constants.rs | 32 +- clippy_lints/src/assign_ops.rs | 60 +- clippy_lints/src/attrs.rs | 266 ++-- clippy_lints/src/bit_mask.rs | 128 +- clippy_lints/src/blacklisted_name.rs | 24 +- clippy_lints/src/block_in_if_condition.rs | 50 +- clippy_lints/src/booleans.rs | 52 +- clippy_lints/src/bytecount.rs | 30 +- clippy_lints/src/cargo_common_metadata.rs | 42 +- clippy_lints/src/collapsible_if.rs | 88 +- clippy_lints/src/const_static_lifetime.rs | 32 +- clippy_lints/src/copies.rs | 150 +-- clippy_lints/src/copy_iterator.rs | 40 +- clippy_lints/src/cyclomatic_complexity.rs | 18 +- clippy_lints/src/dbg_macro.rs | 30 +- clippy_lints/src/default_trait_access.rs | 30 +- clippy_lints/src/derive.rs | 86 +- clippy_lints/src/doc.rs | 36 +- clippy_lints/src/double_comparison.rs | 34 +- clippy_lints/src/double_parens.rs | 26 +- clippy_lints/src/drop_bounds.rs | 44 +- clippy_lints/src/drop_forget_ref.rs | 136 +- clippy_lints/src/duration_subsec.rs | 28 +- clippy_lints/src/else_if_without_else.rs | 54 +- clippy_lints/src/empty_enum.rs | 24 +- clippy_lints/src/entry.rs | 46 +- clippy_lints/src/enum_clike.rs | 32 +- clippy_lints/src/enum_glob_use.rs | 24 +- clippy_lints/src/enum_variants.rs | 138 +-- clippy_lints/src/eq_op.rs | 54 +- clippy_lints/src/erasing_op.rs | 28 +- clippy_lints/src/escape.rs | 34 +- clippy_lints/src/eta_reduction.rs | 38 +- clippy_lints/src/eval_order_dependence.rs | 70 +- clippy_lints/src/excessive_precision.rs | 36 +- clippy_lints/src/explicit_write.rs | 24 +- clippy_lints/src/fallible_impl_from.rs | 30 +- clippy_lints/src/format.rs | 32 +- clippy_lints/src/formatting.rs | 112 +- clippy_lints/src/functions.rs | 106 +- clippy_lints/src/identity_conversion.rs | 22 +- clippy_lints/src/identity_op.rs | 22 +- clippy_lints/src/if_not_else.rs | 50 +- clippy_lints/src/implicit_return.rs | 44 +- clippy_lints/src/indexing_slicing.rs | 124 +- .../src/infallible_destructuring_match.rs | 58 +- clippy_lints/src/infinite_iter.rs | 46 +- clippy_lints/src/inherent_impl.rs | 52 +- clippy_lints/src/inline_fn_without_body.rs | 28 +- clippy_lints/src/int_plus_one.rs | 34 +- clippy_lints/src/invalid_ref.rs | 20 +- clippy_lints/src/items_after_statements.rs | 44 +- clippy_lints/src/large_enum_variant.rs | 32 +- clippy_lints/src/len_zero.rs | 103 +- clippy_lints/src/let_if_seq.rs | 78 +- clippy_lints/src/lib.rs | 92 +- clippy_lints/src/lifetimes.rs | 70 +- clippy_lints/src/literal_representation.rs | 128 +- clippy_lints/src/loops.rs | 598 ++++----- clippy_lints/src/map_clone.rs | 44 +- clippy_lints/src/map_unit_fn.rs | 108 +- clippy_lints/src/matches.rs | 286 ++--- clippy_lints/src/mem_discriminant.rs | 24 +- clippy_lints/src/mem_forget.rs | 24 +- clippy_lints/src/mem_replace.rs | 38 +- clippy_lints/src/methods/mod.rs | 1097 ++++++++--------- clippy_lints/src/minmax.rs | 28 +- clippy_lints/src/misc.rs | 294 ++--- clippy_lints/src/misc_early.rs | 228 ++-- clippy_lints/src/missing_const_for_fn.rs | 88 +- clippy_lints/src/missing_doc.rs | 18 +- clippy_lints/src/missing_inline.rs | 90 +- clippy_lints/src/multiple_crate_versions.rs | 34 +- clippy_lints/src/mut_mut.rs | 24 +- clippy_lints/src/mut_reference.rs | 24 +- clippy_lints/src/mutex_atomic.rs | 56 +- clippy_lints/src/needless_bool.rs | 62 +- clippy_lints/src/needless_borrow.rs | 24 +- clippy_lints/src/needless_borrowed_ref.rs | 72 +- clippy_lints/src/needless_continue.rs | 118 +- clippy_lints/src/needless_pass_by_value.rs | 46 +- clippy_lints/src/needless_update.rs | 32 +- clippy_lints/src/neg_cmp_op_on_partial_ord.rs | 62 +- clippy_lints/src/neg_multiply.rs | 20 +- clippy_lints/src/new_without_default.rs | 134 +- clippy_lints/src/no_effect.rs | 48 +- clippy_lints/src/non_copy_const.rs | 112 +- clippy_lints/src/non_expressive_names.rs | 76 +- clippy_lints/src/ok_if_let.rs | 48 +- clippy_lints/src/open_options.rs | 24 +- .../src/overflow_check_conditional.rs | 22 +- clippy_lints/src/panic_unimplemented.rs | 46 +- clippy_lints/src/partialeq_ne_impl.rs | 36 +- clippy_lints/src/precedence.rs | 34 +- clippy_lints/src/ptr.rs | 126 +- clippy_lints/src/ptr_offset_with_cast.rs | 60 +- clippy_lints/src/question_mark.rs | 36 +- clippy_lints/src/ranges.rs | 104 +- clippy_lints/src/redundant_clone.rs | 62 +- clippy_lints/src/redundant_field_names.rs | 44 +- .../src/redundant_pattern_matching.rs | 60 +- clippy_lints/src/reference.rs | 50 +- clippy_lints/src/regex.rs | 76 +- clippy_lints/src/replace_consts.rs | 34 +- clippy_lints/src/returns.rs | 112 +- clippy_lints/src/serde_api.rs | 18 +- clippy_lints/src/shadow.rs | 100 +- .../src/slow_vector_initialization.rs | 30 +- clippy_lints/src/strings.rs | 96 +- clippy_lints/src/suspicious_trait_impl.rs | 64 +- clippy_lints/src/swap.rs | 56 +- clippy_lints/src/temporary_assignment.rs | 24 +- clippy_lints/src/transmute.rs | 282 ++--- .../src/trivially_copy_pass_by_ref.rs | 64 +- clippy_lints/src/types.rs | 864 ++++++------- clippy_lints/src/unicode.rs | 68 +- clippy_lints/src/unsafe_removed_from_name.rs | 30 +- clippy_lints/src/unused_io_amount.rs | 42 +- clippy_lints/src/unused_label.rs | 28 +- clippy_lints/src/unwrap.rs | 70 +- clippy_lints/src/use_self.rs | 58 +- clippy_lints/src/utils/author.rs | 62 +- clippy_lints/src/utils/inspector.rs | 32 +- clippy_lints/src/utils/internal_lints.rs | 106 +- clippy_lints/src/vec.rs | 22 +- clippy_lints/src/wildcard_dependencies.rs | 28 +- clippy_lints/src/write.rs | 208 ++-- clippy_lints/src/zero_div_zero.rs | 22 +- util/lintlib.py | 55 +- 132 files changed, 5407 insertions(+), 5392 deletions(-) diff --git a/clippy_dev/src/lib.rs b/clippy_dev/src/lib.rs index 7fad43029aca..3efee458cdc0 100644 --- a/clippy_dev/src/lib.rs +++ b/clippy_dev/src/lib.rs @@ -12,8 +12,9 @@ use walkdir::WalkDir; lazy_static! { static ref DEC_CLIPPY_LINT_RE: Regex = Regex::new( r#"(?x) - declare_clippy_lint!\s*[\{(]\s* - pub\s+(?P[A-Z_][A-Z_0-9]*)\s*,\s* + declare_clippy_lint!\s*[\{(] + (?:\s+///.*)* + \s+pub\s+(?P[A-Z_][A-Z_0-9]*)\s*,\s* (?P[a-z_]+)\s*,\s* "(?P(?:[^"\\]+|\\(?s).(?-s))*)"\s*[})] "# @@ -22,7 +23,8 @@ lazy_static! { static ref DEC_DEPRECATED_LINT_RE: Regex = Regex::new( r#"(?x) declare_deprecated_lint!\s*[{(]\s* - pub\s+(?P[A-Z_][A-Z_0-9]*)\s*,\s* + (?:\s+///.*)* + \s+pub\s+(?P[A-Z_][A-Z_0-9]*)\s*,\s* "(?P(?:[^"\\]+|\\(?s).(?-s))*)"\s*[})] "# ) diff --git a/clippy_lints/src/approx_const.rs b/clippy_lints/src/approx_const.rs index 337139e1b1dc..28c536df0c54 100644 --- a/clippy_lints/src/approx_const.rs +++ b/clippy_lints/src/approx_const.rs @@ -6,28 +6,28 @@ use std::f64::consts as f64; use syntax::ast::{FloatTy, Lit, LitKind}; use syntax::symbol; -/// **What it does:** Checks for floating point literals that approximate -/// constants which are defined in -/// [`std::f32::consts`](https://doc.rust-lang.org/stable/std/f32/consts/#constants) -/// or -/// [`std::f64::consts`](https://doc.rust-lang.org/stable/std/f64/consts/#constants), -/// respectively, suggesting to use the predefined constant. -/// -/// **Why is this bad?** Usually, the definition in the standard library is more -/// precise than what people come up with. If you find that your definition is -/// actually more precise, please [file a Rust -/// issue](https://github.com/rust-lang/rust/issues). -/// -/// **Known problems:** If you happen to have a value that is within 1/8192 of a -/// known constant, but is not *and should not* be the same, this lint will -/// report your value anyway. We have not yet noticed any false positives in -/// code we tested clippy with (this includes servo), but YMMV. -/// -/// **Example:** -/// ```rust -/// let x = 3.14; -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for floating point literals that approximate + /// constants which are defined in + /// [`std::f32::consts`](https://doc.rust-lang.org/stable/std/f32/consts/#constants) + /// or + /// [`std::f64::consts`](https://doc.rust-lang.org/stable/std/f64/consts/#constants), + /// respectively, suggesting to use the predefined constant. + /// + /// **Why is this bad?** Usually, the definition in the standard library is more + /// precise than what people come up with. If you find that your definition is + /// actually more precise, please [file a Rust + /// issue](https://github.com/rust-lang/rust/issues). + /// + /// **Known problems:** If you happen to have a value that is within 1/8192 of a + /// known constant, but is not *and should not* be the same, this lint will + /// report your value anyway. We have not yet noticed any false positives in + /// code we tested clippy with (this includes servo), but YMMV. + /// + /// **Example:** + /// ```rust + /// let x = 3.14; + /// ``` pub APPROX_CONSTANT, correctness, "the approximate of a known float constant (in `std::fXX::consts`)" diff --git a/clippy_lints/src/arithmetic.rs b/clippy_lints/src/arithmetic.rs index e14c79374ba4..416ec656e12a 100644 --- a/clippy_lints/src/arithmetic.rs +++ b/clippy_lints/src/arithmetic.rs @@ -5,36 +5,36 @@ use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use rustc::{declare_tool_lint, lint_array}; use syntax::source_map::Span; -/// **What it does:** Checks for plain integer arithmetic. -/// -/// **Why is this bad?** This is only checked against overflow in debug builds. -/// In some applications one wants explicitly checked, wrapping or saturating -/// arithmetic. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// a + 1 -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for plain integer arithmetic. + /// + /// **Why is this bad?** This is only checked against overflow in debug builds. + /// In some applications one wants explicitly checked, wrapping or saturating + /// arithmetic. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// a + 1 + /// ``` pub INTEGER_ARITHMETIC, restriction, "any integer arithmetic statement" } -/// **What it does:** Checks for float arithmetic. -/// -/// **Why is this bad?** For some embedded systems or kernel development, it -/// can be useful to rule out floating-point numbers. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// a + 1.0 -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for float arithmetic. + /// + /// **Why is this bad?** For some embedded systems or kernel development, it + /// can be useful to rule out floating-point numbers. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// a + 1.0 + /// ``` pub FLOAT_ARITHMETIC, restriction, "any floating-point arithmetic statement" diff --git a/clippy_lints/src/assertions_on_constants.rs b/clippy_lints/src/assertions_on_constants.rs index 92ee9d1bc666..54ef63160db0 100644 --- a/clippy_lints/src/assertions_on_constants.rs +++ b/clippy_lints/src/assertions_on_constants.rs @@ -6,23 +6,23 @@ use crate::syntax::ast::LitKind; use crate::utils::{in_macro, is_direct_expn_of, span_help_and_lint}; use if_chain::if_chain; -/// **What it does:** Check to call assert!(true/false) -/// -/// **Why is this bad?** Will be optimized out by the compiler or should probably be replaced by a -/// panic!() or unreachable!() -/// -/// **Known problems:** None -/// -/// **Example:** -/// ```rust -/// assert!(false) -/// // or -/// assert!(true) -/// // or -/// const B: bool = false; -/// assert!(B) -/// ``` declare_clippy_lint! { + /// **What it does:** Check to call assert!(true/false) + /// + /// **Why is this bad?** Will be optimized out by the compiler or should probably be replaced by a + /// panic!() or unreachable!() + /// + /// **Known problems:** None + /// + /// **Example:** + /// ```rust + /// assert!(false) + /// // or + /// assert!(true) + /// // or + /// const B: bool = false; + /// assert!(B) + /// ``` pub ASSERTIONS_ON_CONSTANTS, style, "assert!(true/false) will be optimized out by the compiler/should probably be replaced by a panic!() or unreachable!()" diff --git a/clippy_lints/src/assign_ops.rs b/clippy_lints/src/assign_ops.rs index 376751f860d1..bfa35d4381ae 100644 --- a/clippy_lints/src/assign_ops.rs +++ b/clippy_lints/src/assign_ops.rs @@ -7,43 +7,43 @@ use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use rustc::{declare_tool_lint, lint_array}; use rustc_errors::Applicability; -/// **What it does:** Checks for `a = a op b` or `a = b commutative_op a` -/// patterns. -/// -/// **Why is this bad?** These can be written as the shorter `a op= b`. -/// -/// **Known problems:** While forbidden by the spec, `OpAssign` traits may have -/// implementations that differ from the regular `Op` impl. -/// -/// **Example:** -/// ```rust -/// let mut a = 5; -/// ... -/// a = a + b; -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for `a = a op b` or `a = b commutative_op a` + /// patterns. + /// + /// **Why is this bad?** These can be written as the shorter `a op= b`. + /// + /// **Known problems:** While forbidden by the spec, `OpAssign` traits may have + /// implementations that differ from the regular `Op` impl. + /// + /// **Example:** + /// ```rust + /// let mut a = 5; + /// ... + /// a = a + b; + /// ``` pub ASSIGN_OP_PATTERN, style, "assigning the result of an operation on a variable to that same variable" } -/// **What it does:** Checks for `a op= a op b` or `a op= b op a` patterns. -/// -/// **Why is this bad?** Most likely these are bugs where one meant to write `a -/// op= b`. -/// -/// **Known problems:** Clippy cannot know for sure if `a op= a op b` should have -/// been `a = a op a op b` or `a = a op b`/`a op= b`. Therefore it suggests both. -/// If `a op= a op b` is really the correct behaviour it should be -/// written as `a = a op a op b` as it's less confusing. -/// -/// **Example:** -/// ```rust -/// let mut a = 5; -/// ... -/// a += a + b; -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for `a op= a op b` or `a op= b op a` patterns. + /// + /// **Why is this bad?** Most likely these are bugs where one meant to write `a + /// op= b`. + /// + /// **Known problems:** Clippy cannot know for sure if `a op= a op b` should have + /// been `a = a op a op b` or `a = a op b`/`a op= b`. Therefore it suggests both. + /// If `a op= a op b` is really the correct behaviour it should be + /// written as `a = a op a op b` as it's less confusing. + /// + /// **Example:** + /// ```rust + /// let mut a = 5; + /// ... + /// a += a + b; + /// ``` pub MISREFACTORED_ASSIGN_OP, complexity, "having a variable on both sides of an assign op" diff --git a/clippy_lints/src/attrs.rs b/clippy_lints/src/attrs.rs index a72944bbe028..205b11b3b91a 100644 --- a/clippy_lints/src/attrs.rs +++ b/clippy_lints/src/attrs.rs @@ -17,170 +17,170 @@ use semver::Version; use syntax::ast::{AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem, NestedMetaItemKind}; use syntax::source_map::Span; -/// **What it does:** Checks for items annotated with `#[inline(always)]`, -/// unless the annotated function is empty or simply panics. -/// -/// **Why is this bad?** While there are valid uses of this annotation (and once -/// you know when to use it, by all means `allow` this lint), it's a common -/// newbie-mistake to pepper one's code with it. -/// -/// As a rule of thumb, before slapping `#[inline(always)]` on a function, -/// measure if that additional function call really affects your runtime profile -/// sufficiently to make up for the increase in compile time. -/// -/// **Known problems:** False positives, big time. This lint is meant to be -/// deactivated by everyone doing serious performance work. This means having -/// done the measurement. -/// -/// **Example:** -/// ```rust -/// #[inline(always)] -/// fn not_quite_hot_code(..) { ... } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for items annotated with `#[inline(always)]`, + /// unless the annotated function is empty or simply panics. + /// + /// **Why is this bad?** While there are valid uses of this annotation (and once + /// you know when to use it, by all means `allow` this lint), it's a common + /// newbie-mistake to pepper one's code with it. + /// + /// As a rule of thumb, before slapping `#[inline(always)]` on a function, + /// measure if that additional function call really affects your runtime profile + /// sufficiently to make up for the increase in compile time. + /// + /// **Known problems:** False positives, big time. This lint is meant to be + /// deactivated by everyone doing serious performance work. This means having + /// done the measurement. + /// + /// **Example:** + /// ```rust + /// #[inline(always)] + /// fn not_quite_hot_code(..) { ... } + /// ``` pub INLINE_ALWAYS, pedantic, "use of `#[inline(always)]`" } -/// **What it does:** Checks for `extern crate` and `use` items annotated with -/// lint attributes. -/// -/// This lint whitelists `#[allow(unused_imports)]` and `#[allow(deprecated)]` on -/// `use` items and `#[allow(unused_imports)]` on `extern crate` items with a -/// `#[macro_use]` attribute. -/// -/// **Why is this bad?** Lint attributes have no effect on crate imports. Most -/// likely a `!` was forgotten. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// // Bad -/// #[deny(dead_code)] -/// extern crate foo; -/// #[forbid(dead_code)] -/// use foo::bar; -/// -/// // Ok -/// #[allow(unused_imports)] -/// use foo::baz; -/// #[allow(unused_imports)] -/// #[macro_use] -/// extern crate baz; -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for `extern crate` and `use` items annotated with + /// lint attributes. + /// + /// This lint whitelists `#[allow(unused_imports)]` and `#[allow(deprecated)]` on + /// `use` items and `#[allow(unused_imports)]` on `extern crate` items with a + /// `#[macro_use]` attribute. + /// + /// **Why is this bad?** Lint attributes have no effect on crate imports. Most + /// likely a `!` was forgotten. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// // Bad + /// #[deny(dead_code)] + /// extern crate foo; + /// #[forbid(dead_code)] + /// use foo::bar; + /// + /// // Ok + /// #[allow(unused_imports)] + /// use foo::baz; + /// #[allow(unused_imports)] + /// #[macro_use] + /// extern crate baz; + /// ``` pub USELESS_ATTRIBUTE, correctness, "use of lint attributes on `extern crate` items" } -/// **What it does:** Checks for `#[deprecated]` annotations with a `since` -/// field that is not a valid semantic version. -/// -/// **Why is this bad?** For checking the version of the deprecation, it must be -/// a valid semver. Failing that, the contained information is useless. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// #[deprecated(since = "forever")] -/// fn something_else(..) { ... } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for `#[deprecated]` annotations with a `since` + /// field that is not a valid semantic version. + /// + /// **Why is this bad?** For checking the version of the deprecation, it must be + /// a valid semver. Failing that, the contained information is useless. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// #[deprecated(since = "forever")] + /// fn something_else(..) { ... } + /// ``` pub DEPRECATED_SEMVER, correctness, "use of `#[deprecated(since = \"x\")]` where x is not semver" } -/// **What it does:** Checks for empty lines after outer attributes -/// -/// **Why is this bad?** -/// Most likely the attribute was meant to be an inner attribute using a '!'. -/// If it was meant to be an outer attribute, then the following item -/// should not be separated by empty lines. -/// -/// **Known problems:** Can cause false positives. -/// -/// From the clippy side it's difficult to detect empty lines between an attributes and the -/// following item because empty lines and comments are not part of the AST. The parsing -/// currently works for basic cases but is not perfect. -/// -/// **Example:** -/// ```rust -/// // Bad -/// #[inline(always)] -/// -/// fn not_quite_good_code(..) { ... } -/// -/// // Good (as inner attribute) -/// #![inline(always)] -/// -/// fn this_is_fine(..) { ... } -/// -/// // Good (as outer attribute) -/// #[inline(always)] -/// fn this_is_fine_too(..) { ... } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for empty lines after outer attributes + /// + /// **Why is this bad?** + /// Most likely the attribute was meant to be an inner attribute using a '!'. + /// If it was meant to be an outer attribute, then the following item + /// should not be separated by empty lines. + /// + /// **Known problems:** Can cause false positives. + /// + /// From the clippy side it's difficult to detect empty lines between an attributes and the + /// following item because empty lines and comments are not part of the AST. The parsing + /// currently works for basic cases but is not perfect. + /// + /// **Example:** + /// ```rust + /// // Bad + /// #[inline(always)] + /// + /// fn not_quite_good_code(..) { ... } + /// + /// // Good (as inner attribute) + /// #![inline(always)] + /// + /// fn this_is_fine(..) { ... } + /// + /// // Good (as outer attribute) + /// #[inline(always)] + /// fn this_is_fine_too(..) { ... } + /// ``` pub EMPTY_LINE_AFTER_OUTER_ATTR, nursery, "empty line after outer attribute" } -/// **What it does:** Checks for `allow`/`warn`/`deny`/`forbid` attributes with scoped clippy -/// lints and if those lints exist in clippy. If there is a uppercase letter in the lint name -/// (not the tool name) and a lowercase version of this lint exists, it will suggest to lowercase -/// the lint name. -/// -/// **Why is this bad?** A lint attribute with a mistyped lint name won't have an effect. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// Bad: -/// ```rust -/// #![warn(if_not_els)] -/// #![deny(clippy::All)] -/// ``` -/// -/// Good: -/// ```rust -/// #![warn(if_not_else)] -/// #![deny(clippy::all)] -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for `allow`/`warn`/`deny`/`forbid` attributes with scoped clippy + /// lints and if those lints exist in clippy. If there is a uppercase letter in the lint name + /// (not the tool name) and a lowercase version of this lint exists, it will suggest to lowercase + /// the lint name. + /// + /// **Why is this bad?** A lint attribute with a mistyped lint name won't have an effect. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// Bad: + /// ```rust + /// #![warn(if_not_els)] + /// #![deny(clippy::All)] + /// ``` + /// + /// Good: + /// ```rust + /// #![warn(if_not_else)] + /// #![deny(clippy::all)] + /// ``` pub UNKNOWN_CLIPPY_LINTS, style, "unknown_lints for scoped Clippy lints" } -/// **What it does:** Checks for `#[cfg_attr(rustfmt, rustfmt_skip)]` and suggests to replace it -/// with `#[rustfmt::skip]`. -/// -/// **Why is this bad?** Since tool_attributes ([rust-lang/rust#44690](https://github.com/rust-lang/rust/issues/44690)) -/// are stable now, they should be used instead of the old `cfg_attr(rustfmt)` attributes. -/// -/// **Known problems:** This lint doesn't detect crate level inner attributes, because they get -/// processed before the PreExpansionPass lints get executed. See -/// [#3123](https://github.com/rust-lang/rust-clippy/pull/3123#issuecomment-422321765) -/// -/// **Example:** -/// -/// Bad: -/// ```rust -/// #[cfg_attr(rustfmt, rustfmt_skip)] -/// fn main() { } -/// ``` -/// -/// Good: -/// ```rust -/// #[rustfmt::skip] -/// fn main() { } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for `#[cfg_attr(rustfmt, rustfmt_skip)]` and suggests to replace it + /// with `#[rustfmt::skip]`. + /// + /// **Why is this bad?** Since tool_attributes ([rust-lang/rust#44690](https://github.com/rust-lang/rust/issues/44690)) + /// are stable now, they should be used instead of the old `cfg_attr(rustfmt)` attributes. + /// + /// **Known problems:** This lint doesn't detect crate level inner attributes, because they get + /// processed before the PreExpansionPass lints get executed. See + /// [#3123](https://github.com/rust-lang/rust-clippy/pull/3123#issuecomment-422321765) + /// + /// **Example:** + /// + /// Bad: + /// ```rust + /// #[cfg_attr(rustfmt, rustfmt_skip)] + /// fn main() { } + /// ``` + /// + /// Good: + /// ```rust + /// #[rustfmt::skip] + /// fn main() { } + /// ``` pub DEPRECATED_CFG_ATTR, complexity, "usage of `cfg_attr(rustfmt)` instead of `tool_attributes`" diff --git a/clippy_lints/src/bit_mask.rs b/clippy_lints/src/bit_mask.rs index f052ad6e5ac6..7c5d2495952e 100644 --- a/clippy_lints/src/bit_mask.rs +++ b/clippy_lints/src/bit_mask.rs @@ -9,83 +9,83 @@ use rustc_errors::Applicability; use syntax::ast::LitKind; use syntax::source_map::Span; -/// **What it does:** Checks for incompatible bit masks in comparisons. -/// -/// The formula for detecting if an expression of the type `_ m -/// c` (where `` is one of {`&`, `|`} and `` is one of -/// {`!=`, `>=`, `>`, `!=`, `>=`, `>`}) can be determined from the following -/// table: -/// -/// |Comparison |Bit Op|Example |is always|Formula | -/// |------------|------|------------|---------|----------------------| -/// |`==` or `!=`| `&` |`x & 2 == 3`|`false` |`c & m != c` | -/// |`<` or `>=`| `&` |`x & 2 < 3` |`true` |`m < c` | -/// |`>` or `<=`| `&` |`x & 1 > 1` |`false` |`m <= c` | -/// |`==` or `!=`| `|` |`x | 1 == 0`|`false` |`c | m != c` | -/// |`<` or `>=`| `|` |`x | 1 < 1` |`false` |`m >= c` | -/// |`<=` or `>` | `|` |`x | 1 > 0` |`true` |`m > c` | -/// -/// **Why is this bad?** If the bits that the comparison cares about are always -/// set to zero or one by the bit mask, the comparison is constant `true` or -/// `false` (depending on mask, compared value, and operators). -/// -/// So the code is actively misleading, and the only reason someone would write -/// this intentionally is to win an underhanded Rust contest or create a -/// test-case for this lint. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// if (x & 1 == 2) { … } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for incompatible bit masks in comparisons. + /// + /// The formula for detecting if an expression of the type `_ m + /// c` (where `` is one of {`&`, `|`} and `` is one of + /// {`!=`, `>=`, `>`, `!=`, `>=`, `>`}) can be determined from the following + /// table: + /// + /// |Comparison |Bit Op|Example |is always|Formula | + /// |------------|------|------------|---------|----------------------| + /// |`==` or `!=`| `&` |`x & 2 == 3`|`false` |`c & m != c` | + /// |`<` or `>=`| `&` |`x & 2 < 3` |`true` |`m < c` | + /// |`>` or `<=`| `&` |`x & 1 > 1` |`false` |`m <= c` | + /// |`==` or `!=`| `|` |`x | 1 == 0`|`false` |`c | m != c` | + /// |`<` or `>=`| `|` |`x | 1 < 1` |`false` |`m >= c` | + /// |`<=` or `>` | `|` |`x | 1 > 0` |`true` |`m > c` | + /// + /// **Why is this bad?** If the bits that the comparison cares about are always + /// set to zero or one by the bit mask, the comparison is constant `true` or + /// `false` (depending on mask, compared value, and operators). + /// + /// So the code is actively misleading, and the only reason someone would write + /// this intentionally is to win an underhanded Rust contest or create a + /// test-case for this lint. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// if (x & 1 == 2) { … } + /// ``` pub BAD_BIT_MASK, correctness, "expressions of the form `_ & mask == select` that will only ever return `true` or `false`" } -/// **What it does:** Checks for bit masks in comparisons which can be removed -/// without changing the outcome. The basic structure can be seen in the -/// following table: -/// -/// |Comparison| Bit Op |Example |equals | -/// |----------|---------|-----------|-------| -/// |`>` / `<=`|`|` / `^`|`x | 2 > 3`|`x > 3`| -/// |`<` / `>=`|`|` / `^`|`x ^ 1 < 4`|`x < 4`| -/// -/// **Why is this bad?** Not equally evil as [`bad_bit_mask`](#bad_bit_mask), -/// but still a bit misleading, because the bit mask is ineffective. -/// -/// **Known problems:** False negatives: This lint will only match instances -/// where we have figured out the math (which is for a power-of-two compared -/// value). This means things like `x | 1 >= 7` (which would be better written -/// as `x >= 6`) will not be reported (but bit masks like this are fairly -/// uncommon). -/// -/// **Example:** -/// ```rust -/// if (x | 1 > 3) { … } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for bit masks in comparisons which can be removed + /// without changing the outcome. The basic structure can be seen in the + /// following table: + /// + /// |Comparison| Bit Op |Example |equals | + /// |----------|---------|-----------|-------| + /// |`>` / `<=`|`|` / `^`|`x | 2 > 3`|`x > 3`| + /// |`<` / `>=`|`|` / `^`|`x ^ 1 < 4`|`x < 4`| + /// + /// **Why is this bad?** Not equally evil as [`bad_bit_mask`](#bad_bit_mask), + /// but still a bit misleading, because the bit mask is ineffective. + /// + /// **Known problems:** False negatives: This lint will only match instances + /// where we have figured out the math (which is for a power-of-two compared + /// value). This means things like `x | 1 >= 7` (which would be better written + /// as `x >= 6`) will not be reported (but bit masks like this are fairly + /// uncommon). + /// + /// **Example:** + /// ```rust + /// if (x | 1 > 3) { … } + /// ``` pub INEFFECTIVE_BIT_MASK, correctness, "expressions where a bit mask will be rendered useless by a comparison, e.g. `(x | 1) > 2`" } -/// **What it does:** Checks for bit masks that can be replaced by a call -/// to `trailing_zeros` -/// -/// **Why is this bad?** `x.trailing_zeros() > 4` is much clearer than `x & 15 -/// == 0` -/// -/// **Known problems:** llvm generates better code for `x & 15 == 0` on x86 -/// -/// **Example:** -/// ```rust -/// x & 0x1111 == 0 -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for bit masks that can be replaced by a call + /// to `trailing_zeros` + /// + /// **Why is this bad?** `x.trailing_zeros() > 4` is much clearer than `x & 15 + /// == 0` + /// + /// **Known problems:** llvm generates better code for `x & 15 == 0` on x86 + /// + /// **Example:** + /// ```rust + /// x & 0x1111 == 0 + /// ``` pub VERBOSE_BIT_MASK, style, "expressions where a bit mask is less readable than the corresponding method call" diff --git a/clippy_lints/src/blacklisted_name.rs b/clippy_lints/src/blacklisted_name.rs index 74d45505a4bc..c1ee4d528854 100644 --- a/clippy_lints/src/blacklisted_name.rs +++ b/clippy_lints/src/blacklisted_name.rs @@ -4,19 +4,19 @@ use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use rustc::{declare_tool_lint, lint_array}; use rustc_data_structures::fx::FxHashSet; -/// **What it does:** Checks for usage of blacklisted names for variables, such -/// as `foo`. -/// -/// **Why is this bad?** These names are usually placeholder names and should be -/// avoided. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// let foo = 3.14; -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for usage of blacklisted names for variables, such + /// as `foo`. + /// + /// **Why is this bad?** These names are usually placeholder names and should be + /// avoided. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// let foo = 3.14; + /// ``` pub BLACKLISTED_NAME, style, "usage of a blacklisted/placeholder name" diff --git a/clippy_lints/src/block_in_if_condition.rs b/clippy_lints/src/block_in_if_condition.rs index 8abcfb4cfd6f..7c664866f59e 100644 --- a/clippy_lints/src/block_in_if_condition.rs +++ b/clippy_lints/src/block_in_if_condition.rs @@ -5,38 +5,38 @@ use rustc::hir::*; use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use rustc::{declare_tool_lint, lint_array}; -/// **What it does:** Checks for `if` conditions that use blocks to contain an -/// expression. -/// -/// **Why is this bad?** It isn't really Rust style, same as using parentheses -/// to contain expressions. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// if { true } .. -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for `if` conditions that use blocks to contain an + /// expression. + /// + /// **Why is this bad?** It isn't really Rust style, same as using parentheses + /// to contain expressions. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// if { true } .. + /// ``` pub BLOCK_IN_IF_CONDITION_EXPR, style, "braces that can be eliminated in conditions, e.g. `if { true } ...`" } -/// **What it does:** Checks for `if` conditions that use blocks containing -/// statements, or conditions that use closures with blocks. -/// -/// **Why is this bad?** Using blocks in the condition makes it hard to read. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// if { let x = somefunc(); x } .. -/// // or -/// if somefunc(|x| { x == 47 }) .. -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for `if` conditions that use blocks containing + /// statements, or conditions that use closures with blocks. + /// + /// **Why is this bad?** Using blocks in the condition makes it hard to read. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// if { let x = somefunc(); x } .. + /// // or + /// if somefunc(|x| { x == 47 }) .. + /// ``` pub BLOCK_IN_IF_CONDITION_STMT, style, "complex blocks in conditions, e.g. `if { let x = true; x } ...`" diff --git a/clippy_lints/src/booleans.rs b/clippy_lints/src/booleans.rs index 3b76f288b6b3..5d05caf3aa84 100644 --- a/clippy_lints/src/booleans.rs +++ b/clippy_lints/src/booleans.rs @@ -10,39 +10,39 @@ use rustc_errors::Applicability; use syntax::ast::LitKind; use syntax::source_map::{dummy_spanned, Span, DUMMY_SP}; -/// **What it does:** Checks for boolean expressions that can be written more -/// concisely. -/// -/// **Why is this bad?** Readability of boolean expressions suffers from -/// unnecessary duplication. -/// -/// **Known problems:** Ignores short circuiting behavior of `||` and -/// `&&`. Ignores `|`, `&` and `^`. -/// -/// **Example:** -/// ```rust -/// if a && true // should be: if a -/// if !(a == b) // should be: if a != b -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for boolean expressions that can be written more + /// concisely. + /// + /// **Why is this bad?** Readability of boolean expressions suffers from + /// unnecessary duplication. + /// + /// **Known problems:** Ignores short circuiting behavior of `||` and + /// `&&`. Ignores `|`, `&` and `^`. + /// + /// **Example:** + /// ```rust + /// if a && true // should be: if a + /// if !(a == b) // should be: if a != b + /// ``` pub NONMINIMAL_BOOL, complexity, "boolean expressions that can be written more concisely" } -/// **What it does:** Checks for boolean expressions that contain terminals that -/// can be eliminated. -/// -/// **Why is this bad?** This is most likely a logic bug. -/// -/// **Known problems:** Ignores short circuiting behavior. -/// -/// **Example:** -/// ```rust -/// if a && b || a { ... } -/// ``` -/// The `b` is unnecessary, the expression is equivalent to `if a`. declare_clippy_lint! { + /// **What it does:** Checks for boolean expressions that contain terminals that + /// can be eliminated. + /// + /// **Why is this bad?** This is most likely a logic bug. + /// + /// **Known problems:** Ignores short circuiting behavior. + /// + /// **Example:** + /// ```rust + /// if a && b || a { ... } + /// ``` + /// The `b` is unnecessary, the expression is equivalent to `if a`. pub LOGIC_BUG, correctness, "boolean expressions that contain terminals which can be eliminated" diff --git a/clippy_lints/src/bytecount.rs b/clippy_lints/src/bytecount.rs index b677ef71583b..9fd82ae5946b 100644 --- a/clippy_lints/src/bytecount.rs +++ b/clippy_lints/src/bytecount.rs @@ -10,22 +10,22 @@ use rustc::{declare_tool_lint, lint_array}; use rustc_errors::Applicability; use syntax::ast::{Name, UintTy}; -/// **What it does:** Checks for naive byte counts -/// -/// **Why is this bad?** The [`bytecount`](https://crates.io/crates/bytecount) -/// crate has methods to count your bytes faster, especially for large slices. -/// -/// **Known problems:** If you have predominantly small slices, the -/// `bytecount::count(..)` method may actually be slower. However, if you can -/// ensure that less than 2³²-1 matches arise, the `naive_count_32(..)` can be -/// faster in those cases. -/// -/// **Example:** -/// -/// ```rust -/// &my_data.filter(|&x| x == 0u8).count() // use bytecount::count instead -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for naive byte counts + /// + /// **Why is this bad?** The [`bytecount`](https://crates.io/crates/bytecount) + /// crate has methods to count your bytes faster, especially for large slices. + /// + /// **Known problems:** If you have predominantly small slices, the + /// `bytecount::count(..)` method may actually be slower. However, if you can + /// ensure that less than 2³²-1 matches arise, the `naive_count_32(..)` can be + /// faster in those cases. + /// + /// **Example:** + /// + /// ```rust + /// &my_data.filter(|&x| x == 0u8).count() // use bytecount::count instead + /// ``` pub NAIVE_BYTECOUNT, perf, "use of naive `.filter(|&x| x == y).count()` to count byte values" diff --git a/clippy_lints/src/cargo_common_metadata.rs b/clippy_lints/src/cargo_common_metadata.rs index 1d37c03ff454..57bdce4cf3a9 100644 --- a/clippy_lints/src/cargo_common_metadata.rs +++ b/clippy_lints/src/cargo_common_metadata.rs @@ -7,28 +7,28 @@ use syntax::{ast::*, source_map::DUMMY_SP}; use cargo_metadata; -/// **What it does:** Checks to see if all common metadata is defined in -/// `Cargo.toml`. See: https://rust-lang-nursery.github.io/api-guidelines/documentation.html#cargotoml-includes-all-common-metadata-c-metadata -/// -/// **Why is this bad?** It will be more difficult for users to discover the -/// purpose of the crate, and key information related to it. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```toml -/// # This `Cargo.toml` is missing an authors field: -/// [package] -/// name = "clippy" -/// version = "0.0.212" -/// description = "A bunch of helpful lints to avoid common pitfalls in Rust" -/// repository = "https://github.com/rust-lang/rust-clippy" -/// readme = "README.md" -/// license = "MIT/Apache-2.0" -/// keywords = ["clippy", "lint", "plugin"] -/// categories = ["development-tools", "development-tools::cargo-plugins"] -/// ``` declare_clippy_lint! { + /// **What it does:** Checks to see if all common metadata is defined in + /// `Cargo.toml`. See: https://rust-lang-nursery.github.io/api-guidelines/documentation.html#cargotoml-includes-all-common-metadata-c-metadata + /// + /// **Why is this bad?** It will be more difficult for users to discover the + /// purpose of the crate, and key information related to it. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```toml + /// # This `Cargo.toml` is missing an authors field: + /// [package] + /// name = "clippy" + /// version = "0.0.212" + /// description = "A bunch of helpful lints to avoid common pitfalls in Rust" + /// repository = "https://github.com/rust-lang/rust-clippy" + /// readme = "README.md" + /// license = "MIT/Apache-2.0" + /// keywords = ["clippy", "lint", "plugin"] + /// categories = ["development-tools", "development-tools::cargo-plugins"] + /// ``` pub CARGO_COMMON_METADATA, cargo, "common metadata is defined in `Cargo.toml`" diff --git a/clippy_lints/src/collapsible_if.rs b/clippy_lints/src/collapsible_if.rs index 9539b4d89f96..dd4934f90901 100644 --- a/clippy_lints/src/collapsible_if.rs +++ b/clippy_lints/src/collapsible_if.rs @@ -21,51 +21,51 @@ use crate::utils::sugg::Sugg; use crate::utils::{in_macro, snippet_block, snippet_block_with_applicability, span_lint_and_sugg, span_lint_and_then}; use rustc_errors::Applicability; -/// **What it does:** Checks for nested `if` statements which can be collapsed -/// by `&&`-combining their conditions and for `else { if ... }` expressions -/// that -/// can be collapsed to `else if ...`. -/// -/// **Why is this bad?** Each `if`-statement adds one level of nesting, which -/// makes code look more complex than it really is. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust,ignore -/// if x { -/// if y { -/// … -/// } -/// } -/// -/// // or -/// -/// if x { -/// … -/// } else { -/// if y { -/// … -/// } -/// } -/// ``` -/// -/// Should be written: -/// -/// ```rust.ignore -/// if x && y { -/// … -/// } -/// -/// // or -/// -/// if x { -/// … -/// } else if y { -/// … -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for nested `if` statements which can be collapsed + /// by `&&`-combining their conditions and for `else { if ... }` expressions + /// that + /// can be collapsed to `else if ...`. + /// + /// **Why is this bad?** Each `if`-statement adds one level of nesting, which + /// makes code look more complex than it really is. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust,ignore + /// if x { + /// if y { + /// … + /// } + /// } + /// + /// // or + /// + /// if x { + /// … + /// } else { + /// if y { + /// … + /// } + /// } + /// ``` + /// + /// Should be written: + /// + /// ```rust.ignore + /// if x && y { + /// … + /// } + /// + /// // or + /// + /// if x { + /// … + /// } else if y { + /// … + /// } + /// ``` pub COLLAPSIBLE_IF, style, "`if`s that can be collapsed (e.g. `if x { if y { ... } }` and `else { if x { ... } }`)" diff --git a/clippy_lints/src/const_static_lifetime.rs b/clippy_lints/src/const_static_lifetime.rs index 2684f45660e1..e160008fa558 100644 --- a/clippy_lints/src/const_static_lifetime.rs +++ b/clippy_lints/src/const_static_lifetime.rs @@ -4,23 +4,23 @@ use rustc::{declare_tool_lint, lint_array}; use rustc_errors::Applicability; use syntax::ast::*; -/// **What it does:** Checks for constants with an explicit `'static` lifetime. -/// -/// **Why is this bad?** Adding `'static` to every reference can create very -/// complicated types. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// const FOO: &'static [(&'static str, &'static str, fn(&Bar) -> bool)] = -/// &[...] -/// ``` -/// This code can be rewritten as -/// ```rust -/// const FOO: &[(&str, &str, fn(&Bar) -> bool)] = &[...] -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for constants with an explicit `'static` lifetime. + /// + /// **Why is this bad?** Adding `'static` to every reference can create very + /// complicated types. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// const FOO: &'static [(&'static str, &'static str, fn(&Bar) -> bool)] = + /// &[...] + /// ``` + /// This code can be rewritten as + /// ```rust + /// const FOO: &[(&str, &str, fn(&Bar) -> bool)] = &[...] + /// ``` pub CONST_STATIC_LIFETIME, style, "Using explicit `'static` lifetime for constants when elision rules would allow omitting them." diff --git a/clippy_lints/src/copies.rs b/clippy_lints/src/copies.rs index 2c4b335c1326..603190458308 100644 --- a/clippy_lints/src/copies.rs +++ b/clippy_lints/src/copies.rs @@ -10,94 +10,94 @@ use std::collections::hash_map::Entry; use std::hash::BuildHasherDefault; use syntax::symbol::LocalInternedString; -/// **What it does:** Checks for consecutive `if`s with the same condition. -/// -/// **Why is this bad?** This is probably a copy & paste error. -/// -/// **Known problems:** Hopefully none. -/// -/// **Example:** -/// ```rust -/// if a == b { -/// … -/// } else if a == b { -/// … -/// } -/// ``` -/// -/// Note that this lint ignores all conditions with a function call as it could -/// have side effects: -/// -/// ```rust -/// if foo() { -/// … -/// } else if foo() { // not linted -/// … -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for consecutive `if`s with the same condition. + /// + /// **Why is this bad?** This is probably a copy & paste error. + /// + /// **Known problems:** Hopefully none. + /// + /// **Example:** + /// ```rust + /// if a == b { + /// … + /// } else if a == b { + /// … + /// } + /// ``` + /// + /// Note that this lint ignores all conditions with a function call as it could + /// have side effects: + /// + /// ```rust + /// if foo() { + /// … + /// } else if foo() { // not linted + /// … + /// } + /// ``` pub IFS_SAME_COND, correctness, "consecutive `ifs` with the same condition" } -/// **What it does:** Checks for `if/else` with the same body as the *then* part -/// and the *else* part. -/// -/// **Why is this bad?** This is probably a copy & paste error. -/// -/// **Known problems:** Hopefully none. -/// -/// **Example:** -/// ```rust -/// let foo = if … { -/// 42 -/// } else { -/// 42 -/// }; -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for `if/else` with the same body as the *then* part + /// and the *else* part. + /// + /// **Why is this bad?** This is probably a copy & paste error. + /// + /// **Known problems:** Hopefully none. + /// + /// **Example:** + /// ```rust + /// let foo = if … { + /// 42 + /// } else { + /// 42 + /// }; + /// ``` pub IF_SAME_THEN_ELSE, correctness, "if with the same *then* and *else* blocks" } -/// **What it does:** Checks for `match` with identical arm bodies. -/// -/// **Why is this bad?** This is probably a copy & paste error. If arm bodies -/// are the same on purpose, you can factor them -/// [using `|`](https://doc.rust-lang.org/book/patterns.html#multiple-patterns). -/// -/// **Known problems:** False positive possible with order dependent `match` -/// (see issue -/// [#860](https://github.com/rust-lang/rust-clippy/issues/860)). -/// -/// **Example:** -/// ```rust,ignore -/// match foo { -/// Bar => bar(), -/// Quz => quz(), -/// Baz => bar(), // <= oops -/// } -/// ``` -/// -/// This should probably be -/// ```rust,ignore -/// match foo { -/// Bar => bar(), -/// Quz => quz(), -/// Baz => baz(), // <= fixed -/// } -/// ``` -/// -/// or if the original code was not a typo: -/// ```rust,ignore -/// match foo { -/// Bar | Baz => bar(), // <= shows the intent better -/// Quz => quz(), -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for `match` with identical arm bodies. + /// + /// **Why is this bad?** This is probably a copy & paste error. If arm bodies + /// are the same on purpose, you can factor them + /// [using `|`](https://doc.rust-lang.org/book/patterns.html#multiple-patterns). + /// + /// **Known problems:** False positive possible with order dependent `match` + /// (see issue + /// [#860](https://github.com/rust-lang/rust-clippy/issues/860)). + /// + /// **Example:** + /// ```rust,ignore + /// match foo { + /// Bar => bar(), + /// Quz => quz(), + /// Baz => bar(), // <= oops + /// } + /// ``` + /// + /// This should probably be + /// ```rust,ignore + /// match foo { + /// Bar => bar(), + /// Quz => quz(), + /// Baz => baz(), // <= fixed + /// } + /// ``` + /// + /// or if the original code was not a typo: + /// ```rust,ignore + /// match foo { + /// Bar | Baz => bar(), // <= shows the intent better + /// Quz => quz(), + /// } + /// ``` pub MATCH_SAME_ARMS, pedantic, "`match` with identical arm bodies" diff --git a/clippy_lints/src/copy_iterator.rs b/clippy_lints/src/copy_iterator.rs index 3fac6e78adbe..5c8d6def210f 100644 --- a/clippy_lints/src/copy_iterator.rs +++ b/clippy_lints/src/copy_iterator.rs @@ -3,27 +3,27 @@ use rustc::hir::{Item, ItemKind}; use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use rustc::{declare_tool_lint, lint_array}; -/// **What it does:** Checks for types that implement `Copy` as well as -/// `Iterator`. -/// -/// **Why is this bad?** Implicit copies can be confusing when working with -/// iterator combinators. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// #[derive(Copy, Clone)] -/// struct Countdown(u8); -/// -/// impl Iterator for Countdown { -/// // ... -/// } -/// -/// let a: Vec<_> = my_iterator.take(1).collect(); -/// let b: Vec<_> = my_iterator.collect(); -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for types that implement `Copy` as well as + /// `Iterator`. + /// + /// **Why is this bad?** Implicit copies can be confusing when working with + /// iterator combinators. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// #[derive(Copy, Clone)] + /// struct Countdown(u8); + /// + /// impl Iterator for Countdown { + /// // ... + /// } + /// + /// let a: Vec<_> = my_iterator.take(1).collect(); + /// let b: Vec<_> = my_iterator.collect(); + /// ``` pub COPY_ITERATOR, pedantic, "implementing `Iterator` on a `Copy` type" diff --git a/clippy_lints/src/cyclomatic_complexity.rs b/clippy_lints/src/cyclomatic_complexity.rs index 502937878530..fa046d8bb7b4 100644 --- a/clippy_lints/src/cyclomatic_complexity.rs +++ b/clippy_lints/src/cyclomatic_complexity.rs @@ -11,16 +11,16 @@ use syntax::source_map::Span; use crate::utils::{in_macro, is_allowed, match_type, paths, span_help_and_lint, LimitStack}; -/// **What it does:** Checks for methods with high cyclomatic complexity. -/// -/// **Why is this bad?** Methods of high cyclomatic complexity tend to be badly -/// readable. Also LLVM will usually optimize small methods better. -/// -/// **Known problems:** Sometimes it's hard to find a way to reduce the -/// complexity. -/// -/// **Example:** No. You'll see it when you get the warning. declare_clippy_lint! { + /// **What it does:** Checks for methods with high cyclomatic complexity. + /// + /// **Why is this bad?** Methods of high cyclomatic complexity tend to be badly + /// readable. Also LLVM will usually optimize small methods better. + /// + /// **Known problems:** Sometimes it's hard to find a way to reduce the + /// complexity. + /// + /// **Example:** No. You'll see it when you get the warning. pub CYCLOMATIC_COMPLEXITY, complexity, "functions that should be split up into multiple functions" diff --git a/clippy_lints/src/dbg_macro.rs b/clippy_lints/src/dbg_macro.rs index d75970ce50a2..8b71123ca55b 100644 --- a/clippy_lints/src/dbg_macro.rs +++ b/clippy_lints/src/dbg_macro.rs @@ -6,22 +6,22 @@ use syntax::ast; use syntax::source_map::Span; use syntax::tokenstream::TokenStream; -/// **What it does:** Checks for usage of dbg!() macro. -/// -/// **Why is this bad?** `dbg!` macro is intended as a debugging tool. It -/// should not be in version control. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust,ignore -/// // Bad -/// dbg!(true) -/// -/// // Good -/// true -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for usage of dbg!() macro. + /// + /// **Why is this bad?** `dbg!` macro is intended as a debugging tool. It + /// should not be in version control. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust,ignore + /// // Bad + /// dbg!(true) + /// + /// // Good + /// true + /// ``` pub DBG_MACRO, restriction, "`dbg!` macro is intended as a debugging tool" diff --git a/clippy_lints/src/default_trait_access.rs b/clippy_lints/src/default_trait_access.rs index 3fa2ceda5d7d..3ced814adc31 100644 --- a/clippy_lints/src/default_trait_access.rs +++ b/clippy_lints/src/default_trait_access.rs @@ -7,22 +7,22 @@ use rustc_errors::Applicability; use crate::utils::{any_parent_is_automatically_derived, match_def_path, opt_def_id, paths, span_lint_and_sugg}; -/// **What it does:** Checks for literal calls to `Default::default()`. -/// -/// **Why is this bad?** It's more clear to the reader to use the name of the type whose default is -/// being gotten than the generic `Default`. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// // Bad -/// let s: String = Default::default(); -/// -/// // Good -/// let s = String::default(); -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for literal calls to `Default::default()`. + /// + /// **Why is this bad?** It's more clear to the reader to use the name of the type whose default is + /// being gotten than the generic `Default`. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// // Bad + /// let s: String = Default::default(); + /// + /// // Good + /// let s = String::default(); + /// ``` pub DEFAULT_TRAIT_ACCESS, pedantic, "checks for literal calls to Default::default()" diff --git a/clippy_lints/src/derive.rs b/clippy_lints/src/derive.rs index 2460a2746e3d..a00f7cfe2631 100644 --- a/clippy_lints/src/derive.rs +++ b/clippy_lints/src/derive.rs @@ -7,56 +7,56 @@ use rustc::ty::{self, Ty}; use rustc::{declare_tool_lint, lint_array}; use syntax::source_map::Span; -/// **What it does:** Checks for deriving `Hash` but implementing `PartialEq` -/// explicitly or vice versa. -/// -/// **Why is this bad?** The implementation of these traits must agree (for -/// example for use with `HashMap`) so it’s probably a bad idea to use a -/// default-generated `Hash` implementation with an explicitly defined -/// `PartialEq`. In particular, the following must hold for any type: -/// -/// ```rust -/// k1 == k2 ⇒ hash(k1) == hash(k2) -/// ``` -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// #[derive(Hash)] -/// struct Foo; -/// -/// impl PartialEq for Foo { -/// ... -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for deriving `Hash` but implementing `PartialEq` + /// explicitly or vice versa. + /// + /// **Why is this bad?** The implementation of these traits must agree (for + /// example for use with `HashMap`) so it’s probably a bad idea to use a + /// default-generated `Hash` implementation with an explicitly defined + /// `PartialEq`. In particular, the following must hold for any type: + /// + /// ```rust + /// k1 == k2 ⇒ hash(k1) == hash(k2) + /// ``` + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// #[derive(Hash)] + /// struct Foo; + /// + /// impl PartialEq for Foo { + /// ... + /// } + /// ``` pub DERIVE_HASH_XOR_EQ, correctness, "deriving `Hash` but implementing `PartialEq` explicitly" } -/// **What it does:** Checks for explicit `Clone` implementations for `Copy` -/// types. -/// -/// **Why is this bad?** To avoid surprising behaviour, these traits should -/// agree and the behaviour of `Copy` cannot be overridden. In almost all -/// situations a `Copy` type should have a `Clone` implementation that does -/// nothing more than copy the object, which is what `#[derive(Copy, Clone)]` -/// gets you. -/// -/// **Known problems:** Bounds of generic types are sometimes wrong: https://github.com/rust-lang/rust/issues/26925 -/// -/// **Example:** -/// ```rust -/// #[derive(Copy)] -/// struct Foo; -/// -/// impl Clone for Foo { -/// .. -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for explicit `Clone` implementations for `Copy` + /// types. + /// + /// **Why is this bad?** To avoid surprising behaviour, these traits should + /// agree and the behaviour of `Copy` cannot be overridden. In almost all + /// situations a `Copy` type should have a `Clone` implementation that does + /// nothing more than copy the object, which is what `#[derive(Copy, Clone)]` + /// gets you. + /// + /// **Known problems:** Bounds of generic types are sometimes wrong: https://github.com/rust-lang/rust/issues/26925 + /// + /// **Example:** + /// ```rust + /// #[derive(Copy)] + /// struct Foo; + /// + /// impl Clone for Foo { + /// .. + /// } + /// ``` pub EXPL_IMPL_CLONE_ON_COPY, pedantic, "implementing `Clone` explicitly on `Copy` types" diff --git a/clippy_lints/src/doc.rs b/clippy_lints/src/doc.rs index 87135fb88b66..dda4ab7c3b0b 100644 --- a/clippy_lints/src/doc.rs +++ b/clippy_lints/src/doc.rs @@ -9,25 +9,25 @@ use syntax::source_map::{BytePos, Span}; use syntax_pos::Pos; use url::Url; -/// **What it does:** Checks for the presence of `_`, `::` or camel-case words -/// outside ticks in documentation. -/// -/// **Why is this bad?** *Rustdoc* supports markdown formatting, `_`, `::` and -/// camel-case probably indicates some code which should be included between -/// ticks. `_` can also be used for emphasis in markdown, this lint tries to -/// consider that. -/// -/// **Known problems:** Lots of bad docs won’t be fixed, what the lint checks -/// for is limited, and there are still false positives. -/// -/// **Examples:** -/// ```rust -/// /// Do something with the foo_bar parameter. See also -/// /// that::other::module::foo. -/// // ^ `foo_bar` and `that::other::module::foo` should be ticked. -/// fn doit(foo_bar) { .. } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for the presence of `_`, `::` or camel-case words + /// outside ticks in documentation. + /// + /// **Why is this bad?** *Rustdoc* supports markdown formatting, `_`, `::` and + /// camel-case probably indicates some code which should be included between + /// ticks. `_` can also be used for emphasis in markdown, this lint tries to + /// consider that. + /// + /// **Known problems:** Lots of bad docs won’t be fixed, what the lint checks + /// for is limited, and there are still false positives. + /// + /// **Examples:** + /// ```rust + /// /// Do something with the foo_bar parameter. See also + /// /// that::other::module::foo. + /// // ^ `foo_bar` and `that::other::module::foo` should be ticked. + /// fn doit(foo_bar) { .. } + /// ``` pub DOC_MARKDOWN, pedantic, "presence of `_`, `::` or camel-case outside backticks in documentation" diff --git a/clippy_lints/src/double_comparison.rs b/clippy_lints/src/double_comparison.rs index 6c6b53b0b98d..be6124e45536 100644 --- a/clippy_lints/src/double_comparison.rs +++ b/clippy_lints/src/double_comparison.rs @@ -8,24 +8,24 @@ use syntax::source_map::Span; use crate::utils::{snippet_with_applicability, span_lint_and_sugg, SpanlessEq}; -/// **What it does:** Checks for double comparions that could be simplified to a single expression. -/// -/// -/// **Why is this bad?** Readability. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// x == y || x < y -/// ``` -/// -/// Could be written as: -/// -/// ```rust -/// x <= y -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for double comparions that could be simplified to a single expression. + /// + /// + /// **Why is this bad?** Readability. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// x == y || x < y + /// ``` + /// + /// Could be written as: + /// + /// ```rust + /// x <= y + /// ``` pub DOUBLE_COMPARISONS, complexity, "unnecessary double comparisons that can be simplified" diff --git a/clippy_lints/src/double_parens.rs b/clippy_lints/src/double_parens.rs index 71b2f5f51a7b..5b5639371a18 100644 --- a/clippy_lints/src/double_parens.rs +++ b/clippy_lints/src/double_parens.rs @@ -3,20 +3,20 @@ use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass}; use rustc::{declare_tool_lint, lint_array}; use syntax::ast::*; -/// **What it does:** Checks for unnecessary double parentheses. -/// -/// **Why is this bad?** This makes code harder to read and might indicate a -/// mistake. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// ((0)) -/// foo((0)) -/// ((1, 2)) -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for unnecessary double parentheses. + /// + /// **Why is this bad?** This makes code harder to read and might indicate a + /// mistake. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// ((0)) + /// foo((0)) + /// ((1, 2)) + /// ``` pub DOUBLE_PARENS, complexity, "Warn on unnecessary double parentheses" diff --git a/clippy_lints/src/drop_bounds.rs b/clippy_lints/src/drop_bounds.rs index 90be6c34fe55..702f7eced717 100644 --- a/clippy_lints/src/drop_bounds.rs +++ b/clippy_lints/src/drop_bounds.rs @@ -4,29 +4,29 @@ use rustc::hir::*; use rustc::lint::{LateLintPass, LintArray, LintPass}; use rustc::{declare_tool_lint, lint_array}; -/// **What it does:** Checks for generics with `std::ops::Drop` as bounds. -/// -/// **Why is this bad?** `Drop` bounds do not really accomplish anything. -/// A type may have compiler-generated drop glue without implementing the -/// `Drop` trait itself. The `Drop` trait also only has one method, -/// `Drop::drop`, and that function is by fiat not callable in user code. -/// So there is really no use case for using `Drop` in trait bounds. -/// -/// The most likely use case of a drop bound is to distinguish between types -/// that have destructors and types that don't. Combined with specialization, -/// a naive coder would write an implementation that assumed a type could be -/// trivially dropped, then write a specialization for `T: Drop` that actually -/// calls the destructor. Except that doing so is not correct; String, for -/// example, doesn't actually implement Drop, but because String contains a -/// Vec, assuming it can be trivially dropped will leak memory. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// fn foo() {} -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for generics with `std::ops::Drop` as bounds. + /// + /// **Why is this bad?** `Drop` bounds do not really accomplish anything. + /// A type may have compiler-generated drop glue without implementing the + /// `Drop` trait itself. The `Drop` trait also only has one method, + /// `Drop::drop`, and that function is by fiat not callable in user code. + /// So there is really no use case for using `Drop` in trait bounds. + /// + /// The most likely use case of a drop bound is to distinguish between types + /// that have destructors and types that don't. Combined with specialization, + /// a naive coder would write an implementation that assumed a type could be + /// trivially dropped, then write a specialization for `T: Drop` that actually + /// calls the destructor. Except that doing so is not correct; String, for + /// example, doesn't actually implement Drop, but because String contains a + /// Vec, assuming it can be trivially dropped will leak memory. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// fn foo() {} + /// ``` pub DROP_BOUNDS, correctness, "Bounds of the form `T: Drop` are useless" diff --git a/clippy_lints/src/drop_forget_ref.rs b/clippy_lints/src/drop_forget_ref.rs index b437d6030059..08c523b038ce 100644 --- a/clippy_lints/src/drop_forget_ref.rs +++ b/clippy_lints/src/drop_forget_ref.rs @@ -5,93 +5,93 @@ use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use rustc::ty; use rustc::{declare_tool_lint, lint_array}; -/// **What it does:** Checks for calls to `std::mem::drop` with a reference -/// instead of an owned value. -/// -/// **Why is this bad?** Calling `drop` on a reference will only drop the -/// reference itself, which is a no-op. It will not call the `drop` method (from -/// the `Drop` trait implementation) on the underlying referenced value, which -/// is likely what was intended. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// let mut lock_guard = mutex.lock(); -/// std::mem::drop(&lock_guard) // Should have been drop(lock_guard), mutex -/// // still locked -/// operation_that_requires_mutex_to_be_unlocked(); -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for calls to `std::mem::drop` with a reference + /// instead of an owned value. + /// + /// **Why is this bad?** Calling `drop` on a reference will only drop the + /// reference itself, which is a no-op. It will not call the `drop` method (from + /// the `Drop` trait implementation) on the underlying referenced value, which + /// is likely what was intended. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// let mut lock_guard = mutex.lock(); + /// std::mem::drop(&lock_guard) // Should have been drop(lock_guard), mutex + /// // still locked + /// operation_that_requires_mutex_to_be_unlocked(); + /// ``` pub DROP_REF, correctness, "calls to `std::mem::drop` with a reference instead of an owned value" } -/// **What it does:** Checks for calls to `std::mem::forget` with a reference -/// instead of an owned value. -/// -/// **Why is this bad?** Calling `forget` on a reference will only forget the -/// reference itself, which is a no-op. It will not forget the underlying -/// referenced -/// value, which is likely what was intended. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// let x = Box::new(1); -/// std::mem::forget(&x) // Should have been forget(x), x will still be dropped -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for calls to `std::mem::forget` with a reference + /// instead of an owned value. + /// + /// **Why is this bad?** Calling `forget` on a reference will only forget the + /// reference itself, which is a no-op. It will not forget the underlying + /// referenced + /// value, which is likely what was intended. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// let x = Box::new(1); + /// std::mem::forget(&x) // Should have been forget(x), x will still be dropped + /// ``` pub FORGET_REF, correctness, "calls to `std::mem::forget` with a reference instead of an owned value" } -/// **What it does:** Checks for calls to `std::mem::drop` with a value -/// that derives the Copy trait -/// -/// **Why is this bad?** Calling `std::mem::drop` [does nothing for types that -/// implement Copy](https://doc.rust-lang.org/std/mem/fn.drop.html), since the -/// value will be copied and moved into the function on invocation. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// let x: i32 = 42; // i32 implements Copy -/// std::mem::drop(x) // A copy of x is passed to the function, leaving the -/// // original unaffected -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for calls to `std::mem::drop` with a value + /// that derives the Copy trait + /// + /// **Why is this bad?** Calling `std::mem::drop` [does nothing for types that + /// implement Copy](https://doc.rust-lang.org/std/mem/fn.drop.html), since the + /// value will be copied and moved into the function on invocation. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// let x: i32 = 42; // i32 implements Copy + /// std::mem::drop(x) // A copy of x is passed to the function, leaving the + /// // original unaffected + /// ``` pub DROP_COPY, correctness, "calls to `std::mem::drop` with a value that implements Copy" } -/// **What it does:** Checks for calls to `std::mem::forget` with a value that -/// derives the Copy trait -/// -/// **Why is this bad?** Calling `std::mem::forget` [does nothing for types that -/// implement Copy](https://doc.rust-lang.org/std/mem/fn.drop.html) since the -/// value will be copied and moved into the function on invocation. -/// -/// An alternative, but also valid, explanation is that Copy types do not -/// implement -/// the Drop trait, which means they have no destructors. Without a destructor, -/// there -/// is nothing for `std::mem::forget` to ignore. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// let x: i32 = 42; // i32 implements Copy -/// std::mem::forget(x) // A copy of x is passed to the function, leaving the -/// // original unaffected -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for calls to `std::mem::forget` with a value that + /// derives the Copy trait + /// + /// **Why is this bad?** Calling `std::mem::forget` [does nothing for types that + /// implement Copy](https://doc.rust-lang.org/std/mem/fn.drop.html) since the + /// value will be copied and moved into the function on invocation. + /// + /// An alternative, but also valid, explanation is that Copy types do not + /// implement + /// the Drop trait, which means they have no destructors. Without a destructor, + /// there + /// is nothing for `std::mem::forget` to ignore. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// let x: i32 = 42; // i32 implements Copy + /// std::mem::forget(x) // A copy of x is passed to the function, leaving the + /// // original unaffected + /// ``` pub FORGET_COPY, correctness, "calls to `std::mem::forget` with a value that implements Copy" diff --git a/clippy_lints/src/duration_subsec.rs b/clippy_lints/src/duration_subsec.rs index 3935099fdcea..df0ea31470c6 100644 --- a/clippy_lints/src/duration_subsec.rs +++ b/clippy_lints/src/duration_subsec.rs @@ -9,21 +9,21 @@ use crate::consts::{constant, Constant}; use crate::utils::paths; use crate::utils::{match_type, snippet_with_applicability, span_lint_and_sugg, walk_ptrs_ty}; -/// **What it does:** Checks for calculation of subsecond microseconds or milliseconds -/// from other `Duration` methods. -/// -/// **Why is this bad?** It's more concise to call `Duration::subsec_micros()` or -/// `Duration::subsec_millis()` than to calculate them. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// let dur = Duration::new(5, 0); -/// let _micros = dur.subsec_nanos() / 1_000; -/// let _millis = dur.subsec_nanos() / 1_000_000; -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for calculation of subsecond microseconds or milliseconds + /// from other `Duration` methods. + /// + /// **Why is this bad?** It's more concise to call `Duration::subsec_micros()` or + /// `Duration::subsec_millis()` than to calculate them. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// let dur = Duration::new(5, 0); + /// let _micros = dur.subsec_nanos() / 1_000; + /// let _millis = dur.subsec_nanos() / 1_000_000; + /// ``` pub DURATION_SUBSEC, complexity, "checks for calculation of subsecond microseconds or milliseconds" diff --git a/clippy_lints/src/else_if_without_else.rs b/clippy_lints/src/else_if_without_else.rs index c01ad486484c..a306cff6eba5 100644 --- a/clippy_lints/src/else_if_without_else.rs +++ b/clippy_lints/src/else_if_without_else.rs @@ -6,34 +6,34 @@ use syntax::ast::*; use crate::utils::span_help_and_lint; -/// **What it does:** Checks for usage of if expressions with an `else if` branch, -/// but without a final `else` branch. -/// -/// **Why is this bad?** Some coding guidelines require this (e.g. MISRA-C:2004 Rule 14.10). -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// if x.is_positive() { -/// a(); -/// } else if x.is_negative() { -/// b(); -/// } -/// ``` -/// -/// Could be written: -/// -/// ```rust -/// if x.is_positive() { -/// a(); -/// } else if x.is_negative() { -/// b(); -/// } else { -/// // we don't care about zero -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for usage of if expressions with an `else if` branch, + /// but without a final `else` branch. + /// + /// **Why is this bad?** Some coding guidelines require this (e.g. MISRA-C:2004 Rule 14.10). + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// if x.is_positive() { + /// a(); + /// } else if x.is_negative() { + /// b(); + /// } + /// ``` + /// + /// Could be written: + /// + /// ```rust + /// if x.is_positive() { + /// a(); + /// } else if x.is_negative() { + /// b(); + /// } else { + /// // we don't care about zero + /// } + /// ``` pub ELSE_IF_WITHOUT_ELSE, restriction, "if expression with an `else if`, but without a final `else` branch" diff --git a/clippy_lints/src/empty_enum.rs b/clippy_lints/src/empty_enum.rs index 60d83a98d51e..9075cdc10c8b 100644 --- a/clippy_lints/src/empty_enum.rs +++ b/clippy_lints/src/empty_enum.rs @@ -5,19 +5,19 @@ use rustc::hir::*; use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use rustc::{declare_tool_lint, lint_array}; -/// **What it does:** Checks for `enum`s with no variants. -/// -/// **Why is this bad?** Enum's with no variants should be replaced with `!`, -/// the uninhabited type, -/// or a wrapper around it. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// enum Test {} -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for `enum`s with no variants. + /// + /// **Why is this bad?** Enum's with no variants should be replaced with `!`, + /// the uninhabited type, + /// or a wrapper around it. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// enum Test {} + /// ``` pub EMPTY_ENUM, pedantic, "enum with no variants" diff --git a/clippy_lints/src/entry.rs b/clippy_lints/src/entry.rs index 3e0a6e11be6e..0dc970fcafe2 100644 --- a/clippy_lints/src/entry.rs +++ b/clippy_lints/src/entry.rs @@ -8,30 +8,30 @@ use rustc::{declare_tool_lint, lint_array}; use rustc_errors::Applicability; use syntax::source_map::Span; -/// **What it does:** Checks for uses of `contains_key` + `insert` on `HashMap` -/// or `BTreeMap`. -/// -/// **Why is this bad?** Using `entry` is more efficient. -/// -/// **Known problems:** Some false negatives, eg.: -/// ```rust -/// let k = &key; -/// if !m.contains_key(k) { -/// m.insert(k.clone(), v); -/// } -/// ``` -/// -/// **Example:** -/// ```rust -/// if !m.contains_key(&k) { -/// m.insert(k, v) -/// } -/// ``` -/// can be rewritten as: -/// ```rust -/// m.entry(k).or_insert(v); -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for uses of `contains_key` + `insert` on `HashMap` + /// or `BTreeMap`. + /// + /// **Why is this bad?** Using `entry` is more efficient. + /// + /// **Known problems:** Some false negatives, eg.: + /// ```rust + /// let k = &key; + /// if !m.contains_key(k) { + /// m.insert(k.clone(), v); + /// } + /// ``` + /// + /// **Example:** + /// ```rust + /// if !m.contains_key(&k) { + /// m.insert(k, v) + /// } + /// ``` + /// can be rewritten as: + /// ```rust + /// m.entry(k).or_insert(v); + /// ``` pub MAP_ENTRY, perf, "use of `contains_key` followed by `insert` on a `HashMap` or `BTreeMap`" diff --git a/clippy_lints/src/enum_clike.rs b/clippy_lints/src/enum_clike.rs index 8610bffa6ac4..8e844f9c3988 100644 --- a/clippy_lints/src/enum_clike.rs +++ b/clippy_lints/src/enum_clike.rs @@ -12,23 +12,23 @@ use rustc::ty::util::IntTypeExt; use rustc::{declare_tool_lint, lint_array}; use syntax::ast::{IntTy, UintTy}; -/// **What it does:** Checks for C-like enumerations that are -/// `repr(isize/usize)` and have values that don't fit into an `i32`. -/// -/// **Why is this bad?** This will truncate the variant value on 32 bit -/// architectures, but works fine on 64 bit. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// #[repr(usize)] -/// enum NonPortable { -/// X = 0x1_0000_0000, -/// Y = 0, -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for C-like enumerations that are + /// `repr(isize/usize)` and have values that don't fit into an `i32`. + /// + /// **Why is this bad?** This will truncate the variant value on 32 bit + /// architectures, but works fine on 64 bit. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// #[repr(usize)] + /// enum NonPortable { + /// X = 0x1_0000_0000, + /// Y = 0, + /// } + /// ``` pub ENUM_CLIKE_UNPORTABLE_VARIANT, correctness, "C-like enums that are `repr(isize/usize)` and have values that don't fit into an `i32`" diff --git a/clippy_lints/src/enum_glob_use.rs b/clippy_lints/src/enum_glob_use.rs index 35fef9e3af4e..37575f10f195 100644 --- a/clippy_lints/src/enum_glob_use.rs +++ b/clippy_lints/src/enum_glob_use.rs @@ -7,19 +7,19 @@ use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use rustc::{declare_tool_lint, lint_array}; use syntax::source_map::Span; -/// **What it does:** Checks for `use Enum::*`. -/// -/// **Why is this bad?** It is usually better style to use the prefixed name of -/// an enumeration variant, rather than importing variants. -/// -/// **Known problems:** Old-style enumerations that prefix the variants are -/// still around. -/// -/// **Example:** -/// ```rust -/// use std::cmp::Ordering::*; -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for `use Enum::*`. + /// + /// **Why is this bad?** It is usually better style to use the prefixed name of + /// an enumeration variant, rather than importing variants. + /// + /// **Known problems:** Old-style enumerations that prefix the variants are + /// still around. + /// + /// **Example:** + /// ```rust + /// use std::cmp::Ordering::*; + /// ``` pub ENUM_GLOB_USE, pedantic, "use items that import all variants of an enum" diff --git a/clippy_lints/src/enum_variants.rs b/clippy_lints/src/enum_variants.rs index 74d61c0f6a0d..192668028f1b 100644 --- a/clippy_lints/src/enum_variants.rs +++ b/clippy_lints/src/enum_variants.rs @@ -8,94 +8,94 @@ use syntax::ast::*; use syntax::source_map::Span; use syntax::symbol::{InternedString, LocalInternedString}; -/// **What it does:** Detects enumeration variants that are prefixed or suffixed -/// by the same characters. -/// -/// **Why is this bad?** Enumeration variant names should specify their variant, -/// not repeat the enumeration name. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// enum Cake { -/// BlackForestCake, -/// HummingbirdCake, -/// BattenbergCake, -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Detects enumeration variants that are prefixed or suffixed + /// by the same characters. + /// + /// **Why is this bad?** Enumeration variant names should specify their variant, + /// not repeat the enumeration name. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// enum Cake { + /// BlackForestCake, + /// HummingbirdCake, + /// BattenbergCake, + /// } + /// ``` pub ENUM_VARIANT_NAMES, style, "enums where all variants share a prefix/postfix" } -/// **What it does:** Detects enumeration variants that are prefixed or suffixed -/// by the same characters. -/// -/// **Why is this bad?** Enumeration variant names should specify their variant, -/// not repeat the enumeration name. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// enum Cake { -/// BlackForestCake, -/// HummingbirdCake, -/// BattenbergCake, -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Detects enumeration variants that are prefixed or suffixed + /// by the same characters. + /// + /// **Why is this bad?** Enumeration variant names should specify their variant, + /// not repeat the enumeration name. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// enum Cake { + /// BlackForestCake, + /// HummingbirdCake, + /// BattenbergCake, + /// } + /// ``` pub PUB_ENUM_VARIANT_NAMES, pedantic, "enums where all variants share a prefix/postfix" } -/// **What it does:** Detects type names that are prefixed or suffixed by the -/// containing module's name. -/// -/// **Why is this bad?** It requires the user to type the module name twice. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// mod cake { -/// struct BlackForestCake; -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Detects type names that are prefixed or suffixed by the + /// containing module's name. + /// + /// **Why is this bad?** It requires the user to type the module name twice. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// mod cake { + /// struct BlackForestCake; + /// } + /// ``` pub MODULE_NAME_REPETITIONS, pedantic, "type names prefixed/postfixed with their containing module's name" } -/// **What it does:** Checks for modules that have the same name as their -/// parent module -/// -/// **Why is this bad?** A typical beginner mistake is to have `mod foo;` and -/// again `mod foo { .. -/// }` in `foo.rs`. -/// The expectation is that items inside the inner `mod foo { .. }` are then -/// available -/// through `foo::x`, but they are only available through -/// `foo::foo::x`. -/// If this is done on purpose, it would be better to choose a more -/// representative module name. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// // lib.rs -/// mod foo; -/// // foo.rs -/// mod foo { -/// ... -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for modules that have the same name as their + /// parent module + /// + /// **Why is this bad?** A typical beginner mistake is to have `mod foo;` and + /// again `mod foo { .. + /// }` in `foo.rs`. + /// The expectation is that items inside the inner `mod foo { .. }` are then + /// available + /// through `foo::x`, but they are only available through + /// `foo::foo::x`. + /// If this is done on purpose, it would be better to choose a more + /// representative module name. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// // lib.rs + /// mod foo; + /// // foo.rs + /// mod foo { + /// ... + /// } + /// ``` pub MODULE_INCEPTION, style, "modules that have the same name as their parent module" diff --git a/clippy_lints/src/eq_op.rs b/clippy_lints/src/eq_op.rs index 2602ad45986b..24b6371142fb 100644 --- a/clippy_lints/src/eq_op.rs +++ b/clippy_lints/src/eq_op.rs @@ -6,40 +6,40 @@ use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use rustc::{declare_tool_lint, lint_array}; use rustc_errors::Applicability; -/// **What it does:** Checks for equal operands to comparison, logical and -/// bitwise, difference and division binary operators (`==`, `>`, etc., `&&`, -/// `||`, `&`, `|`, `^`, `-` and `/`). -/// -/// **Why is this bad?** This is usually just a typo or a copy and paste error. -/// -/// **Known problems:** False negatives: We had some false positives regarding -/// calls (notably [racer](https://github.com/phildawes/racer) had one instance -/// of `x.pop() && x.pop()`), so we removed matching any function or method -/// calls. We may introduce a whitelist of known pure functions in the future. -/// -/// **Example:** -/// ```rust -/// x + 1 == x + 1 -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for equal operands to comparison, logical and + /// bitwise, difference and division binary operators (`==`, `>`, etc., `&&`, + /// `||`, `&`, `|`, `^`, `-` and `/`). + /// + /// **Why is this bad?** This is usually just a typo or a copy and paste error. + /// + /// **Known problems:** False negatives: We had some false positives regarding + /// calls (notably [racer](https://github.com/phildawes/racer) had one instance + /// of `x.pop() && x.pop()`), so we removed matching any function or method + /// calls. We may introduce a whitelist of known pure functions in the future. + /// + /// **Example:** + /// ```rust + /// x + 1 == x + 1 + /// ``` pub EQ_OP, correctness, "equal operands on both sides of a comparison or bitwise combination (e.g. `x == x`)" } -/// **What it does:** Checks for arguments to `==` which have their address -/// taken to satisfy a bound -/// and suggests to dereference the other argument instead -/// -/// **Why is this bad?** It is more idiomatic to dereference the other argument. -/// -/// **Known problems:** None -/// -/// **Example:** -/// ```rust -/// &x == y -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for arguments to `==` which have their address + /// taken to satisfy a bound + /// and suggests to dereference the other argument instead + /// + /// **Why is this bad?** It is more idiomatic to dereference the other argument. + /// + /// **Known problems:** None + /// + /// **Example:** + /// ```rust + /// &x == y + /// ``` pub OP_REF, style, "taking a reference to satisfy the type constraints on `==`" diff --git a/clippy_lints/src/erasing_op.rs b/clippy_lints/src/erasing_op.rs index a1d851377eb2..748673c96b12 100644 --- a/clippy_lints/src/erasing_op.rs +++ b/clippy_lints/src/erasing_op.rs @@ -5,21 +5,21 @@ use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use rustc::{declare_tool_lint, lint_array}; use syntax::source_map::Span; -/// **What it does:** Checks for erasing operations, e.g. `x * 0`. -/// -/// **Why is this bad?** The whole expression can be replaced by zero. -/// This is most likely not the intended outcome and should probably be -/// corrected -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// 0 / x; -/// 0 * x; -/// x & 0 -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for erasing operations, e.g. `x * 0`. + /// + /// **Why is this bad?** The whole expression can be replaced by zero. + /// This is most likely not the intended outcome and should probably be + /// corrected + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// 0 / x; + /// 0 * x; + /// x & 0 + /// ``` pub ERASING_OP, correctness, "using erasing operations, e.g. `x * 0` or `y & 0`" diff --git a/clippy_lints/src/escape.rs b/clippy_lints/src/escape.rs index 45ecdc3d3103..c84552d60c1c 100644 --- a/clippy_lints/src/escape.rs +++ b/clippy_lints/src/escape.rs @@ -14,24 +14,24 @@ pub struct Pass { pub too_large_for_stack: u64, } -/// **What it does:** Checks for usage of `Box` where an unboxed `T` would -/// work fine. -/// -/// **Why is this bad?** This is an unnecessary allocation, and bad for -/// performance. It is only necessary to allocate if you wish to move the box -/// into something. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// fn main() { -/// let x = Box::new(1); -/// foo(*x); -/// println!("{}", *x); -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for usage of `Box` where an unboxed `T` would + /// work fine. + /// + /// **Why is this bad?** This is an unnecessary allocation, and bad for + /// performance. It is only necessary to allocate if you wish to move the box + /// into something. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// fn main() { + /// let x = Box::new(1); + /// foo(*x); + /// println!("{}", *x); + /// } + /// ``` pub BOXED_LOCAL, perf, "using `Box` where unnecessary" diff --git a/clippy_lints/src/eta_reduction.rs b/clippy_lints/src/eta_reduction.rs index 331d1a0ec1dc..cd3146cf1be3 100644 --- a/clippy_lints/src/eta_reduction.rs +++ b/clippy_lints/src/eta_reduction.rs @@ -8,26 +8,26 @@ use rustc_errors::Applicability; pub struct EtaPass; -/// **What it does:** Checks for closures which just call another function where -/// the function can be called directly. `unsafe` functions or calls where types -/// get adjusted are ignored. -/// -/// **Why is this bad?** Needlessly creating a closure adds code for no benefit -/// and gives the optimizer more work. -/// -/// **Known problems:** If creating the closure inside the closure has a side- -/// effect then moving the closure creation out will change when that side- -/// effect runs. -/// See https://github.com/rust-lang/rust-clippy/issues/1439 for more -/// details. -/// -/// **Example:** -/// ```rust -/// xs.map(|x| foo(x)) -/// ``` -/// where `foo(_)` is a plain function that takes the exact argument type of -/// `x`. declare_clippy_lint! { + /// **What it does:** Checks for closures which just call another function where + /// the function can be called directly. `unsafe` functions or calls where types + /// get adjusted are ignored. + /// + /// **Why is this bad?** Needlessly creating a closure adds code for no benefit + /// and gives the optimizer more work. + /// + /// **Known problems:** If creating the closure inside the closure has a side- + /// effect then moving the closure creation out will change when that side- + /// effect runs. + /// See https://github.com/rust-lang/rust-clippy/issues/1439 for more + /// details. + /// + /// **Example:** + /// ```rust + /// xs.map(|x| foo(x)) + /// ``` + /// where `foo(_)` is a plain function that takes the exact argument type of + /// `x`. pub REDUNDANT_CLOSURE, style, "redundant closures, i.e. `|a| foo(a)` (which can be written as just `foo`)" diff --git a/clippy_lints/src/eval_order_dependence.rs b/clippy_lints/src/eval_order_dependence.rs index 81e653b6c42c..6bba31b15c1d 100644 --- a/clippy_lints/src/eval_order_dependence.rs +++ b/clippy_lints/src/eval_order_dependence.rs @@ -7,48 +7,48 @@ use rustc::ty; use rustc::{declare_tool_lint, lint_array}; use syntax::ast; -/// **What it does:** Checks for a read and a write to the same variable where -/// whether the read occurs before or after the write depends on the evaluation -/// order of sub-expressions. -/// -/// **Why is this bad?** It is often confusing to read. In addition, the -/// sub-expression evaluation order for Rust is not well documented. -/// -/// **Known problems:** Code which intentionally depends on the evaluation -/// order, or which is correct for any evaluation order. -/// -/// **Example:** -/// ```rust -/// let mut x = 0; -/// let a = { -/// x = 1; -/// 1 -/// } + x; -/// // Unclear whether a is 1 or 2. -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for a read and a write to the same variable where + /// whether the read occurs before or after the write depends on the evaluation + /// order of sub-expressions. + /// + /// **Why is this bad?** It is often confusing to read. In addition, the + /// sub-expression evaluation order for Rust is not well documented. + /// + /// **Known problems:** Code which intentionally depends on the evaluation + /// order, or which is correct for any evaluation order. + /// + /// **Example:** + /// ```rust + /// let mut x = 0; + /// let a = { + /// x = 1; + /// 1 + /// } + x; + /// // Unclear whether a is 1 or 2. + /// ``` pub EVAL_ORDER_DEPENDENCE, complexity, "whether a variable read occurs before a write depends on sub-expression evaluation order" } -/// **What it does:** Checks for diverging calls that are not match arms or -/// statements. -/// -/// **Why is this bad?** It is often confusing to read. In addition, the -/// sub-expression evaluation order for Rust is not well documented. -/// -/// **Known problems:** Someone might want to use `some_bool || panic!()` as a -/// shorthand. -/// -/// **Example:** -/// ```rust -/// let a = b() || panic!() || c(); -/// // `c()` is dead, `panic!()` is only called if `b()` returns `false` -/// let x = (a, b, c, panic!()); -/// // can simply be replaced by `panic!()` -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for diverging calls that are not match arms or + /// statements. + /// + /// **Why is this bad?** It is often confusing to read. In addition, the + /// sub-expression evaluation order for Rust is not well documented. + /// + /// **Known problems:** Someone might want to use `some_bool || panic!()` as a + /// shorthand. + /// + /// **Example:** + /// ```rust + /// let a = b() || panic!() || c(); + /// // `c()` is dead, `panic!()` is only called if `b()` returns `false` + /// let x = (a, b, c, panic!()); + /// // can simply be replaced by `panic!()` + /// ``` pub DIVERGING_SUB_EXPRESSION, complexity, "whether an expression contains a diverging sub expression" diff --git a/clippy_lints/src/excessive_precision.rs b/clippy_lints/src/excessive_precision.rs index 27e033f688da..ff28866e3a7b 100644 --- a/clippy_lints/src/excessive_precision.rs +++ b/clippy_lints/src/excessive_precision.rs @@ -11,25 +11,25 @@ use std::fmt; use syntax::ast::*; use syntax_pos::symbol::Symbol; -/// **What it does:** Checks for float literals with a precision greater -/// than that supported by the underlying type -/// -/// **Why is this bad?** Rust will truncate the literal silently. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// -/// ```rust -/// // Bad -/// let v: f32 = 0.123_456_789_9; -/// println!("{}", v); // 0.123_456_789 -/// -/// // Good -/// let v: f64 = 0.123_456_789_9; -/// println!("{}", v); // 0.123_456_789_9 -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for float literals with a precision greater + /// than that supported by the underlying type + /// + /// **Why is this bad?** Rust will truncate the literal silently. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// + /// ```rust + /// // Bad + /// let v: f32 = 0.123_456_789_9; + /// println!("{}", v); // 0.123_456_789 + /// + /// // Good + /// let v: f64 = 0.123_456_789_9; + /// println!("{}", v); // 0.123_456_789_9 + /// ``` pub EXCESSIVE_PRECISION, style, "excessive precision for float literal" diff --git a/clippy_lints/src/explicit_write.rs b/clippy_lints/src/explicit_write.rs index 2be2bb058bbc..5c75f8888a4e 100644 --- a/clippy_lints/src/explicit_write.rs +++ b/clippy_lints/src/explicit_write.rs @@ -6,19 +6,19 @@ use rustc::{declare_tool_lint, lint_array}; use rustc_errors::Applicability; use syntax::ast::LitKind; -/// **What it does:** Checks for usage of `write!()` / `writeln()!` which can be -/// replaced with `(e)print!()` / `(e)println!()` -/// -/// **Why is this bad?** Using `(e)println! is clearer and more concise -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// // this would be clearer as `eprintln!("foo: {:?}", bar);` -/// writeln!(&mut io::stderr(), "foo: {:?}", bar).unwrap(); -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for usage of `write!()` / `writeln()!` which can be + /// replaced with `(e)print!()` / `(e)println!()` + /// + /// **Why is this bad?** Using `(e)println! is clearer and more concise + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// // this would be clearer as `eprintln!("foo: {:?}", bar);` + /// writeln!(&mut io::stderr(), "foo: {:?}", bar).unwrap(); + /// ``` pub EXPLICIT_WRITE, complexity, "using the `write!()` family of functions instead of the `print!()` family of functions, when using the latter would work" diff --git a/clippy_lints/src/fallible_impl_from.rs b/clippy_lints/src/fallible_impl_from.rs index 48d4db53d32e..2a1f3661c78f 100644 --- a/clippy_lints/src/fallible_impl_from.rs +++ b/clippy_lints/src/fallible_impl_from.rs @@ -7,22 +7,22 @@ use rustc::ty; use rustc::{declare_tool_lint, lint_array}; use syntax_pos::Span; -/// **What it does:** Checks for impls of `From<..>` that contain `panic!()` or `unwrap()` -/// -/// **Why is this bad?** `TryFrom` should be used if there's a possibility of failure. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// struct Foo(i32); -/// impl From for Foo { -/// fn from(s: String) -> Self { -/// Foo(s.parse().unwrap()) -/// } -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for impls of `From<..>` that contain `panic!()` or `unwrap()` + /// + /// **Why is this bad?** `TryFrom` should be used if there's a possibility of failure. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// struct Foo(i32); + /// impl From for Foo { + /// fn from(s: String) -> Self { + /// Foo(s.parse().unwrap()) + /// } + /// } + /// ``` pub FALLIBLE_IMPL_FROM, nursery, "Warn on impls of `From<..>` that contain `panic!()` or `unwrap()`" diff --git a/clippy_lints/src/format.rs b/clippy_lints/src/format.rs index ba956b77f46e..205df2ab43ba 100644 --- a/clippy_lints/src/format.rs +++ b/clippy_lints/src/format.rs @@ -12,23 +12,23 @@ use rustc_errors::Applicability; use syntax::ast::LitKind; use syntax::source_map::Span; -/// **What it does:** Checks for the use of `format!("string literal with no -/// argument")` and `format!("{}", foo)` where `foo` is a string. -/// -/// **Why is this bad?** There is no point of doing that. `format!("foo")` can -/// be replaced by `"foo".to_owned()` if you really need a `String`. The even -/// worse `&format!("foo")` is often encountered in the wild. `format!("{}", -/// foo)` can be replaced by `foo.clone()` if `foo: String` or `foo.to_owned()` -/// if `foo: &str`. -/// -/// **Known problems:** None. -/// -/// **Examples:** -/// ```rust -/// format!("foo") -/// format!("{}", foo) -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for the use of `format!("string literal with no + /// argument")` and `format!("{}", foo)` where `foo` is a string. + /// + /// **Why is this bad?** There is no point of doing that. `format!("foo")` can + /// be replaced by `"foo".to_owned()` if you really need a `String`. The even + /// worse `&format!("foo")` is often encountered in the wild. `format!("{}", + /// foo)` can be replaced by `foo.clone()` if `foo: String` or `foo.to_owned()` + /// if `foo: &str`. + /// + /// **Known problems:** None. + /// + /// **Examples:** + /// ```rust + /// format!("foo") + /// format!("{}", foo) + /// ``` pub USELESS_FORMAT, complexity, "useless use of `format!`" diff --git a/clippy_lints/src/formatting.rs b/clippy_lints/src/formatting.rs index ecc6f9565d05..4788f57d070a 100644 --- a/clippy_lints/src/formatting.rs +++ b/clippy_lints/src/formatting.rs @@ -4,75 +4,75 @@ use rustc::{declare_tool_lint, lint_array}; use syntax::ast; use syntax::ptr::P; -/// **What it does:** Checks for use of the non-existent `=*`, `=!` and `=-` -/// operators. -/// -/// **Why is this bad?** This is either a typo of `*=`, `!=` or `-=` or -/// confusing. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust,ignore -/// a =- 42; // confusing, should it be `a -= 42` or `a = -42`? -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for use of the non-existent `=*`, `=!` and `=-` + /// operators. + /// + /// **Why is this bad?** This is either a typo of `*=`, `!=` or `-=` or + /// confusing. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust,ignore + /// a =- 42; // confusing, should it be `a -= 42` or `a = -42`? + /// ``` pub SUSPICIOUS_ASSIGNMENT_FORMATTING, style, "suspicious formatting of `*=`, `-=` or `!=`" } -/// **What it does:** Checks for formatting of `else`. It lints if the `else` -/// is followed immediately by a newline or the `else` seems to be missing. -/// -/// **Why is this bad?** This is probably some refactoring remnant, even if the -/// code is correct, it might look confusing. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust,ignore -/// if foo { -/// } { // looks like an `else` is missing here -/// } -/// -/// if foo { -/// } if bar { // looks like an `else` is missing here -/// } -/// -/// if foo { -/// } else -/// -/// { // this is the `else` block of the previous `if`, but should it be? -/// } -/// -/// if foo { -/// } else -/// -/// if bar { // this is the `else` block of the previous `if`, but should it be? -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for formatting of `else`. It lints if the `else` + /// is followed immediately by a newline or the `else` seems to be missing. + /// + /// **Why is this bad?** This is probably some refactoring remnant, even if the + /// code is correct, it might look confusing. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust,ignore + /// if foo { + /// } { // looks like an `else` is missing here + /// } + /// + /// if foo { + /// } if bar { // looks like an `else` is missing here + /// } + /// + /// if foo { + /// } else + /// + /// { // this is the `else` block of the previous `if`, but should it be? + /// } + /// + /// if foo { + /// } else + /// + /// if bar { // this is the `else` block of the previous `if`, but should it be? + /// } + /// ``` pub SUSPICIOUS_ELSE_FORMATTING, style, "suspicious formatting of `else`" } -/// **What it does:** Checks for possible missing comma in an array. It lints if -/// an array element is a binary operator expression and it lies on two lines. -/// -/// **Why is this bad?** This could lead to unexpected results. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust,ignore -/// let a = &[ -/// -1, -2, -3 // <= no comma here -/// -4, -5, -6 -/// ]; -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for possible missing comma in an array. It lints if + /// an array element is a binary operator expression and it lies on two lines. + /// + /// **Why is this bad?** This could lead to unexpected results. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust,ignore + /// let a = &[ + /// -1, -2, -3 // <= no comma here + /// -4, -5, -6 + /// ]; + /// ``` pub POSSIBLE_MISSING_COMMA, correctness, "possible missing comma in array" diff --git a/clippy_lints/src/functions.rs b/clippy_lints/src/functions.rs index 1a9089b55d77..ef3debe17a70 100644 --- a/clippy_lints/src/functions.rs +++ b/clippy_lints/src/functions.rs @@ -11,72 +11,72 @@ use rustc_target::spec::abi::Abi; use syntax::ast; use syntax::source_map::Span; -/// **What it does:** Checks for functions with too many parameters. -/// -/// **Why is this bad?** Functions with lots of parameters are considered bad -/// style and reduce readability (“what does the 5th parameter mean?”). Consider -/// grouping some parameters into a new type. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// fn foo(x: u32, y: u32, name: &str, c: Color, w: f32, h: f32, a: f32, b: f32) { -/// .. -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for functions with too many parameters. + /// + /// **Why is this bad?** Functions with lots of parameters are considered bad + /// style and reduce readability (“what does the 5th parameter mean?”). Consider + /// grouping some parameters into a new type. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// fn foo(x: u32, y: u32, name: &str, c: Color, w: f32, h: f32, a: f32, b: f32) { + /// .. + /// } + /// ``` pub TOO_MANY_ARGUMENTS, complexity, "functions with too many arguments" } -/// **What it does:** Checks for functions with a large amount of lines. -/// -/// **Why is this bad?** Functions with a lot of lines are harder to understand -/// due to having to look at a larger amount of code to understand what the -/// function is doing. Consider splitting the body of the function into -/// multiple functions. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ``` rust -/// fn im_too_long() { -/// println!(""); -/// // ... 100 more LoC -/// println!(""); -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for functions with a large amount of lines. + /// + /// **Why is this bad?** Functions with a lot of lines are harder to understand + /// due to having to look at a larger amount of code to understand what the + /// function is doing. Consider splitting the body of the function into + /// multiple functions. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ``` rust + /// fn im_too_long() { + /// println!(""); + /// // ... 100 more LoC + /// println!(""); + /// } + /// ``` pub TOO_MANY_LINES, pedantic, "functions with too many lines" } -/// **What it does:** Checks for public functions that dereferences raw pointer -/// arguments but are not marked unsafe. -/// -/// **Why is this bad?** The function should probably be marked `unsafe`, since -/// for an arbitrary raw pointer, there is no way of telling for sure if it is -/// valid. -/// -/// **Known problems:** -/// -/// * It does not check functions recursively so if the pointer is passed to a -/// private non-`unsafe` function which does the dereferencing, the lint won't -/// trigger. -/// * It only checks for arguments whose type are raw pointers, not raw pointers -/// got from an argument in some other way (`fn foo(bar: &[*const u8])` or -/// `some_argument.get_raw_ptr()`). -/// -/// **Example:** -/// ```rust -/// pub fn foo(x: *const u8) { -/// println!("{}", unsafe { *x }); -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for public functions that dereferences raw pointer + /// arguments but are not marked unsafe. + /// + /// **Why is this bad?** The function should probably be marked `unsafe`, since + /// for an arbitrary raw pointer, there is no way of telling for sure if it is + /// valid. + /// + /// **Known problems:** + /// + /// * It does not check functions recursively so if the pointer is passed to a + /// private non-`unsafe` function which does the dereferencing, the lint won't + /// trigger. + /// * It only checks for arguments whose type are raw pointers, not raw pointers + /// got from an argument in some other way (`fn foo(bar: &[*const u8])` or + /// `some_argument.get_raw_ptr()`). + /// + /// **Example:** + /// ```rust + /// pub fn foo(x: *const u8) { + /// println!("{}", unsafe { *x }); + /// } + /// ``` pub NOT_UNSAFE_PTR_ARG_DEREF, correctness, "public functions dereferencing raw pointer arguments but not marked `unsafe`" diff --git a/clippy_lints/src/identity_conversion.rs b/clippy_lints/src/identity_conversion.rs index b09031b553f9..4d3c5273f0b0 100644 --- a/clippy_lints/src/identity_conversion.rs +++ b/clippy_lints/src/identity_conversion.rs @@ -7,18 +7,18 @@ use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use rustc::{declare_tool_lint, lint_array}; use rustc_errors::Applicability; -/// **What it does:** Checks for always-identical `Into`/`From`/`IntoIter` conversions. -/// -/// **Why is this bad?** Redundant code. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// // format!() returns a `String` -/// let s: String = format!("hello").into(); -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for always-identical `Into`/`From`/`IntoIter` conversions. + /// + /// **Why is this bad?** Redundant code. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// // format!() returns a `String` + /// let s: String = format!("hello").into(); + /// ``` pub IDENTITY_CONVERSION, complexity, "using always-identical `Into`/`From`/`IntoIter` conversions" diff --git a/clippy_lints/src/identity_op.rs b/clippy_lints/src/identity_op.rs index 89d41c796298..06546be817b8 100644 --- a/clippy_lints/src/identity_op.rs +++ b/clippy_lints/src/identity_op.rs @@ -6,18 +6,18 @@ use rustc::ty; use rustc::{declare_tool_lint, lint_array}; use syntax::source_map::Span; -/// **What it does:** Checks for identity operations, e.g. `x + 0`. -/// -/// **Why is this bad?** This code can be removed without changing the -/// meaning. So it just obscures what's going on. Delete it mercilessly. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// x / 1 + 0 * 1 - 0 | 0 -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for identity operations, e.g. `x + 0`. + /// + /// **Why is this bad?** This code can be removed without changing the + /// meaning. So it just obscures what's going on. Delete it mercilessly. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// x / 1 + 0 * 1 - 0 | 0 + /// ``` pub IDENTITY_OP, complexity, "using identity operations, e.g. `x + 0` or `y / 1`" diff --git a/clippy_lints/src/if_not_else.rs b/clippy_lints/src/if_not_else.rs index 38213141de3f..5ce29597cab7 100644 --- a/clippy_lints/src/if_not_else.rs +++ b/clippy_lints/src/if_not_else.rs @@ -7,32 +7,32 @@ use syntax::ast::*; use crate::utils::span_help_and_lint; -/// **What it does:** Checks for usage of `!` or `!=` in an if condition with an -/// else branch. -/// -/// **Why is this bad?** Negations reduce the readability of statements. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// if !v.is_empty() { -/// a() -/// } else { -/// b() -/// } -/// ``` -/// -/// Could be written: -/// -/// ```rust -/// if v.is_empty() { -/// b() -/// } else { -/// a() -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for usage of `!` or `!=` in an if condition with an + /// else branch. + /// + /// **Why is this bad?** Negations reduce the readability of statements. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// if !v.is_empty() { + /// a() + /// } else { + /// b() + /// } + /// ``` + /// + /// Could be written: + /// + /// ```rust + /// if v.is_empty() { + /// b() + /// } else { + /// a() + /// } + /// ``` pub IF_NOT_ELSE, pedantic, "`if` branches that could be swapped so no negation operation is necessary on the condition" diff --git a/clippy_lints/src/implicit_return.rs b/clippy_lints/src/implicit_return.rs index 8bbcce209847..a82a57fe6ff3 100644 --- a/clippy_lints/src/implicit_return.rs +++ b/clippy_lints/src/implicit_return.rs @@ -5,29 +5,29 @@ use rustc::{declare_tool_lint, lint_array}; use rustc_errors::Applicability; use syntax::source_map::Span; -/// **What it does:** Checks for missing return statements at the end of a block. -/// -/// **Why is this bad?** Actually omitting the return keyword is idiomatic Rust code. Programmers -/// coming from other languages might prefer the expressiveness of `return`. It's possible to miss -/// the last returning statement because the only difference is a missing `;`. Especially in bigger -/// code with multiple return paths having a `return` keyword makes it easier to find the -/// corresponding statements. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// fn foo(x: usize) { -/// x -/// } -/// ``` -/// add return -/// ```rust -/// fn foo(x: usize) { -/// return x; -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for missing return statements at the end of a block. + /// + /// **Why is this bad?** Actually omitting the return keyword is idiomatic Rust code. Programmers + /// coming from other languages might prefer the expressiveness of `return`. It's possible to miss + /// the last returning statement because the only difference is a missing `;`. Especially in bigger + /// code with multiple return paths having a `return` keyword makes it easier to find the + /// corresponding statements. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// fn foo(x: usize) { + /// x + /// } + /// ``` + /// add return + /// ```rust + /// fn foo(x: usize) { + /// return x; + /// } + /// ``` pub IMPLICIT_RETURN, restriction, "use a return statement like `return expr` instead of an expression" diff --git a/clippy_lints/src/indexing_slicing.rs b/clippy_lints/src/indexing_slicing.rs index 19e2283dc076..90129d794ac1 100644 --- a/clippy_lints/src/indexing_slicing.rs +++ b/clippy_lints/src/indexing_slicing.rs @@ -10,75 +10,75 @@ use rustc::ty; use rustc::{declare_tool_lint, lint_array}; use syntax::ast::RangeLimits; -/// **What it does:** Checks for out of bounds array indexing with a constant -/// index. -/// -/// **Why is this bad?** This will always panic at runtime. -/// -/// **Known problems:** Hopefully none. -/// -/// **Example:** -/// ```rust -/// let x = [1, 2, 3, 4]; -/// -/// // Bad -/// x[9]; -/// &x[2..9]; -/// -/// // Good -/// x[0]; -/// x[3]; -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for out of bounds array indexing with a constant + /// index. + /// + /// **Why is this bad?** This will always panic at runtime. + /// + /// **Known problems:** Hopefully none. + /// + /// **Example:** + /// ```rust + /// let x = [1, 2, 3, 4]; + /// + /// // Bad + /// x[9]; + /// &x[2..9]; + /// + /// // Good + /// x[0]; + /// x[3]; + /// ``` pub OUT_OF_BOUNDS_INDEXING, correctness, "out of bounds constant indexing" } -/// **What it does:** Checks for usage of indexing or slicing. Arrays are special cased, this lint -/// does report on arrays if we can tell that slicing operations are in bounds and does not -/// lint on constant `usize` indexing on arrays because that is handled by rustc's `const_err` lint. -/// -/// **Why is this bad?** Indexing and slicing can panic at runtime and there are -/// safe alternatives. -/// -/// **Known problems:** Hopefully none. -/// -/// **Example:** -/// ```rust -/// // Vector -/// let x = vec![0; 5]; -/// -/// // Bad -/// x[2]; -/// &x[2..100]; -/// &x[2..]; -/// &x[..100]; -/// -/// // Good -/// x.get(2); -/// x.get(2..100); -/// x.get(2..); -/// x.get(..100); -/// -/// // Array -/// let y = [0, 1, 2, 3]; -/// -/// // Bad -/// &y[10..100]; -/// &y[10..]; -/// &y[..100]; -/// -/// // Good -/// &y[2..]; -/// &y[..2]; -/// &y[0..3]; -/// y.get(10); -/// y.get(10..100); -/// y.get(10..); -/// y.get(..100); -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for usage of indexing or slicing. Arrays are special cased, this lint + /// does report on arrays if we can tell that slicing operations are in bounds and does not + /// lint on constant `usize` indexing on arrays because that is handled by rustc's `const_err` lint. + /// + /// **Why is this bad?** Indexing and slicing can panic at runtime and there are + /// safe alternatives. + /// + /// **Known problems:** Hopefully none. + /// + /// **Example:** + /// ```rust + /// // Vector + /// let x = vec![0; 5]; + /// + /// // Bad + /// x[2]; + /// &x[2..100]; + /// &x[2..]; + /// &x[..100]; + /// + /// // Good + /// x.get(2); + /// x.get(2..100); + /// x.get(2..); + /// x.get(..100); + /// + /// // Array + /// let y = [0, 1, 2, 3]; + /// + /// // Bad + /// &y[10..100]; + /// &y[10..]; + /// &y[..100]; + /// + /// // Good + /// &y[2..]; + /// &y[..2]; + /// &y[0..3]; + /// y.get(10); + /// y.get(10..100); + /// y.get(10..); + /// y.get(..100); + /// ``` pub INDEXING_SLICING, restriction, "indexing/slicing usage" diff --git a/clippy_lints/src/infallible_destructuring_match.rs b/clippy_lints/src/infallible_destructuring_match.rs index 704b583f8138..762d3b17c926 100644 --- a/clippy_lints/src/infallible_destructuring_match.rs +++ b/clippy_lints/src/infallible_destructuring_match.rs @@ -5,36 +5,36 @@ use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use rustc::{declare_tool_lint, lint_array}; use rustc_errors::Applicability; -/// **What it does:** Checks for matches being used to destructure a single-variant enum -/// or tuple struct where a `let` will suffice. -/// -/// **Why is this bad?** Just readability – `let` doesn't nest, whereas a `match` does. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// enum Wrapper { -/// Data(i32), -/// } -/// -/// let wrapper = Wrapper::Data(42); -/// -/// let data = match wrapper { -/// Wrapper::Data(i) => i, -/// }; -/// ``` -/// -/// The correct use would be: -/// ```rust -/// enum Wrapper { -/// Data(i32), -/// } -/// -/// let wrapper = Wrapper::Data(42); -/// let Wrapper::Data(data) = wrapper; -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for matches being used to destructure a single-variant enum + /// or tuple struct where a `let` will suffice. + /// + /// **Why is this bad?** Just readability – `let` doesn't nest, whereas a `match` does. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// enum Wrapper { + /// Data(i32), + /// } + /// + /// let wrapper = Wrapper::Data(42); + /// + /// let data = match wrapper { + /// Wrapper::Data(i) => i, + /// }; + /// ``` + /// + /// The correct use would be: + /// ```rust + /// enum Wrapper { + /// Data(i32), + /// } + /// + /// let wrapper = Wrapper::Data(42); + /// let Wrapper::Data(data) = wrapper; + /// ``` pub INFALLIBLE_DESTRUCTURING_MATCH, style, "a match statement with a single infallible arm instead of a `let`" diff --git a/clippy_lints/src/infinite_iter.rs b/clippy_lints/src/infinite_iter.rs index 9f2bcd487877..bee28a4b741d 100644 --- a/clippy_lints/src/infinite_iter.rs +++ b/clippy_lints/src/infinite_iter.rs @@ -3,36 +3,36 @@ use rustc::hir::*; use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use rustc::{declare_tool_lint, lint_array}; -/// **What it does:** Checks for iteration that is guaranteed to be infinite. -/// -/// **Why is this bad?** While there may be places where this is acceptable -/// (e.g. in event streams), in most cases this is simply an error. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// repeat(1_u8).iter().collect::>() -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for iteration that is guaranteed to be infinite. + /// + /// **Why is this bad?** While there may be places where this is acceptable + /// (e.g. in event streams), in most cases this is simply an error. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// repeat(1_u8).iter().collect::>() + /// ``` pub INFINITE_ITER, correctness, "infinite iteration" } -/// **What it does:** Checks for iteration that may be infinite. -/// -/// **Why is this bad?** While there may be places where this is acceptable -/// (e.g. in event streams), in most cases this is simply an error. -/// -/// **Known problems:** The code may have a condition to stop iteration, but -/// this lint is not clever enough to analyze it. -/// -/// **Example:** -/// ```rust -/// [0..].iter().zip(infinite_iter.take_while(|x| x > 5)) -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for iteration that may be infinite. + /// + /// **Why is this bad?** While there may be places where this is acceptable + /// (e.g. in event streams), in most cases this is simply an error. + /// + /// **Known problems:** The code may have a condition to stop iteration, but + /// this lint is not clever enough to analyze it. + /// + /// **Example:** + /// ```rust + /// [0..].iter().zip(infinite_iter.take_while(|x| x > 5)) + /// ``` pub MAYBE_INFINITE_ITER, pedantic, "possible infinite iteration" diff --git a/clippy_lints/src/inherent_impl.rs b/clippy_lints/src/inherent_impl.rs index 5585ce4cbefe..51d6c310cf62 100644 --- a/clippy_lints/src/inherent_impl.rs +++ b/clippy_lints/src/inherent_impl.rs @@ -8,33 +8,33 @@ use rustc_data_structures::fx::FxHashMap; use std::default::Default; use syntax_pos::Span; -/// **What it does:** Checks for multiple inherent implementations of a struct -/// -/// **Why is this bad?** Splitting the implementation of a type makes the code harder to navigate. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// struct X; -/// impl X { -/// fn one() {} -/// } -/// impl X { -/// fn other() {} -/// } -/// ``` -/// -/// Could be written: -/// -/// ```rust -/// struct X; -/// impl X { -/// fn one() {} -/// fn other() {} -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for multiple inherent implementations of a struct + /// + /// **Why is this bad?** Splitting the implementation of a type makes the code harder to navigate. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// struct X; + /// impl X { + /// fn one() {} + /// } + /// impl X { + /// fn other() {} + /// } + /// ``` + /// + /// Could be written: + /// + /// ```rust + /// struct X; + /// impl X { + /// fn one() {} + /// fn other() {} + /// } + /// ``` pub MULTIPLE_INHERENT_IMPL, restriction, "Multiple inherent impl that could be grouped" diff --git a/clippy_lints/src/inline_fn_without_body.rs b/clippy_lints/src/inline_fn_without_body.rs index bdc17ab46244..cced334f43a8 100644 --- a/clippy_lints/src/inline_fn_without_body.rs +++ b/clippy_lints/src/inline_fn_without_body.rs @@ -8,21 +8,21 @@ use rustc::{declare_tool_lint, lint_array}; use rustc_errors::Applicability; use syntax::ast::{Attribute, Name}; -/// **What it does:** Checks for `#[inline]` on trait methods without bodies -/// -/// **Why is this bad?** Only implementations of trait methods may be inlined. -/// The inline attribute is ignored for trait methods without bodies. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// trait Animal { -/// #[inline] -/// fn name(&self) -> &'static str; -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for `#[inline]` on trait methods without bodies + /// + /// **Why is this bad?** Only implementations of trait methods may be inlined. + /// The inline attribute is ignored for trait methods without bodies. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// trait Animal { + /// #[inline] + /// fn name(&self) -> &'static str; + /// } + /// ``` pub INLINE_FN_WITHOUT_BODY, correctness, "use of `#[inline]` on trait methods without bodies" diff --git a/clippy_lints/src/int_plus_one.rs b/clippy_lints/src/int_plus_one.rs index 9b5938baf5f2..bab7374916da 100644 --- a/clippy_lints/src/int_plus_one.rs +++ b/clippy_lints/src/int_plus_one.rs @@ -7,24 +7,24 @@ use syntax::ast::*; use crate::utils::{snippet_opt, span_lint_and_then}; -/// **What it does:** Checks for usage of `x >= y + 1` or `x - 1 >= y` (and `<=`) in a block -/// -/// -/// **Why is this bad?** Readability -- better to use `> y` instead of `>= y + 1`. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// x >= y + 1 -/// ``` -/// -/// Could be written: -/// -/// ```rust -/// x > y -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for usage of `x >= y + 1` or `x - 1 >= y` (and `<=`) in a block + /// + /// + /// **Why is this bad?** Readability -- better to use `> y` instead of `>= y + 1`. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// x >= y + 1 + /// ``` + /// + /// Could be written: + /// + /// ```rust + /// x > y + /// ``` pub INT_PLUS_ONE, complexity, "instead of using x >= y + 1, use x > y" diff --git a/clippy_lints/src/invalid_ref.rs b/clippy_lints/src/invalid_ref.rs index 90649535958c..63011726b4f7 100644 --- a/clippy_lints/src/invalid_ref.rs +++ b/clippy_lints/src/invalid_ref.rs @@ -5,17 +5,17 @@ use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use rustc::ty; use rustc::{declare_tool_lint, lint_array}; -/// **What it does:** Checks for creation of references to zeroed or uninitialized memory. -/// -/// **Why is this bad?** Creation of null references is undefined behavior. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// let bad_ref: &usize = std::mem::zeroed(); -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for creation of references to zeroed or uninitialized memory. + /// + /// **Why is this bad?** Creation of null references is undefined behavior. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// let bad_ref: &usize = std::mem::zeroed(); + /// ``` pub INVALID_REF, correctness, "creation of invalid reference" diff --git a/clippy_lints/src/items_after_statements.rs b/clippy_lints/src/items_after_statements.rs index dd283d897a56..f93f515d0239 100644 --- a/clippy_lints/src/items_after_statements.rs +++ b/clippy_lints/src/items_after_statements.rs @@ -6,29 +6,29 @@ use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass}; use rustc::{declare_tool_lint, lint_array}; use syntax::ast::*; -/// **What it does:** Checks for items declared after some statement in a block. -/// -/// **Why is this bad?** Items live for the entire scope they are declared -/// in. But statements are processed in order. This might cause confusion as -/// it's hard to figure out which item is meant in a statement. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// fn foo() { -/// println!("cake"); -/// } -/// -/// fn main() { -/// foo(); // prints "foo" -/// fn foo() { -/// println!("foo"); -/// } -/// foo(); // prints "foo" -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for items declared after some statement in a block. + /// + /// **Why is this bad?** Items live for the entire scope they are declared + /// in. But statements are processed in order. This might cause confusion as + /// it's hard to figure out which item is meant in a statement. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// fn foo() { + /// println!("cake"); + /// } + /// + /// fn main() { + /// foo(); // prints "foo" + /// fn foo() { + /// println!("foo"); + /// } + /// foo(); // prints "foo" + /// } + /// ``` pub ITEMS_AFTER_STATEMENTS, pedantic, "blocks where an item comes after a statement" diff --git a/clippy_lints/src/large_enum_variant.rs b/clippy_lints/src/large_enum_variant.rs index 7a1a0e599c14..2e38fcf03672 100644 --- a/clippy_lints/src/large_enum_variant.rs +++ b/clippy_lints/src/large_enum_variant.rs @@ -7,23 +7,23 @@ use rustc::ty::layout::LayoutOf; use rustc::{declare_tool_lint, lint_array}; use rustc_errors::Applicability; -/// **What it does:** Checks for large size differences between variants on -/// `enum`s. -/// -/// **Why is this bad?** Enum size is bounded by the largest variant. Having a -/// large variant -/// can penalize the memory layout of that enum. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// enum Test { -/// A(i32), -/// B([i32; 8000]), -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for large size differences between variants on + /// `enum`s. + /// + /// **Why is this bad?** Enum size is bounded by the largest variant. Having a + /// large variant + /// can penalize the memory layout of that enum. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// enum Test { + /// A(i32), + /// B([i32; 8000]), + /// } + /// ``` pub LARGE_ENUM_VARIANT, perf, "large size difference between variants on an enum" diff --git a/clippy_lints/src/len_zero.rs b/clippy_lints/src/len_zero.rs index 094cfcf1b1f6..c802b267df2f 100644 --- a/clippy_lints/src/len_zero.rs +++ b/clippy_lints/src/len_zero.rs @@ -9,62 +9,61 @@ use rustc_errors::Applicability; use syntax::ast::{Lit, LitKind, Name}; use syntax::source_map::{Span, Spanned}; -/// **What it does:** Checks for getting the length of something via `.len()` -/// just to compare to zero, and suggests using `.is_empty()` where applicable. -/// -/// **Why is this bad?** Some structures can answer `.is_empty()` much faster -/// than calculating their length. Notably, for slices, getting the length -/// requires a subtraction whereas `.is_empty()` is just a comparison. So it is -/// good to get into the habit of using `.is_empty()`, and having it is cheap. -/// Besides, it makes the intent clearer than a manual comparison. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// if x.len() == 0 { -/// .. -/// } -/// if y.len() != 0 { -/// .. -/// } -/// ``` -/// instead use -/// ```rust -/// if x.is_empty() { -/// .. -/// } -/// if !y.is_empty() { -/// .. -/// } -/// ``` declare_clippy_lint! { -pub LEN_ZERO, -style, -"checking `.len() == 0` or `.len() > 0` (or similar) when `.is_empty()` \ - could be used instead" + /// **What it does:** Checks for getting the length of something via `.len()` + /// just to compare to zero, and suggests using `.is_empty()` where applicable. + /// + /// **Why is this bad?** Some structures can answer `.is_empty()` much faster + /// than calculating their length. Notably, for slices, getting the length + /// requires a subtraction whereas `.is_empty()` is just a comparison. So it is + /// good to get into the habit of using `.is_empty()`, and having it is cheap. + /// Besides, it makes the intent clearer than a manual comparison. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// if x.len() == 0 { + /// .. + /// } + /// if y.len() != 0 { + /// .. + /// } + /// ``` + /// instead use + /// ```rust + /// if x.is_empty() { + /// .. + /// } + /// if !y.is_empty() { + /// .. + /// } + /// ``` + pub LEN_ZERO, + style, + "checking `.len() == 0` or `.len() > 0` (or similar) when `.is_empty()` could be used instead" } -/// **What it does:** Checks for items that implement `.len()` but not -/// `.is_empty()`. -/// -/// **Why is this bad?** It is good custom to have both methods, because for -/// some data structures, asking about the length will be a costly operation, -/// whereas `.is_empty()` can usually answer in constant time. Also it used to -/// lead to false positives on the [`len_zero`](#len_zero) lint – currently that -/// lint will ignore such entities. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// impl X { -/// pub fn len(&self) -> usize { -/// .. -/// } -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for items that implement `.len()` but not + /// `.is_empty()`. + /// + /// **Why is this bad?** It is good custom to have both methods, because for + /// some data structures, asking about the length will be a costly operation, + /// whereas `.is_empty()` can usually answer in constant time. Also it used to + /// lead to false positives on the [`len_zero`](#len_zero) lint – currently that + /// lint will ignore such entities. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// impl X { + /// pub fn len(&self) -> usize { + /// .. + /// } + /// } + /// ``` pub LEN_WITHOUT_IS_EMPTY, style, "traits or impls with a public `len` method but no corresponding `is_empty` method" diff --git a/clippy_lints/src/let_if_seq.rs b/clippy_lints/src/let_if_seq.rs index a4f69e321718..e3533ed6d021 100644 --- a/clippy_lints/src/let_if_seq.rs +++ b/clippy_lints/src/let_if_seq.rs @@ -8,46 +8,46 @@ use rustc::{declare_tool_lint, lint_array}; use rustc_errors::Applicability; use syntax::ast; -/// **What it does:** Checks for variable declarations immediately followed by a -/// conditional affectation. -/// -/// **Why is this bad?** This is not idiomatic Rust. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust,ignore -/// let foo; -/// -/// if bar() { -/// foo = 42; -/// } else { -/// foo = 0; -/// } -/// -/// let mut baz = None; -/// -/// if bar() { -/// baz = Some(42); -/// } -/// ``` -/// -/// should be written -/// -/// ```rust,ignore -/// let foo = if bar() { -/// 42 -/// } else { -/// 0 -/// }; -/// -/// let baz = if bar() { -/// Some(42) -/// } else { -/// None -/// }; -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for variable declarations immediately followed by a + /// conditional affectation. + /// + /// **Why is this bad?** This is not idiomatic Rust. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust,ignore + /// let foo; + /// + /// if bar() { + /// foo = 42; + /// } else { + /// foo = 0; + /// } + /// + /// let mut baz = None; + /// + /// if bar() { + /// baz = Some(42); + /// } + /// ``` + /// + /// should be written + /// + /// ```rust,ignore + /// let foo = if bar() { + /// 42 + /// } else { + /// 0 + /// }; + /// + /// let baz = if bar() { + /// Some(42) + /// } else { + /// None + /// }; + /// ``` pub USELESS_LET_IF_SEQ, style, "unidiomatic `let mut` declaration followed by initialization in `if`" diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 1acf2aa8ad2e..ae24ef54c27c 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -39,7 +39,7 @@ use toml; /// /// Every lint declaration consists of 4 parts: /// -/// 1. The documentation above the lint, which is used for the website +/// 1. The documentation, which is used for the website /// 2. The `LINT_NAME`. See [lint naming][lint_naming] on lint naming conventions. /// 3. The `lint_level`, which is a mapping from *one* of our lint groups to `Allow`, `Warn` or /// `Deny`. The lint level here has nothing to do with what lint groups the lint is a part of. @@ -60,22 +60,22 @@ use toml; /// # use clippy_lints::declare_clippy_lint; /// use rustc::declare_tool_lint; /// -/// /// **What it does:** Checks for ... (describe what the lint matches). -/// /// -/// /// **Why is this bad?** Supply the reason for linting the code. -/// /// -/// /// **Known problems:** None. (Or describe where it could go wrong.) -/// /// -/// /// **Example:** -/// /// -/// /// ```rust -/// /// // Bad -/// /// Insert a short example of code that triggers the lint -/// /// -/// /// // Good -/// /// Insert a short example of improved code that doesn't trigger the lint -/// /// ``` /// declare_clippy_lint! { +/// /// **What it does:** Checks for ... (describe what the lint matches). +/// /// +/// /// **Why is this bad?** Supply the reason for linting the code. +/// /// +/// /// **Known problems:** None. (Or describe where it could go wrong.) +/// /// +/// /// **Example:** +/// /// +/// /// ```rust +/// /// // Bad +/// /// Insert a short example of code that triggers the lint +/// /// +/// /// // Good +/// /// Insert a short example of improved code that doesn't trigger the lint +/// /// ``` /// pub LINT_NAME, /// pedantic, /// "description" @@ -84,35 +84,55 @@ use toml; /// [lint_naming]: https://rust-lang.github.io/rfcs/0344-conventions-galore.html#lints #[macro_export] macro_rules! declare_clippy_lint { - { pub $name:tt, style, $description:tt } => { - declare_tool_lint! { pub clippy::$name, Warn, $description, report_in_external_macro: true } + { $(#[$attr:meta])* pub $name:tt, style, $description:tt } => { + declare_tool_lint! { + $(#[$attr])* pub clippy::$name, Warn, $description, report_in_external_macro: true + } }; - { pub $name:tt, correctness, $description:tt } => { - declare_tool_lint! { pub clippy::$name, Deny, $description, report_in_external_macro: true } + { $(#[$attr:meta])* pub $name:tt, correctness, $description:tt } => { + declare_tool_lint! { + $(#[$attr])* pub clippy::$name, Deny, $description, report_in_external_macro: true + } }; - { pub $name:tt, complexity, $description:tt } => { - declare_tool_lint! { pub clippy::$name, Warn, $description, report_in_external_macro: true } + { $(#[$attr:meta])* pub $name:tt, complexity, $description:tt } => { + declare_tool_lint! { + pub clippy::$name, Warn, $description, report_in_external_macro: true + } }; - { pub $name:tt, perf, $description:tt } => { - declare_tool_lint! { pub clippy::$name, Warn, $description, report_in_external_macro: true } + { $(#[$attr:meta])* pub $name:tt, perf, $description:tt } => { + declare_tool_lint! { + pub clippy::$name, Warn, $description, report_in_external_macro: true + } }; - { pub $name:tt, pedantic, $description:tt } => { - declare_tool_lint! { pub clippy::$name, Allow, $description, report_in_external_macro: true } + { $(#[$attr:meta])* pub $name:tt, pedantic, $description:tt } => { + declare_tool_lint! { + pub clippy::$name, Allow, $description, report_in_external_macro: true + } }; - { pub $name:tt, restriction, $description:tt } => { - declare_tool_lint! { pub clippy::$name, Allow, $description, report_in_external_macro: true } + { $(#[$attr:meta])* pub $name:tt, restriction, $description:tt } => { + declare_tool_lint! { + pub clippy::$name, Allow, $description, report_in_external_macro: true + } }; - { pub $name:tt, cargo, $description:tt } => { - declare_tool_lint! { pub clippy::$name, Allow, $description, report_in_external_macro: true } + { $(#[$attr:meta])* pub $name:tt, cargo, $description:tt } => { + declare_tool_lint! { + pub clippy::$name, Allow, $description, report_in_external_macro: true + } }; - { pub $name:tt, nursery, $description:tt } => { - declare_tool_lint! { pub clippy::$name, Allow, $description, report_in_external_macro: true } + { $(#[$attr:meta])* pub $name:tt, nursery, $description:tt } => { + declare_tool_lint! { + pub clippy::$name, Allow, $description, report_in_external_macro: true + } }; - { pub $name:tt, internal, $description:tt } => { - declare_tool_lint! { pub clippy::$name, Allow, $description, report_in_external_macro: true } + { $(#[$attr:meta])* pub $name:tt, internal, $description:tt } => { + declare_tool_lint! { + pub clippy::$name, Allow, $description, report_in_external_macro: true + } }; - { pub $name:tt, internal_warn, $description:tt } => { - declare_tool_lint! { pub clippy::$name, Warn, $description, report_in_external_macro: true } + { $(#[$attr:meta])* pub $name:tt, internal_warn, $description:tt } => { + declare_tool_lint! { + pub clippy::$name, Warn, $description, report_in_external_macro: true + } }; } diff --git a/clippy_lints/src/lifetimes.rs b/clippy_lints/src/lifetimes.rs index 34de33bd546a..0d417fb8b6b0 100644 --- a/clippy_lints/src/lifetimes.rs +++ b/clippy_lints/src/lifetimes.rs @@ -10,45 +10,45 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use syntax::source_map::Span; use syntax::symbol::keywords; -/// **What it does:** Checks for lifetime annotations which can be removed by -/// relying on lifetime elision. -/// -/// **Why is this bad?** The additional lifetimes make the code look more -/// complicated, while there is nothing out of the ordinary going on. Removing -/// them leads to more readable code. -/// -/// **Known problems:** Potential false negatives: we bail out if the function -/// has a `where` clause where lifetimes are mentioned. -/// -/// **Example:** -/// ```rust -/// fn in_and_out<'a>(x: &'a u8, y: u8) -> &'a u8 { -/// x -/// } -/// ``` declare_clippy_lint! { -pub NEEDLESS_LIFETIMES, -complexity, -"using explicit lifetimes for references in function arguments when elision rules \ - would allow omitting them" + /// **What it does:** Checks for lifetime annotations which can be removed by + /// relying on lifetime elision. + /// + /// **Why is this bad?** The additional lifetimes make the code look more + /// complicated, while there is nothing out of the ordinary going on. Removing + /// them leads to more readable code. + /// + /// **Known problems:** Potential false negatives: we bail out if the function + /// has a `where` clause where lifetimes are mentioned. + /// + /// **Example:** + /// ```rust + /// fn in_and_out<'a>(x: &'a u8, y: u8) -> &'a u8 { + /// x + /// } + /// ``` + pub NEEDLESS_LIFETIMES, + complexity, + "using explicit lifetimes for references in function arguments when elision rules \ + would allow omitting them" } -/// **What it does:** Checks for lifetimes in generics that are never used -/// anywhere else. -/// -/// **Why is this bad?** The additional lifetimes make the code look more -/// complicated, while there is nothing out of the ordinary going on. Removing -/// them leads to more readable code. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// fn unused_lifetime<'a>(x: u8) { -/// .. -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for lifetimes in generics that are never used + /// anywhere else. + /// + /// **Why is this bad?** The additional lifetimes make the code look more + /// complicated, while there is nothing out of the ordinary going on. Removing + /// them leads to more readable code. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// fn unused_lifetime<'a>(x: u8) { + /// .. + /// } + /// ``` pub EXTRA_UNUSED_LIFETIMES, complexity, "unused lifetimes in function definitions" diff --git a/clippy_lints/src/literal_representation.rs b/clippy_lints/src/literal_representation.rs index 801e54f055c4..92cc288abb67 100644 --- a/clippy_lints/src/literal_representation.rs +++ b/clippy_lints/src/literal_representation.rs @@ -9,95 +9,95 @@ use rustc_errors::Applicability; use syntax::ast::*; use syntax_pos; -/// **What it does:** Warns if a long integral or floating-point constant does -/// not contain underscores. -/// -/// **Why is this bad?** Reading long numbers is difficult without separators. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// -/// ```rust -/// 61864918973511 -/// ``` declare_clippy_lint! { + /// **What it does:** Warns if a long integral or floating-point constant does + /// not contain underscores. + /// + /// **Why is this bad?** Reading long numbers is difficult without separators. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// + /// ```rust + /// 61864918973511 + /// ``` pub UNREADABLE_LITERAL, style, "long integer literal without underscores" } -/// **What it does:** Warns for mistyped suffix in literals -/// -/// **Why is this bad?** This is most probably a typo -/// -/// **Known problems:** -/// - Recommends a signed suffix, even though the number might be too big and an unsigned -/// suffix is required -/// - Does not match on `_128` since that is a valid grouping for decimal and octal numbers -/// -/// **Example:** -/// -/// ```rust -/// 2_32 -/// ``` declare_clippy_lint! { + /// **What it does:** Warns for mistyped suffix in literals + /// + /// **Why is this bad?** This is most probably a typo + /// + /// **Known problems:** + /// - Recommends a signed suffix, even though the number might be too big and an unsigned + /// suffix is required + /// - Does not match on `_128` since that is a valid grouping for decimal and octal numbers + /// + /// **Example:** + /// + /// ```rust + /// 2_32 + /// ``` pub MISTYPED_LITERAL_SUFFIXES, correctness, "mistyped literal suffix" } -/// **What it does:** Warns if an integral or floating-point constant is -/// grouped inconsistently with underscores. -/// -/// **Why is this bad?** Readers may incorrectly interpret inconsistently -/// grouped digits. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// -/// ```rust -/// 618_64_9189_73_511 -/// ``` declare_clippy_lint! { + /// **What it does:** Warns if an integral or floating-point constant is + /// grouped inconsistently with underscores. + /// + /// **Why is this bad?** Readers may incorrectly interpret inconsistently + /// grouped digits. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// + /// ```rust + /// 618_64_9189_73_511 + /// ``` pub INCONSISTENT_DIGIT_GROUPING, style, "integer literals with digits grouped inconsistently" } -/// **What it does:** Warns if the digits of an integral or floating-point -/// constant are grouped into groups that -/// are too large. -/// -/// **Why is this bad?** Negatively impacts readability. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// -/// ```rust -/// 6186491_8973511 -/// ``` declare_clippy_lint! { + /// **What it does:** Warns if the digits of an integral or floating-point + /// constant are grouped into groups that + /// are too large. + /// + /// **Why is this bad?** Negatively impacts readability. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// + /// ```rust + /// 6186491_8973511 + /// ``` pub LARGE_DIGIT_GROUPS, pedantic, "grouping digits into groups that are too large" } -/// **What it does:** Warns if there is a better representation for a numeric literal. -/// -/// **Why is this bad?** Especially for big powers of 2 a hexadecimal representation is more -/// readable than a decimal representation. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// -/// `255` => `0xFF` -/// `65_535` => `0xFFFF` -/// `4_042_322_160` => `0xF0F0_F0F0` declare_clippy_lint! { + /// **What it does:** Warns if there is a better representation for a numeric literal. + /// + /// **Why is this bad?** Especially for big powers of 2 a hexadecimal representation is more + /// readable than a decimal representation. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// + /// `255` => `0xFF` + /// `65_535` => `0xFFFF` + /// `4_042_322_160` => `0xF0F0_F0F0` pub DECIMAL_LITERAL_REPRESENTATION, restriction, "using decimal representation when hexadecimal would be better" diff --git a/clippy_lints/src/loops.rs b/clippy_lints/src/loops.rs index 811e7fc6c633..35d9bf38797a 100644 --- a/clippy_lints/src/loops.rs +++ b/clippy_lints/src/loops.rs @@ -32,408 +32,408 @@ use crate::utils::{ span_help_and_lint, span_lint, span_lint_and_sugg, span_lint_and_then, SpanlessEq, }; -/// **What it does:** Checks for for-loops that manually copy items between -/// slices that could be optimized by having a memcpy. -/// -/// **Why is this bad?** It is not as fast as a memcpy. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// for i in 0..src.len() { -/// dst[i + 64] = src[i]; -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for for-loops that manually copy items between + /// slices that could be optimized by having a memcpy. + /// + /// **Why is this bad?** It is not as fast as a memcpy. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// for i in 0..src.len() { + /// dst[i + 64] = src[i]; + /// } + /// ``` pub MANUAL_MEMCPY, perf, "manually copying items between slices" } -/// **What it does:** Checks for looping over the range of `0..len` of some -/// collection just to get the values by index. -/// -/// **Why is this bad?** Just iterating the collection itself makes the intent -/// more clear and is probably faster. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// for i in 0..vec.len() { -/// println!("{}", vec[i]); -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for looping over the range of `0..len` of some + /// collection just to get the values by index. + /// + /// **Why is this bad?** Just iterating the collection itself makes the intent + /// more clear and is probably faster. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// for i in 0..vec.len() { + /// println!("{}", vec[i]); + /// } + /// ``` pub NEEDLESS_RANGE_LOOP, style, "for-looping over a range of indices where an iterator over items would do" } -/// **What it does:** Checks for loops on `x.iter()` where `&x` will do, and -/// suggests the latter. -/// -/// **Why is this bad?** Readability. -/// -/// **Known problems:** False negatives. We currently only warn on some known -/// types. -/// -/// **Example:** -/// ```rust -/// // with `y` a `Vec` or slice: -/// for x in y.iter() { -/// .. -/// } -/// ``` -/// can be rewritten to -/// ```rust -/// for x in &y { -/// .. -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for loops on `x.iter()` where `&x` will do, and + /// suggests the latter. + /// + /// **Why is this bad?** Readability. + /// + /// **Known problems:** False negatives. We currently only warn on some known + /// types. + /// + /// **Example:** + /// ```rust + /// // with `y` a `Vec` or slice: + /// for x in y.iter() { + /// .. + /// } + /// ``` + /// can be rewritten to + /// ```rust + /// for x in &y { + /// .. + /// } + /// ``` pub EXPLICIT_ITER_LOOP, pedantic, "for-looping over `_.iter()` or `_.iter_mut()` when `&_` or `&mut _` would do" } -/// **What it does:** Checks for loops on `y.into_iter()` where `y` will do, and -/// suggests the latter. -/// -/// **Why is this bad?** Readability. -/// -/// **Known problems:** None -/// -/// **Example:** -/// ```rust -/// // with `y` a `Vec` or slice: -/// for x in y.into_iter() { -/// .. -/// } -/// ``` -/// can be rewritten to -/// ```rust -/// for x in y { -/// .. -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for loops on `y.into_iter()` where `y` will do, and + /// suggests the latter. + /// + /// **Why is this bad?** Readability. + /// + /// **Known problems:** None + /// + /// **Example:** + /// ```rust + /// // with `y` a `Vec` or slice: + /// for x in y.into_iter() { + /// .. + /// } + /// ``` + /// can be rewritten to + /// ```rust + /// for x in y { + /// .. + /// } + /// ``` pub EXPLICIT_INTO_ITER_LOOP, pedantic, "for-looping over `_.into_iter()` when `_` would do" } -/// **What it does:** Checks for loops on `x.next()`. -/// -/// **Why is this bad?** `next()` returns either `Some(value)` if there was a -/// value, or `None` otherwise. The insidious thing is that `Option<_>` -/// implements `IntoIterator`, so that possibly one value will be iterated, -/// leading to some hard to find bugs. No one will want to write such code -/// [except to win an Underhanded Rust -/// Contest](https://www.reddit.com/r/rust/comments/3hb0wm/underhanded_rust_contest/cu5yuhr). -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// for x in y.next() { -/// .. -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for loops on `x.next()`. + /// + /// **Why is this bad?** `next()` returns either `Some(value)` if there was a + /// value, or `None` otherwise. The insidious thing is that `Option<_>` + /// implements `IntoIterator`, so that possibly one value will be iterated, + /// leading to some hard to find bugs. No one will want to write such code + /// [except to win an Underhanded Rust + /// Contest](https://www.reddit.com/r/rust/comments/3hb0wm/underhanded_rust_contest/cu5yuhr). + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// for x in y.next() { + /// .. + /// } + /// ``` pub ITER_NEXT_LOOP, correctness, "for-looping over `_.next()` which is probably not intended" } -/// **What it does:** Checks for `for` loops over `Option` values. -/// -/// **Why is this bad?** Readability. This is more clearly expressed as an `if -/// let`. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// for x in option { -/// .. -/// } -/// ``` -/// -/// This should be -/// ```rust -/// if let Some(x) = option { -/// .. -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for `for` loops over `Option` values. + /// + /// **Why is this bad?** Readability. This is more clearly expressed as an `if + /// let`. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// for x in option { + /// .. + /// } + /// ``` + /// + /// This should be + /// ```rust + /// if let Some(x) = option { + /// .. + /// } + /// ``` pub FOR_LOOP_OVER_OPTION, correctness, "for-looping over an `Option`, which is more clearly expressed as an `if let`" } -/// **What it does:** Checks for `for` loops over `Result` values. -/// -/// **Why is this bad?** Readability. This is more clearly expressed as an `if -/// let`. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// for x in result { -/// .. -/// } -/// ``` -/// -/// This should be -/// ```rust -/// if let Ok(x) = result { -/// .. -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for `for` loops over `Result` values. + /// + /// **Why is this bad?** Readability. This is more clearly expressed as an `if + /// let`. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// for x in result { + /// .. + /// } + /// ``` + /// + /// This should be + /// ```rust + /// if let Ok(x) = result { + /// .. + /// } + /// ``` pub FOR_LOOP_OVER_RESULT, correctness, "for-looping over a `Result`, which is more clearly expressed as an `if let`" } -/// **What it does:** Detects `loop + match` combinations that are easier -/// written as a `while let` loop. -/// -/// **Why is this bad?** The `while let` loop is usually shorter and more -/// readable. -/// -/// **Known problems:** Sometimes the wrong binding is displayed (#383). -/// -/// **Example:** -/// ```rust -/// loop { -/// let x = match y { -/// Some(x) => x, -/// None => break, -/// } -/// // .. do something with x -/// } -/// // is easier written as -/// while let Some(x) = y { -/// // .. do something with x -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Detects `loop + match` combinations that are easier + /// written as a `while let` loop. + /// + /// **Why is this bad?** The `while let` loop is usually shorter and more + /// readable. + /// + /// **Known problems:** Sometimes the wrong binding is displayed (#383). + /// + /// **Example:** + /// ```rust + /// loop { + /// let x = match y { + /// Some(x) => x, + /// None => break, + /// } + /// // .. do something with x + /// } + /// // is easier written as + /// while let Some(x) = y { + /// // .. do something with x + /// } + /// ``` pub WHILE_LET_LOOP, complexity, "`loop { if let { ... } else break }`, which can be written as a `while let` loop" } -/// **What it does:** Checks for using `collect()` on an iterator without using -/// the result. -/// -/// **Why is this bad?** It is more idiomatic to use a `for` loop over the -/// iterator instead. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// vec.iter().map(|x| /* some operation returning () */).collect::>(); -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for using `collect()` on an iterator without using + /// the result. + /// + /// **Why is this bad?** It is more idiomatic to use a `for` loop over the + /// iterator instead. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// vec.iter().map(|x| /* some operation returning () */).collect::>(); + /// ``` pub UNUSED_COLLECT, perf, "`collect()`ing an iterator without using the result; this is usually better written as a for loop" } -/// **What it does:** Checks for functions collecting an iterator when collect -/// is not needed. -/// -/// **Why is this bad?** `collect` causes the allocation of a new data structure, -/// when this allocation may not be needed. -/// -/// **Known problems:** -/// None -/// -/// **Example:** -/// ```rust -/// let len = iterator.collect::>().len(); -/// // should be -/// let len = iterator.count(); -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for functions collecting an iterator when collect + /// is not needed. + /// + /// **Why is this bad?** `collect` causes the allocation of a new data structure, + /// when this allocation may not be needed. + /// + /// **Known problems:** + /// None + /// + /// **Example:** + /// ```rust + /// let len = iterator.collect::>().len(); + /// // should be + /// let len = iterator.count(); + /// ``` pub NEEDLESS_COLLECT, perf, "collecting an iterator when collect is not needed" } -/// **What it does:** Checks for loops over ranges `x..y` where both `x` and `y` -/// are constant and `x` is greater or equal to `y`, unless the range is -/// reversed or has a negative `.step_by(_)`. -/// -/// **Why is it bad?** Such loops will either be skipped or loop until -/// wrap-around (in debug code, this may `panic!()`). Both options are probably -/// not intended. -/// -/// **Known problems:** The lint cannot catch loops over dynamically defined -/// ranges. Doing this would require simulating all possible inputs and code -/// paths through the program, which would be complex and error-prone. -/// -/// **Example:** -/// ```rust -/// for x in 5..10 - 5 { -/// .. -/// } // oops, stray `-` -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for loops over ranges `x..y` where both `x` and `y` + /// are constant and `x` is greater or equal to `y`, unless the range is + /// reversed or has a negative `.step_by(_)`. + /// + /// **Why is it bad?** Such loops will either be skipped or loop until + /// wrap-around (in debug code, this may `panic!()`). Both options are probably + /// not intended. + /// + /// **Known problems:** The lint cannot catch loops over dynamically defined + /// ranges. Doing this would require simulating all possible inputs and code + /// paths through the program, which would be complex and error-prone. + /// + /// **Example:** + /// ```rust + /// for x in 5..10 - 5 { + /// .. + /// } // oops, stray `-` + /// ``` pub REVERSE_RANGE_LOOP, correctness, "iteration over an empty range, such as `10..0` or `5..5`" } -/// **What it does:** Checks `for` loops over slices with an explicit counter -/// and suggests the use of `.enumerate()`. -/// -/// **Why is it bad?** Not only is the version using `.enumerate()` more -/// readable, the compiler is able to remove bounds checks which can lead to -/// faster code in some instances. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// for i in 0..v.len() { foo(v[i]); -/// for i in 0..v.len() { bar(i, v[i]); } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks `for` loops over slices with an explicit counter + /// and suggests the use of `.enumerate()`. + /// + /// **Why is it bad?** Not only is the version using `.enumerate()` more + /// readable, the compiler is able to remove bounds checks which can lead to + /// faster code in some instances. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// for i in 0..v.len() { foo(v[i]); + /// for i in 0..v.len() { bar(i, v[i]); } + /// ``` pub EXPLICIT_COUNTER_LOOP, complexity, "for-looping with an explicit counter when `_.enumerate()` would do" } -/// **What it does:** Checks for empty `loop` expressions. -/// -/// **Why is this bad?** Those busy loops burn CPU cycles without doing -/// anything. Think of the environment and either block on something or at least -/// make the thread sleep for some microseconds. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// loop {} -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for empty `loop` expressions. + /// + /// **Why is this bad?** Those busy loops burn CPU cycles without doing + /// anything. Think of the environment and either block on something or at least + /// make the thread sleep for some microseconds. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// loop {} + /// ``` pub EMPTY_LOOP, style, "empty `loop {}`, which should block or sleep" } -/// **What it does:** Checks for `while let` expressions on iterators. -/// -/// **Why is this bad?** Readability. A simple `for` loop is shorter and conveys -/// the intent better. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// while let Some(val) = iter() { -/// .. -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for `while let` expressions on iterators. + /// + /// **Why is this bad?** Readability. A simple `for` loop is shorter and conveys + /// the intent better. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// while let Some(val) = iter() { + /// .. + /// } + /// ``` pub WHILE_LET_ON_ITERATOR, style, "using a while-let loop instead of a for loop on an iterator" } -/// **What it does:** Checks for iterating a map (`HashMap` or `BTreeMap`) and -/// ignoring either the keys or values. -/// -/// **Why is this bad?** Readability. There are `keys` and `values` methods that -/// can be used to express that don't need the values or keys. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// for (k, _) in &map { -/// .. -/// } -/// ``` -/// -/// could be replaced by -/// -/// ```rust -/// for k in map.keys() { -/// .. -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for iterating a map (`HashMap` or `BTreeMap`) and + /// ignoring either the keys or values. + /// + /// **Why is this bad?** Readability. There are `keys` and `values` methods that + /// can be used to express that don't need the values or keys. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// for (k, _) in &map { + /// .. + /// } + /// ``` + /// + /// could be replaced by + /// + /// ```rust + /// for k in map.keys() { + /// .. + /// } + /// ``` pub FOR_KV_MAP, style, "looping on a map using `iter` when `keys` or `values` would do" } -/// **What it does:** Checks for loops that will always `break`, `return` or -/// `continue` an outer loop. -/// -/// **Why is this bad?** This loop never loops, all it does is obfuscating the -/// code. -/// -/// **Known problems:** None -/// -/// **Example:** -/// ```rust -/// loop { -/// ..; -/// break; -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for loops that will always `break`, `return` or + /// `continue` an outer loop. + /// + /// **Why is this bad?** This loop never loops, all it does is obfuscating the + /// code. + /// + /// **Known problems:** None + /// + /// **Example:** + /// ```rust + /// loop { + /// ..; + /// break; + /// } + /// ``` pub NEVER_LOOP, correctness, "any loop that will always `break` or `return`" } -/// **What it does:** Checks for loops which have a range bound that is a mutable variable -/// -/// **Why is this bad?** One might think that modifying the mutable variable changes the loop bounds -/// -/// **Known problems:** None -/// -/// **Example:** -/// ```rust -/// let mut foo = 42; -/// for i in 0..foo { -/// foo -= 1; -/// println!("{}", i); // prints numbers from 0 to 42, not 0 to 21 -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for loops which have a range bound that is a mutable variable + /// + /// **Why is this bad?** One might think that modifying the mutable variable changes the loop bounds + /// + /// **Known problems:** None + /// + /// **Example:** + /// ```rust + /// let mut foo = 42; + /// for i in 0..foo { + /// foo -= 1; + /// println!("{}", i); // prints numbers from 0 to 42, not 0 to 21 + /// } + /// ``` pub MUT_RANGE_BOUND, complexity, "for loop over a range where one of the bounds is a mutable variable" } -/// **What it does:** Checks whether variables used within while loop condition -/// can be (and are) mutated in the body. -/// -/// **Why is this bad?** If the condition is unchanged, entering the body of the loop -/// will lead to an infinite loop. -/// -/// **Known problems:** If the `while`-loop is in a closure, the check for mutation of the -/// condition variables in the body can cause false negatives. For example when only `Upvar` `a` is -/// in the condition and only `Upvar` `b` gets mutated in the body, the lint will not trigger. -/// -/// **Example:** -/// ```rust -/// let i = 0; -/// while i > 10 { -/// println!("let me loop forever!"); -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks whether variables used within while loop condition + /// can be (and are) mutated in the body. + /// + /// **Why is this bad?** If the condition is unchanged, entering the body of the loop + /// will lead to an infinite loop. + /// + /// **Known problems:** If the `while`-loop is in a closure, the check for mutation of the + /// condition variables in the body can cause false negatives. For example when only `Upvar` `a` is + /// in the condition and only `Upvar` `b` gets mutated in the body, the lint will not trigger. + /// + /// **Example:** + /// ```rust + /// let i = 0; + /// while i > 10 { + /// println!("let me loop forever!"); + /// } + /// ``` pub WHILE_IMMUTABLE_CONDITION, correctness, "variables used within while expression are not mutated in the body" diff --git a/clippy_lints/src/map_clone.rs b/clippy_lints/src/map_clone.rs index 5699870c307d..4a3092640962 100644 --- a/clippy_lints/src/map_clone.rs +++ b/clippy_lints/src/map_clone.rs @@ -14,29 +14,29 @@ use syntax::source_map::Span; #[derive(Clone)] pub struct Pass; -/// **What it does:** Checks for usage of `iterator.map(|x| x.clone())` and suggests -/// `iterator.cloned()` instead -/// -/// **Why is this bad?** Readability, this can be written more concisely -/// -/// **Known problems:** None -/// -/// **Example:** -/// -/// ```rust -/// let x = vec![42, 43]; -/// let y = x.iter(); -/// let z = y.map(|i| *i); -/// ``` -/// -/// The correct use would be: -/// -/// ```rust -/// let x = vec![42, 43]; -/// let y = x.iter(); -/// let z = y.cloned(); -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for usage of `iterator.map(|x| x.clone())` and suggests + /// `iterator.cloned()` instead + /// + /// **Why is this bad?** Readability, this can be written more concisely + /// + /// **Known problems:** None + /// + /// **Example:** + /// + /// ```rust + /// let x = vec![42, 43]; + /// let y = x.iter(); + /// let z = y.map(|i| *i); + /// ``` + /// + /// The correct use would be: + /// + /// ```rust + /// let x = vec![42, 43]; + /// let y = x.iter(); + /// let z = y.cloned(); + /// ``` pub MAP_CLONE, style, "using `iterator.map(|x| x.clone())`, or dereferencing closures for `Copy` types" diff --git a/clippy_lints/src/map_unit_fn.rs b/clippy_lints/src/map_unit_fn.rs index 75e12cd9fd32..f96418201da7 100644 --- a/clippy_lints/src/map_unit_fn.rs +++ b/clippy_lints/src/map_unit_fn.rs @@ -11,67 +11,67 @@ use syntax::source_map::Span; #[derive(Clone)] pub struct Pass; -/// **What it does:** Checks for usage of `option.map(f)` where f is a function -/// or closure that returns the unit type. -/// -/// **Why is this bad?** Readability, this can be written more clearly with -/// an if let statement -/// -/// **Known problems:** None. -/// -/// **Example:** -/// -/// ```rust -/// let x: Option<&str> = do_stuff(); -/// x.map(log_err_msg); -/// x.map(|msg| log_err_msg(format_msg(msg))) -/// ``` -/// -/// The correct use would be: -/// -/// ```rust -/// let x: Option<&str> = do_stuff(); -/// if let Some(msg) = x { -/// log_err_msg(msg) -/// } -/// if let Some(msg) = x { -/// log_err_msg(format_msg(msg)) -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for usage of `option.map(f)` where f is a function + /// or closure that returns the unit type. + /// + /// **Why is this bad?** Readability, this can be written more clearly with + /// an if let statement + /// + /// **Known problems:** None. + /// + /// **Example:** + /// + /// ```rust + /// let x: Option<&str> = do_stuff(); + /// x.map(log_err_msg); + /// x.map(|msg| log_err_msg(format_msg(msg))) + /// ``` + /// + /// The correct use would be: + /// + /// ```rust + /// let x: Option<&str> = do_stuff(); + /// if let Some(msg) = x { + /// log_err_msg(msg) + /// } + /// if let Some(msg) = x { + /// log_err_msg(format_msg(msg)) + /// } + /// ``` pub OPTION_MAP_UNIT_FN, complexity, "using `option.map(f)`, where f is a function or closure that returns ()" } -/// **What it does:** Checks for usage of `result.map(f)` where f is a function -/// or closure that returns the unit type. -/// -/// **Why is this bad?** Readability, this can be written more clearly with -/// an if let statement -/// -/// **Known problems:** None. -/// -/// **Example:** -/// -/// ```rust -/// let x: Result<&str, &str> = do_stuff(); -/// x.map(log_err_msg); -/// x.map(|msg| log_err_msg(format_msg(msg))) -/// ``` -/// -/// The correct use would be: -/// -/// ```rust -/// let x: Result<&str, &str> = do_stuff(); -/// if let Ok(msg) = x { -/// log_err_msg(msg) -/// } -/// if let Ok(msg) = x { -/// log_err_msg(format_msg(msg)) -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for usage of `result.map(f)` where f is a function + /// or closure that returns the unit type. + /// + /// **Why is this bad?** Readability, this can be written more clearly with + /// an if let statement + /// + /// **Known problems:** None. + /// + /// **Example:** + /// + /// ```rust + /// let x: Result<&str, &str> = do_stuff(); + /// x.map(log_err_msg); + /// x.map(|msg| log_err_msg(format_msg(msg))) + /// ``` + /// + /// The correct use would be: + /// + /// ```rust + /// let x: Result<&str, &str> = do_stuff(); + /// if let Ok(msg) = x { + /// log_err_msg(msg) + /// } + /// if let Ok(msg) = x { + /// log_err_msg(format_msg(msg)) + /// } + /// ``` pub RESULT_MAP_UNIT_FN, complexity, "using `result.map(f)`, where f is a function or closure that returns ()" diff --git a/clippy_lints/src/matches.rs b/clippy_lints/src/matches.rs index e762e2b3a80b..101a31e30860 100644 --- a/clippy_lints/src/matches.rs +++ b/clippy_lints/src/matches.rs @@ -18,192 +18,192 @@ use std::ops::Deref; use syntax::ast::LitKind; use syntax::source_map::Span; -/// **What it does:** Checks for matches with a single arm where an `if let` -/// will usually suffice. -/// -/// **Why is this bad?** Just readability – `if let` nests less than a `match`. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// match x { -/// Some(ref foo) => bar(foo), -/// _ => (), -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for matches with a single arm where an `if let` + /// will usually suffice. + /// + /// **Why is this bad?** Just readability – `if let` nests less than a `match`. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// match x { + /// Some(ref foo) => bar(foo), + /// _ => (), + /// } + /// ``` pub SINGLE_MATCH, style, "a match statement with a single nontrivial arm (i.e. where the other arm is `_ => {}`) instead of `if let`" } -/// **What it does:** Checks for matches with a two arms where an `if let else` will -/// usually suffice. -/// -/// **Why is this bad?** Just readability – `if let` nests less than a `match`. -/// -/// **Known problems:** Personal style preferences may differ. -/// -/// **Example:** -/// -/// Using `match`: -/// -/// ```rust -/// match x { -/// Some(ref foo) => bar(foo), -/// _ => bar(other_ref), -/// } -/// ``` -/// -/// Using `if let` with `else`: -/// -/// ```rust -/// if let Some(ref foo) = x { -/// bar(foo); -/// } else { -/// bar(other_ref); -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for matches with a two arms where an `if let else` will + /// usually suffice. + /// + /// **Why is this bad?** Just readability – `if let` nests less than a `match`. + /// + /// **Known problems:** Personal style preferences may differ. + /// + /// **Example:** + /// + /// Using `match`: + /// + /// ```rust + /// match x { + /// Some(ref foo) => bar(foo), + /// _ => bar(other_ref), + /// } + /// ``` + /// + /// Using `if let` with `else`: + /// + /// ```rust + /// if let Some(ref foo) = x { + /// bar(foo); + /// } else { + /// bar(other_ref); + /// } + /// ``` pub SINGLE_MATCH_ELSE, pedantic, "a match statement with a two arms where the second arm's pattern is a placeholder instead of a specific match pattern" } -/// **What it does:** Checks for matches where all arms match a reference, -/// suggesting to remove the reference and deref the matched expression -/// instead. It also checks for `if let &foo = bar` blocks. -/// -/// **Why is this bad?** It just makes the code less readable. That reference -/// destructuring adds nothing to the code. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// match x { -/// &A(ref y) => foo(y), -/// &B => bar(), -/// _ => frob(&x), -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for matches where all arms match a reference, + /// suggesting to remove the reference and deref the matched expression + /// instead. It also checks for `if let &foo = bar` blocks. + /// + /// **Why is this bad?** It just makes the code less readable. That reference + /// destructuring adds nothing to the code. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// match x { + /// &A(ref y) => foo(y), + /// &B => bar(), + /// _ => frob(&x), + /// } + /// ``` pub MATCH_REF_PATS, style, "a match or `if let` with all arms prefixed with `&` instead of deref-ing the match expression" } -/// **What it does:** Checks for matches where match expression is a `bool`. It -/// suggests to replace the expression with an `if...else` block. -/// -/// **Why is this bad?** It makes the code less readable. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// let condition: bool = true; -/// match condition { -/// true => foo(), -/// false => bar(), -/// } -/// ``` -/// Use if/else instead: -/// ```rust -/// let condition: bool = true; -/// if condition { -/// foo(); -/// } else { -/// bar(); -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for matches where match expression is a `bool`. It + /// suggests to replace the expression with an `if...else` block. + /// + /// **Why is this bad?** It makes the code less readable. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// let condition: bool = true; + /// match condition { + /// true => foo(), + /// false => bar(), + /// } + /// ``` + /// Use if/else instead: + /// ```rust + /// let condition: bool = true; + /// if condition { + /// foo(); + /// } else { + /// bar(); + /// } + /// ``` pub MATCH_BOOL, style, "a match on a boolean expression instead of an `if..else` block" } -/// **What it does:** Checks for overlapping match arms. -/// -/// **Why is this bad?** It is likely to be an error and if not, makes the code -/// less obvious. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// let x = 5; -/// match x { -/// 1...10 => println!("1 ... 10"), -/// 5...15 => println!("5 ... 15"), -/// _ => (), -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for overlapping match arms. + /// + /// **Why is this bad?** It is likely to be an error and if not, makes the code + /// less obvious. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// let x = 5; + /// match x { + /// 1...10 => println!("1 ... 10"), + /// 5...15 => println!("5 ... 15"), + /// _ => (), + /// } + /// ``` pub MATCH_OVERLAPPING_ARM, style, "a match with overlapping arms" } -/// **What it does:** Checks for arm which matches all errors with `Err(_)` -/// and take drastic actions like `panic!`. -/// -/// **Why is this bad?** It is generally a bad practice, just like -/// catching all exceptions in java with `catch(Exception)` -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// let x: Result(i32, &str) = Ok(3); -/// match x { -/// Ok(_) => println!("ok"), -/// Err(_) => panic!("err"), -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for arm which matches all errors with `Err(_)` + /// and take drastic actions like `panic!`. + /// + /// **Why is this bad?** It is generally a bad practice, just like + /// catching all exceptions in java with `catch(Exception)` + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// let x: Result(i32, &str) = Ok(3); + /// match x { + /// Ok(_) => println!("ok"), + /// Err(_) => panic!("err"), + /// } + /// ``` pub MATCH_WILD_ERR_ARM, style, "a match with `Err(_)` arm and take drastic actions" } -/// **What it does:** Checks for match which is used to add a reference to an -/// `Option` value. -/// -/// **Why is this bad?** Using `as_ref()` or `as_mut()` instead is shorter. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// let x: Option<()> = None; -/// let r: Option<&()> = match x { -/// None => None, -/// Some(ref v) => Some(v), -/// }; -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for match which is used to add a reference to an + /// `Option` value. + /// + /// **Why is this bad?** Using `as_ref()` or `as_mut()` instead is shorter. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// let x: Option<()> = None; + /// let r: Option<&()> = match x { + /// None => None, + /// Some(ref v) => Some(v), + /// }; + /// ``` pub MATCH_AS_REF, complexity, "a match on an Option value instead of using `as_ref()` or `as_mut`" } -/// **What it does:** Checks for wildcard enum matches using `_`. -/// -/// **Why is this bad?** New enum variants added by library updates can be missed. -/// -/// **Known problems:** Suggested replacements may be incorrect if guards exhaustively cover some -/// variants, and also may not use correct path to enum if it's not present in the current scope. -/// -/// **Example:** -/// ```rust -/// match x { -/// A => {}, -/// _ => {}, -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for wildcard enum matches using `_`. + /// + /// **Why is this bad?** New enum variants added by library updates can be missed. + /// + /// **Known problems:** Suggested replacements may be incorrect if guards exhaustively cover some + /// variants, and also may not use correct path to enum if it's not present in the current scope. + /// + /// **Example:** + /// ```rust + /// match x { + /// A => {}, + /// _ => {}, + /// } + /// ``` pub WILDCARD_ENUM_MATCH_ARM, restriction, "a wildcard enum match arm using `_`" diff --git a/clippy_lints/src/mem_discriminant.rs b/clippy_lints/src/mem_discriminant.rs index 65e473698198..17a9131640b4 100644 --- a/clippy_lints/src/mem_discriminant.rs +++ b/clippy_lints/src/mem_discriminant.rs @@ -7,19 +7,19 @@ use rustc_errors::Applicability; use std::iter; -/// **What it does:** Checks for calls of `mem::discriminant()` on a non-enum type. -/// -/// **Why is this bad?** The value of `mem::discriminant()` on non-enum types -/// is unspecified. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// mem::discriminant(&"hello"); -/// mem::discriminant(&&Some(2)); -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for calls of `mem::discriminant()` on a non-enum type. + /// + /// **Why is this bad?** The value of `mem::discriminant()` on non-enum types + /// is unspecified. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// mem::discriminant(&"hello"); + /// mem::discriminant(&&Some(2)); + /// ``` pub MEM_DISCRIMINANT_NON_ENUM, correctness, "calling mem::descriminant on non-enum type" diff --git a/clippy_lints/src/mem_forget.rs b/clippy_lints/src/mem_forget.rs index 0f25070318e0..aaaef49cfc41 100644 --- a/clippy_lints/src/mem_forget.rs +++ b/clippy_lints/src/mem_forget.rs @@ -3,19 +3,19 @@ use rustc::hir::{Expr, ExprKind}; use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use rustc::{declare_tool_lint, lint_array}; -/// **What it does:** Checks for usage of `std::mem::forget(t)` where `t` is -/// `Drop`. -/// -/// **Why is this bad?** `std::mem::forget(t)` prevents `t` from running its -/// destructor, possibly causing leaks. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// mem::forget(Rc::new(55)) -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for usage of `std::mem::forget(t)` where `t` is + /// `Drop`. + /// + /// **Why is this bad?** `std::mem::forget(t)` prevents `t` from running its + /// destructor, possibly causing leaks. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// mem::forget(Rc::new(55)) + /// ``` pub MEM_FORGET, restriction, "`mem::forget` usage on `Drop` types, likely to cause memory leaks" diff --git a/clippy_lints/src/mem_replace.rs b/clippy_lints/src/mem_replace.rs index 1b43794bcb77..4d0fae2ac1c5 100644 --- a/clippy_lints/src/mem_replace.rs +++ b/clippy_lints/src/mem_replace.rs @@ -5,26 +5,26 @@ use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use rustc::{declare_tool_lint, lint_array}; use rustc_errors::Applicability; -/// **What it does:** Checks for `mem::replace()` on an `Option` with -/// `None`. -/// -/// **Why is this bad?** `Option` already has the method `take()` for -/// taking its current value (Some(..) or None) and replacing it with -/// `None`. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// let mut an_option = Some(0); -/// let replaced = mem::replace(&mut an_option, None); -/// ``` -/// Is better expressed with: -/// ```rust -/// let mut an_option = Some(0); -/// let taken = an_option.take(); -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for `mem::replace()` on an `Option` with + /// `None`. + /// + /// **Why is this bad?** `Option` already has the method `take()` for + /// taking its current value (Some(..) or None) and replacing it with + /// `None`. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// let mut an_option = Some(0); + /// let replaced = mem::replace(&mut an_option, None); + /// ``` + /// Is better expressed with: + /// ```rust + /// let mut an_option = Some(0); + /// let taken = an_option.take(); + /// ``` pub MEM_REPLACE_OPTION_WITH_NONE, style, "replacing an `Option` with `None` instead of `take()`" diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index deaf054aec7d..75865f9123bd 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -28,749 +28,748 @@ mod unnecessary_filter_map; #[derive(Clone)] pub struct Pass; -/// **What it does:** Checks for `.unwrap()` calls on `Option`s. -/// -/// **Why is this bad?** Usually it is better to handle the `None` case, or to -/// at least call `.expect(_)` with a more helpful message. Still, for a lot of -/// quick-and-dirty code, `unwrap` is a good choice, which is why this lint is -/// `Allow` by default. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// x.unwrap() -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for `.unwrap()` calls on `Option`s. + /// + /// **Why is this bad?** Usually it is better to handle the `None` case, or to + /// at least call `.expect(_)` with a more helpful message. Still, for a lot of + /// quick-and-dirty code, `unwrap` is a good choice, which is why this lint is + /// `Allow` by default. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// x.unwrap() + /// ``` pub OPTION_UNWRAP_USED, restriction, "using `Option.unwrap()`, which should at least get a better message using `expect()`" } -/// **What it does:** Checks for `.unwrap()` calls on `Result`s. -/// -/// **Why is this bad?** `result.unwrap()` will let the thread panic on `Err` -/// values. Normally, you want to implement more sophisticated error handling, -/// and propagate errors upwards with `try!`. -/// -/// Even if you want to panic on errors, not all `Error`s implement good -/// messages on display. Therefore it may be beneficial to look at the places -/// where they may get displayed. Activate this lint to do just that. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// x.unwrap() -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for `.unwrap()` calls on `Result`s. + /// + /// **Why is this bad?** `result.unwrap()` will let the thread panic on `Err` + /// values. Normally, you want to implement more sophisticated error handling, + /// and propagate errors upwards with `try!`. + /// + /// Even if you want to panic on errors, not all `Error`s implement good + /// messages on display. Therefore it may be beneficial to look at the places + /// where they may get displayed. Activate this lint to do just that. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// x.unwrap() + /// ``` pub RESULT_UNWRAP_USED, restriction, "using `Result.unwrap()`, which might be better handled" } -/// **What it does:** Checks for methods that should live in a trait -/// implementation of a `std` trait (see [llogiq's blog -/// post](http://llogiq.github.io/2015/07/30/traits.html) for further -/// information) instead of an inherent implementation. -/// -/// **Why is this bad?** Implementing the traits improve ergonomics for users of -/// the code, often with very little cost. Also people seeing a `mul(...)` -/// method -/// may expect `*` to work equally, so you should have good reason to disappoint -/// them. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// struct X; -/// impl X { -/// fn add(&self, other: &X) -> X { -/// .. -/// } -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for methods that should live in a trait + /// implementation of a `std` trait (see [llogiq's blog + /// post](http://llogiq.github.io/2015/07/30/traits.html) for further + /// information) instead of an inherent implementation. + /// + /// **Why is this bad?** Implementing the traits improve ergonomics for users of + /// the code, often with very little cost. Also people seeing a `mul(...)` + /// method + /// may expect `*` to work equally, so you should have good reason to disappoint + /// them. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// struct X; + /// impl X { + /// fn add(&self, other: &X) -> X { + /// .. + /// } + /// } + /// ``` pub SHOULD_IMPLEMENT_TRAIT, style, "defining a method that should be implementing a std trait" } -/// **What it does:** Checks for methods with certain name prefixes and which -/// doesn't match how self is taken. The actual rules are: -/// -/// |Prefix |`self` taken | -/// |-------|----------------------| -/// |`as_` |`&self` or `&mut self`| -/// |`from_`| none | -/// |`into_`|`self` | -/// |`is_` |`&self` or none | -/// |`to_` |`&self` | -/// -/// **Why is this bad?** Consistency breeds readability. If you follow the -/// conventions, your users won't be surprised that they, e.g., need to supply a -/// mutable reference to a `as_..` function. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// impl X { -/// fn as_str(self) -> &str { -/// .. -/// } -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for methods with certain name prefixes and which + /// doesn't match how self is taken. The actual rules are: + /// + /// |Prefix |`self` taken | + /// |-------|----------------------| + /// |`as_` |`&self` or `&mut self`| + /// |`from_`| none | + /// |`into_`|`self` | + /// |`is_` |`&self` or none | + /// |`to_` |`&self` | + /// + /// **Why is this bad?** Consistency breeds readability. If you follow the + /// conventions, your users won't be surprised that they, e.g., need to supply a + /// mutable reference to a `as_..` function. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// impl X { + /// fn as_str(self) -> &str { + /// .. + /// } + /// } + /// ``` pub WRONG_SELF_CONVENTION, style, "defining a method named with an established prefix (like \"into_\") that takes `self` with the wrong convention" } -/// **What it does:** This is the same as -/// [`wrong_self_convention`](#wrong_self_convention), but for public items. -/// -/// **Why is this bad?** See [`wrong_self_convention`](#wrong_self_convention). -/// -/// **Known problems:** Actually *renaming* the function may break clients if -/// the function is part of the public interface. In that case, be mindful of -/// the stability guarantees you've given your users. -/// -/// **Example:** -/// ```rust -/// impl X { -/// pub fn as_str(self) -> &str { -/// .. -/// } -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** This is the same as + /// [`wrong_self_convention`](#wrong_self_convention), but for public items. + /// + /// **Why is this bad?** See [`wrong_self_convention`](#wrong_self_convention). + /// + /// **Known problems:** Actually *renaming* the function may break clients if + /// the function is part of the public interface. In that case, be mindful of + /// the stability guarantees you've given your users. + /// + /// **Example:** + /// ```rust + /// impl X { + /// pub fn as_str(self) -> &str { + /// .. + /// } + /// } + /// ``` pub WRONG_PUB_SELF_CONVENTION, restriction, "defining a public method named with an established prefix (like \"into_\") that takes `self` with the wrong convention" } -/// **What it does:** Checks for usage of `ok().expect(..)`. -/// -/// **Why is this bad?** Because you usually call `expect()` on the `Result` -/// directly to get a better error message. -/// -/// **Known problems:** The error type needs to implement `Debug` -/// -/// **Example:** -/// ```rust -/// x.ok().expect("why did I do this again?") -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for usage of `ok().expect(..)`. + /// + /// **Why is this bad?** Because you usually call `expect()` on the `Result` + /// directly to get a better error message. + /// + /// **Known problems:** The error type needs to implement `Debug` + /// + /// **Example:** + /// ```rust + /// x.ok().expect("why did I do this again?") + /// ``` pub OK_EXPECT, style, "using `ok().expect()`, which gives worse error messages than calling `expect` directly on the Result" } -/// **What it does:** Checks for usage of `_.map(_).unwrap_or(_)`. -/// -/// **Why is this bad?** Readability, this can be written more concisely as -/// `_.map_or(_, _)`. -/// -/// **Known problems:** The order of the arguments is not in execution order -/// -/// **Example:** -/// ```rust -/// x.map(|a| a + 1).unwrap_or(0) -/// ``` declare_clippy_lint! { -pub OPTION_MAP_UNWRAP_OR, -pedantic, -"using `Option.map(f).unwrap_or(a)`, which is more succinctly expressed as \ - `map_or(a, f)`" -} - -/// **What it does:** Checks for usage of `_.map(_).unwrap_or_else(_)`. -/// -/// **Why is this bad?** Readability, this can be written more concisely as -/// `_.map_or_else(_, _)`. -/// -/// **Known problems:** The order of the arguments is not in execution order. -/// -/// **Example:** -/// ```rust -/// x.map(|a| a + 1).unwrap_or_else(some_function) -/// ``` + /// **What it does:** Checks for usage of `_.map(_).unwrap_or(_)`. + /// + /// **Why is this bad?** Readability, this can be written more concisely as + /// `_.map_or(_, _)`. + /// + /// **Known problems:** The order of the arguments is not in execution order + /// + /// **Example:** + /// ```rust + /// x.map(|a| a + 1).unwrap_or(0) + /// ``` + pub OPTION_MAP_UNWRAP_OR, + pedantic, + "using `Option.map(f).unwrap_or(a)`, which is more succinctly expressed as `map_or(a, f)`" +} + declare_clippy_lint! { + /// **What it does:** Checks for usage of `_.map(_).unwrap_or_else(_)`. + /// + /// **Why is this bad?** Readability, this can be written more concisely as + /// `_.map_or_else(_, _)`. + /// + /// **Known problems:** The order of the arguments is not in execution order. + /// + /// **Example:** + /// ```rust + /// x.map(|a| a + 1).unwrap_or_else(some_function) + /// ``` pub OPTION_MAP_UNWRAP_OR_ELSE, pedantic, "using `Option.map(f).unwrap_or_else(g)`, which is more succinctly expressed as `map_or_else(g, f)`" } -/// **What it does:** Checks for usage of `result.map(_).unwrap_or_else(_)`. -/// -/// **Why is this bad?** Readability, this can be written more concisely as -/// `result.ok().map_or_else(_, _)`. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// x.map(|a| a + 1).unwrap_or_else(some_function) -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for usage of `result.map(_).unwrap_or_else(_)`. + /// + /// **Why is this bad?** Readability, this can be written more concisely as + /// `result.ok().map_or_else(_, _)`. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// x.map(|a| a + 1).unwrap_or_else(some_function) + /// ``` pub RESULT_MAP_UNWRAP_OR_ELSE, pedantic, "using `Result.map(f).unwrap_or_else(g)`, which is more succinctly expressed as `.ok().map_or_else(g, f)`" } -/// **What it does:** Checks for usage of `_.map_or(None, _)`. -/// -/// **Why is this bad?** Readability, this can be written more concisely as -/// `_.and_then(_)`. -/// -/// **Known problems:** The order of the arguments is not in execution order. -/// -/// **Example:** -/// ```rust -/// opt.map_or(None, |a| a + 1) -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for usage of `_.map_or(None, _)`. + /// + /// **Why is this bad?** Readability, this can be written more concisely as + /// `_.and_then(_)`. + /// + /// **Known problems:** The order of the arguments is not in execution order. + /// + /// **Example:** + /// ```rust + /// opt.map_or(None, |a| a + 1) + /// ``` pub OPTION_MAP_OR_NONE, style, "using `Option.map_or(None, f)`, which is more succinctly expressed as `and_then(f)`" } -/// **What it does:** Checks for usage of `_.filter(_).next()`. -/// -/// **Why is this bad?** Readability, this can be written more concisely as -/// `_.find(_)`. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// iter.filter(|x| x == 0).next() -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for usage of `_.filter(_).next()`. + /// + /// **Why is this bad?** Readability, this can be written more concisely as + /// `_.find(_)`. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// iter.filter(|x| x == 0).next() + /// ``` pub FILTER_NEXT, complexity, "using `filter(p).next()`, which is more succinctly expressed as `.find(p)`" } -/// **What it does:** Checks for usage of `_.map(_).flatten(_)`, -/// -/// **Why is this bad?** Readability, this can be written more concisely as a -/// single method call. -/// -/// **Known problems:** -/// -/// **Example:** -/// ```rust -/// iter.map(|x| x.iter()).flatten() -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for usage of `_.map(_).flatten(_)`, + /// + /// **Why is this bad?** Readability, this can be written more concisely as a + /// single method call. + /// + /// **Known problems:** + /// + /// **Example:** + /// ```rust + /// iter.map(|x| x.iter()).flatten() + /// ``` pub MAP_FLATTEN, pedantic, "using combinations of `flatten` and `map` which can usually be written as a single method call" } -/// **What it does:** Checks for usage of `_.filter(_).map(_)`, -/// `_.filter(_).flat_map(_)`, `_.filter_map(_).flat_map(_)` and similar. -/// -/// **Why is this bad?** Readability, this can be written more concisely as a -/// single method call. -/// -/// **Known problems:** Often requires a condition + Option/Iterator creation -/// inside the closure. -/// -/// **Example:** -/// ```rust -/// iter.filter(|x| x == 0).map(|x| x * 2) -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for usage of `_.filter(_).map(_)`, + /// `_.filter(_).flat_map(_)`, `_.filter_map(_).flat_map(_)` and similar. + /// + /// **Why is this bad?** Readability, this can be written more concisely as a + /// single method call. + /// + /// **Known problems:** Often requires a condition + Option/Iterator creation + /// inside the closure. + /// + /// **Example:** + /// ```rust + /// iter.filter(|x| x == 0).map(|x| x * 2) + /// ``` pub FILTER_MAP, pedantic, "using combinations of `filter`, `map`, `filter_map` and `flat_map` which can usually be written as a single method call" } -/// **What it does:** Checks for an iterator search (such as `find()`, -/// `position()`, or `rposition()`) followed by a call to `is_some()`. -/// -/// **Why is this bad?** Readability, this can be written more concisely as -/// `_.any(_)`. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// iter.find(|x| x == 0).is_some() -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for an iterator search (such as `find()`, + /// `position()`, or `rposition()`) followed by a call to `is_some()`. + /// + /// **Why is this bad?** Readability, this can be written more concisely as + /// `_.any(_)`. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// iter.find(|x| x == 0).is_some() + /// ``` pub SEARCH_IS_SOME, complexity, "using an iterator search followed by `is_some()`, which is more succinctly expressed as a call to `any()`" } -/// **What it does:** Checks for usage of `.chars().next()` on a `str` to check -/// if it starts with a given char. -/// -/// **Why is this bad?** Readability, this can be written more concisely as -/// `_.starts_with(_)`. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// name.chars().next() == Some('_') -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for usage of `.chars().next()` on a `str` to check + /// if it starts with a given char. + /// + /// **Why is this bad?** Readability, this can be written more concisely as + /// `_.starts_with(_)`. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// name.chars().next() == Some('_') + /// ``` pub CHARS_NEXT_CMP, complexity, "using `.chars().next()` to check if a string starts with a char" } -/// **What it does:** Checks for calls to `.or(foo(..))`, `.unwrap_or(foo(..))`, -/// etc., and suggests to use `or_else`, `unwrap_or_else`, etc., or -/// `unwrap_or_default` instead. -/// -/// **Why is this bad?** The function will always be called and potentially -/// allocate an object acting as the default. -/// -/// **Known problems:** If the function has side-effects, not calling it will -/// change the semantic of the program, but you shouldn't rely on that anyway. -/// -/// **Example:** -/// ```rust -/// foo.unwrap_or(String::new()) -/// ``` -/// this can instead be written: -/// ```rust -/// foo.unwrap_or_else(String::new) -/// ``` -/// or -/// ```rust -/// foo.unwrap_or_default() -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for calls to `.or(foo(..))`, `.unwrap_or(foo(..))`, + /// etc., and suggests to use `or_else`, `unwrap_or_else`, etc., or + /// `unwrap_or_default` instead. + /// + /// **Why is this bad?** The function will always be called and potentially + /// allocate an object acting as the default. + /// + /// **Known problems:** If the function has side-effects, not calling it will + /// change the semantic of the program, but you shouldn't rely on that anyway. + /// + /// **Example:** + /// ```rust + /// foo.unwrap_or(String::new()) + /// ``` + /// this can instead be written: + /// ```rust + /// foo.unwrap_or_else(String::new) + /// ``` + /// or + /// ```rust + /// foo.unwrap_or_default() + /// ``` pub OR_FUN_CALL, perf, "using any `*or` method with a function call, which suggests `*or_else`" } -/// **What it does:** Checks for calls to `.expect(&format!(...))`, `.expect(foo(..))`, -/// etc., and suggests to use `unwrap_or_else` instead -/// -/// **Why is this bad?** The function will always be called. -/// -/// **Known problems:** If the function has side-effects, not calling it will -/// change the semantic of the program, but you shouldn't rely on that anyway. -/// -/// **Example:** -/// ```rust -/// foo.expect(&format!("Err {}: {}", err_code, err_msg)) -/// ``` -/// or -/// ```rust -/// foo.expect(format!("Err {}: {}", err_code, err_msg).as_str()) -/// ``` -/// this can instead be written: -/// ```rust -/// foo.unwrap_or_else(|_| panic!("Err {}: {}", err_code, err_msg)) -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for calls to `.expect(&format!(...))`, `.expect(foo(..))`, + /// etc., and suggests to use `unwrap_or_else` instead + /// + /// **Why is this bad?** The function will always be called. + /// + /// **Known problems:** If the function has side-effects, not calling it will + /// change the semantic of the program, but you shouldn't rely on that anyway. + /// + /// **Example:** + /// ```rust + /// foo.expect(&format!("Err {}: {}", err_code, err_msg)) + /// ``` + /// or + /// ```rust + /// foo.expect(format!("Err {}: {}", err_code, err_msg).as_str()) + /// ``` + /// this can instead be written: + /// ```rust + /// foo.unwrap_or_else(|_| panic!("Err {}: {}", err_code, err_msg)) + /// ``` pub EXPECT_FUN_CALL, perf, "using any `expect` method with a function call" } -/// **What it does:** Checks for usage of `.clone()` on a `Copy` type. -/// -/// **Why is this bad?** The only reason `Copy` types implement `Clone` is for -/// generics, not for using the `clone` method on a concrete type. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// 42u64.clone() -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for usage of `.clone()` on a `Copy` type. + /// + /// **Why is this bad?** The only reason `Copy` types implement `Clone` is for + /// generics, not for using the `clone` method on a concrete type. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// 42u64.clone() + /// ``` pub CLONE_ON_COPY, complexity, "using `clone` on a `Copy` type" } -/// **What it does:** Checks for usage of `.clone()` on a ref-counted pointer, -/// (`Rc`, `Arc`, `rc::Weak`, or `sync::Weak`), and suggests calling Clone via unified -/// function syntax instead (e.g. `Rc::clone(foo)`). -/// -/// **Why is this bad?** Calling '.clone()' on an Rc, Arc, or Weak -/// can obscure the fact that only the pointer is being cloned, not the underlying -/// data. -/// -/// **Example:** -/// ```rust -/// x.clone() -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for usage of `.clone()` on a ref-counted pointer, + /// (`Rc`, `Arc`, `rc::Weak`, or `sync::Weak`), and suggests calling Clone via unified + /// function syntax instead (e.g. `Rc::clone(foo)`). + /// + /// **Why is this bad?** Calling '.clone()' on an Rc, Arc, or Weak + /// can obscure the fact that only the pointer is being cloned, not the underlying + /// data. + /// + /// **Example:** + /// ```rust + /// x.clone() + /// ``` pub CLONE_ON_REF_PTR, restriction, "using 'clone' on a ref-counted pointer" } -/// **What it does:** Checks for usage of `.clone()` on an `&&T`. -/// -/// **Why is this bad?** Cloning an `&&T` copies the inner `&T`, instead of -/// cloning the underlying `T`. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// fn main() { -/// let x = vec![1]; -/// let y = &&x; -/// let z = y.clone(); -/// println!("{:p} {:p}", *y, z); // prints out the same pointer -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for usage of `.clone()` on an `&&T`. + /// + /// **Why is this bad?** Cloning an `&&T` copies the inner `&T`, instead of + /// cloning the underlying `T`. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// fn main() { + /// let x = vec![1]; + /// let y = &&x; + /// let z = y.clone(); + /// println!("{:p} {:p}", *y, z); // prints out the same pointer + /// } + /// ``` pub CLONE_DOUBLE_REF, correctness, "using `clone` on `&&T`" } -/// **What it does:** Checks for `new` not returning `Self`. -/// -/// **Why is this bad?** As a convention, `new` methods are used to make a new -/// instance of a type. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// impl Foo { -/// fn new(..) -> NotAFoo { -/// } -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for `new` not returning `Self`. + /// + /// **Why is this bad?** As a convention, `new` methods are used to make a new + /// instance of a type. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// impl Foo { + /// fn new(..) -> NotAFoo { + /// } + /// } + /// ``` pub NEW_RET_NO_SELF, style, "not returning `Self` in a `new` method" } -/// **What it does:** Checks for string methods that receive a single-character -/// `str` as an argument, e.g. `_.split("x")`. -/// -/// **Why is this bad?** Performing these methods using a `char` is faster than -/// using a `str`. -/// -/// **Known problems:** Does not catch multi-byte unicode characters. -/// -/// **Example:** -/// `_.split("x")` could be `_.split('x')` declare_clippy_lint! { + /// **What it does:** Checks for string methods that receive a single-character + /// `str` as an argument, e.g. `_.split("x")`. + /// + /// **Why is this bad?** Performing these methods using a `char` is faster than + /// using a `str`. + /// + /// **Known problems:** Does not catch multi-byte unicode characters. + /// + /// **Example:** + /// `_.split("x")` could be `_.split('x')` pub SINGLE_CHAR_PATTERN, perf, "using a single-character str where a char could be used, e.g. `_.split(\"x\")`" } -/// **What it does:** Checks for getting the inner pointer of a temporary -/// `CString`. -/// -/// **Why is this bad?** The inner pointer of a `CString` is only valid as long -/// as the `CString` is alive. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust,ignore -/// let c_str = CString::new("foo").unwrap().as_ptr(); -/// unsafe { -/// call_some_ffi_func(c_str); -/// } -/// ``` -/// Here `c_str` point to a freed address. The correct use would be: -/// ```rust,ignore -/// let c_str = CString::new("foo").unwrap(); -/// unsafe { -/// call_some_ffi_func(c_str.as_ptr()); -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for getting the inner pointer of a temporary + /// `CString`. + /// + /// **Why is this bad?** The inner pointer of a `CString` is only valid as long + /// as the `CString` is alive. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust,ignore + /// let c_str = CString::new("foo").unwrap().as_ptr(); + /// unsafe { + /// call_some_ffi_func(c_str); + /// } + /// ``` + /// Here `c_str` point to a freed address. The correct use would be: + /// ```rust,ignore + /// let c_str = CString::new("foo").unwrap(); + /// unsafe { + /// call_some_ffi_func(c_str.as_ptr()); + /// } + /// ``` pub TEMPORARY_CSTRING_AS_PTR, correctness, "getting the inner pointer of a temporary `CString`" } -/// **What it does:** Checks for use of `.iter().nth()` (and the related -/// `.iter_mut().nth()`) on standard library types with O(1) element access. -/// -/// **Why is this bad?** `.get()` and `.get_mut()` are more efficient and more -/// readable. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// let some_vec = vec![0, 1, 2, 3]; -/// let bad_vec = some_vec.iter().nth(3); -/// let bad_slice = &some_vec[..].iter().nth(3); -/// ``` -/// The correct use would be: -/// ```rust -/// let some_vec = vec![0, 1, 2, 3]; -/// let bad_vec = some_vec.get(3); -/// let bad_slice = &some_vec[..].get(3); -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for use of `.iter().nth()` (and the related + /// `.iter_mut().nth()`) on standard library types with O(1) element access. + /// + /// **Why is this bad?** `.get()` and `.get_mut()` are more efficient and more + /// readable. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// let some_vec = vec![0, 1, 2, 3]; + /// let bad_vec = some_vec.iter().nth(3); + /// let bad_slice = &some_vec[..].iter().nth(3); + /// ``` + /// The correct use would be: + /// ```rust + /// let some_vec = vec![0, 1, 2, 3]; + /// let bad_vec = some_vec.get(3); + /// let bad_slice = &some_vec[..].get(3); + /// ``` pub ITER_NTH, perf, "using `.iter().nth()` on a standard library type with O(1) element access" } -/// **What it does:** Checks for use of `.skip(x).next()` on iterators. -/// -/// **Why is this bad?** `.nth(x)` is cleaner -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// let some_vec = vec![0, 1, 2, 3]; -/// let bad_vec = some_vec.iter().skip(3).next(); -/// let bad_slice = &some_vec[..].iter().skip(3).next(); -/// ``` -/// The correct use would be: -/// ```rust -/// let some_vec = vec![0, 1, 2, 3]; -/// let bad_vec = some_vec.iter().nth(3); -/// let bad_slice = &some_vec[..].iter().nth(3); -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for use of `.skip(x).next()` on iterators. + /// + /// **Why is this bad?** `.nth(x)` is cleaner + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// let some_vec = vec![0, 1, 2, 3]; + /// let bad_vec = some_vec.iter().skip(3).next(); + /// let bad_slice = &some_vec[..].iter().skip(3).next(); + /// ``` + /// The correct use would be: + /// ```rust + /// let some_vec = vec![0, 1, 2, 3]; + /// let bad_vec = some_vec.iter().nth(3); + /// let bad_slice = &some_vec[..].iter().nth(3); + /// ``` pub ITER_SKIP_NEXT, style, "using `.skip(x).next()` on an iterator" } -/// **What it does:** Checks for use of `.get().unwrap()` (or -/// `.get_mut().unwrap`) on a standard library type which implements `Index` -/// -/// **Why is this bad?** Using the Index trait (`[]`) is more clear and more -/// concise. -/// -/// **Known problems:** Not a replacement for error handling: Using either -/// `.unwrap()` or the Index trait (`[]`) carries the risk of causing a `panic` -/// if the value being accessed is `None`. If the use of `.get().unwrap()` is a -/// temporary placeholder for dealing with the `Option` type, then this does -/// not mitigate the need for error handling. If there is a chance that `.get()` -/// will be `None` in your program, then it is advisable that the `None` case -/// is handled in a future refactor instead of using `.unwrap()` or the Index -/// trait. -/// -/// **Example:** -/// ```rust -/// let some_vec = vec![0, 1, 2, 3]; -/// let last = some_vec.get(3).unwrap(); -/// *some_vec.get_mut(0).unwrap() = 1; -/// ``` -/// The correct use would be: -/// ```rust -/// let some_vec = vec![0, 1, 2, 3]; -/// let last = some_vec[3]; -/// some_vec[0] = 1; -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for use of `.get().unwrap()` (or + /// `.get_mut().unwrap`) on a standard library type which implements `Index` + /// + /// **Why is this bad?** Using the Index trait (`[]`) is more clear and more + /// concise. + /// + /// **Known problems:** Not a replacement for error handling: Using either + /// `.unwrap()` or the Index trait (`[]`) carries the risk of causing a `panic` + /// if the value being accessed is `None`. If the use of `.get().unwrap()` is a + /// temporary placeholder for dealing with the `Option` type, then this does + /// not mitigate the need for error handling. If there is a chance that `.get()` + /// will be `None` in your program, then it is advisable that the `None` case + /// is handled in a future refactor instead of using `.unwrap()` or the Index + /// trait. + /// + /// **Example:** + /// ```rust + /// let some_vec = vec![0, 1, 2, 3]; + /// let last = some_vec.get(3).unwrap(); + /// *some_vec.get_mut(0).unwrap() = 1; + /// ``` + /// The correct use would be: + /// ```rust + /// let some_vec = vec![0, 1, 2, 3]; + /// let last = some_vec[3]; + /// some_vec[0] = 1; + /// ``` pub GET_UNWRAP, style, "using `.get().unwrap()` or `.get_mut().unwrap()` when using `[]` would work instead" } -/// **What it does:** Checks for the use of `.extend(s.chars())` where s is a -/// `&str` or `String`. -/// -/// **Why is this bad?** `.push_str(s)` is clearer -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// let abc = "abc"; -/// let def = String::from("def"); -/// let mut s = String::new(); -/// s.extend(abc.chars()); -/// s.extend(def.chars()); -/// ``` -/// The correct use would be: -/// ```rust -/// let abc = "abc"; -/// let def = String::from("def"); -/// let mut s = String::new(); -/// s.push_str(abc); -/// s.push_str(&def)); -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for the use of `.extend(s.chars())` where s is a + /// `&str` or `String`. + /// + /// **Why is this bad?** `.push_str(s)` is clearer + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// let abc = "abc"; + /// let def = String::from("def"); + /// let mut s = String::new(); + /// s.extend(abc.chars()); + /// s.extend(def.chars()); + /// ``` + /// The correct use would be: + /// ```rust + /// let abc = "abc"; + /// let def = String::from("def"); + /// let mut s = String::new(); + /// s.push_str(abc); + /// s.push_str(&def)); + /// ``` pub STRING_EXTEND_CHARS, style, "using `x.extend(s.chars())` where s is a `&str` or `String`" } -/// **What it does:** Checks for the use of `.cloned().collect()` on slice to -/// create a `Vec`. -/// -/// **Why is this bad?** `.to_vec()` is clearer -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// let s = [1, 2, 3, 4, 5]; -/// let s2: Vec = s[..].iter().cloned().collect(); -/// ``` -/// The better use would be: -/// ```rust -/// let s = [1, 2, 3, 4, 5]; -/// let s2: Vec = s.to_vec(); -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for the use of `.cloned().collect()` on slice to + /// create a `Vec`. + /// + /// **Why is this bad?** `.to_vec()` is clearer + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// let s = [1, 2, 3, 4, 5]; + /// let s2: Vec = s[..].iter().cloned().collect(); + /// ``` + /// The better use would be: + /// ```rust + /// let s = [1, 2, 3, 4, 5]; + /// let s2: Vec = s.to_vec(); + /// ``` pub ITER_CLONED_COLLECT, style, "using `.cloned().collect()` on slice to create a `Vec`" } -/// **What it does:** Checks for usage of `.chars().last()` or -/// `.chars().next_back()` on a `str` to check if it ends with a given char. -/// -/// **Why is this bad?** Readability, this can be written more concisely as -/// `_.ends_with(_)`. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// name.chars().last() == Some('_') || name.chars().next_back() == Some('-') -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for usage of `.chars().last()` or + /// `.chars().next_back()` on a `str` to check if it ends with a given char. + /// + /// **Why is this bad?** Readability, this can be written more concisely as + /// `_.ends_with(_)`. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// name.chars().last() == Some('_') || name.chars().next_back() == Some('-') + /// ``` pub CHARS_LAST_CMP, style, "using `.chars().last()` or `.chars().next_back()` to check if a string ends with a char" } -/// **What it does:** Checks for usage of `.as_ref()` or `.as_mut()` where the -/// types before and after the call are the same. -/// -/// **Why is this bad?** The call is unnecessary. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// let x: &[i32] = &[1, 2, 3, 4, 5]; -/// do_stuff(x.as_ref()); -/// ``` -/// The correct use would be: -/// ```rust -/// let x: &[i32] = &[1, 2, 3, 4, 5]; -/// do_stuff(x); -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for usage of `.as_ref()` or `.as_mut()` where the + /// types before and after the call are the same. + /// + /// **Why is this bad?** The call is unnecessary. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// let x: &[i32] = &[1, 2, 3, 4, 5]; + /// do_stuff(x.as_ref()); + /// ``` + /// The correct use would be: + /// ```rust + /// let x: &[i32] = &[1, 2, 3, 4, 5]; + /// do_stuff(x); + /// ``` pub USELESS_ASREF, complexity, "using `as_ref` where the types before and after the call are the same" } -/// **What it does:** Checks for using `fold` when a more succinct alternative exists. -/// Specifically, this checks for `fold`s which could be replaced by `any`, `all`, -/// `sum` or `product`. -/// -/// **Why is this bad?** Readability. -/// -/// **Known problems:** False positive in pattern guards. Will be resolved once -/// non-lexical lifetimes are stable. -/// -/// **Example:** -/// ```rust -/// let _ = (0..3).fold(false, |acc, x| acc || x > 2); -/// ``` -/// This could be written as: -/// ```rust -/// let _ = (0..3).any(|x| x > 2); -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for using `fold` when a more succinct alternative exists. + /// Specifically, this checks for `fold`s which could be replaced by `any`, `all`, + /// `sum` or `product`. + /// + /// **Why is this bad?** Readability. + /// + /// **Known problems:** False positive in pattern guards. Will be resolved once + /// non-lexical lifetimes are stable. + /// + /// **Example:** + /// ```rust + /// let _ = (0..3).fold(false, |acc, x| acc || x > 2); + /// ``` + /// This could be written as: + /// ```rust + /// let _ = (0..3).any(|x| x > 2); + /// ``` pub UNNECESSARY_FOLD, style, "using `fold` when a more succinct alternative exists" } -/// **What it does:** Checks for `filter_map` calls which could be replaced by `filter` or `map`. -/// More specifically it checks if the closure provided is only performing one of the -/// filter or map operations and suggests the appropriate option. -/// -/// **Why is this bad?** Complexity. The intent is also clearer if only a single -/// operation is being performed. -/// -/// **Known problems:** None -/// -/// **Example:** -/// ```rust -/// let _ = (0..3).filter_map(|x| if x > 2 { Some(x) } else { None }); -/// ``` -/// As there is no transformation of the argument this could be written as: -/// ```rust -/// let _ = (0..3).filter(|&x| x > 2); -/// ``` -/// -/// ```rust -/// let _ = (0..4).filter_map(i32::checked_abs); -/// ``` -/// As there is no conditional check on the argument this could be written as: -/// ```rust -/// let _ = (0..4).map(i32::checked_abs); -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for `filter_map` calls which could be replaced by `filter` or `map`. + /// More specifically it checks if the closure provided is only performing one of the + /// filter or map operations and suggests the appropriate option. + /// + /// **Why is this bad?** Complexity. The intent is also clearer if only a single + /// operation is being performed. + /// + /// **Known problems:** None + /// + /// **Example:** + /// ```rust + /// let _ = (0..3).filter_map(|x| if x > 2 { Some(x) } else { None }); + /// ``` + /// As there is no transformation of the argument this could be written as: + /// ```rust + /// let _ = (0..3).filter(|&x| x > 2); + /// ``` + /// + /// ```rust + /// let _ = (0..4).filter_map(i32::checked_abs); + /// ``` + /// As there is no conditional check on the argument this could be written as: + /// ```rust + /// let _ = (0..4).map(i32::checked_abs); + /// ``` pub UNNECESSARY_FILTER_MAP, complexity, "using `filter_map` when a more succinct alternative exists" } -/// **What it does:** Checks for `into_iter` calls on types which should be replaced by `iter` or -/// `iter_mut`. -/// -/// **Why is this bad?** Arrays and `PathBuf` do not yet have an `into_iter` method which move out -/// their content into an iterator. Auto-referencing resolves the `into_iter` call to its reference -/// instead, like `<&[T; N] as IntoIterator>::into_iter`, which just iterates over item references -/// like calling `iter` would. Furthermore, when the standard library actually -/// [implements the `into_iter` method][25725] which moves the content out of the array, the -/// original use of `into_iter` got inferred with the wrong type and the code will be broken. -/// -/// **Known problems:** None -/// -/// **Example:** -/// -/// ```rust -/// let _ = [1, 2, 3].into_iter().map(|x| *x).collect::>(); -/// ``` -/// -/// [25725]: https://github.com/rust-lang/rust/issues/25725 declare_clippy_lint! { + /// **What it does:** Checks for `into_iter` calls on types which should be replaced by `iter` or + /// `iter_mut`. + /// + /// **Why is this bad?** Arrays and `PathBuf` do not yet have an `into_iter` method which move out + /// their content into an iterator. Auto-referencing resolves the `into_iter` call to its reference + /// instead, like `<&[T; N] as IntoIterator>::into_iter`, which just iterates over item references + /// like calling `iter` would. Furthermore, when the standard library actually + /// [implements the `into_iter` method][25725] which moves the content out of the array, the + /// original use of `into_iter` got inferred with the wrong type and the code will be broken. + /// + /// **Known problems:** None + /// + /// **Example:** + /// + /// ```rust + /// let _ = [1, 2, 3].into_iter().map(|x| *x).collect::>(); + /// ``` + /// + /// [25725]: https://github.com/rust-lang/rust/issues/25725 pub INTO_ITER_ON_ARRAY, correctness, "using `.into_iter()` on an array" } -/// **What it does:** Checks for `into_iter` calls on references which should be replaced by `iter` -/// or `iter_mut`. -/// -/// **Why is this bad?** Readability. Calling `into_iter` on a reference will not move out its -/// content into the resulting iterator, which is confusing. It is better just call `iter` or -/// `iter_mut` directly. -/// -/// **Known problems:** None -/// -/// **Example:** -/// -/// ```rust -/// let _ = (&vec![3, 4, 5]).into_iter(); -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for `into_iter` calls on references which should be replaced by `iter` + /// or `iter_mut`. + /// + /// **Why is this bad?** Readability. Calling `into_iter` on a reference will not move out its + /// content into the resulting iterator, which is confusing. It is better just call `iter` or + /// `iter_mut` directly. + /// + /// **Known problems:** None + /// + /// **Example:** + /// + /// ```rust + /// let _ = (&vec![3, 4, 5]).into_iter(); + /// ``` pub INTO_ITER_ON_REF, style, "using `.into_iter()` on a reference" diff --git a/clippy_lints/src/minmax.rs b/clippy_lints/src/minmax.rs index 19bede8a2806..22bc25094bea 100644 --- a/clippy_lints/src/minmax.rs +++ b/clippy_lints/src/minmax.rs @@ -5,21 +5,21 @@ use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use rustc::{declare_tool_lint, lint_array}; use std::cmp::Ordering; -/// **What it does:** Checks for expressions where `std::cmp::min` and `max` are -/// used to clamp values, but switched so that the result is constant. -/// -/// **Why is this bad?** This is in all probability not the intended outcome. At -/// the least it hurts readability of the code. -/// -/// **Known problems:** None -/// -/// **Example:** -/// ```rust -/// min(0, max(100, x)) -/// ``` -/// It will always be equal to `0`. Probably the author meant to clamp the value -/// between 0 and 100, but has erroneously swapped `min` and `max`. declare_clippy_lint! { + /// **What it does:** Checks for expressions where `std::cmp::min` and `max` are + /// used to clamp values, but switched so that the result is constant. + /// + /// **Why is this bad?** This is in all probability not the intended outcome. At + /// the least it hurts readability of the code. + /// + /// **Known problems:** None + /// + /// **Example:** + /// ```rust + /// min(0, max(100, x)) + /// ``` + /// It will always be equal to `0`. Probably the author meant to clamp the value + /// between 0 and 100, but has erroneously swapped `min` and `max`. pub MIN_MAX, correctness, "`min(_, max(_, _))` (or vice versa) with bounds clamping the result to a constant" diff --git a/clippy_lints/src/misc.rs b/clippy_lints/src/misc.rs index 7125c77ec8e0..34e276dcc4bc 100644 --- a/clippy_lints/src/misc.rs +++ b/clippy_lints/src/misc.rs @@ -16,208 +16,208 @@ use rustc_errors::Applicability; use syntax::ast::LitKind; use syntax::source_map::{ExpnFormat, Span}; -/// **What it does:** Checks for function arguments and let bindings denoted as -/// `ref`. -/// -/// **Why is this bad?** The `ref` declaration makes the function take an owned -/// value, but turns the argument into a reference (which means that the value -/// is destroyed when exiting the function). This adds not much value: either -/// take a reference type, or take an owned value and create references in the -/// body. -/// -/// For let bindings, `let x = &foo;` is preferred over `let ref x = foo`. The -/// type of `x` is more obvious with the former. -/// -/// **Known problems:** If the argument is dereferenced within the function, -/// removing the `ref` will lead to errors. This can be fixed by removing the -/// dereferences, e.g. changing `*x` to `x` within the function. -/// -/// **Example:** -/// ```rust -/// fn foo(ref x: u8) -> bool { -/// .. -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for function arguments and let bindings denoted as + /// `ref`. + /// + /// **Why is this bad?** The `ref` declaration makes the function take an owned + /// value, but turns the argument into a reference (which means that the value + /// is destroyed when exiting the function). This adds not much value: either + /// take a reference type, or take an owned value and create references in the + /// body. + /// + /// For let bindings, `let x = &foo;` is preferred over `let ref x = foo`. The + /// type of `x` is more obvious with the former. + /// + /// **Known problems:** If the argument is dereferenced within the function, + /// removing the `ref` will lead to errors. This can be fixed by removing the + /// dereferences, e.g. changing `*x` to `x` within the function. + /// + /// **Example:** + /// ```rust + /// fn foo(ref x: u8) -> bool { + /// .. + /// } + /// ``` pub TOPLEVEL_REF_ARG, style, "an entire binding declared as `ref`, in a function argument or a `let` statement" } -/// **What it does:** Checks for comparisons to NaN. -/// -/// **Why is this bad?** NaN does not compare meaningfully to anything – not -/// even itself – so those comparisons are simply wrong. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// x == NAN -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for comparisons to NaN. + /// + /// **Why is this bad?** NaN does not compare meaningfully to anything – not + /// even itself – so those comparisons are simply wrong. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// x == NAN + /// ``` pub CMP_NAN, correctness, "comparisons to NAN, which will always return false, probably not intended" } -/// **What it does:** Checks for (in-)equality comparisons on floating-point -/// values (apart from zero), except in functions called `*eq*` (which probably -/// implement equality for a type involving floats). -/// -/// **Why is this bad?** Floating point calculations are usually imprecise, so -/// asking if two values are *exactly* equal is asking for trouble. For a good -/// guide on what to do, see [the floating point -/// guide](http://www.floating-point-gui.de/errors/comparison). -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// y == 1.23f64 -/// y != x // where both are floats -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for (in-)equality comparisons on floating-point + /// values (apart from zero), except in functions called `*eq*` (which probably + /// implement equality for a type involving floats). + /// + /// **Why is this bad?** Floating point calculations are usually imprecise, so + /// asking if two values are *exactly* equal is asking for trouble. For a good + /// guide on what to do, see [the floating point + /// guide](http://www.floating-point-gui.de/errors/comparison). + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// y == 1.23f64 + /// y != x // where both are floats + /// ``` pub FLOAT_CMP, correctness, "using `==` or `!=` on float values instead of comparing difference with an epsilon" } -/// **What it does:** Checks for conversions to owned values just for the sake -/// of a comparison. -/// -/// **Why is this bad?** The comparison can operate on a reference, so creating -/// an owned value effectively throws it away directly afterwards, which is -/// needlessly consuming code and heap space. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// x.to_owned() == y -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for conversions to owned values just for the sake + /// of a comparison. + /// + /// **Why is this bad?** The comparison can operate on a reference, so creating + /// an owned value effectively throws it away directly afterwards, which is + /// needlessly consuming code and heap space. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// x.to_owned() == y + /// ``` pub CMP_OWNED, perf, "creating owned instances for comparing with others, e.g. `x == \"foo\".to_string()`" } -/// **What it does:** Checks for getting the remainder of a division by one. -/// -/// **Why is this bad?** The result can only ever be zero. No one will write -/// such code deliberately, unless trying to win an Underhanded Rust -/// Contest. Even for that contest, it's probably a bad idea. Use something more -/// underhanded. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// x % 1 -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for getting the remainder of a division by one. + /// + /// **Why is this bad?** The result can only ever be zero. No one will write + /// such code deliberately, unless trying to win an Underhanded Rust + /// Contest. Even for that contest, it's probably a bad idea. Use something more + /// underhanded. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// x % 1 + /// ``` pub MODULO_ONE, correctness, "taking a number modulo 1, which always returns 0" } -/// **What it does:** Checks for patterns in the form `name @ _`. -/// -/// **Why is this bad?** It's almost always more readable to just use direct -/// bindings. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// match v { -/// Some(x) => (), -/// y @ _ => (), // easier written as `y`, -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for patterns in the form `name @ _`. + /// + /// **Why is this bad?** It's almost always more readable to just use direct + /// bindings. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// match v { + /// Some(x) => (), + /// y @ _ => (), // easier written as `y`, + /// } + /// ``` pub REDUNDANT_PATTERN, style, "using `name @ _` in a pattern" } -/// **What it does:** Checks for the use of bindings with a single leading -/// underscore. -/// -/// **Why is this bad?** A single leading underscore is usually used to indicate -/// that a binding will not be used. Using such a binding breaks this -/// expectation. -/// -/// **Known problems:** The lint does not work properly with desugaring and -/// macro, it has been allowed in the mean time. -/// -/// **Example:** -/// ```rust -/// let _x = 0; -/// let y = _x + 1; // Here we are using `_x`, even though it has a leading -/// // underscore. We should rename `_x` to `x` -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for the use of bindings with a single leading + /// underscore. + /// + /// **Why is this bad?** A single leading underscore is usually used to indicate + /// that a binding will not be used. Using such a binding breaks this + /// expectation. + /// + /// **Known problems:** The lint does not work properly with desugaring and + /// macro, it has been allowed in the mean time. + /// + /// **Example:** + /// ```rust + /// let _x = 0; + /// let y = _x + 1; // Here we are using `_x`, even though it has a leading + /// // underscore. We should rename `_x` to `x` + /// ``` pub USED_UNDERSCORE_BINDING, pedantic, "using a binding which is prefixed with an underscore" } -/// **What it does:** Checks for the use of short circuit boolean conditions as -/// a -/// statement. -/// -/// **Why is this bad?** Using a short circuit boolean condition as a statement -/// may hide the fact that the second part is executed or not depending on the -/// outcome of the first part. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// f() && g(); // We should write `if f() { g(); }`. -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for the use of short circuit boolean conditions as + /// a + /// statement. + /// + /// **Why is this bad?** Using a short circuit boolean condition as a statement + /// may hide the fact that the second part is executed or not depending on the + /// outcome of the first part. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// f() && g(); // We should write `if f() { g(); }`. + /// ``` pub SHORT_CIRCUIT_STATEMENT, complexity, "using a short circuit boolean condition as a statement" } -/// **What it does:** Catch casts from `0` to some pointer type -/// -/// **Why is this bad?** This generally means `null` and is better expressed as -/// {`std`, `core`}`::ptr::`{`null`, `null_mut`}. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// -/// ```rust -/// 0 as *const u32 -/// ``` declare_clippy_lint! { + /// **What it does:** Catch casts from `0` to some pointer type + /// + /// **Why is this bad?** This generally means `null` and is better expressed as + /// {`std`, `core`}`::ptr::`{`null`, `null_mut`}. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// + /// ```rust + /// 0 as *const u32 + /// ``` pub ZERO_PTR, style, "using 0 as *{const, mut} T" } -/// **What it does:** Checks for (in-)equality comparisons on floating-point -/// value and constant, except in functions called `*eq*` (which probably -/// implement equality for a type involving floats). -/// -/// **Why is this bad?** Floating point calculations are usually imprecise, so -/// asking if two values are *exactly* equal is asking for trouble. For a good -/// guide on what to do, see [the floating point -/// guide](http://www.floating-point-gui.de/errors/comparison). -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// const ONE = 1.00f64; -/// x == ONE // where both are floats -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for (in-)equality comparisons on floating-point + /// value and constant, except in functions called `*eq*` (which probably + /// implement equality for a type involving floats). + /// + /// **Why is this bad?** Floating point calculations are usually imprecise, so + /// asking if two values are *exactly* equal is asking for trouble. For a good + /// guide on what to do, see [the floating point + /// guide](http://www.floating-point-gui.de/errors/comparison). + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// const ONE = 1.00f64; + /// x == ONE // where both are floats + /// ``` pub FLOAT_CMP_CONST, restriction, "using `==` or `!=` on float constants instead of comparing difference with an epsilon" diff --git a/clippy_lints/src/misc_early.rs b/clippy_lints/src/misc_early.rs index 88acdbb168ab..e522326066c3 100644 --- a/clippy_lints/src/misc_early.rs +++ b/clippy_lints/src/misc_early.rs @@ -9,163 +9,163 @@ use syntax::ast::*; use syntax::source_map::Span; use syntax::visit::{walk_expr, FnKind, Visitor}; -/// **What it does:** Checks for structure field patterns bound to wildcards. -/// -/// **Why is this bad?** Using `..` instead is shorter and leaves the focus on -/// the fields that are actually bound. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// let { a: _, b: ref b, c: _ } = .. -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for structure field patterns bound to wildcards. + /// + /// **Why is this bad?** Using `..` instead is shorter and leaves the focus on + /// the fields that are actually bound. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// let { a: _, b: ref b, c: _ } = .. + /// ``` pub UNNEEDED_FIELD_PATTERN, style, "struct fields bound to a wildcard instead of using `..`" } -/// **What it does:** Checks for function arguments having the similar names -/// differing by an underscore. -/// -/// **Why is this bad?** It affects code readability. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// fn foo(a: i32, _a: i32) {} -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for function arguments having the similar names + /// differing by an underscore. + /// + /// **Why is this bad?** It affects code readability. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// fn foo(a: i32, _a: i32) {} + /// ``` pub DUPLICATE_UNDERSCORE_ARGUMENT, style, "function arguments having names which only differ by an underscore" } -/// **What it does:** Detects closures called in the same expression where they -/// are defined. -/// -/// **Why is this bad?** It is unnecessarily adding to the expression's -/// complexity. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// (|| 42)() -/// ``` declare_clippy_lint! { + /// **What it does:** Detects closures called in the same expression where they + /// are defined. + /// + /// **Why is this bad?** It is unnecessarily adding to the expression's + /// complexity. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// (|| 42)() + /// ``` pub REDUNDANT_CLOSURE_CALL, complexity, "throwaway closures called in the expression they are defined" } -/// **What it does:** Detects expressions of the form `--x`. -/// -/// **Why is this bad?** It can mislead C/C++ programmers to think `x` was -/// decremented. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// --x; -/// ``` declare_clippy_lint! { + /// **What it does:** Detects expressions of the form `--x`. + /// + /// **Why is this bad?** It can mislead C/C++ programmers to think `x` was + /// decremented. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// --x; + /// ``` pub DOUBLE_NEG, style, "`--x`, which is a double negation of `x` and not a pre-decrement as in C/C++" } -/// **What it does:** Warns on hexadecimal literals with mixed-case letter -/// digits. -/// -/// **Why is this bad?** It looks confusing. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// let y = 0x1a9BAcD; -/// ``` declare_clippy_lint! { + /// **What it does:** Warns on hexadecimal literals with mixed-case letter + /// digits. + /// + /// **Why is this bad?** It looks confusing. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// let y = 0x1a9BAcD; + /// ``` pub MIXED_CASE_HEX_LITERALS, style, "hex literals whose letter digits are not consistently upper- or lowercased" } -/// **What it does:** Warns if literal suffixes are not separated by an -/// underscore. -/// -/// **Why is this bad?** It is much less readable. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// let y = 123832i32; -/// ``` declare_clippy_lint! { + /// **What it does:** Warns if literal suffixes are not separated by an + /// underscore. + /// + /// **Why is this bad?** It is much less readable. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// let y = 123832i32; + /// ``` pub UNSEPARATED_LITERAL_SUFFIX, pedantic, "literals whose suffix is not separated by an underscore" } -/// **What it does:** Warns if an integral constant literal starts with `0`. -/// -/// **Why is this bad?** In some languages (including the infamous C language -/// and most of its -/// family), this marks an octal constant. In Rust however, this is a decimal -/// constant. This could -/// be confusing for both the writer and a reader of the constant. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// -/// In Rust: -/// ```rust -/// fn main() { -/// let a = 0123; -/// println!("{}", a); -/// } -/// ``` -/// -/// prints `123`, while in C: -/// -/// ```c -/// #include -/// -/// int main() { -/// int a = 0123; -/// printf("%d\n", a); -/// } -/// ``` -/// -/// prints `83` (as `83 == 0o123` while `123 == 0o173`). declare_clippy_lint! { + /// **What it does:** Warns if an integral constant literal starts with `0`. + /// + /// **Why is this bad?** In some languages (including the infamous C language + /// and most of its + /// family), this marks an octal constant. In Rust however, this is a decimal + /// constant. This could + /// be confusing for both the writer and a reader of the constant. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// + /// In Rust: + /// ```rust + /// fn main() { + /// let a = 0123; + /// println!("{}", a); + /// } + /// ``` + /// + /// prints `123`, while in C: + /// + /// ```c + /// #include + /// + /// int main() { + /// int a = 0123; + /// printf("%d\n", a); + /// } + /// ``` + /// + /// prints `83` (as `83 == 0o123` while `123 == 0o173`). pub ZERO_PREFIXED_LITERAL, complexity, "integer literals starting with `0`" } -/// **What it does:** Warns if a generic shadows a built-in type. -/// -/// **Why is this bad?** This gives surprising type errors. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// -/// ```rust -/// impl Foo { -/// fn impl_func(&self) -> u32 { -/// 42 -/// } -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Warns if a generic shadows a built-in type. + /// + /// **Why is this bad?** This gives surprising type errors. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// + /// ```rust + /// impl Foo { + /// fn impl_func(&self) -> u32 { + /// 42 + /// } + /// } + /// ``` pub BUILTIN_TYPE_SHADOW, style, "shadowing a builtin type" diff --git a/clippy_lints/src/missing_const_for_fn.rs b/clippy_lints/src/missing_const_for_fn.rs index 633105ff60bb..19757f32e6b4 100644 --- a/clippy_lints/src/missing_const_for_fn.rs +++ b/clippy_lints/src/missing_const_for_fn.rs @@ -8,51 +8,51 @@ use rustc::{declare_tool_lint, lint_array}; use rustc_mir::transform::qualify_min_const_fn::is_min_const_fn; use syntax_pos::Span; -/// **What it does:** -/// -/// Suggests the use of `const` in functions and methods where possible. -/// -/// **Why is this bad?** -/// -/// Not having the function const prevents callers of the function from being const as well. -/// -/// **Known problems:** -/// -/// Const functions are currently still being worked on, with some features only being available -/// on nightly. This lint does not consider all edge cases currently and the suggestions may be -/// incorrect if you are using this lint on stable. -/// -/// Also, the lint only runs one pass over the code. Consider these two non-const functions: -/// -/// ```rust -/// fn a() -> i32 { -/// 0 -/// } -/// fn b() -> i32 { -/// a() -/// } -/// ``` -/// -/// When running Clippy, the lint will only suggest to make `a` const, because `b` at this time -/// can't be const as it calls a non-const function. Making `a` const and running Clippy again, -/// will suggest to make `b` const, too. -/// -/// **Example:** -/// -/// ```rust -/// fn new() -> Self { -/// Self { random_number: 42 } -/// } -/// ``` -/// -/// Could be a const fn: -/// -/// ```rust -/// const fn new() -> Self { -/// Self { random_number: 42 } -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** + /// + /// Suggests the use of `const` in functions and methods where possible. + /// + /// **Why is this bad?** + /// + /// Not having the function const prevents callers of the function from being const as well. + /// + /// **Known problems:** + /// + /// Const functions are currently still being worked on, with some features only being available + /// on nightly. This lint does not consider all edge cases currently and the suggestions may be + /// incorrect if you are using this lint on stable. + /// + /// Also, the lint only runs one pass over the code. Consider these two non-const functions: + /// + /// ```rust + /// fn a() -> i32 { + /// 0 + /// } + /// fn b() -> i32 { + /// a() + /// } + /// ``` + /// + /// When running Clippy, the lint will only suggest to make `a` const, because `b` at this time + /// can't be const as it calls a non-const function. Making `a` const and running Clippy again, + /// will suggest to make `b` const, too. + /// + /// **Example:** + /// + /// ```rust + /// fn new() -> Self { + /// Self { random_number: 42 } + /// } + /// ``` + /// + /// Could be a const fn: + /// + /// ```rust + /// const fn new() -> Self { + /// Self { random_number: 42 } + /// } + /// ``` pub MISSING_CONST_FOR_FN, nursery, "Lint functions definitions that could be made `const fn`" diff --git a/clippy_lints/src/missing_doc.rs b/clippy_lints/src/missing_doc.rs index 8c5c1f65280f..d7e4dd221232 100644 --- a/clippy_lints/src/missing_doc.rs +++ b/clippy_lints/src/missing_doc.rs @@ -14,16 +14,16 @@ use syntax::ast; use syntax::attr; use syntax::source_map::Span; -/// **What it does:** Warns if there is missing doc for any documentable item -/// (public or private). -/// -/// **Why is this bad?** Doc is good. *rustc* has a `MISSING_DOCS` -/// allowed-by-default lint for -/// public members, but has no way to enforce documentation of private items. -/// This lint fixes that. -/// -/// **Known problems:** None. declare_clippy_lint! { + /// **What it does:** Warns if there is missing doc for any documentable item + /// (public or private). + /// + /// **Why is this bad?** Doc is good. *rustc* has a `MISSING_DOCS` + /// allowed-by-default lint for + /// public members, but has no way to enforce documentation of private items. + /// This lint fixes that. + /// + /// **Known problems:** None. pub MISSING_DOCS_IN_PRIVATE_ITEMS, restriction, "detects missing documentation for public and private members" diff --git a/clippy_lints/src/missing_inline.rs b/clippy_lints/src/missing_inline.rs index 2a7a211f26cb..82c5b62145b6 100644 --- a/clippy_lints/src/missing_inline.rs +++ b/clippy_lints/src/missing_inline.rs @@ -5,52 +5,52 @@ use rustc::{declare_tool_lint, lint_array}; use syntax::ast; use syntax::source_map::Span; -/// **What it does:** it lints if an exported function, method, trait method with default impl, -/// or trait method impl is not `#[inline]`. -/// -/// **Why is this bad?** In general, it is not. Functions can be inlined across -/// crates when that's profitable as long as any form of LTO is used. When LTO is disabled, -/// functions that are not `#[inline]` cannot be inlined across crates. Certain types of crates -/// might intend for most of the methods in their public API to be able to be inlined across -/// crates even when LTO is disabled. For these types of crates, enabling this lint might make -/// sense. It allows the crate to require all exported methods to be `#[inline]` by default, and -/// then opt out for specific methods where this might not make sense. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// pub fn foo() {} // missing #[inline] -/// fn ok() {} // ok -/// #[inline] pub fn bar() {} // ok -/// #[inline(always)] pub fn baz() {} // ok -/// -/// pub trait Bar { -/// fn bar(); // ok -/// fn def_bar() {} // missing #[inline] -/// } -/// -/// struct Baz; -/// impl Baz { -/// fn priv() {} // ok -/// } -/// -/// impl Bar for Baz { -/// fn bar() {} // ok - Baz is not exported -/// } -/// -/// pub struct PubBaz; -/// impl PubBaz { -/// fn priv() {} // ok -/// pub not_ptriv() {} // missing #[inline] -/// } -/// -/// impl Bar for PubBaz { -/// fn bar() {} // missing #[inline] -/// fn def_bar() {} // missing #[inline] -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** it lints if an exported function, method, trait method with default impl, + /// or trait method impl is not `#[inline]`. + /// + /// **Why is this bad?** In general, it is not. Functions can be inlined across + /// crates when that's profitable as long as any form of LTO is used. When LTO is disabled, + /// functions that are not `#[inline]` cannot be inlined across crates. Certain types of crates + /// might intend for most of the methods in their public API to be able to be inlined across + /// crates even when LTO is disabled. For these types of crates, enabling this lint might make + /// sense. It allows the crate to require all exported methods to be `#[inline]` by default, and + /// then opt out for specific methods where this might not make sense. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// pub fn foo() {} // missing #[inline] + /// fn ok() {} // ok + /// #[inline] pub fn bar() {} // ok + /// #[inline(always)] pub fn baz() {} // ok + /// + /// pub trait Bar { + /// fn bar(); // ok + /// fn def_bar() {} // missing #[inline] + /// } + /// + /// struct Baz; + /// impl Baz { + /// fn priv() {} // ok + /// } + /// + /// impl Bar for Baz { + /// fn bar() {} // ok - Baz is not exported + /// } + /// + /// pub struct PubBaz; + /// impl PubBaz { + /// fn priv() {} // ok + /// pub not_ptriv() {} // missing #[inline] + /// } + /// + /// impl Bar for PubBaz { + /// fn bar() {} // missing #[inline] + /// fn def_bar() {} // missing #[inline] + /// } + /// ``` pub MISSING_INLINE_IN_PUBLIC_ITEMS, restriction, "detects missing #[inline] attribute for public callables (functions, trait methods, methods...)" diff --git a/clippy_lints/src/multiple_crate_versions.rs b/clippy_lints/src/multiple_crate_versions.rs index f772fa2b21c8..68293f58cadd 100644 --- a/clippy_lints/src/multiple_crate_versions.rs +++ b/clippy_lints/src/multiple_crate_versions.rs @@ -8,24 +8,24 @@ use syntax::{ast::*, source_map::DUMMY_SP}; use cargo_metadata; use itertools::Itertools; -/// **What it does:** Checks to see if multiple versions of a crate are being -/// used. -/// -/// **Why is this bad?** This bloats the size of targets, and can lead to -/// confusing error messages when structs or traits are used interchangeably -/// between different versions of a crate. -/// -/// **Known problems:** Because this can be caused purely by the dependencies -/// themselves, it's not always possible to fix this issue. -/// -/// **Example:** -/// ```toml -/// # This will pull in both winapi v0.3.4 and v0.2.8, triggering a warning. -/// [dependencies] -/// ctrlc = "3.1.0" -/// ansi_term = "0.11.0" -/// ``` declare_clippy_lint! { + /// **What it does:** Checks to see if multiple versions of a crate are being + /// used. + /// + /// **Why is this bad?** This bloats the size of targets, and can lead to + /// confusing error messages when structs or traits are used interchangeably + /// between different versions of a crate. + /// + /// **Known problems:** Because this can be caused purely by the dependencies + /// themselves, it's not always possible to fix this issue. + /// + /// **Example:** + /// ```toml + /// # This will pull in both winapi v0.3.4 and v0.2.8, triggering a warning. + /// [dependencies] + /// ctrlc = "3.1.0" + /// ansi_term = "0.11.0" + /// ``` pub MULTIPLE_CRATE_VERSIONS, cargo, "multiple versions of the same crate being used" diff --git a/clippy_lints/src/mut_mut.rs b/clippy_lints/src/mut_mut.rs index b244c7f30315..41b5f6f38331 100644 --- a/clippy_lints/src/mut_mut.rs +++ b/clippy_lints/src/mut_mut.rs @@ -5,19 +5,19 @@ use rustc::lint::{in_external_macro, LateContext, LateLintPass, LintArray, LintC use rustc::ty; use rustc::{declare_tool_lint, lint_array}; -/// **What it does:** Checks for instances of `mut mut` references. -/// -/// **Why is this bad?** Multiple `mut`s don't add anything meaningful to the -/// source. This is either a copy'n'paste error, or it shows a fundamental -/// misunderstanding of references. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// let x = &mut &mut y; -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for instances of `mut mut` references. + /// + /// **Why is this bad?** Multiple `mut`s don't add anything meaningful to the + /// source. This is either a copy'n'paste error, or it shows a fundamental + /// misunderstanding of references. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// let x = &mut &mut y; + /// ``` pub MUT_MUT, pedantic, "usage of double-mut refs, e.g. `&mut &mut ...`" diff --git a/clippy_lints/src/mut_reference.rs b/clippy_lints/src/mut_reference.rs index 716abbe31fef..69f41e23508d 100644 --- a/clippy_lints/src/mut_reference.rs +++ b/clippy_lints/src/mut_reference.rs @@ -5,19 +5,19 @@ use rustc::ty::subst::Subst; use rustc::ty::{self, Ty}; use rustc::{declare_tool_lint, lint_array}; -/// **What it does:** Detects giving a mutable reference to a function that only -/// requires an immutable reference. -/// -/// **Why is this bad?** The immutable reference rules out all other references -/// to the value. Also the code misleads about the intent of the call site. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// my_vec.push(&mut value) -/// ``` declare_clippy_lint! { + /// **What it does:** Detects giving a mutable reference to a function that only + /// requires an immutable reference. + /// + /// **Why is this bad?** The immutable reference rules out all other references + /// to the value. Also the code misleads about the intent of the call site. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// my_vec.push(&mut value) + /// ``` pub UNNECESSARY_MUT_PASSED, style, "an argument passed as a mutable reference although the callee only demands an immutable reference" diff --git a/clippy_lints/src/mutex_atomic.rs b/clippy_lints/src/mutex_atomic.rs index fa0e8288b307..6800e4295f57 100644 --- a/clippy_lints/src/mutex_atomic.rs +++ b/clippy_lints/src/mutex_atomic.rs @@ -9,41 +9,41 @@ use rustc::ty::{self, Ty}; use rustc::{declare_tool_lint, lint_array}; use syntax::ast; -/// **What it does:** Checks for usages of `Mutex` where an atomic will do. -/// -/// **Why is this bad?** Using a mutex just to make access to a plain bool or -/// reference sequential is shooting flies with cannons. -/// `std::sync::atomic::AtomicBool` and `std::sync::atomic::AtomicPtr` are leaner and -/// faster. -/// -/// **Known problems:** This lint cannot detect if the mutex is actually used -/// for waiting before a critical section. -/// -/// **Example:** -/// ```rust -/// let x = Mutex::new(&y); -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for usages of `Mutex` where an atomic will do. + /// + /// **Why is this bad?** Using a mutex just to make access to a plain bool or + /// reference sequential is shooting flies with cannons. + /// `std::sync::atomic::AtomicBool` and `std::sync::atomic::AtomicPtr` are leaner and + /// faster. + /// + /// **Known problems:** This lint cannot detect if the mutex is actually used + /// for waiting before a critical section. + /// + /// **Example:** + /// ```rust + /// let x = Mutex::new(&y); + /// ``` pub MUTEX_ATOMIC, perf, "using a mutex where an atomic value could be used instead" } -/// **What it does:** Checks for usages of `Mutex` where `X` is an integral -/// type. -/// -/// **Why is this bad?** Using a mutex just to make access to a plain integer -/// sequential is -/// shooting flies with cannons. `std::sync::atomic::AtomicUsize` is leaner and faster. -/// -/// **Known problems:** This lint cannot detect if the mutex is actually used -/// for waiting before a critical section. -/// -/// **Example:** -/// ```rust -/// let x = Mutex::new(0usize); -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for usages of `Mutex` where `X` is an integral + /// type. + /// + /// **Why is this bad?** Using a mutex just to make access to a plain integer + /// sequential is + /// shooting flies with cannons. `std::sync::atomic::AtomicUsize` is leaner and faster. + /// + /// **Known problems:** This lint cannot detect if the mutex is actually used + /// for waiting before a critical section. + /// + /// **Example:** + /// ```rust + /// let x = Mutex::new(0usize); + /// ``` pub MUTEX_INTEGER, nursery, "using a mutex for an integer type" diff --git a/clippy_lints/src/needless_bool.rs b/clippy_lints/src/needless_bool.rs index ec9e0bb16944..2a4f2bb1450f 100644 --- a/clippy_lints/src/needless_bool.rs +++ b/clippy_lints/src/needless_bool.rs @@ -11,44 +11,44 @@ use rustc_errors::Applicability; use syntax::ast::LitKind; use syntax::source_map::Spanned; -/// **What it does:** Checks for expressions of the form `if c { true } else { -/// false }` -/// (or vice versa) and suggest using the condition directly. -/// -/// **Why is this bad?** Redundant code. -/// -/// **Known problems:** Maybe false positives: Sometimes, the two branches are -/// painstakingly documented (which we of course do not detect), so they *may* -/// have some value. Even then, the documentation can be rewritten to match the -/// shorter code. -/// -/// **Example:** -/// ```rust -/// if x { -/// false -/// } else { -/// true -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for expressions of the form `if c { true } else { + /// false }` + /// (or vice versa) and suggest using the condition directly. + /// + /// **Why is this bad?** Redundant code. + /// + /// **Known problems:** Maybe false positives: Sometimes, the two branches are + /// painstakingly documented (which we of course do not detect), so they *may* + /// have some value. Even then, the documentation can be rewritten to match the + /// shorter code. + /// + /// **Example:** + /// ```rust + /// if x { + /// false + /// } else { + /// true + /// } + /// ``` pub NEEDLESS_BOOL, complexity, "if-statements with plain booleans in the then- and else-clause, e.g. `if p { true } else { false }`" } -/// **What it does:** Checks for expressions of the form `x == true`, -/// `x != true` and order comparisons such as `x < true` (or vice versa) and -/// suggest using the variable directly. -/// -/// **Why is this bad?** Unnecessary code. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// if x == true {} // could be `if x { }` -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for expressions of the form `x == true`, + /// `x != true` and order comparisons such as `x < true` (or vice versa) and + /// suggest using the variable directly. + /// + /// **Why is this bad?** Unnecessary code. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// if x == true {} // could be `if x { }` + /// ``` pub BOOL_COMPARISON, complexity, "comparing a variable to a boolean, e.g. `if x == true` or `if x != true`" diff --git a/clippy_lints/src/needless_borrow.rs b/clippy_lints/src/needless_borrow.rs index 91e391873120..59b4095f61ec 100644 --- a/clippy_lints/src/needless_borrow.rs +++ b/clippy_lints/src/needless_borrow.rs @@ -11,19 +11,19 @@ use rustc::ty::adjustment::{Adjust, Adjustment}; use rustc::{declare_tool_lint, lint_array}; use rustc_errors::Applicability; -/// **What it does:** Checks for address of operations (`&`) that are going to -/// be dereferenced immediately by the compiler. -/// -/// **Why is this bad?** Suggests that the receiver of the expression borrows -/// the expression. -/// -/// **Example:** -/// ```rust -/// let x: &i32 = &&&&&&5; -/// ``` -/// -/// **Known problems:** None. declare_clippy_lint! { + /// **What it does:** Checks for address of operations (`&`) that are going to + /// be dereferenced immediately by the compiler. + /// + /// **Why is this bad?** Suggests that the receiver of the expression borrows + /// the expression. + /// + /// **Example:** + /// ```rust + /// let x: &i32 = &&&&&&5; + /// ``` + /// + /// **Known problems:** None. pub NEEDLESS_BORROW, nursery, "taking a reference that is going to be automatically dereferenced" diff --git a/clippy_lints/src/needless_borrowed_ref.rs b/clippy_lints/src/needless_borrowed_ref.rs index eae8ed541e22..2c1f87c53e35 100644 --- a/clippy_lints/src/needless_borrowed_ref.rs +++ b/clippy_lints/src/needless_borrowed_ref.rs @@ -9,43 +9,43 @@ use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use rustc::{declare_tool_lint, lint_array}; use rustc_errors::Applicability; -/// **What it does:** Checks for useless borrowed references. -/// -/// **Why is this bad?** It is mostly useless and make the code look more -/// complex than it -/// actually is. -/// -/// **Known problems:** It seems that the `&ref` pattern is sometimes useful. -/// For instance in the following snippet: -/// ```rust -/// enum Animal { -/// Cat(u64), -/// Dog(u64), -/// } -/// -/// fn foo(a: &Animal, b: &Animal) { -/// match (a, b) { -/// (&Animal::Cat(v), k) | (k, &Animal::Cat(v)) => (), // lifetime -/// mismatch error -/// (&Animal::Dog(ref c), &Animal::Dog(_)) => () -/// } -/// } -/// ``` -/// There is a lifetime mismatch error for `k` (indeed a and b have distinct -/// lifetime). -/// This can be fixed by using the `&ref` pattern. -/// However, the code can also be fixed by much cleaner ways -/// -/// **Example:** -/// ```rust -/// let mut v = Vec::::new(); -/// let _ = v.iter_mut().filter(|&ref a| a.is_empty()); -/// ``` -/// This closure takes a reference on something that has been matched as a -/// reference and -/// de-referenced. -/// As such, it could just be |a| a.is_empty() declare_clippy_lint! { + /// **What it does:** Checks for useless borrowed references. + /// + /// **Why is this bad?** It is mostly useless and make the code look more + /// complex than it + /// actually is. + /// + /// **Known problems:** It seems that the `&ref` pattern is sometimes useful. + /// For instance in the following snippet: + /// ```rust + /// enum Animal { + /// Cat(u64), + /// Dog(u64), + /// } + /// + /// fn foo(a: &Animal, b: &Animal) { + /// match (a, b) { + /// (&Animal::Cat(v), k) | (k, &Animal::Cat(v)) => (), // lifetime + /// mismatch error + /// (&Animal::Dog(ref c), &Animal::Dog(_)) => () + /// } + /// } + /// ``` + /// There is a lifetime mismatch error for `k` (indeed a and b have distinct + /// lifetime). + /// This can be fixed by using the `&ref` pattern. + /// However, the code can also be fixed by much cleaner ways + /// + /// **Example:** + /// ```rust + /// let mut v = Vec::::new(); + /// let _ = v.iter_mut().filter(|&ref a| a.is_empty()); + /// ``` + /// This closure takes a reference on something that has been matched as a + /// reference and + /// de-referenced. + /// As such, it could just be |a| a.is_empty() pub NEEDLESS_BORROWED_REFERENCE, complexity, "taking a needless borrowed reference" diff --git a/clippy_lints/src/needless_continue.rs b/clippy_lints/src/needless_continue.rs index 19d7ab32fea1..00394a9e1e2b 100644 --- a/clippy_lints/src/needless_continue.rs +++ b/clippy_lints/src/needless_continue.rs @@ -35,66 +35,66 @@ use syntax::source_map::{original_sp, DUMMY_SP}; use crate::utils::{in_macro, snippet, snippet_block, span_help_and_lint, trim_multiline}; -/// **What it does:** The lint checks for `if`-statements appearing in loops -/// that contain a `continue` statement in either their main blocks or their -/// `else`-blocks, when omitting the `else`-block possibly with some -/// rearrangement of code can make the code easier to understand. -/// -/// **Why is this bad?** Having explicit `else` blocks for `if` statements -/// containing `continue` in their THEN branch adds unnecessary branching and -/// nesting to the code. Having an else block containing just `continue` can -/// also be better written by grouping the statements following the whole `if` -/// statement within the THEN block and omitting the else block completely. -/// -/// **Known problems:** None -/// -/// **Example:** -/// ```rust -/// while condition() { -/// update_condition(); -/// if x { -/// // ... -/// } else { -/// continue; -/// } -/// println!("Hello, world"); -/// } -/// ``` -/// -/// Could be rewritten as -/// -/// ```rust -/// while condition() { -/// update_condition(); -/// if x { -/// // ... -/// println!("Hello, world"); -/// } -/// } -/// ``` -/// -/// As another example, the following code -/// -/// ```rust -/// loop { -/// if waiting() { -/// continue; -/// } else { -/// // Do something useful -/// } -/// } -/// ``` -/// Could be rewritten as -/// -/// ```rust -/// loop { -/// if waiting() { -/// continue; -/// } -/// // Do something useful -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** The lint checks for `if`-statements appearing in loops + /// that contain a `continue` statement in either their main blocks or their + /// `else`-blocks, when omitting the `else`-block possibly with some + /// rearrangement of code can make the code easier to understand. + /// + /// **Why is this bad?** Having explicit `else` blocks for `if` statements + /// containing `continue` in their THEN branch adds unnecessary branching and + /// nesting to the code. Having an else block containing just `continue` can + /// also be better written by grouping the statements following the whole `if` + /// statement within the THEN block and omitting the else block completely. + /// + /// **Known problems:** None + /// + /// **Example:** + /// ```rust + /// while condition() { + /// update_condition(); + /// if x { + /// // ... + /// } else { + /// continue; + /// } + /// println!("Hello, world"); + /// } + /// ``` + /// + /// Could be rewritten as + /// + /// ```rust + /// while condition() { + /// update_condition(); + /// if x { + /// // ... + /// println!("Hello, world"); + /// } + /// } + /// ``` + /// + /// As another example, the following code + /// + /// ```rust + /// loop { + /// if waiting() { + /// continue; + /// } else { + /// // Do something useful + /// } + /// } + /// ``` + /// Could be rewritten as + /// + /// ```rust + /// loop { + /// if waiting() { + /// continue; + /// } + /// // Do something useful + /// } + /// ``` pub NEEDLESS_CONTINUE, pedantic, "`continue` statements that can be replaced by a rearrangement of code" diff --git a/clippy_lints/src/needless_pass_by_value.rs b/clippy_lints/src/needless_pass_by_value.rs index 43343bcfabf1..5dfc36d3e0e8 100644 --- a/clippy_lints/src/needless_pass_by_value.rs +++ b/clippy_lints/src/needless_pass_by_value.rs @@ -20,30 +20,30 @@ use std::borrow::Cow; use syntax::errors::DiagnosticBuilder; use syntax_pos::Span; -/// **What it does:** Checks for functions taking arguments by value, but not -/// consuming them in its -/// body. -/// -/// **Why is this bad?** Taking arguments by reference is more flexible and can -/// sometimes avoid -/// unnecessary allocations. -/// -/// **Known problems:** -/// * This lint suggests taking an argument by reference, -/// however sometimes it is better to let users decide the argument type -/// (by using `Borrow` trait, for example), depending on how the function is used. -/// -/// **Example:** -/// ```rust -/// fn foo(v: Vec) { -/// assert_eq!(v.len(), 42); -/// } -/// // should be -/// fn foo(v: &[i32]) { -/// assert_eq!(v.len(), 42); -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for functions taking arguments by value, but not + /// consuming them in its + /// body. + /// + /// **Why is this bad?** Taking arguments by reference is more flexible and can + /// sometimes avoid + /// unnecessary allocations. + /// + /// **Known problems:** + /// * This lint suggests taking an argument by reference, + /// however sometimes it is better to let users decide the argument type + /// (by using `Borrow` trait, for example), depending on how the function is used. + /// + /// **Example:** + /// ```rust + /// fn foo(v: Vec) { + /// assert_eq!(v.len(), 42); + /// } + /// // should be + /// fn foo(v: &[i32]) { + /// assert_eq!(v.len(), 42); + /// } + /// ``` pub NEEDLESS_PASS_BY_VALUE, pedantic, "functions taking arguments by value, but not consuming them in its body" diff --git a/clippy_lints/src/needless_update.rs b/clippy_lints/src/needless_update.rs index 1d91feddcbeb..2ce9bf78aa6c 100644 --- a/clippy_lints/src/needless_update.rs +++ b/clippy_lints/src/needless_update.rs @@ -4,23 +4,23 @@ use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use rustc::ty; use rustc::{declare_tool_lint, lint_array}; -/// **What it does:** Checks for needlessly including a base struct on update -/// when all fields are changed anyway. -/// -/// **Why is this bad?** This will cost resources (because the base has to be -/// somewhere), and make the code less readable. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// Point { -/// x: 1, -/// y: 0, -/// ..zero_point -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for needlessly including a base struct on update + /// when all fields are changed anyway. + /// + /// **Why is this bad?** This will cost resources (because the base has to be + /// somewhere), and make the code less readable. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// Point { + /// x: 1, + /// y: 0, + /// ..zero_point + /// } + /// ``` pub NEEDLESS_UPDATE, complexity, "using `Foo { ..base }` when there are no missing fields" diff --git a/clippy_lints/src/neg_cmp_op_on_partial_ord.rs b/clippy_lints/src/neg_cmp_op_on_partial_ord.rs index 50031dd68cf1..eb8a19f2bbb1 100644 --- a/clippy_lints/src/neg_cmp_op_on_partial_ord.rs +++ b/clippy_lints/src/neg_cmp_op_on_partial_ord.rs @@ -5,38 +5,38 @@ use rustc::{declare_tool_lint, lint_array}; use crate::utils::{self, paths, span_lint}; -/// **What it does:** -/// Checks for the usage of negated comparison operators on types which only implement -/// `PartialOrd` (e.g. `f64`). -/// -/// **Why is this bad?** -/// These operators make it easy to forget that the underlying types actually allow not only three -/// potential Orderings (Less, Equal, Greater) but also a fourth one (Uncomparable). This is -/// especially easy to miss if the operator based comparison result is negated. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// -/// ```rust -/// use std::cmp::Ordering; -/// -/// // Bad -/// let a = 1.0; -/// let b = std::f64::NAN; -/// -/// let _not_less_or_equal = !(a <= b); -/// -/// // Good -/// let a = 1.0; -/// let b = std::f64::NAN; -/// -/// let _not_less_or_equal = match a.partial_cmp(&b) { -/// None | Some(Ordering::Greater) => true, -/// _ => false, -/// }; -/// ``` declare_clippy_lint! { + /// **What it does:** + /// Checks for the usage of negated comparison operators on types which only implement + /// `PartialOrd` (e.g. `f64`). + /// + /// **Why is this bad?** + /// These operators make it easy to forget that the underlying types actually allow not only three + /// potential Orderings (Less, Equal, Greater) but also a fourth one (Uncomparable). This is + /// especially easy to miss if the operator based comparison result is negated. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// + /// ```rust + /// use std::cmp::Ordering; + /// + /// // Bad + /// let a = 1.0; + /// let b = std::f64::NAN; + /// + /// let _not_less_or_equal = !(a <= b); + /// + /// // Good + /// let a = 1.0; + /// let b = std::f64::NAN; + /// + /// let _not_less_or_equal = match a.partial_cmp(&b) { + /// None | Some(Ordering::Greater) => true, + /// _ => false, + /// }; + /// ``` pub NEG_CMP_OP_ON_PARTIAL_ORD, complexity, "The use of negated comparison operators on partially ordered types may produce confusing code." diff --git a/clippy_lints/src/neg_multiply.rs b/clippy_lints/src/neg_multiply.rs index b207433b5abb..dde998a9a5c2 100644 --- a/clippy_lints/src/neg_multiply.rs +++ b/clippy_lints/src/neg_multiply.rs @@ -7,17 +7,17 @@ use syntax::source_map::{Span, Spanned}; use crate::consts::{self, Constant}; use crate::utils::span_lint; -/// **What it does:** Checks for multiplication by -1 as a form of negation. -/// -/// **Why is this bad?** It's more readable to just negate. -/// -/// **Known problems:** This only catches integers (for now). -/// -/// **Example:** -/// ```rust -/// x * -1 -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for multiplication by -1 as a form of negation. + /// + /// **Why is this bad?** It's more readable to just negate. + /// + /// **Known problems:** This only catches integers (for now). + /// + /// **Example:** + /// ```rust + /// x * -1 + /// ``` pub NEG_MULTIPLY, style, "multiplying integers with -1" diff --git a/clippy_lints/src/new_without_default.rs b/clippy_lints/src/new_without_default.rs index fe992d3cf22c..127438da9170 100644 --- a/clippy_lints/src/new_without_default.rs +++ b/clippy_lints/src/new_without_default.rs @@ -11,74 +11,74 @@ use rustc::{declare_tool_lint, lint_array}; use rustc_errors::Applicability; use syntax::source_map::Span; -/// **What it does:** Checks for types with a `fn new() -> Self` method and no -/// implementation of -/// [`Default`](https://doc.rust-lang.org/std/default/trait.Default.html). -/// -/// It detects both the case when a manual -/// [`Default`](https://doc.rust-lang.org/std/default/trait.Default.html) -/// implementation is required and also when it can be created with -/// `#[derive(Default)]` -/// -/// **Why is this bad?** The user might expect to be able to use -/// [`Default`](https://doc.rust-lang.org/std/default/trait.Default.html) as the -/// type can be constructed without arguments. -/// -/// **Known problems:** Hopefully none. -/// -/// **Example:** -/// -/// ```rust -/// struct Foo(Bar); -/// -/// impl Foo { -/// fn new() -> Self { -/// Foo(Bar::new()) -/// } -/// } -/// ``` -/// -/// Instead, use: -/// -/// ```rust -/// struct Foo(Bar); -/// -/// impl Default for Foo { -/// fn default() -> Self { -/// Foo(Bar::new()) -/// } -/// } -/// ``` -/// -/// Or, if -/// [`Default`](https://doc.rust-lang.org/std/default/trait.Default.html) -/// can be derived by `#[derive(Default)]`: -/// -/// ```rust -/// struct Foo; -/// -/// impl Foo { -/// fn new() -> Self { -/// Foo -/// } -/// } -/// ``` -/// -/// Instead, use: -/// -/// ```rust -/// #[derive(Default)] -/// struct Foo; -/// -/// impl Foo { -/// fn new() -> Self { -/// Foo -/// } -/// } -/// ``` -/// -/// You can also have `new()` call `Default::default()`. declare_clippy_lint! { + /// **What it does:** Checks for types with a `fn new() -> Self` method and no + /// implementation of + /// [`Default`](https://doc.rust-lang.org/std/default/trait.Default.html). + /// + /// It detects both the case when a manual + /// [`Default`](https://doc.rust-lang.org/std/default/trait.Default.html) + /// implementation is required and also when it can be created with + /// `#[derive(Default)]` + /// + /// **Why is this bad?** The user might expect to be able to use + /// [`Default`](https://doc.rust-lang.org/std/default/trait.Default.html) as the + /// type can be constructed without arguments. + /// + /// **Known problems:** Hopefully none. + /// + /// **Example:** + /// + /// ```rust + /// struct Foo(Bar); + /// + /// impl Foo { + /// fn new() -> Self { + /// Foo(Bar::new()) + /// } + /// } + /// ``` + /// + /// Instead, use: + /// + /// ```rust + /// struct Foo(Bar); + /// + /// impl Default for Foo { + /// fn default() -> Self { + /// Foo(Bar::new()) + /// } + /// } + /// ``` + /// + /// Or, if + /// [`Default`](https://doc.rust-lang.org/std/default/trait.Default.html) + /// can be derived by `#[derive(Default)]`: + /// + /// ```rust + /// struct Foo; + /// + /// impl Foo { + /// fn new() -> Self { + /// Foo + /// } + /// } + /// ``` + /// + /// Instead, use: + /// + /// ```rust + /// #[derive(Default)] + /// struct Foo; + /// + /// impl Foo { + /// fn new() -> Self { + /// Foo + /// } + /// } + /// ``` + /// + /// You can also have `new()` call `Default::default()`. pub NEW_WITHOUT_DEFAULT, style, "`fn new() -> Self` method without `Default` implementation" diff --git a/clippy_lints/src/no_effect.rs b/clippy_lints/src/no_effect.rs index 7799e8fecf2c..dae59bc84b95 100644 --- a/clippy_lints/src/no_effect.rs +++ b/clippy_lints/src/no_effect.rs @@ -6,37 +6,37 @@ use rustc::{declare_tool_lint, lint_array}; use rustc_errors::Applicability; use std::ops::Deref; -/// **What it does:** Checks for statements which have no effect. -/// -/// **Why is this bad?** Similar to dead code, these statements are actually -/// executed. However, as they have no effect, all they do is make the code less -/// readable. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// 0; -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for statements which have no effect. + /// + /// **Why is this bad?** Similar to dead code, these statements are actually + /// executed. However, as they have no effect, all they do is make the code less + /// readable. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// 0; + /// ``` pub NO_EFFECT, complexity, "statements with no effect" } -/// **What it does:** Checks for expression statements that can be reduced to a -/// sub-expression. -/// -/// **Why is this bad?** Expressions by themselves often have no side-effects. -/// Having such expressions reduces readability. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// compute_array()[0]; -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for expression statements that can be reduced to a + /// sub-expression. + /// + /// **Why is this bad?** Expressions by themselves often have no side-effects. + /// Having such expressions reduces readability. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// compute_array()[0]; + /// ``` pub UNNECESSARY_OPERATION, complexity, "outer expressions with no effect" diff --git a/clippy_lints/src/non_copy_const.rs b/clippy_lints/src/non_copy_const.rs index 34a4a7eb2f72..21130e36e465 100644 --- a/clippy_lints/src/non_copy_const.rs +++ b/clippy_lints/src/non_copy_const.rs @@ -14,69 +14,69 @@ use rustc_typeck::hir_ty_to_ty; use std::ptr; use syntax_pos::{Span, DUMMY_SP}; -/// **What it does:** Checks for declaration of `const` items which is interior -/// mutable (e.g. contains a `Cell`, `Mutex`, `AtomicXxxx` etc). -/// -/// **Why is this bad?** Consts are copied everywhere they are referenced, i.e. -/// every time you refer to the const a fresh instance of the `Cell` or `Mutex` -/// or `AtomicXxxx` will be created, which defeats the whole purpose of using -/// these types in the first place. -/// -/// The `const` should better be replaced by a `static` item if a global -/// variable is wanted, or replaced by a `const fn` if a constructor is wanted. -/// -/// **Known problems:** A "non-constant" const item is a legacy way to supply an -/// initialized value to downstream `static` items (e.g. the -/// `std::sync::ONCE_INIT` constant). In this case the use of `const` is legit, -/// and this lint should be suppressed. -/// -/// **Example:** -/// ```rust -/// use std::sync::atomic::{AtomicUsize, Ordering::SeqCst}; -/// -/// // Bad. -/// const CONST_ATOM: AtomicUsize = AtomicUsize::new(12); -/// CONST_ATOM.store(6, SeqCst); // the content of the atomic is unchanged -/// assert_eq!(CONST_ATOM.load(SeqCst), 12); // because the CONST_ATOM in these lines are distinct -/// -/// // Good. -/// static STATIC_ATOM: AtomicUsize = AtomicUsize::new(15); -/// STATIC_ATOM.store(9, SeqCst); -/// assert_eq!(STATIC_ATOM.load(SeqCst), 9); // use a `static` item to refer to the same instance -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for declaration of `const` items which is interior + /// mutable (e.g. contains a `Cell`, `Mutex`, `AtomicXxxx` etc). + /// + /// **Why is this bad?** Consts are copied everywhere they are referenced, i.e. + /// every time you refer to the const a fresh instance of the `Cell` or `Mutex` + /// or `AtomicXxxx` will be created, which defeats the whole purpose of using + /// these types in the first place. + /// + /// The `const` should better be replaced by a `static` item if a global + /// variable is wanted, or replaced by a `const fn` if a constructor is wanted. + /// + /// **Known problems:** A "non-constant" const item is a legacy way to supply an + /// initialized value to downstream `static` items (e.g. the + /// `std::sync::ONCE_INIT` constant). In this case the use of `const` is legit, + /// and this lint should be suppressed. + /// + /// **Example:** + /// ```rust + /// use std::sync::atomic::{AtomicUsize, Ordering::SeqCst}; + /// + /// // Bad. + /// const CONST_ATOM: AtomicUsize = AtomicUsize::new(12); + /// CONST_ATOM.store(6, SeqCst); // the content of the atomic is unchanged + /// assert_eq!(CONST_ATOM.load(SeqCst), 12); // because the CONST_ATOM in these lines are distinct + /// + /// // Good. + /// static STATIC_ATOM: AtomicUsize = AtomicUsize::new(15); + /// STATIC_ATOM.store(9, SeqCst); + /// assert_eq!(STATIC_ATOM.load(SeqCst), 9); // use a `static` item to refer to the same instance + /// ``` pub DECLARE_INTERIOR_MUTABLE_CONST, correctness, "declaring const with interior mutability" } -/// **What it does:** Checks if `const` items which is interior mutable (e.g. -/// contains a `Cell`, `Mutex`, `AtomicXxxx` etc) has been borrowed directly. -/// -/// **Why is this bad?** Consts are copied everywhere they are referenced, i.e. -/// every time you refer to the const a fresh instance of the `Cell` or `Mutex` -/// or `AtomicXxxx` will be created, which defeats the whole purpose of using -/// these types in the first place. -/// -/// The `const` value should be stored inside a `static` item. -/// -/// **Known problems:** None -/// -/// **Example:** -/// ```rust -/// use std::sync::atomic::{AtomicUsize, Ordering::SeqCst}; -/// const CONST_ATOM: AtomicUsize = AtomicUsize::new(12); -/// -/// // Bad. -/// CONST_ATOM.store(6, SeqCst); // the content of the atomic is unchanged -/// assert_eq!(CONST_ATOM.load(SeqCst), 12); // because the CONST_ATOM in these lines are distinct -/// -/// // Good. -/// static STATIC_ATOM: AtomicUsize = CONST_ATOM; -/// STATIC_ATOM.store(9, SeqCst); -/// assert_eq!(STATIC_ATOM.load(SeqCst), 9); // use a `static` item to refer to the same instance -/// ``` declare_clippy_lint! { + /// **What it does:** Checks if `const` items which is interior mutable (e.g. + /// contains a `Cell`, `Mutex`, `AtomicXxxx` etc) has been borrowed directly. + /// + /// **Why is this bad?** Consts are copied everywhere they are referenced, i.e. + /// every time you refer to the const a fresh instance of the `Cell` or `Mutex` + /// or `AtomicXxxx` will be created, which defeats the whole purpose of using + /// these types in the first place. + /// + /// The `const` value should be stored inside a `static` item. + /// + /// **Known problems:** None + /// + /// **Example:** + /// ```rust + /// use std::sync::atomic::{AtomicUsize, Ordering::SeqCst}; + /// const CONST_ATOM: AtomicUsize = AtomicUsize::new(12); + /// + /// // Bad. + /// CONST_ATOM.store(6, SeqCst); // the content of the atomic is unchanged + /// assert_eq!(CONST_ATOM.load(SeqCst), 12); // because the CONST_ATOM in these lines are distinct + /// + /// // Good. + /// static STATIC_ATOM: AtomicUsize = CONST_ATOM; + /// STATIC_ATOM.store(9, SeqCst); + /// assert_eq!(STATIC_ATOM.load(SeqCst), 9); // use a `static` item to refer to the same instance + /// ``` pub BORROW_INTERIOR_MUTABLE_CONST, correctness, "referencing const with interior mutability" diff --git a/clippy_lints/src/non_expressive_names.rs b/clippy_lints/src/non_expressive_names.rs index b1cd1910f5b1..9bb3a1d3d6b1 100644 --- a/clippy_lints/src/non_expressive_names.rs +++ b/clippy_lints/src/non_expressive_names.rs @@ -7,57 +7,57 @@ use syntax::source_map::Span; use syntax::symbol::LocalInternedString; use syntax::visit::{walk_block, walk_expr, walk_pat, Visitor}; -/// **What it does:** Checks for names that are very similar and thus confusing. -/// -/// **Why is this bad?** It's hard to distinguish between names that differ only -/// by a single character. -/// -/// **Known problems:** None? -/// -/// **Example:** -/// ```rust -/// let checked_exp = something; -/// let checked_expr = something_else; -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for names that are very similar and thus confusing. + /// + /// **Why is this bad?** It's hard to distinguish between names that differ only + /// by a single character. + /// + /// **Known problems:** None? + /// + /// **Example:** + /// ```rust + /// let checked_exp = something; + /// let checked_expr = something_else; + /// ``` pub SIMILAR_NAMES, pedantic, "similarly named items and bindings" } -/// **What it does:** Checks for too many variables whose name consists of a -/// single character. -/// -/// **Why is this bad?** It's hard to memorize what a variable means without a -/// descriptive name. -/// -/// **Known problems:** None? -/// -/// **Example:** -/// ```rust -/// let (a, b, c, d, e, f, g) = (...); -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for too many variables whose name consists of a + /// single character. + /// + /// **Why is this bad?** It's hard to memorize what a variable means without a + /// descriptive name. + /// + /// **Known problems:** None? + /// + /// **Example:** + /// ```rust + /// let (a, b, c, d, e, f, g) = (...); + /// ``` pub MANY_SINGLE_CHAR_NAMES, style, "too many single character bindings" } -/// **What it does:** Checks if you have variables whose name consists of just -/// underscores and digits. -/// -/// **Why is this bad?** It's hard to memorize what a variable means without a -/// descriptive name. -/// -/// **Known problems:** None? -/// -/// **Example:** -/// ```rust -/// let _1 = 1; -/// let ___1 = 1; -/// let __1___2 = 11; -/// ``` declare_clippy_lint! { + /// **What it does:** Checks if you have variables whose name consists of just + /// underscores and digits. + /// + /// **Why is this bad?** It's hard to memorize what a variable means without a + /// descriptive name. + /// + /// **Known problems:** None? + /// + /// **Example:** + /// ```rust + /// let _1 = 1; + /// let ___1 = 1; + /// let __1___2 = 11; + /// ``` pub JUST_UNDERSCORES_AND_DIGITS, style, "unclear name" diff --git a/clippy_lints/src/ok_if_let.rs b/clippy_lints/src/ok_if_let.rs index 0789df0d76b8..b82d0372b811 100644 --- a/clippy_lints/src/ok_if_let.rs +++ b/clippy_lints/src/ok_if_let.rs @@ -4,31 +4,31 @@ use rustc::hir::*; use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use rustc::{declare_tool_lint, lint_array}; -/// **What it does:*** Checks for unnecessary `ok()` in if let. -/// -/// **Why is this bad?** Calling `ok()` in if let is unnecessary, instead match -/// on `Ok(pat)` -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// for result in iter { -/// if let Some(bench) = try!(result).parse().ok() { -/// vec.push(bench) -/// } -/// } -/// ``` -/// Could be written: -/// -/// ```rust -/// for result in iter { -/// if let Ok(bench) = try!(result).parse() { -/// vec.push(bench) -/// } -/// } -/// ``` declare_clippy_lint! { + /// **What it does:*** Checks for unnecessary `ok()` in if let. + /// + /// **Why is this bad?** Calling `ok()` in if let is unnecessary, instead match + /// on `Ok(pat)` + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// for result in iter { + /// if let Some(bench) = try!(result).parse().ok() { + /// vec.push(bench) + /// } + /// } + /// ``` + /// Could be written: + /// + /// ```rust + /// for result in iter { + /// if let Ok(bench) = try!(result).parse() { + /// vec.push(bench) + /// } + /// } + /// ``` pub IF_LET_SOME_RESULT, style, "usage of `ok()` in `if let Some(pat)` statements is unnecessary, match on `Ok(pat)` instead" diff --git a/clippy_lints/src/open_options.rs b/clippy_lints/src/open_options.rs index 31a6caa50d69..65257973bead 100644 --- a/clippy_lints/src/open_options.rs +++ b/clippy_lints/src/open_options.rs @@ -5,19 +5,19 @@ use rustc::{declare_tool_lint, lint_array}; use syntax::ast::LitKind; use syntax::source_map::{Span, Spanned}; -/// **What it does:** Checks for duplicate open options as well as combinations -/// that make no sense. -/// -/// **Why is this bad?** In the best case, the code will be harder to read than -/// necessary. I don't know the worst case. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// OpenOptions::new().read(true).truncate(true) -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for duplicate open options as well as combinations + /// that make no sense. + /// + /// **Why is this bad?** In the best case, the code will be harder to read than + /// necessary. I don't know the worst case. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// OpenOptions::new().read(true).truncate(true) + /// ``` pub NONSENSICAL_OPEN_OPTIONS, correctness, "nonsensical combination of options for opening a file" diff --git a/clippy_lints/src/overflow_check_conditional.rs b/clippy_lints/src/overflow_check_conditional.rs index d424e8bcaad7..c041f3a959a0 100644 --- a/clippy_lints/src/overflow_check_conditional.rs +++ b/clippy_lints/src/overflow_check_conditional.rs @@ -4,18 +4,18 @@ use rustc::hir::*; use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use rustc::{declare_tool_lint, lint_array}; -/// **What it does:** Detects classic underflow/overflow checks. -/// -/// **Why is this bad?** Most classic C underflow/overflow checks will fail in -/// Rust. Users can use functions like `overflowing_*` and `wrapping_*` instead. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// a + b < a -/// ``` declare_clippy_lint! { + /// **What it does:** Detects classic underflow/overflow checks. + /// + /// **Why is this bad?** Most classic C underflow/overflow checks will fail in + /// Rust. Users can use functions like `overflowing_*` and `wrapping_*` instead. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// a + b < a + /// ``` pub OVERFLOW_CHECK_CONDITIONAL, complexity, "overflow checks inspired by C which are likely to panic" diff --git a/clippy_lints/src/panic_unimplemented.rs b/clippy_lints/src/panic_unimplemented.rs index d0f7487c24a2..bd73f5a05724 100644 --- a/clippy_lints/src/panic_unimplemented.rs +++ b/clippy_lints/src/panic_unimplemented.rs @@ -7,36 +7,36 @@ use syntax::ast::LitKind; use syntax::ptr::P; use syntax_pos::Span; -/// **What it does:** Checks for missing parameters in `panic!`. -/// -/// **Why is this bad?** Contrary to the `format!` family of macros, there are -/// two forms of `panic!`: if there are no parameters given, the first argument -/// is not a format string and used literally. So while `format!("{}")` will -/// fail to compile, `panic!("{}")` will not. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// panic!("This `panic!` is probably missing a parameter there: {}"); -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for missing parameters in `panic!`. + /// + /// **Why is this bad?** Contrary to the `format!` family of macros, there are + /// two forms of `panic!`: if there are no parameters given, the first argument + /// is not a format string and used literally. So while `format!("{}")` will + /// fail to compile, `panic!("{}")` will not. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// panic!("This `panic!` is probably missing a parameter there: {}"); + /// ``` pub PANIC_PARAMS, style, "missing parameters in `panic!` calls" } -/// **What it does:** Checks for usage of `unimplemented!`. -/// -/// **Why is this bad?** This macro should not be present in production code -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// unimplemented!(); -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for usage of `unimplemented!`. + /// + /// **Why is this bad?** This macro should not be present in production code + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// unimplemented!(); + /// ``` pub UNIMPLEMENTED, restriction, "`unimplemented!` should not be present in production code" diff --git a/clippy_lints/src/partialeq_ne_impl.rs b/clippy_lints/src/partialeq_ne_impl.rs index 5c532516b943..47495fde24a3 100644 --- a/clippy_lints/src/partialeq_ne_impl.rs +++ b/clippy_lints/src/partialeq_ne_impl.rs @@ -4,25 +4,25 @@ use rustc::hir::*; use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use rustc::{declare_tool_lint, lint_array}; -/// **What it does:** Checks for manual re-implementations of `PartialEq::ne`. -/// -/// **Why is this bad?** `PartialEq::ne` is required to always return the -/// negated result of `PartialEq::eq`, which is exactly what the default -/// implementation does. Therefore, there should never be any need to -/// re-implement it. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// struct Foo; -/// -/// impl PartialEq for Foo { -/// fn eq(&self, other: &Foo) -> bool { ... } -/// fn ne(&self, other: &Foo) -> bool { !(self == other) } -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for manual re-implementations of `PartialEq::ne`. + /// + /// **Why is this bad?** `PartialEq::ne` is required to always return the + /// negated result of `PartialEq::eq`, which is exactly what the default + /// implementation does. Therefore, there should never be any need to + /// re-implement it. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// struct Foo; + /// + /// impl PartialEq for Foo { + /// fn eq(&self, other: &Foo) -> bool { ... } + /// fn ne(&self, other: &Foo) -> bool { !(self == other) } + /// } + /// ``` pub PARTIALEQ_NE_IMPL, complexity, "re-implementing `PartialEq::ne`" diff --git a/clippy_lints/src/precedence.rs b/clippy_lints/src/precedence.rs index ed03a8c6aa76..6819ac744744 100644 --- a/clippy_lints/src/precedence.rs +++ b/clippy_lints/src/precedence.rs @@ -5,24 +5,24 @@ use rustc_errors::Applicability; use syntax::ast::*; use syntax::source_map::Spanned; -/// **What it does:** Checks for operations where precedence may be unclear -/// and suggests to add parentheses. Currently it catches the following: -/// * mixed usage of arithmetic and bit shifting/combining operators without -/// parentheses -/// * a "negative" numeric literal (which is really a unary `-` followed by a -/// numeric literal) -/// followed by a method call -/// -/// **Why is this bad?** Not everyone knows the precedence of those operators by -/// heart, so expressions like these may trip others trying to reason about the -/// code. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// * `1 << 2 + 3` equals 32, while `(1 << 2) + 3` equals 7 -/// * `-1i32.abs()` equals -1, while `(-1i32).abs()` equals 1 declare_clippy_lint! { + /// **What it does:** Checks for operations where precedence may be unclear + /// and suggests to add parentheses. Currently it catches the following: + /// * mixed usage of arithmetic and bit shifting/combining operators without + /// parentheses + /// * a "negative" numeric literal (which is really a unary `-` followed by a + /// numeric literal) + /// followed by a method call + /// + /// **Why is this bad?** Not everyone knows the precedence of those operators by + /// heart, so expressions like these may trip others trying to reason about the + /// code. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// * `1 << 2 + 3` equals 32, while `(1 << 2) + 3` equals 7 + /// * `-1i32.abs()` equals -1, while `(-1i32).abs()` equals 1 pub PRECEDENCE, complexity, "operations where precedence may be unclear" diff --git a/clippy_lints/src/ptr.rs b/clippy_lints/src/ptr.rs index e930aae1040b..68fb5b0b20f1 100644 --- a/clippy_lints/src/ptr.rs +++ b/clippy_lints/src/ptr.rs @@ -13,82 +13,82 @@ use std::borrow::Cow; use syntax::source_map::Span; use syntax_pos::MultiSpan; -/// **What it does:** This lint checks for function arguments of type `&String` -/// or `&Vec` unless the references are mutable. It will also suggest you -/// replace `.clone()` calls with the appropriate `.to_owned()`/`to_string()` -/// calls. -/// -/// **Why is this bad?** Requiring the argument to be of the specific size -/// makes the function less useful for no benefit; slices in the form of `&[T]` -/// or `&str` usually suffice and can be obtained from other types, too. -/// -/// **Known problems:** The lint does not follow data. So if you have an -/// argument `x` and write `let y = x; y.clone()` the lint will not suggest -/// changing that `.clone()` to `.to_owned()`. -/// -/// Other functions called from this function taking a `&String` or `&Vec` -/// argument may also fail to compile if you change the argument. Applying -/// this lint on them will fix the problem, but they may be in other crates. -/// -/// Also there may be `fn(&Vec)`-typed references pointing to your function. -/// If you have them, you will get a compiler error after applying this lint's -/// suggestions. You then have the choice to undo your changes or change the -/// type of the reference. -/// -/// Note that if the function is part of your public interface, there may be -/// other crates referencing it you may not be aware. Carefully deprecate the -/// function before applying the lint suggestions in this case. -/// -/// **Example:** -/// ```rust -/// fn foo(&Vec) { .. } -/// ``` declare_clippy_lint! { + /// **What it does:** This lint checks for function arguments of type `&String` + /// or `&Vec` unless the references are mutable. It will also suggest you + /// replace `.clone()` calls with the appropriate `.to_owned()`/`to_string()` + /// calls. + /// + /// **Why is this bad?** Requiring the argument to be of the specific size + /// makes the function less useful for no benefit; slices in the form of `&[T]` + /// or `&str` usually suffice and can be obtained from other types, too. + /// + /// **Known problems:** The lint does not follow data. So if you have an + /// argument `x` and write `let y = x; y.clone()` the lint will not suggest + /// changing that `.clone()` to `.to_owned()`. + /// + /// Other functions called from this function taking a `&String` or `&Vec` + /// argument may also fail to compile if you change the argument. Applying + /// this lint on them will fix the problem, but they may be in other crates. + /// + /// Also there may be `fn(&Vec)`-typed references pointing to your function. + /// If you have them, you will get a compiler error after applying this lint's + /// suggestions. You then have the choice to undo your changes or change the + /// type of the reference. + /// + /// Note that if the function is part of your public interface, there may be + /// other crates referencing it you may not be aware. Carefully deprecate the + /// function before applying the lint suggestions in this case. + /// + /// **Example:** + /// ```rust + /// fn foo(&Vec) { .. } + /// ``` pub PTR_ARG, style, "fn arguments of the type `&Vec<...>` or `&String`, suggesting to use `&[...]` or `&str` instead, respectively" } -/// **What it does:** This lint checks for equality comparisons with `ptr::null` -/// -/// **Why is this bad?** It's easier and more readable to use the inherent -/// `.is_null()` -/// method instead -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// if x == ptr::null { -/// .. -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** This lint checks for equality comparisons with `ptr::null` + /// + /// **Why is this bad?** It's easier and more readable to use the inherent + /// `.is_null()` + /// method instead + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// if x == ptr::null { + /// .. + /// } + /// ``` pub CMP_NULL, style, "comparing a pointer to a null pointer, suggesting to use `.is_null()` instead." } -/// **What it does:** This lint checks for functions that take immutable -/// references and return -/// mutable ones. -/// -/// **Why is this bad?** This is trivially unsound, as one can create two -/// mutable references -/// from the same (immutable!) source. This -/// [error](https://github.com/rust-lang/rust/issues/39465) -/// actually lead to an interim Rust release 1.15.1. -/// -/// **Known problems:** To be on the conservative side, if there's at least one -/// mutable reference -/// with the output lifetime, this lint will not trigger. In practice, this -/// case is unlikely anyway. -/// -/// **Example:** -/// ```rust -/// fn foo(&Foo) -> &mut Bar { .. } -/// ``` declare_clippy_lint! { + /// **What it does:** This lint checks for functions that take immutable + /// references and return + /// mutable ones. + /// + /// **Why is this bad?** This is trivially unsound, as one can create two + /// mutable references + /// from the same (immutable!) source. This + /// [error](https://github.com/rust-lang/rust/issues/39465) + /// actually lead to an interim Rust release 1.15.1. + /// + /// **Known problems:** To be on the conservative side, if there's at least one + /// mutable reference + /// with the output lifetime, this lint will not trigger. In practice, this + /// case is unlikely anyway. + /// + /// **Example:** + /// ```rust + /// fn foo(&Foo) -> &mut Bar { .. } + /// ``` pub MUT_FROM_REF, correctness, "fns that create mutable refs from immutable ref args" diff --git a/clippy_lints/src/ptr_offset_with_cast.rs b/clippy_lints/src/ptr_offset_with_cast.rs index 4ff3f7643ba4..21c7e7213382 100644 --- a/clippy_lints/src/ptr_offset_with_cast.rs +++ b/clippy_lints/src/ptr_offset_with_cast.rs @@ -3,37 +3,37 @@ use rustc::{declare_tool_lint, hir, lint, lint_array}; use rustc_errors::Applicability; use std::fmt; -/// **What it does:** Checks for usage of the `offset` pointer method with a `usize` casted to an -/// `isize`. -/// -/// **Why is this bad?** If we’re always increasing the pointer address, we can avoid the numeric -/// cast by using the `add` method instead. -/// -/// **Known problems:** None -/// -/// **Example:** -/// ```rust -/// let vec = vec![b'a', b'b', b'c']; -/// let ptr = vec.as_ptr(); -/// let offset = 1_usize; -/// -/// unsafe { -/// ptr.offset(offset as isize); -/// } -/// ``` -/// -/// Could be written: -/// -/// ```rust -/// let vec = vec![b'a', b'b', b'c']; -/// let ptr = vec.as_ptr(); -/// let offset = 1_usize; -/// -/// unsafe { -/// ptr.add(offset); -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for usage of the `offset` pointer method with a `usize` casted to an + /// `isize`. + /// + /// **Why is this bad?** If we’re always increasing the pointer address, we can avoid the numeric + /// cast by using the `add` method instead. + /// + /// **Known problems:** None + /// + /// **Example:** + /// ```rust + /// let vec = vec![b'a', b'b', b'c']; + /// let ptr = vec.as_ptr(); + /// let offset = 1_usize; + /// + /// unsafe { + /// ptr.offset(offset as isize); + /// } + /// ``` + /// + /// Could be written: + /// + /// ```rust + /// let vec = vec![b'a', b'b', b'c']; + /// let ptr = vec.as_ptr(); + /// let offset = 1_usize; + /// + /// unsafe { + /// ptr.add(offset); + /// } + /// ``` pub PTR_OFFSET_WITH_CAST, complexity, "unneeded pointer offset cast" diff --git a/clippy_lints/src/question_mark.rs b/clippy_lints/src/question_mark.rs index cab133943a34..13ae2c29b55f 100644 --- a/clippy_lints/src/question_mark.rs +++ b/clippy_lints/src/question_mark.rs @@ -10,25 +10,25 @@ use crate::utils::paths::*; use crate::utils::{match_def_path, match_type, span_lint_and_then, SpanlessEq}; use rustc_errors::Applicability; -/// **What it does:** Checks for expressions that could be replaced by the question mark operator -/// -/// **Why is this bad?** Question mark usage is more idiomatic -/// -/// **Known problems:** None -/// -/// **Example:** -/// ```rust -/// if option.is_none() { -/// return None; -/// } -/// ``` -/// -/// Could be written: -/// -/// ```rust -/// option?; -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for expressions that could be replaced by the question mark operator + /// + /// **Why is this bad?** Question mark usage is more idiomatic + /// + /// **Known problems:** None + /// + /// **Example:** + /// ```rust + /// if option.is_none() { + /// return None; + /// } + /// ``` + /// + /// Could be written: + /// + /// ```rust + /// option?; + /// ``` pub QUESTION_MARK, style, "checks for expressions that could be replaced by the question mark operator" diff --git a/clippy_lints/src/ranges.rs b/clippy_lints/src/ranges.rs index acd2a3ebc65e..353b1700b45a 100644 --- a/clippy_lints/src/ranges.rs +++ b/clippy_lints/src/ranges.rs @@ -9,77 +9,77 @@ use rustc_errors::Applicability; use syntax::ast::RangeLimits; use syntax::source_map::Spanned; -/// **What it does:** Checks for calling `.step_by(0)` on iterators, -/// which never terminates. -/// -/// **Why is this bad?** This very much looks like an oversight, since with -/// `loop { .. }` there is an obvious better way to endlessly loop. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// for x in (5..5).step_by(0) { -/// .. -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for calling `.step_by(0)` on iterators, + /// which never terminates. + /// + /// **Why is this bad?** This very much looks like an oversight, since with + /// `loop { .. }` there is an obvious better way to endlessly loop. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// for x in (5..5).step_by(0) { + /// .. + /// } + /// ``` pub ITERATOR_STEP_BY_ZERO, correctness, "using `Iterator::step_by(0)`, which produces an infinite iterator" } -/// **What it does:** Checks for zipping a collection with the range of -/// `0.._.len()`. -/// -/// **Why is this bad?** The code is better expressed with `.enumerate()`. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// x.iter().zip(0..x.len()) -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for zipping a collection with the range of + /// `0.._.len()`. + /// + /// **Why is this bad?** The code is better expressed with `.enumerate()`. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// x.iter().zip(0..x.len()) + /// ``` pub RANGE_ZIP_WITH_LEN, complexity, "zipping iterator with a range when `enumerate()` would do" } -/// **What it does:** Checks for exclusive ranges where 1 is added to the -/// upper bound, e.g. `x..(y+1)`. -/// -/// **Why is this bad?** The code is more readable with an inclusive range -/// like `x..=y`. -/// -/// **Known problems:** Will add unnecessary pair of parentheses when the -/// expression is not wrapped in a pair but starts with a opening parenthesis -/// and ends with a closing one. -/// I.e: `let _ = (f()+1)..(f()+1)` results in `let _ = ((f()+1)..=f())`. -/// -/// **Example:** -/// ```rust -/// for x..(y+1) { .. } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for exclusive ranges where 1 is added to the + /// upper bound, e.g. `x..(y+1)`. + /// + /// **Why is this bad?** The code is more readable with an inclusive range + /// like `x..=y`. + /// + /// **Known problems:** Will add unnecessary pair of parentheses when the + /// expression is not wrapped in a pair but starts with a opening parenthesis + /// and ends with a closing one. + /// I.e: `let _ = (f()+1)..(f()+1)` results in `let _ = ((f()+1)..=f())`. + /// + /// **Example:** + /// ```rust + /// for x..(y+1) { .. } + /// ``` pub RANGE_PLUS_ONE, complexity, "`x..(y+1)` reads better as `x..=y`" } -/// **What it does:** Checks for inclusive ranges where 1 is subtracted from -/// the upper bound, e.g. `x..=(y-1)`. -/// -/// **Why is this bad?** The code is more readable with an exclusive range -/// like `x..y`. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// for x..=(y-1) { .. } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for inclusive ranges where 1 is subtracted from + /// the upper bound, e.g. `x..=(y-1)`. + /// + /// **Why is this bad?** The code is more readable with an exclusive range + /// like `x..y`. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// for x..=(y-1) { .. } + /// ``` pub RANGE_MINUS_ONE, complexity, "`x..=(y-1)` reads better as `x..y`" diff --git a/clippy_lints/src/redundant_clone.rs b/clippy_lints/src/redundant_clone.rs index 65276937bc2d..3b74de5159f7 100644 --- a/clippy_lints/src/redundant_clone.rs +++ b/clippy_lints/src/redundant_clone.rs @@ -27,38 +27,38 @@ macro_rules! unwrap_or_continue { }; } -/// **What it does:** Checks for a redudant `clone()` (and its relatives) which clones an owned -/// value that is going to be dropped without further use. -/// -/// **Why is this bad?** It is not always possible for the compiler to eliminate useless -/// allocations and deallocations generated by redundant `clone()`s. -/// -/// **Known problems:** -/// -/// * Suggestions made by this lint could require NLL to be enabled. -/// * False-positive if there is a borrow preventing the value from moving out. -/// -/// ```rust -/// let x = String::new(); -/// -/// let y = &x; -/// -/// foo(x.clone()); // This lint suggests to remove this `clone()` -/// ``` -/// -/// **Example:** -/// ```rust -/// { -/// let x = Foo::new(); -/// call(x.clone()); -/// call(x.clone()); // this can just pass `x` -/// } -/// -/// ["lorem", "ipsum"].join(" ").to_string() -/// -/// Path::new("/a/b").join("c").to_path_buf() -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for a redudant `clone()` (and its relatives) which clones an owned + /// value that is going to be dropped without further use. + /// + /// **Why is this bad?** It is not always possible for the compiler to eliminate useless + /// allocations and deallocations generated by redundant `clone()`s. + /// + /// **Known problems:** + /// + /// * Suggestions made by this lint could require NLL to be enabled. + /// * False-positive if there is a borrow preventing the value from moving out. + /// + /// ```rust + /// let x = String::new(); + /// + /// let y = &x; + /// + /// foo(x.clone()); // This lint suggests to remove this `clone()` + /// ``` + /// + /// **Example:** + /// ```rust + /// { + /// let x = Foo::new(); + /// call(x.clone()); + /// call(x.clone()); // this can just pass `x` + /// } + /// + /// ["lorem", "ipsum"].join(" ").to_string() + /// + /// Path::new("/a/b").join("c").to_path_buf() + /// ``` pub REDUNDANT_CLONE, nursery, "`clone()` of an owned value that is going to be dropped immediately" diff --git a/clippy_lints/src/redundant_field_names.rs b/clippy_lints/src/redundant_field_names.rs index aeb7bb6493c6..d05560653ef8 100644 --- a/clippy_lints/src/redundant_field_names.rs +++ b/clippy_lints/src/redundant_field_names.rs @@ -4,29 +4,29 @@ use rustc::{declare_tool_lint, lint_array}; use rustc_errors::Applicability; use syntax::ast::*; -/// **What it does:** Checks for fields in struct literals where shorthands -/// could be used. -/// -/// **Why is this bad?** If the field and variable names are the same, -/// the field name is redundant. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// let bar: u8 = 123; -/// -/// struct Foo { -/// bar: u8, -/// } -/// -/// let foo = Foo{ bar: bar } -/// ``` -/// the last line can be simplified to -/// ```rust -/// let foo = Foo{ bar } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for fields in struct literals where shorthands + /// could be used. + /// + /// **Why is this bad?** If the field and variable names are the same, + /// the field name is redundant. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// let bar: u8 = 123; + /// + /// struct Foo { + /// bar: u8, + /// } + /// + /// let foo = Foo{ bar: bar } + /// ``` + /// the last line can be simplified to + /// ```rust + /// let foo = Foo{ bar } + /// ``` pub REDUNDANT_FIELD_NAMES, style, "checks for fields in struct literals where shorthands could be used" diff --git a/clippy_lints/src/redundant_pattern_matching.rs b/clippy_lints/src/redundant_pattern_matching.rs index 8f833a893dfc..ebc5e240a954 100644 --- a/clippy_lints/src/redundant_pattern_matching.rs +++ b/clippy_lints/src/redundant_pattern_matching.rs @@ -6,37 +6,37 @@ use rustc_errors::Applicability; use syntax::ast::LitKind; use syntax::ptr::P; -/// **What it does:** Lint for redundant pattern matching over `Result` or -/// `Option` -/// -/// **Why is this bad?** It's more concise and clear to just use the proper -/// utility function -/// -/// **Known problems:** None. -/// -/// **Example:** -/// -/// ```rust -/// if let Ok(_) = Ok::(42) {} -/// if let Err(_) = Err::(42) {} -/// if let None = None::<()> {} -/// if let Some(_) = Some(42) {} -/// match Ok::(42) { -/// Ok(_) => true, -/// Err(_) => false, -/// }; -/// ``` -/// -/// The more idiomatic use would be: -/// -/// ```rust -/// if Ok::(42).is_ok() {} -/// if Err::(42).is_err() {} -/// if None::<()>.is_none() {} -/// if Some(42).is_some() {} -/// Ok::(42).is_ok(); -/// ``` declare_clippy_lint! { + /// **What it does:** Lint for redundant pattern matching over `Result` or + /// `Option` + /// + /// **Why is this bad?** It's more concise and clear to just use the proper + /// utility function + /// + /// **Known problems:** None. + /// + /// **Example:** + /// + /// ```rust + /// if let Ok(_) = Ok::(42) {} + /// if let Err(_) = Err::(42) {} + /// if let None = None::<()> {} + /// if let Some(_) = Some(42) {} + /// match Ok::(42) { + /// Ok(_) => true, + /// Err(_) => false, + /// }; + /// ``` + /// + /// The more idiomatic use would be: + /// + /// ```rust + /// if Ok::(42).is_ok() {} + /// if Err::(42).is_err() {} + /// if None::<()>.is_none() {} + /// if Some(42).is_some() {} + /// Ok::(42).is_ok(); + /// ``` pub REDUNDANT_PATTERN_MATCHING, style, "use the proper utility function avoiding an `if let`" diff --git a/clippy_lints/src/reference.rs b/clippy_lints/src/reference.rs index 3a5af498017d..d5447027acba 100644 --- a/clippy_lints/src/reference.rs +++ b/clippy_lints/src/reference.rs @@ -5,20 +5,20 @@ use rustc::{declare_tool_lint, lint_array}; use rustc_errors::Applicability; use syntax::ast::{Expr, ExprKind, UnOp}; -/// **What it does:** Checks for usage of `*&` and `*&mut` in expressions. -/// -/// **Why is this bad?** Immediately dereferencing a reference is no-op and -/// makes the code less clear. -/// -/// **Known problems:** Multiple dereference/addrof pairs are not handled so -/// the suggested fix for `x = **&&y` is `x = *&y`, which is still incorrect. -/// -/// **Example:** -/// ```rust -/// let a = f(*&mut b); -/// let c = *&d; -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for usage of `*&` and `*&mut` in expressions. + /// + /// **Why is this bad?** Immediately dereferencing a reference is no-op and + /// makes the code less clear. + /// + /// **Known problems:** Multiple dereference/addrof pairs are not handled so + /// the suggested fix for `x = **&&y` is `x = *&y`, which is still incorrect. + /// + /// **Example:** + /// ```rust + /// let a = f(*&mut b); + /// let c = *&d; + /// ``` pub DEREF_ADDROF, complexity, "use of `*&` or `*&mut` in an expression" @@ -64,19 +64,19 @@ impl EarlyLintPass for Pass { } } -/// **What it does:** Checks for references in expressions that use -/// auto dereference. -/// -/// **Why is this bad?** The reference is a no-op and is automatically -/// dereferenced by the compiler and makes the code less clear. -/// -/// **Example:** -/// ```rust -/// struct Point(u32, u32); -/// let point = Foo(30, 20); -/// let x = (&point).x; -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for references in expressions that use + /// auto dereference. + /// + /// **Why is this bad?** The reference is a no-op and is automatically + /// dereferenced by the compiler and makes the code less clear. + /// + /// **Example:** + /// ```rust + /// struct Point(u32, u32); + /// let point = Foo(30, 20); + /// let x = (&point).x; + /// ``` pub REF_IN_DEREF, complexity, "Use of reference in auto dereference expression." diff --git a/clippy_lints/src/regex.rs b/clippy_lints/src/regex.rs index eaaa6b93b3b9..a875256870d1 100644 --- a/clippy_lints/src/regex.rs +++ b/clippy_lints/src/regex.rs @@ -10,57 +10,57 @@ use std::convert::TryFrom; use syntax::ast::{LitKind, StrStyle}; use syntax::source_map::{BytePos, Span}; -/// **What it does:** Checks [regex](https://crates.io/crates/regex) creation -/// (with `Regex::new`,`RegexBuilder::new` or `RegexSet::new`) for correct -/// regex syntax. -/// -/// **Why is this bad?** This will lead to a runtime panic. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// Regex::new("|") -/// ``` declare_clippy_lint! { + /// **What it does:** Checks [regex](https://crates.io/crates/regex) creation + /// (with `Regex::new`,`RegexBuilder::new` or `RegexSet::new`) for correct + /// regex syntax. + /// + /// **Why is this bad?** This will lead to a runtime panic. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// Regex::new("|") + /// ``` pub INVALID_REGEX, correctness, "invalid regular expressions" } -/// **What it does:** Checks for trivial [regex](https://crates.io/crates/regex) -/// creation (with `Regex::new`, `RegexBuilder::new` or `RegexSet::new`). -/// -/// **Why is this bad?** Matching the regex can likely be replaced by `==` or -/// `str::starts_with`, `str::ends_with` or `std::contains` or other `str` -/// methods. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// Regex::new("^foobar") -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for trivial [regex](https://crates.io/crates/regex) + /// creation (with `Regex::new`, `RegexBuilder::new` or `RegexSet::new`). + /// + /// **Why is this bad?** Matching the regex can likely be replaced by `==` or + /// `str::starts_with`, `str::ends_with` or `std::contains` or other `str` + /// methods. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// Regex::new("^foobar") + /// ``` pub TRIVIAL_REGEX, style, "trivial regular expressions" } -/// **What it does:** Checks for usage of `regex!(_)` which (as of now) is -/// usually slower than `Regex::new(_)` unless called in a loop (which is a bad -/// idea anyway). -/// -/// **Why is this bad?** Performance, at least for now. The macro version is -/// likely to catch up long-term, but for now the dynamic version is faster. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// regex!("foo|bar") -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for usage of `regex!(_)` which (as of now) is + /// usually slower than `Regex::new(_)` unless called in a loop (which is a bad + /// idea anyway). + /// + /// **Why is this bad?** Performance, at least for now. The macro version is + /// likely to catch up long-term, but for now the dynamic version is faster. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// regex!("foo|bar") + /// ``` pub REGEX_MACRO, style, "use of `regex!(_)` instead of `Regex::new(_)`" diff --git a/clippy_lints/src/replace_consts.rs b/clippy_lints/src/replace_consts.rs index 47168445ad3c..10e339eeb023 100644 --- a/clippy_lints/src/replace_consts.rs +++ b/clippy_lints/src/replace_consts.rs @@ -6,24 +6,24 @@ use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use rustc::{declare_tool_lint, lint_array}; use rustc_errors::Applicability; -/// **What it does:** Checks for usage of `ATOMIC_X_INIT`, `ONCE_INIT`, and -/// `uX/iX::MIN/MAX`. -/// -/// **Why is this bad?** `const fn`s exist -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// static FOO: AtomicIsize = ATOMIC_ISIZE_INIT; -/// ``` -/// -/// Could be written: -/// -/// ```rust -/// static FOO: AtomicIsize = AtomicIsize::new(0); -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for usage of `ATOMIC_X_INIT`, `ONCE_INIT`, and + /// `uX/iX::MIN/MAX`. + /// + /// **Why is this bad?** `const fn`s exist + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// static FOO: AtomicIsize = ATOMIC_ISIZE_INIT; + /// ``` + /// + /// Could be written: + /// + /// ```rust + /// static FOO: AtomicIsize = AtomicIsize::new(0); + /// ``` pub REPLACE_CONSTS, pedantic, "Lint usages of standard library `const`s that could be replaced by `const fn`s" diff --git a/clippy_lints/src/returns.rs b/clippy_lints/src/returns.rs index 71ef3e4bfa03..2ea4b8daf8c9 100644 --- a/clippy_lints/src/returns.rs +++ b/clippy_lints/src/returns.rs @@ -8,75 +8,75 @@ use syntax::source_map::Span; use syntax::visit::FnKind; use syntax_pos::BytePos; -/// **What it does:** Checks for return statements at the end of a block. -/// -/// **Why is this bad?** Removing the `return` and semicolon will make the code -/// more rusty. -/// -/// **Known problems:** If the computation returning the value borrows a local -/// variable, removing the `return` may run afoul of the borrow checker. -/// -/// **Example:** -/// ```rust -/// fn foo(x: usize) { -/// return x; -/// } -/// ``` -/// simplify to -/// ```rust -/// fn foo(x: usize) { -/// x -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for return statements at the end of a block. + /// + /// **Why is this bad?** Removing the `return` and semicolon will make the code + /// more rusty. + /// + /// **Known problems:** If the computation returning the value borrows a local + /// variable, removing the `return` may run afoul of the borrow checker. + /// + /// **Example:** + /// ```rust + /// fn foo(x: usize) { + /// return x; + /// } + /// ``` + /// simplify to + /// ```rust + /// fn foo(x: usize) { + /// x + /// } + /// ``` pub NEEDLESS_RETURN, style, "using a return statement like `return expr;` where an expression would suffice" } -/// **What it does:** Checks for `let`-bindings, which are subsequently -/// returned. -/// -/// **Why is this bad?** It is just extraneous code. Remove it to make your code -/// more rusty. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// fn foo() -> String { -/// let x = String::new(); -/// x -/// } -/// ``` -/// instead, use -/// ``` -/// fn foo() -> String { -/// String::new() -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for `let`-bindings, which are subsequently + /// returned. + /// + /// **Why is this bad?** It is just extraneous code. Remove it to make your code + /// more rusty. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// fn foo() -> String { + /// let x = String::new(); + /// x + /// } + /// ``` + /// instead, use + /// ``` + /// fn foo() -> String { + /// String::new() + /// } + /// ``` pub LET_AND_RETURN, style, "creating a let-binding and then immediately returning it like `let x = expr; x` at the end of a block" } -/// **What it does:** Checks for unit (`()`) expressions that can be removed. -/// -/// **Why is this bad?** Such expressions add no value, but can make the code -/// less readable. Depending on formatting they can make a `break` or `return` -/// statement look like a function call. -/// -/// **Known problems:** The lint currently misses unit return types in types, -/// e.g. the `F` in `fn generic_unit ()>(f: F) { .. }`. -/// -/// **Example:** -/// ```rust -/// fn return_unit() -> () { -/// () -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for unit (`()`) expressions that can be removed. + /// + /// **Why is this bad?** Such expressions add no value, but can make the code + /// less readable. Depending on formatting they can make a `break` or `return` + /// statement look like a function call. + /// + /// **Known problems:** The lint currently misses unit return types in types, + /// e.g. the `F` in `fn generic_unit ()>(f: F) { .. }`. + /// + /// **Example:** + /// ```rust + /// fn return_unit() -> () { + /// () + /// } + /// ``` pub UNUSED_UNIT, style, "needless unit expression" diff --git a/clippy_lints/src/serde_api.rs b/clippy_lints/src/serde_api.rs index 8090ed7fbcff..e9479af54190 100644 --- a/clippy_lints/src/serde_api.rs +++ b/clippy_lints/src/serde_api.rs @@ -3,16 +3,16 @@ use rustc::hir::*; use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use rustc::{declare_tool_lint, lint_array}; -/// **What it does:** Checks for mis-uses of the serde API. -/// -/// **Why is this bad?** Serde is very finnicky about how its API should be -/// used, but the type system can't be used to enforce it (yet?). -/// -/// **Known problems:** None. -/// -/// **Example:** Implementing `Visitor::visit_string` but not -/// `Visitor::visit_str`. declare_clippy_lint! { + /// **What it does:** Checks for mis-uses of the serde API. + /// + /// **Why is this bad?** Serde is very finnicky about how its API should be + /// used, but the type system can't be used to enforce it (yet?). + /// + /// **Known problems:** None. + /// + /// **Example:** Implementing `Visitor::visit_string` but not + /// `Visitor::visit_str`. pub SERDE_API_MISUSE, correctness, "various things that will negatively affect your serde experience" diff --git a/clippy_lints/src/shadow.rs b/clippy_lints/src/shadow.rs index 40e76c2c089b..9572dc7acb5a 100644 --- a/clippy_lints/src/shadow.rs +++ b/clippy_lints/src/shadow.rs @@ -7,69 +7,69 @@ use rustc::ty; use rustc::{declare_tool_lint, lint_array}; use syntax::source_map::Span; -/// **What it does:** Checks for bindings that shadow other bindings already in -/// scope, while just changing reference level or mutability. -/// -/// **Why is this bad?** Not much, in fact it's a very common pattern in Rust -/// code. Still, some may opt to avoid it in their code base, they can set this -/// lint to `Warn`. -/// -/// **Known problems:** This lint, as the other shadowing related lints, -/// currently only catches very simple patterns. -/// -/// **Example:** -/// ```rust -/// let x = &x; -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for bindings that shadow other bindings already in + /// scope, while just changing reference level or mutability. + /// + /// **Why is this bad?** Not much, in fact it's a very common pattern in Rust + /// code. Still, some may opt to avoid it in their code base, they can set this + /// lint to `Warn`. + /// + /// **Known problems:** This lint, as the other shadowing related lints, + /// currently only catches very simple patterns. + /// + /// **Example:** + /// ```rust + /// let x = &x; + /// ``` pub SHADOW_SAME, restriction, "rebinding a name to itself, e.g. `let mut x = &mut x`" } -/// **What it does:** Checks for bindings that shadow other bindings already in -/// scope, while reusing the original value. -/// -/// **Why is this bad?** Not too much, in fact it's a common pattern in Rust -/// code. Still, some argue that name shadowing like this hurts readability, -/// because a value may be bound to different things depending on position in -/// the code. -/// -/// **Known problems:** This lint, as the other shadowing related lints, -/// currently only catches very simple patterns. -/// -/// **Example:** -/// ```rust -/// let x = x + 1; -/// ``` -/// use different variable name: -/// ```rust -/// let y = x + 1; -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for bindings that shadow other bindings already in + /// scope, while reusing the original value. + /// + /// **Why is this bad?** Not too much, in fact it's a common pattern in Rust + /// code. Still, some argue that name shadowing like this hurts readability, + /// because a value may be bound to different things depending on position in + /// the code. + /// + /// **Known problems:** This lint, as the other shadowing related lints, + /// currently only catches very simple patterns. + /// + /// **Example:** + /// ```rust + /// let x = x + 1; + /// ``` + /// use different variable name: + /// ```rust + /// let y = x + 1; + /// ``` pub SHADOW_REUSE, restriction, "rebinding a name to an expression that re-uses the original value, e.g. `let x = x + 1`" } -/// **What it does:** Checks for bindings that shadow other bindings already in -/// scope, either without a initialization or with one that does not even use -/// the original value. -/// -/// **Why is this bad?** Name shadowing can hurt readability, especially in -/// large code bases, because it is easy to lose track of the active binding at -/// any place in the code. This can be alleviated by either giving more specific -/// names to bindings or introducing more scopes to contain the bindings. -/// -/// **Known problems:** This lint, as the other shadowing related lints, -/// currently only catches very simple patterns. -/// -/// **Example:** -/// ```rust -/// let x = y; -/// let x = z; // shadows the earlier binding -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for bindings that shadow other bindings already in + /// scope, either without a initialization or with one that does not even use + /// the original value. + /// + /// **Why is this bad?** Name shadowing can hurt readability, especially in + /// large code bases, because it is easy to lose track of the active binding at + /// any place in the code. This can be alleviated by either giving more specific + /// names to bindings or introducing more scopes to contain the bindings. + /// + /// **Known problems:** This lint, as the other shadowing related lints, + /// currently only catches very simple patterns. + /// + /// **Example:** + /// ```rust + /// let x = y; + /// let x = z; // shadows the earlier binding + /// ``` pub SHADOW_UNRELATED, pedantic, "rebinding a name without even using the original value" diff --git a/clippy_lints/src/slow_vector_initialization.rs b/clippy_lints/src/slow_vector_initialization.rs index e8f480a22c91..7b4fd7732129 100644 --- a/clippy_lints/src/slow_vector_initialization.rs +++ b/clippy_lints/src/slow_vector_initialization.rs @@ -9,22 +9,22 @@ use rustc_errors::Applicability; use syntax::ast::LitKind; use syntax_pos::symbol::Symbol; -/// **What it does:** Checks slow zero-filled vector initialization -/// -/// **Why is this bad?** These structures are non-idiomatic and less efficient than simply using -/// `vec![0; len]`. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// let mut vec1 = Vec::with_capacity(len); -/// vec1.resize(len, 0); -/// -/// let mut vec2 = Vec::with_capacity(len); -/// vec2.extend(repeat(0).take(len)) -/// ``` declare_clippy_lint! { + /// **What it does:** Checks slow zero-filled vector initialization + /// + /// **Why is this bad?** These structures are non-idiomatic and less efficient than simply using + /// `vec![0; len]`. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// let mut vec1 = Vec::with_capacity(len); + /// vec1.resize(len, 0); + /// + /// let mut vec2 = Vec::with_capacity(len); + /// vec2.extend(repeat(0).take(len)) + /// ``` pub SLOW_VECTOR_INITIALIZATION, perf, "slow vector initialization" diff --git a/clippy_lints/src/strings.rs b/clippy_lints/src/strings.rs index ba085396e7ae..0f6603f9d280 100644 --- a/clippy_lints/src/strings.rs +++ b/clippy_lints/src/strings.rs @@ -6,67 +6,67 @@ use rustc::{declare_tool_lint, lint_array}; use rustc_errors::Applicability; use syntax::source_map::Spanned; -/// **What it does:** Checks for string appends of the form `x = x + y` (without -/// `let`!). -/// -/// **Why is this bad?** It's not really bad, but some people think that the -/// `.push_str(_)` method is more readable. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// -/// ```rust -/// let mut x = "Hello".to_owned(); -/// x = x + ", World"; -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for string appends of the form `x = x + y` (without + /// `let`!). + /// + /// **Why is this bad?** It's not really bad, but some people think that the + /// `.push_str(_)` method is more readable. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// + /// ```rust + /// let mut x = "Hello".to_owned(); + /// x = x + ", World"; + /// ``` pub STRING_ADD_ASSIGN, pedantic, "using `x = x + ..` where x is a `String` instead of `push_str()`" } -/// **What it does:** Checks for all instances of `x + _` where `x` is of type -/// `String`, but only if [`string_add_assign`](#string_add_assign) does *not* -/// match. -/// -/// **Why is this bad?** It's not bad in and of itself. However, this particular -/// `Add` implementation is asymmetric (the other operand need not be `String`, -/// but `x` does), while addition as mathematically defined is symmetric, also -/// the `String::push_str(_)` function is a perfectly good replacement. -/// Therefore some dislike it and wish not to have it in their code. -/// -/// That said, other people think that string addition, having a long tradition -/// in other languages is actually fine, which is why we decided to make this -/// particular lint `allow` by default. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// -/// ```rust -/// let x = "Hello".to_owned(); -/// x + ", World" -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for all instances of `x + _` where `x` is of type + /// `String`, but only if [`string_add_assign`](#string_add_assign) does *not* + /// match. + /// + /// **Why is this bad?** It's not bad in and of itself. However, this particular + /// `Add` implementation is asymmetric (the other operand need not be `String`, + /// but `x` does), while addition as mathematically defined is symmetric, also + /// the `String::push_str(_)` function is a perfectly good replacement. + /// Therefore some dislike it and wish not to have it in their code. + /// + /// That said, other people think that string addition, having a long tradition + /// in other languages is actually fine, which is why we decided to make this + /// particular lint `allow` by default. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// + /// ```rust + /// let x = "Hello".to_owned(); + /// x + ", World" + /// ``` pub STRING_ADD, restriction, "using `x + ..` where x is a `String` instead of `push_str()`" } -/// **What it does:** Checks for the `as_bytes` method called on string literals -/// that contain only ASCII characters. -/// -/// **Why is this bad?** Byte string literals (e.g. `b"foo"`) can be used -/// instead. They are shorter but less discoverable than `as_bytes()`. -/// -/// **Known Problems:** None. -/// -/// **Example:** -/// ```rust -/// let bs = "a byte string".as_bytes(); -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for the `as_bytes` method called on string literals + /// that contain only ASCII characters. + /// + /// **Why is this bad?** Byte string literals (e.g. `b"foo"`) can be used + /// instead. They are shorter but less discoverable than `as_bytes()`. + /// + /// **Known Problems:** None. + /// + /// **Example:** + /// ```rust + /// let bs = "a byte string".as_bytes(); + /// ``` pub STRING_LIT_AS_BYTES, style, "calling `as_bytes` on a string literal instead of using a byte string literal" diff --git a/clippy_lints/src/suspicious_trait_impl.rs b/clippy_lints/src/suspicious_trait_impl.rs index 135ffd772db3..cb7fc0fee80f 100644 --- a/clippy_lints/src/suspicious_trait_impl.rs +++ b/clippy_lints/src/suspicious_trait_impl.rs @@ -5,45 +5,45 @@ use rustc::hir::intravisit::{walk_expr, NestedVisitorMap, Visitor}; use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use rustc::{declare_tool_lint, lint_array}; -/// **What it does:** Lints for suspicious operations in impls of arithmetic operators, e.g. -/// subtracting elements in an Add impl. -/// -/// **Why this is bad?** This is probably a typo or copy-and-paste error and not intended. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// impl Add for Foo { -/// type Output = Foo; -/// -/// fn add(self, other: Foo) -> Foo { -/// Foo(self.0 - other.0) -/// } -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Lints for suspicious operations in impls of arithmetic operators, e.g. + /// subtracting elements in an Add impl. + /// + /// **Why this is bad?** This is probably a typo or copy-and-paste error and not intended. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// impl Add for Foo { + /// type Output = Foo; + /// + /// fn add(self, other: Foo) -> Foo { + /// Foo(self.0 - other.0) + /// } + /// } + /// ``` pub SUSPICIOUS_ARITHMETIC_IMPL, correctness, "suspicious use of operators in impl of arithmetic trait" } -/// **What it does:** Lints for suspicious operations in impls of OpAssign, e.g. -/// subtracting elements in an AddAssign impl. -/// -/// **Why this is bad?** This is probably a typo or copy-and-paste error and not intended. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// impl AddAssign for Foo { -/// fn add_assign(&mut self, other: Foo) { -/// *self = *self - other; -/// } -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Lints for suspicious operations in impls of OpAssign, e.g. + /// subtracting elements in an AddAssign impl. + /// + /// **Why this is bad?** This is probably a typo or copy-and-paste error and not intended. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// impl AddAssign for Foo { + /// fn add_assign(&mut self, other: Foo) { + /// *self = *self - other; + /// } + /// } + /// ``` pub SUSPICIOUS_OP_ASSIGN_IMPL, correctness, "suspicious use of operators in impl of OpAssign trait" diff --git a/clippy_lints/src/swap.rs b/clippy_lints/src/swap.rs index 7b532cdb1725..c7003cfb9f03 100644 --- a/clippy_lints/src/swap.rs +++ b/clippy_lints/src/swap.rs @@ -10,41 +10,41 @@ use rustc::ty; use rustc::{declare_tool_lint, lint_array}; use rustc_errors::Applicability; -/// **What it does:** Checks for manual swapping. -/// -/// **Why is this bad?** The `std::mem::swap` function exposes the intent better -/// without deinitializing or copying either variable. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust,ignore -/// let t = b; -/// b = a; -/// a = t; -/// ``` -/// Use std::mem::swap(): -/// ```rust -/// std::mem::swap(&mut a, &mut b); -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for manual swapping. + /// + /// **Why is this bad?** The `std::mem::swap` function exposes the intent better + /// without deinitializing or copying either variable. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust,ignore + /// let t = b; + /// b = a; + /// a = t; + /// ``` + /// Use std::mem::swap(): + /// ```rust + /// std::mem::swap(&mut a, &mut b); + /// ``` pub MANUAL_SWAP, complexity, "manual swap of two variables" } -/// **What it does:** Checks for `foo = bar; bar = foo` sequences. -/// -/// **Why is this bad?** This looks like a failed attempt to swap. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust,ignore -/// a = b; -/// b = a; -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for `foo = bar; bar = foo` sequences. + /// + /// **Why is this bad?** This looks like a failed attempt to swap. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust,ignore + /// a = b; + /// b = a; + /// ``` pub ALMOST_SWAPPED, correctness, "`foo = bar; bar = foo` sequence" diff --git a/clippy_lints/src/temporary_assignment.rs b/clippy_lints/src/temporary_assignment.rs index 0d8cfedf4144..a6126f372828 100644 --- a/clippy_lints/src/temporary_assignment.rs +++ b/clippy_lints/src/temporary_assignment.rs @@ -5,19 +5,19 @@ use rustc::hir::{Expr, ExprKind}; use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use rustc::{declare_tool_lint, lint_array}; -/// **What it does:** Checks for construction of a structure or tuple just to -/// assign a value in it. -/// -/// **Why is this bad?** Readability. If the structure is only created to be -/// updated, why not write the structure you want in the first place? -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// (0, 0).0 = 1 -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for construction of a structure or tuple just to + /// assign a value in it. + /// + /// **Why is this bad?** Readability. If the structure is only created to be + /// updated, why not write the structure you want in the first place? + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// (0, 0).0 = 1 + /// ``` pub TEMPORARY_ASSIGNMENT, complexity, "assignments to temporaries" diff --git a/clippy_lints/src/transmute.rs b/clippy_lints/src/transmute.rs index 513db90477df..aa4f808ee3f1 100644 --- a/clippy_lints/src/transmute.rs +++ b/clippy_lints/src/transmute.rs @@ -9,196 +9,196 @@ use rustc_errors::Applicability; use std::borrow::Cow; use syntax::ast; -/// **What it does:** Checks for transmutes that can't ever be correct on any -/// architecture. -/// -/// **Why is this bad?** It's basically guaranteed to be undefined behaviour. -/// -/// **Known problems:** When accessing C, users might want to store pointer -/// sized objects in `extradata` arguments to save an allocation. -/// -/// **Example:** -/// ```rust -/// let ptr: *const T = core::intrinsics::transmute('x') -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for transmutes that can't ever be correct on any + /// architecture. + /// + /// **Why is this bad?** It's basically guaranteed to be undefined behaviour. + /// + /// **Known problems:** When accessing C, users might want to store pointer + /// sized objects in `extradata` arguments to save an allocation. + /// + /// **Example:** + /// ```rust + /// let ptr: *const T = core::intrinsics::transmute('x') + /// ``` pub WRONG_TRANSMUTE, correctness, "transmutes that are confusing at best, undefined behaviour at worst and always useless" } -/// **What it does:** Checks for transmutes to the original type of the object -/// and transmutes that could be a cast. -/// -/// **Why is this bad?** Readability. The code tricks people into thinking that -/// something complex is going on. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// core::intrinsics::transmute(t) // where the result type is the same as `t`'s -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for transmutes to the original type of the object + /// and transmutes that could be a cast. + /// + /// **Why is this bad?** Readability. The code tricks people into thinking that + /// something complex is going on. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// core::intrinsics::transmute(t) // where the result type is the same as `t`'s + /// ``` pub USELESS_TRANSMUTE, complexity, "transmutes that have the same to and from types or could be a cast/coercion" } -/// **What it does:** Checks for transmutes between a type `T` and `*T`. -/// -/// **Why is this bad?** It's easy to mistakenly transmute between a type and a -/// pointer to that type. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// core::intrinsics::transmute(t) // where the result type is the same as -/// // `*t` or `&t`'s -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for transmutes between a type `T` and `*T`. + /// + /// **Why is this bad?** It's easy to mistakenly transmute between a type and a + /// pointer to that type. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// core::intrinsics::transmute(t) // where the result type is the same as + /// // `*t` or `&t`'s + /// ``` pub CROSSPOINTER_TRANSMUTE, complexity, "transmutes that have to or from types that are a pointer to the other" } -/// **What it does:** Checks for transmutes from a pointer to a reference. -/// -/// **Why is this bad?** This can always be rewritten with `&` and `*`. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// let _: &T = std::mem::transmute(p); // where p: *const T -/// -/// // can be written: -/// let _: &T = &*p; -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for transmutes from a pointer to a reference. + /// + /// **Why is this bad?** This can always be rewritten with `&` and `*`. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// let _: &T = std::mem::transmute(p); // where p: *const T + /// + /// // can be written: + /// let _: &T = &*p; + /// ``` pub TRANSMUTE_PTR_TO_REF, complexity, "transmutes from a pointer to a reference type" } -/// **What it does:** Checks for transmutes from an integer to a `char`. -/// -/// **Why is this bad?** Not every integer is a Unicode scalar value. -/// -/// **Known problems:** -/// - [`from_u32`] which this lint suggests using is slower than `transmute` -/// as it needs to validate the input. -/// If you are certain that the input is always a valid Unicode scalar value, -/// use [`from_u32_unchecked`] which is as fast as `transmute` -/// but has a semantically meaningful name. -/// - You might want to handle `None` returned from [`from_u32`] instead of calling `unwrap`. -/// -/// [`from_u32`]: https://doc.rust-lang.org/std/char/fn.from_u32.html -/// [`from_u32_unchecked`]: https://doc.rust-lang.org/std/char/fn.from_u32_unchecked.html -/// -/// **Example:** -/// ```rust -/// let _: char = std::mem::transmute(x); // where x: u32 -/// -/// // should be: -/// let _ = std::char::from_u32(x).unwrap(); -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for transmutes from an integer to a `char`. + /// + /// **Why is this bad?** Not every integer is a Unicode scalar value. + /// + /// **Known problems:** + /// - [`from_u32`] which this lint suggests using is slower than `transmute` + /// as it needs to validate the input. + /// If you are certain that the input is always a valid Unicode scalar value, + /// use [`from_u32_unchecked`] which is as fast as `transmute` + /// but has a semantically meaningful name. + /// - You might want to handle `None` returned from [`from_u32`] instead of calling `unwrap`. + /// + /// [`from_u32`]: https://doc.rust-lang.org/std/char/fn.from_u32.html + /// [`from_u32_unchecked`]: https://doc.rust-lang.org/std/char/fn.from_u32_unchecked.html + /// + /// **Example:** + /// ```rust + /// let _: char = std::mem::transmute(x); // where x: u32 + /// + /// // should be: + /// let _ = std::char::from_u32(x).unwrap(); + /// ``` pub TRANSMUTE_INT_TO_CHAR, complexity, "transmutes from an integer to a `char`" } -/// **What it does:** Checks for transmutes from a `&[u8]` to a `&str`. -/// -/// **Why is this bad?** Not every byte slice is a valid UTF-8 string. -/// -/// **Known problems:** -/// - [`from_utf8`] which this lint suggests using is slower than `transmute` -/// as it needs to validate the input. -/// If you are certain that the input is always a valid UTF-8, -/// use [`from_utf8_unchecked`] which is as fast as `transmute` -/// but has a semantically meaningful name. -/// - You might want to handle errors returned from [`from_utf8`] instead of calling `unwrap`. -/// -/// [`from_utf8`]: https://doc.rust-lang.org/std/str/fn.from_utf8.html -/// [`from_utf8_unchecked`]: https://doc.rust-lang.org/std/str/fn.from_utf8_unchecked.html -/// -/// **Example:** -/// ```rust -/// let _: &str = std::mem::transmute(b); // where b: &[u8] -/// -/// // should be: -/// let _ = std::str::from_utf8(b).unwrap(); -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for transmutes from a `&[u8]` to a `&str`. + /// + /// **Why is this bad?** Not every byte slice is a valid UTF-8 string. + /// + /// **Known problems:** + /// - [`from_utf8`] which this lint suggests using is slower than `transmute` + /// as it needs to validate the input. + /// If you are certain that the input is always a valid UTF-8, + /// use [`from_utf8_unchecked`] which is as fast as `transmute` + /// but has a semantically meaningful name. + /// - You might want to handle errors returned from [`from_utf8`] instead of calling `unwrap`. + /// + /// [`from_utf8`]: https://doc.rust-lang.org/std/str/fn.from_utf8.html + /// [`from_utf8_unchecked`]: https://doc.rust-lang.org/std/str/fn.from_utf8_unchecked.html + /// + /// **Example:** + /// ```rust + /// let _: &str = std::mem::transmute(b); // where b: &[u8] + /// + /// // should be: + /// let _ = std::str::from_utf8(b).unwrap(); + /// ``` pub TRANSMUTE_BYTES_TO_STR, complexity, "transmutes from a `&[u8]` to a `&str`" } -/// **What it does:** Checks for transmutes from an integer to a `bool`. -/// -/// **Why is this bad?** This might result in an invalid in-memory representation of a `bool`. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// let _: bool = std::mem::transmute(x); // where x: u8 -/// -/// // should be: -/// let _: bool = x != 0; -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for transmutes from an integer to a `bool`. + /// + /// **Why is this bad?** This might result in an invalid in-memory representation of a `bool`. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// let _: bool = std::mem::transmute(x); // where x: u8 + /// + /// // should be: + /// let _: bool = x != 0; + /// ``` pub TRANSMUTE_INT_TO_BOOL, complexity, "transmutes from an integer to a `bool`" } -/// **What it does:** Checks for transmutes from an integer to a float. -/// -/// **Why is this bad?** Transmutes are dangerous and error-prone, whereas `from_bits` is intuitive -/// and safe. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// let _: f32 = std::mem::transmute(x); // where x: u32 -/// -/// // should be: -/// let _: f32 = f32::from_bits(x); -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for transmutes from an integer to a float. + /// + /// **Why is this bad?** Transmutes are dangerous and error-prone, whereas `from_bits` is intuitive + /// and safe. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// let _: f32 = std::mem::transmute(x); // where x: u32 + /// + /// // should be: + /// let _: f32 = f32::from_bits(x); + /// ``` pub TRANSMUTE_INT_TO_FLOAT, complexity, "transmutes from an integer to a float" } -/// **What it does:** Checks for transmutes from a pointer to a pointer, or -/// from a reference to a reference. -/// -/// **Why is this bad?** Transmutes are dangerous, and these can instead be -/// written as casts. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// let ptr = &1u32 as *const u32; -/// unsafe { -/// // pointer-to-pointer transmute -/// let _: *const f32 = std::mem::transmute(ptr); -/// // ref-ref transmute -/// let _: &f32 = std::mem::transmute(&1u32); -/// } -/// // These can be respectively written: -/// let _ = ptr as *const f32 -/// let _ = unsafe{ &*(&1u32 as *const u32 as *const f32) }; -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for transmutes from a pointer to a pointer, or + /// from a reference to a reference. + /// + /// **Why is this bad?** Transmutes are dangerous, and these can instead be + /// written as casts. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// let ptr = &1u32 as *const u32; + /// unsafe { + /// // pointer-to-pointer transmute + /// let _: *const f32 = std::mem::transmute(ptr); + /// // ref-ref transmute + /// let _: &f32 = std::mem::transmute(&1u32); + /// } + /// // These can be respectively written: + /// let _ = ptr as *const f32 + /// let _ = unsafe{ &*(&1u32 as *const u32 as *const f32) }; + /// ``` pub TRANSMUTE_PTR_TO_PTR, complexity, "transmutes from a pointer to a pointer / a reference to a reference" diff --git a/clippy_lints/src/trivially_copy_pass_by_ref.rs b/clippy_lints/src/trivially_copy_pass_by_ref.rs index 5c1d637874c6..d246a7911662 100644 --- a/clippy_lints/src/trivially_copy_pass_by_ref.rs +++ b/clippy_lints/src/trivially_copy_pass_by_ref.rs @@ -15,39 +15,39 @@ use rustc_target::abi::LayoutOf; use rustc_target::spec::abi::Abi; use syntax_pos::Span; -/// **What it does:** Checks for functions taking arguments by reference, where -/// the argument type is `Copy` and small enough to be more efficient to always -/// pass by value. -/// -/// **Why is this bad?** In many calling conventions instances of structs will -/// be passed through registers if they fit into two or less general purpose -/// registers. -/// -/// **Known problems:** This lint is target register size dependent, it is -/// limited to 32-bit to try and reduce portability problems between 32 and -/// 64-bit, but if you are compiling for 8 or 16-bit targets then the limit -/// will be different. -/// -/// The configuration option `trivial_copy_size_limit` can be set to override -/// this limit for a project. -/// -/// This lint attempts to allow passing arguments by reference if a reference -/// to that argument is returned. This is implemented by comparing the lifetime -/// of the argument and return value for equality. However, this can cause -/// false positives in cases involving multiple lifetimes that are bounded by -/// each other. -/// -/// **Example:** -/// ```rust -/// fn foo(v: &u32) { -/// assert_eq!(v, 42); -/// } -/// // should be -/// fn foo(v: u32) { -/// assert_eq!(v, 42); -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for functions taking arguments by reference, where + /// the argument type is `Copy` and small enough to be more efficient to always + /// pass by value. + /// + /// **Why is this bad?** In many calling conventions instances of structs will + /// be passed through registers if they fit into two or less general purpose + /// registers. + /// + /// **Known problems:** This lint is target register size dependent, it is + /// limited to 32-bit to try and reduce portability problems between 32 and + /// 64-bit, but if you are compiling for 8 or 16-bit targets then the limit + /// will be different. + /// + /// The configuration option `trivial_copy_size_limit` can be set to override + /// this limit for a project. + /// + /// This lint attempts to allow passing arguments by reference if a reference + /// to that argument is returned. This is implemented by comparing the lifetime + /// of the argument and return value for equality. However, this can cause + /// false positives in cases involving multiple lifetimes that are bounded by + /// each other. + /// + /// **Example:** + /// ```rust + /// fn foo(v: &u32) { + /// assert_eq!(v, 42); + /// } + /// // should be + /// fn foo(v: u32) { + /// assert_eq!(v, 42); + /// } + /// ``` pub TRIVIALLY_COPY_PASS_BY_REF, perf, "functions taking small copyable arguments by reference" diff --git a/clippy_lints/src/types.rs b/clippy_lints/src/types.rs index 09f596a10254..3b057081c73c 100644 --- a/clippy_lints/src/types.rs +++ b/clippy_lints/src/types.rs @@ -29,135 +29,135 @@ use syntax::source_map::Span; /// Handles all the linting of funky types pub struct TypePass; -/// **What it does:** Checks for use of `Box>` anywhere in the code. -/// -/// **Why is this bad?** `Vec` already keeps its contents in a separate area on -/// the heap. So if you `Box` it, you just add another level of indirection -/// without any benefit whatsoever. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// struct X { -/// values: Box>, -/// } -/// ``` -/// -/// Better: -/// -/// ```rust -/// struct X { -/// values: Vec, -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for use of `Box>` anywhere in the code. + /// + /// **Why is this bad?** `Vec` already keeps its contents in a separate area on + /// the heap. So if you `Box` it, you just add another level of indirection + /// without any benefit whatsoever. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// struct X { + /// values: Box>, + /// } + /// ``` + /// + /// Better: + /// + /// ```rust + /// struct X { + /// values: Vec, + /// } + /// ``` pub BOX_VEC, perf, "usage of `Box>`, vector elements are already on the heap" } -/// **What it does:** Checks for use of `Vec>` where T: Sized anywhere in the code. -/// -/// **Why is this bad?** `Vec` already keeps its contents in a separate area on -/// the heap. So if you `Box` its contents, you just add another level of indirection. -/// -/// **Known problems:** Vec> makes sense if T is a large type (see #3530, -/// 1st comment). -/// -/// **Example:** -/// ```rust -/// struct X { -/// values: Vec>, -/// } -/// ``` -/// -/// Better: -/// -/// ```rust -/// struct X { -/// values: Vec, -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for use of `Vec>` where T: Sized anywhere in the code. + /// + /// **Why is this bad?** `Vec` already keeps its contents in a separate area on + /// the heap. So if you `Box` its contents, you just add another level of indirection. + /// + /// **Known problems:** Vec> makes sense if T is a large type (see #3530, + /// 1st comment). + /// + /// **Example:** + /// ```rust + /// struct X { + /// values: Vec>, + /// } + /// ``` + /// + /// Better: + /// + /// ```rust + /// struct X { + /// values: Vec, + /// } + /// ``` pub VEC_BOX, complexity, "usage of `Vec>` where T: Sized, vector elements are already on the heap" } -/// **What it does:** Checks for use of `Option>` in function signatures and type -/// definitions -/// -/// **Why is this bad?** `Option<_>` represents an optional value. `Option>` -/// represents an optional optional value which is logically the same thing as an optional -/// value but has an unneeded extra level of wrapping. -/// -/// **Known problems:** None. -/// -/// **Example** -/// ```rust -/// fn x() -> Option> { -/// None -/// } declare_clippy_lint! { + /// **What it does:** Checks for use of `Option>` in function signatures and type + /// definitions + /// + /// **Why is this bad?** `Option<_>` represents an optional value. `Option>` + /// represents an optional optional value which is logically the same thing as an optional + /// value but has an unneeded extra level of wrapping. + /// + /// **Known problems:** None. + /// + /// **Example** + /// ```rust + /// fn x() -> Option> { + /// None + /// } pub OPTION_OPTION, complexity, "usage of `Option>`" } -/// **What it does:** Checks for usage of any `LinkedList`, suggesting to use a -/// `Vec` or a `VecDeque` (formerly called `RingBuf`). -/// -/// **Why is this bad?** Gankro says: -/// -/// > The TL;DR of `LinkedList` is that it's built on a massive amount of -/// pointers and indirection. -/// > It wastes memory, it has terrible cache locality, and is all-around slow. -/// `RingBuf`, while -/// > "only" amortized for push/pop, should be faster in the general case for -/// almost every possible -/// > workload, and isn't even amortized at all if you can predict the capacity -/// you need. -/// > -/// > `LinkedList`s are only really good if you're doing a lot of merging or -/// splitting of lists. -/// > This is because they can just mangle some pointers instead of actually -/// copying the data. Even -/// > if you're doing a lot of insertion in the middle of the list, `RingBuf` -/// can still be better -/// > because of how expensive it is to seek to the middle of a `LinkedList`. -/// -/// **Known problems:** False positives – the instances where using a -/// `LinkedList` makes sense are few and far between, but they can still happen. -/// -/// **Example:** -/// ```rust -/// let x = LinkedList::new(); -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for usage of any `LinkedList`, suggesting to use a + /// `Vec` or a `VecDeque` (formerly called `RingBuf`). + /// + /// **Why is this bad?** Gankro says: + /// + /// > The TL;DR of `LinkedList` is that it's built on a massive amount of + /// pointers and indirection. + /// > It wastes memory, it has terrible cache locality, and is all-around slow. + /// `RingBuf`, while + /// > "only" amortized for push/pop, should be faster in the general case for + /// almost every possible + /// > workload, and isn't even amortized at all if you can predict the capacity + /// you need. + /// > + /// > `LinkedList`s are only really good if you're doing a lot of merging or + /// splitting of lists. + /// > This is because they can just mangle some pointers instead of actually + /// copying the data. Even + /// > if you're doing a lot of insertion in the middle of the list, `RingBuf` + /// can still be better + /// > because of how expensive it is to seek to the middle of a `LinkedList`. + /// + /// **Known problems:** False positives – the instances where using a + /// `LinkedList` makes sense are few and far between, but they can still happen. + /// + /// **Example:** + /// ```rust + /// let x = LinkedList::new(); + /// ``` pub LINKEDLIST, pedantic, "usage of LinkedList, usually a vector is faster, or a more specialized data structure like a VecDeque" } -/// **What it does:** Checks for use of `&Box` anywhere in the code. -/// -/// **Why is this bad?** Any `&Box` can also be a `&T`, which is more -/// general. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// fn foo(bar: &Box) { ... } -/// ``` -/// -/// Better: -/// -/// ```rust -/// fn foo(bar: &T) { ... } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for use of `&Box` anywhere in the code. + /// + /// **Why is this bad?** Any `&Box` can also be a `&T`, which is more + /// general. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// fn foo(bar: &Box) { ... } + /// ``` + /// + /// Better: + /// + /// ```rust + /// fn foo(bar: &T) { ... } + /// ``` pub BORROWED_BOX, complexity, "a borrow of a boxed type" @@ -446,20 +446,20 @@ fn is_any_trait(t: &hir::Ty) -> bool { pub struct LetPass; -/// **What it does:** Checks for binding a unit value. -/// -/// **Why is this bad?** A unit value cannot usefully be used anywhere. So -/// binding one is kind of pointless. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// let x = { -/// 1; -/// }; -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for binding a unit value. + /// + /// **Why is this bad?** A unit value cannot usefully be used anywhere. So + /// binding one is kind of pointless. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// let x = { + /// 1; + /// }; + /// ``` pub LET_UNIT_VALUE, style, "creating a let binding to a value of unit type, which usually can't be used afterwards" @@ -499,33 +499,33 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LetPass { } } -/// **What it does:** Checks for comparisons to unit. -/// -/// **Why is this bad?** Unit is always equal to itself, and thus is just a -/// clumsily written constant. Mostly this happens when someone accidentally -/// adds semicolons at the end of the operands. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// if { -/// foo(); -/// } == { -/// bar(); -/// } { -/// baz(); -/// } -/// ``` -/// is equal to -/// ```rust -/// { -/// foo(); -/// bar(); -/// baz(); -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for comparisons to unit. + /// + /// **Why is this bad?** Unit is always equal to itself, and thus is just a + /// clumsily written constant. Mostly this happens when someone accidentally + /// adds semicolons at the end of the operands. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// if { + /// foo(); + /// } == { + /// bar(); + /// } { + /// baz(); + /// } + /// ``` + /// is equal to + /// ```rust + /// { + /// foo(); + /// bar(); + /// baz(); + /// } + /// ``` pub UNIT_CMP, correctness, "comparing unit values" @@ -570,21 +570,21 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnitCmp { } } -/// **What it does:** Checks for passing a unit value as an argument to a function without using a -/// unit literal (`()`). -/// -/// **Why is this bad?** This is likely the result of an accidental semicolon. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// foo({ -/// let a = bar(); -/// baz(a); -/// }) -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for passing a unit value as an argument to a function without using a + /// unit literal (`()`). + /// + /// **Why is this bad?** This is likely the result of an accidental semicolon. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// foo({ + /// let a = bar(); + /// baz(a); + /// }) + /// ``` pub UNIT_ARG, complexity, "passing unit to a function" @@ -677,216 +677,216 @@ fn is_unit_literal(expr: &Expr) -> bool { pub struct CastPass; -/// **What it does:** Checks for casts from any numerical to a float type where -/// the receiving type cannot store all values from the original type without -/// rounding errors. This possible rounding is to be expected, so this lint is -/// `Allow` by default. -/// -/// Basically, this warns on casting any integer with 32 or more bits to `f32` -/// or any 64-bit integer to `f64`. -/// -/// **Why is this bad?** It's not bad at all. But in some applications it can be -/// helpful to know where precision loss can take place. This lint can help find -/// those places in the code. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// let x = u64::MAX; -/// x as f64 -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for casts from any numerical to a float type where + /// the receiving type cannot store all values from the original type without + /// rounding errors. This possible rounding is to be expected, so this lint is + /// `Allow` by default. + /// + /// Basically, this warns on casting any integer with 32 or more bits to `f32` + /// or any 64-bit integer to `f64`. + /// + /// **Why is this bad?** It's not bad at all. But in some applications it can be + /// helpful to know where precision loss can take place. This lint can help find + /// those places in the code. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// let x = u64::MAX; + /// x as f64 + /// ``` pub CAST_PRECISION_LOSS, pedantic, "casts that cause loss of precision, e.g. `x as f32` where `x: u64`" } -/// **What it does:** Checks for casts from a signed to an unsigned numerical -/// type. In this case, negative values wrap around to large positive values, -/// which can be quite surprising in practice. However, as the cast works as -/// defined, this lint is `Allow` by default. -/// -/// **Why is this bad?** Possibly surprising results. You can activate this lint -/// as a one-time check to see where numerical wrapping can arise. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// let y: i8 = -1; -/// y as u128 // will return 18446744073709551615 -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for casts from a signed to an unsigned numerical + /// type. In this case, negative values wrap around to large positive values, + /// which can be quite surprising in practice. However, as the cast works as + /// defined, this lint is `Allow` by default. + /// + /// **Why is this bad?** Possibly surprising results. You can activate this lint + /// as a one-time check to see where numerical wrapping can arise. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// let y: i8 = -1; + /// y as u128 // will return 18446744073709551615 + /// ``` pub CAST_SIGN_LOSS, pedantic, "casts from signed types to unsigned types, e.g. `x as u32` where `x: i32`" } -/// **What it does:** Checks for on casts between numerical types that may -/// truncate large values. This is expected behavior, so the cast is `Allow` by -/// default. -/// -/// **Why is this bad?** In some problem domains, it is good practice to avoid -/// truncation. This lint can be activated to help assess where additional -/// checks could be beneficial. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// fn as_u8(x: u64) -> u8 { -/// x as u8 -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for on casts between numerical types that may + /// truncate large values. This is expected behavior, so the cast is `Allow` by + /// default. + /// + /// **Why is this bad?** In some problem domains, it is good practice to avoid + /// truncation. This lint can be activated to help assess where additional + /// checks could be beneficial. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// fn as_u8(x: u64) -> u8 { + /// x as u8 + /// } + /// ``` pub CAST_POSSIBLE_TRUNCATION, pedantic, "casts that may cause truncation of the value, e.g. `x as u8` where `x: u32`, or `x as i32` where `x: f32`" } -/// **What it does:** Checks for casts from an unsigned type to a signed type of -/// the same size. Performing such a cast is a 'no-op' for the compiler, -/// i.e. nothing is changed at the bit level, and the binary representation of -/// the value is reinterpreted. This can cause wrapping if the value is too big -/// for the target signed type. However, the cast works as defined, so this lint -/// is `Allow` by default. -/// -/// **Why is this bad?** While such a cast is not bad in itself, the results can -/// be surprising when this is not the intended behavior, as demonstrated by the -/// example below. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// u32::MAX as i32 // will yield a value of `-1` -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for casts from an unsigned type to a signed type of + /// the same size. Performing such a cast is a 'no-op' for the compiler, + /// i.e. nothing is changed at the bit level, and the binary representation of + /// the value is reinterpreted. This can cause wrapping if the value is too big + /// for the target signed type. However, the cast works as defined, so this lint + /// is `Allow` by default. + /// + /// **Why is this bad?** While such a cast is not bad in itself, the results can + /// be surprising when this is not the intended behavior, as demonstrated by the + /// example below. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// u32::MAX as i32 // will yield a value of `-1` + /// ``` pub CAST_POSSIBLE_WRAP, pedantic, "casts that may cause wrapping around the value, e.g. `x as i32` where `x: u32` and `x > i32::MAX`" } -/// **What it does:** Checks for on casts between numerical types that may -/// be replaced by safe conversion functions. -/// -/// **Why is this bad?** Rust's `as` keyword will perform many kinds of -/// conversions, including silently lossy conversions. Conversion functions such -/// as `i32::from` will only perform lossless conversions. Using the conversion -/// functions prevents conversions from turning into silent lossy conversions if -/// the types of the input expressions ever change, and make it easier for -/// people reading the code to know that the conversion is lossless. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// fn as_u64(x: u8) -> u64 { -/// x as u64 -/// } -/// ``` -/// -/// Using `::from` would look like this: -/// -/// ```rust -/// fn as_u64(x: u8) -> u64 { -/// u64::from(x) -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for on casts between numerical types that may + /// be replaced by safe conversion functions. + /// + /// **Why is this bad?** Rust's `as` keyword will perform many kinds of + /// conversions, including silently lossy conversions. Conversion functions such + /// as `i32::from` will only perform lossless conversions. Using the conversion + /// functions prevents conversions from turning into silent lossy conversions if + /// the types of the input expressions ever change, and make it easier for + /// people reading the code to know that the conversion is lossless. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// fn as_u64(x: u8) -> u64 { + /// x as u64 + /// } + /// ``` + /// + /// Using `::from` would look like this: + /// + /// ```rust + /// fn as_u64(x: u8) -> u64 { + /// u64::from(x) + /// } + /// ``` pub CAST_LOSSLESS, complexity, "casts using `as` that are known to be lossless, e.g. `x as u64` where `x: u8`" } -/// **What it does:** Checks for casts to the same type. -/// -/// **Why is this bad?** It's just unnecessary. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// let _ = 2i32 as i32 -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for casts to the same type. + /// + /// **Why is this bad?** It's just unnecessary. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// let _ = 2i32 as i32 + /// ``` pub UNNECESSARY_CAST, complexity, "cast to the same type, e.g. `x as i32` where `x: i32`" } -/// **What it does:** Checks for casts from a less-strictly-aligned pointer to a -/// more-strictly-aligned pointer -/// -/// **Why is this bad?** Dereferencing the resulting pointer may be undefined -/// behavior. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// let _ = (&1u8 as *const u8) as *const u16; -/// let _ = (&mut 1u8 as *mut u8) as *mut u16; -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for casts from a less-strictly-aligned pointer to a + /// more-strictly-aligned pointer + /// + /// **Why is this bad?** Dereferencing the resulting pointer may be undefined + /// behavior. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// let _ = (&1u8 as *const u8) as *const u16; + /// let _ = (&mut 1u8 as *mut u8) as *mut u16; + /// ``` pub CAST_PTR_ALIGNMENT, correctness, "cast from a pointer to a more-strictly-aligned pointer" } -/// **What it does:** Checks for casts of function pointers to something other than usize -/// -/// **Why is this bad?** -/// Casting a function pointer to anything other than usize/isize is not portable across -/// architectures, because you end up losing bits if the target type is too small or end up with a -/// bunch of extra bits that waste space and add more instructions to the final binary than -/// strictly necessary for the problem -/// -/// Casting to isize also doesn't make sense since there are no signed addresses. -/// -/// **Example** -/// -/// ```rust -/// // Bad -/// fn fun() -> i32 {} -/// let a = fun as i64; -/// -/// // Good -/// fn fun2() -> i32 {} -/// let a = fun2 as usize; -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for casts of function pointers to something other than usize + /// + /// **Why is this bad?** + /// Casting a function pointer to anything other than usize/isize is not portable across + /// architectures, because you end up losing bits if the target type is too small or end up with a + /// bunch of extra bits that waste space and add more instructions to the final binary than + /// strictly necessary for the problem + /// + /// Casting to isize also doesn't make sense since there are no signed addresses. + /// + /// **Example** + /// + /// ```rust + /// // Bad + /// fn fun() -> i32 {} + /// let a = fun as i64; + /// + /// // Good + /// fn fun2() -> i32 {} + /// let a = fun2 as usize; + /// ``` pub FN_TO_NUMERIC_CAST, style, "casting a function pointer to a numeric type other than usize" } -/// **What it does:** Checks for casts of a function pointer to a numeric type not wide enough to -/// store address. -/// -/// **Why is this bad?** -/// Such a cast discards some bits of the function's address. If this is intended, it would be more -/// clearly expressed by casting to usize first, then casting the usize to the intended type (with -/// a comment) to perform the truncation. -/// -/// **Example** -/// -/// ```rust -/// // Bad -/// fn fn1() -> i16 { -/// 1 -/// }; -/// let _ = fn1 as i32; -/// -/// // Better: Cast to usize first, then comment with the reason for the truncation -/// fn fn2() -> i16 { -/// 1 -/// }; -/// let fn_ptr = fn2 as usize; -/// let fn_ptr_truncated = fn_ptr as i32; -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for casts of a function pointer to a numeric type not wide enough to + /// store address. + /// + /// **Why is this bad?** + /// Such a cast discards some bits of the function's address. If this is intended, it would be more + /// clearly expressed by casting to usize first, then casting the usize to the intended type (with + /// a comment) to perform the truncation. + /// + /// **Example** + /// + /// ```rust + /// // Bad + /// fn fn1() -> i16 { + /// 1 + /// }; + /// let _ = fn1 as i32; + /// + /// // Better: Cast to usize first, then comment with the reason for the truncation + /// fn fn2() -> i16 { + /// 1 + /// }; + /// let fn_ptr = fn2 as usize; + /// let fn_ptr_truncated = fn_ptr as i32; + /// ``` pub FN_TO_NUMERIC_CAST_WITH_TRUNCATION, style, "casting a function pointer to a numeric type not wide enough to store the address" @@ -1287,21 +1287,21 @@ fn lint_fn_to_numeric_cast( } } -/// **What it does:** Checks for types used in structs, parameters and `let` -/// declarations above a certain complexity threshold. -/// -/// **Why is this bad?** Too complex types make the code less readable. Consider -/// using a `type` definition to simplify them. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// struct Foo { -/// inner: Rc>>>, -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for types used in structs, parameters and `let` + /// declarations above a certain complexity threshold. + /// + /// **Why is this bad?** Too complex types make the code less readable. Consider + /// using a `type` definition to simplify them. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// struct Foo { + /// inner: Rc>>>, + /// } + /// ``` pub TYPE_COMPLEXITY, complexity, "usage of very complex types that might be better factored into `type` definitions" @@ -1456,28 +1456,28 @@ impl<'tcx> Visitor<'tcx> for TypeComplexityVisitor { } } -/// **What it does:** Checks for expressions where a character literal is cast -/// to `u8` and suggests using a byte literal instead. -/// -/// **Why is this bad?** In general, casting values to smaller types is -/// error-prone and should be avoided where possible. In the particular case of -/// converting a character literal to u8, it is easy to avoid by just using a -/// byte literal instead. As an added bonus, `b'a'` is even slightly shorter -/// than `'a' as u8`. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// 'x' as u8 -/// ``` -/// -/// A better version, using the byte literal: -/// -/// ```rust -/// b'x' -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for expressions where a character literal is cast + /// to `u8` and suggests using a byte literal instead. + /// + /// **Why is this bad?** In general, casting values to smaller types is + /// error-prone and should be avoided where possible. In the particular case of + /// converting a character literal to u8, it is easy to avoid by just using a + /// byte literal instead. As an added bonus, `b'a'` is even slightly shorter + /// than `'a' as u8`. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// 'x' as u8 + /// ``` + /// + /// A better version, using the byte literal: + /// + /// ```rust + /// b'x' + /// ``` pub CHAR_LIT_AS_U8, complexity, "casting a character literal to u8" @@ -1518,28 +1518,28 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CharLitAsU8 { } } -/// **What it does:** Checks for comparisons where one side of the relation is -/// either the minimum or maximum value for its type and warns if it involves a -/// case that is always true or always false. Only integer and boolean types are -/// checked. -/// -/// **Why is this bad?** An expression like `min <= x` may misleadingly imply -/// that is is possible for `x` to be less than the minimum. Expressions like -/// `max < x` are probably mistakes. -/// -/// **Known problems:** For `usize` the size of the current compile target will -/// be assumed (e.g. 64 bits on 64 bit systems). This means code that uses such -/// a comparison to detect target pointer width will trigger this lint. One can -/// use `mem::sizeof` and compare its value or conditional compilation -/// attributes -/// like `#[cfg(target_pointer_width = "64")] ..` instead. -/// -/// **Example:** -/// ```rust -/// vec.len() <= 0 -/// 100 > std::i32::MAX -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for comparisons where one side of the relation is + /// either the minimum or maximum value for its type and warns if it involves a + /// case that is always true or always false. Only integer and boolean types are + /// checked. + /// + /// **Why is this bad?** An expression like `min <= x` may misleadingly imply + /// that is is possible for `x` to be less than the minimum. Expressions like + /// `max < x` are probably mistakes. + /// + /// **Known problems:** For `usize` the size of the current compile target will + /// be assumed (e.g. 64 bits on 64 bit systems). This means code that uses such + /// a comparison to detect target pointer width will trigger this lint. One can + /// use `mem::sizeof` and compare its value or conditional compilation + /// attributes + /// like `#[cfg(target_pointer_width = "64")] ..` instead. + /// + /// **Example:** + /// ```rust + /// vec.len() <= 0 + /// 100 > std::i32::MAX + /// ``` pub ABSURD_EXTREME_COMPARISONS, correctness, "a comparison with a maximum or minimum value that is always true or false" @@ -1703,22 +1703,22 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AbsurdExtremeComparisons { } } -/// **What it does:** Checks for comparisons where the relation is always either -/// true or false, but where one side has been upcast so that the comparison is -/// necessary. Only integer types are checked. -/// -/// **Why is this bad?** An expression like `let x : u8 = ...; (x as u32) > 300` -/// will mistakenly imply that it is possible for `x` to be outside the range of -/// `u8`. -/// -/// **Known problems:** -/// https://github.com/rust-lang/rust-clippy/issues/886 -/// -/// **Example:** -/// ```rust -/// let x : u8 = ...; (x as u32) > 300 -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for comparisons where the relation is always either + /// true or false, but where one side has been upcast so that the comparison is + /// necessary. Only integer types are checked. + /// + /// **Why is this bad?** An expression like `let x : u8 = ...; (x as u32) > 300` + /// will mistakenly imply that it is possible for `x` to be outside the range of + /// `u8`. + /// + /// **Known problems:** + /// https://github.com/rust-lang/rust-clippy/issues/886 + /// + /// **Example:** + /// ```rust + /// let x : u8 = ...; (x as u32) > 300 + /// ``` pub INVALID_UPCAST_COMPARISONS, pedantic, "a comparison involving an upcast which is always true or false" @@ -1948,24 +1948,24 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidUpcastComparisons { } } -/// **What it does:** Checks for public `impl` or `fn` missing generalization -/// over different hashers and implicitly defaulting to the default hashing -/// algorithm (SipHash). -/// -/// **Why is this bad?** `HashMap` or `HashSet` with custom hashers cannot be -/// used with them. -/// -/// **Known problems:** Suggestions for replacing constructors can contain -/// false-positives. Also applying suggestions can require modification of other -/// pieces of code, possibly including external crates. -/// -/// **Example:** -/// ```rust -/// impl Serialize for HashMap { ... } -/// -/// pub foo(map: &mut HashMap) { .. } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for public `impl` or `fn` missing generalization + /// over different hashers and implicitly defaulting to the default hashing + /// algorithm (SipHash). + /// + /// **Why is this bad?** `HashMap` or `HashSet` with custom hashers cannot be + /// used with them. + /// + /// **Known problems:** Suggestions for replacing constructors can contain + /// false-positives. Also applying suggestions can require modification of other + /// pieces of code, possibly including external crates. + /// + /// **Example:** + /// ```rust + /// impl Serialize for HashMap { ... } + /// + /// pub foo(map: &mut HashMap) { .. } + /// ``` pub IMPLICIT_HASHER, style, "missing generalization over different hashers" @@ -2292,33 +2292,33 @@ impl<'a, 'b, 'tcx: 'a + 'b> Visitor<'tcx> for ImplicitHasherConstructorVisitor<' } } -/// **What it does:** Checks for casts of `&T` to `&mut T` anywhere in the code. -/// -/// **Why is this bad?** It’s basically guaranteed to be undefined behaviour. -/// `UnsafeCell` is the only way to obtain aliasable data that is considered -/// mutable. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// fn x(r: &i32) { -/// unsafe { -/// *(r as *const _ as *mut _) += 1; -/// } -/// } -/// ``` -/// -/// Instead consider using interior mutability types. -/// -/// ```rust -/// fn x(r: &UnsafeCell) { -/// unsafe { -/// *r.get() += 1; -/// } -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for casts of `&T` to `&mut T` anywhere in the code. + /// + /// **Why is this bad?** It’s basically guaranteed to be undefined behaviour. + /// `UnsafeCell` is the only way to obtain aliasable data that is considered + /// mutable. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// fn x(r: &i32) { + /// unsafe { + /// *(r as *const _ as *mut _) += 1; + /// } + /// } + /// ``` + /// + /// Instead consider using interior mutability types. + /// + /// ```rust + /// fn x(r: &UnsafeCell) { + /// unsafe { + /// *r.get() += 1; + /// } + /// } + /// ``` pub CAST_REF_TO_MUT, correctness, "a cast of reference to a mutable pointer" diff --git a/clippy_lints/src/unicode.rs b/clippy_lints/src/unicode.rs index c31a8aebc351..4d9e2f18650e 100644 --- a/clippy_lints/src/unicode.rs +++ b/clippy_lints/src/unicode.rs @@ -6,53 +6,53 @@ use syntax::ast::LitKind; use syntax::source_map::Span; use unicode_normalization::UnicodeNormalization; -/// **What it does:** Checks for the Unicode zero-width space in the code. -/// -/// **Why is this bad?** Having an invisible character in the code makes for all -/// sorts of April fools, but otherwise is very much frowned upon. -/// -/// **Known problems:** None. -/// -/// **Example:** You don't see it, but there may be a zero-width space -/// somewhere in this text. declare_clippy_lint! { + /// **What it does:** Checks for the Unicode zero-width space in the code. + /// + /// **Why is this bad?** Having an invisible character in the code makes for all + /// sorts of April fools, but otherwise is very much frowned upon. + /// + /// **Known problems:** None. + /// + /// **Example:** You don't see it, but there may be a zero-width space + /// somewhere in this text. pub ZERO_WIDTH_SPACE, correctness, "using a zero-width space in a string literal, which is confusing" } -/// **What it does:** Checks for non-ASCII characters in string literals. -/// -/// **Why is this bad?** Yeah, we know, the 90's called and wanted their charset -/// back. Even so, there still are editors and other programs out there that -/// don't work well with Unicode. So if the code is meant to be used -/// internationally, on multiple operating systems, or has other portability -/// requirements, activating this lint could be useful. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// let x = "Hä?" -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for non-ASCII characters in string literals. + /// + /// **Why is this bad?** Yeah, we know, the 90's called and wanted their charset + /// back. Even so, there still are editors and other programs out there that + /// don't work well with Unicode. So if the code is meant to be used + /// internationally, on multiple operating systems, or has other portability + /// requirements, activating this lint could be useful. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// let x = "Hä?" + /// ``` pub NON_ASCII_LITERAL, pedantic, "using any literal non-ASCII chars in a string literal instead of using the `\\u` escape" } -/// **What it does:** Checks for string literals that contain Unicode in a form -/// that is not equal to its -/// [NFC-recomposition](http://www.unicode.org/reports/tr15/#Norm_Forms). -/// -/// **Why is this bad?** If such a string is compared to another, the results -/// may be surprising. -/// -/// **Known problems** None. -/// -/// **Example:** You may not see it, but “à” and “à” aren't the same string. The -/// former when escaped is actually `"a\u{300}"` while the latter is `"\u{e0}"`. declare_clippy_lint! { + /// **What it does:** Checks for string literals that contain Unicode in a form + /// that is not equal to its + /// [NFC-recomposition](http://www.unicode.org/reports/tr15/#Norm_Forms). + /// + /// **Why is this bad?** If such a string is compared to another, the results + /// may be surprising. + /// + /// **Known problems** None. + /// + /// **Example:** You may not see it, but “à” and “à” aren't the same string. The + /// former when escaped is actually `"a\u{300}"` while the latter is `"\u{e0}"`. pub UNICODE_NOT_NFC, pedantic, "using a unicode literal not in NFC normal form (see [unicode tr15](http://www.unicode.org/reports/tr15/) for further information)" diff --git a/clippy_lints/src/unsafe_removed_from_name.rs b/clippy_lints/src/unsafe_removed_from_name.rs index 6cf1a582a654..68ceaaac8a31 100644 --- a/clippy_lints/src/unsafe_removed_from_name.rs +++ b/clippy_lints/src/unsafe_removed_from_name.rs @@ -5,22 +5,22 @@ use syntax::ast::*; use syntax::source_map::Span; use syntax::symbol::LocalInternedString; -/// **What it does:** Checks for imports that remove "unsafe" from an item's -/// name. -/// -/// **Why is this bad?** Renaming makes it less clear which traits and -/// structures are unsafe. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust,ignore -/// use std::cell::{UnsafeCell as TotallySafeCell}; -/// -/// extern crate crossbeam; -/// use crossbeam::{spawn_unsafe as spawn}; -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for imports that remove "unsafe" from an item's + /// name. + /// + /// **Why is this bad?** Renaming makes it less clear which traits and + /// structures are unsafe. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust,ignore + /// use std::cell::{UnsafeCell as TotallySafeCell}; + /// + /// extern crate crossbeam; + /// use crossbeam::{spawn_unsafe as spawn}; + /// ``` pub UNSAFE_REMOVED_FROM_NAME, style, "`unsafe` removed from API names on import" diff --git a/clippy_lints/src/unused_io_amount.rs b/clippy_lints/src/unused_io_amount.rs index d54cd3bba030..89f6873565a5 100644 --- a/clippy_lints/src/unused_io_amount.rs +++ b/clippy_lints/src/unused_io_amount.rs @@ -3,28 +3,28 @@ use rustc::hir; use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use rustc::{declare_tool_lint, lint_array}; -/// **What it does:** Checks for unused written/read amount. -/// -/// **Why is this bad?** `io::Write::write` and `io::Read::read` are not -/// guaranteed to -/// process the entire buffer. They return how many bytes were processed, which -/// might be smaller -/// than a given buffer's length. If you don't need to deal with -/// partial-write/read, use -/// `write_all`/`read_exact` instead. -/// -/// **Known problems:** Detects only common patterns. -/// -/// **Example:** -/// ```rust,ignore -/// use std::io; -/// fn foo(w: &mut W) -> io::Result<()> { -/// // must be `w.write_all(b"foo")?;` -/// w.write(b"foo")?; -/// Ok(()) -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for unused written/read amount. + /// + /// **Why is this bad?** `io::Write::write` and `io::Read::read` are not + /// guaranteed to + /// process the entire buffer. They return how many bytes were processed, which + /// might be smaller + /// than a given buffer's length. If you don't need to deal with + /// partial-write/read, use + /// `write_all`/`read_exact` instead. + /// + /// **Known problems:** Detects only common patterns. + /// + /// **Example:** + /// ```rust,ignore + /// use std::io; + /// fn foo(w: &mut W) -> io::Result<()> { + /// // must be `w.write_all(b"foo")?;` + /// w.write(b"foo")?; + /// Ok(()) + /// } + /// ``` pub UNUSED_IO_AMOUNT, correctness, "unused written/read amount" diff --git a/clippy_lints/src/unused_label.rs b/clippy_lints/src/unused_label.rs index 57aa8810df02..d92511d999fb 100644 --- a/clippy_lints/src/unused_label.rs +++ b/clippy_lints/src/unused_label.rs @@ -7,21 +7,21 @@ use rustc_data_structures::fx::FxHashMap; use syntax::source_map::Span; use syntax::symbol::LocalInternedString; -/// **What it does:** Checks for unused labels. -/// -/// **Why is this bad?** Maybe the label should be used in which case there is -/// an error in the code or it should be removed. -/// -/// **Known problems:** Hopefully none. -/// -/// **Example:** -/// ```rust,ignore -/// fn unused_label() { -/// 'label: for i in 1..2 { -/// if i > 4 { continue } -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for unused labels. + /// + /// **Why is this bad?** Maybe the label should be used in which case there is + /// an error in the code or it should be removed. + /// + /// **Known problems:** Hopefully none. + /// + /// **Example:** + /// ```rust,ignore + /// fn unused_label() { + /// 'label: for i in 1..2 { + /// if i > 4 { continue } + /// } + /// ``` pub UNUSED_LABEL, complexity, "unused labels" diff --git a/clippy_lints/src/unwrap.rs b/clippy_lints/src/unwrap.rs index c2288aed2d6b..6b77e0f16faa 100644 --- a/clippy_lints/src/unwrap.rs +++ b/clippy_lints/src/unwrap.rs @@ -7,48 +7,48 @@ use rustc::hir::intravisit::*; use rustc::hir::*; use syntax::source_map::Span; -/// **What it does:** Checks for calls of `unwrap[_err]()` that cannot fail. -/// -/// **Why is this bad?** Using `if let` or `match` is more idiomatic. -/// -/// **Known problems:** Limitations of the borrow checker might make unwrap() necessary sometimes? -/// -/// **Example:** -/// ```rust -/// if option.is_some() { -/// do_something_with(option.unwrap()) -/// } -/// ``` -/// -/// Could be written: -/// -/// ```rust -/// if let Some(value) = option { -/// do_something_with(value) -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for calls of `unwrap[_err]()` that cannot fail. + /// + /// **Why is this bad?** Using `if let` or `match` is more idiomatic. + /// + /// **Known problems:** Limitations of the borrow checker might make unwrap() necessary sometimes? + /// + /// **Example:** + /// ```rust + /// if option.is_some() { + /// do_something_with(option.unwrap()) + /// } + /// ``` + /// + /// Could be written: + /// + /// ```rust + /// if let Some(value) = option { + /// do_something_with(value) + /// } + /// ``` pub UNNECESSARY_UNWRAP, nursery, "checks for calls of unwrap[_err]() that cannot fail" } -/// **What it does:** Checks for calls of `unwrap[_err]()` that will always fail. -/// -/// **Why is this bad?** If panicking is desired, an explicit `panic!()` should be used. -/// -/// **Known problems:** This lint only checks `if` conditions not assignments. -/// So something like `let x: Option<()> = None; x.unwrap();` will not be recognized. -/// -/// **Example:** -/// ```rust -/// if option.is_none() { -/// do_something_with(option.unwrap()) -/// } -/// ``` -/// -/// This code will always panic. The if condition should probably be inverted. declare_clippy_lint! { + /// **What it does:** Checks for calls of `unwrap[_err]()` that will always fail. + /// + /// **Why is this bad?** If panicking is desired, an explicit `panic!()` should be used. + /// + /// **Known problems:** This lint only checks `if` conditions not assignments. + /// So something like `let x: Option<()> = None; x.unwrap();` will not be recognized. + /// + /// **Example:** + /// ```rust + /// if option.is_none() { + /// do_something_with(option.unwrap()) + /// } + /// ``` + /// + /// This code will always panic. The if condition should probably be inverted. pub PANICKING_UNWRAP, nursery, "checks for calls of unwrap[_err]() that will always fail" diff --git a/clippy_lints/src/use_self.rs b/clippy_lints/src/use_self.rs index fb7bb1f0d2ae..5144e8076abb 100644 --- a/clippy_lints/src/use_self.rs +++ b/clippy_lints/src/use_self.rs @@ -9,36 +9,36 @@ use rustc::{declare_tool_lint, lint_array}; use rustc_errors::Applicability; use syntax_pos::symbol::keywords::SelfUpper; -/// **What it does:** Checks for unnecessary repetition of structure name when a -/// replacement with `Self` is applicable. -/// -/// **Why is this bad?** Unnecessary repetition. Mixed use of `Self` and struct -/// name -/// feels inconsistent. -/// -/// **Known problems:** -/// - False positive when using associated types (#2843) -/// - False positives in some situations when using generics (#3410) -/// -/// **Example:** -/// ```rust -/// struct Foo {} -/// impl Foo { -/// fn new() -> Foo { -/// Foo {} -/// } -/// } -/// ``` -/// could be -/// ```rust -/// struct Foo {} -/// impl Foo { -/// fn new() -> Self { -/// Self {} -/// } -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for unnecessary repetition of structure name when a + /// replacement with `Self` is applicable. + /// + /// **Why is this bad?** Unnecessary repetition. Mixed use of `Self` and struct + /// name + /// feels inconsistent. + /// + /// **Known problems:** + /// - False positive when using associated types (#2843) + /// - False positives in some situations when using generics (#3410) + /// + /// **Example:** + /// ```rust + /// struct Foo {} + /// impl Foo { + /// fn new() -> Foo { + /// Foo {} + /// } + /// } + /// ``` + /// could be + /// ```rust + /// struct Foo {} + /// impl Foo { + /// fn new() -> Self { + /// Self {} + /// } + /// } + /// ``` pub USE_SELF, pedantic, "Unnecessary structure name repetition whereas `Self` is applicable" diff --git a/clippy_lints/src/utils/author.rs b/clippy_lints/src/utils/author.rs index e61fb2bde4b8..f1ab545ad3e4 100644 --- a/clippy_lints/src/utils/author.rs +++ b/clippy_lints/src/utils/author.rs @@ -11,38 +11,38 @@ use rustc::{declare_tool_lint, lint_array}; use rustc_data_structures::fx::FxHashMap; use syntax::ast::{Attribute, LitKind}; -/// **What it does:** Generates clippy code that detects the offending pattern -/// -/// **Example:** -/// ```rust -/// // ./tests/ui/my_lint.rs -/// fn foo() { -/// // detect the following pattern -/// #[clippy::author] -/// if x == 42 { -/// // but ignore everything from here on -/// #![clippy::author = "ignore"] -/// } -/// } -/// ``` -/// -/// Running `TESTNAME=ui/my_lint cargo uitest` will produce -/// a `./tests/ui/new_lint.stdout` file with the generated code: -/// -/// ```rust -/// // ./tests/ui/new_lint.stdout -/// if_chain! { -/// if let ExprKind::If(ref cond, ref then, None) = item.node, -/// if let ExprKind::Binary(BinOp::Eq, ref left, ref right) = cond.node, -/// if let ExprKind::Path(ref path) = left.node, -/// if let ExprKind::Lit(ref lit) = right.node, -/// if let LitKind::Int(42, _) = lit.node, -/// then { -/// // report your lint here -/// } -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Generates clippy code that detects the offending pattern + /// + /// **Example:** + /// ```rust + /// // ./tests/ui/my_lint.rs + /// fn foo() { + /// // detect the following pattern + /// #[clippy::author] + /// if x == 42 { + /// // but ignore everything from here on + /// #![clippy::author = "ignore"] + /// } + /// } + /// ``` + /// + /// Running `TESTNAME=ui/my_lint cargo uitest` will produce + /// a `./tests/ui/new_lint.stdout` file with the generated code: + /// + /// ```rust + /// // ./tests/ui/new_lint.stdout + /// if_chain! { + /// if let ExprKind::If(ref cond, ref then, None) = item.node, + /// if let ExprKind::Binary(BinOp::Eq, ref left, ref right) = cond.node, + /// if let ExprKind::Path(ref path) = left.node, + /// if let ExprKind::Lit(ref lit) = right.node, + /// if let LitKind::Int(42, _) = lit.node, + /// then { + /// // report your lint here + /// } + /// } + /// ``` pub LINT_AUTHOR, internal_warn, "helper for writing lints" diff --git a/clippy_lints/src/utils/inspector.rs b/clippy_lints/src/utils/inspector.rs index 4d43c374b722..219503922701 100644 --- a/clippy_lints/src/utils/inspector.rs +++ b/clippy_lints/src/utils/inspector.rs @@ -8,23 +8,23 @@ use rustc::session::Session; use rustc::{declare_tool_lint, lint_array}; use syntax::ast::Attribute; -/// **What it does:** Dumps every ast/hir node which has the `#[clippy::dump]` -/// attribute -/// -/// **Example:** -/// ```rust -/// #[clippy::dump] -/// extern crate foo; -/// ``` -/// -/// prints -/// -/// ``` -/// item `foo` -/// visibility inherited from outer item -/// extern crate dylib source: "/path/to/foo.so" -/// ``` declare_clippy_lint! { + /// **What it does:** Dumps every ast/hir node which has the `#[clippy::dump]` + /// attribute + /// + /// **Example:** + /// ```rust + /// #[clippy::dump] + /// extern crate foo; + /// ``` + /// + /// prints + /// + /// ``` + /// item `foo` + /// visibility inherited from outer item + /// extern crate dylib source: "/path/to/foo.so" + /// ``` pub DEEP_CODE_INSPECTION, internal_warn, "helper to dump info about code" diff --git a/clippy_lints/src/utils/internal_lints.rs b/clippy_lints/src/utils/internal_lints.rs index 0821ab036b0a..877f431e6413 100644 --- a/clippy_lints/src/utils/internal_lints.rs +++ b/clippy_lints/src/utils/internal_lints.rs @@ -14,78 +14,78 @@ use syntax::ast::{Crate as AstCrate, Ident, ItemKind, Name}; use syntax::source_map::Span; use syntax::symbol::LocalInternedString; -/// **What it does:** Checks for various things we like to keep tidy in clippy. -/// -/// **Why is this bad?** We like to pretend we're an example of tidy code. -/// -/// **Known problems:** None. -/// -/// **Example:** Wrong ordering of the util::paths constants. declare_clippy_lint! { + /// **What it does:** Checks for various things we like to keep tidy in clippy. + /// + /// **Why is this bad?** We like to pretend we're an example of tidy code. + /// + /// **Known problems:** None. + /// + /// **Example:** Wrong ordering of the util::paths constants. pub CLIPPY_LINTS_INTERNAL, internal, "various things that will negatively affect your clippy experience" } -/// **What it does:** Ensures every lint is associated to a `LintPass`. -/// -/// **Why is this bad?** The compiler only knows lints via a `LintPass`. Without -/// putting a lint to a `LintPass::get_lints()`'s return, the compiler will not -/// know the name of the lint. -/// -/// **Known problems:** Only checks for lints associated using the `lint_array!` -/// macro. -/// -/// **Example:** -/// ```rust -/// declare_lint! { pub LINT_1, ... } -/// declare_lint! { pub LINT_2, ... } -/// declare_lint! { pub FORGOTTEN_LINT, ... } -/// // ... -/// pub struct Pass; -/// impl LintPass for Pass { -/// fn get_lints(&self) -> LintArray { -/// lint_array![LINT_1, LINT_2] -/// // missing FORGOTTEN_LINT -/// } -/// } -/// ``` declare_clippy_lint! { + /// **What it does:** Ensures every lint is associated to a `LintPass`. + /// + /// **Why is this bad?** The compiler only knows lints via a `LintPass`. Without + /// putting a lint to a `LintPass::get_lints()`'s return, the compiler will not + /// know the name of the lint. + /// + /// **Known problems:** Only checks for lints associated using the `lint_array!` + /// macro. + /// + /// **Example:** + /// ```rust + /// declare_lint! { pub LINT_1, ... } + /// declare_lint! { pub LINT_2, ... } + /// declare_lint! { pub FORGOTTEN_LINT, ... } + /// // ... + /// pub struct Pass; + /// impl LintPass for Pass { + /// fn get_lints(&self) -> LintArray { + /// lint_array![LINT_1, LINT_2] + /// // missing FORGOTTEN_LINT + /// } + /// } + /// ``` pub LINT_WITHOUT_LINT_PASS, internal, "declaring a lint without associating it in a LintPass" } -/// **What it does:** Checks for the presence of the default hash types "HashMap" or "HashSet" -/// and recommends the FxHash* variants. -/// -/// **Why is this bad?** The FxHash variants have better performance -/// and we don't need any collision prevention in clippy. declare_clippy_lint! { + /// **What it does:** Checks for the presence of the default hash types "HashMap" or "HashSet" + /// and recommends the FxHash* variants. + /// + /// **Why is this bad?** The FxHash variants have better performance + /// and we don't need any collision prevention in clippy. pub DEFAULT_HASH_TYPES, internal, "forbid HashMap and HashSet and suggest the FxHash* variants" } -/// **What it does:** Checks for calls to `cx.span_lint*` and suggests to use the `utils::*` -/// variant of the function. -/// -/// **Why is this bad?** The `utils::*` variants also add a link to the Clippy documentation to the -/// warning/error messages. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// Bad: -/// ```rust -/// cx.span_lint(LINT_NAME, "message"); -/// ``` -/// -/// Good: -/// ```rust -/// utils::span_lint(cx, LINT_NAME, "message"); -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for calls to `cx.span_lint*` and suggests to use the `utils::*` + /// variant of the function. + /// + /// **Why is this bad?** The `utils::*` variants also add a link to the Clippy documentation to the + /// warning/error messages. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// Bad: + /// ```rust + /// cx.span_lint(LINT_NAME, "message"); + /// ``` + /// + /// Good: + /// ```rust + /// utils::span_lint(cx, LINT_NAME, "message"); + /// ``` pub COMPILER_LINT_FUNCTIONS, internal, "usage of the lint functions of the compiler instead of the utils::* variant" diff --git a/clippy_lints/src/vec.rs b/clippy_lints/src/vec.rs index a99b6ca840c0..cd53029e8347 100644 --- a/clippy_lints/src/vec.rs +++ b/clippy_lints/src/vec.rs @@ -8,18 +8,18 @@ use rustc::{declare_tool_lint, lint_array}; use rustc_errors::Applicability; use syntax::source_map::Span; -/// **What it does:** Checks for usage of `&vec![..]` when using `&[..]` would -/// be possible. -/// -/// **Why is this bad?** This is less efficient. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust,ignore -/// foo(&vec![1, 2]) -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for usage of `&vec![..]` when using `&[..]` would + /// be possible. + /// + /// **Why is this bad?** This is less efficient. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust,ignore + /// foo(&vec![1, 2]) + /// ``` pub USELESS_VEC, perf, "useless `vec!`" diff --git a/clippy_lints/src/wildcard_dependencies.rs b/clippy_lints/src/wildcard_dependencies.rs index 8ccf2c69cc7f..30bd2177ca91 100644 --- a/clippy_lints/src/wildcard_dependencies.rs +++ b/clippy_lints/src/wildcard_dependencies.rs @@ -7,21 +7,21 @@ use cargo_metadata; use if_chain::if_chain; use semver; -/// **What it does:** Checks for wildcard dependencies in the `Cargo.toml`. -/// -/// **Why is this bad?** [As the edition guide says](https://rust-lang-nursery.github.io/edition-guide/rust-2018/cargo-and-crates-io/crates-io-disallows-wildcard-dependencies.html), -/// it is highly unlikely that you work with any possible version of your dependency, -/// and wildcard dependencies would cause unnecessary breakage in the ecosystem. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// -/// ```toml -/// [dependencies] -/// regex = "*" -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for wildcard dependencies in the `Cargo.toml`. + /// + /// **Why is this bad?** [As the edition guide says](https://rust-lang-nursery.github.io/edition-guide/rust-2018/cargo-and-crates-io/crates-io-disallows-wildcard-dependencies.html), + /// it is highly unlikely that you work with any possible version of your dependency, + /// and wildcard dependencies would cause unnecessary breakage in the ecosystem. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// + /// ```toml + /// [dependencies] + /// regex = "*" + /// ``` pub WILDCARD_DEPENDENCIES, cargo, "wildcard dependencies being used" diff --git a/clippy_lints/src/write.rs b/clippy_lints/src/write.rs index 012c34e9b535..e433bd69cb01 100644 --- a/clippy_lints/src/write.rs +++ b/clippy_lints/src/write.rs @@ -7,153 +7,153 @@ use syntax::ast::*; use syntax::parse::{parser, token}; use syntax::tokenstream::{TokenStream, TokenTree}; -/// **What it does:** This lint warns when you use `println!("")` to -/// print a newline. -/// -/// **Why is this bad?** You should use `println!()`, which is simpler. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// println!(""); -/// ``` declare_clippy_lint! { + /// **What it does:** This lint warns when you use `println!("")` to + /// print a newline. + /// + /// **Why is this bad?** You should use `println!()`, which is simpler. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// println!(""); + /// ``` pub PRINTLN_EMPTY_STRING, style, "using `println!(\"\")` with an empty string" } -/// **What it does:** This lint warns when you use `print!()` with a format -/// string that -/// ends in a newline. -/// -/// **Why is this bad?** You should use `println!()` instead, which appends the -/// newline. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// print!("Hello {}!\n", name); -/// ``` -/// use println!() instead -/// ```rust -/// println!("Hello {}!", name); -/// ``` declare_clippy_lint! { + /// **What it does:** This lint warns when you use `print!()` with a format + /// string that + /// ends in a newline. + /// + /// **Why is this bad?** You should use `println!()` instead, which appends the + /// newline. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// print!("Hello {}!\n", name); + /// ``` + /// use println!() instead + /// ```rust + /// println!("Hello {}!", name); + /// ``` pub PRINT_WITH_NEWLINE, style, "using `print!()` with a format string that ends in a single newline" } -/// **What it does:** Checks for printing on *stdout*. The purpose of this lint -/// is to catch debugging remnants. -/// -/// **Why is this bad?** People often print on *stdout* while debugging an -/// application and might forget to remove those prints afterward. -/// -/// **Known problems:** Only catches `print!` and `println!` calls. -/// -/// **Example:** -/// ```rust -/// println!("Hello world!"); -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for printing on *stdout*. The purpose of this lint + /// is to catch debugging remnants. + /// + /// **Why is this bad?** People often print on *stdout* while debugging an + /// application and might forget to remove those prints afterward. + /// + /// **Known problems:** Only catches `print!` and `println!` calls. + /// + /// **Example:** + /// ```rust + /// println!("Hello world!"); + /// ``` pub PRINT_STDOUT, restriction, "printing on stdout" } -/// **What it does:** Checks for use of `Debug` formatting. The purpose of this -/// lint is to catch debugging remnants. -/// -/// **Why is this bad?** The purpose of the `Debug` trait is to facilitate -/// debugging Rust code. It should not be used in in user-facing output. -/// -/// **Example:** -/// ```rust -/// println!("{:?}", foo); -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for use of `Debug` formatting. The purpose of this + /// lint is to catch debugging remnants. + /// + /// **Why is this bad?** The purpose of the `Debug` trait is to facilitate + /// debugging Rust code. It should not be used in in user-facing output. + /// + /// **Example:** + /// ```rust + /// println!("{:?}", foo); + /// ``` pub USE_DEBUG, restriction, "use of `Debug`-based formatting" } -/// **What it does:** This lint warns about the use of literals as `print!`/`println!` args. -/// -/// **Why is this bad?** Using literals as `println!` args is inefficient -/// (c.f., https://github.com/matthiaskrgr/rust-str-bench) and unnecessary -/// (i.e., just put the literal in the format string) -/// -/// **Known problems:** Will also warn with macro calls as arguments that expand to literals -/// -- e.g., `println!("{}", env!("FOO"))`. -/// -/// **Example:** -/// ```rust -/// println!("{}", "foo"); -/// ``` -/// use the literal without formatting: -/// ```rust -/// println!("foo"); -/// ``` declare_clippy_lint! { + /// **What it does:** This lint warns about the use of literals as `print!`/`println!` args. + /// + /// **Why is this bad?** Using literals as `println!` args is inefficient + /// (c.f., https://github.com/matthiaskrgr/rust-str-bench) and unnecessary + /// (i.e., just put the literal in the format string) + /// + /// **Known problems:** Will also warn with macro calls as arguments that expand to literals + /// -- e.g., `println!("{}", env!("FOO"))`. + /// + /// **Example:** + /// ```rust + /// println!("{}", "foo"); + /// ``` + /// use the literal without formatting: + /// ```rust + /// println!("foo"); + /// ``` pub PRINT_LITERAL, style, "printing a literal with a format string" } -/// **What it does:** This lint warns when you use `writeln!(buf, "")` to -/// print a newline. -/// -/// **Why is this bad?** You should use `writeln!(buf)`, which is simpler. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// writeln!(""); -/// ``` declare_clippy_lint! { + /// **What it does:** This lint warns when you use `writeln!(buf, "")` to + /// print a newline. + /// + /// **Why is this bad?** You should use `writeln!(buf)`, which is simpler. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// writeln!(""); + /// ``` pub WRITELN_EMPTY_STRING, style, "using `writeln!(\"\")` with an empty string" } -/// **What it does:** This lint warns when you use `write!()` with a format -/// string that -/// ends in a newline. -/// -/// **Why is this bad?** You should use `writeln!()` instead, which appends the -/// newline. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// write!(buf, "Hello {}!\n", name); -/// ``` declare_clippy_lint! { + /// **What it does:** This lint warns when you use `write!()` with a format + /// string that + /// ends in a newline. + /// + /// **Why is this bad?** You should use `writeln!()` instead, which appends the + /// newline. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// write!(buf, "Hello {}!\n", name); + /// ``` pub WRITE_WITH_NEWLINE, style, "using `write!()` with a format string that ends in a single newline" } -/// **What it does:** This lint warns about the use of literals as `write!`/`writeln!` args. -/// -/// **Why is this bad?** Using literals as `writeln!` args is inefficient -/// (c.f., https://github.com/matthiaskrgr/rust-str-bench) and unnecessary -/// (i.e., just put the literal in the format string) -/// -/// **Known problems:** Will also warn with macro calls as arguments that expand to literals -/// -- e.g., `writeln!(buf, "{}", env!("FOO"))`. -/// -/// **Example:** -/// ```rust -/// writeln!(buf, "{}", "foo"); -/// ``` declare_clippy_lint! { + /// **What it does:** This lint warns about the use of literals as `write!`/`writeln!` args. + /// + /// **Why is this bad?** Using literals as `writeln!` args is inefficient + /// (c.f., https://github.com/matthiaskrgr/rust-str-bench) and unnecessary + /// (i.e., just put the literal in the format string) + /// + /// **Known problems:** Will also warn with macro calls as arguments that expand to literals + /// -- e.g., `writeln!(buf, "{}", env!("FOO"))`. + /// + /// **Example:** + /// ```rust + /// writeln!(buf, "{}", "foo"); + /// ``` pub WRITE_LITERAL, style, "writing a literal with a format string" diff --git a/clippy_lints/src/zero_div_zero.rs b/clippy_lints/src/zero_div_zero.rs index a806be954322..de13816f66fd 100644 --- a/clippy_lints/src/zero_div_zero.rs +++ b/clippy_lints/src/zero_div_zero.rs @@ -5,18 +5,18 @@ use rustc::hir::*; use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use rustc::{declare_tool_lint, lint_array}; -/// **What it does:** Checks for `0.0 / 0.0`. -/// -/// **Why is this bad?** It's less readable than `std::f32::NAN` or -/// `std::f64::NAN`. -/// -/// **Known problems:** None. -/// -/// **Example:** -/// ```rust -/// 0.0f32 / 0.0 -/// ``` declare_clippy_lint! { + /// **What it does:** Checks for `0.0 / 0.0`. + /// + /// **Why is this bad?** It's less readable than `std::f32::NAN` or + /// `std::f64::NAN`. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// 0.0f32 / 0.0 + /// ``` pub ZERO_DIVIDED_BY_ZERO, complexity, "usage of `0.0 / 0.0` to obtain NaN instead of std::f32::NaN or std::f64::NaN" diff --git a/util/lintlib.py b/util/lintlib.py index 1c49ab770d5e..a260e00cde46 100644 --- a/util/lintlib.py +++ b/util/lintlib.py @@ -15,6 +15,7 @@ conf_re = re.compile(r'''define_Conf! {\n([^}]*)\n}''', re.MULTILINE) confvar_re = re.compile( r'''/// Lint: (\w+). (.*).*\n\s*\([^,]+,\s+"([^"]+)",\s+([^=\)]+)=>\s+(.*)\),''', re.MULTILINE) +comment_re = re.compile(r'''\s*/// ?(.*)''') lint_levels = { "correctness": 'Deny', @@ -29,37 +30,15 @@ def parse_lints(lints, filepath): - last_comment = [] - comment = True + comment = [] clippy = False deprecated = False name = "" with open(filepath) as fp: for line in fp: - if comment: - if line.startswith("/// "): - last_comment.append(line[4:]) - elif line.startswith("///"): - last_comment.append(line[3:]) - elif line.startswith("declare_lint!"): - import sys - print("don't use `declare_lint!` in Clippy, use `declare_clippy_lint!` instead") - sys.exit(42) - elif line.startswith("declare_clippy_lint!"): - comment = False - deprecated = False - clippy = True - name = "" - elif line.startswith("declare_deprecated_lint!"): - comment = False - deprecated = True - clippy = False - else: - last_comment = [] - if not comment: + if clippy or deprecated: m = lintname_re.search(line) - if m: name = m.group(1).lower() line = next(fp) @@ -81,13 +60,29 @@ def parse_lints(lints, filepath): log.info("found %s with level %s in %s", name, level, filepath) - lints.append(Lint(name, level, last_comment, filepath, group)) - last_comment = [] - comment = True + lints.append(Lint(name, level, comment, filepath, group)) + comment = [] - if "}" in line: - log.warn("Warning: missing Lint-Name in %s", filepath) - comment = True + clippy = False + deprecated = False + name = "" + else: + m = comment_re.search(line) + if m: + comment.append(m.group(1)) + elif line.startswith("declare_clippy_lint!"): + clippy = True + deprecated = False + elif line.startswith("declare_deprecated_lint!"): + clippy = False + deprecated = True + elif line.startswith("declare_lint!"): + import sys + print( + "don't use `declare_lint!` in Clippy, " + "use `declare_clippy_lint!` instead" + ) + sys.exit(42) def parse_configs(path):