@@ -26,10 +26,11 @@ fn main() {
26
26
```
27
27
28
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:
29
+ [ lifetimes section] [ lt ] , we run into some trouble:
30
30
31
31
<!-- ignore: desugared code -->
32
32
``` rust,ignore
33
+ // NOTE: `&'b data.0` and `'x: {` is not valid syntax!
33
34
struct Closure<F> {
34
35
data: (u8, u16),
35
36
func: F,
@@ -66,10 +67,43 @@ desugar this is as follows:
66
67
where for<'a> F: Fn(&'a (u8, u16)) -> &'a u8,
67
68
```
68
69
70
+ Alternatively:
71
+
72
+ <!-- ignore: simplified code -->
73
+ ``` rust,ignore
74
+ where F: for<'a> Fn(&'a (u8, u16)) -> &'a u8,
75
+ ```
76
+
69
77
(Where ` Fn(a, b, c) -> d ` is itself just sugar for the unstable * real* ` Fn `
70
78
trait)
71
79
72
80
` for<'a> ` can be read as "for all choices of ` 'a ` ", and basically produces an
73
81
* infinite list* of trait bounds that F must satisfy. Intense. There aren't many
74
82
places outside of the ` Fn ` traits where we encounter HRTBs, and even for
75
83
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