Make AST borrow checker happy

This commit is contained in:
Taiki Endo 2020-10-24 05:45:15 +09:00
parent c67017d466
commit e81f54fbc8

View File

@ -10,9 +10,11 @@ use syn::{
}; };
pub fn replace_receiver(input: &mut DeriveInput) { pub fn replace_receiver(input: &mut DeriveInput) {
let ident = &input.ident; let self_ty = {
let ty_generics = input.generics.split_for_impl().1; let ident = &input.ident;
let self_ty = parse_quote!(#ident #ty_generics); let ty_generics = input.generics.split_for_impl().1;
parse_quote!(#ident #ty_generics)
};
let mut visitor = ReplaceReceiver(&self_ty); let mut visitor = ReplaceReceiver(&self_ty);
visitor.visit_generics_mut(&mut input.generics); visitor.visit_generics_mut(&mut input.generics);
visitor.visit_data_mut(&mut input.data); visitor.visit_data_mut(&mut input.data);
@ -30,9 +32,12 @@ impl ReplaceReceiver<'_> {
return; return;
} }
let first = &path.segments[0]; // Make borrow checker happy
if first.ident != "Self" || !first.arguments.is_empty() { {
return; let first = &path.segments[0];
if first.ident != "Self" || !first.arguments.is_empty() {
return;
}
} }
if path.segments.len() == 1 { if path.segments.len() == 1 {
@ -40,7 +45,7 @@ impl ReplaceReceiver<'_> {
return; return;
} }
let span = first.ident.span(); let span = path.segments[0].ident.span();
*qself = Some(QSelf { *qself = Some(QSelf {
lt_token: Token![<](span), lt_token: Token![<](span),
ty: Box::new(self.self_ty(span).into()), ty: Box::new(self.self_ty(span).into()),
@ -60,12 +65,15 @@ impl ReplaceReceiver<'_> {
return; return;
} }
let first = &path.segments[0]; // Make borrow checker happy
if first.ident != "Self" || !first.arguments.is_empty() { {
return; let first = &path.segments[0];
if first.ident != "Self" || !first.arguments.is_empty() {
return;
}
} }
let self_ty = self.self_ty(first.ident.span()); let self_ty = self.self_ty(path.segments[0].ident.span());
let variant = mem::replace(path, self_ty.path); let variant = mem::replace(path, self_ty.path);
for segment in &mut path.segments { for segment in &mut path.segments {
if let PathArguments::AngleBracketed(bracketed) = &mut segment.arguments { if let PathArguments::AngleBracketed(bracketed) = &mut segment.arguments {
@ -92,20 +100,21 @@ impl ReplaceReceiver<'_> {
let self_ty = self.self_ty(ident.span()); let self_ty = self.self_ty(ident.span());
match iter.peek() { match iter.peek() {
Some(TokenTree::Punct(p)) Some(TokenTree::Punct(p))
if p.as_char() == ':' && p.spacing() == Spacing::Joint => if p.as_char() == ':' && p.spacing() == Spacing::Joint => {}
{ _ => {
let next = iter.next().unwrap(); out.extend(quote!(#self_ty));
match iter.peek() { continue;
Some(TokenTree::Punct(p)) if p.as_char() == ':' => { }
let span = ident.span(); }
out.extend(quote_spanned!(span=> <#self_ty>)); let next = iter.next().unwrap();
} match iter.peek() {
_ => out.extend(quote!(#self_ty)), Some(TokenTree::Punct(p)) if p.as_char() == ':' => {
} let span = ident.span();
out.push(next); out.extend(quote_spanned!(span=> <#self_ty>));
} }
_ => out.extend(quote!(#self_ty)), _ => out.extend(quote!(#self_ty)),
} }
out.push(next);
} else { } else {
out.push(TokenTree::Ident(ident)); out.push(TokenTree::Ident(ident));
} }
@ -130,15 +139,18 @@ impl ReplaceReceiver<'_> {
impl VisitMut for ReplaceReceiver<'_> { impl VisitMut for ReplaceReceiver<'_> {
// `Self` -> `Receiver` // `Self` -> `Receiver`
fn visit_type_mut(&mut self, ty: &mut Type) { fn visit_type_mut(&mut self, ty: &mut Type) {
if let Type::Path(node) = ty { let span = if let Type::Path(node) = ty {
if node.qself.is_none() && node.path.is_ident("Self") { if node.qself.is_none() && node.path.is_ident("Self") {
*ty = self.self_ty(node.path.segments[0].ident.span()).into(); node.path.segments[0].ident.span()
} else { } else {
self.visit_type_path_mut(node); self.visit_type_path_mut(node);
return;
} }
} else { } else {
visit_mut::visit_type_mut(self, ty); visit_mut::visit_type_mut(self, ty);
} return;
};
*ty = self.self_ty(span).into();
} }
// `Self::Assoc` -> `<Receiver>::Assoc` // `Self::Assoc` -> `<Receiver>::Assoc`