From d318ced660bee68bac0c2c2810b45d747f673cee Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sat, 9 Sep 2017 21:51:54 -0400 Subject: [PATCH] Add CLONE_ON_REF_PTR lint Closes issue #1645 --- clippy_lints/src/consts.rs | 2 +- clippy_lints/src/methods.rs | 48 +++ clippy_lints/src/utils/paths.rs | 4 + tests/ui/methods.rs | 24 ++ tests/ui/methods.stderr | 518 +++++++++++++++++--------------- 5 files changed, 349 insertions(+), 247 deletions(-) diff --git a/clippy_lints/src/consts.rs b/clippy_lints/src/consts.rs index d50cb05576f..b1bd6b06ee4 100644 --- a/clippy_lints/src/consts.rs +++ b/clippy_lints/src/consts.rs @@ -171,7 +171,7 @@ pub fn lit_to_constant<'a, 'tcx>(lit: &LitKind, tcx: TyCtxt<'a, 'tcx, 'tcx>, mut match *lit { LitKind::Str(ref is, style) => Constant::Str(is.to_string(), style), LitKind::Byte(b) => Constant::Int(ConstInt::U8(b)), - LitKind::ByteStr(ref s) => Constant::Binary(s.clone()), + LitKind::ByteStr(ref s) => Constant::Binary(Rc::clone(s)), LitKind::Char(c) => Constant::Char(c), LitKind::Int(n, hint) => match (&ty.sty, hint) { (&ty::TyInt(ity), _) | (_, Signed(ity)) => { diff --git a/clippy_lints/src/methods.rs b/clippy_lints/src/methods.rs index 74719d006d0..90208369caa 100644 --- a/clippy_lints/src/methods.rs +++ b/clippy_lints/src/methods.rs @@ -310,6 +310,24 @@ declare_lint! { "using `clone` on a `Copy` type" } +/// **What it does:** Checks for usage of `.clone()` on a ref-counted pointer, +/// (Rc, Arc, rc::Weak, or sync::Weak), and suggests calling Clone on +/// the corresponding trait instead. +/// +/// **Why is this bad?**: Calling '.clone()' on an Rc, Arc, or Weak +/// can obscure the fact that only the pointer is being cloned, not the underlying +/// data. +/// +/// **Example:** +/// ```rust +/// x.clone() +/// ``` +declare_lint! { + pub CLONE_ON_REF_PTR, + Warn, + "using 'clone' on a ref-counted pointer" +} + /// **What it does:** Checks for usage of `.clone()` on an `&&T`. /// /// **Why is this bad?** Cloning an `&&T` copies the inner `&T`, instead of @@ -539,6 +557,7 @@ impl LintPass for Pass { OR_FUN_CALL, CHARS_NEXT_CMP, CLONE_ON_COPY, + CLONE_ON_REF_PTR, CLONE_DOUBLE_REF, NEW_RET_NO_SELF, SINGLE_CHAR_PATTERN, @@ -615,6 +634,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { let self_ty = cx.tables.expr_ty_adjusted(&args[0]); if args.len() == 1 && method_call.name == "clone" { lint_clone_on_copy(cx, expr, &args[0], self_ty); + lint_clone_on_ref_ptr(cx, expr, &args[0]); } match self_ty.sty { @@ -853,6 +873,34 @@ fn lint_clone_on_copy(cx: &LateContext, expr: &hir::Expr, arg: &hir::Expr, arg_t } } +fn lint_clone_on_ref_ptr(cx: &LateContext, expr: &hir::Expr, arg: &hir::Expr) { + let (obj_ty, _) = walk_ptrs_ty_depth(cx.tables.expr_ty(arg)); + + let caller_type = if match_type(cx, obj_ty, &paths::RC) { + "Rc" + } else if match_type(cx, obj_ty, &paths::ARC) { + "Arc" + } else if match_type(cx, obj_ty, &paths::WEAK_RC) || match_type(cx, obj_ty, &paths::WEAK_ARC) { + "Weak" + } else { + return; + }; + + span_lint_and_sugg( + cx, + CLONE_ON_REF_PTR, + expr.span, + "using '.clone()' on a ref-counted pointer", + "try this", + format!("{}::clone(&{})", + caller_type, + snippet(cx, arg.span, "_") + ) + ); + +} + + fn lint_string_extend(cx: &LateContext, expr: &hir::Expr, args: &[hir::Expr]) { let arg = &args[1]; if let Some(arglists) = method_chain_args(arg, &["chars"]) { diff --git a/clippy_lints/src/utils/paths.rs b/clippy_lints/src/utils/paths.rs index 9057920098e..d18a5af59e3 100644 --- a/clippy_lints/src/utils/paths.rs +++ b/clippy_lints/src/utils/paths.rs @@ -2,6 +2,7 @@ //! about. pub const ANY_TRAIT: [&'static str; 3] = ["std", "any", "Any"]; +pub const ARC: [&'static str; 3] = ["alloc", "arc", "Arc"]; pub const ASMUT_TRAIT: [&'static str; 3] = ["core", "convert", "AsMut"]; pub const ASREF_TRAIT: [&'static str; 3] = ["core", "convert", "AsRef"]; pub const BEGIN_PANIC: [&'static str; 3] = ["std", "panicking", "begin_panic"]; @@ -58,6 +59,7 @@ pub const RANGE_TO: [&'static str; 3] = ["core", "ops", "RangeTo"]; pub const RANGE_TO_INCLUSIVE: [&'static str; 3] = ["core", "ops", "RangeToInclusive"]; pub const RANGE_TO_INCLUSIVE_STD: [&'static str; 3] = ["std", "ops", "RangeToInclusive"]; pub const RANGE_TO_STD: [&'static str; 3] = ["std", "ops", "RangeTo"]; +pub const RC: [&'static str; 3] = ["alloc", "rc", "Rc"]; pub const REGEX: [&'static str; 3] = ["regex", "re_unicode", "Regex"]; pub const REGEX_BUILDER_NEW: [&'static str; 5] = ["regex", "re_builder", "unicode", "RegexBuilder", "new"]; pub const REGEX_BYTES: [&'static str; 3] = ["regex", "re_bytes", "Regex"]; @@ -81,3 +83,5 @@ pub const TRY_INTO_RESULT: [&'static str; 4] = ["std", "ops", "Try", "into_resul pub const VEC: [&'static str; 3] = ["alloc", "vec", "Vec"]; pub const VEC_DEQUE: [&'static str; 3] = ["alloc", "vec_deque", "VecDeque"]; pub const VEC_FROM_ELEM: [&'static str; 3] = ["alloc", "vec", "from_elem"]; +pub const WEAK_ARC: [&'static str; 3] = ["alloc", "arc", "Weak"]; +pub const WEAK_RC: [&'static str; 3] = ["alloc", "rc", "Weak"]; diff --git a/tests/ui/methods.rs b/tests/ui/methods.rs index a9716d4e7b4..3bbaff29c98 100644 --- a/tests/ui/methods.rs +++ b/tests/ui/methods.rs @@ -11,6 +11,8 @@ use std::collections::HashSet; use std::collections::VecDeque; use std::ops::Mul; use std::iter::FromIterator; +use std::rc::{self, Rc}; +use std::sync::{self, Arc}; struct T; @@ -456,6 +458,28 @@ fn clone_on_copy() { (&42).clone(); } +fn clone_on_ref_ptr() { + let rc = Rc::new(true); + let arc = Arc::new(true); + + let rcweak = Rc::downgrade(&rc); + let arc_weak = Arc::downgrade(&arc); + + rc.clone(); + Rc::clone(&rc); + + arc.clone(); + Arc::clone(&arc); + + rcweak.clone(); + rc::Weak::clone(&rcweak); + + arc_weak.clone(); + sync::Weak::clone(&arc_weak); + + +} + fn clone_on_copy_generic(t: T) { t.clone(); diff --git a/tests/ui/methods.stderr b/tests/ui/methods.stderr index 8570dccd0fe..e22fdc116c1 100644 --- a/tests/ui/methods.stderr +++ b/tests/ui/methods.stderr @@ -1,716 +1,742 @@ error: unnecessary structure name repetition - --> $DIR/methods.rs:18:25 + --> $DIR/methods.rs:20:25 | -18 | fn add(self, other: T) -> T { self } +20 | 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:18:31 + --> $DIR/methods.rs:20:31 | -18 | fn add(self, other: T) -> T { self } +20 | fn add(self, other: T) -> T { self } | ^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/methods.rs:21:26 + --> $DIR/methods.rs:23:26 | -21 | fn sub(&self, other: T) -> &T { self } // no error, self is a ref +23 | 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:21:33 + --> $DIR/methods.rs:23:33 | -21 | fn sub(&self, other: T) -> &T { self } // no error, self is a ref +23 | 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:22:21 + --> $DIR/methods.rs:24:21 | -22 | fn div(self) -> T { self } // no error, different #arguments +24 | fn div(self) -> T { self } // no error, different #arguments | ^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/methods.rs:23:25 + --> $DIR/methods.rs:25:25 | -23 | fn rem(self, other: T) { } // no error, wrong return type +25 | 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:18:5 + --> $DIR/methods.rs:20:5 | -18 | fn add(self, other: T) -> T { self } +20 | fn add(self, other: T) -> T { self } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `-D should-implement-trait` implied by `-D warnings` error: defining a method called `drop` on this type; consider implementing the `std::ops::Drop` trait or choosing a less ambiguous name - --> $DIR/methods.rs:19:5 + --> $DIR/methods.rs:21:5 | -19 | fn drop(&mut self) { } +21 | fn drop(&mut self) { } | ^^^^^^^^^^^^^^^^^^^^^^ error: methods called `into_*` usually take self by value; consider choosing a less ambiguous name - --> $DIR/methods.rs:26:17 + --> $DIR/methods.rs:28:17 | -26 | fn into_u16(&self) -> u16 { 0 } +28 | 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:28:21 + --> $DIR/methods.rs:30:21 | -28 | fn to_something(self) -> u32 { 0 } +30 | fn to_something(self) -> u32 { 0 } | ^^^^ error: methods called `new` usually take no self; consider choosing a less ambiguous name - --> $DIR/methods.rs:30:12 + --> $DIR/methods.rs:32:12 | -30 | fn new(self) {} +32 | fn new(self) {} | ^^^^ error: methods called `new` usually return `Self` - --> $DIR/methods.rs:30:5 + --> $DIR/methods.rs:32:5 | -30 | fn new(self) {} +32 | fn new(self) {} | ^^^^^^^^^^^^^^^ | = note: `-D new-ret-no-self` implied by `-D warnings` error: unnecessary structure name repetition - --> $DIR/methods.rs:74:24 + --> $DIR/methods.rs:76:24 | -74 | fn new() -> Option> { None } +76 | fn new() -> Option> { None } | ^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/methods.rs:78:19 + --> $DIR/methods.rs:80:19 | -78 | type Output = T; +80 | type Output = T; | ^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/methods.rs:79:25 + --> $DIR/methods.rs:81:25 | -79 | fn mul(self, other: T) -> T { self } // no error, obviously +81 | fn mul(self, other: T) -> T { self } // no error, obviously | ^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/methods.rs:79:31 + --> $DIR/methods.rs:81:31 | -79 | fn mul(self, other: T) -> T { self } // no error, obviously +81 | 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:97:13 - | -97 | let _ = opt.map(|x| x + 1) - | _____________^ -98 | | -99 | | .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)` + --> $DIR/methods.rs:99:13 + | +99 | let _ = opt.map(|x| x + 1) + | _____________^ +100 | | +101 | | .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:101:13 + --> $DIR/methods.rs:103:13 | -101 | let _ = opt.map(|x| { +103 | let _ = opt.map(|x| { | _____________^ -102 | | x + 1 -103 | | } -104 | | ).unwrap_or(0); +104 | | x + 1 +105 | | } +106 | | ).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:105:13 + --> $DIR/methods.rs:107:13 | -105 | let _ = opt.map(|x| x + 1) +107 | let _ = opt.map(|x| x + 1) | _____________^ -106 | | .unwrap_or({ -107 | | 0 -108 | | }); +108 | | .unwrap_or({ +109 | | 0 +110 | | }); | |__________________^ 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:114:13 + --> $DIR/methods.rs:116:13 | -114 | let _ = opt.map(|x| x + 1) +116 | let _ = opt.map(|x| x + 1) | _____________^ -115 | | -116 | | .unwrap_or_else(|| 0); // should lint even though this call is on a separate line +117 | | +118 | | .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:118:13 + --> $DIR/methods.rs:120:13 | -118 | let _ = opt.map(|x| { +120 | let _ = opt.map(|x| { | _____________^ -119 | | x + 1 -120 | | } -121 | | ).unwrap_or_else(|| 0); +121 | | x + 1 +122 | | } +123 | | ).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:122:13 + --> $DIR/methods.rs:124:13 | -122 | let _ = opt.map(|x| x + 1) +124 | let _ = opt.map(|x| x + 1) | _____________^ -123 | | .unwrap_or_else(|| -124 | | 0 -125 | | ); +125 | | .unwrap_or_else(|| +126 | | 0 +127 | | ); | |_________________^ error: unnecessary structure name repetition - --> $DIR/methods.rs:151:24 + --> $DIR/methods.rs:153:24 | -151 | fn filter(self) -> IteratorFalsePositives { +153 | fn filter(self) -> IteratorFalsePositives { | ^^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/methods.rs:155:22 + --> $DIR/methods.rs:157:22 | -155 | fn next(self) -> IteratorFalsePositives { +157 | fn next(self) -> IteratorFalsePositives { | ^^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/methods.rs:175:32 + --> $DIR/methods.rs:177:32 | -175 | fn skip(self, _: usize) -> IteratorFalsePositives { +177 | 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:194:13 + --> $DIR/methods.rs:196:13 | -194 | let _ = v.iter().filter(|&x| *x < 0).next(); +196 | 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:197:13 + --> $DIR/methods.rs:199:13 | -197 | let _ = v.iter().filter(|&x| { +199 | let _ = v.iter().filter(|&x| { | _____________^ -198 | | *x < 0 -199 | | } -200 | | ).next(); +200 | | *x < 0 +201 | | } +202 | | ).next(); | |___________________________^ error: called `is_some()` after searching an `Iterator` with find. This is more succinctly expressed by calling `any()`. - --> $DIR/methods.rs:212:13 + --> $DIR/methods.rs:214:13 | -212 | let _ = v.iter().find(|&x| *x < 0).is_some(); +214 | 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:215:13 + --> $DIR/methods.rs:217:13 | -215 | let _ = v.iter().find(|&x| { +217 | let _ = v.iter().find(|&x| { | _____________^ -216 | | *x < 0 -217 | | } -218 | | ).is_some(); +218 | | *x < 0 +219 | | } +220 | | ).is_some(); | |______________________________^ error: called `is_some()` after searching an `Iterator` with position. This is more succinctly expressed by calling `any()`. - --> $DIR/methods.rs:221:13 + --> $DIR/methods.rs:223:13 | -221 | let _ = v.iter().position(|&x| x < 0).is_some(); +223 | 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:224:13 + --> $DIR/methods.rs:226:13 | -224 | let _ = v.iter().position(|&x| { +226 | let _ = v.iter().position(|&x| { | _____________^ -225 | | x < 0 -226 | | } -227 | | ).is_some(); +227 | | x < 0 +228 | | } +229 | | ).is_some(); | |______________________________^ error: called `is_some()` after searching an `Iterator` with rposition. This is more succinctly expressed by calling `any()`. - --> $DIR/methods.rs:230:13 + --> $DIR/methods.rs:232:13 | -230 | let _ = v.iter().rposition(|&x| x < 0).is_some(); +232 | 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:233:13 + --> $DIR/methods.rs:235:13 | -233 | let _ = v.iter().rposition(|&x| { +235 | let _ = v.iter().rposition(|&x| { | _____________^ -234 | | x < 0 -235 | | } -236 | | ).is_some(); +236 | | x < 0 +237 | | } +238 | | ).is_some(); | |______________________________^ error: unnecessary structure name repetition - --> $DIR/methods.rs:250:21 + --> $DIR/methods.rs:252:21 | -250 | fn new() -> Foo { Foo } +252 | fn new() -> Foo { Foo } | ^^^ help: use the applicable keyword: `Self` error: use of `unwrap_or` followed by a function call - --> $DIR/methods.rs:268:5 + --> $DIR/methods.rs:270:5 | -268 | with_constructor.unwrap_or(make()); +270 | with_constructor.unwrap_or(make()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `with_constructor.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:271:5 + --> $DIR/methods.rs:273:5 | -271 | with_new.unwrap_or(Vec::new()); +273 | 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:274:5 + --> $DIR/methods.rs:276:5 | -274 | with_const_args.unwrap_or(Vec::with_capacity(12)); +276 | with_const_args.unwrap_or(Vec::with_capacity(12)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `with_const_args.unwrap_or_else(|| Vec::with_capacity(12))` error: use of `unwrap_or` followed by a function call - --> $DIR/methods.rs:277:5 + --> $DIR/methods.rs:279:5 | -277 | with_err.unwrap_or(make()); +279 | with_err.unwrap_or(make()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `with_err.unwrap_or_else(|_| make())` error: use of `unwrap_or` followed by a function call - --> $DIR/methods.rs:280:5 + --> $DIR/methods.rs:282:5 | -280 | with_err_args.unwrap_or(Vec::with_capacity(12)); +282 | with_err_args.unwrap_or(Vec::with_capacity(12)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `with_err_args.unwrap_or_else(|_| Vec::with_capacity(12))` error: use of `unwrap_or` followed by a call to `default` - --> $DIR/methods.rs:283:5 + --> $DIR/methods.rs:285:5 | -283 | with_default_trait.unwrap_or(Default::default()); +285 | 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:286:5 + --> $DIR/methods.rs:288:5 | -286 | with_default_type.unwrap_or(u64::default()); +288 | 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:289:5 + --> $DIR/methods.rs:291:5 | -289 | with_vec.unwrap_or(vec![]); +291 | with_vec.unwrap_or(vec![]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `with_vec.unwrap_or_else(|| < [ _ ] > :: into_vec ( box [ $ ( $ x ) , * ] ))` error: use of `unwrap_or` followed by a function call - --> $DIR/methods.rs:294:5 + --> $DIR/methods.rs:296:5 | -294 | without_default.unwrap_or(Foo::new()); +296 | without_default.unwrap_or(Foo::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `without_default.unwrap_or_else(Foo::new)` error: use of `or_insert` followed by a function call - --> $DIR/methods.rs:297:5 + --> $DIR/methods.rs:299:5 | -297 | map.entry(42).or_insert(String::new()); +299 | map.entry(42).or_insert(String::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `map.entry(42).or_insert_with(String::new)` error: use of `or_insert` followed by a function call - --> $DIR/methods.rs:300:5 + --> $DIR/methods.rs:302:5 | -300 | btree.entry(42).or_insert(String::new()); +302 | btree.entry(42).or_insert(String::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `btree.entry(42).or_insert_with(String::new)` error: use of `unwrap_or` followed by a function call - --> $DIR/methods.rs:303:13 + --> $DIR/methods.rs:305:13 | -303 | let _ = stringy.unwrap_or("".to_owned()); +305 | let _ = stringy.unwrap_or("".to_owned()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `stringy.unwrap_or_else(|| "".to_owned())` error: called `.iter().nth()` on a Vec. Calling `.get()` is both faster and more readable - --> $DIR/methods.rs:314:23 + --> $DIR/methods.rs:316:23 | -314 | let bad_vec = some_vec.iter().nth(3); +316 | 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:315:26 + --> $DIR/methods.rs:317:26 | -315 | let bad_slice = &some_vec[..].iter().nth(3); +317 | 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:316:31 + --> $DIR/methods.rs:318:31 | -316 | let bad_boxed_slice = boxed_slice.iter().nth(3); +318 | 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:317:29 + --> $DIR/methods.rs:319:29 | -317 | let bad_vec_deque = some_vec_deque.iter().nth(3); +319 | 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:322:23 + --> $DIR/methods.rs:324:23 | -322 | let bad_vec = some_vec.iter_mut().nth(3); +324 | 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:325:26 + --> $DIR/methods.rs:327:26 | -325 | let bad_slice = &some_vec[..].iter_mut().nth(3); +327 | 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:328:29 + --> $DIR/methods.rs:330:29 | -328 | let bad_vec_deque = some_vec_deque.iter_mut().nth(3); +330 | 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:340:13 + --> $DIR/methods.rs:342:13 | -340 | let _ = some_vec.iter().skip(42).next(); +342 | 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:341:13 + --> $DIR/methods.rs:343:13 | -341 | let _ = some_vec.iter().cycle().skip(42).next(); +343 | 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:342:13 + --> $DIR/methods.rs:344:13 | -342 | let _ = (1..10).skip(10).next(); +344 | 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:343:14 + --> $DIR/methods.rs:345:14 | -343 | let _ = &some_vec[..].iter().skip(3).next(); +345 | let _ = &some_vec[..].iter().skip(3).next(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise - --> $DIR/methods.rs:369:17 + --> $DIR/methods.rs:371:17 | -369 | let _ = boxed_slice.get(1).unwrap(); +371 | let _ = boxed_slice.get(1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&boxed_slice[1]` | = note: `-D get-unwrap` implied by `-D warnings` error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise - --> $DIR/methods.rs:370:17 + --> $DIR/methods.rs:372:17 | -370 | let _ = some_slice.get(0).unwrap(); +372 | let _ = some_slice.get(0).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&some_slice[0]` error: called `.get().unwrap()` on a Vec. Using `[]` is more clear and more concise - --> $DIR/methods.rs:371:17 + --> $DIR/methods.rs:373:17 | -371 | let _ = some_vec.get(0).unwrap(); +373 | let _ = some_vec.get(0).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&some_vec[0]` error: called `.get().unwrap()` on a VecDeque. Using `[]` is more clear and more concise - --> $DIR/methods.rs:372:17 + --> $DIR/methods.rs:374:17 | -372 | let _ = some_vecdeque.get(0).unwrap(); +374 | let _ = some_vecdeque.get(0).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&some_vecdeque[0]` error: called `.get().unwrap()` on a HashMap. Using `[]` is more clear and more concise - --> $DIR/methods.rs:373:17 + --> $DIR/methods.rs:375:17 | -373 | let _ = some_hashmap.get(&1).unwrap(); +375 | let _ = some_hashmap.get(&1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&some_hashmap[&1]` error: called `.get().unwrap()` on a BTreeMap. Using `[]` is more clear and more concise - --> $DIR/methods.rs:374:17 + --> $DIR/methods.rs:376:17 | -374 | let _ = some_btreemap.get(&1).unwrap(); +376 | let _ = some_btreemap.get(&1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&some_btreemap[&1]` error: called `.get_mut().unwrap()` on a slice. Using `[]` is more clear and more concise - --> $DIR/methods.rs:379:10 + --> $DIR/methods.rs:381:10 | -379 | *boxed_slice.get_mut(0).unwrap() = 1; +381 | *boxed_slice.get_mut(0).unwrap() = 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&mut boxed_slice[0]` error: called `.get_mut().unwrap()` on a slice. Using `[]` is more clear and more concise - --> $DIR/methods.rs:380:10 + --> $DIR/methods.rs:382:10 | -380 | *some_slice.get_mut(0).unwrap() = 1; +382 | *some_slice.get_mut(0).unwrap() = 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&mut some_slice[0]` error: called `.get_mut().unwrap()` on a Vec. Using `[]` is more clear and more concise - --> $DIR/methods.rs:381:10 + --> $DIR/methods.rs:383:10 | -381 | *some_vec.get_mut(0).unwrap() = 1; +383 | *some_vec.get_mut(0).unwrap() = 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&mut some_vec[0]` error: called `.get_mut().unwrap()` on a VecDeque. Using `[]` is more clear and more concise - --> $DIR/methods.rs:382:10 + --> $DIR/methods.rs:384:10 | -382 | *some_vecdeque.get_mut(0).unwrap() = 1; +384 | *some_vecdeque.get_mut(0).unwrap() = 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&mut some_vecdeque[0]` 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:396:13 + --> $DIR/methods.rs:398:13 | -396 | let _ = opt.unwrap(); +398 | let _ = opt.unwrap(); | ^^^^^^^^^^^^ | = note: `-D option-unwrap-used` implied by `-D warnings` error: used unwrap() on a Result value. If you don't want to handle the Err case gracefully, consider using expect() to provide a better panic message - --> $DIR/methods.rs:399:13 + --> $DIR/methods.rs:401:13 | -399 | let _ = res.unwrap(); +401 | let _ = res.unwrap(); | ^^^^^^^^^^^^ | = note: `-D result-unwrap-used` implied by `-D warnings` error: called `ok().expect()` on a Result value. You can call `expect` directly on the `Result` - --> $DIR/methods.rs:401:5 + --> $DIR/methods.rs:403:5 | -401 | res.ok().expect("disaster!"); +403 | res.ok().expect("disaster!"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `-D ok-expect` implied by `-D warnings` -error: called `ok().expect()` on a Result value. You can call `expect` directly on the `Result` - --> $DIR/methods.rs:407:5 - | -407 | res3.ok().expect("whoof"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - error: called `ok().expect()` on a Result value. You can call `expect` directly on the `Result` --> $DIR/methods.rs:409:5 | -409 | res4.ok().expect("argh"); - | ^^^^^^^^^^^^^^^^^^^^^^^^ +409 | res3.ok().expect("whoof"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: called `ok().expect()` on a Result value. You can call `expect` directly on the `Result` --> $DIR/methods.rs:411:5 | -411 | res5.ok().expect("oops"); +411 | res4.ok().expect("argh"); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: called `ok().expect()` on a Result value. You can call `expect` directly on the `Result` --> $DIR/methods.rs:413:5 | -413 | res6.ok().expect("meh"); +413 | res5.ok().expect("oops"); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: called `ok().expect()` on a Result value. You can call `expect` directly on the `Result` + --> $DIR/methods.rs:415:5 + | +415 | res6.ok().expect("meh"); | ^^^^^^^^^^^^^^^^^^^^^^^ error: you should use the `starts_with` method - --> $DIR/methods.rs:425:5 + --> $DIR/methods.rs:427:5 | -425 | "".chars().next() == Some(' '); +427 | "".chars().next() == Some(' '); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `"".starts_with(' ')` | = note: `-D chars-next-cmp` implied by `-D warnings` error: you should use the `starts_with` method - --> $DIR/methods.rs:426:5 + --> $DIR/methods.rs:428:5 | -426 | Some(' ') != "".chars().next(); +428 | Some(' ') != "".chars().next(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `!"".starts_with(' ')` error: calling `.extend(_.chars())` - --> $DIR/methods.rs:435:5 + --> $DIR/methods.rs:437:5 | -435 | s.extend(abc.chars()); +437 | s.extend(abc.chars()); | ^^^^^^^^^^^^^^^^^^^^^ help: try this: `s.push_str(abc)` | = note: `-D string-extend-chars` implied by `-D warnings` error: calling `.extend(_.chars())` - --> $DIR/methods.rs:438:5 + --> $DIR/methods.rs:440:5 | -438 | s.extend("abc".chars()); +440 | s.extend("abc".chars()); | ^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `s.push_str("abc")` error: calling `.extend(_.chars())` - --> $DIR/methods.rs:441:5 + --> $DIR/methods.rs:443:5 | -441 | s.extend(def.chars()); +443 | s.extend(def.chars()); | ^^^^^^^^^^^^^^^^^^^^^ help: try this: `s.push_str(&def)` error: using `clone` on a `Copy` type - --> $DIR/methods.rs:452:5 + --> $DIR/methods.rs:454:5 | -452 | 42.clone(); +454 | 42.clone(); | ^^^^^^^^^^ help: try removing the `clone` call: `42` | = note: `-D clone-on-copy` implied by `-D warnings` error: using `clone` on a `Copy` type - --> $DIR/methods.rs:456:5 + --> $DIR/methods.rs:458:5 | -456 | (&42).clone(); +458 | (&42).clone(); | ^^^^^^^^^^^^^ help: try dereferencing it: `*(&42)` -error: using `clone` on a `Copy` type - --> $DIR/methods.rs:460:5 +error: using '.clone()' on a ref-counted pointer + --> $DIR/methods.rs:468:5 | -460 | t.clone(); +468 | rc.clone(); + | ^^^^^^^^^^ help: try this: `Rc::clone(&rc)` + | + = note: `-D clone-on-ref-ptr` implied by `-D warnings` + +error: using '.clone()' on a ref-counted pointer + --> $DIR/methods.rs:471:5 + | +471 | arc.clone(); + | ^^^^^^^^^^^ help: try this: `Arc::clone(&arc)` + +error: using '.clone()' on a ref-counted pointer + --> $DIR/methods.rs:474:5 + | +474 | rcweak.clone(); + | ^^^^^^^^^^^^^^ help: try this: `Weak::clone(&rcweak)` + +error: using '.clone()' on a ref-counted pointer + --> $DIR/methods.rs:477:5 + | +477 | arc_weak.clone(); + | ^^^^^^^^^^^^^^^^ help: try this: `Weak::clone(&arc_weak)` + +error: using `clone` on a `Copy` type + --> $DIR/methods.rs:484:5 + | +484 | t.clone(); | ^^^^^^^^^ help: try removing the `clone` call: `t` error: using `clone` on a `Copy` type - --> $DIR/methods.rs:462:5 + --> $DIR/methods.rs:486:5 | -462 | Some(t).clone(); +486 | Some(t).clone(); | ^^^^^^^^^^^^^^^ help: try removing the `clone` call: `Some(t)` error: using `clone` on a double-reference; this will copy the reference instead of cloning the inner type - --> $DIR/methods.rs:468:22 + --> $DIR/methods.rs:492:22 | -468 | let z: &Vec<_> = y.clone(); +492 | let z: &Vec<_> = y.clone(); | ^^^^^^^^^ help: try dereferencing it: `(*y).clone()` | = note: `-D clone-double-ref` implied by `-D warnings` error: single-character string constant used as pattern - --> $DIR/methods.rs:475:13 + --> $DIR/methods.rs:499:13 | -475 | x.split("x"); +499 | x.split("x"); | --------^^^- help: try using a char instead: `x.split('x')` | = note: `-D single-char-pattern` implied by `-D warnings` error: single-character string constant used as pattern - --> $DIR/methods.rs:492:16 + --> $DIR/methods.rs:516:16 | -492 | x.contains("x"); +516 | x.contains("x"); | -----------^^^- help: try using a char instead: `x.contains('x')` error: single-character string constant used as pattern - --> $DIR/methods.rs:493:19 + --> $DIR/methods.rs:517:19 | -493 | x.starts_with("x"); +517 | x.starts_with("x"); | --------------^^^- help: try using a char instead: `x.starts_with('x')` error: single-character string constant used as pattern - --> $DIR/methods.rs:494:17 + --> $DIR/methods.rs:518:17 | -494 | x.ends_with("x"); +518 | x.ends_with("x"); | ------------^^^- help: try using a char instead: `x.ends_with('x')` error: single-character string constant used as pattern - --> $DIR/methods.rs:495:12 + --> $DIR/methods.rs:519:12 | -495 | x.find("x"); +519 | x.find("x"); | -------^^^- help: try using a char instead: `x.find('x')` error: single-character string constant used as pattern - --> $DIR/methods.rs:496:13 + --> $DIR/methods.rs:520:13 | -496 | x.rfind("x"); +520 | x.rfind("x"); | --------^^^- help: try using a char instead: `x.rfind('x')` error: single-character string constant used as pattern - --> $DIR/methods.rs:497:14 + --> $DIR/methods.rs:521:14 | -497 | x.rsplit("x"); +521 | x.rsplit("x"); | ---------^^^- help: try using a char instead: `x.rsplit('x')` error: single-character string constant used as pattern - --> $DIR/methods.rs:498:24 + --> $DIR/methods.rs:522:24 | -498 | x.split_terminator("x"); +522 | x.split_terminator("x"); | -------------------^^^- help: try using a char instead: `x.split_terminator('x')` error: single-character string constant used as pattern - --> $DIR/methods.rs:499:25 + --> $DIR/methods.rs:523:25 | -499 | x.rsplit_terminator("x"); +523 | x.rsplit_terminator("x"); | --------------------^^^- help: try using a char instead: `x.rsplit_terminator('x')` error: single-character string constant used as pattern - --> $DIR/methods.rs:500:17 + --> $DIR/methods.rs:524:17 | -500 | x.splitn(0, "x"); +524 | x.splitn(0, "x"); | ------------^^^- help: try using a char instead: `x.splitn(0, 'x')` error: single-character string constant used as pattern - --> $DIR/methods.rs:501:18 + --> $DIR/methods.rs:525:18 | -501 | x.rsplitn(0, "x"); +525 | x.rsplitn(0, "x"); | -------------^^^- help: try using a char instead: `x.rsplitn(0, 'x')` error: single-character string constant used as pattern - --> $DIR/methods.rs:502:15 + --> $DIR/methods.rs:526:15 | -502 | x.matches("x"); +526 | x.matches("x"); | ----------^^^- help: try using a char instead: `x.matches('x')` error: single-character string constant used as pattern - --> $DIR/methods.rs:503:16 + --> $DIR/methods.rs:527:16 | -503 | x.rmatches("x"); +527 | x.rmatches("x"); | -----------^^^- help: try using a char instead: `x.rmatches('x')` error: single-character string constant used as pattern - --> $DIR/methods.rs:504:21 + --> $DIR/methods.rs:528:21 | -504 | x.match_indices("x"); +528 | x.match_indices("x"); | ----------------^^^- help: try using a char instead: `x.match_indices('x')` error: single-character string constant used as pattern - --> $DIR/methods.rs:505:22 + --> $DIR/methods.rs:529:22 | -505 | x.rmatch_indices("x"); +529 | x.rmatch_indices("x"); | -----------------^^^- help: try using a char instead: `x.rmatch_indices('x')` error: single-character string constant used as pattern - --> $DIR/methods.rs:506:25 + --> $DIR/methods.rs:530:25 | -506 | x.trim_left_matches("x"); +530 | x.trim_left_matches("x"); | --------------------^^^- help: try using a char instead: `x.trim_left_matches('x')` error: single-character string constant used as pattern - --> $DIR/methods.rs:507:26 + --> $DIR/methods.rs:531:26 | -507 | x.trim_right_matches("x"); +531 | x.trim_right_matches("x"); | ---------------------^^^- help: try using a char instead: `x.trim_right_matches('x')` error: you are getting the inner pointer of a temporary `CString` - --> $DIR/methods.rs:517:5 + --> $DIR/methods.rs:541:5 | -517 | CString::new("foo").unwrap().as_ptr(); +541 | CString::new("foo").unwrap().as_ptr(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `-D temporary-cstring-as-ptr` implied by `-D warnings` = note: that pointer will be invalid outside this expression help: assign the `CString` to a variable to extend its lifetime - --> $DIR/methods.rs:517:5 + --> $DIR/methods.rs:541:5 | -517 | CString::new("foo").unwrap().as_ptr(); +541 | CString::new("foo").unwrap().as_ptr(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: called `cloned().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and more readable - --> $DIR/methods.rs:522:27 + --> $DIR/methods.rs:546:27 | -522 | let v2 : Vec = v.iter().cloned().collect(); +546 | let v2 : Vec = v.iter().cloned().collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `-D iter-cloned-collect` implied by `-D warnings` -error: aborting due to 103 previous errors +error: aborting due to 107 previous errors