diff options
Diffstat (limited to 'crates/ra_hir_expand/src/builtin_macro.rs')
-rw-r--r-- | crates/ra_hir_expand/src/builtin_macro.rs | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/crates/ra_hir_expand/src/builtin_macro.rs b/crates/ra_hir_expand/src/builtin_macro.rs index a90007f26..f9d3787f6 100644 --- a/crates/ra_hir_expand/src/builtin_macro.rs +++ b/crates/ra_hir_expand/src/builtin_macro.rs | |||
@@ -88,6 +88,7 @@ register_builtin! { | |||
88 | (compile_error, CompileError) => compile_error_expand, | 88 | (compile_error, CompileError) => compile_error_expand, |
89 | (file, File) => file_expand, | 89 | (file, File) => file_expand, |
90 | (line, Line) => line_expand, | 90 | (line, Line) => line_expand, |
91 | (assert, Assert) => assert_expand, | ||
91 | (stringify, Stringify) => stringify_expand, | 92 | (stringify, Stringify) => stringify_expand, |
92 | (format_args, FormatArgs) => format_args_expand, | 93 | (format_args, FormatArgs) => format_args_expand, |
93 | // format_args_nl only differs in that it adds a newline in the end, | 94 | // format_args_nl only differs in that it adds a newline in the end, |
@@ -151,6 +152,45 @@ fn column_expand( | |||
151 | Ok(expanded) | 152 | Ok(expanded) |
152 | } | 153 | } |
153 | 154 | ||
155 | fn assert_expand( | ||
156 | _db: &dyn AstDatabase, | ||
157 | _id: LazyMacroId, | ||
158 | tt: &tt::Subtree, | ||
159 | ) -> Result<tt::Subtree, mbe::ExpandError> { | ||
160 | // A hacky implementation for goto def and hover | ||
161 | // We expand `assert!(cond, arg1, arg2)` to | ||
162 | // ``` | ||
163 | // {(cond, &(arg1), &(arg2));} | ||
164 | // ```, | ||
165 | // which is wrong but useful. | ||
166 | |||
167 | let mut args = Vec::new(); | ||
168 | let mut current = Vec::new(); | ||
169 | for tt in tt.token_trees.iter().cloned() { | ||
170 | match tt { | ||
171 | tt::TokenTree::Leaf(tt::Leaf::Punct(p)) if p.char == ',' => { | ||
172 | args.push(current); | ||
173 | current = Vec::new(); | ||
174 | } | ||
175 | _ => { | ||
176 | current.push(tt); | ||
177 | } | ||
178 | } | ||
179 | } | ||
180 | if !current.is_empty() { | ||
181 | args.push(current); | ||
182 | } | ||
183 | |||
184 | let arg_tts = args.into_iter().flat_map(|arg| { | ||
185 | quote! { &(##arg), } | ||
186 | }.token_trees).collect::<Vec<_>>(); | ||
187 | |||
188 | let expanded = quote! { | ||
189 | { { (##arg_tts); } } | ||
190 | }; | ||
191 | Ok(expanded) | ||
192 | } | ||
193 | |||
154 | fn file_expand( | 194 | fn file_expand( |
155 | _db: &dyn AstDatabase, | 195 | _db: &dyn AstDatabase, |
156 | _id: LazyMacroId, | 196 | _id: LazyMacroId, |
@@ -494,6 +534,22 @@ mod tests { | |||
494 | } | 534 | } |
495 | 535 | ||
496 | #[test] | 536 | #[test] |
537 | fn test_assert_expand() { | ||
538 | let expanded = expand_builtin_macro( | ||
539 | r#" | ||
540 | #[rustc_builtin_macro] | ||
541 | macro_rules! assert { | ||
542 | ($cond:expr) => ({ /* compiler built-in */ }); | ||
543 | ($cond:expr, $($args:tt)*) => ({ /* compiler built-in */ }) | ||
544 | } | ||
545 | assert!(true, "{} {:?}", arg1(a, b, c), arg2); | ||
546 | "#, | ||
547 | ); | ||
548 | |||
549 | assert_eq!(expanded, "{{(&(true), &(\"{} {:?}\"), &(arg1(a,b,c)), &(arg2),);}}"); | ||
550 | } | ||
551 | |||
552 | #[test] | ||
497 | fn test_compile_error_expand() { | 553 | fn test_compile_error_expand() { |
498 | let expanded = expand_builtin_macro( | 554 | let expanded = expand_builtin_macro( |
499 | r#" | 555 | r#" |