diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c71281acd48..e471c6d71f9d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5497,6 +5497,7 @@ Released 2018-09-13 [`const_is_empty`]: https://rust-lang.github.io/rust-clippy/master/index.html#const_is_empty [`const_static_lifetime`]: https://rust-lang.github.io/rust-clippy/master/index.html#const_static_lifetime [`copy_iterator`]: https://rust-lang.github.io/rust-clippy/master/index.html#copy_iterator +[`copy_then_borrow_mut`]: https://rust-lang.github.io/rust-clippy/master/index.html#copy_then_borrow_mut [`crate_in_macro_def`]: https://rust-lang.github.io/rust-clippy/master/index.html#crate_in_macro_def [`create_dir`]: https://rust-lang.github.io/rust-clippy/master/index.html#create_dir [`crosspointer_transmute`]: https://rust-lang.github.io/rust-clippy/master/index.html#crosspointer_transmute diff --git a/clippy_lints/src/copy_then_borrow_mut.rs b/clippy_lints/src/copy_then_borrow_mut.rs new file mode 100644 index 000000000000..04f2705cfd7a --- /dev/null +++ b/clippy_lints/src/copy_then_borrow_mut.rs @@ -0,0 +1,57 @@ +use clippy_utils::diagnostics::span_lint_and_note; +use clippy_utils::ty::is_copy; +use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability}; +use rustc_lint::{LateContext, LateLintPass}; +use rustc_session::declare_lint_pass; + +declare_clippy_lint! { + /// ### What it does + /// Checks for mutable reference on a freshly copied data due to + /// the use of a block to return an value implementing `Copy`. + /// + /// ### Why is this bad? + /// Using a block will make a copy of the block result if its type + /// implements `Copy`. This might be an indication of a failed attempt + /// to borrow the original data instead. + /// + /// ### Example + /// ```no_run + /// # fn f(_: &mut [i32]) {} + /// let arr = &mut [10, 20, 30]; + /// f(&mut { *arr }); + /// ``` + /// If you intend to modify `arr` in `f`, use instead: + /// ```no_run + /// # fn f(_: &mut [i32]) {} + /// let arr = &mut [10, 20, 30]; + /// f(arr); + /// ``` + #[clippy::version = "1.86.0"] + pub COPY_THEN_BORROW_MUT, + suspicious, + "mutable borrow of a data which was just copied" +} + +declare_lint_pass!(CopyThenBorrowMut => [COPY_THEN_BORROW_MUT]); + +impl LateLintPass<'_> for CopyThenBorrowMut { + fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { + if !expr.span.from_expansion() + && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Mut, sub_expr) = expr.kind + && let ExprKind::Block(block, _) = sub_expr.kind + && block.span.eq_ctxt(expr.span) + && let Some(block_expr) = block.expr + && let block_ty = cx.typeck_results().expr_ty_adjusted(block_expr) + && is_copy(cx, block_ty) + { + span_lint_and_note( + cx, + COPY_THEN_BORROW_MUT, + expr.span, + "mutable borrow of a value which was just copied", + (!block.targeted_by_break).then_some(block_expr.span), + "the return value of the block implements `Copy` and will be copied", + ); + } + } +} diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index ac933d7cd705..a916f600663a 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -113,6 +113,7 @@ pub static LINTS: &[&crate::LintInfo] = &[ crate::copies::IF_SAME_THEN_ELSE_INFO, crate::copies::SAME_FUNCTIONS_IN_IF_CONDITION_INFO, crate::copy_iterator::COPY_ITERATOR_INFO, + crate::copy_then_borrow_mut::COPY_THEN_BORROW_MUT_INFO, crate::crate_in_macro_def::CRATE_IN_MACRO_DEF_INFO, crate::create_dir::CREATE_DIR_INFO, crate::dbg_macro::DBG_MACRO_INFO, diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 1e8cfe22b229..f9671411a4b1 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -103,6 +103,7 @@ mod collection_is_never_read; mod comparison_chain; mod copies; mod copy_iterator; +mod copy_then_borrow_mut; mod crate_in_macro_def; mod create_dir; mod dbg_macro; @@ -972,5 +973,6 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) { store.register_late_pass(|_| Box::new(unnecessary_literal_bound::UnnecessaryLiteralBound)); store.register_late_pass(move |_| Box::new(arbitrary_source_item_ordering::ArbitrarySourceItemOrdering::new(conf))); store.register_late_pass(|_| Box::new(unneeded_struct_pattern::UnneededStructPattern)); + store.register_late_pass(|_| Box::new(copy_then_borrow_mut::CopyThenBorrowMut)); // add lints here, do not remove this comment, it's used in `new_lint` } diff --git a/tests/ui-toml/excessive_nesting/excessive_nesting.rs b/tests/ui-toml/excessive_nesting/excessive_nesting.rs index 858aab528a91..d209af8fdcd3 100644 --- a/tests/ui-toml/excessive_nesting/excessive_nesting.rs +++ b/tests/ui-toml/excessive_nesting/excessive_nesting.rs @@ -13,6 +13,7 @@ clippy::collapsible_if, clippy::blocks_in_conditions, clippy::single_match, + clippy::copy_then_borrow_mut )] #[macro_use] diff --git a/tests/ui-toml/excessive_nesting/excessive_nesting.stderr b/tests/ui-toml/excessive_nesting/excessive_nesting.stderr index 9cf6fc66757d..5f84e2ec9d83 100644 --- a/tests/ui-toml/excessive_nesting/excessive_nesting.stderr +++ b/tests/ui-toml/excessive_nesting/excessive_nesting.stderr @@ -1,5 +1,5 @@ error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:25:25 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:26:25 | LL | let w = { 3 }; | ^^^^^ @@ -9,7 +9,7 @@ LL | let w = { 3 }; = help: to override `-D warnings` add `#[allow(clippy::excessive_nesting)]` error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:71:17 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:72:17 | LL | / impl C { LL | | pub fn c() {} @@ -19,7 +19,7 @@ LL | | } = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:85:25 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:86:25 | LL | let x = { 1 }; // not a warning, but cc is | ^^^^^ @@ -27,7 +27,7 @@ LL | let x = { 1 }; // not a warning, but cc is = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:102:17 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:103:17 | LL | / pub mod e { LL | | pub mod f {} @@ -37,7 +37,7 @@ LL | | } // not here = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:115:18 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:116:18 | LL | a_but_not({{{{{{{{0}}}}}}}}); | ^^^^^^^^^^^ @@ -45,7 +45,7 @@ LL | a_but_not({{{{{{{{0}}}}}}}}); = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:116:12 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:117:12 | LL | a.a({{{{{{{{{0}}}}}}}}}); | ^^^^^^^^^^^^^ @@ -53,7 +53,7 @@ LL | a.a({{{{{{{{{0}}}}}}}}}); = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:117:12 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:118:12 | LL | (0, {{{{{{{1}}}}}}}); | ^^^^^^^^^ @@ -61,7 +61,7 @@ LL | (0, {{{{{{{1}}}}}}}); = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:122:25 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:123:25 | LL | if true { | _________________________^ @@ -73,7 +73,7 @@ LL | | } = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:134:29 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:135:29 | LL | let z = (|| { | _____________________________^ @@ -85,7 +85,7 @@ LL | | })(); = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:153:13 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:154:13 | LL | y += {{{{{5}}}}}; | ^^^^^ @@ -93,7 +93,7 @@ LL | y += {{{{{5}}}}}; = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:154:20 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:155:20 | LL | let z = y + {{{{{{{{{5}}}}}}}}}; | ^^^^^^^^^^^^^ @@ -101,7 +101,7 @@ LL | let z = y + {{{{{{{{{5}}}}}}}}}; = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:155:12 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:156:12 | LL | [0, {{{{{{{{{{0}}}}}}}}}}]; | ^^^^^^^^^^^^^^^ @@ -109,7 +109,7 @@ LL | [0, {{{{{{{{{{0}}}}}}}}}}]; = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:156:25 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:157:25 | LL | let mut xx = [0; {{{{{{{{100}}}}}}}}]; | ^^^^^^^^^^^^^ @@ -117,7 +117,7 @@ LL | let mut xx = [0; {{{{{{{{100}}}}}}}}]; = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:157:11 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:158:11 | LL | xx[{{{{{{{{{{{{{{{{{{{{{{{{3}}}}}}}}}}}}}}}}}}}}}}}}]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -125,7 +125,7 @@ LL | xx[{{{{{{{{{{{{{{{{{{{{{{{{3}}}}}}}}}}}}}}}}}}}}}}}}]; = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:158:13 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:159:13 | LL | &mut {{{{{{{{{{y}}}}}}}}}}; | ^^^^^^^^^^^^^^^ @@ -133,7 +133,7 @@ LL | &mut {{{{{{{{{{y}}}}}}}}}}; = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:160:17 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:161:17 | LL | for i in {{{{xx}}}} {{{{{{{{}}}}}}}} | ^^^^ @@ -141,7 +141,7 @@ LL | for i in {{{{xx}}}} {{{{{{{{}}}}}}}} = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:160:28 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:161:28 | LL | for i in {{{{xx}}}} {{{{{{{{}}}}}}}} | ^^^^^^^^^^ @@ -149,7 +149,7 @@ LL | for i in {{{{xx}}}} {{{{{{{{}}}}}}}} = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:162:28 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:163:28 | LL | while let Some(i) = {{{{{{Some(1)}}}}}} {{{{{{{}}}}}}} | ^^^^^^^^^^^^^ @@ -157,7 +157,7 @@ LL | while let Some(i) = {{{{{{Some(1)}}}}}} {{{{{{{}}}}}}} = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:162:48 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:163:48 | LL | while let Some(i) = {{{{{{Some(1)}}}}}} {{{{{{{}}}}}}} | ^^^^^^^^ @@ -165,7 +165,7 @@ LL | while let Some(i) = {{{{{{Some(1)}}}}}} {{{{{{{}}}}}}} = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:164:14 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:165:14 | LL | while {{{{{{{{true}}}}}}}} {{{{{{{{{}}}}}}}}} | ^^^^^^^^^^^^^^ @@ -173,7 +173,7 @@ LL | while {{{{{{{{true}}}}}}}} {{{{{{{{{}}}}}}}}} = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:164:35 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:165:35 | LL | while {{{{{{{{true}}}}}}}} {{{{{{{{{}}}}}}}}} | ^^^^^^^^^^^^ @@ -181,7 +181,7 @@ LL | while {{{{{{{{true}}}}}}}} {{{{{{{{{}}}}}}}}} = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:166:23 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:167:23 | LL | let d = D { d: {{{{{{{{{{{{{{{{{{{{{{{3}}}}}}}}}}}}}}}}}}}}}}} }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -189,7 +189,7 @@ LL | let d = D { d: {{{{{{{{{{{{{{{{{{{{{{{3}}}}}}}}}}}}}}}}}}}}}}} }; = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:168:8 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:169:8 | LL | {{{{1;}}}}..{{{{{{3}}}}}}; | ^^^^ @@ -197,7 +197,7 @@ LL | {{{{1;}}}}..{{{{{{3}}}}}}; = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:168:20 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:169:20 | LL | {{{{1;}}}}..{{{{{{3}}}}}}; | ^^^^^^^ @@ -205,7 +205,7 @@ LL | {{{{1;}}}}..{{{{{{3}}}}}}; = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:169:8 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:170:8 | LL | {{{{1;}}}}..={{{{{{{{{{{{{{{{{{{{{{{{{{6}}}}}}}}}}}}}}}}}}}}}}}}}}; | ^^^^ @@ -213,7 +213,7 @@ LL | {{{{1;}}}}..={{{{{{{{{{{{{{{{{{{{{{{{{{6}}}}}}}}}}}}}}}}}}}}}}}}}}; = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:169:21 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:170:21 | LL | {{{{1;}}}}..={{{{{{{{{{{{{{{{{{{{{{{{{{6}}}}}}}}}}}}}}}}}}}}}}}}}}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -221,7 +221,7 @@ LL | {{{{1;}}}}..={{{{{{{{{{{{{{{{{{{{{{{{{{6}}}}}}}}}}}}}}}}}}}}}}}}}}; = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:170:10 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:171:10 | LL | ..{{{{{{{5}}}}}}}; | ^^^^^^^^^ @@ -229,7 +229,7 @@ LL | ..{{{{{{{5}}}}}}}; = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:171:11 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:172:11 | LL | ..={{{{{3}}}}}; | ^^^^^ @@ -237,7 +237,7 @@ LL | ..={{{{{3}}}}}; = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:172:8 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:173:8 | LL | {{{{{1;}}}}}..; | ^^^^^^ @@ -245,7 +245,7 @@ LL | {{{{{1;}}}}}..; = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:174:20 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:175:20 | LL | loop { break {{{{1}}}} }; | ^^^^^ @@ -253,7 +253,7 @@ LL | loop { break {{{{1}}}} }; = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:175:13 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:176:13 | LL | loop {{{{{{}}}}}} | ^^^^^^ @@ -261,7 +261,7 @@ LL | loop {{{{{{}}}}}} = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:177:14 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:178:14 | LL | match {{{{{{true}}}}}} { | ^^^^^^^^^^ @@ -269,7 +269,7 @@ LL | match {{{{{{true}}}}}} { = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:178:20 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:179:20 | LL | true => {{{{}}}}, | ^^ @@ -277,7 +277,7 @@ LL | true => {{{{}}}}, = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:179:21 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:180:21 | LL | false => {{{{}}}}, | ^^ @@ -285,7 +285,7 @@ LL | false => {{{{}}}}, = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:185:17 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:186:17 | LL | / { LL | | println!("warning! :)"); @@ -295,7 +295,7 @@ LL | | } = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:194:28 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:195:28 | LL | async fn c() -> u32 {{{{{{{0}}}}}}} | ^^^^^^^^^ @@ -303,7 +303,7 @@ LL | async fn c() -> u32 {{{{{{{0}}}}}}} = help: try refactoring your code to minimize nesting error: this block is too nested - --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:200:8 + --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:201:8 | LL | {{{{b().await}}}}; | ^^^^^^^^^^^ diff --git a/tests/ui/copy_then_borrow_mut.rs b/tests/ui/copy_then_borrow_mut.rs new file mode 100644 index 000000000000..f08405ee14c3 --- /dev/null +++ b/tests/ui/copy_then_borrow_mut.rs @@ -0,0 +1,49 @@ +//@no-rustfix +#![warn(clippy::copy_then_borrow_mut)] + +fn main() { + let a = &[0u8; 2]; + let _ = &mut { *a }; //~ ERROR: mutable borrow + + let a = [0u8; 2]; + let _ = &mut { a }; //~ ERROR: mutable borrow + let _ = &mut { *&a }; //~ ERROR: mutable borrow + + let _ = &mut 'label: { + //~^ ERROR: mutable borrow + if a[0] == 1 { + break 'label 42u8; + } + 10u8 + }; + + let a = vec![0u8; 2]; + let _ = &mut { a }; // `a` is not `Copy` + + let a: *const u8 = &0u8; + let _ = &mut { unsafe { *a } }; //~ ERROR: mutable borrow + + let _ = &mut {}; // Do not lint on empty block + + macro_rules! mac { + () => {{ 0u8 }}; + } + let _ = &mut mac!(); // Do not lint on borrowed macro result + + macro_rules! mac2 { + // Do not lint, as it depends on `Copy`-ness of `a` + ($x:expr) => { + &mut unsafe { *$x } + }; + } + let a = 0u8; + let _ = &mut mac2!(&raw const a); +} + +// From https://users.rust-lang.org/t/runtime-speed-when-converting-as-bytes-or-as-ref-to-be-mut/123712/10 +fn f, T: Copy>() { + let _: &mut T = { + let n = N::default(); + &mut { *n.as_ref() } //~ ERROR: mutable borrow + }; +} diff --git a/tests/ui/copy_then_borrow_mut.stderr b/tests/ui/copy_then_borrow_mut.stderr new file mode 100644 index 000000000000..6f87709654e1 --- /dev/null +++ b/tests/ui/copy_then_borrow_mut.stderr @@ -0,0 +1,88 @@ +error: immediately dereferencing a reference + --> tests/ui/copy_then_borrow_mut.rs:10:20 + | +LL | let _ = &mut { *&a }; + | ^^^ help: try: `a` + | + = note: `-D clippy::deref-addrof` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::deref_addrof)]` + +error: mutable borrow of a value which was just copied + --> tests/ui/copy_then_borrow_mut.rs:6:13 + | +LL | let _ = &mut { *a }; + | ^^^^^^^^^^^ + | +note: the return value of the block implements `Copy` and will be copied + --> tests/ui/copy_then_borrow_mut.rs:6:20 + | +LL | let _ = &mut { *a }; + | ^^ + = note: `-D clippy::copy-then-borrow-mut` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::copy_then_borrow_mut)]` + +error: mutable borrow of a value which was just copied + --> tests/ui/copy_then_borrow_mut.rs:9:13 + | +LL | let _ = &mut { a }; + | ^^^^^^^^^^ + | +note: the return value of the block implements `Copy` and will be copied + --> tests/ui/copy_then_borrow_mut.rs:9:20 + | +LL | let _ = &mut { a }; + | ^ + +error: mutable borrow of a value which was just copied + --> tests/ui/copy_then_borrow_mut.rs:10:13 + | +LL | let _ = &mut { *&a }; + | ^^^^^^^^^^^^ + | +note: the return value of the block implements `Copy` and will be copied + --> tests/ui/copy_then_borrow_mut.rs:10:20 + | +LL | let _ = &mut { *&a }; + | ^^^ + +error: mutable borrow of a value which was just copied + --> tests/ui/copy_then_borrow_mut.rs:12:13 + | +LL | let _ = &mut 'label: { + | _____________^ +LL | | +LL | | if a[0] == 1 { +LL | | break 'label 42u8; +LL | | } +LL | | 10u8 +LL | | }; + | |_____^ + | + = note: the return value of the block implements `Copy` and will be copied + +error: mutable borrow of a value which was just copied + --> tests/ui/copy_then_borrow_mut.rs:24:13 + | +LL | let _ = &mut { unsafe { *a } }; + | ^^^^^^^^^^^^^^^^^^^^^^ + | +note: the return value of the block implements `Copy` and will be copied + --> tests/ui/copy_then_borrow_mut.rs:24:20 + | +LL | let _ = &mut { unsafe { *a } }; + | ^^^^^^^^^^^^^ + +error: mutable borrow of a value which was just copied + --> tests/ui/copy_then_borrow_mut.rs:47:9 + | +LL | &mut { *n.as_ref() } + | ^^^^^^^^^^^^^^^^^^^^ + | +note: the return value of the block implements `Copy` and will be copied + --> tests/ui/copy_then_borrow_mut.rs:47:16 + | +LL | &mut { *n.as_ref() } + | ^^^^^^^^^^^ + +error: aborting due to 7 previous errors + diff --git a/tests/ui/needless_borrow.fixed b/tests/ui/needless_borrow.fixed index 2763830e09c9..a47db358ff9c 100644 --- a/tests/ui/needless_borrow.fixed +++ b/tests/ui/needless_borrow.fixed @@ -5,7 +5,8 @@ clippy::unnecessary_mut_passed, clippy::unnecessary_to_owned, clippy::unnecessary_literal_unwrap, - clippy::needless_lifetimes + clippy::needless_lifetimes, + clippy::copy_then_borrow_mut )] #![warn(clippy::needless_borrow)] diff --git a/tests/ui/needless_borrow.rs b/tests/ui/needless_borrow.rs index b46f82b18c64..1986b618e4e0 100644 --- a/tests/ui/needless_borrow.rs +++ b/tests/ui/needless_borrow.rs @@ -5,7 +5,8 @@ clippy::unnecessary_mut_passed, clippy::unnecessary_to_owned, clippy::unnecessary_literal_unwrap, - clippy::needless_lifetimes + clippy::needless_lifetimes, + clippy::copy_then_borrow_mut )] #![warn(clippy::needless_borrow)] diff --git a/tests/ui/needless_borrow.stderr b/tests/ui/needless_borrow.stderr index 4b2b17e7e570..6a72d9d0bd27 100644 --- a/tests/ui/needless_borrow.stderr +++ b/tests/ui/needless_borrow.stderr @@ -1,5 +1,5 @@ error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:16:15 + --> tests/ui/needless_borrow.rs:17:15 | LL | let _ = x(&&a); // warn | ^^^ help: change this to: `&a` @@ -8,163 +8,163 @@ LL | let _ = x(&&a); // warn = help: to override `-D warnings` add `#[allow(clippy::needless_borrow)]` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:20:13 + --> tests/ui/needless_borrow.rs:21:13 | LL | mut_ref(&mut &mut b); // warn | ^^^^^^^^^^^ help: change this to: `&mut b` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:32:13 + --> tests/ui/needless_borrow.rs:33:13 | LL | &&a | ^^^ help: change this to: `&a` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:34:15 + --> tests/ui/needless_borrow.rs:35:15 | LL | 46 => &&a, | ^^^ help: change this to: `&a` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:40:27 + --> tests/ui/needless_borrow.rs:41:27 | LL | break &ref_a; | ^^^^^^ help: change this to: `ref_a` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:47:15 + --> tests/ui/needless_borrow.rs:48:15 | LL | let _ = x(&&&a); | ^^^^ help: change this to: `&a` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:48:15 + --> tests/ui/needless_borrow.rs:49:15 | LL | let _ = x(&mut &&a); | ^^^^^^^^ help: change this to: `&a` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:49:15 + --> tests/ui/needless_borrow.rs:50:15 | LL | let _ = x(&&&mut b); | ^^^^^^^^ help: change this to: `&mut b` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:50:15 + --> tests/ui/needless_borrow.rs:51:15 | LL | let _ = x(&&ref_a); | ^^^^^^^ help: change this to: `ref_a` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:53:11 + --> tests/ui/needless_borrow.rs:54:11 | LL | x(&b); | ^^ help: change this to: `b` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:60:13 + --> tests/ui/needless_borrow.rs:61:13 | LL | mut_ref(&mut x); | ^^^^^^ help: change this to: `x` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:61:13 + --> tests/ui/needless_borrow.rs:62:13 | LL | mut_ref(&mut &mut x); | ^^^^^^^^^^^ help: change this to: `x` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:62:23 + --> tests/ui/needless_borrow.rs:63:23 | LL | let y: &mut i32 = &mut x; | ^^^^^^ help: change this to: `x` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:63:23 + --> tests/ui/needless_borrow.rs:64:23 | LL | let y: &mut i32 = &mut &mut x; | ^^^^^^^^^^^ help: change this to: `x` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:72:14 + --> tests/ui/needless_borrow.rs:73:14 | LL | 0 => &mut x, | ^^^^^^ help: change this to: `x` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:78:14 + --> tests/ui/needless_borrow.rs:79:14 | LL | 0 => &mut x, | ^^^^^^ help: change this to: `x` error: this expression borrows a value the compiler would automatically borrow - --> tests/ui/needless_borrow.rs:90:13 + --> tests/ui/needless_borrow.rs:91:13 | LL | let _ = (&x).0; | ^^^^ help: change this to: `x` error: this expression borrows a value the compiler would automatically borrow - --> tests/ui/needless_borrow.rs:92:22 + --> tests/ui/needless_borrow.rs:93:22 | LL | let _ = unsafe { (&*x).0 }; | ^^^^^ help: change this to: `(*x)` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:102:5 + --> tests/ui/needless_borrow.rs:103:5 | LL | (&&()).foo(); | ^^^^^^ help: change this to: `(&())` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:111:5 + --> tests/ui/needless_borrow.rs:112:5 | LL | (&&5).foo(); | ^^^^^ help: change this to: `(&5)` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:137:23 + --> tests/ui/needless_borrow.rs:138:23 | LL | let x: (&str,) = (&"",); | ^^^ help: change this to: `""` error: this expression borrows a value the compiler would automatically borrow - --> tests/ui/needless_borrow.rs:179:13 + --> tests/ui/needless_borrow.rs:180:13 | LL | (&self.f)() | ^^^^^^^^^ help: change this to: `(self.f)` error: this expression borrows a value the compiler would automatically borrow - --> tests/ui/needless_borrow.rs:188:13 + --> tests/ui/needless_borrow.rs:189:13 | LL | (&mut self.f)() | ^^^^^^^^^^^^^ help: change this to: `(self.f)` error: this expression borrows a value the compiler would automatically borrow - --> tests/ui/needless_borrow.rs:225:22 + --> tests/ui/needless_borrow.rs:226:22 | LL | let _ = &mut (&mut { x.u }).x; | ^^^^^^^^^^^^^^ help: change this to: `{ x.u }` error: this expression borrows a value the compiler would automatically borrow - --> tests/ui/needless_borrow.rs:232:22 + --> tests/ui/needless_borrow.rs:233:22 | LL | let _ = &mut (&mut { x.u }).x; | ^^^^^^^^^^^^^^ help: change this to: `{ x.u }` error: this expression borrows a value the compiler would automatically borrow - --> tests/ui/needless_borrow.rs:236:22 + --> tests/ui/needless_borrow.rs:237:22 | LL | let _ = &mut (&mut x.u).x; | ^^^^^^^^^^ help: change this to: `x.u` error: this expression borrows a value the compiler would automatically borrow - --> tests/ui/needless_borrow.rs:237:22 + --> tests/ui/needless_borrow.rs:238:22 | LL | let _ = &mut (&mut { x.u }).x; | ^^^^^^^^^^^^^^ help: change this to: `{ x.u }` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:258:23 + --> tests/ui/needless_borrow.rs:259:23 | LL | option.unwrap_or((&x.0,)); | ^^^^ help: change this to: `x.0`