mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-19 11:18:19 +00:00
Auto merge of #4574 - Manishearth:rustup, r=yaahc,centril
Rustup to rustc 1.39.0-nightly (acf7b50c7 2019-09-25) changelog: none fixes https://github.com/rust-lang/rust/issues/64777 r? @phansch @yaahc
This commit is contained in:
commit
d5570e44e8
22 changed files with 146 additions and 174 deletions
|
@ -85,6 +85,8 @@ matrix:
|
|||
allow_failures:
|
||||
- os: windows
|
||||
env: CARGO_INCREMENTAL=0 BASE_TESTS=true OS_WINDOWS=true
|
||||
- os: osx # run base tests on both platforms
|
||||
env: BASE_TESTS=true
|
||||
# prevent these jobs with default env vars
|
||||
exclude:
|
||||
- os: linux
|
||||
|
|
|
@ -46,7 +46,7 @@ rustc_tools_util = { version = "0.2.0", path = "rustc_tools_util"}
|
|||
|
||||
[dev-dependencies]
|
||||
cargo_metadata = "0.8.0"
|
||||
compiletest_rs = { version = "0.3.22", features = ["tmp"] }
|
||||
compiletest_rs = { version = "0.3.23", features = ["tmp"] }
|
||||
lazy_static = "1.0"
|
||||
clippy-mini-macro-test = { version = "0.2", path = "mini-macro" }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
|
|
|
@ -112,8 +112,7 @@ impl<'tcx> Visitor<'tcx> for CCHelper {
|
|||
walk_expr(self, e);
|
||||
match e.node {
|
||||
ExprKind::Match(_, ref arms, _) => {
|
||||
let arms_n: u64 = arms.iter().map(|arm| arm.pats.len() as u64).sum();
|
||||
if arms_n > 1 {
|
||||
if arms.len() > 1 {
|
||||
self.cc += 1;
|
||||
}
|
||||
self.cc += arms.iter().filter(|arm| arm.guard.is_some()).count() as u64;
|
||||
|
|
|
@ -193,7 +193,7 @@ fn lint_match_arms<'tcx>(cx: &LateContext<'_, 'tcx>, expr: &Expr) {
|
|||
(min_index..=max_index).all(|index| arms[index].guard.is_none()) &&
|
||||
SpanlessEq::new(cx).eq_expr(&lhs.body, &rhs.body) &&
|
||||
// all patterns should have the same bindings
|
||||
same_bindings(cx, &bindings(cx, &lhs.pats[0]), &bindings(cx, &rhs.pats[0]))
|
||||
same_bindings(cx, &bindings(cx, &lhs.pat), &bindings(cx, &rhs.pat))
|
||||
};
|
||||
|
||||
let indexed_arms: Vec<(usize, &Arm)> = arms.iter().enumerate().collect();
|
||||
|
@ -213,27 +213,22 @@ fn lint_match_arms<'tcx>(cx: &LateContext<'_, 'tcx>, expr: &Expr) {
|
|||
// span for the whole pattern, the suggestion is only shown when there is only
|
||||
// one pattern. The user should know about `|` if they are already using it…
|
||||
|
||||
if i.pats.len() == 1 && j.pats.len() == 1 {
|
||||
let lhs = snippet(cx, i.pats[0].span, "<pat1>");
|
||||
let rhs = snippet(cx, j.pats[0].span, "<pat2>");
|
||||
let lhs = snippet(cx, i.pat.span, "<pat1>");
|
||||
let rhs = snippet(cx, j.pat.span, "<pat2>");
|
||||
|
||||
if let PatKind::Wild = j.pats[0].node {
|
||||
// if the last arm is _, then i could be integrated into _
|
||||
// note that i.pats[0] cannot be _, because that would mean that we're
|
||||
// hiding all the subsequent arms, and rust won't compile
|
||||
db.span_note(
|
||||
i.body.span,
|
||||
&format!(
|
||||
"`{}` has the same arm body as the `_` wildcard, consider removing it`",
|
||||
lhs
|
||||
),
|
||||
);
|
||||
} else {
|
||||
db.span_help(
|
||||
i.pats[0].span,
|
||||
&format!("consider refactoring into `{} | {}`", lhs, rhs),
|
||||
);
|
||||
}
|
||||
if let PatKind::Wild = j.pat.node {
|
||||
// if the last arm is _, then i could be integrated into _
|
||||
// note that i.pat cannot be _, because that would mean that we're
|
||||
// hiding all the subsequent arms, and rust won't compile
|
||||
db.span_note(
|
||||
i.body.span,
|
||||
&format!(
|
||||
"`{}` has the same arm body as the `_` wildcard, consider removing it`",
|
||||
lhs
|
||||
),
|
||||
);
|
||||
} else {
|
||||
db.span_help(i.pat.span, &format!("consider refactoring into `{} | {}`", lhs, rhs));
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
|
@ -84,9 +84,8 @@ fn on_argumentv1_new<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr, arm
|
|||
if let ExprKind::Path(ref qpath) = args[1].node;
|
||||
if let Some(did) = resolve_node(cx, qpath, args[1].hir_id).opt_def_id();
|
||||
if match_def_path(cx, did, &paths::DISPLAY_FMT_METHOD);
|
||||
if arms[0].pats.len() == 1;
|
||||
// check `(arg0,)` in match block
|
||||
if let PatKind::Tuple(ref pats, None) = arms[0].pats[0].node;
|
||||
if let PatKind::Tuple(ref pats, None) = arms[0].pat.node;
|
||||
if pats.len() == 1;
|
||||
then {
|
||||
let ty = walk_ptrs_ty(cx.tables.pat_ty(&pats[0]));
|
||||
|
|
|
@ -47,8 +47,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InfallibleDestructingMatch {
|
|||
if_chain! {
|
||||
if let Some(ref expr) = local.init;
|
||||
if let ExprKind::Match(ref target, ref arms, MatchSource::Normal) = expr.node;
|
||||
if arms.len() == 1 && arms[0].pats.len() == 1 && arms[0].guard.is_none();
|
||||
if let PatKind::TupleStruct(QPath::Resolved(None, ref variant_name), ref args, _) = arms[0].pats[0].node;
|
||||
if arms.len() == 1 && arms[0].guard.is_none();
|
||||
if let PatKind::TupleStruct(QPath::Resolved(None, ref variant_name), ref args, _) = arms[0].pat.node;
|
||||
if args.len() == 1;
|
||||
if let Some(arg) = get_arg_name(&args[0]);
|
||||
let body = remove_blocks(&arms[0].body);
|
||||
|
|
|
@ -517,9 +517,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Loops {
|
|||
match *source {
|
||||
MatchSource::Normal | MatchSource::IfLetDesugar { .. } => {
|
||||
if arms.len() == 2
|
||||
&& arms[0].pats.len() == 1
|
||||
&& arms[0].guard.is_none()
|
||||
&& arms[1].pats.len() == 1
|
||||
&& arms[1].guard.is_none()
|
||||
&& is_simple_break_expr(&arms[1].body)
|
||||
{
|
||||
|
@ -541,7 +539,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Loops {
|
|||
"try",
|
||||
format!(
|
||||
"while let {} = {} {{ .. }}",
|
||||
snippet_with_applicability(cx, arms[0].pats[0].span, "..", &mut applicability),
|
||||
snippet_with_applicability(cx, arms[0].pat.span, "..", &mut applicability),
|
||||
snippet_with_applicability(cx, matchexpr.span, "..", &mut applicability),
|
||||
),
|
||||
applicability,
|
||||
|
@ -554,7 +552,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Loops {
|
|||
}
|
||||
}
|
||||
if let ExprKind::Match(ref match_expr, ref arms, MatchSource::WhileLetDesugar) = expr.node {
|
||||
let pat = &arms[0].pats[0].node;
|
||||
let pat = &arms[0].pat.node;
|
||||
if let (
|
||||
&PatKind::TupleStruct(ref qpath, ref pat_args, _),
|
||||
&ExprKind::MethodCall(ref method_path, _, ref method_args),
|
||||
|
|
|
@ -14,7 +14,6 @@ use rustc::{declare_lint_pass, declare_tool_lint};
|
|||
use rustc_errors::Applicability;
|
||||
use std::cmp::Ordering;
|
||||
use std::collections::Bound;
|
||||
use std::ops::Deref;
|
||||
use syntax::ast::LitKind;
|
||||
use syntax::source_map::Span;
|
||||
|
||||
|
@ -255,9 +254,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Matches {
|
|||
|
||||
#[rustfmt::skip]
|
||||
fn check_single_match(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm], expr: &Expr) {
|
||||
if arms.len() == 2 &&
|
||||
arms[0].pats.len() == 1 && arms[0].guard.is_none() &&
|
||||
arms[1].pats.len() == 1 && arms[1].guard.is_none() {
|
||||
if arms.len() == 2 && arms[0].guard.is_none() && arms[1].guard.is_none() {
|
||||
if let PatKind::Or(..) = arms[0].pat.node {
|
||||
// don't lint for or patterns for now, this makes
|
||||
// the lint noisy in unnecessary situations
|
||||
return;
|
||||
}
|
||||
let els = remove_blocks(&arms[1].body);
|
||||
let els = if is_unit_expr(els) {
|
||||
None
|
||||
|
@ -283,7 +285,7 @@ fn check_single_match_single_pattern(
|
|||
expr: &Expr,
|
||||
els: Option<&Expr>,
|
||||
) {
|
||||
if is_wild(&arms[1].pats[0]) {
|
||||
if is_wild(&arms[1].pat) {
|
||||
report_single_match_single_pattern(cx, ex, arms, expr, els);
|
||||
}
|
||||
}
|
||||
|
@ -308,7 +310,7 @@ fn report_single_match_single_pattern(
|
|||
"try this",
|
||||
format!(
|
||||
"if let {} = {} {}{}",
|
||||
snippet(cx, arms[0].pats[0].span, ".."),
|
||||
snippet(cx, arms[0].pat.span, ".."),
|
||||
snippet(cx, ex.span, ".."),
|
||||
expr_block(cx, &arms[0].body, None, ".."),
|
||||
els_str,
|
||||
|
@ -336,7 +338,7 @@ fn check_single_match_opt_like(
|
|||
(&paths::RESULT, "Ok"),
|
||||
];
|
||||
|
||||
let path = match arms[1].pats[0].node {
|
||||
let path = match arms[1].pat.node {
|
||||
PatKind::TupleStruct(ref path, ref inner, _) => {
|
||||
// Contains any non wildcard patterns (e.g., `Err(err)`)?
|
||||
if !inner.iter().all(is_wild) {
|
||||
|
@ -365,9 +367,9 @@ fn check_match_bool(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm], expr: &Ex
|
|||
expr.span,
|
||||
"you seem to be trying to match on a boolean expression",
|
||||
move |db| {
|
||||
if arms.len() == 2 && arms[0].pats.len() == 1 {
|
||||
if arms.len() == 2 {
|
||||
// no guards
|
||||
let exprs = if let PatKind::Lit(ref arm_bool) = arms[0].pats[0].node {
|
||||
let exprs = if let PatKind::Lit(ref arm_bool) = arms[0].pat.node {
|
||||
if let ExprKind::Lit(ref lit) = arm_bool.node {
|
||||
match lit.node {
|
||||
LitKind::Bool(true) => Some((&*arms[0].body, &*arms[1].body)),
|
||||
|
@ -446,7 +448,7 @@ fn check_wild_err_arm(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm]) {
|
|||
let ex_ty = walk_ptrs_ty(cx.tables.expr_ty(ex));
|
||||
if match_type(cx, ex_ty, &paths::RESULT) {
|
||||
for arm in arms {
|
||||
if let PatKind::TupleStruct(ref path, ref inner, _) = arm.pats[0].node {
|
||||
if let PatKind::TupleStruct(ref path, ref inner, _) = arm.pat.node {
|
||||
let path_str = print::to_string(print::NO_ANN, |s| s.print_qpath(path, false));
|
||||
if_chain! {
|
||||
if path_str == "Err";
|
||||
|
@ -457,9 +459,9 @@ fn check_wild_err_arm(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm]) {
|
|||
// `Err(_)` arm with `panic!` found
|
||||
span_note_and_lint(cx,
|
||||
MATCH_WILD_ERR_ARM,
|
||||
arm.pats[0].span,
|
||||
arm.pat.span,
|
||||
"Err(_) will match all errors, maybe not a good idea",
|
||||
arm.pats[0].span,
|
||||
arm.pat.span,
|
||||
"to remove this warning, match each error separately \
|
||||
or use unreachable macro");
|
||||
}
|
||||
|
@ -482,13 +484,11 @@ fn check_wild_enum_match(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm]) {
|
|||
let mut wildcard_span = None;
|
||||
let mut wildcard_ident = None;
|
||||
for arm in arms {
|
||||
for pat in &arm.pats {
|
||||
if let PatKind::Wild = pat.node {
|
||||
wildcard_span = Some(pat.span);
|
||||
} else if let PatKind::Binding(_, _, ident, None) = pat.node {
|
||||
wildcard_span = Some(pat.span);
|
||||
wildcard_ident = Some(ident);
|
||||
}
|
||||
if let PatKind::Wild = arm.pat.node {
|
||||
wildcard_span = Some(arm.pat.span);
|
||||
} else if let PatKind::Binding(_, _, ident, None) = arm.pat.node {
|
||||
wildcard_span = Some(arm.pat.span);
|
||||
wildcard_ident = Some(ident);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -510,15 +510,13 @@ fn check_wild_enum_match(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm]) {
|
|||
// covered by the set of guards that cover it, but that's really hard to do.
|
||||
continue;
|
||||
}
|
||||
for pat in &arm.pats {
|
||||
if let PatKind::Path(ref path) = pat.deref().node {
|
||||
if let QPath::Resolved(_, p) = path {
|
||||
missing_variants.retain(|e| e.ctor_def_id != Some(p.res.def_id()));
|
||||
}
|
||||
} else if let PatKind::TupleStruct(ref path, ..) = pat.deref().node {
|
||||
if let QPath::Resolved(_, p) = path {
|
||||
missing_variants.retain(|e| e.ctor_def_id != Some(p.res.def_id()));
|
||||
}
|
||||
if let PatKind::Path(ref path) = arm.pat.node {
|
||||
if let QPath::Resolved(_, p) = path {
|
||||
missing_variants.retain(|e| e.ctor_def_id != Some(p.res.def_id()));
|
||||
}
|
||||
} else if let PatKind::TupleStruct(ref path, ..) = arm.pat.node {
|
||||
if let QPath::Resolved(_, p) = path {
|
||||
missing_variants.retain(|e| e.ctor_def_id != Some(p.res.def_id()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -588,9 +586,9 @@ fn check_match_ref_pats(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm], expr:
|
|||
)
|
||||
};
|
||||
|
||||
suggs.extend(arms.iter().flat_map(|a| &a.pats).filter_map(|p| {
|
||||
if let PatKind::Ref(ref refp, _) = p.node {
|
||||
Some((p.span, snippet(cx, refp.span, "..").to_string()))
|
||||
suggs.extend(arms.iter().filter_map(|a| {
|
||||
if let PatKind::Ref(ref refp, _) = a.pat.node {
|
||||
Some((a.pat.span, snippet(cx, refp.span, "..").to_string()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -605,12 +603,7 @@ fn check_match_ref_pats(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm], expr:
|
|||
}
|
||||
|
||||
fn check_match_as_ref(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm], expr: &Expr) {
|
||||
if arms.len() == 2
|
||||
&& arms[0].pats.len() == 1
|
||||
&& arms[0].guard.is_none()
|
||||
&& arms[1].pats.len() == 1
|
||||
&& arms[1].guard.is_none()
|
||||
{
|
||||
if arms.len() == 2 && arms[0].guard.is_none() && arms[1].guard.is_none() {
|
||||
let arm_ref: Option<BindingAnnotation> = if is_none_arm(&arms[0]) {
|
||||
is_ref_some_arm(&arms[1])
|
||||
} else if is_none_arm(&arms[1]) {
|
||||
|
@ -666,14 +659,9 @@ fn all_ranges<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, arms: &'tcx [Arm]) -> Vec<Sp
|
|||
arms.iter()
|
||||
.flat_map(|arm| {
|
||||
if let Arm {
|
||||
ref pats, guard: None, ..
|
||||
ref pat, guard: None, ..
|
||||
} = *arm
|
||||
{
|
||||
pats.iter()
|
||||
} else {
|
||||
[].iter()
|
||||
}
|
||||
.filter_map(|pat| {
|
||||
if let PatKind::Range(ref lhs, ref rhs, ref range_end) = pat.node {
|
||||
let lhs = constant(cx, cx.tables, lhs)?.0;
|
||||
let rhs = constant(cx, cx.tables, rhs)?.0;
|
||||
|
@ -694,9 +682,8 @@ fn all_ranges<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, arms: &'tcx [Arm]) -> Vec<Sp
|
|||
node: (value.clone(), Bound::Included(value)),
|
||||
});
|
||||
}
|
||||
|
||||
None
|
||||
})
|
||||
}
|
||||
None
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
@ -743,7 +730,7 @@ fn is_unit_expr(expr: &Expr) -> bool {
|
|||
|
||||
// Checks if arm has the form `None => None`
|
||||
fn is_none_arm(arm: &Arm) -> bool {
|
||||
match arm.pats[0].node {
|
||||
match arm.pat.node {
|
||||
PatKind::Path(ref path) if match_qpath(path, &paths::OPTION_NONE) => true,
|
||||
_ => false,
|
||||
}
|
||||
|
@ -752,7 +739,7 @@ fn is_none_arm(arm: &Arm) -> bool {
|
|||
// Checks if arm has the form `Some(ref v) => Some(v)` (checks for `ref` and `ref mut`)
|
||||
fn is_ref_some_arm(arm: &Arm) -> Option<BindingAnnotation> {
|
||||
if_chain! {
|
||||
if let PatKind::TupleStruct(ref path, ref pats, _) = arm.pats[0].node;
|
||||
if let PatKind::TupleStruct(ref path, ref pats, _) = arm.pat.node;
|
||||
if pats.len() == 1 && match_qpath(path, &paths::OPTION_SOME);
|
||||
if let PatKind::Binding(rb, .., ident, _) = pats[0].node;
|
||||
if rb == BindingAnnotation::Ref || rb == BindingAnnotation::RefMut;
|
||||
|
@ -772,9 +759,8 @@ fn is_ref_some_arm(arm: &Arm) -> Option<BindingAnnotation> {
|
|||
fn has_only_ref_pats(arms: &[Arm]) -> bool {
|
||||
let mapped = arms
|
||||
.iter()
|
||||
.flat_map(|a| &a.pats)
|
||||
.map(|p| {
|
||||
match p.node {
|
||||
.map(|a| {
|
||||
match a.pat.node {
|
||||
PatKind::Ref(..) => Some(true), // &-patterns
|
||||
PatKind::Wild => Some(false), // an "anything" wildcard is also fine
|
||||
_ => None, // any other pattern is not fine
|
||||
|
|
|
@ -42,7 +42,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for OkIfLet {
|
|||
if let ExprKind::Match(ref op, ref body, ref source) = expr.node; //test if expr is a match
|
||||
if let MatchSource::IfLetDesugar { .. } = *source; //test if it is an If Let
|
||||
if let ExprKind::MethodCall(_, _, ref result_types) = op.node; //check is expr.ok() has type Result<T,E>.ok()
|
||||
if let PatKind::TupleStruct(QPath::Resolved(_, ref x), ref y, _) = body[0].pats[0].node; //get operation
|
||||
if let PatKind::TupleStruct(QPath::Resolved(_, ref x), ref y, _) = body[0].pat.node; //get operation
|
||||
if method_chain_args(op, &["ok"]).is_some(); //test to see if using ok() methoduse std::marker::Sized;
|
||||
|
||||
then {
|
||||
|
|
|
@ -57,50 +57,48 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for RedundantPatternMatching {
|
|||
}
|
||||
|
||||
fn find_sugg_for_if_let<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr, op: &P<Expr>, arms: &HirVec<Arm>) {
|
||||
if arms[0].pats.len() == 1 {
|
||||
let good_method = match arms[0].pats[0].node {
|
||||
PatKind::TupleStruct(ref path, ref patterns, _) if patterns.len() == 1 => {
|
||||
if let PatKind::Wild = patterns[0].node {
|
||||
if match_qpath(path, &paths::RESULT_OK) {
|
||||
"is_ok()"
|
||||
} else if match_qpath(path, &paths::RESULT_ERR) {
|
||||
"is_err()"
|
||||
} else if match_qpath(path, &paths::OPTION_SOME) {
|
||||
"is_some()"
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
let good_method = match arms[0].pat.node {
|
||||
PatKind::TupleStruct(ref path, ref patterns, _) if patterns.len() == 1 => {
|
||||
if let PatKind::Wild = patterns[0].node {
|
||||
if match_qpath(path, &paths::RESULT_OK) {
|
||||
"is_ok()"
|
||||
} else if match_qpath(path, &paths::RESULT_ERR) {
|
||||
"is_err()"
|
||||
} else if match_qpath(path, &paths::OPTION_SOME) {
|
||||
"is_some()"
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
},
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
},
|
||||
|
||||
PatKind::Path(ref path) if match_qpath(path, &paths::OPTION_NONE) => "is_none()",
|
||||
PatKind::Path(ref path) if match_qpath(path, &paths::OPTION_NONE) => "is_none()",
|
||||
|
||||
_ => return,
|
||||
};
|
||||
_ => return,
|
||||
};
|
||||
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
REDUNDANT_PATTERN_MATCHING,
|
||||
arms[0].pats[0].span,
|
||||
&format!("redundant pattern matching, consider using `{}`", good_method),
|
||||
|db| {
|
||||
let span = expr.span.to(op.span);
|
||||
db.span_suggestion(
|
||||
span,
|
||||
"try this",
|
||||
format!("{}.{}", snippet(cx, op.span, "_"), good_method),
|
||||
Applicability::MaybeIncorrect, // snippet
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
REDUNDANT_PATTERN_MATCHING,
|
||||
arms[0].pat.span,
|
||||
&format!("redundant pattern matching, consider using `{}`", good_method),
|
||||
|db| {
|
||||
let span = expr.span.to(op.span);
|
||||
db.span_suggestion(
|
||||
span,
|
||||
"try this",
|
||||
format!("{}.{}", snippet(cx, op.span, "_"), good_method),
|
||||
Applicability::MaybeIncorrect, // snippet
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
fn find_sugg_for_match<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr, op: &P<Expr>, arms: &HirVec<Arm>) {
|
||||
if arms.len() == 2 {
|
||||
let node_pair = (&arms[0].pats[0].node, &arms[1].pats[0].node);
|
||||
let node_pair = (&arms[0].pat.node, &arms[1].pat.node);
|
||||
|
||||
let found_good_method = match node_pair {
|
||||
(
|
||||
|
|
|
@ -328,17 +328,15 @@ fn check_expr<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr, bindings:
|
|||
check_expr(cx, init, bindings);
|
||||
let len = bindings.len();
|
||||
for arm in arms {
|
||||
for pat in &arm.pats {
|
||||
check_pat(cx, pat, Some(&**init), pat.span, bindings);
|
||||
// This is ugly, but needed to get the right type
|
||||
if let Some(ref guard) = arm.guard {
|
||||
match guard {
|
||||
Guard::If(if_expr) => check_expr(cx, if_expr, bindings),
|
||||
}
|
||||
check_pat(cx, &arm.pat, Some(&**init), arm.pat.span, bindings);
|
||||
// This is ugly, but needed to get the right type
|
||||
if let Some(ref guard) = arm.guard {
|
||||
match guard {
|
||||
Guard::If(if_expr) => check_expr(cx, if_expr, bindings),
|
||||
}
|
||||
check_expr(cx, &arm.body, bindings);
|
||||
bindings.truncate(len);
|
||||
}
|
||||
check_expr(cx, &arm.body, bindings);
|
||||
bindings.truncate(len);
|
||||
}
|
||||
},
|
||||
_ => (),
|
||||
|
|
|
@ -354,11 +354,8 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor {
|
|||
},
|
||||
}
|
||||
}
|
||||
println!(" if {}[{}].pats.len() == {};", arms_pat, i, arm.pats.len());
|
||||
for (j, pat) in arm.pats.iter().enumerate() {
|
||||
self.current = format!("{}[{}].pats[{}]", arms_pat, i, j);
|
||||
self.visit_pat(pat);
|
||||
}
|
||||
self.current = format!("{}[{}].pat", arms_pat, i);
|
||||
self.visit_pat(&arm.pat);
|
||||
}
|
||||
},
|
||||
ExprKind::Closure(ref _capture_clause, ref _func, _, _, _) => {
|
||||
|
|
|
@ -124,7 +124,7 @@ impl<'a, 'tcx> SpanlessEq<'a, 'tcx> {
|
|||
&& over(la, ra, |l, r| {
|
||||
self.eq_expr(&l.body, &r.body)
|
||||
&& both(&l.guard, &r.guard, |l, r| self.eq_guard(l, r))
|
||||
&& over(&l.pats, &r.pats, |l, r| self.eq_pat(l, r))
|
||||
&& self.eq_pat(&l.pat, &r.pat)
|
||||
})
|
||||
},
|
||||
(&ExprKind::MethodCall(ref l_path, _, ref l_args), &ExprKind::MethodCall(ref r_path, _, ref r_args)) => {
|
||||
|
|
|
@ -101,9 +101,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DeepCodeInspector {
|
|||
if !has_attr(cx.sess(), &arm.attrs) {
|
||||
return;
|
||||
}
|
||||
for pat in &arm.pats {
|
||||
print_pat(cx, pat, 1);
|
||||
}
|
||||
print_pat(cx, &arm.pat, 1);
|
||||
if let Some(ref guard) = arm.guard {
|
||||
println!("guard:");
|
||||
print_guard(cx, guard, 1);
|
||||
|
|
|
@ -909,7 +909,7 @@ pub fn iter_input_pats<'tcx>(decl: &FnDecl, body: &'tcx Body) -> impl Iterator<I
|
|||
pub fn is_try(expr: &Expr) -> Option<&Expr> {
|
||||
fn is_ok(arm: &Arm) -> bool {
|
||||
if_chain! {
|
||||
if let PatKind::TupleStruct(ref path, ref pat, None) = arm.pats[0].node;
|
||||
if let PatKind::TupleStruct(ref path, ref pat, None) = arm.pat.node;
|
||||
if match_qpath(path, &paths::RESULT_OK[1..]);
|
||||
if let PatKind::Binding(_, hir_id, _, None) = pat[0].node;
|
||||
if let ExprKind::Path(QPath::Resolved(None, ref path)) = arm.body.node;
|
||||
|
@ -923,7 +923,7 @@ pub fn is_try(expr: &Expr) -> Option<&Expr> {
|
|||
}
|
||||
|
||||
fn is_err(arm: &Arm) -> bool {
|
||||
if let PatKind::TupleStruct(ref path, _, _) = arm.pats[0].node {
|
||||
if let PatKind::TupleStruct(ref path, _, _) = arm.pat.node {
|
||||
match_qpath(path, &paths::RESULT_ERR[1..])
|
||||
} else {
|
||||
false
|
||||
|
@ -938,8 +938,8 @@ pub fn is_try(expr: &Expr) -> Option<&Expr> {
|
|||
|
||||
if_chain! {
|
||||
if arms.len() == 2;
|
||||
if arms[0].pats.len() == 1 && arms[0].guard.is_none();
|
||||
if arms[1].pats.len() == 1 && arms[1].guard.is_none();
|
||||
if arms[0].guard.is_none();
|
||||
if arms[1].guard.is_none();
|
||||
if (is_ok(&arms[0]) && is_err(&arms[1])) ||
|
||||
(is_ok(&arms[1]) && is_err(&arms[0]));
|
||||
then {
|
||||
|
|
|
@ -31,14 +31,12 @@ if_chain! {
|
|||
if match_qpath(path4, &["__next"]);
|
||||
if let ExprKind::Path(ref path5) = value.node;
|
||||
if match_qpath(path5, &["val"]);
|
||||
if arms1[0].pats.len() == 1;
|
||||
if let PatKind::TupleStruct(ref path6, ref fields1, None) = arms1[0].pats[0].node;
|
||||
if let PatKind::TupleStruct(ref path6, ref fields1, None) = arms1[0].pat.node;
|
||||
if match_qpath(path6, &["{{root}}", "std", "option", "Option", "Some"]);
|
||||
if fields1.len() == 1;
|
||||
// unimplemented: field checks
|
||||
if let ExprKind::Break(ref destination, None) = arms1[1].body.node;
|
||||
if arms1[1].pats.len() == 1;
|
||||
if let PatKind::Path(ref path7) = arms1[1].pats[0].node;
|
||||
if let PatKind::Path(ref path7) = arms1[1].pat.node;
|
||||
if match_qpath(path7, &["{{root}}", "std", "option", "Option", "None"]);
|
||||
if let StmtKind::Local(ref local1) = body.stmts[2].node;
|
||||
if let Some(ref init) = local1.init;
|
||||
|
@ -56,8 +54,7 @@ if_chain! {
|
|||
if match_qpath(path9, &["y"]);
|
||||
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name2, None) = local2.pat.node;
|
||||
if name2.node.as_str() == "z";
|
||||
if arms[0].pats.len() == 1;
|
||||
if let PatKind::Binding(BindingAnnotation::Mutable, _, name3, None) = arms[0].pats[0].node;
|
||||
if let PatKind::Binding(BindingAnnotation::Mutable, _, name3, None) = arms[0].pat.node;
|
||||
if name3.node.as_str() == "iter";
|
||||
then {
|
||||
// report your lint here
|
||||
|
|
|
@ -29,7 +29,7 @@ fn bla() {
|
|||
fn bindings(a: i32, b: i32, c: i32, d: i32, e: i32, f: i32, g: i32, h: i32) {}
|
||||
|
||||
fn bindings2() {
|
||||
let (a, b, c, d, e, f, g, h) = unimplemented!();
|
||||
let (a, b, c, d, e, f, g, h): (bool, bool, bool, bool, bool, bool, bool, bool) = unimplemented!();
|
||||
}
|
||||
|
||||
fn shadowing() {
|
||||
|
|
|
@ -44,7 +44,7 @@ LL | fn bindings(a: i32, b: i32, c: i32, d: i32, e: i32, f: i32, g: i32, h: i32)
|
|||
error: 8 bindings with single-character names in scope
|
||||
--> $DIR/many_single_char_names.rs:32:10
|
||||
|
|
||||
LL | let (a, b, c, d, e, f, g, h) = unimplemented!();
|
||||
LL | let (a, b, c, d, e, f, g, h): (bool, bool, bool, bool, bool, bool, bool, bool) = unimplemented!();
|
||||
| ^ ^ ^ ^ ^ ^ ^ ^
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
|
|
@ -5,7 +5,12 @@
|
|||
clippy::shadow_reuse,
|
||||
clippy::shadow_unrelated
|
||||
)]
|
||||
#![allow(unused_parens, unused_variables, clippy::missing_docs_in_private_items)]
|
||||
#![allow(
|
||||
unused_parens,
|
||||
unused_variables,
|
||||
clippy::missing_docs_in_private_items,
|
||||
clippy::single_match
|
||||
)]
|
||||
|
||||
fn id<T>(x: T) -> T {
|
||||
x
|
||||
|
|
|
@ -1,135 +1,135 @@
|
|||
error: `x` is shadowed by itself in `&mut x`
|
||||
--> $DIR/shadow.rs:20:5
|
||||
--> $DIR/shadow.rs:25:5
|
||||
|
|
||||
LL | let x = &mut x;
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `-D clippy::shadow-same` implied by `-D warnings`
|
||||
note: previous binding is here
|
||||
--> $DIR/shadow.rs:19:13
|
||||
--> $DIR/shadow.rs:24:13
|
||||
|
|
||||
LL | let mut x = 1;
|
||||
| ^
|
||||
|
||||
error: `x` is shadowed by itself in `{ x }`
|
||||
--> $DIR/shadow.rs:21:5
|
||||
--> $DIR/shadow.rs:26:5
|
||||
|
|
||||
LL | let x = { x };
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
note: previous binding is here
|
||||
--> $DIR/shadow.rs:20:9
|
||||
--> $DIR/shadow.rs:25:9
|
||||
|
|
||||
LL | let x = &mut x;
|
||||
| ^
|
||||
|
||||
error: `x` is shadowed by itself in `(&*x)`
|
||||
--> $DIR/shadow.rs:22:5
|
||||
--> $DIR/shadow.rs:27:5
|
||||
|
|
||||
LL | let x = (&*x);
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
note: previous binding is here
|
||||
--> $DIR/shadow.rs:21:9
|
||||
--> $DIR/shadow.rs:26:9
|
||||
|
|
||||
LL | let x = { x };
|
||||
| ^
|
||||
|
||||
error: `x` is shadowed by `{ *x + 1 }` which reuses the original value
|
||||
--> $DIR/shadow.rs:23:9
|
||||
--> $DIR/shadow.rs:28:9
|
||||
|
|
||||
LL | let x = { *x + 1 };
|
||||
| ^
|
||||
|
|
||||
= note: `-D clippy::shadow-reuse` implied by `-D warnings`
|
||||
note: initialization happens here
|
||||
--> $DIR/shadow.rs:23:13
|
||||
--> $DIR/shadow.rs:28:13
|
||||
|
|
||||
LL | let x = { *x + 1 };
|
||||
| ^^^^^^^^^^
|
||||
note: previous binding is here
|
||||
--> $DIR/shadow.rs:22:9
|
||||
--> $DIR/shadow.rs:27:9
|
||||
|
|
||||
LL | let x = (&*x);
|
||||
| ^
|
||||
|
||||
error: `x` is shadowed by `id(x)` which reuses the original value
|
||||
--> $DIR/shadow.rs:24:9
|
||||
--> $DIR/shadow.rs:29:9
|
||||
|
|
||||
LL | let x = id(x);
|
||||
| ^
|
||||
|
|
||||
note: initialization happens here
|
||||
--> $DIR/shadow.rs:24:13
|
||||
--> $DIR/shadow.rs:29:13
|
||||
|
|
||||
LL | let x = id(x);
|
||||
| ^^^^^
|
||||
note: previous binding is here
|
||||
--> $DIR/shadow.rs:23:9
|
||||
--> $DIR/shadow.rs:28:9
|
||||
|
|
||||
LL | let x = { *x + 1 };
|
||||
| ^
|
||||
|
||||
error: `x` is shadowed by `(1, x)` which reuses the original value
|
||||
--> $DIR/shadow.rs:25:9
|
||||
--> $DIR/shadow.rs:30:9
|
||||
|
|
||||
LL | let x = (1, x);
|
||||
| ^
|
||||
|
|
||||
note: initialization happens here
|
||||
--> $DIR/shadow.rs:25:13
|
||||
--> $DIR/shadow.rs:30:13
|
||||
|
|
||||
LL | let x = (1, x);
|
||||
| ^^^^^^
|
||||
note: previous binding is here
|
||||
--> $DIR/shadow.rs:24:9
|
||||
--> $DIR/shadow.rs:29:9
|
||||
|
|
||||
LL | let x = id(x);
|
||||
| ^
|
||||
|
||||
error: `x` is shadowed by `first(x)` which reuses the original value
|
||||
--> $DIR/shadow.rs:26:9
|
||||
--> $DIR/shadow.rs:31:9
|
||||
|
|
||||
LL | let x = first(x);
|
||||
| ^
|
||||
|
|
||||
note: initialization happens here
|
||||
--> $DIR/shadow.rs:26:13
|
||||
--> $DIR/shadow.rs:31:13
|
||||
|
|
||||
LL | let x = first(x);
|
||||
| ^^^^^^^^
|
||||
note: previous binding is here
|
||||
--> $DIR/shadow.rs:25:9
|
||||
--> $DIR/shadow.rs:30:9
|
||||
|
|
||||
LL | let x = (1, x);
|
||||
| ^
|
||||
|
||||
error: `x` is shadowed by `y`
|
||||
--> $DIR/shadow.rs:28:9
|
||||
--> $DIR/shadow.rs:33:9
|
||||
|
|
||||
LL | let x = y;
|
||||
| ^
|
||||
|
|
||||
= note: `-D clippy::shadow-unrelated` implied by `-D warnings`
|
||||
note: initialization happens here
|
||||
--> $DIR/shadow.rs:28:13
|
||||
--> $DIR/shadow.rs:33:13
|
||||
|
|
||||
LL | let x = y;
|
||||
| ^
|
||||
note: previous binding is here
|
||||
--> $DIR/shadow.rs:26:9
|
||||
--> $DIR/shadow.rs:31:9
|
||||
|
|
||||
LL | let x = first(x);
|
||||
| ^
|
||||
|
||||
error: `x` shadows a previous declaration
|
||||
--> $DIR/shadow.rs:30:5
|
||||
--> $DIR/shadow.rs:35:5
|
||||
|
|
||||
LL | let x;
|
||||
| ^^^^^^
|
||||
|
|
||||
note: previous binding is here
|
||||
--> $DIR/shadow.rs:28:9
|
||||
--> $DIR/shadow.rs:33:9
|
||||
|
|
||||
LL | let x = y;
|
||||
| ^
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// run-rustfix
|
||||
|
||||
#![deny(clippy::wildcard_enum_match_arm)]
|
||||
#![allow(unreachable_code, unused_variables)]
|
||||
#![allow(unreachable_code, unused_variables, dead_code)]
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
enum Color {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// run-rustfix
|
||||
|
||||
#![deny(clippy::wildcard_enum_match_arm)]
|
||||
#![allow(unreachable_code, unused_variables)]
|
||||
#![allow(unreachable_code, unused_variables, dead_code)]
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
enum Color {
|
||||
|
|
Loading…
Reference in a new issue