Skip to content

Commit f4d1b42

Browse files
authored
Clarify the HRTB chapter (#330)
1 parent ca00ee8 commit f4d1b42

File tree

1 file changed

+35
-1
lines changed

1 file changed

+35
-1
lines changed

src/hrtb.md

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,11 @@ fn main() {
2626
```
2727

2828
If we try to naively desugar this code in the same way that we did in the
29-
lifetimes section, we run into some trouble:
29+
[lifetimes section][lt], we run into some trouble:
3030

3131
<!-- ignore: desugared code -->
3232
```rust,ignore
33+
// NOTE: `&'b data.0` and `'x: {` is not valid syntax!
3334
struct Closure<F> {
3435
data: (u8, u16),
3536
func: F,
@@ -66,10 +67,43 @@ desugar this is as follows:
6667
where for<'a> F: Fn(&'a (u8, u16)) -> &'a u8,
6768
```
6869

70+
Alternatively:
71+
72+
<!-- ignore: simplified code -->
73+
```rust,ignore
74+
where F: for<'a> Fn(&'a (u8, u16)) -> &'a u8,
75+
```
76+
6977
(Where `Fn(a, b, c) -> d` is itself just sugar for the unstable *real* `Fn`
7078
trait)
7179

7280
`for<'a>` can be read as "for all choices of `'a`", and basically produces an
7381
*infinite list* of trait bounds that F must satisfy. Intense. There aren't many
7482
places outside of the `Fn` traits where we encounter HRTBs, and even for
7583
those we have a nice magic sugar for the common cases.
84+
85+
In summary, we can rewrite the original code more explicitly as:
86+
87+
```rust
88+
struct Closure<F> {
89+
data: (u8, u16),
90+
func: F,
91+
}
92+
93+
impl<F> Closure<F>
94+
where for<'a> F: Fn(&'a (u8, u16)) -> &'a u8,
95+
{
96+
fn call(&self) -> &u8 {
97+
(self.func)(&self.data)
98+
}
99+
}
100+
101+
fn do_it(data: &(u8, u16)) -> &u8 { &data.0 }
102+
103+
fn main() {
104+
let clo = Closure { data: (0, 1), func: do_it };
105+
println!("{}", clo.call());
106+
}
107+
```
108+
109+
[lt]: lifetimes.html

0 commit comments

Comments
 (0)