//! floating-point literal expressions.
use rustc::lint::*;
+use rustc::{declare_lint, lint_array};
+use if_chain::if_chain;
use syntax::ast::*;
use syntax_pos;
-use utils::{in_external_macro, snippet_opt, span_lint_and_sugg};
+use crate::utils::{in_external_macro, snippet_opt, span_lint_and_sugg};
/// **What it does:** Warns if a long integral or floating-point constant does
/// not contain underscores.
/// ```rust
/// 61864918973511
/// ```
-declare_lint! {
+declare_clippy_lint! {
pub UNREADABLE_LITERAL,
- Warn,
+ style,
"long integer literal without underscores"
}
/// ```rust
/// 618_64_9189_73_511
/// ```
-declare_lint! {
+declare_clippy_lint! {
pub INCONSISTENT_DIGIT_GROUPING,
- Warn,
+ style,
"integer literals with digits grouped inconsistently"
}
/// ```rust
/// 6186491_8973511
/// ```
-declare_lint! {
+declare_clippy_lint! {
pub LARGE_DIGIT_GROUPS,
- Warn,
+ style,
"grouping digits into groups that are too large"
}
/// `255` => `0xFF`
/// `65_535` => `0xFFFF`
/// `4_042_322_160` => `0xF0F0_F0F0`
-declare_restriction_lint! {
+declare_clippy_lint! {
pub DECIMAL_LITERAL_REPRESENTATION,
+ restriction,
"using decimal representation when hexadecimal would be better"
}
#[derive(Debug, PartialEq)]
-enum Radix {
+pub(super) enum Radix {
Binary,
Octal,
Decimal,
impl Radix {
/// Return a reasonable digit group size for this radix.
- pub fn suggest_grouping(&self) -> usize {
+ crate fn suggest_grouping(&self) -> usize {
match *self {
Radix::Binary | Radix::Hexadecimal => 4,
Radix::Octal | Radix::Decimal => 3,
}
#[derive(Debug)]
-struct DigitInfo<'a> {
+pub(super) struct DigitInfo<'a> {
/// Characters of a literal between the radix prefix and type suffix.
- pub digits: &'a str,
+ crate digits: &'a str,
/// Which radix the literal was represented in.
- pub radix: Radix,
+ crate radix: Radix,
/// The radix prefix, if present.
- pub prefix: Option<&'a str>,
+ crate prefix: Option<&'a str>,
/// The type suffix, including preceding underscore if present.
- pub suffix: Option<&'a str>,
+ crate suffix: Option<&'a str>,
/// True for floating-point literals.
- pub float: bool,
+ crate float: bool,
}
impl<'a> DigitInfo<'a> {
- pub fn new(lit: &'a str, float: bool) -> Self {
+ crate fn new(lit: &'a str, float: bool) -> Self {
// Determine delimiter for radix prefix, if present, and radix.
let radix = if lit.starts_with("0x") {
Radix::Hexadecimal
let suffix_start = if last_d == '_' { d_idx - 1 } else { d_idx };
let (digits, suffix) = sans_prefix.split_at(suffix_start);
return Self {
- digits: digits,
- radix: radix,
- prefix: prefix,
+ digits,
+ radix,
+ prefix,
suffix: Some(suffix),
- float: float,
+ float,
};
}
last_d = d
// No suffix found
Self {
digits: sans_prefix,
- radix: radix,
- prefix: prefix,
+ radix,
+ prefix,
suffix: None,
- float: float,
+ float,
}
}
/// Returns digits grouped in a sensible way.
- fn grouping_hint(&self) -> String {
+ crate fn grouping_hint(&self) -> String {
let group_size = self.radix.suggest_grouping();
if self.digits.contains('.') {
let mut parts = self.digits.split('.');
self.suffix.unwrap_or("")
)
} else {
- let hint = self.digits
+ let filtered_digits_vec = self.digits
.chars()
- .rev()
.filter(|&c| c != '_')
- .collect::<Vec<_>>()
+ .rev()
+ .collect::<Vec<_>>();
+ let mut hint = filtered_digits_vec
.chunks(group_size)
.map(|chunk| chunk.into_iter().rev().collect())
.rev()
.collect::<Vec<String>>()
.join("_");
+ // Forces hexadecimal values to be grouped by 4 being filled with zeroes (e.g 0x00ab_cdef)
+ let nb_digits_to_fill = filtered_digits_vec.len() % 4;
+ if self.radix == Radix::Hexadecimal && nb_digits_to_fill != 0 {
+ hint = format!("{:0>4}{}", &hint[..nb_digits_to_fill], &hint[nb_digits_to_fill..]);
+ }
format!(
"{}{}{}",
self.prefix.unwrap_or(""),
}
impl WarningType {
- pub fn display(&self, grouping_hint: &str, cx: &EarlyContext, span: &syntax_pos::Span) {
- match *self {
+ crate fn display(&self, grouping_hint: &str, cx: &EarlyContext, span: syntax_pos::Span) {
+ match self {
WarningType::UnreadableLiteral => span_lint_and_sugg(
cx,
UNREADABLE_LITERAL,
- *span,
+ span,
"long literal lacking separators",
"consider",
grouping_hint.to_owned(),
WarningType::LargeDigitGroups => span_lint_and_sugg(
cx,
LARGE_DIGIT_GROUPS,
- *span,
+ span,
"digit groups should be smaller",
"consider",
grouping_hint.to_owned(),
WarningType::InconsistentDigitGrouping => span_lint_and_sugg(
cx,
INCONSISTENT_DIGIT_GROUPING,
- *span,
+ span,
"digits grouped inconsistently by underscores",
"consider",
grouping_hint.to_owned(),
WarningType::DecimalRepresentation => span_lint_and_sugg(
cx,
DECIMAL_LITERAL_REPRESENTATION,
- *span,
+ span,
"integer literal has a better hexadecimal representation",
"consider",
grouping_hint.to_owned(),
}
impl LiteralDigitGrouping {
- fn check_lit(&self, cx: &EarlyContext, lit: &Lit) {
+ fn check_lit(self, cx: &EarlyContext, lit: &Lit) {
match lit.node {
LitKind::Int(..) => {
// Lint integral literals.
then {
let digit_info = DigitInfo::new(&src, false);
let _ = Self::do_lint(digit_info.digits).map_err(|warning_type| {
- warning_type.display(&digit_info.grouping_hint(), cx, &lit.span)
+ warning_type.display(&digit_info.grouping_hint(), cx, lit.span)
});
}
}
if !consistent {
WarningType::InconsistentDigitGrouping.display(&digit_info.grouping_hint(),
cx,
- &lit.span);
+ lit.span);
}
})
.map_err(|warning_type| warning_type.display(&digit_info.grouping_hint(),
cx,
- &lit.span));
+ lit.span));
}
})
- .map_err(|warning_type| warning_type.display(&digit_info.grouping_hint(), cx, &lit.span));
+ .map_err(|warning_type| warning_type.display(&digit_info.grouping_hint(), cx, lit.span));
}
}
},
impl LiteralRepresentation {
pub fn new(threshold: u64) -> Self {
Self {
- threshold: threshold,
+ threshold,
}
}
- fn check_lit(&self, cx: &EarlyContext, lit: &Lit) {
+ fn check_lit(self, cx: &EarlyContext, lit: &Lit) {
// Lint integral literals.
if_chain! {
if let LitKind::Int(..) = lit.node;
.filter(|&c| c != '_')
.collect::<String>()
.parse::<u128>().unwrap();
- if val < self.threshold as u128 {
+ if val < u128::from(self.threshold) {
return
}
let hex = format!("{:#X}", val);
let digit_info = DigitInfo::new(&hex[..], false);
let _ = Self::do_lint(digit_info.digits).map_err(|warning_type| {
- warning_type.display(&digit_info.grouping_hint(), cx, &lit.span)
+ warning_type.display(&digit_info.grouping_hint(), cx, lit.span)
});
}
}