Skip to content

Commit cea7d9d

Browse files
committed
Cleaner code for unsep literals
1 parent 0ccb9ea commit cea7d9d

File tree

1 file changed

+69
-73
lines changed

1 file changed

+69
-73
lines changed

clippy_lints/src/misc_early.rs

Lines changed: 69 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use rustc::lint::{in_external_macro, EarlyContext, EarlyLintPass, LintArray, Lin
66
use rustc::{declare_lint_pass, declare_tool_lint};
77
use rustc_data_structures::fx::FxHashMap;
88
use rustc_errors::Applicability;
9-
use std::char;
109
use syntax::ast::*;
1110
use syntax::source_map::Span;
1211
use syntax::visit::{walk_expr, FnKind, Visitor};
@@ -391,91 +390,88 @@ impl EarlyLintPass for MiscEarlyLints {
391390

392391
impl MiscEarlyLints {
393392
fn check_lit(self, cx: &EarlyContext<'_>, lit: &Lit) {
394-
if_chain! {
395-
if let LitKind::Int(value, ..) = lit.node;
396-
if let Some(src) = snippet_opt(cx, lit.span);
397-
if let Some(firstch) = src.chars().next();
398-
if char::to_digit(firstch, 10).is_some();
399-
then {
400-
let mut prev = '\0';
401-
for (idx, ch) in src.chars().enumerate() {
402-
if ch == 'i' || ch == 'u' {
403-
if prev != '_' {
404-
span_lint_and_sugg(
405-
cx,
406-
UNSEPARATED_LITERAL_SUFFIX,
407-
lit.span,
408-
"integer type suffix should be separated by an underscore",
409-
"add an underscore",
410-
format!("{}_{}", &src[0..idx], &src[idx..]),
411-
Applicability::MachineApplicable,
412-
);
413-
}
414-
break;
415-
}
416-
prev = ch;
393+
if in_external_macro(cx.sess(), lit.span) {
394+
return;
395+
}
396+
397+
if let LitKind::Int(value, lit_int_type) = lit.node {
398+
if let Some(src) = snippet_opt(cx, lit.span) {
399+
let suffix = match lit_int_type {
400+
LitIntType::Signed(ty) => ty.ty_to_string(),
401+
LitIntType::Unsigned(ty) => ty.ty_to_string(),
402+
LitIntType::Unsuffixed => "",
403+
};
404+
405+
let maybe_last_sep_idx = src.len() - suffix.len() - 1;
406+
// Do not suggest when literal is unsuffixed.
407+
if !suffix.is_empty() && src.as_bytes()[maybe_last_sep_idx] != b'_' {
408+
span_lint_and_sugg(
409+
cx,
410+
UNSEPARATED_LITERAL_SUFFIX,
411+
lit.span,
412+
"integer type suffix should be separated by an underscore",
413+
"add an underscore",
414+
format!("{}_{}", &src[..=maybe_last_sep_idx], suffix),
415+
Applicability::MachineApplicable,
416+
);
417417
}
418+
418419
if src.starts_with("0x") {
419420
let mut seen = (false, false);
420-
for ch in src.chars() {
421+
for ch in src.as_bytes()[2..=maybe_last_sep_idx].iter() {
421422
match ch {
422-
'a' ..= 'f' => seen.0 = true,
423-
'A' ..= 'F' => seen.1 = true,
424-
'i' | 'u' => break, // start of suffix already
425-
_ => ()
423+
b'a'..=b'f' => seen.0 = true,
424+
b'A'..=b'F' => seen.1 = true,
425+
_ => {},
426426
}
427427
}
428428
if seen.0 && seen.1 {
429-
span_lint(cx, MIXED_CASE_HEX_LITERALS, lit.span,
430-
"inconsistent casing in hexadecimal literal");
429+
span_lint(
430+
cx,
431+
MIXED_CASE_HEX_LITERALS,
432+
lit.span,
433+
"inconsistent casing in hexadecimal literal",
434+
);
431435
}
432436
} else if src.starts_with("0b") || src.starts_with("0o") {
433437
/* nothing to do */
434438
} else if value != 0 && src.starts_with('0') {
435-
span_lint_and_then(cx,
436-
ZERO_PREFIXED_LITERAL,
437-
lit.span,
438-
"this is a decimal constant",
439-
|db| {
440-
db.span_suggestion(
441-
lit.span,
442-
"if you mean to use a decimal constant, remove the `0` to remove confusion",
443-
src.trim_start_matches(|c| c == '_' || c == '0').to_string(),
444-
Applicability::MaybeIncorrect,
445-
);
446-
db.span_suggestion(
447-
lit.span,
448-
"if you mean to use an octal constant, use `0o`",
449-
format!("0o{}", src.trim_start_matches(|c| c == '_' || c == '0')),
450-
Applicability::MaybeIncorrect,
451-
);
452-
});
453-
}
454-
}
455-
}
456-
if_chain! {
457-
if let LitKind::Float(..) = lit.node;
458-
if let Some(src) = snippet_opt(cx, lit.span);
459-
if let Some(firstch) = src.chars().next();
460-
if char::to_digit(firstch, 10).is_some();
461-
then {
462-
let mut prev = '\0';
463-
for (idx, ch) in src.chars().enumerate() {
464-
if ch == 'f' {
465-
if prev != '_' {
466-
span_lint_and_sugg(
467-
cx,
468-
UNSEPARATED_LITERAL_SUFFIX,
439+
span_lint_and_then(
440+
cx,
441+
ZERO_PREFIXED_LITERAL,
442+
lit.span,
443+
"this is a decimal constant",
444+
|db| {
445+
db.span_suggestion(
469446
lit.span,
470-
"float type suffix should be separated by an underscore",
471-
"add an underscore",
472-
format!("{}_{}", &src[0..idx], &src[idx..]),
473-
Applicability::MachineApplicable,
447+
"if you mean to use a decimal constant, remove the `0` to avoid confusion",
448+
src.trim_start_matches(|c| c == '_' || c == '0').to_string(),
449+
Applicability::MaybeIncorrect,
474450
);
475-
}
476-
break;
477-
}
478-
prev = ch;
451+
db.span_suggestion(
452+
lit.span,
453+
"if you mean to use an octal constant, use `0o`",
454+
format!("0o{}", src.trim_start_matches(|c| c == '_' || c == '0')),
455+
Applicability::MaybeIncorrect,
456+
);
457+
},
458+
);
459+
}
460+
}
461+
} else if let LitKind::Float(_, float_ty) = lit.node {
462+
if let Some(src) = snippet_opt(cx, lit.span) {
463+
let suffix = float_ty.ty_to_string();
464+
let maybe_last_sep_idx = src.len() - suffix.len() - 1;
465+
if src.as_bytes()[maybe_last_sep_idx] != b'_' {
466+
span_lint_and_sugg(
467+
cx,
468+
UNSEPARATED_LITERAL_SUFFIX,
469+
lit.span,
470+
"float type suffix should be separated by an underscore",
471+
"add an underscore",
472+
format!("{}_{}", &src[..=maybe_last_sep_idx], suffix),
473+
Applicability::MachineApplicable,
474+
);
479475
}
480476
}
481477
}

0 commit comments

Comments
 (0)