Handle DropKind::ForLint in coroutines correctly
(cherry picked from commit 42d1a4c48b
)
This commit is contained in:
parent
f757f96296
commit
730b84074d
3 changed files with 91 additions and 10 deletions
|
@ -1484,14 +1484,6 @@ fn build_scope_drops<'tcx>(
|
||||||
block = next;
|
block = next;
|
||||||
}
|
}
|
||||||
DropKind::ForLint => {
|
DropKind::ForLint => {
|
||||||
// If the operand has been moved, and we are not on an unwind
|
|
||||||
// path, then don't generate the drop. (We only take this into
|
|
||||||
// account for non-unwind paths so as not to disturb the
|
|
||||||
// caching mechanism.)
|
|
||||||
if scope.moved_locals.iter().any(|&o| o == local) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// As in the `DropKind::Storage` case below:
|
// As in the `DropKind::Storage` case below:
|
||||||
// normally lint-related drops are not emitted for unwind,
|
// normally lint-related drops are not emitted for unwind,
|
||||||
// so we can just leave `unwind_to` unmodified, but in some
|
// so we can just leave `unwind_to` unmodified, but in some
|
||||||
|
@ -1503,6 +1495,14 @@ fn build_scope_drops<'tcx>(
|
||||||
unwind_to = unwind_drops.drops[unwind_to].next;
|
unwind_to = unwind_drops.drops[unwind_to].next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the operand has been moved, and we are not on an unwind
|
||||||
|
// path, then don't generate the drop. (We only take this into
|
||||||
|
// account for non-unwind paths so as not to disturb the
|
||||||
|
// caching mechanism.)
|
||||||
|
if scope.moved_locals.iter().any(|&o| o == local) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
cfg.push(block, Statement {
|
cfg.push(block, Statement {
|
||||||
source_info,
|
source_info,
|
||||||
kind: StatementKind::BackwardIncompatibleDropHint {
|
kind: StatementKind::BackwardIncompatibleDropHint {
|
||||||
|
@ -1555,7 +1555,7 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> {
|
||||||
let mut unwind_indices = IndexVec::from_elem_n(unwind_target, 1);
|
let mut unwind_indices = IndexVec::from_elem_n(unwind_target, 1);
|
||||||
for (drop_idx, drop_node) in drops.drops.iter_enumerated().skip(1) {
|
for (drop_idx, drop_node) in drops.drops.iter_enumerated().skip(1) {
|
||||||
match drop_node.data.kind {
|
match drop_node.data.kind {
|
||||||
DropKind::Storage => {
|
DropKind::Storage | DropKind::ForLint => {
|
||||||
if is_coroutine {
|
if is_coroutine {
|
||||||
let unwind_drop = self
|
let unwind_drop = self
|
||||||
.scopes
|
.scopes
|
||||||
|
@ -1566,7 +1566,7 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> {
|
||||||
unwind_indices.push(unwind_indices[drop_node.next]);
|
unwind_indices.push(unwind_indices[drop_node.next]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DropKind::Value | DropKind::ForLint => {
|
DropKind::Value => {
|
||||||
let unwind_drop = self
|
let unwind_drop = self
|
||||||
.scopes
|
.scopes
|
||||||
.unwind_drops
|
.unwind_drops
|
||||||
|
|
29
tests/ui/drop/tail_expr_drop_order-on-coroutine-unwind.rs
Normal file
29
tests/ui/drop/tail_expr_drop_order-on-coroutine-unwind.rs
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
//@ edition: 2021
|
||||||
|
//@ build-fail
|
||||||
|
|
||||||
|
// Make sure we don't ICE when emitting the "lint" drop statement
|
||||||
|
// used for tail_expr_drop_order.
|
||||||
|
|
||||||
|
#![deny(tail_expr_drop_order)]
|
||||||
|
|
||||||
|
struct Drop;
|
||||||
|
impl std::ops::Drop for Drop {
|
||||||
|
fn drop(&mut self) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn func() -> Result<(), Drop> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn retry_db() -> Result<(), Drop> {
|
||||||
|
loop {
|
||||||
|
match func().await {
|
||||||
|
//~^ ERROR relative drop order changing in Rust 2024
|
||||||
|
//~| WARNING this changes meaning in Rust 2024
|
||||||
|
Ok(()) => return Ok(()),
|
||||||
|
Err(e) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,52 @@
|
||||||
|
error: relative drop order changing in Rust 2024
|
||||||
|
--> $DIR/tail_expr_drop_order-on-coroutine-unwind.rs:20:15
|
||||||
|
|
|
||||||
|
LL | match func().await {
|
||||||
|
| ^^^^^^^-----
|
||||||
|
| | |
|
||||||
|
| | this value will be stored in a temporary; let us call it `#1`
|
||||||
|
| | `#1` will be dropped later as of Edition 2024
|
||||||
|
| this value will be stored in a temporary; let us call it `#2`
|
||||||
|
| up until Edition 2021 `#2` is dropped last but will be dropped earlier in Edition 2024
|
||||||
|
...
|
||||||
|
LL | Err(e) => {}
|
||||||
|
| -
|
||||||
|
| |
|
||||||
|
| `e` calls a custom destructor
|
||||||
|
| `e` will be dropped later as of Edition 2024
|
||||||
|
LL | }
|
||||||
|
LL | }
|
||||||
|
| - now the temporary value is dropped here, before the local variables in the block or statement
|
||||||
|
|
|
||||||
|
= warning: this changes meaning in Rust 2024
|
||||||
|
= note: for more information, see issue #123739 <https://github.com/rust-lang/rust/issues/123739>
|
||||||
|
note: `#2` invokes this custom destructor
|
||||||
|
--> $DIR/tail_expr_drop_order-on-coroutine-unwind.rs:10:1
|
||||||
|
|
|
||||||
|
LL | / impl std::ops::Drop for Drop {
|
||||||
|
LL | | fn drop(&mut self) {}
|
||||||
|
LL | | }
|
||||||
|
| |_^
|
||||||
|
note: `#1` invokes this custom destructor
|
||||||
|
--> $DIR/tail_expr_drop_order-on-coroutine-unwind.rs:10:1
|
||||||
|
|
|
||||||
|
LL | / impl std::ops::Drop for Drop {
|
||||||
|
LL | | fn drop(&mut self) {}
|
||||||
|
LL | | }
|
||||||
|
| |_^
|
||||||
|
note: `e` invokes this custom destructor
|
||||||
|
--> $DIR/tail_expr_drop_order-on-coroutine-unwind.rs:10:1
|
||||||
|
|
|
||||||
|
LL | / impl std::ops::Drop for Drop {
|
||||||
|
LL | | fn drop(&mut self) {}
|
||||||
|
LL | | }
|
||||||
|
| |_^
|
||||||
|
= note: most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects like releasing locks or sending messages
|
||||||
|
note: the lint level is defined here
|
||||||
|
--> $DIR/tail_expr_drop_order-on-coroutine-unwind.rs:7:9
|
||||||
|
|
|
||||||
|
LL | #![deny(tail_expr_drop_order)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
Loading…
Add table
Reference in a new issue