1#[derive(Clone, Copy, Debug, PartialEq, Eq)]
11pub enum PrimitiveCall {
12 AsPtr,
13 AsMutPtr,
14 AsPtrRange,
15 AsMutPtrRange,
16 PtrCast,
17 PtrAdd,
18 PtrSub,
19 PtrOffset,
20 PtrByteAdd,
21 PtrByteSub,
22 PtrByteOffset,
23 PtrRead,
24 PtrWrite,
25 Len,
26 MaybeUninitUninit,
27 AlignOf,
28 SizeOf,
29 FromRawParts,
30 FromRawPartsMut,
31 SplitAt,
32 SplitAtMut,
33}
34
35impl PrimitiveCall {
36 pub fn classify(name: &str) -> Option<Self> {
38 if name.ends_with("::as_ptr")
39 || (name.contains("::as_ptr") && !name.ends_with("::as_ptr_range"))
40 {
41 return Some(Self::AsPtr);
42 }
43 if name.ends_with("::as_mut_ptr")
44 || (name.contains("::as_mut_ptr") && !name.ends_with("::as_mut_ptr_range"))
45 {
46 return Some(Self::AsMutPtr);
47 }
48 if name.ends_with("::as_ptr_range") || name.contains("::as_ptr_range") {
49 return Some(Self::AsPtrRange);
50 }
51 if name.ends_with("::as_mut_ptr_range") || name.contains("::as_mut_ptr_range") {
52 return Some(Self::AsMutPtrRange);
53 }
54 if name.contains("::cast") || name.contains("cast_array") || name.contains("cast_const") || name.contains("cast_mut") {
55 return Some(Self::PtrCast);
56 }
57 if name.contains("::byte_add") || name.contains("::wrapping_byte_add") {
58 return Some(Self::PtrByteAdd);
59 }
60 if name.contains("::byte_sub") || name.contains("::wrapping_byte_sub") {
61 return Some(Self::PtrByteSub);
62 }
63 if name.contains("::byte_offset") || name.contains("::wrapping_byte_offset") {
64 return Some(Self::PtrByteOffset);
65 }
66 if name.contains("::add") || name.contains("::wrapping_add") {
67 return Some(Self::PtrAdd);
68 }
69 if name.contains("::sub") || name.contains("::wrapping_sub") {
70 return Some(Self::PtrSub);
71 }
72 if name.contains("::offset") || name.contains("::wrapping_offset") {
73 return Some(Self::PtrOffset);
74 }
75 if name.contains("::read") || name.ends_with("read") {
76 return Some(Self::PtrRead);
77 }
78 if (name.contains("::write") || name.ends_with("write"))
79 && !name.contains("write_bytes")
80 && !name.contains("write_unaligned")
81 && !name.contains("write_volatile")
82 {
83 return Some(Self::PtrWrite);
84 }
85 if name.ends_with("::len") || name.contains("::len") {
86 return Some(Self::Len);
87 }
88 if name.contains("MaybeUninit") && name.ends_with("::uninit") {
89 return Some(Self::MaybeUninitUninit);
90 }
91 if name.contains("align_of") {
92 return Some(Self::AlignOf);
93 }
94 if name.contains("size_of") {
95 return Some(Self::SizeOf);
96 }
97 if name.ends_with("::from_raw_parts_mut") || name.contains("::from_raw_parts_mut") {
98 return Some(Self::FromRawPartsMut);
99 }
100 if name.contains("::split_at") || name.ends_with("::split_at_mut") {
101 if name.contains("_mut") {
102 return Some(Self::SplitAtMut);
103 }
104 return Some(Self::SplitAt);
105 }
106 if name.ends_with("::from_raw_parts") || name.contains("::from_raw_parts") {
107 return Some(Self::FromRawParts);
108 }
109 None
110 }
111
112 pub fn is_as_ptr_like(self) -> bool {
114 matches!(self, Self::AsPtr | Self::AsMutPtr | Self::PtrCast)
115 }
116
117 pub fn is_pointer_add_like(self) -> bool {
119 matches!(
120 self,
121 Self::PtrAdd | Self::PtrOffset | Self::PtrByteAdd | Self::PtrByteOffset
122 )
123 }
124
125 pub fn is_pointer_sub_like(self) -> bool {
127 matches!(self, Self::PtrSub | Self::PtrByteSub)
128 }
129
130 pub fn is_pointer_arithmetic(self) -> bool {
132 matches!(
133 self,
134 Self::PtrAdd
135 | Self::PtrSub
136 | Self::PtrOffset
137 | Self::PtrByteAdd
138 | Self::PtrByteSub
139 | Self::PtrByteOffset
140 )
141 }
142
143 pub fn is_byte_pointer_arithmetic(self) -> bool {
145 matches!(
146 self,
147 Self::PtrByteAdd | Self::PtrByteSub | Self::PtrByteOffset
148 )
149 }
150
151 pub fn is_signed_pointer_arithmetic(self) -> bool {
153 matches!(self, Self::PtrOffset | Self::PtrByteOffset)
154 }
155
156 pub fn is_layout_constant(self) -> bool {
158 matches!(self, Self::AlignOf | Self::SizeOf)
159 }
160}