1 // Copyright 2018 Syn Developers
3 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6 // option. This file may not be copied, modified, or distributed
7 // except according to those terms.
9 //! Syn is a parsing library for parsing a stream of Rust tokens into a syntax
10 //! tree of Rust source code.
12 //! Currently this library is geared toward the [custom derive] use case but
13 //! contains some APIs that may be useful for Rust procedural macros more
16 //! [custom derive]: https://github.com/rust-lang/rfcs/blob/master/text/1681-macros-1.1.md
18 //! - **Data structures** — Syn provides a complete syntax tree that can
19 //! represent any valid Rust source code. The syntax tree is rooted at
20 //! [`syn::File`] which represents a full source file, but there are other
21 //! entry points that may be useful to procedural macros including
22 //! [`syn::Item`], [`syn::Expr`] and [`syn::Type`].
24 //! - **Custom derives** — Of particular interest to custom derives is
25 //! [`syn::DeriveInput`] which is any of the three legal input items to a
26 //! derive macro. An example below shows using this type in a library that can
27 //! derive implementations of a trait of your own.
29 //! - **Parser combinators** — Parsing in Syn is built on a suite of public
30 //! parser combinator macros that you can use for parsing any token-based
31 //! syntax you dream up within a `functionlike!(...)` procedural macro. Every
32 //! syntax tree node defined by Syn is individually parsable and may be used
33 //! as a building block for custom syntaxes, or you may do it all yourself
34 //! working from the most primitive tokens.
36 //! - **Location information** — Every token parsed by Syn is associated with a
37 //! `Span` that tracks line and column information back to the source of that
38 //! token. These spans allow a procedural macro to display detailed error
39 //! messages pointing to all the right places in the user's code. There is an
40 //! example of this below.
42 //! - **Feature flags** — Functionality is aggressively feature gated so your
43 //! procedural macros enable only what they need, and do not pay in compile
44 //! time for all the rest.
46 //! [`syn::File`]: struct.File.html
47 //! [`syn::Item`]: enum.Item.html
48 //! [`syn::Expr`]: enum.Expr.html
49 //! [`syn::Type`]: enum.Type.html
50 //! [`syn::DeriveInput`]: struct.DeriveInput.html
52 //! *Version requirement: Syn supports any compiler version back to Rust's very
53 //! first support for procedural macros in Rust 1.15.0. Some features especially
54 //! around error reporting are only available in newer compilers or on the
57 //! ## Example of a custom derive
59 //! The canonical custom derive using Syn looks like this. We write an ordinary
60 //! Rust function tagged with a `proc_macro_derive` attribute and the name of
61 //! the trait we are deriving. Any time that derive appears in the user's code,
62 //! the Rust compiler passes their data structure as tokens into our macro. We
63 //! get to execute arbitrary Rust code to figure out what to do with those
64 //! tokens, then hand some tokens back to the compiler to compile into the
67 //! [`TokenStream`]: https://doc.rust-lang.org/proc_macro/struct.TokenStream.html
79 //! extern crate proc_macro;
83 //! extern crate quote;
85 //! use proc_macro::TokenStream;
86 //! use syn::DeriveInput;
88 //! # const IGNORE_TOKENS: &str = stringify! {
89 //! #[proc_macro_derive(MyMacro)]
91 //! pub fn my_macro(input: TokenStream) -> TokenStream {
92 //! // Parse the input tokens into a syntax tree
93 //! let input: DeriveInput = syn::parse(input).unwrap();
95 //! // Build the output, possibly using quasi-quotation
96 //! let expanded = quote! {
100 //! // Hand the output tokens back to the compiler
107 //! The [`heapsize`] example directory shows a complete working Macros 1.1
108 //! implementation of a custom derive. It works on any Rust compiler \>=1.15.0.
109 //! The example derives a `HeapSize` trait which computes an estimate of the
110 //! amount of heap memory owned by a value.
112 //! [`heapsize`]: https://github.com/dtolnay/syn/tree/master/examples/heapsize
115 //! pub trait HeapSize {
116 //! /// Total number of bytes of heap memory owned by `self`.
117 //! fn heap_size_of_children(&self) -> usize;
121 //! The custom derive allows users to write `#[derive(HeapSize)]` on data
122 //! structures in their program.
125 //! # const IGNORE_TOKENS: &str = stringify! {
126 //! #[derive(HeapSize)]
128 //! struct Demo<'a, T: ?Sized> {
136 //! ## Spans and error reporting
138 //! The [`heapsize2`] example directory is an extension of the `heapsize`
139 //! example that demonstrates some of the hygiene and error reporting properties
140 //! of Macros 2.0. This example currently requires a nightly Rust compiler
141 //! \>=1.24.0-nightly but we are working to stabilize all of the APIs involved.
143 //! [`heapsize2`]: https://github.com/dtolnay/syn/tree/master/examples/heapsize2
145 //! The token-based procedural macro API provides great control over where the
146 //! compiler's error messages are displayed in user code. Consider the error the
147 //! user sees if one of their field types does not implement `HeapSize`.
150 //! # const IGNORE_TOKENS: &str = stringify! {
151 //! #[derive(HeapSize)]
155 //! bad: std::thread::Thread,
159 //! In the Macros 1.1 string-based procedural macro world, the resulting error
160 //! would point unhelpfully to the invocation of the derive macro and not to the
161 //! actual problematic field.
164 //! error[E0599]: no method named `heap_size_of_children` found for type `std::thread::Thread` in the current scope
165 //! --> src/main.rs:4:10
167 //! 4 | #[derive(HeapSize)]
171 //! By tracking span information all the way through the expansion of a
172 //! procedural macro as shown in the `heapsize2` example, token-based macros in
173 //! Syn are able to trigger errors that directly pinpoint the source of the
177 //! error[E0277]: the trait bound `std::thread::Thread: HeapSize` is not satisfied
178 //! --> src/main.rs:7:5
180 //! 7 | bad: std::thread::Thread,
181 //! | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HeapSize` is not implemented for `Thread`
184 //! ## Parsing a custom syntax using combinators
186 //! The [`lazy-static`] example directory shows the implementation of a
187 //! `functionlike!(...)` procedural macro in which the input tokens are parsed
188 //! using [`nom`]-style parser combinators.
190 //! [`lazy-static`]: https://github.com/dtolnay/syn/tree/master/examples/lazy-static
191 //! [`nom`]: https://github.com/Geal/nom
193 //! The example reimplements the popular `lazy_static` crate from crates.io as a
194 //! procedural macro.
197 //! # macro_rules! lazy_static {
198 //! # ($($tt:tt)*) => {}
202 //! static ref USERNAME: Regex = Regex::new("^[a-z0-9_-]{3,16}$").unwrap();
206 //! The implementation shows how to trigger custom warnings and error messages
207 //! on the macro input.
210 //! warning: come on, pick a more creative name
211 //! --> src/main.rs:10:16
213 //! 10 | static ref FOO: String = "lazy_static".to_owned();
219 //! When developing a procedural macro it can be helpful to look at what the
220 //! generated code looks like. Use `cargo rustc -- -Zunstable-options
221 //! --pretty=expanded` or the [`cargo expand`] subcommand.
223 //! [`cargo expand`]: https://github.com/dtolnay/cargo-expand
225 //! To show the expanded code for some crate that uses your procedural macro,
226 //! run `cargo expand` from that crate. To show the expanded code for one of
227 //! your own test cases, run `cargo expand --test the_test_case` where the last
228 //! argument is the name of the test file without the `.rs` extension.
230 //! This write-up by Brandon W Maister discusses debugging in more detail:
231 //! [Debugging Rust's new Custom Derive system][debugging].
233 //! [debugging]: https://quodlibetor.github.io/posts/debugging-rusts-new-custom-derive-system/
235 //! ## Optional features
237 //! Syn puts a lot of functionality behind optional features in order to
238 //! optimize compile time for the most common use cases. The following features
241 //! - **`derive`** *(enabled by default)* — Data structures for representing the
242 //! possible input to a custom derive, including structs and enums and types.
243 //! - **`full`** — Data structures for representing the syntax tree of all valid
244 //! Rust source code, including items and expressions.
245 //! - **`parsing`** *(enabled by default)* — Ability to parse input tokens into
246 //! a syntax tree node of a chosen type.
247 //! - **`printing`** *(enabled by default)* — Ability to print a syntax tree
248 //! node as tokens of Rust source code.
249 //! - **`visit`** — Trait for traversing a syntax tree.
250 //! - **`visit-mut`** — Trait for traversing and mutating in place a syntax
252 //! - **`fold`** — Trait for transforming an owned syntax tree.
253 //! - **`clone-impls`** *(enabled by default)* — Clone impls for all syntax tree
255 //! - **`extra-traits`** — Debug, Eq, PartialEq, Hash impls for all syntax tree
257 //! - **`proc-macro`** *(enabled by default)* — Runtime dependency on the
258 //! dynamic library libproc_macro from rustc toolchain.
260 // Syn types in rustdoc of other crates get linked to here.
261 #![doc(html_root_url = "https://docs.rs/syn/0.13.11")]
263 feature
= "cargo-clippy",
265 const_static_lifetime
, doc_markdown
, large_enum_variant
, match_bool
, redundant_closure
,
266 needless_pass_by_value
, redundant_field_names
270 #[cfg(feature = "proc-macro")]
271 extern crate proc_macro
;
272 extern crate proc_macro2
;
273 extern crate unicode_xid
;
275 #[cfg(feature = "printing")]
278 #[cfg(feature = "parsing")]
289 #[cfg(any(feature = "full", feature = "derive"))]
291 #[cfg(any(feature = "full", feature = "derive"))]
292 pub use attr
::{AttrStyle, Attribute, Meta, MetaList, MetaNameValue, NestedMeta}
;
294 #[cfg(any(feature = "full", feature = "derive"))]
296 #[cfg(any(feature = "full", feature = "derive"))]
298 Field
, Fields
, FieldsNamed
, FieldsUnnamed
, Variant
, VisCrate
, VisPublic
, VisRestricted
,
302 #[cfg(any(feature = "full", feature = "derive"))]
304 #[cfg(any(feature = "full", feature = "derive"))]
306 Expr
, ExprArray
, ExprAssign
, ExprAssignOp
, ExprBinary
, ExprBlock
, ExprBox
, ExprBreak
, ExprCall
,
307 ExprCast
, ExprCatch
, ExprClosure
, ExprContinue
, ExprField
, ExprForLoop
, ExprGroup
, ExprIf
,
308 ExprIfLet
, ExprInPlace
, ExprIndex
, ExprLit
, ExprLoop
, ExprMacro
, ExprMatch
, ExprMethodCall
,
309 ExprParen
, ExprPath
, ExprRange
, ExprReference
, ExprRepeat
, ExprReturn
, ExprStruct
, ExprTry
,
310 ExprTuple
, ExprType
, ExprUnary
, ExprUnsafe
, ExprVerbatim
, ExprWhile
, ExprWhileLet
, ExprYield
,
314 #[cfg(feature = "full")]
316 Arm
, Block
, FieldPat
, FieldValue
, GenericMethodArgument
, Label
, Local
, MethodTurbofish
, Pat
,
317 PatBox
, PatIdent
, PatLit
, PatMacro
, PatPath
, PatRange
, PatRef
, PatSlice
, PatStruct
, PatTuple
,
318 PatTupleStruct
, PatVerbatim
, PatWild
, RangeLimits
, Stmt
,
321 #[cfg(any(feature = "full", feature = "derive"))]
323 #[cfg(any(feature = "full", feature = "derive"))]
325 BoundLifetimes
, ConstParam
, GenericParam
, Generics
, LifetimeDef
, PredicateEq
,
326 PredicateLifetime
, PredicateType
, TraitBound
, TraitBoundModifier
, TypeParam
, TypeParamBound
,
327 WhereClause
, WherePredicate
,
329 #[cfg(all(any(feature = "full", feature = "derive"), feature = "printing"))]
330 pub use generics
::{ImplGenerics, Turbofish, TypeGenerics}
;
333 pub use ident
::Ident
;
335 #[cfg(feature = "full")]
337 #[cfg(feature = "full")]
339 ArgCaptured
, ArgSelf
, ArgSelfRef
, FnArg
, FnDecl
, ForeignItem
, ForeignItemFn
, ForeignItemStatic
,
340 ForeignItemType
, ForeignItemVerbatim
, ImplItem
, ImplItemConst
, ImplItemMacro
, ImplItemMethod
,
341 ImplItemType
, ImplItemVerbatim
, Item
, ItemConst
, ItemEnum
, ItemExternCrate
, ItemFn
,
342 ItemForeignMod
, ItemImpl
, ItemMacro
, ItemMacro2
, ItemMod
, ItemStatic
, ItemStruct
, ItemTrait
,
343 ItemType
, ItemUnion
, ItemUse
, ItemVerbatim
, MethodSig
, TraitItem
, TraitItemConst
,
344 TraitItemMacro
, TraitItemMethod
, TraitItemType
, TraitItemVerbatim
, UseGlob
, UseGroup
, UseName
,
345 UsePath
, UseRename
, UseTree
,
348 #[cfg(feature = "full")]
350 #[cfg(feature = "full")]
353 #[cfg(any(feature = "full", feature = "derive"))]
355 #[cfg(any(feature = "full", feature = "derive"))]
356 pub use lifetime
::Lifetime
;
358 #[cfg(any(feature = "full", feature = "derive"))]
360 #[cfg(any(feature = "full", feature = "derive"))]
362 FloatSuffix
, IntSuffix
, Lit
, LitBool
, LitByte
, LitByteStr
, LitChar
, LitFloat
, LitInt
, LitStr
,
363 LitVerbatim
, StrStyle
,
366 #[cfg(any(feature = "full", feature = "derive"))]
368 #[cfg(any(feature = "full", feature = "derive"))]
369 pub use mac
::{Macro, MacroDelimiter}
;
371 #[cfg(any(feature = "full", feature = "derive"))]
373 #[cfg(feature = "derive")]
374 pub use derive
::{Data, DataEnum, DataStruct, DataUnion, DeriveInput}
;
376 #[cfg(any(feature = "full", feature = "derive"))]
378 #[cfg(any(feature = "full", feature = "derive"))]
379 pub use op
::{BinOp, UnOp}
;
381 #[cfg(any(feature = "full", feature = "derive"))]
383 #[cfg(any(feature = "full", feature = "derive"))]
385 Abi
, BareFnArg
, BareFnArgName
, ReturnType
, Type
, TypeArray
, TypeBareFn
, TypeGroup
,
386 TypeImplTrait
, TypeInfer
, TypeMacro
, TypeNever
, TypeParen
, TypePath
, TypePtr
, TypeReference
,
387 TypeSlice
, TypeTraitObject
, TypeTuple
, TypeVerbatim
,
390 #[cfg(any(feature = "full", feature = "derive"))]
392 #[cfg(all(any(feature = "full", feature = "derive"), feature = "printing"))]
393 pub use path
::PathTokens
;
394 #[cfg(any(feature = "full", feature = "derive"))]
396 AngleBracketedGenericArguments
, Binding
, GenericArgument
, ParenthesizedGenericArguments
, Path
,
397 PathArguments
, PathSegment
, QSelf
,
400 #[cfg(feature = "parsing")]
403 #[cfg(feature = "parsing")]
405 #[cfg(any(feature = "full", feature = "derive"))]
408 // Not public API except the `parse_quote!` macro.
409 #[cfg(feature = "parsing")]
413 #[cfg(all(feature = "parsing", feature = "printing"))]
417 /// Syntax tree traversal to walk a shared borrow of a syntax tree.
419 /// Each method of the [`Visit`] trait is a hook that can be overridden to
420 /// customize the behavior when visiting the corresponding type of node. By
421 /// default, every method recursively visits the substructure of the input
422 /// by invoking the right visitor method of each of its fields.
424 /// [`Visit`]: trait.Visit.html
427 /// # use syn::{Attribute, BinOp, Expr, ExprBinary};
429 /// pub trait Visit<'ast> {
432 /// fn visit_expr_binary(&mut self, node: &'ast ExprBinary) {
433 /// for attr in &node.attrs {
434 /// self.visit_attribute(attr);
436 /// self.visit_expr(&*node.left);
437 /// self.visit_bin_op(&node.op);
438 /// self.visit_expr(&*node.right);
442 /// # fn visit_attribute(&mut self, node: &'ast Attribute);
443 /// # fn visit_expr(&mut self, node: &'ast Expr);
444 /// # fn visit_bin_op(&mut self, node: &'ast BinOp);
448 /// *This module is available if Syn is built with the `"visit"` feature.*
449 #[cfg(feature = "visit")]
452 /// Syntax tree traversal to mutate an exclusive borrow of a syntax tree in
455 /// Each method of the [`VisitMut`] trait is a hook that can be overridden
456 /// to customize the behavior when mutating the corresponding type of node.
457 /// By default, every method recursively visits the substructure of the
458 /// input by invoking the right visitor method of each of its fields.
460 /// [`VisitMut`]: trait.VisitMut.html
463 /// # use syn::{Attribute, BinOp, Expr, ExprBinary};
465 /// pub trait VisitMut {
468 /// fn visit_expr_binary_mut(&mut self, node: &mut ExprBinary) {
469 /// for attr in &mut node.attrs {
470 /// self.visit_attribute_mut(attr);
472 /// self.visit_expr_mut(&mut *node.left);
473 /// self.visit_bin_op_mut(&mut node.op);
474 /// self.visit_expr_mut(&mut *node.right);
478 /// # fn visit_attribute_mut(&mut self, node: &mut Attribute);
479 /// # fn visit_expr_mut(&mut self, node: &mut Expr);
480 /// # fn visit_bin_op_mut(&mut self, node: &mut BinOp);
484 /// *This module is available if Syn is built with the `"visit-mut"`
486 #[cfg(feature = "visit-mut")]
489 /// Syntax tree traversal to transform the nodes of an owned syntax tree.
491 /// Each method of the [`Fold`] trait is a hook that can be overridden to
492 /// customize the behavior when transforming the corresponding type of node.
493 /// By default, every method recursively visits the substructure of the
494 /// input by invoking the right visitor method of each of its fields.
496 /// [`Fold`]: trait.Fold.html
499 /// # use syn::{Attribute, BinOp, Expr, ExprBinary};
504 /// fn fold_expr_binary(&mut self, node: ExprBinary) -> ExprBinary {
506 /// attrs: node.attrs
508 /// .map(|attr| self.fold_attribute(attr))
510 /// left: Box::new(self.fold_expr(*node.left)),
511 /// op: self.fold_bin_op(node.op),
512 /// right: Box::new(self.fold_expr(*node.right)),
517 /// # fn fold_attribute(&mut self, node: Attribute) -> Attribute;
518 /// # fn fold_expr(&mut self, node: Expr) -> Expr;
519 /// # fn fold_bin_op(&mut self, node: BinOp) -> BinOp;
523 /// *This module is available if Syn is built with the `"fold"` feature.*
524 #[cfg(feature = "fold")]
527 #[cfg(any(feature = "full", feature = "derive"))]
528 #[path = "../gen_helper.rs"]
533 ////////////////////////////////////////////////////////////////////////////////
535 #[cfg(feature = "parsing")]
536 use synom
::{Parser, Synom}
;
538 #[cfg(feature = "parsing")]
540 #[cfg(feature = "parsing")]
541 use error
::ParseError
;
544 #[cfg(feature = "parsing")]
546 pub use error
::parse_error
;
548 /// Parse tokens of source code into the chosen syntax tree node.
550 /// This is preferred over parsing a string because tokens are able to preserve
551 /// information about where in the user's code they were originally written (the
552 /// "span" of the token), possibly allowing the compiler to produce better error
555 /// This function parses a `proc_macro::TokenStream` which is the type used for
556 /// interop with the compiler in a procedural macro. To parse a
557 /// `proc_macro2::TokenStream`, use [`syn::parse2`] instead.
559 /// [`syn::parse2`]: fn.parse2.html
561 /// *This function is available if Syn is built with both the `"parsing"` and
562 /// `"proc-macro"` features.*
567 /// extern crate proc_macro;
568 /// use proc_macro::TokenStream;
570 /// extern crate syn;
573 /// extern crate quote;
575 /// use syn::DeriveInput;
577 /// # const IGNORE_TOKENS: &str = stringify! {
578 /// #[proc_macro_derive(MyMacro)]
580 /// pub fn my_macro(input: TokenStream) -> TokenStream {
581 /// // Parse the tokens into a syntax tree
582 /// let ast: DeriveInput = syn::parse(input).unwrap();
584 /// // Build the output, possibly using quasi-quotation
585 /// let expanded = quote! {
589 /// // Convert into a token stream and return it
595 #[cfg(all(feature = "parsing", feature = "proc-macro"))]
596 pub fn parse
<T
>(tokens
: proc_macro
::TokenStream
) -> Result
<T
, ParseError
>
600 parse2(tokens
.into())
603 /// Parse a proc-macro2 token stream into the chosen syntax tree node.
605 /// This function parses a `proc_macro2::TokenStream` which is commonly useful
606 /// when the input comes from a node of the Syn syntax tree, for example the tts
607 /// of a [`Macro`] node. When in a procedural macro parsing the
608 /// `proc_macro::TokenStream` provided by the compiler, use [`syn::parse`]
611 /// [`Macro`]: struct.Macro.html
612 /// [`syn::parse`]: fn.parse.html
614 /// *This function is available if Syn is built with the `"parsing"` feature.*
615 #[cfg(feature = "parsing")]
616 pub fn parse2
<T
>(tokens
: proc_macro2
::TokenStream
) -> Result
<T
, ParseError
>
620 let parser
= T
::parse
;
621 parser
.parse2(tokens
).map_err(|err
| match T
::description() {
622 Some(s
) => ParseError
::new(format
!("failed to parse {}: {}", s
, err
)),
627 /// Parse a string of Rust code into the chosen syntax tree node.
629 /// *This function is available if Syn is built with the `"parsing"` feature.*
633 /// Every span in the resulting syntax tree will be set to resolve at the macro
639 /// extern crate syn;
642 /// # type Result<T> = std::result::Result<T, Box<std::error::Error>>;
646 /// fn run() -> Result<()> {
647 /// let code = "assert_eq!(u8::max_value(), 255)";
648 /// let expr = syn::parse_str::<Expr>(code)?;
649 /// println!("{:#?}", expr);
653 /// # fn main() { run().unwrap() }
655 #[cfg(feature = "parsing")]
656 pub fn parse_str
<T
: Synom
>(s
: &str) -> Result
<T
, ParseError
> {
658 Ok(tts
) => parse2(tts
),
659 Err(_
) => Err(ParseError
::new("error while lexing input string")),
663 // FIXME the name parse_file makes it sound like you might pass in a path to a
664 // file, rather than the content.
665 /// Parse the content of a file of Rust code.
667 /// This is different from `syn::parse_str::<File>(content)` in two ways:
669 /// - It discards a leading byte order mark `\u{FEFF}` if the file has one.
670 /// - It preserves the shebang line of the file, such as `#!/usr/bin/env rustx`.
672 /// If present, either of these would be an error using `from_str`.
674 /// *This function is available if Syn is built with the `"parsing"` and `"full"` features.*
679 /// extern crate syn;
682 /// # type Result<T> = std::result::Result<T, Box<std::error::Error>>;
684 /// use std::fs::File;
685 /// use std::io::Read;
687 /// fn run() -> Result<()> {
688 /// let mut file = File::open("path/to/code.rs")?;
689 /// let mut content = String::new();
690 /// file.read_to_string(&mut content)?;
692 /// let ast = syn::parse_file(&content)?;
693 /// if let Some(shebang) = ast.shebang {
694 /// println!("{}", shebang);
696 /// println!("{} items", ast.items.len());
701 /// # fn main() { run().unwrap() }
703 #[cfg(all(feature = "parsing", feature = "full"))]
704 pub fn parse_file(mut content
: &str) -> Result
<File
, ParseError
> {
705 // Strip the BOM if it is present
706 const BOM
: &'
static str = "\u{feff}";
707 if content
.starts_with(BOM
) {
708 content
= &content
[BOM
.len()..];
711 let mut shebang
= None
;
712 if content
.starts_with("#!") && !content
.starts_with("#![") {
713 if let Some(idx
) = content
.find('
\n'
) {
714 shebang
= Some(content
[..idx
].to_string());
715 content
= &content
[idx
..];
717 shebang
= Some(content
.to_string());
722 let mut file
: File
= parse_str(content
)?
;
723 file
.shebang
= shebang
;
727 #[cfg(all(any(feature = "full", feature = "derive"), feature = "printing"))]
728 struct TokensOrDefault
<'a
, T
: 'a
>(&'a Option
<T
>);
730 #[cfg(all(any(feature = "full", feature = "derive"), feature = "printing"))]
731 impl<'a
, T
> quote
::ToTokens
for TokensOrDefault
<'a
, T
>
733 T
: quote
::ToTokens
+ Default
,
735 fn to_tokens(&self, tokens
: &mut quote
::Tokens
) {
737 Some(ref t
) => t
.to_tokens(tokens
),
738 None
=> T
::default().to_tokens(tokens
),