expand: Stop using nonterminals for passing tokens to attribute and derive macros

This commit is contained in:
Vadim Petrochenkov 2020-06-14 14:30:42 +03:00
parent d462551a86
commit a5764de00b
26 changed files with 118 additions and 88 deletions

View file

@ -7,6 +7,6 @@ use proc_macro::TokenStream;
#[proc_macro_derive(A)]
pub fn derive(input: TokenStream) -> TokenStream {
let input = input.to_string();
assert!(input.contains("struct A;"));
assert!(input.contains("struct A ;"));
"struct B;".parse().unwrap()
}

View file

@ -1,3 +1,3 @@
async fn f(mut x: u8) { }
async fn g((mut x, y, mut z): (u8, u8, u8)) { }
async fn g(mut x: u8, (a, mut b, c): (u8, u8, u8), y: u8) { }
async fn f(mut x : u8) { }
async fn g((mut x, y, mut z) : (u8, u8, u8)) { }
async fn g(mut x : u8, (a, mut b, c) : (u8, u8, u8), y : u8) { }

View file

@ -11,11 +11,9 @@ use proc_macro::TokenStream;
pub fn attr_cfg(args: TokenStream, input: TokenStream) -> TokenStream {
let input_str = input.to_string();
assert_eq!(input_str, "fn outer() -> u8 {
#[cfg(foo)]
fn inner() -> u8 { 1 }
#[cfg(bar)]
fn inner() -> u8 { 2 }
assert_eq!(input_str, "fn outer() -> u8
{
#[cfg(foo)] fn inner() -> u8 { 1 } #[cfg(bar)] fn inner() -> u8 { 2 }
inner()
}");

View file

@ -10,14 +10,14 @@ use proc_macro::TokenStream;
#[proc_macro_attribute]
pub fn expect_let(attr: TokenStream, item: TokenStream) -> TokenStream {
assert!(attr.to_string().is_empty());
assert_eq!(item.to_string(), "let string = \"Hello, world!\";");
assert_eq!(item.to_string(), "let string = \"Hello, world!\" ;");
item
}
#[proc_macro_attribute]
pub fn expect_print_stmt(attr: TokenStream, item: TokenStream) -> TokenStream {
assert!(attr.to_string().is_empty());
assert_eq!(item.to_string(), "println!(\"{}\", string);");
assert_eq!(item.to_string(), "println ! (\"{}\", string) ;");
item
}
@ -31,7 +31,7 @@ pub fn expect_expr(attr: TokenStream, item: TokenStream) -> TokenStream {
#[proc_macro_attribute]
pub fn expect_print_expr(attr: TokenStream, item: TokenStream) -> TokenStream {
assert!(attr.to_string().is_empty());
assert_eq!(item.to_string(), "println!(\"{}\", string)");
assert_eq!(item.to_string(), "println ! (\"{}\", string)");
item
}

View file

@ -10,14 +10,14 @@ use proc_macro::TokenStream;
#[proc_macro_attribute]
pub fn expect_let(attr: TokenStream, item: TokenStream) -> TokenStream {
assert!(attr.to_string().is_empty());
assert_eq!(item.to_string(), "let string = \"Hello, world!\";");
assert_eq!(item.to_string(), "let string = \"Hello, world!\" ;");
item
}
#[proc_macro_attribute]
pub fn expect_print_stmt(attr: TokenStream, item: TokenStream) -> TokenStream {
assert!(attr.to_string().is_empty());
assert_eq!(item.to_string(), "println!(\"{}\", string);");
assert_eq!(item.to_string(), "println ! (\"{}\", string) ;");
item
}
@ -31,7 +31,7 @@ pub fn expect_expr(attr: TokenStream, item: TokenStream) -> TokenStream {
#[proc_macro_attribute]
pub fn expect_print_expr(attr: TokenStream, item: TokenStream) -> TokenStream {
assert!(attr.to_string().is_empty());
assert_eq!(item.to_string(), "println!(\"{}\", string)");
assert_eq!(item.to_string(), "println ! (\"{}\", string)");
item
}

View file

@ -10,6 +10,6 @@ use proc_macro::TokenStream;
#[proc_macro_derive(A)]
pub fn derive(input: TokenStream) -> TokenStream {
let input = input.to_string();
assert!(input.contains("struct A;"));
assert!(input.contains("struct A ;"));
"".parse().unwrap()
}

View file

@ -10,6 +10,6 @@ use proc_macro::TokenStream;
#[proc_macro_derive(AToB)]
pub fn derive(input: TokenStream) -> TokenStream {
let input = input.to_string();
assert_eq!(input, "struct A;");
assert_eq!(input, "struct A ;");
"struct B;".parse().unwrap()
}

View file

@ -10,7 +10,7 @@ use proc_macro::TokenStream;
#[proc_macro_derive(B, attributes(B, C))]
pub fn derive(input: TokenStream) -> TokenStream {
let input = input.to_string();
assert!(input.contains("#[B[arbitrary tokens]]"));
assert!(input.contains("#[B [arbitrary tokens]]"));
assert!(input.contains("struct B {"));
assert!(input.contains("#[C]"));
"".parse().unwrap()

View file

@ -10,6 +10,6 @@ use proc_macro::TokenStream;
#[proc_macro_derive(CToD)]
pub fn derive(input: TokenStream) -> TokenStream {
let input = input.to_string();
assert_eq!(input, "struct C;");
assert_eq!(input, "struct C ;");
"struct D;".parse().unwrap()
}

View file

@ -10,12 +10,12 @@ use proc_macro::TokenStream;
#[proc_macro_derive(AToB)]
pub fn derive1(input: TokenStream) -> TokenStream {
println!("input1: {:?}", input.to_string());
assert_eq!(input.to_string(), "struct A;");
assert_eq!(input.to_string(), "struct A ;");
"#[derive(BToC)] struct B;".parse().unwrap()
}
#[proc_macro_derive(BToC)]
pub fn derive2(input: TokenStream) -> TokenStream {
assert_eq!(input.to_string(), "struct B;");
assert_eq!(input.to_string(), "struct B ;");
"struct C;".parse().unwrap()
}

View file

@ -12,7 +12,7 @@ pub fn derive(input: TokenStream) -> TokenStream {
let input = input.to_string();
assert!(input.contains("#[repr(C)]"));
assert!(input.contains("union Test {"));
assert!(input.contains("a: u8,"));
assert!(input.contains("a : u8,"));
assert!(input.contains("}"));
"".parse().unwrap()
}

View file

@ -1,15 +1,16 @@
// force-host
// no-prefer-dynamic
#![feature(proc_macro_quote)]
#![crate_type = "proc-macro"]
extern crate proc_macro;
use proc_macro::TokenStream;
use proc_macro::*;
// Outputs another copy of the struct. Useful for testing the tokens
// seen by the proc_macro.
#[proc_macro_derive(Double)]
pub fn derive(input: TokenStream) -> TokenStream {
format!("mod foo {{ {} }}", input.to_string()).parse().unwrap()
quote!(mod foo { $input })
}

View file

@ -11,7 +11,7 @@ use proc_macro::TokenStream;
#[proc_macro_derive(A)]
pub fn derive(input: TokenStream) -> TokenStream {
let input = input.to_string();
assert!(input.contains("struct A;"));
assert!(input.contains("struct A ;"));
r#"
impl A {
fn a(&self) {

View file

@ -1 +1 @@
input1: "struct A;"
input1: "struct A ;"

View file

@ -38,8 +38,7 @@ PRINT-BANG INPUT (DEBUG): TokenStream [
span: #3 bytes(LO..HI),
},
]
PRINT-ATTR INPUT (DISPLAY): struct A(crate::S);
PRINT-ATTR RE-COLLECTED (DISPLAY): struct A($crate :: S) ;
PRINT-ATTR INPUT (DISPLAY): struct A($crate :: S) ;
PRINT-ATTR INPUT (DEBUG): TokenStream [
Ident {
ident: "struct",

View file

@ -1,5 +1,4 @@
PRINT-ATTR INPUT (DISPLAY): struct A(identity!(crate :: S));
PRINT-ATTR RE-COLLECTED (DISPLAY): struct A(identity ! ($crate :: S)) ;
PRINT-ATTR INPUT (DISPLAY): struct A(identity ! ($crate :: S)) ;
PRINT-ATTR INPUT (DEBUG): TokenStream [
Ident {
ident: "struct",
@ -54,8 +53,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
span: #3 bytes(LO..HI),
},
]
PRINT-ATTR INPUT (DISPLAY): struct B(identity!(::dollar_crate_external :: S));
PRINT-ATTR RE-COLLECTED (DISPLAY): struct B(identity ! ($crate :: S)) ;
PRINT-ATTR INPUT (DISPLAY): struct B(identity ! ($crate :: S)) ;
PRINT-ATTR INPUT (DEBUG): TokenStream [
Ident {
ident: "struct",

View file

@ -38,8 +38,7 @@ PRINT-BANG INPUT (DEBUG): TokenStream [
span: #3 bytes(LO..HI),
},
]
PRINT-ATTR INPUT (DISPLAY): struct A(crate::S);
PRINT-ATTR RE-COLLECTED (DISPLAY): struct A($crate :: S) ;
PRINT-ATTR INPUT (DISPLAY): struct A($crate :: S) ;
PRINT-ATTR INPUT (DEBUG): TokenStream [
Ident {
ident: "struct",
@ -79,8 +78,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
span: #3 bytes(LO..HI),
},
]
PRINT-DERIVE INPUT (DISPLAY): struct D(crate::S);
PRINT-DERIVE RE-COLLECTED (DISPLAY): struct D($crate :: S) ;
PRINT-DERIVE INPUT (DISPLAY): struct D($crate :: S) ;
PRINT-DERIVE INPUT (DEBUG): TokenStream [
Ident {
ident: "struct",
@ -160,8 +158,7 @@ PRINT-BANG INPUT (DEBUG): TokenStream [
span: #13 bytes(LO..HI),
},
]
PRINT-ATTR INPUT (DISPLAY): struct A(::dollar_crate_external::S);
PRINT-ATTR RE-COLLECTED (DISPLAY): struct A($crate :: S) ;
PRINT-ATTR INPUT (DISPLAY): struct A($crate :: S) ;
PRINT-ATTR INPUT (DEBUG): TokenStream [
Ident {
ident: "struct",
@ -201,8 +198,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
span: #13 bytes(LO..HI),
},
]
PRINT-DERIVE INPUT (DISPLAY): struct D(::dollar_crate_external::S);
PRINT-DERIVE RE-COLLECTED (DISPLAY): struct D($crate :: S) ;
PRINT-DERIVE INPUT (DISPLAY): struct D($crate :: S) ;
PRINT-DERIVE INPUT (DEBUG): TokenStream [
Ident {
ident: "struct",

View file

@ -12,8 +12,7 @@ PRINT-BANG INPUT (DEBUG): TokenStream [
span: #3 bytes(269..271),
},
]
PRINT-ATTR INPUT (DISPLAY): const A: u8 = 0;
PRINT-ATTR RE-COLLECTED (DISPLAY): const A : u8 = 0 ;
PRINT-ATTR INPUT (DISPLAY): const A : u8 = 0 ;
PRINT-ATTR INPUT (DEBUG): TokenStream [
Ident {
ident: "const",
@ -49,9 +48,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
span: #0 bytes(0..0),
},
]
PRINT-DERIVE INPUT (DISPLAY): struct A {
}
PRINT-DERIVE RE-COLLECTED (DISPLAY): struct A { }
PRINT-DERIVE INPUT (DISPLAY): struct A { }
PRINT-DERIVE INPUT (DEBUG): TokenStream [
Ident {
ident: "struct",

View file

@ -17,28 +17,27 @@ macro_rules! checker {
}
}
checker!(attr_extern, r#"extern "C" {
fn ffi(#[a1] arg1: i32, #[a2] ...);
}"#);
checker!(attr_extern_cvar, r#"unsafe extern "C" fn cvar(arg1: i32, #[a1] mut args: ...) { }"#);
checker!(attr_alias, "type Alias = fn(#[a1] u8, #[a2] ...);");
checker!(attr_free, "fn free(#[a1] arg1: u8) { let lam = |#[a2] W(x), #[a3] y| (); }");
checker!(attr_inherent_1, "fn inherent1(#[a1] self, #[a2] arg1: u8) { }");
checker!(attr_inherent_2, "fn inherent2(#[a1] &self, #[a2] arg1: u8) { }");
checker!(attr_inherent_3, "fn inherent3<'a>(#[a1] &'a mut self, #[a2] arg1: u8) { }");
checker!(attr_inherent_4, "fn inherent4<'a>(#[a1] self: Box<Self>, #[a2] arg1: u8) { }");
checker!(attr_inherent_issue_64682, "fn inherent5(#[a1] #[a2] arg1: u8, #[a3] arg2: u8) { }");
checker!(attr_trait_1, "fn trait1(#[a1] self, #[a2] arg1: u8);");
checker!(attr_trait_2, "fn trait2(#[a1] &self, #[a2] arg1: u8);");
checker!(attr_trait_3, "fn trait3<'a>(#[a1] &'a mut self, #[a2] arg1: u8);");
checker!(attr_trait_4, "fn trait4<'a>(#[a1] self: Box<Self>, #[a2] arg1: u8, #[a3] Vec<u8>);");
checker!(attr_trait_issue_64682, "fn trait5(#[a1] #[a2] arg1: u8, #[a3] arg2: u8);");
checker!(rename_params, r#"impl Foo {
fn hello(#[angery(true)] a: i32, #[a2] b: i32, #[what = "how"] c: u32) { }
fn hello2(#[a1] #[a2] a: i32, #[what = "how"] b: i32,
#[angery(true)] c: u32) {
}
fn hello_self(#[a1] #[a2] &self, #[a1] #[a2] a: i32,
#[what = "how"] b: i32, #[angery(true)] c: u32) {
}
checker!(attr_extern, r#"extern "C" { fn ffi(#[a1] arg1 : i32, #[a2] ...) ; }"#);
checker!(attr_extern_cvar, r#"unsafe extern "C" fn cvar(arg1 : i32, #[a1] mut args : ...) { }"#);
checker!(attr_alias, "type Alias = fn(#[a1] u8, #[a2] ...) ;");
checker!(attr_free, "fn free(#[a1] arg1 : u8) { let lam = | #[a2] W(x), #[a3] y | () ; }");
checker!(attr_inherent_1, "fn inherent1(#[a1] self, #[a2] arg1 : u8) { }");
checker!(attr_inherent_2, "fn inherent2(#[a1] & self, #[a2] arg1 : u8) { }");
checker!(attr_inherent_3, "fn inherent3 < 'a > (#[a1] & 'a mut self, #[a2] arg1 : u8) { }");
checker!(attr_inherent_4, "fn inherent4 < 'a > (#[a1] self : Box < Self >, #[a2] arg1 : u8) { }");
checker!(attr_inherent_issue_64682, "fn inherent5(#[a1] #[a2] arg1 : u8, #[a3] arg2 : u8) { }");
checker!(attr_trait_1, "fn trait1(#[a1] self, #[a2] arg1 : u8) ;");
checker!(attr_trait_2, "fn trait2(#[a1] & self, #[a2] arg1 : u8) ;");
checker!(attr_trait_3, "fn trait3 < 'a > (#[a1] & 'a mut self, #[a2] arg1 : u8) ;");
checker!(attr_trait_4, r#"fn trait4 < 'a >
(#[a1] self : Box < Self >, #[a2] arg1 : u8, #[a3] Vec < u8 >) ;"#);
checker!(attr_trait_issue_64682, "fn trait5(#[a1] #[a2] arg1 : u8, #[a3] arg2 : u8) ;");
checker!(rename_params, r#"impl Foo
{
fn hello(#[angery(true)] a : i32, #[a2] b : i32, #[what = "how"] c : u32)
{ } fn
hello2(#[a1] #[a2] a : i32, #[what = "how"] b : i32, #[angery(true)] c :
u32) { } fn
hello_self(#[a1] #[a2] & self, #[a1] #[a2] a : i32, #[what = "how"] b :
i32, #[angery(true)] c : u32) { }
}"#);