Skip to content

Commit fbc121f

Browse files
authored
Rollup merge of #104363 - WaffleLapkin:bonk_box_new, r=Nilstrieb
Make `unused_allocation` lint against `Box::new` too Previously it only linted against `box` syntax, which likely won't ever be stabilized, which is pretty useless. Even now I'm not sure if it's a meaningful lint, but it's at least something 🤷 This means that code like the following will be linted against: ```rust Box::new([1, 2, 3]).len(); f(&Box::new(1)); // where f : &i32 -> () ``` The lint works by checking if a `Box::new` (or `box`) expression has an a borrow adjustment, meaning that the code that first stores the box in a variable won't be linted against: ```rust let boxed = Box::new([1, 2, 3]); // no lint boxed.len(); ```
2 parents e350fe4 + a90abd6 commit fbc121f

File tree

11 files changed

+59
-39
lines changed

11 files changed

+59
-39
lines changed

compiler/rustc_lint/src/unused.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1349,9 +1349,8 @@ declare_lint! {
13491349
/// ### Example
13501350
///
13511351
/// ```rust
1352-
/// #![feature(box_syntax)]
13531352
/// fn main() {
1354-
/// let a = (box [1, 2, 3]).len();
1353+
/// let a = Box::new([1, 2, 3]).len();
13551354
/// }
13561355
/// ```
13571356
///
@@ -1373,6 +1372,11 @@ impl<'tcx> LateLintPass<'tcx> for UnusedAllocation {
13731372
fn check_expr(&mut self, cx: &LateContext<'_>, e: &hir::Expr<'_>) {
13741373
match e.kind {
13751374
hir::ExprKind::Box(_) => {}
1375+
hir::ExprKind::Call(path_expr, [_])
1376+
if let hir::ExprKind::Path(qpath) = &path_expr.kind
1377+
&& let Some(did) = cx.qpath_res(qpath, path_expr.hir_id).opt_def_id()
1378+
&& cx.tcx.is_diagnostic_item(sym::box_new, did)
1379+
=> {}
13761380
_ => return,
13771381
}
13781382

compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,7 @@ symbols! {
429429
borrowck_graphviz_format,
430430
borrowck_graphviz_postflow,
431431
box_free,
432+
box_new,
432433
box_patterns,
433434
box_syntax,
434435
bpf_target_feature,

library/alloc/src/boxed.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ impl<T> Box<T> {
214214
#[inline(always)]
215215
#[stable(feature = "rust1", since = "1.0.0")]
216216
#[must_use]
217+
#[rustc_diagnostic_item = "box_new"]
217218
pub fn new(x: T) -> Self {
218219
#[rustc_box]
219220
Box::new(x)

library/alloc/src/tests.rs

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use core::any::Any;
44
use core::clone::Clone;
55
use core::convert::TryInto;
66
use core::ops::Deref;
7-
use core::result::Result::{Err, Ok};
87

98
use std::boxed::Box;
109

@@ -15,32 +14,25 @@ fn test_owned_clone() {
1514
assert!(a == b);
1615
}
1716

18-
#[derive(PartialEq, Eq)]
17+
#[derive(Debug, PartialEq, Eq)]
1918
struct Test;
2019

2120
#[test]
2221
fn any_move() {
2322
let a = Box::new(8) as Box<dyn Any>;
2423
let b = Box::new(Test) as Box<dyn Any>;
2524

26-
match a.downcast::<i32>() {
27-
Ok(a) => {
28-
assert!(a == Box::new(8));
29-
}
30-
Err(..) => panic!(),
31-
}
32-
match b.downcast::<Test>() {
33-
Ok(a) => {
34-
assert!(a == Box::new(Test));
35-
}
36-
Err(..) => panic!(),
37-
}
25+
let a: Box<i32> = a.downcast::<i32>().unwrap();
26+
assert_eq!(*a, 8);
27+
28+
let b: Box<Test> = b.downcast::<Test>().unwrap();
29+
assert_eq!(*b, Test);
3830

3931
let a = Box::new(8) as Box<dyn Any>;
4032
let b = Box::new(Test) as Box<dyn Any>;
4133

42-
assert!(a.downcast::<Box<Test>>().is_err());
43-
assert!(b.downcast::<Box<i32>>().is_err());
34+
assert!(a.downcast::<Box<i32>>().is_err());
35+
assert!(b.downcast::<Box<Test>>().is_err());
4436
}
4537

4638
#[test]

tests/ui/issues/issue-3029.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22
// error-pattern:so long
33
// ignore-emscripten no processes
44

5-
#![allow(unused_allocation)]
65
#![allow(unreachable_code)]
7-
#![allow(unused_variables)]
86

97
fn main() {
108
let mut x = Vec::new();

tests/ui/iterators/into-iter-on-arrays-lint.fixed

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// run-rustfix
33
// rustfix-only-machine-applicable
44

5-
#[allow(unused_must_use)]
5+
#[allow(unused_must_use, unused_allocation)]
66
fn main() {
77
let small = [1, 2];
88
let big = [0u8; 33];

tests/ui/iterators/into-iter-on-arrays-lint.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// run-rustfix
33
// rustfix-only-machine-applicable
44

5-
#[allow(unused_must_use)]
5+
#[allow(unused_must_use, unused_allocation)]
66
fn main() {
77
let small = [1, 2];
88
let big = [0u8; 33];
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#![feature(rustc_attrs, stmt_expr_attributes)]
2+
#![deny(unused_allocation)]
3+
4+
fn main() {
5+
_ = (#[rustc_box] Box::new([1])).len(); //~ error: unnecessary allocation, use `&` instead
6+
_ = Box::new([1]).len(); //~ error: unnecessary allocation, use `&` instead
7+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error: unnecessary allocation, use `&` instead
2+
--> $DIR/unused-allocation.rs:5:9
3+
|
4+
LL | _ = (#[rustc_box] Box::new([1])).len();
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
note: the lint level is defined here
8+
--> $DIR/unused-allocation.rs:2:9
9+
|
10+
LL | #![deny(unused_allocation)]
11+
| ^^^^^^^^^^^^^^^^^
12+
13+
error: unnecessary allocation, use `&` instead
14+
--> $DIR/unused-allocation.rs:6:9
15+
|
16+
LL | _ = Box::new([1]).len();
17+
| ^^^^^^^^^^^^^
18+
19+
error: aborting due to 2 previous errors
20+

tests/ui/self/arbitrary_self_types_trait.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// run-pass
2+
#![allow(unused_allocation)]
23

34
use std::rc::Rc;
45

@@ -13,7 +14,7 @@ impl Trait for Vec<i32> {
1314
}
1415

1516
fn main() {
16-
let v = vec![1,2,3];
17+
let v = vec![1, 2, 3];
1718

18-
assert_eq!(&[1,2,3], Box::new(Rc::new(v)).trait_method());
19+
assert_eq!(&[1, 2, 3], Box::new(Rc::new(v)).trait_method());
1920
}

0 commit comments

Comments
 (0)