1 use internals::respan::respan;
2 use proc_macro2::Span;
3 use quote::ToTokens;
4 use std::mem;
5 use syn::punctuated::Punctuated;
6 use syn::{
7 parse_quote, Data, DeriveInput, Expr, ExprPath, GenericArgument, GenericParam, Generics, Macro,
8 Path, PathArguments, QSelf, ReturnType, Type, TypeParamBound, TypePath, WherePredicate,
9 };
10
replace_receiver(input: &mut DeriveInput)11 pub 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
22 struct ReplaceReceiver<'a>(&'a TypePath);
23
24 impl ReplaceReceiver<'_> {
self_ty(&self, span: Span) -> TypePath25 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
self_to_qself(&self, qself: &mut Option<QSelf>, path: &mut Path)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
self_to_expr_path(&self, path: &mut Path)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
73 impl ReplaceReceiver<'_> {
74 // `Self` -> `Receiver`
visit_type_mut(&mut self, ty: &mut Type)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 = self.self_ty(span).into();
88 }
89
90 // `Self::Assoc` -> `<Receiver>::Assoc`
visit_type_path_mut(&mut self, ty: &mut TypePath)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`
visit_expr_path_mut(&mut self, expr: &mut ExprPath)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
visit_type_mut_impl(&mut self, ty: &mut Type)108 fn visit_type_mut_impl(&mut self, ty: &mut Type) {
109 match ty {
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 #[cfg(test)]
151 Type::__TestExhaustive(_) => unimplemented!(),
152 #[cfg(not(test))]
153 _ => {}
154 }
155 }
156
visit_type_path_mut_impl(&mut self, ty: &mut TypePath)157 fn visit_type_path_mut_impl(&mut self, ty: &mut TypePath) {
158 if let Some(qself) = &mut ty.qself {
159 self.visit_type_mut(&mut qself.ty);
160 }
161 self.visit_path_mut(&mut ty.path);
162 }
163
visit_expr_path_mut_impl(&mut self, expr: &mut ExprPath)164 fn visit_expr_path_mut_impl(&mut self, expr: &mut ExprPath) {
165 if let Some(qself) = &mut expr.qself {
166 self.visit_type_mut(&mut qself.ty);
167 }
168 self.visit_path_mut(&mut expr.path);
169 }
170
visit_path_mut(&mut self, path: &mut Path)171 fn visit_path_mut(&mut self, path: &mut Path) {
172 for segment in &mut path.segments {
173 self.visit_path_arguments_mut(&mut segment.arguments);
174 }
175 }
176
visit_path_arguments_mut(&mut self, arguments: &mut PathArguments)177 fn visit_path_arguments_mut(&mut self, arguments: &mut PathArguments) {
178 match arguments {
179 PathArguments::None => {}
180 PathArguments::AngleBracketed(arguments) => {
181 for arg in &mut arguments.args {
182 match arg {
183 GenericArgument::Type(arg) => self.visit_type_mut(arg),
184 GenericArgument::Binding(arg) => self.visit_type_mut(&mut arg.ty),
185 GenericArgument::Lifetime(_)
186 | GenericArgument::Constraint(_)
187 | GenericArgument::Const(_) => {}
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
visit_return_type_mut(&mut self, return_type: &mut ReturnType)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
visit_type_param_bound_mut(&mut self, bound: &mut TypeParamBound)207 fn visit_type_param_bound_mut(&mut self, bound: &mut TypeParamBound) {
208 match bound {
209 TypeParamBound::Trait(bound) => self.visit_path_mut(&mut bound.path),
210 TypeParamBound::Lifetime(_) => {}
211 }
212 }
213
visit_generics_mut(&mut self, generics: &mut Generics)214 fn visit_generics_mut(&mut self, generics: &mut Generics) {
215 for param in &mut generics.params {
216 match param {
217 GenericParam::Type(param) => {
218 for bound in &mut param.bounds {
219 self.visit_type_param_bound_mut(bound);
220 }
221 }
222 GenericParam::Lifetime(_) | GenericParam::Const(_) => {}
223 }
224 }
225 if let Some(where_clause) = &mut generics.where_clause {
226 for predicate in &mut where_clause.predicates {
227 match predicate {
228 WherePredicate::Type(predicate) => {
229 self.visit_type_mut(&mut predicate.bounded_ty);
230 for bound in &mut predicate.bounds {
231 self.visit_type_param_bound_mut(bound);
232 }
233 }
234 WherePredicate::Lifetime(_) | WherePredicate::Eq(_) => {}
235 }
236 }
237 }
238 }
239
visit_data_mut(&mut self, data: &mut Data)240 fn visit_data_mut(&mut self, data: &mut Data) {
241 match data {
242 Data::Struct(data) => {
243 for field in &mut data.fields {
244 self.visit_type_mut(&mut field.ty);
245 }
246 }
247 Data::Enum(data) => {
248 for variant in &mut data.variants {
249 for field in &mut variant.fields {
250 self.visit_type_mut(&mut field.ty);
251 }
252 }
253 }
254 Data::Union(_) => {}
255 }
256 }
257
visit_expr_mut(&mut self, expr: &mut Expr)258 fn visit_expr_mut(&mut self, expr: &mut Expr) {
259 match expr {
260 Expr::Binary(expr) => {
261 self.visit_expr_mut(&mut expr.left);
262 self.visit_expr_mut(&mut expr.right);
263 }
264 Expr::Call(expr) => {
265 self.visit_expr_mut(&mut expr.func);
266 for arg in &mut expr.args {
267 self.visit_expr_mut(arg);
268 }
269 }
270 Expr::Cast(expr) => {
271 self.visit_expr_mut(&mut expr.expr);
272 self.visit_type_mut(&mut expr.ty);
273 }
274 Expr::Field(expr) => self.visit_expr_mut(&mut expr.base),
275 Expr::Index(expr) => {
276 self.visit_expr_mut(&mut expr.expr);
277 self.visit_expr_mut(&mut expr.index);
278 }
279 Expr::Paren(expr) => self.visit_expr_mut(&mut expr.expr),
280 Expr::Path(expr) => self.visit_expr_path_mut(expr),
281 Expr::Unary(expr) => self.visit_expr_mut(&mut expr.expr),
282 _ => {}
283 }
284 }
285
visit_macro_mut(&mut self, _mac: &mut Macro)286 fn visit_macro_mut(&mut self, _mac: &mut Macro) {}
287 }
288