关联类型的生命周期绑定被拒绝,尽管它看起来有效
lifetime bound on associated type is rejected although it seems valid
我有一段代码无法编译,可以简化为这个片段:
use std::error::Error;
use std::convert::TryFrom;
// A trait that provides methods for parsing data into a type T.
pub trait Deserializable<T> {
// some methods
}
pub struct MyBuffer<'a> {
inner: &'a [u8]
}
impl<'a, T> Deserializable<T> for MyBuffer<'a>
where
T: TryFrom<&'a [u8]>,
<T as TryFrom<&'a [u8]>>::Error: Error + Sync + Send + 'static
{
// some methods to implement
}
fn main() {}
编译器拒绝此程序并显示令人困惑的错误消息:
error[E0310]: the associated type `<T as std::convert::TryFrom<&[u8]>>::Error` may not live long enough
--> src/main.rs:13:13
|
13 | impl<'a, T> Deserializable<T> for MyBuffer<'a>
| ^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `<T as std::convert::TryFrom<&[u8]>>::Error: 'static`...
note: ...so that the type `<T as std::convert::TryFrom<&[u8]>>::Error` will meet its required lifetime bounds
--> src/main.rs:13:13
|
13 | impl<'a, T> Deserializable<T> for MyBuffer<'a>
| ^^^^^^^^^^^^^^^^^
错误提示我添加 'static
lifetime bound,但我已经添加了它:
consider adding an explicit lifetime bound `<T as std::convert::TryFrom<&[u8]>>::Error: 'static`
有人可以解释为什么这个程序不能编译,and/or如何修复它(如果可能)?在我看来,应该 可以让 <T as TryFrom<&'a [u8]>>::Error
成为 'static
,即使 T
本身绑定到 'a
。
我希望 Error
成为 'static
的原因是我使用 failure
并且 failure::Fail
是为 Send + Sync + Error + 'static
实现的。
我仍然不确定为什么,但似乎只是删除错误的静态绑定?
这似乎是编译器推断生命周期和相关类型的能力的一个差距。
有时,为了帮助编译器,您可以添加泛型参数来为关联类型添加别名。这个参数不是 "count" 因为它不会使项目 "more generic",但是因为泛型是在使用而不是声明时解析的,所以它推迟了类型检查的困难部分,直到知道确切的类型.换句话说:编译器可能能够证明任何 particular T::Error
有效,但它不能完全证明 every T::Error
必须工作,所以我们引入一个新参数 E
,它必然是 T::Error
并告诉编译器只有在我们尝试使用它时才弄清楚 E
是什么.
以下作品(playground):
impl<'a, T, E> Deserializable<T> for MyBuffer<'a>
where
T: TryFrom<&'a [u8], Error = E>,
E: Error + Sync + Send + 'static,
{
// ...
}
我们引入了一个新的类型参数E
,而不是边界T::Error
,并限制T
,使其TryFrom::Error
为E
.这在逻辑上(据我所知)与你写的是一样的,但它编译时没有抱怨。
我找不到相关的官方文档;它可能是求解器的固有限制,或者仅仅是一个错误。
我有一段代码无法编译,可以简化为这个片段:
use std::error::Error;
use std::convert::TryFrom;
// A trait that provides methods for parsing data into a type T.
pub trait Deserializable<T> {
// some methods
}
pub struct MyBuffer<'a> {
inner: &'a [u8]
}
impl<'a, T> Deserializable<T> for MyBuffer<'a>
where
T: TryFrom<&'a [u8]>,
<T as TryFrom<&'a [u8]>>::Error: Error + Sync + Send + 'static
{
// some methods to implement
}
fn main() {}
编译器拒绝此程序并显示令人困惑的错误消息:
error[E0310]: the associated type `<T as std::convert::TryFrom<&[u8]>>::Error` may not live long enough
--> src/main.rs:13:13
|
13 | impl<'a, T> Deserializable<T> for MyBuffer<'a>
| ^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `<T as std::convert::TryFrom<&[u8]>>::Error: 'static`...
note: ...so that the type `<T as std::convert::TryFrom<&[u8]>>::Error` will meet its required lifetime bounds
--> src/main.rs:13:13
|
13 | impl<'a, T> Deserializable<T> for MyBuffer<'a>
| ^^^^^^^^^^^^^^^^^
错误提示我添加 'static
lifetime bound,但我已经添加了它:
consider adding an explicit lifetime bound `<T as std::convert::TryFrom<&[u8]>>::Error: 'static`
有人可以解释为什么这个程序不能编译,and/or如何修复它(如果可能)?在我看来,应该 可以让 <T as TryFrom<&'a [u8]>>::Error
成为 'static
,即使 T
本身绑定到 'a
。
我希望 Error
成为 'static
的原因是我使用 failure
并且 failure::Fail
是为 Send + Sync + Error + 'static
实现的。
我仍然不确定为什么,但似乎只是删除错误的静态绑定?
这似乎是编译器推断生命周期和相关类型的能力的一个差距。
有时,为了帮助编译器,您可以添加泛型参数来为关联类型添加别名。这个参数不是 "count" 因为它不会使项目 "more generic",但是因为泛型是在使用而不是声明时解析的,所以它推迟了类型检查的困难部分,直到知道确切的类型.换句话说:编译器可能能够证明任何 particular T::Error
有效,但它不能完全证明 every T::Error
必须工作,所以我们引入一个新参数 E
,它必然是 T::Error
并告诉编译器只有在我们尝试使用它时才弄清楚 E
是什么.
以下作品(playground):
impl<'a, T, E> Deserializable<T> for MyBuffer<'a>
where
T: TryFrom<&'a [u8], Error = E>,
E: Error + Sync + Send + 'static,
{
// ...
}
我们引入了一个新的类型参数E
,而不是边界T::Error
,并限制T
,使其TryFrom::Error
为E
.这在逻辑上(据我所知)与你写的是一样的,但它编译时没有抱怨。
我找不到相关的官方文档;它可能是求解器的固有限制,或者仅仅是一个错误。