dyn trait coherence design meeting

Background gist


trait Object<U> {
    type Output;
}

impl<T: ?Sized, U> Object<U> for T {
// ^-- Here is the blanket impl; relies on `?Sized`.
    type Output = U;
}

fn foo<T: ?Sized, U>(x: <T as Object<U>>::Output) -> U {
    x
}

fn transmute<T, U>(x: T) -> U {
    foo::<dyn Object<U, Output = T>, U>(x)
}

Notes from meeting


why have a vtable impl?


// trait MyWrite: Write
impl<T: Write + ?Sized> MyWrite for T {
  fn my_write(&self) { self.write(); }
}

fn foo<T: ?Sized + Any>(x: &T) {
    let foo = x.type_id();
}

  • observation on Any trait
  • if we made it default, that would allow other crates to specialize Any, which we don’t want
  • why does dyn Any: Any?
  • why not have virtual calls in MIR, in particular

// Upstream crate
impl<A> Object for A { 
  default type Output = ();
}

fn foo<T>() {
  let y: T::Output = ..;
  // before specialization: T::Output = ()
  // after specialization: T::Output kept as a placeholder
}