-
Notifications
You must be signed in to change notification settings - Fork 12.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rollup merge of #125293 - dingxiangfei2009:tail-expr-temp-lifetime, r…
…=estebank,davidtwco Place tail expression behind terminating scope This PR implements #123739 so that we can do further experiments in nightly. A little rewrite has been applied to `for await` lowering. It was previously `unsafe { Pin::unchecked_new(into_async_iter(..)) }`. Under the edition 2024 rule, however, `into_async_iter` gets dropped at the end of the `unsafe` block. This presumably the first Edition 2024 migration rule goes by hoisting `into_async_iter(..)` into `match` one level above, so it now looks like the following. ```rust match into_async_iter($iter_expr) { ref mut iter => match unsafe { Pin::unchecked_new(iter) } { ... } } ```
- Loading branch information
Showing
19 changed files
with
376 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
//@ edition:2021 | ||
|
||
#[macro_export] | ||
macro_rules! edition_2021_block { | ||
($($c:tt)*) => { | ||
{ $($c)* } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
//@ edition:2024 | ||
//@ compile-flags: -Zunstable-options | ||
|
||
#[macro_export] | ||
macro_rules! edition_2024_block { | ||
($($c:tt)*) => { | ||
{ $($c)* } | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
tests/ui/drop/tail-expr-drop-order-negative.edition2024.stderr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
error[E0716]: temporary value dropped while borrowed | ||
--> $DIR/tail-expr-drop-order-negative.rs:11:15 | ||
| | ||
LL | x.replace(std::cell::RefCell::new(123).borrow()).is_some() | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - temporary value is freed at the end of this statement | ||
| | | ||
| creates a temporary value which is freed while still in use | ||
LL | | ||
LL | } | ||
| - borrow might be used here, when `x` is dropped and runs the destructor for type `Option<Ref<'_, i32>>` | ||
| | ||
= note: consider using a `let` binding to create a longer lived value | ||
|
||
error: aborting due to 1 previous error | ||
|
||
For more information about this error, try `rustc --explain E0716`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
//@ revisions: edition2021 edition2024 | ||
//@ [edition2024] compile-flags: -Zunstable-options | ||
//@ [edition2024] edition: 2024 | ||
//@ [edition2021] check-pass | ||
|
||
#![feature(shorter_tail_lifetimes)] | ||
|
||
fn why_would_you_do_this() -> bool { | ||
let mut x = None; | ||
// Make a temporary `RefCell` and put a `Ref` that borrows it in `x`. | ||
x.replace(std::cell::RefCell::new(123).borrow()).is_some() | ||
//[edition2024]~^ ERROR: temporary value dropped while borrowed | ||
} | ||
|
||
fn main() { | ||
why_would_you_do_this(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
//@ aux-build:edition-2021-macros.rs | ||
//@ aux-build:edition-2024-macros.rs | ||
//@ compile-flags: -Z validate-mir -Zunstable-options | ||
//@ edition: 2024 | ||
//@ run-pass | ||
|
||
#![feature(shorter_tail_lifetimes)] | ||
#![allow(unused_imports)] | ||
#![allow(dead_code)] | ||
#![allow(unused_variables)] | ||
|
||
#[macro_use] | ||
extern crate edition_2021_macros; | ||
#[macro_use] | ||
extern crate edition_2024_macros; | ||
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 assert_sorted(&self, expected: usize) { | ||
let result = self.0.borrow(); | ||
assert_eq!(result.len(), expected); | ||
for i in 1..result.len() { | ||
assert!( | ||
result[i - 1] < result[i], | ||
"inversion at {} ({} followed by {})", | ||
i - 1, | ||
result[i - 1], | ||
result[i] | ||
); | ||
} | ||
} | ||
} | ||
|
||
fn edition_2021_around_2021() { | ||
let c = DropOrderCollector::default(); | ||
let _ = edition_2021_block! { | ||
let a = c.loud_drop(1); | ||
edition_2021_block! { | ||
let b = c.loud_drop(0); | ||
c.loud_drop(2).1 | ||
} | ||
}; | ||
c.assert_sorted(3); | ||
} | ||
|
||
fn edition_2021_around_2024() { | ||
let c = DropOrderCollector::default(); | ||
let _ = edition_2021_block! { | ||
let a = c.loud_drop(2); | ||
edition_2024_block! { | ||
let b = c.loud_drop(1); | ||
c.loud_drop(0).1 | ||
} | ||
}; | ||
c.assert_sorted(3); | ||
} | ||
|
||
fn edition_2024_around_2021() { | ||
let c = DropOrderCollector::default(); | ||
let _ = edition_2024_block! { | ||
let a = c.loud_drop(2); | ||
edition_2021_block! { | ||
let b = c.loud_drop(0); | ||
c.loud_drop(1).1 | ||
} | ||
}; | ||
c.assert_sorted(3); | ||
} | ||
|
||
fn edition_2024_around_2024() { | ||
let c = DropOrderCollector::default(); | ||
let _ = edition_2024_block! { | ||
let a = c.loud_drop(2); | ||
edition_2024_block! { | ||
let b = c.loud_drop(1); | ||
c.loud_drop(0).1 | ||
} | ||
}; | ||
c.assert_sorted(3); | ||
} | ||
|
||
fn main() { | ||
edition_2021_around_2021(); | ||
edition_2021_around_2024(); | ||
edition_2024_around_2021(); | ||
edition_2024_around_2024(); | ||
} |
8 changes: 8 additions & 0 deletions
8
tests/ui/feature-gates/feature-gate-shorter_tail_lifetimes.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
fn f() -> usize { | ||
let c = std::cell::RefCell::new(".."); | ||
c.borrow().len() //~ ERROR: `c` does not live long enough | ||
} | ||
|
||
fn main() { | ||
let _ = f(); | ||
} |
26 changes: 26 additions & 0 deletions
26
tests/ui/feature-gates/feature-gate-shorter_tail_lifetimes.stderr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
error[E0597]: `c` does not live long enough | ||
--> $DIR/feature-gate-shorter_tail_lifetimes.rs:3:5 | ||
| | ||
LL | let c = std::cell::RefCell::new(".."); | ||
| - binding `c` declared here | ||
LL | c.borrow().len() | ||
| ^--------- | ||
| | | ||
| borrowed value does not live long enough | ||
| a temporary with access to the borrow is created here ... | ||
LL | } | ||
| - | ||
| | | ||
| `c` dropped here while still borrowed | ||
| ... and the borrow might be used here, when that temporary is dropped and runs the destructor for type `Ref<'_, &str>` | ||
| | ||
= note: the temporary is part of an expression at the end of a block; | ||
consider forcing this temporary to be dropped sooner, before the block's local variables are dropped | ||
help: for example, you could save the expression's value in a new local variable `x` and then make `x` be the expression at the end of the block | ||
| | ||
LL | let x = c.borrow().len(); x | ||
| +++++++ +++ | ||
|
||
error: aborting due to 1 previous error | ||
|
||
For more information about this error, try `rustc --explain E0597`. |
26 changes: 26 additions & 0 deletions
26
tests/ui/lifetimes/refcell-in-tail-expr.edition2021.stderr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
error[E0597]: `cell` does not live long enough | ||
--> $DIR/refcell-in-tail-expr.rs:12:27 | ||
| | ||
LL | let cell = std::cell::RefCell::new(0u8); | ||
| ---- binding `cell` declared here | ||
LL | | ||
LL | if let Ok(mut byte) = cell.try_borrow_mut() { | ||
| ^^^^----------------- | ||
| | | ||
| borrowed value does not live long enough | ||
| a temporary with access to the borrow is created here ... | ||
... | ||
LL | } | ||
| - | ||
| | | ||
| `cell` dropped here while still borrowed | ||
| ... and the borrow might be used here, when that temporary is dropped and runs the destructor for type `Result<RefMut<'_, u8>, BorrowMutError>` | ||
| | ||
help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped | ||
| | ||
LL | }; | ||
| + | ||
|
||
error: aborting due to 1 previous error | ||
|
||
For more information about this error, try `rustc --explain E0597`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
//@ revisions: edition2021 edition2024 | ||
//@ [edition2021] edition: 2021 | ||
//@ [edition2024] edition: 2024 | ||
//@ [edition2024] compile-flags: -Zunstable-options | ||
//@ [edition2024] check-pass | ||
|
||
#![cfg_attr(edition2024, feature(shorter_tail_lifetimes))] | ||
|
||
fn main() { | ||
let cell = std::cell::RefCell::new(0u8); | ||
|
||
if let Ok(mut byte) = cell.try_borrow_mut() { | ||
//[edition2021]~^ ERROR: `cell` does not live long enough | ||
*byte = 1; | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
tests/ui/lifetimes/shorter-tail-expr-lifetime.edition2021.stderr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
error[E0597]: `c` does not live long enough | ||
--> $DIR/shorter-tail-expr-lifetime.rs:10:5 | ||
| | ||
LL | let c = std::cell::RefCell::new(".."); | ||
| - binding `c` declared here | ||
LL | c.borrow().len() | ||
| ^--------- | ||
| | | ||
| borrowed value does not live long enough | ||
| a temporary with access to the borrow is created here ... | ||
LL | } | ||
| - | ||
| | | ||
| `c` dropped here while still borrowed | ||
| ... and the borrow might be used here, when that temporary is dropped and runs the destructor for type `Ref<'_, &str>` | ||
| | ||
= note: the temporary is part of an expression at the end of a block; | ||
consider forcing this temporary to be dropped sooner, before the block's local variables are dropped | ||
help: for example, you could save the expression's value in a new local variable `x` and then make `x` be the expression at the end of the block | ||
| | ||
LL | let x = c.borrow().len(); x | ||
| +++++++ +++ | ||
|
||
error: aborting due to 1 previous error | ||
|
||
For more information about this error, try `rustc --explain E0597`. |
Oops, something went wrong.