# Change Log
All notable changes to this project will be documented in this file.
+## 0.0.93 — ?
+* [`option_map_unwrap_or`] and [`option_map_unwrap_or_else`] are now
+ allowed by default.
+* New lint: [`explicit_into_iter_loop`]
+
## 0.0.92 — 2016-09-30
* Rustup to *rustc 1.14.0-nightly (289f3a4ca 2016-09-29)*
[`eval_order_dependence`]: https://github.com/Manishearth/rust-clippy/wiki#eval_order_dependence
[`expl_impl_clone_on_copy`]: https://github.com/Manishearth/rust-clippy/wiki#expl_impl_clone_on_copy
[`explicit_counter_loop`]: https://github.com/Manishearth/rust-clippy/wiki#explicit_counter_loop
+[`explicit_into_iter_loop`]: https://github.com/Manishearth/rust-clippy/wiki#explicit_into_iter_loop
[`explicit_iter_loop`]: https://github.com/Manishearth/rust-clippy/wiki#explicit_iter_loop
[`extend_from_slice`]: https://github.com/Manishearth/rust-clippy/wiki#extend_from_slice
[`filter_map`]: https://github.com/Manishearth/rust-clippy/wiki#filter_map
## Lints
-There are 171 lints included in this crate:
+There are 172 lints included in this crate:
name | default | triggers on
---------------------------------------------------------------------------------------------------------------------|---------|----------------------------------------------------------------------------------------------------------------------------------
[eval_order_dependence](https://github.com/Manishearth/rust-clippy/wiki#eval_order_dependence) | warn | whether a variable read occurs before a write depends on sub-expression evaluation order
[expl_impl_clone_on_copy](https://github.com/Manishearth/rust-clippy/wiki#expl_impl_clone_on_copy) | warn | implementing `Clone` explicitly on `Copy` types
[explicit_counter_loop](https://github.com/Manishearth/rust-clippy/wiki#explicit_counter_loop) | warn | for-looping with an explicit counter when `_.enumerate()` would do
+[explicit_into_iter_loop](https://github.com/Manishearth/rust-clippy/wiki#explicit_into_iter_loop) | warn | for-looping over `_.into_iter()` when `_` would do
[explicit_iter_loop](https://github.com/Manishearth/rust-clippy/wiki#explicit_iter_loop) | warn | for-looping over `_.iter()` or `_.iter_mut()` when `&_` or `&mut _` would do
[extend_from_slice](https://github.com/Manishearth/rust-clippy/wiki#extend_from_slice) | warn | `.extend_from_slice(_)` is a faster way to extend a Vec by a slice
[filter_map](https://github.com/Manishearth/rust-clippy/wiki#filter_map) | allow | using combinations of `filter`, `map`, `filter_map` and `flat_map` which can usually be written as a single method call
[nonsensical_open_options](https://github.com/Manishearth/rust-clippy/wiki#nonsensical_open_options) | warn | nonsensical combination of options for opening a file
[not_unsafe_ptr_arg_deref](https://github.com/Manishearth/rust-clippy/wiki#not_unsafe_ptr_arg_deref) | warn | public functions dereferencing raw pointer arguments but not marked `unsafe`
[ok_expect](https://github.com/Manishearth/rust-clippy/wiki#ok_expect) | warn | using `ok().expect()`, which gives worse error messages than calling `expect` directly on the Result
-[option_map_unwrap_or](https://github.com/Manishearth/rust-clippy/wiki#option_map_unwrap_or) | warn | using `Option.map(f).unwrap_or(a)`, which is more succinctly expressed as `map_or(a, f)`
-[option_map_unwrap_or_else](https://github.com/Manishearth/rust-clippy/wiki#option_map_unwrap_or_else) | warn | using `Option.map(f).unwrap_or_else(g)`, which is more succinctly expressed as `map_or_else(g, f)`
+[option_map_unwrap_or](https://github.com/Manishearth/rust-clippy/wiki#option_map_unwrap_or) | allow | using `Option.map(f).unwrap_or(a)`, which is more succinctly expressed as `map_or(a, f)`
+[option_map_unwrap_or_else](https://github.com/Manishearth/rust-clippy/wiki#option_map_unwrap_or_else) | allow | using `Option.map(f).unwrap_or_else(g)`, which is more succinctly expressed as `map_or_else(g, f)`
[option_unwrap_used](https://github.com/Manishearth/rust-clippy/wiki#option_unwrap_used) | allow | using `Option.unwrap()`, which should at least get a better message using `expect()`
[or_fun_call](https://github.com/Manishearth/rust-clippy/wiki#or_fun_call) | warn | using any `*or` method with a function call, which suggests `*or_else`
[out_of_bounds_indexing](https://github.com/Manishearth/rust-clippy/wiki#out_of_bounds_indexing) | deny | out of bounds constant indexing
self.visit_expr(guard);
}
// make sure top level arm expressions aren't linted
- walk_expr(self, &*arm.body);
+ self.maybe_walk_expr(&*arm.body);
}
}
_ => walk_expr(self, e),
matches::SINGLE_MATCH_ELSE,
mem_forget::MEM_FORGET,
methods::FILTER_MAP,
+ methods::OPTION_MAP_UNWRAP_OR,
+ methods::OPTION_MAP_UNWRAP_OR_ELSE,
methods::OPTION_UNWRAP_USED,
methods::RESULT_UNWRAP_USED,
methods::WRONG_PUB_SELF_CONVENTION,
lifetimes::UNUSED_LIFETIMES,
loops::EMPTY_LOOP,
loops::EXPLICIT_COUNTER_LOOP,
+ loops::EXPLICIT_INTO_ITER_LOOP,
loops::EXPLICIT_ITER_LOOP,
loops::FOR_KV_MAP,
loops::FOR_LOOP_OVER_OPTION,
methods::ITER_NTH,
methods::NEW_RET_NO_SELF,
methods::OK_EXPECT,
- methods::OPTION_MAP_UNWRAP_OR,
- methods::OPTION_MAP_UNWRAP_OR_ELSE,
methods::OR_FUN_CALL,
methods::SEARCH_IS_SOME,
methods::SHOULD_IMPLEMENT_TRAIT,
"for-looping over `_.iter()` or `_.iter_mut()` when `&_` or `&mut _` would do"
}
+/// **What it does:** Checks for loops on `y.into_iter()` where `y` will do, and
+/// suggests the latter.
+///
+/// **Why is this bad?** Readability.
+///
+/// **Known problems:** None
+///
+/// **Example:**
+/// ```rust
+/// // with `y` a `Vec` or slice:
+/// for x in y.into_iter() { .. }
+/// ```
+declare_lint! {
+ pub EXPLICIT_INTO_ITER_LOOP,
+ Warn,
+ "for-looping over `_.into_iter()` when `_` would do"
+}
+
/// **What it does:** Checks for loops on `x.next()`.
///
/// **Why is this bad?** `next()` returns either `Some(value)` if there was a
fn get_lints(&self) -> LintArray {
lint_array!(NEEDLESS_RANGE_LOOP,
EXPLICIT_ITER_LOOP,
+ EXPLICIT_INTO_ITER_LOOP,
ITER_NEXT_LOOP,
FOR_LOOP_OVER_RESULT,
FOR_LOOP_OVER_OPTION,
object,
method_name));
}
+ } else if method_name.as_str() == "into_iter" && match_trait_method(cx, arg, &paths::INTO_ITERATOR) {
+ let object = snippet(cx, args[0].span, "_");
+ span_lint(cx,
+ EXPLICIT_INTO_ITER_LOOP,
+ expr.span,
+ &format!("it is more idiomatic to loop over `{}` instead of `{}.{}()`",
+ object,
+ object,
+ method_name));
+
} else if method_name.as_str() == "next" && match_trait_method(cx, arg, &paths::ITERATOR) {
span_lint(cx,
ITER_NEXT_LOOP,
/// ```
declare_lint! {
pub OPTION_MAP_UNWRAP_OR,
- Warn,
+ Allow,
"using `Option.map(f).unwrap_or(a)`, which is more succinctly expressed as \
`map_or(a, f)`"
}
/// ```
declare_lint! {
pub OPTION_MAP_UNWRAP_OR_ELSE,
- Warn,
+ Allow,
"using `Option.map(f).unwrap_or_else(g)`, which is more succinctly expressed as \
`map_or_else(g, f)`"
}
pub const HASHMAP: [&'static str; 5] = ["std", "collections", "hash", "map", "HashMap"];
pub const HASHMAP_ENTRY: [&'static str; 5] = ["std", "collections", "hash", "map", "Entry"];
pub const HASHSET: [&'static str; 5] = ["std", "collections", "hash", "set", "HashSet"];
+pub const INTO_ITERATOR: [&'static str; 4] = ["core", "iter", "traits", "IntoIterator"];
pub const IO_PRINT: [&'static str; 3] = ["std", "io", "_print"];
pub const ITERATOR: [&'static str; 4] = ["core", "iter", "iterator", "Iterator"];
pub const LINKED_LIST: [&'static str; 3] = ["collections", "linked_list", "LinkedList"];
8 => break,
9 => diverge(),
3 => (println!("moo"), diverge()), //~ ERROR sub-expression diverges
+ 10 => match 42 {
+ 99 => return,
+ _ => ((), panic!("boo")),
+ },
_ => (println!("boo"), break), //~ ERROR sub-expression diverges
};
}
}
}
-#[deny(needless_range_loop, explicit_iter_loop, iter_next_loop, reverse_range_loop, explicit_counter_loop)]
+#[deny(needless_range_loop, explicit_iter_loop, explicit_into_iter_loop, iter_next_loop, reverse_range_loop, explicit_counter_loop)]
#[deny(unused_collect)]
#[allow(linkedlist, shadow_unrelated, unnecessary_mut_passed, cyclomatic_complexity, similar_names)]
#[allow(many_single_char_names)]
for _v in vec.iter() { } //~ERROR it is more idiomatic to loop over `&vec`
for _v in vec.iter_mut() { } //~ERROR it is more idiomatic to loop over `&mut vec`
+
+ let out_vec = vec![1,2,3];
+ for _v in out_vec.into_iter() { } //~ERROR it is more idiomatic to loop over `out_vec` instead of `out_vec.into_iter()`
+
for _v in &vec { } // these are fine
for _v in &mut vec { } // these are fine