mirror of
https://github.com/rust-lang/rust.git
synced 2025-10-02 18:27:37 +00:00
146 lines
3.7 KiB
Rust
146 lines
3.7 KiB
Rust
// See drop-order-comparisons.rs
|
|
|
|
//@ edition: 2024
|
|
//@ run-pass
|
|
|
|
#![feature(if_let_guard)]
|
|
|
|
fn t_if_let_chains_then() {
|
|
let e = Events::new();
|
|
_ = if e.ok(1).is_ok()
|
|
&& let true = e.ok(9).is_ok()
|
|
&& let Ok(_v) = e.ok(8)
|
|
&& let Ok(_) = e.ok(7)
|
|
&& let Ok(_) = e.ok(6).as_ref()
|
|
&& e.ok(2).is_ok()
|
|
&& let Ok(_v) = e.ok(5)
|
|
&& let Ok(_) = e.ok(4).as_ref() {
|
|
e.mark(3);
|
|
};
|
|
e.assert(9);
|
|
}
|
|
|
|
fn t_guard_if_let_chains_then() {
|
|
let e = Events::new();
|
|
_ = match () {
|
|
() if e.ok(1).is_ok()
|
|
&& let true = e.ok(9).is_ok()
|
|
&& let Ok(_v) = e.ok(8)
|
|
&& let Ok(_) = e.ok(7)
|
|
&& let Ok(_) = e.ok(6).as_ref()
|
|
&& e.ok(2).is_ok()
|
|
&& let Ok(_v) = e.ok(5)
|
|
&& let Ok(_) = e.ok(4).as_ref() => {
|
|
e.mark(3);
|
|
}
|
|
_ => {}
|
|
};
|
|
e.assert(9);
|
|
}
|
|
|
|
fn t_if_let_chains_then_else() {
|
|
let e = Events::new();
|
|
_ = if e.ok(1).is_ok()
|
|
&& let true = e.ok(8).is_ok()
|
|
&& let Ok(_v) = e.ok(7)
|
|
&& let Ok(_) = e.ok(6)
|
|
&& let Ok(_) = e.ok(5).as_ref()
|
|
&& e.ok(2).is_ok()
|
|
&& let Ok(_v) = e.ok(4)
|
|
&& let Ok(_) = e.err(3) {} else {
|
|
e.mark(9);
|
|
};
|
|
e.assert(9);
|
|
}
|
|
|
|
fn t_guard_if_let_chains_then_else() {
|
|
let e = Events::new();
|
|
_ = match () {
|
|
() if e.ok(1).is_ok()
|
|
&& let true = e.ok(8).is_ok()
|
|
&& let Ok(_v) = e.ok(7)
|
|
&& let Ok(_) = e.ok(6)
|
|
&& let Ok(_) = e.ok(5).as_ref()
|
|
&& e.ok(2).is_ok()
|
|
&& let Ok(_v) = e.ok(4)
|
|
&& let Ok(_) = e.err(3) => {}
|
|
_ => {
|
|
e.mark(9);
|
|
}
|
|
};
|
|
e.assert(9);
|
|
}
|
|
|
|
fn main() {
|
|
t_if_let_chains_then();
|
|
t_guard_if_let_chains_then();
|
|
t_if_let_chains_then_else();
|
|
t_guard_if_let_chains_then_else();
|
|
}
|
|
|
|
// # Test scaffolding
|
|
|
|
use core::cell::RefCell;
|
|
use std::collections::HashSet;
|
|
|
|
/// A buffer to track the order of events.
|
|
///
|
|
/// First, numbered events are logged into this buffer.
|
|
///
|
|
/// Then, `assert` is called to verify that the correct number of
|
|
/// events were logged, and that they were logged in the expected
|
|
/// order.
|
|
struct Events(RefCell<Option<Vec<u64>>>);
|
|
|
|
impl Events {
|
|
const fn new() -> Self {
|
|
Self(RefCell::new(Some(Vec::new())))
|
|
}
|
|
#[track_caller]
|
|
fn assert(&self, max: u64) {
|
|
let buf = &self.0;
|
|
let v1 = buf.borrow().as_ref().unwrap().clone();
|
|
let mut v2 = buf.borrow().as_ref().unwrap().clone();
|
|
*buf.borrow_mut() = None;
|
|
v2.sort();
|
|
let uniq_len = v2.iter().collect::<HashSet<_>>().len();
|
|
// Check that the sequence is sorted.
|
|
assert_eq!(v1, v2);
|
|
// Check that there are no duplicates.
|
|
assert_eq!(v2.len(), uniq_len);
|
|
// Check that the length is the expected one.
|
|
assert_eq!(max, uniq_len as u64);
|
|
// Check that the last marker is the expected one.
|
|
assert_eq!(v2.last().unwrap(), &max);
|
|
}
|
|
/// Return an `Ok` value that logs its drop.
|
|
fn ok(&self, m: u64) -> Result<LogDrop<'_>, LogDrop<'_>> {
|
|
Ok(LogDrop(self, m))
|
|
}
|
|
/// Return an `Err` value that logs its drop.
|
|
fn err(&self, m: u64) -> Result<LogDrop<'_>, LogDrop<'_>> {
|
|
Err(LogDrop(self, m))
|
|
}
|
|
/// Log an event.
|
|
fn mark(&self, m: u64) {
|
|
self.0.borrow_mut().as_mut().unwrap().push(m);
|
|
}
|
|
}
|
|
|
|
impl Drop for Events {
|
|
fn drop(&mut self) {
|
|
if self.0.borrow().is_some() {
|
|
panic!("failed to call `Events::assert()`");
|
|
}
|
|
}
|
|
}
|
|
|
|
/// A type that logs its drop events.
|
|
struct LogDrop<'b>(&'b Events, u64);
|
|
|
|
impl<'b> Drop for LogDrop<'b> {
|
|
fn drop(&mut self) {
|
|
self.0.mark(self.1);
|
|
}
|
|
}
|