Auto merge of #52488 - nikomatsakis:nll-issue-48071-universe-and-sub, r=pnkfelix
introduce universes to NLL type check This branch aims to fix #48071 and also advance chalk integration a bit at the same time. It re-implements the subtyping/type-equating check so that NLL doesn't "piggy back" on the subtyping code of the old type checker. This new code uses the "universe-based" approach to handling higher-ranked lifetimes, which sidesteps some of the limitations of the current "leak-based" scheme. This avoids the ICE in #48071. At the same time, I aim for this to potentially be a kind of optimization. This NLL code is (currently) not cached, but it also generates constraints without doing as much instantiation, substitution, and folding. Right now, though, it still piggy backs on the `relate_tys` trait, which is a bit unfortunate -- it means we are doing more hashing and things than we have to. I want to measure the see the perf. Refactoring that trait is something I'd prefer to leave for follow-up work. r? @pnkfelix -- but I want to measure perf etc first
This commit is contained in:
commit
bfbf8375d7
79 changed files with 2049 additions and 771 deletions
|
|
@ -2,28 +2,37 @@ error[E0499]: cannot borrow `*arg` as mutable more than once at a time
|
|||
--> $DIR/mut-borrow-in-loop.rs:20:25
|
||||
|
|
||||
LL | (self.func)(arg) //~ ERROR cannot borrow
|
||||
| ------------^^^-
|
||||
| | |
|
||||
| | mutable borrow starts here in previous iteration of loop
|
||||
| borrow later used here
|
||||
| ^^^ mutable borrow starts here in previous iteration of loop
|
||||
|
|
||||
note: borrowed value must be valid for the lifetime 'a as defined on the impl at 17:6...
|
||||
--> $DIR/mut-borrow-in-loop.rs:17:6
|
||||
|
|
||||
LL | impl<'a, T : 'a> FuncWrapper<'a, T> {
|
||||
| ^^
|
||||
|
||||
error[E0499]: cannot borrow `*arg` as mutable more than once at a time
|
||||
--> $DIR/mut-borrow-in-loop.rs:26:25
|
||||
|
|
||||
LL | (self.func)(arg) //~ ERROR cannot borrow
|
||||
| ------------^^^-
|
||||
| | |
|
||||
| | mutable borrow starts here in previous iteration of loop
|
||||
| borrow later used here
|
||||
| ^^^ mutable borrow starts here in previous iteration of loop
|
||||
|
|
||||
note: borrowed value must be valid for the lifetime 'a as defined on the impl at 17:6...
|
||||
--> $DIR/mut-borrow-in-loop.rs:17:6
|
||||
|
|
||||
LL | impl<'a, T : 'a> FuncWrapper<'a, T> {
|
||||
| ^^
|
||||
|
||||
error[E0499]: cannot borrow `*arg` as mutable more than once at a time
|
||||
--> $DIR/mut-borrow-in-loop.rs:33:25
|
||||
|
|
||||
LL | (self.func)(arg) //~ ERROR cannot borrow
|
||||
| ------------^^^-
|
||||
| | |
|
||||
| | mutable borrow starts here in previous iteration of loop
|
||||
| borrow later used here
|
||||
| ^^^ mutable borrow starts here in previous iteration of loop
|
||||
|
|
||||
note: borrowed value must be valid for the lifetime 'a as defined on the impl at 17:6...
|
||||
--> $DIR/mut-borrow-in-loop.rs:17:6
|
||||
|
|
||||
LL | impl<'a, T : 'a> FuncWrapper<'a, T> {
|
||||
| ^^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -10,19 +10,21 @@ warning: not reporting region error due to nll
|
|||
LL | self.x.iter().map(|a| a.0)
|
||||
| ^^^^
|
||||
|
||||
error: unsatisfied lifetime constraints
|
||||
error: borrowed data escapes outside of closure
|
||||
--> $DIR/static-return-lifetime-infered.rs:17:9
|
||||
|
|
||||
LL | fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
|
||||
| - let's call the lifetime of this reference `'1`
|
||||
| ----- `self` is a reference that is only valid in the closure body
|
||||
LL | self.x.iter().map(|a| a.0)
|
||||
| ^^^^^^ cast requires that `'1` must outlive `'static`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ `self` escapes the closure body here
|
||||
|
||||
error: unsatisfied lifetime constraints
|
||||
error: borrowed data escapes outside of closure
|
||||
--> $DIR/static-return-lifetime-infered.rs:21:9
|
||||
|
|
||||
LL | fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> {
|
||||
| -------- `self` is a reference that is only valid in the closure body
|
||||
LL | self.x.iter().map(|a| a.0)
|
||||
| ^^^^^^ cast requires that `'a` must outlive `'static`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ `self` escapes the closure body here
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -35,20 +35,22 @@ LL | let mut out = Struct { head: x, _tail: [()] };
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0621]: explicit lifetime required in the type of `y`
|
||||
--> $DIR/issue-40288-2.rs:14:9
|
||||
--> $DIR/issue-40288-2.rs:17:9
|
||||
|
|
||||
LL | fn lifetime_transmute_slice<'a, T: ?Sized>(x: &'a T, y: &T) -> &'a T {
|
||||
| - consider changing the type of `y` to `&'a T`
|
||||
LL | let mut out = [x];
|
||||
| ^^^^^^^ lifetime `'a` required
|
||||
...
|
||||
LL | slice[0] = y;
|
||||
| ^^^^^^^^^^^^ lifetime `'a` required
|
||||
|
||||
error[E0621]: explicit lifetime required in the type of `y`
|
||||
--> $DIR/issue-40288-2.rs:29:9
|
||||
--> $DIR/issue-40288-2.rs:32:9
|
||||
|
|
||||
LL | fn lifetime_transmute_struct<'a, T: ?Sized>(x: &'a T, y: &T) -> &'a T {
|
||||
| - consider changing the type of `y` to `&'a T`
|
||||
LL | let mut out = Struct { head: x, _tail: [()] };
|
||||
| ^^^^^^^ lifetime `'a` required
|
||||
...
|
||||
LL | dst.head = y;
|
||||
| ^^^^^^^^^^^^ lifetime `'a` required
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -5,12 +5,12 @@ LL | if x > y { x } else { y } //~ ERROR explicit lifetime
|
|||
| ^
|
||||
|
||||
error[E0621]: explicit lifetime required in parameter type
|
||||
--> $DIR/ex1-return-one-existing-name-if-else-3.rs:11:13
|
||||
--> $DIR/ex1-return-one-existing-name-if-else-3.rs:11:16
|
||||
|
|
||||
LL | fn foo<'a>((x, y): (&'a i32, &i32)) -> &'a i32 {
|
||||
| -^----
|
||||
| ||
|
||||
| |lifetime `'a` required
|
||||
| ----^-
|
||||
| | |
|
||||
| | lifetime `'a` required
|
||||
| consider changing type to `(&'a i32, &'a i32)`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ error[E0621]: explicit lifetime required in the type of `x`
|
|||
LL | fn foo<'a>(x: Ref<i32>, y: &mut Vec<Ref<'a, i32>>) {
|
||||
| - consider changing the type of `x` to `Ref<'a, i32>`
|
||||
LL | y.push(x); //~ ERROR explicit lifetime
|
||||
| ^ lifetime `'a` required
|
||||
| ^^^^^^^^^ lifetime `'a` required
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ error[E0621]: explicit lifetime required in the type of `y`
|
|||
LL | fn foo<'a>(x: &mut Vec<Ref<'a, i32>>, y: Ref<i32>) {
|
||||
| - consider changing the type of `y` to `Ref<'a, i32>`
|
||||
LL | x.push(y); //~ ERROR explicit lifetime
|
||||
| ^ lifetime `'a` required
|
||||
| ^^^^^^^^^ lifetime `'a` required
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ error[E0623]: lifetime mismatch
|
|||
LL | fn foo(x: &mut Vec<Ref<i32>>, y: Ref<i32>) {
|
||||
| -------- -------- these two types are declared with different lifetimes...
|
||||
LL | x.push(y); //~ ERROR lifetime mismatch
|
||||
| ^ ...but data from `y` flows into `x` here
|
||||
| ^^^^^^^^^ ...but data from `y` flows into `x` here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -5,12 +5,13 @@ LL | let z = Ref { data: y.data };
|
|||
| ^^^
|
||||
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/ex2c-push-inference-variable.rs:16:9
|
||||
--> $DIR/ex2c-push-inference-variable.rs:17:5
|
||||
|
|
||||
LL | fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {
|
||||
| ------------ ------------ these two types are declared with different lifetimes...
|
||||
LL | let z = Ref { data: y.data };
|
||||
| ^ ...but data from `y` flows into `x` here
|
||||
LL | x.push(z); //~ ERROR lifetime mismatch
|
||||
| ^^^^^^^^^ ...but data from `y` flows into `x` here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -5,12 +5,13 @@ LL | let b = Ref { data: y.data };
|
|||
| ^^^
|
||||
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/ex2d-push-inference-variable-2.rs:16:9
|
||||
--> $DIR/ex2d-push-inference-variable-2.rs:18:5
|
||||
|
|
||||
LL | fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {
|
||||
| ------------ ------------ these two types are declared with different lifetimes...
|
||||
LL | let a: &mut Vec<Ref<i32>> = x; //~ ERROR lifetime mismatch
|
||||
| ^ ...but data from `y` flows into `x` here
|
||||
...
|
||||
LL | a.push(b);
|
||||
| ^^^^^^^^^ ...but data from `y` flows into `x` here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -5,12 +5,13 @@ LL | let b = Ref { data: y.data };
|
|||
| ^^^
|
||||
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/ex2e-push-inference-variable-3.rs:16:9
|
||||
--> $DIR/ex2e-push-inference-variable-3.rs:18:5
|
||||
|
|
||||
LL | fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {
|
||||
| ------------ ------------ these two types are declared with different lifetimes...
|
||||
LL | let a: &mut Vec<Ref<i32>> = x; //~ ERROR lifetime mismatch
|
||||
| ^ ...but data from `y` flows into `x` here
|
||||
...
|
||||
LL | Vec::push(a, b);
|
||||
| ^^^^^^^^^^^^^^^ ...but data from `y` flows into `x` here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -5,12 +5,12 @@ LL | *v = x; //~ ERROR lifetime mismatch
|
|||
| ^
|
||||
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/ex3-both-anon-regions-2.rs:11:14
|
||||
--> $DIR/ex3-both-anon-regions-2.rs:12:5
|
||||
|
|
||||
LL | fn foo(&mut (ref mut v, w): &mut (&u8, &u8), x: &u8) {
|
||||
| ^^^^^^^^^ --- --- these two types are declared with different lifetimes...
|
||||
| |
|
||||
| ...but data from `x` flows here
|
||||
| --- --- these two types are declared with different lifetimes...
|
||||
LL | *v = x; //~ ERROR lifetime mismatch
|
||||
| ^^^^^^ ...but data from `x` flows here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -11,20 +11,20 @@ LL | z.push((x,y)); //~ ERROR lifetime mismatch
|
|||
| ^
|
||||
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/ex3-both-anon-regions-3.rs:11:33
|
||||
--> $DIR/ex3-both-anon-regions-3.rs:12:5
|
||||
|
|
||||
LL | fn foo(z: &mut Vec<(&u8,&u8)>, (x, y): (&u8, &u8)) {
|
||||
| --- ^ --- these two types are declared with different lifetimes...
|
||||
| |
|
||||
| ...but data flows into `z` here
|
||||
| --- --- these two types are declared with different lifetimes...
|
||||
LL | z.push((x,y)); //~ ERROR lifetime mismatch
|
||||
| ^^^^^^^^^^^^^ ...but data flows into `z` here
|
||||
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/ex3-both-anon-regions-3.rs:11:33
|
||||
--> $DIR/ex3-both-anon-regions-3.rs:12:5
|
||||
|
|
||||
LL | fn foo(z: &mut Vec<(&u8,&u8)>, (x, y): (&u8, &u8)) {
|
||||
| --- ^ --- these two types are declared with different lifetimes...
|
||||
| |
|
||||
| ...but data flows into `z` here
|
||||
| --- --- these two types are declared with different lifetimes...
|
||||
LL | z.push((x,y)); //~ ERROR lifetime mismatch
|
||||
| ^^^^^^^^^^^^^ ...but data flows into `z` here
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ LL | fn foo<'a, 'b>(mut x: Vec<Ref<'a>>, y: Ref<'b>)
|
|||
| ------- ------- these two types are declared with different lifetimes...
|
||||
...
|
||||
LL | x.push(y); //~ ERROR lifetime mismatch
|
||||
| ^ ...but data from `y` flows into `x` here
|
||||
| ^^^^^^^^^ ...but data from `y` flows into `x` here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ error[E0623]: lifetime mismatch
|
|||
LL | fn foo<'a, 'b>(mut x: Vec<Ref<'a>>, y: Ref<'b>) {
|
||||
| ------- ------- these two types are declared with different lifetimes...
|
||||
LL | x.push(y); //~ ERROR lifetime mismatch
|
||||
| ^ ...but data from `y` flows into `x` here
|
||||
| ^^^^^^^^^ ...but data from `y` flows into `x` here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ error[E0623]: lifetime mismatch
|
|||
LL | fn foo(mut x: Vec<Ref>, y: Ref) {
|
||||
| --- --- these two types are declared with different lifetimes...
|
||||
LL | x.push(y); //~ ERROR lifetime mismatch
|
||||
| ^ ...but data from `y` flows into `x` here
|
||||
| ^^^^^^^^^ ...but data from `y` flows into `x` here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ error[E0623]: lifetime mismatch
|
|||
LL | fn foo<'a,'b>(x: &mut Vec<&'a u8>, y: &'b u8) {
|
||||
| ------ ------ these two types are declared with different lifetimes...
|
||||
LL | x.push(y); //~ ERROR lifetime mismatch
|
||||
| ^ ...but data from `y` flows into `x` here
|
||||
| ^^^^^^^^^ ...but data from `y` flows into `x` here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ error[E0623]: lifetime mismatch
|
|||
LL | fn foo(x:fn(&u8, &u8), y: Vec<&u8>, z: &u8) {
|
||||
| --- --- these two types are declared with different lifetimes...
|
||||
LL | y.push(z); //~ ERROR lifetime mismatch
|
||||
| ^ ...but data from `z` flows into `y` here
|
||||
| ^^^^^^^^^ ...but data from `z` flows into `y` here
|
||||
|
||||
error[E0596]: cannot borrow `y` as mutable, as it is not declared as mutable
|
||||
--> $DIR/ex3-both-anon-regions-using-fn-items.rs:11:3
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ error[E0623]: lifetime mismatch
|
|||
LL | fn foo(x: &mut Vec<&u8>, y: &u8) {
|
||||
| --- --- these two types are declared with different lifetimes...
|
||||
LL | x.push(y); //~ ERROR lifetime mismatch
|
||||
| ^ ...but data from `y` flows into `x` here
|
||||
| ^^^^^^^^^ ...but data from `y` flows into `x` here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ error[E0623]: lifetime mismatch
|
|||
LL | fn foo(x:Box<Fn(&u8, &u8)> , y: Vec<&u8>, z: &u8) {
|
||||
| --- --- these two types are declared with different lifetimes...
|
||||
LL | y.push(z); //~ ERROR lifetime mismatch
|
||||
| ^ ...but data from `z` flows into `y` here
|
||||
| ^^^^^^^^^ ...but data from `z` flows into `y` here
|
||||
|
||||
error[E0596]: cannot borrow `y` as mutable, as it is not declared as mutable
|
||||
--> $DIR/ex3-both-anon-regions-using-trait-objects.rs:11:3
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ error[E0623]: lifetime mismatch
|
|||
LL | fn foo(x: &mut Vec<&u8>, y: &u8) {
|
||||
| --- --- these two types are declared with different lifetimes...
|
||||
LL | x.push(y); //~ ERROR lifetime mismatch
|
||||
| ^ ...but data from `y` flows into `x` here
|
||||
| ^^^^^^^^^ ...but data from `y` flows into `x` here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -52,9 +52,9 @@ fn supply<'a, 'b, 'c>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>, cell_c: Cell
|
|||
cell_c,
|
||||
|_outlives1, _outlives2, _outlives3, x, y| {
|
||||
// Only works if 'x: 'y:
|
||||
let p = x.get(); //~ ERROR
|
||||
let p = x.get();
|
||||
//~^ WARN not reporting region error due to nll
|
||||
demand_y(x, y, p)
|
||||
demand_y(x, y, p) //~ ERROR
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,28 +1,28 @@
|
|||
warning: not reporting region error due to nll
|
||||
--> $DIR/propagate-approximated-fail-no-postdom.rs:55:21
|
||||
|
|
||||
LL | let p = x.get(); //~ ERROR
|
||||
LL | let p = x.get();
|
||||
| ^^^^^^^
|
||||
|
||||
error: unsatisfied lifetime constraints
|
||||
--> $DIR/propagate-approximated-fail-no-postdom.rs:55:21
|
||||
--> $DIR/propagate-approximated-fail-no-postdom.rs:57:13
|
||||
|
|
||||
LL | |_outlives1, _outlives2, _outlives3, x, y| {
|
||||
| ---------- ---------- lifetime `'2` appears in this argument
|
||||
| |
|
||||
| lifetime `'1` appears in this argument
|
||||
LL | // Only works if 'x: 'y:
|
||||
LL | let p = x.get(); //~ ERROR
|
||||
| ^^^^^^^ argument requires that `'1` must outlive `'2`
|
||||
...
|
||||
LL | demand_y(x, y, p) //~ ERROR
|
||||
| ^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
|
||||
|
||||
note: No external requirements
|
||||
--> $DIR/propagate-approximated-fail-no-postdom.rs:53:9
|
||||
|
|
||||
LL | / |_outlives1, _outlives2, _outlives3, x, y| {
|
||||
LL | | // Only works if 'x: 'y:
|
||||
LL | | let p = x.get(); //~ ERROR
|
||||
LL | | let p = x.get();
|
||||
LL | | //~^ WARN not reporting region error due to nll
|
||||
LL | | demand_y(x, y, p)
|
||||
LL | | demand_y(x, y, p) //~ ERROR
|
||||
LL | | },
|
||||
| |_________^
|
||||
|
|
||||
|
|
|
|||
|
|
@ -24,14 +24,19 @@ LL | | });
|
|||
= note: where '_#1r: '_#2r
|
||||
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/propagate-approximated-ref.rs:53:29
|
||||
--> $DIR/propagate-approximated-ref.rs:53:5
|
||||
|
|
||||
LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
|
||||
| ------- -------
|
||||
| |
|
||||
| these two types are declared with different lifetimes...
|
||||
LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
|
||||
| ^^^^^^^ ...but data from `cell_a` flows into `cell_b` here
|
||||
LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
|
||||
| ------- -------
|
||||
| |
|
||||
| these two types are declared with different lifetimes...
|
||||
LL | / establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
|
||||
LL | | //~^ ERROR lifetime mismatch
|
||||
LL | |
|
||||
LL | | // Only works if 'x: 'y:
|
||||
LL | | demand_y(x, y, x.get()) //~ WARNING not reporting region error due to nll
|
||||
LL | | });
|
||||
| |______^ ...but data from `cell_a` flows into `cell_b` here
|
||||
|
||||
note: No external requirements
|
||||
--> $DIR/propagate-approximated-ref.rs:52:1
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ LL | foo(cell, |cell_a, cell_x| {
|
|||
| ^^^
|
||||
|
||||
error: borrowed data escapes outside of closure
|
||||
--> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:33:20
|
||||
--> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:33:9
|
||||
|
|
||||
LL | foo(cell, |cell_a, cell_x| {
|
||||
| ------ ------ `cell_x` is a reference that is only valid in the closure body
|
||||
|
|
@ -13,7 +13,7 @@ LL | foo(cell, |cell_a, cell_x| {
|
|||
| `cell_a` is declared here, outside of the closure body
|
||||
LL | //~^ WARNING not reporting region error due to nll
|
||||
LL | cell_a.set(cell_x.get()); // forces 'x: 'a, error in closure
|
||||
| ^^^^^^^^^^^^ `cell_x` escapes the closure body here
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ `cell_x` escapes the closure body here
|
||||
|
||||
note: No external requirements
|
||||
--> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:31:15
|
||||
|
|
|
|||
|
|
@ -24,14 +24,19 @@ LL | | });
|
|||
= note: where '_#1r: '_#2r
|
||||
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/propagate-approximated-val.rs:46:29
|
||||
--> $DIR/propagate-approximated-val.rs:46:5
|
||||
|
|
||||
LL | fn test<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
|
||||
| ------- -------
|
||||
| |
|
||||
| these two types are declared with different lifetimes...
|
||||
LL | establish_relationships(cell_a, cell_b, |outlives1, outlives2, x, y| {
|
||||
| ^^^^^^ ...but data from `cell_a` flows into `cell_b` here
|
||||
LL | fn test<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
|
||||
| ------- -------
|
||||
| |
|
||||
| these two types are declared with different lifetimes...
|
||||
LL | / establish_relationships(cell_a, cell_b, |outlives1, outlives2, x, y| {
|
||||
LL | | //~^ ERROR lifetime mismatch
|
||||
LL | |
|
||||
LL | | // Only works if 'x: 'y:
|
||||
LL | | demand_y(outlives1, outlives2, x.get()) //~ WARNING not reporting region error due to nll
|
||||
LL | | });
|
||||
| |______^ ...but data from `cell_a` flows into `cell_b` here
|
||||
|
||||
note: No external requirements
|
||||
--> $DIR/propagate-approximated-val.rs:45:1
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ LL | demand_y(x, y, x.get())
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: unsatisfied lifetime constraints
|
||||
--> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:47:24
|
||||
--> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:47:9
|
||||
|
|
||||
LL | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
|
||||
| --------- - lifetime `'1` appears in this argument
|
||||
|
|
@ -13,7 +13,7 @@ LL | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
|
|||
| lifetime `'2` appears in this argument
|
||||
LL | // Only works if 'x: 'y:
|
||||
LL | demand_y(x, y, x.get())
|
||||
| ^^^^^^^ argument requires that `'1` must outlive `'2`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
|
||||
|
||||
note: No external requirements
|
||||
--> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:45:47
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ LL | demand_y(x, y, x.get())
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: unsatisfied lifetime constraints
|
||||
--> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:51:24
|
||||
--> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:51:9
|
||||
|
|
||||
LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
|
||||
| ---------- ---------- lifetime `'2` appears in this argument
|
||||
|
|
@ -13,7 +13,7 @@ LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y
|
|||
| lifetime `'1` appears in this argument
|
||||
LL | // Only works if 'x: 'y:
|
||||
LL | demand_y(x, y, x.get())
|
||||
| ^^^^^^^ argument requires that `'1` must outlive `'2`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
|
||||
|
||||
note: No external requirements
|
||||
--> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:49:47
|
||||
|
|
|
|||
22
src/test/ui/nll/mir_check_cast_closure.rs
Normal file
22
src/test/ui/nll/mir_check_cast_closure.rs
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// compile-flags: -Z borrowck=mir
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
fn bar<'a, 'b>() -> fn(&'a u32, &'b u32) -> &'a u32 {
|
||||
let g: fn(_, _) -> _ = |_x, y| y;
|
||||
//~^ ERROR unsatisfied lifetime constraints
|
||||
g
|
||||
//~^ WARNING not reporting region error due to nll
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
14
src/test/ui/nll/mir_check_cast_closure.stderr
Normal file
14
src/test/ui/nll/mir_check_cast_closure.stderr
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
warning: not reporting region error due to nll
|
||||
--> $DIR/mir_check_cast_closure.rs:18:5
|
||||
|
|
||||
LL | g
|
||||
| ^
|
||||
|
||||
error: unsatisfied lifetime constraints
|
||||
--> $DIR/mir_check_cast_closure.rs:16:28
|
||||
|
|
||||
LL | let g: fn(_, _) -> _ = |_x, y| y;
|
||||
| ^^^^^^^^^ cast requires that `'b` must outlive `'a`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
52
src/test/ui/nll/mir_check_cast_reify.rs
Normal file
52
src/test/ui/nll/mir_check_cast_reify.rs
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// compile-flags: -Zborrowck=mir
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
// Test that we relate the type of the fn type to the type of the fn
|
||||
// ptr when doing a `ReifyFnPointer` cast.
|
||||
//
|
||||
// This test is a bit tortured, let me explain:
|
||||
//
|
||||
|
||||
// The `where 'a: 'a` clause here ensures that `'a` is early bound,
|
||||
// which is needed below to ensure that this test hits the path we are
|
||||
// concerned with.
|
||||
fn foo<'a>(x: &'a u32) -> &'a u32
|
||||
where
|
||||
'a: 'a,
|
||||
{
|
||||
panic!()
|
||||
}
|
||||
|
||||
fn bar<'a>(x: &'a u32) -> &'static u32 {
|
||||
// Here, the type of `foo` is `typeof(foo::<'x>)` for some fresh variable `'x`.
|
||||
// During NLL region analysis, this will get renumbered to `typeof(foo::<'?0>)`
|
||||
// where `'?0` is a new region variable.
|
||||
//
|
||||
// (Note that if `'a` on `foo` were late-bound, the type would be
|
||||
// `typeof(foo)`, which would interact differently with because
|
||||
// the renumbering later.)
|
||||
//
|
||||
// This type is then coerced to a fn type `fn(&'?1 u32) -> &'?2
|
||||
// u32`. Here, the `'?1` and `'?2` will have been created during
|
||||
// the NLL region renumbering.
|
||||
//
|
||||
// The MIR type checker must therefore relate `'?0` to `'?1` and `'?2`
|
||||
// as part of checking the `ReifyFnPointer`.
|
||||
let f: fn(_) -> _ = foo;
|
||||
//~^ WARNING not reporting region error due to nll
|
||||
f(x)
|
||||
//~^ ERROR
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
17
src/test/ui/nll/mir_check_cast_reify.stderr
Normal file
17
src/test/ui/nll/mir_check_cast_reify.stderr
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
warning: not reporting region error due to nll
|
||||
--> $DIR/mir_check_cast_reify.rs:46:25
|
||||
|
|
||||
LL | let f: fn(_) -> _ = foo;
|
||||
| ^^^
|
||||
|
||||
error: borrowed data escapes outside of closure
|
||||
--> $DIR/mir_check_cast_reify.rs:48:5
|
||||
|
|
||||
LL | fn bar<'a>(x: &'a u32) -> &'static u32 {
|
||||
| - `x` is a reference that is only valid in the closure body
|
||||
...
|
||||
LL | f(x)
|
||||
| ^^^^ `x` escapes the closure body here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
24
src/test/ui/nll/mir_check_cast_unsafe_fn.rs
Normal file
24
src/test/ui/nll/mir_check_cast_unsafe_fn.rs
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// compile-flags: -Zborrowck=mir
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
fn bar<'a>(input: &'a u32, f: fn(&'a u32) -> &'a u32) -> &'static u32 {
|
||||
// Here the NLL checker must relate the types in `f` to the types
|
||||
// in `g`. These are related via the `UnsafeFnPointer` cast.
|
||||
let g: unsafe fn(_) -> _ = f;
|
||||
//~^ WARNING not reporting region error due to nll
|
||||
unsafe { g(input) }
|
||||
//~^ ERROR
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
17
src/test/ui/nll/mir_check_cast_unsafe_fn.stderr
Normal file
17
src/test/ui/nll/mir_check_cast_unsafe_fn.stderr
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
warning: not reporting region error due to nll
|
||||
--> $DIR/mir_check_cast_unsafe_fn.rs:18:32
|
||||
|
|
||||
LL | let g: unsafe fn(_) -> _ = f;
|
||||
| ^
|
||||
|
||||
error: borrowed data escapes outside of closure
|
||||
--> $DIR/mir_check_cast_unsafe_fn.rs:20:14
|
||||
|
|
||||
LL | fn bar<'a>(input: &'a u32, f: fn(&'a u32) -> &'a u32) -> &'static u32 {
|
||||
| ----- `input` is a reference that is only valid in the closure body
|
||||
...
|
||||
LL | unsafe { g(input) }
|
||||
| ^^^^^^^^ `input` escapes the closure body here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
23
src/test/ui/nll/mir_check_cast_unsize.rs
Normal file
23
src/test/ui/nll/mir_check_cast_unsize.rs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// compile-flags: -Z borrowck=mir
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
use std::fmt::Debug;
|
||||
|
||||
fn bar<'a>(x: &'a u32) -> &'static dyn Debug {
|
||||
//~^ ERROR unsatisfied lifetime constraints
|
||||
x
|
||||
//~^ WARNING not reporting region error due to nll
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
19
src/test/ui/nll/mir_check_cast_unsize.stderr
Normal file
19
src/test/ui/nll/mir_check_cast_unsize.stderr
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
warning: not reporting region error due to nll
|
||||
--> $DIR/mir_check_cast_unsize.rs:19:5
|
||||
|
|
||||
LL | x
|
||||
| ^
|
||||
|
||||
error: unsatisfied lifetime constraints
|
||||
--> $DIR/mir_check_cast_unsize.rs:17:46
|
||||
|
|
||||
LL | fn bar<'a>(x: &'a u32) -> &'static dyn Debug {
|
||||
| ______________________________________________^
|
||||
LL | | //~^ ERROR unsatisfied lifetime constraints
|
||||
LL | | x
|
||||
LL | | //~^ WARNING not reporting region error due to nll
|
||||
LL | | }
|
||||
| |_^ return requires that `'a` must outlive `'static`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
27
src/test/ui/nll/relate_tys/hr-fn-aaa-as-aba.rs
Normal file
27
src/test/ui/nll/relate_tys/hr-fn-aaa-as-aba.rs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Test that the NLL `relate_tys` code correctly deduces that a
|
||||
// function returning either argument CANNOT be upcast to one
|
||||
// that returns always its first argument.
|
||||
//
|
||||
// compile-flags:-Zno-leak-check
|
||||
|
||||
#![feature(nll)]
|
||||
|
||||
fn make_it() -> for<'a> fn(&'a u32, &'a u32) -> &'a u32 {
|
||||
panic!()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let a: for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32 = make_it();
|
||||
//~^ ERROR higher-ranked subtype error
|
||||
drop(a);
|
||||
}
|
||||
8
src/test/ui/nll/relate_tys/hr-fn-aaa-as-aba.stderr
Normal file
8
src/test/ui/nll/relate_tys/hr-fn-aaa-as-aba.stderr
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
error: higher-ranked subtype error
|
||||
--> $DIR/hr-fn-aaa-as-aba.rs:24:58
|
||||
|
|
||||
LL | let a: for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32 = make_it();
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
38
src/test/ui/nll/relate_tys/hr-fn-aau-eq-abu.rs
Normal file
38
src/test/ui/nll/relate_tys/hr-fn-aau-eq-abu.rs
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Test an interesting corner case that ought to be legal (though the
|
||||
// current code actually gets it wrong, see below): a fn that takes
|
||||
// two arguments that are references with the same lifetime is in fact
|
||||
// equivalent to a fn that takes two references with distinct
|
||||
// lifetimes. This is true because the two functions can call one
|
||||
// another -- effectively, the single lifetime `'a` is just inferred
|
||||
// to be the intersection of the two distinct lifetimes.
|
||||
//
|
||||
// FIXME: However, we currently reject this example with an error,
|
||||
// because of how we handle binders and equality in `relate_tys`.
|
||||
//
|
||||
// compile-flags:-Zno-leak-check
|
||||
|
||||
#![feature(nll)]
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
fn make_cell_aa() -> Cell<for<'a> fn(&'a u32, &'a u32)> {
|
||||
panic!()
|
||||
}
|
||||
|
||||
fn aa_eq_ab() {
|
||||
let a: Cell<for<'a, 'b> fn(&'a u32, &'b u32)> = make_cell_aa();
|
||||
//~^ ERROR higher-ranked subtype error
|
||||
drop(a);
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
8
src/test/ui/nll/relate_tys/hr-fn-aau-eq-abu.stderr
Normal file
8
src/test/ui/nll/relate_tys/hr-fn-aau-eq-abu.stderr
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
error: higher-ranked subtype error
|
||||
--> $DIR/hr-fn-aau-eq-abu.rs:33:53
|
||||
|
|
||||
LL | let a: Cell<for<'a, 'b> fn(&'a u32, &'b u32)> = make_cell_aa();
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
27
src/test/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs
Normal file
27
src/test/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Test that the NLL `relate_tys` code correctly deduces that a
|
||||
// function returning always its first argument can be upcast to one
|
||||
// that returns either first or second argument.
|
||||
//
|
||||
// compile-pass
|
||||
// compile-flags:-Zno-leak-check
|
||||
|
||||
#![feature(nll)]
|
||||
|
||||
fn make_it() -> for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32 {
|
||||
panic!()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let a: for<'a> fn(&'a u32, &'a u32) -> &'a u32 = make_it();
|
||||
drop(a);
|
||||
}
|
||||
38
src/test/ui/nll/relate_tys/issue-48071.rs
Normal file
38
src/test/ui/nll/relate_tys/issue-48071.rs
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Regression test for #48071. This test used to ICE because -- in
|
||||
// the leak-check -- it would pass since we knew that the return type
|
||||
// was `'static`, and hence `'static: 'a` was legal even for a
|
||||
// placeholder region, but in NLL land it would fail because we had
|
||||
// rewritten `'static` to a region variable.
|
||||
//
|
||||
// compile-pass
|
||||
|
||||
#![allow(warnings)]
|
||||
#![feature(dyn_trait)]
|
||||
#![feature(nll)]
|
||||
|
||||
trait Foo {
|
||||
fn foo(&self) { }
|
||||
}
|
||||
|
||||
impl Foo for () {
|
||||
}
|
||||
|
||||
type MakeFooFn = for<'a> fn(&'a u8) -> Box<dyn Foo + 'a>;
|
||||
|
||||
fn make_foo(x: &u8) -> Box<dyn Foo + 'static> {
|
||||
Box::new(())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x: MakeFooFn = make_foo as MakeFooFn;
|
||||
}
|
||||
|
|
@ -23,13 +23,16 @@ LL | Box::new(items.iter()) //~ ERROR cannot infer an appropriate lifetime
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: unsatisfied lifetime constraints
|
||||
--> $DIR/dyn-trait-underscore.rs:18:5
|
||||
--> $DIR/dyn-trait-underscore.rs:16:52
|
||||
|
|
||||
LL | fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T>> {
|
||||
| - let's call the lifetime of this reference `'1`
|
||||
LL | // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static`
|
||||
LL | Box::new(items.iter()) //~ ERROR cannot infer an appropriate lifetime
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ cast requires that `'1` must outlive `'static`
|
||||
LL | fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T>> {
|
||||
| ________________-___________________________________^
|
||||
| | |
|
||||
| | let's call the lifetime of this reference `'1`
|
||||
LL | | // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static`
|
||||
LL | | Box::new(items.iter()) //~ ERROR cannot infer an appropriate lifetime
|
||||
LL | | }
|
||||
| |_^ return requires that `'1` must outlive `'static`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue