1 use crate::detection
::inside_proc_macro
;
2 use crate::{fallback, Delimiter, Punct, Spacing, TokenTree}
;
3 use core
::fmt
::{self, Debug, Display}
;
4 use core
::iter
::FromIterator
;
5 use core
::ops
::RangeBounds
;
6 use core
::str::FromStr
;
9 use std
::path
::PathBuf
;
12 pub(crate) enum TokenStream
{
13 Compiler(DeferredTokenStream
),
14 Fallback(fallback
::TokenStream
),
17 // Work around https://github.com/rust-lang/rust/issues/65080.
18 // In `impl Extend<TokenTree> for TokenStream` which is used heavily by quote,
19 // we hold on to the appended tokens and do proc_macro::TokenStream::extend as
20 // late as possible to batch together consecutive uses of the Extend impl.
22 pub(crate) struct DeferredTokenStream
{
23 stream
: proc_macro
::TokenStream
,
24 extra
: Vec
<proc_macro
::TokenTree
>,
27 pub(crate) enum LexError
{
28 Compiler(proc_macro
::LexError
),
29 Fallback(fallback
::LexError
),
33 fn call_site() -> Self {
34 LexError
::Fallback(fallback
::LexError
{
35 span
: fallback
::Span
::call_site(),
41 panic
!("stable/nightly mismatch")
44 impl DeferredTokenStream
{
45 fn new(stream
: proc_macro
::TokenStream
) -> Self {
52 fn is_empty(&self) -> bool
{
53 self.stream
.is_empty() && self.extra
.is_empty()
56 fn evaluate_now(&mut self) {
57 // If-check provides a fast short circuit for the common case of `extra`
58 // being empty, which saves a round trip over the proc macro bridge.
59 // Improves macro expansion time in winrt by 6% in debug mode.
60 if !self.extra
.is_empty() {
61 self.stream
.extend(self.extra
.drain(..));
65 fn into_token_stream(mut self) -> proc_macro
::TokenStream
{
72 pub fn new() -> Self {
73 if inside_proc_macro() {
74 TokenStream
::Compiler(DeferredTokenStream
::new(proc_macro
::TokenStream
::new()))
76 TokenStream
::Fallback(fallback
::TokenStream
::new())
80 pub fn is_empty(&self) -> bool
{
82 TokenStream
::Compiler(tts
) => tts
.is_empty(),
83 TokenStream
::Fallback(tts
) => tts
.is_empty(),
87 fn unwrap_nightly(self) -> proc_macro
::TokenStream
{
89 TokenStream
::Compiler(s
) => s
.into_token_stream(),
90 TokenStream
::Fallback(_
) => mismatch(),
94 fn unwrap_stable(self) -> fallback
::TokenStream
{
96 TokenStream
::Compiler(_
) => mismatch(),
97 TokenStream
::Fallback(s
) => s
,
102 impl FromStr
for TokenStream
{
105 fn from_str(src
: &str) -> Result
<TokenStream
, LexError
> {
106 if inside_proc_macro() {
107 Ok(TokenStream
::Compiler(DeferredTokenStream
::new(
108 proc_macro_parse(src
)?
,
111 Ok(TokenStream
::Fallback(src
.parse()?
))
116 // Work around https://github.com/rust-lang/rust/issues/58736.
117 fn proc_macro_parse(src
: &str) -> Result
<proc_macro
::TokenStream
, LexError
> {
118 let result
= panic
::catch_unwind(|| src
.parse().map_err(LexError
::Compiler
));
119 result
.unwrap_or_else(|_
| Err(LexError
::call_site()))
122 impl Display
for TokenStream
{
123 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
125 TokenStream
::Compiler(tts
) => Display
::fmt(&tts
.clone().into_token_stream(), f
),
126 TokenStream
::Fallback(tts
) => Display
::fmt(tts
, f
),
131 impl From
<proc_macro
::TokenStream
> for TokenStream
{
132 fn from(inner
: proc_macro
::TokenStream
) -> TokenStream
{
133 TokenStream
::Compiler(DeferredTokenStream
::new(inner
))
137 impl From
<TokenStream
> for proc_macro
::TokenStream
{
138 fn from(inner
: TokenStream
) -> proc_macro
::TokenStream
{
140 TokenStream
::Compiler(inner
) => inner
.into_token_stream(),
141 TokenStream
::Fallback(inner
) => inner
.to_string().parse().unwrap(),
146 impl From
<fallback
::TokenStream
> for TokenStream
{
147 fn from(inner
: fallback
::TokenStream
) -> TokenStream
{
148 TokenStream
::Fallback(inner
)
152 // Assumes inside_proc_macro().
153 fn into_compiler_token(token
: TokenTree
) -> proc_macro
::TokenTree
{
155 TokenTree
::Group(tt
) => tt
.inner
.unwrap_nightly().into(),
156 TokenTree
::Punct(tt
) => {
157 let spacing
= match tt
.spacing() {
158 Spacing
::Joint
=> proc_macro
::Spacing
::Joint
,
159 Spacing
::Alone
=> proc_macro
::Spacing
::Alone
,
161 let mut punct
= proc_macro
::Punct
::new(tt
.as_char(), spacing
);
162 punct
.set_span(tt
.span().inner
.unwrap_nightly());
165 TokenTree
::Ident(tt
) => tt
.inner
.unwrap_nightly().into(),
166 TokenTree
::Literal(tt
) => tt
.inner
.unwrap_nightly().into(),
170 impl From
<TokenTree
> for TokenStream
{
171 fn from(token
: TokenTree
) -> TokenStream
{
172 if inside_proc_macro() {
173 TokenStream
::Compiler(DeferredTokenStream
::new(into_compiler_token(token
).into()))
175 TokenStream
::Fallback(token
.into())
180 impl FromIterator
<TokenTree
> for TokenStream
{
181 fn from_iter
<I
: IntoIterator
<Item
= TokenTree
>>(trees
: I
) -> Self {
182 if inside_proc_macro() {
183 TokenStream
::Compiler(DeferredTokenStream
::new(
184 trees
.into_iter().map(into_compiler_token
).collect(),
187 TokenStream
::Fallback(trees
.into_iter().collect())
192 impl FromIterator
<TokenStream
> for TokenStream
{
193 fn from_iter
<I
: IntoIterator
<Item
= TokenStream
>>(streams
: I
) -> Self {
194 let mut streams
= streams
.into_iter();
195 match streams
.next() {
196 Some(TokenStream
::Compiler(mut first
)) => {
197 first
.evaluate_now();
198 first
.stream
.extend(streams
.map(|s
| match s
{
199 TokenStream
::Compiler(s
) => s
.into_token_stream(),
200 TokenStream
::Fallback(_
) => mismatch(),
202 TokenStream
::Compiler(first
)
204 Some(TokenStream
::Fallback(mut first
)) => {
205 first
.extend(streams
.map(|s
| match s
{
206 TokenStream
::Fallback(s
) => s
,
207 TokenStream
::Compiler(_
) => mismatch(),
209 TokenStream
::Fallback(first
)
211 None
=> TokenStream
::new(),
216 impl Extend
<TokenTree
> for TokenStream
{
217 fn extend
<I
: IntoIterator
<Item
= TokenTree
>>(&mut self, stream
: I
) {
219 TokenStream
::Compiler(tts
) => {
220 // Here is the reason for DeferredTokenStream.
221 for token
in stream
{
222 tts
.extra
.push(into_compiler_token(token
));
225 TokenStream
::Fallback(tts
) => tts
.extend(stream
),
230 impl Extend
<TokenStream
> for TokenStream
{
231 fn extend
<I
: IntoIterator
<Item
= TokenStream
>>(&mut self, streams
: I
) {
233 TokenStream
::Compiler(tts
) => {
236 .extend(streams
.into_iter().map(TokenStream
::unwrap_nightly
));
238 TokenStream
::Fallback(tts
) => {
239 tts
.extend(streams
.into_iter().map(TokenStream
::unwrap_stable
));
245 impl Debug
for TokenStream
{
246 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
248 TokenStream
::Compiler(tts
) => Debug
::fmt(&tts
.clone().into_token_stream(), f
),
249 TokenStream
::Fallback(tts
) => Debug
::fmt(tts
, f
),
255 pub(crate) fn span(&self) -> Span
{
257 LexError
::Compiler(_
) => Span
::call_site(),
258 LexError
::Fallback(e
) => Span
::Fallback(e
.span()),
263 impl From
<proc_macro
::LexError
> for LexError
{
264 fn from(e
: proc_macro
::LexError
) -> LexError
{
265 LexError
::Compiler(e
)
269 impl From
<fallback
::LexError
> for LexError
{
270 fn from(e
: fallback
::LexError
) -> LexError
{
271 LexError
::Fallback(e
)
275 impl Debug
for LexError
{
276 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
278 LexError
::Compiler(e
) => Debug
::fmt(e
, f
),
279 LexError
::Fallback(e
) => Debug
::fmt(e
, f
),
284 impl Display
for LexError
{
285 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
287 #[cfg(not(no_lexerror_display))]
288 LexError
::Compiler(e
) => Display
::fmt(e
, f
),
289 #[cfg(no_lexerror_display)]
290 LexError
::Compiler(_e
) => Display
::fmt(
291 &fallback
::LexError
{
292 span
: fallback
::Span
::call_site(),
296 LexError
::Fallback(e
) => Display
::fmt(e
, f
),
302 pub(crate) enum TokenTreeIter
{
303 Compiler(proc_macro
::token_stream
::IntoIter
),
304 Fallback(fallback
::TokenTreeIter
),
307 impl IntoIterator
for TokenStream
{
308 type Item
= TokenTree
;
309 type IntoIter
= TokenTreeIter
;
311 fn into_iter(self) -> TokenTreeIter
{
313 TokenStream
::Compiler(tts
) => {
314 TokenTreeIter
::Compiler(tts
.into_token_stream().into_iter())
316 TokenStream
::Fallback(tts
) => TokenTreeIter
::Fallback(tts
.into_iter()),
321 impl Iterator
for TokenTreeIter
{
322 type Item
= TokenTree
;
324 fn next(&mut self) -> Option
<TokenTree
> {
325 let token
= match self {
326 TokenTreeIter
::Compiler(iter
) => iter
.next()?
,
327 TokenTreeIter
::Fallback(iter
) => return iter
.next(),
330 proc_macro
::TokenTree
::Group(tt
) => crate::Group
::_new(Group
::Compiler(tt
)).into(),
331 proc_macro
::TokenTree
::Punct(tt
) => {
332 let spacing
= match tt
.spacing() {
333 proc_macro
::Spacing
::Joint
=> Spacing
::Joint
,
334 proc_macro
::Spacing
::Alone
=> Spacing
::Alone
,
336 let mut o
= Punct
::new(tt
.as_char(), spacing
);
337 o
.set_span(crate::Span
::_new(Span
::Compiler(tt
.span())));
340 proc_macro
::TokenTree
::Ident(s
) => crate::Ident
::_new(Ident
::Compiler(s
)).into(),
341 proc_macro
::TokenTree
::Literal(l
) => crate::Literal
::_new(Literal
::Compiler(l
)).into(),
345 fn size_hint(&self) -> (usize, Option
<usize>) {
347 TokenTreeIter
::Compiler(tts
) => tts
.size_hint(),
348 TokenTreeIter
::Fallback(tts
) => tts
.size_hint(),
353 #[derive(Clone, PartialEq, Eq)]
354 #[cfg(super_unstable)]
355 pub(crate) enum SourceFile
{
356 Compiler(proc_macro
::SourceFile
),
357 Fallback(fallback
::SourceFile
),
360 #[cfg(super_unstable)]
362 fn nightly(sf
: proc_macro
::SourceFile
) -> Self {
363 SourceFile
::Compiler(sf
)
366 /// Get the path to this source file as a string.
367 pub fn path(&self) -> PathBuf
{
369 SourceFile
::Compiler(a
) => a
.path(),
370 SourceFile
::Fallback(a
) => a
.path(),
374 pub fn is_real(&self) -> bool
{
376 SourceFile
::Compiler(a
) => a
.is_real(),
377 SourceFile
::Fallback(a
) => a
.is_real(),
382 #[cfg(super_unstable)]
383 impl Debug
for SourceFile
{
384 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
386 SourceFile
::Compiler(a
) => Debug
::fmt(a
, f
),
387 SourceFile
::Fallback(a
) => Debug
::fmt(a
, f
),
392 #[cfg(any(super_unstable, feature = "span-locations"))]
393 pub(crate) struct LineColumn
{
398 #[derive(Copy, Clone)]
399 pub(crate) enum Span
{
400 Compiler(proc_macro
::Span
),
401 Fallback(fallback
::Span
),
405 pub fn call_site() -> Self {
406 if inside_proc_macro() {
407 Span
::Compiler(proc_macro
::Span
::call_site())
409 Span
::Fallback(fallback
::Span
::call_site())
413 #[cfg(not(no_hygiene))]
414 pub fn mixed_site() -> Self {
415 if inside_proc_macro() {
416 Span
::Compiler(proc_macro
::Span
::mixed_site())
418 Span
::Fallback(fallback
::Span
::mixed_site())
422 #[cfg(super_unstable)]
423 pub fn def_site() -> Self {
424 if inside_proc_macro() {
425 Span
::Compiler(proc_macro
::Span
::def_site())
427 Span
::Fallback(fallback
::Span
::def_site())
431 pub fn resolved_at(&self, other
: Span
) -> Span
{
432 match (self, other
) {
433 #[cfg(not(no_hygiene))]
434 (Span
::Compiler(a
), Span
::Compiler(b
)) => Span
::Compiler(a
.resolved_at(b
)),
436 // Name resolution affects semantics, but location is only cosmetic
438 (Span
::Compiler(_
), Span
::Compiler(_
)) => other
,
440 (Span
::Fallback(a
), Span
::Fallback(b
)) => Span
::Fallback(a
.resolved_at(b
)),
445 pub fn located_at(&self, other
: Span
) -> Span
{
446 match (self, other
) {
447 #[cfg(not(no_hygiene))]
448 (Span
::Compiler(a
), Span
::Compiler(b
)) => Span
::Compiler(a
.located_at(b
)),
450 // Name resolution affects semantics, but location is only cosmetic
452 (Span
::Compiler(_
), Span
::Compiler(_
)) => *self,
454 (Span
::Fallback(a
), Span
::Fallback(b
)) => Span
::Fallback(a
.located_at(b
)),
459 pub fn unwrap(self) -> proc_macro
::Span
{
461 Span
::Compiler(s
) => s
,
462 Span
::Fallback(_
) => panic
!("proc_macro::Span is only available in procedural macros"),
466 #[cfg(super_unstable)]
467 pub fn source_file(&self) -> SourceFile
{
469 Span
::Compiler(s
) => SourceFile
::nightly(s
.source_file()),
470 Span
::Fallback(s
) => SourceFile
::Fallback(s
.source_file()),
474 #[cfg(any(super_unstable, feature = "span-locations"))]
475 pub fn start(&self) -> LineColumn
{
477 #[cfg(proc_macro_span)]
478 Span
::Compiler(s
) => {
479 let proc_macro
::LineColumn { line, column }
= s
.start();
480 LineColumn { line, column }
482 #[cfg(not(proc_macro_span))]
483 Span
::Compiler(_
) => LineColumn { line: 0, column: 0 }
,
484 Span
::Fallback(s
) => {
485 let fallback
::LineColumn { line, column }
= s
.start();
486 LineColumn { line, column }
491 #[cfg(any(super_unstable, feature = "span-locations"))]
492 pub fn end(&self) -> LineColumn
{
494 #[cfg(proc_macro_span)]
495 Span
::Compiler(s
) => {
496 let proc_macro
::LineColumn { line, column }
= s
.end();
497 LineColumn { line, column }
499 #[cfg(not(proc_macro_span))]
500 Span
::Compiler(_
) => LineColumn { line: 0, column: 0 }
,
501 Span
::Fallback(s
) => {
502 let fallback
::LineColumn { line, column }
= s
.end();
503 LineColumn { line, column }
508 #[cfg(super_unstable)]
509 pub fn before(&self) -> Span
{
511 Span
::Compiler(s
) => Span
::Compiler(s
.before()),
512 Span
::Fallback(s
) => Span
::Fallback(s
.before()),
516 #[cfg(super_unstable)]
517 pub fn after(&self) -> Span
{
519 Span
::Compiler(s
) => Span
::Compiler(s
.after()),
520 Span
::Fallback(s
) => Span
::Fallback(s
.after()),
524 pub fn join(&self, other
: Span
) -> Option
<Span
> {
525 let ret
= match (self, other
) {
526 #[cfg(proc_macro_span)]
527 (Span
::Compiler(a
), Span
::Compiler(b
)) => Span
::Compiler(a
.join(b
)?
),
528 (Span
::Fallback(a
), Span
::Fallback(b
)) => Span
::Fallback(a
.join(b
)?
),
534 #[cfg(super_unstable)]
535 pub fn eq(&self, other
: &Span
) -> bool
{
536 match (self, other
) {
537 (Span
::Compiler(a
), Span
::Compiler(b
)) => a
.eq(b
),
538 (Span
::Fallback(a
), Span
::Fallback(b
)) => a
.eq(b
),
543 fn unwrap_nightly(self) -> proc_macro
::Span
{
545 Span
::Compiler(s
) => s
,
546 Span
::Fallback(_
) => mismatch(),
551 impl From
<proc_macro
::Span
> for crate::Span
{
552 fn from(proc_span
: proc_macro
::Span
) -> crate::Span
{
553 crate::Span
::_new(Span
::Compiler(proc_span
))
557 impl From
<fallback
::Span
> for Span
{
558 fn from(inner
: fallback
::Span
) -> Span
{
559 Span
::Fallback(inner
)
563 impl Debug
for Span
{
564 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
566 Span
::Compiler(s
) => Debug
::fmt(s
, f
),
567 Span
::Fallback(s
) => Debug
::fmt(s
, f
),
572 pub(crate) fn debug_span_field_if_nontrivial(debug
: &mut fmt
::DebugStruct
, span
: Span
) {
574 Span
::Compiler(s
) => {
575 debug
.field("span", &s
);
577 Span
::Fallback(s
) => fallback
::debug_span_field_if_nontrivial(debug
, s
),
582 pub(crate) enum Group
{
583 Compiler(proc_macro
::Group
),
584 Fallback(fallback
::Group
),
588 pub fn new(delimiter
: Delimiter
, stream
: TokenStream
) -> Self {
590 TokenStream
::Compiler(tts
) => {
591 let delimiter
= match delimiter
{
592 Delimiter
::Parenthesis
=> proc_macro
::Delimiter
::Parenthesis
,
593 Delimiter
::Bracket
=> proc_macro
::Delimiter
::Bracket
,
594 Delimiter
::Brace
=> proc_macro
::Delimiter
::Brace
,
595 Delimiter
::None
=> proc_macro
::Delimiter
::None
,
597 Group
::Compiler(proc_macro
::Group
::new(delimiter
, tts
.into_token_stream()))
599 TokenStream
::Fallback(stream
) => {
600 Group
::Fallback(fallback
::Group
::new(delimiter
, stream
))
605 pub fn delimiter(&self) -> Delimiter
{
607 Group
::Compiler(g
) => match g
.delimiter() {
608 proc_macro
::Delimiter
::Parenthesis
=> Delimiter
::Parenthesis
,
609 proc_macro
::Delimiter
::Bracket
=> Delimiter
::Bracket
,
610 proc_macro
::Delimiter
::Brace
=> Delimiter
::Brace
,
611 proc_macro
::Delimiter
::None
=> Delimiter
::None
,
613 Group
::Fallback(g
) => g
.delimiter(),
617 pub fn stream(&self) -> TokenStream
{
619 Group
::Compiler(g
) => TokenStream
::Compiler(DeferredTokenStream
::new(g
.stream())),
620 Group
::Fallback(g
) => TokenStream
::Fallback(g
.stream()),
624 pub fn span(&self) -> Span
{
626 Group
::Compiler(g
) => Span
::Compiler(g
.span()),
627 Group
::Fallback(g
) => Span
::Fallback(g
.span()),
631 pub fn span_open(&self) -> Span
{
633 #[cfg(not(no_group_open_close))]
634 Group
::Compiler(g
) => Span
::Compiler(g
.span_open()),
635 #[cfg(no_group_open_close)]
636 Group
::Compiler(g
) => Span
::Compiler(g
.span()),
637 Group
::Fallback(g
) => Span
::Fallback(g
.span_open()),
641 pub fn span_close(&self) -> Span
{
643 #[cfg(not(no_group_open_close))]
644 Group
::Compiler(g
) => Span
::Compiler(g
.span_close()),
645 #[cfg(no_group_open_close)]
646 Group
::Compiler(g
) => Span
::Compiler(g
.span()),
647 Group
::Fallback(g
) => Span
::Fallback(g
.span_close()),
651 pub fn set_span(&mut self, span
: Span
) {
653 (Group
::Compiler(g
), Span
::Compiler(s
)) => g
.set_span(s
),
654 (Group
::Fallback(g
), Span
::Fallback(s
)) => g
.set_span(s
),
659 fn unwrap_nightly(self) -> proc_macro
::Group
{
661 Group
::Compiler(g
) => g
,
662 Group
::Fallback(_
) => mismatch(),
667 impl From
<fallback
::Group
> for Group
{
668 fn from(g
: fallback
::Group
) -> Self {
673 impl Display
for Group
{
674 fn fmt(&self, formatter
: &mut fmt
::Formatter
) -> fmt
::Result
{
676 Group
::Compiler(group
) => Display
::fmt(group
, formatter
),
677 Group
::Fallback(group
) => Display
::fmt(group
, formatter
),
682 impl Debug
for Group
{
683 fn fmt(&self, formatter
: &mut fmt
::Formatter
) -> fmt
::Result
{
685 Group
::Compiler(group
) => Debug
::fmt(group
, formatter
),
686 Group
::Fallback(group
) => Debug
::fmt(group
, formatter
),
692 pub(crate) enum Ident
{
693 Compiler(proc_macro
::Ident
),
694 Fallback(fallback
::Ident
),
698 pub fn new(string
: &str, span
: Span
) -> Self {
700 Span
::Compiler(s
) => Ident
::Compiler(proc_macro
::Ident
::new(string
, s
)),
701 Span
::Fallback(s
) => Ident
::Fallback(fallback
::Ident
::new(string
, s
)),
705 pub fn new_raw(string
: &str, span
: Span
) -> Self {
707 #[cfg(not(no_ident_new_raw))]
708 Span
::Compiler(s
) => Ident
::Compiler(proc_macro
::Ident
::new_raw(string
, s
)),
709 #[cfg(no_ident_new_raw)]
710 Span
::Compiler(s
) => {
711 let _
= proc_macro
::Ident
::new(string
, s
);
712 // At this point the un-r#-prefixed string is known to be a
713 // valid identifier. Try to produce a valid raw identifier by
714 // running the `TokenStream` parser, and unwrapping the first
715 // token as an `Ident`.
716 let raw_prefixed
= format
!("r#{}", string
);
717 if let Ok(ts
) = raw_prefixed
.parse
::<proc_macro
::TokenStream
>() {
718 let mut iter
= ts
.into_iter();
719 if let (Some(proc_macro
::TokenTree
::Ident(mut id
)), None
) =
720 (iter
.next(), iter
.next())
723 return Ident
::Compiler(id
);
726 panic
!("not allowed as a raw identifier: `{}`", raw_prefixed
)
728 Span
::Fallback(s
) => Ident
::Fallback(fallback
::Ident
::new_raw(string
, s
)),
732 pub fn span(&self) -> Span
{
734 Ident
::Compiler(t
) => Span
::Compiler(t
.span()),
735 Ident
::Fallback(t
) => Span
::Fallback(t
.span()),
739 pub fn set_span(&mut self, span
: Span
) {
741 (Ident
::Compiler(t
), Span
::Compiler(s
)) => t
.set_span(s
),
742 (Ident
::Fallback(t
), Span
::Fallback(s
)) => t
.set_span(s
),
747 fn unwrap_nightly(self) -> proc_macro
::Ident
{
749 Ident
::Compiler(s
) => s
,
750 Ident
::Fallback(_
) => mismatch(),
755 impl PartialEq
for Ident
{
756 fn eq(&self, other
: &Ident
) -> bool
{
757 match (self, other
) {
758 (Ident
::Compiler(t
), Ident
::Compiler(o
)) => t
.to_string() == o
.to_string(),
759 (Ident
::Fallback(t
), Ident
::Fallback(o
)) => t
== o
,
765 impl<T
> PartialEq
<T
> for Ident
767 T
: ?Sized
+ AsRef
<str>,
769 fn eq(&self, other
: &T
) -> bool
{
770 let other
= other
.as_ref();
772 Ident
::Compiler(t
) => t
.to_string() == other
,
773 Ident
::Fallback(t
) => t
== other
,
778 impl Display
for Ident
{
779 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
781 Ident
::Compiler(t
) => Display
::fmt(t
, f
),
782 Ident
::Fallback(t
) => Display
::fmt(t
, f
),
787 impl Debug
for Ident
{
788 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
790 Ident
::Compiler(t
) => Debug
::fmt(t
, f
),
791 Ident
::Fallback(t
) => Debug
::fmt(t
, f
),
797 pub(crate) enum Literal
{
798 Compiler(proc_macro
::Literal
),
799 Fallback(fallback
::Literal
),
802 macro_rules
! suffixed_numbers
{
803 ($
($name
:ident
=> $kind
:ident
,)*) => ($
(
804 pub fn $
name(n
: $kind
) -> Literal
{
805 if inside_proc_macro() {
806 Literal
::Compiler(proc_macro
::Literal
::$
name(n
))
808 Literal
::Fallback(fallback
::Literal
::$
name(n
))
814 macro_rules
! unsuffixed_integers
{
815 ($
($name
:ident
=> $kind
:ident
,)*) => ($
(
816 pub fn $
name(n
: $kind
) -> Literal
{
817 if inside_proc_macro() {
818 Literal
::Compiler(proc_macro
::Literal
::$
name(n
))
820 Literal
::Fallback(fallback
::Literal
::$
name(n
))
827 pub unsafe fn from_str_unchecked(repr
: &str) -> Self {
828 if inside_proc_macro() {
829 Literal
::Compiler(compiler_literal_from_str(repr
).expect("invalid literal"))
831 Literal
::Fallback(fallback
::Literal
::from_str_unchecked(repr
))
840 u128_suffixed
=> u128
,
841 usize_suffixed
=> usize,
846 i128_suffixed
=> i128
,
847 isize_suffixed
=> isize,
853 unsuffixed_integers
! {
855 u16_unsuffixed
=> u16,
856 u32_unsuffixed
=> u32,
857 u64_unsuffixed
=> u64,
858 u128_unsuffixed
=> u128
,
859 usize_unsuffixed
=> usize,
861 i16_unsuffixed
=> i16,
862 i32_unsuffixed
=> i32,
863 i64_unsuffixed
=> i64,
864 i128_unsuffixed
=> i128
,
865 isize_unsuffixed
=> isize,
868 pub fn f32_unsuffixed(f
: f32) -> Literal
{
869 if inside_proc_macro() {
870 Literal
::Compiler(proc_macro
::Literal
::f32_unsuffixed(f
))
872 Literal
::Fallback(fallback
::Literal
::f32_unsuffixed(f
))
876 pub fn f64_unsuffixed(f
: f64) -> Literal
{
877 if inside_proc_macro() {
878 Literal
::Compiler(proc_macro
::Literal
::f64_unsuffixed(f
))
880 Literal
::Fallback(fallback
::Literal
::f64_unsuffixed(f
))
884 pub fn string(t
: &str) -> Literal
{
885 if inside_proc_macro() {
886 Literal
::Compiler(proc_macro
::Literal
::string(t
))
888 Literal
::Fallback(fallback
::Literal
::string(t
))
892 pub fn character(t
: char) -> Literal
{
893 if inside_proc_macro() {
894 Literal
::Compiler(proc_macro
::Literal
::character(t
))
896 Literal
::Fallback(fallback
::Literal
::character(t
))
900 pub fn byte_string(bytes
: &[u8]) -> Literal
{
901 if inside_proc_macro() {
902 Literal
::Compiler(proc_macro
::Literal
::byte_string(bytes
))
904 Literal
::Fallback(fallback
::Literal
::byte_string(bytes
))
908 pub fn span(&self) -> Span
{
910 Literal
::Compiler(lit
) => Span
::Compiler(lit
.span()),
911 Literal
::Fallback(lit
) => Span
::Fallback(lit
.span()),
915 pub fn set_span(&mut self, span
: Span
) {
917 (Literal
::Compiler(lit
), Span
::Compiler(s
)) => lit
.set_span(s
),
918 (Literal
::Fallback(lit
), Span
::Fallback(s
)) => lit
.set_span(s
),
923 pub fn subspan
<R
: RangeBounds
<usize>>(&self, range
: R
) -> Option
<Span
> {
925 #[cfg(proc_macro_span)]
926 Literal
::Compiler(lit
) => lit
.subspan(range
).map(Span
::Compiler
),
927 #[cfg(not(proc_macro_span))]
928 Literal
::Compiler(_lit
) => None
,
929 Literal
::Fallback(lit
) => lit
.subspan(range
).map(Span
::Fallback
),
933 fn unwrap_nightly(self) -> proc_macro
::Literal
{
935 Literal
::Compiler(s
) => s
,
936 Literal
::Fallback(_
) => mismatch(),
941 impl From
<fallback
::Literal
> for Literal
{
942 fn from(s
: fallback
::Literal
) -> Literal
{
947 impl FromStr
for Literal
{
950 fn from_str(repr
: &str) -> Result
<Self, Self::Err
> {
951 if inside_proc_macro() {
952 compiler_literal_from_str(repr
).map(Literal
::Compiler
)
954 let literal
= fallback
::Literal
::from_str(repr
)?
;
955 Ok(Literal
::Fallback(literal
))
960 fn compiler_literal_from_str(repr
: &str) -> Result
<proc_macro
::Literal
, LexError
> {
961 #[cfg(not(no_literal_from_str))]
963 proc_macro
::Literal
::from_str(repr
).map_err(LexError
::Compiler
)
965 #[cfg(no_literal_from_str)]
967 let tokens
= proc_macro_parse(repr
)?
;
968 let mut iter
= tokens
.into_iter();
969 if let (Some(proc_macro
::TokenTree
::Literal(literal
)), None
) = (iter
.next(), iter
.next()) {
970 if literal
.to_string().len() == repr
.len() {
974 Err(LexError
::call_site())
978 impl Display
for Literal
{
979 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
981 Literal
::Compiler(t
) => Display
::fmt(t
, f
),
982 Literal
::Fallback(t
) => Display
::fmt(t
, f
),
987 impl Debug
for Literal
{
988 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
990 Literal
::Compiler(t
) => Debug
::fmt(t
, f
),
991 Literal
::Fallback(t
) => Debug
::fmt(t
, f
),