diff options
Diffstat (limited to 'tests/ui/drop/lint-tail-expr-drop-order.rs')
| -rw-r--r-- | tests/ui/drop/lint-tail-expr-drop-order.rs | 215 |
1 files changed, 199 insertions, 16 deletions
diff --git a/tests/ui/drop/lint-tail-expr-drop-order.rs b/tests/ui/drop/lint-tail-expr-drop-order.rs index d61abae5187..0fabc1f085c 100644 --- a/tests/ui/drop/lint-tail-expr-drop-order.rs +++ b/tests/ui/drop/lint-tail-expr-drop-order.rs @@ -1,13 +1,26 @@ -//@ edition: 2021 - // Edition 2024 lint for change in drop order at tail expression // This lint is to capture potential change in program semantics // due to implementation of RFC 3606 <https://github.com/rust-lang/rfcs/pull/3606> +//@ edition: 2021 +//@ build-fail -#![deny(tail_expr_drop_order)] +#![deny(tail_expr_drop_order)] //~ NOTE: the lint level is defined here +#![allow(dropping_copy_types)] struct LoudDropper; impl Drop for LoudDropper { + //~^ NOTE: `#1` invokes this custom destructor + //~| NOTE: `x` invokes this custom destructor + //~| NOTE: `#1` invokes this custom destructor + //~| NOTE: `x` invokes this custom destructor + //~| NOTE: `#1` invokes this custom destructor + //~| NOTE: `x` invokes this custom destructor + //~| NOTE: `#1` invokes this custom destructor + //~| NOTE: `x` invokes this custom destructor + //~| NOTE: `#1` invokes this custom destructor + //~| NOTE: `future` invokes this custom destructor + //~| NOTE: `_x` invokes this custom destructor + //~| NOTE: `#1` invokes this custom destructor fn drop(&mut self) { // This destructor should be considered significant because it is a custom destructor // and we will assume that the destructor can generate side effects arbitrarily so that @@ -23,30 +36,70 @@ impl LoudDropper { fn should_lint() -> i32 { let x = LoudDropper; + //~^ NOTE: `x` calls a custom destructor + //~| NOTE: `x` will be dropped later as of Edition 2024 // Should lint x.get() + LoudDropper.get() - //~^ ERROR: these values and local bindings have significant drop implementation that will have a different drop order from that of Edition 2021 + //~^ ERROR: relative drop order changing in Rust 2024 + //~| NOTE: this value will be stored in a temporary; let us call it `#1` + //~| NOTE: up until Edition 2021 `#1` is dropped last but will be dropped earlier in Edition 2024 //~| WARN: this changes meaning in Rust 2024 + //~| NOTE: most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects + //~| NOTE: for more information, see issue #123739 } +//~^ NOTE: now the temporary value is dropped here, before the local variables in the block or statement -fn should_lint_closure() -> impl FnOnce() -> i32 { +fn should_not_lint_closure() -> impl FnOnce() -> i32 { let x = LoudDropper; - move || x.get() + LoudDropper.get() - //~^ ERROR: these values and local bindings have significant drop implementation that will have a different drop order from that of Edition 2021 - //~| WARN: this changes meaning in Rust 2024 + move || { + // Should not lint because ... + x.get() + LoudDropper.get() + } + // ^ closure captures like `x` are always dropped last by contract +} + +fn should_lint_in_nested_items() { + fn should_lint_me() -> i32 { + let x = LoudDropper; + //~^ NOTE: `x` calls a custom destructor + //~| NOTE: `x` will be dropped later as of Edition 2024 + // Should lint + x.get() + LoudDropper.get() + //~^ ERROR: relative drop order changing in Rust 2024 + //~| NOTE: this value will be stored in a temporary; let us call it `#1` + //~| NOTE: up until Edition 2021 `#1` is dropped last but will be dropped earlier in Edition 2024 + //~| WARN: this changes meaning in Rust 2024 + //~| NOTE: most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects + //~| NOTE: for more information, see issue #123739 + } + //~^ NOTE: now the temporary value is dropped here, before the local variables in the block or statement } +fn should_not_lint_params(x: LoudDropper) -> i32 { + // Should not lint because ... + x.get() + LoudDropper.get() +} +// ^ function parameters like `x` are always dropped last + fn should_not_lint() -> i32 { let x = LoudDropper; // Should not lint x.get() } -fn should_not_lint_in_nested_block() -> i32 { +fn should_lint_in_nested_block() -> i32 { let x = LoudDropper; - // Should not lint because Edition 2021 drops temporaries in blocks earlier already + //~^ NOTE: `x` calls a custom destructor + //~| NOTE: `x` will be dropped later as of Edition 2024 { LoudDropper.get() } + //~^ ERROR: relative drop order changing in Rust 2024 + //~| NOTE: this value will be stored in a temporary; let us call it `#1` + //~| NOTE: up until Edition 2021 `#1` is dropped last but will be dropped earlier in Edition 2024 + //~| WARN: this changes meaning in Rust 2024 + //~| NOTE: most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects + //~| NOTE: for more information, see issue #123739 } +//~^ NOTE: now the temporary value is dropped here, before the local variables in the block or statement fn should_not_lint_in_match_arm() -> i32 { let x = LoudDropper; @@ -56,14 +109,144 @@ fn should_not_lint_in_match_arm() -> i32 { } } -fn should_lint_in_nested_items() { - fn should_lint_me() -> i32 { +fn should_not_lint_when_consumed() -> (LoudDropper, i32) { + let x = LoudDropper; + // Should not lint because `LoudDropper` is consumed by the return value + (LoudDropper, x.get()) +} + +struct MyAdt { + a: LoudDropper, + b: LoudDropper, +} + +fn should_not_lint_when_consumed_in_ctor() -> MyAdt { + let a = LoudDropper; + // Should not lint + MyAdt { a, b: LoudDropper } +} + +fn should_not_lint_when_moved() -> i32 { + let x = LoudDropper; + drop(x); + // Should not lint because `x` is not live + LoudDropper.get() +} + +fn should_lint_into_async_body() -> i32 { + async fn f() { + async fn f() {} let x = LoudDropper; - // Should lint - x.get() + LoudDropper.get() - //~^ ERROR: these values and local bindings have significant drop implementation that will have a different drop order from that of Edition 2021 - //~| WARN: this changes meaning in Rust 2024 + f().await; + drop(x); + } + + let future = f(); + //~^ NOTE: `future` calls a custom destructor + //~| NOTE: `future` will be dropped later as of Edition 2024 + LoudDropper.get() + //~^ ERROR: relative drop order changing in Rust 2024 + //~| WARN: this changes meaning in Rust 2024 + //~| NOTE: this value will be stored in a temporary; let us call it `#1` + //~| NOTE: up until Edition 2021 `#1` is dropped last but will be dropped earlier in Edition 2024 + //~| NOTE: most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects + //~| NOTE: for more information, see issue #123739 +} +//~^ NOTE: now the temporary value is dropped here, before the local variables in the block or statement + +fn should_lint_generics<T: Default>() -> &'static str { + fn extract<T>(_: &T) -> &'static str { + todo!() + } + let x = T::default(); + //~^ NOTE: `x` calls a custom destructor + //~| NOTE: `x` will be dropped later as of Edition 2024 + extract(&T::default()) + //~^ ERROR: relative drop order changing in Rust 2024 + //~| WARN: this changes meaning in Rust 2024 + //~| NOTE: this value will be stored in a temporary; let us call it `#1` + //~| NOTE: up until Edition 2021 `#1` is dropped last but will be dropped earlier in Edition 2024 + //~| NOTE: most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects + //~| NOTE: for more information, see issue #123739 +} +//~^ NOTE: now the temporary value is dropped here, before the local variables in the block or statement + +fn should_lint_adt() -> i32 { + let x: Result<LoudDropper, ()> = Ok(LoudDropper); + //~^ NOTE: `x` calls a custom destructor + //~| NOTE: `x` will be dropped later as of Edition 2024 + LoudDropper.get() + //~^ ERROR: relative drop order changing in Rust 2024 + //~| WARN: this changes meaning in Rust 2024 + //~| NOTE: this value will be stored in a temporary; let us call it `#1` + //~| NOTE: up until Edition 2021 `#1` is dropped last but will be dropped earlier in Edition 2024 + //~| NOTE: most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects + //~| NOTE: for more information, see issue #123739 +} +//~^ NOTE: now the temporary value is dropped here, before the local variables in the block or statement + +fn should_not_lint_insign_dtor() -> i32 { + let x = String::new(); + LoudDropper.get() +} + +fn should_lint_with_dtor_span() -> i32 { + struct LoudDropper3; + impl Drop for LoudDropper3 { + //~^ NOTE: `#1` invokes this custom destructor + fn drop(&mut self) { + println!("loud drop"); + } } + impl LoudDropper3 { + fn get(&self) -> i32 { + 0 + } + } + struct LoudDropper2; + impl Drop for LoudDropper2 { + //~^ NOTE: `x` invokes this custom destructor + fn drop(&mut self) { + println!("loud drop"); + } + } + impl LoudDropper2 { + fn get(&self) -> i32 { + 0 + } + } + + let x = LoudDropper2; + //~^ NOTE: `x` calls a custom destructor + //~| NOTE: `x` will be dropped later as of Edition 2024 + LoudDropper3.get() + //~^ ERROR: relative drop order changing in Rust 2024 + //~| NOTE: this value will be stored in a temporary; let us call it `#1` + //~| NOTE: up until Edition 2021 `#1` is dropped last but will be dropped earlier in Edition 2024 + //~| WARN: this changes meaning in Rust 2024 + //~| NOTE: most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects + //~| NOTE: for more information, see issue #123739 +} +//~^ NOTE: now the temporary value is dropped here, before the local variables in the block or statement + +fn should_lint_with_transient_drops() { + drop(( + { + LoudDropper.get() + //~^ ERROR: relative drop order changing in Rust 2024 + //~| NOTE: this value will be stored in a temporary; let us call it `#1` + //~| NOTE: up until Edition 2021 `#1` is dropped last but will be dropped earlier in Edition 2024 + //~| WARN: this changes meaning in Rust 2024 + //~| NOTE: most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects + //~| NOTE: for more information, see issue #123739 + }, + { + let _x = LoudDropper; + //~^ NOTE: `_x` calls a custom destructor + //~| NOTE: `_x` will be dropped later as of Edition 2024 + }, + )); + //~^ NOTE: now the temporary value is dropped here, before the local variables in the block or statement } fn main() {} |
