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
1112#![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(negative_impls)]
26#![feature(panic_can_unwind)]
27#![feature(restricted_std)]
28#![feature(rustc_attrs)]
29#![feature(extend_one)]
30#![recursion_limit = "256"]
31#![allow(internal_features)]
32#![deny(ffi_unwind_calls)]
33#![allow(rustc::internal)] // Can't use FxHashMap when compiled as part of the standard library
34#![warn(rustdoc::unescaped_backticks)]
35#![warn(unreachable_pub)]
36#![deny(unsafe_op_in_unsafe_fn)]
3738#[unstable(feature = "proc_macro_internals", issue = "27812")]
39#[doc(hidden)]
40pub mod bridge;
4142mod diagnostic;
43mod escape;
44mod to_tokens;
4546use core::ops::BitOr;
47use std::ffi::CStr;
48use std::ops::{Range, RangeBounds};
49use std::path::PathBuf;
50use std::str::FromStr;
51use std::{error, fmt};
5253#[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, unescape_byte_str, unescape_c_str, unescape_str};
58#[unstable(feature = "proc_macro_totokens", issue = "130977")]
59pub use to_tokens::ToTokens;
6061use crate::escape::{EscapeOptions, escape_bytes};
6263/// Errors returned when trying to retrieve a literal unescaped value.
64#[unstable(feature = "proc_macro_value", issue = "136652")]
65#[derive(#[automatically_derived]
#[unstable(feature = "proc_macro_value", issue = "136652")]
impl ::core::fmt::Debug for ConversionErrorKind {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
ConversionErrorKind::FailedToUnescape(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"FailedToUnescape", &__self_0),
ConversionErrorKind::InvalidLiteralKind =>
::core::fmt::Formatter::write_str(f, "InvalidLiteralKind"),
}
}
}Debug, #[automatically_derived]
#[unstable(feature = "proc_macro_value", issue = "136652")]
impl ::core::cmp::PartialEq for ConversionErrorKind {
#[inline]
fn eq(&self, other: &ConversionErrorKind) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(ConversionErrorKind::FailedToUnescape(__self_0),
ConversionErrorKind::FailedToUnescape(__arg1_0)) =>
__self_0 == __arg1_0,
_ => true,
}
}
}PartialEq, #[automatically_derived]
#[unstable(feature = "proc_macro_value", issue = "136652")]
impl ::core::cmp::Eq for ConversionErrorKind {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_receiver_is_total_eq(&self) -> () {
let _: ::core::cmp::AssertParamIsEq<EscapeError>;
}
}Eq)]
66pub enum ConversionErrorKind {
67/// The literal failed to be escaped, take a look at [`EscapeError`] for more information.
68FailedToUnescape(EscapeError),
69/// Trying to convert a literal with the wrong type.
70InvalidLiteralKind,
71}
7273/// 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}
9091/// 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#[cfg_attr(feature = "rustc-dep-of-std", rustc_diagnostic_item = "TokenStream")]
99#[stable(feature = "proc_macro_lib", since = "1.15.0")]
100#[derive(#[automatically_derived]
#[stable(feature = "proc_macro_lib", since = "1.15.0")]
impl ::core::clone::Clone for TokenStream {
#[inline]
fn clone(&self) -> TokenStream {
TokenStream(::core::clone::Clone::clone(&self.0))
}
}Clone)]
101pub struct TokenStream(Option<bridge::client::TokenStream>);
102103#[stable(feature = "proc_macro_lib", since = "1.15.0")]
104impl !Sendfor TokenStream {}
105#[stable(feature = "proc_macro_lib", since = "1.15.0")]
106impl !Syncfor TokenStream {}
107108/// Error returned from `TokenStream::from_str`.
109#[stable(feature = "proc_macro_lib", since = "1.15.0")]
110#[non_exhaustive]
111#[derive(#[automatically_derived]
#[stable(feature = "proc_macro_lib", since = "1.15.0")]
impl ::core::fmt::Debug for LexError {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f, "LexError")
}
}Debug)]
112pub struct LexError;
113114#[stable(feature = "proc_macro_lexerror_impls", since = "1.44.0")]
115impl fmt::Displayfor LexError {
116fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
117f.write_str("cannot parse string into token stream")
118 }
119}
120121#[stable(feature = "proc_macro_lexerror_impls", since = "1.44.0")]
122impl error::Errorfor LexError {}
123124#[stable(feature = "proc_macro_lib", since = "1.15.0")]
125impl !Sendfor LexError {}
126#[stable(feature = "proc_macro_lib", since = "1.15.0")]
127impl !Syncfor LexError {}
128129/// Error returned from `TokenStream::expand_expr`.
130#[unstable(feature = "proc_macro_expand", issue = "90765")]
131#[non_exhaustive]
132#[derive(#[automatically_derived]
#[unstable(feature = "proc_macro_expand", issue = "90765")]
impl ::core::fmt::Debug for ExpandError {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f, "ExpandError")
}
}Debug)]
133pub struct ExpandError;
134135#[unstable(feature = "proc_macro_expand", issue = "90765")]
136impl fmt::Displayfor ExpandError {
137fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
138f.write_str("macro expansion failed")
139 }
140}
141142#[unstable(feature = "proc_macro_expand", issue = "90765")]
143impl error::Errorfor ExpandError {}
144145#[unstable(feature = "proc_macro_expand", issue = "90765")]
146impl !Sendfor ExpandError {}
147148#[unstable(feature = "proc_macro_expand", issue = "90765")]
149impl !Syncfor ExpandError {}
150151impl TokenStream {
152/// Returns an empty `TokenStream` containing no token trees.
153#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
154pub fn new() -> TokenStream {
155TokenStream(None)
156 }
157158/// Checks if this `TokenStream` is empty.
159#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
160pub fn is_empty(&self) -> bool {
161self.0.as_ref().map(|h| h.is_empty()).unwrap_or(true)
162 }
163164/// 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")]
175pub fn expand_expr(&self) -> Result<TokenStream, ExpandError> {
176let stream = self.0.as_ref().ok_or(ExpandError)?;
177match bridge::client::TokenStream::expand_expr(stream) {
178Ok(stream) => Ok(TokenStream(Some(stream))),
179Err(_) => Err(ExpandError),
180 }
181 }
182}
183184/// 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 FromStrfor TokenStream {
193type Err = LexError;
194195fn from_str(src: &str) -> Result<TokenStream, LexError> {
196Ok(TokenStream(Some(bridge::client::TokenStream::from_str(src))))
197 }
198}
199200/// 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::Displayfor TokenStream {
213fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
214match &self.0 {
215Some(ts) => f.write_fmt(format_args!("{0}", ts.to_string()))write!(f, "{}", ts.to_string()),
216None => Ok(()),
217 }
218 }
219}
220221/// Prints tokens in a form convenient for debugging.
222#[stable(feature = "proc_macro_lib", since = "1.15.0")]
223impl fmt::Debugfor TokenStream {
224fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
225f.write_str("TokenStream ")?;
226f.debug_list().entries(self.clone()).finish()
227 }
228}
229230#[stable(feature = "proc_macro_token_stream_default", since = "1.45.0")]
231impl Defaultfor TokenStream {
232fn default() -> Self {
233TokenStream::new()
234 }
235}
236237#[unstable(feature = "proc_macro_quote", issue = "54722")]
238pub use quote::{HasIterator, RepInterp, ThereIsNoIteratorInRepetition, ext, quote, quote_span};
239240fn tree_to_bridge_tree(
241 tree: TokenTree,
242) -> bridge::TokenTree<bridge::client::TokenStream, bridge::client::Span, bridge::client::Symbol> {
243match tree {
244 TokenTree::Group(tt) => bridge::TokenTree::Group(tt.0),
245 TokenTree::Punct(tt) => bridge::TokenTree::Punct(tt.0),
246 TokenTree::Ident(tt) => bridge::TokenTree::Ident(tt.0),
247 TokenTree::Literal(tt) => bridge::TokenTree::Literal(tt.0),
248 }
249}
250251/// Creates a token stream containing a single token tree.
252#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
253impl From<TokenTree> for TokenStream {
254fn from(tree: TokenTree) -> TokenStream {
255TokenStream(Some(bridge::client::TokenStream::from_token_tree(tree_to_bridge_tree(tree))))
256 }
257}
258259/// Non-generic helper for implementing `FromIterator<TokenTree>` and
260/// `Extend<TokenTree>` with less monomorphization in calling crates.
261struct ConcatTreesHelper {
262 trees: Vec<
263 bridge::TokenTree<
264 bridge::client::TokenStream,
265 bridge::client::Span,
266 bridge::client::Symbol,
267 >,
268 >,
269}
270271impl ConcatTreesHelper {
272fn new(capacity: usize) -> Self {
273ConcatTreesHelper { trees: Vec::with_capacity(capacity) }
274 }
275276fn push(&mut self, tree: TokenTree) {
277self.trees.push(tree_to_bridge_tree(tree));
278 }
279280fn build(self) -> TokenStream {
281if self.trees.is_empty() {
282TokenStream(None)
283 } else {
284TokenStream(Some(bridge::client::TokenStream::concat_trees(None, self.trees)))
285 }
286 }
287288fn append_to(self, stream: &mut TokenStream) {
289if self.trees.is_empty() {
290return;
291 }
292stream.0 = Some(bridge::client::TokenStream::concat_trees(stream.0.take(), self.trees))
293 }
294}
295296/// Non-generic helper for implementing `FromIterator<TokenStream>` and
297/// `Extend<TokenStream>` with less monomorphization in calling crates.
298struct ConcatStreamsHelper {
299 streams: Vec<bridge::client::TokenStream>,
300}
301302impl ConcatStreamsHelper {
303fn new(capacity: usize) -> Self {
304ConcatStreamsHelper { streams: Vec::with_capacity(capacity) }
305 }
306307fn push(&mut self, stream: TokenStream) {
308if let Some(stream) = stream.0 {
309self.streams.push(stream);
310 }
311 }
312313fn build(mut self) -> TokenStream {
314if self.streams.len() <= 1 {
315TokenStream(self.streams.pop())
316 } else {
317TokenStream(Some(bridge::client::TokenStream::concat_streams(None, self.streams)))
318 }
319 }
320321fn append_to(mut self, stream: &mut TokenStream) {
322if self.streams.is_empty() {
323return;
324 }
325let base = stream.0.take();
326if base.is_none() && self.streams.len() == 1 {
327stream.0 = self.streams.pop();
328 } else {
329stream.0 = Some(bridge::client::TokenStream::concat_streams(base, self.streams));
330 }
331 }
332}
333334/// Collects a number of token trees into a single stream.
335#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
336impl FromIterator<TokenTree> for TokenStream {
337fn from_iter<I: IntoIterator<Item = TokenTree>>(trees: I) -> Self {
338let iter = trees.into_iter();
339let mut builder = ConcatTreesHelper::new(iter.size_hint().0);
340iter.for_each(|tree| builder.push(tree));
341builder.build()
342 }
343}
344345/// A "flattening" operation on token streams, collects token trees
346/// from multiple token streams into a single stream.
347#[stable(feature = "proc_macro_lib", since = "1.15.0")]
348impl FromIterator<TokenStream> for TokenStream {
349fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self {
350let iter = streams.into_iter();
351let mut builder = ConcatStreamsHelper::new(iter.size_hint().0);
352iter.for_each(|stream| builder.push(stream));
353builder.build()
354 }
355}
356357#[stable(feature = "token_stream_extend", since = "1.30.0")]
358impl Extend<TokenTree> for TokenStream {
359fn extend<I: IntoIterator<Item = TokenTree>>(&mut self, trees: I) {
360let iter = trees.into_iter();
361let mut builder = ConcatTreesHelper::new(iter.size_hint().0);
362iter.for_each(|tree| builder.push(tree));
363builder.append_to(self);
364 }
365}
366367#[stable(feature = "token_stream_extend", since = "1.30.0")]
368impl Extend<TokenStream> for TokenStream {
369fn extend<I: IntoIterator<Item = TokenStream>>(&mut self, streams: I) {
370let iter = streams.into_iter();
371let mut builder = ConcatStreamsHelper::new(iter.size_hint().0);
372iter.for_each(|stream| builder.push(stream));
373builder.append_to(self);
374 }
375}
376377macro_rules!extend_items {
378 ($($item:ident)*) => {
379 $(
380#[stable(feature = "token_stream_extend_tt_items", since = "1.92.0")]
381impl Extend<$item> for TokenStream {
382fn extend<T: IntoIterator<Item = $item>>(&mut self, iter: T) {
383self.extend(iter.into_iter().map(TokenTree::$item));
384 }
385 }
386 )*
387 };
388}
389390#[stable(feature = "token_stream_extend_tt_items", since = "1.92.0")]
impl Extend<Ident> for TokenStream {
fn extend<T: IntoIterator<Item = Ident>>(&mut self, iter: T) {
self.extend(iter.into_iter().map(TokenTree::Ident));
}
}extend_items!(Group Literal Punct Ident);
391392/// Public implementation details for the `TokenStream` type, such as iterators.
393#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
394pub mod token_stream {
395use crate::{Group, Ident, Literal, Punct, TokenStream, TokenTree, bridge};
396397/// An iterator over `TokenStream`'s `TokenTree`s.
398 /// The iteration is "shallow", e.g., the iterator doesn't recurse into delimited groups,
399 /// and returns whole groups as token trees.
400#[derive(#[automatically_derived]
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl ::core::clone::Clone for IntoIter {
#[inline]
fn clone(&self) -> IntoIter {
IntoIter(::core::clone::Clone::clone(&self.0))
}
}Clone)]
401 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
402pub struct IntoIter(
403 std::vec::IntoIter<
404 bridge::TokenTree<
405 bridge::client::TokenStream,
406 bridge::client::Span,
407 bridge::client::Symbol,
408 >,
409 >,
410 );
411412#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
413impl Iteratorfor IntoIter {
414type Item = TokenTree;
415416fn next(&mut self) -> Option<TokenTree> {
417self.0.next().map(|tree| match tree {
418 bridge::TokenTree::Group(tt) => TokenTree::Group(Group(tt)),
419 bridge::TokenTree::Punct(tt) => TokenTree::Punct(Punct(tt)),
420 bridge::TokenTree::Ident(tt) => TokenTree::Ident(Ident(tt)),
421 bridge::TokenTree::Literal(tt) => TokenTree::Literal(Literal(tt)),
422 })
423 }
424425fn size_hint(&self) -> (usize, Option<usize>) {
426self.0.size_hint()
427 }
428429fn count(self) -> usize {
430self.0.count()
431 }
432 }
433434#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
435impl IntoIteratorfor TokenStream {
436type Item = TokenTree;
437type IntoIter = IntoIter;
438439fn into_iter(self) -> IntoIter {
440IntoIter(self.0.map(|v| v.into_trees()).unwrap_or_default().into_iter())
441 }
442 }
443}
444445/// `quote!(..)` accepts arbitrary tokens and expands into a `TokenStream` describing the input.
446/// For example, `quote!(a + b)` will produce an expression, that, when evaluated, constructs
447/// the `TokenStream` `[Ident("a"), Punct('+', Alone), Ident("b")]`.
448///
449/// Unquoting is done with `$`, and works by taking the single next ident as the unquoted term.
450/// To quote `$` itself, use `$$`.
451#[unstable(feature = "proc_macro_quote", issue = "54722")]
452#[allow_internal_unstable(proc_macro_def_site, proc_macro_internals, proc_macro_totokens)]
453#[rustc_builtin_macro]
454pub macro quote($($t:tt)*) {
455/* compiler built-in */
456}
457458#[unstable(feature = "proc_macro_internals", issue = "27812")]
459#[doc(hidden)]
460mod quote;
461462/// A region of source code, along with macro expansion information.
463#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
464#[derive(#[automatically_derived]
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl ::core::marker::Copy for Span { }Copy, #[automatically_derived]
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl ::core::clone::Clone for Span {
#[inline]
fn clone(&self) -> Span {
let _: ::core::clone::AssertParamIsClone<bridge::client::Span>;
*self
}
}Clone)]
465pub struct Span(bridge::client::Span);
466467#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
468impl !Sendfor Span {}
469#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
470impl !Syncfor Span {}
471472macro_rules!diagnostic_method {
473 ($name:ident, $level:expr) => {
474/// Creates a new `Diagnostic` with the given `message` at the span
475 /// `self`.
476#[unstable(feature = "proc_macro_diagnostic", issue = "54140")]
477pub fn $name<T: Into<String>>(self, message: T) -> Diagnostic {
478 Diagnostic::spanned(self, $level, message)
479 }
480 };
481}
482483impl Span {
484/// A span that resolves at the macro definition site.
485#[unstable(feature = "proc_macro_def_site", issue = "54724")]
486pub fn def_site() -> Span {
487Span(bridge::client::Span::def_site())
488 }
489490/// The span of the invocation of the current procedural macro.
491 /// Identifiers created with this span will be resolved as if they were written
492 /// directly at the macro call location (call-site hygiene) and other code
493 /// at the macro call site will be able to refer to them as well.
494#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
495pub fn call_site() -> Span {
496Span(bridge::client::Span::call_site())
497 }
498499/// A span that represents `macro_rules` hygiene, and sometimes resolves at the macro
500 /// definition site (local variables, labels, `$crate`) and sometimes at the macro
501 /// call site (everything else).
502 /// The span location is taken from the call-site.
503#[stable(feature = "proc_macro_mixed_site", since = "1.45.0")]
504pub fn mixed_site() -> Span {
505Span(bridge::client::Span::mixed_site())
506 }
507508/// The `Span` for the tokens in the previous macro expansion from which
509 /// `self` was generated from, if any.
510#[unstable(feature = "proc_macro_span", issue = "54725")]
511pub fn parent(&self) -> Option<Span> {
512self.0.parent().map(Span)
513 }
514515/// The span for the origin source code that `self` was generated from. If
516 /// this `Span` wasn't generated from other macro expansions then the return
517 /// value is the same as `*self`.
518#[unstable(feature = "proc_macro_span", issue = "54725")]
519pub fn source(&self) -> Span {
520Span(self.0.source())
521 }
522523/// Returns the span's byte position range in the source file.
524#[unstable(feature = "proc_macro_span", issue = "54725")]
525pub fn byte_range(&self) -> Range<usize> {
526self.0.byte_range()
527 }
528529/// Creates an empty span pointing to directly before this span.
530#[stable(feature = "proc_macro_span_location", since = "1.88.0")]
531pub fn start(&self) -> Span {
532Span(self.0.start())
533 }
534535/// Creates an empty span pointing to directly after this span.
536#[stable(feature = "proc_macro_span_location", since = "1.88.0")]
537pub fn end(&self) -> Span {
538Span(self.0.end())
539 }
540541/// The one-indexed line of the source file where the span starts.
542 ///
543 /// To obtain the line of the span's end, use `span.end().line()`.
544#[stable(feature = "proc_macro_span_location", since = "1.88.0")]
545pub fn line(&self) -> usize {
546self.0.line()
547 }
548549/// The one-indexed column of the source file where the span starts.
550 ///
551 /// To obtain the column of the span's end, use `span.end().column()`.
552#[stable(feature = "proc_macro_span_location", since = "1.88.0")]
553pub fn column(&self) -> usize {
554self.0.column()
555 }
556557/// The path to the source file in which this span occurs, for display purposes.
558 ///
559 /// This might not correspond to a valid file system path.
560 /// It might be remapped (e.g. `"/src/lib.rs"`) or an artificial path (e.g. `"<command line>"`).
561#[stable(feature = "proc_macro_span_file", since = "1.88.0")]
562pub fn file(&self) -> String {
563self.0.file()
564 }
565566/// The path to the source file in which this span occurs on the local file system.
567 ///
568 /// This is the actual path on disk. It is unaffected by path remapping.
569 ///
570 /// This path should not be embedded in the output of the macro; prefer `file()` instead.
571#[stable(feature = "proc_macro_span_file", since = "1.88.0")]
572pub fn local_file(&self) -> Option<PathBuf> {
573self.0.local_file().map(PathBuf::from)
574 }
575576/// Creates a new span encompassing `self` and `other`.
577 ///
578 /// Returns `None` if `self` and `other` are from different files.
579#[unstable(feature = "proc_macro_span", issue = "54725")]
580pub fn join(&self, other: Span) -> Option<Span> {
581self.0.join(other.0).map(Span)
582 }
583584/// Creates a new span with the same line/column information as `self` but
585 /// that resolves symbols as though it were at `other`.
586#[stable(feature = "proc_macro_span_resolved_at", since = "1.45.0")]
587pub fn resolved_at(&self, other: Span) -> Span {
588Span(self.0.resolved_at(other.0))
589 }
590591/// Creates a new span with the same name resolution behavior as `self` but
592 /// with the line/column information of `other`.
593#[stable(feature = "proc_macro_span_located_at", since = "1.45.0")]
594pub fn located_at(&self, other: Span) -> Span {
595other.resolved_at(*self)
596 }
597598/// Compares two spans to see if they're equal.
599#[unstable(feature = "proc_macro_span", issue = "54725")]
600pub fn eq(&self, other: &Span) -> bool {
601self.0 == other.0
602}
603604/// Returns the source text behind a span. This preserves the original source
605 /// code, including spaces and comments. It only returns a result if the span
606 /// corresponds to real source code.
607 ///
608 /// Note: The observable result of a macro should only rely on the tokens and
609 /// not on this source text. The result of this function is a best effort to
610 /// be used for diagnostics only.
611#[stable(feature = "proc_macro_source_text", since = "1.66.0")]
612pub fn source_text(&self) -> Option<String> {
613self.0.source_text()
614 }
615616// Used by the implementation of `Span::quote`
617#[doc(hidden)]
618 #[unstable(feature = "proc_macro_internals", issue = "27812")]
619pub fn save_span(&self) -> usize {
620self.0.save_span()
621 }
622623// Used by the implementation of `Span::quote`
624#[doc(hidden)]
625 #[unstable(feature = "proc_macro_internals", issue = "27812")]
626pub fn recover_proc_macro_span(id: usize) -> Span {
627Span(bridge::client::Span::recover_proc_macro_span(id))
628 }
629630String
Self
self
T
message
Diagnostic
Diagnostic::spanned(self, Level::Error, message);diagnostic_method!(error, Level::Error);
631String
Self
self
T
message
Diagnostic
Diagnostic::spanned(self, Level::Warning, message);diagnostic_method!(warning, Level::Warning);
632String
Self
self
T
message
Diagnostic
Diagnostic::spanned(self, Level::Note, message);diagnostic_method!(note, Level::Note);
633String
Self
self
T
message
Diagnostic
Diagnostic::spanned(self, Level::Help, message);diagnostic_method!(help, Level::Help);
634}
635636/// Prints a span in a form convenient for debugging.
637#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
638impl fmt::Debugfor Span {
639fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
640self.0.fmt(f)
641 }
642}
643644/// A single token or a delimited sequence of token trees (e.g., `[1, (), ..]`).
645#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
646#[derive(#[automatically_derived]
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl ::core::clone::Clone for TokenTree {
#[inline]
fn clone(&self) -> TokenTree {
match self {
TokenTree::Group(__self_0) =>
TokenTree::Group(::core::clone::Clone::clone(__self_0)),
TokenTree::Ident(__self_0) =>
TokenTree::Ident(::core::clone::Clone::clone(__self_0)),
TokenTree::Punct(__self_0) =>
TokenTree::Punct(::core::clone::Clone::clone(__self_0)),
TokenTree::Literal(__self_0) =>
TokenTree::Literal(::core::clone::Clone::clone(__self_0)),
}
}
}Clone)]
647pub enum TokenTree {
648/// A token stream surrounded by bracket delimiters.
649#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
650Group(#[stable(feature = "proc_macro_lib2", since = "1.29.0")] Group),
651/// An identifier.
652#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
653Ident(#[stable(feature = "proc_macro_lib2", since = "1.29.0")] Ident),
654/// A single punctuation character (`+`, `,`, `$`, etc.).
655#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
656Punct(#[stable(feature = "proc_macro_lib2", since = "1.29.0")] Punct),
657/// A literal character (`'a'`), string (`"hello"`), number (`2.3`), etc.
658#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
659Literal(#[stable(feature = "proc_macro_lib2", since = "1.29.0")] Literal),
660}
661662#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
663impl !Sendfor TokenTree {}
664#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
665impl !Syncfor TokenTree {}
666667impl TokenTree {
668/// Returns the span of this tree, delegating to the `span` method of
669 /// the contained token or a delimited stream.
670#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
671pub fn span(&self) -> Span {
672match *self {
673 TokenTree::Group(ref t) => t.span(),
674 TokenTree::Ident(ref t) => t.span(),
675 TokenTree::Punct(ref t) => t.span(),
676 TokenTree::Literal(ref t) => t.span(),
677 }
678 }
679680/// Configures the span for *only this token*.
681 ///
682 /// Note that if this token is a `Group` then this method will not configure
683 /// the span of each of the internal tokens, this will simply delegate to
684 /// the `set_span` method of each variant.
685#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
686pub fn set_span(&mut self, span: Span) {
687match *self {
688 TokenTree::Group(ref mut t) => t.set_span(span),
689 TokenTree::Ident(ref mut t) => t.set_span(span),
690 TokenTree::Punct(ref mut t) => t.set_span(span),
691 TokenTree::Literal(ref mut t) => t.set_span(span),
692 }
693 }
694}
695696/// Prints token tree in a form convenient for debugging.
697#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
698impl fmt::Debugfor TokenTree {
699fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
700// Each of these has the name in the struct type in the derived debug,
701 // so don't bother with an extra layer of indirection
702match *self {
703 TokenTree::Group(ref tt) => tt.fmt(f),
704 TokenTree::Ident(ref tt) => tt.fmt(f),
705 TokenTree::Punct(ref tt) => tt.fmt(f),
706 TokenTree::Literal(ref tt) => tt.fmt(f),
707 }
708 }
709}
710711#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
712impl From<Group> for TokenTree {
713fn from(g: Group) -> TokenTree {
714 TokenTree::Group(g)
715 }
716}
717718#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
719impl From<Ident> for TokenTree {
720fn from(g: Ident) -> TokenTree {
721 TokenTree::Ident(g)
722 }
723}
724725#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
726impl From<Punct> for TokenTree {
727fn from(g: Punct) -> TokenTree {
728 TokenTree::Punct(g)
729 }
730}
731732#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
733impl From<Literal> for TokenTree {
734fn from(g: Literal) -> TokenTree {
735 TokenTree::Literal(g)
736 }
737}
738739/// Prints the token tree as a string that is supposed to be losslessly convertible back
740/// into the same token tree (modulo spans), except for possibly `TokenTree::Group`s
741/// with `Delimiter::None` delimiters and negative numeric literals.
742///
743/// Note: the exact form of the output is subject to change, e.g. there might
744/// be changes in the whitespace used between tokens. Therefore, you should
745/// *not* do any kind of simple substring matching on the output string (as
746/// produced by `to_string`) to implement a proc macro, because that matching
747/// might stop working if such changes happen. Instead, you should work at the
748/// `TokenTree` level, e.g. matching against `TokenTree::Ident`,
749/// `TokenTree::Punct`, or `TokenTree::Literal`.
750#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
751impl fmt::Displayfor TokenTree {
752fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
753match self {
754 TokenTree::Group(t) => f.write_fmt(format_args!("{0}", t))write!(f, "{t}"),
755 TokenTree::Ident(t) => f.write_fmt(format_args!("{0}", t))write!(f, "{t}"),
756 TokenTree::Punct(t) => f.write_fmt(format_args!("{0}", t))write!(f, "{t}"),
757 TokenTree::Literal(t) => f.write_fmt(format_args!("{0}", t))write!(f, "{t}"),
758 }
759 }
760}
761762/// A delimited token stream.
763///
764/// A `Group` internally contains a `TokenStream` which is surrounded by `Delimiter`s.
765#[derive(#[automatically_derived]
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl ::core::clone::Clone for Group {
#[inline]
fn clone(&self) -> Group { Group(::core::clone::Clone::clone(&self.0)) }
}Clone)]
766#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
767pub struct Group(bridge::Group<bridge::client::TokenStream, bridge::client::Span>);
768769#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
770impl !Sendfor Group {}
771#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
772impl !Syncfor Group {}
773774/// Describes how a sequence of token trees is delimited.
775#[derive(#[automatically_derived]
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl ::core::marker::Copy for Delimiter { }Copy, #[automatically_derived]
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl ::core::clone::Clone for Delimiter {
#[inline]
fn clone(&self) -> Delimiter { *self }
}Clone, #[automatically_derived]
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl ::core::fmt::Debug for Delimiter {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
Delimiter::Parenthesis => "Parenthesis",
Delimiter::Brace => "Brace",
Delimiter::Bracket => "Bracket",
Delimiter::None => "None",
})
}
}Debug, #[automatically_derived]
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl ::core::cmp::PartialEq for Delimiter {
#[inline]
fn eq(&self, other: &Delimiter) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl ::core::cmp::Eq for Delimiter {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_receiver_is_total_eq(&self) -> () {}
}Eq)]
776#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
777pub enum Delimiter {
778/// `( ... )`
779#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
780Parenthesis,
781/// `{ ... }`
782#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
783Brace,
784/// `[ ... ]`
785#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
786Bracket,
787/// `∅ ... ∅`
788 /// An invisible delimiter, that may, for example, appear around tokens coming from a
789 /// "macro variable" `$var`. It is important to preserve operator priorities in cases like
790 /// `$var * 3` where `$var` is `1 + 2`.
791 /// Invisible delimiters might not survive roundtrip of a token stream through a string.
792 ///
793 /// <div class="warning">
794 ///
795 /// Note: rustc currently can ignore the grouping of tokens delimited by `None` in the output
796 /// of a proc_macro. Only `None`-delimited groups created by a macro_rules macro in the input
797 /// of a proc_macro macro are preserved, and only in very specific circumstances.
798 /// Any `None`-delimited groups (re)created by a proc_macro will therefore not preserve
799 /// operator priorities as indicated above. The other `Delimiter` variants should be used
800 /// instead in this context. This is a rustc bug. For details, see
801 /// [rust-lang/rust#67062](https://github.com/rust-lang/rust/issues/67062).
802 ///
803 /// </div>
804#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
805None,
806}
807808impl Group {
809/// Creates a new `Group` with the given delimiter and token stream.
810 ///
811 /// This constructor will set the span for this group to
812 /// `Span::call_site()`. To change the span you can use the `set_span`
813 /// method below.
814#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
815pub fn new(delimiter: Delimiter, stream: TokenStream) -> Group {
816Group(bridge::Group {
817delimiter,
818 stream: stream.0,
819 span: bridge::DelimSpan::from_single(Span::call_site().0),
820 })
821 }
822823/// Returns the delimiter of this `Group`
824#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
825pub fn delimiter(&self) -> Delimiter {
826self.0.delimiter
827 }
828829/// Returns the `TokenStream` of tokens that are delimited in this `Group`.
830 ///
831 /// Note that the returned token stream does not include the delimiter
832 /// returned above.
833#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
834pub fn stream(&self) -> TokenStream {
835TokenStream(self.0.stream.clone())
836 }
837838/// Returns the span for the delimiters of this token stream, spanning the
839 /// entire `Group`.
840 ///
841 /// ```text
842 /// pub fn span(&self) -> Span {
843 /// ^^^^^^^
844 /// ```
845#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
846pub fn span(&self) -> Span {
847Span(self.0.span.entire)
848 }
849850/// Returns the span pointing to the opening delimiter of this group.
851 ///
852 /// ```text
853 /// pub fn span_open(&self) -> Span {
854 /// ^
855 /// ```
856#[stable(feature = "proc_macro_group_span", since = "1.55.0")]
857pub fn span_open(&self) -> Span {
858Span(self.0.span.open)
859 }
860861/// Returns the span pointing to the closing delimiter of this group.
862 ///
863 /// ```text
864 /// pub fn span_close(&self) -> Span {
865 /// ^
866 /// ```
867#[stable(feature = "proc_macro_group_span", since = "1.55.0")]
868pub fn span_close(&self) -> Span {
869Span(self.0.span.close)
870 }
871872/// Configures the span for this `Group`'s delimiters, but not its internal
873 /// tokens.
874 ///
875 /// This method will **not** set the span of all the internal tokens spanned
876 /// by this group, but rather it will only set the span of the delimiter
877 /// tokens at the level of the `Group`.
878#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
879pub fn set_span(&mut self, span: Span) {
880self.0.span = bridge::DelimSpan::from_single(span.0);
881 }
882}
883884/// Prints the group as a string that should be losslessly convertible back
885/// into the same group (modulo spans), except for possibly `TokenTree::Group`s
886/// with `Delimiter::None` delimiters.
887#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
888impl fmt::Displayfor Group {
889fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
890f.write_fmt(format_args!("{0}",
TokenStream::from(TokenTree::from(self.clone()))))write!(f, "{}", TokenStream::from(TokenTree::from(self.clone())))891 }
892}
893894#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
895impl fmt::Debugfor Group {
896fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
897f.debug_struct("Group")
898 .field("delimiter", &self.delimiter())
899 .field("stream", &self.stream())
900 .field("span", &self.span())
901 .finish()
902 }
903}
904905/// A `Punct` is a single punctuation character such as `+`, `-` or `#`.
906///
907/// Multi-character operators like `+=` are represented as two instances of `Punct` with different
908/// forms of `Spacing` returned.
909#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
910#[derive(#[automatically_derived]
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl ::core::clone::Clone for Punct {
#[inline]
fn clone(&self) -> Punct { Punct(::core::clone::Clone::clone(&self.0)) }
}Clone)]
911pub struct Punct(bridge::Punct<bridge::client::Span>);
912913#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
914impl !Sendfor Punct {}
915#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
916impl !Syncfor Punct {}
917918/// Indicates whether a `Punct` token can join with the following token
919/// to form a multi-character operator.
920#[derive(#[automatically_derived]
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl ::core::marker::Copy for Spacing { }Copy, #[automatically_derived]
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl ::core::clone::Clone for Spacing {
#[inline]
fn clone(&self) -> Spacing { *self }
}Clone, #[automatically_derived]
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl ::core::fmt::Debug for Spacing {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
Spacing::Joint => "Joint",
Spacing::Alone => "Alone",
})
}
}Debug, #[automatically_derived]
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl ::core::cmp::PartialEq for Spacing {
#[inline]
fn eq(&self, other: &Spacing) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl ::core::cmp::Eq for Spacing {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_receiver_is_total_eq(&self) -> () {}
}Eq)]
921#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
922pub enum Spacing {
923/// A `Punct` token can join with the following token to form a multi-character operator.
924 ///
925 /// In token streams constructed using proc macro interfaces, `Joint` punctuation tokens can be
926 /// followed by any other tokens. However, in token streams parsed from source code, the
927 /// compiler will only set spacing to `Joint` in the following cases.
928 /// - When a `Punct` is immediately followed by another `Punct` without a whitespace. E.g. `+`
929 /// is `Joint` in `+=` and `++`.
930 /// - When a single quote `'` is immediately followed by an identifier without a whitespace.
931 /// E.g. `'` is `Joint` in `'lifetime`.
932 ///
933 /// This list may be extended in the future to enable more token combinations.
934#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
935Joint,
936/// A `Punct` token cannot join with the following token to form a multi-character operator.
937 ///
938 /// `Alone` punctuation tokens can be followed by any other tokens. In token streams parsed
939 /// from source code, the compiler will set spacing to `Alone` in all cases not covered by the
940 /// conditions for `Joint` above. E.g. `+` is `Alone` in `+ =`, `+ident` and `+()`. In
941 /// particular, tokens not followed by anything will be marked as `Alone`.
942#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
943Alone,
944}
945946impl Punct {
947/// Creates a new `Punct` from the given character and spacing.
948 /// The `ch` argument must be a valid punctuation character permitted by the language,
949 /// otherwise the function will panic.
950 ///
951 /// The returned `Punct` will have the default span of `Span::call_site()`
952 /// which can be further configured with the `set_span` method below.
953#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
954pub fn new(ch: char, spacing: Spacing) -> Punct {
955const LEGAL_CHARS: &[char] = &[
956'=', '<', '>', '!', '~', '+', '-', '*', '/', '%', '^', '&', '|', '@', '.', ',', ';',
957':', '#', '$', '?', '\'',
958 ];
959if !LEGAL_CHARS.contains(&ch) {
960{
::core::panicking::panic_fmt(format_args!("unsupported character `{0:?}`",
ch));
};panic!("unsupported character `{:?}`", ch);
961 }
962Punct(bridge::Punct {
963 ch: chas u8,
964 joint: spacing == Spacing::Joint,
965 span: Span::call_site().0,
966 })
967 }
968969/// Returns the value of this punctuation character as `char`.
970#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
971pub fn as_char(&self) -> char {
972self.0.ch as char973 }
974975/// Returns the spacing of this punctuation character, indicating whether it can be potentially
976 /// combined into a multi-character operator with the following token (`Joint`), or whether the
977 /// operator has definitely ended (`Alone`).
978#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
979pub fn spacing(&self) -> Spacing {
980if self.0.joint { Spacing::Joint } else { Spacing::Alone }
981 }
982983/// Returns the span for this punctuation character.
984#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
985pub fn span(&self) -> Span {
986Span(self.0.span)
987 }
988989/// Configure the span for this punctuation character.
990#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
991pub fn set_span(&mut self, span: Span) {
992self.0.span = span.0;
993 }
994}
995996/// Prints the punctuation character as a string that should be losslessly convertible
997/// back into the same character.
998#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
999impl fmt::Displayfor Punct {
1000fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1001f.write_fmt(format_args!("{0}", self.as_char()))write!(f, "{}", self.as_char())1002 }
1003}
10041005#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1006impl fmt::Debugfor Punct {
1007fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1008f.debug_struct("Punct")
1009 .field("ch", &self.as_char())
1010 .field("spacing", &self.spacing())
1011 .field("span", &self.span())
1012 .finish()
1013 }
1014}
10151016#[stable(feature = "proc_macro_punct_eq", since = "1.50.0")]
1017impl PartialEq<char> for Punct {
1018fn eq(&self, rhs: &char) -> bool {
1019self.as_char() == *rhs1020 }
1021}
10221023#[stable(feature = "proc_macro_punct_eq_flipped", since = "1.52.0")]
1024impl PartialEq<Punct> for char {
1025fn eq(&self, rhs: &Punct) -> bool {
1026*self == rhs.as_char()
1027 }
1028}
10291030/// An identifier (`ident`).
1031#[derive(#[automatically_derived]
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl ::core::clone::Clone for Ident {
#[inline]
fn clone(&self) -> Ident { Ident(::core::clone::Clone::clone(&self.0)) }
}Clone)]
1032#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1033pub struct Ident(bridge::Ident<bridge::client::Span, bridge::client::Symbol>);
10341035impl Ident {
1036/// Creates a new `Ident` with the given `string` as well as the specified
1037 /// `span`.
1038 /// The `string` argument must be a valid identifier permitted by the
1039 /// language (including keywords, e.g. `self` or `fn`). Otherwise, the function will panic.
1040 ///
1041 /// The constructed identifier will be NFC-normalized. See the [Reference] for more info.
1042 ///
1043 /// Note that `span`, currently in rustc, configures the hygiene information
1044 /// for this identifier.
1045 ///
1046 /// As of this time `Span::call_site()` explicitly opts-in to "call-site" hygiene
1047 /// meaning that identifiers created with this span will be resolved as if they were written
1048 /// directly at the location of the macro call, and other code at the macro call site will be
1049 /// able to refer to them as well.
1050 ///
1051 /// Later spans like `Span::def_site()` will allow to opt-in to "definition-site" hygiene
1052 /// meaning that identifiers created with this span will be resolved at the location of the
1053 /// macro definition and other code at the macro call site will not be able to refer to them.
1054 ///
1055 /// Due to the current importance of hygiene this constructor, unlike other
1056 /// tokens, requires a `Span` to be specified at construction.
1057 ///
1058 /// [Reference]: https://doc.rust-lang.org/nightly/reference/identifiers.html#r-ident.normalization
1059#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1060pub fn new(string: &str, span: Span) -> Ident {
1061Ident(bridge::Ident {
1062 sym: bridge::client::Symbol::new_ident(string, false),
1063 is_raw: false,
1064 span: span.0,
1065 })
1066 }
10671068/// Same as `Ident::new`, but creates a raw identifier (`r#ident`).
1069 /// The `string` argument be a valid identifier permitted by the language
1070 /// (including keywords, e.g. `fn`). Keywords which are usable in path segments
1071 /// (e.g. `self`, `super`) are not supported, and will cause a panic.
1072#[stable(feature = "proc_macro_raw_ident", since = "1.47.0")]
1073pub fn new_raw(string: &str, span: Span) -> Ident {
1074Ident(bridge::Ident {
1075 sym: bridge::client::Symbol::new_ident(string, true),
1076 is_raw: true,
1077 span: span.0,
1078 })
1079 }
10801081/// Returns the span of this `Ident`, encompassing the entire string returned
1082 /// by [`to_string`](ToString::to_string).
1083#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1084pub fn span(&self) -> Span {
1085Span(self.0.span)
1086 }
10871088/// Configures the span of this `Ident`, possibly changing its hygiene context.
1089#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1090pub fn set_span(&mut self, span: Span) {
1091self.0.span = span.0;
1092 }
1093}
10941095/// Prints the identifier as a string that should be losslessly convertible back
1096/// into the same identifier.
1097#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1098impl fmt::Displayfor Ident {
1099fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1100if self.0.is_raw {
1101f.write_str("r#")?;
1102 }
1103 fmt::Display::fmt(&self.0.sym, f)
1104 }
1105}
11061107#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1108impl fmt::Debugfor Ident {
1109fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1110f.debug_struct("Ident")
1111 .field("ident", &self.to_string())
1112 .field("span", &self.span())
1113 .finish()
1114 }
1115}
11161117/// A literal string (`"hello"`), byte string (`b"hello"`), C string (`c"hello"`),
1118/// character (`'a'`), byte character (`b'a'`), an integer or floating point number
1119/// with or without a suffix (`1`, `1u8`, `2.3`, `2.3f32`).
1120/// Boolean literals like `true` and `false` do not belong here, they are `Ident`s.
1121#[derive(#[automatically_derived]
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl ::core::clone::Clone for Literal {
#[inline]
fn clone(&self) -> Literal {
Literal(::core::clone::Clone::clone(&self.0))
}
}Clone)]
1122#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1123pub struct Literal(bridge::Literal<bridge::client::Span, bridge::client::Symbol>);
11241125macro_rules!suffixed_int_literals {
1126 ($($name:ident => $kind:ident,)*) => ($(
1127/// Creates a new suffixed integer literal with the specified value.
1128 ///
1129 /// This function will create an integer like `1u32` where the integer
1130 /// value specified is the first part of the token and the integral is
1131 /// also suffixed at the end.
1132 /// Literals created from negative numbers might not survive round-trips through
1133 /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
1134 ///
1135 /// Literals created through this method have the `Span::call_site()`
1136 /// span by default, which can be configured with the `set_span` method
1137 /// below.
1138#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1139pub fn $name(n: $kind) -> Literal {
1140 Literal(bridge::Literal {
1141 kind: bridge::LitKind::Integer,
1142 symbol: bridge::client::Symbol::new(&n.to_string()),
1143 suffix: Some(bridge::client::Symbol::new(stringify!($kind))),
1144 span: Span::call_site().0,
1145 })
1146 }
1147 )*)
1148}
11491150macro_rules!unsuffixed_int_literals {
1151 ($($name:ident => $kind:ident,)*) => ($(
1152/// Creates a new unsuffixed integer literal with the specified value.
1153 ///
1154 /// This function will create an integer like `1` where the integer
1155 /// value specified is the first part of the token. No suffix is
1156 /// specified on this token, meaning that invocations like
1157 /// `Literal::i8_unsuffixed(1)` are equivalent to
1158 /// `Literal::u32_unsuffixed(1)`.
1159 /// Literals created from negative numbers might not survive rountrips through
1160 /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
1161 ///
1162 /// Literals created through this method have the `Span::call_site()`
1163 /// span by default, which can be configured with the `set_span` method
1164 /// below.
1165#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1166pub fn $name(n: $kind) -> Literal {
1167 Literal(bridge::Literal {
1168 kind: bridge::LitKind::Integer,
1169 symbol: bridge::client::Symbol::new(&n.to_string()),
1170 suffix: None,
1171 span: Span::call_site().0,
1172 })
1173 }
1174 )*)
1175}
11761177impl Literal {
1178fn new(kind: bridge::LitKind, value: &str, suffix: Option<&str>) -> Self {
1179Literal(bridge::Literal {
1180kind,
1181 symbol: bridge::client::Symbol::new(value),
1182 suffix: suffix.map(bridge::client::Symbol::new),
1183 span: Span::call_site().0,
1184 })
1185 }
11861187n
Literal
Literal(bridge::Literal {
kind: bridge::LitKind::Integer,
symbol: bridge::client::Symbol::new(&n.to_string()),
suffix: Some(bridge::client::Symbol::new("isize")),
span: Span::call_site().0,
});suffixed_int_literals! {
1188 u8_suffixed => u8,
1189 u16_suffixed => u16,
1190 u32_suffixed => u32,
1191 u64_suffixed => u64,
1192 u128_suffixed => u128,
1193 usize_suffixed => usize,
1194 i8_suffixed => i8,
1195 i16_suffixed => i16,
1196 i32_suffixed => i32,
1197 i64_suffixed => i64,
1198 i128_suffixed => i128,
1199 isize_suffixed => isize,
1200 }12011202n
Literal
Literal(bridge::Literal {
kind: bridge::LitKind::Integer,
symbol: bridge::client::Symbol::new(&n.to_string()),
suffix: None,
span: Span::call_site().0,
});unsuffixed_int_literals! {
1203 u8_unsuffixed => u8,
1204 u16_unsuffixed => u16,
1205 u32_unsuffixed => u32,
1206 u64_unsuffixed => u64,
1207 u128_unsuffixed => u128,
1208 usize_unsuffixed => usize,
1209 i8_unsuffixed => i8,
1210 i16_unsuffixed => i16,
1211 i32_unsuffixed => i32,
1212 i64_unsuffixed => i64,
1213 i128_unsuffixed => i128,
1214 isize_unsuffixed => isize,
1215 }12161217/// Creates a new unsuffixed floating-point literal.
1218 ///
1219 /// This constructor is similar to those like `Literal::i8_unsuffixed` where
1220 /// the float's value is emitted directly into the token but no suffix is
1221 /// used, so it may be inferred to be a `f64` later in the compiler.
1222 /// Literals created from negative numbers might not survive rountrips through
1223 /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
1224 ///
1225 /// # Panics
1226 ///
1227 /// This function requires that the specified float is finite, for
1228 /// example if it is infinity or NaN this function will panic.
1229#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1230pub fn f32_unsuffixed(n: f32) -> Literal {
1231if !n.is_finite() {
1232{
::core::panicking::panic_fmt(format_args!("Invalid float literal {0}",
n));
};panic!("Invalid float literal {n}");
1233 }
1234let mut repr = n.to_string();
1235if !repr.contains('.') {
1236repr.push_str(".0");
1237 }
1238Literal::new(bridge::LitKind::Float, &repr, None)
1239 }
12401241/// Creates a new suffixed floating-point literal.
1242 ///
1243 /// This constructor will create a literal like `1.0f32` where the value
1244 /// specified is the preceding part of the token and `f32` is the suffix of
1245 /// the token. This token will always be inferred to be an `f32` in the
1246 /// compiler.
1247 /// Literals created from negative numbers might not survive rountrips through
1248 /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
1249 ///
1250 /// # Panics
1251 ///
1252 /// This function requires that the specified float is finite, for
1253 /// example if it is infinity or NaN this function will panic.
1254#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1255pub fn f32_suffixed(n: f32) -> Literal {
1256if !n.is_finite() {
1257{
::core::panicking::panic_fmt(format_args!("Invalid float literal {0}",
n));
};panic!("Invalid float literal {n}");
1258 }
1259Literal::new(bridge::LitKind::Float, &n.to_string(), Some("f32"))
1260 }
12611262/// Creates a new unsuffixed floating-point literal.
1263 ///
1264 /// This constructor is similar to those like `Literal::i8_unsuffixed` where
1265 /// the float's value is emitted directly into the token but no suffix is
1266 /// used, so it may be inferred to be a `f64` later in the compiler.
1267 /// Literals created from negative numbers might not survive rountrips through
1268 /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
1269 ///
1270 /// # Panics
1271 ///
1272 /// This function requires that the specified float is finite, for
1273 /// example if it is infinity or NaN this function will panic.
1274#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1275pub fn f64_unsuffixed(n: f64) -> Literal {
1276if !n.is_finite() {
1277{
::core::panicking::panic_fmt(format_args!("Invalid float literal {0}",
n));
};panic!("Invalid float literal {n}");
1278 }
1279let mut repr = n.to_string();
1280if !repr.contains('.') {
1281repr.push_str(".0");
1282 }
1283Literal::new(bridge::LitKind::Float, &repr, None)
1284 }
12851286/// Creates a new suffixed floating-point literal.
1287 ///
1288 /// This constructor will create a literal like `1.0f64` where the value
1289 /// specified is the preceding part of the token and `f64` is the suffix of
1290 /// the token. This token will always be inferred to be an `f64` in the
1291 /// compiler.
1292 /// Literals created from negative numbers might not survive rountrips through
1293 /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
1294 ///
1295 /// # Panics
1296 ///
1297 /// This function requires that the specified float is finite, for
1298 /// example if it is infinity or NaN this function will panic.
1299#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1300pub fn f64_suffixed(n: f64) -> Literal {
1301if !n.is_finite() {
1302{
::core::panicking::panic_fmt(format_args!("Invalid float literal {0}",
n));
};panic!("Invalid float literal {n}");
1303 }
1304Literal::new(bridge::LitKind::Float, &n.to_string(), Some("f64"))
1305 }
13061307/// String literal.
1308#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1309pub fn string(string: &str) -> Literal {
1310let escape = EscapeOptions {
1311 escape_single_quote: false,
1312 escape_double_quote: true,
1313 escape_nonascii: false,
1314 };
1315let repr = escape_bytes(string.as_bytes(), escape);
1316Literal::new(bridge::LitKind::Str, &repr, None)
1317 }
13181319/// Character literal.
1320#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1321pub fn character(ch: char) -> Literal {
1322let escape = EscapeOptions {
1323 escape_single_quote: true,
1324 escape_double_quote: false,
1325 escape_nonascii: false,
1326 };
1327let repr = escape_bytes(ch.encode_utf8(&mut [0u8; 4]).as_bytes(), escape);
1328Literal::new(bridge::LitKind::Char, &repr, None)
1329 }
13301331/// Byte character literal.
1332#[stable(feature = "proc_macro_byte_character", since = "1.79.0")]
1333pub fn byte_character(byte: u8) -> Literal {
1334let escape = EscapeOptions {
1335 escape_single_quote: true,
1336 escape_double_quote: false,
1337 escape_nonascii: true,
1338 };
1339let repr = escape_bytes(&[byte], escape);
1340Literal::new(bridge::LitKind::Byte, &repr, None)
1341 }
13421343/// Byte string literal.
1344#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1345pub fn byte_string(bytes: &[u8]) -> Literal {
1346let escape = EscapeOptions {
1347 escape_single_quote: false,
1348 escape_double_quote: true,
1349 escape_nonascii: true,
1350 };
1351let repr = escape_bytes(bytes, escape);
1352Literal::new(bridge::LitKind::ByteStr, &repr, None)
1353 }
13541355/// C string literal.
1356#[stable(feature = "proc_macro_c_str_literals", since = "1.79.0")]
1357pub fn c_string(string: &CStr) -> Literal {
1358let escape = EscapeOptions {
1359 escape_single_quote: false,
1360 escape_double_quote: true,
1361 escape_nonascii: false,
1362 };
1363let repr = escape_bytes(string.to_bytes(), escape);
1364Literal::new(bridge::LitKind::CStr, &repr, None)
1365 }
13661367/// Returns the span encompassing this literal.
1368#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1369pub fn span(&self) -> Span {
1370Span(self.0.span)
1371 }
13721373/// Configures the span associated for this literal.
1374#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1375pub fn set_span(&mut self, span: Span) {
1376self.0.span = span.0;
1377 }
13781379/// Returns a `Span` that is a subset of `self.span()` containing only the
1380 /// source bytes in range `range`. Returns `None` if the would-be trimmed
1381 /// span is outside the bounds of `self`.
1382// FIXME(SergioBenitez): check that the byte range starts and ends at a
1383 // UTF-8 boundary of the source. otherwise, it's likely that a panic will
1384 // occur elsewhere when the source text is printed.
1385 // FIXME(SergioBenitez): there is no way for the user to know what
1386 // `self.span()` actually maps to, so this method can currently only be
1387 // called blindly. For example, `to_string()` for the character 'c' returns
1388 // "'\u{63}'"; there is no way for the user to know whether the source text
1389 // was 'c' or whether it was '\u{63}'.
1390#[unstable(feature = "proc_macro_span", issue = "54725")]
1391pub fn subspan<R: RangeBounds<usize>>(&self, range: R) -> Option<Span> {
1392self.0.span.subspan(range.start_bound().cloned(), range.end_bound().cloned()).map(Span)
1393 }
13941395fn with_symbol_and_suffix<R>(&self, f: impl FnOnce(&str, &str) -> R) -> R {
1396self.0.symbol.with(|symbol| match self.0.suffix {
1397Some(suffix) => suffix.with(|suffix| f(symbol, suffix)),
1398None => f(symbol, ""),
1399 })
1400 }
14011402/// Invokes the callback with a `&[&str]` consisting of each part of the
1403 /// literal's representation. This is done to allow the `ToString` and
1404 /// `Display` implementations to borrow references to symbol values, and
1405 /// both be optimized to reduce overhead.
1406fn with_stringify_parts<R>(&self, f: impl FnOnce(&[&str]) -> R) -> R {
1407/// Returns a string containing exactly `num` '#' characters.
1408 /// Uses a 256-character source string literal which is always safe to
1409 /// index with a `u8` index.
1410fn get_hashes_str(num: u8) -> &'static str {
1411const HASHES: &str = "\
1412 ################################################################\
1413 ################################################################\
1414 ################################################################\
1415 ################################################################\
1416 ";
1417const _: () = if !(HASHES.len() == 256) {
::core::panicking::panic("assertion failed: HASHES.len() == 256")
}assert!(HASHES.len() == 256);
1418&HASHES[..num as usize]
1419 }
14201421self.with_symbol_and_suffix(|symbol, suffix| match self.0.kind {
1422 bridge::LitKind::Byte => f(&["b'", symbol, "'", suffix]),
1423 bridge::LitKind::Char => f(&["'", symbol, "'", suffix]),
1424 bridge::LitKind::Str => f(&["\"", symbol, "\"", suffix]),
1425 bridge::LitKind::StrRaw(n) => {
1426let hashes = get_hashes_str(n);
1427f(&["r", hashes, "\"", symbol, "\"", hashes, suffix])
1428 }
1429 bridge::LitKind::ByteStr => f(&["b\"", symbol, "\"", suffix]),
1430 bridge::LitKind::ByteStrRaw(n) => {
1431let hashes = get_hashes_str(n);
1432f(&["br", hashes, "\"", symbol, "\"", hashes, suffix])
1433 }
1434 bridge::LitKind::CStr => f(&["c\"", symbol, "\"", suffix]),
1435 bridge::LitKind::CStrRaw(n) => {
1436let hashes = get_hashes_str(n);
1437f(&["cr", hashes, "\"", symbol, "\"", hashes, suffix])
1438 }
14391440 bridge::LitKind::Integer | bridge::LitKind::Float | bridge::LitKind::ErrWithGuar => {
1441f(&[symbol, suffix])
1442 }
1443 })
1444 }
14451446/// Returns the unescaped string value if the current literal is a string or a string literal.
1447#[unstable(feature = "proc_macro_value", issue = "136652")]
1448pub fn str_value(&self) -> Result<String, ConversionErrorKind> {
1449self.0.symbol.with(|symbol| match self.0.kind {
1450 bridge::LitKind::Str => {
1451if symbol.contains('\\') {
1452let mut buf = String::with_capacity(symbol.len());
1453let mut error = None;
1454// Force-inlining here is aggressive but the closure is
1455 // called on every char in the string, so it can be hot in
1456 // programs with many long strings containing escapes.
1457unescape_str(
1458symbol,
1459#[inline(always)]
1460|_, c| match c {
1461Ok(c) => buf.push(c),
1462Err(err) => {
1463if err.is_fatal() {
1464error = Some(ConversionErrorKind::FailedToUnescape(err));
1465 }
1466 }
1467 },
1468 );
1469if let Some(error) = error { Err(error) } else { Ok(buf) }
1470 } else {
1471Ok(symbol.to_string())
1472 }
1473 }
1474 bridge::LitKind::StrRaw(_) => Ok(symbol.to_string()),
1475_ => Err(ConversionErrorKind::InvalidLiteralKind),
1476 })
1477 }
14781479/// Returns the unescaped string value if the current literal is a c-string or a c-string
1480 /// literal.
1481#[unstable(feature = "proc_macro_value", issue = "136652")]
1482pub fn cstr_value(&self) -> Result<Vec<u8>, ConversionErrorKind> {
1483self.0.symbol.with(|symbol| match self.0.kind {
1484 bridge::LitKind::CStr => {
1485let mut error = None;
1486let mut buf = Vec::with_capacity(symbol.len());
14871488unescape_c_str(symbol, |_span, res| match res {
1489Ok(MixedUnit::Char(c)) => {
1490buf.extend_from_slice(c.get().encode_utf8(&mut [0; 4]).as_bytes())
1491 }
1492Ok(MixedUnit::HighByte(b)) => buf.push(b.get()),
1493Err(err) => {
1494if err.is_fatal() {
1495error = Some(ConversionErrorKind::FailedToUnescape(err));
1496 }
1497 }
1498 });
1499if let Some(error) = error {
1500Err(error)
1501 } else {
1502buf.push(0);
1503Ok(buf)
1504 }
1505 }
1506 bridge::LitKind::CStrRaw(_) => {
1507// Raw strings have no escapes so we can convert the symbol
1508 // directly to a `Lrc<u8>` after appending the terminating NUL
1509 // char.
1510let mut buf = symbol.to_owned().into_bytes();
1511buf.push(0);
1512Ok(buf)
1513 }
1514_ => Err(ConversionErrorKind::InvalidLiteralKind),
1515 })
1516 }
15171518/// Returns the unescaped string value if the current literal is a byte string or a byte string
1519 /// literal.
1520#[unstable(feature = "proc_macro_value", issue = "136652")]
1521pub fn byte_str_value(&self) -> Result<Vec<u8>, ConversionErrorKind> {
1522self.0.symbol.with(|symbol| match self.0.kind {
1523 bridge::LitKind::ByteStr => {
1524let mut buf = Vec::with_capacity(symbol.len());
1525let mut error = None;
15261527unescape_byte_str(symbol, |_, res| match res {
1528Ok(b) => buf.push(b),
1529Err(err) => {
1530if err.is_fatal() {
1531error = Some(ConversionErrorKind::FailedToUnescape(err));
1532 }
1533 }
1534 });
1535if let Some(error) = error { Err(error) } else { Ok(buf) }
1536 }
1537 bridge::LitKind::ByteStrRaw(_) => {
1538// Raw strings have no escapes so we can convert the symbol
1539 // directly to a `Lrc<u8>`.
1540Ok(symbol.to_owned().into_bytes())
1541 }
1542_ => Err(ConversionErrorKind::InvalidLiteralKind),
1543 })
1544 }
1545}
15461547/// Parse a single literal from its stringified representation.
1548///
1549/// In order to parse successfully, the input string must not contain anything
1550/// but the literal token. Specifically, it must not contain whitespace or
1551/// comments in addition to the literal.
1552///
1553/// The resulting literal token will have a `Span::call_site()` span.
1554///
1555/// NOTE: some errors may cause panics instead of returning `LexError`. We
1556/// reserve the right to change these errors into `LexError`s later.
1557#[stable(feature = "proc_macro_literal_parse", since = "1.54.0")]
1558impl FromStrfor Literal {
1559type Err = LexError;
15601561fn from_str(src: &str) -> Result<Self, LexError> {
1562match bridge::client::FreeFunctions::literal_from_str(src) {
1563Ok(literal) => Ok(Literal(literal)),
1564Err(()) => Err(LexError),
1565 }
1566 }
1567}
15681569/// Prints the literal as a string that should be losslessly convertible
1570/// back into the same literal (except for possible rounding for floating point literals).
1571#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1572impl fmt::Displayfor Literal {
1573fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1574self.with_stringify_parts(|parts| {
1575for part in parts {
1576 fmt::Display::fmt(part, f)?;
1577 }
1578Ok(())
1579 })
1580 }
1581}
15821583#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1584impl fmt::Debugfor Literal {
1585fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1586f.debug_struct("Literal")
1587// format the kind on one line even in {:#?} mode
1588 .field("kind", &format_args!("{0:?}", self.0.kind)format_args!("{:?}", self.0.kind))
1589 .field("symbol", &self.0.symbol)
1590// format `Some("...")` on one line even in {:#?} mode
1591 .field("suffix", &format_args!("{0:?}", self.0.suffix)format_args!("{:?}", self.0.suffix))
1592 .field("span", &self.0.span)
1593 .finish()
1594 }
1595}
15961597#[unstable(
1598 feature = "proc_macro_tracked_path",
1599 issue = "99515",
1600 implied_by = "proc_macro_tracked_env"
1601)]
1602/// Functionality for adding environment state to the build dependency info.
1603pub mod tracked {
16041605use std::env::{self, VarError};
1606use std::ffi::OsStr;
1607use std::path::Path;
16081609/// Retrieve an environment variable and add it to build dependency info.
1610 /// The build system executing the compiler will know that the variable was accessed during
1611 /// compilation, and will be able to rerun the build when the value of that variable changes.
1612 /// Besides the dependency tracking this function should be equivalent to `env::var` from the
1613 /// standard library, except that the argument must be UTF-8.
1614#[unstable(feature = "proc_macro_tracked_env", issue = "99515")]
1615pub fn env_var<K: AsRef<OsStr> + AsRef<str>>(key: K) -> Result<String, VarError> {
1616let key: &str = key.as_ref();
1617let value = crate::bridge::client::FreeFunctions::injected_env_var(key)
1618 .map_or_else(|| env::var(key), Ok);
1619crate::bridge::client::FreeFunctions::track_env_var(key, value.as_deref().ok());
1620value1621 }
16221623/// Track a file or directory explicitly.
1624 ///
1625 /// Commonly used for tracking asset preprocessing.
1626#[unstable(feature = "proc_macro_tracked_path", issue = "99515")]
1627pub fn path<P: AsRef<Path>>(path: P) {
1628let path: &str = path.as_ref().to_str().unwrap();
1629crate::bridge::client::FreeFunctions::track_path(path);
1630 }
1631}