syn::parse::ParseBuffer::peek() 如何接受类型作为参数?

How does syn::parse::ParseBuffer::peek() accept a type as an argument?

我们如何将类型作为参数而不是 turbofish 传递给 syn::parse::ParseBuffer::peek

方法通常被称为input.parse::<Token![;]>()。我们将类型作为泛型传递,但 peek 期望它们作为 input.peek(Token![;]).

我想知道,因为如果我像 type TokenAlias = Token![;] 一样为 Token![;] 创建类型别名并像 input.peek(TokenAlias) 那样使用它, 我收到错误:

expected value, found type alias `TokenAlias` can't use a type alias as a constructor

如果 Token![;] 也不允许的话,这将是有意义的。

为什么我在使用类型别名时会出现此错误?

代码 TokenAlias:

// COMPILE ERROR: expected value, found type alias `TokenAlias` can't use a type alias as a constructor

type TokenAlias = Token![;];

impl Parse for PathSegments {
    fn parse(input: ParseStream) -> Result<Self> {
        let mut segments = Punctuated::new();

        let first = parse_until(input, TokenAlias)?;
        segments.push_value(syn::parse2(first)?);

        while input.peek(TokenAlias) {
            segments.push_punct(input.parse()?);

            let next = parse_until(input, TokenAlias)?;
            segments.push_value(syn::parse2(next)?);
        }

        Ok(PathSegments { segments })
    }
}

Playground

代码 Token![;]:

// BUILDS SUCCESSFULLY

impl Parse for PathSegments {
    fn parse(input: ParseStream) -> Result<Self> {
        let mut segments = Punctuated::new();

        let first = parse_until(input, Token![;])?;
        segments.push_value(syn::parse2(first)?);

        while input.peek(Token![;]) {
            segments.push_punct(input.parse()?);

            let next = parse_until(input, Token![;])?;
            segments.push_value(syn::parse2(next)?);
        }

        Ok(PathSegments { segments })
    }
}

Playground

以下是来自synpeek的源代码:

pub fn peek<T: Peek>(&self, token: T) -> bool {
    let _ = token;
    T::Token::peek(self.cursor())
}

Source code

peek 函数接受标记 ,而不是类型。

它接受 Token[;] 的原因是它扩展为一个标识符,该标识符是对文档隐藏的 a type, but also of a global function 的名称!您的类型别名指的是类型,并且尝试使用构造函数语法为类似单元的结构构造一个值会使编译器抱怨这种语法不适用于类型别名。 (即使是这样,Semi 也不是类似单元的结构,因此它尤其不适用于该类型。)