Blanket impl、HRTB 和 "impl" 抽象返回类型:"expected bound lifetime parameter"



我启动了一个非常小的程序来玩 Rust 中的解析器组合器,很快就遇到了一个我觉得很奇怪的错误:

trait Parser<T, E> {
    fn parse<'a>(&self, input: &'a [u8]) -> Result<(&'a [u8], T), E>;
}
impl<F, T, E> Parser<T, E> for F
where
    F: for<'a> Fn(&'a [u8]) -> Result<(&'a [u8], T), E>,
{
    fn parse<'a>(&self, input: &'a [u8]) -> Result<(&'a [u8], T), E> {
        (*self)(input)
    }
}
// why can't I write:
// fn byte(b: u8) -> impl Parser<u8, ()> {
// this works, and the blanket Parser impl picks it up correctly
fn byte(b: u8) -> impl for<'a> Fn(&'a [u8]) -> Result<(&'a [u8], u8), ()> {
    move |input: &[u8]| match input.first() {
        Some(x) if *x == b => Ok((&input[1..], *x)),
        _ => Err(()),
    }
}
fn main() {
    println!("{:?}", byte(b'c').parse(b"c123"));
}

byte(返回 impl Parser<u8, ()>(的注释签名编译失败:

error[E0271]: type mismatch resolving `for<'a> <[closure@parser.rs:14:5: 19:6 b:_] as std::ops::FnOnce<(&'a [u8],)>>::Output == std::result::Result<(&'a [u8], u8), ()>`
  --> parser.rs:12:19
   |
12 | fn byte(b: u8) -> impl Parser<u8, ()> {
   |                   ^^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'a, found concrete lifetime
   |
   = note: required because of the requirements on the impl of `Parser<u8, ()>` for `[closure@parser.rs:14:5: 19:6 b:_]`
   = note: the return type of a function must have a statically known size

我既不理解为什么需要绑定生存期参数,也不明白找到了什么具体的生存期。

在我看来,返回的闭包具有某种不可言喻的类型。此类型实现for <'a> Fn(&'a [u8]) -> Result<(&'a [u8], u8), ()>(编译器会识别这一点(。因此,它也应该通过毯子实施Parser<u8, ()>,或者我是这么认为的。

在我看来,返回的闭包具有某种不可言喻的类型。此类型实现 <'a>Fn(&'a [u8]( -> Result<(&'a [u8], u8(、((>(编译器会识别这一点(。

那只是在你指定它的情况下。

考虑没有生存期信息的函数签名:

fn byte(b: u8) -> impl Fn(&[u8]) -> Result<(&[u8], u8), ()>

如果你写出省略的一生,就会给出

fn byte<'a>(b: u8) -> impl Fn(&'a [u8]) -> Result<(&'a [u8], u8), ()>

这不会实现高阶for<'a> Fn ... - 它只实现一些固定'aFn特征,由调用者决定byte

这就是编译器抱怨的具体生存期 - 它期望找到一个受for<...>约束的生存期,而是找到一个已经描述过的生存期。

最新更新