### start Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-span.md Get the starting line/column in the source file for this span. Requires the `span-locations` feature. ```APIDOC ## start() -> LineColumn ### Description Get the starting line/column in the source file for this span. ### Method `start` ### Returns - **LineColumn** - A struct with `line` (1-indexed) and `column` (0-indexed, in UTF-8 characters). ### Availability Requires `"span-locations"` feature. ### Note Accuracy depends on toolchain and context (see `byte_range()`). ### Request Example ```rust use proc_macro2::Span; let span = Span::call_site(); let loc = span.start(); println!("Line {}, Column {}", loc.line, loc.column); ``` ``` -------------------------------- ### Example: Displaying a Group Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-group-delim.md Demonstrates how to create a Group and print its string representation. ```rust use proc_macro2::{Group, Delimiter, TokenStream}; let group = Group::new(Delimiter::Brace, TokenStream::new()); println!("{}", group); // Prints: {} ``` -------------------------------- ### Usage Example: Building and Iterating a TokenStream Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-tokentree-lexerror.md A comprehensive example demonstrating how to build a TokenStream with mixed token types (Ident and Group) and then iterate over it, matching each TokenTree variant. ```rust use proc_macro2::{TokenTree, TokenStream, Group, Delimiter, Ident, Span}; let inner = TokenStream::new(); let group = Group::new(Delimiter::Parenthesis, inner); // Build a stream with mixed token types let mut stream = TokenStream::new(); stream.extend(vec![ TokenTree::from(Ident::new("foo", Span::call_site())), TokenTree::from(group), ]); for tt in stream { match tt { TokenTree::Group(g) => println!("Group: {:?}", g.delimiter()), TokenTree::Ident(i) => println!("Ident: {}", i), TokenTree::Punct(p) => println!("Punct: {}", p.as_char()), TokenTree::Literal(l) => println!("Literal: {}", l), } } ``` -------------------------------- ### Example: Iterate over TokenStream Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-tokenstream.md Shows how to iterate through the token trees of a TokenStream and print each one. ```rust use proc_macro2::TokenStream; let stream = TokenStream::from_str("fn main() { }").unwrap(); for token in stream { println!("{:?}", token); } ``` -------------------------------- ### Get Start Line and Column of a Span Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-span.md The `start` method retrieves the starting line (1-indexed) and column (0-indexed, in UTF-8 characters) of a span. Accuracy depends on the toolchain and context. ```rust use proc_macro2::Span; let span = Span::call_site(); let loc = span.start(); println!("Line {}, Column {}", loc.line, loc.column); ``` -------------------------------- ### Example: Display TokenStream Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-tokenstream.md Demonstrates printing an empty TokenStream using the Display trait. ```rust use proc_macro2::TokenStream; let stream = TokenStream::new(); println!("{}", stream); // Prints empty string ``` -------------------------------- ### Example: Opening Delimiter Span Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-group-delim.md Demonstrates obtaining a span for only the opening delimiter using `open()`. ```rust use proc_macro2::{Group, Delimiter, TokenStream}; let group = Group::new(Delimiter::Bracket, TokenStream::new()); let delim = group.delim_span(); let open_span = delim.open(); ``` -------------------------------- ### Example: Debug TokenStream Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-tokenstream.md Demonstrates printing an empty TokenStream using the Debug trait. ```rust use proc_macro2::TokenStream; let stream = TokenStream::new(); println!("{:?}", stream); // TokenStream [] ``` -------------------------------- ### Example: Joining DelimSpan Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-group-delim.md Demonstrates obtaining a span for the entire delimited group using `join()`. ```rust use proc_macro2::{Group, Delimiter, TokenStream}; let group = Group::new(Delimiter::Parenthesis, TokenStream::new()); let delim = group.delim_span(); let full_span = delim.join(); ``` -------------------------------- ### Example Usage of span() Method Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-tokentree-lexerror.md Demonstrates how to use the span() method to get the location of a lex error when parsing a TokenStream. ```rust use proc_macro2::TokenStream; use std::str::FromStr; match TokenStream::from_str("fn main() {") { Ok(_) => {}, Err(err) => { let span = err.span(); println!("Error at {:?}", span); } } ``` -------------------------------- ### Example Usage of Display Implementation Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-tokentree-lexerror.md Shows how the Display implementation formats a LexError into a human-readable string, such as 'cannot parse string into token stream'. ```rust use proc_macro2::TokenStream; use std::str::FromStr; match TokenStream::from_str("invalid {") { Ok(_) => {}, Err(err) => println!("Error: {}", err), // Prints: Error: cannot parse string into token stream } ``` -------------------------------- ### Punct Constructor Example Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-punct-spacing.md Demonstrates creating Punct instances with different spacing. Use Spacing::Joint for the first character of a multi-character operator like '+='. ```rust use proc_macro2::{Punct, Spacing}; let plus = Punct::new('+', Spacing::Alone); let equals = Punct::new('=', Spacing::Alone); // For `+=`, the first `+` should be Joint: let plus_joint = Punct::new('+', Spacing::Joint); let equals_alone = Punct::new('=', Spacing::Alone); ``` -------------------------------- ### Usage Example: Creating and Extending TokenStream with Literals Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-literal.md Demonstrates how to create integer, string, and float literals using proc_macro2 and extend a TokenStream with them. Shows the resulting output when the TokenStream is printed. ```rust use proc_macro2::{Literal, TokenStream, TokenTree}; let lit_int = Literal::i32_suffixed(42); let lit_str = Literal::string("hello"); let lit_float = Literal::f64_suffixed(3.14); let mut stream = TokenStream::new(); stream.extend(vec![ TokenTree::Literal(lit_int), TokenTree::Literal(lit_str), TokenTree::Literal(lit_float), ]); println!("{}", stream); // Prints: 42i32 "hello" 3.14f64 ``` -------------------------------- ### Example: Closing Delimiter Span Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-group-delim.md Demonstrates obtaining a span for only the closing delimiter using `close()`. ```rust use proc_macro2::{Group, Delimiter, TokenStream}; let group = Group::new(Delimiter::Bracket, TokenStream::new()); let delim = group.delim_span(); let close_span = delim.close(); ``` -------------------------------- ### Get the start line and column of a span Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/MANIFEST.txt With the span-locations feature enabled, span.start() returns the LineColumn information for the beginning of the span. ```rust span.start() ``` -------------------------------- ### Thread Safety Example Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/README.md Demonstrates that `proc_macro2::TokenStream` is not `Sync` and cannot be shared across threads. Attempting to do so will result in a compile-time error. ```rust use proc_macro2::TokenStream; // This will NOT compile: // let stream = TokenStream::new(); // std::thread::spawn(move || { // println!("{}", stream); // Error: TokenStream is !Sync // }); ``` -------------------------------- ### Get Call-Site and Mixed-Site Spans Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/README.md Illustrates obtaining Span objects for call-site and mixed-site hygiene. ```Rust use proc_macro2::Span; // Call-site hygiene: resolves at the macro call location let call_site = Span::call_site(); // Mixed-site hygiene: like macro_rules! (variables at def-site, items at call-site) let mixed = Span::mixed_site(); ``` -------------------------------- ### DelimSpan Method: open() Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-group-delim.md Returns a span for the opening punctuation of the group only. Use this to get a span specifically for the opening delimiter. ```rust pub fn open(&self) -> Span ``` -------------------------------- ### Enable span-locations feature for Span methods Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/README.md To enable location methods like start, end, file, and byte_range on Span, activate the 'span-locations' feature. ```toml [dependencies] proc-macro2 = { version = "1.0", features = ["span-locations"] } ``` -------------------------------- ### TokenStream::new() Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-tokenstream.md Creates a new, empty TokenStream. This stream contains no token trees and can be used as a starting point for building token sequences. ```APIDOC ## TokenStream::new() ### Description Creates an empty `TokenStream` containing no token trees. ### Method `new()` ### Parameters No parameters. ### Returns `TokenStream` — An empty token stream. ### Example ```rust use proc_macro2::TokenStream; let empty = TokenStream::new(); assert!(empty.is_empty()); ``` ``` -------------------------------- ### LexError Example Sites Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/errors.md Illustrates common scenarios that trigger a LexError during TokenStream parsing, such as unbalanced delimiters, invalid escape sequences, and unexpected input. ```Rust use std::str::FromStr; // Unbalanced braces let err = TokenStream::from_str("fn main() {").unwrap_err(); // Error: cannot parse string into token stream // Unbalanced parens let err = TokenStream::from_str("foo(bar").unwrap_err(); // Invalid escape let err = TokenStream::from_str(r#"invalid\x"#).unwrap_err(); ``` -------------------------------- ### DelimSpan Method: join() Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-group-delim.md Returns a span covering the entire delimited group. Use this to get a span encompassing both opening and closing delimiters. ```rust pub fn join(&self) -> Span ``` -------------------------------- ### Get Source File Path of a Span Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-span.md The `file` method returns a string representing the source file path for a span. This path is for display purposes and may be artificial, such as ''. ```rust use proc_macro2::Span; let span = Span::call_site(); let file = span.file(); println!("File: {}", file); ``` -------------------------------- ### proc-macro2 with Span Locations Enabled Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/configuration.md This TOML configuration enables the `span-locations` feature for proc-macro2. The accompanying Rust code demonstrates how to access span start location data, which is useful for debugging or advanced macro logic. ```toml [dependencies] proc-macro2 = { version = "1.0", features = ["span-locations"] } ``` ```rust use proc_macro2::Span; use std::str::FromStr; let span = Span::call_site(); let loc = span.start(); // Now available println!("Location: {}:{}", loc.line, loc.column); ``` -------------------------------- ### Get Opening Delimiter Span Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-group-delim.md Retrieves the span specifically for the opening delimiter of a Group. Useful for pinpointing the start of a delimited section. ```rust use proc_macro2::{Group, Delimiter, TokenStream}; let group = Group::new(Delimiter::Bracket, TokenStream::new()); let open = group.span_open(); // This span points to the `[` ``` -------------------------------- ### Get Byte Range of a Span Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-span.md The `byte_range` method returns the byte position range [start, end) of a span within its source file. Accuracy may vary in procedural macro contexts on stable Rust. ```rust use proc_macro2::Span; let span = Span::call_site(); let range = span.byte_range(); println!("Bytes {}-{}", range.start, range.end); ``` -------------------------------- ### Build and Test with procmacro2_semver_exempt Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/configuration.md Demonstrates how to build and test your project with the procmacro2_semver_exempt flag. Ensure all dependencies also have this flag enabled to avoid compile errors. ```bash # Build your crate AND all dependencies with the flag RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo build # Run tests with the flag RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo test ``` -------------------------------- ### Add Development Dependencies Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/configuration.md Include common development dependencies for testing and benchmarking, such as flate2, quote, rayon, rustversion, and tar. ```toml [dev-dependencies] flate2 = "1.0" quote = "1.0" rayon = "1.0" rustversion = "1" tar = "0.4" ``` -------------------------------- ### end Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-span.md Get the ending line/column in the source file for this span. Requires the `span-locations` feature. ```APIDOC ## end() -> LineColumn ### Description Get the ending line/column in the source file for this span. ### Method `end` ### Returns - **LineColumn** - A struct with `line` (1-indexed) and `column` (0-indexed, in UTF-8 characters). ### Availability Requires `"span-locations"` feature. ### Request Example ```rust use proc_macro2::Span; let span = Span::call_site(); let loc = span.end(); println!("Line {}, Column {}", loc.line, loc.column); ``` ``` -------------------------------- ### Example of ConversionErrorKind::InvalidLiteralKind Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/types.md Demonstrates how `str_value()` returns `Err(InvalidLiteralKind)` when called on a literal that is not a string. ```rust let lit = Literal::from_str("42").unwrap(); let err = lit.str_value(); // Returns Err(InvalidLiteralKind) ``` -------------------------------- ### Benchmarking Output for proc-macro2 Source: https://github.com/dtolnay/proc-macro2/blob/master/benches/bench-libproc-macro/README.md This output shows the time taken for string-to-token-stream conversion and direct token stream processing during a release build. It highlights the performance difference between the two methods. ```console $ cargo check --release Compiling bench-libproc-macro v0.0.0 STRING: 37 millis TOKENSTREAM: 276 millis Finished release [optimized] target(s) in 1.16s ``` -------------------------------- ### Documentation Build Configuration for docs.rs Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/configuration.md Configures metadata for docs.rs to include semver-exempt APIs and specify build targets and arguments. This ensures experimental APIs are visible online with feature annotations. ```toml [package.metadata.docs.rs] rustc-args = ["--cfg=procmacro2_semver_exempt"] targets = ["x86_64-unknown-linux-gnu"] rustdoc-args = [ "--cfg=procmacro2_semver_exempt", "--generate-link-to-definition", "--generate-macro-expansion", # ... more args ] ``` -------------------------------- ### Create a TokenTree from an Identifier Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/README.md Shows how to create an identifier and wrap it in a TokenTree. ```Rust use proc_macro2::{TokenTree, Ident, Span}; let ident = Ident::new("name", Span::call_site()); let tree = TokenTree::Ident(ident); ``` -------------------------------- ### Construct TokenTree from Group Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-tokentree-lexerror.md Demonstrates creating a TokenTree by converting a Group. This is useful when building complex token streams programmatically. ```rust use proc_macro2::{TokenTree, Group, Delimiter, TokenStream}; let group = Group::new(Delimiter::Parenthesis, TokenStream::new()); let tree = TokenTree::from(group); ``` -------------------------------- ### Get Ident Span Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-ident.md Retrieves the Span associated with an Ident. This is useful for debugging or understanding the origin of the identifier. ```rust use proc_macro2::{Ident, Span}; let ident = Ident::new("x", Span::call_site()); let span = ident.span(); println!("{:?}", span); ``` -------------------------------- ### Enable Experimental APIs via .cargo/config.toml Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/configuration.md Configure project-level rustflags in .cargo/config.toml to enable experimental APIs by default. ```toml [build] rustflags = ["--cfg", "procmacro2_semver_exempt"] ``` -------------------------------- ### Get TokenTree Span Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-tokentree-lexerror.md Retrieves the span of a TokenTree. This method delegates to the span method of the contained token. ```rust pub fn span(&self) -> Span ``` ```rust use proc_macro2::{TokenTree, Ident, Span}; let ident = Ident::new("x", Span::call_site()); let tree = TokenTree::Ident(ident); let span = tree.span(); println!("{:?}", span); ``` -------------------------------- ### span() Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-punct-spacing.md Gets the source code span associated with a Punct object, useful for error reporting and debugging. ```APIDOC ## span() ### Description Returns the span for this punctuation character. ### Method `span() -> Span` ### Returns `Span` — The span of this punct. ### Example ```rust use proc_macro2::{Punct, Spacing, Span}; let mut punct = Punct::new('+', Spacing::Alone); let span = punct.span(); println!("{:?}", span); ``` ``` -------------------------------- ### Basic Identifier Creation Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-ident.md Demonstrates the basic creation of an Ident using `Ident::new` and its usage with the `quote!` macro. ```APIDOC ## Basic Identifier Creation ### Description Demonstrates the basic creation of an `Ident` using `Ident::new` and its usage with the `quote!` macro. ### Example ```rust use proc_macro2::{Ident, Span, TokenTree, TokenStream}; let ident = Ident::new("my_function", Span::call_site()); // Use with quote! macro from quote crate use quote::quote; let tokens = quote! { #ident() }; println!("{}", tokens); // Prints: my_function () ``` ``` -------------------------------- ### Create Basic Identifier with quote! Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-ident.md Shows how to create an identifier and use it with the quote! macro from the quote crate. ```rust use proc_macro2::{Ident, Span, TokenTree, TokenStream}; let ident = Ident::new("my_function", Span::call_site()); // Use with quote! macro from quote crate use quote::quote; let tokens = quote! { #ident() }; println!("{}", tokens); // Prints: my_function () ``` -------------------------------- ### file Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-span.md Get the path to the source file in which this span occurs. Requires the `span-locations` feature. The path is for display purposes only. ```APIDOC ## file() -> String ### Description Get the path to the source file in which this span occurs (for display purposes). ### Method `file` ### Returns - **String** - A file path, which may be remapped or artificial (e.g., `""`). ### Availability Requires `"span-locations"` feature. ### Description This path is for display only and may not correspond to a real file system path. ### Request Example ```rust use proc_macro2::Span; let span = Span::call_site(); let file = span.file(); println!("File: {}", file); ``` ``` -------------------------------- ### Get the file name of a span Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/MANIFEST.txt With the span-locations feature enabled, span.file() returns the source file name as a String. ```rust span.file() ``` -------------------------------- ### Enable Nightly Feature (Deprecated) Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/configuration.md This configuration was historically used to enable nightly-only features but is now deprecated and has no effect. Migration to procmacro2_semver_exempt is recommended. ```toml [features] nightly = [] ``` -------------------------------- ### Testing Macro Logic with Fallback Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-extra-fallback.md Demonstrates how to test procedural macro logic using the proc-macro2 fallback implementation. This allows testing outside of a procedural macro context. ```rust #[cfg(test)] mod tests { use proc_macro2::{TokenStream, Ident, Span}; use std::str::FromStr; #[test] fn test_parsing() { let input = TokenStream::from_str("fn main() { }").unwrap(); assert!(!input.is_empty()); } #[test] fn test_ident_creation() { let ident = Ident::new("my_var", Span::call_site()); assert_eq!(ident.to_string(), "my_var"); } } ``` -------------------------------- ### DelimSpan Method: close() Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-group-delim.md Returns a span for the closing punctuation of the group only. Use this to get a span specifically for the closing delimiter. ```rust pub fn close(&self) -> Span ``` -------------------------------- ### Integrate Punct into TokenTree Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-punct-spacing.md Shows how to create a TokenTree variant from a Punct token. This is a fundamental step when constructing or manipulating token streams. ```rust pub enum TokenTree { Group(Group), Ident(Ident), Punct(Punct), // ← Here Literal(Literal), } impl TokenTree { pub fn span(&self) -> Span { ... } pub fn set_span(&mut self, span: Span) { ... } } ``` ```rust use proc_macro2::{Punct, Spacing, TokenTree}; let punct = Punct::new('+', Spacing::Alone); let tree = TokenTree::Punct(punct); ``` -------------------------------- ### Enable experimental APIs with procmacro2_semver_exempt Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/README.md Use the 'procmacro2_semver_exempt' configuration flag to enable experimental APIs that track unstable compiler features. Note that these APIs do not adhere to semver. ```bash RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo build ``` -------------------------------- ### Group Constructor and Span Setting Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-group-delim.md Demonstrates how to create a new Group with a specified delimiter and token stream, and how to set its span. This is useful for constructing delimited token streams programmatically. ```rust use proc_macro2::{Group, Delimiter, TokenStream, Span}; let tokens = TokenStream::new(); let group = Group::new(Delimiter::Parenthesis, tokens); let mut group_mut = group.clone(); group_mut.set_span(Span::call_site()); ``` -------------------------------- ### Get the source text of a span Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/MANIFEST.txt span.source_text() returns an Option containing the source code corresponding to the span, if available. ```rust span.source_text() ``` -------------------------------- ### Patch Configuration for Local Development Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/configuration.md Use a patch configuration to ensure dependencies use the local proc-macro2 during development and testing, avoiding version mismatches. ```toml [patch.crates-io] proc-macro2 = { path = "." } ``` -------------------------------- ### Create Raw Identifiers for Keywords Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-ident.md Illustrates how to create raw identifiers using `Ident::new_raw` to avoid conflicts with Rust keywords. ```rust use proc_macro2::{Ident, Span}; // Create an identifier that uses a keyword let fn_ident = Ident::new_raw("fn", Span::call_site()); let type_ident = Ident::new_raw("type", Span::call_site()); println!("{}", fn_ident); // Prints: r#fn ``` -------------------------------- ### Get Literal Span Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-literal.md Retrieves the source code span associated with a proc-macro2::Literal. This is useful for error reporting or code analysis. ```rust use proc_macro2::Literal; let lit = Literal::string("test"); let span = lit.span(); println!("{:?}", span); ``` -------------------------------- ### Create Punctuation Token with Spacing Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-punct-spacing.md Demonstrates creating a punctuation token with specific spacing. Use Spacing::Joint when the punctuation is followed by another character that forms a single token (e.g., `+=`), and Spacing::Alone otherwise. ```rust use proc_macro2::{Punct, Spacing, TokenStream, TokenTree}; // Create tokens for `+=` let plus = Punct::new('+', Spacing::Joint); // Joint because next is `=` let equals = Punct::new('=', Spacing::Alone); // Alone because nothing after // Add to a stream let mut stream = TokenStream::new(); stream.extend(vec![ TokenTree::Punct(plus), TokenTree::Punct(equals), ]); println!("{}", stream); // Prints: += ``` -------------------------------- ### Get Closing Delimiter Span Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-group-delim.md Retrieves the span specifically for the closing delimiter of a Group. Useful for pinpointing the end of a delimited section. ```rust use proc_macro2::{Group, Delimiter, TokenStream}; let group = Group::new(Delimiter::Bracket, TokenStream::new()); let close = group.span_close(); // This span points to the `]` ``` -------------------------------- ### Parse Rust Code into TokenStream Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/README.md Demonstrates parsing a Rust code string into a TokenStream. Handles potential parsing errors. ```Rust use proc_macro2::TokenStream; use std::str::FromStr; // Parse from string let tokens = TokenStream::from_str("fn main() { }")?; // Construct empty let empty = TokenStream::new(); // Iterate for token in tokens { println!("{:?}", token); } ``` -------------------------------- ### Get Group Delimiter Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-group-delim.md Retrieves the delimiter character used for a Group. Useful for checking if a group is delimited by parentheses, braces, or brackets. ```rust use proc_macro2::{Group, Delimiter, TokenStream}; let group = Group::new(Delimiter::Brace, TokenStream::new()); assert_eq!(group.delimiter(), Delimiter::Brace); ``` -------------------------------- ### Get Punct Character Value Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-punct-spacing.md Retrieves the character representation of a Punct object. Use this when you need to know the specific punctuation mark. ```rust use proc_macro2::{Punct, Spacing}; let punct = Punct::new('+', Spacing::Alone); assert_eq!(punct.as_char(), '+'); ``` -------------------------------- ### Generate Code with Quote Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/README.md Shows how to programmatically generate Rust code using the quote! macro. This is essential for writing macros that produce new code constructs. ```rust use proc_macro2::{Ident, Span}; use quote::quote; fn generate_getter(field_name: &str) -> proc_macro2::TokenStream { let field = Ident::new(field_name, Span::call_site()); let getter_name = Ident::new( &format!("get_{}", field_name), Span::call_site(), ); quote! { pub fn #getter_name(&self) -> &i32 { &self.#field } } } ``` -------------------------------- ### Ident::new_raw() Panic with Keywords Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/errors.md Demonstrates the correct usage of Ident::new_raw with valid keywords and highlights the panic that occurs when using path-segment keywords. ```rust use proc_macro2::{Ident, Span}; // OK let raw_fn = Ident::new_raw("fn", Span::call_site()); println!("{}", raw_fn); // Prints: r#fn // Panics! // let raw_self = Ident::new_raw("self", Span::call_site()); // panicked at 'invalid raw identifier' ``` -------------------------------- ### Implement Display for TokenStream Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-tokenstream.md Prints the token stream as a losslessly-convertible string. Suitable for code generation. ```rust impl Display for TokenStream { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result } ``` -------------------------------- ### Using Ident with quote! Macro Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-ident.md Demonstrates how to create an Ident and use it within the quote! macro to generate Rust code. ```rust use proc_macro2::{Ident, Span}; use quote::quote; let name = Ident::new("MyStruct", Span::call_site()); let expanded = quote! { struct #name { field: i32, } }; ``` -------------------------------- ### join() Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-span.md Creates a new span that encompasses both the current span and another provided span. Returns `None` if the spans are from different files. ```APIDOC ## join(other: Span) ### Description Create a new span encompassing both `self` and `other`. ### Method `join(&self, other: Span) -> Option` ### Parameters * `&self`: The first span. * `other` (Span): The second span to join with. ### Returns * `Option`: A span covering both, or `None` if from different files. ### Note The underlying `proc_macro::Span::join` is nightly-only. When called from a procedural macro without a nightly compiler, this method always returns `None`. ### Example ```rust use proc_macro2::Span; let span1 = Span::call_site(); let span2 = Span::call_site(); if let Some(joined) = span1.join(span2) { println!("Joined span"); } ``` ``` -------------------------------- ### set_span() Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-literal.md Modifies the source code span associated with a Literal. This allows updating the span information for a literal, for example, to point to a different location in the source. ```APIDOC ## set_span() ### Description Configures the span associated with this literal. ### Method PUT (Conceptual) ### Parameters #### Path Parameters - **&mut self** (Literal) - Required - The mutable literal instance. - **span** (Span) - Required - The new span to associate with the literal. ### Request Example ```rust use proc_macro2::{Literal, Span}; let mut lit = Literal::string("test"); lit.set_span(Span::mixed_site()); ``` ``` -------------------------------- ### Get Group Token Stream Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-group-delim.md Extracts the inner token stream of a Group, excluding the delimiters. Useful for processing the content within a delimited group. ```rust use proc_macro2::{Group, Delimiter, TokenStream}; use std::str::FromStr; let tokens = TokenStream::from_str("a b c").unwrap(); let group = Group::new(Delimiter::Parenthesis, tokens); let inner = group.stream(); println!("{}", inner); // Prints: a b c ``` -------------------------------- ### Test Macro Logic with proc_macro2 Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/README.md Illustrates how to test macro logic directly using proc_macro2 types within unit tests. This avoids the need for a full procedural macro compilation context. ```rust #[test] fn test_identifier() { let ident = proc_macro2::Ident::new("test", proc_macro2::Span::call_site()); assert_eq!(ident.to_string(), "test"); } ``` -------------------------------- ### Avoiding Ident::new() Panics Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/errors.md Shows safe ways to create Identifiers, either by pre-validating the name or by using the syn crate's parsing functions which return a Result instead of panicking. ```Rust use proc_macro2::{Ident, Span}; // Safe: check first or use syn::parse_str if is_valid_ident(name) { let ident = Ident::new(name, Span::call_site()); } // Alternative: use syn use syn; let ident: syn::Ident = syn::parse_str(name)?; ``` -------------------------------- ### Get Punct Span Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-punct-spacing.md Retrieves the source code span associated with a Punct object. Use this for debugging or to understand the origin of the punctuation in the source code. ```rust use proc_macro2::{Punct, Spacing, Span}; let mut punct = Punct::new('+', Spacing::Alone); let span = punct.span(); println!("{:?}", span); ``` -------------------------------- ### Get Punct Spacing (Alone) Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-punct-spacing.md Retrieves the spacing of a Punct object, indicating if it is not followed by another Punct. Use this to check if the punctuation stands alone. ```rust use proc_macro2::{Punct, Spacing}; let punct = Punct::new('+', Spacing::Alone); assert_eq!(punct.spacing(), Spacing::Alone); ``` -------------------------------- ### Creating Float Literals with proc-macro2 Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/errors.md Demonstrates the creation of valid f64 and f32 literals. Non-finite float values like NaN and Infinity will cause a panic. ```rust use proc_macro2::Literal; // OK let lit1 = Literal::f64_unsuffixed(3.14); let lit2 = Literal::f32_suffixed(1.0); // Panics! // let nan = Literal::f64_unsuffixed(f64::NAN); // panicked at 'assertion failed: f.is_finite()' // Panics! // let inf = Literal::f64_suffixed(f64::INFINITY); // panicked at 'assertion failed: f.is_finite()' ``` -------------------------------- ### Combine Span Hygiene and Location Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-span.md Use `located_at` to create a new span with the name resolution behavior of the first span and the line/column information of the second span. ```rust use proc_macro2::Span; let span1 = Span::call_site(); let span2 = Span::mixed_site(); let combined = span1.located_at(span2); ``` -------------------------------- ### Get Combined Delimiter Span Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-group-delim.md Obtains a `DelimSpan` struct containing both the opening and closing delimiter spans. This is a more compact way to represent the delimiter's location. ```rust use proc_macro2::{Group, Delimiter, TokenStream}; let group = Group::new(Delimiter::Brace, TokenStream::new()); let delim = group.delim_span(); println!("Opening: {:?}", delim.open()); println!("Closing: {:?}", delim.close()); ``` -------------------------------- ### Get Group Span Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-group-delim.md Obtains the span covering the entire Group, including both opening and closing delimiters. Useful for error reporting or locating the group in source code. ```rust use proc_macro2::{Group, Delimiter, TokenStream, Span}; let group = Group::new(Delimiter::Parenthesis, TokenStream::new()); let span = group.span(); println!("{:?}", span); ``` -------------------------------- ### Extend TokenStream with TokenTree items Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-tokenstream.md Use this to add multiple token trees to an existing TokenStream. Requires importing `proc_macro2::{TokenStream, TokenTree}`. ```rust use proc_macro2::{TokenStream, TokenTree}; let mut stream = TokenStream::new(); stream.extend(vec![/* TokenTree items */]); ``` -------------------------------- ### Get Punct Spacing (Joint) Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-punct-spacing.md Retrieves the spacing of a Punct object, indicating if it's part of a multi-character operator. Use this to check if the punctuation is followed by another Punct. ```rust use proc_macro2::{Punct, Spacing}; let punct = Punct::new('+', Spacing::Joint); assert_eq!(punct.spacing(), Spacing::Joint); ``` -------------------------------- ### Get End Line and Column of a Span Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-span.md The `end` method retrieves the ending line (1-indexed) and column (0-indexed, in UTF-8 characters) of a span. Accuracy depends on the toolchain and context. ```rust use proc_macro2::Span; let span = Span::call_site(); let loc = span.end(); println!("Line {}, Column {}", loc.line, loc.column); ``` -------------------------------- ### Compare Ident for Ordering Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-ident.md Shows how Ident instances are ordered based on their string representation. Use this to sort or check relative order. ```rust use proc_macro2::{Ident, Span}; let a = Ident::new("a", Span::call_site()); let b = Ident::new("b", Span::call_site()); assert!(a < b); ``` -------------------------------- ### Enable Span Locations Feature Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/configuration.md This configuration enables the exposure of span location methods like start(), end(), file(), and byte_range(). It is disabled by default and reduces code size when not needed. ```toml [features] span-locations = [] ``` -------------------------------- ### Parse and Iterate Token Stream Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/README.md Demonstrates how to parse a string into a TokenStream and iterate over its individual tokens. Useful for analyzing or transforming code structures. ```rust use proc_macro2::{TokenStream, TokenTree, Ident, Span}; use std::str::FromStr; // Parse let stream = TokenStream::from_str("x + y").unwrap(); // Iterate for token in stream { match token { TokenTree::Ident(i) => println!("Ident: {}", i), TokenTree::Punct(p) => println!("Punct: {}", p.as_char()), _ => println!("Other: {:?}", token), } } ``` -------------------------------- ### Basic Procedural Macro Structure Source: https://github.com/dtolnay/proc-macro2/blob/master/README.md This is the typical skeleton of a procedural macro using proc-macro2 for token stream manipulation. ```rust extern crate proc_macro; #[proc_macro_derive(MyDerive)] pub fn my_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let input = proc_macro2::TokenStream::from(input); let output: proc_macro2::TokenStream = { /* transform input */ }; proc_macro::TokenStream::from(output) } ``` -------------------------------- ### Implement Debug for TokenStream Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-tokenstream.md Prints the token stream in a human-readable debug format. ```rust impl Debug for TokenStream { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result } ``` -------------------------------- ### Example Usage of invalidate_current_thread_spans Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-extra-fallback.md Demonstrates how to use `invalidate_current_thread_spans` to reset span tracking after processing a large batch of files. This prevents issues with 32-bit source location counters wrapping around. ```rust use proc_macro2::extra::invalidate_current_thread_spans; use std::str::FromStr; // Process many files let mut total_bytes = 0; for file_content in all_rust_files() { let tokens = proc_macro2::TokenStream::from_str(file_content)?; total_bytes += file_content.len(); // Reset after processing a large batch if total_bytes > 2_000_000_000 { invalidate_current_thread_spans(); total_bytes = 0; } } ``` -------------------------------- ### Get Local File Path from Span Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-span.md Retrieves the actual, unremapped file path on disk for a given span. This is useful for debugging but should not be embedded in macro output. Requires the 'span-locations' feature. ```rust #[cfg(span_locations)] pub fn local_file(&self) -> Option ``` ```rust use proc_macro2::Span; let span = Span::call_site(); if let Some(path) = span.local_file() { println!("Real path: {}", path.display()); } ``` -------------------------------- ### Group Constructor Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-group-delim.md Creates a new Group with the given delimiter and token stream. The span is set to Span::call_site() by default. ```APIDOC ## Constructor ### `new(delimiter: Delimiter, stream: TokenStream) -> Group` Creates a new `Group` with the given delimiter and token stream. #### Parameters - **delimiter** (Delimiter) - Required - The delimiter type (Parenthesis, Brace, Bracket, or None) - **stream** (TokenStream) - Required - The token stream to be delimited **Returns:** `Group` — A new group with span set to `Span::call_site()` by default. **Example:** ```rust use proc_macro2::{Group, Delimiter, TokenStream, Span}; let tokens = TokenStream::new(); let group = Group::new(Delimiter::Parenthesis, tokens); let mut group_mut = group.clone(); group_mut.set_span(Span::call_site()); ``` ``` -------------------------------- ### Implement Display for Ident Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-ident.md Prints the identifier as a string, losslessly convertible back. For raw identifiers, prints with the `r#` prefix. ```rust impl Display for Ident { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result } ``` -------------------------------- ### Default proc-macro2 Configuration Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/configuration.md This TOML snippet shows the default dependency configuration for proc-macro2, which relies on the compiler's implementation for macros and a fallback for other uses. ```toml [dependencies] proc-macro2 = "1.0" [dependencies.syn] version = "2.0" features = ["full"] ``` -------------------------------- ### Get Subspan of Literal Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-literal.md Obtains a span covering a specific byte range within a proc-macro2::Literal. Note that this method returns None on stable Rust and is only fully functional on nightly builds. ```rust use proc_macro2::Literal; let lit = Literal::string("hello"); if let Some(span) = lit.subspan(1..4) { println!("Span for 'ell'"); } ``` -------------------------------- ### Get Source Text from Span Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-span.md Retrieves the original source code text associated with a span, including whitespace and comments. This is intended for diagnostic purposes only and should not be relied upon for macro output. Returns None if the span does not correspond to real source. ```rust pub fn source_text(&self) -> Option ``` ```rust use proc_macro2::Span; let span = Span::call_site(); if let Some(text) = span.source_text() { println!("Source: {}", text); } ``` -------------------------------- ### Generate Dynamic Identifier Names Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-ident.md Demonstrates creating an identifier dynamically by formatting a string, useful for generating getter names. ```rust use proc_macro2::{Ident, Span}; fn make_getter_name(field: &str) -> Ident { Ident::new(&format!("get_{}", field), Span::call_site()) } let getter = make_getter_name("count"); println!("{}", getter); // Prints: get_count ``` -------------------------------- ### Enable Experimental APIs via RUSTFLAGS Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/configuration.md Build or test with experimental APIs by setting the RUSTFLAGS environment variable to include the '--cfg procmacro2_semver_exempt' flag. ```bash # Build with experimental APIs RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo build # Run tests RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo test ``` -------------------------------- ### Configure Workspace Members Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/configuration.md Define workspace members in Cargo.toml to include benchmarking and UI test suites. ```toml [workspace] members = [ "benches/bench-libproc-macro", "tests/ui", ] ``` -------------------------------- ### Control hygiene with mixed site span Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/MANIFEST.txt Span::mixed_site() creates a span similar to macro_rules! hygiene. ```rust Span::mixed_site() ``` -------------------------------- ### Punct Constructor Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/api-reference-punct-spacing.md Creates a new Punct instance representing a single punctuation character with its associated spacing information. It panics if the provided character is not a valid punctuation. ```APIDOC ## Constructor ### `new(ch: char, spacing: Spacing) -> Punct` Creates a new `Punct` from the given character and spacing. ### Parameters - **ch** (char) - Required - A single punctuation character - **spacing** (Spacing) - Required - Whether this punct is immediately followed by another ### Returns `Punct` - A new punct with span set to `Span::call_site()`. ### Panics If `ch` is not a valid punctuation character. Valid characters are: `! # $ % & ' * + , - . / : ; < = > ? @ ^ \| ~` ### Example ```rust use proc_macro2::{Punct, Spacing}; let plus = Punct::new('+', Spacing::Alone); let equals = Punct::new('=', Spacing::Alone); // For `+=`, the first `+` should be Joint: let plus_joint = Punct::new('+', Spacing::Joint); let equals_alone = Punct::new('=', Spacing::Alone); ``` ``` -------------------------------- ### Add proc-macro2 Dependency Source: https://github.com/dtolnay/proc-macro2/blob/master/README.md Add proc-macro2 to your Cargo.toml to include it in your project. ```toml [dependencies] proc-macro2 = "1.0" ``` -------------------------------- ### proc-macro2 with Fallback Only for Testing Source: https://github.com/dtolnay/proc-macro2/blob/master/_autodocs/configuration.md This TOML configuration disables default features for proc-macro2, forcing the use of its fallback implementation. This is beneficial for testing macro logic in unit tests without relying on the compiler's specific implementation. ```toml [dependencies] proc-macro2 = { version = "1.0", default-features = false } ```