diff --git a/clippy_lints/src/types.rs b/clippy_lints/src/types.rs index ed0027af5..b537ad5e7 100644 --- a/clippy_lints/src/types.rs +++ b/clippy_lints/src/types.rs @@ -10,7 +10,7 @@ use syntax::ast::{IntTy, UintTy, FloatTy}; use syntax::attr::IntType; use syntax::codemap::Span; use utils::{comparisons, higher, in_external_macro, in_macro, match_def_path, snippet, span_help_and_lint, span_lint, - span_lint_and_sugg, opt_def_id, last_path_segment, type_size}; + span_lint_and_sugg, opt_def_id, last_path_segment, type_size, match_path_old}; use utils::paths; /// Handles all the linting of funky types @@ -212,6 +212,17 @@ fn check_ty(cx: &LateContext, ast_ty: &hir::Ty, is_local: bool) { let PathParameters::AngleBracketedParameters(ref ab_data) = bx.parameters, let [ref inner] = *ab_data.types ], { + if_let_chain! {[ + let TyTraitObject(ref traits, _) = inner.node, + traits.len() >= 1, + // Only Send/Sync can be used as additional traits, so it is enough to + // check only the first trait. + match_path_old(&traits[0].trait_ref.path, &paths::ANY_TRAIT) + ], { + // Ignore `Box` types, see #1884 for details. + return; + }} + let ltopt = if lt.is_elided() { "".to_owned() } else { diff --git a/clippy_lints/src/utils/paths.rs b/clippy_lints/src/utils/paths.rs index 675d70878..d5d252009 100644 --- a/clippy_lints/src/utils/paths.rs +++ b/clippy_lints/src/utils/paths.rs @@ -1,6 +1,7 @@ //! This module contains paths to types and functions Clippy needs to know //! about. +pub const ANY_TRAIT: [&'static str; 3] = ["std", "any", "Any"]; pub const ASMUT_TRAIT: [&'static str; 3] = ["core", "convert", "AsMut"]; pub const ASREF_TRAIT: [&'static str; 3] = ["core", "convert", "AsRef"]; pub const BEGIN_PANIC: [&'static str; 3] = ["std", "panicking", "begin_panic"]; diff --git a/tests/ui/borrow_box.rs b/tests/ui/borrow_box.rs index ef569ab03..b5543da6e 100644 --- a/tests/ui/borrow_box.rs +++ b/tests/ui/borrow_box.rs @@ -28,7 +28,57 @@ impl<'a> Test4 for Test3<'a> { } } +use std::any::Any; + +pub fn test5(foo: &mut Box) { + println!("{:?}", foo) +} + +pub fn test6() { + let foo: &Box; +} + +struct Test7<'a> { + foo: &'a Box +} + +trait Test8 { + fn test8(a: &Box); +} + +impl<'a> Test8 for Test7<'a> { + fn test8(a: &Box) { + unimplemented!(); + } +} + +pub fn test9(foo: &mut Box) { + let _ = foo; +} + +pub fn test10() { + let foo: &Box; +} + +struct Test11<'a> { + foo: &'a Box +} + +trait Test12 { + fn test4(a: &Box); +} + +impl<'a> Test12 for Test11<'a> { + fn test4(a: &Box) { + unimplemented!(); + } +} + fn main(){ test1(&mut Box::new(false)); test2(); + test5(&mut (Box::new(false) as Box)); + test6(); + test9(&mut (Box::new(false) as Box)); + test10(); }