I think the confusion is based on the fact that this compiles:
fn check_peek(buf: syn::parse::ParseBuffer) {
buf.peek(syn::Ident);
buf.peek(syn::Lifetime);
}
...despite both syn::Ident
and syn::Lifetime
seemingly being types and not values.
To check what's really going on, let's ask the compiler: if you treat these two as values, allowing us to pass them as arguments, surely they have a type - what is this type, then? Standard trick for asking this - assign them to the place of wrong type:
fn check_types() {
let _: () = syn::Ident;
let _: () = syn::Lifetime;
}
Errors:
error[E0308]: mismatched types
--> src/lib.rs:2:17
|
2 | let _: () = syn::Ident;
| -- ^^^^^^^^^^ expected `()`, found fn item
| |
| expected due to this
|
= note: expected unit type `()`
found fn item `fn(syn::lookahead::TokenMarker) -> syn::Ident {syn::Ident}`
error[E0308]: mismatched types
--> src/lib.rs:3:17
|
3 | let _: () = syn::Lifetime;
| -- ^^^^^^^^^^^^^ expected `()`, found fn item
| |
| expected due to this
|
= note: expected unit type `()`
found fn item `fn(syn::lookahead::TokenMarker) -> syn::Lifetime {syn::Lifetime}`
So, both syn::Ident
and syn::Lifetime
are not only types, but also values - namely, function items (or just functions). And, indeed, there they are in source - here's Ident
, here's Lifetime
. They are both doc(hidden)
, so they don't appear in documentation.
As for why the function items can be used as Peek
types - well, that's the only things that can, in fact, since there's only one implementation:
impl<F: Copy + FnOnce(TokenMarker) -> T, T: Token> Peek for F {
type Token = T;
}
where TokenMarker
is some private type, ensuring that such function can't be created outside syn
.