1pub trait BoxRaw {
56 fn clean(self);
64}
65
66impl<X> BoxRaw for *mut X {
67 fn clean(self) {
68 unsafe {
69 let _ = Box::from_raw(self);
70 }
71 }
72}
73
74macro_rules! impl_mut_raws_for_tuple {
75 ($($T:tt),*) => {
76 paste::paste! {
77 impl<$($T,)*> BoxRaw for ($($T,)*)
78 where
79 $($T: BoxRaw,)*
80 {
81 fn clean(self) {
82 let ($([<$T:lower>],)*) = self;
83 $(
84 [<$T:lower>].clean();
85 )*
86 }
87 }
88 }
89 }
90}
91
92impl_mut_raws_for_tuple!(A);
93impl_mut_raws_for_tuple!(A, B);
94impl_mut_raws_for_tuple!(A, B, C);
95impl_mut_raws_for_tuple!(A, B, C, D);
96impl_mut_raws_for_tuple!(A, B, C, D, E);
97impl_mut_raws_for_tuple!(A, B, C, D, E, F);
98impl_mut_raws_for_tuple!(A, B, C, D, E, F, G);
99impl_mut_raws_for_tuple!(A, B, C, D, E, F, G, H);
100impl_mut_raws_for_tuple!(A, B, C, D, E, F, G, H, I);
101impl_mut_raws_for_tuple!(A, B, C, D, E, F, G, H, I, J);
102impl_mut_raws_for_tuple!(A, B, C, D, E, F, G, H, I, J, K);
103impl_mut_raws_for_tuple!(A, B, C, D, E, F, G, H, I, J, K, L);
104
105
106pub struct BoxRaws<X: BoxRaw>(pub X);
107
108impl<X: BoxRaw> BoxRaw for BoxRaws<X> {
109 fn clean(self) {
110 self.0.clean();
111 }
112}
113
114impl<X: BoxRaw> BoxRaws<X> {
115 pub fn new(raws: X) -> Self { Self(raws) }
116}
117
118
119#[cfg(test)]
120mod tests {
121 use super::*;
122
123 #[test]
125 fn pass_miri() {
126
127 let x = Box::into_raw(Box::new(2u8));
128 x.clean();
129
130 let x = (
131 Box::into_raw(Box::new(2u8)),
132 Box::into_raw(Box::new(2u32))
133 );
134 x.clean();
135
136 let i = Box::into_raw(Box::new(0));
137
138 let x = (
139 i,
140 Box::into_raw(Box::new(2u32)),
141 Box::into_raw(Box::new(String::from("raw")))
142 );
143 x.clean();
144 }
145
146 #[test]
147 #[cfg_attr(miri, ignore)]
148 fn not_pass_miri() {
149
150 let i = Box::into_raw(Box::new(0));
151
152 let x = (
153 i,
154 Box::into_raw(Box::new(14u32))
155 );
156
157 x.clean();
158
159 unsafe {
160 let y = *i + 10;
162 assert_eq!(y, 10);
163 }
164 }
165
166 #[test]
167 fn box_raws() {
168 let x: Box<Vec<String>> = Box::new(vec![String::from("Rome")]);
169 let x = Box::into_raw(x);
170 let y = Box::into_raw(Box::new(10i32));
171
172 (x, y).clean();
173
174 let x: Box<Vec<String>> = Box::new(vec![String::from("Rome")]);
176 let x = Box::into_raw(x);
177 let y = Box::into_raw(Box::new(10i32));
178
179 let raws = BoxRaws::new((x, y));
180 raws.clean();
181 }
182}