SHARE
TWEET

Untitled

a guest May 25th, 2019 62 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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!("---- calling trait_object.generic_fn(T); --\n");
  76.     trait_object.generic_fn(T{});
  77.    
  78.     println!("\n---- calling (*trait_object).generic_fn(T); --\n");
  79.     (*trait_object).generic_fn(T{});
  80. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top