Skip to content

Commit fe8e171

Browse files
committed
Add support for ExprKind::Use
Introduced in rust-lang/rust#60225
1 parent b2b734c commit fe8e171

File tree

7 files changed

+36
-23
lines changed

7 files changed

+36
-23
lines changed

clippy_lints/src/loops.rs

+1
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,7 @@ fn never_loop_expr(expr: &Expr, main_loop_id: HirId) -> NeverLoopResult {
671671
match expr.node {
672672
ExprKind::Box(ref e)
673673
| ExprKind::Unary(_, ref e)
674+
| ExprKind::Use(ref e)
674675
| ExprKind::Cast(ref e, _)
675676
| ExprKind::Type(ref e, _)
676677
| ExprKind::Field(ref e, _)

clippy_lints/src/utils/author.rs

+6
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,12 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor {
492492
self.current = value_pat;
493493
self.visit_expr(value);
494494
},
495+
ExprKind::Use(ref inner) => {
496+
let inner_pat = self.next("inner");
497+
println!("Use(ref {}) = {};", inner_pat, current);
498+
self.current = inner_pat;
499+
self.visit_expr(inner);
500+
}
495501
ExprKind::Err => {
496502
println!("Err = {}", current);
497503
},

clippy_lints/src/utils/higher.rs

+1
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ pub fn is_from_for_desugar(local: &hir::Local) -> bool {
184184
/// `for pat in arg { body }` becomes `(pat, arg, body)`.
185185
pub fn for_loop(expr: &hir::Expr) -> Option<(&hir::Pat, &hir::Expr, &hir::Expr)> {
186186
if_chain! {
187+
if let hir::ExprKind::Use(ref expr) = expr.node;
187188
if let hir::ExprKind::Match(ref iterexpr, ref arms, hir::MatchSource::ForLoopDesugar) = expr.node;
188189
if let hir::ExprKind::Call(_, ref iterargs) = iterexpr.node;
189190
if iterargs.len() == 1 && arms.len() == 1 && arms[0].guard.is_none();

clippy_lints/src/utils/hir_utils.rs

+6
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
101101
&& both(le, re, |l, r| self.eq_expr(l, r))
102102
},
103103
(&ExprKind::Box(ref l), &ExprKind::Box(ref r)) => self.eq_expr(l, r),
104+
(&ExprKind::Use(ref l), &ExprKind::Use(ref r)) => self.eq_expr(l, r),
104105
(&ExprKind::Call(ref l_fun, ref l_args), &ExprKind::Call(ref r_fun, ref r_args)) => {
105106
!self.ignore_fn && self.eq_expr(l_fun, r_fun) && self.eq_exprs(l_args, r_args)
106107
},
@@ -454,6 +455,11 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
454455
c.hash(&mut self.s);
455456
self.hash_expr(e);
456457
},
458+
ExprKind::Use(ref e) => {
459+
let c: fn(_) -> _ = ExprKind::Use;
460+
c.hash(&mut self.s);
461+
self.hash_expr(e);
462+
},
457463
ExprKind::Call(ref fun, ref args) => {
458464
let c: fn(_, _) -> _ = ExprKind::Call;
459465
c.hash(&mut self.s);

clippy_lints/src/utils/inspector.rs

+4
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,10 @@ fn print_expr(cx: &LateContext<'_, '_>, expr: &hir::Expr, indent: usize) {
154154
println!("{}Box", ind);
155155
print_expr(cx, e, indent + 1);
156156
},
157+
hir::ExprKind::Use(ref e) => {
158+
println!("{}Use", ind);
159+
print_expr(cx, e, indent + 1);
160+
},
157161
hir::ExprKind::Array(ref v) => {
158162
println!("{}Array", ind);
159163
for e in v {

clippy_lints/src/utils/sugg.rs

+1
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ impl<'a> Sugg<'a> {
9393
match expr.node {
9494
hir::ExprKind::AddrOf(..)
9595
| hir::ExprKind::Box(..)
96+
| hir::ExprKind::Use(..)
9697
| hir::ExprKind::Closure(.., _)
9798
| hir::ExprKind::If(..)
9899
| hir::ExprKind::Unary(..)

tests/ui/author/for_loop.stdout

+17-23
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
if_chain! {
2-
if let ExprKind::Block(ref block) = expr.node;
3-
if let StmtKind::Local(ref local) = block.node;
4-
if let Some(ref init) = local.init;
5-
if let ExprKind::Match(ref expr, ref arms, MatchSource::ForLoopDesugar) = init.node;
2+
if let ExprKind::Use(ref inner) = expr.node;
3+
if let ExprKind::Match(ref expr, ref arms, MatchSource::ForLoopDesugar) = inner.node;
64
if let ExprKind::Call(ref func, ref args) = expr.node;
75
if let ExprKind::Path(ref path) = func.node;
86
if match_qpath(path, &["{{root}}", "std", "iter", "IntoIterator", "into_iter"]);
@@ -13,17 +11,17 @@ if_chain! {
1311
// unimplemented: field checks
1412
if arms.len() == 1;
1513
if let ExprKind::Loop(ref body, ref label, LoopSource::ForLoop) = arms[0].body.node;
16-
if let StmtKind::Local(ref local1) = body.node;
17-
if let PatKind::Binding(BindingAnnotation::Mutable, _, name, None) = local1.pat.node;
14+
if let StmtKind::Local(ref local) = body.node;
15+
if let PatKind::Binding(BindingAnnotation::Mutable, _, name, None) = local.pat.node;
1816
if name.node.as_str() == "__next";
19-
if let StmtKind::Expr(ref e, _) = local1.pat.node
17+
if let StmtKind::Expr(ref e, _) = local.pat.node
2018
if let ExprKind::Match(ref expr1, ref arms1, MatchSource::ForLoopDesugar) = e.node;
2119
if let ExprKind::Call(ref func1, ref args1) = expr1.node;
2220
if let ExprKind::Path(ref path2) = func1.node;
2321
if match_qpath(path2, &["{{root}}", "std", "iter", "Iterator", "next"]);
2422
if args1.len() == 1;
25-
if let ExprKind::AddrOf(MutMutable, ref inner) = args1[0].node;
26-
if let ExprKind::Path(ref path3) = inner.node;
23+
if let ExprKind::AddrOf(MutMutable, ref inner1) = args1[0].node;
24+
if let ExprKind::Path(ref path3) = inner1.node;
2725
if match_qpath(path3, &["iter"]);
2826
if arms1.len() == 2;
2927
if let ExprKind::Assign(ref target, ref value) = arms1[0].body.node;
@@ -40,27 +38,23 @@ if_chain! {
4038
if arms1[1].pats.len() == 1;
4139
if let PatKind::Path(ref path7) = arms1[1].pats[0].node;
4240
if match_qpath(path7, &["{{root}}", "std", "option", "Option", "None"]);
43-
if let StmtKind::Local(ref local2) = path7.node;
44-
if let Some(ref init1) = local2.init;
45-
if let ExprKind::Path(ref path8) = init1.node;
41+
if let StmtKind::Local(ref local1) = path7.node;
42+
if let Some(ref init) = local1.init;
43+
if let ExprKind::Path(ref path8) = init.node;
4644
if match_qpath(path8, &["__next"]);
47-
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name1, None) = local2.pat.node;
45+
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name1, None) = local1.pat.node;
4846
if name1.node.as_str() == "y";
49-
if let StmtKind::Expr(ref e1, _) = local2.pat.node
50-
if let ExprKind::Block(ref block1) = e1.node;
51-
if let StmtKind::Local(ref local3) = block1.node;
52-
if let Some(ref init2) = local3.init;
53-
if let ExprKind::Path(ref path9) = init2.node;
47+
if let StmtKind::Expr(ref e1, _) = local1.pat.node
48+
if let ExprKind::Block(ref block) = e1.node;
49+
if let StmtKind::Local(ref local2) = block.node;
50+
if let Some(ref init1) = local2.init;
51+
if let ExprKind::Path(ref path9) = init1.node;
5452
if match_qpath(path9, &["y"]);
55-
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name2, None) = local3.pat.node;
53+
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name2, None) = local2.pat.node;
5654
if name2.node.as_str() == "z";
5755
if arms[0].pats.len() == 1;
5856
if let PatKind::Binding(BindingAnnotation::Mutable, _, name3, None) = arms[0].pats[0].node;
5957
if name3.node.as_str() == "iter";
60-
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name4, None) = local.pat.node;
61-
if name4.node.as_str() == "_result";
62-
if let ExprKind::Path(ref path10) = local.pat.node;
63-
if match_qpath(path10, &["_result"]);
6458
then {
6559
// report your lint here
6660
}

0 commit comments

Comments
 (0)