blob: c28fc87fdcf87b53b61ac03354c17bc89a178a9a [file] [log] [blame]
#[macro_use]
mod macros;
use proc_macro2::{Delimiter, Group, Ident, Span, TokenStream, TokenTree};
use quote::quote;
use std::iter::FromIterator;
use syn::Item;
#[test]
fn test_macro_variable_attr() {
// mimics the token stream corresponding to `$attr fn f() {}`
let tokens = TokenStream::from_iter(vec![
TokenTree::Group(Group::new(Delimiter::None, quote! { #[test] })),
TokenTree::Ident(Ident::new("fn", Span::call_site())),
TokenTree::Ident(Ident::new("f", Span::call_site())),
TokenTree::Group(Group::new(Delimiter::Parenthesis, TokenStream::new())),
TokenTree::Group(Group::new(Delimiter::Brace, TokenStream::new())),
]);
snapshot!(tokens as Item, @r###"
Item::Fn {
attrs: [
Attribute {
style: Outer,
path: Path {
segments: [
PathSegment {
ident: "test",
arguments: None,
},
],
},
tokens: TokenStream(``),
},
],
vis: Inherited,
sig: Signature {
ident: "f",
generics: Generics,
output: Default,
},
block: Block,
}
"###);
}
#[test]
fn test_negative_impl() {
// Rustc parses all of the following.
#[cfg(any())]
impl ! {}
let tokens = quote! {
impl ! {}
};
snapshot!(tokens as Item, @r###"
Item::Impl {
generics: Generics,
self_ty: Type::Never,
}
"###);
#[cfg(any())]
#[rustfmt::skip]
impl !Trait {}
let tokens = quote! {
impl !Trait {}
};
snapshot!(tokens as Item, @r###"
Item::Impl {
generics: Generics,
self_ty: Verbatim(`! Trait`),
}
"###);
#[cfg(any())]
impl !Trait for T {}
let tokens = quote! {
impl !Trait for T {}
};
snapshot!(tokens as Item, @r###"
Item::Impl {
generics: Generics,
trait_: Some((
Some,
Path {
segments: [
PathSegment {
ident: "Trait",
arguments: None,
},
],
},
)),
self_ty: Type::Path {
path: Path {
segments: [
PathSegment {
ident: "T",
arguments: None,
},
],
},
},
}
"###);
#[cfg(any())]
#[rustfmt::skip]
impl !! {}
let tokens = quote! {
impl !! {}
};
snapshot!(tokens as Item, @r###"
Item::Impl {
generics: Generics,
self_ty: Verbatim(`! !`),
}
"###);
}
#[test]
fn test_macro_variable_impl() {
// mimics the token stream corresponding to `impl $trait for $ty {}`
let tokens = TokenStream::from_iter(vec![
TokenTree::Ident(Ident::new("impl", Span::call_site())),
TokenTree::Group(Group::new(Delimiter::None, quote!(Trait))),
TokenTree::Ident(Ident::new("for", Span::call_site())),
TokenTree::Group(Group::new(Delimiter::None, quote!(Type))),
TokenTree::Group(Group::new(Delimiter::Brace, TokenStream::new())),
]);
snapshot!(tokens as Item, @r###"
Item::Impl {
generics: Generics,
trait_: Some((
None,
Path {
segments: [
PathSegment {
ident: "Trait",
arguments: None,
},
],
},
)),
self_ty: Type::Group {
elem: Type::Path {
path: Path {
segments: [
PathSegment {
ident: "Type",
arguments: None,
},
],
},
},
},
}
"###);
}