Run rustfmt
This commit is contained in:
parent
81401ddc8c
commit
5842463562
@ -223,7 +223,7 @@ fn lint_match_arms(cx: &LateContext, expr: &Expr) {
|
|||||||
/// `if a { c } else if b { d } else { e }`.
|
/// `if a { c } else if b { d } else { e }`.
|
||||||
fn if_sequence(mut expr: &Expr) -> (SmallVector<&Expr>, SmallVector<&Block>) {
|
fn if_sequence(mut expr: &Expr) -> (SmallVector<&Expr>, SmallVector<&Block>) {
|
||||||
let mut conds = SmallVector::new();
|
let mut conds = SmallVector::new();
|
||||||
let mut blocks : SmallVector<&Block> = SmallVector::new();
|
let mut blocks: SmallVector<&Block> = SmallVector::new();
|
||||||
|
|
||||||
while let ExprIf(ref cond, ref then_expr, ref else_expr) = expr.node {
|
while let ExprIf(ref cond, ref then_expr, ref else_expr) = expr.node {
|
||||||
conds.push(&**cond);
|
conds.push(&**cond);
|
||||||
@ -315,10 +315,10 @@ fn search_same<T, Hash, Eq>(exprs: &[T], hash: Hash, eq: Eq) -> Option<(&T, &T)>
|
|||||||
return None;
|
return None;
|
||||||
} else if exprs.len() == 2 {
|
} else if exprs.len() == 2 {
|
||||||
return if eq(&exprs[0], &exprs[1]) {
|
return if eq(&exprs[0], &exprs[1]) {
|
||||||
Some((&exprs[0], &exprs[1]))
|
Some((&exprs[0], &exprs[1]))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut map: HashMap<_, Vec<&_>> = HashMap::with_capacity(exprs.len());
|
let mut map: HashMap<_, Vec<&_>> = HashMap::with_capacity(exprs.len());
|
||||||
|
@ -46,11 +46,11 @@ fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
|
|||||||
if let Some((ty, map, key)) = check_cond(cx, check) {
|
if let Some((ty, map, key)) = check_cond(cx, check) {
|
||||||
// in case of `if !m.contains_key(&k) { m.insert(k, v); }`
|
// in case of `if !m.contains_key(&k) { m.insert(k, v); }`
|
||||||
// we can give a better error message
|
// we can give a better error message
|
||||||
let sole_expr = {
|
let sole_expr = {
|
||||||
else_block.is_none() &&
|
else_block.is_none() &&
|
||||||
if let ExprBlock(ref then_block) = then_block.node {
|
if let ExprBlock(ref then_block) = then_block.node {
|
||||||
(then_block.expr.is_some() as usize) + then_block.stmts.len() == 1
|
(then_block.expr.is_some() as usize) + then_block.stmts.len() == 1
|
||||||
} else {
|
} else {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -56,9 +56,9 @@ fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
|
|||||||
if is_valid_operator(op) {
|
if is_valid_operator(op) {
|
||||||
if SpanlessEq::new(cx).ignore_fn().eq_expr(left, right) {
|
if SpanlessEq::new(cx).ignore_fn().eq_expr(left, right) {
|
||||||
span_lint(cx,
|
span_lint(cx,
|
||||||
EQ_OP,
|
EQ_OP,
|
||||||
e.span,
|
e.span,
|
||||||
&format!("equal expressions as operands to `{}`", op.node.as_str()));
|
&format!("equal expressions as operands to `{}`", op.node.as_str()));
|
||||||
} else {
|
} else {
|
||||||
let trait_id = match op.node {
|
let trait_id = match op.node {
|
||||||
BiAdd => cx.tcx.lang_items.add_trait(),
|
BiAdd => cx.tcx.lang_items.add_trait(),
|
||||||
@ -66,19 +66,14 @@ fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
|
|||||||
BiMul => cx.tcx.lang_items.mul_trait(),
|
BiMul => cx.tcx.lang_items.mul_trait(),
|
||||||
BiDiv => cx.tcx.lang_items.div_trait(),
|
BiDiv => cx.tcx.lang_items.div_trait(),
|
||||||
BiRem => cx.tcx.lang_items.rem_trait(),
|
BiRem => cx.tcx.lang_items.rem_trait(),
|
||||||
BiAnd |
|
BiAnd | BiOr => None,
|
||||||
BiOr => None,
|
|
||||||
BiBitXor => cx.tcx.lang_items.bitxor_trait(),
|
BiBitXor => cx.tcx.lang_items.bitxor_trait(),
|
||||||
BiBitAnd => cx.tcx.lang_items.bitand_trait(),
|
BiBitAnd => cx.tcx.lang_items.bitand_trait(),
|
||||||
BiBitOr => cx.tcx.lang_items.bitor_trait(),
|
BiBitOr => cx.tcx.lang_items.bitor_trait(),
|
||||||
BiShl => cx.tcx.lang_items.shl_trait(),
|
BiShl => cx.tcx.lang_items.shl_trait(),
|
||||||
BiShr => cx.tcx.lang_items.shr_trait(),
|
BiShr => cx.tcx.lang_items.shr_trait(),
|
||||||
BiNe |
|
BiNe | BiEq => cx.tcx.lang_items.eq_trait(),
|
||||||
BiEq => cx.tcx.lang_items.eq_trait(),
|
BiLt | BiLe | BiGe | BiGt => cx.tcx.lang_items.ord_trait(),
|
||||||
BiLt |
|
|
||||||
BiLe |
|
|
||||||
BiGe |
|
|
||||||
BiGt => cx.tcx.lang_items.ord_trait(),
|
|
||||||
};
|
};
|
||||||
if let Some(trait_id) = trait_id {
|
if let Some(trait_id) = trait_id {
|
||||||
#[allow(match_same_arms)]
|
#[allow(match_same_arms)]
|
||||||
@ -90,57 +85,55 @@ fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
|
|||||||
(&ExprAddrOf(_, ref l), &ExprAddrOf(_, ref r)) => {
|
(&ExprAddrOf(_, ref l), &ExprAddrOf(_, ref r)) => {
|
||||||
if implements_trait(cx, cx.tables.expr_ty(l), trait_id, &[cx.tables.expr_ty(r)], None) {
|
if implements_trait(cx, cx.tables.expr_ty(l), trait_id, &[cx.tables.expr_ty(r)], None) {
|
||||||
span_lint_and_then(cx,
|
span_lint_and_then(cx,
|
||||||
OP_REF,
|
OP_REF,
|
||||||
e.span,
|
e.span,
|
||||||
"taken reference of both operands, which is done automatically by the operator anyway",
|
"taken reference of both operands, which is done automatically \
|
||||||
|db| {
|
by the operator anyway",
|
||||||
let lsnip = snippet(cx, l.span, "...").to_string();
|
|db| {
|
||||||
let rsnip = snippet(cx, r.span, "...").to_string();
|
let lsnip = snippet(cx, l.span, "...").to_string();
|
||||||
multispan_sugg(db,
|
let rsnip = snippet(cx, r.span, "...").to_string();
|
||||||
"use the values directly".to_string(),
|
multispan_sugg(db,
|
||||||
vec![(left.span, lsnip),
|
"use the values directly".to_string(),
|
||||||
|
vec![(left.span, lsnip),
|
||||||
(right.span, rsnip)]);
|
(right.span, rsnip)]);
|
||||||
}
|
})
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
// &foo == bar
|
// &foo == bar
|
||||||
(&ExprAddrOf(_, ref l), _) => {
|
(&ExprAddrOf(_, ref l), _) => {
|
||||||
if implements_trait(cx, cx.tables.expr_ty(l), trait_id, &[cx.tables.expr_ty(right)], None) {
|
if implements_trait(cx,
|
||||||
span_lint_and_then(cx,
|
cx.tables.expr_ty(l),
|
||||||
OP_REF,
|
trait_id,
|
||||||
e.span,
|
&[cx.tables.expr_ty(right)],
|
||||||
"taken reference of left operand",
|
None) {
|
||||||
|db| {
|
span_lint_and_then(cx, OP_REF, e.span, "taken reference of left operand", |db| {
|
||||||
let lsnip = snippet(cx, l.span, "...").to_string();
|
let lsnip = snippet(cx, l.span, "...").to_string();
|
||||||
let rsnip = Sugg::hir(cx, right, "...").deref().to_string();
|
let rsnip = Sugg::hir(cx, right, "...").deref().to_string();
|
||||||
multispan_sugg(db,
|
multispan_sugg(db,
|
||||||
"dereference the right operand instead".to_string(),
|
"dereference the right operand instead".to_string(),
|
||||||
vec![(left.span, lsnip),
|
vec![(left.span, lsnip),
|
||||||
(right.span, rsnip)]);
|
(right.span, rsnip)]);
|
||||||
}
|
})
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
// foo == &bar
|
// foo == &bar
|
||||||
(_, &ExprAddrOf(_, ref r)) => {
|
(_, &ExprAddrOf(_, ref r)) => {
|
||||||
if implements_trait(cx, cx.tables.expr_ty(left), trait_id, &[cx.tables.expr_ty(r)], None) {
|
if implements_trait(cx,
|
||||||
span_lint_and_then(cx,
|
cx.tables.expr_ty(left),
|
||||||
OP_REF,
|
trait_id,
|
||||||
e.span,
|
&[cx.tables.expr_ty(r)],
|
||||||
"taken reference of right operand",
|
None) {
|
||||||
|db| {
|
span_lint_and_then(cx, OP_REF, e.span, "taken reference of right operand", |db| {
|
||||||
let lsnip = Sugg::hir(cx, left, "...").deref().to_string();
|
let lsnip = Sugg::hir(cx, left, "...").deref().to_string();
|
||||||
let rsnip = snippet(cx, r.span, "...").to_string();
|
let rsnip = snippet(cx, r.span, "...").to_string();
|
||||||
multispan_sugg(db,
|
multispan_sugg(db,
|
||||||
"dereference the left operand instead".to_string(),
|
"dereference the left operand instead".to_string(),
|
||||||
vec![(left.span, lsnip),
|
vec![(left.span, lsnip),
|
||||||
(right.span, rsnip)]);
|
(right.span, rsnip)]);
|
||||||
}
|
})
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
_ => {}
|
_ => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,11 +100,19 @@ fn check_expr(&mut self, cx: &EarlyContext, expr: &ast::Expr) {
|
|||||||
fn check_assign(cx: &EarlyContext, expr: &ast::Expr) {
|
fn check_assign(cx: &EarlyContext, expr: &ast::Expr) {
|
||||||
if let ast::ExprKind::Assign(ref lhs, ref rhs) = expr.node {
|
if let ast::ExprKind::Assign(ref lhs, ref rhs) = expr.node {
|
||||||
if !differing_macro_contexts(lhs.span, rhs.span) && !in_macro(lhs.span) {
|
if !differing_macro_contexts(lhs.span, rhs.span) && !in_macro(lhs.span) {
|
||||||
let eq_span = Span { lo: lhs.span.hi, hi: rhs.span.lo, ctxt: NO_EXPANSION };
|
let eq_span = Span {
|
||||||
|
lo: lhs.span.hi,
|
||||||
|
hi: rhs.span.lo,
|
||||||
|
ctxt: NO_EXPANSION,
|
||||||
|
};
|
||||||
if let ast::ExprKind::Unary(op, ref sub_rhs) = rhs.node {
|
if let ast::ExprKind::Unary(op, ref sub_rhs) = rhs.node {
|
||||||
if let Some(eq_snippet) = snippet_opt(cx, eq_span) {
|
if let Some(eq_snippet) = snippet_opt(cx, eq_span) {
|
||||||
let op = ast::UnOp::to_string(op);
|
let op = ast::UnOp::to_string(op);
|
||||||
let eqop_span= Span { lo: lhs.span.hi, hi: sub_rhs.span.lo, ctxt: NO_EXPANSION };
|
let eqop_span = Span {
|
||||||
|
lo: lhs.span.hi,
|
||||||
|
hi: sub_rhs.span.lo,
|
||||||
|
ctxt: NO_EXPANSION,
|
||||||
|
};
|
||||||
if eq_snippet.ends_with('=') {
|
if eq_snippet.ends_with('=') {
|
||||||
span_note_and_lint(cx,
|
span_note_and_lint(cx,
|
||||||
SUSPICIOUS_ASSIGNMENT_FORMATTING,
|
SUSPICIOUS_ASSIGNMENT_FORMATTING,
|
||||||
@ -127,7 +135,11 @@ fn check_else_if(cx: &EarlyContext, expr: &ast::Expr) {
|
|||||||
if unsugar_if(else_).is_some() && !differing_macro_contexts(then.span, else_.span) && !in_macro(then.span) {
|
if unsugar_if(else_).is_some() && !differing_macro_contexts(then.span, else_.span) && !in_macro(then.span) {
|
||||||
// this will be a span from the closing ‘}’ of the “then” block (excluding) to the
|
// this will be a span from the closing ‘}’ of the “then” block (excluding) to the
|
||||||
// “if” of the “else if” block (excluding)
|
// “if” of the “else if” block (excluding)
|
||||||
let else_span = Span { lo: then.span.hi, hi: else_.span.lo, ctxt: NO_EXPANSION };
|
let else_span = Span {
|
||||||
|
lo: then.span.hi,
|
||||||
|
hi: else_.span.lo,
|
||||||
|
ctxt: NO_EXPANSION,
|
||||||
|
};
|
||||||
|
|
||||||
// the snippet should look like " else \n " with maybe comments anywhere
|
// the snippet should look like " else \n " with maybe comments anywhere
|
||||||
// it’s bad when there is a ‘\n’ after the “else”
|
// it’s bad when there is a ‘\n’ after the “else”
|
||||||
@ -154,9 +166,17 @@ fn check_array(cx: &EarlyContext, expr: &ast::Expr) {
|
|||||||
for element in array {
|
for element in array {
|
||||||
if let ast::ExprKind::Binary(ref op, ref lhs, _) = element.node {
|
if let ast::ExprKind::Binary(ref op, ref lhs, _) = element.node {
|
||||||
if !differing_macro_contexts(lhs.span, op.span) {
|
if !differing_macro_contexts(lhs.span, op.span) {
|
||||||
let space_span = Span { lo: lhs.span.hi, hi: op.span.lo, ctxt: NO_EXPANSION };
|
let space_span = Span {
|
||||||
|
lo: lhs.span.hi,
|
||||||
|
hi: op.span.lo,
|
||||||
|
ctxt: NO_EXPANSION,
|
||||||
|
};
|
||||||
if let Some(space_snippet) = snippet_opt(cx, space_span) {
|
if let Some(space_snippet) = snippet_opt(cx, space_span) {
|
||||||
let lint_span = Span { lo: lhs.span.hi, hi: lhs.span.hi, ctxt: NO_EXPANSION };
|
let lint_span = Span {
|
||||||
|
lo: lhs.span.hi,
|
||||||
|
hi: lhs.span.hi,
|
||||||
|
ctxt: NO_EXPANSION,
|
||||||
|
};
|
||||||
if space_snippet.contains('\n') {
|
if space_snippet.contains('\n') {
|
||||||
span_note_and_lint(cx,
|
span_note_and_lint(cx,
|
||||||
POSSIBLE_MISSING_COMMA,
|
POSSIBLE_MISSING_COMMA,
|
||||||
@ -174,10 +194,14 @@ fn check_array(cx: &EarlyContext, expr: &ast::Expr) {
|
|||||||
|
|
||||||
/// Implementation of the `SUSPICIOUS_ELSE_FORMATTING` lint for consecutive ifs.
|
/// Implementation of the `SUSPICIOUS_ELSE_FORMATTING` lint for consecutive ifs.
|
||||||
fn check_consecutive_ifs(cx: &EarlyContext, first: &ast::Expr, second: &ast::Expr) {
|
fn check_consecutive_ifs(cx: &EarlyContext, first: &ast::Expr, second: &ast::Expr) {
|
||||||
if !differing_macro_contexts(first.span, second.span) && !in_macro(first.span) &&
|
if !differing_macro_contexts(first.span, second.span) && !in_macro(first.span) && unsugar_if(first).is_some() &&
|
||||||
unsugar_if(first).is_some() && unsugar_if(second).is_some() {
|
unsugar_if(second).is_some() {
|
||||||
// where the else would be
|
// where the else would be
|
||||||
let else_span = Span { lo: first.span.hi, hi: second.span.lo, ctxt: NO_EXPANSION };
|
let else_span = Span {
|
||||||
|
lo: first.span.hi,
|
||||||
|
hi: second.span.lo,
|
||||||
|
ctxt: NO_EXPANSION,
|
||||||
|
};
|
||||||
|
|
||||||
if let Some(else_snippet) = snippet_opt(cx, else_span) {
|
if let Some(else_snippet) = snippet_opt(cx, else_span) {
|
||||||
if !else_snippet.contains('\n') {
|
if !else_snippet.contains('\n') {
|
||||||
|
@ -89,7 +89,13 @@ enum RefLt {
|
|||||||
Named(Name),
|
Named(Name),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_fn_inner<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, decl: &'tcx FnDecl, body: Option<BodyId>, generics: &'tcx Generics, span: Span) {
|
fn check_fn_inner<'a, 'tcx>(
|
||||||
|
cx: &LateContext<'a, 'tcx>,
|
||||||
|
decl: &'tcx FnDecl,
|
||||||
|
body: Option<BodyId>,
|
||||||
|
generics: &'tcx Generics,
|
||||||
|
span: Span
|
||||||
|
) {
|
||||||
if in_external_macro(cx, span) || has_where_lifetimes(cx, &generics.where_clause) {
|
if in_external_macro(cx, span) || has_where_lifetimes(cx, &generics.where_clause) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -128,7 +134,7 @@ fn could_use_elision<'a, 'tcx: 'a>(
|
|||||||
func: &'tcx FnDecl,
|
func: &'tcx FnDecl,
|
||||||
body: Option<BodyId>,
|
body: Option<BodyId>,
|
||||||
named_lts: &'tcx [LifetimeDef],
|
named_lts: &'tcx [LifetimeDef],
|
||||||
bounds_lts: Vec<&'tcx Lifetime>,
|
bounds_lts: Vec<&'tcx Lifetime>
|
||||||
) -> bool {
|
) -> bool {
|
||||||
// There are two scenarios where elision works:
|
// There are two scenarios where elision works:
|
||||||
// * no output references, all input references have different LT
|
// * no output references, all input references have different LT
|
||||||
@ -265,11 +271,7 @@ fn record(&mut self, lifetime: &Option<Lifetime>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn into_vec(self) -> Option<Vec<RefLt>> {
|
fn into_vec(self) -> Option<Vec<RefLt>> {
|
||||||
if self.abort {
|
if self.abort { None } else { Some(self.lts) }
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(self.lts)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn collect_anonymous_lifetimes(&mut self, qpath: &QPath, ty: &Ty) {
|
fn collect_anonymous_lifetimes(&mut self, qpath: &QPath, ty: &Ty) {
|
||||||
@ -359,9 +361,11 @@ fn has_where_lifetimes<'a, 'tcx: 'a>(cx: &LateContext<'a, 'tcx>, where_clause: &
|
|||||||
// and check that all lifetimes are allowed
|
// and check that all lifetimes are allowed
|
||||||
match visitor.into_vec() {
|
match visitor.into_vec() {
|
||||||
None => return false,
|
None => return false,
|
||||||
Some(lts) => for lt in lts {
|
Some(lts) => {
|
||||||
if !allowed_lts.contains(<) {
|
for lt in lts {
|
||||||
return true;
|
if !allowed_lts.contains(<) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -409,8 +409,7 @@ fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
|
|||||||
fn check_stmt(&mut self, cx: &LateContext<'a, 'tcx>, stmt: &'tcx Stmt) {
|
fn check_stmt(&mut self, cx: &LateContext<'a, 'tcx>, stmt: &'tcx Stmt) {
|
||||||
if let StmtSemi(ref expr, _) = stmt.node {
|
if let StmtSemi(ref expr, _) = stmt.node {
|
||||||
if let ExprMethodCall(ref method, _, ref args) = expr.node {
|
if let ExprMethodCall(ref method, _, ref args) = expr.node {
|
||||||
if args.len() == 1 && method.node == "collect" &&
|
if args.len() == 1 && method.node == "collect" && match_trait_method(cx, expr, &paths::ITERATOR) {
|
||||||
match_trait_method(cx, expr, &paths::ITERATOR) {
|
|
||||||
span_lint(cx,
|
span_lint(cx,
|
||||||
UNUSED_COLLECT,
|
UNUSED_COLLECT,
|
||||||
expr.span,
|
expr.span,
|
||||||
|
@ -499,9 +499,7 @@ fn is_used(cx: &LateContext, expr: &Expr) -> bool {
|
|||||||
/// Test whether an expression is in a macro expansion (e.g. something generated by
|
/// Test whether an expression is in a macro expansion (e.g. something generated by
|
||||||
/// `#[derive(...)`] or the like).
|
/// `#[derive(...)`] or the like).
|
||||||
fn in_attributes_expansion(expr: &Expr) -> bool {
|
fn in_attributes_expansion(expr: &Expr) -> bool {
|
||||||
expr.span.ctxt.outer().expn_info().map_or(false, |info| {
|
expr.span.ctxt.outer().expn_info().map_or(false, |info| matches!(info.callee.format, ExpnFormat::MacroAttribute(_)))
|
||||||
matches!(info.callee.format, ExpnFormat::MacroAttribute(_))
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Test whether `def` is a variable defined outside a macro.
|
/// Test whether `def` is a variable defined outside a macro.
|
||||||
|
@ -77,27 +77,27 @@ fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
|
|||||||
|db| { db.span_suggestion(e.span, "you can reduce it to", hint); });
|
|db| { db.span_suggestion(e.span, "you can reduce it to", hint); });
|
||||||
};
|
};
|
||||||
if let ExprBlock(ref then_block) = then_block.node {
|
if let ExprBlock(ref then_block) = then_block.node {
|
||||||
match (fetch_bool_block(then_block), fetch_bool_expr(else_expr)) {
|
match (fetch_bool_block(then_block), fetch_bool_expr(else_expr)) {
|
||||||
(RetBool(true), RetBool(true)) |
|
(RetBool(true), RetBool(true)) |
|
||||||
(Bool(true), Bool(true)) => {
|
(Bool(true), Bool(true)) => {
|
||||||
span_lint(cx,
|
span_lint(cx,
|
||||||
NEEDLESS_BOOL,
|
NEEDLESS_BOOL,
|
||||||
e.span,
|
e.span,
|
||||||
"this if-then-else expression will always return true");
|
"this if-then-else expression will always return true");
|
||||||
},
|
},
|
||||||
(RetBool(false), RetBool(false)) |
|
(RetBool(false), RetBool(false)) |
|
||||||
(Bool(false), Bool(false)) => {
|
(Bool(false), Bool(false)) => {
|
||||||
span_lint(cx,
|
span_lint(cx,
|
||||||
NEEDLESS_BOOL,
|
NEEDLESS_BOOL,
|
||||||
e.span,
|
e.span,
|
||||||
"this if-then-else expression will always return false");
|
"this if-then-else expression will always return false");
|
||||||
},
|
},
|
||||||
(RetBool(true), RetBool(false)) => reduce(true, false),
|
(RetBool(true), RetBool(false)) => reduce(true, false),
|
||||||
(Bool(true), Bool(false)) => reduce(false, false),
|
(Bool(true), Bool(false)) => reduce(false, false),
|
||||||
(RetBool(false), RetBool(true)) => reduce(true, true),
|
(RetBool(false), RetBool(true)) => reduce(true, true),
|
||||||
(Bool(false), Bool(true)) => reduce(false, true),
|
(Bool(false), Bool(true)) => reduce(false, true),
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
panic!("IfExpr 'then' node is not an ExprBlock");
|
panic!("IfExpr 'then' node is not an ExprBlock");
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,7 @@ pub fn eq_expr(&self, left: &Expr, right: &Expr) -> bool {
|
|||||||
},
|
},
|
||||||
(&ExprIndex(ref la, ref li), &ExprIndex(ref ra, ref ri)) => self.eq_expr(la, ra) && self.eq_expr(li, ri),
|
(&ExprIndex(ref la, ref li), &ExprIndex(ref ra, ref ri)) => self.eq_expr(la, ra) && self.eq_expr(li, ri),
|
||||||
(&ExprIf(ref lc, ref lt, ref le), &ExprIf(ref rc, ref rt, ref re)) => {
|
(&ExprIf(ref lc, ref lt, ref le), &ExprIf(ref rc, ref rt, ref re)) => {
|
||||||
self.eq_expr(lc, rc) && self.eq_expr(&**lt, &**rt) && both(le, re, |l, r| self.eq_expr(l, r))
|
self.eq_expr(lc, rc) && self.eq_expr(&**lt, &**rt) && both(le, re, |l, r| self.eq_expr(l, r))
|
||||||
},
|
},
|
||||||
(&ExprLit(ref l), &ExprLit(ref r)) => l.node == r.node,
|
(&ExprLit(ref l), &ExprLit(ref r)) => l.node == r.node,
|
||||||
(&ExprLoop(ref lb, ref ll, ref lls), &ExprLoop(ref rb, ref rl, ref rls)) => {
|
(&ExprLoop(ref lb, ref ll, ref lls), &ExprLoop(ref rb, ref rl, ref rls)) => {
|
||||||
|
@ -690,8 +690,10 @@ fn parse_attrs<F: FnMut(u64)>(sess: &Session, attrs: &[ast::Attribute], name: &'
|
|||||||
/// See also `is_direct_expn_of`.
|
/// See also `is_direct_expn_of`.
|
||||||
pub fn is_expn_of(mut span: Span, name: &str) -> Option<Span> {
|
pub fn is_expn_of(mut span: Span, name: &str) -> Option<Span> {
|
||||||
loop {
|
loop {
|
||||||
let span_name_span = span.ctxt.outer()
|
let span_name_span = span.ctxt
|
||||||
.expn_info().map(|ei| (ei.callee.name(), ei.call_site));
|
.outer()
|
||||||
|
.expn_info()
|
||||||
|
.map(|ei| (ei.callee.name(), ei.call_site));
|
||||||
|
|
||||||
match span_name_span {
|
match span_name_span {
|
||||||
Some((mac_name, new_span)) if mac_name == name => return Some(new_span),
|
Some((mac_name, new_span)) if mac_name == name => return Some(new_span),
|
||||||
@ -709,8 +711,10 @@ pub fn is_expn_of(mut span: Span, name: &str) -> Option<Span> {
|
|||||||
/// `42` is considered expanded from `foo!` and `bar!` by `is_expn_of` but only `bar!` by
|
/// `42` is considered expanded from `foo!` and `bar!` by `is_expn_of` but only `bar!` by
|
||||||
/// `is_direct_expn_of`.
|
/// `is_direct_expn_of`.
|
||||||
pub fn is_direct_expn_of(span: Span, name: &str) -> Option<Span> {
|
pub fn is_direct_expn_of(span: Span, name: &str) -> Option<Span> {
|
||||||
let span_name_span = span.ctxt.outer()
|
let span_name_span = span.ctxt
|
||||||
.expn_info().map(|ei| (ei.callee.name(), ei.call_site));
|
.outer()
|
||||||
|
.expn_info()
|
||||||
|
.map(|ei| (ei.callee.name(), ei.call_site));
|
||||||
|
|
||||||
match span_name_span {
|
match span_name_span {
|
||||||
Some((mac_name, new_span)) if mac_name == name => Some(new_span),
|
Some((mac_name, new_span)) if mac_name == name => Some(new_span),
|
||||||
|
@ -12,8 +12,13 @@
|
|||||||
#[plugin_registrar]
|
#[plugin_registrar]
|
||||||
pub fn plugin_registrar(reg: &mut Registry) {
|
pub fn plugin_registrar(reg: &mut Registry) {
|
||||||
if let Ok(lint_store) = reg.sess.lint_store.try_borrow() {
|
if let Ok(lint_store) = reg.sess.lint_store.try_borrow() {
|
||||||
if lint_store.get_lint_groups().iter().any(|&(s, _, _)| s == "clippy") {
|
if lint_store
|
||||||
reg.sess.struct_warn("running cargo clippy on a crate that also imports the clippy plugin").emit();
|
.get_lint_groups()
|
||||||
|
.iter()
|
||||||
|
.any(|&(s, _, _)| s == "clippy") {
|
||||||
|
reg.sess
|
||||||
|
.struct_warn("running cargo clippy on a crate that also imports the clippy plugin")
|
||||||
|
.emit();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
116
src/main.rs
116
src/main.rs
@ -43,9 +43,10 @@ fn early_callback(
|
|||||||
sopts: &config::Options,
|
sopts: &config::Options,
|
||||||
cfg: &ast::CrateConfig,
|
cfg: &ast::CrateConfig,
|
||||||
descriptions: &rustc_errors::registry::Registry,
|
descriptions: &rustc_errors::registry::Registry,
|
||||||
output: ErrorOutputType
|
output: ErrorOutputType,
|
||||||
) -> Compilation {
|
) -> Compilation {
|
||||||
self.default.early_callback(matches, sopts, cfg, descriptions, output)
|
self.default
|
||||||
|
.early_callback(matches, sopts, cfg, descriptions, output)
|
||||||
}
|
}
|
||||||
fn no_input(
|
fn no_input(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -54,9 +55,10 @@ fn no_input(
|
|||||||
cfg: &ast::CrateConfig,
|
cfg: &ast::CrateConfig,
|
||||||
odir: &Option<PathBuf>,
|
odir: &Option<PathBuf>,
|
||||||
ofile: &Option<PathBuf>,
|
ofile: &Option<PathBuf>,
|
||||||
descriptions: &rustc_errors::registry::Registry
|
descriptions: &rustc_errors::registry::Registry,
|
||||||
) -> Option<(Input, Option<PathBuf>)> {
|
) -> Option<(Input, Option<PathBuf>)> {
|
||||||
self.default.no_input(matches, sopts, cfg, odir, ofile, descriptions)
|
self.default
|
||||||
|
.no_input(matches, sopts, cfg, odir, ofile, descriptions)
|
||||||
}
|
}
|
||||||
fn late_callback(
|
fn late_callback(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -64,9 +66,10 @@ fn late_callback(
|
|||||||
sess: &Session,
|
sess: &Session,
|
||||||
input: &Input,
|
input: &Input,
|
||||||
odir: &Option<PathBuf>,
|
odir: &Option<PathBuf>,
|
||||||
ofile: &Option<PathBuf>
|
ofile: &Option<PathBuf>,
|
||||||
) -> Compilation {
|
) -> Compilation {
|
||||||
self.default.late_callback(matches, sess, input, odir, ofile)
|
self.default
|
||||||
|
.late_callback(matches, sess, input, odir, ofile)
|
||||||
}
|
}
|
||||||
fn build_controller(&mut self, sess: &Session, matches: &getopts::Matches) -> driver::CompileController<'a> {
|
fn build_controller(&mut self, sess: &Session, matches: &getopts::Matches) -> driver::CompileController<'a> {
|
||||||
let mut control = self.default.build_controller(sess, matches);
|
let mut control = self.default.build_controller(sess, matches);
|
||||||
@ -76,7 +79,8 @@ fn build_controller(&mut self, sess: &Session, matches: &getopts::Matches) -> dr
|
|||||||
control.after_parse.callback = Box::new(move |state| {
|
control.after_parse.callback = Box::new(move |state| {
|
||||||
{
|
{
|
||||||
let mut registry = rustc_plugin::registry::Registry::new(state.session,
|
let mut registry = rustc_plugin::registry::Registry::new(state.session,
|
||||||
state.krate
|
state
|
||||||
|
.krate
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.expect("at this compilation stage \
|
.expect("at this compilation stage \
|
||||||
the krate must be parsed")
|
the krate must be parsed")
|
||||||
@ -84,12 +88,14 @@ fn build_controller(&mut self, sess: &Session, matches: &getopts::Matches) -> dr
|
|||||||
registry.args_hidden = Some(Vec::new());
|
registry.args_hidden = Some(Vec::new());
|
||||||
clippy_lints::register_plugins(&mut registry);
|
clippy_lints::register_plugins(&mut registry);
|
||||||
|
|
||||||
let rustc_plugin::registry::Registry { early_lint_passes,
|
let rustc_plugin::registry::Registry {
|
||||||
late_lint_passes,
|
early_lint_passes,
|
||||||
lint_groups,
|
late_lint_passes,
|
||||||
llvm_passes,
|
lint_groups,
|
||||||
attributes,
|
llvm_passes,
|
||||||
.. } = registry;
|
attributes,
|
||||||
|
..
|
||||||
|
} = registry;
|
||||||
let sess = &state.session;
|
let sess = &state.session;
|
||||||
let mut ls = sess.lint_store.borrow_mut();
|
let mut ls = sess.lint_store.borrow_mut();
|
||||||
for pass in early_lint_passes {
|
for pass in early_lint_passes {
|
||||||
@ -172,29 +178,35 @@ pub fn main() {
|
|||||||
if let Some("clippy") = std::env::args().nth(1).as_ref().map(AsRef::as_ref) {
|
if let Some("clippy") = std::env::args().nth(1).as_ref().map(AsRef::as_ref) {
|
||||||
// this arm is executed on the initial call to `cargo clippy`
|
// this arm is executed on the initial call to `cargo clippy`
|
||||||
|
|
||||||
let manifest_path_arg = std::env::args().skip(2).find(|val| val.starts_with("--manifest-path="));
|
let manifest_path_arg = std::env::args()
|
||||||
|
.skip(2)
|
||||||
|
.find(|val| val.starts_with("--manifest-path="));
|
||||||
|
|
||||||
let mut metadata = if let Ok(metadata) = cargo_metadata::metadata(manifest_path_arg.as_ref()
|
let mut metadata =
|
||||||
.map(AsRef::as_ref)) {
|
if let Ok(metadata) = cargo_metadata::metadata(manifest_path_arg.as_ref().map(AsRef::as_ref)) {
|
||||||
metadata
|
metadata
|
||||||
} else {
|
} else {
|
||||||
let _ = io::stderr().write_fmt(format_args!("error: Could not obtain cargo metadata.\n"));
|
let _ = io::stderr().write_fmt(format_args!("error: Could not obtain cargo metadata.\n"));
|
||||||
process::exit(101);
|
process::exit(101);
|
||||||
};
|
};
|
||||||
|
|
||||||
let manifest_path = manifest_path_arg.map(|arg| PathBuf::from(Path::new(&arg["--manifest-path=".len()..])));
|
let manifest_path = manifest_path_arg.map(|arg| PathBuf::from(Path::new(&arg["--manifest-path=".len()..])));
|
||||||
|
|
||||||
let current_dir = std::env::current_dir();
|
let current_dir = std::env::current_dir();
|
||||||
|
|
||||||
let package_index = metadata.packages
|
let package_index = metadata
|
||||||
|
.packages
|
||||||
.iter()
|
.iter()
|
||||||
.position(|package| {
|
.position(|package| {
|
||||||
let package_manifest_path = Path::new(&package.manifest_path);
|
let package_manifest_path = Path::new(&package.manifest_path);
|
||||||
if let Some(ref manifest_path) = manifest_path {
|
if let Some(ref manifest_path) = manifest_path {
|
||||||
package_manifest_path == manifest_path
|
package_manifest_path == manifest_path
|
||||||
} else {
|
} else {
|
||||||
let current_dir = current_dir.as_ref().expect("could not read current directory");
|
let current_dir = current_dir
|
||||||
let package_manifest_directory = package_manifest_path.parent()
|
.as_ref()
|
||||||
|
.expect("could not read current directory");
|
||||||
|
let package_manifest_directory = package_manifest_path
|
||||||
|
.parent()
|
||||||
.expect("could not find parent directory of package manifest");
|
.expect("could not find parent directory of package manifest");
|
||||||
package_manifest_directory == current_dir
|
package_manifest_directory == current_dir
|
||||||
}
|
}
|
||||||
@ -209,7 +221,9 @@ pub fn main() {
|
|||||||
std::process::exit(code);
|
std::process::exit(code);
|
||||||
}
|
}
|
||||||
} else if ["bin", "example", "test", "bench"].contains(&&**first) {
|
} else if ["bin", "example", "test", "bench"].contains(&&**first) {
|
||||||
if let Err(code) = process(vec![format!("--{}", first), target.name].into_iter().chain(args)) {
|
if let Err(code) = process(vec![format!("--{}", first), target.name]
|
||||||
|
.into_iter()
|
||||||
|
.chain(args)) {
|
||||||
std::process::exit(code);
|
std::process::exit(code);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -218,7 +232,8 @@ pub fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// this arm is executed when cargo-clippy runs `cargo rustc` with the `RUSTC` env var set to itself
|
// this arm is executed when cargo-clippy runs `cargo rustc` with the `RUSTC`
|
||||||
|
// env var set to itself
|
||||||
|
|
||||||
let home = option_env!("RUSTUP_HOME").or(option_env!("MULTIRUST_HOME"));
|
let home = option_env!("RUSTUP_HOME").or(option_env!("MULTIRUST_HOME"));
|
||||||
let toolchain = option_env!("RUSTUP_TOOLCHAIN").or(option_env!("MULTIRUST_TOOLCHAIN"));
|
let toolchain = option_env!("RUSTUP_TOOLCHAIN").or(option_env!("MULTIRUST_TOOLCHAIN"));
|
||||||
@ -240,31 +255,36 @@ pub fn main() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
rustc_driver::in_rustc_thread(|| {
|
rustc_driver::in_rustc_thread(|| {
|
||||||
// this conditional check for the --sysroot flag is there so users can call `cargo-clippy` directly
|
// this conditional check for the --sysroot flag is there so users can call
|
||||||
// without having to pass --sysroot or anything
|
// `cargo-clippy` directly
|
||||||
let mut args: Vec<String> = if env::args().any(|s| s == "--sysroot") {
|
// without having to pass --sysroot or anything
|
||||||
env::args().collect()
|
let mut args: Vec<String> = if env::args().any(|s| s == "--sysroot") {
|
||||||
} else {
|
env::args().collect()
|
||||||
env::args().chain(Some("--sysroot".to_owned())).chain(Some(sys_root)).collect()
|
} else {
|
||||||
};
|
env::args()
|
||||||
|
.chain(Some("--sysroot".to_owned()))
|
||||||
|
.chain(Some(sys_root))
|
||||||
|
.collect()
|
||||||
|
};
|
||||||
|
|
||||||
// this check ensures that dependencies are built but not linted and the final crate is
|
// this check ensures that dependencies are built but not linted and the final
|
||||||
// linted but not built
|
// crate is
|
||||||
let clippy_enabled = env::args().any(|s| s == "-Zno-trans");
|
// linted but not built
|
||||||
|
let clippy_enabled = env::args().any(|s| s == "-Zno-trans");
|
||||||
|
|
||||||
if clippy_enabled {
|
if clippy_enabled {
|
||||||
args.extend_from_slice(&["--cfg".to_owned(), r#"feature="cargo-clippy""#.to_owned()]);
|
args.extend_from_slice(&["--cfg".to_owned(), r#"feature="cargo-clippy""#.to_owned()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut ccc = ClippyCompilerCalls::new(clippy_enabled);
|
||||||
|
let (result, _) = rustc_driver::run_compiler(&args, &mut ccc, None, None);
|
||||||
|
if let Err(err_count) = result {
|
||||||
|
if err_count > 0 {
|
||||||
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
let mut ccc = ClippyCompilerCalls::new(clippy_enabled);
|
})
|
||||||
let (result, _) = rustc_driver::run_compiler(&args, &mut ccc, None, None);
|
.expect("rustc_thread failed");
|
||||||
if let Err(err_count) = result {
|
|
||||||
if err_count > 0 {
|
|
||||||
std::process::exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.expect("rustc_thread failed");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,14 +14,14 @@ struct Test {
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
use Baz::*;
|
use Baz::*;
|
||||||
let x = Test {
|
let x = Test { t: Some(0), b: One };
|
||||||
t: Some(0),
|
|
||||||
b: One,
|
|
||||||
};
|
|
||||||
|
|
||||||
match x {
|
match x {
|
||||||
Test { t: Some(_), b: One } => unreachable!(),
|
Test { t: Some(_), b: One } => unreachable!(),
|
||||||
Test { t: Some(42), b: Two } => unreachable!(),
|
Test {
|
||||||
|
t: Some(42),
|
||||||
|
b: Two,
|
||||||
|
} => unreachable!(),
|
||||||
Test { t: None, .. } => unreachable!(),
|
Test { t: None, .. } => unreachable!(),
|
||||||
Test { .. } => unreachable!(),
|
Test { .. } => unreachable!(),
|
||||||
}
|
}
|
||||||
|
@ -20,9 +20,13 @@ fn test_overlapping() {
|
|||||||
assert_eq!(None, overlapping(&[sp(1, Bound::Included(4))]));
|
assert_eq!(None, overlapping(&[sp(1, Bound::Included(4))]));
|
||||||
assert_eq!(None, overlapping(&[sp(1, Bound::Included(4)), sp(5, Bound::Included(6))]));
|
assert_eq!(None, overlapping(&[sp(1, Bound::Included(4)), sp(5, Bound::Included(6))]));
|
||||||
assert_eq!(None,
|
assert_eq!(None,
|
||||||
overlapping(&[sp(1, Bound::Included(4)), sp(5, Bound::Included(6)), sp(10, Bound::Included(11))]));
|
overlapping(&[sp(1, Bound::Included(4)),
|
||||||
|
sp(5, Bound::Included(6)),
|
||||||
|
sp(10, Bound::Included(11))]));
|
||||||
assert_eq!(Some((&sp(1, Bound::Included(4)), &sp(3, Bound::Included(6)))),
|
assert_eq!(Some((&sp(1, Bound::Included(4)), &sp(3, Bound::Included(6)))),
|
||||||
overlapping(&[sp(1, Bound::Included(4)), sp(3, Bound::Included(6))]));
|
overlapping(&[sp(1, Bound::Included(4)), sp(3, Bound::Included(6))]));
|
||||||
assert_eq!(Some((&sp(5, Bound::Included(6)), &sp(6, Bound::Included(11)))),
|
assert_eq!(Some((&sp(5, Bound::Included(6)), &sp(6, Bound::Included(11)))),
|
||||||
overlapping(&[sp(1, Bound::Included(4)), sp(5, Bound::Included(6)), sp(6, Bound::Included(11))]));
|
overlapping(&[sp(1, Bound::Included(4)),
|
||||||
|
sp(5, Bound::Included(6)),
|
||||||
|
sp(6, Bound::Included(11))]));
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,8 @@
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
|
||||||
/// Test that we do not lint for unused underscores in a `MacroAttribute` expansion
|
/// Test that we do not lint for unused underscores in a `MacroAttribute`
|
||||||
|
/// expansion
|
||||||
#[deny(used_underscore_binding)]
|
#[deny(used_underscore_binding)]
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct MacroAttributesTest {
|
struct MacroAttributesTest {
|
||||||
|
Loading…
Reference in New Issue
Block a user