1
Fork 0

modify leak-check to track only outgoing edges from placeholders

Also, update the affected tests. This seems strictly better but it is
actually more permissive than I initially intended. In particular it
accepts this

```
forall<'a, 'b> {
  exists<'intersection> {
    'a: 'intersection,
    'b: 'intersection,
  }
}
```

and I'm not sure I want to accept that. It implies that we have a
`'empty` in the new universe intoduced by the `forall`.
This commit is contained in:
Niko Matsakis 2020-05-18 09:43:36 +00:00
parent 1a4e2b6f9c
commit bcc0a9c8eb
30 changed files with 222 additions and 204 deletions

View file

@ -42,10 +42,23 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
_ => bug!("leak_check: expected placeholder found {:?}", placeholder_region,), _ => bug!("leak_check: expected placeholder found {:?}", placeholder_region,),
}; };
// Find all regions that are related to this placeholder // Find all regions that this placeholder `!p` must outlive -- i.e.,
// in some way. This means any region that either outlives // any region `r` where `!p: r` must hold. It is an error if any
// or is outlived by a placeholder. // such region `r` is another placeholder or in a universe that
let mut taint_set = TaintSet::new(TaintDirections::both(), placeholder_region); // can't see the placeholder. (This is actually incorrect, because
// we don't take into account the possibility of bounds in
// environment that tell us that the placeholder may be related to
// other regions).
//
// Note that we *don't* look for cases like `r: !p`. This is
// because:
//
// * If `r` is some other placeholder `!p1`, then we'll find the
// error when we search the regions that `!p1` must outlive.
// * If `r` is a variable in some outer universe, then it can
// potentially be assigned to `'static`, so this relation could
// hold.
let mut taint_set = TaintSet::new(TaintDirections::outgoing(), placeholder_region);
taint_set.fixed_point( taint_set.fixed_point(
tcx, tcx,
self.undo_log.region_constraints(), self.undo_log.region_constraints(),

View file

@ -28,14 +28,14 @@ fn expect_free_supply_bound() {
// Here, we are given a function whose region is bound at closure level, // Here, we are given a function whose region is bound at closure level,
// but we expect one bound in the argument. Error results. // but we expect one bound in the argument. Error results.
with_closure_expecting_fn_with_free_region(|x: fn(&u32), y| {}); with_closure_expecting_fn_with_free_region(|x: fn(&u32), y| {});
//~^ ERROR type mismatch //~^ ERROR mismatched types
} }
fn expect_bound_supply_free_from_fn<'x>(x: &'x u32) { fn expect_bound_supply_free_from_fn<'x>(x: &'x u32) {
// Here, we are given a `fn(&u32)` but we expect a `fn(&'x // Here, we are given a `fn(&u32)` but we expect a `fn(&'x
// u32)`. In principle, this could be ok, but we demand equality. // u32)`. In principle, this could be ok, but we demand equality.
with_closure_expecting_fn_with_bound_region(|x: fn(&'x u32), y| {}); with_closure_expecting_fn_with_bound_region(|x: fn(&'x u32), y| {});
//~^ ERROR type mismatch //~^ ERROR mismatched types
} }
fn expect_bound_supply_free_from_closure() { fn expect_bound_supply_free_from_closure() {
@ -44,7 +44,7 @@ fn expect_bound_supply_free_from_closure() {
// the argument level. // the argument level.
type Foo<'a> = fn(&'a u32); type Foo<'a> = fn(&'a u32);
with_closure_expecting_fn_with_bound_region(|x: Foo<'_>, y| { with_closure_expecting_fn_with_bound_region(|x: Foo<'_>, y| {
//~^ ERROR type mismatch //~^ ERROR mismatched types
}); });
} }

View file

@ -36,46 +36,33 @@ note: ...does not necessarily outlive the anonymous lifetime #2 defined on the b
LL | with_closure_expecting_fn_with_free_region(|x: fn(&'x u32), y| {}); LL | with_closure_expecting_fn_with_free_region(|x: fn(&'x u32), y| {});
| ^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^
error[E0631]: type mismatch in closure arguments error[E0308]: mismatched types
--> $DIR/expect-fn-supply-fn.rs:30:5 --> $DIR/expect-fn-supply-fn.rs:30:52
| |
LL | fn with_closure_expecting_fn_with_free_region<F>(_: F)
| ------------------------------------------ required by a bound in this
LL | where F: for<'a> FnOnce(fn(&'a u32), &i32)
| ------------------------- required by this bound in `with_closure_expecting_fn_with_free_region`
...
LL | with_closure_expecting_fn_with_free_region(|x: fn(&u32), y| {}); LL | with_closure_expecting_fn_with_free_region(|x: fn(&u32), y| {});
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ---------------- found signature of `fn(for<'r> fn(&'r u32), _) -> _` | ^^^^^^^^ one type is more general than the other
| | |
| expected signature of `fn(fn(&'a u32), &i32) -> _` = note: expected fn pointer `fn(&u32)`
found fn pointer `for<'r> fn(&'r u32)`
error[E0631]: type mismatch in closure arguments
--> $DIR/expect-fn-supply-fn.rs:37:5 error[E0308]: mismatched types
--> $DIR/expect-fn-supply-fn.rs:37:53
| |
LL | fn with_closure_expecting_fn_with_bound_region<F>(_: F)
| ------------------------------------------- required by a bound in this
LL | where F: FnOnce(fn(&u32), &i32)
| ---------------------- required by this bound in `with_closure_expecting_fn_with_bound_region`
...
LL | with_closure_expecting_fn_with_bound_region(|x: fn(&'x u32), y| {}); LL | with_closure_expecting_fn_with_bound_region(|x: fn(&'x u32), y| {});
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------------------- found signature of `fn(fn(&'x u32), _) -> _` | ^^^^^^^^^^^ one type is more general than the other
| | |
| expected signature of `fn(for<'r> fn(&'r u32), &i32) -> _` = note: expected fn pointer `for<'r> fn(&'r u32)`
found fn pointer `fn(&'x u32)`
error[E0631]: type mismatch in closure arguments
--> $DIR/expect-fn-supply-fn.rs:46:5 error[E0308]: mismatched types
--> $DIR/expect-fn-supply-fn.rs:46:53
| |
LL | fn with_closure_expecting_fn_with_bound_region<F>(_: F)
| ------------------------------------------- required by a bound in this
LL | where F: FnOnce(fn(&u32), &i32)
| ---------------------- required by this bound in `with_closure_expecting_fn_with_bound_region`
...
LL | with_closure_expecting_fn_with_bound_region(|x: Foo<'_>, y| { LL | with_closure_expecting_fn_with_bound_region(|x: Foo<'_>, y| {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ --------------- found signature of `for<'r> fn(fn(&'r u32), _) -> _` | ^^^^^^^ one type is more general than the other
| | |
| expected signature of `fn(for<'r> fn(&'r u32), &i32) -> _` = note: expected fn pointer `for<'r> fn(&'r u32)`
found fn pointer `fn(&u32)`
error: aborting due to 5 previous errors error: aborting due to 5 previous errors
Some errors have detailed explanations: E0308, E0631. For more information about this error, try `rustc --explain E0308`.
For more information about an error, try `rustc --explain E0308`.

View file

@ -1,17 +1,14 @@
error[E0308]: mismatched types error: fatal error triggered by #[rustc_error]
--> $DIR/hr-subtype.rs:39:26 --> $DIR/hr-subtype.rs:96:1
| |
LL | gimme::<$t1>(None::<$t2>); LL | / fn main() {
| ^^^^^^^^^^^ expected concrete lifetime, found bound lifetime parameter 'a LL | |
... LL | |
LL | / check! { bound_a_b_vs_bound_a: (for<'a,'b> fn(&'a u32, &'b u32), LL | |
LL | | for<'a> fn(&'a u32, &'a u32)) } ... |
| |__________________________________________________________________- in this macro invocation LL | |
| LL | | }
= 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)>`
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.

View file

@ -1,11 +1,11 @@
error: fatal error triggered by #[rustc_error] error: fatal error triggered by #[rustc_error]
--> $DIR/hr-subtype.rs:100:1 --> $DIR/hr-subtype.rs:96:1
| |
LL | / fn main() { LL | / fn main() {
LL | | LL | |
LL | | LL | |
LL | | LL | |
LL | | ... |
LL | | LL | |
LL | | } LL | | }
| |_^ | |_^

View file

@ -1,11 +1,11 @@
error: fatal error triggered by #[rustc_error] error: fatal error triggered by #[rustc_error]
--> $DIR/hr-subtype.rs:100:1 --> $DIR/hr-subtype.rs:96:1
| |
LL | / fn main() { LL | / fn main() {
LL | | LL | |
LL | | LL | |
LL | | LL | |
LL | | ... |
LL | | LL | |
LL | | } LL | | }
| |_^ | |_^

View file

@ -2,7 +2,7 @@ error[E0308]: mismatched types
--> $DIR/hr-subtype.rs:39:26 --> $DIR/hr-subtype.rs:39:26
| |
LL | gimme::<$t1>(None::<$t2>); LL | gimme::<$t1>(None::<$t2>);
| ^^^^^^^^^^^ expected concrete lifetime, found bound lifetime parameter 'a | ^^^^^^^^^^^ one type is more general than the other
... ...
LL | / check! { bound_a_vs_free_x: (for<'a> fn(&'a u32), LL | / check! { bound_a_vs_free_x: (for<'a> fn(&'a u32),
LL | | fn(&'x u32)) } LL | | fn(&'x u32)) }

View file

@ -1,17 +1,14 @@
error[E0308]: mismatched types error: fatal error triggered by #[rustc_error]
--> $DIR/hr-subtype.rs:39:26 --> $DIR/hr-subtype.rs:96:1
| |
LL | gimme::<$t1>(None::<$t2>); LL | / fn main() {
| ^^^^^^^^^^^ expected concrete lifetime, found bound lifetime parameter 'a LL | |
... LL | |
LL | / check! { bound_co_a_b_vs_bound_co_a: (for<'a,'b> fn(Co<'a>, Co<'b>), LL | |
LL | | for<'a> fn(Co<'a>, Co<'a>)) } ... |
| |______________________________________________________________________- in this macro invocation LL | |
| LL | | }
= 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)
error: aborting due to previous error error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.

View file

@ -1,17 +1,14 @@
error[E0308]: mismatched types error: fatal error triggered by #[rustc_error]
--> $DIR/hr-subtype.rs:39:26 --> $DIR/hr-subtype.rs:96:1
| |
LL | gimme::<$t1>(None::<$t2>); LL | / fn main() {
| ^^^^^^^^^^^ expected concrete lifetime, found bound lifetime parameter 'a LL | |
... LL | |
LL | / check! { bound_co_a_co_b_ret_contra_a: (for<'a,'b> fn(Co<'a>, Co<'b>) -> Contra<'a>, LL | |
LL | | for<'a> fn(Co<'a>, Co<'a>) -> Contra<'a>) } ... |
| |______________________________________________________________________________________- in this macro invocation LL | |
| LL | | }
= 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)
error: aborting due to previous error error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.

View file

@ -1,11 +1,11 @@
error: fatal error triggered by #[rustc_error] error: fatal error triggered by #[rustc_error]
--> $DIR/hr-subtype.rs:100:1 --> $DIR/hr-subtype.rs:96:1
| |
LL | / fn main() { LL | / fn main() {
LL | | LL | |
LL | | LL | |
LL | | LL | |
LL | | ... |
LL | | LL | |
LL | | } LL | | }
| |_^ | |_^

View file

@ -1,17 +1,14 @@
error[E0308]: mismatched types error: fatal error triggered by #[rustc_error]
--> $DIR/hr-subtype.rs:39:26 --> $DIR/hr-subtype.rs:96:1
| |
LL | gimme::<$t1>(None::<$t2>); LL | / fn main() {
| ^^^^^^^^^^^ expected concrete lifetime, found bound lifetime parameter 'a LL | |
... LL | |
LL | / check! { bound_contra_a_contra_b_ret_co_a: (for<'a,'b> fn(Contra<'a>, Contra<'b>) -> Co<'a>, LL | |
LL | | for<'a> fn(Contra<'a>, Contra<'a>) -> Co<'a>) } ... |
| |______________________________________________________________________________________________- in this macro invocation LL | |
| LL | | }
= 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>>`
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.

View file

@ -1,11 +1,11 @@
error: fatal error triggered by #[rustc_error] error: fatal error triggered by #[rustc_error]
--> $DIR/hr-subtype.rs:100:1 --> $DIR/hr-subtype.rs:96:1
| |
LL | / fn main() { LL | / fn main() {
LL | | LL | |
LL | | LL | |
LL | | LL | |
LL | | ... |
LL | | LL | |
LL | | } LL | | }
| |_^ | |_^

View file

@ -1,11 +1,11 @@
error: fatal error triggered by #[rustc_error] error: fatal error triggered by #[rustc_error]
--> $DIR/hr-subtype.rs:100:1 --> $DIR/hr-subtype.rs:96:1
| |
LL | / fn main() { LL | / fn main() {
LL | | LL | |
LL | | LL | |
LL | | LL | |
LL | | ... |
LL | | LL | |
LL | | } LL | | }
| |_^ | |_^

View file

@ -42,10 +42,6 @@ macro_rules! check {
//[bound_inv_a_b_vs_bound_inv_a]~^^^ ERROR //[bound_inv_a_b_vs_bound_inv_a]~^^^ ERROR
//[bound_a_b_ret_a_vs_bound_a_ret_a]~^^^^ ERROR //[bound_a_b_ret_a_vs_bound_a_ret_a]~^^^^ ERROR
//[free_inv_x_vs_free_inv_y]~^^^^^ 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
} }
} }
} }
@ -103,4 +99,8 @@ fn main() {
//[bound_inv_a_vs_bound_inv_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] //[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] //[free_x_vs_free_x]~^^^^^ ERROR fatal error triggered by #[rustc_error]
//[bound_a_b_vs_bound_a]~^^^^^^ ERROR fatal error triggered by #[rustc_error]
//[bound_co_a_b_vs_bound_co_a]~^^^^^^^ ERROR fatal error triggered by #[rustc_error]
//[bound_co_a_co_b_ret_contra_a]~^^^^^^^^ ERROR fatal error triggered by #[rustc_error]
//[bound_contra_a_contra_b_ret_co_a]~^^^^^^^^^ ERROR fatal error triggered by #[rustc_error]
} }

View file

@ -2,9 +2,7 @@ error[E0308]: mismatched types
--> $DIR/hrtb-exists-forall-fn.rs:17:34 --> $DIR/hrtb-exists-forall-fn.rs:17:34
| |
LL | let _: for<'b> fn(&'b u32) = foo(); LL | let _: for<'b> fn(&'b u32) = foo();
| ------------------- ^^^^^ expected concrete lifetime, found bound lifetime parameter 'b | ^^^^^ one type is more general than the other
| |
| expected due to this
| |
= note: expected fn pointer `for<'b> fn(&'b u32)` = note: expected fn pointer `for<'b> fn(&'b u32)`
found fn pointer `fn(&u32)` found fn pointer `fn(&u32)`

View file

@ -32,5 +32,5 @@ fn main() {
// NB. *However*, the reinstated leak-check gives an error here. // NB. *However*, the reinstated leak-check gives an error here.
foo::<()>(); foo::<()>();
//~^ ERROR not satisfied //~^ ERROR implementation of `Trait` is not general enough
} }

View file

@ -1,18 +1,14 @@
error[E0277]: the trait bound `(): Trait<for<'b> fn(&'b u32)>` is not satisfied error: implementation of `Trait` is not general enough
--> $DIR/hrtb-exists-forall-trait-contravariant.rs:34:11 --> $DIR/hrtb-exists-forall-trait-contravariant.rs:34:5
| |
LL | fn foo<T>() LL | trait Trait<T> {}
| --- required by a bound in this | ----------------- trait `Trait` defined here
LL | where
LL | T: Trait<for<'b> fn(&'b u32)>,
| -------------------------- required by this bound in `foo`
... ...
LL | foo::<()>(); LL | foo::<()>();
| ^^ the trait `Trait<for<'b> fn(&'b u32)>` is not implemented for `()` | ^^^^^^^^^ implementation of `Trait` is not general enough
| |
= help: the following implementations were found: = note: `()` must implement `Trait<for<'b> fn(&'b u32)>`
<() as Trait<fn(&'a u32)>> = note: ...but `()` actually implements `Trait<fn(&'0 u32)>`, for some specific lifetime `'0`
error: aborting due to previous error error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.

View file

@ -1,19 +1,12 @@
error[E0277]: the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied error[E0308]: mismatched types
--> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:47:26 --> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:47:5
| |
LL | fn want_bar_for_any_ccx<B>(b: &B)
| -------------------- required by a bound in this
LL | where B : for<'ccx> Bar<'ccx>
| ------------------- required by this bound in `want_bar_for_any_ccx`
...
LL | want_bar_for_any_ccx(b); LL | want_bar_for_any_ccx(b);
| ^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B` | ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
| |
help: consider further restricting this bound = note: expected type `for<'ccx> Bar<'ccx>`
| found type `Bar<'static>`
LL | where B : Qux + for<'ccx> Bar<'ccx>
| ^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`. For more information about this error, try `rustc --explain E0308`.

View file

@ -1,16 +1,16 @@
error[E0277]: the trait bound `for<'a> StaticInt: Foo<&'a isize>` is not satisfied error: implementation of `Foo` is not general enough
--> $DIR/hrtb-just-for-static.rs:24:17 --> $DIR/hrtb-just-for-static.rs:24:5
| |
LL | fn want_hrtb<T>() LL | / trait Foo<X> {
| --------- required by a bound in this LL | | fn foo(&self, x: X) { }
LL | where T : for<'a> Foo<&'a isize> LL | | }
| ---------------------- required by this bound in `want_hrtb` | |_- trait `Foo` defined here
... ...
LL | want_hrtb::<StaticInt>() LL | want_hrtb::<StaticInt>()
| ^^^^^^^^^ the trait `for<'a> Foo<&'a isize>` is not implemented for `StaticInt` | ^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
| |
= help: the following implementations were found: = note: `StaticInt` must implement `Foo<&'0 isize>`, for any lifetime `'0`...
<StaticInt as Foo<&'static isize>> = note: ...but `StaticInt` actually implements `Foo<&'1 isize>`, for some specific lifetime `'1`
error[E0277]: the trait bound `for<'a> &'a u32: Foo<&'a isize>` is not satisfied error[E0277]: the trait bound `for<'a> &'a u32: Foo<&'a isize>` is not satisfied
--> $DIR/hrtb-just-for-static.rs:30:17 --> $DIR/hrtb-just-for-static.rs:30:17

View file

@ -38,5 +38,5 @@ fn assert_foo<T: Foo>() {}
fn main() { fn main() {
assert_foo::<fn(&i32)>(); assert_foo::<fn(&i32)>();
//~^ ERROR the trait bound `for<'r> fn(&'r i32): Foo` is not satisfied //~^ ERROR implementation of `Foo` is not general enough
} }

View file

@ -1,15 +1,16 @@
error[E0277]: the trait bound `for<'r> fn(&'r i32): Foo` is not satisfied error: implementation of `Foo` is not general enough
--> $DIR/issue-46989.rs:40:18 --> $DIR/issue-46989.rs:40:5
| |
LL | fn assert_foo<T: Foo>() {} LL | / trait Foo {
| --- required by this bound in `assert_foo` LL | |
LL | | }
| |_- trait `Foo` defined here
... ...
LL | assert_foo::<fn(&i32)>(); LL | assert_foo::<fn(&i32)>();
| ^^^^^^^^ the trait `Foo` is not implemented for `for<'r> fn(&'r i32)` | ^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
| |
= help: the following implementations were found: = note: `Foo` would have to be implemented for the type `for<'r> fn(&'r i32)`
<fn(A) as Foo> = note: ...but `Foo` is actually implemented for the type `fn(&'0 i32)`, for some specific lifetime `'0`
error: aborting due to previous error error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.

View file

@ -17,7 +17,7 @@ impl<T> Trait for fn(&T) {
fn f() { fn f() {
let a: fn(_) = |_: &u8| {}; let a: fn(_) = |_: &u8| {};
a.f(); //~ ERROR no method named `f` a.f(); //~ ERROR implementation of `Trait` is not general enough
} }
fn main() {} fn main() {}

View file

@ -1,17 +1,16 @@
error[E0599]: no method named `f` found for fn pointer `fn(&u8)` in the current scope error: implementation of `Trait` is not general enough
--> $DIR/issue-57362-1.rs:20:7 --> $DIR/issue-57362-1.rs:20:7
| |
LL | a.f(); LL | / trait Trait {
| ^ method not found in `fn(&u8)` LL | | fn f(self);
LL | | }
| |_- trait `Trait` defined here
...
LL | a.f();
| ^ implementation of `Trait` is not general enough
| |
= note: `a` is a function, perhaps you wish to call it = note: `Trait` would have to be implemented for the type `fn(&'0 u8)`, for some specific lifetime `'0`...
= help: items from traits can only be used if the trait is implemented and in scope = note: ...but `Trait` is actually implemented for the type `for<'r> fn(&'r u8)`
note: `Trait` defines an item `f`, perhaps you need to implement it
--> $DIR/issue-57362-1.rs:8:1
|
LL | trait Trait {
| ^^^^^^^^^^^
error: aborting due to previous error error: aborting due to previous error
For more information about this error, try `rustc --explain E0599`.

View file

@ -19,7 +19,9 @@ impl<'a> X for fn(&'a ()) {
} }
fn g() { fn g() {
let x = <fn (&())>::make_g(); //~ ERROR no function or associated item let x = <fn (&())>::make_g();
//~^ ERROR implementation of `X` is not general enough
//~| ERROR implementation of `X` is not general enough
} }
fn main() {} fn main() {}

View file

@ -1,16 +1,33 @@
error[E0599]: no function or associated item named `make_g` found for fn pointer `for<'r> fn(&'r ())` in the current scope error: implementation of `X` is not general enough
--> $DIR/issue-57362-2.rs:22:25 --> $DIR/issue-57362-2.rs:22:13
| |
LL | let x = <fn (&())>::make_g(); LL | / trait X {
| ^^^^^^ function or associated item not found in `for<'r> fn(&'r ())` LL | | type G;
LL | | fn make_g() -> Self::G;
LL | | }
| |_- trait `X` defined here
...
LL | let x = <fn (&())>::make_g();
| ^^^^^^^^^^^^^^^^^^ implementation of `X` is not general enough
| |
= help: items from traits can only be used if the trait is implemented and in scope = note: `X` would have to be implemented for the type `for<'r> fn(&'r ())`
note: `X` defines an item `make_g`, perhaps you need to implement it = note: ...but `X` is actually implemented for the type `fn(&'0 ())`, for some specific lifetime `'0`
--> $DIR/issue-57362-2.rs:8:1
|
LL | trait X {
| ^^^^^^^
error: aborting due to previous error error: implementation of `X` is not general enough
--> $DIR/issue-57362-2.rs:22:13
|
LL | / trait X {
LL | | type G;
LL | | fn make_g() -> Self::G;
| | ----------------------- due to a where-clause on `X::make_g`...
LL | | }
| |_- trait `X` defined here
...
LL | let x = <fn (&())>::make_g();
| ^^^^^^^^^^^^^^^^^^ doesn't satisfy where-clause
|
= note: ...`X` would have to be implemented for the type `for<'r> fn(&'r ())`
= note: ...but `X` is actually implemented for the type `fn(&'0 ())`, for some specific lifetime `'0`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0599`.

View file

@ -3,21 +3,21 @@
// error. However, now that we handle subtyping correctly, we no // error. However, now that we handle subtyping correctly, we no
// longer get an error, because we recognize these two types as // longer get an error, because we recognize these two types as
// equivalent! // equivalent!
//
// Whoops -- now that we reinstituted the leak-check, we get an error
// again.
fn foo( fn foo(
x: fn(&u8, &u8), x: fn(&u8, &u8),
y: for<'a> fn(&'a u8, &'a u8), y: for<'a> fn(&'a u8, &'a u8),
) { ) {
// The two types above are actually equivalent. With the older
// leak check, though, we didn't consider them as equivalent, and
// hence we gave errors. But now we've fixed that.
let z = match 22 { let z = match 22 {
0 => x, 0 => x,
_ => y, //~ ERROR `match` arms have incompatible types _ => y,
}; };
} }
fn bar( fn foo_cast(
x: fn(&u8, &u8), x: fn(&u8, &u8),
y: for<'a> fn(&'a u8, &'a u8), y: for<'a> fn(&'a u8, &'a u8),
) { ) {
@ -28,5 +28,30 @@ fn bar(
}; };
} }
fn bar(
x: for<'a, 'b> fn(&'a u8, &'b u8)-> &'a u8,
y: for<'a> fn(&'a u8, &'a u8) -> &'a u8,
) {
// The two types above are not equivalent. With the older LUB/GLB
// algorithm, this may have worked (I don't remember), but now it
// doesn't because we require equality.
let z = match 22 {
0 => x,
_ => y, //~ ERROR `match` arms have incompatible types
};
}
fn bar_cast(
x: for<'a, 'b> fn(&'a u8, &'b u8)-> &'a u8,
y: for<'a> fn(&'a u8, &'a u8) -> &'a u8,
) {
// But we can *upcast* explicitly the type of `x` and figure
// things out:
let z = match 22 {
0 => x as for<'a> fn(&'a u8, &'a u8) -> &'a u8,
_ => y,
};
}
fn main() { fn main() {
} }

View file

@ -1,17 +1,17 @@
error[E0308]: `match` arms have incompatible types error[E0308]: `match` arms have incompatible types
--> $DIR/old-lub-glb-hr.rs:16:14 --> $DIR/old-lub-glb-hr.rs:40:14
| |
LL | let z = match 22 { LL | let z = match 22 {
| _____________- | _____________-
LL | | 0 => x, LL | | 0 => x,
| | - this is found to be of type `for<'r, 's> fn(&'r u8, &'s u8)` | | - this is found to be of type `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8`
LL | | _ => y, LL | | _ => y,
| | ^ expected bound lifetime parameter, found concrete lifetime | | ^ expected bound lifetime parameter 'a, found concrete lifetime
LL | | }; LL | | };
| |_____- `match` arms have incompatible types | |_____- `match` arms have incompatible types
| |
= note: expected type `for<'r, 's> fn(&'r u8, &'s u8)` = note: expected type `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8`
found fn pointer `for<'a> fn(&'a u8, &'a u8)` found fn pointer `for<'a> fn(&'a u8, &'a u8) -> &'a u8`
error: aborting due to previous error error: aborting due to previous error

View file

@ -11,10 +11,10 @@ error[E0308]: mismatched types
--> $DIR/regions-fn-subtyping-return-static-fail.rs:48:12 --> $DIR/regions-fn-subtyping-return-static-fail.rs:48:12
| |
LL | want_G(baz); LL | want_G(baz);
| ^^^ expected concrete lifetime, found bound lifetime parameter 'cx | ^^^ one type is more general than the other
| |
= note: expected fn pointer `for<'cx> fn(&'cx S) -> &'static S` = note: expected fn pointer `for<'cx> fn(&'cx S) -> &'static S`
found fn item `for<'r> fn(&'r S) -> &'r S {baz}` found fn pointer `for<'r> fn(&'r S) -> &'r S`
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View file

@ -18,5 +18,5 @@ fn foo<T>(x: &T)
{} {}
fn main() { fn main() {
foo(&X); //~ ERROR trait bound foo(&X); //~ ERROR implementation of `Bar` is not general enough
} }

View file

@ -1,17 +1,16 @@
error[E0277]: the trait bound `for<'a> &'a _: Bar` is not satisfied error: implementation of `Bar` is not general enough
--> $DIR/where-for-self-2.rs:21:5 --> $DIR/where-for-self-2.rs:21:5
| |
LL | fn foo<T>(x: &T) LL | / trait Bar {
| --- required by a bound in this LL | | fn bar(&self);
LL | where for<'a> &'a T: Bar LL | | }
| --- required by this bound in `foo` | |_- trait `Bar` defined here
... ...
LL | foo(&X); LL | foo(&X);
| ^^^ the trait `for<'a> Bar` is not implemented for `&'a _` | ^^^ implementation of `Bar` is not general enough
| |
= help: the following implementations were found: = note: `Bar` would have to be implemented for the type `&'0 u32`, for any lifetime `'0`...
<&'static u32 as Bar> = note: ...but `Bar` is actually implemented for the type `&'1 u32`, for some specific lifetime `'1`
error: aborting due to previous error error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.