1#![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#![feature(f16)]
31#![recursion_limit = "256"]
32#![allow(internal_features)]
33#![deny(ffi_unwind_calls)]
34#![allow(rustc::internal)] #![warn(rustdoc::unescaped_backticks)]
36#![warn(unreachable_pub)]
37#![deny(unsafe_op_in_unsafe_fn)]
38
39#[unstable(feature = "proc_macro_internals", issue = "none")]
40#[doc(hidden)]
41pub mod bridge;
42
43mod diagnostic;
44mod escape;
45mod to_tokens;
46
47use core::convert::From;
48use core::ops::BitOr;
49use std::borrow::Cow;
50use std::ffi::CStr;
51use std::ops::{Range, RangeBounds};
52use std::path::PathBuf;
53use std::str::FromStr;
54use std::{error, fmt};
55
56#[unstable(feature = "proc_macro_diagnostic", issue = "54140")]
57pub use diagnostic::{Diagnostic, Level, MultiSpan};
58use rustc_literal_escaper::{
59 MixedUnit, unescape_byte, unescape_byte_str, unescape_c_str, unescape_char, unescape_str,
60};
61#[unstable(feature = "proc_macro_totokens", issue = "130977")]
62pub use to_tokens::ToTokens;
63
64use crate::bridge::client::Methods as BridgeMethods;
65use crate::escape::{EscapeOptions, escape_bytes};
66
67#[unstable(feature = "proc_macro_value", issue = "136652")]
69#[derive(Debug, PartialEq, Eq)]
70#[non_exhaustive]
71pub enum EscapeError {
72 ZeroChars,
74 MoreThanOneChar,
76
77 LoneSlash,
79 InvalidEscape,
81 BareCarriageReturn,
83 BareCarriageReturnInRawString,
85 EscapeOnlyChar,
87
88 TooShortHexEscape,
90 InvalidCharInHexEscape,
92 OutOfRangeHexEscape,
94
95 NoBraceInUnicodeEscape,
97 InvalidCharInUnicodeEscape,
99 EmptyUnicodeEscape,
101 UnclosedUnicodeEscape,
103 LeadingUnderscoreUnicodeEscape,
105 OverlongUnicodeEscape,
107 LoneSurrogateUnicodeEscape,
109 OutOfRangeUnicodeEscape,
111
112 UnicodeEscapeInByte,
114 NonAsciiCharInByte,
116
117 NulInCStr,
119
120 UnskippedWhitespaceWarning,
123
124 MultipleSkippedLinesWarning,
126}
127
128#[unstable(feature = "proc_macro_value", issue = "136652")]
129#[doc(hidden)]
130impl From<rustc_literal_escaper::EscapeError> for EscapeError {
131 fn from(value: rustc_literal_escaper::EscapeError) -> Self {
132 use rustc_literal_escaper::EscapeError as EE;
133
134 match value {
135 EE::ZeroChars => Self::ZeroChars,
136 EE::MoreThanOneChar => Self::MoreThanOneChar,
137 EE::LoneSlash => Self::LoneSlash,
138 EE::InvalidEscape => Self::InvalidEscape,
139 EE::BareCarriageReturn => Self::BareCarriageReturn,
140 EE::BareCarriageReturnInRawString => Self::BareCarriageReturnInRawString,
141 EE::EscapeOnlyChar => Self::EscapeOnlyChar,
142 EE::TooShortHexEscape => Self::TooShortHexEscape,
143 EE::InvalidCharInHexEscape => Self::InvalidCharInHexEscape,
144 EE::OutOfRangeHexEscape => Self::OutOfRangeHexEscape,
145 EE::NoBraceInUnicodeEscape => Self::NoBraceInUnicodeEscape,
146 EE::InvalidCharInUnicodeEscape => Self::InvalidCharInUnicodeEscape,
147 EE::EmptyUnicodeEscape => Self::EmptyUnicodeEscape,
148 EE::UnclosedUnicodeEscape => Self::UnclosedUnicodeEscape,
149 EE::LeadingUnderscoreUnicodeEscape => Self::LeadingUnderscoreUnicodeEscape,
150 EE::OverlongUnicodeEscape => Self::OverlongUnicodeEscape,
151 EE::LoneSurrogateUnicodeEscape => Self::LoneSurrogateUnicodeEscape,
152 EE::OutOfRangeUnicodeEscape => Self::OutOfRangeUnicodeEscape,
153 EE::UnicodeEscapeInByte => Self::UnicodeEscapeInByte,
154 EE::NonAsciiCharInByte => Self::NonAsciiCharInByte,
155 EE::NulInCStr => Self::NulInCStr,
156 EE::UnskippedWhitespaceWarning => Self::UnskippedWhitespaceWarning,
157 EE::MultipleSkippedLinesWarning => Self::MultipleSkippedLinesWarning,
158 }
159 }
160}
161
162#[unstable(feature = "proc_macro_value", issue = "136652")]
163impl error::Error for EscapeError {}
164
165#[unstable(feature = "proc_macro_value", issue = "136652")]
166impl fmt::Display for EscapeError {
167 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
168 f.write_str(match self {
169 Self::ZeroChars => "zero chars",
170 Self::MoreThanOneChar => "more than one char",
171 Self::LoneSlash => "lone slash",
172 Self::InvalidEscape => "invalid escape",
173 Self::BareCarriageReturn => "bare carriage return",
174 Self::BareCarriageReturnInRawString => "bare carriage return in raw string",
175 Self::EscapeOnlyChar => "escape only char",
176 Self::TooShortHexEscape => "too short hex escape",
177 Self::InvalidCharInHexEscape => "invalid char in hex escape",
178 Self::OutOfRangeHexEscape => "out of range hex escape",
179 Self::NoBraceInUnicodeEscape => "no brace in unicode escape",
180 Self::InvalidCharInUnicodeEscape => "invalid char in unicode escape",
181 Self::EmptyUnicodeEscape => "empty unicode escape",
182 Self::UnclosedUnicodeEscape => "unclosed unicode escape",
183 Self::LeadingUnderscoreUnicodeEscape => "leading underscore unicode escape",
184 Self::OverlongUnicodeEscape => "overlong unicode escape",
185 Self::LoneSurrogateUnicodeEscape => "lone surrogate unicode escape",
186 Self::OutOfRangeUnicodeEscape => "out of range unicode escape",
187 Self::UnicodeEscapeInByte => "unicode escape in byte",
188 Self::NonAsciiCharInByte => "non ascii char in byte",
189 Self::NulInCStr => "nul in CStr",
190 Self::UnskippedWhitespaceWarning => "unskipped whitespace warning",
191 Self::MultipleSkippedLinesWarning => "multiple skipped lines warning",
192 })
193 }
194}
195
196#[unstable(feature = "proc_macro_value", issue = "136652")]
198#[derive(Debug, PartialEq, Eq)]
199#[non_exhaustive]
200pub enum ConversionErrorKind {
201 FailedToUnescape(EscapeError),
203 InvalidLiteralKind,
205}
206
207#[stable(feature = "proc_macro_is_available", since = "1.57.0")]
221pub fn is_available() -> bool {
222 bridge::client::is_available()
223}
224
225#[cfg_attr(feature = "rustc-dep-of-std", rustc_diagnostic_item = "TokenStream")]
233#[stable(feature = "proc_macro_lib", since = "1.15.0")]
234#[derive(Clone)]
235pub struct TokenStream(Option<bridge::client::TokenStream>);
236
237#[stable(feature = "proc_macro_lib", since = "1.15.0")]
238impl !Send for TokenStream {}
239#[stable(feature = "proc_macro_lib", since = "1.15.0")]
240impl !Sync for TokenStream {}
241
242#[stable(feature = "proc_macro_lib", since = "1.15.0")]
247#[derive(Debug)]
248pub struct LexError(String);
249
250#[stable(feature = "proc_macro_lexerror_impls", since = "1.44.0")]
251impl fmt::Display for LexError {
252 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
253 f.write_str(&self.0)
254 }
255}
256
257#[stable(feature = "proc_macro_lexerror_impls", since = "1.44.0")]
258impl error::Error for LexError {}
259
260#[stable(feature = "proc_macro_lib", since = "1.15.0")]
261impl !Send for LexError {}
262#[stable(feature = "proc_macro_lib", since = "1.15.0")]
263impl !Sync for LexError {}
264
265#[unstable(feature = "proc_macro_expand", issue = "90765")]
267#[non_exhaustive]
268#[derive(Debug)]
269pub struct ExpandError;
270
271#[unstable(feature = "proc_macro_expand", issue = "90765")]
272impl fmt::Display for ExpandError {
273 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
274 f.write_str("macro expansion failed")
275 }
276}
277
278#[unstable(feature = "proc_macro_expand", issue = "90765")]
279impl error::Error for ExpandError {}
280
281#[unstable(feature = "proc_macro_expand", issue = "90765")]
282impl !Send for ExpandError {}
283
284#[unstable(feature = "proc_macro_expand", issue = "90765")]
285impl !Sync for ExpandError {}
286
287impl TokenStream {
288 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
290 pub fn new() -> TokenStream {
291 TokenStream(None)
292 }
293
294 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
296 pub fn is_empty(&self) -> bool {
297 self.0.as_ref().map(BridgeMethods::ts_is_empty).unwrap_or(true)
298 }
299
300 #[unstable(feature = "proc_macro_expand", issue = "90765")]
311 pub fn expand_expr(&self) -> Result<TokenStream, ExpandError> {
312 let stream = self.0.as_ref().ok_or(ExpandError)?;
313 match BridgeMethods::ts_expand_expr(stream) {
314 Ok(stream) => Ok(TokenStream(Some(stream))),
315 Err(_) => Err(ExpandError),
316 }
317 }
318}
319
320#[stable(feature = "proc_macro_lib", since = "1.15.0")]
328impl FromStr for TokenStream {
329 type Err = LexError;
330
331 fn from_str(src: &str) -> Result<TokenStream, LexError> {
332 Ok(TokenStream(Some(BridgeMethods::ts_from_str(src).map_err(LexError)?)))
333 }
334}
335
336#[stable(feature = "proc_macro_lib", since = "1.15.0")]
348impl fmt::Display for TokenStream {
349 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
350 match &self.0 {
351 Some(ts) => write!(f, "{}", BridgeMethods::ts_to_string(ts)),
352 None => Ok(()),
353 }
354 }
355}
356
357#[stable(feature = "proc_macro_lib", since = "1.15.0")]
359impl fmt::Debug for TokenStream {
360 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
361 f.write_str("TokenStream ")?;
362 f.debug_list().entries(self.clone()).finish()
363 }
364}
365
366#[stable(feature = "proc_macro_token_stream_default", since = "1.45.0")]
367impl Default for TokenStream {
368 fn default() -> Self {
369 TokenStream::new()
370 }
371}
372
373#[unstable(feature = "proc_macro_quote", issue = "54722")]
374pub use quote::{HasIterator, RepInterp, ThereIsNoIteratorInRepetition, ext, quote, quote_span};
375
376fn tree_to_bridge_tree(
377 tree: TokenTree,
378) -> bridge::TokenTree<bridge::client::TokenStream, bridge::client::Span, bridge::client::Symbol> {
379 match tree {
380 TokenTree::Group(tt) => bridge::TokenTree::Group(tt.0),
381 TokenTree::Punct(tt) => bridge::TokenTree::Punct(tt.0),
382 TokenTree::Ident(tt) => bridge::TokenTree::Ident(tt.0),
383 TokenTree::Literal(tt) => bridge::TokenTree::Literal(tt.0),
384 }
385}
386
387#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
389impl From<TokenTree> for TokenStream {
390 fn from(tree: TokenTree) -> TokenStream {
391 TokenStream(Some(BridgeMethods::ts_from_token_tree(tree_to_bridge_tree(tree))))
392 }
393}
394
395struct ConcatTreesHelper {
398 trees: Vec<
399 bridge::TokenTree<
400 bridge::client::TokenStream,
401 bridge::client::Span,
402 bridge::client::Symbol,
403 >,
404 >,
405}
406
407impl ConcatTreesHelper {
408 fn new(capacity: usize) -> Self {
409 ConcatTreesHelper { trees: Vec::with_capacity(capacity) }
410 }
411
412 fn push(&mut self, tree: TokenTree) {
413 self.trees.push(tree_to_bridge_tree(tree));
414 }
415
416 fn build(self) -> TokenStream {
417 if self.trees.is_empty() {
418 TokenStream(None)
419 } else {
420 TokenStream(Some(BridgeMethods::ts_concat_trees(None, self.trees)))
421 }
422 }
423
424 fn append_to(self, stream: &mut TokenStream) {
425 if self.trees.is_empty() {
426 return;
427 }
428 stream.0 = Some(BridgeMethods::ts_concat_trees(stream.0.take(), self.trees))
429 }
430}
431
432struct ConcatStreamsHelper {
435 streams: Vec<bridge::client::TokenStream>,
436}
437
438impl ConcatStreamsHelper {
439 fn new(capacity: usize) -> Self {
440 ConcatStreamsHelper { streams: Vec::with_capacity(capacity) }
441 }
442
443 fn push(&mut self, stream: TokenStream) {
444 if let Some(stream) = stream.0 {
445 self.streams.push(stream);
446 }
447 }
448
449 fn build(mut self) -> TokenStream {
450 if self.streams.len() <= 1 {
451 TokenStream(self.streams.pop())
452 } else {
453 TokenStream(Some(BridgeMethods::ts_concat_streams(None, self.streams)))
454 }
455 }
456
457 fn append_to(mut self, stream: &mut TokenStream) {
458 if self.streams.is_empty() {
459 return;
460 }
461 let base = stream.0.take();
462 if base.is_none() && self.streams.len() == 1 {
463 stream.0 = self.streams.pop();
464 } else {
465 stream.0 = Some(BridgeMethods::ts_concat_streams(base, self.streams));
466 }
467 }
468}
469
470#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
472impl FromIterator<TokenTree> for TokenStream {
473 fn from_iter<I: IntoIterator<Item = TokenTree>>(trees: I) -> Self {
474 let iter = trees.into_iter();
475 let mut builder = ConcatTreesHelper::new(iter.size_hint().0);
476 iter.for_each(|tree| builder.push(tree));
477 builder.build()
478 }
479}
480
481#[stable(feature = "proc_macro_lib", since = "1.15.0")]
484impl FromIterator<TokenStream> for TokenStream {
485 fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self {
486 let iter = streams.into_iter();
487 let mut builder = ConcatStreamsHelper::new(iter.size_hint().0);
488 iter.for_each(|stream| builder.push(stream));
489 builder.build()
490 }
491}
492
493#[stable(feature = "token_stream_extend", since = "1.30.0")]
494impl Extend<TokenTree> for TokenStream {
495 fn extend<I: IntoIterator<Item = TokenTree>>(&mut self, trees: I) {
496 let iter = trees.into_iter();
497 let mut builder = ConcatTreesHelper::new(iter.size_hint().0);
498 iter.for_each(|tree| builder.push(tree));
499 builder.append_to(self);
500 }
501}
502
503#[stable(feature = "token_stream_extend", since = "1.30.0")]
504impl Extend<TokenStream> for TokenStream {
505 fn extend<I: IntoIterator<Item = TokenStream>>(&mut self, streams: I) {
506 let iter = streams.into_iter();
507 let mut builder = ConcatStreamsHelper::new(iter.size_hint().0);
508 iter.for_each(|stream| builder.push(stream));
509 builder.append_to(self);
510 }
511}
512
513macro_rules! extend_items {
514 ($($item:ident)*) => {
515 $(
516 #[stable(feature = "token_stream_extend_ts_items", since = "1.92.0")]
517 impl Extend<$item> for TokenStream {
518 fn extend<I: IntoIterator<Item = $item>>(&mut self, iter: I) {
519 self.extend(iter.into_iter().map(TokenTree::$item));
520 }
521 }
522 )*
523 };
524}
525
526extend_items!(Group Literal Punct Ident);
527
528#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
530pub mod token_stream {
531 use crate::{BridgeMethods, Group, Ident, Literal, Punct, TokenStream, TokenTree, bridge};
532
533 #[derive(Clone)]
537 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
538 pub struct IntoIter(
539 std::vec::IntoIter<
540 bridge::TokenTree<
541 bridge::client::TokenStream,
542 bridge::client::Span,
543 bridge::client::Symbol,
544 >,
545 >,
546 );
547
548 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
549 impl Iterator for IntoIter {
550 type Item = TokenTree;
551
552 fn next(&mut self) -> Option<TokenTree> {
553 self.0.next().map(|tree| match tree {
554 bridge::TokenTree::Group(tt) => TokenTree::Group(Group(tt)),
555 bridge::TokenTree::Punct(tt) => TokenTree::Punct(Punct(tt)),
556 bridge::TokenTree::Ident(tt) => TokenTree::Ident(Ident(tt)),
557 bridge::TokenTree::Literal(tt) => TokenTree::Literal(Literal(tt)),
558 })
559 }
560
561 fn size_hint(&self) -> (usize, Option<usize>) {
562 self.0.size_hint()
563 }
564
565 fn count(self) -> usize {
566 self.0.count()
567 }
568 }
569
570 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
571 impl IntoIterator for TokenStream {
572 type Item = TokenTree;
573 type IntoIter = IntoIter;
574
575 fn into_iter(self) -> IntoIter {
576 IntoIter(self.0.map(BridgeMethods::ts_into_trees).unwrap_or_default().into_iter())
577 }
578 }
579}
580
581#[unstable(feature = "proc_macro_quote", issue = "54722")]
588#[allow_internal_unstable(proc_macro_def_site, proc_macro_internals, proc_macro_totokens)]
589#[rustc_builtin_macro]
590pub macro quote($($t:tt)*) {
591 }
593
594#[unstable(feature = "proc_macro_internals", issue = "none")]
595#[doc(hidden)]
596mod quote;
597
598#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
600#[derive(Copy, Clone)]
601pub struct Span(bridge::client::Span);
602
603#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
604impl !Send for Span {}
605#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
606impl !Sync for Span {}
607
608macro_rules! diagnostic_method {
609 ($name:ident, $level:expr) => {
610 #[unstable(feature = "proc_macro_diagnostic", issue = "54140")]
613 pub fn $name<T: Into<String>>(self, message: T) -> Diagnostic {
614 Diagnostic::spanned(self, $level, message)
615 }
616 };
617}
618
619impl Span {
620 #[unstable(feature = "proc_macro_def_site", issue = "54724")]
622 pub fn def_site() -> Span {
623 Span(bridge::client::Span::def_site())
624 }
625
626 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
631 pub fn call_site() -> Span {
632 Span(bridge::client::Span::call_site())
633 }
634
635 #[stable(feature = "proc_macro_mixed_site", since = "1.45.0")]
640 pub fn mixed_site() -> Span {
641 Span(bridge::client::Span::mixed_site())
642 }
643
644 #[unstable(feature = "proc_macro_span", issue = "54725")]
647 pub fn parent(&self) -> Option<Span> {
648 BridgeMethods::span_parent(self.0).map(Span)
649 }
650
651 #[unstable(feature = "proc_macro_span", issue = "54725")]
655 pub fn source(&self) -> Span {
656 Span(BridgeMethods::span_source(self.0))
657 }
658
659 #[unstable(feature = "proc_macro_span", issue = "54725")]
661 pub fn byte_range(&self) -> Range<usize> {
662 BridgeMethods::span_byte_range(self.0)
663 }
664
665 #[stable(feature = "proc_macro_span_location", since = "1.88.0")]
667 pub fn start(&self) -> Span {
668 Span(BridgeMethods::span_start(self.0))
669 }
670
671 #[stable(feature = "proc_macro_span_location", since = "1.88.0")]
673 pub fn end(&self) -> Span {
674 Span(BridgeMethods::span_end(self.0))
675 }
676
677 #[stable(feature = "proc_macro_span_location", since = "1.88.0")]
681 pub fn line(&self) -> usize {
682 BridgeMethods::span_line(self.0)
683 }
684
685 #[stable(feature = "proc_macro_span_location", since = "1.88.0")]
689 pub fn column(&self) -> usize {
690 BridgeMethods::span_column(self.0)
691 }
692
693 #[stable(feature = "proc_macro_span_file", since = "1.88.0")]
698 pub fn file(&self) -> String {
699 BridgeMethods::span_file(self.0)
700 }
701
702 #[stable(feature = "proc_macro_span_file", since = "1.88.0")]
708 pub fn local_file(&self) -> Option<PathBuf> {
709 BridgeMethods::span_local_file(self.0).map(PathBuf::from)
710 }
711
712 #[unstable(feature = "proc_macro_span", issue = "54725")]
716 pub fn join(&self, other: Span) -> Option<Span> {
717 BridgeMethods::span_join(self.0, other.0).map(Span)
718 }
719
720 #[stable(feature = "proc_macro_span_resolved_at", since = "1.45.0")]
723 pub fn resolved_at(&self, other: Span) -> Span {
724 Span(BridgeMethods::span_resolved_at(self.0, other.0))
725 }
726
727 #[stable(feature = "proc_macro_span_located_at", since = "1.45.0")]
730 pub fn located_at(&self, other: Span) -> Span {
731 other.resolved_at(*self)
732 }
733
734 #[unstable(feature = "proc_macro_span", issue = "54725")]
736 pub fn eq(&self, other: &Span) -> bool {
737 self.0 == other.0
738 }
739
740 #[stable(feature = "proc_macro_source_text", since = "1.66.0")]
748 pub fn source_text(&self) -> Option<String> {
749 BridgeMethods::span_source_text(self.0)
750 }
751
752 #[doc(hidden)]
754 #[unstable(feature = "proc_macro_internals", issue = "none")]
755 pub fn save_span(&self) -> usize {
756 BridgeMethods::span_save_span(self.0)
757 }
758
759 #[doc(hidden)]
761 #[unstable(feature = "proc_macro_internals", issue = "none")]
762 pub fn recover_proc_macro_span(id: usize) -> Span {
763 Span(BridgeMethods::span_recover_proc_macro_span(id))
764 }
765
766 diagnostic_method!(error, Level::Error);
767 diagnostic_method!(warning, Level::Warning);
768 diagnostic_method!(note, Level::Note);
769 diagnostic_method!(help, Level::Help);
770}
771
772#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
774impl fmt::Debug for Span {
775 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
776 self.0.fmt(f)
777 }
778}
779
780#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
782#[derive(Clone)]
783pub enum TokenTree {
784 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
786 Group(#[stable(feature = "proc_macro_lib2", since = "1.29.0")] Group),
787 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
789 Ident(#[stable(feature = "proc_macro_lib2", since = "1.29.0")] Ident),
790 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
792 Punct(#[stable(feature = "proc_macro_lib2", since = "1.29.0")] Punct),
793 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
795 Literal(#[stable(feature = "proc_macro_lib2", since = "1.29.0")] Literal),
796}
797
798#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
799impl !Send for TokenTree {}
800#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
801impl !Sync for TokenTree {}
802
803impl TokenTree {
804 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
807 pub fn span(&self) -> Span {
808 match *self {
809 TokenTree::Group(ref t) => t.span(),
810 TokenTree::Ident(ref t) => t.span(),
811 TokenTree::Punct(ref t) => t.span(),
812 TokenTree::Literal(ref t) => t.span(),
813 }
814 }
815
816 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
822 pub fn set_span(&mut self, span: Span) {
823 match *self {
824 TokenTree::Group(ref mut t) => t.set_span(span),
825 TokenTree::Ident(ref mut t) => t.set_span(span),
826 TokenTree::Punct(ref mut t) => t.set_span(span),
827 TokenTree::Literal(ref mut t) => t.set_span(span),
828 }
829 }
830}
831
832#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
834impl fmt::Debug for TokenTree {
835 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
836 match *self {
839 TokenTree::Group(ref tt) => tt.fmt(f),
840 TokenTree::Ident(ref tt) => tt.fmt(f),
841 TokenTree::Punct(ref tt) => tt.fmt(f),
842 TokenTree::Literal(ref tt) => tt.fmt(f),
843 }
844 }
845}
846
847#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
848impl From<Group> for TokenTree {
849 fn from(g: Group) -> TokenTree {
850 TokenTree::Group(g)
851 }
852}
853
854#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
855impl From<Ident> for TokenTree {
856 fn from(g: Ident) -> TokenTree {
857 TokenTree::Ident(g)
858 }
859}
860
861#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
862impl From<Punct> for TokenTree {
863 fn from(g: Punct) -> TokenTree {
864 TokenTree::Punct(g)
865 }
866}
867
868#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
869impl From<Literal> for TokenTree {
870 fn from(g: Literal) -> TokenTree {
871 TokenTree::Literal(g)
872 }
873}
874
875#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
887impl fmt::Display for TokenTree {
888 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
889 match self {
890 TokenTree::Group(t) => write!(f, "{t}"),
891 TokenTree::Ident(t) => write!(f, "{t}"),
892 TokenTree::Punct(t) => write!(f, "{t}"),
893 TokenTree::Literal(t) => write!(f, "{t}"),
894 }
895 }
896}
897
898#[derive(Clone)]
902#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
903pub struct Group(bridge::Group<bridge::client::TokenStream, bridge::client::Span>);
904
905#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
906impl !Send for Group {}
907#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
908impl !Sync for Group {}
909
910#[derive(Copy, Clone, Debug, PartialEq, Eq)]
912#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
913pub enum Delimiter {
914 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
916 Parenthesis,
917 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
919 Brace,
920 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
922 Bracket,
923 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
941 None,
942}
943
944impl Group {
945 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
951 pub fn new(delimiter: Delimiter, stream: TokenStream) -> Group {
952 Group(bridge::Group {
953 delimiter,
954 stream: stream.0,
955 span: bridge::DelimSpan::from_single(Span::call_site().0),
956 })
957 }
958
959 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
961 pub fn delimiter(&self) -> Delimiter {
962 self.0.delimiter
963 }
964
965 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
970 pub fn stream(&self) -> TokenStream {
971 TokenStream(self.0.stream.clone())
972 }
973
974 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
982 pub fn span(&self) -> Span {
983 Span(self.0.span.entire)
984 }
985
986 #[stable(feature = "proc_macro_group_span", since = "1.55.0")]
993 pub fn span_open(&self) -> Span {
994 Span(self.0.span.open)
995 }
996
997 #[stable(feature = "proc_macro_group_span", since = "1.55.0")]
1004 pub fn span_close(&self) -> Span {
1005 Span(self.0.span.close)
1006 }
1007
1008 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1015 pub fn set_span(&mut self, span: Span) {
1016 self.0.span = bridge::DelimSpan::from_single(span.0);
1017 }
1018}
1019
1020#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1024impl fmt::Display for Group {
1025 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1026 write!(f, "{}", TokenStream::from(TokenTree::from(self.clone())))
1027 }
1028}
1029
1030#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1031impl fmt::Debug for Group {
1032 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1033 f.debug_struct("Group")
1034 .field("delimiter", &self.delimiter())
1035 .field("stream", &self.stream())
1036 .field("span", &self.span())
1037 .finish()
1038 }
1039}
1040
1041#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1046#[derive(Clone)]
1047pub struct Punct(bridge::Punct<bridge::client::Span>);
1048
1049#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1050impl !Send for Punct {}
1051#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1052impl !Sync for Punct {}
1053
1054#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1057#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1058pub enum Spacing {
1059 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1071 Joint,
1072 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1079 Alone,
1080}
1081
1082impl Punct {
1083 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1090 pub fn new(ch: char, spacing: Spacing) -> Punct {
1091 const LEGAL_CHARS: &[char] = &[
1092 '=', '<', '>', '!', '~', '+', '-', '*', '/', '%', '^', '&', '|', '@', '.', ',', ';',
1093 ':', '#', '$', '?', '\'',
1094 ];
1095 if !LEGAL_CHARS.contains(&ch) {
1096 panic!("unsupported character `{:?}`", ch);
1097 }
1098 Punct(bridge::Punct {
1099 ch: ch as u8,
1100 joint: spacing == Spacing::Joint,
1101 span: Span::call_site().0,
1102 })
1103 }
1104
1105 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1107 pub fn as_char(&self) -> char {
1108 self.0.ch as char
1109 }
1110
1111 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1115 pub fn spacing(&self) -> Spacing {
1116 if self.0.joint { Spacing::Joint } else { Spacing::Alone }
1117 }
1118
1119 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1121 pub fn span(&self) -> Span {
1122 Span(self.0.span)
1123 }
1124
1125 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1127 pub fn set_span(&mut self, span: Span) {
1128 self.0.span = span.0;
1129 }
1130}
1131
1132#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1135impl fmt::Display for Punct {
1136 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1137 write!(f, "{}", self.as_char())
1138 }
1139}
1140
1141#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1142impl fmt::Debug for Punct {
1143 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1144 f.debug_struct("Punct")
1145 .field("ch", &self.as_char())
1146 .field("spacing", &self.spacing())
1147 .field("span", &self.span())
1148 .finish()
1149 }
1150}
1151
1152#[stable(feature = "proc_macro_punct_eq", since = "1.50.0")]
1153impl PartialEq<char> for Punct {
1154 fn eq(&self, rhs: &char) -> bool {
1155 self.as_char() == *rhs
1156 }
1157}
1158
1159#[stable(feature = "proc_macro_punct_eq_flipped", since = "1.52.0")]
1160impl PartialEq<Punct> for char {
1161 fn eq(&self, rhs: &Punct) -> bool {
1162 *self == rhs.as_char()
1163 }
1164}
1165
1166#[derive(Clone)]
1168#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1169pub struct Ident(bridge::Ident<bridge::client::Span, bridge::client::Symbol>);
1170
1171impl Ident {
1172 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1196 pub fn new(string: &str, span: Span) -> Ident {
1197 Ident(bridge::Ident {
1198 sym: bridge::client::Symbol::new_ident(string, false),
1199 kind: bridge::IdentKind::Normal,
1200 span: span.0,
1201 })
1202 }
1203
1204 #[stable(feature = "proc_macro_raw_ident", since = "1.47.0")]
1209 pub fn new_raw(string: &str, span: Span) -> Ident {
1210 Ident(bridge::Ident {
1211 sym: bridge::client::Symbol::new_ident(string, true),
1212 kind: bridge::IdentKind::Raw,
1213 span: span.0,
1214 })
1215 }
1216
1217 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1220 pub fn span(&self) -> Span {
1221 Span(self.0.span)
1222 }
1223
1224 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1226 pub fn set_span(&mut self, span: Span) {
1227 self.0.span = span.0;
1228 }
1229}
1230
1231#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1234impl fmt::Display for Ident {
1235 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1236 if let Some(prefix) = self.0.kind.prefix() {
1237 f.write_str(prefix)?;
1238 }
1239 fmt::Display::fmt(&self.0.sym, f)
1240 }
1241}
1242
1243#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1244impl fmt::Debug for Ident {
1245 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1246 f.debug_struct("Ident")
1247 .field("ident", &self.to_string())
1248 .field("span", &self.span())
1249 .finish()
1250 }
1251}
1252
1253#[derive(Clone)]
1258#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1259pub struct Literal(bridge::Literal<bridge::client::Span, bridge::client::Symbol>);
1260
1261macro_rules! suffixed_int_literals {
1262 ($($name:ident => $kind:ident,)*) => ($(
1263 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1275 pub fn $name(n: $kind) -> Literal {
1276 Literal(bridge::Literal {
1277 kind: bridge::LitKind::Integer,
1278 symbol: bridge::client::Symbol::new(&n.to_string()),
1279 suffix: Some(bridge::client::Symbol::new(stringify!($kind))),
1280 span: Span::call_site().0,
1281 })
1282 }
1283 )*)
1284}
1285
1286macro_rules! unsuffixed_int_literals {
1287 ($($name:ident => $kind:ident,)*) => ($(
1288 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1302 pub fn $name(n: $kind) -> Literal {
1303 Literal(bridge::Literal {
1304 kind: bridge::LitKind::Integer,
1305 symbol: bridge::client::Symbol::new(&n.to_string()),
1306 suffix: None,
1307 span: Span::call_site().0,
1308 })
1309 }
1310 )*)
1311}
1312
1313macro_rules! integer_values {
1314 ($($nb:ident => $fn_name:ident,)+) => {
1315 $(
1316 #[doc = concat!(
1317 "Returns the unescaped `",
1318 stringify!($nb),
1319 "` value if the literal is a `",
1320 stringify!($nb),
1321 "` or if it's an \"unmarked\" integer which doesn't overflow.")]
1322 #[unstable(feature = "proc_macro_value", issue = "136652")]
1323 pub fn $fn_name(&self) -> Result<$nb, ConversionErrorKind> {
1324 if self.0.kind != bridge::LitKind::Integer {
1325 return Err(ConversionErrorKind::InvalidLiteralKind);
1326 }
1327 self.with_symbol_and_suffix(|symbol, suffix| {
1328 match suffix {
1329 stringify!($nb) | "" => {
1330 let symbol = strip_underscores(symbol);
1331 let (number, base) = parse_number(&symbol);
1332 $nb::from_str_radix(&number, base as u32).map_err(|_| ConversionErrorKind::InvalidLiteralKind)
1333 }
1334 _ => Err(ConversionErrorKind::InvalidLiteralKind),
1335 }
1336 })
1337 }
1338 )+
1339 }
1340}
1341
1342macro_rules! float_values {
1343 ($($nb:ident => $fn_name:ident,)+) => {
1344 $(
1345 #[doc = concat!(
1346 "Returns the unescaped `",
1347 stringify!($nb),
1348 "` value if the literal is a `",
1349 stringify!($nb),
1350 "` or if it's an \"unmarked\" float which doesn't overflow.")]
1351 #[unstable(feature = "proc_macro_value", issue = "136652")]
1352 pub fn $fn_name(&self) -> Result<$nb, ConversionErrorKind> {
1353 if self.0.kind != bridge::LitKind::Float {
1354 return Err(ConversionErrorKind::InvalidLiteralKind);
1355 }
1356 self.with_symbol_and_suffix(|symbol, suffix| {
1357 match suffix {
1358 stringify!($nb) | "" => {
1359 let number = strip_underscores(symbol);
1360 $nb::from_str(&number).map_err(|_| ConversionErrorKind::InvalidLiteralKind)
1361 }
1362 _ => Err(ConversionErrorKind::InvalidLiteralKind),
1363 }
1364 })
1365 }
1366 )+
1367 }
1368}
1369
1370impl Literal {
1371 fn new(kind: bridge::LitKind, value: &str, suffix: Option<&str>) -> Self {
1372 Literal(bridge::Literal {
1373 kind,
1374 symbol: bridge::client::Symbol::new(value),
1375 suffix: suffix.map(bridge::client::Symbol::new),
1376 span: Span::call_site().0,
1377 })
1378 }
1379
1380 suffixed_int_literals! {
1381 u8_suffixed => u8,
1382 u16_suffixed => u16,
1383 u32_suffixed => u32,
1384 u64_suffixed => u64,
1385 u128_suffixed => u128,
1386 usize_suffixed => usize,
1387 i8_suffixed => i8,
1388 i16_suffixed => i16,
1389 i32_suffixed => i32,
1390 i64_suffixed => i64,
1391 i128_suffixed => i128,
1392 isize_suffixed => isize,
1393 }
1394
1395 unsuffixed_int_literals! {
1396 u8_unsuffixed => u8,
1397 u16_unsuffixed => u16,
1398 u32_unsuffixed => u32,
1399 u64_unsuffixed => u64,
1400 u128_unsuffixed => u128,
1401 usize_unsuffixed => usize,
1402 i8_unsuffixed => i8,
1403 i16_unsuffixed => i16,
1404 i32_unsuffixed => i32,
1405 i64_unsuffixed => i64,
1406 i128_unsuffixed => i128,
1407 isize_unsuffixed => isize,
1408 }
1409
1410 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1423 pub fn f32_unsuffixed(n: f32) -> Literal {
1424 if !n.is_finite() {
1425 panic!("Invalid float literal {n}");
1426 }
1427 let mut repr = n.to_string();
1428 if !repr.contains('.') {
1429 repr.push_str(".0");
1430 }
1431 Literal::new(bridge::LitKind::Float, &repr, None)
1432 }
1433
1434 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1448 pub fn f32_suffixed(n: f32) -> Literal {
1449 if !n.is_finite() {
1450 panic!("Invalid float literal {n}");
1451 }
1452 Literal::new(bridge::LitKind::Float, &n.to_string(), Some("f32"))
1453 }
1454
1455 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1468 pub fn f64_unsuffixed(n: f64) -> Literal {
1469 if !n.is_finite() {
1470 panic!("Invalid float literal {n}");
1471 }
1472 let mut repr = n.to_string();
1473 if !repr.contains('.') {
1474 repr.push_str(".0");
1475 }
1476 Literal::new(bridge::LitKind::Float, &repr, None)
1477 }
1478
1479 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1493 pub fn f64_suffixed(n: f64) -> Literal {
1494 if !n.is_finite() {
1495 panic!("Invalid float literal {n}");
1496 }
1497 Literal::new(bridge::LitKind::Float, &n.to_string(), Some("f64"))
1498 }
1499
1500 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1502 pub fn string(string: &str) -> Literal {
1503 let escape = EscapeOptions {
1504 escape_single_quote: false,
1505 escape_double_quote: true,
1506 escape_nonascii: false,
1507 };
1508 let repr = escape_bytes(string.as_bytes(), escape);
1509 Literal::new(bridge::LitKind::Str, &repr, None)
1510 }
1511
1512 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1514 pub fn character(ch: char) -> Literal {
1515 let escape = EscapeOptions {
1516 escape_single_quote: true,
1517 escape_double_quote: false,
1518 escape_nonascii: false,
1519 };
1520 let repr = escape_bytes(ch.encode_utf8(&mut [0u8; 4]).as_bytes(), escape);
1521 Literal::new(bridge::LitKind::Char, &repr, None)
1522 }
1523
1524 #[stable(feature = "proc_macro_byte_character", since = "1.79.0")]
1526 pub fn byte_character(byte: u8) -> Literal {
1527 let escape = EscapeOptions {
1528 escape_single_quote: true,
1529 escape_double_quote: false,
1530 escape_nonascii: true,
1531 };
1532 let repr = escape_bytes(&[byte], escape);
1533 Literal::new(bridge::LitKind::Byte, &repr, None)
1534 }
1535
1536 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1538 pub fn byte_string(bytes: &[u8]) -> Literal {
1539 let escape = EscapeOptions {
1540 escape_single_quote: false,
1541 escape_double_quote: true,
1542 escape_nonascii: true,
1543 };
1544 let repr = escape_bytes(bytes, escape);
1545 Literal::new(bridge::LitKind::ByteStr, &repr, None)
1546 }
1547
1548 #[stable(feature = "proc_macro_c_str_literals", since = "1.79.0")]
1550 pub fn c_string(string: &CStr) -> Literal {
1551 let escape = EscapeOptions {
1552 escape_single_quote: false,
1553 escape_double_quote: true,
1554 escape_nonascii: false,
1555 };
1556 let repr = escape_bytes(string.to_bytes(), escape);
1557 Literal::new(bridge::LitKind::CStr, &repr, None)
1558 }
1559
1560 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1562 pub fn span(&self) -> Span {
1563 Span(self.0.span)
1564 }
1565
1566 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1568 pub fn set_span(&mut self, span: Span) {
1569 self.0.span = span.0;
1570 }
1571
1572 #[unstable(feature = "proc_macro_span", issue = "54725")]
1584 pub fn subspan<R: RangeBounds<usize>>(&self, range: R) -> Option<Span> {
1585 BridgeMethods::span_subspan(
1586 self.0.span,
1587 range.start_bound().cloned(),
1588 range.end_bound().cloned(),
1589 )
1590 .map(Span)
1591 }
1592
1593 fn with_symbol_and_suffix<R>(&self, f: impl FnOnce(&str, &str) -> R) -> R {
1594 self.0.symbol.with(|symbol| match self.0.suffix {
1595 Some(suffix) => suffix.with(|suffix| f(symbol, suffix)),
1596 None => f(symbol, ""),
1597 })
1598 }
1599
1600 fn with_stringify_parts<R>(&self, f: impl FnOnce(&[&str]) -> R) -> R {
1605 fn get_hashes_str(num: u8) -> &'static str {
1609 const HASHES: &str = "\
1610 ################################################################\
1611 ################################################################\
1612 ################################################################\
1613 ################################################################\
1614 ";
1615 const _: () = assert!(HASHES.len() == 256);
1616 &HASHES[..num as usize]
1617 }
1618
1619 self.with_symbol_and_suffix(|symbol, suffix| match self.0.kind {
1620 bridge::LitKind::Byte => f(&["b'", symbol, "'", suffix]),
1621 bridge::LitKind::Char => f(&["'", symbol, "'", suffix]),
1622 bridge::LitKind::Str => f(&["\"", symbol, "\"", suffix]),
1623 bridge::LitKind::StrRaw(n) => {
1624 let hashes = get_hashes_str(n);
1625 f(&["r", hashes, "\"", symbol, "\"", hashes, suffix])
1626 }
1627 bridge::LitKind::ByteStr => f(&["b\"", symbol, "\"", suffix]),
1628 bridge::LitKind::ByteStrRaw(n) => {
1629 let hashes = get_hashes_str(n);
1630 f(&["br", hashes, "\"", symbol, "\"", hashes, suffix])
1631 }
1632 bridge::LitKind::CStr => f(&["c\"", symbol, "\"", suffix]),
1633 bridge::LitKind::CStrRaw(n) => {
1634 let hashes = get_hashes_str(n);
1635 f(&["cr", hashes, "\"", symbol, "\"", hashes, suffix])
1636 }
1637
1638 bridge::LitKind::Integer | bridge::LitKind::Float | bridge::LitKind::ErrWithGuar => {
1639 f(&[symbol, suffix])
1640 }
1641 })
1642 }
1643
1644 #[unstable(feature = "proc_macro_value", issue = "136652")]
1646 pub fn byte_character_value(&self) -> Result<u8, ConversionErrorKind> {
1647 self.0.symbol.with(|symbol| match self.0.kind {
1648 bridge::LitKind::Byte => unescape_byte(symbol)
1649 .map_err(|err| ConversionErrorKind::FailedToUnescape(err.into())),
1650 _ => Err(ConversionErrorKind::InvalidLiteralKind),
1651 })
1652 }
1653
1654 #[unstable(feature = "proc_macro_value", issue = "136652")]
1656 pub fn character_value(&self) -> Result<char, ConversionErrorKind> {
1657 self.0.symbol.with(|symbol| match self.0.kind {
1658 bridge::LitKind::Char => unescape_char(symbol)
1659 .map_err(|err| ConversionErrorKind::FailedToUnescape(err.into())),
1660 _ => Err(ConversionErrorKind::InvalidLiteralKind),
1661 })
1662 }
1663
1664 #[unstable(feature = "proc_macro_value", issue = "136652")]
1666 pub fn str_value(&self) -> Result<String, ConversionErrorKind> {
1667 self.0.symbol.with(|symbol| match self.0.kind {
1668 bridge::LitKind::Str => {
1669 if symbol.contains('\\') {
1670 let mut buf = String::with_capacity(symbol.len());
1671 let mut error = None;
1672 unescape_str(
1676 symbol,
1677 #[inline(always)]
1678 |_, c| match c {
1679 Ok(c) => buf.push(c),
1680 Err(err) => {
1681 if err.is_fatal() {
1682 error = Some(ConversionErrorKind::FailedToUnescape(err.into()));
1683 }
1684 }
1685 },
1686 );
1687 if let Some(error) = error { Err(error) } else { Ok(buf) }
1688 } else {
1689 Ok(symbol.to_string())
1690 }
1691 }
1692 bridge::LitKind::StrRaw(_) => Ok(symbol.to_string()),
1693 _ => Err(ConversionErrorKind::InvalidLiteralKind),
1694 })
1695 }
1696
1697 #[unstable(feature = "proc_macro_value", issue = "136652")]
1700 pub fn cstr_value(&self) -> Result<Vec<u8>, ConversionErrorKind> {
1701 self.0.symbol.with(|symbol| match self.0.kind {
1702 bridge::LitKind::CStr => {
1703 let mut error = None;
1704 let mut buf = Vec::with_capacity(symbol.len());
1705
1706 unescape_c_str(symbol, |_span, res| match res {
1707 Ok(MixedUnit::Char(c)) => {
1708 buf.extend_from_slice(c.get().encode_utf8(&mut [0; 4]).as_bytes())
1709 }
1710 Ok(MixedUnit::HighByte(b)) => buf.push(b.get()),
1711 Err(err) => {
1712 if err.is_fatal() {
1713 error = Some(ConversionErrorKind::FailedToUnescape(err.into()));
1714 }
1715 }
1716 });
1717 if let Some(error) = error {
1718 Err(error)
1719 } else {
1720 buf.push(0);
1721 Ok(buf)
1722 }
1723 }
1724 bridge::LitKind::CStrRaw(_) => {
1725 let mut buf = symbol.to_owned().into_bytes();
1729 buf.push(0);
1730 Ok(buf)
1731 }
1732 _ => Err(ConversionErrorKind::InvalidLiteralKind),
1733 })
1734 }
1735
1736 #[unstable(feature = "proc_macro_value", issue = "136652")]
1739 pub fn byte_str_value(&self) -> Result<Vec<u8>, ConversionErrorKind> {
1740 self.0.symbol.with(|symbol| match self.0.kind {
1741 bridge::LitKind::ByteStr => {
1742 let mut buf = Vec::with_capacity(symbol.len());
1743 let mut error = None;
1744
1745 unescape_byte_str(symbol, |_, res| match res {
1746 Ok(b) => buf.push(b),
1747 Err(err) => {
1748 if err.is_fatal() {
1749 error = Some(ConversionErrorKind::FailedToUnescape(err.into()));
1750 }
1751 }
1752 });
1753 if let Some(error) = error { Err(error) } else { Ok(buf) }
1754 }
1755 bridge::LitKind::ByteStrRaw(_) => {
1756 Ok(symbol.to_owned().into_bytes())
1759 }
1760 _ => Err(ConversionErrorKind::InvalidLiteralKind),
1761 })
1762 }
1763
1764 integer_values! {
1765 u8 => u8_value,
1766 u16 => u16_value,
1767 u32 => u32_value,
1768 u64 => u64_value,
1769 u128 => u128_value,
1770 i8 => i8_value,
1771 i16 => i16_value,
1772 i32 => i32_value,
1773 i64 => i64_value,
1774 i128 => i128_value,
1775 }
1776
1777 float_values! {
1778 f16 => f16_value,
1779 f32 => f32_value,
1780 f64 => f64_value,
1781 }
1785}
1786
1787#[repr(u32)]
1788#[derive(PartialEq, Eq)]
1789enum Base {
1790 Decimal = 10,
1791 Binary = 2,
1792 Octal = 8,
1793 Hexadecimal = 16,
1794}
1795
1796fn parse_number(value: &str) -> (&str, Base) {
1797 let mut iter = value.as_bytes().iter().copied();
1798 let Some(first_digit) = iter.next() else {
1799 return ("0", Base::Decimal);
1800 };
1801 let Some(second_digit) = iter.next() else {
1802 return (value, Base::Decimal);
1803 };
1804
1805 let mut base = Base::Decimal;
1806 if first_digit == b'0' {
1807 match second_digit {
1809 b'b' => {
1810 base = Base::Binary;
1811 }
1812 b'o' => {
1813 base = Base::Octal;
1814 }
1815 b'x' => {
1816 base = Base::Hexadecimal;
1817 }
1818 _ => {}
1819 }
1820 }
1821
1822 let offset = if base == Base::Decimal { 0 } else { 2 };
1823
1824 (&value[offset..], base)
1825}
1826
1827fn strip_underscores(value_s: &str) -> Cow<'_, str> {
1828 let value = value_s.as_bytes();
1829 if value.iter().copied().all(|c| c != b'_' && c != b'f') {
1830 return Cow::Borrowed(value_s);
1831 }
1832 let mut output = String::with_capacity(value.len());
1833 for c in value.iter().copied() {
1834 if c != b'_' {
1835 output.push(c as char);
1836 }
1837 }
1838 Cow::Owned(output)
1839}
1840
1841#[stable(feature = "proc_macro_literal_parse", since = "1.54.0")]
1852impl FromStr for Literal {
1853 type Err = LexError;
1854
1855 fn from_str(src: &str) -> Result<Self, LexError> {
1856 match BridgeMethods::literal_from_str(src) {
1857 Ok(literal) => Ok(Literal(literal)),
1858 Err(msg) => Err(LexError(msg)),
1859 }
1860 }
1861}
1862
1863#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1866impl fmt::Display for Literal {
1867 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1868 self.with_stringify_parts(|parts| {
1869 for part in parts {
1870 fmt::Display::fmt(part, f)?;
1871 }
1872 Ok(())
1873 })
1874 }
1875}
1876
1877#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1878impl fmt::Debug for Literal {
1879 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1880 f.debug_struct("Literal")
1881 .field("kind", &format_args!("{:?}", self.0.kind))
1883 .field("symbol", &self.0.symbol)
1884 .field("suffix", &format_args!("{:?}", self.0.suffix))
1886 .field("span", &self.0.span)
1887 .finish()
1888 }
1889}
1890
1891#[unstable(
1892 feature = "proc_macro_tracked_path",
1893 issue = "99515",
1894 implied_by = "proc_macro_tracked_env"
1895)]
1896pub mod tracked {
1898 use std::env::{self, VarError};
1899 use std::ffi::OsStr;
1900 use std::path::Path;
1901
1902 use crate::BridgeMethods;
1903
1904 #[unstable(feature = "proc_macro_tracked_env", issue = "99515")]
1910 pub fn env_var<K: AsRef<OsStr> + AsRef<str>>(key: K) -> Result<String, VarError> {
1911 let key: &str = key.as_ref();
1912 let value = env::var(key);
1913 BridgeMethods::track_env_var(key, value.as_deref().ok());
1914 value
1915 }
1916
1917 #[unstable(feature = "proc_macro_tracked_path", issue = "99515")]
1921 pub fn path<P: AsRef<Path>>(path: P) {
1922 let path: &str = path.as_ref().to_str().unwrap();
1923 BridgeMethods::track_path(path);
1924 }
1925}