From 88801bf8813035cdc01a5261b8228fd782b8ac92 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Fri, 1 Mar 2019 13:34:35 +0100 Subject: [PATCH] Unit tests for #57464 ICE. --- ...-eager-conversion-to-region-vid.ast.stderr | 15 ++++++ ...-eager-conversion-to-region-vid.mig.stderr | 14 +++++ ...-eager-conversion-to-region-vid.nll.stderr | 21 ++++++++ ...64-avoid-eager-conversion-to-region-vid.rs | 52 +++++++++++++++++++ 4 files changed, 102 insertions(+) create mode 100644 src/test/ui/issues/issue-57464-avoid-eager-conversion-to-region-vid.ast.stderr create mode 100644 src/test/ui/issues/issue-57464-avoid-eager-conversion-to-region-vid.mig.stderr create mode 100644 src/test/ui/issues/issue-57464-avoid-eager-conversion-to-region-vid.nll.stderr create mode 100644 src/test/ui/issues/issue-57464-avoid-eager-conversion-to-region-vid.rs diff --git a/src/test/ui/issues/issue-57464-avoid-eager-conversion-to-region-vid.ast.stderr b/src/test/ui/issues/issue-57464-avoid-eager-conversion-to-region-vid.ast.stderr new file mode 100644 index 0000000000000..544cebcaadc1f --- /dev/null +++ b/src/test/ui/issues/issue-57464-avoid-eager-conversion-to-region-vid.ast.stderr @@ -0,0 +1,15 @@ +error[E0373]: closure may outlive the current function, but it borrows `local`, which is owned by the current function + --> $DIR/issue-57464-avoid-eager-conversion-to-region-vid.rs:45:13 + | +LL | let m = |_: ()| poll_fn(|| { local; }); + | ^^^^^^^ ----- `local` is borrowed here + | | + | may outlive borrowed value `local` +help: to force the closure to take ownership of `local` (and any other referenced variables), use the `move` keyword + | +LL | let m = move |_: ()| poll_fn(|| { local; }); + | ^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0373`. diff --git a/src/test/ui/issues/issue-57464-avoid-eager-conversion-to-region-vid.mig.stderr b/src/test/ui/issues/issue-57464-avoid-eager-conversion-to-region-vid.mig.stderr new file mode 100644 index 0000000000000..74e25951c2b75 --- /dev/null +++ b/src/test/ui/issues/issue-57464-avoid-eager-conversion-to-region-vid.mig.stderr @@ -0,0 +1,14 @@ +error[E0373]: closure may outlive the current function, but it borrows `local`, which is owned by the current function + --> $DIR/issue-57464-avoid-eager-conversion-to-region-vid.rs:46:13 + | +LL | let m = |_: ()| poll_fn(|| { local; }); + | ^^^^^^^ ----- `local` is borrowed here + | | + | may outlive borrowed value `local` +help: to force the closure to take ownership of `local` (and any other referenced variables), use the `move` keyword + | +LL | let m = move |_: ()| poll_fn(|| { local; }); + | ^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/issues/issue-57464-avoid-eager-conversion-to-region-vid.nll.stderr b/src/test/ui/issues/issue-57464-avoid-eager-conversion-to-region-vid.nll.stderr new file mode 100644 index 0000000000000..9690adbd05f1d --- /dev/null +++ b/src/test/ui/issues/issue-57464-avoid-eager-conversion-to-region-vid.nll.stderr @@ -0,0 +1,21 @@ +error[E0373]: closure may outlive the current function, but it borrows `local`, which is owned by the current function + --> $DIR/issue-57464-avoid-eager-conversion-to-region-vid.rs:45:13 + | +LL | let m = |_: ()| poll_fn(|| { local; }); + | ^^^^^^^ ----- `local` is borrowed here + | | + | may outlive borrowed value `local` + | +note: closure is returned here + --> $DIR/issue-57464-avoid-eager-conversion-to-region-vid.rs:51:5 + | +LL | and_then(f) + | ^^^^^^^^^^^ +help: to force the closure to take ownership of `local` (and any other referenced variables), use the `move` keyword + | +LL | let m = move |_: ()| poll_fn(|| { local; }); + | ^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0373`. diff --git a/src/test/ui/issues/issue-57464-avoid-eager-conversion-to-region-vid.rs b/src/test/ui/issues/issue-57464-avoid-eager-conversion-to-region-vid.rs new file mode 100644 index 0000000000000..c140338e831dd --- /dev/null +++ b/src/test/ui/issues/issue-57464-avoid-eager-conversion-to-region-vid.rs @@ -0,0 +1,52 @@ +// This test managed to tickle a part of the compiler where a region +// representing a static scope (a call-site scope, to be precise) was +// leaking the where clause of a type underlying an `impl Trait`. This +// caused an ICE in spots where we assume that all regions must be +// region_vid's (unique representatives used in NLL) and then +// attempted to eagerly convert the region to its region_vid, which +// does not work for scopes which do not have region_vids (apart from +// the 'static region). +// +// This regression test is just meant to check that we do not ICE, +// regardless of whether NLL is turned on or not. + +// revisions: ast nll +//[ast]compile-flags: -Z borrowck=ast +//[mig]compile-flags: -Z borrowck=migrate -Z two-phase-borrows +//[nll]compile-flags: -Z borrowck=mir -Z two-phase-borrows + +// don't worry about the --compare-mode=nll on this test. +// ignore-compare-mode-nll + +pub struct AndThen(B, F); +fn and_then(_: F) -> AndThen where F: FnOnce() -> B { unimplemented!() } + +pub trait Trait { } +impl Trait for AndThen { } + +pub struct JoinAll where I: Iterator { _elem: std::marker::PhantomData } +pub fn join_all(_i: I) -> JoinAll where I: Iterator { unimplemented!() } + +pub struct PollFn(F, std::marker::PhantomData T>); +pub fn poll_fn(_f: F) -> PollFn where F: FnMut() -> T { unimplemented!() } + +impl Iterator for Map where F: FnMut(I::Item) -> B { + type Item = B; + fn next(&mut self) -> Option { unimplemented!() } +} + +struct Map { iter: I, f: F } + +fn main() { let _b: Box = Box::new(graphql()); } + +fn graphql() -> impl Trait +{ + let local = (); + let m = |_: ()| poll_fn(|| { local; }); + //[ast]~^ ERROR closure may outlive the current function, but it borrows `local` + //[mig]~^^ ERROR closure may outlive the current function, but it borrows `local` + //[nll]~^^^ ERROR closure may outlive the current function, but it borrows `local` + let v = Map { iter: std::iter::once(()), f: m }; + let f = || join_all(v); + and_then(f) +}