Rust 编译器无法识别为结构实现的通用特征绑定

Rust compiler not recognizing a generic trait bound implemented for a struct

我正在使用 Nom, the parser combinator, to write a TOML parser. The parser function I am having trouble with parses a date time string using the chrono 板条箱。

fn offset_datetime<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, TomlValue, E> {
    match DateTime::parse_from_rfc3339(input) {
        ParseResult::Ok(dt) => IResult::Ok(("", TomlValue::OffsetDateTime(dt))),
        ParseResult::Err(e) => {
            Err(Err::Error(Error::from_error_kind(input, ErrorKind::Fail)))
        }
    }
}

Playground

在上面的代码中,我使用 chrono::DatetTime::parse_from_rfc3339 解析字符串切片,其中 returns 和 chrono::format::ParseResult。然后,我匹配它以便我可以将它转换为正确的 nom::IResultParseResult::Ok 手臂没问题,但我无法为 ParseResult::Err 编写正确的代码。这是我在编译上面的代码片段时遇到的错误:

error[E0308]: mismatched types
   --> src/parser.rs:193:28
    |
188 | fn offset_datetime<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, TomlValue, E> {
    |                        - this type parameter
...
193 |             Err(Err::Error(Error::from_error_kind(input, ErrorKind::Fail)))
    |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `E`, found struct `nom::error::Error`
    |
    = note: expected type parameter `E`
                       found struct `nom::error::Error<&str>`

来自 Error::from_error_kindError 是 Nom 自己的结构之一,它具有 implement ParseError 特征,正如 E 泛型指定的那样。为什么编译器不能识别这个?

每当您为函数 (offset_datetime) 提供通用参数 (E) 时,您就承诺该函数可以适用于 E 的所有可能类型] 可能 受其限制。您的函数签名承诺 return 一个错误类型 EIResult。但是你不那样做;相反,你 return 一个错误类型 nom::error::Error (使用 Error::from_error_kind)。

一种可能的修复方法是将函数签名更改为return函数体实际执行的具体错误类型:

fn offset_datetime<'a>(input: &'a str) -> IResult<&'a str, TomlValue, Error<&'a str>> {

另一种方法是更改​​函数体以使用签名声明的通用类型:

        ParseResult::Err(e) => Err(Err::Error(E::from_error_kind(input, ErrorKind::Fail))),

请注意,不是在具体类型 nom::error::Error 上调用 from_error_kind,而是在类型变量 E 上调用它(由于 E: ParseError绑定)。

我不熟悉如何正确使用nom,所以我不能告诉你哪个更合适。