diff options
| author | Michael Goulet <michael@errs.io> | 2025-07-21 18:35:34 +0000 | 
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2025-08-08 18:53:18 +0000 | 
| commit | 560e5dcbcf776e06302ecb2fa81f77313d514306 (patch) | |
| tree | 61f1a3a2ea3a51c3d75426b62b812b78eb0c7cb5 | |
| parent | d47150111d8f76b900d23e314c1b63093361e740 (diff) | |
| download | rust-560e5dcbcf776e06302ecb2fa81f77313d514306.tar.gz rust-560e5dcbcf776e06302ecb2fa81f77313d514306.zip  | |
Add test for upvar breakage
| -rw-r--r-- | tests/ui/async-await/drop-live-upvar-2.may_not_dangle.stderr | 18 | ||||
| -rw-r--r-- | tests/ui/async-await/drop-live-upvar-2.rs | 37 | 
2 files changed, 55 insertions, 0 deletions
diff --git a/tests/ui/async-await/drop-live-upvar-2.may_not_dangle.stderr b/tests/ui/async-await/drop-live-upvar-2.may_not_dangle.stderr new file mode 100644 index 00000000000..34f6ba79246 --- /dev/null +++ b/tests/ui/async-await/drop-live-upvar-2.may_not_dangle.stderr @@ -0,0 +1,18 @@ +error[E0597]: `y` does not live long enough + --> $DIR/drop-live-upvar-2.rs:31:26 + | +LL | let y = (); + | - binding `y` declared here +LL | drop_me = Droppy(&y); + | ^^ borrowed value does not live long enough +... +LL | } + | - `y` dropped here while still borrowed +LL | } + | - borrow might be used here, when `fut` is dropped and runs the destructor for coroutine + | + = note: values in a scope are dropped in the opposite order they are defined + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0597`. diff --git a/tests/ui/async-await/drop-live-upvar-2.rs b/tests/ui/async-await/drop-live-upvar-2.rs new file mode 100644 index 00000000000..605db4c8f76 --- /dev/null +++ b/tests/ui/async-await/drop-live-upvar-2.rs @@ -0,0 +1,37 @@ +//@ revisions: may_dangle may_not_dangle +//@[may_dangle] check-pass +//@ edition: 2018 + +// Ensure that if a coroutine's interior has no drop types then we don't require the upvars to +// be *use-live*, but instead require them to be *drop-live*. In this case, `Droppy<&'?0 ()>` +// does not require that `'?0` is live for drops since the parameter is `#[may_dangle]` in +// the may_dangle revision, but not in the may_not_dangle revision. + +#![feature(dropck_eyepatch)] + +struct Droppy<T>(T); + +#[cfg(may_dangle)] +unsafe impl<#[may_dangle] T> Drop for Droppy<T> { + fn drop(&mut self) { + // This does not use `T` of course. + } +} + +#[cfg(may_not_dangle)] +impl<T> Drop for Droppy<T> { + fn drop(&mut self) {} +} + +fn main() { + let drop_me; + let fut; + { + let y = (); + drop_me = Droppy(&y); + //[may_not_dangle]~^ ERROR `y` does not live long enough + fut = async { + std::mem::drop(drop_me); + }; + } +}  | 
