|
1 | 1 | use darling::ToTokens;
|
2 |
| -use syn::punctuated::Punctuated; |
| 2 | +use syn::visit_mut::VisitMut; |
3 | 3 | use syn::{Attribute, Expr, GenericArgument, ItemImpl, Lit, Meta, PathArguments, Type, TypePath};
|
4 | 4 |
|
5 | 5 | /// From a let of attributes to an item, extracts the ones that are documentation, as strings.
|
@@ -27,53 +27,45 @@ pub fn extract_doc_lines(attributes: &[Attribute]) -> Vec<String> {
|
27 | 27 | docs
|
28 | 28 | }
|
29 | 29 |
|
30 |
| -/// Ugly, incomplete function to purge `'a` from a `Generic<'a, T>`. |
31 |
| -pub fn purge_lifetimes_from_type(the_type: &Type) -> Type { |
32 |
| - let mut rval = the_type.clone(); |
33 |
| - |
34 |
| - match &mut rval { |
35 |
| - Type::Path(x) => { |
36 |
| - for p in &mut x.path.segments { |
37 |
| - let mut still_has_parameter = false; |
38 |
| - |
39 |
| - match &mut p.arguments { |
40 |
| - PathArguments::None => {} |
41 |
| - PathArguments::AngleBracketed(angled_args) => { |
42 |
| - let mut p = Punctuated::new(); |
| 30 | +struct LifetimeRemover; |
43 | 31 |
|
44 |
| - for generic_arg in &mut angled_args.args { |
45 |
| - match generic_arg { |
46 |
| - GenericArgument::Lifetime(_) => {} |
47 |
| - GenericArgument::Type(x) => { |
48 |
| - let x = purge_lifetimes_from_type(x); |
49 |
| - p.push(GenericArgument::Type(x)); |
50 |
| - } |
51 |
| - GenericArgument::Constraint(x) => p.push(GenericArgument::Constraint(x.clone())), |
52 |
| - GenericArgument::Const(x) => p.push(GenericArgument::Const(x.clone())), |
53 |
| - _ => {} |
54 |
| - } |
| 32 | +impl syn::visit_mut::VisitMut for LifetimeRemover { |
| 33 | + fn visit_path_segment_mut(&mut self, path_segment: &mut syn::PathSegment) { |
| 34 | + match &mut path_segment.arguments { |
| 35 | + PathArguments::None => {} |
| 36 | + PathArguments::AngleBracketed(angled_args) => { |
| 37 | + let punctuated = std::mem::take(&mut angled_args.args); |
| 38 | + angled_args.args = punctuated |
| 39 | + .into_iter() |
| 40 | + .filter_map(|mut arg| match arg { |
| 41 | + GenericArgument::Lifetime(_) => None, |
| 42 | + _ => { |
| 43 | + self.visit_generic_argument_mut(&mut arg); |
| 44 | + Some(arg) |
55 | 45 | }
|
| 46 | + }) |
| 47 | + .collect(); |
56 | 48 |
|
57 |
| - still_has_parameter = !p.is_empty(); |
58 |
| - angled_args.args = p; |
59 |
| - } |
60 |
| - PathArguments::Parenthesized(_) => {} |
61 |
| - } |
62 |
| - |
63 |
| - if !still_has_parameter { |
64 |
| - p.arguments = PathArguments::None; |
| 49 | + if angled_args.args.empty_or_trailing() { |
| 50 | + path_segment.arguments = PathArguments::None; |
65 | 51 | }
|
66 | 52 | }
|
| 53 | + PathArguments::Parenthesized(_) => path_segment.arguments = PathArguments::None, |
67 | 54 | }
|
68 |
| - Type::Reference(x) => { |
69 |
| - x.lifetime = None; |
70 |
| - x.elem = Box::new(purge_lifetimes_from_type(&x.elem)) |
71 |
| - } |
72 |
| - Type::Ptr(x) => x.elem = Box::new(purge_lifetimes_from_type(&x.elem)), |
73 |
| - Type::Group(x) => x.elem = Box::new(purge_lifetimes_from_type(&x.elem)), |
74 |
| - _ => {} |
75 | 55 | }
|
76 | 56 |
|
| 57 | + fn visit_type_reference_mut(&mut self, type_reference: &mut syn::TypeReference) { |
| 58 | + type_reference.lifetime = None; |
| 59 | + self.visit_type_mut(&mut type_reference.elem); |
| 60 | + } |
| 61 | +} |
| 62 | + |
| 63 | +/// Ugly, incomplete function to purge `'a` from a `Generic<'a, T>`. |
| 64 | +pub fn purge_lifetimes_from_type(the_type: &Type) -> Type { |
| 65 | + let mut rval = the_type.clone(); |
| 66 | + |
| 67 | + LifetimeRemover.visit_type_mut(&mut rval); |
| 68 | + |
77 | 69 | rval
|
78 | 70 | }
|
79 | 71 |
|
|
0 commit comments