News for hackers. Stuff that matters.
Re:What's in the Box? by justinsaccount on Monday April 19, 2021 @04:37PM (#26867703)
That actually makes perfect sense to me.

I ran into that issue trying to port something else to rust, just didn't realize it was this same issue. In go you just define an interface and then make a slice of that interface and put things in it. In rust I ended up having to do

  Vec<Box<dyn Checker>>
I think initially I tried just doing a

  Vec<Checker>
and when that failed I ended up putting something like "How do I make a vec of an impl in rust" and found a code sample.

That's where the compiler just saying "The types don't match" is not very helpful.

Re:What's in the Box? by brundolf on Monday April 19, 2021 @07:47PM (#26869147)
I think the fundamental issue is that most languages these days use dynamic-dispatch invisibly and by default. Rust seeks to empower users to be more efficient by default (which is good), but sometimes, especially on this iterators case, it creates deeply confusing/frustrating barriers that have to be explicitly stepped around.
Re:What's in the Box? by estebank on Monday April 19, 2021 @05:47PM (#26868299)
If I'm following correctly, you had a situation like the following, right?

https://play.rust-lang.org/?version=stable&mode=debug&editio...

    error[E0277]: the size for values of type `dyn std::fmt::Display` cannot be known at compilation time
       --> src/main.rs:5:12
        |
    5   |     let y: Vec<dyn Display> = x.into_iter().collect();
        |            ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
        |
        = help: the trait `Sized` is not implemented for `dyn std::fmt::Display`
    
    error[E0277]: a value of type `Vec<dyn std::fmt::Display>` cannot be built from an iterator over elements of type `{integer}`
     --> src/main.rs:5:45
      |
    5 |     let y: Vec<dyn Display> = x.into_iter().collect();
      |                                             ^^^^^^^ value of type `Vec<dyn std::fmt::Display>` cannot be built from `std::iter::Iterator<Item={integer}>`
      |
      = help: the trait `FromIterator<{integer}>` is not implemented for `Vec<dyn std::fmt::Display>`
    
    error[E0277]: the size for values of type `dyn std::fmt::Display` cannot be known at compilation time
       --> src/main.rs:5:31
        |
    5   |     let y: Vec<dyn Display> = x.into_iter().collect();
        |                               ^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
        |
        = help: the trait `Sized` is not implemented for `dyn std::fmt::Display`
I can see a bunch of places where we could improve the output that we haven't gotten to yet:

- The third error shouldn't have been emitted in the first place, the first two are more than enough

- The first error has a note, but that note with a little bit of work could be turned into a structured suggestion for boxing or borrowing

- For the second suggestion we could detect this case in particular where the result would be !Sized and also suggest Boxing.

Edit: filed https://github.com/rust-lang/rust/issues/84346

It is also somehow unfortunate that `impl Trait` in locals isn't yet in stable, but once it is it would let you write `let z: Vec<impl Display> = x.into_iter().collect();`, but as you can see here, that doesn't currently work even on nightly: https://play.rust-lang.org/?version=nightly&mode=debug&editi...