Merge pull request #1831 from taiki-e/borrow-macro

Collect lifetimes inside macro invocations
This commit is contained in:
David Tolnay 2021-01-24 19:08:20 -08:00 committed by GitHub
commit aeee73fe92
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
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;
@ -1901,17 +1901,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>),
}
}
//////////////////////////////////////////////////////////////////////////