mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-10 23:24:24 +00:00
Auto merge of #7726 - dswij:unseparated-literal-suffix, r=flip1995
Unseparated literal suffix Closes #7658 Since `literal_suffix` style is opinionated, we should disable by default and only enforce if it's stated as so. changelog: [`unseparated_literal_suffix`] is renamed to `literal_suffix`, adds a new configuration `literal-suffix-style` to enforce a certain style writing literal_suffix. Possible values for `literal-suffix-style`: `"separated"`, `"unseparated"`
This commit is contained in:
commit
38d80257d0
10 changed files with 152 additions and 60 deletions
|
@ -3123,6 +3123,7 @@ Released 2018-09-13
|
|||
[`self_named_constructors`]: https://rust-lang.github.io/rust-clippy/master/index.html#self_named_constructors
|
||||
[`self_named_module_files`]: https://rust-lang.github.io/rust-clippy/master/index.html#self_named_module_files
|
||||
[`semicolon_if_nothing_returned`]: https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_if_nothing_returned
|
||||
[`separated_literal_suffix`]: https://rust-lang.github.io/rust-clippy/master/index.html#separated_literal_suffix
|
||||
[`serde_api_misuse`]: https://rust-lang.github.io/rust-clippy/master/index.html#serde_api_misuse
|
||||
[`shadow_reuse`]: https://rust-lang.github.io/rust-clippy/master/index.html#shadow_reuse
|
||||
[`shadow_same`]: https://rust-lang.github.io/rust-clippy/master/index.html#shadow_same
|
||||
|
|
|
@ -327,6 +327,7 @@ store.register_lints(&[
|
|||
misc_early::DUPLICATE_UNDERSCORE_ARGUMENT,
|
||||
misc_early::MIXED_CASE_HEX_LITERALS,
|
||||
misc_early::REDUNDANT_PATTERN,
|
||||
misc_early::SEPARATED_LITERAL_SUFFIX,
|
||||
misc_early::UNNEEDED_FIELD_PATTERN,
|
||||
misc_early::UNNEEDED_WILDCARD_PATTERN,
|
||||
misc_early::UNSEPARATED_LITERAL_SUFFIX,
|
||||
|
|
|
@ -66,7 +66,6 @@ store.register_group(true, "clippy::pedantic", Some("clippy_pedantic"), vec![
|
|||
LintId::of(methods::MAP_UNWRAP_OR),
|
||||
LintId::of(misc::FLOAT_CMP),
|
||||
LintId::of(misc::USED_UNDERSCORE_BINDING),
|
||||
LintId::of(misc_early::UNSEPARATED_LITERAL_SUFFIX),
|
||||
LintId::of(mut_mut::MUT_MUT),
|
||||
LintId::of(needless_bitwise_bool::NEEDLESS_BITWISE_BOOL),
|
||||
LintId::of(needless_borrow::REF_BINDING_TO_REFERENCE),
|
||||
|
|
|
@ -35,7 +35,9 @@ store.register_group(true, "clippy::restriction", Some("clippy_restriction"), ve
|
|||
LintId::of(methods::GET_UNWRAP),
|
||||
LintId::of(methods::UNWRAP_USED),
|
||||
LintId::of(misc::FLOAT_CMP_CONST),
|
||||
LintId::of(misc_early::SEPARATED_LITERAL_SUFFIX),
|
||||
LintId::of(misc_early::UNNEEDED_FIELD_PATTERN),
|
||||
LintId::of(misc_early::UNSEPARATED_LITERAL_SUFFIX),
|
||||
LintId::of(missing_doc::MISSING_DOCS_IN_PRIVATE_ITEMS),
|
||||
LintId::of(missing_enforced_import_rename::MISSING_ENFORCED_IMPORT_RENAMES),
|
||||
LintId::of(missing_inline::MISSING_INLINE_IN_PUBLIC_ITEMS),
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use super::MiscEarlyLints;
|
||||
use clippy_utils::diagnostics::span_lint;
|
||||
use rustc_ast::ast::{Expr, ExprKind, UnOp};
|
||||
use rustc_lint::EarlyContext;
|
||||
|
@ -6,18 +5,14 @@ use rustc_lint::EarlyContext;
|
|||
use super::DOUBLE_NEG;
|
||||
|
||||
pub(super) fn check(cx: &EarlyContext<'_>, expr: &Expr) {
|
||||
match expr.kind {
|
||||
ExprKind::Unary(UnOp::Neg, ref inner) => {
|
||||
if let ExprKind::Unary(UnOp::Neg, _) = inner.kind {
|
||||
span_lint(
|
||||
cx,
|
||||
DOUBLE_NEG,
|
||||
expr.span,
|
||||
"`--x` could be misinterpreted as pre-decrement by C programmers, is usually a no-op",
|
||||
);
|
||||
}
|
||||
},
|
||||
ExprKind::Lit(ref lit) => MiscEarlyLints::check_lit(cx, lit),
|
||||
_ => (),
|
||||
if let ExprKind::Unary(UnOp::Neg, ref inner) = expr.kind {
|
||||
if let ExprKind::Unary(UnOp::Neg, _) = inner.kind {
|
||||
span_lint(
|
||||
cx,
|
||||
DOUBLE_NEG,
|
||||
expr.span,
|
||||
"`--x` could be misinterpreted as pre-decrement by C programmers, is usually a no-op",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
38
clippy_lints/src/misc_early/literal_suffix.rs
Normal file
38
clippy_lints/src/misc_early/literal_suffix.rs
Normal file
|
@ -0,0 +1,38 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use rustc_ast::ast::Lit;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_lint::EarlyContext;
|
||||
|
||||
use super::{SEPARATED_LITERAL_SUFFIX, UNSEPARATED_LITERAL_SUFFIX};
|
||||
|
||||
pub(super) fn check(cx: &EarlyContext<'_>, lit: &Lit, lit_snip: &str, suffix: &str, sugg_type: &str) {
|
||||
let maybe_last_sep_idx = if let Some(val) = lit_snip.len().checked_sub(suffix.len() + 1) {
|
||||
val
|
||||
} else {
|
||||
return; // It's useless so shouldn't lint.
|
||||
};
|
||||
// Do not lint when literal is unsuffixed.
|
||||
if !suffix.is_empty() {
|
||||
if lit_snip.as_bytes()[maybe_last_sep_idx] == b'_' {
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
SEPARATED_LITERAL_SUFFIX,
|
||||
lit.span,
|
||||
&format!("{} type suffix should not be separated by an underscore", sugg_type),
|
||||
"remove the underscore",
|
||||
format!("{}{}", &lit_snip[..maybe_last_sep_idx], suffix),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
} else {
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
UNSEPARATED_LITERAL_SUFFIX,
|
||||
lit.span,
|
||||
&format!("{} type suffix should be separated by an underscore", sugg_type),
|
||||
"add an underscore",
|
||||
format!("{}_{}", &lit_snip[..=maybe_last_sep_idx], suffix),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,15 +1,15 @@
|
|||
mod builtin_type_shadow;
|
||||
mod double_neg;
|
||||
mod literal_suffix;
|
||||
mod mixed_case_hex_literals;
|
||||
mod redundant_pattern;
|
||||
mod unneeded_field_pattern;
|
||||
mod unneeded_wildcard_pattern;
|
||||
mod unseparated_literal_suffix;
|
||||
mod zero_prefixed_literal;
|
||||
|
||||
use clippy_utils::diagnostics::span_lint;
|
||||
use clippy_utils::source::snippet_opt;
|
||||
use rustc_ast::ast::{Expr, Generics, Lit, LitFloatType, LitIntType, LitKind, NodeId, Pat, PatKind};
|
||||
use rustc_ast::ast::{Expr, ExprKind, Generics, Lit, LitFloatType, LitIntType, LitKind, NodeId, Pat, PatKind};
|
||||
use rustc_ast::visit::FnKind;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass};
|
||||
|
@ -115,9 +115,11 @@ declare_clippy_lint! {
|
|||
/// ### What it does
|
||||
/// Warns if literal suffixes are not separated by an
|
||||
/// underscore.
|
||||
/// To enforce unseparated literal suffix style,
|
||||
/// see the `separated_literal_suffix` lint.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
/// It is much less readable.
|
||||
/// Suffix style should be consistent.
|
||||
///
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
|
@ -128,10 +130,32 @@ declare_clippy_lint! {
|
|||
/// let y = 123832_i32;
|
||||
/// ```
|
||||
pub UNSEPARATED_LITERAL_SUFFIX,
|
||||
pedantic,
|
||||
restriction,
|
||||
"literals whose suffix is not separated by an underscore"
|
||||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Warns if literal suffixes are separated by an underscore.
|
||||
/// To enforce separated literal suffix style,
|
||||
/// see the `unseparated_literal_suffix` lint.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
/// Suffix style should be consistent.
|
||||
///
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// // Bad
|
||||
/// let y = 123832_i32;
|
||||
///
|
||||
/// // Good
|
||||
/// let y = 123832i32;
|
||||
/// ```
|
||||
pub SEPARATED_LITERAL_SUFFIX,
|
||||
restriction,
|
||||
"literals whose suffix is separated by an underscore"
|
||||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Warns if an integral constant literal starts with `0`.
|
||||
|
@ -260,6 +284,7 @@ declare_lint_pass!(MiscEarlyLints => [
|
|||
DOUBLE_NEG,
|
||||
MIXED_CASE_HEX_LITERALS,
|
||||
UNSEPARATED_LITERAL_SUFFIX,
|
||||
SEPARATED_LITERAL_SUFFIX,
|
||||
ZERO_PREFIXED_LITERAL,
|
||||
BUILTIN_TYPE_SHADOW,
|
||||
REDUNDANT_PATTERN,
|
||||
|
@ -310,6 +335,10 @@ impl EarlyLintPass for MiscEarlyLints {
|
|||
if in_external_macro(cx.sess, expr.span) {
|
||||
return;
|
||||
}
|
||||
|
||||
if let ExprKind::Lit(ref lit) = expr.kind {
|
||||
MiscEarlyLints::check_lit(cx, lit);
|
||||
}
|
||||
double_neg::check(cx, expr);
|
||||
}
|
||||
}
|
||||
|
@ -332,7 +361,7 @@ impl MiscEarlyLints {
|
|||
LitIntType::Unsigned(ty) => ty.name_str(),
|
||||
LitIntType::Unsuffixed => "",
|
||||
};
|
||||
unseparated_literal_suffix::check(cx, lit, &lit_snip, suffix, "integer");
|
||||
literal_suffix::check(cx, lit, &lit_snip, suffix, "integer");
|
||||
if lit_snip.starts_with("0x") {
|
||||
mixed_case_hex_literals::check(cx, lit, suffix, &lit_snip);
|
||||
} else if lit_snip.starts_with("0b") || lit_snip.starts_with("0o") {
|
||||
|
@ -342,7 +371,7 @@ impl MiscEarlyLints {
|
|||
}
|
||||
} else if let LitKind::Float(_, LitFloatType::Suffixed(float_ty)) = lit.kind {
|
||||
let suffix = float_ty.name_str();
|
||||
unseparated_literal_suffix::check(cx, lit, &lit_snip, suffix, "float");
|
||||
literal_suffix::check(cx, lit, &lit_snip, suffix, "float");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use rustc_ast::ast::Lit;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_lint::EarlyContext;
|
||||
|
||||
use super::UNSEPARATED_LITERAL_SUFFIX;
|
||||
|
||||
pub(super) fn check(cx: &EarlyContext<'_>, lit: &Lit, lit_snip: &str, suffix: &str, sugg_type: &str) {
|
||||
let maybe_last_sep_idx = if let Some(val) = lit_snip.len().checked_sub(suffix.len() + 1) {
|
||||
val
|
||||
} else {
|
||||
return; // It's useless so shouldn't lint.
|
||||
};
|
||||
// Do not lint when literal is unsuffixed.
|
||||
if !suffix.is_empty() && lit_snip.as_bytes()[maybe_last_sep_idx] != b'_' {
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
UNSEPARATED_LITERAL_SUFFIX,
|
||||
lit.span,
|
||||
&format!("{} type suffix should be separated by an underscore", sugg_type),
|
||||
"add an underscore",
|
||||
format!("{}_{}", &lit_snip[..=maybe_last_sep_idx], suffix),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
}
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
#![warn(clippy::mixed_case_hex_literals)]
|
||||
#![warn(clippy::zero_prefixed_literal)]
|
||||
#![allow(clippy::unseparated_literal_suffix)]
|
||||
#![warn(clippy::unseparated_literal_suffix)]
|
||||
#![warn(clippy::separated_literal_suffix)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
fn main() {
|
||||
|
|
|
@ -1,25 +1,65 @@
|
|||
error: integer type suffix should not be separated by an underscore
|
||||
--> $DIR/literals.rs:12:15
|
||||
|
|
||||
LL | let ok4 = 0xab_cd_i32;
|
||||
| ^^^^^^^^^^^ help: remove the underscore: `0xab_cdi32`
|
||||
|
|
||||
= note: `-D clippy::separated-literal-suffix` implied by `-D warnings`
|
||||
|
||||
error: integer type suffix should not be separated by an underscore
|
||||
--> $DIR/literals.rs:13:15
|
||||
|
|
||||
LL | let ok5 = 0xAB_CD_u32;
|
||||
| ^^^^^^^^^^^ help: remove the underscore: `0xAB_CDu32`
|
||||
|
||||
error: integer type suffix should not be separated by an underscore
|
||||
--> $DIR/literals.rs:14:15
|
||||
|
|
||||
LL | let ok5 = 0xAB_CD_isize;
|
||||
| ^^^^^^^^^^^^^ help: remove the underscore: `0xAB_CDisize`
|
||||
|
||||
error: inconsistent casing in hexadecimal literal
|
||||
--> $DIR/literals.rs:14:17
|
||||
--> $DIR/literals.rs:15:17
|
||||
|
|
||||
LL | let fail1 = 0xabCD;
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: `-D clippy::mixed-case-hex-literals` implied by `-D warnings`
|
||||
|
||||
error: inconsistent casing in hexadecimal literal
|
||||
--> $DIR/literals.rs:15:17
|
||||
error: integer type suffix should not be separated by an underscore
|
||||
--> $DIR/literals.rs:16:17
|
||||
|
|
||||
LL | let fail2 = 0xabCD_u32;
|
||||
| ^^^^^^^^^^
|
||||
| ^^^^^^^^^^ help: remove the underscore: `0xabCDu32`
|
||||
|
||||
error: inconsistent casing in hexadecimal literal
|
||||
--> $DIR/literals.rs:16:17
|
||||
|
|
||||
LL | let fail2 = 0xabCD_u32;
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: integer type suffix should not be separated by an underscore
|
||||
--> $DIR/literals.rs:17:17
|
||||
|
|
||||
LL | let fail2 = 0xabCD_isize;
|
||||
| ^^^^^^^^^^^^ help: remove the underscore: `0xabCDisize`
|
||||
|
||||
error: inconsistent casing in hexadecimal literal
|
||||
--> $DIR/literals.rs:17:17
|
||||
|
|
||||
LL | let fail2 = 0xabCD_isize;
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: integer type suffix should be separated by an underscore
|
||||
--> $DIR/literals.rs:18:27
|
||||
|
|
||||
LL | let fail_multi_zero = 000_123usize;
|
||||
| ^^^^^^^^^^^^ help: add an underscore: `000_123_usize`
|
||||
|
|
||||
= note: `-D clippy::unseparated-literal-suffix` implied by `-D warnings`
|
||||
|
||||
error: this is a decimal constant
|
||||
--> $DIR/literals.rs:17:27
|
||||
--> $DIR/literals.rs:18:27
|
||||
|
|
||||
LL | let fail_multi_zero = 000_123usize;
|
||||
| ^^^^^^^^^^^^
|
||||
|
@ -34,8 +74,14 @@ help: if you mean to use an octal constant, use `0o`
|
|||
LL | let fail_multi_zero = 0o123usize;
|
||||
| ~~~~~~~~~~
|
||||
|
||||
error: integer type suffix should not be separated by an underscore
|
||||
--> $DIR/literals.rs:21:16
|
||||
|
|
||||
LL | let ok10 = 0_i64;
|
||||
| ^^^^^ help: remove the underscore: `0i64`
|
||||
|
||||
error: this is a decimal constant
|
||||
--> $DIR/literals.rs:21:17
|
||||
--> $DIR/literals.rs:22:17
|
||||
|
|
||||
LL | let fail8 = 0123;
|
||||
| ^^^^
|
||||
|
@ -49,8 +95,14 @@ help: if you mean to use an octal constant, use `0o`
|
|||
LL | let fail8 = 0o123;
|
||||
| ~~~~~
|
||||
|
||||
error: integer type suffix should not be separated by an underscore
|
||||
--> $DIR/literals.rs:31:16
|
||||
|
|
||||
LL | let ok17 = 0x123_4567_8901_usize;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ help: remove the underscore: `0x123_4567_8901usize`
|
||||
|
||||
error: digits grouped inconsistently by underscores
|
||||
--> $DIR/literals.rs:33:18
|
||||
--> $DIR/literals.rs:34:18
|
||||
|
|
||||
LL | let fail19 = 12_3456_21;
|
||||
| ^^^^^^^^^^ help: consider: `12_345_621`
|
||||
|
@ -58,19 +110,19 @@ LL | let fail19 = 12_3456_21;
|
|||
= note: `-D clippy::inconsistent-digit-grouping` implied by `-D warnings`
|
||||
|
||||
error: digits grouped inconsistently by underscores
|
||||
--> $DIR/literals.rs:34:18
|
||||
--> $DIR/literals.rs:35:18
|
||||
|
|
||||
LL | let fail22 = 3__4___23;
|
||||
| ^^^^^^^^^ help: consider: `3_423`
|
||||
|
||||
error: digits grouped inconsistently by underscores
|
||||
--> $DIR/literals.rs:35:18
|
||||
--> $DIR/literals.rs:36:18
|
||||
|
|
||||
LL | let fail23 = 3__16___23;
|
||||
| ^^^^^^^^^^ help: consider: `31_623`
|
||||
|
||||
error: digits of hex or binary literal not grouped by four
|
||||
--> $DIR/literals.rs:37:18
|
||||
--> $DIR/literals.rs:38:18
|
||||
|
|
||||
LL | let fail24 = 0xAB_ABC_AB;
|
||||
| ^^^^^^^^^^^ help: consider: `0x0ABA_BCAB`
|
||||
|
@ -78,10 +130,10 @@ LL | let fail24 = 0xAB_ABC_AB;
|
|||
= note: `-D clippy::unusual-byte-groupings` implied by `-D warnings`
|
||||
|
||||
error: digits of hex or binary literal not grouped by four
|
||||
--> $DIR/literals.rs:38:18
|
||||
--> $DIR/literals.rs:39:18
|
||||
|
|
||||
LL | let fail25 = 0b01_100_101;
|
||||
| ^^^^^^^^^^^^ help: consider: `0b0110_0101`
|
||||
|
||||
error: aborting due to 10 previous errors
|
||||
error: aborting due to 18 previous errors
|
||||
|
||||
|
|
Loading…
Reference in a new issue