serde_derive/internals/
receiver.rs

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