Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better docs of rusty parts of typeck #40146

Merged
merged 5 commits into from
Mar 12, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/librustc/infer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ course, it depends on the program.

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

```text
```rust
fn foo<T>(x: T, y: T) { ... }

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

Note: `@` and `@mut` are replaced with `Rc<T>` and `Rc<RefCell<T>>` in current Rust.

### What to do when not all bounds are present

In the prior discussion we assumed that A.ub was not top and B.lb was
Expand Down
108 changes: 59 additions & 49 deletions src/librustc/infer/region_inference/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,17 +121,19 @@ every expression, block, and pattern (patterns are considered to
"execute" by testing the value they are applied to and creating any
relevant bindings). So, for example:

fn foo(x: isize, y: isize) { // -+
// +------------+ // |
// | +-----+ // |
// | +-+ +-+ +-+ // |
// | | | | | | | // |
// v v v v v v v // |
let z = x + y; // |
... // |
} // -+

fn bar() { ... }
```rust
fn foo(x: isize, y: isize) { // -+
// +------------+ // |
// | +-----+ // |
// | +-+ +-+ +-+ // |
// | | | | | | | // |
// v v v v v v v // |
let z = x + y; // |
... // |
} // -+

fn bar() { ... }
```

In this example, there is a region for the fn body block as a whole,
and then a subregion for the declaration of the local variable.
Expand Down Expand Up @@ -160,28 +162,32 @@ this, we get a lot of spurious errors around nested calls, in
particular when combined with `&mut` functions. For example, a call
like this one

self.foo(self.bar())
```rust
self.foo(self.bar())
```

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

Here is a more involved example (which is safe) so we can see what's
going on:

struct Foo { f: usize, g: usize }
...
fn add(p: &mut usize, v: usize) {
*p += v;
}
...
fn inc(p: &mut usize) -> usize {
*p += 1; *p
}
fn weird() {
let mut x: Box<Foo> = box Foo { ... };
'a: add(&mut (*x).f,
'b: inc(&mut (*x).f)) // (..)
}
```rust
struct Foo { f: usize, g: usize }
// ...
fn add(p: &mut usize, v: usize) {
*p += v;
}
// ...
fn inc(p: &mut usize) -> usize {
*p += 1; *p
}
fn weird() {
let mut x: Box<Foo> = box Foo { /* ... */ };
'a: add(&mut (*x).f,
'b: inc(&mut (*x).f)) // (..)
}
```

The important part is the line marked `(..)` which contains a call to
`add()`. The first argument is a mutable borrow of the field `f`. The
Expand All @@ -197,16 +203,18 @@ can see that this error is unnecessary. Let's examine the lifetimes
involved with `'a` in detail. We'll break apart all the steps involved
in a call expression:

'a: {
'a_arg1: let a_temp1: ... = add;
'a_arg2: let a_temp2: &'a mut usize = &'a mut (*x).f;
'a_arg3: let a_temp3: usize = {
let b_temp1: ... = inc;
let b_temp2: &'b = &'b mut (*x).f;
'b_call: b_temp1(b_temp2)
};
'a_call: a_temp1(a_temp2, a_temp3) // (**)
}
```rust
'a: {
'a_arg1: let a_temp1: ... = add;
'a_arg2: let a_temp2: &'a mut usize = &'a mut (*x).f;
'a_arg3: let a_temp3: usize = {
let b_temp1: ... = inc;
let b_temp2: &'b = &'b mut (*x).f;
'b_call: b_temp1(b_temp2)
};
'a_call: a_temp1(a_temp2, a_temp3) // (**)
}
```

Here we see that the lifetime `'a` includes a number of substatements.
In particular, there is this lifetime I've called `'a_call` that
Expand All @@ -225,19 +233,21 @@ it will not be *dereferenced* during the evaluation of the second
argument, it can still be *invalidated* by that evaluation. Consider
this similar but unsound example:

struct Foo { f: usize, g: usize }
...
fn add(p: &mut usize, v: usize) {
*p += v;
}
...
fn consume(x: Box<Foo>) -> usize {
x.f + x.g
}
fn weird() {
let mut x: Box<Foo> = box Foo { ... };
'a: add(&mut (*x).f, consume(x)) // (..)
}
```rust
struct Foo { f: usize, g: usize }
// ...
fn add(p: &mut usize, v: usize) {
*p += v;
}
// ...
fn consume(x: Box<Foo>) -> usize {
x.f + x.g
}
fn weird() {
let mut x: Box<Foo> = box Foo { ... };
'a: add(&mut (*x).f, consume(x)) // (..)
}
```

In this case, the second argument to `add` actually consumes `x`, thus
invalidating the first argument.
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/infer/region_inference/graphviz.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ pub fn maybe_print_constraints_for<'a, 'gcx, 'tcx>(
};

if output_template.is_empty() {
bug!("empty string provided as RUST_REGION_GRAPH");
panic!("empty string provided as RUST_REGION_GRAPH");
}

if output_template.contains('%') {
Expand Down