Skip to content

Commit 2efc2d6

Browse files
committed
Auto merge of #5491 - smklein:borrowed_box, r=flip1995
Fix issue #2907. Update the "borrow box" lint to avoid recommending the following conversion: ``` // Old pub fn f(&mut Box<T>) {...} // New pub fn f(&mut T) {...} ``` Given a mutable reference to a box, functions may want to change "which" object the Box is pointing at. This change avoids recommending removing the "Box" parameter for mutable references. changelog: Don't trigger [`borrow_box`] lint on `&mut Box` references
2 parents e5fe56d + 0ef5dee commit 2efc2d6

File tree

3 files changed

+31
-19
lines changed

3 files changed

+31
-19
lines changed

clippy_lints/src/types.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -531,11 +531,12 @@ impl Types {
531531
} else {
532532
format!("{} ", lt.name.ident().as_str())
533533
};
534-
let mutopt = if mut_ty.mutbl == Mutability::Mut {
535-
"mut "
536-
} else {
537-
""
538-
};
534+
535+
if mut_ty.mutbl == Mutability::Mut {
536+
// Ignore `&mut Box<T>` types; see issue #2907 for
537+
// details.
538+
return;
539+
}
539540
let mut applicability = Applicability::MachineApplicable;
540541
span_lint_and_sugg(
541542
cx,
@@ -544,9 +545,8 @@ impl Types {
544545
"you seem to be trying to use `&Box<T>`. Consider using just `&T`",
545546
"try",
546547
format!(
547-
"&{}{}{}",
548+
"&{}{}",
548549
ltopt,
549-
mutopt,
550550
&snippet_with_applicability(cx, inner.span, "..", &mut applicability)
551551
),
552552
Applicability::Unspecified,

tests/ui/borrow_box.rs

+18
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@
44
#![allow(dead_code)]
55

66
pub fn test1(foo: &mut Box<bool>) {
7+
// Although this function could be changed to "&mut bool",
8+
// avoiding the Box, mutable references to boxes are not
9+
// flagged by this lint.
10+
//
11+
// This omission is intentional: By passing a mutable Box,
12+
// the memory location of the pointed-to object could be
13+
// modified. By passing a mutable reference, the contents
14+
// could change, but not the location.
715
println!("{:?}", foo)
816
}
917

@@ -71,6 +79,16 @@ impl<'a> Test12 for Test11<'a> {
7179
}
7280
}
7381

82+
pub fn test13(boxed_slice: &mut Box<[i32]>) {
83+
// Unconditionally replaces the box pointer.
84+
//
85+
// This cannot be accomplished if "&mut [i32]" is passed,
86+
// and provides a test case where passing a reference to
87+
// a Box is valid.
88+
let mut data = vec![12];
89+
*boxed_slice = data.into_boxed_slice();
90+
}
91+
7492
fn main() {
7593
test1(&mut Box::new(false));
7694
test2();

tests/ui/borrow_box.stderr

+6-12
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error: you seem to be trying to use `&Box<T>`. Consider using just `&T`
2-
--> $DIR/borrow_box.rs:6:19
2+
--> $DIR/borrow_box.rs:19:14
33
|
4-
LL | pub fn test1(foo: &mut Box<bool>) {
5-
| ^^^^^^^^^^^^^^ help: try: `&mut bool`
4+
LL | let foo: &Box<bool>;
5+
| ^^^^^^^^^^ help: try: `&bool`
66
|
77
note: the lint level is defined here
88
--> $DIR/borrow_box.rs:1:9
@@ -11,22 +11,16 @@ LL | #![deny(clippy::borrowed_box)]
1111
| ^^^^^^^^^^^^^^^^^^^^
1212

1313
error: you seem to be trying to use `&Box<T>`. Consider using just `&T`
14-
--> $DIR/borrow_box.rs:11:14
15-
|
16-
LL | let foo: &Box<bool>;
17-
| ^^^^^^^^^^ help: try: `&bool`
18-
19-
error: you seem to be trying to use `&Box<T>`. Consider using just `&T`
20-
--> $DIR/borrow_box.rs:15:10
14+
--> $DIR/borrow_box.rs:23:10
2115
|
2216
LL | foo: &'a Box<bool>,
2317
| ^^^^^^^^^^^^^ help: try: `&'a bool`
2418

2519
error: you seem to be trying to use `&Box<T>`. Consider using just `&T`
26-
--> $DIR/borrow_box.rs:19:17
20+
--> $DIR/borrow_box.rs:27:17
2721
|
2822
LL | fn test4(a: &Box<bool>);
2923
| ^^^^^^^^^^ help: try: `&bool`
3024

31-
error: aborting due to 4 previous errors
25+
error: aborting due to 3 previous errors
3226

0 commit comments

Comments
 (0)