// SPDX-License-Identifier: Apache-2.0 OR MIT12//! Parsing interface for parsing a token stream into a syntax tree node.3//!4//! Parsing in Syn is built on parser functions that take in a [`ParseStream`]5//! and produce a [`Result<T>`] where `T` is some syntax tree node. Underlying6//! these parser functions is a lower level mechanism built around the7//! [`Cursor`] type. `Cursor` is a cheaply copyable cursor over a range of8//! tokens in a token stream.9//!10//! [`Result<T>`]: Result11//! [`Cursor`]: crate::buffer::Cursor12//!13//! # Example14//!15//! Here is a snippet of parsing code to get a feel for the style of the16//! library. We define data structures for a subset of Rust syntax including17//! enums (not shown) and structs, then provide implementations of the [`Parse`]18//! trait to parse these syntax tree data structures from a token stream.19//!20//! Once `Parse` impls have been defined, they can be called conveniently from a21//! procedural macro through [`parse_macro_input!`] as shown at the bottom of22//! the snippet. If the caller provides syntactically invalid input to the23//! procedural macro, they will receive a helpful compiler error message24//! pointing out the exact token that triggered the failure to parse.25//!26//! [`parse_macro_input!`]: crate::parse_macro_input!27//!28//! ```29//! # extern crate proc_macro;30//! #31//! use proc_macro::TokenStream;32//! use syn::{braced, parse_macro_input, token, Field, Ident, Result, Token};33//! use syn::parse::{Parse, ParseStream};34//! use syn::punctuated::Punctuated;35//!36//! enum Item {37//! Struct(ItemStruct),38//! Enum(ItemEnum),39//! }40//!41//! struct ItemStruct {42//! struct_token: Token![struct],43//! ident: Ident,44//! brace_token: token::Brace,45//! fields: Punctuated<Field, Token![,]>,46//! }47//! #48//! # enum ItemEnum {}49//!50//! impl Parse for Item {51//! fn parse(input: ParseStream) -> Result<Self> {52//! let lookahead = input.lookahead1();53//! if lookahead.peek(Token![struct]) {54//! input.parse().map(Item::Struct)55//! } else if lookahead.peek(Token![enum]) {56//! input.parse().map(Item::Enum)57//! } else {58//! Err(lookahead.error())59//! }60//! }61//! }62//!63//! impl Parse for ItemStruct {64//! fn parse(input: ParseStream) -> Result<Self> {65//! let content;66//! Ok(ItemStruct {67//! struct_token: input.parse()?,68//! ident: input.parse()?,69//! brace_token: braced!(content in input),70//! fields: content.parse_terminated(Field::parse_named, Token![,])?,71//! })72//! }73//! }74//! #75//! # impl Parse for ItemEnum {76//! # fn parse(input: ParseStream) -> Result<Self> {77//! # unimplemented!()78//! # }79//! # }80//!81//! # const IGNORE: &str = stringify! {82//! #[proc_macro]83//! # };84//! pub fn my_macro(tokens: TokenStream) -> TokenStream {85//! let input = parse_macro_input!(tokens as Item);86//!87//! /* ... */88//! # TokenStream::new()89//! }90//! ```91//!92//! # The `syn::parse*` functions93//!94//! The [`syn::parse`], [`syn::parse2`], and [`syn::parse_str`] functions serve95//! as an entry point for parsing syntax tree nodes that can be parsed in an96//! obvious default way. These functions can return any syntax tree node that97//! implements the [`Parse`] trait, which includes most types in Syn.98//!99//! [`syn::parse`]: crate::parse()100//! [`syn::parse2`]: crate::parse2()101//! [`syn::parse_str`]: crate::parse_str()102//!103//! ```104//! use syn::Type;105//!106//! # fn run_parser() -> syn::Result<()> {107//! let t: Type = syn::parse_str("std::collections::HashMap<String, Value>")?;108//! # Ok(())109//! # }110//! #111//! # run_parser().unwrap();112//! ```113//!114//! The [`parse_quote!`] macro also uses this approach.115//!116//! [`parse_quote!`]: crate::parse_quote!117//!118//! # The `Parser` trait119//!120//! Some types can be parsed in several ways depending on context. For example121//! an [`Attribute`] can be either "outer" like `#[...]` or "inner" like122//! `#![...]` and parsing the wrong one would be a bug. Similarly [`Punctuated`]123//! may or may not allow trailing punctuation, and parsing it the wrong way124//! would either reject valid input or accept invalid input.125//!126//! [`Attribute`]: crate::Attribute127//! [`Punctuated`]: crate::punctuated128//!129//! The `Parse` trait is not implemented in these cases because there is no good130//! behavior to consider the default.131//!132//! ```compile_fail133//! # extern crate proc_macro;134//! #135//! # use syn::punctuated::Punctuated;136//! # use syn::{PathSegment, Result, Token};137//! #138//! # fn f(tokens: proc_macro::TokenStream) -> Result<()> {139//! #140//! // Can't parse `Punctuated` without knowing whether trailing punctuation141//! // should be allowed in this context.142//! let path: Punctuated<PathSegment, Token![::]> = syn::parse(tokens)?;143//! #144//! # Ok(())145//! # }146//! ```147//!148//! In these cases the types provide a choice of parser functions rather than a149//! single `Parse` implementation, and those parser functions can be invoked150//! through the [`Parser`] trait.151//!152//!153//! ```154//! # extern crate proc_macro;155//! #156//! use proc_macro::TokenStream;157//! use syn::parse::Parser;158//! use syn::punctuated::Punctuated;159//! use syn::{Attribute, Expr, PathSegment, Result, Token};160//!161//! fn call_some_parser_methods(input: TokenStream) -> Result<()> {162//! // Parse a nonempty sequence of path segments separated by `::` punctuation163//! // with no trailing punctuation.164//! let tokens = input.clone();165//! let parser = Punctuated::<PathSegment, Token![::]>::parse_separated_nonempty;166//! let _path = parser.parse(tokens)?;167//!168//! // Parse a possibly empty sequence of expressions terminated by commas with169//! // an optional trailing punctuation.170//! let tokens = input.clone();171//! let parser = Punctuated::<Expr, Token![,]>::parse_terminated;172//! let _args = parser.parse(tokens)?;173//!174//! // Parse zero or more outer attributes but not inner attributes.175//! let tokens = input.clone();176//! let parser = Attribute::parse_outer;177//! let _attrs = parser.parse(tokens)?;178//!179//! Ok(())180//! }181//! ```182183#[path = "discouraged.rs"]184pub mod discouraged;185186use crate::buffer::{Cursor, TokenBuffer};187use crate::error;188use crate::lookahead;189use crate::punctuated::Punctuated;190use crate::token::Token;191use proc_macro2::{Delimiter, Group, Literal, Punct, Span, TokenStream, TokenTree};192#[cfg(feature = "printing")]193use quote::ToTokens;194use std::cell::Cell;195use std::fmt::{self, Debug, Display};196#[cfg(feature = "extra-traits")]197use std::hash::{Hash, Hasher};198use std::marker::PhantomData;199use std::mem;200use std::ops::Deref;201use std::panic::{RefUnwindSafe, UnwindSafe};202use std::rc::Rc;203use std::str::FromStr;204205pub use crate::error::{Error, Result};206pub use crate::lookahead::{End, Lookahead1, Peek};207208/// Parsing interface implemented by all types that can be parsed in a default209/// way from a token stream.210///211/// Refer to the [module documentation] for details about implementing and using212/// the `Parse` trait.213///214/// [module documentation]: self215pub trait Parse: Sized {216fn parse(input: ParseStream) -> Result<Self>;217}218219/// Input to a Syn parser function.220///221/// See the methods of this type under the documentation of [`ParseBuffer`]. For222/// an overview of parsing in Syn, refer to the [module documentation].223///224/// [module documentation]: self225pub type ParseStream<'a> = &'a ParseBuffer<'a>;226227/// Cursor position within a buffered token stream.228///229/// This type is more commonly used through the type alias [`ParseStream`] which230/// is an alias for `&ParseBuffer`.231///232/// `ParseStream` is the input type for all parser functions in Syn. They have233/// the signature `fn(ParseStream) -> Result<T>`.234///235/// ## Calling a parser function236///237/// There is no public way to construct a `ParseBuffer`. Instead, if you are238/// looking to invoke a parser function that requires `ParseStream` as input,239/// you will need to go through one of the public parsing entry points.240///241/// - The [`parse_macro_input!`] macro if parsing input of a procedural macro;242/// - One of [the `syn::parse*` functions][syn-parse]; or243/// - A method of the [`Parser`] trait.244///245/// [`parse_macro_input!`]: crate::parse_macro_input!246/// [syn-parse]: self#the-synparse-functions247pub struct ParseBuffer<'a> {248scope: Span,249// Instead of Cell<Cursor<'a>> so that ParseBuffer<'a> is covariant in 'a.250// The rest of the code in this module needs to be careful that only a251// cursor derived from this `cell` is ever assigned to this `cell`.252//253// Cell<Cursor<'a>> cannot be covariant in 'a because then we could take a254// ParseBuffer<'a>, upcast to ParseBuffer<'short> for some lifetime shorter255// than 'a, and then assign a Cursor<'short> into the Cell.256//257// By extension, it would not be safe to expose an API that accepts a258// Cursor<'a> and trusts that it lives as long as the cursor currently in259// the cell.260cell: Cell<Cursor<'static>>,261marker: PhantomData<Cursor<'a>>,262unexpected: Cell<Option<Rc<Cell<Unexpected>>>>,263}264265impl<'a> Drop for ParseBuffer<'a> {266fn drop(&mut self) {267if let Some((unexpected_span, delimiter)) = span_of_unexpected_ignoring_nones(self.cursor())268{269let (inner, old_span) = inner_unexpected(self);270if old_span.is_none() {271inner.set(Unexpected::Some(unexpected_span, delimiter));272}273}274}275}276277impl<'a> Display for ParseBuffer<'a> {278fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {279Display::fmt(&self.cursor().token_stream(), f)280}281}282283impl<'a> Debug for ParseBuffer<'a> {284fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {285Debug::fmt(&self.cursor().token_stream(), f)286}287}288289impl<'a> UnwindSafe for ParseBuffer<'a> {}290impl<'a> RefUnwindSafe for ParseBuffer<'a> {}291292/// Cursor state associated with speculative parsing.293///294/// This type is the input of the closure provided to [`ParseStream::step`].295///296/// [`ParseStream::step`]: ParseBuffer::step297///298/// # Example299///300/// ```301/// use proc_macro2::TokenTree;302/// use syn::Result;303/// use syn::parse::ParseStream;304///305/// // This function advances the stream past the next occurrence of `@`. If306/// // no `@` is present in the stream, the stream position is unchanged and307/// // an error is returned.308/// fn skip_past_next_at(input: ParseStream) -> Result<()> {309/// input.step(|cursor| {310/// let mut rest = *cursor;311/// while let Some((tt, next)) = rest.token_tree() {312/// match &tt {313/// TokenTree::Punct(punct) if punct.as_char() == '@' => {314/// return Ok(((), next));315/// }316/// _ => rest = next,317/// }318/// }319/// Err(cursor.error("no `@` was found after this point"))320/// })321/// }322/// #323/// # fn remainder_after_skipping_past_next_at(324/// # input: ParseStream,325/// # ) -> Result<proc_macro2::TokenStream> {326/// # skip_past_next_at(input)?;327/// # input.parse()328/// # }329/// #330/// # use syn::parse::Parser;331/// # let remainder = remainder_after_skipping_past_next_at332/// # .parse_str("a @ b c")333/// # .unwrap();334/// # assert_eq!(remainder.to_string(), "b c");335/// ```336pub struct StepCursor<'c, 'a> {337scope: Span,338// This field is covariant in 'c.339cursor: Cursor<'c>,340// This field is contravariant in 'c. Together these make StepCursor341// invariant in 'c. Also covariant in 'a. The user cannot cast 'c to a342// different lifetime but can upcast into a StepCursor with a shorter343// lifetime 'a.344//345// As long as we only ever construct a StepCursor for which 'c outlives 'a,346// this means if ever a StepCursor<'c, 'a> exists we are guaranteed that 'c347// outlives 'a.348marker: PhantomData<fn(Cursor<'c>) -> Cursor<'a>>,349}350351impl<'c, 'a> Deref for StepCursor<'c, 'a> {352type Target = Cursor<'c>;353354fn deref(&self) -> &Self::Target {355&self.cursor356}357}358359impl<'c, 'a> Copy for StepCursor<'c, 'a> {}360361impl<'c, 'a> Clone for StepCursor<'c, 'a> {362fn clone(&self) -> Self {363*self364}365}366367impl<'c, 'a> StepCursor<'c, 'a> {368/// Triggers an error at the current position of the parse stream.369///370/// The `ParseStream::step` invocation will return this same error without371/// advancing the stream state.372pub fn error<T: Display>(self, message: T) -> Error {373error::new_at(self.scope, self.cursor, message)374}375}376377pub(crate) fn advance_step_cursor<'c, 'a>(proof: StepCursor<'c, 'a>, to: Cursor<'c>) -> Cursor<'a> {378// Refer to the comments within the StepCursor definition. We use the379// fact that a StepCursor<'c, 'a> exists as proof that 'c outlives 'a.380// Cursor is covariant in its lifetime parameter so we can cast a381// Cursor<'c> to one with the shorter lifetime Cursor<'a>.382let _ = proof;383unsafe { mem::transmute::<Cursor<'c>, Cursor<'a>>(to) }384}385386pub(crate) fn new_parse_buffer(387scope: Span,388cursor: Cursor,389unexpected: Rc<Cell<Unexpected>>,390) -> ParseBuffer {391ParseBuffer {392scope,393// See comment on `cell` in the struct definition.394cell: Cell::new(unsafe { mem::transmute::<Cursor, Cursor<'static>>(cursor) }),395marker: PhantomData,396unexpected: Cell::new(Some(unexpected)),397}398}399400pub(crate) enum Unexpected {401None,402Some(Span, Delimiter),403Chain(Rc<Cell<Unexpected>>),404}405406impl Default for Unexpected {407fn default() -> Self {408Unexpected::None409}410}411412impl Clone for Unexpected {413fn clone(&self) -> Self {414match self {415Unexpected::None => Unexpected::None,416Unexpected::Some(span, delimiter) => Unexpected::Some(*span, *delimiter),417Unexpected::Chain(next) => Unexpected::Chain(next.clone()),418}419}420}421422// We call this on Cell<Unexpected> and Cell<Option<T>> where temporarily423// swapping in a None is cheap.424fn cell_clone<T: Default + Clone>(cell: &Cell<T>) -> T {425let prev = cell.take();426let ret = prev.clone();427cell.set(prev);428ret429}430431fn inner_unexpected(buffer: &ParseBuffer) -> (Rc<Cell<Unexpected>>, Option<(Span, Delimiter)>) {432let mut unexpected = get_unexpected(buffer);433loop {434match cell_clone(&unexpected) {435Unexpected::None => return (unexpected, None),436Unexpected::Some(span, delimiter) => return (unexpected, Some((span, delimiter))),437Unexpected::Chain(next) => unexpected = next,438}439}440}441442pub(crate) fn get_unexpected(buffer: &ParseBuffer) -> Rc<Cell<Unexpected>> {443cell_clone(&buffer.unexpected).unwrap()444}445446fn span_of_unexpected_ignoring_nones(mut cursor: Cursor) -> Option<(Span, Delimiter)> {447if cursor.eof() {448return None;449}450while let Some((inner, _span, rest)) = cursor.group(Delimiter::None) {451if let Some(unexpected) = span_of_unexpected_ignoring_nones(inner) {452return Some(unexpected);453}454cursor = rest;455}456if cursor.eof() {457None458} else {459Some((cursor.span(), cursor.scope_delimiter()))460}461}462463impl<'a> ParseBuffer<'a> {464/// Parses a syntax tree node of type `T`, advancing the position of our465/// parse stream past it.466pub fn parse<T: Parse>(&self) -> Result<T> {467T::parse(self)468}469470/// Calls the given parser function to parse a syntax tree node of type `T`471/// from this stream.472///473/// # Example474///475/// The parser below invokes [`Attribute::parse_outer`] to parse a vector of476/// zero or more outer attributes.477///478/// [`Attribute::parse_outer`]: crate::Attribute::parse_outer479///480/// ```481/// use syn::{Attribute, Ident, Result, Token};482/// use syn::parse::{Parse, ParseStream};483///484/// // Parses a unit struct with attributes.485/// //486/// // #[path = "s.tmpl"]487/// // struct S;488/// struct UnitStruct {489/// attrs: Vec<Attribute>,490/// struct_token: Token![struct],491/// name: Ident,492/// semi_token: Token![;],493/// }494///495/// impl Parse for UnitStruct {496/// fn parse(input: ParseStream) -> Result<Self> {497/// Ok(UnitStruct {498/// attrs: input.call(Attribute::parse_outer)?,499/// struct_token: input.parse()?,500/// name: input.parse()?,501/// semi_token: input.parse()?,502/// })503/// }504/// }505/// ```506pub fn call<T>(&'a self, function: fn(ParseStream<'a>) -> Result<T>) -> Result<T> {507function(self)508}509510/// Looks at the next token in the parse stream to determine whether it511/// matches the requested type of token.512///513/// Does not advance the position of the parse stream.514///515/// # Syntax516///517/// Note that this method does not use turbofish syntax. Pass the peek type518/// inside of parentheses.519///520/// - `input.peek(Token![struct])`521/// - `input.peek(Token![==])`522/// - `input.peek(syn::Ident)` *(does not accept keywords)*523/// - `input.peek(syn::Ident::peek_any)`524/// - `input.peek(Lifetime)`525/// - `input.peek(token::Brace)`526///527/// # Example528///529/// In this example we finish parsing the list of supertraits when the next530/// token in the input is either `where` or an opening curly brace.531///532/// ```533/// use syn::{braced, token, Generics, Ident, Result, Token, TypeParamBound};534/// use syn::parse::{Parse, ParseStream};535/// use syn::punctuated::Punctuated;536///537/// // Parses a trait definition containing no associated items.538/// //539/// // trait Marker<'de, T>: A + B<'de> where Box<T>: Clone {}540/// struct MarkerTrait {541/// trait_token: Token![trait],542/// ident: Ident,543/// generics: Generics,544/// colon_token: Option<Token![:]>,545/// supertraits: Punctuated<TypeParamBound, Token![+]>,546/// brace_token: token::Brace,547/// }548///549/// impl Parse for MarkerTrait {550/// fn parse(input: ParseStream) -> Result<Self> {551/// let trait_token: Token![trait] = input.parse()?;552/// let ident: Ident = input.parse()?;553/// let mut generics: Generics = input.parse()?;554/// let colon_token: Option<Token![:]> = input.parse()?;555///556/// let mut supertraits = Punctuated::new();557/// if colon_token.is_some() {558/// loop {559/// supertraits.push_value(input.parse()?);560/// if input.peek(Token![where]) || input.peek(token::Brace) {561/// break;562/// }563/// supertraits.push_punct(input.parse()?);564/// }565/// }566///567/// generics.where_clause = input.parse()?;568/// let content;569/// let empty_brace_token = braced!(content in input);570///571/// Ok(MarkerTrait {572/// trait_token,573/// ident,574/// generics,575/// colon_token,576/// supertraits,577/// brace_token: empty_brace_token,578/// })579/// }580/// }581/// ```582pub fn peek<T: Peek>(&self, token: T) -> bool {583let _ = token;584T::Token::peek(self.cursor())585}586587/// Looks at the second-next token in the parse stream.588///589/// This is commonly useful as a way to implement contextual keywords.590///591/// # Example592///593/// This example needs to use `peek2` because the symbol `union` is not a594/// keyword in Rust. We can't use just `peek` and decide to parse a union if595/// the very next token is `union`, because someone is free to write a `mod596/// union` and a macro invocation that looks like `union::some_macro! { ...597/// }`. In other words `union` is a contextual keyword.598///599/// ```600/// use syn::{Ident, ItemUnion, Macro, Result, Token};601/// use syn::parse::{Parse, ParseStream};602///603/// // Parses either a union or a macro invocation.604/// enum UnionOrMacro {605/// // union MaybeUninit<T> { uninit: (), value: T }606/// Union(ItemUnion),607/// // lazy_static! { ... }608/// Macro(Macro),609/// }610///611/// impl Parse for UnionOrMacro {612/// fn parse(input: ParseStream) -> Result<Self> {613/// if input.peek(Token![union]) && input.peek2(Ident) {614/// input.parse().map(UnionOrMacro::Union)615/// } else {616/// input.parse().map(UnionOrMacro::Macro)617/// }618/// }619/// }620/// ```621pub fn peek2<T: Peek>(&self, token: T) -> bool {622fn peek2(buffer: &ParseBuffer, peek: fn(Cursor) -> bool) -> bool {623buffer.cursor().skip().map_or(false, peek)624}625626let _ = token;627peek2(self, T::Token::peek)628}629630/// Looks at the third-next token in the parse stream.631pub fn peek3<T: Peek>(&self, token: T) -> bool {632fn peek3(buffer: &ParseBuffer, peek: fn(Cursor) -> bool) -> bool {633buffer634.cursor()635.skip()636.and_then(Cursor::skip)637.map_or(false, peek)638}639640let _ = token;641peek3(self, T::Token::peek)642}643644/// Parses zero or more occurrences of `T` separated by punctuation of type645/// `P`, with optional trailing punctuation.646///647/// Parsing continues until the end of this parse stream. The entire content648/// of this parse stream must consist of `T` and `P`.649///650/// # Example651///652/// ```653/// # use quote::quote;654/// #655/// use syn::{parenthesized, token, Ident, Result, Token, Type};656/// use syn::parse::{Parse, ParseStream};657/// use syn::punctuated::Punctuated;658///659/// // Parse a simplified tuple struct syntax like:660/// //661/// // struct S(A, B);662/// struct TupleStruct {663/// struct_token: Token![struct],664/// ident: Ident,665/// paren_token: token::Paren,666/// fields: Punctuated<Type, Token![,]>,667/// semi_token: Token![;],668/// }669///670/// impl Parse for TupleStruct {671/// fn parse(input: ParseStream) -> Result<Self> {672/// let content;673/// Ok(TupleStruct {674/// struct_token: input.parse()?,675/// ident: input.parse()?,676/// paren_token: parenthesized!(content in input),677/// fields: content.parse_terminated(Type::parse, Token![,])?,678/// semi_token: input.parse()?,679/// })680/// }681/// }682/// #683/// # let input = quote! {684/// # struct S(A, B);685/// # };686/// # syn::parse2::<TupleStruct>(input).unwrap();687/// ```688///689/// # See also690///691/// If your separator is anything more complicated than an invocation of the692/// `Token!` macro, this method won't be applicable and you can instead693/// directly use `Punctuated`'s parser functions: [`parse_terminated`],694/// [`parse_separated_nonempty`] etc.695///696/// [`parse_terminated`]: Punctuated::parse_terminated697/// [`parse_separated_nonempty`]: Punctuated::parse_separated_nonempty698///699/// ```700/// use syn::{custom_keyword, Expr, Result, Token};701/// use syn::parse::{Parse, ParseStream};702/// use syn::punctuated::Punctuated;703///704/// mod kw {705/// syn::custom_keyword!(fin);706/// }707///708/// struct Fin(kw::fin, Token![;]);709///710/// impl Parse for Fin {711/// fn parse(input: ParseStream) -> Result<Self> {712/// Ok(Self(input.parse()?, input.parse()?))713/// }714/// }715///716/// struct Thing {717/// steps: Punctuated<Expr, Fin>,718/// }719///720/// impl Parse for Thing {721/// fn parse(input: ParseStream) -> Result<Self> {722/// # if true {723/// Ok(Thing {724/// steps: Punctuated::parse_terminated(input)?,725/// })726/// # } else {727/// // or equivalently, this means the same thing:728/// # Ok(Thing {729/// steps: input.call(Punctuated::parse_terminated)?,730/// # })731/// # }732/// }733/// }734/// ```735pub fn parse_terminated<T, P>(736&'a self,737parser: fn(ParseStream<'a>) -> Result<T>,738separator: P,739) -> Result<Punctuated<T, P::Token>>740where741P: Peek,742P::Token: Parse,743{744let _ = separator;745Punctuated::parse_terminated_with(self, parser)746}747748/// Returns whether there are no more tokens remaining to be parsed from749/// this stream.750///751/// This method returns true upon reaching the end of the content within a752/// set of delimiters, as well as at the end of the tokens provided to the753/// outermost parsing entry point.754///755/// This is equivalent to756/// <code>.<a href="#method.peek">peek</a>(<a href="struct.End.html">syn::parse::End</a>)</code>.757/// Use `.peek2(End)` or `.peek3(End)` to look for the end of a parse stream758/// further ahead than the current position.759///760/// # Example761///762/// ```763/// use syn::{braced, token, Ident, Item, Result, Token};764/// use syn::parse::{Parse, ParseStream};765///766/// // Parses a Rust `mod m { ... }` containing zero or more items.767/// struct Mod {768/// mod_token: Token![mod],769/// name: Ident,770/// brace_token: token::Brace,771/// items: Vec<Item>,772/// }773///774/// impl Parse for Mod {775/// fn parse(input: ParseStream) -> Result<Self> {776/// let content;777/// Ok(Mod {778/// mod_token: input.parse()?,779/// name: input.parse()?,780/// brace_token: braced!(content in input),781/// items: {782/// let mut items = Vec::new();783/// while !content.is_empty() {784/// items.push(content.parse()?);785/// }786/// items787/// },788/// })789/// }790/// }791/// ```792pub fn is_empty(&self) -> bool {793self.cursor().eof()794}795796/// Constructs a helper for peeking at the next token in this stream and797/// building an error message if it is not one of a set of expected tokens.798///799/// # Example800///801/// ```802/// use syn::{ConstParam, Ident, Lifetime, LifetimeParam, Result, Token, TypeParam};803/// use syn::parse::{Parse, ParseStream};804///805/// // A generic parameter, a single one of the comma-separated elements inside806/// // angle brackets in:807/// //808/// // fn f<T: Clone, 'a, 'b: 'a, const N: usize>() { ... }809/// //810/// // On invalid input, lookahead gives us a reasonable error message.811/// //812/// // error: expected one of: identifier, lifetime, `const`813/// // |814/// // 5 | fn f<!Sized>() {}815/// // | ^816/// enum GenericParam {817/// Type(TypeParam),818/// Lifetime(LifetimeParam),819/// Const(ConstParam),820/// }821///822/// impl Parse for GenericParam {823/// fn parse(input: ParseStream) -> Result<Self> {824/// let lookahead = input.lookahead1();825/// if lookahead.peek(Ident) {826/// input.parse().map(GenericParam::Type)827/// } else if lookahead.peek(Lifetime) {828/// input.parse().map(GenericParam::Lifetime)829/// } else if lookahead.peek(Token![const]) {830/// input.parse().map(GenericParam::Const)831/// } else {832/// Err(lookahead.error())833/// }834/// }835/// }836/// ```837pub fn lookahead1(&self) -> Lookahead1<'a> {838lookahead::new(self.scope, self.cursor())839}840841/// Forks a parse stream so that parsing tokens out of either the original842/// or the fork does not advance the position of the other.843///844/// # Performance845///846/// Forking a parse stream is a cheap fixed amount of work and does not847/// involve copying token buffers. Where you might hit performance problems848/// is if your macro ends up parsing a large amount of content more than849/// once.850///851/// ```852/// # use syn::{Expr, Result};853/// # use syn::parse::ParseStream;854/// #855/// # fn bad(input: ParseStream) -> Result<Expr> {856/// // Do not do this.857/// if input.fork().parse::<Expr>().is_ok() {858/// return input.parse::<Expr>();859/// }860/// # unimplemented!()861/// # }862/// ```863///864/// As a rule, avoid parsing an unbounded amount of tokens out of a forked865/// parse stream. Only use a fork when the amount of work performed against866/// the fork is small and bounded.867///868/// When complex speculative parsing against the forked stream is869/// unavoidable, use [`parse::discouraged::Speculative`] to advance the870/// original stream once the fork's parse is determined to have been871/// successful.872///873/// For a lower level way to perform speculative parsing at the token level,874/// consider using [`ParseStream::step`] instead.875///876/// [`parse::discouraged::Speculative`]: discouraged::Speculative877/// [`ParseStream::step`]: ParseBuffer::step878///879/// # Example880///881/// The parse implementation shown here parses possibly restricted `pub`882/// visibilities.883///884/// - `pub`885/// - `pub(crate)`886/// - `pub(self)`887/// - `pub(super)`888/// - `pub(in some::path)`889///890/// To handle the case of visibilities inside of tuple structs, the parser891/// needs to distinguish parentheses that specify visibility restrictions892/// from parentheses that form part of a tuple type.893///894/// ```895/// # struct A;896/// # struct B;897/// # struct C;898/// #899/// struct S(pub(crate) A, pub (B, C));900/// ```901///902/// In this example input the first tuple struct element of `S` has903/// `pub(crate)` visibility while the second tuple struct element has `pub`904/// visibility; the parentheses around `(B, C)` are part of the type rather905/// than part of a visibility restriction.906///907/// The parser uses a forked parse stream to check the first token inside of908/// parentheses after the `pub` keyword. This is a small bounded amount of909/// work performed against the forked parse stream.910///911/// ```912/// use syn::{parenthesized, token, Ident, Path, Result, Token};913/// use syn::ext::IdentExt;914/// use syn::parse::{Parse, ParseStream};915///916/// struct PubVisibility {917/// pub_token: Token![pub],918/// restricted: Option<Restricted>,919/// }920///921/// struct Restricted {922/// paren_token: token::Paren,923/// in_token: Option<Token![in]>,924/// path: Path,925/// }926///927/// impl Parse for PubVisibility {928/// fn parse(input: ParseStream) -> Result<Self> {929/// let pub_token: Token![pub] = input.parse()?;930///931/// if input.peek(token::Paren) {932/// let ahead = input.fork();933/// let mut content;934/// parenthesized!(content in ahead);935///936/// if content.peek(Token![crate])937/// || content.peek(Token![self])938/// || content.peek(Token![super])939/// {940/// return Ok(PubVisibility {941/// pub_token,942/// restricted: Some(Restricted {943/// paren_token: parenthesized!(content in input),944/// in_token: None,945/// path: Path::from(content.call(Ident::parse_any)?),946/// }),947/// });948/// } else if content.peek(Token![in]) {949/// return Ok(PubVisibility {950/// pub_token,951/// restricted: Some(Restricted {952/// paren_token: parenthesized!(content in input),953/// in_token: Some(content.parse()?),954/// path: content.call(Path::parse_mod_style)?,955/// }),956/// });957/// }958/// }959///960/// Ok(PubVisibility {961/// pub_token,962/// restricted: None,963/// })964/// }965/// }966/// ```967pub fn fork(&self) -> Self {968ParseBuffer {969scope: self.scope,970cell: self.cell.clone(),971marker: PhantomData,972// Not the parent's unexpected. Nothing cares whether the clone973// parses all the way unless we `advance_to`.974unexpected: Cell::new(Some(Rc::new(Cell::new(Unexpected::None)))),975}976}977978/// Triggers an error at the current position of the parse stream.979///980/// # Example981///982/// ```983/// use syn::{Expr, Result, Token};984/// use syn::parse::{Parse, ParseStream};985///986/// // Some kind of loop: `while` or `for` or `loop`.987/// struct Loop {988/// expr: Expr,989/// }990///991/// impl Parse for Loop {992/// fn parse(input: ParseStream) -> Result<Self> {993/// if input.peek(Token![while])994/// || input.peek(Token![for])995/// || input.peek(Token![loop])996/// {997/// Ok(Loop {998/// expr: input.parse()?,999/// })1000/// } else {1001/// Err(input.error("expected some kind of loop"))1002/// }1003/// }1004/// }1005/// ```1006pub fn error<T: Display>(&self, message: T) -> Error {1007error::new_at(self.scope, self.cursor(), message)1008}10091010/// Speculatively parses tokens from this parse stream, advancing the1011/// position of this stream only if parsing succeeds.1012///1013/// This is a powerful low-level API used for defining the `Parse` impls of1014/// the basic built-in token types. It is not something that will be used1015/// widely outside of the Syn codebase.1016///1017/// # Example1018///1019/// ```1020/// use proc_macro2::TokenTree;1021/// use syn::Result;1022/// use syn::parse::ParseStream;1023///1024/// // This function advances the stream past the next occurrence of `@`. If1025/// // no `@` is present in the stream, the stream position is unchanged and1026/// // an error is returned.1027/// fn skip_past_next_at(input: ParseStream) -> Result<()> {1028/// input.step(|cursor| {1029/// let mut rest = *cursor;1030/// while let Some((tt, next)) = rest.token_tree() {1031/// match &tt {1032/// TokenTree::Punct(punct) if punct.as_char() == '@' => {1033/// return Ok(((), next));1034/// }1035/// _ => rest = next,1036/// }1037/// }1038/// Err(cursor.error("no `@` was found after this point"))1039/// })1040/// }1041/// #1042/// # fn remainder_after_skipping_past_next_at(1043/// # input: ParseStream,1044/// # ) -> Result<proc_macro2::TokenStream> {1045/// # skip_past_next_at(input)?;1046/// # input.parse()1047/// # }1048/// #1049/// # use syn::parse::Parser;1050/// # let remainder = remainder_after_skipping_past_next_at1051/// # .parse_str("a @ b c")1052/// # .unwrap();1053/// # assert_eq!(remainder.to_string(), "b c");1054/// ```1055pub fn step<F, R>(&self, function: F) -> Result<R>1056where1057F: for<'c> FnOnce(StepCursor<'c, 'a>) -> Result<(R, Cursor<'c>)>,1058{1059// Since the user's function is required to work for any 'c, we know1060// that the Cursor<'c> they return is either derived from the input1061// StepCursor<'c, 'a> or from a Cursor<'static>.1062//1063// It would not be legal to write this function without the invariant1064// lifetime 'c in StepCursor<'c, 'a>. If this function were written only1065// in terms of 'a, the user could take our ParseBuffer<'a>, upcast it to1066// a ParseBuffer<'short> which some shorter lifetime than 'a, invoke1067// `step` on their ParseBuffer<'short> with a closure that returns1068// Cursor<'short>, and we would wrongly write that Cursor<'short> into1069// the Cell intended to hold Cursor<'a>.1070//1071// In some cases it may be necessary for R to contain a Cursor<'a>.1072// Within Syn we solve this using `advance_step_cursor` which uses the1073// existence of a StepCursor<'c, 'a> as proof that it is safe to cast1074// from Cursor<'c> to Cursor<'a>. If needed outside of Syn, it would be1075// safe to expose that API as a method on StepCursor.1076let (node, rest) = function(StepCursor {1077scope: self.scope,1078cursor: self.cell.get(),1079marker: PhantomData,1080})?;1081self.cell.set(rest);1082Ok(node)1083}10841085/// Returns the `Span` of the next token in the parse stream, or1086/// `Span::call_site()` if this parse stream has completely exhausted its1087/// input `TokenStream`.1088pub fn span(&self) -> Span {1089let cursor = self.cursor();1090if cursor.eof() {1091self.scope1092} else {1093crate::buffer::open_span_of_group(cursor)1094}1095}10961097/// Provides low-level access to the token representation underlying this1098/// parse stream.1099///1100/// Cursors are immutable so no operations you perform against the cursor1101/// will affect the state of this parse stream.1102///1103/// # Example1104///1105/// ```1106/// use proc_macro2::TokenStream;1107/// use syn::buffer::Cursor;1108/// use syn::parse::{ParseStream, Result};1109///1110/// // Run a parser that returns T, but get its output as TokenStream instead of T.1111/// // This works without T needing to implement ToTokens.1112/// fn recognize_token_stream<T>(1113/// recognizer: fn(ParseStream) -> Result<T>,1114/// ) -> impl Fn(ParseStream) -> Result<TokenStream> {1115/// move |input| {1116/// let begin = input.cursor();1117/// recognizer(input)?;1118/// let end = input.cursor();1119/// Ok(tokens_between(begin, end))1120/// }1121/// }1122///1123/// // Collect tokens between two cursors as a TokenStream.1124/// fn tokens_between(begin: Cursor, end: Cursor) -> TokenStream {1125/// assert!(begin <= end);1126///1127/// let mut cursor = begin;1128/// let mut tokens = TokenStream::new();1129/// while cursor < end {1130/// let (token, next) = cursor.token_tree().unwrap();1131/// tokens.extend(std::iter::once(token));1132/// cursor = next;1133/// }1134/// tokens1135/// }1136///1137/// fn main() {1138/// use quote::quote;1139/// use syn::parse::{Parse, Parser};1140/// use syn::Token;1141///1142/// // Parse syn::Type as a TokenStream, surrounded by angle brackets.1143/// fn example(input: ParseStream) -> Result<TokenStream> {1144/// let _langle: Token![<] = input.parse()?;1145/// let ty = recognize_token_stream(syn::Type::parse)(input)?;1146/// let _rangle: Token![>] = input.parse()?;1147/// Ok(ty)1148/// }1149///1150/// let tokens = quote! { <fn() -> u8> };1151/// println!("{}", example.parse2(tokens).unwrap());1152/// }1153/// ```1154pub fn cursor(&self) -> Cursor<'a> {1155self.cell.get()1156}11571158fn check_unexpected(&self) -> Result<()> {1159match inner_unexpected(self).1 {1160Some((span, delimiter)) => Err(err_unexpected_token(span, delimiter)),1161None => Ok(()),1162}1163}1164}11651166#[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]1167impl<T: Parse> Parse for Box<T> {1168fn parse(input: ParseStream) -> Result<Self> {1169input.parse().map(Box::new)1170}1171}11721173#[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]1174impl<T: Parse + Token> Parse for Option<T> {1175fn parse(input: ParseStream) -> Result<Self> {1176if T::peek(input.cursor()) {1177Ok(Some(input.parse()?))1178} else {1179Ok(None)1180}1181}1182}11831184#[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]1185impl Parse for TokenStream {1186fn parse(input: ParseStream) -> Result<Self> {1187input.step(|cursor| Ok((cursor.token_stream(), Cursor::empty())))1188}1189}11901191#[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]1192impl Parse for TokenTree {1193fn parse(input: ParseStream) -> Result<Self> {1194input.step(|cursor| match cursor.token_tree() {1195Some((tt, rest)) => Ok((tt, rest)),1196None => Err(cursor.error("expected token tree")),1197})1198}1199}12001201#[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]1202impl Parse for Group {1203fn parse(input: ParseStream) -> Result<Self> {1204input.step(|cursor| {1205if let Some((group, rest)) = cursor.any_group_token() {1206if group.delimiter() != Delimiter::None {1207return Ok((group, rest));1208}1209}1210Err(cursor.error("expected group token"))1211})1212}1213}12141215#[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]1216impl Parse for Punct {1217fn parse(input: ParseStream) -> Result<Self> {1218input.step(|cursor| match cursor.punct() {1219Some((punct, rest)) => Ok((punct, rest)),1220None => Err(cursor.error("expected punctuation token")),1221})1222}1223}12241225#[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]1226impl Parse for Literal {1227fn parse(input: ParseStream) -> Result<Self> {1228input.step(|cursor| match cursor.literal() {1229Some((literal, rest)) => Ok((literal, rest)),1230None => Err(cursor.error("expected literal token")),1231})1232}1233}12341235/// Parser that can parse Rust tokens into a particular syntax tree node.1236///1237/// Refer to the [module documentation] for details about parsing in Syn.1238///1239/// [module documentation]: self1240pub trait Parser: Sized {1241type Output;12421243/// Parse a proc-macro2 token stream into the chosen syntax tree node.1244///1245/// This function enforces that the input is fully parsed. If there are any1246/// unparsed tokens at the end of the stream, an error is returned.1247fn parse2(self, tokens: TokenStream) -> Result<Self::Output>;12481249/// Parse tokens of source code into the chosen syntax tree node.1250///1251/// This function enforces that the input is fully parsed. If there are any1252/// unparsed tokens at the end of the stream, an error is returned.1253#[cfg(feature = "proc-macro")]1254#[cfg_attr(docsrs, doc(cfg(feature = "proc-macro")))]1255fn parse(self, tokens: proc_macro::TokenStream) -> Result<Self::Output> {1256self.parse2(proc_macro2::TokenStream::from(tokens))1257}12581259/// Parse a string of Rust code into the chosen syntax tree node.1260///1261/// This function enforces that the input is fully parsed. If there are any1262/// unparsed tokens at the end of the string, an error is returned.1263///1264/// # Hygiene1265///1266/// Every span in the resulting syntax tree will be set to resolve at the1267/// macro call site.1268fn parse_str(self, s: &str) -> Result<Self::Output> {1269self.parse2(proc_macro2::TokenStream::from_str(s)?)1270}12711272// Not public API.1273#[doc(hidden)]1274fn __parse_scoped(self, scope: Span, tokens: TokenStream) -> Result<Self::Output> {1275let _ = scope;1276self.parse2(tokens)1277}1278}12791280fn tokens_to_parse_buffer(tokens: &TokenBuffer) -> ParseBuffer {1281let scope = Span::call_site();1282let cursor = tokens.begin();1283let unexpected = Rc::new(Cell::new(Unexpected::None));1284new_parse_buffer(scope, cursor, unexpected)1285}12861287impl<F, T> Parser for F1288where1289F: FnOnce(ParseStream) -> Result<T>,1290{1291type Output = T;12921293fn parse2(self, tokens: TokenStream) -> Result<T> {1294let buf = TokenBuffer::new2(tokens);1295let state = tokens_to_parse_buffer(&buf);1296let node = self(&state)?;1297state.check_unexpected()?;1298if let Some((unexpected_span, delimiter)) =1299span_of_unexpected_ignoring_nones(state.cursor())1300{1301Err(err_unexpected_token(unexpected_span, delimiter))1302} else {1303Ok(node)1304}1305}13061307fn __parse_scoped(self, scope: Span, tokens: TokenStream) -> Result<Self::Output> {1308let buf = TokenBuffer::new2(tokens);1309let cursor = buf.begin();1310let unexpected = Rc::new(Cell::new(Unexpected::None));1311let state = new_parse_buffer(scope, cursor, unexpected);1312let node = self(&state)?;1313state.check_unexpected()?;1314if let Some((unexpected_span, delimiter)) =1315span_of_unexpected_ignoring_nones(state.cursor())1316{1317Err(err_unexpected_token(unexpected_span, delimiter))1318} else {1319Ok(node)1320}1321}1322}13231324pub(crate) fn parse_scoped<F: Parser>(f: F, scope: Span, tokens: TokenStream) -> Result<F::Output> {1325f.__parse_scoped(scope, tokens)1326}13271328fn err_unexpected_token(span: Span, delimiter: Delimiter) -> Error {1329let msg = match delimiter {1330Delimiter::Parenthesis => "unexpected token, expected `)`",1331Delimiter::Brace => "unexpected token, expected `}`",1332Delimiter::Bracket => "unexpected token, expected `]`",1333Delimiter::None => "unexpected token",1334};1335Error::new(span, msg)1336}13371338/// An empty syntax tree node that consumes no tokens when parsed.1339///1340/// This is useful for attribute macros that want to ensure they are not1341/// provided any attribute args.1342///1343/// ```1344/// # extern crate proc_macro;1345/// #1346/// use proc_macro::TokenStream;1347/// use syn::parse_macro_input;1348/// use syn::parse::Nothing;1349///1350/// # const IGNORE: &str = stringify! {1351/// #[proc_macro_attribute]1352/// # };1353/// pub fn my_attr(args: TokenStream, input: TokenStream) -> TokenStream {1354/// parse_macro_input!(args as Nothing);1355///1356/// /* ... */1357/// # TokenStream::new()1358/// }1359/// ```1360///1361/// ```text1362/// error: unexpected token1363/// --> src/main.rs:3:191364/// |1365/// 3 | #[my_attr(asdf)]1366/// | ^^^^1367/// ```1368pub struct Nothing;13691370impl Parse for Nothing {1371fn parse(_input: ParseStream) -> Result<Self> {1372Ok(Nothing)1373}1374}13751376#[cfg(feature = "printing")]1377#[cfg_attr(docsrs, doc(cfg(feature = "printing")))]1378impl ToTokens for Nothing {1379fn to_tokens(&self, tokens: &mut TokenStream) {1380let _ = tokens;1381}1382}13831384#[cfg(feature = "clone-impls")]1385#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]1386impl Clone for Nothing {1387fn clone(&self) -> Self {1388*self1389}1390}13911392#[cfg(feature = "clone-impls")]1393#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]1394impl Copy for Nothing {}13951396#[cfg(feature = "extra-traits")]1397#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]1398impl Debug for Nothing {1399fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {1400f.write_str("Nothing")1401}1402}14031404#[cfg(feature = "extra-traits")]1405#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]1406impl Eq for Nothing {}14071408#[cfg(feature = "extra-traits")]1409#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]1410impl PartialEq for Nothing {1411fn eq(&self, _other: &Self) -> bool {1412true1413}1414}14151416#[cfg(feature = "extra-traits")]1417#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]1418impl Hash for Nothing {1419fn hash<H: Hasher>(&self, _state: &mut H) {}1420}142114221423