// SPDX-License-Identifier: Apache-2.0 OR MIT //! Parsing interface for parsing a token stream into a syntax tree node.//!//! Parsing in Syn is built on parser functions that take in a [`ParseStream`]//! and produce a [`Result<T>`] where `T` is some syntax tree node. Underlying//! these parser functions is a lower level mechanism built around the//! [`Cursor`] type. `Cursor` is a cheaply copyable cursor over a range of//! tokens in a token stream.//!//! [`Result<T>`]: Result//! [`Cursor`]: crate::buffer::Cursor//!//! # Example//!//! Here is a snippet of parsing code to get a feel for the style of the//! library. We define data structures for a subset of Rust syntax including//! enums (not shown) and structs, then provide implementations of the [`Parse`]//! trait to parse these syntax tree data structures from a token stream.//!//! Once `Parse` impls have been defined, they can be called conveniently from a//! procedural macro through [`parse_macro_input!`] as shown at the bottom of//! the snippet. If the caller provides syntactically invalid input to the//! procedural macro, they will receive a helpful compiler error message//! pointing out the exact token that triggered the failure to parse.//!//! [`parse_macro_input!`]: crate::parse_macro_input!//!//! ```//! # extern crate proc_macro;//! #//! use proc_macro::TokenStream;//! use syn::{braced, parse_macro_input, token, Field, Ident, Result, Token};//! use syn::parse::{Parse, ParseStream};//! use syn::punctuated::Punctuated;//!//! enum Item {//! Struct(ItemStruct),//! Enum(ItemEnum),//! }//!//! struct ItemStruct {//! struct_token: Token![struct],//! ident: Ident,//! brace_token: token::Brace,//! fields: Punctuated<Field, Token![,]>,//! }//! #//! # enum ItemEnum {}//!//! impl Parse for Item {//! fn parse(input: ParseStream) -> Result<Self> {//! let lookahead = input.lookahead1();//! if lookahead.peek(Token![struct]) {//! input.parse().map(Item::Struct)//! } else if lookahead.peek(Token![enum]) {//! input.parse().map(Item::Enum)//! } else {//! Err(lookahead.error())//! }//! }//! }//!//! impl Parse for ItemStruct {//! fn parse(input: ParseStream) -> Result<Self> {//! let content;//! Ok(ItemStruct {//! struct_token: input.parse()?,//! ident: input.parse()?,//! brace_token: braced!(content in input),//! fields: content.parse_terminated(Field::parse_named, Token![,])?,//! })//! }//! }//! #//! # impl Parse for ItemEnum {//! # fn parse(input: ParseStream) -> Result<Self> {//! # unimplemented!()//! # }//! # }//!//! # const IGNORE: &str = stringify! {//! #[proc_macro]//! # };//! pub fn my_macro(tokens: TokenStream) -> TokenStream {//! let input = parse_macro_input!(tokens as Item);//!//! /* ... *///! # TokenStream::new()//! }//! ```//!//! # The `syn::parse*` functions//!//! The [`syn::parse`], [`syn::parse2`], and [`syn::parse_str`] functions serve//! as an entry point for parsing syntax tree nodes that can be parsed in an//! obvious default way. These functions can return any syntax tree node that//! implements the [`Parse`] trait, which includes most types in Syn.//!//! [`syn::parse`]: crate::parse()//! [`syn::parse2`]: crate::parse2()//! [`syn::parse_str`]: crate::parse_str()//!//! ```//! use syn::Type;//!//! # fn run_parser() -> syn::Result<()> {//! let t: Type = syn::parse_str("std::collections::HashMap<String, Value>")?;//! # Ok(())//! # }//! #//! # run_parser().unwrap();//! ```//!//! The [`parse_quote!`] macro also uses this approach.//!//! [`parse_quote!`]: crate::parse_quote!//!//! # The `Parser` trait//!//! Some types can be parsed in several ways depending on context. For example//! an [`Attribute`] can be either "outer" like `#[...]` or "inner" like//! `#![...]` and parsing the wrong one would be a bug. Similarly [`Punctuated`]//! may or may not allow trailing punctuation, and parsing it the wrong way//! would either reject valid input or accept invalid input.//!//! [`Attribute`]: crate::Attribute//! [`Punctuated`]: crate::punctuated//!//! The `Parse` trait is not implemented in these cases because there is no good//! behavior to consider the default.//!//! ```compile_fail//! # extern crate proc_macro;//! #//! # use syn::punctuated::Punctuated;//! # use syn::{PathSegment, Result, Token};//! #//! # fn f(tokens: proc_macro::TokenStream) -> Result<()> {//! #//! // Can't parse `Punctuated` without knowing whether trailing punctuation//! // should be allowed in this context.//! let path: Punctuated<PathSegment, Token![::]> = syn::parse(tokens)?;//! #//! # Ok(())//! # }//! ```//!//! In these cases the types provide a choice of parser functions rather than a//! single `Parse` implementation, and those parser functions can be invoked//! through the [`Parser`] trait.//!//!//! ```//! # extern crate proc_macro;//! #//! use proc_macro::TokenStream;//! use syn::parse::Parser;//! use syn::punctuated::Punctuated;//! use syn::{Attribute, Expr, PathSegment, Result, Token};//!//! fn call_some_parser_methods(input: TokenStream) -> Result<()> {//! // Parse a nonempty sequence of path segments separated by `::` punctuation//! // with no trailing punctuation.//! let tokens = input.clone();//! let parser = Punctuated::<PathSegment, Token![::]>::parse_separated_nonempty;//! let _path = parser.parse(tokens)?;//!//! // Parse a possibly empty sequence of expressions terminated by commas with//! // an optional trailing punctuation.//! let tokens = input.clone();//! let parser = Punctuated::<Expr, Token![,]>::parse_terminated;//! let _args = parser.parse(tokens)?;//!//! // Parse zero or more outer attributes but not inner attributes.//! let tokens = input.clone();//! let parser = Attribute::parse_outer;//! let _attrs = parser.parse(tokens)?;//!//! Ok(())//! }//! ``` #[path = "discouraged.rs"]pub mod discouraged; use crate::buffer::{Cursor, TokenBuffer};use crate::error;use crate::lookahead;use crate::punctuated::Punctuated;use crate::token::Token;use proc_macro2::{Delimiter, Group, Literal, Punct, Span, TokenStream, TokenTree};#[cfg(feature = "printing")]use quote::ToTokens;use std::cell::Cell;use std::fmt::{self, Debug, Display};#[cfg(feature = "extra-traits")]use std::hash::{Hash, Hasher};use std::marker::PhantomData;use std::mem;use std::ops::Deref;use std::panic::{RefUnwindSafe, UnwindSafe};use std::rc::Rc;use std::str::FromStr; pub use crate::error::{Error, Result};pub use crate::lookahead::{End, Lookahead1, Peek}; /// Parsing interface implemented by all types that can be parsed in a default/// way from a token stream.////// Refer to the [module documentation] for details about implementing and using/// the `Parse` trait.////// [module documentation]: selfpub trait Parse: Sized { fn parse(input: ParseStream) -> Result<Self>;} /// Input to a Syn parser function.////// See the methods of this type under the documentation of [`ParseBuffer`]. For/// an overview of parsing in Syn, refer to the [module documentation].////// [module documentation]: selfpub type ParseStream<'a> = &'a ParseBuffer<'a>; /// Cursor position within a buffered token stream.////// This type is more commonly used through the type alias [`ParseStream`] which/// is an alias for `&ParseBuffer`.////// `ParseStream` is the input type for all parser functions in Syn. They have/// the signature `fn(ParseStream) -> Result<T>`.////// ## Calling a parser function////// There is no public way to construct a `ParseBuffer`. Instead, if you are/// looking to invoke a parser function that requires `ParseStream` as input,/// you will need to go through one of the public parsing entry points.////// - The [`parse_macro_input!`] macro if parsing input of a procedural macro;/// - One of [the `syn::parse*` functions][syn-parse]; or/// - A method of the [`Parser`] trait.////// [`parse_macro_input!`]: crate::parse_macro_input!/// [syn-parse]: self#the-synparse-functionspub struct ParseBuffer<'a> { scope: Span, // Instead of Cell<Cursor<'a>> so that ParseBuffer<'a> is covariant in 'a. // The rest of the code in this module needs to be careful that only a // cursor derived from this `cell` is ever assigned to this `cell`. // // Cell<Cursor<'a>> cannot be covariant in 'a because then we could take a // ParseBuffer<'a>, upcast to ParseBuffer<'short> for some lifetime shorter // than 'a, and then assign a Cursor<'short> into the Cell. // // By extension, it would not be safe to expose an API that accepts a // Cursor<'a> and trusts that it lives as long as the cursor currently in // the cell. cell: Cell<Cursor<'static>>, marker: PhantomData<Cursor<'a>>, unexpected: Cell<Option<Rc<Cell<Unexpected>>>>,} impl<'a> Drop for ParseBuffer<'a> { fn drop(&mut self) { if let Some((unexpected_span, delimiter)) = span_of_unexpected_ignoring_nones(self.cursor()) { let (inner, old_span) = inner_unexpected(self); if old_span.is_none() { inner.set(Unexpected::Some(unexpected_span, delimiter)); } } }} impl<'a> Display for ParseBuffer<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { Display::fmt(&self.cursor().token_stream(), f) }} impl<'a> Debug for ParseBuffer<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { Debug::fmt(&self.cursor().token_stream(), f) }} impl<'a> UnwindSafe for ParseBuffer<'a> {}impl<'a> RefUnwindSafe for ParseBuffer<'a> {} /// Cursor state associated with speculative parsing.////// This type is the input of the closure provided to [`ParseStream::step`].////// [`ParseStream::step`]: ParseBuffer::step////// # Example////// ```/// use proc_macro2::TokenTree;/// use syn::Result;/// use syn::parse::ParseStream;////// // This function advances the stream past the next occurrence of `@`. If/// // no `@` is present in the stream, the stream position is unchanged and/// // an error is returned./// fn skip_past_next_at(input: ParseStream) -> Result<()> {/// input.step(|cursor| {/// let mut rest = *cursor;/// while let Some((tt, next)) = rest.token_tree() {/// match &tt {/// TokenTree::Punct(punct) if punct.as_char() == '@' => {/// return Ok(((), next));/// }/// _ => rest = next,/// }/// }/// Err(cursor.error("no `@` was found after this point"))/// })/// }/// #/// # fn remainder_after_skipping_past_next_at(/// # input: ParseStream,/// # ) -> Result<proc_macro2::TokenStream> {/// # skip_past_next_at(input)?;/// # input.parse()/// # }/// #/// # use syn::parse::Parser;/// # let remainder = remainder_after_skipping_past_next_at/// # .parse_str("a @ b c")/// # .unwrap();/// # assert_eq!(remainder.to_string(), "b c");/// ```pub struct StepCursor<'c, 'a> { scope: Span, // This field is covariant in 'c. cursor: Cursor<'c>, // This field is contravariant in 'c. Together these make StepCursor // invariant in 'c. Also covariant in 'a. The user cannot cast 'c to a // different lifetime but can upcast into a StepCursor with a shorter // lifetime 'a. // // As long as we only ever construct a StepCursor for which 'c outlives 'a, // this means if ever a StepCursor<'c, 'a> exists we are guaranteed that 'c // outlives 'a. marker: PhantomData<fn(Cursor<'c>) -> Cursor<'a>>,} impl<'c, 'a> Deref for StepCursor<'c, 'a> { type Target = Cursor<'c>; fn deref(&self) -> &Self::Target { &self.cursor }} impl<'c, 'a> Copy for StepCursor<'c, 'a> {} impl<'c, 'a> Clone for StepCursor<'c, 'a> { fn clone(&self) -> Self { *self }} impl<'c, 'a> StepCursor<'c, 'a> { /// Triggers an error at the current position of the parse stream. /// /// The `ParseStream::step` invocation will return this same error without /// advancing the stream state. pub fn error<T: Display>(self, message: T) -> Error { error::new_at(self.scope, self.cursor, message) }} pub(crate) fn advance_step_cursor<'c, 'a>(proof: StepCursor<'c, 'a>, to: Cursor<'c>) -> Cursor<'a> { // Refer to the comments within the StepCursor definition. We use the // fact that a StepCursor<'c, 'a> exists as proof that 'c outlives 'a. // Cursor is covariant in its lifetime parameter so we can cast a // Cursor<'c> to one with the shorter lifetime Cursor<'a>. let _ = proof; unsafe { mem::transmute::<Cursor<'c>, Cursor<'a>>(to) }} pub(crate) fn new_parse_buffer( scope: Span, cursor: Cursor, unexpected: Rc<Cell<Unexpected>>,) -> ParseBuffer { ParseBuffer { scope, // See comment on `cell` in the struct definition. cell: Cell::new(unsafe { mem::transmute::<Cursor, Cursor<'static>>(cursor) }), marker: PhantomData, unexpected: Cell::new(Some(unexpected)), }} pub(crate) enum Unexpected { None, Some(Span, Delimiter), Chain(Rc<Cell<Unexpected>>),} impl Default for Unexpected { fn default() -> Self { Unexpected::None }} impl Clone for Unexpected { fn clone(&self) -> Self { match self { Unexpected::None => Unexpected::None, Unexpected::Some(span, delimiter) => Unexpected::Some(*span, *delimiter), Unexpected::Chain(next) => Unexpected::Chain(next.clone()), } }} // We call this on Cell<Unexpected> and Cell<Option<T>> where temporarily// swapping in a None is cheap.fn cell_clone<T: Default + Clone>(cell: &Cell<T>) -> T { let prev = cell.take(); let ret = prev.clone(); cell.set(prev); ret} fn inner_unexpected(buffer: &ParseBuffer) -> (Rc<Cell<Unexpected>>, Option<(Span, Delimiter)>) { let mut unexpected = get_unexpected(buffer); loop { match cell_clone(&unexpected) { Unexpected::None => return (unexpected, None), Unexpected::Some(span, delimiter) => return (unexpected, Some((span, delimiter))), Unexpected::Chain(next) => unexpected = next, } }} pub(crate) fn get_unexpected(buffer: &ParseBuffer) -> Rc<Cell<Unexpected>> { cell_clone(&buffer.unexpected).unwrap()} fn span_of_unexpected_ignoring_nones(mut cursor: Cursor) -> Option<(Span, Delimiter)> { if cursor.eof() { return None; } while let Some((inner, _span, rest)) = cursor.group(Delimiter::None) { if let Some(unexpected) = span_of_unexpected_ignoring_nones(inner) { return Some(unexpected); } cursor = rest; } if cursor.eof() { None } else { Some((cursor.span(), cursor.scope_delimiter())) }} impl<'a> ParseBuffer<'a> { /// Parses a syntax tree node of type `T`, advancing the position of our /// parse stream past it. pub fn parse<T: Parse>(&self) -> Result<T> { T::parse(self) } /// Calls the given parser function to parse a syntax tree node of type `T` /// from this stream. /// /// # Example /// /// The parser below invokes [`Attribute::parse_outer`] to parse a vector of /// zero or more outer attributes. /// /// [`Attribute::parse_outer`]: crate::Attribute::parse_outer /// /// ``` /// use syn::{Attribute, Ident, Result, Token}; /// use syn::parse::{Parse, ParseStream}; /// /// // Parses a unit struct with attributes. /// // /// // #[path = "s.tmpl"] /// // struct S; /// struct UnitStruct { /// attrs: Vec<Attribute>, /// struct_token: Token![struct], /// name: Ident, /// semi_token: Token![;], /// } /// /// impl Parse for UnitStruct { /// fn parse(input: ParseStream) -> Result<Self> { /// Ok(UnitStruct { /// attrs: input.call(Attribute::parse_outer)?, /// struct_token: input.parse()?,Lines 1–500 of 1421. Load more
// SPDX-License-Identifier: Apache-2.0 OR MIT //! Parsing interface for parsing a token stream into a syntax tree node. //! //! Parsing in Syn is built on parser functions that take in a [`ParseStream`] //! and produce a [`Result<T>`] where `T` is some syntax tree node. Underlying //! these parser functions is a lower level mechanism built around the //! [`Cursor`] type. `Cursor` is a cheaply copyable cursor over a range of //! tokens in a token stream. //! //! [`Result<T>`]: Result //! [`Cursor`]: crate::buffer::Cursor //! //! # Example //! //! Here is a snippet of parsing code to get a feel for the style of the //! library. We define data structures for a subset of Rust syntax including //! enums (not shown) and structs, then provide implementations of the [`Parse`] //! trait to parse these syntax tree data structures from a token stream. //! //! Once `Parse` impls have been defined, they can be called conveniently from a //! procedural macro through [`parse_macro_input!`] as shown at the bottom of //! the snippet. If the caller provides syntactically invalid input to the //! procedural macro, they will receive a helpful compiler error message //! pointing out the exact token that triggered the failure to parse. //! //! [`parse_macro_input!`]: crate::parse_macro_input! //! //! ``` //! # extern crate proc_macro; //! # //! use proc_macro::TokenStream; //! use syn::{braced, parse_macro_input, token, Field, Ident, Result, Token}; //! use syn::parse::{Parse, ParseStream}; //! use syn::punctuated::Punctuated; //! //! enum Item { //! Struct(ItemStruct), //! Enum(ItemEnum), //! } //! //! struct ItemStruct { //! struct_token: Token![struct], //! ident: Ident, //! brace_token: token::Brace, //! fields: Punctuated<Field, Token![,]>, //! } //! # //! # enum ItemEnum {} //! //! impl Parse for Item { //! fn parse(input: ParseStream) -> Result<Self> { //! let lookahead = input.lookahead1(); //! if lookahead.peek(Token![struct]) { //! input.parse().map(Item::Struct) //! } else if lookahead.peek(Token![enum]) { //! input.parse().map(Item::Enum) //! } else { //! Err(lookahead.error()) //! } //! } //! } //! //! impl Parse for ItemStruct { //! fn parse(input: ParseStream) -> Result<Self> { //! let content; //! Ok(ItemStruct { //! struct_token: input.parse()?, //! ident: input.parse()?, //! brace_token: braced!(content in input), //! fields: content.parse_terminated(Field::parse_named, Token![,])?, //! }) //! } //! } //! # //! # impl Parse for ItemEnum { //! # fn parse(input: ParseStream) -> Result<Self> { //! # unimplemented!() //! # } //! # } //! //! # const IGNORE: &str = stringify! { //! #[proc_macro] //! # }; //! pub fn my_macro(tokens: TokenStream) -> TokenStream { //! let input = parse_macro_input!(tokens as Item); //! //! /* ... */ //! # TokenStream::new() //! } //! ``` //! //! # The `syn::parse*` functions //! //! The [`syn::parse`], [`syn::parse2`], and [`syn::parse_str`] functions serve //! as an entry point for parsing syntax tree nodes that can be parsed in an //! obvious default way. These functions can return any syntax tree node that //! implements the [`Parse`] trait, which includes most types in Syn. //! //! [`syn::parse`]: crate::parse() //! [`syn::parse2`]: crate::parse2() //! [`syn::parse_str`]: crate::parse_str() //! //! ``` //! use syn::Type; //! //! # fn run_parser() -> syn::Result<()> { //! let t: Type = syn::parse_str("std::collections::HashMap<String, Value>")?; //! # Ok(()) //! # } //! # //! # run_parser().unwrap(); //! ``` //! //! The [`parse_quote!`] macro also uses this approach. //! //! [`parse_quote!`]: crate::parse_quote! //! //! # The `Parser` trait //! //! Some types can be parsed in several ways depending on context. For example //! an [`Attribute`] can be either "outer" like `#[...]` or "inner" like //! `#![...]` and parsing the wrong one would be a bug. Similarly [`Punctuated`] //! may or may not allow trailing punctuation, and parsing it the wrong way //! would either reject valid input or accept invalid input. //! //! [`Attribute`]: crate::Attribute //! [`Punctuated`]: crate::punctuated //! //! The `Parse` trait is not implemented in these cases because there is no good //! behavior to consider the default. //! //! ```compile_fail //! # extern crate proc_macro; //! # //! # use syn::punctuated::Punctuated; //! # use syn::{PathSegment, Result, Token}; //! # //! # fn f(tokens: proc_macro::TokenStream) -> Result<()> { //! # //! // Can't parse `Punctuated` without knowing whether trailing punctuation //! // should be allowed in this context. //! let path: Punctuated<PathSegment, Token![::]> = syn::parse(tokens)?; //! # //! # Ok(()) //! # } //! ``` //! //! In these cases the types provide a choice of parser functions rather than a //! single `Parse` implementation, and those parser functions can be invoked //! through the [`Parser`] trait. //! //! //! ``` //! # extern crate proc_macro; //! # //! use proc_macro::TokenStream; //! use syn::parse::Parser; //! use syn::punctuated::Punctuated; //! use syn::{Attribute, Expr, PathSegment, Result, Token}; //! //! fn call_some_parser_methods(input: TokenStream) -> Result<()> { //! // Parse a nonempty sequence of path segments separated by `::` punctuation //! // with no trailing punctuation. //! let tokens = input.clone(); //! let parser = Punctuated::<PathSegment, Token![::]>::parse_separated_nonempty; //! let _path = parser.parse(tokens)?; //! //! // Parse a possibly empty sequence of expressions terminated by commas with //! // an optional trailing punctuation. //! let tokens = input.clone(); //! let parser = Punctuated::<Expr, Token![,]>::parse_terminated; //! let _args = parser.parse(tokens)?; //! //! // Parse zero or more outer attributes but not inner attributes. //! let tokens = input.clone(); //! let parser = Attribute::parse_outer; //! let _attrs = parser.parse(tokens)?; //! //! Ok(()) //! } //! ``` #[path = "discouraged.rs"] pub mod discouraged; use crate::buffer::{Cursor, TokenBuffer}; use crate::error; use crate::lookahead; use crate::punctuated::Punctuated; use crate::token::Token; use proc_macro2::{Delimiter, Group, Literal, Punct, Span, TokenStream, TokenTree}; #[cfg(feature = "printing")] use quote::ToTokens; use std::cell::Cell; use std::fmt::{self, Debug, Display}; #[cfg(feature = "extra-traits")] use std::hash::{Hash, Hasher}; use std::marker::PhantomData; use std::mem; use std::ops::Deref; use std::panic::{RefUnwindSafe, UnwindSafe}; use std::rc::Rc; use std::str::FromStr; pub use crate::error::{Error, Result}; pub use crate::lookahead::{End, Lookahead1, Peek}; /// Parsing interface implemented by all types that can be parsed in a default /// way from a token stream. /// /// Refer to the [module documentation] for details about implementing and using /// the `Parse` trait. /// /// [module documentation]: self pub trait Parse: Sized { fn parse(input: ParseStream) -> Result<Self>; } /// Input to a Syn parser function. /// /// See the methods of this type under the documentation of [`ParseBuffer`]. For /// an overview of parsing in Syn, refer to the [module documentation]. /// /// [module documentation]: self pub type ParseStream<'a> = &'a ParseBuffer<'a>; /// Cursor position within a buffered token stream. /// /// This type is more commonly used through the type alias [`ParseStream`] which /// is an alias for `&ParseBuffer`. /// /// `ParseStream` is the input type for all parser functions in Syn. They have /// the signature `fn(ParseStream) -> Result<T>`. /// /// ## Calling a parser function /// /// There is no public way to construct a `ParseBuffer`. Instead, if you are /// looking to invoke a parser function that requires `ParseStream` as input, /// you will need to go through one of the public parsing entry points. /// /// - The [`parse_macro_input!`] macro if parsing input of a procedural macro; /// - One of [the `syn::parse*` functions][syn-parse]; or /// - A method of the [`Parser`] trait. /// /// [`parse_macro_input!`]: crate::parse_macro_input! /// [syn-parse]: self#the-synparse-functions pub struct ParseBuffer<'a> { scope: Span, // Instead of Cell<Cursor<'a>> so that ParseBuffer<'a> is covariant in 'a. // The rest of the code in this module needs to be careful that only a // cursor derived from this `cell` is ever assigned to this `cell`. // // Cell<Cursor<'a>> cannot be covariant in 'a because then we could take a // ParseBuffer<'a>, upcast to ParseBuffer<'short> for some lifetime shorter // than 'a, and then assign a Cursor<'short> into the Cell. // // By extension, it would not be safe to expose an API that accepts a // Cursor<'a> and trusts that it lives as long as the cursor currently in // the cell. cell: Cell<Cursor<'static>>, marker: PhantomData<Cursor<'a>>, unexpected: Cell<Option<Rc<Cell<Unexpected>>>>, } impl<'a> Drop for ParseBuffer<'a> { fn drop(&mut self) { if let Some((unexpected_span, delimiter)) = span_of_unexpected_ignoring_nones(self.cursor()) { let (inner, old_span) = inner_unexpected(self); if old_span.is_none() { inner.set(Unexpected::Some(unexpected_span, delimiter)); } } } } impl<'a> Display for ParseBuffer<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { Display::fmt(&self.cursor().token_stream(), f) } } impl<'a> Debug for ParseBuffer<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { Debug::fmt(&self.cursor().token_stream(), f) } } impl<'a> UnwindSafe for ParseBuffer<'a> {} impl<'a> RefUnwindSafe for ParseBuffer<'a> {} /// Cursor state associated with speculative parsing. /// /// This type is the input of the closure provided to [`ParseStream::step`]. /// /// [`ParseStream::step`]: ParseBuffer::step /// /// # Example /// /// ``` /// use proc_macro2::TokenTree; /// use syn::Result; /// use syn::parse::ParseStream; /// /// // This function advances the stream past the next occurrence of `@`. If /// // no `@` is present in the stream, the stream position is unchanged and /// // an error is returned. /// fn skip_past_next_at(input: ParseStream) -> Result<()> { /// input.step(|cursor| { /// let mut rest = *cursor; /// while let Some((tt, next)) = rest.token_tree() { /// match &tt { /// TokenTree::Punct(punct) if punct.as_char() == '@' => { /// return Ok(((), next)); /// } /// _ => rest = next, /// } /// } /// Err(cursor.error("no `@` was found after this point")) /// }) /// } /// # /// # fn remainder_after_skipping_past_next_at( /// # input: ParseStream, /// # ) -> Result<proc_macro2::TokenStream> { /// # skip_past_next_at(input)?; /// # input.parse() /// # } /// # /// # use syn::parse::Parser; /// # let remainder = remainder_after_skipping_past_next_at /// # .parse_str("a @ b c") /// # .unwrap(); /// # assert_eq!(remainder.to_string(), "b c"); /// ``` pub struct StepCursor<'c, 'a> { scope: Span, // This field is covariant in 'c. cursor: Cursor<'c>, // This field is contravariant in 'c. Together these make StepCursor // invariant in 'c. Also covariant in 'a. The user cannot cast 'c to a // different lifetime but can upcast into a StepCursor with a shorter // lifetime 'a. // // As long as we only ever construct a StepCursor for which 'c outlives 'a, // this means if ever a StepCursor<'c, 'a> exists we are guaranteed that 'c // outlives 'a. marker: PhantomData<fn(Cursor<'c>) -> Cursor<'a>>, } impl<'c, 'a> Deref for StepCursor<'c, 'a> { type Target = Cursor<'c>; fn deref(&self) -> &Self::Target { &self.cursor } } impl<'c, 'a> Copy for StepCursor<'c, 'a> {} impl<'c, 'a> Clone for StepCursor<'c, 'a> { fn clone(&self) -> Self { *self } } impl<'c, 'a> StepCursor<'c, 'a> { /// Triggers an error at the current position of the parse stream. /// /// The `ParseStream::step` invocation will return this same error without /// advancing the stream state. pub fn error<T: Display>(self, message: T) -> Error { error::new_at(self.scope, self.cursor, message) } } pub(crate) fn advance_step_cursor<'c, 'a>(proof: StepCursor<'c, 'a>, to: Cursor<'c>) -> Cursor<'a> { // Refer to the comments within the StepCursor definition. We use the // fact that a StepCursor<'c, 'a> exists as proof that 'c outlives 'a. // Cursor is covariant in its lifetime parameter so we can cast a // Cursor<'c> to one with the shorter lifetime Cursor<'a>. let _ = proof; unsafe { mem::transmute::<Cursor<'c>, Cursor<'a>>(to) } } pub(crate) fn new_parse_buffer( scope: Span, cursor: Cursor, unexpected: Rc<Cell<Unexpected>>, ) -> ParseBuffer { ParseBuffer { scope, // See comment on `cell` in the struct definition. cell: Cell::new(unsafe { mem::transmute::<Cursor, Cursor<'static>>(cursor) }), marker: PhantomData, unexpected: Cell::new(Some(unexpected)), } } pub(crate) enum Unexpected { None, Some(Span, Delimiter), Chain(Rc<Cell<Unexpected>>), } impl Default for Unexpected { fn default() -> Self { Unexpected::None } } impl Clone for Unexpected { fn clone(&self) -> Self { match self { Unexpected::None => Unexpected::None, Unexpected::Some(span, delimiter) => Unexpected::Some(*span, *delimiter), Unexpected::Chain(next) => Unexpected::Chain(next.clone()), } } } // We call this on Cell<Unexpected> and Cell<Option<T>> where temporarily // swapping in a None is cheap. fn cell_clone<T: Default + Clone>(cell: &Cell<T>) -> T { let prev = cell.take(); let ret = prev.clone(); cell.set(prev); ret } fn inner_unexpected(buffer: &ParseBuffer) -> (Rc<Cell<Unexpected>>, Option<(Span, Delimiter)>) { let mut unexpected = get_unexpected(buffer); loop { match cell_clone(&unexpected) { Unexpected::None => return (unexpected, None), Unexpected::Some(span, delimiter) => return (unexpected, Some((span, delimiter))), Unexpected::Chain(next) => unexpected = next, } } } pub(crate) fn get_unexpected(buffer: &ParseBuffer) -> Rc<Cell<Unexpected>> { cell_clone(&buffer.unexpected).unwrap() } fn span_of_unexpected_ignoring_nones(mut cursor: Cursor) -> Option<(Span, Delimiter)> { if cursor.eof() { return None; } while let Some((inner, _span, rest)) = cursor.group(Delimiter::None) { if let Some(unexpected) = span_of_unexpected_ignoring_nones(inner) { return Some(unexpected); } cursor = rest; } if cursor.eof() { None } else { Some((cursor.span(), cursor.scope_delimiter())) } } impl<'a> ParseBuffer<'a> { /// Parses a syntax tree node of type `T`, advancing the position of our /// parse stream past it. pub fn parse<T: Parse>(&self) -> Result<T> { T::parse(self) } /// Calls the given parser function to parse a syntax tree node of type `T` /// from this stream. /// /// # Example /// /// The parser below invokes [`Attribute::parse_outer`] to parse a vector of /// zero or more outer attributes. /// /// [`Attribute::parse_outer`]: crate::Attribute::parse_outer /// /// ``` /// use syn::{Attribute, Ident, Result, Token}; /// use syn::parse::{Parse, ParseStream}; /// /// // Parses a unit struct with attributes. /// // /// // #[path = "s.tmpl"] /// // struct S; /// struct UnitStruct { /// attrs: Vec<Attribute>, /// struct_token: Token![struct], /// name: Ident, /// semi_token: Token![;], /// } /// /// impl Parse for UnitStruct { /// fn parse(input: ParseStream) -> Result<Self> { /// Ok(UnitStruct { /// attrs: input.call(Attribute::parse_outer)?, /// struct_token: input.parse()?,