9402: internal: add cloning macro fixture r=matklad a=matklad

bors r+
🤖

Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
bors[bot] 2021-06-25 20:38:18 +00:00 committed by GitHub
commit 9552d79f63
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 41 additions and 1 deletions

View File

@ -42,6 +42,19 @@ fn test_fn_like_macro() {
);
}
#[test]
fn test_fn_like_macro2() {
assert_expand(
"fn_like_clone_tokens",
r#"ident, []"#,
expect![[r#"
SUBTREE $
IDENT ident 4294967295
PUNCH , [alone] 4294967295
SUBTREE [] 4294967295"#]],
);
}
#[test]
fn test_attr_macro() {
// Corresponds to
@ -70,6 +83,7 @@ fn list_test_macros() {
fn_like_noop [FuncLike]
fn_like_panic [FuncLike]
fn_like_error [FuncLike]
fn_like_clone_tokens [FuncLike]
attr_noop [Attr]
attr_panic [Attr]
attr_error [Attr]

View File

@ -1,6 +1,6 @@
//! Exports a few trivial procedural macros for testing.
use proc_macro::TokenStream;
use proc_macro::{Group, Ident, Punct, TokenStream, TokenTree};
#[proc_macro]
pub fn fn_like_noop(args: TokenStream) -> TokenStream {
@ -17,6 +17,11 @@ pub fn fn_like_error(args: TokenStream) -> TokenStream {
format!("compile_error!(\"fn_like_error!({})\");", args).parse().unwrap()
}
#[proc_macro]
pub fn fn_like_clone_tokens(args: TokenStream) -> TokenStream {
clone_stream(args)
}
#[proc_macro_attribute]
pub fn attr_noop(_args: TokenStream, item: TokenStream) -> TokenStream {
item
@ -46,3 +51,24 @@ pub fn derive_panic(item: TokenStream) -> TokenStream {
pub fn derive_error(item: TokenStream) -> TokenStream {
format!("compile_error!(\"#[derive(DeriveError)] {}\");", item).parse().unwrap()
}
fn clone_stream(ts: TokenStream) -> TokenStream {
ts.into_iter().map(clone_tree).collect()
}
fn clone_tree(t: TokenTree) -> TokenTree {
match t {
TokenTree::Group(orig) => {
let mut new = Group::new(orig.delimiter(), clone_stream(orig.stream()));
new.set_span(orig.span());
TokenTree::Group(new)
}
TokenTree::Ident(orig) => TokenTree::Ident(Ident::new(&orig.to_string(), orig.span())),
TokenTree::Punct(orig) => {
let mut new = Punct::new(orig.as_char(), orig.spacing());
new.set_span(orig.span());
TokenTree::Punct(new)
}
TokenTree::Literal(_orig) => unimplemented!(),
}
}