Skip to content

Commit 80b11a9

Browse files
committed
Move more functions to utils::higher
1 parent dba8b14 commit 80b11a9

File tree

8 files changed

+46
-47
lines changed

8 files changed

+46
-47
lines changed

clippy_lints/src/formatting.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ fn check_consecutive_ifs(cx: &EarlyContext, first: &ast::Expr, second: &ast::Exp
156156
}
157157
}
158158

159-
/// Match `if` or `else if` expressions and return the `then` and `else` block.
159+
/// Match `if` or `if let` expressions and return the `then` and `else` block.
160160
fn unsugar_if(expr: &ast::Expr) -> Option<(&P<ast::Block>, &Option<P<ast::Expr>>)> {
161161
match expr.node {
162162
ast::ExprKind::If(_, ref then, ref else_) |

clippy_lints/src/loops.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use syntax::ast;
1515

1616
use utils::{snippet, span_lint, get_parent_expr, match_trait_method, match_type, in_external_macro,
1717
span_help_and_lint, is_integer_literal, get_enclosing_block, span_lint_and_then, higher,
18-
walk_ptrs_ty, recover_for_loop};
18+
walk_ptrs_ty};
1919
use utils::paths;
2020

2121
/// **What it does:** This lint checks for looping over the range of `0..len` of some collection just to get the values by index.
@@ -223,7 +223,7 @@ impl LintPass for Pass {
223223

224224
impl LateLintPass for Pass {
225225
fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
226-
if let Some((pat, arg, body)) = recover_for_loop(expr) {
226+
if let Some((pat, arg, body)) = higher::for_loop(expr) {
227227
check_for_loop(cx, pat, arg, body, expr);
228228
}
229229
// check for `loop { if let {} else break }` that could be `while let`

clippy_lints/src/mut_mut.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use rustc::hir;
22
use rustc::hir::intravisit;
33
use rustc::lint::*;
44
use rustc::ty::{TypeAndMut, TyRef};
5-
use utils::{in_external_macro, recover_for_loop, span_lint};
5+
use utils::{higher, in_external_macro, span_lint};
66

77
/// **What it does:** This lint checks for instances of `mut mut` references.
88
///
@@ -49,7 +49,7 @@ impl<'a, 'tcx, 'v> intravisit::Visitor<'v> for MutVisitor<'a, 'tcx> {
4949
return;
5050
}
5151

52-
if let Some((_, arg, body)) = recover_for_loop(expr) {
52+
if let Some((_, arg, body)) = higher::for_loop(expr) {
5353
// A `for` loop lowers to:
5454
// ```rust
5555
// match ::std::iter::Iterator::next(&mut iter) {

clippy_lints/src/shadow.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc::hir::*;
55
use rustc::hir::intravisit::{Visitor, FnKind};
66
use std::ops::Deref;
77
use syntax::codemap::Span;
8-
use utils::{is_from_for_desugar, in_external_macro, snippet, span_lint_and_then};
8+
use utils::{higher, in_external_macro, snippet, span_lint_and_then};
99

1010
/// **What it does:** This lint checks for bindings that shadow other bindings already in scope, while just changing reference level or mutability.
1111
///
@@ -91,7 +91,7 @@ fn check_decl(cx: &LateContext, decl: &Decl, bindings: &mut Vec<(Name, Span)>) {
9191
if in_external_macro(cx, decl.span) {
9292
return;
9393
}
94-
if is_from_for_desugar(decl) {
94+
if higher::is_from_for_desugar(decl) {
9595
return;
9696
}
9797
if let DeclLocal(ref local) = decl.node {

clippy_lints/src/types.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use rustc::ty;
66
use std::cmp::Ordering;
77
use syntax::ast::{IntTy, UintTy, FloatTy};
88
use syntax::codemap::Span;
9-
use utils::{comparisons, in_external_macro, in_macro, is_from_for_desugar, match_def_path, snippet,
9+
use utils::{comparisons, higher, in_external_macro, in_macro, match_def_path, snippet,
1010
span_help_and_lint, span_lint};
1111
use utils::paths;
1212

@@ -106,7 +106,7 @@ fn check_let_unit(cx: &LateContext, decl: &Decl) {
106106
if in_external_macro(cx, decl.span) || in_macro(cx, local.pat.span) {
107107
return;
108108
}
109-
if is_from_for_desugar(decl) {
109+
if higher::is_from_for_desugar(decl) {
110110
return;
111111
}
112112
span_lint(cx,

clippy_lints/src/utils/higher.rs

+33
Original file line numberDiff line numberDiff line change
@@ -115,3 +115,36 @@ pub fn range(expr: &hir::Expr) -> Option<Range> {
115115
}
116116
}
117117

118+
/// Checks if a `let` decl is from a `for` loop desugaring.
119+
pub fn is_from_for_desugar(decl: &hir::Decl) -> bool {
120+
if_let_chain! {[
121+
let hir::DeclLocal(ref loc) = decl.node,
122+
let Some(ref expr) = loc.init,
123+
let hir::ExprMatch(_, _, hir::MatchSource::ForLoopDesugar) = expr.node,
124+
], {
125+
return true;
126+
}}
127+
false
128+
}
129+
130+
/// Recover the essential nodes of a desugared for loop:
131+
/// `for pat in arg { body }` becomes `(pat, arg, body)`.
132+
pub fn for_loop(expr: &hir::Expr) -> Option<(&hir::Pat, &hir::Expr, &hir::Expr)> {
133+
if_let_chain! {[
134+
let hir::ExprMatch(ref iterexpr, ref arms, _) = expr.node,
135+
let hir::ExprCall(_, ref iterargs) = iterexpr.node,
136+
iterargs.len() == 1 && arms.len() == 1 && arms[0].guard.is_none(),
137+
let hir::ExprLoop(ref block, _) = arms[0].body.node,
138+
block.stmts.is_empty(),
139+
let Some(ref loopexpr) = block.expr,
140+
let hir::ExprMatch(_, ref innerarms, hir::MatchSource::ForLoopDesugar) = loopexpr.node,
141+
innerarms.len() == 2 && innerarms[0].pats.len() == 1,
142+
let hir::PatKind::TupleStruct(_, ref somepats, _) = innerarms[0].pats[0].node,
143+
somepats.len() == 1
144+
], {
145+
return Some((&somepats[0],
146+
&iterargs[0],
147+
&innerarms[0].body));
148+
}}
149+
None
150+
}

clippy_lints/src/utils/mod.rs

+2-36
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ use syntax::ptr::P;
2121
pub mod cargo;
2222
pub mod comparisons;
2323
pub mod conf;
24-
pub mod higher;
2524
mod hir;
2625
pub mod paths;
2726
pub mod sugg;
@@ -82,6 +81,8 @@ macro_rules! if_let_chain {
8281
};
8382
}
8483

84+
pub mod higher;
85+
8586
/// Returns true if the two spans come from differing expansions (i.e. one is from a macro and one
8687
/// isn't).
8788
pub fn differing_macro_contexts(lhs: Span, rhs: Span) -> bool {
@@ -319,19 +320,6 @@ pub fn get_item_name(cx: &LateContext, expr: &Expr) -> Option<Name> {
319320
}
320321
}
321322

322-
/// Checks if a `let` decl is from a `for` loop desugaring.
323-
pub fn is_from_for_desugar(decl: &Decl) -> bool {
324-
if_let_chain! {[
325-
let DeclLocal(ref loc) = decl.node,
326-
let Some(ref expr) = loc.init,
327-
let ExprMatch(_, _, MatchSource::ForLoopDesugar) = expr.node
328-
], {
329-
return true;
330-
}}
331-
false
332-
}
333-
334-
335323
/// Convert a span to a code snippet if available, otherwise use default.
336324
///
337325
/// # Example
@@ -706,25 +694,3 @@ pub fn same_tys<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, a: ty::Ty<'tcx>, b: ty::Ty
706694
infcx.can_equate(&new_a, &new_b).is_ok()
707695
})
708696
}
709-
710-
/// Recover the essential nodes of a desugared for loop:
711-
/// `for pat in arg { body }` becomes `(pat, arg, body)`.
712-
pub fn recover_for_loop(expr: &Expr) -> Option<(&Pat, &Expr, &Expr)> {
713-
if_let_chain! {[
714-
let ExprMatch(ref iterexpr, ref arms, _) = expr.node,
715-
let ExprCall(_, ref iterargs) = iterexpr.node,
716-
iterargs.len() == 1 && arms.len() == 1 && arms[0].guard.is_none(),
717-
let ExprLoop(ref block, _) = arms[0].body.node,
718-
block.stmts.is_empty(),
719-
let Some(ref loopexpr) = block.expr,
720-
let ExprMatch(_, ref innerarms, MatchSource::ForLoopDesugar) = loopexpr.node,
721-
innerarms.len() == 2 && innerarms[0].pats.len() == 1,
722-
let PatKind::TupleStruct(_, ref somepats, _) = innerarms[0].pats[0].node,
723-
somepats.len() == 1
724-
], {
725-
return Some((&somepats[0],
726-
&iterargs[0],
727-
&innerarms[0].body));
728-
}}
729-
None
730-
}

clippy_lints/src/vec.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use rustc::ty::TypeVariants;
33
use rustc::hir::*;
44
use syntax::codemap::Span;
55
use syntax::ptr::P;
6-
use utils::{is_expn_of, match_path, paths, recover_for_loop, snippet, span_lint_and_then};
6+
use utils::{higher, is_expn_of, match_path, paths, snippet, span_lint_and_then};
77

88
/// **What it does:** This lint warns about using `&vec![..]` when using `&[..]` would be possible.
99
///
@@ -42,7 +42,7 @@ impl LateLintPass for Pass {
4242
}}
4343

4444
// search for `for _ in vec![…]`
45-
if let Some((_, arg, _)) = recover_for_loop(expr) {
45+
if let Some((_, arg, _)) = higher::for_loop(expr) {
4646
// report the error around the `vec!` not inside `<std macros>:`
4747
let span = cx.sess().codemap().source_callsite(arg.span);
4848
check_vec_macro(cx, arg, span);

0 commit comments

Comments
 (0)