From eb93058dd538ee30be835e750955deb30c01598d Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Fri, 5 May 2017 14:25:54 +0200 Subject: [PATCH 1/2] Also print type adjustments in the inspector --- clippy_lints/src/utils/inspector.rs | 59 +++++++++++++++-------------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/clippy_lints/src/utils/inspector.rs b/clippy_lints/src/utils/inspector.rs index 4a4ddf5f3fc..19e205c9920 100644 --- a/clippy_lints/src/utils/inspector.rs +++ b/clippy_lints/src/utils/inspector.rs @@ -152,21 +152,22 @@ fn print_decl(cx: &LateContext, decl: &hir::Decl) { fn print_expr(cx: &LateContext, expr: &hir::Expr, indent: usize) { let ind = " ".repeat(indent); - let ty = cx.tables.node_id_to_type(expr.id); println!("{}+", ind); + println!("{}ty: {}", ind, cx.tables.expr_ty(expr)); + println!("{}adjustments: {:?}", ind, cx.tables.adjustments.get(&expr.id)); match expr.node { hir::ExprBox(ref e) => { - println!("{}Box, {}", ind, ty); + println!("{}Box", ind); print_expr(cx, e, indent + 1); }, hir::ExprArray(ref v) => { - println!("{}Array, {}", ind, ty); + println!("{}Array", ind); for e in v { print_expr(cx, e, indent + 1); } }, hir::ExprCall(ref func, ref args) => { - println!("{}Call, {}", ind, ty); + println!("{}Call", ind); println!("{}function:", ind); print_expr(cx, func, indent + 1); println!("{}arguments:", ind); @@ -175,20 +176,20 @@ fn print_expr(cx: &LateContext, expr: &hir::Expr, indent: usize) { } }, hir::ExprMethodCall(ref name, _, ref args) => { - println!("{}MethodCall, {}", ind, ty); + println!("{}MethodCall", ind); println!("{}method name: {}", ind, name.node); for arg in args { print_expr(cx, arg, indent + 1); } }, hir::ExprTup(ref v) => { - println!("{}Tup, {}", ind, ty); + println!("{}Tup", ind); for e in v { print_expr(cx, e, indent + 1); } }, hir::ExprBinary(op, ref lhs, ref rhs) => { - println!("{}Binary, {}", ind, ty); + println!("{}Binary", ind); println!("{}op: {:?}", ind, op.node); println!("{}lhs:", ind); print_expr(cx, lhs, indent + 1); @@ -196,26 +197,26 @@ fn print_expr(cx: &LateContext, expr: &hir::Expr, indent: usize) { print_expr(cx, rhs, indent + 1); }, hir::ExprUnary(op, ref inner) => { - println!("{}Unary, {}", ind, ty); + println!("{}Unary", ind); println!("{}op: {:?}", ind, op); print_expr(cx, inner, indent + 1); }, hir::ExprLit(ref lit) => { - println!("{}Lit, {}", ind, ty); + println!("{}Lit", ind); println!("{}{:?}", ind, lit); }, hir::ExprCast(ref e, ref target) => { - println!("{}Cast, {}", ind, ty); + println!("{}Cast", ind); print_expr(cx, e, indent + 1); println!("{}target type: {:?}", ind, target); }, hir::ExprType(ref e, ref target) => { - println!("{}Type, {}", ind, ty); + println!("{}Type", ind); print_expr(cx, e, indent + 1); println!("{}target type: {:?}", ind, target); }, hir::ExprIf(ref e, _, ref els) => { - println!("{}If, {}", ind, ty); + println!("{}If", ind); println!("{}condition:", ind); print_expr(cx, e, indent + 1); if let Some(ref els) = *els { @@ -224,35 +225,35 @@ fn print_expr(cx: &LateContext, expr: &hir::Expr, indent: usize) { } }, hir::ExprWhile(ref cond, _, _) => { - println!("{}While, {}", ind, ty); + println!("{}While", ind); println!("{}condition:", ind); print_expr(cx, cond, indent + 1); }, hir::ExprLoop(..) => { - println!("{}Loop, {}", ind, ty); + println!("{}Loop", ind); }, hir::ExprMatch(ref cond, _, ref source) => { - println!("{}Match, {}", ind, ty); + println!("{}Match", ind); println!("{}condition:", ind); print_expr(cx, cond, indent + 1); println!("{}source: {:?}", ind, source); }, hir::ExprClosure(ref clause, _, _, _) => { - println!("{}Closure, {}", ind, ty); + println!("{}Closure", ind); println!("{}clause: {:?}", ind, clause); }, hir::ExprBlock(_) => { - println!("{}Block, {}", ind, ty); + println!("{}Block", ind); }, hir::ExprAssign(ref lhs, ref rhs) => { - println!("{}Assign, {}", ind, ty); + println!("{}Assign", ind); println!("{}lhs:", ind); print_expr(cx, lhs, indent + 1); println!("{}rhs:", ind); print_expr(cx, rhs, indent + 1); }, hir::ExprAssignOp(ref binop, ref lhs, ref rhs) => { - println!("{}AssignOp, {}", ind, ty); + println!("{}AssignOp", ind); println!("{}op: {:?}", ind, binop.node); println!("{}lhs:", ind); print_expr(cx, lhs, indent + 1); @@ -260,19 +261,19 @@ fn print_expr(cx: &LateContext, expr: &hir::Expr, indent: usize) { print_expr(cx, rhs, indent + 1); }, hir::ExprField(ref e, ref name) => { - println!("{}Field, {}", ind, ty); + println!("{}Field", ind); println!("{}field name: {}", ind, name.node); println!("{}struct expr:", ind); print_expr(cx, e, indent + 1); }, hir::ExprTupField(ref e, ref idx) => { - println!("{}TupField, {}", ind, ty); + println!("{}TupField", ind); println!("{}field index: {}", ind, idx.node); println!("{}tuple expr:", ind); print_expr(cx, e, indent + 1); }, hir::ExprIndex(ref arr, ref idx) => { - println!("{}Index, {}", ind, ty); + println!("{}Index", ind); println!("{}array expr:", ind); print_expr(cx, arr, indent + 1); println!("{}index expr:", ind); @@ -287,25 +288,25 @@ fn print_expr(cx: &LateContext, expr: &hir::Expr, indent: usize) { println!("{}seg: {:?}", ind, seg); }, hir::ExprAddrOf(ref muta, ref e) => { - println!("{}AddrOf, {}", ind, ty); + println!("{}AddrOf", ind); println!("mutability: {:?}", muta); print_expr(cx, e, indent + 1); }, hir::ExprBreak(_, ref e) => { - println!("{}Break, {}", ind, ty); + println!("{}Break", ind); if let Some(ref e) = *e { print_expr(cx, e, indent + 1); } }, - hir::ExprAgain(_) => println!("{}Again, {}", ind, ty), + hir::ExprAgain(_) => println!("{}Again", ind), hir::ExprRet(ref e) => { - println!("{}Ret, {}", ind, ty); + println!("{}Ret", ind); if let Some(ref e) = *e { print_expr(cx, e, indent + 1); } }, hir::ExprInlineAsm(_, ref input, ref output) => { - println!("{}InlineAsm, {}", ind, ty); + println!("{}InlineAsm", ind); println!("{}inputs:", ind); for e in input { print_expr(cx, e, indent + 1); @@ -316,7 +317,7 @@ fn print_expr(cx: &LateContext, expr: &hir::Expr, indent: usize) { } }, hir::ExprStruct(ref path, ref fields, ref base) => { - println!("{}Struct, {}", ind, ty); + println!("{}Struct", ind); println!("{}path: {:?}", ind, path); for field in fields { println!("{}field \"{}\":", ind, field.name.node); @@ -328,7 +329,7 @@ fn print_expr(cx: &LateContext, expr: &hir::Expr, indent: usize) { } }, hir::ExprRepeat(ref val, body_id) => { - println!("{}Repeat, {}", ind, ty); + println!("{}Repeat", ind); println!("{}value:", ind); print_expr(cx, val, indent + 1); println!("{}repeat count:", ind); From 866239b1a8828f6f4e1401d0951299234751498a Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Fri, 5 May 2017 14:26:14 +0200 Subject: [PATCH 2/2] Add a test showing a false positive on needless_borrow --- tests/ui/needless_borrow.rs | 9 +++++++++ tests/ui/needless_borrow.stderr | 16 ++++++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/tests/ui/needless_borrow.rs b/tests/ui/needless_borrow.rs index 1fc36c0be18..27ee4d1f696 100644 --- a/tests/ui/needless_borrow.rs +++ b/tests/ui/needless_borrow.rs @@ -18,6 +18,15 @@ fn main() { let vec_val = g(&vec); // should not error, because `&Vec` derefs to `&[T]` h(&"foo"); // should not error, because the `&&str` is required, due to `&Trait` if let Some(ref cake) = Some(&5) {} + let garbl = match 42 { + 44 => &a, + 45 => { + println!("foo"); + &&a // FIXME: this should lint, too + }, + 46 => &&a, + _ => panic!(), + }; } fn f(y: &T) -> T { diff --git a/tests/ui/needless_borrow.stderr b/tests/ui/needless_borrow.stderr index a5d549c986b..eab79e63bc4 100644 --- a/tests/ui/needless_borrow.stderr +++ b/tests/ui/needless_borrow.stderr @@ -19,13 +19,21 @@ error: this pattern creates a reference to a reference | = note: #[deny(needless_borrow)] implied by #[deny(clippy)] -warning: this pattern creates a reference to a reference - --> $DIR/needless_borrow.rs:41:31 +error: this expression borrows a reference that is immediately dereferenced by the compiler + --> $DIR/needless_borrow.rs:27:15 | -41 | let _ = v.iter().filter(|&ref a| a.is_empty()); +27 | 46 => &&a, + | ^^^ + | + = note: #[deny(needless_borrow)] implied by #[deny(clippy)] + +warning: this pattern creates a reference to a reference + --> $DIR/needless_borrow.rs:50:31 + | +50 | let _ = v.iter().filter(|&ref a| a.is_empty()); | ^^^^^ | = note: #[warn(needless_borrow)] on by default -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors