stackbox/dyn_traits/custom_dyn.rs
1#[cfg(doc)]
2use crate::StackBox;
3
4/**
5Helper macro to define custom `StackBox<dyn …>` trait objects.
6
7Mainly useful for [`FnOnce`], **when higher-order lifetimes** are needed.
8
9<details><summary><b>What are higher-order lifetimes?</b></summary>
10
11Consider the following example: you are able to create some local value within
12a function, and want to call some provided callback on a _borrow_ of it.
13
14```rust
15# use ::core::cell::RefCell;
16#
17fn with_nested_refcell (
18 nested: &'_ RefCell<RefCell<str>>,
19 f: fn(&'_ str),
20)
21{
22 f(&*nested.borrow().borrow())
23}
24```
25
26The main question then is:
27
28> what is the lifetime of that borrow?
29
30 1. If we try to unsugar each elided lifetime (`'_`) with a lifetime parameter
31 on the function, the code no longer compiles:
32
33 ```rust,compile_fail
34 # use ::core::cell::RefCell;
35 #
36 fn with_nested_refcell<'nested, 'arg> (
37 nested: &'nested RefCell<RefCell<str>>,
38 f: fn(&'arg str),
39 )
40 {
41 f(&*nested.borrow().borrow())
42 }
43 ```
44
45 <details><summary>Error message</summary>
46
47 ```text
48 error[E0716]: temporary value dropped while borrowed
49 --> src/lib.rs:8:9
50 |
51 3 | fn with_nested_refcell<'nested, 'arg> (
52 | ---- lifetime `'arg` defined here
53 ...
54 8 | f(&*nested.borrow().borrow())
55 | ^^^^^^^^^^^^^^^---------
56 | |
57 | creates a temporary which is freed while still in use
58 | argument requires that borrow lasts for `'arg`
59 9 | }
60 | - temporary value is freed at the end of this statement
61
62 error[E0716]: temporary value dropped while borrowed
63 --> src/lib.rs:8:9
64 |
65 3 | fn with_nested_refcell<'nested, 'arg> (
66 | ---- lifetime `'arg` defined here
67 ...
68 8 | f(&*nested.borrow().borrow())
69 | ----^^^^^^^^^^^^^^^^^^^^^^^^-
70 | | |
71 | | creates a temporary which is freed while still in use
72 | argument requires that borrow lasts for `'arg`
73 9 | }
74 | - temporary value is freed at the end of this statement
75 ```
76
77 ___
78
79 </details>
80
81 1. So Rust considers that **generic lifetime parameters represent
82 lifetimes that span beyond the end of a function's body** (_c.f._ the
83 previous error message).
84
85 Or in other words, since generic parameters, including generic lifetime
86 parameters, are _chosen by the caller_, and since the body of a callee
87 is opaque to the caller, it is impossible for the caller to provide /
88 choose a lifetime that is able to match an internal scope.
89
90 1. Because of that, in order for a callback to be able to use a borrow with
91 some existential but unnameable lifetime, only one solution remains:
92
93 > **That the caller provide a callback able to handle _all_ the lifetimes /
94 _any lifetime possible_**.
95
96 - Imaginary syntax:
97
98 ```rust
99 # macro_rules! ignore {($($t:tt)*) => ()} ignore! {
100 fn with_nested_refcell<'nested> (
101 nested: &'nested RefCell<RefCell<str>>,
102 f: fn<'arg>(&'arg str),
103 )
104 {
105 f(&*nested.borrow().borrow())
106 }
107 # } fn main () {}
108 ```
109
110 the difference then being:
111
112 <!--
113
114 ```diff
115 - fn with_nested_refcell<'nested, 'arg> (
116 + fn with_nested_refcell<'nested> (
117 nested: &'nested RefCell<RefCell<str>>,
118 - f: fn(&'arg str),
119 + f: fn<'arg>(&'arg str),
120 )
121 ```
122
123 -->
124
125 <html>
126 <head>
127 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
128 <style type="text/css">
129 pre { white-space: pre-wrap; }
130 .ef0,.f0 { color: #000000; } .eb0,.b0 { background-color: #000000; }
131 .ef1,.f1 { color: #AA0000; } .eb1,.b1 { background-color: #AA0000; }
132 .ef2,.f2 { color: #00AA00; } .eb2,.b2 { background-color: #00AA00; }
133 .ef3,.f3 { color: #AA5500; } .eb3,.b3 { background-color: #AA5500; }
134 .ef4,.f4 { color: #0000AA; } .eb4,.b4 { background-color: #0000AA; }
135 .ef5,.f5 { color: #AA00AA; } .eb5,.b5 { background-color: #AA00AA; }
136 .ef6,.f6 { color: #00AAAA; } .eb6,.b6 { background-color: #00AAAA; }
137 .ef7,.f7 { color: #AAAAAA; } .eb7,.b7 { background-color: #AAAAAA; }
138 .ef8, .f0 > .bold,.bold > .f0 { color: #555555; font-weight: normal; }
139 .ef9, .f1 > .bold,.bold > .f1 { color: #FF5555; font-weight: normal; }
140 .ef10,.f2 > .bold,.bold > .f2 { color: #55FF55; font-weight: normal; }
141 .ef11,.f3 > .bold,.bold > .f3 { color: #FFFF55; font-weight: normal; }
142 .ef12,.f4 > .bold,.bold > .f4 { color: #5555FF; font-weight: normal; }
143 .ef13,.f5 > .bold,.bold > .f5 { color: #FF55FF; font-weight: normal; }
144 .ef14,.f6 > .bold,.bold > .f6 { color: #55FFFF; font-weight: normal; }
145 .ef15,.f7 > .bold,.bold > .f7 { color: #FFFFFF; font-weight: normal; }
146 .eb8 { background-color: #555555; }
147 .eb9 { background-color: #FF5555; }
148 .eb10 { background-color: #55FF55; }
149 .eb11 { background-color: #FFFF55; }
150 .eb12 { background-color: #5555FF; }
151 .eb13 { background-color: #FF55FF; }
152 .eb14 { background-color: #55FFFF; }
153 .eb15 { background-color: #FFFFFF; }
154 .ef16 { color: #000000; } .eb16 { background-color: #000000; }
155 .ef17 { color: #00005f; } .eb17 { background-color: #00005f; }
156 .ef18 { color: #000087; } .eb18 { background-color: #000087; }
157 .ef19 { color: #0000af; } .eb19 { background-color: #0000af; }
158 .ef20 { color: #0000d7; } .eb20 { background-color: #0000d7; }
159 .ef21 { color: #0000ff; } .eb21 { background-color: #0000ff; }
160 .ef22 { color: #005f00; } .eb22 { background-color: #005f00; }
161 .ef23 { color: #005f5f; } .eb23 { background-color: #005f5f; }
162 .ef24 { color: #005f87; } .eb24 { background-color: #005f87; }
163 .ef25 { color: #005faf; } .eb25 { background-color: #005faf; }
164 .ef26 { color: #005fd7; } .eb26 { background-color: #005fd7; }
165 .ef27 { color: #005fff; } .eb27 { background-color: #005fff; }
166 .ef28 { color: #008700; } .eb28 { background-color: #008700; }
167 .ef29 { color: #00875f; } .eb29 { background-color: #00875f; }
168 .ef30 { color: #008787; } .eb30 { background-color: #008787; }
169 .ef31 { color: #0087af; } .eb31 { background-color: #0087af; }
170 .ef32 { color: #0087d7; } .eb32 { background-color: #0087d7; }
171 .ef33 { color: #0087ff; } .eb33 { background-color: #0087ff; }
172 .ef34 { color: #00af00; } .eb34 { background-color: #00af00; }
173 .ef35 { color: #00af5f; } .eb35 { background-color: #00af5f; }
174 .ef36 { color: #00af87; } .eb36 { background-color: #00af87; }
175 .ef37 { color: #00afaf; } .eb37 { background-color: #00afaf; }
176 .ef38 { color: #00afd7; } .eb38 { background-color: #00afd7; }
177 .ef39 { color: #00afff; } .eb39 { background-color: #00afff; }
178 .ef40 { color: #00d700; } .eb40 { background-color: #00d700; }
179 .ef41 { color: #00d75f; } .eb41 { background-color: #00d75f; }
180 .ef42 { color: #00d787; } .eb42 { background-color: #00d787; }
181 .ef43 { color: #00d7af; } .eb43 { background-color: #00d7af; }
182 .ef44 { color: #00d7d7; } .eb44 { background-color: #00d7d7; }
183 .ef45 { color: #00d7ff; } .eb45 { background-color: #00d7ff; }
184 .ef46 { color: #00ff00; } .eb46 { background-color: #00ff00; }
185 .ef47 { color: #00ff5f; } .eb47 { background-color: #00ff5f; }
186 .ef48 { color: #00ff87; } .eb48 { background-color: #00ff87; }
187 .ef49 { color: #00ffaf; } .eb49 { background-color: #00ffaf; }
188 .ef50 { color: #00ffd7; } .eb50 { background-color: #00ffd7; }
189 .ef51 { color: #00ffff; } .eb51 { background-color: #00ffff; }
190 .ef52 { color: #5f0000; } .eb52 { background-color: #5f0000; }
191 .ef53 { color: #5f005f; } .eb53 { background-color: #5f005f; }
192 .ef54 { color: #5f0087; } .eb54 { background-color: #5f0087; }
193 .ef55 { color: #5f00af; } .eb55 { background-color: #5f00af; }
194 .ef56 { color: #5f00d7; } .eb56 { background-color: #5f00d7; }
195 .ef57 { color: #5f00ff; } .eb57 { background-color: #5f00ff; }
196 .ef58 { color: #5f5f00; } .eb58 { background-color: #5f5f00; }
197 .ef59 { color: #5f5f5f; } .eb59 { background-color: #5f5f5f; }
198 .ef60 { color: #5f5f87; } .eb60 { background-color: #5f5f87; }
199 .ef61 { color: #5f5faf; } .eb61 { background-color: #5f5faf; }
200 .ef62 { color: #5f5fd7; } .eb62 { background-color: #5f5fd7; }
201 .ef63 { color: #5f5fff; } .eb63 { background-color: #5f5fff; }
202 .ef64 { color: #5f8700; } .eb64 { background-color: #5f8700; }
203 .ef65 { color: #5f875f; } .eb65 { background-color: #5f875f; }
204 .ef66 { color: #5f8787; } .eb66 { background-color: #5f8787; }
205 .ef67 { color: #5f87af; } .eb67 { background-color: #5f87af; }
206 .ef68 { color: #5f87d7; } .eb68 { background-color: #5f87d7; }
207 .ef69 { color: #5f87ff; } .eb69 { background-color: #5f87ff; }
208 .ef70 { color: #5faf00; } .eb70 { background-color: #5faf00; }
209 .ef71 { color: #5faf5f; } .eb71 { background-color: #5faf5f; }
210 .ef72 { color: #5faf87; } .eb72 { background-color: #5faf87; }
211 .ef73 { color: #5fafaf; } .eb73 { background-color: #5fafaf; }
212 .ef74 { color: #5fafd7; } .eb74 { background-color: #5fafd7; }
213 .ef75 { color: #5fafff; } .eb75 { background-color: #5fafff; }
214 .ef76 { color: #5fd700; } .eb76 { background-color: #5fd700; }
215 .ef77 { color: #5fd75f; } .eb77 { background-color: #5fd75f; }
216 .ef78 { color: #5fd787; } .eb78 { background-color: #5fd787; }
217 .ef79 { color: #5fd7af; } .eb79 { background-color: #5fd7af; }
218 .ef80 { color: #5fd7d7; } .eb80 { background-color: #5fd7d7; }
219 .ef81 { color: #5fd7ff; } .eb81 { background-color: #5fd7ff; }
220 .ef82 { color: #5fff00; } .eb82 { background-color: #5fff00; }
221 .ef83 { color: #5fff5f; } .eb83 { background-color: #5fff5f; }
222 .ef84 { color: #5fff87; } .eb84 { background-color: #5fff87; }
223 .ef85 { color: #5fffaf; } .eb85 { background-color: #5fffaf; }
224 .ef86 { color: #5fffd7; } .eb86 { background-color: #5fffd7; }
225 .ef87 { color: #5fffff; } .eb87 { background-color: #5fffff; }
226 .ef88 { color: #870000; } .eb88 { background-color: #870000; }
227 .ef89 { color: #87005f; } .eb89 { background-color: #87005f; }
228 .ef90 { color: #870087; } .eb90 { background-color: #870087; }
229 .ef91 { color: #8700af; } .eb91 { background-color: #8700af; }
230 .ef92 { color: #8700d7; } .eb92 { background-color: #8700d7; }
231 .ef93 { color: #8700ff; } .eb93 { background-color: #8700ff; }
232 .ef94 { color: #875f00; } .eb94 { background-color: #875f00; }
233 .ef95 { color: #875f5f; } .eb95 { background-color: #875f5f; }
234 .ef96 { color: #875f87; } .eb96 { background-color: #875f87; }
235 .ef97 { color: #875faf; } .eb97 { background-color: #875faf; }
236 .ef98 { color: #875fd7; } .eb98 { background-color: #875fd7; }
237 .ef99 { color: #875fff; } .eb99 { background-color: #875fff; }
238 .ef100 { color: #878700; } .eb100 { background-color: #878700; }
239 .ef101 { color: #87875f; } .eb101 { background-color: #87875f; }
240 .ef102 { color: #878787; } .eb102 { background-color: #878787; }
241 .ef103 { color: #8787af; } .eb103 { background-color: #8787af; }
242 .ef104 { color: #8787d7; } .eb104 { background-color: #8787d7; }
243 .ef105 { color: #8787ff; } .eb105 { background-color: #8787ff; }
244 .ef106 { color: #87af00; } .eb106 { background-color: #87af00; }
245 .ef107 { color: #87af5f; } .eb107 { background-color: #87af5f; }
246 .ef108 { color: #87af87; } .eb108 { background-color: #87af87; }
247 .ef109 { color: #87afaf; } .eb109 { background-color: #87afaf; }
248 .ef110 { color: #87afd7; } .eb110 { background-color: #87afd7; }
249 .ef111 { color: #87afff; } .eb111 { background-color: #87afff; }
250 .ef112 { color: #87d700; } .eb112 { background-color: #87d700; }
251 .ef113 { color: #87d75f; } .eb113 { background-color: #87d75f; }
252 .ef114 { color: #87d787; } .eb114 { background-color: #87d787; }
253 .ef115 { color: #87d7af; } .eb115 { background-color: #87d7af; }
254 .ef116 { color: #87d7d7; } .eb116 { background-color: #87d7d7; }
255 .ef117 { color: #87d7ff; } .eb117 { background-color: #87d7ff; }
256 .ef118 { color: #87ff00; } .eb118 { background-color: #87ff00; }
257 .ef119 { color: #87ff5f; } .eb119 { background-color: #87ff5f; }
258 .ef120 { color: #87ff87; } .eb120 { background-color: #87ff87; }
259 .ef121 { color: #87ffaf; } .eb121 { background-color: #87ffaf; }
260 .ef122 { color: #87ffd7; } .eb122 { background-color: #87ffd7; }
261 .ef123 { color: #87ffff; } .eb123 { background-color: #87ffff; }
262 .ef124 { color: #af0000; } .eb124 { background-color: #af0000; }
263 .ef125 { color: #af005f; } .eb125 { background-color: #af005f; }
264 .ef126 { color: #af0087; } .eb126 { background-color: #af0087; }
265 .ef127 { color: #af00af; } .eb127 { background-color: #af00af; }
266 .ef128 { color: #af00d7; } .eb128 { background-color: #af00d7; }
267 .ef129 { color: #af00ff; } .eb129 { background-color: #af00ff; }
268 .ef130 { color: #af5f00; } .eb130 { background-color: #af5f00; }
269 .ef131 { color: #af5f5f; } .eb131 { background-color: #af5f5f; }
270 .ef132 { color: #af5f87; } .eb132 { background-color: #af5f87; }
271 .ef133 { color: #af5faf; } .eb133 { background-color: #af5faf; }
272 .ef134 { color: #af5fd7; } .eb134 { background-color: #af5fd7; }
273 .ef135 { color: #af5fff; } .eb135 { background-color: #af5fff; }
274 .ef136 { color: #af8700; } .eb136 { background-color: #af8700; }
275 .ef137 { color: #af875f; } .eb137 { background-color: #af875f; }
276 .ef138 { color: #af8787; } .eb138 { background-color: #af8787; }
277 .ef139 { color: #af87af; } .eb139 { background-color: #af87af; }
278 .ef140 { color: #af87d7; } .eb140 { background-color: #af87d7; }
279 .ef141 { color: #af87ff; } .eb141 { background-color: #af87ff; }
280 .ef142 { color: #afaf00; } .eb142 { background-color: #afaf00; }
281 .ef143 { color: #afaf5f; } .eb143 { background-color: #afaf5f; }
282 .ef144 { color: #afaf87; } .eb144 { background-color: #afaf87; }
283 .ef145 { color: #afafaf; } .eb145 { background-color: #afafaf; }
284 .ef146 { color: #afafd7; } .eb146 { background-color: #afafd7; }
285 .ef147 { color: #afafff; } .eb147 { background-color: #afafff; }
286 .ef148 { color: #afd700; } .eb148 { background-color: #afd700; }
287 .ef149 { color: #afd75f; } .eb149 { background-color: #afd75f; }
288 .ef150 { color: #afd787; } .eb150 { background-color: #afd787; }
289 .ef151 { color: #afd7af; } .eb151 { background-color: #afd7af; }
290 .ef152 { color: #afd7d7; } .eb152 { background-color: #afd7d7; }
291 .ef153 { color: #afd7ff; } .eb153 { background-color: #afd7ff; }
292 .ef154 { color: #afff00; } .eb154 { background-color: #afff00; }
293 .ef155 { color: #afff5f; } .eb155 { background-color: #afff5f; }
294 .ef156 { color: #afff87; } .eb156 { background-color: #afff87; }
295 .ef157 { color: #afffaf; } .eb157 { background-color: #afffaf; }
296 .ef158 { color: #afffd7; } .eb158 { background-color: #afffd7; }
297 .ef159 { color: #afffff; } .eb159 { background-color: #afffff; }
298 .ef160 { color: #d70000; } .eb160 { background-color: #d70000; }
299 .ef161 { color: #d7005f; } .eb161 { background-color: #d7005f; }
300 .ef162 { color: #d70087; } .eb162 { background-color: #d70087; }
301 .ef163 { color: #d700af; } .eb163 { background-color: #d700af; }
302 .ef164 { color: #d700d7; } .eb164 { background-color: #d700d7; }
303 .ef165 { color: #d700ff; } .eb165 { background-color: #d700ff; }
304 .ef166 { color: #d75f00; } .eb166 { background-color: #d75f00; }
305 .ef167 { color: #d75f5f; } .eb167 { background-color: #d75f5f; }
306 .ef168 { color: #d75f87; } .eb168 { background-color: #d75f87; }
307 .ef169 { color: #d75faf; } .eb169 { background-color: #d75faf; }
308 .ef170 { color: #d75fd7; } .eb170 { background-color: #d75fd7; }
309 .ef171 { color: #d75fff; } .eb171 { background-color: #d75fff; }
310 .ef172 { color: #d78700; } .eb172 { background-color: #d78700; }
311 .ef173 { color: #d7875f; } .eb173 { background-color: #d7875f; }
312 .ef174 { color: #d78787; } .eb174 { background-color: #d78787; }
313 .ef175 { color: #d787af; } .eb175 { background-color: #d787af; }
314 .ef176 { color: #d787d7; } .eb176 { background-color: #d787d7; }
315 .ef177 { color: #d787ff; } .eb177 { background-color: #d787ff; }
316 .ef178 { color: #d7af00; } .eb178 { background-color: #d7af00; }
317 .ef179 { color: #d7af5f; } .eb179 { background-color: #d7af5f; }
318 .ef180 { color: #d7af87; } .eb180 { background-color: #d7af87; }
319 .ef181 { color: #d7afaf; } .eb181 { background-color: #d7afaf; }
320 .ef182 { color: #d7afd7; } .eb182 { background-color: #d7afd7; }
321 .ef183 { color: #d7afff; } .eb183 { background-color: #d7afff; }
322 .ef184 { color: #d7d700; } .eb184 { background-color: #d7d700; }
323 .ef185 { color: #d7d75f; } .eb185 { background-color: #d7d75f; }
324 .ef186 { color: #d7d787; } .eb186 { background-color: #d7d787; }
325 .ef187 { color: #d7d7af; } .eb187 { background-color: #d7d7af; }
326 .ef188 { color: #d7d7d7; } .eb188 { background-color: #d7d7d7; }
327 .ef189 { color: #d7d7ff; } .eb189 { background-color: #d7d7ff; }
328 .ef190 { color: #d7ff00; } .eb190 { background-color: #d7ff00; }
329 .ef191 { color: #d7ff5f; } .eb191 { background-color: #d7ff5f; }
330 .ef192 { color: #d7ff87; } .eb192 { background-color: #d7ff87; }
331 .ef193 { color: #d7ffaf; } .eb193 { background-color: #d7ffaf; }
332 .ef194 { color: #d7ffd7; } .eb194 { background-color: #d7ffd7; }
333 .ef195 { color: #d7ffff; } .eb195 { background-color: #d7ffff; }
334 .ef196 { color: #ff0000; } .eb196 { background-color: #ff0000; }
335 .ef197 { color: #ff005f; } .eb197 { background-color: #ff005f; }
336 .ef198 { color: #ff0087; } .eb198 { background-color: #ff0087; }
337 .ef199 { color: #ff00af; } .eb199 { background-color: #ff00af; }
338 .ef200 { color: #ff00d7; } .eb200 { background-color: #ff00d7; }
339 .ef201 { color: #ff00ff; } .eb201 { background-color: #ff00ff; }
340 .ef202 { color: #ff5f00; } .eb202 { background-color: #ff5f00; }
341 .ef203 { color: #ff5f5f; } .eb203 { background-color: #ff5f5f; }
342 .ef204 { color: #ff5f87; } .eb204 { background-color: #ff5f87; }
343 .ef205 { color: #ff5faf; } .eb205 { background-color: #ff5faf; }
344 .ef206 { color: #ff5fd7; } .eb206 { background-color: #ff5fd7; }
345 .ef207 { color: #ff5fff; } .eb207 { background-color: #ff5fff; }
346 .ef208 { color: #ff8700; } .eb208 { background-color: #ff8700; }
347 .ef209 { color: #ff875f; } .eb209 { background-color: #ff875f; }
348 .ef210 { color: #ff8787; } .eb210 { background-color: #ff8787; }
349 .ef211 { color: #ff87af; } .eb211 { background-color: #ff87af; }
350 .ef212 { color: #ff87d7; } .eb212 { background-color: #ff87d7; }
351 .ef213 { color: #ff87ff; } .eb213 { background-color: #ff87ff; }
352 .ef214 { color: #ffaf00; } .eb214 { background-color: #ffaf00; }
353 .ef215 { color: #ffaf5f; } .eb215 { background-color: #ffaf5f; }
354 .ef216 { color: #ffaf87; } .eb216 { background-color: #ffaf87; }
355 .ef217 { color: #ffafaf; } .eb217 { background-color: #ffafaf; }
356 .ef218 { color: #ffafd7; } .eb218 { background-color: #ffafd7; }
357 .ef219 { color: #ffafff; } .eb219 { background-color: #ffafff; }
358 .ef220 { color: #ffd700; } .eb220 { background-color: #ffd700; }
359 .ef221 { color: #ffd75f; } .eb221 { background-color: #ffd75f; }
360 .ef222 { color: #ffd787; } .eb222 { background-color: #ffd787; }
361 .ef223 { color: #ffd7af; } .eb223 { background-color: #ffd7af; }
362 .ef224 { color: #ffd7d7; } .eb224 { background-color: #ffd7d7; }
363 .ef225 { color: #ffd7ff; } .eb225 { background-color: #ffd7ff; }
364 .ef226 { color: #ffff00; } .eb226 { background-color: #ffff00; }
365 .ef227 { color: #ffff5f; } .eb227 { background-color: #ffff5f; }
366 .ef228 { color: #ffff87; } .eb228 { background-color: #ffff87; }
367 .ef229 { color: #ffffaf; } .eb229 { background-color: #ffffaf; }
368 .ef230 { color: #ffffd7; } .eb230 { background-color: #ffffd7; }
369 .ef231 { color: #ffffff; } .eb231 { background-color: #ffffff; }
370 .ef232 { color: #080808; } .eb232 { background-color: #080808; }
371 .ef233 { color: #121212; } .eb233 { background-color: #121212; }
372 .ef234 { color: #1c1c1c; } .eb234 { background-color: #1c1c1c; }
373 .ef235 { color: #262626; } .eb235 { background-color: #262626; }
374 .ef236 { color: #303030; } .eb236 { background-color: #303030; }
375 .ef237 { color: #3a3a3a; } .eb237 { background-color: #3a3a3a; }
376 .ef238 { color: #444444; } .eb238 { background-color: #444444; }
377 .ef239 { color: #4e4e4e; } .eb239 { background-color: #4e4e4e; }
378 .ef240 { color: #585858; } .eb240 { background-color: #585858; }
379 .ef241 { color: #626262; } .eb241 { background-color: #626262; }
380 .ef242 { color: #6c6c6c; } .eb242 { background-color: #6c6c6c; }
381 .ef243 { color: #767676; } .eb243 { background-color: #767676; }
382 .ef244 { color: #808080; } .eb244 { background-color: #808080; }
383 .ef245 { color: #8a8a8a; } .eb245 { background-color: #8a8a8a; }
384 .ef246 { color: #949494; } .eb246 { background-color: #949494; }
385 .ef247 { color: #9e9e9e; } .eb247 { background-color: #9e9e9e; }
386 .ef248 { color: #a8a8a8; } .eb248 { background-color: #a8a8a8; }
387 .ef249 { color: #b2b2b2; } .eb249 { background-color: #b2b2b2; }
388 .ef250 { color: #bcbcbc; } .eb250 { background-color: #bcbcbc; }
389 .ef251 { color: #c6c6c6; } .eb251 { background-color: #c6c6c6; }
390 .ef252 { color: #d0d0d0; } .eb252 { background-color: #d0d0d0; }
391 .ef253 { color: #dadada; } .eb253 { background-color: #dadada; }
392 .ef254 { color: #e4e4e4; } .eb254 { background-color: #e4e4e4; }
393 .ef255 { color: #eeeeee; } .eb255 { background-color: #eeeeee; }
394
395 .f9 { color: #000000; }
396 .b9 { background-color: #FFFFFF; }
397 .f9 > .bold,.bold > .f9, body.f9 > pre > .bold {
398 /* Bold is heavy black on white, or bright white
399 depending on the default background */
400 color: #000000;
401 font-weight: bold;
402 }
403 .reverse {
404 /* CSS does not support swapping fg and bg colours unfortunately,
405 so just hardcode something that will look OK on all backgrounds. */
406 color: #000000; background-color: #AAAAAA;
407 }
408 .underline { text-decoration: underline; }
409 .line-through { text-decoration: line-through; }
410 .blink { text-decoration: blink; }
411
412 /* Avoid pixels between adjacent span elements.
413 Note this only works for lines less than 80 chars
414 where we close span elements on the same line.
415 span { display: inline-block; }
416 */
417 </style>
418 </head>
419
420 <body class="f9 b9">
421 <pre>
422 <span class="f1">- fn with_nested_refcell<'nested, 'arg> (</span>
423 <span class="f2">+ fn with_nested_refcell<'nested> (</span>
424 nested: &'nested RefCell<RefCell<str>>,
425 <span class="f1">- f: fn(&'arg str),</span>
426 <span class="f2">+ f: fn<'arg>(&'arg str),</span>
427 )
428 </pre>
429 </body>
430 </html>
431
432
433This is actually a real property with real syntax that can be expressed in
434Rust, and thus that Rust can check, and is precisely the mechanism that enables
435to have closures (and other objects involving custom traits with lifetimes,
436such as [`Deserialize<'de>`]( https://serde.rs/lifetimes.html)) operate on
437borrow over callee locals.
438
439The real syntax for this, is:
440
441```rust
442# use ::core::cell::RefCell;
443#
444fn with_nested_refcell<'nested> (
445 nested: &'nested RefCell<RefCell<str>>,
446 f: for<'arg> fn(&'arg str), // ≈ fn<'arg> (&'arg str),
447)
448{
449 f(&*nested.borrow().borrow())
450}
451```
452
453 - For function pointer types (`fn`):
454
455 ```rust
456 # macro_rules! ignore {($($t:tt)*) => ()} ignore! {
457 for<'lifetimes...> fn(args...) -> Ret
458 # } fn main () {}
459 ```
460
461 - For trait bounds:
462
463 ```rust
464 # macro_rules! ignore {($($t:tt)*) => ()} ignore! {
465 for<'lifetimes...>
466 Type : Bounds
467 ,
468 // e.g.,
469 for<'arg>
470 F : Fn(&'arg str)
471 ,
472 # } fn main () {}
473 ```
474
475 or:
476
477 ```rust
478 # macro_rules! ignore {($($t:tt)*) => ()} ignore! {
479 Type : for<'lifetimes...> Bounds
480 // e.g.,
481 F : for<'arg> Fn(&'arg str)
482 # } fn main () {}
483 ```
484
485Back to the `::serde::Deserialize` example, it can be interesting to
486observe that `DeserializeOwned` is defined as the following simple trait alias:
487
488```rust
489# macro_rules! ignore {($($t:tt)*) => ()} ignore! {
490DeserializeOwned = for<'any> Deserialize<'any>
491# } fn main () {}
492```
493
494> **This whole thing is called Higher-Rank Trait Bounds ([HRTB]) or
495> higher-order lifetimes.**
496
497[HRTB]: https://doc.rust-lang.org/nomicon/hrtb.html
498
499___
500
501Ok, time to go back to the question at hand, that of using the [`custom_dyn!`]
502macro in the context of [`StackBox`]es:
503
504</details>
505
506So the problem is that the currently defined types and impls in this crate do
507not support higher-order lifetimes. Indeed, although it is possible to write
508an impl that supports a specific higher-order signature, it is currently
509impossible in Rust to write generic code that covers all the possible
510higher-order signatures:
511
512 1. For instance, given an `impl<A> Trait for fn(A) { … }`, we won't
513 have `fn(&str)` implementing `Trait`, since
514 `fn(&str) = for<'any> fn(&'any str) ≠ fn(A)`.
515
516 1. And even if we wrote `impl<A : ?Sized> Trait for fn(&A) { … }`, we won't
517 have `fn(&&str)` implementing `Trait`, since
518
519 ```rust
520 # macro_rules! ignore {($($t:tt)*) => ()} ignore! {
521 fn(&&str) = for<'a, 'b> fn(&'a &'b str) != for<'c> fn(&'c A) = fn(&A)
522 # } fn main () {}
523 ```
524
525That's where [`custom_dyn!`] comes into play:
526
527 - I, the crate author, cannot know which higher-order signature(s) you, the
528 user of the library, will be using, and sadly cannot cover that with a
529 generic impl.
530
531 - But since _you_ know which kind of signature you need, I can "let you impl
532 yourself". Sadly, the actual impl is complex and error-prone (involves
533 `unsafe` and VTables!), so instead I provide you this handy macro that will
534 take care of all the nitty-gritty details for you.
535
536In a way, since I am hitting a limitation of the too-early-type-checked Rust
537metaprogramming tool (generics), I am falling back to the duck-typed /
538only-type-checked-when-instanced metaprogramming tool (macros), thus acting as
539a C++ template of sorts, we could say 😄
540
541## Example: `dyn FnOnce(&str) = dyn for<'any> FnOnce(&'any str)`
542
543The following example fails to compile:
544
545```rust,compile_fail
546use ::stackbox::prelude::*;
547
548// `f: StackBox<dyn FnOnce(&'arg str) -> ()>`
549fn call_with_local<'arg> (f: StackBoxDynFnOnce_1<&'arg str, ()>)
550{
551 let local = format!("...");
552 f.call(&local)
553}
554
555fn main ()
556{
557 stackbox!(let f = |_: &str| ());
558 call_with_local(f.into_dyn());
559}
560```
561
562<details><summary>Error message</summary>
563
564```text
565error[E0597]: `local` does not live long enough
566 --> src/some/file.rs:8:12
567 |
5685 | fn call_with_local<'arg> (f: StackBoxDynFnOnce_1<&'arg str, ()>)
569 | ---- lifetime `'arg` defined here
570...
5718 | f.call(&local)
572 | -------^^^^^^-
573 | | |
574 | | borrowed value does not live long enough
575 | argument requires that `local` is borrowed for `'arg`
5769 | }
577 | - `local` dropped here while still borrowed
578```
579
580This is exactly the same problem we had when I was explaining higher-order
581signatures and we had `fn nested_refcells<'nested, 'arg>...`: the lifetime
582of the parameter is an _outer_ (fixed) generic lifetime parameter, and it can
583thus not work with a local / callee-specific lifetime.
584
585___
586
587</details>
588
589The solution is to define a new `DynFnOnce...` trait, which involves a
590higher-order lifetime in the signature:
591
592```rust
593use ::stackbox::prelude::*;
594
595custom_dyn! {
596 pub
597 dyn FnOnceStr : FnOnce(&str) {
598 fn call (self: Self, arg: &str)
599 {
600 self(arg)
601 }
602 }
603}
604// `f: StackBox<dyn FnOnce(&str) -> ()>`
605fn call_with_local (f: StackBoxDynFnOnceStr)
606{
607 let local = format!("...");
608 f.call(&local)
609}
610
611fn main ()
612{
613 stackbox!(let f = |_: &str| ());
614 call_with_local(f.into_dyn());
615}
616```
617
618*/
619#[macro_export]
620macro_rules! custom_dyn {(
621 #![dollar = $__:tt]
622 $( #[doc = $doc:expr] )*
623 $pub:vis
624 dyn $Trait:ident $(
625 <
626 $($lt:lifetime),* $(,)? $($T:ident),* $(,)?
627 >
628 )?
629 : $super:path
630 $(
631 where { $($wc:tt)* }
632 )?
633 {
634 $(
635 fn $method:ident (
636 $self:ident :
637 $(
638 & $($ref:lifetime)?
639 $(mut $(@$mut:tt)?)?
640 )?
641 Self
642 $(,
643 $arg_name:ident : $ArgTy:ty )*
644 $(,)?
645 ) $(-> $RetTy:ty)?
646 {
647 $($body:tt)*
648 }
649 )*
650 }
651) => ($crate::__::paste! {
652 $( #[doc = $doc] )*
653 $pub
654 struct [<StackBoxDyn $Trait>] <
655 '__frame,
656 $($($lt : '__frame ,)* $($T : '__frame ,)*)?
657 __AutoTraits : ?$crate::__::Sized + $crate::__::Sendness + $crate::__::Syncness = $crate::__::NoAutoTraits,
658 >
659 $( where $($wc)* )?
660 {
661 ptr: $crate::__::ErasedPtr,
662 vtable: &'__frame <Self as $crate::__::GetVTable>::VTable,
663 _auto_traits: $crate::__::PhantomData<__AutoTraits>,
664 }
665 const _: () = {
666 trait $Trait<$($($lt ,)* $($T ,)*)?> : $crate::__::Sized + $super
667 $( where $($wc)* )?
668 {
669 $(
670 #[inline(always)]
671 fn [<__ $method>] ( // underscored to avoid conflicts
672 $self :
673 $(
674 & $($ref)?
675 $(mut $(@$mut)?)?
676 )?
677 Self
678 $(,
679 $arg_name : $ArgTy )*
680 ) $(-> $RetTy)?
681 {
682 $($body)*
683 }
684 )*
685 }
686 impl<$($($lt ,)* $($T ,)*)? __Self : $super> $Trait<$($($lt ,)* $($T ,)*)?>
687 for __Self
688 $(where $($wc)* )?
689 {}
690
691 pub
692 struct __VTable<$($($lt ,)* $($T ,)*)?>
693 $( where $($wc)* )?
694 {
695 drop_in_place: unsafe fn ($crate::__::ErasedPtr),
696 $(
697 $method:
698 unsafe
699 fn(
700 __ptr: $crate::__::ErasedPtr $(,
701 $arg_name: $ArgTy )*
702 ) $(-> $RetTy)?
703 ,
704 )*
705 }
706
707 impl<
708 '__frame,
709 $($($lt ,)* $($T : '__frame ,)*)?
710 __AutoTraits : ?$crate::__::Sized + $crate::__::Sendness + $crate::__::Syncness,
711 >
712 $crate::__::GetVTable
713 for
714 [<StackBoxDyn $Trait>]<'__frame, $($($lt ,)* $($T ,)*)? __AutoTraits>
715 $( where $($wc)* )?
716 {
717 type VTable = __VTable<$($($lt ,)* $($T ,)*)?>;
718 }
719
720 trait HasVTable<
721 '__frame,
722 $($($lt ,)* $($T : '__frame ,)*)?
723 >
724 :
725 $crate::__::Sized
726 $( where $($wc)* )?
727 {
728 const VTABLE: __VTable<$($($lt ,)* $($T ,)*)?>;
729 }
730
731 impl<
732 '__frame,
733 $($($lt ,)* $($T : '__frame ,)*)?
734 __Self : $super,
735 >
736 HasVTable<'__frame, $($($lt ,)* $($T ,)*)?>
737 for
738 __Self
739 $( where $($wc)* )?
740 {
741 const VTABLE: __VTable<$($($lt ,)* $($T ,)*)?> = __VTable {
742 drop_in_place: $crate::__::drop_in_place::<Self>,
743 $(
744 $method: {
745 |
746 __ptr: $crate::__::ErasedPtr $(,
747 $arg_name: $ArgTy )*
748 | $( -> $RetTy )?
749 { unsafe {
750 // Safety: immediately coerced to an `unsafe fn`
751 let _convert =
752 |ptr: $crate::__::ErasedPtr| -> Self {
753 let ptr: $crate::StackBox<'_, Self> =
754 $crate::__::transmute(ptr)
755 ;
756 ptr.into_inner()
757 }
758 ;
759 {
760 $(
761 let _convert =
762 $crate::__::transmute::<
763 $crate::__::ErasedPtr,
764 &'_ $(mut $($mut)?)? Self,
765 >
766 ;
767 )?
768 _convert(__ptr).[<__ $method>]($($arg_name),*)
769 }
770 }}
771 },
772 )*
773 };
774 }
775
776 define_coercions! {
777 [$crate::__::Send] => dyn $crate::__::Send,
778 [$crate::__::Sync] => dyn $crate::__::Sync,
779 [$crate::__::Send, $crate::__::Sync] => dyn $crate::__::Send + $crate::__::Sync,
780 [] => $crate::__::NoAutoTraits,
781 } macro_rules! define_coercions {(
782 $__(
783 [$__($AutoTrait:path),* $__(,)?] => $Marker:ty
784 ),* $__(,)?
785 ) => (
786 $__(
787 impl<
788 '__frame,
789 $($($lt : '__frame ,)* $($T : '__frame ,)*)?
790 __Pointee : $super
791 >
792 $crate::__::DynCoerce<$crate::StackBox<'__frame, __Pointee>>
793 for
794 [<StackBoxDyn $Trait>]<'__frame, $($($lt ,)* $($T ,)*)? $Marker>
795 where
796 $__(
797 __Pointee : $AutoTrait,
798 )*
799 $($($wc)*)?
800 {
801 fn fatten (it: $crate::StackBox<'__frame, __Pointee>)
802 -> Self
803 {
804 Self {
805 vtable: &<__Pointee as HasVTable<'__frame, $($($lt ,)* $($T ,)*)?>>::VTABLE,
806 ptr: unsafe { $crate::__::transmute(it) },
807 _auto_traits: $crate::__::PhantomData,
808 }
809 }
810 }
811
812 $__(
813 unsafe // Safety: from the `DynCoerce` bound added at construction site.
814 impl<'__frame, $($($lt : '__frame ,)* $($T : '__frame ,)*)?>
815 $AutoTrait
816 for
817 [<StackBoxDyn $Trait>]<'__frame, $($($lt ,)* $($T ,)*)? $Marker>
818 {}
819 )*
820 )*
821 )} use define_coercions;
822
823 impl<
824 '__frame,
825 $($($lt : '__frame ,)* $($T : '__frame ,)*)?
826 __AutoTraits : ?$crate::__::Sized + $crate::__::Sendness + $crate::__::Syncness,
827 >
828 [<StackBoxDyn $Trait>]<'__frame, $($($lt ,)* $($T ,)*)? __AutoTraits>
829 $(where $($wc)* )?
830 {
831 $(
832 $pub
833 fn $method (
834 self:
835 $(
836 & $($ref)?
837 $(mut $($mut)?)?
838 )?
839 Self
840 $(,
841 $arg_name: $ArgTy )*
842 ) $(-> $RetTy)?
843 {
844 unsafe {
845 (self.vtable.$method)(
846 $crate::__::ManuallyDrop::new(self).ptr $(,
847 $arg_name )*
848 )
849 }
850 }
851 )*
852 }
853
854 impl<
855 '__frame,
856 $($($lt : '__frame ,)* $($T : '__frame ,)*)?
857 __AutoTraits : ?$crate::__::Sized + $crate::__::Sendness + $crate::__::Syncness,
858 >
859 $crate::__::Drop
860 for
861 [<StackBoxDyn $Trait>]<'__frame, $($($lt ,)* $($T ,)*)? __AutoTraits>
862 $(where $($wc)* )?
863 {
864 fn drop (self: &'_ mut Self)
865 {
866 unsafe {
867 (self.vtable.drop_in_place)(self.ptr)
868 }
869 }
870 }
871 };
872}); (
873 // Missing dollar case
874 $( #[doc = $doc:expr ] )*
875 $pub:vis
876 dyn $($rest:tt)*
877) => ($crate::custom_dyn! {
878 #![dollar = $]
879 $( #[doc = $doc] )*
880 $pub
881 dyn $($rest)*
882})}
883
884#[cfg(doc)]
885use custom_dyn;