From 53d3c8939e3cf45f9e08fd360d9289e9440b6ece Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Tue, 28 Feb 2017 10:57:10 +0100 Subject: [PATCH 1/5] Dont bug! on user error --- src/librustc/infer/region_inference/graphviz.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/infer/region_inference/graphviz.rs b/src/librustc/infer/region_inference/graphviz.rs index 95ce8d39ff48..a67049f72852 100644 --- a/src/librustc/infer/region_inference/graphviz.rs +++ b/src/librustc/infer/region_inference/graphviz.rs @@ -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('%') { From 54a1c8b1a66ce6dd4f46fc6063612607897b2638 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Tue, 28 Feb 2017 10:59:36 +0100 Subject: [PATCH 2/5] Fix indentation in region infer docs --- src/librustc/infer/region_inference/README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/librustc/infer/region_inference/README.md b/src/librustc/infer/region_inference/README.md index 80da861139b4..4f24b37682eb 100644 --- a/src/librustc/infer/region_inference/README.md +++ b/src/librustc/infer/region_inference/README.md @@ -122,14 +122,14 @@ every expression, block, and pattern (patterns are considered to relevant bindings). So, for example: fn foo(x: isize, y: isize) { // -+ - // +------------+ // | - // | +-----+ // | - // | +-+ +-+ +-+ // | - // | | | | | | | // | - // v v v v v v v // | - let z = x + y; // | - ... // | - } // -+ + // +------------+ // | + // | +-----+ // | + // | +-+ +-+ +-+ // | + // | | | | | | | // | + // v v v v v v v // | + let z = x + y; // | + ... // | + } // -+ fn bar() { ... } From 2a40918928818bdaa8bdc3780ce5d6449bb69f85 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Tue, 28 Feb 2017 11:17:14 +0100 Subject: [PATCH 3/5] Syntax highlighting in region infer docs --- src/librustc/infer/region_inference/README.md | 108 ++++++++++-------- 1 file changed, 59 insertions(+), 49 deletions(-) diff --git a/src/librustc/infer/region_inference/README.md b/src/librustc/infer/region_inference/README.md index 4f24b37682eb..f5c254a45940 100644 --- a/src/librustc/infer/region_inference/README.md +++ b/src/librustc/infer/region_inference/README.md @@ -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. @@ -160,7 +162,9 @@ 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. @@ -168,20 +172,22 @@ 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 = 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 = 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 @@ -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 @@ -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) -> usize { - x.f + x.g - } - fn weird() { - let mut x: Box = 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) -> usize { + x.f + x.g +} +fn weird() { + let mut x: Box = 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. From be49671df9772ee8b82a53c147f8a3cd115fd8f0 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Tue, 28 Feb 2017 11:19:48 +0100 Subject: [PATCH 4/5] Improve a bit more --- src/librustc/infer/region_inference/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/infer/region_inference/README.md b/src/librustc/infer/region_inference/README.md index f5c254a45940..b564faf3d0c2 100644 --- a/src/librustc/infer/region_inference/README.md +++ b/src/librustc/infer/region_inference/README.md @@ -183,7 +183,7 @@ fn inc(p: &mut usize) -> usize { *p += 1; *p } fn weird() { - let mut x: Box = box Foo { ... }; + let mut x: Box = box Foo { /* ... */ }; 'a: add(&mut (*x).f, 'b: inc(&mut (*x).f)) // (..) } From 90e94d97f2635af1f976a1c6ad2f1296df05c784 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Tue, 28 Feb 2017 11:39:00 +0100 Subject: [PATCH 5/5] Syntax highlight and note about current rust in infer docs --- src/librustc/infer/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/librustc/infer/README.md b/src/librustc/infer/README.md index c835189820e5..68e64b8b7bfc 100644 --- a/src/librustc/infer/README.md +++ b/src/librustc/infer/README.md @@ -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(x: T, y: T) { ... } fn bar() { @@ -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` and `Rc>` 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