diff --git a/clippy_lints/src/default_trait_access.rs b/clippy_lints/src/default_trait_access.rs new file mode 100644 index 000000000000..d96ed8db7865 --- /dev/null +++ b/clippy_lints/src/default_trait_access.rs @@ -0,0 +1,68 @@ +use rustc::hir::*; +use rustc::lint::*; +use rustc::ty::TypeVariants; + +use crate::utils::{any_parent_is_automatically_derived, match_def_path, opt_def_id, paths, span_lint_and_sugg}; + + +/// **What it does:** Checks for literal calls to `Default::default()`. +/// +/// **Why is this bad?** It's more clear to the reader to use the name of the type whose default is +/// being gotten than the generic `Default`. +/// +/// **Known problems:** None. +/// +/// **Example:** +/// ```rust +/// // Bad +/// let s: String = Default::default(); +/// +/// // Good +/// let s = String::default(); +/// ``` +declare_clippy_lint! { + pub DEFAULT_TRAIT_ACCESS, + style, + "checks for literal calls to Default::default()" +} + +#[derive(Copy, Clone)] +pub struct DefaultTraitAccess; + +impl LintPass for DefaultTraitAccess { + fn get_lints(&self) -> LintArray { + lint_array!(DEFAULT_TRAIT_ACCESS) + } +} + +impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DefaultTraitAccess { + fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) { + if_chain! { + if let ExprCall(ref path, ..) = expr.node; + if !any_parent_is_automatically_derived(cx.tcx, expr.id); + if let ExprPath(ref qpath) = path.node; + if let Some(def_id) = opt_def_id(cx.tables.qpath_def(qpath, path.hir_id)); + if match_def_path(cx.tcx, def_id, &paths::DEFAULT_TRAIT_METHOD); + then { + match qpath { + QPath::Resolved(..) => { + // TODO: Work out a way to put "whatever the imported way of referencing + // this type in this file" rather than a fully-qualified type. + let expr_ty = cx.tables.expr_ty(expr); + if let TypeVariants::TyAdt(..) = expr_ty.sty { + let replacement = format!("{}::default()", expr_ty); + span_lint_and_sugg( + cx, + DEFAULT_TRAIT_ACCESS, + expr.span, + &format!("Calling {} is more clear than this expression", replacement), + "try", + replacement); + } + }, + QPath::TypeRelative(..) => {}, + } + } + } + } +} diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 31649c30db87..adf1020e07b8 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -111,6 +111,7 @@ pub mod collapsible_if; pub mod const_static_lifetime; pub mod copies; pub mod cyclomatic_complexity; +pub mod default_trait_access; pub mod derive; pub mod doc; pub mod double_comparison; @@ -430,6 +431,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) { reg.register_late_lint_pass(box neg_cmp_op_on_partial_ord::NoNegCompOpForPartialOrd); reg.register_late_lint_pass(box unwrap::Pass); reg.register_late_lint_pass(box duration_subsec::DurationSubsec); + reg.register_late_lint_pass(box default_trait_access::DefaultTraitAccess); reg.register_lint_group("clippy_restriction", vec![ @@ -517,6 +519,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) { copies::IF_SAME_THEN_ELSE, copies::IFS_SAME_COND, cyclomatic_complexity::CYCLOMATIC_COMPLEXITY, + default_trait_access::DEFAULT_TRAIT_ACCESS, derive::DERIVE_HASH_XOR_EQ, double_comparison::DOUBLE_COMPARISONS, double_parens::DOUBLE_PARENS, @@ -715,6 +718,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) { block_in_if_condition::BLOCK_IN_IF_CONDITION_STMT, collapsible_if::COLLAPSIBLE_IF, const_static_lifetime::CONST_STATIC_LIFETIME, + default_trait_access::DEFAULT_TRAIT_ACCESS, enum_variants::ENUM_VARIANT_NAMES, enum_variants::MODULE_INCEPTION, eq_op::OP_REF, diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index 02391cde61da..612fdfafe3bb 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -1129,3 +1129,17 @@ pub fn without_block_comments(lines: Vec<&str>) -> Vec<&str> { without } + +pub fn any_parent_is_automatically_derived(tcx: TyCtxt, node: NodeId) -> bool { + let map = &tcx.hir; + let mut prev_enclosing_node = None; + let mut enclosing_node = node; + while Some(enclosing_node) != prev_enclosing_node { + if is_automatically_derived(map.attrs(enclosing_node)) { + return true; + } + prev_enclosing_node = Some(enclosing_node); + enclosing_node = map.get_parent(enclosing_node); + } + false +} diff --git a/clippy_lints/src/utils/paths.rs b/clippy_lints/src/utils/paths.rs index 5af1a151c8ca..7606f4f8471e 100644 --- a/clippy_lints/src/utils/paths.rs +++ b/clippy_lints/src/utils/paths.rs @@ -24,6 +24,7 @@ pub const C_VOID: [&str; 4] = ["std", "os", "raw", "c_void"]; pub const C_VOID_LIBC: [&str; 2] = ["libc", "c_void"]; pub const DEBUG_FMT_METHOD: [&str; 4] = ["core", "fmt", "Debug", "fmt"]; pub const DEFAULT_TRAIT: [&str; 3] = ["core", "default", "Default"]; +pub const DEFAULT_TRAIT_METHOD: [&str; 4] = ["core", "default", "Default", "default"]; pub const DISPLAY_FMT_METHOD: [&str; 4] = ["core", "fmt", "Display", "fmt"]; pub const DOUBLE_ENDED_ITERATOR: [&str; 4] = ["core", "iter", "traits", "DoubleEndedIterator"]; pub const DROP: [&str; 3] = ["core", "mem", "drop"]; diff --git a/tests/ui/default_trait_access.rs b/tests/ui/default_trait_access.rs new file mode 100644 index 000000000000..675e64246fa9 --- /dev/null +++ b/tests/ui/default_trait_access.rs @@ -0,0 +1,100 @@ +#![warn(default_trait_access)] + +use std::default::Default as D2; +use std::string; +use std::default; + +fn main() { + let s1: String = Default::default(); + + let s2 = String::default(); + + let s3: String = D2::default(); + + let s4: String = std::default::Default::default(); + + let s5 = string::String::default(); + + let s6: String = default::Default::default(); + + let s7 = std::string::String::default(); + + let s8: String = DefaultFactory::make_t_badly(); + + let s9: String = DefaultFactory::make_t_nicely(); + + let s10 = DerivedDefault::default(); + + let s11: GenericDerivedDefault = Default::default(); + + let s12 = GenericDerivedDefault::::default(); + + let s13 = TupleDerivedDefault::default(); + + let s14: TupleDerivedDefault = Default::default(); + + let s15: ArrayDerivedDefault = Default::default(); + + let s16 = ArrayDerivedDefault::default(); + + let s17: TupleStructDerivedDefault = Default::default(); + + let s18 = TupleStructDerivedDefault::default(); + + println!( + "[{}] [{}] [{}] [{}] [{}] [{}] [{}] [{}] [{}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}]", + s1, + s2, + s3, + s4, + s5, + s6, + s7, + s8, + s9, + s10, + s11, + s12, + s13, + s14, + s15, + s16, + s17, + s18, + ); +} + +struct DefaultFactory; + +impl DefaultFactory { + pub fn make_t_badly() -> T { + Default::default() + } + + pub fn make_t_nicely() -> T { + T::default() + } +} + +#[derive(Debug, Default)] +struct DerivedDefault { + pub s: String, +} + +#[derive(Debug, Default)] +struct GenericDerivedDefault { + pub s: T, +} + +#[derive(Debug, Default)] +struct TupleDerivedDefault { + pub s: (String, String), +} + +#[derive(Debug, Default)] +struct ArrayDerivedDefault { + pub s: [String; 10], +} + +#[derive(Debug, Default)] +struct TupleStructDerivedDefault(String); diff --git a/tests/ui/default_trait_access.stderr b/tests/ui/default_trait_access.stderr new file mode 100644 index 000000000000..8bb4731035ae --- /dev/null +++ b/tests/ui/default_trait_access.stderr @@ -0,0 +1,52 @@ +error: Calling std::string::String::default() is more clear than this expression + --> $DIR/default_trait_access.rs:8:22 + | +8 | let s1: String = Default::default(); + | ^^^^^^^^^^^^^^^^^^ help: try: `std::string::String::default()` + | + = note: `-D default-trait-access` implied by `-D warnings` + +error: Calling std::string::String::default() is more clear than this expression + --> $DIR/default_trait_access.rs:12:22 + | +12 | let s3: String = D2::default(); + | ^^^^^^^^^^^^^ help: try: `std::string::String::default()` + +error: Calling std::string::String::default() is more clear than this expression + --> $DIR/default_trait_access.rs:14:22 + | +14 | let s4: String = std::default::Default::default(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::string::String::default()` + +error: Calling std::string::String::default() is more clear than this expression + --> $DIR/default_trait_access.rs:18:22 + | +18 | let s6: String = default::Default::default(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::string::String::default()` + +error: Calling GenericDerivedDefault::default() is more clear than this expression + --> $DIR/default_trait_access.rs:28:46 + | +28 | let s11: GenericDerivedDefault = Default::default(); + | ^^^^^^^^^^^^^^^^^^ help: try: `GenericDerivedDefault::default()` + +error: Calling TupleDerivedDefault::default() is more clear than this expression + --> $DIR/default_trait_access.rs:34:36 + | +34 | let s14: TupleDerivedDefault = Default::default(); + | ^^^^^^^^^^^^^^^^^^ help: try: `TupleDerivedDefault::default()` + +error: Calling ArrayDerivedDefault::default() is more clear than this expression + --> $DIR/default_trait_access.rs:36:36 + | +36 | let s15: ArrayDerivedDefault = Default::default(); + | ^^^^^^^^^^^^^^^^^^ help: try: `ArrayDerivedDefault::default()` + +error: Calling TupleStructDerivedDefault::default() is more clear than this expression + --> $DIR/default_trait_access.rs:40:42 + | +40 | let s17: TupleStructDerivedDefault = Default::default(); + | ^^^^^^^^^^^^^^^^^^ help: try: `TupleStructDerivedDefault::default()` + +error: aborting due to 8 previous errors + diff --git a/tests/ui/default_trait_access.stdout b/tests/ui/default_trait_access.stdout new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tests/ui/implicit_hasher.rs b/tests/ui/implicit_hasher.rs index c8b9f74bb32d..49df39ca71bc 100644 --- a/tests/ui/implicit_hasher.rs +++ b/tests/ui/implicit_hasher.rs @@ -30,12 +30,12 @@ impl Foo for HashMap { impl Foo for HashMap { fn make() -> (Self, Self) { - (HashMap::default(), HashMap::with_capacity_and_hasher(10, Default::default())) + (HashMap::default(), HashMap::with_capacity_and_hasher(10, S::default())) } } impl Foo for HashMap { fn make() -> (Self, Self) { - (HashMap::default(), HashMap::with_capacity_and_hasher(10, Default::default())) + (HashMap::default(), HashMap::with_capacity_and_hasher(10, S::default())) } } @@ -53,12 +53,12 @@ impl Foo for HashSet { impl Foo for HashSet { fn make() -> (Self, Self) { - (HashSet::default(), HashSet::with_capacity_and_hasher(10, Default::default())) + (HashSet::default(), HashSet::with_capacity_and_hasher(10, S::default())) } } impl Foo for HashSet { fn make() -> (Self, Self) { - (HashSet::default(), HashSet::with_capacity_and_hasher(10, Default::default())) + (HashSet::default(), HashSet::with_capacity_and_hasher(10, S::default())) } } diff --git a/tests/ui/methods.rs b/tests/ui/methods.rs index b04c008ba239..b42cc1f75b72 100644 --- a/tests/ui/methods.rs +++ b/tests/ui/methods.rs @@ -3,7 +3,8 @@ #![warn(clippy, clippy_pedantic, option_unwrap_used)] #![allow(blacklisted_name, unused, print_stdout, non_ascii_literal, new_without_default, - new_without_default_derive, missing_docs_in_private_items, needless_pass_by_value)] + new_without_default_derive, missing_docs_in_private_items, needless_pass_by_value, + default_trait_access)] use std::collections::BTreeMap; use std::collections::HashMap; diff --git a/tests/ui/methods.stderr b/tests/ui/methods.stderr index edf081aaa470..01ec0895fb00 100644 --- a/tests/ui/methods.stderr +++ b/tests/ui/methods.stderr @@ -1,528 +1,528 @@ error: unnecessary structure name repetition - --> $DIR/methods.rs:20:29 + --> $DIR/methods.rs:21:29 | -20 | pub fn add(self, other: T) -> T { self } +21 | pub fn add(self, other: T) -> T { self } | ^ help: use the applicable keyword: `Self` | = note: `-D use-self` implied by `-D warnings` error: unnecessary structure name repetition - --> $DIR/methods.rs:20:35 + --> $DIR/methods.rs:21:35 | -20 | pub fn add(self, other: T) -> T { self } +21 | pub fn add(self, other: T) -> T { self } | ^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/methods.rs:24:25 + --> $DIR/methods.rs:25:25 | -24 | fn eq(&self, other: T) -> bool { true } // no error, private function +25 | fn eq(&self, other: T) -> bool { true } // no error, private function | ^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/methods.rs:26:26 + --> $DIR/methods.rs:27:26 | -26 | fn sub(&self, other: T) -> &T { self } // no error, self is a ref +27 | fn sub(&self, other: T) -> &T { self } // no error, self is a ref | ^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/methods.rs:26:33 + --> $DIR/methods.rs:27:33 | -26 | fn sub(&self, other: T) -> &T { self } // no error, self is a ref +27 | fn sub(&self, other: T) -> &T { self } // no error, self is a ref | ^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/methods.rs:27:21 + --> $DIR/methods.rs:28:21 | -27 | fn div(self) -> T { self } // no error, different #arguments +28 | fn div(self) -> T { self } // no error, different #arguments | ^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/methods.rs:28:25 + --> $DIR/methods.rs:29:25 | -28 | fn rem(self, other: T) { } // no error, wrong return type +29 | fn rem(self, other: T) { } // no error, wrong return type | ^ help: use the applicable keyword: `Self` error: defining a method called `add` on this type; consider implementing the `std::ops::Add` trait or choosing a less ambiguous name - --> $DIR/methods.rs:20:5 + --> $DIR/methods.rs:21:5 | -20 | pub fn add(self, other: T) -> T { self } +21 | pub fn add(self, other: T) -> T { self } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `-D should-implement-trait` implied by `-D warnings` error: methods called `into_*` usually take self by value; consider choosing a less ambiguous name - --> $DIR/methods.rs:31:17 + --> $DIR/methods.rs:32:17 | -31 | fn into_u16(&self) -> u16 { 0 } +32 | fn into_u16(&self) -> u16 { 0 } | ^^^^^ | = note: `-D wrong-self-convention` implied by `-D warnings` error: methods called `to_*` usually take self by reference; consider choosing a less ambiguous name - --> $DIR/methods.rs:33:21 + --> $DIR/methods.rs:34:21 | -33 | fn to_something(self) -> u32 { 0 } +34 | fn to_something(self) -> u32 { 0 } | ^^^^ error: methods called `new` usually take no self; consider choosing a less ambiguous name - --> $DIR/methods.rs:35:12 + --> $DIR/methods.rs:36:12 | -35 | fn new(self) {} +36 | fn new(self) {} | ^^^^ error: methods called `new` usually return `Self` - --> $DIR/methods.rs:35:5 + --> $DIR/methods.rs:36:5 | -35 | fn new(self) {} +36 | fn new(self) {} | ^^^^^^^^^^^^^^^ | = note: `-D new-ret-no-self` implied by `-D warnings` error: unnecessary structure name repetition - --> $DIR/methods.rs:79:24 + --> $DIR/methods.rs:80:24 | -79 | fn new() -> Option> { None } +80 | fn new() -> Option> { None } | ^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/methods.rs:83:19 + --> $DIR/methods.rs:84:19 | -83 | type Output = T; +84 | type Output = T; | ^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/methods.rs:84:25 + --> $DIR/methods.rs:85:25 | -84 | fn mul(self, other: T) -> T { self } // no error, obviously +85 | fn mul(self, other: T) -> T { self } // no error, obviously | ^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/methods.rs:84:31 + --> $DIR/methods.rs:85:31 | -84 | fn mul(self, other: T) -> T { self } // no error, obviously +85 | fn mul(self, other: T) -> T { self } // no error, obviously | ^ help: use the applicable keyword: `Self` error: called `map(f).unwrap_or(a)` on an Option value. This can be done more directly by calling `map_or(a, f)` instead - --> $DIR/methods.rs:103:13 + --> $DIR/methods.rs:104:13 | -103 | let _ = opt.map(|x| x + 1) +104 | let _ = opt.map(|x| x + 1) | _____________^ -104 | | -105 | | .unwrap_or(0); // should lint even though this call is on a separate line +105 | | +106 | | .unwrap_or(0); // should lint even though this call is on a separate line | |____________________________^ | = note: `-D option-map-unwrap-or` implied by `-D warnings` = note: replace `map(|x| x + 1).unwrap_or(0)` with `map_or(0, |x| x + 1)` error: called `map(f).unwrap_or(a)` on an Option value. This can be done more directly by calling `map_or(a, f)` instead - --> $DIR/methods.rs:107:13 + --> $DIR/methods.rs:108:13 | -107 | let _ = opt.map(|x| { +108 | let _ = opt.map(|x| { | _____________^ -108 | | x + 1 -109 | | } -110 | | ).unwrap_or(0); +109 | | x + 1 +110 | | } +111 | | ).unwrap_or(0); | |____________________________^ error: called `map(f).unwrap_or(a)` on an Option value. This can be done more directly by calling `map_or(a, f)` instead - --> $DIR/methods.rs:111:13 + --> $DIR/methods.rs:112:13 | -111 | let _ = opt.map(|x| x + 1) +112 | let _ = opt.map(|x| x + 1) | _____________^ -112 | | .unwrap_or({ -113 | | 0 -114 | | }); +113 | | .unwrap_or({ +114 | | 0 +115 | | }); | |__________________^ error: called `map(f).unwrap_or(None)` on an Option value. This can be done more directly by calling `and_then(f)` instead - --> $DIR/methods.rs:116:13 + --> $DIR/methods.rs:117:13 | -116 | let _ = opt.map(|x| Some(x + 1)).unwrap_or(None); +117 | let _ = opt.map(|x| Some(x + 1)).unwrap_or(None); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: replace `map(|x| Some(x + 1)).unwrap_or(None)` with `and_then(|x| Some(x + 1))` error: called `map(f).unwrap_or(None)` on an Option value. This can be done more directly by calling `and_then(f)` instead - --> $DIR/methods.rs:118:13 + --> $DIR/methods.rs:119:13 | -118 | let _ = opt.map(|x| { +119 | let _ = opt.map(|x| { | _____________^ -119 | | Some(x + 1) -120 | | } -121 | | ).unwrap_or(None); +120 | | Some(x + 1) +121 | | } +122 | | ).unwrap_or(None); | |_____________________^ error: called `map(f).unwrap_or(None)` on an Option value. This can be done more directly by calling `and_then(f)` instead - --> $DIR/methods.rs:122:13 + --> $DIR/methods.rs:123:13 | -122 | let _ = opt +123 | let _ = opt | _____________^ -123 | | .map(|x| Some(x + 1)) -124 | | .unwrap_or(None); +124 | | .map(|x| Some(x + 1)) +125 | | .unwrap_or(None); | |________________________^ | = note: replace `map(|x| Some(x + 1)).unwrap_or(None)` with `and_then(|x| Some(x + 1))` error: called `map(f).unwrap_or_else(g)` on an Option value. This can be done more directly by calling `map_or_else(g, f)` instead - --> $DIR/methods.rs:130:13 + --> $DIR/methods.rs:131:13 | -130 | let _ = opt.map(|x| x + 1) +131 | let _ = opt.map(|x| x + 1) | _____________^ -131 | | -132 | | .unwrap_or_else(|| 0); // should lint even though this call is on a separate line +132 | | +133 | | .unwrap_or_else(|| 0); // should lint even though this call is on a separate line | |____________________________________^ | = note: `-D option-map-unwrap-or-else` implied by `-D warnings` = note: replace `map(|x| x + 1).unwrap_or_else(|| 0)` with `map_or_else(|| 0, |x| x + 1)` error: called `map(f).unwrap_or_else(g)` on an Option value. This can be done more directly by calling `map_or_else(g, f)` instead - --> $DIR/methods.rs:134:13 + --> $DIR/methods.rs:135:13 | -134 | let _ = opt.map(|x| { +135 | let _ = opt.map(|x| { | _____________^ -135 | | x + 1 -136 | | } -137 | | ).unwrap_or_else(|| 0); +136 | | x + 1 +137 | | } +138 | | ).unwrap_or_else(|| 0); | |____________________________________^ error: called `map(f).unwrap_or_else(g)` on an Option value. This can be done more directly by calling `map_or_else(g, f)` instead - --> $DIR/methods.rs:138:13 + --> $DIR/methods.rs:139:13 | -138 | let _ = opt.map(|x| x + 1) +139 | let _ = opt.map(|x| x + 1) | _____________^ -139 | | .unwrap_or_else(|| -140 | | 0 -141 | | ); +140 | | .unwrap_or_else(|| +141 | | 0 +142 | | ); | |_________________^ error: called `map_or(None, f)` on an Option value. This can be done more directly by calling `and_then(f)` instead - --> $DIR/methods.rs:147:13 + --> $DIR/methods.rs:148:13 | -147 | let _ = opt.map_or(None, |x| Some(x + 1)); +148 | let _ = opt.map_or(None, |x| Some(x + 1)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using and_then instead: `opt.and_then(|x| Some(x + 1))` | = note: `-D option-map-or-none` implied by `-D warnings` error: called `map_or(None, f)` on an Option value. This can be done more directly by calling `and_then(f)` instead - --> $DIR/methods.rs:149:13 + --> $DIR/methods.rs:150:13 | -149 | let _ = opt.map_or(None, |x| { +150 | let _ = opt.map_or(None, |x| { | _____________^ -150 | | Some(x + 1) -151 | | } -152 | | ); +151 | | Some(x + 1) +152 | | } +153 | | ); | |_________________^ help: try using and_then instead | -149 | let _ = opt.and_then(|x| { -150 | Some(x + 1) -151 | }); +150 | let _ = opt.and_then(|x| { +151 | Some(x + 1) +152 | }); | error: called `map(f).unwrap_or_else(g)` on a Result value. This can be done more directly by calling `ok().map_or_else(g, f)` instead - --> $DIR/methods.rs:162:13 + --> $DIR/methods.rs:163:13 | -162 | let _ = res.map(|x| x + 1) +163 | let _ = res.map(|x| x + 1) | _____________^ -163 | | -164 | | .unwrap_or_else(|e| 0); // should lint even though this call is on a separate line +164 | | +165 | | .unwrap_or_else(|e| 0); // should lint even though this call is on a separate line | |_____________________________________^ | = note: `-D result-map-unwrap-or-else` implied by `-D warnings` = note: replace `map(|x| x + 1).unwrap_or_else(|e| 0)` with `ok().map_or_else(|e| 0, |x| x + 1)` error: called `map(f).unwrap_or_else(g)` on a Result value. This can be done more directly by calling `ok().map_or_else(g, f)` instead - --> $DIR/methods.rs:166:13 + --> $DIR/methods.rs:167:13 | -166 | let _ = res.map(|x| { +167 | let _ = res.map(|x| { | _____________^ -167 | | x + 1 -168 | | } -169 | | ).unwrap_or_else(|e| 0); +168 | | x + 1 +169 | | } +170 | | ).unwrap_or_else(|e| 0); | |_____________________________________^ error: called `map(f).unwrap_or_else(g)` on a Result value. This can be done more directly by calling `ok().map_or_else(g, f)` instead - --> $DIR/methods.rs:170:13 + --> $DIR/methods.rs:171:13 | -170 | let _ = res.map(|x| x + 1) +171 | let _ = res.map(|x| x + 1) | _____________^ -171 | | .unwrap_or_else(|e| -172 | | 0 -173 | | ); +172 | | .unwrap_or_else(|e| +173 | | 0 +174 | | ); | |_________________^ error: unnecessary structure name repetition - --> $DIR/methods.rs:199:24 + --> $DIR/methods.rs:200:24 | -199 | fn filter(self) -> IteratorFalsePositives { +200 | fn filter(self) -> IteratorFalsePositives { | ^^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/methods.rs:203:22 + --> $DIR/methods.rs:204:22 | -203 | fn next(self) -> IteratorFalsePositives { +204 | fn next(self) -> IteratorFalsePositives { | ^^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/methods.rs:223:32 + --> $DIR/methods.rs:224:32 | -223 | fn skip(self, _: usize) -> IteratorFalsePositives { +224 | fn skip(self, _: usize) -> IteratorFalsePositives { | ^^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self` error: called `filter(p).next()` on an `Iterator`. This is more succinctly expressed by calling `.find(p)` instead. - --> $DIR/methods.rs:233:13 + --> $DIR/methods.rs:234:13 | -233 | let _ = v.iter().filter(|&x| *x < 0).next(); +234 | let _ = v.iter().filter(|&x| *x < 0).next(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `-D filter-next` implied by `-D warnings` = note: replace `filter(|&x| *x < 0).next()` with `find(|&x| *x < 0)` error: called `filter(p).next()` on an `Iterator`. This is more succinctly expressed by calling `.find(p)` instead. - --> $DIR/methods.rs:236:13 + --> $DIR/methods.rs:237:13 | -236 | let _ = v.iter().filter(|&x| { +237 | let _ = v.iter().filter(|&x| { | _____________^ -237 | | *x < 0 -238 | | } -239 | | ).next(); +238 | | *x < 0 +239 | | } +240 | | ).next(); | |___________________________^ error: called `is_some()` after searching an `Iterator` with find. This is more succinctly expressed by calling `any()`. - --> $DIR/methods.rs:251:13 + --> $DIR/methods.rs:252:13 | -251 | let _ = v.iter().find(|&x| *x < 0).is_some(); +252 | let _ = v.iter().find(|&x| *x < 0).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `-D search-is-some` implied by `-D warnings` = note: replace `find(|&x| *x < 0).is_some()` with `any(|&x| *x < 0)` error: called `is_some()` after searching an `Iterator` with find. This is more succinctly expressed by calling `any()`. - --> $DIR/methods.rs:254:13 + --> $DIR/methods.rs:255:13 | -254 | let _ = v.iter().find(|&x| { +255 | let _ = v.iter().find(|&x| { | _____________^ -255 | | *x < 0 -256 | | } -257 | | ).is_some(); +256 | | *x < 0 +257 | | } +258 | | ).is_some(); | |______________________________^ error: called `is_some()` after searching an `Iterator` with position. This is more succinctly expressed by calling `any()`. - --> $DIR/methods.rs:260:13 + --> $DIR/methods.rs:261:13 | -260 | let _ = v.iter().position(|&x| x < 0).is_some(); +261 | let _ = v.iter().position(|&x| x < 0).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: replace `position(|&x| x < 0).is_some()` with `any(|&x| x < 0)` error: called `is_some()` after searching an `Iterator` with position. This is more succinctly expressed by calling `any()`. - --> $DIR/methods.rs:263:13 + --> $DIR/methods.rs:264:13 | -263 | let _ = v.iter().position(|&x| { +264 | let _ = v.iter().position(|&x| { | _____________^ -264 | | x < 0 -265 | | } -266 | | ).is_some(); +265 | | x < 0 +266 | | } +267 | | ).is_some(); | |______________________________^ error: called `is_some()` after searching an `Iterator` with rposition. This is more succinctly expressed by calling `any()`. - --> $DIR/methods.rs:269:13 + --> $DIR/methods.rs:270:13 | -269 | let _ = v.iter().rposition(|&x| x < 0).is_some(); +270 | let _ = v.iter().rposition(|&x| x < 0).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: replace `rposition(|&x| x < 0).is_some()` with `any(|&x| x < 0)` error: called `is_some()` after searching an `Iterator` with rposition. This is more succinctly expressed by calling `any()`. - --> $DIR/methods.rs:272:13 + --> $DIR/methods.rs:273:13 | -272 | let _ = v.iter().rposition(|&x| { +273 | let _ = v.iter().rposition(|&x| { | _____________^ -273 | | x < 0 -274 | | } -275 | | ).is_some(); +274 | | x < 0 +275 | | } +276 | | ).is_some(); | |______________________________^ error: unnecessary structure name repetition - --> $DIR/methods.rs:289:21 + --> $DIR/methods.rs:290:21 | -289 | fn new() -> Foo { Foo } +290 | fn new() -> Foo { Foo } | ^^^ help: use the applicable keyword: `Self` error: use of `unwrap_or` followed by a function call - --> $DIR/methods.rs:307:22 + --> $DIR/methods.rs:308:22 | -307 | with_constructor.unwrap_or(make()); +308 | with_constructor.unwrap_or(make()); | ^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(make)` | = note: `-D or-fun-call` implied by `-D warnings` error: use of `unwrap_or` followed by a call to `new` - --> $DIR/methods.rs:310:5 + --> $DIR/methods.rs:311:5 | -310 | with_new.unwrap_or(Vec::new()); +311 | with_new.unwrap_or(Vec::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `with_new.unwrap_or_default()` error: use of `unwrap_or` followed by a function call - --> $DIR/methods.rs:313:21 + --> $DIR/methods.rs:314:21 | -313 | with_const_args.unwrap_or(Vec::with_capacity(12)); +314 | with_const_args.unwrap_or(Vec::with_capacity(12)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| Vec::with_capacity(12))` error: use of `unwrap_or` followed by a function call - --> $DIR/methods.rs:316:14 + --> $DIR/methods.rs:317:14 | -316 | with_err.unwrap_or(make()); +317 | with_err.unwrap_or(make()); | ^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|_| make())` error: use of `unwrap_or` followed by a function call - --> $DIR/methods.rs:319:19 + --> $DIR/methods.rs:320:19 | -319 | with_err_args.unwrap_or(Vec::with_capacity(12)); +320 | with_err_args.unwrap_or(Vec::with_capacity(12)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|_| Vec::with_capacity(12))` error: use of `unwrap_or` followed by a call to `default` - --> $DIR/methods.rs:322:5 + --> $DIR/methods.rs:323:5 | -322 | with_default_trait.unwrap_or(Default::default()); +323 | with_default_trait.unwrap_or(Default::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `with_default_trait.unwrap_or_default()` error: use of `unwrap_or` followed by a call to `default` - --> $DIR/methods.rs:325:5 + --> $DIR/methods.rs:326:5 | -325 | with_default_type.unwrap_or(u64::default()); +326 | with_default_type.unwrap_or(u64::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `with_default_type.unwrap_or_default()` error: use of `unwrap_or` followed by a function call - --> $DIR/methods.rs:328:14 + --> $DIR/methods.rs:329:14 | -328 | with_vec.unwrap_or(vec![]); +329 | with_vec.unwrap_or(vec![]); | ^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| < [ _ ] > :: into_vec ( box [ $ ( $ x ) , * ] ))` error: use of `unwrap_or` followed by a function call - --> $DIR/methods.rs:333:21 + --> $DIR/methods.rs:334:21 | -333 | without_default.unwrap_or(Foo::new()); +334 | without_default.unwrap_or(Foo::new()); | ^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(Foo::new)` error: use of `or_insert` followed by a function call - --> $DIR/methods.rs:336:19 + --> $DIR/methods.rs:337:19 | -336 | map.entry(42).or_insert(String::new()); +337 | map.entry(42).or_insert(String::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `or_insert_with(String::new)` error: use of `or_insert` followed by a function call - --> $DIR/methods.rs:339:21 + --> $DIR/methods.rs:340:21 | -339 | btree.entry(42).or_insert(String::new()); +340 | btree.entry(42).or_insert(String::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `or_insert_with(String::new)` error: use of `unwrap_or` followed by a function call - --> $DIR/methods.rs:342:21 + --> $DIR/methods.rs:343:21 | -342 | let _ = stringy.unwrap_or("".to_owned()); +343 | let _ = stringy.unwrap_or("".to_owned()); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| "".to_owned())` error: use of `expect` followed by a function call - --> $DIR/methods.rs:365:26 + --> $DIR/methods.rs:366:26 | -365 | with_none_and_format.expect(&format!("Error {}: fake error", error_code)); +366 | with_none_and_format.expect(&format!("Error {}: fake error", error_code)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| panic!("Error {}: fake error", error_code))` | = note: `-D expect-fun-call` implied by `-D warnings` error: use of `expect` followed by a function call - --> $DIR/methods.rs:368:26 + --> $DIR/methods.rs:369:26 | -368 | with_none_and_as_str.expect(format!("Error {}: fake error", error_code).as_str()); +369 | with_none_and_as_str.expect(format!("Error {}: fake error", error_code).as_str()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| panic!(format!("Error {}: fake error", error_code).as_str()))` error: use of `expect` followed by a function call - --> $DIR/methods.rs:378:25 + --> $DIR/methods.rs:379:25 | -378 | with_err_and_format.expect(&format!("Error {}: fake error", error_code)); +379 | with_err_and_format.expect(&format!("Error {}: fake error", error_code)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|_| panic!("Error {}: fake error", error_code))` error: use of `expect` followed by a function call - --> $DIR/methods.rs:381:25 + --> $DIR/methods.rs:382:25 | -381 | with_err_and_as_str.expect(format!("Error {}: fake error", error_code).as_str()); +382 | with_err_and_as_str.expect(format!("Error {}: fake error", error_code).as_str()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|_| panic!(format!("Error {}: fake error", error_code).as_str()))` error: called `.iter().nth()` on a Vec. Calling `.get()` is both faster and more readable - --> $DIR/methods.rs:401:23 + --> $DIR/methods.rs:402:23 | -401 | let bad_vec = some_vec.iter().nth(3); +402 | let bad_vec = some_vec.iter().nth(3); | ^^^^^^^^^^^^^^^^^^^^^^ | = note: `-D iter-nth` implied by `-D warnings` error: called `.iter().nth()` on a slice. Calling `.get()` is both faster and more readable - --> $DIR/methods.rs:402:26 + --> $DIR/methods.rs:403:26 | -402 | let bad_slice = &some_vec[..].iter().nth(3); +403 | let bad_slice = &some_vec[..].iter().nth(3); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: called `.iter().nth()` on a slice. Calling `.get()` is both faster and more readable - --> $DIR/methods.rs:403:31 + --> $DIR/methods.rs:404:31 | -403 | let bad_boxed_slice = boxed_slice.iter().nth(3); +404 | let bad_boxed_slice = boxed_slice.iter().nth(3); | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: called `.iter().nth()` on a VecDeque. Calling `.get()` is both faster and more readable - --> $DIR/methods.rs:404:29 + --> $DIR/methods.rs:405:29 | -404 | let bad_vec_deque = some_vec_deque.iter().nth(3); +405 | let bad_vec_deque = some_vec_deque.iter().nth(3); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: called `.iter_mut().nth()` on a Vec. Calling `.get_mut()` is both faster and more readable - --> $DIR/methods.rs:409:23 + --> $DIR/methods.rs:410:23 | -409 | let bad_vec = some_vec.iter_mut().nth(3); +410 | let bad_vec = some_vec.iter_mut().nth(3); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: called `.iter_mut().nth()` on a slice. Calling `.get_mut()` is both faster and more readable - --> $DIR/methods.rs:412:26 + --> $DIR/methods.rs:413:26 | -412 | let bad_slice = &some_vec[..].iter_mut().nth(3); +413 | let bad_slice = &some_vec[..].iter_mut().nth(3); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: called `.iter_mut().nth()` on a VecDeque. Calling `.get_mut()` is both faster and more readable - --> $DIR/methods.rs:415:29 + --> $DIR/methods.rs:416:29 | -415 | let bad_vec_deque = some_vec_deque.iter_mut().nth(3); +416 | let bad_vec_deque = some_vec_deque.iter_mut().nth(3); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: called `skip(x).next()` on an iterator. This is more succinctly expressed by calling `nth(x)` - --> $DIR/methods.rs:427:13 + --> $DIR/methods.rs:428:13 | -427 | let _ = some_vec.iter().skip(42).next(); +428 | let _ = some_vec.iter().skip(42).next(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `-D iter-skip-next` implied by `-D warnings` error: called `skip(x).next()` on an iterator. This is more succinctly expressed by calling `nth(x)` - --> $DIR/methods.rs:428:13 + --> $DIR/methods.rs:429:13 | -428 | let _ = some_vec.iter().cycle().skip(42).next(); +429 | let _ = some_vec.iter().cycle().skip(42).next(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: called `skip(x).next()` on an iterator. This is more succinctly expressed by calling `nth(x)` - --> $DIR/methods.rs:429:13 + --> $DIR/methods.rs:430:13 | -429 | let _ = (1..10).skip(10).next(); +430 | let _ = (1..10).skip(10).next(); | ^^^^^^^^^^^^^^^^^^^^^^^ error: called `skip(x).next()` on an iterator. This is more succinctly expressed by calling `nth(x)` - --> $DIR/methods.rs:430:14 + --> $DIR/methods.rs:431:14 | -430 | let _ = &some_vec[..].iter().skip(3).next(); +431 | let _ = &some_vec[..].iter().skip(3).next(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used unwrap() on an Option value. If you don't want to handle the None case gracefully, consider using expect() to provide a better panic message - --> $DIR/methods.rs:439:13 + --> $DIR/methods.rs:440:13 | -439 | let _ = opt.unwrap(); +440 | let _ = opt.unwrap(); | ^^^^^^^^^^^^ | = note: `-D option-unwrap-used` implied by `-D warnings`