Skip to content

Commit

Permalink
Add support for ExprKind::Use
Browse files Browse the repository at this point in the history
Introduced in rust-lang/rust#60225
  • Loading branch information
Manishearth committed Apr 27, 2019
1 parent b2b734c commit fe8e171
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 23 deletions.
1 change: 1 addition & 0 deletions clippy_lints/src/loops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,7 @@ fn never_loop_expr(expr: &Expr, main_loop_id: HirId) -> NeverLoopResult {
match expr.node {
ExprKind::Box(ref e)
| ExprKind::Unary(_, ref e)
| ExprKind::Use(ref e)
| ExprKind::Cast(ref e, _)
| ExprKind::Type(ref e, _)
| ExprKind::Field(ref e, _)
Expand Down
6 changes: 6 additions & 0 deletions clippy_lints/src/utils/author.rs
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,12 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor {
self.current = value_pat;
self.visit_expr(value);
},
ExprKind::Use(ref inner) => {
let inner_pat = self.next("inner");
println!("Use(ref {}) = {};", inner_pat, current);
self.current = inner_pat;
self.visit_expr(inner);
}
ExprKind::Err => {
println!("Err = {}", current);
},
Expand Down
1 change: 1 addition & 0 deletions clippy_lints/src/utils/higher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ pub fn is_from_for_desugar(local: &hir::Local) -> bool {
/// `for pat in arg { body }` becomes `(pat, arg, body)`.
pub fn for_loop(expr: &hir::Expr) -> Option<(&hir::Pat, &hir::Expr, &hir::Expr)> {
if_chain! {
if let hir::ExprKind::Use(ref expr) = expr.node;
if let hir::ExprKind::Match(ref iterexpr, ref arms, hir::MatchSource::ForLoopDesugar) = expr.node;
if let hir::ExprKind::Call(_, ref iterargs) = iterexpr.node;
if iterargs.len() == 1 && arms.len() == 1 && arms[0].guard.is_none();
Expand Down
6 changes: 6 additions & 0 deletions clippy_lints/src/utils/hir_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
&& both(le, re, |l, r| self.eq_expr(l, r))
},
(&ExprKind::Box(ref l), &ExprKind::Box(ref r)) => self.eq_expr(l, r),
(&ExprKind::Use(ref l), &ExprKind::Use(ref r)) => self.eq_expr(l, r),
(&ExprKind::Call(ref l_fun, ref l_args), &ExprKind::Call(ref r_fun, ref r_args)) => {
!self.ignore_fn && self.eq_expr(l_fun, r_fun) && self.eq_exprs(l_args, r_args)
},
Expand Down Expand Up @@ -454,6 +455,11 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
c.hash(&mut self.s);
self.hash_expr(e);
},
ExprKind::Use(ref e) => {
let c: fn(_) -> _ = ExprKind::Use;
c.hash(&mut self.s);
self.hash_expr(e);
},
ExprKind::Call(ref fun, ref args) => {
let c: fn(_, _) -> _ = ExprKind::Call;
c.hash(&mut self.s);
Expand Down
4 changes: 4 additions & 0 deletions clippy_lints/src/utils/inspector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,10 @@ fn print_expr(cx: &LateContext<'_, '_>, expr: &hir::Expr, indent: usize) {
println!("{}Box", ind);
print_expr(cx, e, indent + 1);
},
hir::ExprKind::Use(ref e) => {
println!("{}Use", ind);
print_expr(cx, e, indent + 1);
},
hir::ExprKind::Array(ref v) => {
println!("{}Array", ind);
for e in v {
Expand Down
1 change: 1 addition & 0 deletions clippy_lints/src/utils/sugg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ impl<'a> Sugg<'a> {
match expr.node {
hir::ExprKind::AddrOf(..)
| hir::ExprKind::Box(..)
| hir::ExprKind::Use(..)
| hir::ExprKind::Closure(.., _)
| hir::ExprKind::If(..)
| hir::ExprKind::Unary(..)
Expand Down
40 changes: 17 additions & 23 deletions tests/ui/author/for_loop.stdout
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
if_chain! {
if let ExprKind::Block(ref block) = expr.node;
if let StmtKind::Local(ref local) = block.node;
if let Some(ref init) = local.init;
if let ExprKind::Match(ref expr, ref arms, MatchSource::ForLoopDesugar) = init.node;
if let ExprKind::Use(ref inner) = expr.node;
if let ExprKind::Match(ref expr, ref arms, MatchSource::ForLoopDesugar) = inner.node;
if let ExprKind::Call(ref func, ref args) = expr.node;
if let ExprKind::Path(ref path) = func.node;
if match_qpath(path, &["{{root}}", "std", "iter", "IntoIterator", "into_iter"]);
Expand All @@ -13,17 +11,17 @@ if_chain! {
// unimplemented: field checks
if arms.len() == 1;
if let ExprKind::Loop(ref body, ref label, LoopSource::ForLoop) = arms[0].body.node;
if let StmtKind::Local(ref local1) = body.node;
if let PatKind::Binding(BindingAnnotation::Mutable, _, name, None) = local1.pat.node;
if let StmtKind::Local(ref local) = body.node;
if let PatKind::Binding(BindingAnnotation::Mutable, _, name, None) = local.pat.node;
if name.node.as_str() == "__next";
if let StmtKind::Expr(ref e, _) = local1.pat.node
if let StmtKind::Expr(ref e, _) = local.pat.node
if let ExprKind::Match(ref expr1, ref arms1, MatchSource::ForLoopDesugar) = e.node;
if let ExprKind::Call(ref func1, ref args1) = expr1.node;
if let ExprKind::Path(ref path2) = func1.node;
if match_qpath(path2, &["{{root}}", "std", "iter", "Iterator", "next"]);
if args1.len() == 1;
if let ExprKind::AddrOf(MutMutable, ref inner) = args1[0].node;
if let ExprKind::Path(ref path3) = inner.node;
if let ExprKind::AddrOf(MutMutable, ref inner1) = args1[0].node;
if let ExprKind::Path(ref path3) = inner1.node;
if match_qpath(path3, &["iter"]);
if arms1.len() == 2;
if let ExprKind::Assign(ref target, ref value) = arms1[0].body.node;
Expand All @@ -40,27 +38,23 @@ if_chain! {
if arms1[1].pats.len() == 1;
if let PatKind::Path(ref path7) = arms1[1].pats[0].node;
if match_qpath(path7, &["{{root}}", "std", "option", "Option", "None"]);
if let StmtKind::Local(ref local2) = path7.node;
if let Some(ref init1) = local2.init;
if let ExprKind::Path(ref path8) = init1.node;
if let StmtKind::Local(ref local1) = path7.node;
if let Some(ref init) = local1.init;
if let ExprKind::Path(ref path8) = init.node;
if match_qpath(path8, &["__next"]);
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name1, None) = local2.pat.node;
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name1, None) = local1.pat.node;
if name1.node.as_str() == "y";
if let StmtKind::Expr(ref e1, _) = local2.pat.node
if let ExprKind::Block(ref block1) = e1.node;
if let StmtKind::Local(ref local3) = block1.node;
if let Some(ref init2) = local3.init;
if let ExprKind::Path(ref path9) = init2.node;
if let StmtKind::Expr(ref e1, _) = local1.pat.node
if let ExprKind::Block(ref block) = e1.node;
if let StmtKind::Local(ref local2) = block.node;
if let Some(ref init1) = local2.init;
if let ExprKind::Path(ref path9) = init1.node;
if match_qpath(path9, &["y"]);
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name2, None) = local3.pat.node;
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 name3.node.as_str() == "iter";
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name4, None) = local.pat.node;
if name4.node.as_str() == "_result";
if let ExprKind::Path(ref path10) = local.pat.node;
if match_qpath(path10, &["_result"]);
then {
// report your lint here
}
Expand Down

0 comments on commit fe8e171

Please sign in to comment.