From 0b21c55b725fd7f6d265a18d8425de165c6a8ce1 Mon Sep 17 00:00:00 2001 From: Kirill Chibisov Date: Sun, 8 Jun 2025 22:11:02 +0900 Subject: [PATCH] winit-core/as_any: fix `Box` casting The casting was doing an incorrect check on the `ref` instead of actually trying to downcast a ref as `cast_ref` does. So use `cast_ref` to check whether we can safely `cast` to owned type. --- winit-core/src/as_any.rs | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/winit-core/src/as_any.rs b/winit-core/src/as_any.rs index c22c3621..5274bbe7 100644 --- a/winit-core/src/as_any.rs +++ b/winit-core/src/as_any.rs @@ -55,8 +55,7 @@ macro_rules! impl_dyn_casting { /// /// Returns `Err` with `self` if the object was not from that backend. pub fn cast(self: Box) -> Result, Box> { - let reference: &dyn std::any::Any = self.__as_any(); - if reference.is::() { + if self.cast_ref::().is_some() { let this: Box = self.__into_any(); // Unwrap is okay, we just checked the type of `self` is `T`. Ok(this.downcast::().unwrap()) @@ -69,3 +68,25 @@ macro_rules! impl_dyn_casting { } pub use impl_dyn_casting; + +#[cfg(test)] +mod tests { + use super::AsAny; + + struct Foo; + trait FooTrait: AsAny {} + impl FooTrait for Foo {} + impl_dyn_casting!(FooTrait); + + #[test] + fn dyn_casting() { + let foo_owned: Box = Box::new(Foo); + assert!(foo_owned.cast::().is_ok()); + + let mut foo = Foo; + let foo_ref: &mut dyn FooTrait = &mut foo; + assert!((foo_ref).cast_ref::().is_some()); + assert!((&&&&foo_ref).cast_ref::().is_some()); + assert!(foo_ref.cast_mut::().is_some()); + } +}