diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 3a92f5806c9ef..b32fc96164a30 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -1349,9 +1349,8 @@ declare_lint! { /// ### Example /// /// ```rust - /// #![feature(box_syntax)] /// fn main() { - /// let a = (box [1, 2, 3]).len(); + /// let a = Box::new([1, 2, 3]).len(); /// } /// ``` /// @@ -1373,6 +1372,11 @@ impl<'tcx> LateLintPass<'tcx> for UnusedAllocation { fn check_expr(&mut self, cx: &LateContext<'_>, e: &hir::Expr<'_>) { match e.kind { hir::ExprKind::Box(_) => {} + hir::ExprKind::Call(path_expr, [_]) + if let hir::ExprKind::Path(qpath) = &path_expr.kind + && let Some(did) = cx.qpath_res(qpath, path_expr.hir_id).opt_def_id() + && cx.tcx.is_diagnostic_item(sym::box_new, did) + => {} _ => return, } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index fb579e4ff772a..a76bf45ec890a 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -429,6 +429,7 @@ symbols! { borrowck_graphviz_format, borrowck_graphviz_postflow, box_free, + box_new, box_patterns, box_syntax, bpf_target_feature, diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 44a37899007f8..241b11c3f5f52 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -214,6 +214,7 @@ impl Box { #[inline(always)] #[stable(feature = "rust1", since = "1.0.0")] #[must_use] + #[rustc_diagnostic_item = "box_new"] pub fn new(x: T) -> Self { #[rustc_box] Box::new(x) diff --git a/library/alloc/src/tests.rs b/library/alloc/src/tests.rs index 299ed156a5d27..b1d3a9fa8ac90 100644 --- a/library/alloc/src/tests.rs +++ b/library/alloc/src/tests.rs @@ -4,7 +4,6 @@ use core::any::Any; use core::clone::Clone; use core::convert::TryInto; use core::ops::Deref; -use core::result::Result::{Err, Ok}; use std::boxed::Box; @@ -15,7 +14,7 @@ fn test_owned_clone() { assert!(a == b); } -#[derive(PartialEq, Eq)] +#[derive(Debug, PartialEq, Eq)] struct Test; #[test] @@ -23,24 +22,17 @@ fn any_move() { let a = Box::new(8) as Box; let b = Box::new(Test) as Box; - match a.downcast::() { - Ok(a) => { - assert!(a == Box::new(8)); - } - Err(..) => panic!(), - } - match b.downcast::() { - Ok(a) => { - assert!(a == Box::new(Test)); - } - Err(..) => panic!(), - } + let a: Box = a.downcast::().unwrap(); + assert_eq!(*a, 8); + + let b: Box = b.downcast::().unwrap(); + assert_eq!(*b, Test); let a = Box::new(8) as Box; let b = Box::new(Test) as Box; - assert!(a.downcast::>().is_err()); - assert!(b.downcast::>().is_err()); + assert!(a.downcast::>().is_err()); + assert!(b.downcast::>().is_err()); } #[test] diff --git a/tests/ui/issues/issue-3029.rs b/tests/ui/issues/issue-3029.rs index a5d30960a4cdb..43c8a0a23fb5b 100644 --- a/tests/ui/issues/issue-3029.rs +++ b/tests/ui/issues/issue-3029.rs @@ -2,9 +2,7 @@ // error-pattern:so long // ignore-emscripten no processes -#![allow(unused_allocation)] #![allow(unreachable_code)] -#![allow(unused_variables)] fn main() { let mut x = Vec::new(); diff --git a/tests/ui/iterators/into-iter-on-arrays-lint.fixed b/tests/ui/iterators/into-iter-on-arrays-lint.fixed index 6e02a7024b949..5b91aaf9ea554 100644 --- a/tests/ui/iterators/into-iter-on-arrays-lint.fixed +++ b/tests/ui/iterators/into-iter-on-arrays-lint.fixed @@ -2,7 +2,7 @@ // run-rustfix // rustfix-only-machine-applicable -#[allow(unused_must_use)] +#[allow(unused_must_use, unused_allocation)] fn main() { let small = [1, 2]; let big = [0u8; 33]; diff --git a/tests/ui/iterators/into-iter-on-arrays-lint.rs b/tests/ui/iterators/into-iter-on-arrays-lint.rs index 582d5cadd0658..25b0cef73d777 100644 --- a/tests/ui/iterators/into-iter-on-arrays-lint.rs +++ b/tests/ui/iterators/into-iter-on-arrays-lint.rs @@ -2,7 +2,7 @@ // run-rustfix // rustfix-only-machine-applicable -#[allow(unused_must_use)] +#[allow(unused_must_use, unused_allocation)] fn main() { let small = [1, 2]; let big = [0u8; 33]; diff --git a/tests/ui/lint/unused/unused-allocation.rs b/tests/ui/lint/unused/unused-allocation.rs new file mode 100644 index 0000000000000..c1a6f5ceaf178 --- /dev/null +++ b/tests/ui/lint/unused/unused-allocation.rs @@ -0,0 +1,7 @@ +#![feature(rustc_attrs, stmt_expr_attributes)] +#![deny(unused_allocation)] + +fn main() { + _ = (#[rustc_box] Box::new([1])).len(); //~ error: unnecessary allocation, use `&` instead + _ = Box::new([1]).len(); //~ error: unnecessary allocation, use `&` instead +} diff --git a/tests/ui/lint/unused/unused-allocation.stderr b/tests/ui/lint/unused/unused-allocation.stderr new file mode 100644 index 0000000000000..c9ccfbd30e5d4 --- /dev/null +++ b/tests/ui/lint/unused/unused-allocation.stderr @@ -0,0 +1,20 @@ +error: unnecessary allocation, use `&` instead + --> $DIR/unused-allocation.rs:5:9 + | +LL | _ = (#[rustc_box] Box::new([1])).len(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/unused-allocation.rs:2:9 + | +LL | #![deny(unused_allocation)] + | ^^^^^^^^^^^^^^^^^ + +error: unnecessary allocation, use `&` instead + --> $DIR/unused-allocation.rs:6:9 + | +LL | _ = Box::new([1]).len(); + | ^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/self/arbitrary_self_types_trait.rs b/tests/ui/self/arbitrary_self_types_trait.rs index 973c7cae85a94..c4651ec717787 100644 --- a/tests/ui/self/arbitrary_self_types_trait.rs +++ b/tests/ui/self/arbitrary_self_types_trait.rs @@ -1,4 +1,5 @@ // run-pass +#![allow(unused_allocation)] use std::rc::Rc; @@ -13,7 +14,7 @@ impl Trait for Vec { } fn main() { - let v = vec![1,2,3]; + let v = vec![1, 2, 3]; - assert_eq!(&[1,2,3], Box::new(Rc::new(v)).trait_method()); + assert_eq!(&[1, 2, 3], Box::new(Rc::new(v)).trait_method()); } diff --git a/tests/ui/structs-enums/align-struct.rs b/tests/ui/structs-enums/align-struct.rs index f5418e754b239..54092542f98fa 100644 --- a/tests/ui/structs-enums/align-struct.rs +++ b/tests/ui/structs-enums/align-struct.rs @@ -1,5 +1,5 @@ // run-pass -#![allow(dead_code)] +#![allow(dead_code, unused_allocation)] use std::mem; @@ -20,7 +20,6 @@ struct AlignMany(i32); // Raising alignment may not alter size. #[repr(align(8))] -#[allow(dead_code)] struct Align8Many { a: i32, b: i32, @@ -29,9 +28,8 @@ struct Align8Many { } enum Enum { - #[allow(dead_code)] A(i32), - B(Align16) + B(Align16), } // Nested alignment - use `#[repr(C)]` to suppress field reordering for sizeof test @@ -73,7 +71,7 @@ struct AlignLarge { union UnionContainsAlign { a: Align16, - b: f32 + b: f32, } impl Align16 { @@ -158,7 +156,7 @@ pub fn main() { // Note that the size of Nested may change if struct field re-ordering is enabled assert_eq!(mem::align_of::(), 16); assert_eq!(mem::size_of::(), 48); - let a = Nested{ a: 1, b: 2, c: Align16(3), d: 4}; + let a = Nested { a: 1, b: 2, c: Align16(3), d: 4 }; assert_eq!(mem::align_of_val(&a), 16); assert_eq!(mem::align_of_val(&a.b), 4); assert_eq!(mem::align_of_val(&a.c), 16); @@ -179,8 +177,8 @@ pub fn main() { assert_eq!(a.0, 15); assert_eq!(mem::align_of_val(a), 16); assert_eq!(mem::size_of_val(a), 16); - }, - _ => () + } + _ => (), } assert!(is_aligned_to(&e, 16)); @@ -197,8 +195,8 @@ pub fn main() { } // arrays of aligned elements should also be aligned - assert_eq!(mem::align_of::<[Align16;2]>(), 16); - assert_eq!(mem::size_of::<[Align16;2]>(), 32); + assert_eq!(mem::align_of::<[Align16; 2]>(), 16); + assert_eq!(mem::size_of::<[Align16; 2]>(), 32); let a = [Align16(0), Align16(1)]; assert_eq!(mem::align_of_val(&a[0]), 16); @@ -209,7 +207,7 @@ pub fn main() { assert_eq!(mem::align_of_val(Box::new(Align16(0)).as_ref()), 16); // check heap array is aligned - let a = vec!(Align16(0), Align16(1)); + let a = vec![Align16(0), Align16(1)]; assert_eq!(mem::align_of_val(&a[0]), 16); assert_eq!(mem::align_of_val(&a[1]), 16); @@ -224,16 +222,14 @@ pub fn main() { assert_eq!(mem::align_of::(), 16); assert_eq!(mem::size_of::(), 32); - let a = AlignContainsPacked4C { a: Packed4C{ a: 1, b: 2 }, b: 3 }; + let a = AlignContainsPacked4C { a: Packed4C { a: 1, b: 2 }, b: 3 }; assert_eq!(mem::align_of_val(&a), 16); assert_eq!(mem::align_of_val(&a.a), 4); assert_eq!(mem::align_of_val(&a.b), mem::align_of::()); assert_eq!(mem::size_of_val(&a), 32); assert!(is_aligned_to(&a, 16)); - let mut large = Box::new(AlignLarge { - stuff: [0; 0x10000], - }); + let mut large = Box::new(AlignLarge { stuff: [0; 0x10000] }); large.stuff[0] = 132; *large.stuff.last_mut().unwrap() = 102; assert_eq!(large.stuff[0], 132);