How to have a struct as a field in another struct when there is a type argument?


#1

How to correct the code here? I did not get how traits and lifetimes get mixed. Would be very grateful if someone can explain why I’m getting this error and instruct on the correct way to fix it.

pub struct Interface<'a, 'b, 'c, DeviceT: Device + 'a> {}

pub struct Foo {
    iface: Interface<'static, 'static, 'static, Device + 'static>,
}

pub trait Device {
    type RxBuffer: AsRef<[u8]>;
    type TxBuffer: AsRef<[u8]> + AsMut<[u8]>;
}
error[E0191]: the value of the associated type `TxBuffer` (from the trait `Device`) must be specified
 --> src/main.rs:4:50
  |
4 |     iface : Interface<'static, 'static, 'static, Device + 'static>,
  |                                                  ^^^^^^^^^^^^^^^^ missing associated type `TxBuffer` value

error[E0191]: the value of the associated type `RxBuffer` (from the trait `Device`) must be specified
 --> src/main.rs:4:50
  |
4 |     iface : Interface<'static, 'static, 'static, Device + 'static>,
  |                                                  ^^^^^^^^^^^^^^^^ missing associated type `RxBuffer` value

#2

Foo is generic over type which implements Device trait and has 'static lifetime, so you have to reflect this fact in its signature:

pub struct Foo<T: Device + 'static> {
    iface: Interface<'static, 'static, 'static, T>,
}

#3

Thanks, How to have the lifetime parameters in the implementation of Foo?

impl Foo {
}


#4
struct Foo<'a> { ... }

impl<'a> Foo<'a> { ... }

But perhaps you can be more specific about your needs.


#5

Thanks, although I meant was how to have the parameters if Foo is

pub struct Foo<T: Device + 'static> {
iface: Interface<'static, 'static, 'static, T>,
}

impl <?> Foo <?> {
}

What should I include in place of ?. Having <T: Device + 'static> at both places gives a compilation error.


#6
impl<T: Device + 'static> Foo<T> { ... }

#7

Thanks a lot. Really appreciate some help again. This is really confusing to me.

pub static ref FOO: MutexIrqSafe<Foo> = MutexIrqSafe::new(Foo{

    });

This would result in the following error

error[E0243]: wrong number of type arguments: expected 1, found 0
–> network/src/server2.rs:25:45
|
25 | pub static ref FOO: MutexIrqSafe<Foo> = MutexIrqSafe::new(Foo{
| ^^^^^^ expected 1 type argument


#8

You need to initialize Foo properly - it expects a type parameter and you need to initialize the iface field which is where the type parameter is used.


#9

Hi Didn’t quite get it. MutexIrqSafe<Foo> what is the type parameter that the compiler is requesting?


#10

You’re missing the T in Foo<T>.


#11

This results in

pub static ref FOO: MutexIrqSafe<Foo<T>> = MutexIrqSafe::new(Foo{

    });

error[E0412]: cannot find type T in this scope


#12

You have to specify a real type for T at this point. It’s like Vec<T> - when you want to actually use it with something concrete, you need to give a concrete type (e.g. Vec<i32>).