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

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy