mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
Rollup merge of #64292 - davidtwco:issue-63832-await-temporary-lifetimes, r=matthewjasper
lowering: extend temporary lifetimes around await Fixes #63832. r? @matthewjasper cc @nikomatsakis
This commit is contained in:
commit
a1755dfbc7
@ -507,14 +507,13 @@ impl LoweringContext<'_> {
|
||||
|
||||
/// Desugar `<expr>.await` into:
|
||||
/// ```rust
|
||||
/// {
|
||||
/// let mut pinned = <expr>;
|
||||
/// loop {
|
||||
/// match <expr> {
|
||||
/// mut pinned => loop {
|
||||
/// match ::std::future::poll_with_tls_context(unsafe {
|
||||
/// ::std::pin::Pin::new_unchecked(&mut pinned)
|
||||
/// <::std::pin::Pin>::new_unchecked(&mut pinned)
|
||||
/// }) {
|
||||
/// ::std::task::Poll::Ready(result) => break result,
|
||||
/// ::std::task::Poll::Pending => {},
|
||||
/// ::std::task::Poll::Pending => {}
|
||||
/// }
|
||||
/// yield ();
|
||||
/// }
|
||||
@ -549,21 +548,12 @@ impl LoweringContext<'_> {
|
||||
self.allow_gen_future.clone(),
|
||||
);
|
||||
|
||||
// let mut pinned = <expr>;
|
||||
let expr = P(self.lower_expr(expr));
|
||||
let pinned_ident = Ident::with_dummy_span(sym::pinned);
|
||||
let (pinned_pat, pinned_pat_hid) = self.pat_ident_binding_mode(
|
||||
span,
|
||||
pinned_ident,
|
||||
hir::BindingAnnotation::Mutable,
|
||||
);
|
||||
let pinned_let = self.stmt_let_pat(
|
||||
ThinVec::new(),
|
||||
span,
|
||||
Some(expr),
|
||||
pinned_pat,
|
||||
hir::LocalSource::AwaitDesugar,
|
||||
);
|
||||
|
||||
// ::std::future::poll_with_tls_context(unsafe {
|
||||
// ::std::pin::Pin::new_unchecked(&mut pinned)
|
||||
@ -621,7 +611,7 @@ impl LoweringContext<'_> {
|
||||
self.arm(hir_vec![pending_pat], empty_block)
|
||||
};
|
||||
|
||||
let match_stmt = {
|
||||
let inner_match_stmt = {
|
||||
let match_expr = self.expr_match(
|
||||
span,
|
||||
poll_expr,
|
||||
@ -643,10 +633,11 @@ impl LoweringContext<'_> {
|
||||
|
||||
let loop_block = P(self.block_all(
|
||||
span,
|
||||
hir_vec![match_stmt, yield_stmt],
|
||||
hir_vec![inner_match_stmt, yield_stmt],
|
||||
None,
|
||||
));
|
||||
|
||||
// loop { .. }
|
||||
let loop_expr = P(hir::Expr {
|
||||
hir_id: loop_hir_id,
|
||||
node: hir::ExprKind::Loop(
|
||||
@ -658,10 +649,14 @@ impl LoweringContext<'_> {
|
||||
attrs: ThinVec::new(),
|
||||
});
|
||||
|
||||
hir::ExprKind::Block(
|
||||
P(self.block_all(span, hir_vec![pinned_let], Some(loop_expr))),
|
||||
None,
|
||||
)
|
||||
// mut pinned => loop { ... }
|
||||
let pinned_arm = self.arm(hir_vec![pinned_pat], loop_expr);
|
||||
|
||||
// match <expr> {
|
||||
// mut pinned => loop { .. }
|
||||
// }
|
||||
let expr = P(self.lower_expr(expr));
|
||||
hir::ExprKind::Match(expr, hir_vec![pinned_arm], hir::MatchSource::AwaitDesugar)
|
||||
}
|
||||
|
||||
fn lower_expr_closure(
|
||||
|
@ -9,9 +9,9 @@ LL | assert_send(local_dropped_before_await());
|
||||
|
|
||||
= help: within `impl std::future::Future`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<()>`
|
||||
= note: required because it appears within the type `impl std::fmt::Debug`
|
||||
= note: required because it appears within the type `{impl std::fmt::Debug, impl std::future::Future, ()}`
|
||||
= note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:21:39: 26:2 {impl std::fmt::Debug, impl std::future::Future, ()}]`
|
||||
= note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:21:39: 26:2 {impl std::fmt::Debug, impl std::future::Future, ()}]>`
|
||||
= note: required because it appears within the type `{impl std::fmt::Debug, fn() -> impl std::future::Future {fut}, impl std::future::Future, ()}`
|
||||
= note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:21:39: 26:2 {impl std::fmt::Debug, fn() -> impl std::future::Future {fut}, impl std::future::Future, ()}]`
|
||||
= note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:21:39: 26:2 {impl std::fmt::Debug, fn() -> impl std::future::Future {fut}, impl std::future::Future, ()}]>`
|
||||
= note: required because it appears within the type `impl std::future::Future`
|
||||
= note: required because it appears within the type `impl std::future::Future`
|
||||
|
||||
@ -26,9 +26,9 @@ LL | assert_send(non_send_temporary_in_match());
|
||||
|
|
||||
= help: within `impl std::future::Future`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<()>`
|
||||
= note: required because it appears within the type `impl std::fmt::Debug`
|
||||
= note: required because it appears within the type `{fn(impl std::fmt::Debug) -> std::option::Option<impl std::fmt::Debug> {std::option::Option::<impl std::fmt::Debug>::Some}, fn() -> impl std::fmt::Debug {non_send}, impl std::fmt::Debug, std::option::Option<impl std::fmt::Debug>, impl std::future::Future, ()}`
|
||||
= note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:28:40: 37:2 {fn(impl std::fmt::Debug) -> std::option::Option<impl std::fmt::Debug> {std::option::Option::<impl std::fmt::Debug>::Some}, fn() -> impl std::fmt::Debug {non_send}, impl std::fmt::Debug, std::option::Option<impl std::fmt::Debug>, impl std::future::Future, ()}]`
|
||||
= note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:28:40: 37:2 {fn(impl std::fmt::Debug) -> std::option::Option<impl std::fmt::Debug> {std::option::Option::<impl std::fmt::Debug>::Some}, fn() -> impl std::fmt::Debug {non_send}, impl std::fmt::Debug, std::option::Option<impl std::fmt::Debug>, impl std::future::Future, ()}]>`
|
||||
= note: required because it appears within the type `{fn(impl std::fmt::Debug) -> std::option::Option<impl std::fmt::Debug> {std::option::Option::<impl std::fmt::Debug>::Some}, fn() -> impl std::fmt::Debug {non_send}, impl std::fmt::Debug, std::option::Option<impl std::fmt::Debug>, fn() -> impl std::future::Future {fut}, impl std::future::Future, ()}`
|
||||
= note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:28:40: 37:2 {fn(impl std::fmt::Debug) -> std::option::Option<impl std::fmt::Debug> {std::option::Option::<impl std::fmt::Debug>::Some}, fn() -> impl std::fmt::Debug {non_send}, impl std::fmt::Debug, std::option::Option<impl std::fmt::Debug>, fn() -> impl std::future::Future {fut}, impl std::future::Future, ()}]`
|
||||
= note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:28:40: 37:2 {fn(impl std::fmt::Debug) -> std::option::Option<impl std::fmt::Debug> {std::option::Option::<impl std::fmt::Debug>::Some}, fn() -> impl std::fmt::Debug {non_send}, impl std::fmt::Debug, std::option::Option<impl std::fmt::Debug>, fn() -> impl std::future::Future {fut}, impl std::future::Future, ()}]>`
|
||||
= note: required because it appears within the type `impl std::future::Future`
|
||||
= note: required because it appears within the type `impl std::future::Future`
|
||||
|
||||
@ -45,9 +45,9 @@ LL | assert_send(non_sync_with_method_call());
|
||||
= note: required because of the requirements on the impl of `std::marker::Send` for `&mut dyn std::fmt::Write`
|
||||
= note: required because it appears within the type `std::fmt::Formatter<'_>`
|
||||
= note: required because of the requirements on the impl of `std::marker::Send` for `&mut std::fmt::Formatter<'_>`
|
||||
= note: required because it appears within the type `for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}`
|
||||
= note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:39:38: 45:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}]`
|
||||
= note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:39:38: 45:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}]>`
|
||||
= note: required because it appears within the type `for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, fn() -> impl std::future::Future {fut}, impl std::future::Future, ()}`
|
||||
= note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:39:38: 45:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, fn() -> impl std::future::Future {fut}, impl std::future::Future, ()}]`
|
||||
= note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:39:38: 45:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, fn() -> impl std::future::Future {fut}, impl std::future::Future, ()}]>`
|
||||
= note: required because it appears within the type `impl std::future::Future`
|
||||
= note: required because it appears within the type `impl std::future::Future`
|
||||
|
||||
@ -68,9 +68,9 @@ LL | assert_send(non_sync_with_method_call());
|
||||
= note: required because of the requirements on the impl of `std::marker::Send` for `std::slice::Iter<'_, std::fmt::ArgumentV1<'_>>`
|
||||
= note: required because it appears within the type `std::fmt::Formatter<'_>`
|
||||
= note: required because of the requirements on the impl of `std::marker::Send` for `&mut std::fmt::Formatter<'_>`
|
||||
= note: required because it appears within the type `for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}`
|
||||
= note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:39:38: 45:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}]`
|
||||
= note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:39:38: 45:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}]>`
|
||||
= note: required because it appears within the type `for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, fn() -> impl std::future::Future {fut}, impl std::future::Future, ()}`
|
||||
= note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:39:38: 45:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, fn() -> impl std::future::Future {fut}, impl std::future::Future, ()}]`
|
||||
= note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:39:38: 45:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, fn() -> impl std::future::Future {fut}, impl std::future::Future, ()}]>`
|
||||
= note: required because it appears within the type `impl std::future::Future`
|
||||
= note: required because it appears within the type `impl std::future::Future`
|
||||
|
||||
|
@ -0,0 +1,19 @@
|
||||
// check-pass
|
||||
// edition:2018
|
||||
|
||||
struct Test(String);
|
||||
|
||||
impl Test {
|
||||
async fn borrow_async(&self) {}
|
||||
|
||||
fn with(&mut self, s: &str) -> &mut Self {
|
||||
self.0 = s.into();
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
async fn test() {
|
||||
Test("".to_string()).with("123").borrow_async().await;
|
||||
}
|
||||
|
||||
fn main() { }
|
@ -0,0 +1,12 @@
|
||||
// check-pass
|
||||
// edition:2018
|
||||
|
||||
async fn foo(x: &[Vec<u32>]) -> u32 {
|
||||
0
|
||||
}
|
||||
|
||||
async fn bar() {
|
||||
foo(&[vec![123]]).await;
|
||||
}
|
||||
|
||||
fn main() { }
|
Loading…
Reference in New Issue
Block a user