]> git.proxmox.com Git - rustc.git/blob - src/doc/nomicon/hrtb.md
Imported Upstream version 1.3.0+dfsg1
[rustc.git] / src / doc / nomicon / hrtb.md
1 % Higher-Rank Trait Bounds (HRTBs)
2
3 Rust's `Fn` traits are a little bit magic. For instance, we can write the
4 following code:
5
6 ```rust
7 struct Closure<F> {
8 data: (u8, u16),
9 func: F,
10 }
11
12 impl<F> Closure<F>
13 where F: Fn(&(u8, u16)) -> &u8,
14 {
15 fn call(&self) -> &u8 {
16 (self.func)(&self.data)
17 }
18 }
19
20 fn do_it(data: &(u8, u16)) -> &u8 { &data.0 }
21
22 fn main() {
23 let clo = Closure { data: (0, 1), func: do_it };
24 println!("{}", clo.call());
25 }
26 ```
27
28 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:
30
31 ```rust,ignore
32 struct Closure<F> {
33 data: (u8, u16),
34 func: F,
35 }
36
37 impl<F> Closure<F>
38 // where F: Fn(&'??? (u8, u16)) -> &'??? u8,
39 {
40 fn call<'a>(&'a self) -> &'a u8 {
41 (self.func)(&self.data)
42 }
43 }
44
45 fn do_it<'b>(data: &'b (u8, u16)) -> &'b u8 { &'b data.0 }
46
47 fn main() {
48 'x: {
49 let clo = Closure { data: (0, 1), func: do_it };
50 println!("{}", clo.call());
51 }
52 }
53 ```
54
55 How on earth are we supposed to express the lifetimes on `F`'s trait bound? We
56 need to provide some lifetime there, but the lifetime we care about can't be
57 named until we enter the body of `call`! Also, that isn't some fixed lifetime;
58 `call` works with *any* lifetime `&self` happens to have at that point.
59
60 This job requires The Magic of Higher-Rank Trait Bounds (HRTBs). The way we
61 desugar this is as follows:
62
63 ```rust,ignore
64 where for<'a> F: Fn(&'a (u8, u16)) -> &'a u8,
65 ```
66
67 (Where `Fn(a, b, c) -> d` is itself just sugar for the unstable *real* `Fn`
68 trait)
69
70 `for<'a>` can be read as "for all choices of `'a`", and basically produces an
71 *infinite list* of trait bounds that F must satisfy. Intense. There aren't many
72 places outside of the `Fn` traits where we encounter HRTBs, and even for
73 those we have a nice magic sugar for the common cases.