Skip to content

Commit 88801bf

Browse files
committed
Unit tests for rust-lang#57464 ICE.
1 parent 9f75f51 commit 88801bf

4 files changed

+102
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0373]: closure may outlive the current function, but it borrows `local`, which is owned by the current function
2+
--> $DIR/issue-57464-avoid-eager-conversion-to-region-vid.rs:45:13
3+
|
4+
LL | let m = |_: ()| poll_fn(|| { local; });
5+
| ^^^^^^^ ----- `local` is borrowed here
6+
| |
7+
| may outlive borrowed value `local`
8+
help: to force the closure to take ownership of `local` (and any other referenced variables), use the `move` keyword
9+
|
10+
LL | let m = move |_: ()| poll_fn(|| { local; });
11+
| ^^^^^^^^^^^^
12+
13+
error: aborting due to previous error
14+
15+
For more information about this error, try `rustc --explain E0373`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error[E0373]: closure may outlive the current function, but it borrows `local`, which is owned by the current function
2+
--> $DIR/issue-57464-avoid-eager-conversion-to-region-vid.rs:46:13
3+
|
4+
LL | let m = |_: ()| poll_fn(|| { local; });
5+
| ^^^^^^^ ----- `local` is borrowed here
6+
| |
7+
| may outlive borrowed value `local`
8+
help: to force the closure to take ownership of `local` (and any other referenced variables), use the `move` keyword
9+
|
10+
LL | let m = move |_: ()| poll_fn(|| { local; });
11+
| ^^^^^^^^^^^^
12+
13+
error: aborting due to previous error
14+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
error[E0373]: closure may outlive the current function, but it borrows `local`, which is owned by the current function
2+
--> $DIR/issue-57464-avoid-eager-conversion-to-region-vid.rs:45:13
3+
|
4+
LL | let m = |_: ()| poll_fn(|| { local; });
5+
| ^^^^^^^ ----- `local` is borrowed here
6+
| |
7+
| may outlive borrowed value `local`
8+
|
9+
note: closure is returned here
10+
--> $DIR/issue-57464-avoid-eager-conversion-to-region-vid.rs:51:5
11+
|
12+
LL | and_then(f)
13+
| ^^^^^^^^^^^
14+
help: to force the closure to take ownership of `local` (and any other referenced variables), use the `move` keyword
15+
|
16+
LL | let m = move |_: ()| poll_fn(|| { local; });
17+
| ^^^^^^^^^^^^
18+
19+
error: aborting due to previous error
20+
21+
For more information about this error, try `rustc --explain E0373`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// This test managed to tickle a part of the compiler where a region
2+
// representing a static scope (a call-site scope, to be precise) was
3+
// leaking the where clause of a type underlying an `impl Trait`. This
4+
// caused an ICE in spots where we assume that all regions must be
5+
// region_vid's (unique representatives used in NLL) and then
6+
// attempted to eagerly convert the region to its region_vid, which
7+
// does not work for scopes which do not have region_vids (apart from
8+
// the 'static region).
9+
//
10+
// This regression test is just meant to check that we do not ICE,
11+
// regardless of whether NLL is turned on or not.
12+
13+
// revisions: ast nll
14+
//[ast]compile-flags: -Z borrowck=ast
15+
//[mig]compile-flags: -Z borrowck=migrate -Z two-phase-borrows
16+
//[nll]compile-flags: -Z borrowck=mir -Z two-phase-borrows
17+
18+
// don't worry about the --compare-mode=nll on this test.
19+
// ignore-compare-mode-nll
20+
21+
pub struct AndThen<B, F>(B, F);
22+
fn and_then<F, B>(_: F) -> AndThen<B, F> where F: FnOnce() -> B { unimplemented!() }
23+
24+
pub trait Trait { }
25+
impl<B, F> Trait for AndThen<B, F> { }
26+
27+
pub struct JoinAll<I> where I: Iterator { _elem: std::marker::PhantomData<I::Item> }
28+
pub fn join_all<I>(_i: I) -> JoinAll<I> where I: Iterator { unimplemented!() }
29+
30+
pub struct PollFn<F, T>(F, std::marker::PhantomData<fn () -> T>);
31+
pub fn poll_fn<T, F>(_f: F) -> PollFn<F, T> where F: FnMut() -> T { unimplemented!() }
32+
33+
impl<B, I: Iterator, F> Iterator for Map<I, F> where F: FnMut(I::Item) -> B {
34+
type Item = B;
35+
fn next(&mut self) -> Option<B> { unimplemented!() }
36+
}
37+
38+
struct Map<I, F> { iter: I, f: F }
39+
40+
fn main() { let _b: Box<Trait + Send> = Box::new(graphql()); }
41+
42+
fn graphql() -> impl Trait
43+
{
44+
let local = ();
45+
let m = |_: ()| poll_fn(|| { local; });
46+
//[ast]~^ ERROR closure may outlive the current function, but it borrows `local`
47+
//[mig]~^^ ERROR closure may outlive the current function, but it borrows `local`
48+
//[nll]~^^^ ERROR closure may outlive the current function, but it borrows `local`
49+
let v = Map { iter: std::iter::once(()), f: m };
50+
let f = || join_all(v);
51+
and_then(f)
52+
}

0 commit comments

Comments
 (0)