]> git.lizzy.rs Git - rust.git/blob - crates/hir_def/src/macro_expansion_tests/mbe/tt_conversion.rs
parameters.split_last()
[rust.git] / crates / hir_def / src / macro_expansion_tests / mbe / tt_conversion.rs
1 //! Unlike rustc, rust-analyzer's syntax tree are not "made of" token trees.
2 //! Rather, token trees are an explicit bridge between the parser and
3 //! (procedural or declarative) macros.
4 //!
5 //! This module tests tt <-> syntax tree conversion specifically. In particular,
6 //! it, among other things, check that we convert `tt` to the right kind of
7 //! syntax node depending on the macro call-site.
8 use expect_test::expect;
9
10 use crate::macro_expansion_tests::check;
11
12 #[test]
13 fn round_trips_compound_tokens() {
14     check(
15         r#"
16 macro_rules! m {
17     () => { type qual: ::T = qual::T; }
18 }
19 m!();
20 "#,
21         expect![[r#"
22 macro_rules! m {
23     () => { type qual: ::T = qual::T; }
24 }
25 type qual: ::T = qual::T;
26 "#]],
27     )
28 }
29
30 #[test]
31 fn round_trips_literals() {
32     check(
33         r#"
34 macro_rules! m {
35     () => {
36         let _ = 'c';
37         let _ = 1000;
38         let _ = 12E+99_f64;
39         let _ = "rust1";
40         let _ = -92;
41     }
42 }
43 fn f() {
44     m!()
45 }
46 "#,
47         expect![[r#"
48 macro_rules! m {
49     () => {
50         let _ = 'c';
51         let _ = 1000;
52         let _ = 12E+99_f64;
53         let _ = "rust1";
54         let _ = -92;
55     }
56 }
57 fn f() {
58     let _ = 'c';
59     let _ = 1000;
60     let _ = 12E+99_f64;
61     let _ = "rust1";
62     let _ = -92;
63 }
64 "#]],
65     );
66 }
67
68 #[test]
69 fn roundtrip_lifetime() {
70     check(
71         r#"
72 macro_rules! m {
73     ($($t:tt)*) => { $($t)*}
74 }
75 m!(static bar: &'static str = "hello";);
76 "#,
77         expect![[r#"
78 macro_rules! m {
79     ($($t:tt)*) => { $($t)*}
80 }
81 static bar: & 'static str = "hello";
82 "#]],
83     );
84 }
85
86 #[test]
87 fn broken_parenthesis_sequence() {
88     check(
89         r#"
90 macro_rules! m1 { ($x:ident) => { ($x } }
91 macro_rules! m2 { ($x:ident) => {} }
92
93 m1!();
94 m2!(x
95 "#,
96         expect![[r#"
97 macro_rules! m1 { ($x:ident) => { ($x } }
98 macro_rules! m2 { ($x:ident) => {} }
99
100 /* error: invalid macro definition: expected subtree */
101 /* error: Failed to lower macro args to token tree */
102 "#]],
103     )
104 }
105
106 #[test]
107 fn expansion_does_not_parse_as_expression() {
108     check(
109         r#"
110 macro_rules! stmts {
111     () => { let _ = 0; }
112 }
113
114 fn f() { let _ = stmts!/*+errors*/(); }
115 "#,
116         expect![[r#"
117 macro_rules! stmts {
118     () => { let _ = 0; }
119 }
120
121 fn f() { let _ = /* parse error: expected expression */
122 let _ = 0;; }
123 "#]],
124     )
125 }
126
127 #[test]
128 fn broken_pat() {
129     check(
130         r#"
131 macro_rules! m1 { () => (Some(x) left overs) }
132 macro_rules! m2 { () => ($) }
133
134 fn main() {
135     let m1!() = ();
136     let m2!/*+errors*/() = ();
137 }
138 "#,
139         expect![[r#"
140 macro_rules! m1 { () => (Some(x) left overs) }
141 macro_rules! m2 { () => ($) }
142
143 fn main() {
144     let Some(x)left overs = ();
145     let /* parse error: expected pattern */
146 $ = ();
147 }
148 "#]],
149     )
150 }