1

I'm new to Rust and I have been looking around without any success. This is what I'm trying to do that resulted in the error:

error: implementation of `UseA1Trait` is not general enough
  --> src/lib.rs:77:24
   |
48 |     fn new(a1: T, a2:U) -> Self;
   |     ---------------------------- due to a where-clause on `OuterStructTrait::new`...
...
77 |     let outer_struct = OuterStruct::new(use_a1, use_a2);
   |                        ^^^^^^^^^^^^^^^^ doesn't satisfy where-clause
   |
   = note: ...`UseA1Trait<'0>` would have to be implemented for the type `UseA1<'_>`, for any lifetime `'0`...
   = note: ...but `UseA1Trait<'1>` is actually implemented for the type `UseA1<'1>`, for some specific lifetime `'1`
struct A {}

impl A {
    fn new() -> A {
        A {}
    }
}

trait UseA1Trait<'a> 
{
   fn new(a: &'a A) -> Self;
}

impl <'a> UseA1Trait<'a> for UseA1<'a> {
    fn new(a: &'a A) -> UseA1 {
        UseA1 {
            a
        }
    }
}

struct UseA1<'a> {
    a: &'a A
}

trait UseA2Trait<'a> 
{
   fn new(a: &'a A) -> Self;
}

struct UseA2<'a> {
    a: &'a A
}

impl <'a> UseA2Trait<'a> for UseA2<'a> {
    fn new(a: &'a A) -> UseA2 {
        UseA2 {
            a
        }
    }
}

trait OuterStructTrait<T,U>
where 
     T:for<'a> UseA1Trait<'a>,
     U:for<'a> UseA2Trait<'a>,
{
    fn new(a1: T, a2:U) -> Self;
}

struct OuterStruct<T: for<'a> UseA1Trait<'a>, U: for<'a> UseA2Trait<'a>> {
    a1: T,
    a2: U,
}

impl<T, U> OuterStructTrait<T, U> for OuterStruct<T, U>
where
    T: for<'a> UseA1Trait<'a>,
    U: for<'a> UseA2Trait<'a>, 
{
    fn new(a1: T, a2: U) -> OuterStruct<T, U> 
    {
      OuterStruct {
            a1,
            a2,
      }
    }
}

fn main() {
    let a = A::new();

    let use_a1 = UseA1::new(&a);
    let use_a2 = UseA2::new(&a);

    let outer_struct = OuterStruct::new(use_a1, use_a2);
}

I'm suspecting that use_a1 and use_a2 has to be forced to share the same lifetime but I have no idea how I can do this.

kmdreko
  • 25,172
  • 5
  • 32
  • 61
CChyuan
  • 103
  • 9
  • Should `T` and `U` share the same lifetime, or use separate ones? – kmdreko Sep 04 '21 at 18:41
  • It doesn't matter that `use_a1` and `use_a2` don't share the same lifetime: [you get the same error with just `use_a1`](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=b0dbc372ac3280ae37496a4623892068). It's not clear how this should be solved, though, because the design is so abstract. Should the bound on `OuterStruct` be relaxed? Or should the `impl` on `UseA1`/`UseA2` be restricted? Only you can decide... – trent Sep 04 '21 at 22:25
  • As an exercise, consider [just deleting all the bounds](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=e4b62552fb931982236590847f0c62dd). This compiles. Now, for each bound you want to add back: what is wrong with the current solution? How is adding a bound going to help? *Where* does that bound belong -- on a `trait`, on an `impl`, on a `fn`? (Bounds on a `struct`, though legal, [are almost never what you want](/a/66369912).) If you don't have a clear idea of the answers to these questions, you're likely to find yourself at odds with the compiler. – trent Sep 04 '21 at 22:47

0 Answers0