cxx_build/syntax/
signature.rs

1use crate::syntax::set::{OrderedSet, UnorderedSet};
2use crate::syntax::{FnKind, Receiver, Signature, Type};
3use proc_macro2::Ident;
4use syn::Lifetime;
5
6impl Signature {
7    pub fn receiver(&self) -> Option<&Receiver> {
8        match &self.kind {
9            FnKind::Method(receiver) => Some(receiver),
10            FnKind::Assoc(_) | FnKind::Free => None,
11        }
12    }
13
14    pub fn receiver_mut(&mut self) -> Option<&mut Receiver> {
15        match &mut self.kind {
16            FnKind::Method(receiver) => Some(receiver),
17            FnKind::Assoc(_) | FnKind::Free => None,
18        }
19    }
20
21    pub fn self_type(&self) -> Option<&Ident> {
22        match &self.kind {
23            FnKind::Method(receiver) => Some(&receiver.ty.rust),
24            FnKind::Assoc(self_type) => Some(self_type),
25            FnKind::Free => None,
26        }
27    }
28
29    #[cfg_attr(not(proc_macro), allow(dead_code))]
30    pub fn undeclared_lifetimes<'a>(&'a self) -> OrderedSet<&'a Lifetime> {
31        let mut declared_lifetimes = UnorderedSet::new();
32        for param in self.generics.lifetimes() {
33            declared_lifetimes.insert(&param.lifetime);
34        }
35
36        let mut undeclared_lifetimes = OrderedSet::new();
37        let mut collect_lifetime = |lifetime: &'a Lifetime| {
38            if lifetime.ident != "_"
39                && lifetime.ident != "static"
40                && !declared_lifetimes.contains(lifetime)
41            {
42                undeclared_lifetimes.insert(lifetime);
43            }
44        };
45
46        match &self.kind {
47            FnKind::Method(receiver) => {
48                if let Some(lifetime) = &receiver.lifetime {
49                    collect_lifetime(lifetime);
50                }
51                for lifetime in &receiver.ty.generics.lifetimes {
52                    collect_lifetime(lifetime);
53                }
54            }
55            FnKind::Assoc(self_type) => {
56                // If support is added for explicit lifetimes in the Self type
57                // of static member functions, that needs to be handled here.
58                let _: &Ident = self_type;
59            }
60            FnKind::Free => {}
61        }
62
63        fn collect_type<'a>(collect_lifetime: &mut impl FnMut(&'a Lifetime), ty: &'a Type) {
64            match ty {
65                Type::Ident(named_type) => {
66                    for lifetime in &named_type.generics.lifetimes {
67                        collect_lifetime(lifetime);
68                    }
69                }
70                Type::RustBox(ty1)
71                | Type::RustVec(ty1)
72                | Type::UniquePtr(ty1)
73                | Type::SharedPtr(ty1)
74                | Type::WeakPtr(ty1)
75                | Type::CxxVector(ty1) => collect_type(collect_lifetime, &ty1.inner),
76                Type::Ref(ty) | Type::Str(ty) => {
77                    if let Some(lifetime) = &ty.lifetime {
78                        collect_lifetime(lifetime);
79                    }
80                    collect_type(collect_lifetime, &ty.inner);
81                }
82                Type::Ptr(ty) => collect_type(collect_lifetime, &ty.inner),
83                Type::Fn(signature) => {
84                    for lifetime in signature.undeclared_lifetimes() {
85                        collect_lifetime(lifetime);
86                    }
87                }
88                Type::Void(_) => {}
89                Type::SliceRef(ty) => {
90                    if let Some(lifetime) = &ty.lifetime {
91                        collect_lifetime(lifetime);
92                    }
93                    collect_type(collect_lifetime, &ty.inner);
94                }
95                Type::Array(ty) => collect_type(collect_lifetime, &ty.inner),
96            }
97        }
98
99        for arg in &self.args {
100            collect_type(&mut collect_lifetime, &arg.ty);
101        }
102
103        if let Some(ret) = &self.ret {
104            collect_type(&mut collect_lifetime, ret);
105        }
106
107        undeclared_lifetimes
108    }
109}