about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--clippy_lints/src/types.rs14
-rw-r--r--tests/ui/borrow_box.rs18
-rw-r--r--tests/ui/borrow_box.stderr18
3 files changed, 31 insertions, 19 deletions
diff --git a/clippy_lints/src/types.rs b/clippy_lints/src/types.rs
index 31d8daa2d97..153a2b7249c 100644
--- a/clippy_lints/src/types.rs
+++ b/clippy_lints/src/types.rs
@@ -531,11 +531,12 @@ impl Types {
                         } else {
                             format!("{} ", lt.name.ident().as_str())
                         };
-                        let mutopt = if mut_ty.mutbl == Mutability::Mut {
-                            "mut "
-                        } else {
-                            ""
-                        };
+
+                        if mut_ty.mutbl == Mutability::Mut {
+                            // Ignore `&mut Box<T>` types; see issue #2907 for
+                            // details.
+                            return;
+                        }
                         let mut applicability = Applicability::MachineApplicable;
                         span_lint_and_sugg(
                             cx,
@@ -544,9 +545,8 @@ impl Types {
                             "you seem to be trying to use `&Box<T>`. Consider using just `&T`",
                             "try",
                             format!(
-                                "&{}{}{}",
+                                "&{}{}",
                                 ltopt,
-                                mutopt,
                                 &snippet_with_applicability(cx, inner.span, "..", &mut applicability)
                             ),
                             Applicability::Unspecified,
diff --git a/tests/ui/borrow_box.rs b/tests/ui/borrow_box.rs
index b30f7290ffe..1901de46ca8 100644
--- a/tests/ui/borrow_box.rs
+++ b/tests/ui/borrow_box.rs
@@ -4,6 +4,14 @@
 #![allow(dead_code)]
 
 pub fn test1(foo: &mut Box<bool>) {
+    // Although this function could be changed to "&mut bool",
+    // avoiding the Box, mutable references to boxes are not
+    // flagged by this lint.
+    //
+    // This omission is intentional: By passing a mutable Box,
+    // the memory location of the pointed-to object could be
+    // modified. By passing a mutable reference, the contents
+    // could change, but not the location.
     println!("{:?}", foo)
 }
 
@@ -71,6 +79,16 @@ impl<'a> Test12 for Test11<'a> {
     }
 }
 
+pub fn test13(boxed_slice: &mut Box<[i32]>) {
+    // Unconditionally replaces the box pointer.
+    //
+    // This cannot be accomplished if "&mut [i32]" is passed,
+    // and provides a test case where passing a reference to
+    // a Box is valid.
+    let mut data = vec![12];
+    *boxed_slice = data.into_boxed_slice();
+}
+
 fn main() {
     test1(&mut Box::new(false));
     test2();
diff --git a/tests/ui/borrow_box.stderr b/tests/ui/borrow_box.stderr
index 89171ddd7c6..b5db691f89f 100644
--- a/tests/ui/borrow_box.stderr
+++ b/tests/ui/borrow_box.stderr
@@ -1,8 +1,8 @@
 error: you seem to be trying to use `&Box<T>`. Consider using just `&T`
-  --> $DIR/borrow_box.rs:6:19
+  --> $DIR/borrow_box.rs:19:14
    |
-LL | pub fn test1(foo: &mut Box<bool>) {
-   |                   ^^^^^^^^^^^^^^ help: try: `&mut bool`
+LL |     let foo: &Box<bool>;
+   |              ^^^^^^^^^^ help: try: `&bool`
    |
 note: the lint level is defined here
   --> $DIR/borrow_box.rs:1:9
@@ -11,22 +11,16 @@ LL | #![deny(clippy::borrowed_box)]
    |         ^^^^^^^^^^^^^^^^^^^^
 
 error: you seem to be trying to use `&Box<T>`. Consider using just `&T`
-  --> $DIR/borrow_box.rs:11:14
-   |
-LL |     let foo: &Box<bool>;
-   |              ^^^^^^^^^^ help: try: `&bool`
-
-error: you seem to be trying to use `&Box<T>`. Consider using just `&T`
-  --> $DIR/borrow_box.rs:15:10
+  --> $DIR/borrow_box.rs:23:10
    |
 LL |     foo: &'a Box<bool>,
    |          ^^^^^^^^^^^^^ help: try: `&'a bool`
 
 error: you seem to be trying to use `&Box<T>`. Consider using just `&T`
-  --> $DIR/borrow_box.rs:19:17
+  --> $DIR/borrow_box.rs:27:17
    |
 LL |     fn test4(a: &Box<bool>);
    |                 ^^^^^^^^^^ help: try: `&bool`
 
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors