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&lt;'nested, 'arg&gt; (</span>
423        <span class="f2">+ fn with_nested_refcell&lt;'nested&gt; (</span>
424              nested: &amp;'nested RefCell&lt;RefCell&lt;str&gt;&gt;,
425        <span class="f1">-     f: fn(&amp;'arg str),</span>
426        <span class="f2">+     f: fn&lt;'arg&gt;(&amp;'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;