aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_expand/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_expand/src')
-rw-r--r--crates/hir_expand/src/builtin_macro.rs64
1 files changed, 27 insertions, 37 deletions
diff --git a/crates/hir_expand/src/builtin_macro.rs b/crates/hir_expand/src/builtin_macro.rs
index 57bc6fbd7..eb57ea7d6 100644
--- a/crates/hir_expand/src/builtin_macro.rs
+++ b/crates/hir_expand/src/builtin_macro.rs
@@ -6,7 +6,7 @@ use crate::{
6 6
7use base_db::{AnchoredPath, FileId}; 7use base_db::{AnchoredPath, FileId};
8use either::Either; 8use either::Either;
9use mbe::{parse_to_token_tree, ExpandResult}; 9use mbe::{parse_exprs_with_sep, parse_to_token_tree, ExpandResult};
10use parser::FragmentKind; 10use parser::FragmentKind;
11use syntax::ast::{self, AstToken}; 11use syntax::ast::{self, AstToken};
12 12
@@ -182,25 +182,10 @@ fn assert_expand(
182 // ```, 182 // ```,
183 // which is wrong but useful. 183 // which is wrong but useful.
184 184
185 let mut args = Vec::new(); 185 let args = parse_exprs_with_sep(tt, ',');
186 let mut current = Vec::new();
187 for tt in tt.token_trees.iter().cloned() {
188 match tt {
189 tt::TokenTree::Leaf(tt::Leaf::Punct(p)) if p.char == ',' => {
190 args.push(current);
191 current = Vec::new();
192 }
193 _ => {
194 current.push(tt);
195 }
196 }
197 }
198 if !current.is_empty() {
199 args.push(current);
200 }
201 186
202 let arg_tts = args.into_iter().flat_map(|arg| { 187 let arg_tts = args.into_iter().flat_map(|arg| {
203 quote! { &(##arg), } 188 quote! { &(#arg), }
204 }.token_trees).collect::<Vec<_>>(); 189 }.token_trees).collect::<Vec<_>>();
205 190
206 let expanded = quote! { 191 let expanded = quote! {
@@ -238,35 +223,21 @@ fn format_args_expand(
238 // ]) 223 // ])
239 // ```, 224 // ```,
240 // which is still not really correct, but close enough for now 225 // which is still not really correct, but close enough for now
241 let mut args = Vec::new(); 226 let mut args = parse_exprs_with_sep(tt, ',');
242 let mut current = Vec::new(); 227
243 for tt in tt.token_trees.iter().cloned() {
244 match tt {
245 tt::TokenTree::Leaf(tt::Leaf::Punct(p)) if p.char == ',' => {
246 args.push(current);
247 current = Vec::new();
248 }
249 _ => {
250 current.push(tt);
251 }
252 }
253 }
254 if !current.is_empty() {
255 args.push(current);
256 }
257 if args.is_empty() { 228 if args.is_empty() {
258 return ExpandResult::only_err(mbe::ExpandError::NoMatchingRule); 229 return ExpandResult::only_err(mbe::ExpandError::NoMatchingRule);
259 } 230 }
260 for arg in &mut args { 231 for arg in &mut args {
261 // Remove `key =`. 232 // Remove `key =`.
262 if matches!(arg.get(1), Some(tt::TokenTree::Leaf(tt::Leaf::Punct(p))) if p.char == '=' && p.spacing != tt::Spacing::Joint) 233 if matches!(arg.token_trees.get(1), Some(tt::TokenTree::Leaf(tt::Leaf::Punct(p))) if p.char == '=' && p.spacing != tt::Spacing::Joint)
263 { 234 {
264 arg.drain(..2); 235 arg.token_trees.drain(..2);
265 } 236 }
266 } 237 }
267 let _format_string = args.remove(0); 238 let _format_string = args.remove(0);
268 let arg_tts = args.into_iter().flat_map(|arg| { 239 let arg_tts = args.into_iter().flat_map(|arg| {
269 quote! { std::fmt::ArgumentV1::new(&(##arg), std::fmt::Display::fmt), } 240 quote! { std::fmt::ArgumentV1::new(&(#arg), std::fmt::Display::fmt), }
270 }.token_trees).collect::<Vec<_>>(); 241 }.token_trees).collect::<Vec<_>>();
271 let expanded = quote! { 242 let expanded = quote! {
272 std::fmt::Arguments::new_v1(&[], &[##arg_tts]) 243 std::fmt::Arguments::new_v1(&[], &[##arg_tts])
@@ -720,6 +691,25 @@ mod tests {
720 } 691 }
721 692
722 #[test] 693 #[test]
694 fn test_format_args_expand_with_comma_exprs() {
695 let expanded = expand_builtin_macro(
696 r#"
697 #[rustc_builtin_macro]
698 macro_rules! format_args {
699 ($fmt:expr) => ({ /* compiler built-in */ });
700 ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ })
701 }
702 format_args!("{} {:?}", a::<A,B>(), b);
703 "#,
704 );
705
706 assert_eq!(
707 expanded,
708 r#"std::fmt::Arguments::new_v1(&[], &[std::fmt::ArgumentV1::new(&(a::<A,B>()),std::fmt::Display::fmt),std::fmt::ArgumentV1::new(&(b),std::fmt::Display::fmt),])"#
709 );
710 }
711
712 #[test]
723 fn test_include_bytes_expand() { 713 fn test_include_bytes_expand() {
724 let expanded = expand_builtin_macro( 714 let expanded = expand_builtin_macro(
725 r#" 715 r#"