-2

Here's the minimum reproducible example:

trait TestTrait {
    fn as_any(&self) -> &dyn Any;
}

pub fn test() {
    let test_vector : Vec<Box<dyn TestTrait>> = Vec::new();
    // populate the vector
    test_generic(test_vector.get(0).unwrap());
}

fn test_generic<T : 'static + TestTrait>( x:&Box<T> ) -> bool {
    let test_vector : Vec<Box<dyn TestTrait>> = Vec::new();
    // populate the vector
    for value in test_vector.iter() {
        match value.as_any().downcast_ref::<T>() {
            None => {}
            Some(_) => {return true;}
        }
    }
    false
}

This gives this error:

error[E0277]: the size for values of type `dyn TestTrait` cannot be known at compilation time
  --> src\main.rs:37:18
   |
37 |     test_generic(test_vector.get(0).unwrap());
   |     ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
   |     |
   |     required by a bound introduced by this call
   |
   = help: the trait `Sized` is not implemented for `dyn TestTrait`

So what do we have here:

  • There are two vectors of Boxes of items implementing TestTrait

  • test_generic has access to one of the vectors, and test to another

  • I want to know if there are any items in the second vector that have the same type as a specific item from the first vector

Is it possible, or is it gibberish?

I particularly don't understand why it needs to know the size of the type at compile time. It's a Box, isn't it? Its entire shtick is that it can point to a position on the heap that might be arbitrarily sized. I think I misunderstand something fundamental here. The Rust book even gives this exact scenario as a use-case for Boxes:

When you have a type whose size can’t be known at compile time and you want to use a value of that type in a context that requires an exact size

Herohtar
  • 5,347
  • 4
  • 31
  • 41
user2649762
  • 541
  • 3
  • 13
  • Does this answer your question? [What does "Sized is not implemented" mean?](https://stackoverflow.com/questions/28044231/what-does-sized-is-not-implemented-mean) – E_net4 Dec 16 '21 at 16:10
  • Not really. If I permit the type parameter to be ?Sized, the compiler still complains and says specifically that I have to remove the ?Sized constraint – user2649762 Dec 16 '21 at 16:13
  • Please see [ask], then revise your post title to ask a clear, specific question. Do not tack on keyword tags. – isherwood Dec 16 '21 at 20:54

1 Answers1

1

You cannot get a concrete type T from a dynamic type dyn TestTrait; you'd have to already know what T you're looking for.

You can instead match types based on their TypeId:

use std::any::Any;

trait TestTrait {
    fn as_any(&self) -> &dyn Any;
}

pub fn test() {
    let test_vector : Vec<Box<dyn TestTrait>> = Vec::new();
    test_generic(&*test_vector[0]);
}

fn test_generic(x: &dyn TestTrait) -> bool {
    let x_type_id = x.as_any().type_id();
    let test_vector : Vec<Box<dyn TestTrait>> = Vec::new();
    test_vector.iter().any(|value| value.as_any().type_id() == x_type_id)
}
kmdreko
  • 42,554
  • 6
  • 57
  • 106