]> git.lizzy.rs Git - rust.git/blob - crates/hir_def/src/body/tests.rs
Merge #8882
[rust.git] / crates / hir_def / src / body / tests.rs
1 mod block;
2
3 use base_db::{fixture::WithFixture, SourceDatabase};
4 use expect_test::Expect;
5
6 use crate::{test_db::TestDB, ModuleDefId};
7
8 use super::*;
9
10 fn lower(ra_fixture: &str) -> Arc<Body> {
11     let db = crate::test_db::TestDB::with_files(ra_fixture);
12
13     let krate = db.crate_graph().iter().next().unwrap();
14     let def_map = db.crate_def_map(krate);
15     let mut fn_def = None;
16     'outer: for (_, module) in def_map.modules() {
17         for decl in module.scope.declarations() {
18             match decl {
19                 ModuleDefId::FunctionId(it) => {
20                     fn_def = Some(it);
21                     break 'outer;
22                 }
23                 _ => {}
24             }
25         }
26     }
27
28     db.body(fn_def.unwrap().into())
29 }
30
31 fn check_diagnostics(ra_fixture: &str) {
32     let db: TestDB = TestDB::with_files(ra_fixture);
33     db.check_diagnostics();
34 }
35
36 fn block_def_map_at(ra_fixture: &str) -> String {
37     let (db, position) = crate::test_db::TestDB::with_position(ra_fixture);
38
39     let module = db.module_at_position(position);
40     module.def_map(&db).dump(&db)
41 }
42
43 fn check_block_scopes_at(ra_fixture: &str, expect: Expect) {
44     let (db, position) = crate::test_db::TestDB::with_position(ra_fixture);
45
46     let module = db.module_at_position(position);
47     let actual = module.def_map(&db).dump_block_scopes(&db);
48     expect.assert_eq(&actual);
49 }
50
51 fn check_at(ra_fixture: &str, expect: Expect) {
52     let actual = block_def_map_at(ra_fixture);
53     expect.assert_eq(&actual);
54 }
55
56 #[test]
57 fn your_stack_belongs_to_me() {
58     cov_mark::check!(your_stack_belongs_to_me);
59     lower(
60         "
61 macro_rules! n_nuple {
62     ($e:tt) => ();
63     ($($rest:tt)*) => {{
64         (n_nuple!($($rest)*)None,)
65     }};
66 }
67 fn main() { n_nuple!(1,2,3); }
68 ",
69     );
70 }
71
72 #[test]
73 fn macro_resolve() {
74     // Regression test for a path resolution bug introduced with inner item handling.
75     lower(
76         r"
77 macro_rules! vec {
78     () => { () };
79     ($elem:expr; $n:expr) => { () };
80     ($($x:expr),+ $(,)?) => { () };
81 }
82 mod m {
83     fn outer() {
84         let _ = vec![FileSet::default(); self.len()];
85     }
86 }
87       ",
88     );
89 }
90
91 #[test]
92 fn cfg_diagnostics() {
93     check_diagnostics(
94         r"
95 fn f() {
96     // The three g̶e̶n̶d̶e̶r̶s̶ statements:
97
98     #[cfg(a)] fn f() {}  // Item statement
99   //^^^^^^^^^^^^^^^^^^^ code is inactive due to #[cfg] directives: a is disabled
100     #[cfg(a)] {}         // Expression statement
101   //^^^^^^^^^^^^ code is inactive due to #[cfg] directives: a is disabled
102     #[cfg(a)] let x = 0; // let statement
103   //^^^^^^^^^^^^^^^^^^^^ code is inactive due to #[cfg] directives: a is disabled
104
105     abc(#[cfg(a)] 0);
106       //^^^^^^^^^^^ code is inactive due to #[cfg] directives: a is disabled
107     let x = Struct {
108         #[cfg(a)] f: 0,
109       //^^^^^^^^^^^^^^ code is inactive due to #[cfg] directives: a is disabled
110     };
111     match () {
112         () => (),
113         #[cfg(a)] () => (),
114       //^^^^^^^^^^^^^^^^^^ code is inactive due to #[cfg] directives: a is disabled
115     }
116
117     #[cfg(a)] 0          // Trailing expression of block
118   //^^^^^^^^^^^ code is inactive due to #[cfg] directives: a is disabled
119 }
120     ",
121     );
122 }
123
124 #[test]
125 fn macro_diag_builtin() {
126     check_diagnostics(
127         r#"
128 #[rustc_builtin_macro]
129 macro_rules! env {}
130
131 #[rustc_builtin_macro]
132 macro_rules! include {}
133
134 #[rustc_builtin_macro]
135 macro_rules! compile_error {}
136
137 #[rustc_builtin_macro]
138 macro_rules! format_args {
139     () => {}
140 }
141
142 fn f() {
143     // Test a handful of built-in (eager) macros:
144
145     include!(invalid);
146   //^^^^^^^^^^^^^^^^^ could not convert tokens
147     include!("does not exist");
148   //^^^^^^^^^^^^^^^^^^^^^^^^^^ failed to load file `does not exist`
149
150     env!(invalid);
151   //^^^^^^^^^^^^^ could not convert tokens
152
153     env!("OUT_DIR");
154   //^^^^^^^^^^^^^^^ `OUT_DIR` not set, enable "run build scripts" to fix
155
156     compile_error!("compile_error works");
157   //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ compile_error works
158
159     // Lazy:
160
161     format_args!();
162   //^^^^^^^^^^^^^^ no rule matches input tokens
163 }
164         "#,
165     );
166 }
167
168 #[test]
169 fn macro_rules_diag() {
170     check_diagnostics(
171         r#"
172 macro_rules! m {
173     () => {};
174 }
175 fn f() {
176     m!();
177
178     m!(hi);
179   //^^^^^^ leftover tokens
180 }
181       "#,
182     );
183 }
184
185 #[test]
186 fn unresolved_macro_diag() {
187     check_diagnostics(
188         r#"
189 fn f() {
190     m!();
191   //^^^^ unresolved macro `m!`
192 }
193       "#,
194     );
195 }
196
197 #[test]
198 fn dollar_crate_in_builtin_macro() {
199     check_diagnostics(
200         r#"
201 #[macro_export]
202 #[rustc_builtin_macro]
203 macro_rules! format_args {}
204
205 #[macro_export]
206 macro_rules! arg {
207     () => {}
208 }
209
210 #[macro_export]
211 macro_rules! outer {
212     () => {
213         $crate::format_args!( "", $crate::arg!(1) )
214     };
215 }
216
217 fn f() {
218     outer!();
219   //^^^^^^^^ leftover tokens
220 }
221         "#,
222     )
223 }