]> git.proxmox.com Git - rustc.git/blob - vendor/syn/src/lit.rs
New upstream version 1.55.0+dfsg1
[rustc.git] / vendor / syn / src / lit.rs
1 #[cfg(feature = "parsing")]
2 use crate::lookahead;
3 #[cfg(feature = "parsing")]
4 use crate::parse::{Parse, Parser};
5 use crate::{Error, Result};
6 #[cfg(feature = "printing")]
7 use proc_macro2::Ident;
8 #[cfg(feature = "parsing")]
9 use proc_macro2::TokenStream;
10 use proc_macro2::TokenTree;
11 use proc_macro2::{Literal, Span};
12 use std::fmt::{self, Display};
13 #[cfg(feature = "extra-traits")]
14 use std::hash::{Hash, Hasher};
15 use std::str::{self, FromStr};
16
17 ast_enum_of_structs! {
18 /// A Rust literal such as a string or integer or boolean.
19 ///
20 /// # Syntax tree enum
21 ///
22 /// This type is a [syntax tree enum].
23 ///
24 /// [syntax tree enum]: crate::Expr#syntax-tree-enums
25 pub enum Lit {
26 /// A UTF-8 string literal: `"foo"`.
27 Str(LitStr),
28
29 /// A byte string literal: `b"foo"`.
30 ByteStr(LitByteStr),
31
32 /// A byte literal: `b'f'`.
33 Byte(LitByte),
34
35 /// A character literal: `'a'`.
36 Char(LitChar),
37
38 /// An integer literal: `1` or `1u16`.
39 Int(LitInt),
40
41 /// A floating point literal: `1f64` or `1.0e10f64`.
42 ///
43 /// Must be finite. May not be infinite or NaN.
44 Float(LitFloat),
45
46 /// A boolean literal: `true` or `false`.
47 Bool(LitBool),
48
49 /// A raw token literal not interpreted by Syn.
50 Verbatim(Literal),
51 }
52 }
53
54 ast_struct! {
55 /// A UTF-8 string literal: `"foo"`.
56 pub struct LitStr {
57 repr: Box<LitRepr>,
58 }
59 }
60
61 ast_struct! {
62 /// A byte string literal: `b"foo"`.
63 pub struct LitByteStr {
64 repr: Box<LitRepr>,
65 }
66 }
67
68 ast_struct! {
69 /// A byte literal: `b'f'`.
70 pub struct LitByte {
71 repr: Box<LitRepr>,
72 }
73 }
74
75 ast_struct! {
76 /// A character literal: `'a'`.
77 pub struct LitChar {
78 repr: Box<LitRepr>,
79 }
80 }
81
82 struct LitRepr {
83 token: Literal,
84 suffix: Box<str>,
85 }
86
87 ast_struct! {
88 /// An integer literal: `1` or `1u16`.
89 pub struct LitInt {
90 repr: Box<LitIntRepr>,
91 }
92 }
93
94 struct LitIntRepr {
95 token: Literal,
96 digits: Box<str>,
97 suffix: Box<str>,
98 }
99
100 ast_struct! {
101 /// A floating point literal: `1f64` or `1.0e10f64`.
102 ///
103 /// Must be finite. May not be infinite or NaN.
104 pub struct LitFloat {
105 repr: Box<LitFloatRepr>,
106 }
107 }
108
109 struct LitFloatRepr {
110 token: Literal,
111 digits: Box<str>,
112 suffix: Box<str>,
113 }
114
115 ast_struct! {
116 /// A boolean literal: `true` or `false`.
117 pub struct LitBool {
118 pub value: bool,
119 pub span: Span,
120 }
121 }
122
123 impl LitStr {
124 pub fn new(value: &str, span: Span) -> Self {
125 let mut token = Literal::string(value);
126 token.set_span(span);
127 LitStr {
128 repr: Box::new(LitRepr {
129 token,
130 suffix: Box::<str>::default(),
131 }),
132 }
133 }
134
135 pub fn value(&self) -> String {
136 let repr = self.repr.token.to_string();
137 let (value, _suffix) = value::parse_lit_str(&repr);
138 String::from(value)
139 }
140
141 /// Parse a syntax tree node from the content of this string literal.
142 ///
143 /// All spans in the syntax tree will point to the span of this `LitStr`.
144 ///
145 /// # Example
146 ///
147 /// ```
148 /// use proc_macro2::Span;
149 /// use syn::{Attribute, Error, Ident, Lit, Meta, MetaNameValue, Path, Result};
150 ///
151 /// // Parses the path from an attribute that looks like:
152 /// //
153 /// // #[path = "a::b::c"]
154 /// //
155 /// // or returns `None` if the input is some other attribute.
156 /// fn get_path(attr: &Attribute) -> Result<Option<Path>> {
157 /// if !attr.path.is_ident("path") {
158 /// return Ok(None);
159 /// }
160 ///
161 /// match attr.parse_meta()? {
162 /// Meta::NameValue(MetaNameValue { lit: Lit::Str(lit_str), .. }) => {
163 /// lit_str.parse().map(Some)
164 /// }
165 /// _ => {
166 /// let message = "expected #[path = \"...\"]";
167 /// Err(Error::new_spanned(attr, message))
168 /// }
169 /// }
170 /// }
171 /// ```
172 #[cfg(feature = "parsing")]
173 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
174 pub fn parse<T: Parse>(&self) -> Result<T> {
175 self.parse_with(T::parse)
176 }
177
178 /// Invoke parser on the content of this string literal.
179 ///
180 /// All spans in the syntax tree will point to the span of this `LitStr`.
181 ///
182 /// # Example
183 ///
184 /// ```
185 /// # use proc_macro2::Span;
186 /// # use syn::{LitStr, Result};
187 /// #
188 /// # fn main() -> Result<()> {
189 /// # let lit_str = LitStr::new("a::b::c", Span::call_site());
190 /// #
191 /// # const IGNORE: &str = stringify! {
192 /// let lit_str: LitStr = /* ... */;
193 /// # };
194 ///
195 /// // Parse a string literal like "a::b::c" into a Path, not allowing
196 /// // generic arguments on any of the path segments.
197 /// let basic_path = lit_str.parse_with(syn::Path::parse_mod_style)?;
198 /// #
199 /// # Ok(())
200 /// # }
201 /// ```
202 #[cfg(feature = "parsing")]
203 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
204 pub fn parse_with<F: Parser>(&self, parser: F) -> Result<F::Output> {
205 use proc_macro2::Group;
206
207 // Token stream with every span replaced by the given one.
208 fn respan_token_stream(stream: TokenStream, span: Span) -> TokenStream {
209 stream
210 .into_iter()
211 .map(|token| respan_token_tree(token, span))
212 .collect()
213 }
214
215 // Token tree with every span replaced by the given one.
216 fn respan_token_tree(mut token: TokenTree, span: Span) -> TokenTree {
217 match &mut token {
218 TokenTree::Group(g) => {
219 let stream = respan_token_stream(g.stream(), span);
220 *g = Group::new(g.delimiter(), stream);
221 g.set_span(span);
222 }
223 other => other.set_span(span),
224 }
225 token
226 }
227
228 // Parse string literal into a token stream with every span equal to the
229 // original literal's span.
230 let mut tokens = crate::parse_str(&self.value())?;
231 tokens = respan_token_stream(tokens, self.span());
232
233 parser.parse2(tokens)
234 }
235
236 pub fn span(&self) -> Span {
237 self.repr.token.span()
238 }
239
240 pub fn set_span(&mut self, span: Span) {
241 self.repr.token.set_span(span);
242 }
243
244 pub fn suffix(&self) -> &str {
245 &self.repr.suffix
246 }
247 }
248
249 impl LitByteStr {
250 pub fn new(value: &[u8], span: Span) -> Self {
251 let mut token = Literal::byte_string(value);
252 token.set_span(span);
253 LitByteStr {
254 repr: Box::new(LitRepr {
255 token,
256 suffix: Box::<str>::default(),
257 }),
258 }
259 }
260
261 pub fn value(&self) -> Vec<u8> {
262 let repr = self.repr.token.to_string();
263 let (value, _suffix) = value::parse_lit_byte_str(&repr);
264 value
265 }
266
267 pub fn span(&self) -> Span {
268 self.repr.token.span()
269 }
270
271 pub fn set_span(&mut self, span: Span) {
272 self.repr.token.set_span(span);
273 }
274
275 pub fn suffix(&self) -> &str {
276 &self.repr.suffix
277 }
278 }
279
280 impl LitByte {
281 pub fn new(value: u8, span: Span) -> Self {
282 let mut token = Literal::u8_suffixed(value);
283 token.set_span(span);
284 LitByte {
285 repr: Box::new(LitRepr {
286 token,
287 suffix: Box::<str>::default(),
288 }),
289 }
290 }
291
292 pub fn value(&self) -> u8 {
293 let repr = self.repr.token.to_string();
294 let (value, _suffix) = value::parse_lit_byte(&repr);
295 value
296 }
297
298 pub fn span(&self) -> Span {
299 self.repr.token.span()
300 }
301
302 pub fn set_span(&mut self, span: Span) {
303 self.repr.token.set_span(span);
304 }
305
306 pub fn suffix(&self) -> &str {
307 &self.repr.suffix
308 }
309 }
310
311 impl LitChar {
312 pub fn new(value: char, span: Span) -> Self {
313 let mut token = Literal::character(value);
314 token.set_span(span);
315 LitChar {
316 repr: Box::new(LitRepr {
317 token,
318 suffix: Box::<str>::default(),
319 }),
320 }
321 }
322
323 pub fn value(&self) -> char {
324 let repr = self.repr.token.to_string();
325 let (value, _suffix) = value::parse_lit_char(&repr);
326 value
327 }
328
329 pub fn span(&self) -> Span {
330 self.repr.token.span()
331 }
332
333 pub fn set_span(&mut self, span: Span) {
334 self.repr.token.set_span(span);
335 }
336
337 pub fn suffix(&self) -> &str {
338 &self.repr.suffix
339 }
340 }
341
342 impl LitInt {
343 pub fn new(repr: &str, span: Span) -> Self {
344 let (digits, suffix) = match value::parse_lit_int(repr) {
345 Some(parse) => parse,
346 None => panic!("Not an integer literal: `{}`", repr),
347 };
348
349 let mut token = match value::to_literal(repr, &digits, &suffix) {
350 Some(token) => token,
351 None => panic!("Unsupported integer literal: `{}`", repr),
352 };
353
354 token.set_span(span);
355 LitInt {
356 repr: Box::new(LitIntRepr {
357 token,
358 digits,
359 suffix,
360 }),
361 }
362 }
363
364 pub fn base10_digits(&self) -> &str {
365 &self.repr.digits
366 }
367
368 /// Parses the literal into a selected number type.
369 ///
370 /// This is equivalent to `lit.base10_digits().parse()` except that the
371 /// resulting errors will be correctly spanned to point to the literal token
372 /// in the macro input.
373 ///
374 /// ```
375 /// use syn::LitInt;
376 /// use syn::parse::{Parse, ParseStream, Result};
377 ///
378 /// struct Port {
379 /// value: u16,
380 /// }
381 ///
382 /// impl Parse for Port {
383 /// fn parse(input: ParseStream) -> Result<Self> {
384 /// let lit: LitInt = input.parse()?;
385 /// let value = lit.base10_parse::<u16>()?;
386 /// Ok(Port { value })
387 /// }
388 /// }
389 /// ```
390 pub fn base10_parse<N>(&self) -> Result<N>
391 where
392 N: FromStr,
393 N::Err: Display,
394 {
395 self.base10_digits()
396 .parse()
397 .map_err(|err| Error::new(self.span(), err))
398 }
399
400 pub fn suffix(&self) -> &str {
401 &self.repr.suffix
402 }
403
404 pub fn span(&self) -> Span {
405 self.repr.token.span()
406 }
407
408 pub fn set_span(&mut self, span: Span) {
409 self.repr.token.set_span(span);
410 }
411 }
412
413 impl From<Literal> for LitInt {
414 fn from(token: Literal) -> Self {
415 let repr = token.to_string();
416 if let Some((digits, suffix)) = value::parse_lit_int(&repr) {
417 LitInt {
418 repr: Box::new(LitIntRepr {
419 token,
420 digits,
421 suffix,
422 }),
423 }
424 } else {
425 panic!("Not an integer literal: `{}`", repr);
426 }
427 }
428 }
429
430 impl Display for LitInt {
431 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
432 self.repr.token.fmt(formatter)
433 }
434 }
435
436 impl LitFloat {
437 pub fn new(repr: &str, span: Span) -> Self {
438 let (digits, suffix) = match value::parse_lit_float(repr) {
439 Some(parse) => parse,
440 None => panic!("Not a float literal: `{}`", repr),
441 };
442
443 let mut token = match value::to_literal(repr, &digits, &suffix) {
444 Some(token) => token,
445 None => panic!("Unsupported float literal: `{}`", repr),
446 };
447
448 token.set_span(span);
449 LitFloat {
450 repr: Box::new(LitFloatRepr {
451 token,
452 digits,
453 suffix,
454 }),
455 }
456 }
457
458 pub fn base10_digits(&self) -> &str {
459 &self.repr.digits
460 }
461
462 pub fn base10_parse<N>(&self) -> Result<N>
463 where
464 N: FromStr,
465 N::Err: Display,
466 {
467 self.base10_digits()
468 .parse()
469 .map_err(|err| Error::new(self.span(), err))
470 }
471
472 pub fn suffix(&self) -> &str {
473 &self.repr.suffix
474 }
475
476 pub fn span(&self) -> Span {
477 self.repr.token.span()
478 }
479
480 pub fn set_span(&mut self, span: Span) {
481 self.repr.token.set_span(span);
482 }
483 }
484
485 impl From<Literal> for LitFloat {
486 fn from(token: Literal) -> Self {
487 let repr = token.to_string();
488 if let Some((digits, suffix)) = value::parse_lit_float(&repr) {
489 LitFloat {
490 repr: Box::new(LitFloatRepr {
491 token,
492 digits,
493 suffix,
494 }),
495 }
496 } else {
497 panic!("Not a float literal: `{}`", repr);
498 }
499 }
500 }
501
502 impl Display for LitFloat {
503 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
504 self.repr.token.fmt(formatter)
505 }
506 }
507
508 impl LitBool {
509 pub fn new(value: bool, span: Span) -> Self {
510 LitBool { value, span }
511 }
512
513 pub fn value(&self) -> bool {
514 self.value
515 }
516
517 pub fn span(&self) -> Span {
518 self.span
519 }
520
521 pub fn set_span(&mut self, span: Span) {
522 self.span = span;
523 }
524 }
525
526 #[cfg(feature = "extra-traits")]
527 mod debug_impls {
528 use super::*;
529 use std::fmt::{self, Debug};
530
531 #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
532 impl Debug for LitStr {
533 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
534 formatter
535 .debug_struct("LitStr")
536 .field("token", &format_args!("{}", self.repr.token))
537 .finish()
538 }
539 }
540
541 #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
542 impl Debug for LitByteStr {
543 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
544 formatter
545 .debug_struct("LitByteStr")
546 .field("token", &format_args!("{}", self.repr.token))
547 .finish()
548 }
549 }
550
551 #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
552 impl Debug for LitByte {
553 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
554 formatter
555 .debug_struct("LitByte")
556 .field("token", &format_args!("{}", self.repr.token))
557 .finish()
558 }
559 }
560
561 #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
562 impl Debug for LitChar {
563 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
564 formatter
565 .debug_struct("LitChar")
566 .field("token", &format_args!("{}", self.repr.token))
567 .finish()
568 }
569 }
570
571 #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
572 impl Debug for LitInt {
573 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
574 formatter
575 .debug_struct("LitInt")
576 .field("token", &format_args!("{}", self.repr.token))
577 .finish()
578 }
579 }
580
581 #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
582 impl Debug for LitFloat {
583 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
584 formatter
585 .debug_struct("LitFloat")
586 .field("token", &format_args!("{}", self.repr.token))
587 .finish()
588 }
589 }
590
591 #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
592 impl Debug for LitBool {
593 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
594 formatter
595 .debug_struct("LitBool")
596 .field("value", &self.value)
597 .finish()
598 }
599 }
600 }
601
602 #[cfg(feature = "clone-impls")]
603 #[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
604 impl Clone for LitRepr {
605 fn clone(&self) -> Self {
606 LitRepr {
607 token: self.token.clone(),
608 suffix: self.suffix.clone(),
609 }
610 }
611 }
612
613 #[cfg(feature = "clone-impls")]
614 #[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
615 impl Clone for LitIntRepr {
616 fn clone(&self) -> Self {
617 LitIntRepr {
618 token: self.token.clone(),
619 digits: self.digits.clone(),
620 suffix: self.suffix.clone(),
621 }
622 }
623 }
624
625 #[cfg(feature = "clone-impls")]
626 #[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
627 impl Clone for LitFloatRepr {
628 fn clone(&self) -> Self {
629 LitFloatRepr {
630 token: self.token.clone(),
631 digits: self.digits.clone(),
632 suffix: self.suffix.clone(),
633 }
634 }
635 }
636
637 macro_rules! lit_extra_traits {
638 ($ty:ident) => {
639 #[cfg(feature = "clone-impls")]
640 #[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
641 impl Clone for $ty {
642 fn clone(&self) -> Self {
643 $ty {
644 repr: self.repr.clone(),
645 }
646 }
647 }
648
649 #[cfg(feature = "extra-traits")]
650 #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
651 impl PartialEq for $ty {
652 fn eq(&self, other: &Self) -> bool {
653 self.repr.token.to_string() == other.repr.token.to_string()
654 }
655 }
656
657 #[cfg(feature = "extra-traits")]
658 #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
659 impl Hash for $ty {
660 fn hash<H>(&self, state: &mut H)
661 where
662 H: Hasher,
663 {
664 self.repr.token.to_string().hash(state);
665 }
666 }
667
668 #[cfg(feature = "parsing")]
669 #[doc(hidden)]
670 #[allow(non_snake_case)]
671 pub fn $ty(marker: lookahead::TokenMarker) -> $ty {
672 match marker {}
673 }
674 };
675 }
676
677 lit_extra_traits!(LitStr);
678 lit_extra_traits!(LitByteStr);
679 lit_extra_traits!(LitByte);
680 lit_extra_traits!(LitChar);
681 lit_extra_traits!(LitInt);
682 lit_extra_traits!(LitFloat);
683
684 #[cfg(feature = "parsing")]
685 #[doc(hidden)]
686 #[allow(non_snake_case)]
687 pub fn LitBool(marker: lookahead::TokenMarker) -> LitBool {
688 match marker {}
689 }
690
691 ast_enum! {
692 /// The style of a string literal, either plain quoted or a raw string like
693 /// `r##"data"##`.
694 pub enum StrStyle #no_visit {
695 /// An ordinary string like `"data"`.
696 Cooked,
697 /// A raw string like `r##"data"##`.
698 ///
699 /// The unsigned integer is the number of `#` symbols used.
700 Raw(usize),
701 }
702 }
703
704 #[cfg(feature = "parsing")]
705 #[doc(hidden)]
706 #[allow(non_snake_case)]
707 pub fn Lit(marker: lookahead::TokenMarker) -> Lit {
708 match marker {}
709 }
710
711 #[cfg(feature = "parsing")]
712 pub mod parsing {
713 use super::*;
714 use crate::buffer::Cursor;
715 use crate::parse::{Parse, ParseStream, Result};
716 use proc_macro2::Punct;
717
718 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
719 impl Parse for Lit {
720 fn parse(input: ParseStream) -> Result<Self> {
721 input.step(|cursor| {
722 if let Some((lit, rest)) = cursor.literal() {
723 return Ok((Lit::new(lit), rest));
724 }
725
726 if let Some((ident, rest)) = cursor.ident() {
727 let value = ident == "true";
728 if value || ident == "false" {
729 let lit_bool = LitBool {
730 value,
731 span: ident.span(),
732 };
733 return Ok((Lit::Bool(lit_bool), rest));
734 }
735 }
736
737 if let Some((punct, rest)) = cursor.punct() {
738 if punct.as_char() == '-' {
739 if let Some((lit, rest)) = parse_negative_lit(punct, rest) {
740 return Ok((lit, rest));
741 }
742 }
743 }
744
745 Err(cursor.error("expected literal"))
746 })
747 }
748 }
749
750 fn parse_negative_lit(neg: Punct, cursor: Cursor) -> Option<(Lit, Cursor)> {
751 let (lit, rest) = cursor.literal()?;
752
753 let mut span = neg.span();
754 span = span.join(lit.span()).unwrap_or(span);
755
756 let mut repr = lit.to_string();
757 repr.insert(0, '-');
758
759 if let Some((digits, suffix)) = value::parse_lit_int(&repr) {
760 if let Some(mut token) = value::to_literal(&repr, &digits, &suffix) {
761 token.set_span(span);
762 return Some((
763 Lit::Int(LitInt {
764 repr: Box::new(LitIntRepr {
765 token,
766 digits,
767 suffix,
768 }),
769 }),
770 rest,
771 ));
772 }
773 }
774
775 let (digits, suffix) = value::parse_lit_float(&repr)?;
776 let mut token = value::to_literal(&repr, &digits, &suffix)?;
777 token.set_span(span);
778 Some((
779 Lit::Float(LitFloat {
780 repr: Box::new(LitFloatRepr {
781 token,
782 digits,
783 suffix,
784 }),
785 }),
786 rest,
787 ))
788 }
789
790 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
791 impl Parse for LitStr {
792 fn parse(input: ParseStream) -> Result<Self> {
793 let head = input.fork();
794 match input.parse() {
795 Ok(Lit::Str(lit)) => Ok(lit),
796 _ => Err(head.error("expected string literal")),
797 }
798 }
799 }
800
801 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
802 impl Parse for LitByteStr {
803 fn parse(input: ParseStream) -> Result<Self> {
804 let head = input.fork();
805 match input.parse() {
806 Ok(Lit::ByteStr(lit)) => Ok(lit),
807 _ => Err(head.error("expected byte string literal")),
808 }
809 }
810 }
811
812 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
813 impl Parse for LitByte {
814 fn parse(input: ParseStream) -> Result<Self> {
815 let head = input.fork();
816 match input.parse() {
817 Ok(Lit::Byte(lit)) => Ok(lit),
818 _ => Err(head.error("expected byte literal")),
819 }
820 }
821 }
822
823 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
824 impl Parse for LitChar {
825 fn parse(input: ParseStream) -> Result<Self> {
826 let head = input.fork();
827 match input.parse() {
828 Ok(Lit::Char(lit)) => Ok(lit),
829 _ => Err(head.error("expected character literal")),
830 }
831 }
832 }
833
834 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
835 impl Parse for LitInt {
836 fn parse(input: ParseStream) -> Result<Self> {
837 let head = input.fork();
838 match input.parse() {
839 Ok(Lit::Int(lit)) => Ok(lit),
840 _ => Err(head.error("expected integer literal")),
841 }
842 }
843 }
844
845 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
846 impl Parse for LitFloat {
847 fn parse(input: ParseStream) -> Result<Self> {
848 let head = input.fork();
849 match input.parse() {
850 Ok(Lit::Float(lit)) => Ok(lit),
851 _ => Err(head.error("expected floating point literal")),
852 }
853 }
854 }
855
856 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
857 impl Parse for LitBool {
858 fn parse(input: ParseStream) -> Result<Self> {
859 let head = input.fork();
860 match input.parse() {
861 Ok(Lit::Bool(lit)) => Ok(lit),
862 _ => Err(head.error("expected boolean literal")),
863 }
864 }
865 }
866 }
867
868 #[cfg(feature = "printing")]
869 mod printing {
870 use super::*;
871 use proc_macro2::TokenStream;
872 use quote::{ToTokens, TokenStreamExt};
873
874 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
875 impl ToTokens for LitStr {
876 fn to_tokens(&self, tokens: &mut TokenStream) {
877 self.repr.token.to_tokens(tokens);
878 }
879 }
880
881 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
882 impl ToTokens for LitByteStr {
883 fn to_tokens(&self, tokens: &mut TokenStream) {
884 self.repr.token.to_tokens(tokens);
885 }
886 }
887
888 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
889 impl ToTokens for LitByte {
890 fn to_tokens(&self, tokens: &mut TokenStream) {
891 self.repr.token.to_tokens(tokens);
892 }
893 }
894
895 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
896 impl ToTokens for LitChar {
897 fn to_tokens(&self, tokens: &mut TokenStream) {
898 self.repr.token.to_tokens(tokens);
899 }
900 }
901
902 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
903 impl ToTokens for LitInt {
904 fn to_tokens(&self, tokens: &mut TokenStream) {
905 self.repr.token.to_tokens(tokens);
906 }
907 }
908
909 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
910 impl ToTokens for LitFloat {
911 fn to_tokens(&self, tokens: &mut TokenStream) {
912 self.repr.token.to_tokens(tokens);
913 }
914 }
915
916 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
917 impl ToTokens for LitBool {
918 fn to_tokens(&self, tokens: &mut TokenStream) {
919 let s = if self.value { "true" } else { "false" };
920 tokens.append(Ident::new(s, self.span));
921 }
922 }
923 }
924
925 mod value {
926 use super::*;
927 use crate::bigint::BigInt;
928 use proc_macro2::TokenStream;
929 use std::char;
930 use std::ops::{Index, RangeFrom};
931
932 impl Lit {
933 /// Interpret a Syn literal from a proc-macro2 literal.
934 pub fn new(token: Literal) -> Self {
935 let repr = token.to_string();
936
937 match byte(&repr, 0) {
938 b'"' | b'r' => {
939 let (_, suffix) = parse_lit_str(&repr);
940 return Lit::Str(LitStr {
941 repr: Box::new(LitRepr { token, suffix }),
942 });
943 }
944 b'b' => match byte(&repr, 1) {
945 b'"' | b'r' => {
946 let (_, suffix) = parse_lit_byte_str(&repr);
947 return Lit::ByteStr(LitByteStr {
948 repr: Box::new(LitRepr { token, suffix }),
949 });
950 }
951 b'\'' => {
952 let (_, suffix) = parse_lit_byte(&repr);
953 return Lit::Byte(LitByte {
954 repr: Box::new(LitRepr { token, suffix }),
955 });
956 }
957 _ => {}
958 },
959 b'\'' => {
960 let (_, suffix) = parse_lit_char(&repr);
961 return Lit::Char(LitChar {
962 repr: Box::new(LitRepr { token, suffix }),
963 });
964 }
965 b'0'..=b'9' | b'-' => {
966 if let Some((digits, suffix)) = parse_lit_int(&repr) {
967 return Lit::Int(LitInt {
968 repr: Box::new(LitIntRepr {
969 token,
970 digits,
971 suffix,
972 }),
973 });
974 }
975 if let Some((digits, suffix)) = parse_lit_float(&repr) {
976 return Lit::Float(LitFloat {
977 repr: Box::new(LitFloatRepr {
978 token,
979 digits,
980 suffix,
981 }),
982 });
983 }
984 }
985 b't' | b'f' => {
986 if repr == "true" || repr == "false" {
987 return Lit::Bool(LitBool {
988 value: repr == "true",
989 span: token.span(),
990 });
991 }
992 }
993 _ => {}
994 }
995
996 panic!("Unrecognized literal: `{}`", repr);
997 }
998
999 pub fn suffix(&self) -> &str {
1000 match self {
1001 Lit::Str(lit) => lit.suffix(),
1002 Lit::ByteStr(lit) => lit.suffix(),
1003 Lit::Byte(lit) => lit.suffix(),
1004 Lit::Char(lit) => lit.suffix(),
1005 Lit::Int(lit) => lit.suffix(),
1006 Lit::Float(lit) => lit.suffix(),
1007 Lit::Bool(_) | Lit::Verbatim(_) => "",
1008 }
1009 }
1010
1011 pub fn span(&self) -> Span {
1012 match self {
1013 Lit::Str(lit) => lit.span(),
1014 Lit::ByteStr(lit) => lit.span(),
1015 Lit::Byte(lit) => lit.span(),
1016 Lit::Char(lit) => lit.span(),
1017 Lit::Int(lit) => lit.span(),
1018 Lit::Float(lit) => lit.span(),
1019 Lit::Bool(lit) => lit.span,
1020 Lit::Verbatim(lit) => lit.span(),
1021 }
1022 }
1023
1024 pub fn set_span(&mut self, span: Span) {
1025 match self {
1026 Lit::Str(lit) => lit.set_span(span),
1027 Lit::ByteStr(lit) => lit.set_span(span),
1028 Lit::Byte(lit) => lit.set_span(span),
1029 Lit::Char(lit) => lit.set_span(span),
1030 Lit::Int(lit) => lit.set_span(span),
1031 Lit::Float(lit) => lit.set_span(span),
1032 Lit::Bool(lit) => lit.span = span,
1033 Lit::Verbatim(lit) => lit.set_span(span),
1034 }
1035 }
1036 }
1037
1038 /// Get the byte at offset idx, or a default of `b'\0'` if we're looking
1039 /// past the end of the input buffer.
1040 pub fn byte<S: AsRef<[u8]> + ?Sized>(s: &S, idx: usize) -> u8 {
1041 let s = s.as_ref();
1042 if idx < s.len() {
1043 s[idx]
1044 } else {
1045 0
1046 }
1047 }
1048
1049 fn next_chr(s: &str) -> char {
1050 s.chars().next().unwrap_or('\0')
1051 }
1052
1053 // Returns (content, suffix).
1054 pub fn parse_lit_str(s: &str) -> (Box<str>, Box<str>) {
1055 match byte(s, 0) {
1056 b'"' => parse_lit_str_cooked(s),
1057 b'r' => parse_lit_str_raw(s),
1058 _ => unreachable!(),
1059 }
1060 }
1061
1062 // Clippy false positive
1063 // https://github.com/rust-lang-nursery/rust-clippy/issues/2329
1064 #[allow(clippy::needless_continue)]
1065 fn parse_lit_str_cooked(mut s: &str) -> (Box<str>, Box<str>) {
1066 assert_eq!(byte(s, 0), b'"');
1067 s = &s[1..];
1068
1069 let mut content = String::new();
1070 'outer: loop {
1071 let ch = match byte(s, 0) {
1072 b'"' => break,
1073 b'\\' => {
1074 let b = byte(s, 1);
1075 s = &s[2..];
1076 match b {
1077 b'x' => {
1078 let (byte, rest) = backslash_x(s);
1079 s = rest;
1080 assert!(byte <= 0x80, "Invalid \\x byte in string literal");
1081 char::from_u32(u32::from(byte)).unwrap()
1082 }
1083 b'u' => {
1084 let (chr, rest) = backslash_u(s);
1085 s = rest;
1086 chr
1087 }
1088 b'n' => '\n',
1089 b'r' => '\r',
1090 b't' => '\t',
1091 b'\\' => '\\',
1092 b'0' => '\0',
1093 b'\'' => '\'',
1094 b'"' => '"',
1095 b'\r' | b'\n' => loop {
1096 let ch = next_chr(s);
1097 if ch.is_whitespace() {
1098 s = &s[ch.len_utf8()..];
1099 } else {
1100 continue 'outer;
1101 }
1102 },
1103 b => panic!("unexpected byte {:?} after \\ character in byte literal", b),
1104 }
1105 }
1106 b'\r' => {
1107 assert_eq!(byte(s, 1), b'\n', "Bare CR not allowed in string");
1108 s = &s[2..];
1109 '\n'
1110 }
1111 _ => {
1112 let ch = next_chr(s);
1113 s = &s[ch.len_utf8()..];
1114 ch
1115 }
1116 };
1117 content.push(ch);
1118 }
1119
1120 assert!(s.starts_with('"'));
1121 let content = content.into_boxed_str();
1122 let suffix = s[1..].to_owned().into_boxed_str();
1123 (content, suffix)
1124 }
1125
1126 fn parse_lit_str_raw(mut s: &str) -> (Box<str>, Box<str>) {
1127 assert_eq!(byte(s, 0), b'r');
1128 s = &s[1..];
1129
1130 let mut pounds = 0;
1131 while byte(s, pounds) == b'#' {
1132 pounds += 1;
1133 }
1134 assert_eq!(byte(s, pounds), b'"');
1135 let close = s.rfind('"').unwrap();
1136 for end in s[close + 1..close + 1 + pounds].bytes() {
1137 assert_eq!(end, b'#');
1138 }
1139
1140 let content = s[pounds + 1..close].to_owned().into_boxed_str();
1141 let suffix = s[close + 1 + pounds..].to_owned().into_boxed_str();
1142 (content, suffix)
1143 }
1144
1145 // Returns (content, suffix).
1146 pub fn parse_lit_byte_str(s: &str) -> (Vec<u8>, Box<str>) {
1147 assert_eq!(byte(s, 0), b'b');
1148 match byte(s, 1) {
1149 b'"' => parse_lit_byte_str_cooked(s),
1150 b'r' => parse_lit_byte_str_raw(s),
1151 _ => unreachable!(),
1152 }
1153 }
1154
1155 // Clippy false positive
1156 // https://github.com/rust-lang-nursery/rust-clippy/issues/2329
1157 #[allow(clippy::needless_continue)]
1158 fn parse_lit_byte_str_cooked(mut s: &str) -> (Vec<u8>, Box<str>) {
1159 assert_eq!(byte(s, 0), b'b');
1160 assert_eq!(byte(s, 1), b'"');
1161 s = &s[2..];
1162
1163 // We're going to want to have slices which don't respect codepoint boundaries.
1164 let mut v = s.as_bytes();
1165
1166 let mut out = Vec::new();
1167 'outer: loop {
1168 let byte = match byte(v, 0) {
1169 b'"' => break,
1170 b'\\' => {
1171 let b = byte(v, 1);
1172 v = &v[2..];
1173 match b {
1174 b'x' => {
1175 let (b, rest) = backslash_x(v);
1176 v = rest;
1177 b
1178 }
1179 b'n' => b'\n',
1180 b'r' => b'\r',
1181 b't' => b'\t',
1182 b'\\' => b'\\',
1183 b'0' => b'\0',
1184 b'\'' => b'\'',
1185 b'"' => b'"',
1186 b'\r' | b'\n' => loop {
1187 let byte = byte(v, 0);
1188 let ch = char::from_u32(u32::from(byte)).unwrap();
1189 if ch.is_whitespace() {
1190 v = &v[1..];
1191 } else {
1192 continue 'outer;
1193 }
1194 },
1195 b => panic!("unexpected byte {:?} after \\ character in byte literal", b),
1196 }
1197 }
1198 b'\r' => {
1199 assert_eq!(byte(v, 1), b'\n', "Bare CR not allowed in string");
1200 v = &v[2..];
1201 b'\n'
1202 }
1203 b => {
1204 v = &v[1..];
1205 b
1206 }
1207 };
1208 out.push(byte);
1209 }
1210
1211 assert_eq!(byte(v, 0), b'"');
1212 let suffix = s[s.len() - v.len() + 1..].to_owned().into_boxed_str();
1213 (out, suffix)
1214 }
1215
1216 fn parse_lit_byte_str_raw(s: &str) -> (Vec<u8>, Box<str>) {
1217 assert_eq!(byte(s, 0), b'b');
1218 let (value, suffix) = parse_lit_str_raw(&s[1..]);
1219 (String::from(value).into_bytes(), suffix)
1220 }
1221
1222 // Returns (value, suffix).
1223 pub fn parse_lit_byte(s: &str) -> (u8, Box<str>) {
1224 assert_eq!(byte(s, 0), b'b');
1225 assert_eq!(byte(s, 1), b'\'');
1226
1227 // We're going to want to have slices which don't respect codepoint boundaries.
1228 let mut v = s[2..].as_bytes();
1229
1230 let b = match byte(v, 0) {
1231 b'\\' => {
1232 let b = byte(v, 1);
1233 v = &v[2..];
1234 match b {
1235 b'x' => {
1236 let (b, rest) = backslash_x(v);
1237 v = rest;
1238 b
1239 }
1240 b'n' => b'\n',
1241 b'r' => b'\r',
1242 b't' => b'\t',
1243 b'\\' => b'\\',
1244 b'0' => b'\0',
1245 b'\'' => b'\'',
1246 b'"' => b'"',
1247 b => panic!("unexpected byte {:?} after \\ character in byte literal", b),
1248 }
1249 }
1250 b => {
1251 v = &v[1..];
1252 b
1253 }
1254 };
1255
1256 assert_eq!(byte(v, 0), b'\'');
1257 let suffix = s[s.len() - v.len() + 1..].to_owned().into_boxed_str();
1258 (b, suffix)
1259 }
1260
1261 // Returns (value, suffix).
1262 pub fn parse_lit_char(mut s: &str) -> (char, Box<str>) {
1263 assert_eq!(byte(s, 0), b'\'');
1264 s = &s[1..];
1265
1266 let ch = match byte(s, 0) {
1267 b'\\' => {
1268 let b = byte(s, 1);
1269 s = &s[2..];
1270 match b {
1271 b'x' => {
1272 let (byte, rest) = backslash_x(s);
1273 s = rest;
1274 assert!(byte <= 0x80, "Invalid \\x byte in string literal");
1275 char::from_u32(u32::from(byte)).unwrap()
1276 }
1277 b'u' => {
1278 let (chr, rest) = backslash_u(s);
1279 s = rest;
1280 chr
1281 }
1282 b'n' => '\n',
1283 b'r' => '\r',
1284 b't' => '\t',
1285 b'\\' => '\\',
1286 b'0' => '\0',
1287 b'\'' => '\'',
1288 b'"' => '"',
1289 b => panic!("unexpected byte {:?} after \\ character in byte literal", b),
1290 }
1291 }
1292 _ => {
1293 let ch = next_chr(s);
1294 s = &s[ch.len_utf8()..];
1295 ch
1296 }
1297 };
1298 assert_eq!(byte(s, 0), b'\'');
1299 let suffix = s[1..].to_owned().into_boxed_str();
1300 (ch, suffix)
1301 }
1302
1303 fn backslash_x<S>(s: &S) -> (u8, &S)
1304 where
1305 S: Index<RangeFrom<usize>, Output = S> + AsRef<[u8]> + ?Sized,
1306 {
1307 let mut ch = 0;
1308 let b0 = byte(s, 0);
1309 let b1 = byte(s, 1);
1310 ch += 0x10
1311 * match b0 {
1312 b'0'..=b'9' => b0 - b'0',
1313 b'a'..=b'f' => 10 + (b0 - b'a'),
1314 b'A'..=b'F' => 10 + (b0 - b'A'),
1315 _ => panic!("unexpected non-hex character after \\x"),
1316 };
1317 ch += match b1 {
1318 b'0'..=b'9' => b1 - b'0',
1319 b'a'..=b'f' => 10 + (b1 - b'a'),
1320 b'A'..=b'F' => 10 + (b1 - b'A'),
1321 _ => panic!("unexpected non-hex character after \\x"),
1322 };
1323 (ch, &s[2..])
1324 }
1325
1326 fn backslash_u(mut s: &str) -> (char, &str) {
1327 if byte(s, 0) != b'{' {
1328 panic!("{}", "expected { after \\u");
1329 }
1330 s = &s[1..];
1331
1332 let mut ch = 0;
1333 let mut digits = 0;
1334 loop {
1335 let b = byte(s, 0);
1336 let digit = match b {
1337 b'0'..=b'9' => b - b'0',
1338 b'a'..=b'f' => 10 + b - b'a',
1339 b'A'..=b'F' => 10 + b - b'A',
1340 b'_' if digits > 0 => {
1341 s = &s[1..];
1342 continue;
1343 }
1344 b'}' if digits == 0 => panic!("invalid empty unicode escape"),
1345 b'}' => break,
1346 _ => panic!("unexpected non-hex character after \\u"),
1347 };
1348 if digits == 6 {
1349 panic!("overlong unicode escape (must have at most 6 hex digits)");
1350 }
1351 ch *= 0x10;
1352 ch += u32::from(digit);
1353 digits += 1;
1354 s = &s[1..];
1355 }
1356 assert!(byte(s, 0) == b'}');
1357 s = &s[1..];
1358
1359 if let Some(ch) = char::from_u32(ch) {
1360 (ch, s)
1361 } else {
1362 panic!("character code {:x} is not a valid unicode character", ch);
1363 }
1364 }
1365
1366 // Returns base 10 digits and suffix.
1367 pub fn parse_lit_int(mut s: &str) -> Option<(Box<str>, Box<str>)> {
1368 let negative = byte(s, 0) == b'-';
1369 if negative {
1370 s = &s[1..];
1371 }
1372
1373 let base = match (byte(s, 0), byte(s, 1)) {
1374 (b'0', b'x') => {
1375 s = &s[2..];
1376 16
1377 }
1378 (b'0', b'o') => {
1379 s = &s[2..];
1380 8
1381 }
1382 (b'0', b'b') => {
1383 s = &s[2..];
1384 2
1385 }
1386 (b'0'..=b'9', _) => 10,
1387 _ => return None,
1388 };
1389
1390 let mut value = BigInt::new();
1391 'outer: loop {
1392 let b = byte(s, 0);
1393 let digit = match b {
1394 b'0'..=b'9' => b - b'0',
1395 b'a'..=b'f' if base > 10 => b - b'a' + 10,
1396 b'A'..=b'F' if base > 10 => b - b'A' + 10,
1397 b'_' => {
1398 s = &s[1..];
1399 continue;
1400 }
1401 // If looking at a floating point literal, we don't want to
1402 // consider it an integer.
1403 b'.' if base == 10 => return None,
1404 b'e' | b'E' if base == 10 => {
1405 let mut has_exp = false;
1406 for (i, b) in s[1..].bytes().enumerate() {
1407 match b {
1408 b'_' => {}
1409 b'-' | b'+' => return None,
1410 b'0'..=b'9' => has_exp = true,
1411 _ => {
1412 let suffix = &s[1 + i..];
1413 if has_exp && crate::ident::xid_ok(suffix) {
1414 return None;
1415 } else {
1416 break 'outer;
1417 }
1418 }
1419 }
1420 }
1421 if has_exp {
1422 return None;
1423 } else {
1424 break;
1425 }
1426 }
1427 _ => break,
1428 };
1429
1430 if digit >= base {
1431 return None;
1432 }
1433
1434 value *= base;
1435 value += digit;
1436 s = &s[1..];
1437 }
1438
1439 let suffix = s;
1440 if suffix.is_empty() || crate::ident::xid_ok(suffix) {
1441 let mut repr = value.to_string();
1442 if negative {
1443 repr.insert(0, '-');
1444 }
1445 Some((repr.into_boxed_str(), suffix.to_owned().into_boxed_str()))
1446 } else {
1447 None
1448 }
1449 }
1450
1451 // Returns base 10 digits and suffix.
1452 pub fn parse_lit_float(input: &str) -> Option<(Box<str>, Box<str>)> {
1453 // Rust's floating point literals are very similar to the ones parsed by
1454 // the standard library, except that rust's literals can contain
1455 // ignorable underscores. Let's remove those underscores.
1456
1457 let mut bytes = input.to_owned().into_bytes();
1458
1459 let start = (*bytes.get(0)? == b'-') as usize;
1460 match bytes.get(start)? {
1461 b'0'..=b'9' => {}
1462 _ => return None,
1463 }
1464
1465 let mut read = start;
1466 let mut write = start;
1467 let mut has_dot = false;
1468 let mut has_e = false;
1469 let mut has_sign = false;
1470 let mut has_exponent = false;
1471 while read < bytes.len() {
1472 match bytes[read] {
1473 b'_' => {
1474 // Don't increase write
1475 read += 1;
1476 continue;
1477 }
1478 b'0'..=b'9' => {
1479 if has_e {
1480 has_exponent = true;
1481 }
1482 bytes[write] = bytes[read];
1483 }
1484 b'.' => {
1485 if has_e || has_dot {
1486 return None;
1487 }
1488 has_dot = true;
1489 bytes[write] = b'.';
1490 }
1491 b'e' | b'E' => {
1492 match bytes[read + 1..]
1493 .iter()
1494 .find(|b| **b != b'_')
1495 .unwrap_or(&b'\0')
1496 {
1497 b'-' | b'+' | b'0'..=b'9' => {}
1498 _ => break,
1499 }
1500 if has_e {
1501 if has_exponent {
1502 break;
1503 } else {
1504 return None;
1505 }
1506 }
1507 has_e = true;
1508 bytes[write] = b'e';
1509 }
1510 b'-' | b'+' => {
1511 if has_sign || has_exponent || !has_e {
1512 return None;
1513 }
1514 has_sign = true;
1515 if bytes[read] == b'-' {
1516 bytes[write] = bytes[read];
1517 } else {
1518 // Omit '+'
1519 read += 1;
1520 continue;
1521 }
1522 }
1523 _ => break,
1524 }
1525 read += 1;
1526 write += 1;
1527 }
1528
1529 if has_e && !has_exponent {
1530 return None;
1531 }
1532
1533 let mut digits = String::from_utf8(bytes).unwrap();
1534 let suffix = digits.split_off(read);
1535 digits.truncate(write);
1536 if suffix.is_empty() || crate::ident::xid_ok(&suffix) {
1537 Some((digits.into_boxed_str(), suffix.into_boxed_str()))
1538 } else {
1539 None
1540 }
1541 }
1542
1543 pub fn to_literal(repr: &str, digits: &str, suffix: &str) -> Option<Literal> {
1544 if repr.starts_with('-') {
1545 let f64_parse_finite = || digits.parse().ok().filter(|x: &f64| x.is_finite());
1546 let f32_parse_finite = || digits.parse().ok().filter(|x: &f32| x.is_finite());
1547 if suffix == "f64" {
1548 f64_parse_finite().map(Literal::f64_suffixed)
1549 } else if suffix == "f32" {
1550 f32_parse_finite().map(Literal::f32_suffixed)
1551 } else if suffix == "i64" {
1552 digits.parse().ok().map(Literal::i64_suffixed)
1553 } else if suffix == "i32" {
1554 digits.parse().ok().map(Literal::i32_suffixed)
1555 } else if suffix == "i16" {
1556 digits.parse().ok().map(Literal::i16_suffixed)
1557 } else if suffix == "i8" {
1558 digits.parse().ok().map(Literal::i8_suffixed)
1559 } else if !suffix.is_empty() {
1560 None
1561 } else if digits.contains('.') {
1562 f64_parse_finite().map(Literal::f64_unsuffixed)
1563 } else {
1564 digits.parse().ok().map(Literal::i64_unsuffixed)
1565 }
1566 } else {
1567 let stream = repr.parse::<TokenStream>().unwrap();
1568 match stream.into_iter().next().unwrap() {
1569 TokenTree::Literal(l) => Some(l),
1570 _ => unreachable!(),
1571 }
1572 }
1573 }
1574 }