diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:13 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:13 +0000 |
commit | 218caa410aa38c29984be31a5229b9fa717560ee (patch) | |
tree | c54bd55eeb6e4c508940a30e94c0032fbd45d677 /tests/ui/let-else/let-else-temporary-lifetime.rs | |
parent | Releasing progress-linux version 1.67.1+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-218caa410aa38c29984be31a5229b9fa717560ee.tar.xz rustc-218caa410aa38c29984be31a5229b9fa717560ee.zip |
Merging upstream version 1.68.2+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/ui/let-else/let-else-temporary-lifetime.rs')
-rw-r--r-- | tests/ui/let-else/let-else-temporary-lifetime.rs | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/tests/ui/let-else/let-else-temporary-lifetime.rs b/tests/ui/let-else/let-else-temporary-lifetime.rs new file mode 100644 index 000000000..c23eaa997 --- /dev/null +++ b/tests/ui/let-else/let-else-temporary-lifetime.rs @@ -0,0 +1,99 @@ +// run-pass +// compile-flags: -Zvalidate-mir + +use std::fmt::Display; +use std::rc::Rc; +use std::sync::atomic::{AtomicU8, Ordering}; + +static TRACKER: AtomicU8 = AtomicU8::new(0); + +#[derive(Default)] +struct Droppy { + inner: u32, +} + +impl Drop for Droppy { + fn drop(&mut self) { + TRACKER.store(1, Ordering::Release); + println!("I've been dropped"); + } +} + +fn foo<'a>(x: &'a str) -> Result<impl Display + 'a, ()> { + Ok(x) +} + +fn main() { + assert_eq!(TRACKER.load(Ordering::Acquire), 0); + let 0 = Droppy::default().inner else { return }; + assert_eq!(TRACKER.load(Ordering::Acquire), 1); + println!("Should have dropped 👆"); + + { + // cf. https://github.com/rust-lang/rust/pull/99518#issuecomment-1191520030 + struct Foo<'a>(&'a mut u32); + + impl<'a> Drop for Foo<'a> { + fn drop(&mut self) { + *self.0 = 0; + } + } + let mut foo = 0; + let Foo(0) = Foo(&mut foo) else { + *&mut foo = 1; + todo!() + }; + } + { + let x = String::from("Hey"); + + let Ok(s) = foo(&x) else { panic!() }; + assert_eq!(s.to_string(), x); + } + { + // test let-else drops temps after statement + let rc = Rc::new(0); + let 0 = *rc.clone() else { unreachable!() }; + Rc::try_unwrap(rc).unwrap(); + } + { + let mut rc = Rc::new(0); + let mut i = 0; + loop { + if i > 3 { + break; + } + let 1 = *rc.clone() else { + if let Ok(v) = Rc::try_unwrap(rc) { + rc = Rc::new(v); + } else { + panic!() + } + i += 1; + continue + }; + } + } + { + fn must_pass() { + let rc = Rc::new(()); + let &None = &Some(Rc::clone(&rc)) else { + Rc::try_unwrap(rc).unwrap(); + return; + }; + unreachable!(); + } + must_pass(); + } + { + // test let-else drops temps before else block + // NOTE: this test has to be the last block in the `main` + // body. + let rc = Rc::new(0); + let 1 = *rc.clone() else { + Rc::try_unwrap(rc).unwrap(); + return; + }; + unreachable!(); + } +} |