Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 4e4d49d

Browse files
committedApr 16, 2020
Auto merge of #70831 - sfackler:shrink-future-stack, r=matthewjasper
Remove a stack frame from .await calls The stack frames when `.await`ing one async fn from another currently look like this: ``` 12: foo::b::{{closure}} at src/main.rs:2 13: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll at /home/sfackler/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libcore/future/mod.rs:66 14: core::future::poll_with_context at /home/sfackler/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libcore/future/mod.rs:84 15: foo::a::{{closure}} at src/main.rs:6 ``` Since the move away from using TLS to pass the Context around, it's now easy to remove frame 14 by removing poll_with_context in favor of calling Future::poll directly. This still leaves the `GenFuture` frame, but that seems significantly harder to deal with. It also improves diagnostics a bit since they no longer talk about the private poll_with_context function.
2 parents 534a41a + 3ba3bd5 commit 4e4d49d

File tree

5 files changed

+40
-25
lines changed

5 files changed

+40
-25
lines changed
 

‎src/libcore/future/mod.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,6 @@ where
7777
#[unstable(feature = "gen_future", issue = "50547")]
7878
#[cfg(not(bootstrap))]
7979
#[inline]
80-
pub unsafe fn poll_with_context<F>(f: Pin<&mut F>, mut cx: ResumeTy) -> Poll<F::Output>
81-
where
82-
F: Future,
83-
{
84-
F::poll(f, cx.0.as_mut())
80+
pub unsafe fn get_context<'a, 'b>(cx: ResumeTy) -> &'a mut Context<'b> {
81+
&mut *cx.0.as_ptr().cast()
8582
}

‎src/librustc_ast_lowering/expr.rs

+34-11
Original file line numberDiff line numberDiff line change
@@ -556,9 +556,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
556556
/// ```rust
557557
/// match <expr> {
558558
/// mut pinned => loop {
559-
/// match unsafe { ::std::future::poll_with_context(
559+
/// match unsafe { ::std::future::Future::poll(
560560
/// <::std::pin::Pin>::new_unchecked(&mut pinned),
561-
/// task_context,
561+
/// ::std::future::get_context(task_context),
562562
/// ) } {
563563
/// ::std::task::Poll::Ready(result) => break result,
564564
/// ::std::task::Poll::Pending => {}
@@ -599,9 +599,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
599599
let task_context_ident = Ident::with_dummy_span(sym::_task_context);
600600

601601
// unsafe {
602-
// ::std::future::poll_with_context(
602+
// ::std::future::Future::poll(
603603
// ::std::pin::Pin::new_unchecked(&mut pinned),
604-
// task_context,
604+
// ::std::future::get_context(task_context),
605605
// )
606606
// }
607607
let poll_expr = {
@@ -622,10 +622,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
622622
arena_vec![self; ref_mut_pinned],
623623
);
624624
let new_unchecked = self.expr(span, new_unchecked_expr_kind, ThinVec::new());
625-
let call = self.expr_call_std_path(
625+
let get_context = self.expr_call_std_path_mut(
626626
gen_future_span,
627-
&[sym::future, sym::poll_with_context],
628-
arena_vec![self; new_unchecked, task_context],
627+
&[sym::future, sym::get_context],
628+
arena_vec![self; task_context],
629+
);
630+
let call = self.expr_call_std_path(
631+
span,
632+
&[sym::future, sym::Future, sym::poll],
633+
arena_vec![self; new_unchecked, get_context],
629634
);
630635
self.arena.alloc(self.expr_unsafe(call))
631636
};
@@ -1326,25 +1331,43 @@ impl<'hir> LoweringContext<'_, 'hir> {
13261331
self.arena.alloc(self.expr(sp, hir::ExprKind::Tup(&[]), ThinVec::new()))
13271332
}
13281333

1334+
fn expr_call_mut(
1335+
&mut self,
1336+
span: Span,
1337+
e: &'hir hir::Expr<'hir>,
1338+
args: &'hir [hir::Expr<'hir>],
1339+
) -> hir::Expr<'hir> {
1340+
self.expr(span, hir::ExprKind::Call(e, args), ThinVec::new())
1341+
}
1342+
13291343
fn expr_call(
13301344
&mut self,
13311345
span: Span,
13321346
e: &'hir hir::Expr<'hir>,
13331347
args: &'hir [hir::Expr<'hir>],
13341348
) -> &'hir hir::Expr<'hir> {
1335-
self.arena.alloc(self.expr(span, hir::ExprKind::Call(e, args), ThinVec::new()))
1349+
self.arena.alloc(self.expr_call_mut(span, e, args))
13361350
}
13371351

13381352
// Note: associated functions must use `expr_call_std_path`.
1339-
fn expr_call_std_path(
1353+
fn expr_call_std_path_mut(
13401354
&mut self,
13411355
span: Span,
13421356
path_components: &[Symbol],
13431357
args: &'hir [hir::Expr<'hir>],
1344-
) -> &'hir hir::Expr<'hir> {
1358+
) -> hir::Expr<'hir> {
13451359
let path =
13461360
self.arena.alloc(self.expr_std_path(span, path_components, None, ThinVec::new()));
1347-
self.expr_call(span, path, args)
1361+
self.expr_call_mut(span, path, args)
1362+
}
1363+
1364+
fn expr_call_std_path(
1365+
&mut self,
1366+
span: Span,
1367+
path_components: &[Symbol],
1368+
args: &'hir [hir::Expr<'hir>],
1369+
) -> &'hir hir::Expr<'hir> {
1370+
self.arena.alloc(self.expr_call_std_path_mut(span, path_components, args))
13481371
}
13491372

13501373
// Create an expression calling an associated function of an std type.

‎src/librustc_span/symbol.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,7 @@ symbols! {
348348
generators,
349349
generic_associated_types,
350350
generic_param_attrs,
351+
get_context,
351352
global_allocator,
352353
global_asm,
353354
globs,
@@ -547,8 +548,8 @@ symbols! {
547548
plugin,
548549
plugin_registrar,
549550
plugins,
551+
poll,
550552
Poll,
551-
poll_with_context,
552553
powerpc_target_feature,
553554
precise_pointer_size_matching,
554555
pref_align_of,

‎src/test/ui/async-await/issue-70594.stderr

+1-4
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,8 @@ error[E0277]: the trait bound `(): std::future::Future` is not satisfied
3232
|
3333
LL | [1; ().await];
3434
| ^^^^^^^^ the trait `std::future::Future` is not implemented for `()`
35-
|
36-
::: $SRC_DIR/libcore/future/mod.rs:LL:COL
3735
|
38-
LL | F: Future,
39-
| ------ required by this bound in `std::future::poll_with_context`
36+
= note: required by `std::future::Future::poll`
4037

4138
error: aborting due to 5 previous errors
4239

‎src/test/ui/async-await/issues/issue-62009-1.stderr

+1-4
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,8 @@ error[E0277]: the trait bound `[closure@$DIR/issue-62009-1.rs:12:5: 12:15]: std:
3232
|
3333
LL | (|_| 2333).await;
3434
| ^^^^^^^^^^^^^^^^ the trait `std::future::Future` is not implemented for `[closure@$DIR/issue-62009-1.rs:12:5: 12:15]`
35-
|
36-
::: $SRC_DIR/libcore/future/mod.rs:LL:COL
3735
|
38-
LL | F: Future,
39-
| ------ required by this bound in `std::future::poll_with_context`
36+
= note: required by `std::future::Future::poll`
4037

4138
error: aborting due to 4 previous errors
4239

0 commit comments

Comments
 (0)