diff options
| author | bors <bors@rust-lang.org> | 2023-08-07 13:39:28 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-08-07 13:39:28 +0000 |
| commit | 84ec2633defc5c459c682ac0c45efb41715249df (patch) | |
| tree | b9278f7a43740dde5eb72e2058badfe1fd936c13 /tests | |
| parent | 139b49b99523c43219b39079aa8fb2e084c52a1c (diff) | |
| parent | b4b33df983b4badac5c2578756cd42a76236be8d (diff) | |
| download | rust-84ec2633defc5c459c682ac0c45efb41715249df.tar.gz rust-84ec2633defc5c459c682ac0c45efb41715249df.zip | |
Auto merge of #113902 - Enselic:lint-recursive-drop, r=oli-obk
Make `unconditional_recursion` warning detect recursive drops Closes #55388 Also closes #50049 unless we want to keep it for the second example which this PR does not solve, but I think it is better to track that work in #57965. r? `@oli-obk` since you are the mentor for #55388 Unresolved questions: - [x] There are two false positives that must be fixed before merging (see diff). I suspect the best way to solve them is to perform analysis after drop elaboration instead of before, as now, but I have not explored that any further yet. Could that be an option? **Answer:** Yes, that solved the problem. `@rustbot` label +T-compiler +C-enhancement +A-lint
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/ui/lint/lint-unconditional-drop-recursion.rs | 38 | ||||
| -rw-r--r-- | tests/ui/lint/lint-unconditional-drop-recursion.stderr | 17 |
2 files changed, 55 insertions, 0 deletions
diff --git a/tests/ui/lint/lint-unconditional-drop-recursion.rs b/tests/ui/lint/lint-unconditional-drop-recursion.rs new file mode 100644 index 00000000000..348cd280139 --- /dev/null +++ b/tests/ui/lint/lint-unconditional-drop-recursion.rs @@ -0,0 +1,38 @@ +// Because drop recursion can only be detected after drop elaboration which +// happens for codegen: +// build-fail + +#![deny(unconditional_recursion)] +#![allow(dead_code)] + +pub struct RecursiveDrop; + +impl Drop for RecursiveDrop { + fn drop(&mut self) { //~ ERROR function cannot return without recursing + let _ = RecursiveDrop; + } +} + +#[derive(Default)] +struct NotRecursiveDrop1; + +impl Drop for NotRecursiveDrop1 { + fn drop(&mut self) { + // Before drop elaboration, the MIR can look like a recursive drop will + // occur. But it will not, since forget() prevents drop() from running. + let taken = std::mem::take(self); + std::mem::forget(taken); + } +} + +struct NotRecursiveDrop2; + +impl Drop for NotRecursiveDrop2 { + fn drop(&mut self) { + // Before drop elaboration, the MIR can look like a recursive drop will + // occur. But it will not, since this will panic. + std::panic::panic_any(NotRecursiveDrop2); + } +} + +fn main() {} diff --git a/tests/ui/lint/lint-unconditional-drop-recursion.stderr b/tests/ui/lint/lint-unconditional-drop-recursion.stderr new file mode 100644 index 00000000000..76f95481605 --- /dev/null +++ b/tests/ui/lint/lint-unconditional-drop-recursion.stderr @@ -0,0 +1,17 @@ +error: function cannot return without recursing + --> $DIR/lint-unconditional-drop-recursion.rs:11:5 + | +LL | fn drop(&mut self) { + | ^^^^^^^^^^^^^^^^^^ cannot return without recursing +LL | let _ = RecursiveDrop; + | - recursive call site + | + = help: a `loop` may express intention better if this is on purpose +note: the lint level is defined here + --> $DIR/lint-unconditional-drop-recursion.rs:5:9 + | +LL | #![deny(unconditional_recursion)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + |
