// SPDX-License-Identifier: Apache-2.0 OR MIT //! [![github]](https://github.com/dtolnay/syn) [![crates-io]](https://crates.io/crates/syn) [![docs-rs]](crate)//!//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs//!//! <br>//!//! Syn is a parsing library for parsing a stream of Rust tokens into a syntax//! tree of Rust source code.//!//! Currently this library is geared toward use in Rust procedural macros, but//! contains some APIs that may be useful more generally.//!//! - **Data structures** — Syn provides a complete syntax tree that can//! represent any valid Rust source code. The syntax tree is rooted at//! [`syn::File`] which represents a full source file, but there are other//! entry points that may be useful to procedural macros including//! [`syn::Item`], [`syn::Expr`] and [`syn::Type`].//!//! - **Derives** — Of particular interest to derive macros is//! [`syn::DeriveInput`] which is any of the three legal input items to a//! derive macro. An example below shows using this type in a library that can//! derive implementations of a user-defined trait.//!//! - **Parsing** — Parsing in Syn is built around [parser functions] with the//! signature `fn(ParseStream) -> Result<T>`. Every syntax tree node defined//! by Syn is individually parsable and may be used as a building block for//! custom syntaxes, or you may dream up your own brand new syntax without//! involving any of our syntax tree types.//!//! - **Location information** — Every token parsed by Syn is associated with a//! `Span` that tracks line and column information back to the source of that//! token. These spans allow a procedural macro to display detailed error//! messages pointing to all the right places in the user's code. There is an//! example of this below.//!//! - **Feature flags** — Functionality is aggressively feature gated so your//! procedural macros enable only what they need, and do not pay in compile//! time for all the rest.//!//! [`syn::File`]: File//! [`syn::Item`]: Item//! [`syn::Expr`]: Expr//! [`syn::Type`]: Type//! [`syn::DeriveInput`]: DeriveInput//! [parser functions]: mod@parse//!//! <br>//!//! # Example of a derive macro//!//! The canonical derive macro using Syn looks like this. We write an ordinary//! Rust function tagged with a `proc_macro_derive` attribute and the name of//! the trait we are deriving. Any time that derive appears in the user's code,//! the Rust compiler passes their data structure as tokens into our macro. We//! get to execute arbitrary Rust code to figure out what to do with those//! tokens, then hand some tokens back to the compiler to compile into the//! user's crate.//!//! [`TokenStream`]: proc_macro::TokenStream//!//! ```toml//! [dependencies]//! syn = "2.0"//! quote = "1.0"//!//! [lib]//! proc-macro = true//! ```//!//! ```//! # extern crate proc_macro;//! #//! use proc_macro::TokenStream;//! use quote::quote;//! use syn::{parse_macro_input, DeriveInput};//!//! # const IGNORE_TOKENS: &str = stringify! {//! #[proc_macro_derive(MyMacro)]//! # };//! pub fn my_macro(input: TokenStream) -> TokenStream {//! // Parse the input tokens into a syntax tree//! let input = parse_macro_input!(input as DeriveInput);//!//! // Build the output, possibly using quasi-quotation//! let expanded = quote! {//! // ...//! };//!//! // Hand the output tokens back to the compiler//! TokenStream::from(expanded)//! }//! ```//!//! The [`heapsize`] example directory shows a complete working implementation//! of a derive macro. The example derives a `HeapSize` trait which computes an//! estimate of the amount of heap memory owned by a value.//!//! [`heapsize`]: https://github.com/dtolnay/syn/tree/master/examples/heapsize//!//! ```//! pub trait HeapSize {//! /// Total number of bytes of heap memory owned by `self`.//! fn heap_size_of_children(&self) -> usize;//! }//! ```//!//! The derive macro allows users to write `#[derive(HeapSize)]` on data//! structures in their program.//!//! ```//! # const IGNORE_TOKENS: &str = stringify! {//! #[derive(HeapSize)]//! # };//! struct Demo<'a, T: ?Sized> {//! a: Box<T>,//! b: u8,//! c: &'a str,//! d: String,//! }//! ```//!//! <p><br></p>//!//! # Spans and error reporting//!//! The token-based procedural macro API provides great control over where the//! compiler's error messages are displayed in user code. Consider the error the//! user sees if one of their field types does not implement `HeapSize`.//!//! ```//! # const IGNORE_TOKENS: &str = stringify! {//! #[derive(HeapSize)]//! # };//! struct Broken {//! ok: String,//! bad: std::thread::Thread,//! }//! ```//!//! By tracking span information all the way through the expansion of a//! procedural macro as shown in the `heapsize` example, token-based macros in//! Syn are able to trigger errors that directly pinpoint the source of the//! problem.//!//! ```text//! error[E0277]: the trait bound `std::thread::Thread: HeapSize` is not satisfied//! --> src/main.rs:7:5//! |//! 7 | bad: std::thread::Thread,//! | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HeapSize` is not implemented for `Thread`//! ```//!//! <br>//!//! # Parsing a custom syntax//!//! The [`lazy-static`] example directory shows the implementation of a//! `functionlike!(...)` procedural macro in which the input tokens are parsed//! using Syn's parsing API.//!//! [`lazy-static`]: https://github.com/dtolnay/syn/tree/master/examples/lazy-static//!//! The example reimplements the popular `lazy_static` crate from crates.io as a//! procedural macro.//!//! ```//! # macro_rules! lazy_static {//! # ($($tt:tt)*) => {}//! # }//! #//! lazy_static! {//! static ref USERNAME: Regex = Regex::new("^[a-z0-9_-]{3,16}$").unwrap();//! }//! ```//!//! The implementation shows how to trigger custom warnings and error messages//! on the macro input.//!//! ```text//! warning: come on, pick a more creative name//! --> src/main.rs:10:16//! |//! 10 | static ref FOO: String = "lazy_static".to_owned();//! | ^^^//! ```//!//! <br>//!//! # Testing//!//! When testing macros, we often care not just that the macro can be used//! successfully but also that when the macro is provided with invalid input it//! produces maximally helpful error messages. Consider using the [`trybuild`]//! crate to write tests for errors that are emitted by your macro or errors//! detected by the Rust compiler in the expanded code following misuse of the//! macro. Such tests help avoid regressions from later refactors that//! mistakenly make an error no longer trigger or be less helpful than it used//! to be.//!//! [`trybuild`]: https://github.com/dtolnay/trybuild//!//! <br>//!//! # Debugging//!//! When developing a procedural macro it can be helpful to look at what the//! generated code looks like. Use `cargo rustc -- -Zunstable-options//! --pretty=expanded` or the [`cargo expand`] subcommand.//!//! [`cargo expand`]: https://github.com/dtolnay/cargo-expand//!//! To show the expanded code for some crate that uses your procedural macro,//! run `cargo expand` from that crate. To show the expanded code for one of//! your own test cases, run `cargo expand --test the_test_case` where the last//! argument is the name of the test file without the `.rs` extension.//!//! This write-up by Brandon W Maister discusses debugging in more detail://! [Debugging Rust's new Custom Derive system][debugging].//!//! [debugging]: https://quodlibetor.github.io/posts/debugging-rusts-new-custom-derive-system///!//! <br>//!//! # Optional features//!//! Syn puts a lot of functionality behind optional features in order to//! optimize compile time for the most common use cases. The following features//! are available.//!//! - **`derive`** *(enabled by default)* — Data structures for representing the//! possible input to a derive macro, including structs and enums and types.//! - **`full`** — Data structures for representing the syntax tree of all valid//! Rust source code, including items and expressions.//! - **`parsing`** *(enabled by default)* — Ability to parse input tokens into//! a syntax tree node of a chosen type.//! - **`printing`** *(enabled by default)* — Ability to print a syntax tree//! node as tokens of Rust source code.//! - **`visit`** — Trait for traversing a syntax tree.//! - **`visit-mut`** — Trait for traversing and mutating in place a syntax//! tree.//! - **`fold`** — Trait for transforming an owned syntax tree.//! - **`clone-impls`** *(enabled by default)* — Clone impls for all syntax tree//! types.//! - **`extra-traits`** — Debug, Eq, PartialEq, Hash impls for all syntax tree//! types.//! - **`proc-macro`** *(enabled by default)* — Runtime dependency on the//! dynamic library libproc_macro from rustc toolchain. // Syn types in rustdoc of other crates get linked to here.#![doc(html_root_url = "https://docs.rs/syn/2.0.106")]#![cfg_attr(docsrs, feature(doc_cfg))]#![deny(unsafe_op_in_unsafe_fn)]#![allow(non_camel_case_types)]#![cfg_attr(not(check_cfg), allow(unexpected_cfgs))]#![allow( clippy::bool_to_int_with_if, clippy::cast_lossless, clippy::cast_possible_truncation, clippy::cast_possible_wrap, clippy::cast_ptr_alignment, clippy::default_trait_access, clippy::derivable_impls, clippy::diverging_sub_expression, clippy::doc_markdown, clippy::elidable_lifetime_names, clippy::enum_glob_use, clippy::expl_impl_clone_on_copy, clippy::explicit_auto_deref, clippy::fn_params_excessive_bools, clippy::if_not_else, clippy::inherent_to_string, clippy::into_iter_without_iter, clippy::items_after_statements, clippy::large_enum_variant, clippy::let_underscore_untyped, // https://github.com/rust-lang/rust-clippy/issues/10410 clippy::manual_assert, clippy::manual_let_else, clippy::manual_map, clippy::match_like_matches_macro, clippy::match_same_arms, clippy::match_wildcard_for_single_variants, // clippy bug: https://github.com/rust-lang/rust-clippy/issues/6984 clippy::missing_errors_doc, clippy::missing_panics_doc, clippy::module_name_repetitions, clippy::must_use_candidate, clippy::needless_doctest_main, clippy::needless_lifetimes, clippy::needless_pass_by_value, clippy::needless_update, clippy::never_loop, clippy::range_plus_one, clippy::redundant_else, clippy::ref_option, clippy::return_self_not_must_use, clippy::similar_names, clippy::single_match_else, clippy::struct_excessive_bools, clippy::too_many_arguments, clippy::too_many_lines, clippy::trivially_copy_pass_by_ref, clippy::unconditional_recursion, // https://github.com/rust-lang/rust-clippy/issues/12133 clippy::uninhabited_references, clippy::uninlined_format_args, clippy::unnecessary_box_returns, clippy::unnecessary_unwrap, clippy::used_underscore_binding, clippy::wildcard_imports,)]#![allow(unknown_lints, mismatched_lifetime_syntaxes)] extern crate self as syn; #[cfg(feature = "proc-macro")]extern crate proc_macro; #[macro_use]mod macros; #[cfg(feature = "parsing")]#[macro_use]mod group; #[macro_use]pub mod token; #[cfg(any(feature = "full", feature = "derive"))]mod attr;#[cfg(any(feature = "full", feature = "derive"))]#[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]pub use crate::attr::{AttrStyle, Attribute, Meta, MetaList, MetaNameValue}; mod bigint; #[cfg(feature = "parsing")]#[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]pub mod buffer; #[cfg(any( all(feature = "parsing", feature = "full"), all(feature = "printing", any(feature = "full", feature = "derive")),))]mod classify; mod custom_keyword; mod custom_punctuation; #[cfg(any(feature = "full", feature = "derive"))]mod data;#[cfg(any(feature = "full", feature = "derive"))]#[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]pub use crate::data::{Field, Fields, FieldsNamed, FieldsUnnamed, Variant}; #[cfg(any(feature = "full", feature = "derive"))]mod derive;#[cfg(feature = "derive")]#[cfg_attr(docsrs, doc(cfg(feature = "derive")))]pub use crate::derive::{Data, DataEnum, DataStruct, DataUnion, DeriveInput}; mod drops; mod error;pub use crate::error::{Error, Result}; #[cfg(any(feature = "full", feature = "derive"))]mod expr;#[cfg(feature = "full")]#[cfg_attr(docsrs, doc(cfg(feature = "full")))]pub use crate::expr::{Arm, Label, PointerMutability, RangeLimits};#[cfg(any(feature = "full", feature = "derive"))]#[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]pub use crate::expr::{ Expr, ExprBinary, ExprCall, ExprCast, ExprField, ExprIndex, ExprLit, ExprMacro, ExprMethodCall, ExprParen, ExprPath, ExprReference, ExprStruct, ExprUnary, FieldValue, Index, Member,};#[cfg(any(feature = "full", feature = "derive"))]#[cfg_attr(docsrs, doc(cfg(feature = "full")))]pub use crate::expr::{ ExprArray, ExprAssign, ExprAsync, ExprAwait, ExprBlock, ExprBreak, ExprClosure, ExprConst, ExprContinue, ExprForLoop, ExprGroup, ExprIf, ExprInfer, ExprLet, ExprLoop, ExprMatch, ExprRange, ExprRawAddr, ExprRepeat, ExprReturn, ExprTry, ExprTryBlock, ExprTuple, ExprUnsafe, ExprWhile, ExprYield,}; #[cfg(feature = "parsing")]#[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]pub mod ext; #[cfg(feature = "full")]mod file;#[cfg(feature = "full")]#[cfg_attr(docsrs, doc(cfg(feature = "full")))]pub use crate::file::File; #[cfg(all(any(feature = "full", feature = "derive"), feature = "printing"))]mod fixup; #[cfg(any(feature = "full", feature = "derive"))]mod generics;#[cfg(any(feature = "full", feature = "derive"))]#[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]pub use crate::generics::{ BoundLifetimes, ConstParam, GenericParam, Generics, LifetimeParam, PredicateLifetime, PredicateType, TraitBound, TraitBoundModifier, TypeParam, TypeParamBound, WhereClause, WherePredicate,};#[cfg(feature = "full")]#[cfg_attr(docsrs, doc(cfg(feature = "full")))]pub use crate::generics::{CapturedParam, PreciseCapture};#[cfg(all(any(feature = "full", feature = "derive"), feature = "printing"))]#[cfg_attr( docsrs, doc(cfg(all(any(feature = "full", feature = "derive"), feature = "printing"))))]pub use crate::generics::{ImplGenerics, Turbofish, TypeGenerics}; mod ident;#[doc(inline)]pub use crate::ident::Ident; #[cfg(feature = "full")]mod item;#[cfg(feature = "full")]#[cfg_attr(docsrs, doc(cfg(feature = "full")))]pub use crate::item::{ FnArg, ForeignItem, ForeignItemFn, ForeignItemMacro, ForeignItemStatic, ForeignItemType, ImplItem, ImplItemConst, ImplItemFn, ImplItemMacro, ImplItemType, ImplRestriction, Item, ItemConst, ItemEnum, ItemExternCrate, ItemFn, ItemForeignMod, ItemImpl, ItemMacro, ItemMod, ItemStatic, ItemStruct, ItemTrait, ItemTraitAlias, ItemType, ItemUnion, ItemUse, Receiver, Signature, StaticMutability, TraitItem, TraitItemConst, TraitItemFn, TraitItemMacro, TraitItemType, UseGlob, UseGroup, UseName, UsePath, UseRename, UseTree, Variadic,}; mod lifetime;#[doc(inline)]pub use crate::lifetime::Lifetime; mod lit;#[doc(hidden)] // https://github.com/dtolnay/syn/issues/1566pub use crate::lit::StrStyle;#[doc(inline)]pub use crate::lit::{ Lit, LitBool, LitByte, LitByteStr, LitCStr, LitChar, LitFloat, LitInt, LitStr,}; #[cfg(feature = "parsing")]mod lookahead; #[cfg(any(feature = "full", feature = "derive"))]mod mac;#[cfg(any(feature = "full", feature = "derive"))]#[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]pub use crate::mac::{Macro, MacroDelimiter}; #[cfg(all(feature = "parsing", any(feature = "full", feature = "derive")))]#[cfg_attr( docsrs, doc(cfg(all(feature = "parsing", any(feature = "full", feature = "derive")))))]pub mod meta; #[cfg(any(feature = "full", feature = "derive"))]mod op;#[cfg(any(feature = "full", feature = "derive"))]#[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]pub use crate::op::{BinOp, UnOp}; #[cfg(feature = "parsing")]#[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]pub mod parse; #[cfg(all(feature = "parsing", feature = "proc-macro"))]mod parse_macro_input; #[cfg(all(feature = "parsing", feature = "printing"))]mod parse_quote; #[cfg(feature = "full")]mod pat;#[cfg(feature = "full")]#[cfg_attr(docsrs, doc(cfg(feature = "full")))]pub use crate::pat::{ FieldPat, Pat, PatConst, PatIdent, PatLit, PatMacro, PatOr, PatParen, PatPath, PatRange, PatReference, PatRest, PatSlice, PatStruct, PatTuple, PatTupleStruct, PatType, PatWild,}; #[cfg(any(feature = "full", feature = "derive"))]mod path;#[cfg(any(feature = "full", feature = "derive"))]#[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]pub use crate::path::{ AngleBracketedGenericArguments, AssocConst, AssocType, Constraint, GenericArgument, ParenthesizedGenericArguments, Path, PathArguments, PathSegment, QSelf,}; #[cfg(all(Lines 1–500 of 1013. Load more
// SPDX-License-Identifier: Apache-2.0 OR MIT //! [![github]](https://github.com/dtolnay/syn) [![crates-io]](https://crates.io/crates/syn) [![docs-rs]](crate) //! //! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github //! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust //! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs //! //! <br> //! //! Syn is a parsing library for parsing a stream of Rust tokens into a syntax //! tree of Rust source code. //! //! Currently this library is geared toward use in Rust procedural macros, but //! contains some APIs that may be useful more generally. //! //! - **Data structures** — Syn provides a complete syntax tree that can //! represent any valid Rust source code. The syntax tree is rooted at //! [`syn::File`] which represents a full source file, but there are other //! entry points that may be useful to procedural macros including //! [`syn::Item`], [`syn::Expr`] and [`syn::Type`]. //! //! - **Derives** — Of particular interest to derive macros is //! [`syn::DeriveInput`] which is any of the three legal input items to a //! derive macro. An example below shows using this type in a library that can //! derive implementations of a user-defined trait. //! //! - **Parsing** — Parsing in Syn is built around [parser functions] with the //! signature `fn(ParseStream) -> Result<T>`. Every syntax tree node defined //! by Syn is individually parsable and may be used as a building block for //! custom syntaxes, or you may dream up your own brand new syntax without //! involving any of our syntax tree types. //! //! - **Location information** — Every token parsed by Syn is associated with a //! `Span` that tracks line and column information back to the source of that //! token. These spans allow a procedural macro to display detailed error //! messages pointing to all the right places in the user's code. There is an //! example of this below. //! //! - **Feature flags** — Functionality is aggressively feature gated so your //! procedural macros enable only what they need, and do not pay in compile //! time for all the rest. //! //! [`syn::File`]: File //! [`syn::Item`]: Item //! [`syn::Expr`]: Expr //! [`syn::Type`]: Type //! [`syn::DeriveInput`]: DeriveInput //! [parser functions]: mod@parse //! //! <br> //! //! # Example of a derive macro //! //! The canonical derive macro using Syn looks like this. We write an ordinary //! Rust function tagged with a `proc_macro_derive` attribute and the name of //! the trait we are deriving. Any time that derive appears in the user's code, //! the Rust compiler passes their data structure as tokens into our macro. We //! get to execute arbitrary Rust code to figure out what to do with those //! tokens, then hand some tokens back to the compiler to compile into the //! user's crate. //! //! [`TokenStream`]: proc_macro::TokenStream //! //! ```toml //! [dependencies] //! syn = "2.0" //! quote = "1.0" //! //! [lib] //! proc-macro = true //! ``` //! //! ``` //! # extern crate proc_macro; //! # //! use proc_macro::TokenStream; //! use quote::quote; //! use syn::{parse_macro_input, DeriveInput}; //! //! # const IGNORE_TOKENS: &str = stringify! { //! #[proc_macro_derive(MyMacro)] //! # }; //! pub fn my_macro(input: TokenStream) -> TokenStream { //! // Parse the input tokens into a syntax tree //! let input = parse_macro_input!(input as DeriveInput); //! //! // Build the output, possibly using quasi-quotation //! let expanded = quote! { //! // ... //! }; //! //! // Hand the output tokens back to the compiler //! TokenStream::from(expanded) //! } //! ``` //! //! The [`heapsize`] example directory shows a complete working implementation //! of a derive macro. The example derives a `HeapSize` trait which computes an //! estimate of the amount of heap memory owned by a value. //! //! [`heapsize`]: https://github.com/dtolnay/syn/tree/master/examples/heapsize //! //! ``` //! pub trait HeapSize { //! /// Total number of bytes of heap memory owned by `self`. //! fn heap_size_of_children(&self) -> usize; //! } //! ``` //! //! The derive macro allows users to write `#[derive(HeapSize)]` on data //! structures in their program. //! //! ``` //! # const IGNORE_TOKENS: &str = stringify! { //! #[derive(HeapSize)] //! # }; //! struct Demo<'a, T: ?Sized> { //! a: Box<T>, //! b: u8, //! c: &'a str, //! d: String, //! } //! ``` //! //! <p><br></p> //! //! # Spans and error reporting //! //! The token-based procedural macro API provides great control over where the //! compiler's error messages are displayed in user code. Consider the error the //! user sees if one of their field types does not implement `HeapSize`. //! //! ``` //! # const IGNORE_TOKENS: &str = stringify! { //! #[derive(HeapSize)] //! # }; //! struct Broken { //! ok: String, //! bad: std::thread::Thread, //! } //! ``` //! //! By tracking span information all the way through the expansion of a //! procedural macro as shown in the `heapsize` example, token-based macros in //! Syn are able to trigger errors that directly pinpoint the source of the //! problem. //! //! ```text //! error[E0277]: the trait bound `std::thread::Thread: HeapSize` is not satisfied //! --> src/main.rs:7:5 //! | //! 7 | bad: std::thread::Thread, //! | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HeapSize` is not implemented for `Thread` //! ``` //! //! <br> //! //! # Parsing a custom syntax //! //! The [`lazy-static`] example directory shows the implementation of a //! `functionlike!(...)` procedural macro in which the input tokens are parsed //! using Syn's parsing API. //! //! [`lazy-static`]: https://github.com/dtolnay/syn/tree/master/examples/lazy-static //! //! The example reimplements the popular `lazy_static` crate from crates.io as a //! procedural macro. //! //! ``` //! # macro_rules! lazy_static { //! # ($($tt:tt)*) => {} //! # } //! # //! lazy_static! { //! static ref USERNAME: Regex = Regex::new("^[a-z0-9_-]{3,16}$").unwrap(); //! } //! ``` //! //! The implementation shows how to trigger custom warnings and error messages //! on the macro input. //! //! ```text //! warning: come on, pick a more creative name //! --> src/main.rs:10:16 //! | //! 10 | static ref FOO: String = "lazy_static".to_owned(); //! | ^^^ //! ``` //! //! <br> //! //! # Testing //! //! When testing macros, we often care not just that the macro can be used //! successfully but also that when the macro is provided with invalid input it //! produces maximally helpful error messages. Consider using the [`trybuild`] //! crate to write tests for errors that are emitted by your macro or errors //! detected by the Rust compiler in the expanded code following misuse of the //! macro. Such tests help avoid regressions from later refactors that //! mistakenly make an error no longer trigger or be less helpful than it used //! to be. //! //! [`trybuild`]: https://github.com/dtolnay/trybuild //! //! <br> //! //! # Debugging //! //! When developing a procedural macro it can be helpful to look at what the //! generated code looks like. Use `cargo rustc -- -Zunstable-options //! --pretty=expanded` or the [`cargo expand`] subcommand. //! //! [`cargo expand`]: https://github.com/dtolnay/cargo-expand //! //! To show the expanded code for some crate that uses your procedural macro, //! run `cargo expand` from that crate. To show the expanded code for one of //! your own test cases, run `cargo expand --test the_test_case` where the last //! argument is the name of the test file without the `.rs` extension. //! //! This write-up by Brandon W Maister discusses debugging in more detail: //! [Debugging Rust's new Custom Derive system][debugging]. //! //! [debugging]: https://quodlibetor.github.io/posts/debugging-rusts-new-custom-derive-system/ //! //! <br> //! //! # Optional features //! //! Syn puts a lot of functionality behind optional features in order to //! optimize compile time for the most common use cases. The following features //! are available. //! //! - **`derive`** *(enabled by default)* — Data structures for representing the //! possible input to a derive macro, including structs and enums and types. //! - **`full`** — Data structures for representing the syntax tree of all valid //! Rust source code, including items and expressions. //! - **`parsing`** *(enabled by default)* — Ability to parse input tokens into //! a syntax tree node of a chosen type. //! - **`printing`** *(enabled by default)* — Ability to print a syntax tree //! node as tokens of Rust source code. //! - **`visit`** — Trait for traversing a syntax tree. //! - **`visit-mut`** — Trait for traversing and mutating in place a syntax //! tree. //! - **`fold`** — Trait for transforming an owned syntax tree. //! - **`clone-impls`** *(enabled by default)* — Clone impls for all syntax tree //! types. //! - **`extra-traits`** — Debug, Eq, PartialEq, Hash impls for all syntax tree //! types. //! - **`proc-macro`** *(enabled by default)* — Runtime dependency on the //! dynamic library libproc_macro from rustc toolchain. // Syn types in rustdoc of other crates get linked to here. #![doc(html_root_url = "https://docs.rs/syn/2.0.106")] #![cfg_attr(docsrs, feature(doc_cfg))] #![deny(unsafe_op_in_unsafe_fn)] #![allow(non_camel_case_types)] #![cfg_attr(not(check_cfg), allow(unexpected_cfgs))] #![allow( clippy::bool_to_int_with_if, clippy::cast_lossless, clippy::cast_possible_truncation, clippy::cast_possible_wrap, clippy::cast_ptr_alignment, clippy::default_trait_access, clippy::derivable_impls, clippy::diverging_sub_expression, clippy::doc_markdown, clippy::elidable_lifetime_names, clippy::enum_glob_use, clippy::expl_impl_clone_on_copy, clippy::explicit_auto_deref, clippy::fn_params_excessive_bools, clippy::if_not_else, clippy::inherent_to_string, clippy::into_iter_without_iter, clippy::items_after_statements, clippy::large_enum_variant, clippy::let_underscore_untyped, // https://github.com/rust-lang/rust-clippy/issues/10410 clippy::manual_assert, clippy::manual_let_else, clippy::manual_map, clippy::match_like_matches_macro, clippy::match_same_arms, clippy::match_wildcard_for_single_variants, // clippy bug: https://github.com/rust-lang/rust-clippy/issues/6984 clippy::missing_errors_doc, clippy::missing_panics_doc, clippy::module_name_repetitions, clippy::must_use_candidate, clippy::needless_doctest_main, clippy::needless_lifetimes, clippy::needless_pass_by_value, clippy::needless_update, clippy::never_loop, clippy::range_plus_one, clippy::redundant_else, clippy::ref_option, clippy::return_self_not_must_use, clippy::similar_names, clippy::single_match_else, clippy::struct_excessive_bools, clippy::too_many_arguments, clippy::too_many_lines, clippy::trivially_copy_pass_by_ref, clippy::unconditional_recursion, // https://github.com/rust-lang/rust-clippy/issues/12133 clippy::uninhabited_references, clippy::uninlined_format_args, clippy::unnecessary_box_returns, clippy::unnecessary_unwrap, clippy::used_underscore_binding, clippy::wildcard_imports, )] #![allow(unknown_lints, mismatched_lifetime_syntaxes)] extern crate self as syn; #[cfg(feature = "proc-macro")] extern crate proc_macro; #[macro_use] mod macros; #[cfg(feature = "parsing")] #[macro_use] mod group; #[macro_use] pub mod token; #[cfg(any(feature = "full", feature = "derive"))] mod attr; #[cfg(any(feature = "full", feature = "derive"))] #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] pub use crate::attr::{AttrStyle, Attribute, Meta, MetaList, MetaNameValue}; mod bigint; #[cfg(feature = "parsing")] #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] pub mod buffer; #[cfg(any( all(feature = "parsing", feature = "full"), all(feature = "printing", any(feature = "full", feature = "derive")), ))] mod classify; mod custom_keyword; mod custom_punctuation; #[cfg(any(feature = "full", feature = "derive"))] mod data; #[cfg(any(feature = "full", feature = "derive"))] #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] pub use crate::data::{Field, Fields, FieldsNamed, FieldsUnnamed, Variant}; #[cfg(any(feature = "full", feature = "derive"))] mod derive; #[cfg(feature = "derive")] #[cfg_attr(docsrs, doc(cfg(feature = "derive")))] pub use crate::derive::{Data, DataEnum, DataStruct, DataUnion, DeriveInput}; mod drops; mod error; pub use crate::error::{Error, Result}; #[cfg(any(feature = "full", feature = "derive"))] mod expr; #[cfg(feature = "full")] #[cfg_attr(docsrs, doc(cfg(feature = "full")))] pub use crate::expr::{Arm, Label, PointerMutability, RangeLimits}; #[cfg(any(feature = "full", feature = "derive"))] #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] pub use crate::expr::{ Expr, ExprBinary, ExprCall, ExprCast, ExprField, ExprIndex, ExprLit, ExprMacro, ExprMethodCall, ExprParen, ExprPath, ExprReference, ExprStruct, ExprUnary, FieldValue, Index, Member, }; #[cfg(any(feature = "full", feature = "derive"))] #[cfg_attr(docsrs, doc(cfg(feature = "full")))] pub use crate::expr::{ ExprArray, ExprAssign, ExprAsync, ExprAwait, ExprBlock, ExprBreak, ExprClosure, ExprConst, ExprContinue, ExprForLoop, ExprGroup, ExprIf, ExprInfer, ExprLet, ExprLoop, ExprMatch, ExprRange, ExprRawAddr, ExprRepeat, ExprReturn, ExprTry, ExprTryBlock, ExprTuple, ExprUnsafe, ExprWhile, ExprYield, }; #[cfg(feature = "parsing")] #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] pub mod ext; #[cfg(feature = "full")] mod file; #[cfg(feature = "full")] #[cfg_attr(docsrs, doc(cfg(feature = "full")))] pub use crate::file::File; #[cfg(all(any(feature = "full", feature = "derive"), feature = "printing"))] mod fixup; #[cfg(any(feature = "full", feature = "derive"))] mod generics; #[cfg(any(feature = "full", feature = "derive"))] #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] pub use crate::generics::{ BoundLifetimes, ConstParam, GenericParam, Generics, LifetimeParam, PredicateLifetime, PredicateType, TraitBound, TraitBoundModifier, TypeParam, TypeParamBound, WhereClause, WherePredicate, }; #[cfg(feature = "full")] #[cfg_attr(docsrs, doc(cfg(feature = "full")))] pub use crate::generics::{CapturedParam, PreciseCapture}; #[cfg(all(any(feature = "full", feature = "derive"), feature = "printing"))] #[cfg_attr( docsrs, doc(cfg(all(any(feature = "full", feature = "derive"), feature = "printing"))) )] pub use crate::generics::{ImplGenerics, Turbofish, TypeGenerics}; mod ident; #[doc(inline)] pub use crate::ident::Ident; #[cfg(feature = "full")] mod item; #[cfg(feature = "full")] #[cfg_attr(docsrs, doc(cfg(feature = "full")))] pub use crate::item::{ FnArg, ForeignItem, ForeignItemFn, ForeignItemMacro, ForeignItemStatic, ForeignItemType, ImplItem, ImplItemConst, ImplItemFn, ImplItemMacro, ImplItemType, ImplRestriction, Item, ItemConst, ItemEnum, ItemExternCrate, ItemFn, ItemForeignMod, ItemImpl, ItemMacro, ItemMod, ItemStatic, ItemStruct, ItemTrait, ItemTraitAlias, ItemType, ItemUnion, ItemUse, Receiver, Signature, StaticMutability, TraitItem, TraitItemConst, TraitItemFn, TraitItemMacro, TraitItemType, UseGlob, UseGroup, UseName, UsePath, UseRename, UseTree, Variadic, }; mod lifetime; #[doc(inline)] pub use crate::lifetime::Lifetime; mod lit; #[doc(hidden)] // https://github.com/dtolnay/syn/issues/1566 pub use crate::lit::StrStyle; #[doc(inline)] pub use crate::lit::{ Lit, LitBool, LitByte, LitByteStr, LitCStr, LitChar, LitFloat, LitInt, LitStr, }; #[cfg(feature = "parsing")] mod lookahead; #[cfg(any(feature = "full", feature = "derive"))] mod mac; #[cfg(any(feature = "full", feature = "derive"))] #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] pub use crate::mac::{Macro, MacroDelimiter}; #[cfg(all(feature = "parsing", any(feature = "full", feature = "derive")))] #[cfg_attr( docsrs, doc(cfg(all(feature = "parsing", any(feature = "full", feature = "derive")))) )] pub mod meta; #[cfg(any(feature = "full", feature = "derive"))] mod op; #[cfg(any(feature = "full", feature = "derive"))] #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] pub use crate::op::{BinOp, UnOp}; #[cfg(feature = "parsing")] #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] pub mod parse; #[cfg(all(feature = "parsing", feature = "proc-macro"))] mod parse_macro_input; #[cfg(all(feature = "parsing", feature = "printing"))] mod parse_quote; #[cfg(feature = "full")] mod pat; #[cfg(feature = "full")] #[cfg_attr(docsrs, doc(cfg(feature = "full")))] pub use crate::pat::{ FieldPat, Pat, PatConst, PatIdent, PatLit, PatMacro, PatOr, PatParen, PatPath, PatRange, PatReference, PatRest, PatSlice, PatStruct, PatTuple, PatTupleStruct, PatType, PatWild, }; #[cfg(any(feature = "full", feature = "derive"))] mod path; #[cfg(any(feature = "full", feature = "derive"))] #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] pub use crate::path::{ AngleBracketedGenericArguments, AssocConst, AssocType, Constraint, GenericArgument, ParenthesizedGenericArguments, Path, PathArguments, PathSegment, QSelf, }; #[cfg(all(