@@ -10,25 +10,35 @@ use rustc_session::declare_lint_pass;
1010declare_clippy_lint ! {
1111 /// ### What it does
1212 ///
13- /// Detects cases where a `&dyn Any` is constructed directly referencing a `Box< dyn Any>` or
14- /// other value that dereferences to `dyn Any`.
13+ /// Protects against unintended coercion of references to container types to `& dyn Any`
14+ /// when the container type dereferences to a `dyn Any` which could be reborrowed instead .
1515 ///
1616 /// ### Why is this bad?
1717 ///
18- /// The intention is usually to borrow the `dyn Any` available by dereferencing the value,
19- /// rather than the value itself .
18+ /// The intention is usually to get a reference to the `dyn Any` the value derefernces to ,
19+ /// rather than getting a `&dyn Any` which is actually referring to the outer container type .
2020 ///
2121 /// ### Example
22+ ///
23+ /// Here we see that because `Box<dyn Any>` itself implements `Any`, `&Box<dyn Any>`
24+ /// gets coerced to an `&dyn Any` which refers to *the `Box` itself`*, rather than the
25+ /// inner `dyn Any`.
2226 /// ```no_run
2327 /// # use std::any::Any;
24- /// let x: Box<dyn Any> = Box::new(());
25- /// let _: &dyn Any = &x;
28+ /// let x: Box<dyn Any> = Box::new(0u32);
29+ /// let dyn_any_of_box: &dyn Any = &x;
30+ ///
31+ /// // Fails as we have a &dyn Any to the Box, not the u32
32+ /// assert_eq!(dyn_any_of_box.downcast_ref::<u32>(), None);
2633 /// ```
2734 /// Use instead:
2835 /// ```no_run
2936 /// # use std::any::Any;
30- /// let x: Box<dyn Any> = Box::new(());
31- /// let _: &dyn Any = &*x;
37+ /// let x: Box<dyn Any> = Box::new(0u32);
38+ /// let dyn_any_of_u32: &dyn Any = &*x;
39+ ///
40+ /// // Succeeds sincwe have a &dyn Any to the inner u32!
41+ /// assert_eq!(dyn_any_of_u32.downcast_ref::<u32>(), Some(&0u32));
3242 /// ```
3343 #[ clippy:: version = "1.88.0" ]
3444 pub COERCE_ANY_REF_TO_ANY ,
0 commit comments