serde_derive/internals/
receiver.rs

1use crate::internals::respan::respan;
2use proc_macro2::Span;
3use quote::ToTokens;
4use std::mem;
5use syn::{
6    parse_quote, Data, DeriveInput, Expr, ExprPath, GenericArgument, GenericParam, Generics, Macro,
7    Path, PathArguments, QSelf, ReturnType, Token, Type, TypeParamBound, TypePath, WherePredicate,
8};
9
10pub fn replace_receiver(input: &mut DeriveInput) {
11    let self_ty = {
12        let ident = &input.ident;
13        let ty_generics = input.generics.split_for_impl().1;
14        parse_quote!(#ident #ty_generics)
15    };
16    let mut visitor = ReplaceReceiver(&self_ty);
17    visitor.visit_generics_mut(&mut input.generics);
18    visitor.visit_data_mut(&mut input.data);
19}
20
21struct ReplaceReceiver<'a>(&'a TypePath);
22
23impl ReplaceReceiver<'_> {
24    fn self_ty(&self, span: Span) -> TypePath {
25        let tokens = self.0.to_token_stream();
26        let respanned = respan(tokens, span);
27        syn::parse2(respanned).unwrap()
28    }
29
30    fn self_to_qself(&self, qself: &mut Option<QSelf>, path: &mut Path) {
31        if path.leading_colon.is_some() || path.segments[0].ident != "Self" {
32            return;
33        }
34
35        if path.segments.len() == 1 {
36            self.self_to_expr_path(path);
37            return;
38        }
39
40        let span = path.segments[0].ident.span();
41        *qself = Some(QSelf {
42            lt_token: Token![<](span),
43            ty: Box::new(Type::Path(self.self_ty(span))),
44            position: 0,
45            as_token: None,
46            gt_token: Token![>](span),
47        });
48
49        path.leading_colon = Some(**path.segments.pairs().next().unwrap().punct().unwrap());
50
51        let segments = mem::take(&mut path.segments);
52        path.segments = segments.into_pairs().skip(1).collect();
53    }
54
55    fn self_to_expr_path(&self, path: &mut Path) {
56        let self_ty = self.self_ty(path.segments[0].ident.span());
57        let variant = mem::replace(path, self_ty.path);
58        for segment in &mut path.segments {
59            if let PathArguments::AngleBracketed(bracketed) = &mut segment.arguments {
60                if bracketed.colon2_token.is_none() && !bracketed.args.is_empty() {
61                    bracketed.colon2_token = Some(<Token![::]>::default());
62                }
63            }
64        }
65        if variant.segments.len() > 1 {
66            path.segments.push_punct(<Token![::]>::default());
67            path.segments.extend(variant.segments.into_pairs().skip(1));
68        }
69    }
70}
71
72impl ReplaceReceiver<'_> {
73    // `Self` -> `Receiver`
74    fn visit_type_mut(&mut self, ty: &mut Type) {
75        let span = if let Type::Path(node) = ty {
76            if node.qself.is_none() && node.path.is_ident("Self") {
77                node.path.segments[0].ident.span()
78            } else {
79                self.visit_type_path_mut(node);
80                return;
81            }
82        } else {
83            self.visit_type_mut_impl(ty);
84            return;
85        };
86        *ty = Type::Path(self.self_ty(span));
87    }
88
89    // `Self::Assoc` -> `<Receiver>::Assoc`
90    fn visit_type_path_mut(&mut self, ty: &mut TypePath) {
91        if ty.qself.is_none() {
92            self.self_to_qself(&mut ty.qself, &mut ty.path);
93        }
94        self.visit_type_path_mut_impl(ty);
95    }
96
97    // `Self::method` -> `<Receiver>::method`
98    fn visit_expr_path_mut(&mut self, expr: &mut ExprPath) {
99        if expr.qself.is_none() {
100            self.self_to_qself(&mut expr.qself, &mut expr.path);
101        }
102        self.visit_expr_path_mut_impl(expr);
103    }
104
105    // Everything below is simply traversing the syntax tree.
106
107    fn visit_type_mut_impl(&mut self, ty: &mut Type) {
108        match ty {
109            #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
110            Type::Array(ty) => {
111                self.visit_type_mut(&mut ty.elem);
112                self.visit_expr_mut(&mut ty.len);
113            }
114            Type::BareFn(ty) => {
115                for arg in &mut ty.inputs {
116                    self.visit_type_mut(&mut arg.ty);
117                }
118                self.visit_return_type_mut(&mut ty.output);
119            }
120            Type::Group(ty) => self.visit_type_mut(&mut ty.elem),
121            Type::ImplTrait(ty) => {
122                for bound in &mut ty.bounds {
123                    self.visit_type_param_bound_mut(bound);
124                }
125            }
126            Type::Macro(ty) => self.visit_macro_mut(&mut ty.mac),
127            Type::Paren(ty) => self.visit_type_mut(&mut ty.elem),
128            Type::Path(ty) => {
129                if let Some(qself) = &mut ty.qself {
130                    self.visit_type_mut(&mut qself.ty);
131                }
132                self.visit_path_mut(&mut ty.path);
133            }
134            Type::Ptr(ty) => self.visit_type_mut(&mut ty.elem),
135            Type::Reference(ty) => self.visit_type_mut(&mut ty.elem),
136            Type::Slice(ty) => self.visit_type_mut(&mut ty.elem),
137            Type::TraitObject(ty) => {
138                for bound in &mut ty.bounds {
139                    self.visit_type_param_bound_mut(bound);
140                }
141            }
142            Type::Tuple(ty) => {
143                for elem in &mut ty.elems {
144                    self.visit_type_mut(elem);
145                }
146            }
147
148            Type::Infer(_) | Type::Never(_) | Type::Verbatim(_) => {}
149
150            _ => {}
151        }
152    }
153
154    fn visit_type_path_mut_impl(&mut self, ty: &mut TypePath) {
155        if let Some(qself) = &mut ty.qself {
156            self.visit_type_mut(&mut qself.ty);
157        }
158        self.visit_path_mut(&mut ty.path);
159    }
160
161    fn visit_expr_path_mut_impl(&mut self, expr: &mut ExprPath) {
162        if let Some(qself) = &mut expr.qself {
163            self.visit_type_mut(&mut qself.ty);
164        }
165        self.visit_path_mut(&mut expr.path);
166    }
167
168    fn visit_path_mut(&mut self, path: &mut Path) {
169        for segment in &mut path.segments {
170            self.visit_path_arguments_mut(&mut segment.arguments);
171        }
172    }
173
174    fn visit_path_arguments_mut(&mut self, arguments: &mut PathArguments) {
175        match arguments {
176            PathArguments::None => {}
177            PathArguments::AngleBracketed(arguments) => {
178                for arg in &mut arguments.args {
179                    match arg {
180                        #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
181                        GenericArgument::Type(arg) => self.visit_type_mut(arg),
182                        GenericArgument::AssocType(arg) => self.visit_type_mut(&mut arg.ty),
183                        GenericArgument::Lifetime(_)
184                        | GenericArgument::Const(_)
185                        | GenericArgument::AssocConst(_)
186                        | GenericArgument::Constraint(_) => {}
187                        _ => {}
188                    }
189                }
190            }
191            PathArguments::Parenthesized(arguments) => {
192                for argument in &mut arguments.inputs {
193                    self.visit_type_mut(argument);
194                }
195                self.visit_return_type_mut(&mut arguments.output);
196            }
197        }
198    }
199
200    fn visit_return_type_mut(&mut self, return_type: &mut ReturnType) {
201        match return_type {
202            ReturnType::Default => {}
203            ReturnType::Type(_, output) => self.visit_type_mut(output),
204        }
205    }
206
207    fn visit_type_param_bound_mut(&mut self, bound: &mut TypeParamBound) {
208        match bound {
209            #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
210            TypeParamBound::Trait(bound) => self.visit_path_mut(&mut bound.path),
211            TypeParamBound::Lifetime(_)
212            | TypeParamBound::PreciseCapture(_)
213            | TypeParamBound::Verbatim(_) => {}
214            _ => {}
215        }
216    }
217
218    fn visit_generics_mut(&mut self, generics: &mut Generics) {
219        for param in &mut generics.params {
220            match param {
221                GenericParam::Type(param) => {
222                    for bound in &mut param.bounds {
223                        self.visit_type_param_bound_mut(bound);
224                    }
225                }
226                GenericParam::Lifetime(_) | GenericParam::Const(_) => {}
227            }
228        }
229        if let Some(where_clause) = &mut generics.where_clause {
230            for predicate in &mut where_clause.predicates {
231                match predicate {
232                    #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
233                    WherePredicate::Type(predicate) => {
234                        self.visit_type_mut(&mut predicate.bounded_ty);
235                        for bound in &mut predicate.bounds {
236                            self.visit_type_param_bound_mut(bound);
237                        }
238                    }
239                    WherePredicate::Lifetime(_) => {}
240                    _ => {}
241                }
242            }
243        }
244    }
245
246    fn visit_data_mut(&mut self, data: &mut Data) {
247        match data {
248            Data::Struct(data) => {
249                for field in &mut data.fields {
250                    self.visit_type_mut(&mut field.ty);
251                }
252            }
253            Data::Enum(data) => {
254                for variant in &mut data.variants {
255                    for field in &mut variant.fields {
256                        self.visit_type_mut(&mut field.ty);
257                    }
258                }
259            }
260            Data::Union(_) => {}
261        }
262    }
263
264    fn visit_expr_mut(&mut self, expr: &mut Expr) {
265        match expr {
266            Expr::Binary(expr) => {
267                self.visit_expr_mut(&mut expr.left);
268                self.visit_expr_mut(&mut expr.right);
269            }
270            Expr::Call(expr) => {
271                self.visit_expr_mut(&mut expr.func);
272                for arg in &mut expr.args {
273                    self.visit_expr_mut(arg);
274                }
275            }
276            Expr::Cast(expr) => {
277                self.visit_expr_mut(&mut expr.expr);
278                self.visit_type_mut(&mut expr.ty);
279            }
280            Expr::Field(expr) => self.visit_expr_mut(&mut expr.base),
281            Expr::Index(expr) => {
282                self.visit_expr_mut(&mut expr.expr);
283                self.visit_expr_mut(&mut expr.index);
284            }
285            Expr::Paren(expr) => self.visit_expr_mut(&mut expr.expr),
286            Expr::Path(expr) => self.visit_expr_path_mut(expr),
287            Expr::Unary(expr) => self.visit_expr_mut(&mut expr.expr),
288            _ => {}
289        }
290    }
291
292    fn visit_macro_mut(&mut self, _mac: &mut Macro) {}
293}