diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:03 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:03 +0000 |
commit | 64d98f8ee037282c35007b64c2649055c56af1db (patch) | |
tree | 5492bcf97fce41ee1c0b1cc2add283f3e66cdab0 /tests/ui/regions/region-borrow-params-issue-29793-big.rs | |
parent | Adding debian version 1.67.1+dfsg1-1. (diff) | |
download | rustc-64d98f8ee037282c35007b64c2649055c56af1db.tar.xz rustc-64d98f8ee037282c35007b64c2649055c56af1db.zip |
Merging upstream version 1.68.2+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/ui/regions/region-borrow-params-issue-29793-big.rs')
-rw-r--r-- | tests/ui/regions/region-borrow-params-issue-29793-big.rs | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/tests/ui/regions/region-borrow-params-issue-29793-big.rs b/tests/ui/regions/region-borrow-params-issue-29793-big.rs new file mode 100644 index 000000000..83b1a6eab --- /dev/null +++ b/tests/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 +} |