Advertisement
Guest User

Untitled

a guest
May 25th, 2019
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.66 KB | None | 0 0
  1. #![feature(core_intrinsics)]
  2. use std::intrinsics::type_name;
  3.  
  4. /////////////////////////////////////////////////////////////////////
  5. // Suppose these are the real traits from Serde.
  6.  
  7. trait Querializer {}
  8.  
  9. trait Generic {
  10. // Not object safe because of this generic method.
  11. fn generic_fn<Q: Querializer>(&self, querializer: Q);
  12. }
  13.  
  14. impl<'a, T> Querializer for &'a T where T: Querializer + ?Sized {}
  15.  
  16. impl<'a, T> Generic for Box<T> where T: Generic + ?Sized {
  17. fn generic_fn<Q: Querializer>(&self, querializer: Q) {
  18. let name = unsafe { type_name::<T>() };
  19. println!("impl-1# T=({})#\t\t call to 'generic_fn()' for 'impl<'a, T> Generic for Box<T> where T: Generic + ?Sized'", name);
  20. (**self).generic_fn(querializer)
  21. }
  22. }
  23.  
  24. /////////////////////////////////////////////////////////////////////
  25. // This is an object-safe equivalent that interoperates seamlessly.
  26.  
  27. trait ErasedGeneric {
  28. fn erased_fn(&self, querializer: &Querializer);
  29. }
  30.  
  31. impl Generic for ErasedGeneric {
  32. // Depending on the trait method signatures and the upstream
  33. // impls, could also implement for:
  34. //
  35. // - &'a ErasedGeneric
  36. // - &'a (ErasedGeneric + Send)
  37. // - &'a (ErasedGeneric + Sync)
  38. // - &'a (ErasedGeneric + Send + Sync)
  39. // - Box<ErasedGeneric>
  40. // - Box<ErasedGeneric + Send>
  41. // - Box<ErasedGeneric + Sync>
  42. // - Box<ErasedGeneric + Send + Sync>
  43. fn generic_fn<Q: Querializer>(&self, querializer: Q) {
  44. println!("impl-2# T=([hardcoded]ErasedGeneric)#\t call to 'generic_fn()' for 'impl Generic for ErasedGeneric'");
  45. self.erased_fn(&querializer)
  46. }
  47. }
  48.  
  49. impl<T> ErasedGeneric for T where T: Generic {
  50. fn erased_fn(&self, querializer: &Querializer) {
  51. let name = unsafe { type_name::<T>() };
  52. println!("impl-3# T=({})#\t\t\t call to 'erased_fn()' for 'impl<T> ErasedGeneric for T where T: Generic'", name);
  53. self.generic_fn(querializer)
  54. }
  55. }
  56.  
  57. fn main() {
  58. struct T;
  59. impl Querializer for T {}
  60.  
  61. struct S;
  62. impl Generic for S {
  63. fn generic_fn<Q: Querializer>(&self, _querializer: Q) {
  64. println!("impl-4# T=([hard-coded]S)#\t\t call to 'generic_fn()' querying the real S");
  65. }
  66. }
  67.  
  68. // Construct a trait object.
  69. let trait_object: Box<ErasedGeneric> = Box::new(S{});
  70.  
  71. // Seamlessly invoke the generic method on the trait object.
  72. //
  73. // THIS LINE LOOKS LIKE MAGIC. We have a value of type trait
  74. // object and we are invoking a generic method on it.
  75. println!("---- call-1# trait_object.generic_fn(T); --\n");
  76. trait_object.generic_fn(T{});
  77.  
  78. println!("\n---- call-2# (*trait_object).generic_fn(T); --\n");
  79. (*trait_object).generic_fn(T{});
  80. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement