diff --git a/src/hrtb.md b/src/hrtb.md index be5a55b..fb2c600 100644 --- a/src/hrtb.md +++ b/src/hrtb.md @@ -26,10 +26,11 @@ fn main() { ``` If we try to naively desugar this code in the same way that we did in the -lifetimes section, we run into some trouble: +[lifetimes section][lt], we run into some trouble: ```rust,ignore +// NOTE: `&'b data.0` and `'x: {` is not valid syntax! struct Closure { data: (u8, u16), func: F, @@ -66,6 +67,13 @@ desugar this is as follows: where for<'a> F: Fn(&'a (u8, u16)) -> &'a u8, ``` +Alternatively: + + +```rust,ignore +where F: for<'a> Fn(&'a (u8, u16)) -> &'a u8, +``` + (Where `Fn(a, b, c) -> d` is itself just sugar for the unstable *real* `Fn` trait) @@ -73,3 +81,29 @@ trait) *infinite list* of trait bounds that F must satisfy. Intense. There aren't many places outside of the `Fn` traits where we encounter HRTBs, and even for those we have a nice magic sugar for the common cases. + +In summary, we can rewrite the original code more explicitly as: + +```rust +struct Closure { + data: (u8, u16), + func: F, +} + +impl Closure + where for<'a> F: Fn(&'a (u8, u16)) -> &'a u8, +{ + fn call(&self) -> &u8 { + (self.func)(&self.data) + } +} + +fn do_it(data: &(u8, u16)) -> &u8 { &data.0 } + +fn main() { + let clo = Closure { data: (0, 1), func: do_it }; + println!("{}", clo.call()); +} +``` + +[lt]: lifetimes.html