Skip to content

Commit

Permalink
Collect lifetimes inside macro invocations
Browse files Browse the repository at this point in the history
  • Loading branch information
taiki-e committed Jun 7, 2020
1 parent 9f331cc commit dc4996d
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 2 deletions.
27 changes: 25 additions & 2 deletions serde_derive/src/internals/attr.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use internals::symbol::*;
use internals::{ungroup, Ctxt};
use proc_macro2::{Group, Span, TokenStream, TokenTree};
use proc_macro2::{Group, Spacing, Span, TokenStream, TokenTree};
use quote::ToTokens;
use std::borrow::Cow;
use std::collections::BTreeSet;
Expand Down Expand Up @@ -1917,17 +1917,40 @@ fn collect_lifetimes(ty: &syn::Type, out: &mut BTreeSet<syn::Lifetime>) {
syn::Type::Group(ty) => {
collect_lifetimes(&ty.elem, out);
}
syn::Type::Macro(ty) => {
collect_lifetimes_from_tokens(ty.mac.tokens.clone(), out);
}
syn::Type::BareFn(_)
| syn::Type::Never(_)
| syn::Type::TraitObject(_)
| syn::Type::ImplTrait(_)
| syn::Type::Infer(_)
| syn::Type::Macro(_)
| syn::Type::Verbatim(_)
| _ => {}
}
}

fn collect_lifetimes_from_tokens(tokens: TokenStream, out: &mut BTreeSet<syn::Lifetime>) {
let mut iter = tokens.into_iter();
while let Some(tt) = iter.next() {
match &tt {
TokenTree::Punct(op) if op.as_char() == '\'' && op.spacing() == Spacing::Joint => {
if let Some(TokenTree::Ident(ident)) = iter.next() {
out.insert(syn::Lifetime {
apostrophe: op.span(),
ident,
});
}
}
TokenTree::Group(group) => {
let tokens = group.stream();
collect_lifetimes_from_tokens(tokens, out);
}
_ => {}
}
}
}

fn parse_lit_str<T>(s: &syn::LitStr) -> parse::Result<T>
where
T: Parse,
Expand Down
12 changes: 12 additions & 0 deletions test_suite/tests/test_gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,18 @@ fn test_gen() {
}

deriving!(&'a str);

macro_rules! mac {
($($tt:tt)*) => {
$($tt)*
};
}

#[derive(Deserialize)]
struct BorrowLifetimeInsideMacro<'a> {
#[serde(borrow = "'a")]
f: mac!(Cow<'a, str>),
}
}

//////////////////////////////////////////////////////////////////////////
Expand Down

0 comments on commit dc4996d

Please sign in to comment.