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,
43 ty: Box::new(Type::Path(self.self_ty(span))),
44 position: 0,
45 as_token: None,
46 gt_token: Token,
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 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 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 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 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}