The following is the code and what the error said. I do not paste the all code, because I think the solution may be simple. If nessacery I could paste the whole code.

``````trait ForeCalc {
type A;
type B;
fn calc(&self, di: &'_ Di, data: Self::A) -> Self::B;
}

pub trait Ta {
type A<'a>: where Self: 'a;
type B;
fn from_di<'c, 'a>(&'c self, di: &'a Di) -> Self::A<'a>;
fn from_da<'e, 'a>(&'e self, da: Self::A<'a>) -> Self::B;
}

impl<'a, K> ForeCalc for K
where
K: Ta<A<'a> = Vec<f32>, B = Vec<f32>> + 'static,
{
type A = i32;
type B = Vec<f32>;
fn calc(&self, di: &'_ Di, _data: Self::A) -> Self::B
{
self.from_di(di)
}
}
Error: lifetime may not live long enough
โญโ[command_42:1:1]
โ
9 โ impl<'a, K> ForeCalc for K
ยท      โโฌ
ยท       โฐโโ lifetime `'a` defined here
ยท
15 โ     fn calc(&self, di: &'_ Di, _data: Self::A) -> Self::B
ยท                        โฌ
ยท                        โฐโโ let's call the lifetime of this reference `'1`
ยท
17 โ         self.from_di(di)
ยท         โโโโโโโโโฌโโโโโโโ
ยท                 โฐโโโโโโโโโ argument requires that `'1` must outlive `'a`
โโโโโฏ
``````

To diagnose this, weโll need to see the definitions of `trait Ta` and `fn from_di` at least. If you can, post enough code so that we can recreate the problem on the playground.

1 Like

Yes, I append the `trait Ta` in it.

The problem is that your bound on `K` only specifies the associated type `A` for the specific lifetime `'a`, which might be different than the lifetime of the reference `&Di`. You need to instead require that for every possible lifetime 'a, `A<'a>=Vec<f32>`:

``````
impl<K> ForeCalc for K
where
K: for<'a> Ta<A<'a> = Vec<f32>, B = Vec<f32>> + 'static,
{
type A = i32;
type B = Vec<f32>;
fn calc(&self, di: & Di, _data: Self::A) -> Self::B
{
self.from_di(di)
}
}
``````
1 Like

After I changed my code, there is one more problem:
This works fine:

``````pub struct Rank(usize, usize);
impl Rank {
pub fn rank(&self, data: Vec<f32>) -> Vec<f32> {
vec![1.0f32, 2, 3]
}
}

impl ForeCalc for Rank {
type A = Vec<f32>;
type B = Vec<f32>;
fn calc(&self, di: &'_ Di, data: Self::A) -> Self::B {
self.rank(data)
}
}

impl<K> ForeCalc for K
where
K: for<'a> Ta<A<'a> = Vec<f32>, B = Vec<f32>> + 'static,
{
type A = i32;
type B = Vec<f32>;
fn calc(&self, di: & Di, _data: Self::A) -> Self::B
{
self.from_di(di)
}
}
``````

But when I move `Rank` to my crate, the code crash.

``````//my crate: Outer.rs
pub struct Rank(usize, usize);
impl Rank {
pub fn rank(&self, data: Vec<f32>) -> Vec<f32> {
vec![1.0f32, 2, 3]
}
}
``````

Then in main.rs

``````use crate::Outer;

impl ForeCalc for Outer::Rank {
type A = Vec<f32>;
type B = Vec<f32>;
fn calc(&self, di: &'_ Di, data: Self::A) -> Self::B {
self.rank(data)
}
}

impl<K> ForeCalc for K
where
K: for<'a> Ta<A<'a> = Vec<f32>, B = Vec<f32>> + 'static,
{
type A = i32;
type B = Vec<f32>;
fn calc(&self, di: & Di, _data: Self::A) -> Self::B
{
self.from_di(di)
}
}

[E0119] Error: conflicting implementations of trait `ForeCalc` for type `bt::aa::Rank`
โญโ[command_56:1:1]
โ
1 โ impl ForeCalc for Rank {
ยท โโโโโโโโโโโโฌโโโโโโโโโโ
ยท            โฐโโโโโโโโโโโโ first implementation here
ยท
9 โ impl<K> ForeCalc for K
ยท โโโโโโโโโโโโฌโโโโโโโโโโ
ยท            โฐโโโโโโโโโโโโ conflicting implementation for `bt::aa::Rank`
โโโโฏ
``````

I guess the reason is:

When `Rank` comes from other crate, the compilter can not know if the `Rank` is implemented the `trait` `ForeCalc`. So, if `Rank` has been implemented `ForeCalc`, then

``````impl<K> ForeCalc for K
where
K: for<'a> Ta<A<'a> = Vec<f32>, B = Vec<f32>> + 'static,
``````

this where make a duplicate implementing on `Rank`.

But when `Rank` comes from local file, the compiler does know weather the `Rank` has been implemted `ForeCalc`.
If this guess is true, what can I do to avoid it?

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.