rewrite leak check to be based on universes
In the new leak check, instead of getting a list of placeholders to track, we look for any placeholder that is part of a universe which was created during the snapshot. We are looking for the following error patterns: * P1: P2, where P1 != P2 * P1: R, where R is in some universe that cannot name P1 This new leak check is more precise than before, in that it accepts this patterns: * R: P1, even if R cannot name P1, because R = 'static is a valid sol'n * R: P1, R: P2, as above Note that this leak check, when running during subtyping, is less efficient than before in some sense because it is going to check and re-check all the universes created since the snapshot. We're going to move when the leak check runs to try and correct that.
This commit is contained in:
parent
4199b3ae26
commit
f2cf994483
29 changed files with 572 additions and 320 deletions
|
|
@ -49,7 +49,7 @@ LL | where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'x isize>
|
|||
| ------------- required by this bound in `tuple_one`
|
||||
...
|
||||
LL | tuple_one::<Tuple>();
|
||||
| ^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'x, found concrete lifetime
|
||||
| ^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'y, found concrete lifetime
|
||||
|
||||
error[E0277]: the trait bound `for<'x, 'y> Tuple: TheTrait<(&'x isize, &'y isize)>` is not satisfied
|
||||
--> $DIR/associated-types-eq-hr.rs:97:17
|
||||
|
|
@ -74,7 +74,7 @@ LL | where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'y isize>
|
|||
| ------------- required by this bound in `tuple_two`
|
||||
...
|
||||
LL | tuple_two::<Tuple>();
|
||||
| ^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'x, found concrete lifetime
|
||||
| ^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'y, found concrete lifetime
|
||||
|
||||
error[E0277]: the trait bound `for<'x, 'y> Tuple: TheTrait<(&'x isize, &'y isize)>` is not satisfied
|
||||
--> $DIR/associated-types-eq-hr.rs:107:18
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/hr-subtype.rs:39:26
|
||||
--> $DIR/hr-subtype.rs:45:26
|
||||
|
|
||||
LL | gimme::<$t1>(None::<$t2>);
|
||||
| ^^^^^^^^^^^ expected concrete lifetime, found bound lifetime parameter 'a
|
||||
...
|
||||
LL | / check! { bound_a_b_ret_a_vs_bound_a_ret_a: (for<'a,'b> fn(&'a u32, &'b u32) -> &'a u32,
|
||||
LL | | for<'a> fn(&'a u32, &'a u32) -> &'a u32) }
|
||||
| |_________________________________________________________________________________________- in this macro invocation
|
||||
LL | | for<'a> fn(&'a u32, &'a u32) -> &'a u32) }
|
||||
| |_____________________________________________- in this macro invocation
|
||||
|
|
||||
= note: expected enum `std::option::Option<for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32>`
|
||||
found enum `std::option::Option<for<'a> fn(&'a u32, &'a u32) -> &'a u32>`
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/hr-subtype.rs:39:26
|
||||
--> $DIR/hr-subtype.rs:45:26
|
||||
|
|
||||
LL | gimme::<$t1>(None::<$t2>);
|
||||
| ^^^^^^^^^^^ expected concrete lifetime, found bound lifetime parameter 'a
|
||||
...
|
||||
LL | / check! { bound_a_b_vs_bound_a: (for<'a,'b> fn(&'a u32, &'b u32),
|
||||
LL | | for<'a> fn(&'a u32, &'a u32)) }
|
||||
| |__________________________________________________________________- in this macro invocation
|
||||
LL | | for<'a> fn(&'a u32, &'a u32)) }
|
||||
| |__________________________________- in this macro invocation
|
||||
|
|
||||
= note: expected enum `std::option::Option<for<'a, 'b> fn(&'a u32, &'b u32)>`
|
||||
found enum `std::option::Option<for<'a> fn(&'a u32, &'a u32)>`
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
error: fatal error triggered by #[rustc_error]
|
||||
--> $DIR/hr-subtype.rs:100:1
|
||||
--> $DIR/hr-subtype.rs:104:1
|
||||
|
|
||||
LL | / fn main() {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
... |
|
||||
LL | |
|
||||
LL | | }
|
||||
| |_^
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
error: fatal error triggered by #[rustc_error]
|
||||
--> $DIR/hr-subtype.rs:100:1
|
||||
--> $DIR/hr-subtype.rs:104:1
|
||||
|
|
||||
LL | / fn main() {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
... |
|
||||
LL | |
|
||||
LL | | }
|
||||
| |_^
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/hr-subtype.rs:39:26
|
||||
--> $DIR/hr-subtype.rs:45:26
|
||||
|
|
||||
LL | gimme::<$t1>(None::<$t2>);
|
||||
| ^^^^^^^^^^^ expected concrete lifetime, found bound lifetime parameter 'a
|
||||
...
|
||||
LL | / check! { bound_a_vs_free_x: (for<'a> fn(&'a u32),
|
||||
LL | | fn(&'x u32)) }
|
||||
| |___________________________________________- in this macro invocation
|
||||
LL | | fn(&'x u32)) }
|
||||
| |______________- in this macro invocation
|
||||
|
|
||||
= note: expected enum `std::option::Option<for<'a> fn(&'a u32)>`
|
||||
found enum `std::option::Option<fn(&'x u32)>`
|
||||
|
|
|
|||
|
|
@ -1,17 +1,14 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/hr-subtype.rs:39:26
|
||||
error: fatal error triggered by #[rustc_error]
|
||||
--> $DIR/hr-subtype.rs:104:1
|
||||
|
|
||||
LL | gimme::<$t1>(None::<$t2>);
|
||||
| ^^^^^^^^^^^ expected concrete lifetime, found bound lifetime parameter 'a
|
||||
...
|
||||
LL | / check! { bound_co_a_b_vs_bound_co_a: (for<'a,'b> fn(Co<'a>, Co<'b>),
|
||||
LL | | for<'a> fn(Co<'a>, Co<'a>)) }
|
||||
| |______________________________________________________________________- in this macro invocation
|
||||
|
|
||||
= note: expected enum `std::option::Option<for<'a, 'b> fn(Co<'a>, Co<'b>)>`
|
||||
found enum `std::option::Option<for<'a> fn(Co<'a>, Co<'a>)>`
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
LL | / fn main() {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
... |
|
||||
LL | |
|
||||
LL | | }
|
||||
| |_^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
|
|
|
|||
|
|
@ -1,17 +1,14 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/hr-subtype.rs:39:26
|
||||
error: fatal error triggered by #[rustc_error]
|
||||
--> $DIR/hr-subtype.rs:104:1
|
||||
|
|
||||
LL | gimme::<$t1>(None::<$t2>);
|
||||
| ^^^^^^^^^^^ expected concrete lifetime, found bound lifetime parameter 'a
|
||||
...
|
||||
LL | / check! { bound_co_a_co_b_ret_contra_a: (for<'a,'b> fn(Co<'a>, Co<'b>) -> Contra<'a>,
|
||||
LL | | for<'a> fn(Co<'a>, Co<'a>) -> Contra<'a>) }
|
||||
| |______________________________________________________________________________________- in this macro invocation
|
||||
|
|
||||
= note: expected enum `std::option::Option<for<'a, 'b> fn(Co<'a>, Co<'b>) -> Contra<'a>>`
|
||||
found enum `std::option::Option<for<'a> fn(Co<'a>, Co<'a>) -> Contra<'a>>`
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
LL | / fn main() {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
... |
|
||||
LL | |
|
||||
LL | | }
|
||||
| |_^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
error: fatal error triggered by #[rustc_error]
|
||||
--> $DIR/hr-subtype.rs:100:1
|
||||
--> $DIR/hr-subtype.rs:104:1
|
||||
|
|
||||
LL | / fn main() {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
... |
|
||||
LL | |
|
||||
LL | | }
|
||||
| |_^
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/hr-subtype.rs:39:26
|
||||
--> $DIR/hr-subtype.rs:45:26
|
||||
|
|
||||
LL | gimme::<$t1>(None::<$t2>);
|
||||
| ^^^^^^^^^^^ expected concrete lifetime, found bound lifetime parameter 'a
|
||||
...
|
||||
LL | / check! { bound_contra_a_contra_b_ret_co_a: (for<'a,'b> fn(Contra<'a>, Contra<'b>) -> Co<'a>,
|
||||
LL | | for<'a> fn(Contra<'a>, Contra<'a>) -> Co<'a>) }
|
||||
| |______________________________________________________________________________________________- in this macro invocation
|
||||
LL | | for<'a> fn(Contra<'a>, Contra<'a>) -> Co<'a>) }
|
||||
| |__________________________________________________- in this macro invocation
|
||||
|
|
||||
= note: expected enum `std::option::Option<for<'a, 'b> fn(Contra<'a>, Contra<'b>) -> Co<'a>>`
|
||||
found enum `std::option::Option<for<'a> fn(Contra<'a>, Contra<'a>) -> Co<'a>>`
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/hr-subtype.rs:39:26
|
||||
--> $DIR/hr-subtype.rs:45:26
|
||||
|
|
||||
LL | gimme::<$t1>(None::<$t2>);
|
||||
| ^^^^^^^^^^^ expected concrete lifetime, found bound lifetime parameter 'a
|
||||
...
|
||||
LL | / check! { bound_inv_a_b_vs_bound_inv_a: (for<'a,'b> fn(Inv<'a>, Inv<'b>),
|
||||
LL | | for<'a> fn(Inv<'a>, Inv<'a>)) }
|
||||
| |__________________________________________________________________________- in this macro invocation
|
||||
LL | | for<'a> fn(Inv<'a>, Inv<'a>)) }
|
||||
| |__________________________________- in this macro invocation
|
||||
|
|
||||
= note: expected enum `std::option::Option<for<'a, 'b> fn(Inv<'a>, Inv<'b>)>`
|
||||
found enum `std::option::Option<for<'a> fn(Inv<'a>, Inv<'a>)>`
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
error: fatal error triggered by #[rustc_error]
|
||||
--> $DIR/hr-subtype.rs:100:1
|
||||
--> $DIR/hr-subtype.rs:104:1
|
||||
|
|
||||
LL | / fn main() {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
... |
|
||||
LL | |
|
||||
LL | | }
|
||||
| |_^
|
||||
|
|
|
|||
|
|
@ -1,65 +1,65 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/hr-subtype.rs:33:26
|
||||
--> $DIR/hr-subtype.rs:39:26
|
||||
|
|
||||
LL | gimme::<$t2>(None::<$t1>);
|
||||
| ^^^^^^^^^^^ lifetime mismatch
|
||||
...
|
||||
LL | / check! { free_inv_x_vs_free_inv_y: (fn(Inv<'x>),
|
||||
LL | | fn(Inv<'y>)) }
|
||||
| |__________________________________________________- in this macro invocation
|
||||
LL | | fn(Inv<'y>)) }
|
||||
| |______________- in this macro invocation
|
||||
|
|
||||
= note: expected enum `std::option::Option<fn(Inv<'y>)>`
|
||||
found enum `std::option::Option<fn(Inv<'x>)>`
|
||||
note: the lifetime `'x` as defined on the function body at 32:20...
|
||||
--> $DIR/hr-subtype.rs:32:20
|
||||
note: the lifetime `'x` as defined on the function body at 38:20...
|
||||
--> $DIR/hr-subtype.rs:38:20
|
||||
|
|
||||
LL | fn subtype<'x,'y:'x,'z:'y>() {
|
||||
LL | fn subtype<'x, 'y: 'x, 'z: 'y>() {
|
||||
| ^^
|
||||
...
|
||||
LL | / check! { free_inv_x_vs_free_inv_y: (fn(Inv<'x>),
|
||||
LL | | fn(Inv<'y>)) }
|
||||
| |__________________________________________________- in this macro invocation
|
||||
note: ...does not necessarily outlive the lifetime `'y` as defined on the function body at 32:23
|
||||
--> $DIR/hr-subtype.rs:32:23
|
||||
LL | | fn(Inv<'y>)) }
|
||||
| |______________- in this macro invocation
|
||||
note: ...does not necessarily outlive the lifetime `'y` as defined on the function body at 38:24
|
||||
--> $DIR/hr-subtype.rs:38:24
|
||||
|
|
||||
LL | fn subtype<'x,'y:'x,'z:'y>() {
|
||||
| ^^
|
||||
LL | fn subtype<'x, 'y: 'x, 'z: 'y>() {
|
||||
| ^^
|
||||
...
|
||||
LL | / check! { free_inv_x_vs_free_inv_y: (fn(Inv<'x>),
|
||||
LL | | fn(Inv<'y>)) }
|
||||
| |__________________________________________________- in this macro invocation
|
||||
LL | | fn(Inv<'y>)) }
|
||||
| |______________- in this macro invocation
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/hr-subtype.rs:39:26
|
||||
--> $DIR/hr-subtype.rs:45:26
|
||||
|
|
||||
LL | gimme::<$t1>(None::<$t2>);
|
||||
| ^^^^^^^^^^^ lifetime mismatch
|
||||
...
|
||||
LL | / check! { free_inv_x_vs_free_inv_y: (fn(Inv<'x>),
|
||||
LL | | fn(Inv<'y>)) }
|
||||
| |__________________________________________________- in this macro invocation
|
||||
LL | | fn(Inv<'y>)) }
|
||||
| |______________- in this macro invocation
|
||||
|
|
||||
= note: expected enum `std::option::Option<fn(Inv<'x>)>`
|
||||
found enum `std::option::Option<fn(Inv<'y>)>`
|
||||
note: the lifetime `'x` as defined on the function body at 38:22...
|
||||
--> $DIR/hr-subtype.rs:38:22
|
||||
note: the lifetime `'x` as defined on the function body at 44:22...
|
||||
--> $DIR/hr-subtype.rs:44:22
|
||||
|
|
||||
LL | fn supertype<'x,'y:'x,'z:'y>() {
|
||||
LL | fn supertype<'x, 'y: 'x, 'z: 'y>() {
|
||||
| ^^
|
||||
...
|
||||
LL | / check! { free_inv_x_vs_free_inv_y: (fn(Inv<'x>),
|
||||
LL | | fn(Inv<'y>)) }
|
||||
| |__________________________________________________- in this macro invocation
|
||||
note: ...does not necessarily outlive the lifetime `'y` as defined on the function body at 38:25
|
||||
--> $DIR/hr-subtype.rs:38:25
|
||||
LL | | fn(Inv<'y>)) }
|
||||
| |______________- in this macro invocation
|
||||
note: ...does not necessarily outlive the lifetime `'y` as defined on the function body at 44:26
|
||||
--> $DIR/hr-subtype.rs:44:26
|
||||
|
|
||||
LL | fn supertype<'x,'y:'x,'z:'y>() {
|
||||
| ^^
|
||||
LL | fn supertype<'x, 'y: 'x, 'z: 'y>() {
|
||||
| ^^
|
||||
...
|
||||
LL | / check! { free_inv_x_vs_free_inv_y: (fn(Inv<'x>),
|
||||
LL | | fn(Inv<'y>)) }
|
||||
| |__________________________________________________- in this macro invocation
|
||||
LL | | fn(Inv<'y>)) }
|
||||
| |______________- in this macro invocation
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
error: fatal error triggered by #[rustc_error]
|
||||
--> $DIR/hr-subtype.rs:100:1
|
||||
--> $DIR/hr-subtype.rs:104:1
|
||||
|
|
||||
LL | / fn main() {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
... |
|
||||
LL | |
|
||||
LL | | }
|
||||
| |_^
|
||||
|
|
|
|||
|
|
@ -1,33 +1,33 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/hr-subtype.rs:39:26
|
||||
--> $DIR/hr-subtype.rs:45:26
|
||||
|
|
||||
LL | gimme::<$t1>(None::<$t2>);
|
||||
| ^^^^^^^^^^^ lifetime mismatch
|
||||
...
|
||||
LL | / check! { free_x_vs_free_y: (fn(&'x u32),
|
||||
LL | | fn(&'y u32)) }
|
||||
| |__________________________________________- in this macro invocation
|
||||
LL | | fn(&'y u32)) }
|
||||
| |______________- in this macro invocation
|
||||
|
|
||||
= note: expected enum `std::option::Option<fn(&'x u32)>`
|
||||
found enum `std::option::Option<fn(&'y u32)>`
|
||||
note: the lifetime `'x` as defined on the function body at 38:22...
|
||||
--> $DIR/hr-subtype.rs:38:22
|
||||
note: the lifetime `'x` as defined on the function body at 44:22...
|
||||
--> $DIR/hr-subtype.rs:44:22
|
||||
|
|
||||
LL | fn supertype<'x,'y:'x,'z:'y>() {
|
||||
LL | fn supertype<'x, 'y: 'x, 'z: 'y>() {
|
||||
| ^^
|
||||
...
|
||||
LL | / check! { free_x_vs_free_y: (fn(&'x u32),
|
||||
LL | | fn(&'y u32)) }
|
||||
| |__________________________________________- in this macro invocation
|
||||
note: ...does not necessarily outlive the lifetime `'y` as defined on the function body at 38:25
|
||||
--> $DIR/hr-subtype.rs:38:25
|
||||
LL | | fn(&'y u32)) }
|
||||
| |______________- in this macro invocation
|
||||
note: ...does not necessarily outlive the lifetime `'y` as defined on the function body at 44:26
|
||||
--> $DIR/hr-subtype.rs:44:26
|
||||
|
|
||||
LL | fn supertype<'x,'y:'x,'z:'y>() {
|
||||
| ^^
|
||||
LL | fn supertype<'x, 'y: 'x, 'z: 'y>() {
|
||||
| ^^
|
||||
...
|
||||
LL | / check! { free_x_vs_free_y: (fn(&'x u32),
|
||||
LL | | fn(&'y u32)) }
|
||||
| |__________________________________________- in this macro invocation
|
||||
LL | | fn(&'y u32)) }
|
||||
| |______________- in this macro invocation
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
|
|
|||
|
|
@ -18,24 +18,30 @@
|
|||
// revisions: bound_inv_a_b_vs_bound_inv_a
|
||||
// revisions: bound_a_b_ret_a_vs_bound_a_ret_a
|
||||
|
||||
fn gimme<T>(_: Option<T>) { }
|
||||
fn gimme<T>(_: Option<T>) {}
|
||||
|
||||
struct Inv<'a> { x: *mut &'a u32 }
|
||||
struct Inv<'a> {
|
||||
x: *mut &'a u32,
|
||||
}
|
||||
|
||||
struct Co<'a> { x: fn(&'a u32) }
|
||||
struct Co<'a> {
|
||||
x: fn(&'a u32),
|
||||
}
|
||||
|
||||
struct Contra<'a> { x: &'a u32 }
|
||||
struct Contra<'a> {
|
||||
x: &'a u32,
|
||||
}
|
||||
|
||||
macro_rules! check {
|
||||
($rev:ident: ($t1:ty, $t2:ty)) => {
|
||||
#[cfg($rev)]
|
||||
fn subtype<'x,'y:'x,'z:'y>() {
|
||||
fn subtype<'x, 'y: 'x, 'z: 'y>() {
|
||||
gimme::<$t2>(None::<$t1>);
|
||||
//[free_inv_x_vs_free_inv_y]~^ ERROR
|
||||
}
|
||||
|
||||
#[cfg($rev)]
|
||||
fn supertype<'x,'y:'x,'z:'y>() {
|
||||
fn supertype<'x, 'y: 'x, 'z: 'y>() {
|
||||
gimme::<$t1>(None::<$t2>);
|
||||
//[bound_a_vs_free_x]~^ ERROR
|
||||
//[free_x_vs_free_y]~^^ ERROR
|
||||
|
|
@ -43,35 +49,33 @@ macro_rules! check {
|
|||
//[bound_a_b_ret_a_vs_bound_a_ret_a]~^^^^ ERROR
|
||||
//[free_inv_x_vs_free_inv_y]~^^^^^ ERROR
|
||||
//[bound_a_b_vs_bound_a]~^^^^^^ ERROR mismatched types
|
||||
//[bound_co_a_co_b_ret_contra_a]~^^^^^^^ ERROR
|
||||
//[bound_contra_a_contra_b_ret_co_a]~^^^^^^^^ ERROR
|
||||
//[bound_co_a_b_vs_bound_co_a]~^^^^^^^^^ ERROR
|
||||
//[bound_contra_a_contra_b_ret_co_a]~^^^^^^^ ERROR
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// If both have bound regions, they are equivalent, regardless of
|
||||
// variant.
|
||||
check! { bound_a_vs_bound_a: (for<'a> fn(&'a u32),
|
||||
for<'a> fn(&'a u32)) }
|
||||
for<'a> fn(&'a u32)) }
|
||||
check! { bound_a_vs_bound_b: (for<'a> fn(&'a u32),
|
||||
for<'b> fn(&'b u32)) }
|
||||
for<'b> fn(&'b u32)) }
|
||||
check! { bound_inv_a_vs_bound_inv_b: (for<'a> fn(Inv<'a>),
|
||||
for<'b> fn(Inv<'b>)) }
|
||||
for<'b> fn(Inv<'b>)) }
|
||||
check! { bound_co_a_vs_bound_co_b: (for<'a> fn(Co<'a>),
|
||||
for<'b> fn(Co<'b>)) }
|
||||
for<'b> fn(Co<'b>)) }
|
||||
|
||||
// Bound is a subtype of free.
|
||||
check! { bound_a_vs_free_x: (for<'a> fn(&'a u32),
|
||||
fn(&'x u32)) }
|
||||
fn(&'x u32)) }
|
||||
|
||||
// Two free regions are relatable if subtyping holds.
|
||||
check! { free_x_vs_free_x: (fn(&'x u32),
|
||||
fn(&'x u32)) }
|
||||
fn(&'x u32)) }
|
||||
check! { free_x_vs_free_y: (fn(&'x u32),
|
||||
fn(&'y u32)) }
|
||||
fn(&'y u32)) }
|
||||
check! { free_inv_x_vs_free_inv_y: (fn(Inv<'x>),
|
||||
fn(Inv<'y>)) }
|
||||
fn(Inv<'y>)) }
|
||||
|
||||
// Somewhat surprisingly, a fn taking two distinct bound lifetimes and
|
||||
// a fn taking one bound lifetime can be interchangeable, but only if
|
||||
|
|
@ -82,25 +86,27 @@ check! { free_inv_x_vs_free_inv_y: (fn(Inv<'x>),
|
|||
// intersection;
|
||||
// - if we are contravariant, then 'a can be inferred to 'static.
|
||||
check! { bound_a_b_vs_bound_a: (for<'a,'b> fn(&'a u32, &'b u32),
|
||||
for<'a> fn(&'a u32, &'a u32)) }
|
||||
for<'a> fn(&'a u32, &'a u32)) }
|
||||
check! { bound_co_a_b_vs_bound_co_a: (for<'a,'b> fn(Co<'a>, Co<'b>),
|
||||
for<'a> fn(Co<'a>, Co<'a>)) }
|
||||
for<'a> fn(Co<'a>, Co<'a>)) }
|
||||
check! { bound_contra_a_contra_b_ret_co_a: (for<'a,'b> fn(Contra<'a>, Contra<'b>) -> Co<'a>,
|
||||
for<'a> fn(Contra<'a>, Contra<'a>) -> Co<'a>) }
|
||||
for<'a> fn(Contra<'a>, Contra<'a>) -> Co<'a>) }
|
||||
check! { bound_co_a_co_b_ret_contra_a: (for<'a,'b> fn(Co<'a>, Co<'b>) -> Contra<'a>,
|
||||
for<'a> fn(Co<'a>, Co<'a>) -> Contra<'a>) }
|
||||
for<'a> fn(Co<'a>, Co<'a>) -> Contra<'a>) }
|
||||
|
||||
// If we make those lifetimes invariant, then the two types are not interchangeable.
|
||||
check! { bound_inv_a_b_vs_bound_inv_a: (for<'a,'b> fn(Inv<'a>, Inv<'b>),
|
||||
for<'a> fn(Inv<'a>, Inv<'a>)) }
|
||||
for<'a> fn(Inv<'a>, Inv<'a>)) }
|
||||
check! { bound_a_b_ret_a_vs_bound_a_ret_a: (for<'a,'b> fn(&'a u32, &'b u32) -> &'a u32,
|
||||
for<'a> fn(&'a u32, &'a u32) -> &'a u32) }
|
||||
for<'a> fn(&'a u32, &'a u32) -> &'a u32) }
|
||||
|
||||
#[rustc_error]
|
||||
fn main() {
|
||||
//[bound_a_vs_bound_a]~^ ERROR fatal error triggered by #[rustc_error]
|
||||
//[bound_a_vs_bound_b]~^^ ERROR fatal error triggered by #[rustc_error]
|
||||
//[bound_inv_a_vs_bound_inv_b]~^^^ ERROR fatal error triggered by #[rustc_error]
|
||||
//[bound_co_a_vs_bound_co_b]~^^^^ ERROR fatal error triggered by #[rustc_error]
|
||||
//[free_x_vs_free_x]~^^^^^ ERROR fatal error triggered by #[rustc_error]
|
||||
//[bound_a_vs_bound_a]~^ ERROR fatal error triggered by #[rustc_error]
|
||||
//[bound_a_vs_bound_b]~^^ ERROR fatal error triggered by #[rustc_error]
|
||||
//[bound_inv_a_vs_bound_inv_b]~^^^ ERROR fatal error triggered by #[rustc_error]
|
||||
//[bound_co_a_vs_bound_co_b]~^^^^ ERROR fatal error triggered by #[rustc_error]
|
||||
//[free_x_vs_free_x]~^^^^^ ERROR fatal error triggered by #[rustc_error]
|
||||
//[bound_co_a_b_vs_bound_co_a]~^^^^^^ ERROR
|
||||
//[bound_co_a_co_b_ret_contra_a]~^^^^^^^ ERROR
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
//
|
||||
// In particular, we test this pattern in trait solving, where it is not connected
|
||||
// to any part of the source code.
|
||||
//
|
||||
// check-pass
|
||||
|
||||
trait Trait<T> {}
|
||||
|
||||
|
|
@ -30,9 +32,6 @@ fn main() {
|
|||
// - `?b: ?a` -- solveable if `?b` is inferred to `'static`
|
||||
// - So the subtyping check succeeds, somewhat surprisingly.
|
||||
// This is because we can use `'static`.
|
||||
//
|
||||
// NB. *However*, the reinstated leak-check gives an error here.
|
||||
|
||||
foo::<()>();
|
||||
//~^ ERROR not satisfied
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +0,0 @@
|
|||
error[E0277]: the trait bound `(): Trait<for<'b> fn(fn(&'b u32))>` is not satisfied
|
||||
--> $DIR/hrtb-exists-forall-trait-covariant.rs:36:11
|
||||
|
|
||||
LL | fn foo<T>()
|
||||
| --- required by a bound in this
|
||||
LL | where
|
||||
LL | T: Trait<for<'b> fn(fn(&'b u32))>,
|
||||
| ------------------------------ required by this bound in `foo`
|
||||
...
|
||||
LL | foo::<()>();
|
||||
| ^^ the trait `Trait<for<'b> fn(fn(&'b u32))>` is not implemented for `()`
|
||||
|
|
||||
= help: the following implementations were found:
|
||||
<() as Trait<fn(fn(&'a u32))>>
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
|
@ -13,11 +13,11 @@ struct S;
|
|||
|
||||
// Given 'cx, return 'cx
|
||||
type F = for<'cx> fn(&'cx S) -> &'cx S;
|
||||
fn want_F(f: F) { }
|
||||
fn want_F(f: F) {}
|
||||
|
||||
// Given anything, return 'static
|
||||
type G = for<'cx> fn(&'cx S) -> &'static S;
|
||||
fn want_G(f: G) { }
|
||||
fn want_G(f: G) {}
|
||||
|
||||
// Should meet both.
|
||||
fn foo(x: &S) -> &'static S {
|
||||
|
|
@ -25,7 +25,7 @@ fn foo(x: &S) -> &'static S {
|
|||
}
|
||||
|
||||
// Should meet both.
|
||||
fn bar<'a,'b>(x: &'a S) -> &'b S {
|
||||
fn bar<'a, 'b>(x: &'a S) -> &'b S {
|
||||
panic!()
|
||||
}
|
||||
|
||||
|
|
@ -37,7 +37,7 @@ fn baz(x: &S) -> &S {
|
|||
fn supply_F() {
|
||||
want_F(foo);
|
||||
|
||||
want_F(bar); //~ ERROR mismatched types
|
||||
want_F(bar);
|
||||
|
||||
want_F(baz);
|
||||
}
|
||||
|
|
@ -48,5 +48,4 @@ fn supply_G() {
|
|||
want_G(baz); //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
}
|
||||
pub fn main() {}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,3 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/regions-fn-subtyping-return-static-fail.rs:40:12
|
||||
|
|
||||
LL | want_F(bar);
|
||||
| ^^^ expected concrete lifetime, found bound lifetime parameter 'cx
|
||||
|
|
||||
= note: expected fn pointer `for<'cx> fn(&'cx S) -> &'cx S`
|
||||
found fn item `for<'a> fn(&'a S) -> &S {bar::<'_>}`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/regions-fn-subtyping-return-static-fail.rs:48:12
|
||||
|
|
||||
|
|
@ -16,6 +7,6 @@ LL | want_G(baz);
|
|||
= note: expected fn pointer `for<'cx> fn(&'cx S) -> &'static S`
|
||||
found fn item `for<'r> fn(&'r S) -> &'r S {baz}`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@
|
|||
// *ANY* lifetime and returns a reference with the 'static lifetime.
|
||||
// This can safely be considered to be an instance of `F` because all
|
||||
// lifetimes are sublifetimes of 'static.
|
||||
//
|
||||
// check-pass
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![allow(unused_variables)]
|
||||
|
|
@ -14,11 +16,11 @@ struct S;
|
|||
|
||||
// Given 'cx, return 'cx
|
||||
type F = for<'cx> fn(&'cx S) -> &'cx S;
|
||||
fn want_F(f: F) { }
|
||||
fn want_F(f: F) {}
|
||||
|
||||
// Given anything, return 'static
|
||||
type G = for<'cx> fn(&'cx S) -> &'static S;
|
||||
fn want_G(f: G) { }
|
||||
fn want_G(f: G) {}
|
||||
|
||||
// Should meet both.
|
||||
fn foo(x: &S) -> &'static S {
|
||||
|
|
@ -26,7 +28,7 @@ fn foo(x: &S) -> &'static S {
|
|||
}
|
||||
|
||||
// Should meet both.
|
||||
fn bar<'a,'b>(x: &'a S) -> &'b S {
|
||||
fn bar<'a, 'b>(x: &'a S) -> &'b S {
|
||||
panic!()
|
||||
}
|
||||
|
||||
|
|
@ -38,10 +40,9 @@ fn baz(x: &S) -> &S {
|
|||
fn supply_F() {
|
||||
want_F(foo);
|
||||
|
||||
want_F(bar); //~ ERROR mismatched types
|
||||
want_F(bar);
|
||||
|
||||
want_F(baz);
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
}
|
||||
pub fn main() {}
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/regions-fn-subtyping-return-static.rs:41:12
|
||||
|
|
||||
LL | want_F(bar);
|
||||
| ^^^ expected concrete lifetime, found bound lifetime parameter 'cx
|
||||
|
|
||||
= note: expected fn pointer `for<'cx> fn(&'cx S) -> &'cx S`
|
||||
found fn item `for<'a> fn(&'a S) -> &S {bar::<'_>}`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
|
|
@ -36,7 +36,7 @@ error[E0271]: type mismatch resolving `for<'a, 'b> <fn(_) -> _ {id::<_>} as std:
|
|||
--> $DIR/rfc1623.rs:25:8
|
||||
|
|
||||
LL | f: &id,
|
||||
| ^^^ expected bound lifetime parameter 'a, found concrete lifetime
|
||||
| ^^^ expected bound lifetime parameter 'b, found concrete lifetime
|
||||
|
|
||||
= note: required for the cast to the object type `dyn for<'a, 'b> std::ops::Fn(&'a Foo<'b>) -> &'a Foo<'b>`
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue