diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index b5c5fc0608b95..3fbd7db765b70 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -48,7 +48,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { } let ty = cx.tables.expr_ty(&expr); - let type_permits_lack_of_use = check_must_use_ty(cx, ty, &expr, s.span, ""); + let type_permits_lack_of_use = check_must_use_ty(cx, ty, &expr, s.span, "", ""); let mut fn_warned = false; let mut op_warned = false; @@ -133,6 +133,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { ty: Ty<'tcx>, expr: &hir::Expr, span: Span, + descr_pre_path: &str, descr_post_path: &str, ) -> bool { if ty.is_unit() || cx.tcx.is_ty_uninhabited_from( @@ -142,14 +143,22 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { } match ty.sty { - ty::Adt(def, _) => check_must_use_def(cx, def.did, span, "", descr_post_path), + ty::Adt(..) if ty.is_box() => { + let boxed_ty = ty.boxed_ty(); + let descr_pre_path = &format!("{}boxed ", descr_pre_path); + check_must_use_ty(cx, boxed_ty, expr, span, descr_pre_path, descr_post_path) + } + ty::Adt(def, _) => { + check_must_use_def(cx, def.did, span, descr_pre_path, descr_post_path) + } ty::Opaque(def, _) => { let mut has_emitted = false; for (predicate, _) in &cx.tcx.predicates_of(def).predicates { if let ty::Predicate::Trait(ref poly_trait_predicate) = predicate { let trait_ref = poly_trait_predicate.skip_binder().trait_ref; let def_id = trait_ref.def_id; - if check_must_use_def(cx, def_id, span, "implementer of ", "") { + let descr_pre = &format!("{}implementer of ", descr_pre_path); + if check_must_use_def(cx, def_id, span, descr_pre, descr_post_path) { has_emitted = true; break; } @@ -162,7 +171,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { for predicate in binder.skip_binder().iter() { if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate { let def_id = trait_ref.def_id; - if check_must_use_def(cx, def_id, span, "", " trait object") { + let descr_post = &format!(" trait object{}", descr_post_path); + if check_must_use_def(cx, def_id, span, descr_pre_path, descr_post) { has_emitted = true; break; } @@ -181,7 +191,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { for (i, ty) in tys.iter().map(|k| k.expect_ty()).enumerate() { let descr_post_path = &format!(" in tuple element {}", i); let span = *spans.get(i).unwrap_or(&span); - if check_must_use_ty(cx, ty, expr, span, descr_post_path) { + if check_must_use_ty(cx, ty, expr, span, descr_pre_path, descr_post_path) { has_emitted = true; } } diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs index 9ef42063f9412..797d85e941d96 100644 --- a/src/libstd/panicking.rs +++ b/src/libstd/panicking.rs @@ -103,7 +103,9 @@ pub fn set_hook(hook: Box) + 'static + Sync + Send>) { HOOK_LOCK.write_unlock(); if let Hook::Custom(ptr) = old_hook { - Box::from_raw(ptr); + #[allow(unused_must_use)] { + Box::from_raw(ptr); + } } } } diff --git a/src/test/ui/lint/must_use-trait.rs b/src/test/ui/lint/must_use-trait.rs index 23df4fa6132d3..0aa751443a080 100644 --- a/src/test/ui/lint/must_use-trait.rs +++ b/src/test/ui/lint/must_use-trait.rs @@ -17,6 +17,23 @@ fn get_critical() -> impl NotSoCritical + Critical + DecidedlyUnimportant { Anon {} } +fn get_boxed_critical() -> Box { + Box::new(Anon {}) +} + +fn get_nested_boxed_critical() -> Box> { + Box::new(Box::new(Anon {})) +} + +fn get_critical_tuple() -> (u32, Box, impl Critical, ()) { + (0, get_boxed_critical(), get_critical(), ()) +} + fn main() { get_critical(); //~ ERROR unused implementer of `Critical` that must be used + get_boxed_critical(); //~ ERROR unused boxed `Critical` trait object that must be used + get_nested_boxed_critical(); + //~^ ERROR unused boxed boxed `Critical` trait object that must be used + get_critical_tuple(); //~ ERROR unused boxed `Critical` trait object in tuple element 1 + //~^ ERROR unused implementer of `Critical` in tuple element 2 } diff --git a/src/test/ui/lint/must_use-trait.stderr b/src/test/ui/lint/must_use-trait.stderr index 7e2b2f67964ac..be74362e29d62 100644 --- a/src/test/ui/lint/must_use-trait.stderr +++ b/src/test/ui/lint/must_use-trait.stderr @@ -1,5 +1,5 @@ error: unused implementer of `Critical` that must be used - --> $DIR/must_use-trait.rs:21:5 + --> $DIR/must_use-trait.rs:33:5 | LL | get_critical(); | ^^^^^^^^^^^^^^^ @@ -10,5 +10,29 @@ note: lint level defined here LL | #![deny(unused_must_use)] | ^^^^^^^^^^^^^^^ -error: aborting due to previous error +error: unused boxed `Critical` trait object that must be used + --> $DIR/must_use-trait.rs:34:5 + | +LL | get_boxed_critical(); + | ^^^^^^^^^^^^^^^^^^^^^ + +error: unused boxed boxed `Critical` trait object that must be used + --> $DIR/must_use-trait.rs:35:5 + | +LL | get_nested_boxed_critical(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: unused boxed `Critical` trait object in tuple element 1 that must be used + --> $DIR/must_use-trait.rs:37:5 + | +LL | get_critical_tuple(); + | ^^^^^^^^^^^^^^^^^^^^^ + +error: unused implementer of `Critical` in tuple element 2 that must be used + --> $DIR/must_use-trait.rs:37:5 + | +LL | get_critical_tuple(); + | ^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 5 previous errors