bon_macros/normalization/
self_ty.rs
1use crate::util::prelude::*;
2use syn::spanned::Spanned;
3use syn::visit_mut::VisitMut;
4
5pub(crate) struct NormalizeSelfTy<'a> {
6 pub(crate) self_ty: &'a syn::Type,
7}
8
9impl VisitMut for NormalizeSelfTy<'_> {
10 fn visit_item_mut(&mut self, _item: &mut syn::Item) {
11 }
13
14 fn visit_receiver_mut(&mut self, _receiver: &mut syn::Receiver) {
15 }
21
22 fn visit_impl_item_fn_mut(&mut self, fn_item: &mut syn::ImplItemFn) {
23 self.visit_signature_mut(&mut fn_item.sig);
26 }
27
28 fn visit_type_mut(&mut self, ty: &mut syn::Type) {
32 syn::visit_mut::visit_type_mut(self, ty);
33
34 let ty_path = match ty {
35 syn::Type::Path(ty_path) => ty_path,
36 _ => return,
37 };
38
39 if !ty_path.path.is_ident("Self") {
40 return;
41 }
42
43 *ty = (*self.self_ty).clone();
44 }
45
46 fn visit_type_path_mut(&mut self, type_path: &mut syn::TypePath) {
47 syn::visit_mut::visit_type_path_mut(self, type_path);
48
49 let syn::TypePath { qself, path } = type_path;
50
51 let is_self_projection =
52 qself.is_none() && path.starts_with_segment("Self") && path.segments.len() > 1;
53
54 if !is_self_projection {
55 return;
56 }
57
58 path.segments = std::mem::take(&mut path.segments)
61 .into_iter()
62 .skip(1)
63 .collect();
64
65 let span = type_path.span();
66
67 type_path.qself = Some(syn::QSelf {
69 lt_token: syn::Token,
70 ty: Box::new(self.self_ty.clone()),
71 position: 0,
72 as_token: None,
73 gt_token: syn::Token,
74 });
75 }
76}