Skip to content

Commit

Permalink
closure-requirements: add regression tests
Browse files Browse the repository at this point in the history
  • Loading branch information
lcnr committed Dec 3, 2024
1 parent 65d0b5d commit 1c96ddd
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// This example broke while refactoring the way closure
// requirements are handled. The setup here matches
// `thread::scope`.

//@ check-pass

struct Outlives<'hr, 'scope: 'hr>(*mut (&'scope (), &'hr ()));
impl<'hr, 'scope> Outlives<'hr, 'scope> {
fn outlives_hr<T: 'hr>(self) {}
}

fn takes_closure_implied_bound<'scope>(f: impl for<'hr> FnOnce(Outlives<'hr, 'scope>)) {}

fn requires_external_outlives_hr<T>() {
// implied bounds:
// - `T: 'scope` as `'scope` is local to this function
// - `'scope: 'hr` as it's an implied bound of `Outlives`
//
// need to prove `T: 'hr` :>
takes_closure_implied_bound(|proof| proof.outlives_hr::<T>());
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// This example incorrectly compiled while refactoring the way
// closure requirements are handled.

struct Outlives<'hr: 'scope, 'scope>(*mut (&'scope (), &'hr ()));
impl<'hr, 'scope> Outlives<'hr, 'scope> {
fn outlives_hr<T: 'hr>(self) {}
}

fn takes_closure_implied_bound<'scope>(f: impl for<'hr> FnOnce(Outlives<'hr, 'scope>)) {}

fn requires_external_outlives_hr<T>() {
// implied bounds:
// - `T: 'scope` as `'scope` is local to this function
// - `'hr: 'scope` as it's an implied bound of `Outlives`
//
// need to prove `T: 'hr` :<
takes_closure_implied_bound(|proof| proof.outlives_hr::<T>());
//~^ ERROR the parameter type `T` may not live long enough
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
error[E0310]: the parameter type `T` may not live long enough
--> $DIR/thread_scope_incorrect_implied_bound.rs:17:47
|
LL | takes_closure_implied_bound(|proof| proof.outlives_hr::<T>());
| ^^^^^^^^^^^
| |
| the parameter type `T` must be valid for the static lifetime...
| ...so that the type `T` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound
|
LL | fn requires_external_outlives_hr<T: 'static>() {
| +++++++++

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0310`.
2 changes: 0 additions & 2 deletions tests/ui/nll/ty-outlives/projection-implied-bounds.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// Test that we can deduce when projections like `T::Item` outlive the
// function body. Test that this does not imply that `T: 'a` holds.

//@ compile-flags:-Zverbose-internals

use std::cell::Cell;

fn twice<F, T>(mut value: T, mut f: F)
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/nll/ty-outlives/projection-implied-bounds.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0310]: the parameter type `T` may not live long enough
--> $DIR/projection-implied-bounds.rs:30:36
--> $DIR/projection-implied-bounds.rs:28:36
|
LL | twice(value, |value_ref, item| invoke2(value_ref, item));
| ^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down

0 comments on commit 1c96ddd

Please sign in to comment.