| ▲ | pornel 8 hours ago | |
Yeah, Rust closures that capture data are fat pointers { fn*, data* }, so you need an awkward dance to make them thin pointers for C.
It requires a userdata arg for the C function, since there's no allocation or executable-stack magic to give a unique function pointer to each data instance. OTOH it's zero-cost. The generic make_trampoline inlines code of the closure, so there's no extra indirection. | ||
| ▲ | skavi 4 hours ago | parent | next [-] | |
> Rust closures that capture data are fat pointers { fn, data } This isn’t fully accurate. In your example, `&mut C` actually has the same layout as usize. It’s not a fat pointer. `C` is a concrete type and essentially just an anonymous struct with FnMut implemented for it. You’re probably thinking of `&mut dyn FnMut` which is a fat pointer that pairs a pointer to the data with a pointer to a VTable. So in your specific example, the double indirection is unnecessary. The following passes miri: https://play.rust-lang.org/?version=nightly&mode=debug&editi... (did this on mobile, so please excuse any messiness). | ||
| ▲ | nesarkvechnep 7 hours ago | parent | prev [-] | |
I know about this technique but it uses too much unsafe for my taste. Not that it's bad or anything, just a personal preference. | ||