diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
commit | 698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch) | |
tree | 173a775858bd501c378080a10dca74132f05bc50 /src/test/ui/regions/region-borrow-params-issue-29793-big.rs | |
parent | Initial commit. (diff) | |
download | rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip |
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/test/ui/regions/region-borrow-params-issue-29793-big.rs')
-rw-r--r-- | src/test/ui/regions/region-borrow-params-issue-29793-big.rs | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/src/test/ui/regions/region-borrow-params-issue-29793-big.rs b/src/test/ui/regions/region-borrow-params-issue-29793-big.rs new file mode 100644 index 000000000..83b1a6eab --- /dev/null +++ b/src/test/ui/regions/region-borrow-params-issue-29793-big.rs @@ -0,0 +1,74 @@ +// Issue #29793, big regression test: do not let borrows of +// parameters to ever be returned (expanded with exploration of +// variations). +// +// This is the version of the test that actually exposed unsound +// behavior (because the improperly accepted closure was actually +// able to be invoked). + +struct WrapA<F>(Option<F>); + +impl<F> WrapA<F> { + fn new() -> WrapA<F> { + WrapA(None) + } + fn set(mut self, f: F) -> Self { + self.0 = Some(f); + self + } +} + +struct WrapB<F>(Option<F>); + +impl<F> WrapB<F> { + fn new() -> WrapB<F> { + WrapB(None) + } + fn set(mut self, f: F) -> Self { + self.0 = Some(f); + self + } +} + +trait DoStuff : Sized { + fn handle(self); +} + +impl<F, T> DoStuff for WrapA<F> + where F: FnMut(usize, usize) -> T, T: DoStuff { + fn handle(mut self) { + if let Some(ref mut f) = self.0 { + let x = f(1, 2); + let _foo = [0usize; 16]; + x.handle(); + } + } + } + +impl<F> DoStuff for WrapB<F> where F: FnMut(bool) -> usize { + fn handle(mut self) { + if let Some(ref mut f) = self.0 { + println!("{}", f(true)); + } + } +} + +impl<F, T> WrapA<F> + where F: FnMut(usize, usize) -> T, T: DoStuff { + fn handle_ref(&mut self) { + if let Some(ref mut f) = self.0 { + let x = f(1, 2); + } + } + } + +fn main() { + let mut w = WrapA::new().set(|x: usize, y: usize| { + WrapB::new().set(|t: bool| if t { x } else { y }) // (separate errors for `x` vs `y`) + //~^ ERROR closure may outlive the current function + //~| ERROR closure may outlive the current function + }); + + w.handle(); // This works + // w.handle_ref(); // This doesn't +} |