Code change:
The following code was working in nightly-2019-09-05, but no longer works in nightly-2019-10-15. The workaround is not quite intuitive. () Errors: <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
I'm also running into this error using Tide and a DB Pool from Diesel I've managed to get a slightly simpler/different version of the above code - I'd expect this to work because I'd expect the to be finished before the starts (I guess it's similar to how pre-NLL we'd expect function calls in arguments to work but sometimes they wouldn't because existing borrows?) I've managed to track it down to happening somewhere between these - but I'm not sure how to go about figuring this out any further (I've never built the compiler, let alone actually debugged it) This successfully buildsThis fails
This was an intentional change to match the drop order in synchronous code:
This was an intentional change but these errors also look like they are caused by "overapproximation" of the set of captured values. We are working to improve that; separately, we are also working on improving the diagnostics here.
Assigning to myself as this is a case I'd hope to tackle in . It isn't currently handled by that PR, as the current diagnostic improvements only work when the error originates from an , not . claim
I found a similar problem: Is this the same bug?
Unassigning myself since has landed.
adds a compiler message to suggest a workaround for this problem. Is it not possible to make the compiler smarter and not borrow unnecessary variables across ?
rustc is not that smarter yet, we already have an issue tracking this , along with were trying to lint users with "shorten" workaround(might be lifted once the analysis is improved) in these two "common" cases.
It's a matter of having consistent language semantics for async and non-async code. The lang team discussed this and decided the drop order should be consistent (i.e. we shouldn't drop temporaries until the end of the statement, even if the statement contains ).

Related discussion:
text: if let Some(expr_id) = expr { let expr = hir.expect_expr(expr_id); <del> let is_ref = tables.expr_adjustments(expr).iter().any(|adj| adj.is_region_borrow()); </del> <ins> debug!("target_ty evaluated from {:?}", expr); </ins> let parent = hir.get_parent_node(expr_id); if let Some(hir::Node::Expr(e)) = hir.find(parent) { <del> let method_span = hir.span(parent); if tables.is_method_call(e) && is_ref { </del> <ins> let parent_span = hir.span(parent); let parent_did = parent.owner_def_id(); // ```rust // impl T { //     fn foo(&self) -> i32 {} // } // T.foo(); // ^^^^^^^ a temporary `&T` created inside this method call due to `&self` // ``` // let is_region_borrow = tables.expr_adjustments(expr).iter().any(|adj| adj.is_region_borrow()); // ```rust // struct Foo(*const u8); // bar(Foo(std::ptr::null())).await; //     ^^^^^^^^^^^^^^^^^^^^^ raw-ptr `*T` created inside this struct ctor. // ``` debug!("parent_def_kind: {:?}", self.tcx.def_kind(parent_did)); let is_raw_borrow_inside_fn_like_call = match self.tcx.def_kind(parent_did) { Some(DefKind::Fn) | Some(DefKind::Ctor(..)) => target_ty.is_unsafe_ptr(), _ => false, }; if (tables.is_method_call(e) && is_region_borrow) || is_raw_borrow_inside_fn_like_call { </ins> err.span_help( <del> method_span, "consider moving this method call into a `let`  </del> <ins> parent_span, "consider moving this into a `let`  </ins> binding to create a shorter lived borrow", ); }