From: Ian Jackson Date: Mon, 5 Jun 2023 17:53:13 +0000 (+0100) Subject: broken from pad X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ian/git?a=commitdiff_plain;h=9881445c4efb81c08d4e656de8b2a50ce42092c1;p=rust-experiments.git broken from pad --- diff --git a/src/main.rs b/src/main.rs index beb677c..d253eb7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -39,9 +39,29 @@ impl HasPseudoMethods for Frog { } } + +fn cast1(inp: &dyn HasPseudoMethods) -> Option<&dyn HasFeet> { + dbg!(std::any::type_name::<&'static dyn HasFeet>()); + let caster: &'static dyn Any = inp.get_caster(TypeId::of::<&'static dyn HasFeet>())?; + let caster: &'static fn (&dyn HasPseudoMethods) -> &dyn HasFeet = caster.downcast_ref().unwrap(); + let with_feet = caster(inp); + Some(with_feet) +} + + +fn cast2(inp: &dyn HasPseudoMethods) -> Option<&T> { + dbg!(std::any::type_name::<&'static T>()); + let caster: &'static dyn Any = inp.get_caster(TypeId::of::<&'static T>())?; + let caster: &'static fn (&dyn HasPseudoMethods) -> &T = caster.downcast_ref().unwrap(); + let with_feet = caster(inp); + Some(with_feet) +} + + fn main() { let frog = Arc::new(Frog); let erased_frog: Arc = frog as _; +/* let erased_frog: &dyn HasPseudoMethods = &*erased_frog; let caster: &'static dyn Any = erased_frog @@ -51,6 +71,11 @@ fn main() { let caster: &'static fn(&dyn HasPseudoMethods) -> &dyn HasFeet = caster.downcast_ref().unwrap(); let with_feet: &dyn HasFeet = caster(erased_frog); +*/ + // THIS WORKS. + let with_feet: &dyn HasFeet = cast1(erased_frog.as_ref()).unwrap(); + // THIS CRASHES. + let with_feet: &dyn HasFeet = cast2::(erased_frog.as_ref()).unwrap(); println!( "A frog has {} feet and eats .", @@ -58,3 +83,4 @@ fn main() { eats_food.favorite_food()*/ ) } +