@@ -5,66 +5,44 @@ extern crate proc_macro;
55use proc_macro:: { Delimiter , Group , Ident , Literal , Punct , Spacing , Span , TokenStream , TokenTree } ;
66use std:: iter:: FromIterator ;
77
8- /// Expands to a call to `println!` having a format string as its argument
9- /// but with the format string's span set to that of the proc macro's input token
10- #[ proc_macro]
11- pub fn foo ( input : TokenStream ) -> TokenStream {
12- let token = input. into_iter ( ) . next ( ) . unwrap ( ) ;
13- let mut lit: Literal = r#"r"{}""# . parse ( ) . unwrap ( ) ;
14- lit. set_span ( token. span ( ) ) ;
8+ /// Builds a `println!(<fmt_str>)` token stream with the given span on the format string literal.
9+ fn make_println ( fmt_str : & str , span : Span ) -> TokenStream {
10+ let mut lit: Literal = fmt_str. parse ( ) . unwrap ( ) ;
11+ lit. set_span ( span) ;
1512 FromIterator :: < TokenTree > :: from_iter ( [
1613 Ident :: new ( "println" , Span :: mixed_site ( ) ) . into ( ) ,
1714 Punct :: new ( '!' , Spacing :: Alone ) . into ( ) ,
1815 Group :: new ( Delimiter :: Parenthesis , TokenTree :: from ( lit) . into ( ) ) . into ( ) ,
1916 ] )
2017}
2118
19+ /// Expands to `println!(r"{}")` with the span of the first input token.
20+ #[ proc_macro]
21+ pub fn foo ( input : TokenStream ) -> TokenStream {
22+ let span = input. into_iter ( ) . next ( ) . unwrap ( ) . span ( ) ;
23+ make_println ( r#"r"{}""# , span)
24+ }
2225
23- /// Same as `foo` but with the format string containing multiple `#`s
26+ /// Same as `foo` but with hashes: expands to `println!(r##"{}"##)`.
2427#[ proc_macro]
2528pub fn foo2 ( input : TokenStream ) -> TokenStream {
26- let token = input. into_iter ( ) . next ( ) . unwrap ( ) ;
27- let mut lit: Literal = r###"r##"{}"##"### . parse ( ) . unwrap ( ) ;
28- lit. set_span ( token. span ( ) ) ;
29- FromIterator :: < TokenTree > :: from_iter ( [
30- Ident :: new ( "println" , Span :: mixed_site ( ) ) . into ( ) ,
31- Punct :: new ( '!' , Spacing :: Alone ) . into ( ) ,
32- Group :: new ( Delimiter :: Parenthesis , TokenTree :: from ( lit) . into ( ) ) . into ( ) ,
33- ] )
29+ let span = input. into_iter ( ) . next ( ) . unwrap ( ) . span ( ) ;
30+ make_println ( r###"r##"{}"##"### , span)
3431}
3532
36-
37- /// Same as `foo` but respans to a combination of two consecutive tokens.
38- /// This makes possible scenarios where you can land on the second token
39- /// which is a multi-byte char
33+ /// Expands to `println!(r"{}")` with a span joining two input tokens,
34+ /// creating a span whose source text may not be a valid raw string.
4035#[ proc_macro]
4136pub fn foo3 ( input : TokenStream ) -> TokenStream {
4237 let mut iter = input. into_iter ( ) ;
43- let first = iter. next ( ) . unwrap ( ) ;
44- let second = iter. next ( ) . unwrap ( ) ;
45- let joined_span = first. span ( ) . join ( second. span ( ) ) . unwrap ( ) ;
46- let mut lit: Literal = r#"r"{}""# . parse ( ) . unwrap ( ) ;
47- lit. set_span ( joined_span) ;
48- FromIterator :: < TokenTree > :: from_iter ( [
49- Ident :: new ( "println" , Span :: mixed_site ( ) ) . into ( ) ,
50- Punct :: new ( '!' , Spacing :: Alone ) . into ( ) ,
51- Group :: new ( Delimiter :: Parenthesis , TokenTree :: from ( lit) . into ( ) ) . into ( ) ,
52- ] )
38+ let span = iter. next ( ) . unwrap ( ) . span ( ) . join ( iter. next ( ) . unwrap ( ) . span ( ) ) . unwrap ( ) ;
39+ make_println ( r#"r"{}""# , span)
5340}
5441
55-
56- /// Same as `foo3` but with hashes in the raw string literal
42+ /// Same as `foo3` but with hashes: expands to `println!(r##"{}"##)`.
5743#[ proc_macro]
5844pub fn foo4 ( input : TokenStream ) -> TokenStream {
5945 let mut iter = input. into_iter ( ) ;
60- let first = iter. next ( ) . unwrap ( ) ;
61- let second = iter. next ( ) . unwrap ( ) ;
62- let joined_span = first. span ( ) . join ( second. span ( ) ) . unwrap ( ) ;
63- let mut lit: Literal = r###"r##"{}"##"### . parse ( ) . unwrap ( ) ;
64- lit. set_span ( joined_span) ;
65- FromIterator :: < TokenTree > :: from_iter ( [
66- Ident :: new ( "println" , Span :: mixed_site ( ) ) . into ( ) ,
67- Punct :: new ( '!' , Spacing :: Alone ) . into ( ) ,
68- Group :: new ( Delimiter :: Parenthesis , TokenTree :: from ( lit) . into ( ) ) . into ( ) ,
69- ] )
46+ let span = iter. next ( ) . unwrap ( ) . span ( ) . join ( iter. next ( ) . unwrap ( ) . span ( ) ) . unwrap ( ) ;
47+ make_println ( r###"r##"{}"##"### , span)
7048}
0 commit comments