@@ -287,23 +287,34 @@ fn concat_expand(
287
287
_arg_id : EagerMacroId ,
288
288
tt : & tt:: Subtree ,
289
289
) -> ExpandResult < Option < ( tt:: Subtree , FragmentKind ) > > {
290
+ let mut err = None ;
290
291
let mut text = String :: new ( ) ;
291
292
for ( i, t) in tt. token_trees . iter ( ) . enumerate ( ) {
292
293
match t {
293
294
tt:: TokenTree :: Leaf ( tt:: Leaf :: Literal ( it) ) if i % 2 == 0 => {
294
- text += & match unquote_str ( & it) {
295
- Some ( s) => s,
296
- None => {
297
- return ExpandResult :: only_err ( mbe:: ExpandError :: ConversionError ) ;
298
- }
299
- } ;
295
+ // concat works with string and char literals, so remove any quotes.
296
+ // It also works with integer, float and boolean literals, so just use the rest
297
+ // as-is.
298
+
299
+ text += it
300
+ . text
301
+ . trim_start_matches ( |c| match c {
302
+ 'r' | '#' | '\'' | '"' => true ,
303
+ _ => false ,
304
+ } )
305
+ . trim_end_matches ( |c| match c {
306
+ '#' | '\'' | '"' => true ,
307
+ _ => false ,
308
+ } ) ;
300
309
}
301
310
tt:: TokenTree :: Leaf ( tt:: Leaf :: Punct ( punct) ) if i % 2 == 1 && punct. char == ',' => ( ) ,
302
- _ => return ExpandResult :: only_err ( mbe:: ExpandError :: UnexpectedToken ) ,
311
+ _ => {
312
+ err. get_or_insert ( mbe:: ExpandError :: UnexpectedToken ) ;
313
+ }
303
314
}
304
315
}
305
316
306
- ExpandResult :: ok ( Some ( ( quote ! ( #text) , FragmentKind :: Expr ) ) )
317
+ ExpandResult { value : Some ( ( quote ! ( #text) , FragmentKind :: Expr ) ) , err }
307
318
}
308
319
309
320
fn relative_file (
@@ -686,4 +697,19 @@ mod tests {
686
697
687
698
assert_eq ! ( expanded, r#"b"""# ) ;
688
699
}
700
+
701
+ #[ test]
702
+ fn test_concat_expand ( ) {
703
+ let expanded = expand_builtin_macro (
704
+ r##"
705
+ #[rustc_builtin_macro]
706
+ macro_rules! concat {}
707
+ concat!("foo", 0, r#"bar"#);
708
+ "## ,
709
+ ) ;
710
+
711
+ assert_eq ! ( expanded, r#""foo0bar""# ) ;
712
+
713
+ // FIXME: `true`/`false` literals don't work.
714
+ }
689
715
}
0 commit comments