Auto merge of #4149 - flip1995:rollup-6knpdqb, r=flip1995
Rollup of 2 pull requests Successful merges: - #4102 (Fix match_same_arms to fail late) - #4119 (Improve non ascii literal) Failed merges: r? @ghost
This commit is contained in:
commit
eb0a2884d2
8 changed files with 245 additions and 86 deletions
|
|
@ -152,7 +152,7 @@ fn lint_same_cond(cx: &LateContext<'_, '_>, conds: &[&Expr]) {
|
|||
let eq: &dyn Fn(&&Expr, &&Expr) -> bool =
|
||||
&|&lhs, &rhs| -> bool { SpanlessEq::new(cx).ignore_fn().eq_expr(lhs, rhs) };
|
||||
|
||||
if let Some((i, j)) = search_same(conds, hash, eq) {
|
||||
for (i, j) in search_same(conds, hash, eq) {
|
||||
span_note_and_lint(
|
||||
cx,
|
||||
IFS_SAME_COND,
|
||||
|
|
@ -185,7 +185,7 @@ fn lint_match_arms(cx: &LateContext<'_, '_>, expr: &Expr) {
|
|||
};
|
||||
|
||||
let indexed_arms: Vec<(usize, &Arm)> = arms.iter().enumerate().collect();
|
||||
if let Some((&(_, i), &(_, j))) = search_same(&indexed_arms, hash, eq) {
|
||||
for (&(_, i), &(_, j)) in search_same(&indexed_arms, hash, eq) {
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
MATCH_SAME_ARMS,
|
||||
|
|
@ -217,7 +217,10 @@ fn lint_match_arms(cx: &LateContext<'_, '_>, expr: &Expr) {
|
|||
),
|
||||
);
|
||||
} else {
|
||||
db.span_note(i.body.span, &format!("consider refactoring into `{} | {}`", lhs, rhs));
|
||||
db.span_help(
|
||||
i.pats[0].span,
|
||||
&format!("consider refactoring into `{} | {}`", lhs, rhs),
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -323,22 +326,34 @@ where
|
|||
None
|
||||
}
|
||||
|
||||
fn search_same<T, Hash, Eq>(exprs: &[T], hash: Hash, eq: Eq) -> Option<(&T, &T)>
|
||||
fn search_common_cases<'a, T, Eq>(exprs: &'a [T], eq: &Eq) -> Option<(&'a T, &'a T)>
|
||||
where
|
||||
Eq: Fn(&T, &T) -> bool,
|
||||
{
|
||||
if exprs.len() < 2 {
|
||||
None
|
||||
} else if exprs.len() == 2 {
|
||||
if eq(&exprs[0], &exprs[1]) {
|
||||
Some((&exprs[0], &exprs[1]))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn search_same<T, Hash, Eq>(exprs: &[T], hash: Hash, eq: Eq) -> Vec<(&T, &T)>
|
||||
where
|
||||
Hash: Fn(&T) -> u64,
|
||||
Eq: Fn(&T, &T) -> bool,
|
||||
{
|
||||
// common cases
|
||||
if exprs.len() < 2 {
|
||||
return None;
|
||||
} else if exprs.len() == 2 {
|
||||
return if eq(&exprs[0], &exprs[1]) {
|
||||
Some((&exprs[0], &exprs[1]))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
if let Some(expr) = search_common_cases(&exprs, &eq) {
|
||||
return vec![expr];
|
||||
}
|
||||
|
||||
let mut match_expr_list: Vec<(&T, &T)> = Vec::new();
|
||||
|
||||
let mut map: FxHashMap<_, Vec<&_>> =
|
||||
FxHashMap::with_capacity_and_hasher(exprs.len(), BuildHasherDefault::default());
|
||||
|
||||
|
|
@ -347,7 +362,7 @@ where
|
|||
Entry::Occupied(mut o) => {
|
||||
for o in o.get() {
|
||||
if eq(o, expr) {
|
||||
return Some((o, expr));
|
||||
match_expr_list.push((o, expr));
|
||||
}
|
||||
}
|
||||
o.get_mut().push(expr);
|
||||
|
|
@ -358,5 +373,5 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
None
|
||||
match_expr_list
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
use crate::utils::{is_allowed, snippet, span_help_and_lint};
|
||||
use crate::utils::{is_allowed, snippet, span_lint_and_sugg};
|
||||
use rustc::hir::*;
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_lint_pass, declare_tool_lint};
|
||||
use rustc_errors::Applicability;
|
||||
use syntax::ast::LitKind;
|
||||
use syntax::source_map::Span;
|
||||
use unicode_normalization::UnicodeNormalization;
|
||||
|
|
@ -34,7 +35,11 @@ declare_clippy_lint! {
|
|||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let x = "Hä?"
|
||||
/// let x = String::from("€");
|
||||
/// ```
|
||||
/// Could be written as:
|
||||
/// ```rust
|
||||
/// let x = String::from("\u{20ac}");
|
||||
/// ```
|
||||
pub NON_ASCII_LITERAL,
|
||||
pedantic,
|
||||
|
|
@ -87,43 +92,40 @@ fn escape<T: Iterator<Item = char>>(s: T) -> String {
|
|||
fn check_str(cx: &LateContext<'_, '_>, span: Span, id: HirId) {
|
||||
let string = snippet(cx, span, "");
|
||||
if string.contains('\u{200B}') {
|
||||
span_help_and_lint(
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
ZERO_WIDTH_SPACE,
|
||||
span,
|
||||
"zero-width space detected",
|
||||
&format!(
|
||||
"Consider replacing the string with:\n\"{}\"",
|
||||
string.replace("\u{200B}", "\\u{200B}")
|
||||
),
|
||||
"consider replacing the string with",
|
||||
string.replace("\u{200B}", "\\u{200B}"),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
if string.chars().any(|c| c as u32 > 0x7F) {
|
||||
span_help_and_lint(
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
NON_ASCII_LITERAL,
|
||||
span,
|
||||
"literal non-ASCII character detected",
|
||||
&format!(
|
||||
"Consider replacing the string with:\n\"{}\"",
|
||||
if is_allowed(cx, UNICODE_NOT_NFC, id) {
|
||||
escape(string.chars())
|
||||
} else {
|
||||
escape(string.nfc())
|
||||
}
|
||||
),
|
||||
"consider replacing the string with",
|
||||
if is_allowed(cx, UNICODE_NOT_NFC, id) {
|
||||
escape(string.chars())
|
||||
} else {
|
||||
escape(string.nfc())
|
||||
},
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
if is_allowed(cx, NON_ASCII_LITERAL, id) && string.chars().zip(string.nfc()).any(|(a, b)| a != b) {
|
||||
span_help_and_lint(
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
UNICODE_NOT_NFC,
|
||||
span,
|
||||
"non-nfc unicode sequence detected",
|
||||
&format!(
|
||||
"Consider replacing the string with:\n\"{}\"",
|
||||
string.nfc().collect::<String>()
|
||||
),
|
||||
"consider replacing the string with",
|
||||
string.nfc().collect::<String>(),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue