Skip to content

Commit 1c96ddd

Browse files
committed
closure-requirements: add regression tests
1 parent 65d0b5d commit 1c96ddd

5 files changed

+62
-3
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// This example broke while refactoring the way closure
2+
// requirements are handled. The setup here matches
3+
// `thread::scope`.
4+
5+
//@ check-pass
6+
7+
struct Outlives<'hr, 'scope: 'hr>(*mut (&'scope (), &'hr ()));
8+
impl<'hr, 'scope> Outlives<'hr, 'scope> {
9+
fn outlives_hr<T: 'hr>(self) {}
10+
}
11+
12+
fn takes_closure_implied_bound<'scope>(f: impl for<'hr> FnOnce(Outlives<'hr, 'scope>)) {}
13+
14+
fn requires_external_outlives_hr<T>() {
15+
// implied bounds:
16+
// - `T: 'scope` as `'scope` is local to this function
17+
// - `'scope: 'hr` as it's an implied bound of `Outlives`
18+
//
19+
// need to prove `T: 'hr` :>
20+
takes_closure_implied_bound(|proof| proof.outlives_hr::<T>());
21+
}
22+
23+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// This example incorrectly compiled while refactoring the way
2+
// closure requirements are handled.
3+
4+
struct Outlives<'hr: 'scope, 'scope>(*mut (&'scope (), &'hr ()));
5+
impl<'hr, 'scope> Outlives<'hr, 'scope> {
6+
fn outlives_hr<T: 'hr>(self) {}
7+
}
8+
9+
fn takes_closure_implied_bound<'scope>(f: impl for<'hr> FnOnce(Outlives<'hr, 'scope>)) {}
10+
11+
fn requires_external_outlives_hr<T>() {
12+
// implied bounds:
13+
// - `T: 'scope` as `'scope` is local to this function
14+
// - `'hr: 'scope` as it's an implied bound of `Outlives`
15+
//
16+
// need to prove `T: 'hr` :<
17+
takes_closure_implied_bound(|proof| proof.outlives_hr::<T>());
18+
//~^ ERROR the parameter type `T` may not live long enough
19+
}
20+
21+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error[E0310]: the parameter type `T` may not live long enough
2+
--> $DIR/thread_scope_incorrect_implied_bound.rs:17:47
3+
|
4+
LL | takes_closure_implied_bound(|proof| proof.outlives_hr::<T>());
5+
| ^^^^^^^^^^^
6+
| |
7+
| the parameter type `T` must be valid for the static lifetime...
8+
| ...so that the type `T` will meet its required lifetime bounds
9+
|
10+
help: consider adding an explicit lifetime bound
11+
|
12+
LL | fn requires_external_outlives_hr<T: 'static>() {
13+
| +++++++++
14+
15+
error: aborting due to 1 previous error
16+
17+
For more information about this error, try `rustc --explain E0310`.

tests/ui/nll/ty-outlives/projection-implied-bounds.rs

-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
// Test that we can deduce when projections like `T::Item` outlive the
22
// function body. Test that this does not imply that `T: 'a` holds.
33

4-
//@ compile-flags:-Zverbose-internals
5-
64
use std::cell::Cell;
75

86
fn twice<F, T>(mut value: T, mut f: F)

tests/ui/nll/ty-outlives/projection-implied-bounds.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0310]: the parameter type `T` may not live long enough
2-
--> $DIR/projection-implied-bounds.rs:30:36
2+
--> $DIR/projection-implied-bounds.rs:28:36
33
|
44
LL | twice(value, |value_ref, item| invoke2(value_ref, item));
55
| ^^^^^^^^^^^^^^^^^^^^^^^^

0 commit comments

Comments
 (0)