0

I want to make a function that counts occurencies of the actual type in a slice.

struct Struct1;
struct Struct2;

trait Lol {}

impl Lol for Struct1 {}
impl Lol for Struct2 {}

fn countActualTypes<T>(s: &[&dyn Lol]) -> u32 {   
    let mut cnt = 0;        
    s.iter().for_each(|e| {   // (1) e type is &&dyn Lol so *e is &dyn Lol "seems ok"
        if (*e as &dyn Any).is::<T>() { // (2)
            cnt += 1;
        }        
    });   
    cnt
}

fn main() {
    let slice = [&Struct1 as &dyn Lol, &Struct2 as &dyn Lol].as_slice();
    assert_eq!(1, countActualTypes::<Struct1>(slice));    
}

It gives error at (2): error[E0605]: non-primitive cast: &dyn Lol as `&(dyn Any + 'static).

So I thought the reason is the default 'static lifetime of dyn Any and changed the function to this:

fn countActualTypes<'a, T>(s: &[&'a dyn Lol]) -> u32 {   
    let mut cnt = 0;        
    s.iter().for_each(|e| {   // e type is &&dyn Lol (1)
        if (*e as &'a dyn Any).is::<T>() {
            cnt += 1;
        }        
    });   
    cnt
}

Same error. Next I tried this:

fn countActualTypes<'a, T>(s: &[&(dyn Lol + 'a)]) -> u32 {   
    let mut cnt = 0;        
    s.iter().for_each(|e| {   // e type is &&dyn Lol (1)
        if (*e as &(dyn Any + 'a)).is::<T>() {
            cnt += 1;
        }        
    });   
    cnt
}

Error: error[E0605]: non-primitive cast: &dyn Lol as &(dyn Any + 'a)

Q1. Does &(dyn Lol + 'a) and &'a dyn Lol differ?

Q2. How to make it work?

UPDATE: Thanks for answering, I finally came to:

trait Lol: Any {}

fn countActualTypes<T: 'static>(s: &[&dyn Lol]) -> u32 {   
    let mut cnt = 0;        
    s.iter().for_each(|e| {       
        if (*e).type_id() == TypeId::of::<T>() {
            cnt += 1;
        }          
    });   
    cnt
}
user3070377
  • 441
  • 4
  • 10

1 Answers1

2

Does &(dyn Lol + 'a) and &'a dyn Lol differ?

Not really. Both just make lifetime elision explicit, in different aspects of it.

How to make it work?

You cannot convert from Lol to Any unless you built this conversion for the trait Lol. For how, see How to get a reference to a concrete type from a trait object?.

Chayim Friedman
  • 47,971
  • 5
  • 48
  • 77