Box is Unsized?

I'm trying to make this trait work:

pub trait ToUser {
  type O;
  fn to_user(self, msg: String) -> Result<Self::O, UserFacing>;
}

impl<T, E> ToUser for Result<T, Box<E>> where E: Error + 'static + ?Sized {
  type O = T;

  fn to_user(self, msg: String) -> Result<Self::O, UserFacing> {
    match self {
      Ok(o) => Ok(o),
      Err(e) => Err(UserFacing {msg, source: Some(e)})
    }

  }
}

but I'm seeing this error message:

||     |
|| 100 | impl<T, E> ToUser for Result<T, Box<E>> where E: Error + 'static + ?Sized {
||     |         - this type parameter needs to be `std::marker::Sized`
|| ...
|| 106 |       Err(e) => Err(UserFacing {msg, source: Some(e)})
||     |                                                   ^ doesn't have a size known at compile-time
||     |
||     = note: required for the cast to the object type `dyn StdError`
|| For more information about this error, try `rustc --explain E0277`.

That's somewhat surprising. Note that e is of type Box<E>, so it should be Sized, right? What can I do here? I specifically want to use that trait for Result<T, Box<dyn Error>>, and I can just replace E by Box<dyn Error> here to make it all work. I'd just like to understand what's going on...

In case it matters, here's the definition of UserFacing:

#[derive(Debug)]
pub struct UserFacing {
  pub msg: String,
  pub source: Option<Box<dyn Error>>,
}

Can you add an example in the playground?

in the meantime, you can try this :wink:

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=773a71a0a6bd456ea2cdea9a21768526

Adding .into() did not help.

You can't convert a Box<T> where T: Error + ?Sized to Box<dyn Error>. You must remove the ?Sized bound.

This is because you can't construct virtual tables at runtime, so all the information needs to he available at compile time, which is only possible for sized types.

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.