lib.rs - source (original) (raw)
proc_macro/
lib.rs
1//! A support library for macro authors when defining new macros.
2//!
3//! This library, provided by the standard distribution, provides the types
4//! consumed in the interfaces of procedurally defined macro definitions such as
5//! function-like macros `#[proc_macro]`, macro attributes `#[proc_macro_attribute]` and
6//! custom derive attributes`#[proc_macro_derive]`.
7//!
8//! See [the book] for more.
9//!
10//! [the book]: ../book/ch19-06-macros.html#procedural-macros-for-generating-code-from-attributes
11
12#![stable(feature = "proc_macro_lib", since = "1.15.0")]
13#![deny(missing_docs)]
14#![doc(
15 html_playground_url = "https://play.rust-lang.org/",
16 issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/",
17 test(no_crate_inject, attr(deny(warnings))),
18 test(attr(allow(dead_code, deprecated, unused_variables, unused_mut)))
19)]
20#![doc(rust_logo)]
21#![feature(rustdoc_internals)]
22#![feature(staged_api)]
23#![feature(allow_internal_unstable)]
24#![feature(decl_macro)]
25#![feature(maybe_uninit_write_slice)]
26#![feature(negative_impls)]
27#![feature(panic_can_unwind)]
28#![feature(restricted_std)]
29#![feature(rustc_attrs)]
30#![feature(extend_one)]
31#![recursion_limit = "256"]
32#![allow(internal_features)]
33#![deny(ffi_unwind_calls)]
34#![warn(rustdoc::unescaped_backticks)]
35#![warn(unreachable_pub)]
36#![deny(unsafe_op_in_unsafe_fn)]
37
38#[unstable(feature = "proc_macro_internals", issue = "27812")]
39#[doc(hidden)]
40pub mod bridge;
41
42mod diagnostic;
43mod escape;
44mod to_tokens;
45
46use std::ffi::CStr;
47use std::ops::{Range, RangeBounds};
48use std::path::PathBuf;
49use std::str::FromStr;
50use std::{error, fmt};
51
52#[unstable(feature = "proc_macro_diagnostic", issue = "54140")]
53pub use diagnostic::{Diagnostic, Level, MultiSpan};
54#[unstable(feature = "proc_macro_totokens", issue = "130977")]
55pub use to_tokens::ToTokens;
56
57use crate::escape::{EscapeOptions, escape_bytes};
58
59/// Determines whether proc_macro has been made accessible to the currently
60/// running program.
61///
62/// The proc_macro crate is only intended for use inside the implementation of
63/// procedural macros. All the functions in this crate panic if invoked from
64/// outside of a procedural macro, such as from a build script or unit test or
65/// ordinary Rust binary.
66///
67/// With consideration for Rust libraries that are designed to support both
68/// macro and non-macro use cases, `proc_macro::is_available()` provides a
69/// non-panicking way to detect whether the infrastructure required to use the
70/// API of proc_macro is presently available. Returns true if invoked from
71/// inside of a procedural macro, false if invoked from any other binary.
72#[stable(feature = "proc_macro_is_available", since = "1.57.0")]
73pub fn is_available() -> bool {
74 bridge::client::is_available()
75}
76
77/// The main type provided by this crate, representing an abstract stream of
78/// tokens, or, more specifically, a sequence of token trees.
79/// The type provides interfaces for iterating over those token trees and, conversely,
80/// collecting a number of token trees into one stream.
81///
82/// This is both the input and output of `#[proc_macro]`, `#[proc_macro_attribute]`
83/// and `#[proc_macro_derive]` definitions.
84#[rustc_diagnostic_item = "TokenStream"]
85#[stable(feature = "proc_macro_lib", since = "1.15.0")]
86#[derive(Clone)]
87pub struct TokenStream(Option<bridge::client::TokenStream>);
88
89#[stable(feature = "proc_macro_lib", since = "1.15.0")]
90impl !Send for TokenStream {}
91#[stable(feature = "proc_macro_lib", since = "1.15.0")]
92impl !Sync for TokenStream {}
93
94/// Error returned from `TokenStream::from_str`.
95#[stable(feature = "proc_macro_lib", since = "1.15.0")]
96#[non_exhaustive]
97#[derive(Debug)]
98pub struct LexError;
99
100#[stable(feature = "proc_macro_lexerror_impls", since = "1.44.0")]
101impl fmt::Display for LexError {
102 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
103 f.write_str("cannot parse string into token stream")
104 }
105}
106
107#[stable(feature = "proc_macro_lexerror_impls", since = "1.44.0")]
108impl error::Error for LexError {}
109
110#[stable(feature = "proc_macro_lib", since = "1.15.0")]
111impl !Send for LexError {}
112#[stable(feature = "proc_macro_lib", since = "1.15.0")]
113impl !Sync for LexError {}
114
115/// Error returned from `TokenStream::expand_expr`.
116#[unstable(feature = "proc_macro_expand", issue = "90765")]
117#[non_exhaustive]
118#[derive(Debug)]
119pub struct ExpandError;
120
121#[unstable(feature = "proc_macro_expand", issue = "90765")]
122impl fmt::Display for ExpandError {
123 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
124 f.write_str("macro expansion failed")
125 }
126}
127
128#[unstable(feature = "proc_macro_expand", issue = "90765")]
129impl error::Error for ExpandError {}
130
131#[unstable(feature = "proc_macro_expand", issue = "90765")]
132impl !Send for ExpandError {}
133
134#[unstable(feature = "proc_macro_expand", issue = "90765")]
135impl !Sync for ExpandError {}
136
137impl TokenStream {
138 /// Returns an empty `TokenStream` containing no token trees.
139 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
140 pub fn new() -> TokenStream {
141 TokenStream(None)
142 }
143
144 /// Checks if this `TokenStream` is empty.
145 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
146 pub fn is_empty(&self) -> bool {
147 self.0.as_ref().map(|h| h.is_empty()).unwrap_or(true)
148 }
149
150 /// Parses this `TokenStream` as an expression and attempts to expand any
151 /// macros within it. Returns the expanded `TokenStream`.
152 ///
153 /// Currently only expressions expanding to literals will succeed, although
154 /// this may be relaxed in the future.
155 ///
156 /// NOTE: In error conditions, `expand_expr` may leave macros unexpanded,
157 /// report an error, failing compilation, and/or return an `Err(..)`. The
158 /// specific behavior for any error condition, and what conditions are
159 /// considered errors, is unspecified and may change in the future.
160 #[unstable(feature = "proc_macro_expand", issue = "90765")]
161 pub fn expand_expr(&self) -> Result<TokenStream, ExpandError> {
162 let stream = self.0.as_ref().ok_or(ExpandError)?;
163 match bridge::client::TokenStream::expand_expr(stream) {
164 Ok(stream) => Ok(TokenStream(Some(stream))),
165 Err(_) => Err(ExpandError),
166 }
167 }
168}
169
170/// Attempts to break the string into tokens and parse those tokens into a token stream.
171/// May fail for a number of reasons, for example, if the string contains unbalanced delimiters
172/// or characters not existing in the language.
173/// All tokens in the parsed stream get `Span::call_site()` spans.
174///
175/// NOTE: some errors may cause panics instead of returning `LexError`. We reserve the right to
176/// change these errors into `LexError`s later.
177#[stable(feature = "proc_macro_lib", since = "1.15.0")]
178impl FromStr for TokenStream {
179 type Err = LexError;
180
181 fn from_str(src: &str) -> Result<TokenStream, LexError> {
182 Ok(TokenStream(Some(bridge::client::TokenStream::from_str(src))))
183 }
184}
185
186/// Prints the token stream as a string that is supposed to be losslessly convertible back
187/// into the same token stream (modulo spans), except for possibly `TokenTree::Group`s
188/// with `Delimiter::None` delimiters and negative numeric literals.
189///
190/// Note: the exact form of the output is subject to change, e.g. there might
191/// be changes in the whitespace used between tokens. Therefore, you should
192/// *not* do any kind of simple substring matching on the output string (as
193/// produced by `to_string`) to implement a proc macro, because that matching
194/// might stop working if such changes happen. Instead, you should work at the
195/// `TokenTree` level, e.g. matching against `TokenTree::Ident`,
196/// `TokenTree::Punct`, or `TokenTree::Literal`.
197#[stable(feature = "proc_macro_lib", since = "1.15.0")]
198impl fmt::Display for TokenStream {
199 #[allow(clippy::recursive_format_impl)] // clippy doesn't see the specialization
200 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
201 match &self.0 {
202 Some(ts) => write!(f, "{}", ts.to_string()),
203 None => Ok(()),
204 }
205 }
206}
207
208/// Prints token in a form convenient for debugging.
209#[stable(feature = "proc_macro_lib", since = "1.15.0")]
210impl fmt::Debug for TokenStream {
211 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
212 f.write_str("TokenStream ")?;
213 f.debug_list().entries(self.clone()).finish()
214 }
215}
216
217#[stable(feature = "proc_macro_token_stream_default", since = "1.45.0")]
218impl Default for TokenStream {
219 fn default() -> Self {
220 TokenStream::new()
221 }
222}
223
224#[unstable(feature = "proc_macro_quote", issue = "54722")]
225pub use quote::{quote, quote_span};
226
227fn tree_to_bridge_tree(
228 tree: TokenTree,
229) -> bridge::TokenTree<bridge::client::TokenStream, bridge::client::Span, bridge::client::Symbol> {
230 match tree {
231 TokenTree::Group(tt) => bridge::TokenTree::Group(tt.0),
232 TokenTree::Punct(tt) => bridge::TokenTree::Punct(tt.0),
233 TokenTree::Ident(tt) => bridge::TokenTree::Ident(tt.0),
234 TokenTree::Literal(tt) => bridge::TokenTree::Literal(tt.0),
235 }
236}
237
238/// Creates a token stream containing a single token tree.
239#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
240impl From<TokenTree> for TokenStream {
241 fn from(tree: TokenTree) -> TokenStream {
242 TokenStream(Some(bridge::client::TokenStream::from_token_tree(tree_to_bridge_tree(tree))))
243 }
244}
245
246/// Non-generic helper for implementing `FromIterator<TokenTree>` and
247/// `Extend<TokenTree>` with less monomorphization in calling crates.
248struct ConcatTreesHelper {
249 trees: Vec<
250 bridge::TokenTree<
251 bridge::client::TokenStream,
252 bridge::client::Span,
253 bridge::client::Symbol,
254 >,
255 >,
256}
257
258impl ConcatTreesHelper {
259 fn new(capacity: usize) -> Self {
260 ConcatTreesHelper { trees: Vec::with_capacity(capacity) }
261 }
262
263 fn push(&mut self, tree: TokenTree) {
264 self.trees.push(tree_to_bridge_tree(tree));
265 }
266
267 fn build(self) -> TokenStream {
268 if self.trees.is_empty() {
269 TokenStream(None)
270 } else {
271 TokenStream(Some(bridge::client::TokenStream::concat_trees(None, self.trees)))
272 }
273 }
274
275 fn append_to(self, stream: &mut TokenStream) {
276 if self.trees.is_empty() {
277 return;
278 }
279 stream.0 = Some(bridge::client::TokenStream::concat_trees(stream.0.take(), self.trees))
280 }
281}
282
283/// Non-generic helper for implementing `FromIterator<TokenStream>` and
284/// `Extend<TokenStream>` with less monomorphization in calling crates.
285struct ConcatStreamsHelper {
286 streams: Vec<bridge::client::TokenStream>,
287}
288
289impl ConcatStreamsHelper {
290 fn new(capacity: usize) -> Self {
291 ConcatStreamsHelper { streams: Vec::with_capacity(capacity) }
292 }
293
294 fn push(&mut self, stream: TokenStream) {
295 if let Some(stream) = stream.0 {
296 self.streams.push(stream);
297 }
298 }
299
300 fn build(mut self) -> TokenStream {
301 if self.streams.len() <= 1 {
302 TokenStream(self.streams.pop())
303 } else {
304 TokenStream(Some(bridge::client::TokenStream::concat_streams(None, self.streams)))
305 }
306 }
307
308 fn append_to(mut self, stream: &mut TokenStream) {
309 if self.streams.is_empty() {
310 return;
311 }
312 let base = stream.0.take();
313 if base.is_none() && self.streams.len() == 1 {
314 stream.0 = self.streams.pop();
315 } else {
316 stream.0 = Some(bridge::client::TokenStream::concat_streams(base, self.streams));
317 }
318 }
319}
320
321/// Collects a number of token trees into a single stream.
322#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
323impl FromIterator<TokenTree> for TokenStream {
324 fn from_iter<I: IntoIterator<Item = TokenTree>>(trees: I) -> Self {
325 let iter = trees.into_iter();
326 let mut builder = ConcatTreesHelper::new(iter.size_hint().0);
327 iter.for_each(|tree| builder.push(tree));
328 builder.build()
329 }
330}
331
332/// A "flattening" operation on token streams, collects token trees
333/// from multiple token streams into a single stream.
334#[stable(feature = "proc_macro_lib", since = "1.15.0")]
335impl FromIterator<TokenStream> for TokenStream {
336 fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self {
337 let iter = streams.into_iter();
338 let mut builder = ConcatStreamsHelper::new(iter.size_hint().0);
339 iter.for_each(|stream| builder.push(stream));
340 builder.build()
341 }
342}
343
344#[stable(feature = "token_stream_extend", since = "1.30.0")]
345impl Extend<TokenTree> for TokenStream {
346 fn extend<I: IntoIterator<Item = TokenTree>>(&mut self, trees: I) {
347 let iter = trees.into_iter();
348 let mut builder = ConcatTreesHelper::new(iter.size_hint().0);
349 iter.for_each(|tree| builder.push(tree));
350 builder.append_to(self);
351 }
352}
353
354#[stable(feature = "token_stream_extend", since = "1.30.0")]
355impl Extend<TokenStream> for TokenStream {
356 fn extend<I: IntoIterator<Item = TokenStream>>(&mut self, streams: I) {
357 let iter = streams.into_iter();
358 let mut builder = ConcatStreamsHelper::new(iter.size_hint().0);
359 iter.for_each(|stream| builder.push(stream));
360 builder.append_to(self);
361 }
362}
363
364/// Public implementation details for the `TokenStream` type, such as iterators.
365#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
366pub mod token_stream {
367 use crate::{Group, Ident, Literal, Punct, TokenStream, TokenTree, bridge};
368
369 /// An iterator over `TokenStream`'s `TokenTree`s.
370 /// The iteration is "shallow", e.g., the iterator doesn't recurse into delimited groups,
371 /// and returns whole groups as token trees.
372 #[derive(Clone)]
373 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
374 pub struct IntoIter(
375 std::vec::IntoIter<
376 bridge::TokenTree<
377 bridge::client::TokenStream,
378 bridge::client::Span,
379 bridge::client::Symbol,
380 >,
381 >,
382 );
383
384 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
385 impl Iterator for IntoIter {
386 type Item = TokenTree;
387
388 fn next(&mut self) -> Option<TokenTree> {
389 self.0.next().map(|tree| match tree {
390 bridge::TokenTree::Group(tt) => TokenTree::Group(Group(tt)),
391 bridge::TokenTree::Punct(tt) => TokenTree::Punct(Punct(tt)),
392 bridge::TokenTree::Ident(tt) => TokenTree::Ident(Ident(tt)),
393 bridge::TokenTree::Literal(tt) => TokenTree::Literal(Literal(tt)),
394 })
395 }
396
397 fn size_hint(&self) -> (usize, Option<usize>) {
398 self.0.size_hint()
399 }
400
401 fn count(self) -> usize {
402 self.0.count()
403 }
404 }
405
406 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
407 impl IntoIterator for TokenStream {
408 type Item = TokenTree;
409 type IntoIter = IntoIter;
410
411 fn into_iter(self) -> IntoIter {
412 IntoIter(self.0.map(|v| v.into_trees()).unwrap_or_default().into_iter())
413 }
414 }
415}
416
417/// `quote!(..)` accepts arbitrary tokens and expands into a `TokenStream` describing the input.
418/// For example, `quote!(a + b)` will produce an expression, that, when evaluated, constructs
419/// the `TokenStream` `[Ident("a"), Punct('+', Alone), Ident("b")]`.
420///
421/// Unquoting is done with `$`, and works by taking the single next ident as the unquoted term.
422/// To quote `$` itself, use `$$`.
423#[unstable(feature = "proc_macro_quote", issue = "54722")]
424#[allow_internal_unstable(proc_macro_def_site, proc_macro_internals, proc_macro_totokens)]
425#[rustc_builtin_macro]
426pub macro quote($($t:tt)*) {
427 /* compiler built-in */
428}
429
430#[unstable(feature = "proc_macro_internals", issue = "27812")]
431#[doc(hidden)]
432mod quote;
433
434/// A region of source code, along with macro expansion information.
435#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
436#[derive(Copy, Clone)]
437pub struct Span(bridge::client::Span);
438
439#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
440impl !Send for Span {}
441#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
442impl !Sync for Span {}
443
444macro_rules! diagnostic_method {
445 ($name:ident, $level:expr) => {
446 /// Creates a new `Diagnostic` with the given `message` at the span
447 /// `self`.
448 #[unstable(feature = "proc_macro_diagnostic", issue = "54140")]
449 pub fn $name<T: Into<String>>(self, message: T) -> Diagnostic {
450 Diagnostic::spanned(self, $level, message)
451 }
452 };
453}
454
455impl Span {
456 /// A span that resolves at the macro definition site.
457 #[unstable(feature = "proc_macro_def_site", issue = "54724")]
458 pub fn def_site() -> Span {
459 Span(bridge::client::Span::def_site())
460 }
461
462 /// The span of the invocation of the current procedural macro.
463 /// Identifiers created with this span will be resolved as if they were written
464 /// directly at the macro call location (call-site hygiene) and other code
465 /// at the macro call site will be able to refer to them as well.
466 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
467 pub fn call_site() -> Span {
468 Span(bridge::client::Span::call_site())
469 }
470
471 /// A span that represents `macro_rules` hygiene, and sometimes resolves at the macro
472 /// definition site (local variables, labels, `$crate`) and sometimes at the macro
473 /// call site (everything else).
474 /// The span location is taken from the call-site.
475 #[stable(feature = "proc_macro_mixed_site", since = "1.45.0")]
476 pub fn mixed_site() -> Span {
477 Span(bridge::client::Span::mixed_site())
478 }
479
480 /// The original source file into which this span points.
481 #[unstable(feature = "proc_macro_span", issue = "54725")]
482 pub fn source_file(&self) -> SourceFile {
483 SourceFile(self.0.source_file())
484 }
485
486 /// The `Span` for the tokens in the previous macro expansion from which
487 /// `self` was generated from, if any.
488 #[unstable(feature = "proc_macro_span", issue = "54725")]
489 pub fn parent(&self) -> Option<Span> {
490 self.0.parent().map(Span)
491 }
492
493 /// The span for the origin source code that `self` was generated from. If
494 /// this `Span` wasn't generated from other macro expansions then the return
495 /// value is the same as `*self`.
496 #[unstable(feature = "proc_macro_span", issue = "54725")]
497 pub fn source(&self) -> Span {
498 Span(self.0.source())
499 }
500
501 /// Returns the span's byte position range in the source file.
502 #[unstable(feature = "proc_macro_span", issue = "54725")]
503 pub fn byte_range(&self) -> Range<usize> {
504 self.0.byte_range()
505 }
506
507 /// Creates an empty span pointing to directly before this span.
508 #[unstable(feature = "proc_macro_span", issue = "54725")]
509 pub fn start(&self) -> Span {
510 Span(self.0.start())
511 }
512
513 /// Creates an empty span pointing to directly after this span.
514 #[unstable(feature = "proc_macro_span", issue = "54725")]
515 pub fn end(&self) -> Span {
516 Span(self.0.end())
517 }
518
519 /// The one-indexed line of the source file where the span starts.
520 ///
521 /// To obtain the line of the span's end, use `span.end().line()`.
522 #[unstable(feature = "proc_macro_span", issue = "54725")]
523 pub fn line(&self) -> usize {
524 self.0.line()
525 }
526
527 /// The one-indexed column of the source file where the span starts.
528 ///
529 /// To obtain the column of the span's end, use `span.end().column()`.
530 #[unstable(feature = "proc_macro_span", issue = "54725")]
531 pub fn column(&self) -> usize {
532 self.0.column()
533 }
534
535 /// Creates a new span encompassing `self` and `other`.
536 ///
537 /// Returns `None` if `self` and `other` are from different files.
538 #[unstable(feature = "proc_macro_span", issue = "54725")]
539 pub fn join(&self, other: Span) -> Option<Span> {
540 self.0.join(other.0).map(Span)
541 }
542
543 /// Creates a new span with the same line/column information as `self` but
544 /// that resolves symbols as though it were at `other`.
545 #[stable(feature = "proc_macro_span_resolved_at", since = "1.45.0")]
546 pub fn resolved_at(&self, other: Span) -> Span {
547 Span(self.0.resolved_at(other.0))
548 }
549
550 /// Creates a new span with the same name resolution behavior as `self` but
551 /// with the line/column information of `other`.
552 #[stable(feature = "proc_macro_span_located_at", since = "1.45.0")]
553 pub fn located_at(&self, other: Span) -> Span {
554 other.resolved_at(*self)
555 }
556
557 /// Compares two spans to see if they're equal.
558 #[unstable(feature = "proc_macro_span", issue = "54725")]
559 pub fn eq(&self, other: &Span) -> bool {
560 self.0 == other.0
561 }
562
563 /// Returns the source text behind a span. This preserves the original source
564 /// code, including spaces and comments. It only returns a result if the span
565 /// corresponds to real source code.
566 ///
567 /// Note: The observable result of a macro should only rely on the tokens and
568 /// not on this source text. The result of this function is a best effort to
569 /// be used for diagnostics only.
570 #[stable(feature = "proc_macro_source_text", since = "1.66.0")]
571 pub fn source_text(&self) -> Option<String> {
572 self.0.source_text()
573 }
574
575 // Used by the implementation of `Span::quote`
576 #[doc(hidden)]
577 #[unstable(feature = "proc_macro_internals", issue = "27812")]
578 pub fn save_span(&self) -> usize {
579 self.0.save_span()
580 }
581
582 // Used by the implementation of `Span::quote`
583 #[doc(hidden)]
584 #[unstable(feature = "proc_macro_internals", issue = "27812")]
585 pub fn recover_proc_macro_span(id: usize) -> Span {
586 Span(bridge::client::Span::recover_proc_macro_span(id))
587 }
588
589 diagnostic_method!(error, Level::Error);
590 diagnostic_method!(warning, Level::Warning);
591 diagnostic_method!(note, Level::Note);
592 diagnostic_method!(help, Level::Help);
593}
594
595/// Prints a span in a form convenient for debugging.
596#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
597impl fmt::Debug for Span {
598 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
599 self.0.fmt(f)
600 }
601}
602
603/// The source file of a given `Span`.
604#[unstable(feature = "proc_macro_span", issue = "54725")]
605#[derive(Clone)]
606pub struct SourceFile(bridge::client::SourceFile);
607
608impl SourceFile {
609 /// Gets the path to this source file.
610 ///
611 /// ### Note
612 /// If the code span associated with this `SourceFile` was generated by an external macro, this
613 /// macro, this might not be an actual path on the filesystem. Use [`is_real`] to check.
614 ///
615 /// Also note that even if `is_real` returns `true`, if `--remap-path-prefix` was passed on
616 /// the command line, the path as given might not actually be valid.
617 ///
618 /// [`is_real`]: Self::is_real
619 #[unstable(feature = "proc_macro_span", issue = "54725")]
620 pub fn path(&self) -> PathBuf {
621 PathBuf::from(self.0.path())
622 }
623
624 /// Returns `true` if this source file is a real source file, and not generated by an external
625 /// macro's expansion.
626 #[unstable(feature = "proc_macro_span", issue = "54725")]
627 pub fn is_real(&self) -> bool {
628 // This is a hack until intercrate spans are implemented and we can have real source files
629 // for spans generated in external macros.
630 // https://github.com/rust-lang/rust/pull/43604#issuecomment-333334368
631 self.0.is_real()
632 }
633}
634
635#[unstable(feature = "proc_macro_span", issue = "54725")]
636impl fmt::Debug for SourceFile {
637 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
638 f.debug_struct("SourceFile")
639 .field("path", &self.path())
640 .field("is_real", &self.is_real())
641 .finish()
642 }
643}
644
645#[unstable(feature = "proc_macro_span", issue = "54725")]
646impl PartialEq for SourceFile {
647 fn eq(&self, other: &Self) -> bool {
648 self.0.eq(&other.0)
649 }
650}
651
652#[unstable(feature = "proc_macro_span", issue = "54725")]
653impl Eq for SourceFile {}
654
655/// A single token or a delimited sequence of token trees (e.g., `[1, (), ..]`).
656#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
657#[derive(Clone)]
658pub enum TokenTree {
659 /// A token stream surrounded by bracket delimiters.
660 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
661 Group(#[stable(feature = "proc_macro_lib2", since = "1.29.0")] Group),
662 /// An identifier.
663 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
664 Ident(#[stable(feature = "proc_macro_lib2", since = "1.29.0")] Ident),
665 /// A single punctuation character (`+`, `,`, `$`, etc.).
666 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
667 Punct(#[stable(feature = "proc_macro_lib2", since = "1.29.0")] Punct),
668 /// A literal character (`'a'`), string (`"hello"`), number (`2.3`), etc.
669 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
670 Literal(#[stable(feature = "proc_macro_lib2", since = "1.29.0")] Literal),
671}
672
673#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
674impl !Send for TokenTree {}
675#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
676impl !Sync for TokenTree {}
677
678impl TokenTree {
679 /// Returns the span of this tree, delegating to the `span` method of
680 /// the contained token or a delimited stream.
681 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
682 pub fn span(&self) -> Span {
683 match *self {
684 TokenTree::Group(ref t) => t.span(),
685 TokenTree::Ident(ref t) => t.span(),
686 TokenTree::Punct(ref t) => t.span(),
687 TokenTree::Literal(ref t) => t.span(),
688 }
689 }
690
691 /// Configures the span for *only this token*.
692 ///
693 /// Note that if this token is a `Group` then this method will not configure
694 /// the span of each of the internal tokens, this will simply delegate to
695 /// the `set_span` method of each variant.
696 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
697 pub fn set_span(&mut self, span: Span) {
698 match *self {
699 TokenTree::Group(ref mut t) => t.set_span(span),
700 TokenTree::Ident(ref mut t) => t.set_span(span),
701 TokenTree::Punct(ref mut t) => t.set_span(span),
702 TokenTree::Literal(ref mut t) => t.set_span(span),
703 }
704 }
705}
706
707/// Prints token tree in a form convenient for debugging.
708#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
709impl fmt::Debug for TokenTree {
710 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
711 // Each of these has the name in the struct type in the derived debug,
712 // so don't bother with an extra layer of indirection
713 match *self {
714 TokenTree::Group(ref tt) => tt.fmt(f),
715 TokenTree::Ident(ref tt) => tt.fmt(f),
716 TokenTree::Punct(ref tt) => tt.fmt(f),
717 TokenTree::Literal(ref tt) => tt.fmt(f),
718 }
719 }
720}
721
722#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
723impl From<Group> for TokenTree {
724 fn from(g: Group) -> TokenTree {
725 TokenTree::Group(g)
726 }
727}
728
729#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
730impl From<Ident> for TokenTree {
731 fn from(g: Ident) -> TokenTree {
732 TokenTree::Ident(g)
733 }
734}
735
736#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
737impl From<Punct> for TokenTree {
738 fn from(g: Punct) -> TokenTree {
739 TokenTree::Punct(g)
740 }
741}
742
743#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
744impl From<Literal> for TokenTree {
745 fn from(g: Literal) -> TokenTree {
746 TokenTree::Literal(g)
747 }
748}
749
750/// Prints the token tree as a string that is supposed to be losslessly convertible back
751/// into the same token tree (modulo spans), except for possibly `TokenTree::Group`s
752/// with `Delimiter::None` delimiters and negative numeric literals.
753///
754/// Note: the exact form of the output is subject to change, e.g. there might
755/// be changes in the whitespace used between tokens. Therefore, you should
756/// *not* do any kind of simple substring matching on the output string (as
757/// produced by `to_string`) to implement a proc macro, because that matching
758/// might stop working if such changes happen. Instead, you should work at the
759/// `TokenTree` level, e.g. matching against `TokenTree::Ident`,
760/// `TokenTree::Punct`, or `TokenTree::Literal`.
761#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
762impl fmt::Display for TokenTree {
763 #[allow(clippy::recursive_format_impl)] // clippy doesn't see the specialization
764 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
765 match self {
766 TokenTree::Group(t) => write!(f, "{t}"),
767 TokenTree::Ident(t) => write!(f, "{t}"),
768 TokenTree::Punct(t) => write!(f, "{t}"),
769 TokenTree::Literal(t) => write!(f, "{t}"),
770 }
771 }
772}
773
774/// A delimited token stream.
775///
776/// A `Group` internally contains a `TokenStream` which is surrounded by `Delimiter`s.
777#[derive(Clone)]
778#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
779pub struct Group(bridge::Group<bridge::client::TokenStream, bridge::client::Span>);
780
781#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
782impl !Send for Group {}
783#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
784impl !Sync for Group {}
785
786/// Describes how a sequence of token trees is delimited.
787#[derive(Copy, Clone, Debug, PartialEq, Eq)]
788#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
789pub enum Delimiter {
790 /// `( ... )`
791 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
792 Parenthesis,
793 /// `{ ... }`
794 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
795 Brace,
796 /// `[ ... ]`
797 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
798 Bracket,
799 /// `∅ ... ∅`
800 /// An invisible delimiter, that may, for example, appear around tokens coming from a
801 /// "macro variable" `$var`. It is important to preserve operator priorities in cases like
802 /// `$var * 3` where `$var` is `1 + 2`.
803 /// Invisible delimiters might not survive roundtrip of a token stream through a string.
804 ///
805 /// <div class="warning">
806 ///
807 /// Note: rustc currently can ignore the grouping of tokens delimited by `None` in the output
808 /// of a proc_macro. Only `None`-delimited groups created by a macro_rules macro in the input
809 /// of a proc_macro macro are preserved, and only in very specific circumstances.
810 /// Any `None`-delimited groups (re)created by a proc_macro will therefore not preserve
811 /// operator priorities as indicated above. The other `Delimiter` variants should be used
812 /// instead in this context. This is a rustc bug. For details, see
813 /// [rust-lang/rust#67062](https://github.com/rust-lang/rust/issues/67062).
814 ///
815 /// </div>
816 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
817 None,
818}
819
820impl Group {
821 /// Creates a new `Group` with the given delimiter and token stream.
822 ///
823 /// This constructor will set the span for this group to
824 /// `Span::call_site()`. To change the span you can use the `set_span`
825 /// method below.
826 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
827 pub fn new(delimiter: Delimiter, stream: TokenStream) -> Group {
828 Group(bridge::Group {
829 delimiter,
830 stream: stream.0,
831 span: bridge::DelimSpan::from_single(Span::call_site().0),
832 })
833 }
834
835 /// Returns the delimiter of this `Group`
836 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
837 pub fn delimiter(&self) -> Delimiter {
838 self.0.delimiter
839 }
840
841 /// Returns the `TokenStream` of tokens that are delimited in this `Group`.
842 ///
843 /// Note that the returned token stream does not include the delimiter
844 /// returned above.
845 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
846 pub fn stream(&self) -> TokenStream {
847 TokenStream(self.0.stream.clone())
848 }
849
850 /// Returns the span for the delimiters of this token stream, spanning the
851 /// entire `Group`.
852 ///
853 /// ```text
854 /// pub fn span(&self) -> Span {
855 /// ^^^^^^^
856 /// ```
857 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
858 pub fn span(&self) -> Span {
859 Span(self.0.span.entire)
860 }
861
862 /// Returns the span pointing to the opening delimiter of this group.
863 ///
864 /// ```text
865 /// pub fn span_open(&self) -> Span {
866 /// ^
867 /// ```
868 #[stable(feature = "proc_macro_group_span", since = "1.55.0")]
869 pub fn span_open(&self) -> Span {
870 Span(self.0.span.open)
871 }
872
873 /// Returns the span pointing to the closing delimiter of this group.
874 ///
875 /// ```text
876 /// pub fn span_close(&self) -> Span {
877 /// ^
878 /// ```
879 #[stable(feature = "proc_macro_group_span", since = "1.55.0")]
880 pub fn span_close(&self) -> Span {
881 Span(self.0.span.close)
882 }
883
884 /// Configures the span for this `Group`'s delimiters, but not its internal
885 /// tokens.
886 ///
887 /// This method will **not** set the span of all the internal tokens spanned
888 /// by this group, but rather it will only set the span of the delimiter
889 /// tokens at the level of the `Group`.
890 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
891 pub fn set_span(&mut self, span: Span) {
892 self.0.span = bridge::DelimSpan::from_single(span.0);
893 }
894}
895
896/// Prints the group as a string that should be losslessly convertible back
897/// into the same group (modulo spans), except for possibly `TokenTree::Group`s
898/// with `Delimiter::None` delimiters.
899#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
900impl fmt::Display for Group {
901 #[allow(clippy::recursive_format_impl)] // clippy doesn't see the specialization
902 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
903 write!(f, "{}", TokenStream::from(TokenTree::from(self.clone())))
904 }
905}
906
907#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
908impl fmt::Debug for Group {
909 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
910 f.debug_struct("Group")
911 .field("delimiter", &self.delimiter())
912 .field("stream", &self.stream())
913 .field("span", &self.span())
914 .finish()
915 }
916}
917
918/// A `Punct` is a single punctuation character such as `+`, `-` or `#`.
919///
920/// Multi-character operators like `+=` are represented as two instances of `Punct` with different
921/// forms of `Spacing` returned.
922#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
923#[derive(Clone)]
924pub struct Punct(bridge::Punct<bridge::client::Span>);
925
926#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
927impl !Send for Punct {}
928#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
929impl !Sync for Punct {}
930
931/// Indicates whether a `Punct` token can join with the following token
932/// to form a multi-character operator.
933#[derive(Copy, Clone, Debug, PartialEq, Eq)]
934#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
935pub enum Spacing {
936 /// A `Punct` token can join with the following token to form a multi-character operator.
937 ///
938 /// In token streams constructed using proc macro interfaces, `Joint` punctuation tokens can be
939 /// followed by any other tokens. However, in token streams parsed from source code, the
940 /// compiler will only set spacing to `Joint` in the following cases.
941 /// - When a `Punct` is immediately followed by another `Punct` without a whitespace. E.g. `+`
942 /// is `Joint` in `+=` and `++`.
943 /// - When a single quote `'` is immediately followed by an identifier without a whitespace.
944 /// E.g. `'` is `Joint` in `'lifetime`.
945 ///
946 /// This list may be extended in the future to enable more token combinations.
947 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
948 Joint,
949 /// A `Punct` token cannot join with the following token to form a multi-character operator.
950 ///
951 /// `Alone` punctuation tokens can be followed by any other tokens. In token streams parsed
952 /// from source code, the compiler will set spacing to `Alone` in all cases not covered by the
953 /// conditions for `Joint` above. E.g. `+` is `Alone` in `+ =`, `+ident` and `+()`. In
954 /// particular, tokens not followed by anything will be marked as `Alone`.
955 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
956 Alone,
957}
958
959impl Punct {
960 /// Creates a new `Punct` from the given character and spacing.
961 /// The `ch` argument must be a valid punctuation character permitted by the language,
962 /// otherwise the function will panic.
963 ///
964 /// The returned `Punct` will have the default span of `Span::call_site()`
965 /// which can be further configured with the `set_span` method below.
966 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
967 pub fn new(ch: char, spacing: Spacing) -> Punct {
968 const LEGAL_CHARS: &[char] = &[
969 '=', '<', '>', '!', '~', '+', '-', '*', '/', '%', '^', '&', '|', '@', '.', ',', ';',
970 ':', '#', '$', '?', '\'',
971 ];
972 if !LEGAL_CHARS.contains(&ch) {
973 panic!("unsupported character `{:?}`", ch);
974 }
975 Punct(bridge::Punct {
976 ch: ch as u8,
977 joint: spacing == Spacing::Joint,
978 span: Span::call_site().0,
979 })
980 }
981
982 /// Returns the value of this punctuation character as `char`.
983 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
984 pub fn as_char(&self) -> char {
985 self.0.ch as char
986 }
987
988 /// Returns the spacing of this punctuation character, indicating whether it can be potentially
989 /// combined into a multi-character operator with the following token (`Joint`), or whether the
990 /// operator has definitely ended (`Alone`).
991 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
992 pub fn spacing(&self) -> Spacing {
993 if self.0.joint { Spacing::Joint } else { Spacing::Alone }
994 }
995
996 /// Returns the span for this punctuation character.
997 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
998 pub fn span(&self) -> Span {
999 Span(self.0.span)
1000 }
1001
1002 /// Configure the span for this punctuation character.
1003 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1004 pub fn set_span(&mut self, span: Span) {
1005 self.0.span = span.0;
1006 }
1007}
1008
1009/// Prints the punctuation character as a string that should be losslessly convertible
1010/// back into the same character.
1011#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1012impl fmt::Display for Punct {
1013 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1014 write!(f, "{}", self.as_char())
1015 }
1016}
1017
1018#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1019impl fmt::Debug for Punct {
1020 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1021 f.debug_struct("Punct")
1022 .field("ch", &self.as_char())
1023 .field("spacing", &self.spacing())
1024 .field("span", &self.span())
1025 .finish()
1026 }
1027}
1028
1029#[stable(feature = "proc_macro_punct_eq", since = "1.50.0")]
1030impl PartialEq<char> for Punct {
1031 fn eq(&self, rhs: &char) -> bool {
1032 self.as_char() == *rhs
1033 }
1034}
1035
1036#[stable(feature = "proc_macro_punct_eq_flipped", since = "1.52.0")]
1037impl PartialEq<Punct> for char {
1038 fn eq(&self, rhs: &Punct) -> bool {
1039 *self == rhs.as_char()
1040 }
1041}
1042
1043/// An identifier (`ident`).
1044#[derive(Clone)]
1045#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1046pub struct Ident(bridge::Ident<bridge::client::Span, bridge::client::Symbol>);
1047
1048impl Ident {
1049 /// Creates a new `Ident` with the given `string` as well as the specified
1050 /// `span`.
1051 /// The `string` argument must be a valid identifier permitted by the
1052 /// language (including keywords, e.g. `self` or `fn`). Otherwise, the function will panic.
1053 ///
1054 /// Note that `span`, currently in rustc, configures the hygiene information
1055 /// for this identifier.
1056 ///
1057 /// As of this time `Span::call_site()` explicitly opts-in to "call-site" hygiene
1058 /// meaning that identifiers created with this span will be resolved as if they were written
1059 /// directly at the location of the macro call, and other code at the macro call site will be
1060 /// able to refer to them as well.
1061 ///
1062 /// Later spans like `Span::def_site()` will allow to opt-in to "definition-site" hygiene
1063 /// meaning that identifiers created with this span will be resolved at the location of the
1064 /// macro definition and other code at the macro call site will not be able to refer to them.
1065 ///
1066 /// Due to the current importance of hygiene this constructor, unlike other
1067 /// tokens, requires a `Span` to be specified at construction.
1068 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1069 pub fn new(string: &str, span: Span) -> Ident {
1070 Ident(bridge::Ident {
1071 sym: bridge::client::Symbol::new_ident(string, false),
1072 is_raw: false,
1073 span: span.0,
1074 })
1075 }
1076
1077 /// Same as `Ident::new`, but creates a raw identifier (`r#ident`).
1078 /// The `string` argument be a valid identifier permitted by the language
1079 /// (including keywords, e.g. `fn`). Keywords which are usable in path segments
1080 /// (e.g. `self`, `super`) are not supported, and will cause a panic.
1081 #[stable(feature = "proc_macro_raw_ident", since = "1.47.0")]
1082 pub fn new_raw(string: &str, span: Span) -> Ident {
1083 Ident(bridge::Ident {
1084 sym: bridge::client::Symbol::new_ident(string, true),
1085 is_raw: true,
1086 span: span.0,
1087 })
1088 }
1089
1090 /// Returns the span of this `Ident`, encompassing the entire string returned
1091 /// by [`to_string`](ToString::to_string).
1092 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1093 pub fn span(&self) -> Span {
1094 Span(self.0.span)
1095 }
1096
1097 /// Configures the span of this `Ident`, possibly changing its hygiene context.
1098 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1099 pub fn set_span(&mut self, span: Span) {
1100 self.0.span = span.0;
1101 }
1102}
1103
1104/// Prints the identifier as a string that should be losslessly convertible back
1105/// into the same identifier.
1106#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1107impl fmt::Display for Ident {
1108 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1109 if self.0.is_raw {
1110 f.write_str("r#")?;
1111 }
1112 fmt::Display::fmt(&self.0.sym, f)
1113 }
1114}
1115
1116#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1117impl fmt::Debug for Ident {
1118 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1119 f.debug_struct("Ident")
1120 .field("ident", &self.to_string())
1121 .field("span", &self.span())
1122 .finish()
1123 }
1124}
1125
1126/// A literal string (`"hello"`), byte string (`b"hello"`), C string (`c"hello"`),
1127/// character (`'a'`), byte character (`b'a'`), an integer or floating point number
1128/// with or without a suffix (`1`, `1u8`, `2.3`, `2.3f32`).
1129/// Boolean literals like `true` and `false` do not belong here, they are `Ident`s.
1130#[derive(Clone)]
1131#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1132pub struct Literal(bridge::Literal<bridge::client::Span, bridge::client::Symbol>);
1133
1134macro_rules! suffixed_int_literals {
1135 ($($name:ident => <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi><mi>i</mi><mi>n</mi><mi>d</mi><mo>:</mo><mi>i</mi><mi>d</mi><mi>e</mi><mi>n</mi><mi>t</mi><mo separator="true">,</mo><mo stretchy="false">)</mo><mo>∗</mo><mo stretchy="false">)</mo><mo>=</mo><mo>></mo><mo stretchy="false">(</mo></mrow><annotation encoding="application/x-tex">kind:ident,)*) => (</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">kin</span><span class="mord mathnormal">d</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">:</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">i</span><span class="mord mathnormal">d</span><span class="mord mathnormal">e</span><span class="mord mathnormal">n</span><span class="mord mathnormal">t</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mclose">)</span><span class="mord">∗</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=></span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span></span></span></span>(
1136 /// Creates a new suffixed integer literal with the specified value.
1137 ///
1138 /// This function will create an integer like `1u32` where the integer
1139 /// value specified is the first part of the token and the integral is
1140 /// also suffixed at the end.
1141 /// Literals created from negative numbers might not survive round-trips through
1142 /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
1143 ///
1144 /// Literals created through this method have the `Span::call_site()`
1145 /// span by default, which can be configured with the `set_span` method
1146 /// below.
1147 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1148 pub fn <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mi>a</mi><mi>m</mi><mi>e</mi><mo stretchy="false">(</mo><mi>n</mi><mo>:</mo></mrow><annotation encoding="application/x-tex">name(n: </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">nam</span><span class="mord mathnormal">e</span><span class="mopen">(</span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">:</span></span></span></span>kind) -> Literal {
1149 Literal(bridge::Literal {
1150 kind: bridge::LitKind::Integer,
1151 symbol: bridge::client::Symbol::new(&n.to_string()),
1152 suffix: Some(bridge::client::Symbol::new(stringify!($kind))),
1153 span: Span::call_site().0,
1154 })
1155 }
1156 )*)
1157}
1158
1159macro_rules! unsuffixed_int_literals {
1160 ($($name:ident => <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi><mi>i</mi><mi>n</mi><mi>d</mi><mo>:</mo><mi>i</mi><mi>d</mi><mi>e</mi><mi>n</mi><mi>t</mi><mo separator="true">,</mo><mo stretchy="false">)</mo><mo>∗</mo><mo stretchy="false">)</mo><mo>=</mo><mo>></mo><mo stretchy="false">(</mo></mrow><annotation encoding="application/x-tex">kind:ident,)*) => (</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">kin</span><span class="mord mathnormal">d</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">:</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">i</span><span class="mord mathnormal">d</span><span class="mord mathnormal">e</span><span class="mord mathnormal">n</span><span class="mord mathnormal">t</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mclose">)</span><span class="mord">∗</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=></span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span></span></span></span>(
1161 /// Creates a new unsuffixed integer literal with the specified value.
1162 ///
1163 /// This function will create an integer like `1` where the integer
1164 /// value specified is the first part of the token. No suffix is
1165 /// specified on this token, meaning that invocations like
1166 /// `Literal::i8_unsuffixed(1)` are equivalent to
1167 /// `Literal::u32_unsuffixed(1)`.
1168 /// Literals created from negative numbers might not survive rountrips through
1169 /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
1170 ///
1171 /// Literals created through this method have the `Span::call_site()`
1172 /// span by default, which can be configured with the `set_span` method
1173 /// below.
1174 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1175 pub fn <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mi>a</mi><mi>m</mi><mi>e</mi><mo stretchy="false">(</mo><mi>n</mi><mo>:</mo></mrow><annotation encoding="application/x-tex">name(n: </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">nam</span><span class="mord mathnormal">e</span><span class="mopen">(</span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">:</span></span></span></span>kind) -> Literal {
1176 Literal(bridge::Literal {
1177 kind: bridge::LitKind::Integer,
1178 symbol: bridge::client::Symbol::new(&n.to_string()),
1179 suffix: None,
1180 span: Span::call_site().0,
1181 })
1182 }
1183 )*)
1184}
1185
1186impl Literal {
1187 fn new(kind: bridge::LitKind, value: &str, suffix: Option<&str>) -> Self {
1188 Literal(bridge::Literal {
1189 kind,
1190 symbol: bridge::client::Symbol::new(value),
1191 suffix: suffix.map(bridge::client::Symbol::new),
1192 span: Span::call_site().0,
1193 })
1194 }
1195
1196 suffixed_int_literals! {
1197 u8_suffixed => u8,
1198 u16_suffixed => u16,
1199 u32_suffixed => u32,
1200 u64_suffixed => u64,
1201 u128_suffixed => u128,
1202 usize_suffixed => usize,
1203 i8_suffixed => i8,
1204 i16_suffixed => i16,
1205 i32_suffixed => i32,
1206 i64_suffixed => i64,
1207 i128_suffixed => i128,
1208 isize_suffixed => isize,
1209 }
1210
1211 unsuffixed_int_literals! {
1212 u8_unsuffixed => u8,
1213 u16_unsuffixed => u16,
1214 u32_unsuffixed => u32,
1215 u64_unsuffixed => u64,
1216 u128_unsuffixed => u128,
1217 usize_unsuffixed => usize,
1218 i8_unsuffixed => i8,
1219 i16_unsuffixed => i16,
1220 i32_unsuffixed => i32,
1221 i64_unsuffixed => i64,
1222 i128_unsuffixed => i128,
1223 isize_unsuffixed => isize,
1224 }
1225
1226 /// Creates a new unsuffixed floating-point literal.
1227 ///
1228 /// This constructor is similar to those like `Literal::i8_unsuffixed` where
1229 /// the float's value is emitted directly into the token but no suffix is
1230 /// used, so it may be inferred to be a `f64` later in the compiler.
1231 /// Literals created from negative numbers might not survive rountrips through
1232 /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
1233 ///
1234 /// # Panics
1235 ///
1236 /// This function requires that the specified float is finite, for
1237 /// example if it is infinity or NaN this function will panic.
1238 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1239 pub fn f32_unsuffixed(n: f32) -> Literal {
1240 if !n.is_finite() {
1241 panic!("Invalid float literal {n}");
1242 }
1243 let mut repr = n.to_string();
1244 if !repr.contains('.') {
1245 repr.push_str(".0");
1246 }
1247 Literal::new(bridge::LitKind::Float, &repr, None)
1248 }
1249
1250 /// Creates a new suffixed floating-point literal.
1251 ///
1252 /// This constructor will create a literal like `1.0f32` where the value
1253 /// specified is the preceding part of the token and `f32` is the suffix of
1254 /// the token. This token will always be inferred to be an `f32` in the
1255 /// compiler.
1256 /// Literals created from negative numbers might not survive rountrips through
1257 /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
1258 ///
1259 /// # Panics
1260 ///
1261 /// This function requires that the specified float is finite, for
1262 /// example if it is infinity or NaN this function will panic.
1263 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1264 pub fn f32_suffixed(n: f32) -> Literal {
1265 if !n.is_finite() {
1266 panic!("Invalid float literal {n}");
1267 }
1268 Literal::new(bridge::LitKind::Float, &n.to_string(), Some("f32"))
1269 }
1270
1271 /// Creates a new unsuffixed floating-point literal.
1272 ///
1273 /// This constructor is similar to those like `Literal::i8_unsuffixed` where
1274 /// the float's value is emitted directly into the token but no suffix is
1275 /// used, so it may be inferred to be a `f64` later in the compiler.
1276 /// Literals created from negative numbers might not survive rountrips through
1277 /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
1278 ///
1279 /// # Panics
1280 ///
1281 /// This function requires that the specified float is finite, for
1282 /// example if it is infinity or NaN this function will panic.
1283 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1284 pub fn f64_unsuffixed(n: f64) -> Literal {
1285 if !n.is_finite() {
1286 panic!("Invalid float literal {n}");
1287 }
1288 let mut repr = n.to_string();
1289 if !repr.contains('.') {
1290 repr.push_str(".0");
1291 }
1292 Literal::new(bridge::LitKind::Float, &repr, None)
1293 }
1294
1295 /// Creates a new suffixed floating-point literal.
1296 ///
1297 /// This constructor will create a literal like `1.0f64` where the value
1298 /// specified is the preceding part of the token and `f64` is the suffix of
1299 /// the token. This token will always be inferred to be an `f64` in the
1300 /// compiler.
1301 /// Literals created from negative numbers might not survive rountrips through
1302 /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
1303 ///
1304 /// # Panics
1305 ///
1306 /// This function requires that the specified float is finite, for
1307 /// example if it is infinity or NaN this function will panic.
1308 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1309 pub fn f64_suffixed(n: f64) -> Literal {
1310 if !n.is_finite() {
1311 panic!("Invalid float literal {n}");
1312 }
1313 Literal::new(bridge::LitKind::Float, &n.to_string(), Some("f64"))
1314 }
1315
1316 /// String literal.
1317 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1318 pub fn string(string: &str) -> Literal {
1319 let escape = EscapeOptions {
1320 escape_single_quote: false,
1321 escape_double_quote: true,
1322 escape_nonascii: false,
1323 };
1324 let repr = escape_bytes(string.as_bytes(), escape);
1325 Literal::new(bridge::LitKind::Str, &repr, None)
1326 }
1327
1328 /// Character literal.
1329 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1330 pub fn character(ch: char) -> Literal {
1331 let escape = EscapeOptions {
1332 escape_single_quote: true,
1333 escape_double_quote: false,
1334 escape_nonascii: false,
1335 };
1336 let repr = escape_bytes(ch.encode_utf8(&mut [0u8; 4]).as_bytes(), escape);
1337 Literal::new(bridge::LitKind::Char, &repr, None)
1338 }
1339
1340 /// Byte character literal.
1341 #[stable(feature = "proc_macro_byte_character", since = "1.79.0")]
1342 pub fn byte_character(byte: u8) -> Literal {
1343 let escape = EscapeOptions {
1344 escape_single_quote: true,
1345 escape_double_quote: false,
1346 escape_nonascii: true,
1347 };
1348 let repr = escape_bytes(&[byte], escape);
1349 Literal::new(bridge::LitKind::Byte, &repr, None)
1350 }
1351
1352 /// Byte string literal.
1353 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1354 pub fn byte_string(bytes: &[u8]) -> Literal {
1355 let escape = EscapeOptions {
1356 escape_single_quote: false,
1357 escape_double_quote: true,
1358 escape_nonascii: true,
1359 };
1360 let repr = escape_bytes(bytes, escape);
1361 Literal::new(bridge::LitKind::ByteStr, &repr, None)
1362 }
1363
1364 /// C string literal.
1365 #[stable(feature = "proc_macro_c_str_literals", since = "1.79.0")]
1366 pub fn c_string(string: &CStr) -> Literal {
1367 let escape = EscapeOptions {
1368 escape_single_quote: false,
1369 escape_double_quote: true,
1370 escape_nonascii: false,
1371 };
1372 let repr = escape_bytes(string.to_bytes(), escape);
1373 Literal::new(bridge::LitKind::CStr, &repr, None)
1374 }
1375
1376 /// Returns the span encompassing this literal.
1377 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1378 pub fn span(&self) -> Span {
1379 Span(self.0.span)
1380 }
1381
1382 /// Configures the span associated for this literal.
1383 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1384 pub fn set_span(&mut self, span: Span) {
1385 self.0.span = span.0;
1386 }
1387
1388 /// Returns a `Span` that is a subset of `self.span()` containing only the
1389 /// source bytes in range `range`. Returns `None` if the would-be trimmed
1390 /// span is outside the bounds of `self`.
1391 // FIXME(SergioBenitez): check that the byte range starts and ends at a
1392 // UTF-8 boundary of the source. otherwise, it's likely that a panic will
1393 // occur elsewhere when the source text is printed.
1394 // FIXME(SergioBenitez): there is no way for the user to know what
1395 // `self.span()` actually maps to, so this method can currently only be
1396 // called blindly. For example, `to_string()` for the character 'c' returns
1397 // "'\u{63}'"; there is no way for the user to know whether the source text
1398 // was 'c' or whether it was '\u{63}'.
1399 #[unstable(feature = "proc_macro_span", issue = "54725")]
1400 pub fn subspan<R: RangeBounds<usize>>(&self, range: R) -> Option<Span> {
1401 self.0.span.subspan(range.start_bound().cloned(), range.end_bound().cloned()).map(Span)
1402 }
1403
1404 fn with_symbol_and_suffix<R>(&self, f: impl FnOnce(&str, &str) -> R) -> R {
1405 self.0.symbol.with(|symbol| match self.0.suffix {
1406 Some(suffix) => suffix.with(|suffix| f(symbol, suffix)),
1407 None => f(symbol, ""),
1408 })
1409 }
1410
1411 /// Invokes the callback with a `&[&str]` consisting of each part of the
1412 /// literal's representation. This is done to allow the `ToString` and
1413 /// `Display` implementations to borrow references to symbol values, and
1414 /// both be optimized to reduce overhead.
1415 fn with_stringify_parts<R>(&self, f: impl FnOnce(&[&str]) -> R) -> R {
1416 /// Returns a string containing exactly `num` '#' characters.
1417 /// Uses a 256-character source string literal which is always safe to
1418 /// index with a `u8` index.
1419 fn get_hashes_str(num: u8) -> &'static str {
1420 const HASHES: &str = "\
1421 ################################################################\
1422 ################################################################\
1423 ################################################################\
1424 ################################################################\
1425 ";
1426 const _: () = assert!(HASHES.len() == 256);
1427 &HASHES[..num as usize]
1428 }
1429
1430 self.with_symbol_and_suffix(|symbol, suffix| match self.0.kind {
1431 bridge::LitKind::Byte => f(&["b'", symbol, "'", suffix]),
1432 bridge::LitKind::Char => f(&["'", symbol, "'", suffix]),
1433 bridge::LitKind::Str => f(&["\"", symbol, "\"", suffix]),
1434 bridge::LitKind::StrRaw(n) => {
1435 let hashes = get_hashes_str(n);
1436 f(&["r", hashes, "\"", symbol, "\"", hashes, suffix])
1437 }
1438 bridge::LitKind::ByteStr => f(&["b\"", symbol, "\"", suffix]),
1439 bridge::LitKind::ByteStrRaw(n) => {
1440 let hashes = get_hashes_str(n);
1441 f(&["br", hashes, "\"", symbol, "\"", hashes, suffix])
1442 }
1443 bridge::LitKind::CStr => f(&["c\"", symbol, "\"", suffix]),
1444 bridge::LitKind::CStrRaw(n) => {
1445 let hashes = get_hashes_str(n);
1446 f(&["cr", hashes, "\"", symbol, "\"", hashes, suffix])
1447 }
1448
1449 bridge::LitKind::Integer | bridge::LitKind::Float | bridge::LitKind::ErrWithGuar => {
1450 f(&[symbol, suffix])
1451 }
1452 })
1453 }
1454}
1455
1456/// Parse a single literal from its stringified representation.
1457///
1458/// In order to parse successfully, the input string must not contain anything
1459/// but the literal token. Specifically, it must not contain whitespace or
1460/// comments in addition to the literal.
1461///
1462/// The resulting literal token will have a `Span::call_site()` span.
1463///
1464/// NOTE: some errors may cause panics instead of returning `LexError`. We
1465/// reserve the right to change these errors into `LexError`s later.
1466#[stable(feature = "proc_macro_literal_parse", since = "1.54.0")]
1467impl FromStr for Literal {
1468 type Err = LexError;
1469
1470 fn from_str(src: &str) -> Result<Self, LexError> {
1471 match bridge::client::FreeFunctions::literal_from_str(src) {
1472 Ok(literal) => Ok(Literal(literal)),
1473 Err(()) => Err(LexError),
1474 }
1475 }
1476}
1477
1478/// Prints the literal as a string that should be losslessly convertible
1479/// back into the same literal (except for possible rounding for floating point literals).
1480#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1481impl fmt::Display for Literal {
1482 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1483 self.with_stringify_parts(|parts| {
1484 for part in parts {
1485 fmt::Display::fmt(part, f)?;
1486 }
1487 Ok(())
1488 })
1489 }
1490}
1491
1492#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1493impl fmt::Debug for Literal {
1494 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1495 f.debug_struct("Literal")
1496 // format the kind on one line even in {:#?} mode
1497 .field("kind", &format_args!("{:?}", self.0.kind))
1498 .field("symbol", &self.0.symbol)
1499 // format `Some("...")` on one line even in {:#?} mode
1500 .field("suffix", &format_args!("{:?}", self.0.suffix))
1501 .field("span", &self.0.span)
1502 .finish()
1503 }
1504}
1505
1506/// Tracked access to environment variables.
1507#[unstable(feature = "proc_macro_tracked_env", issue = "99515")]
1508pub mod tracked_env {
1509 use std::env::{self, VarError};
1510 use std::ffi::OsStr;
1511
1512 /// Retrieve an environment variable and add it to build dependency info.
1513 /// The build system executing the compiler will know that the variable was accessed during
1514 /// compilation, and will be able to rerun the build when the value of that variable changes.
1515 /// Besides the dependency tracking this function should be equivalent to `env::var` from the
1516 /// standard library, except that the argument must be UTF-8.
1517 #[unstable(feature = "proc_macro_tracked_env", issue = "99515")]
1518 pub fn var<K: AsRef<OsStr> + AsRef<str>>(key: K) -> Result<String, VarError> {
1519 let key: &str = key.as_ref();
1520 let value = crate:🌉:client::FreeFunctions::injected_env_var(key)
1521 .map_or_else(|| env::var(key), Ok);
1522 crate:🌉:client::FreeFunctions::track_env_var(key, value.as_deref().ok());
1523 value
1524 }
1525}
1526
1527/// Tracked access to additional files.
1528#[unstable(feature = "track_path", issue = "99515")]
1529pub mod tracked_path {
1530
1531 /// Track a file explicitly.
1532 ///
1533 /// Commonly used for tracking asset preprocessing.
1534 #[unstable(feature = "track_path", issue = "99515")]
1535 pub fn path<P: AsRef<str>>(path: P) {
1536 let path: &str = path.as_ref();
1537 crate:🌉:client::FreeFunctions::track_path(path);
1538 }
1539}