Collect lifetimes inside macro invocations

This commit is contained in:
Taiki Endo 2020-06-07 20:30:03 +09:00
parent 8084258a3e
commit a227a87865
2 changed files with 37 additions and 2 deletions

View File

@ -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;
@ -1921,17 +1921,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,

View File

@ -723,6 +723,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>),
}
}
//////////////////////////////////////////////////////////////////////////