8000 Rollup of 6 pull requests by matthiaskrgr · Pull Request #100540 · rust-lang/rust · GitHub
[go: up one dir, main page]

Skip to content

Rollup of 6 pull requests #100540

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Aug 15, 2022
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add tests for the drop behavior of some control flow constructs
In #100513 it was shown that the drop behavior of let_chains is not correct
currently. Since drop behavior is something pretty subtle, this adds
explicit tests for the drop behavior of `if`, `if let` and `match` to
make sure that it does not regress in the future.

The `println!`s were left in to make debugging easier in case something
goes wrong, but they are not required for the test.
  • Loading branch information
Noratrieb committed Aug 14, 2022
commit f6c2816f4779eae60e9d2eb12f72b6450c789864
145 changes: 145 additions & 0 deletions src/test/ui/drop/drop_order.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
// run-pass

use std::cell::RefCell;
use std::convert::TryInto;

#[derive(Default)]
struct DropOrderCollector(RefCell<Vec<u32>>);

struct LoudDrop<'a>(&'a DropOrderCollector, u32);

impl Drop for LoudDrop<'_> {
fn drop(&mut self) {
println!("{}", self.1);
self.0.0.borrow_mut().push(self.1);
}
}

impl DropOrderCollector {
fn option_loud_drop(&self, n: u32) -> Option<LoudDrop> {
Some(LoudDrop(self, n))
}

fn loud_drop(&self, n: u32) -> LoudDrop {
LoudDrop(self, n)
}

fn print(&self, n: u32) {
println!("{}", n);
self.0.borrow_mut().push(n)
}

fn if_(&self) {
if self.option_loud_drop(1).is_some() {
self.print(2);
}

if self.option_loud_drop(3).is_none() {
unreachable!();
} else if self.option_loud_drop(4).is_some() {
self.print(5);
}

if {
if self.option_loud_drop(7).is_some() && self.option_loud_drop(6).is_some() {
self.loud_drop(8);
true
} else {
false
}
} {
self.print(9);
}
}

fn if_let(&self) {
if let None = self.option_loud_drop(2) {
unreachable!();
} else {
self.print(1);
}

if let Some(_) = self.option_loud_drop(4) {
self.print(3);
}

if let Some(_d) = self.option_loud_drop(6) {
self.print(5);
}
}

fn match_(&self) {
match self.option_loud_drop(2) {
_any => self.print(1),
}

match self.option_loud_drop(4) {
_ => self.print(3),
}

match self.option_loud_drop(6) {
Some(_) => self.print(5),
_ => unreachable!(),
}

match {
let _ = self.loud_drop(7);
let _d = self.loud_drop(9);
self.print(8);
()
} {
() => self.print(10),
}

match {
match self.option_loud_drop(14) {
_ => {
self.print(11);
self.option_loud_drop(13)
}
}
} {
_ => self.print(12),
}

match {
loop {
break match self.option_loud_drop(16) {
_ => {
self.print(15);
self.option_loud_drop(18)
}
};
}
} {
_ => self.print(17),
}
}

fn assert_sorted(self) {
assert!(
self.0
.into_inner()
.into_iter()
.enumerate()
.all(|(idx, item)| idx + 1 == item.try_into().unwrap())
);
}
}

fn main() {
println!("-- if --");
let collector = DropOrderCollector::default();
collector.if_();
collector.assert_sorted();

println!("-- if let --");
let collector = DropOrderCollector::default();
collector.if_let();
collector.assert_sorted();

println!("-- match --");
let collector = DropOrderCollector::default();
collector.match_();
collector.assert_sorted();
}
0