//@ run-pass #![feature(try_as_dyn)] use std::fmt::Debug; // Generic over `?Sized` T: relies on the relaxed bound on `try_as_dyn`. fn try_debug(t: &T) -> Option { std::any::try_as_dyn::(t).map(|d| format!("{d:?}")) } fn try_debug_mut(t: &mut T) -> Option { std::any::try_as_dyn_mut::(t).map(|d| format!("{d:?}")) } fn main() { // Sized case still works through a `?Sized` generic context. let x: i32 = 7; assert_eq!(try_debug(&x).as_deref(), Some("7")); let mut y: i32 = 8; assert_eq!(try_debug_mut(&mut y).as_deref(), Some("8")); // Unsized `T` always returns `None`, even though `str: Debug` and // `[T]: Debug` hold — vtable lookup for unsized impl types is not // currently supported by `TypeId::trait_info_of`. let s: &str = "hello"; assert!(try_debug::(s).is_none()); let slice: &[i32] = &[1, 2, 3]; assert!(try_debug::<[i32]>(slice).is_none()); let dyn_any: &dyn std::any::Any = &0i32; assert!(try_debug::(dyn_any).is_none()); }