@@ -121,17 +121,19 @@ every expression, block, and pattern (patterns are considered to
121121"execute" by testing the value they are applied to and creating any
122122relevant bindings). So, for example:
123123
124- fn foo(x: isize, y: isize) { // -+
125- // +------------+ // |
126- // | +-----+ // |
127- // | +-+ +-+ +-+ // |
128- // | | | | | | | // |
129- // v v v v v v v // |
130- let z = x + y; // |
131- ... // |
132- } // -+
133-
134- fn bar() { ... }
124+ ``` rust
125+ fn foo (x : isize , y : isize ) { // -+
126+ // +------------+ // |
127+ // | +-----+ // |
128+ // | +-+ +-+ +-+ // |
129+ // | | | | | | | // |
130+ // v v v v v v v // |
131+ let z = x + y ; // |
132+ ... // |
133+ } // -+
134+
135+ fn bar () { ... }
136+ ```
135137
136138In this example, there is a region for the fn body block as a whole,
137139and then a subregion for the declaration of the local variable.
@@ -160,28 +162,32 @@ this, we get a lot of spurious errors around nested calls, in
160162particular when combined with ` &mut ` functions. For example, a call
161163like this one
162164
163- self.foo(self.bar())
165+ ``` rust
166+ self . foo (self . bar ())
167+ ```
164168
165169where both ` foo ` and ` bar ` are ` &mut self ` functions will always yield
166170an error.
167171
168172Here is a more involved example (which is safe) so we can see what's
169173going on:
170174
171- struct Foo { f: usize, g: usize }
172- ...
173- fn add(p: &mut usize, v: usize) {
174- *p += v;
175- }
176- ...
177- fn inc(p: &mut usize) -> usize {
178- *p += 1; *p
179- }
180- fn weird() {
181- let mut x: Box<Foo> = box Foo { ... };
182- 'a: add(&mut (*x).f,
183- 'b: inc(&mut (*x).f)) // (..)
184- }
175+ ``` rust
176+ struct Foo { f : usize , g : usize }
177+ // ...
178+ fn add (p : & mut usize , v : usize ) {
179+ * p += v ;
180+ }
181+ // ...
182+ fn inc (p : & mut usize ) -> usize {
183+ * p += 1 ; * p
184+ }
185+ fn weird () {
186+ let mut x : Box <Foo > = box Foo { /* ... */ };
187+ 'a : add (& mut (* x ). f,
188+ 'b : inc (& mut (* x ). f)) // (..)
189+ }
190+ ```
185191
186192The important part is the line marked ` (..) ` which contains a call to
187193` add() ` . The first argument is a mutable borrow of the field ` f ` . The
@@ -197,16 +203,18 @@ can see that this error is unnecessary. Let's examine the lifetimes
197203involved with ` 'a ` in detail. We'll break apart all the steps involved
198204in a call expression:
199205
200- 'a: {
201- 'a_arg1: let a_temp1: ... = add;
202- 'a_arg2: let a_temp2: &'a mut usize = &'a mut (*x).f;
203- 'a_arg3: let a_temp3: usize = {
204- let b_temp1: ... = inc;
205- let b_temp2: &'b = &'b mut (*x).f;
206- 'b_call: b_temp1(b_temp2)
207- };
208- 'a_call: a_temp1(a_temp2, a_temp3) // (**)
209- }
206+ ``` rust
207+ 'a : {
208+ 'a_arg1 : let a_temp1 : ... = add ;
209+ 'a_arg2 : let a_temp2 : & 'a mut usize = & 'a mut (* x ). f;
210+ 'a_arg3 : let a_temp3 : usize = {
211+ let b_temp1 : ... = inc ;
212+ let b_temp2 : & 'b = & 'b mut (* x ). f;
213+ 'b_call : b_temp1 (b_temp2 )
214+ };
215+ 'a_call : a_temp1 (a_temp2 , a_temp3 ) // (**)
216+ }
217+ ```
210218
211219Here we see that the lifetime ` 'a ` includes a number of substatements.
212220In particular, there is this lifetime I've called ` 'a_call ` that
@@ -225,19 +233,21 @@ it will not be *dereferenced* during the evaluation of the second
225233argument, it can still be * invalidated* by that evaluation. Consider
226234this similar but unsound example:
227235
228- struct Foo { f: usize, g: usize }
229- ...
230- fn add(p: &mut usize, v: usize) {
231- *p += v;
232- }
233- ...
234- fn consume(x: Box<Foo>) -> usize {
235- x.f + x.g
236- }
237- fn weird() {
238- let mut x: Box<Foo> = box Foo { ... };
239- 'a: add(&mut (*x).f, consume(x)) // (..)
240- }
236+ ``` rust
237+ struct Foo { f : usize , g : usize }
238+ // ...
239+ fn add (p : & mut usize , v : usize ) {
240+ * p += v ;
241+ }
242+ // ...
243+ fn consume (x : Box <Foo >) -> usize {
244+ x . f + x . g
245+ }
246+ fn weird () {
247+ let mut x : Box <Foo > = box Foo { ... };
248+ 'a : add (& mut (* x ). f, consume (x )) // (..)
249+ }
250+ ```
241251
242252In this case, the second argument to ` add ` actually consumes ` x ` , thus
243253invalidating the first argument.
0 commit comments