2

Given a Box<str> I would like to produce a Box<dyn _> for it. Concretely:

trait StringLike {
    fn length(&self) -> usize;
}

impl StringLike for str {
    fn length(&self) -> usize {
        self.len()
    }
}

fn main() {
    let x1: String = "test".to_owned();
    let x2: Box<str> = x1.into_boxed_str();
    let x3: Box<dyn StringLike> = x2;
}

This gives an error on x3 stating that:

error[E0277]: the size for values of type `str` cannot be known at compilation time
  --> src/main.rs:15:35
   |
15 |     let x3: Box<dyn StringLike> = x2;
   |                                   ^^ doesn't have a size known at compile-time
   |
   = help: the trait `std::marker::Sized` is not implemented for `str`
   = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
   = note: required for the cast to the object type `dyn StringLike`

The second link explains that:

Due to Rust’s need to know certain details, such as how much space to allocate for a value of a particular type, there is a corner of its type system that can be confusing: the concept of dynamically sized types.

I understand that, but in this instance I want to go from a Box<str> (which I believe internally looks like *str) to a Box<dyn StringLike> (which I believe internally looks like (*str, *vtable_Stringlike)), so I don't see the conceptual requirement to know the type of str at compile-time.

Is it possible to do the conversion? If not, is that for conceptual reasons or just currently unavailable?

Neil Mitchell
  • 9,090
  • 1
  • 27
  • 85
  • 1
    I think this is answered over at [Use trait object to pass str in rust](https://stackoverflow.com/questions/57817405/use-trait-object-to-pass-str-in-rust). – trent Apr 21 '20 at 21:46
  • 1
    The short version: it's not possible because `*str` and `*dyn StringLike` are both fat pointers but they need the extra pointer-sized metadata for conflicting reasons. You can't directly cast one kind of fat pointer to a different kind of fat pointer. In effect, the implementation of `StringLike` for `str` can *only* be dispatched statically, never dynamically. – trent Apr 21 '20 at 21:49
  • Thanks @trentcl - that gets to the heart of my question - I hadn't realised &str was a fat pointer. The links in that other question are helpful, and the details in https://stackoverflow.com/questions/57754901/what-is-a-fat-pointer-in-rust explain why. – Neil Mitchell Apr 22 '20 at 07:27

0 Answers0