Expand description
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::Filewhich represents a full source file, but there are other entry points that may be useful to procedural macros includingsyn::Item,syn::Exprandsyn::Type.
- 
Derives — Of particular interest to derive macros is syn::DeriveInputwhich 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 Spanthat 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. 
§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.
[dependencies]
syn = "2.0"
quote = "1.0"
[lib]
proc-macro = true
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, DeriveInput};
#[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.
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.
#[derive(HeapSize)]
struct Demo<'a, T: ?Sized> {
    a: Box<T>,
    b: u8,
    c: &'a str,
    d: String,
}§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.
#[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.
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`
§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.
The example reimplements the popular lazy_static crate from crates.io as a
procedural macro.
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.
warning: come on, pick a more creative name
  --> src/main.rs:10:16
   |
10 |     static ref FOO: String = "lazy_static".to_owned();
   |                ^^^
§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.
§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.
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.
§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.
Modules§
- bufferparsingA stably addressed token buffer supporting efficient traversal based on a cheaply copyable cursor.
- extparsingExtension traits to provide parsing methods on foreign types.
- foldfoldSyntax tree traversal to transform the nodes of an owned syntax tree.
- metaparsingand (fullorderive)Facility for interpreting structured content inside of anAttribute.
- parseparsingParsing interface for parsing a token stream into a syntax tree node.
- A punctuated sequence of syntax tree nodes separated by punctuation.
- spannedparsingandprintingA trait that can provide theSpanof the complete contents of a syntax tree node.
- Tokens representing Rust punctuation, keywords, and delimiters.
- visitvisitSyntax tree traversal to walk a shared borrow of a syntax tree.
- visit_mutvisit-mutSyntax tree traversal to mutate an exclusive borrow of a syntax tree in place.
Macros§
- A type-macro that expands to the name of the Rust type representation of a given token.
- bracedparsingParse a set of curly braces and expose their content to subsequent parsers.
- bracketedparsingParse a set of square brackets and expose their content to subsequent parsers.
- Define a type that supports parsing and printing a given identifier as if it were a keyword.
- Define a type that supports parsing and printing a multi-character symbol as if it were a punctuation token.
- parenthesizedparsingParse a set of parentheses and expose their content to subsequent parsers.
- parse_macro_inputparsingandproc-macroParse the input TokenStream of a macro, triggering a compile error if the tokens fail to parse.
- parse_quoteparsingandprintingQuasi-quotation macro that accepts input like thequote!macro but uses type inference to figure out a return type for those tokens.
- parse_quote_spannedparsingandprintingThis macro isparse_quote!+quote_spanned!.
Structs§
- AbifullorderiveThe binary interface of a function:extern "C".
- AngleBracketedGenericArgumentsfullorderiveAngle bracketed arguments of a path segment: the<K, V>inHashMap<K, V>.
- ArmfullOne arm of amatchexpression:0..=10 => { return true; }.
- AssocConstfullorderiveAn equality constraint on an associated constant: thePANIC = falseinTrait<PANIC = false>.
- AssocTypefullorderiveA binding (equality constraint) on an associated type: theItem = u8inIterator<Item = u8>.
- AttributefullorderiveAn attribute, like#[repr(transparent)].
- BareFnArgfullorderiveAn argument in a function type: theusizeinfn(usize) -> bool.
- BareVariadicfullorderiveThe variadic argument of a function pointer likefn(usize, ...).
- BlockfullA braced block containing Rust statements.
- BoundLifetimesfullorderiveA set of bound lifetimes:for<'a, 'b, 'c>.
- ConstParamfullorderiveA const generic parameter:const LENGTH: usize.
- ConstraintfullorderiveAn associated type bound:Iterator<Item: Display>.
- DataEnumderiveAn enum input to aproc_macro_derivemacro.
- DataStructderiveA struct input to aproc_macro_derivemacro.
- DataUnionderiveAn untagged union input to aproc_macro_derivemacro.
- DeriveInputderiveData structure sent to aproc_macro_derivemacro.
- Error returned when a Syn parser cannot parse the input tokens.
- ExprArrayfullA slice literal expression:[a, b, c, d].
- ExprAssignfullAn assignment expression:a = compute().
- ExprAsyncfullAn async block:async { ... }.
- ExprAwaitfullAn await expression:fut.await.
- ExprBinaryfullorderiveA binary operation:a + b,a += b.
- ExprBlockfullA blocked scope:{ ... }.
- ExprBreakfullAbreak, with an optional label to break and an optional expression.
- ExprCallfullorderiveA function call expression:invoke(a, b).
- ExprCastfullorderiveA cast expression:foo as f64.
- ExprClosurefullA closure expression:|a, b| a + b.
- ExprConstfullA const block:const { ... }.
- ExprContinuefullAcontinue, with an optional label.
- ExprFieldfullorderiveAccess of a named struct field (obj.k) or unnamed tuple struct field (obj.0).
- ExprForLoopfullA for loop:for pat in expr { ... }.
- ExprGroupfullAn expression contained within invisible delimiters.
- ExprIffullAnifexpression with an optionalelseblock:if expr { ... } else { ... }.
- ExprIndexfullorderiveA square bracketed indexing expression:vector[2].
- ExprInferfullThe inferred value of a const generic argument, denoted_.
- ExprLetfullAletguard:let Some(x) = opt.
- ExprLitfullorderiveA literal in place of an expression:1,"foo".
- ExprLoopfullConditionless loop:loop { ... }.
- ExprMacrofullorderiveA macro invocation expression:format!("{}", q).
- ExprMatchfullAmatchexpression:match n { Some(n) => {}, None => {} }.
- ExprMethodCallfullorderiveA method call expression:x.foo::<T>(a, b).
- ExprParenfullorderiveA parenthesized expression:(a + b).
- ExprPathfullorderiveA path likestd::mem::replacepossibly containing generic parameters and a qualified self-type.
- ExprRangefullA range expression:1..2,1..,..2,1..=2,..=2.
- ExprReferencefullorderiveA referencing operation:&aor&mut a.
- ExprRepeatfullAn array literal constructed from one repeated element:[0u8; N].
- ExprReturnfullAreturn, with an optional value to be returned.
- ExprStructfullorderiveA struct literal expression:Point { x: 1, y: 1 }.
- ExprTryfullA try-expression:expr?.
- ExprTryBlockfullA try block:try { ... }.
- ExprTuplefullA tuple expression:(a, b, c, d).
- ExprUnaryfullorderiveA unary operation:!x,*x.
- ExprUnsafefullAn unsafe block:unsafe { ... }.
- ExprWhilefullA while loop:while expr { ... }.
- ExprYieldfullA yield expression:yield expr.
- FieldfullorderiveA field of a struct or enum variant.
- FieldPatfullA single field in a struct pattern.
- FieldValuefullorderiveA field-value pair in a struct literal.
- FieldsNamedfullorderiveNamed fields of a struct or struct variant such asPoint { x: f64, y: f64 }.
- FieldsUnnamedfullorderiveUnnamed fields of a tuple struct or tuple variant such asSome(T).
- FilefullA complete file of Rust source code.
- ForeignItemFnfullA foreign function in anexternblock.
- ForeignItemMacrofullA macro invocation within an extern block.
- A foreign static item in anexternblock:static ext: u8.
- ForeignItemTypefullA foreign type in anexternblock:type void.
- GenericsfullorderiveLifetimes and type parameters attached to a declaration of a function, enum, trait, etc.
- A word of Rust code, which may be a keyword or legal variable name.
- ImplGenerics(fullorderive) andprintingReturned byGenerics::split_for_impl.
- ImplItemConstfullAn associated constant within an impl block.
- ImplItemFnfullAn associated function within an impl block.
- ImplItemMacrofullA macro invocation within an impl block.
- ImplItemTypefullAn associated type within an impl block.
- IndexfullorderiveThe index of an unnamed tuple struct field.
- ItemConstfullA constant item:const MAX: u16 = 65535.
- ItemEnumfullAn enum definition:enum Foo<A, B> { A(A), B(B) }.
- ItemExternCratefullAnextern crateitem:extern crate serde.
- ItemFnfullA free-standing function:fn process(n: usize) -> Result<()> { ... }.
- ItemForeignModfullA block of foreign items:extern "C" { ... }.
- ItemImplfullAn impl block providing trait or associated items:impl<A> Trait for Data<A> { ... }.
- ItemMacrofullA macro invocation, which includesmacro_rules!definitions.
- ItemModfullA module or module declaration:mod mormod m { ... }.
- ItemStaticfullA static item:static BIKE: Shed = Shed(42).
- ItemStructfullA struct definition:struct Foo<A> { x: A }.
- ItemTraitfullA trait definition:pub trait Iterator { ... }.
- ItemTraitAliasfullA trait alias:pub trait SharableIterator = Iterator + Sync.
- ItemTypefullA type alias:type Result<T> = std::result::Result<T, MyError>.
- ItemUnionfullA union definition:union Foo<A, B> { x: A, y: B }.
- ItemUsefullA use declaration:use std::collections::HashMap.
- LabelfullA lifetime labeling afor,while, orloop.
- A Rust lifetime:'a.
- LifetimeParamfullorderiveA lifetime definition:'a: 'b + 'c + 'd.
- A boolean literal:trueorfalse.
- A byte literal:b'f'.
- A byte string literal:b"foo".
- A nul-terminated C-string literal:c"foo".
- A character literal:'a'.
- A floating point literal:1f64or1.0e10f64.
- An integer literal:1or1u16.
- A UTF-8 string literal:"foo".
- LocalfullA localletbinding:let x: u64 = s.parse()?.
- LocalInitfullThe expression assigned in a localletbinding, including optional divergingelseblock.
- MacrofullorderiveA macro invocation:println!("{}", mac).
- MetaListfullorderiveA structured list within an attribute, likederive(Copy, Clone).
- MetaNameValuefullorderiveA name-value pair within an attribute, likefeature = "nightly".
- ParenthesizedGenericArgumentsfullorderiveArguments of a function path segment: the(A, B) -> CinFn(A,B) -> C.
- PatConstfullA const block:const { ... }.
- PatIdentfullA pattern that binds a new variable:ref mut binding @ SUBPATTERN.
- PatLitfullA literal in place of an expression:1,"foo".
- PatMacrofullA macro invocation expression:format!("{}", q).
- PatOrfullA pattern that matches any one of a set of cases.
- PatParenfullA parenthesized pattern:(A | B).
- PatPathfullA path likestd::mem::replacepossibly containing generic parameters and a qualified self-type.
- PatRangefullA range expression:1..2,1..,..2,1..=2,..=2.
- PatReferencefullA reference pattern:&mut var.
- PatRestfullThe dots in a tuple or slice pattern:[0, 1, ..].
- PatSlicefullA dynamically sized slice pattern:[a, b, ref i @ .., y, z].
- PatStructfullA struct or struct variant pattern:Variant { x, y, .. }.
- PatTuplefullA tuple pattern:(a, b).
- PatTupleStructfullA tuple struct or tuple variant pattern:Variant(x, y, .., z).
- PatTypefullA type ascription pattern:foo: f64.
- PatWildfullA pattern that matches any value:_.
- PathfullorderiveA path at which a named item is exported (e.g.std::collections::HashMap).
- PathSegmentfullorderiveA segment of a path together with any path arguments on that segment.
- PredicateLifetimefullorderiveA lifetime predicate in awhereclause:'a: 'b + 'c.
- PredicateTypefullorderiveA type predicate in awhereclause:for<'c> Foo<'c>: Trait<'c>.
- QSelffullorderiveThe explicit Self type in a qualified path: theTin<T as Display>::fmt.
- ReceiverfullTheselfargument of an associated method.
- SignaturefullA function signature in a trait or implementation:unsafe fn initialize(&self).
- StmtMacrofullA macro invocation in statement position.
- TraitBoundfullorderiveA trait used as a bound on a type parameter.
- TraitItemConstfullAn associated constant within the definition of a trait.
- TraitItemFnfullAn associated function within the definition of a trait.
- TraitItemMacrofullA macro invocation within the definition of a trait.
- TraitItemTypefullAn associated type within the definition of a trait.
- Turbofish(fullorderive) andprintingReturned byTypeGenerics::as_turbofish.
- TypeArrayfullorderiveA fixed size array type:[T; n].
- TypeBareFnfullorderiveA bare function type:fn(usize) -> bool.
- TypeGenerics(fullorderive) andprintingReturned byGenerics::split_for_impl.
- TypeGroupfullorderiveA type contained within invisible delimiters.
- TypeImplTraitfullorderiveAnimpl Bound1 + Bound2 + Bound3type whereBoundis a trait or a lifetime.
- TypeInferfullorderiveIndication that a type should be inferred by the compiler:_.
- TypeMacrofullorderiveA macro in the type position.
- TypeNeverfullorderiveThe never type:!.
- TypeParamfullorderiveA generic type parameter:T: Into<String>.
- TypeParenfullorderiveA parenthesized type equivalent to the inner type.
- TypePathfullorderiveA path likestd::slice::Iter, optionally qualified with a self-type as in<Vec<T> as SomeTrait>::Associated.
- TypePtrfullorderiveA raw pointer type:*const Tor*mut T.
- TypeReferencefullorderiveA reference type:&'a Tor&'a mut T.
- TypeSlicefullorderiveA dynamically sized slice type:[T].
- TypeTraitObjectfullorderiveA trait object typedyn Bound1 + Bound2 + Bound3whereBoundis a trait or a lifetime.
- TypeTuplefullorderiveA tuple type:(A, B, C, String).
- UseGlobfullA glob import in auseitem:*.
- UseGroupfullA braced group of imports in auseitem:{A, B, C}.
- UseNamefullAn identifier imported by auseitem:HashMap.
- UsePathfullA path prefix of imports in auseitem:std::....
- UseRenamefullAn renamed identifier imported by auseitem:HashMap as Map.
- VariadicfullThe variadic argument of a foreign function.
- VariantfullorderiveAn enum variant.
- VisRestrictedfullorderiveA visibility level restricted to some path:pub(self)orpub(super)orpub(crate)orpub(in some::module).
- WhereClausefullorderiveAwhereclause in a definition:where T: Deserialize<'de>, D: 'static.
Enums§
- AttrStylefullorderiveDistinguishes between attributes that decorate an item and attributes that are contained within an item.
- BinOpfullorderiveA binary operator:+,+=,&.
- DataderiveThe storage of a struct, enum or union data structure.
- ExprfullorderiveA Rust expression.
- FieldMutabilityfullorderiveUnused, but reserved for RFC 3323 restrictions.
- FieldsfullorderiveData stored within an enum variant or struct.
- FnArgfullAn argument in a function signature: then: usizeinfn f(n: usize).
- ForeignItemfullAn item within anexternblock.
- GenericArgumentfullorderiveAn individual generic argument, like'a,T, orItem = T.
- GenericParamfullorderiveA generic type parameter, lifetime, or const generic:T: Into<String>,'a: 'b,const LEN: usize.
- ImplItemfullAn item within an impl block.
- ImplRestrictionfullUnused, but reserved for RFC 3323 restrictions.
- ItemfullThings that can appear directly inside of a module or scope.
- A Rust literal such as a string or integer or boolean.
- MacroDelimiterfullorderiveA grouping token that surrounds a macro body:m!(...)orm!{...}orm![...].
- MemberfullorderiveA struct or tuple struct field accessed in a struct literal or field expression.
- MetafullorderiveContent of a compile-time structured attribute.
- PatfullA pattern in a local binding, function signature, match expression, or various other places.
- PathArgumentsfullorderiveAngle bracketed or parenthesized arguments of a path segment.
- RangeLimitsfullLimit types of a range, inclusive or exclusive.
- ReturnTypefullorderiveReturn type of a function signature.
- StaticMutabilityfullThe mutability of anItem::StaticorForeignItem::Static.
- StmtfullA statement, usually ending in a semicolon.
- TraitBoundModifierfullorderiveA modifier on a trait bound, currently only used for the?in?Sized.
- TraitItemfullAn item declaration within the definition of a trait.
- TypefullorderiveThe possible types that a Rust value could have.
- TypeParamBoundfullorderiveA trait or lifetime used as a bound on a type parameter.
- UnOpfullorderiveA unary operator:*,!,-.
- UseTreefullA suffix of an import tree in auseitem:Type as Renamedor*.
- VisibilityfullorderiveThe visibility level of an item: inherited orpuborpub(restricted).
- WherePredicatefullorderiveA single predicate in awhereclause:T: Deserialize<'de>.
Functions§
- parseparsingandproc-macroParse tokens of source code into the chosen syntax tree node.
- parse2parsingParse a proc-macro2 token stream into the chosen syntax tree node.
- parse_fileparsingandfullParse the content of a file of Rust code.
- parse_strparsingParse a string of Rust code into the chosen syntax tree node.
Type Aliases§
- The result of a Syn parser.