Skip to content

Commit 8ef05c2

Browse files
author
Ariel Ben-Yehuda
authored
Rollup merge of rust-lang#40146 - bjorn3:few-infer-changes, r=pnkfelix
Better docs of rusty parts of typeck
2 parents 2474e86 + 90e94d9 commit 8ef05c2

File tree

3 files changed

+63
-51
lines changed

3 files changed

+63
-51
lines changed

src/librustc/infer/README.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ course, it depends on the program.
152152

153153
The main case which fails today that I would like to support is:
154154

155-
```text
155+
```rust
156156
fn foo<T>(x: T, y: T) { ... }
157157

158158
fn bar() {
@@ -168,6 +168,8 @@ because the type variable `T` is merged with the type variable for
168168
`X`, and thus inherits its UB/LB of `@mut int`. This leaves no
169169
flexibility for `T` to later adjust to accommodate `@int`.
170170

171+
Note: `@` and `@mut` are replaced with `Rc<T>` and `Rc<RefCell<T>>` in current Rust.
172+
171173
### What to do when not all bounds are present
172174

173175
In the prior discussion we assumed that A.ub was not top and B.lb was

src/librustc/infer/region_inference/README.md

+59-49
Original file line numberDiff line numberDiff line change
@@ -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
122122
relevant 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

136138
In this example, there is a region for the fn body block as a whole,
137139
and 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
160162
particular when combined with `&mut` functions. For example, a call
161163
like this one
162164

163-
self.foo(self.bar())
165+
```rust
166+
self.foo(self.bar())
167+
```
164168

165169
where both `foo` and `bar` are `&mut self` functions will always yield
166170
an error.
167171

168172
Here is a more involved example (which is safe) so we can see what's
169173
going 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

186192
The 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
197203
involved with `'a` in detail. We'll break apart all the steps involved
198204
in 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

211219
Here we see that the lifetime `'a` includes a number of substatements.
212220
In 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
225233
argument, it can still be *invalidated* by that evaluation. Consider
226234
this 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

242252
In this case, the second argument to `add` actually consumes `x`, thus
243253
invalidating the first argument.

src/librustc/infer/region_inference/graphviz.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ pub fn maybe_print_constraints_for<'a, 'gcx, 'tcx>(
9191
};
9292

9393
if output_template.is_empty() {
94-
bug!("empty string provided as RUST_REGION_GRAPH");
94+
panic!("empty string provided as RUST_REGION_GRAPH");
9595
}
9696

9797
if output_template.contains('%') {

0 commit comments

Comments
 (0)