Skip to content

Commit dfa0db5

Browse files
committed
Reintroduce into_future in .await desugaring
This is a reintroduction of the remaining parts from rust-lang#65244 that have not been relanded yet. Issues rust-langGH-67644, rust-langGH-67982
1 parent 936f260 commit dfa0db5

File tree

9 files changed

+91
-9
lines changed

9 files changed

+91
-9
lines changed

compiler/rustc_ast_lowering/src/expr.rs

+21-5
Original file line numberDiff line numberDiff line change
@@ -593,7 +593,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
593593

594594
/// Desugar `<expr>.await` into:
595595
/// ```rust
596-
/// match <expr> {
596+
/// match ::std::future::IntoFuture::into_future(<expr>) {
597597
/// mut pinned => loop {
598598
/// match unsafe { ::std::future::Future::poll(
599599
/// <::std::pin::Pin>::new_unchecked(&mut pinned),
@@ -629,7 +629,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
629629
await_span,
630630
self.allow_gen_future.clone(),
631631
);
632-
let expr = self.lower_expr(expr);
632+
let expr = self.lower_expr_mut(expr);
633633

634634
let pinned_ident = Ident::with_dummy_span(sym::pinned);
635635
let (pinned_pat, pinned_pat_hid) =
@@ -746,10 +746,26 @@ impl<'hir> LoweringContext<'_, 'hir> {
746746
// mut pinned => loop { ... }
747747
let pinned_arm = self.arm(pinned_pat, loop_expr);
748748

749-
// match <expr> {
750-
// mut pinned => loop { .. }
749+
// `match ::std::future::IntoFuture::into_future(<expr>) { ... }`
750+
let into_future_span = self.mark_span_with_reason(
751+
DesugaringKind::Await,
752+
await_span,
753+
self.allow_into_future.clone(),
754+
);
755+
//let expr = self.lower_expr_mut(expr);
756+
let into_future_expr = self.expr_call_lang_item_fn(
757+
into_future_span,
758+
hir::LangItem::IntoFutureIntoFuture,
759+
arena_vec![self; expr],
760+
);
761+
762+
// match <into_future_expr> { // mut pinned => loop { .. }
751763
// }
752-
hir::ExprKind::Match(expr, arena_vec![self; pinned_arm], hir::MatchSource::AwaitDesugar)
764+
hir::ExprKind::Match(
765+
into_future_expr,
766+
arena_vec![self; pinned_arm],
767+
hir::MatchSource::AwaitDesugar,
768+
)
753769
}
754770

755771
fn lower_expr_closure(

compiler/rustc_ast_lowering/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ struct LoweringContext<'a, 'hir: 'a> {
162162

163163
allow_try_trait: Option<Lrc<[Symbol]>>,
164164
allow_gen_future: Option<Lrc<[Symbol]>>,
165+
allow_into_future: Option<Lrc<[Symbol]>>,
165166
}
166167

167168
pub trait ResolverAstLowering {
@@ -320,6 +321,7 @@ pub fn lower_crate<'a, 'hir>(
320321
in_scope_lifetimes: Vec::new(),
321322
allow_try_trait: Some([sym::try_trait_v2][..].into()),
322323
allow_gen_future: Some([sym::gen_future][..].into()),
324+
allow_into_future: Some([sym::into_future][..].into()),
323325
}
324326
.lower_crate(krate)
325327
}

compiler/rustc_hir/src/lang_items.rs

+1
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,7 @@ language_item_table! {
347347
ControlFlowContinue, sym::Continue, cf_continue_variant, Target::Variant, GenericRequirement::None;
348348
ControlFlowBreak, sym::Break, cf_break_variant, Target::Variant, GenericRequirement::None;
349349

350+
IntoFutureIntoFuture, sym::into_future, into_future_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None;
350351
IntoIterIntoIter, sym::into_iter, into_iter_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None;
351352
IteratorNext, sym::next, next_fn, Target::Method(MethodKind::Trait { body: false}), GenericRequirement::None;
352353

compiler/rustc_span/src/symbol.rs

+2
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ symbols! {
196196
Implied,
197197
Input,
198198
Into,
199+
IntoFuture,
199200
IntoIterator,
200201
IoRead,
201202
IoWrite,
@@ -734,6 +735,7 @@ symbols! {
734735
inout,
735736
instruction_set,
736737
intel,
738+
into_future,
737739
into_iter,
738740
intra_doc_pointers,
739741
intrinsics,

library/core/src/future/into_future.rs

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ pub trait IntoFuture {
1313

1414
/// Creates a future from a value.
1515
#[unstable(feature = "into_future", issue = "67644")]
16+
#[cfg_attr(not(bootstrap), lang = "into_future")]
1617
fn into_future(self) -> Self::Future;
1718
}
1819

src/test/ui/async-await/async-fn-size-moved-locals.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ async fn mixed_sizes() {
112112
fn main() {
113113
assert_eq!(1025, std::mem::size_of_val(&single()));
114114
assert_eq!(1026, std::mem::size_of_val(&single_with_noop()));
115-
assert_eq!(3078, std::mem::size_of_val(&joined()));
116-
assert_eq!(3079, std::mem::size_of_val(&joined_with_noop()));
117-
assert_eq!(7181, std::mem::size_of_val(&mixed_sizes()));
115+
assert_eq!(3076, std::mem::size_of_val(&joined()));
116+
assert_eq!(3076, std::mem::size_of_val(&joined_with_noop()));
117+
assert_eq!(6157, std::mem::size_of_val(&mixed_sizes()));
118118
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// check-pass
2+
3+
// edition:2021
4+
5+
#![feature(into_future)]
6+
7+
use std::{future::{Future, IntoFuture}, pin::Pin};
8+
9+
struct AwaitMe;
10+
11+
impl IntoFuture for AwaitMe {
12+
type Output = i32;
13+
type Future = Pin<Box<dyn Future<Output = i32>>>;
14+
15+
fn into_future(self) -> Self::Future {
16+
Box::pin(me())
17+
}
18+
}
19+
20+
async fn me() -> i32 {
21+
41
22+
}
23+
24+
async fn run() {
25+
assert_eq!(AwaitMe.await, 41);
26+
}
27+
28+
fn main() {}

src/test/ui/async-await/unresolved_type_param.rs

+8
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,20 @@ async fn foo() {
1010
//~^ ERROR type inside `async fn` body must be known in this context
1111
//~| ERROR type inside `async fn` body must be known in this context
1212
//~| ERROR type inside `async fn` body must be known in this context
13+
//~| ERROR type inside `async fn` body must be known in this context
14+
//~| ERROR type inside `async fn` body must be known in this context
15+
//~| NOTE cannot infer type for type parameter `T`
16+
//~| NOTE cannot infer type for type parameter `T`
1317
//~| NOTE cannot infer type for type parameter `T`
1418
//~| NOTE cannot infer type for type parameter `T`
1519
//~| NOTE cannot infer type for type parameter `T`
1620
//~| NOTE the type is part of the `async fn` body because of this `await`
1721
//~| NOTE the type is part of the `async fn` body because of this `await`
1822
//~| NOTE the type is part of the `async fn` body because of this `await`
23+
//~| NOTE the type is part of the `async fn` body because of this `await`
24+
//~| NOTE the type is part of the `async fn` body because of this `await`
25+
//~| NOTE in this expansion of desugaring of `await`
26+
//~| NOTE in this expansion of desugaring of `await`
1927
//~| NOTE in this expansion of desugaring of `await`
2028
//~| NOTE in this expansion of desugaring of `await`
2129
//~| NOTE in this expansion of desugaring of `await`

src/test/ui/async-await/unresolved_type_param.stderr

+25-1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,30 @@ note: the type is part of the `async fn` body because of this `await`
3434
LL | bar().await;
3535
| ^^^^^^^^^^^
3636

37-
error: aborting due to 3 previous errors
37+
error[E0698]: type inside `async fn` body must be known in this context
38+
--> $DIR/unresolved_type_param.rs:9:5
39+
|
40+
LL | bar().await;
41+
| ^^^ cannot infer type for type parameter `T` declared on the function `bar`
42+
|
43+
note: the type is part of the `async fn` body because of this `await`
44+
--> $DIR/unresolved_type_param.rs:9:5
45+
|
46+
LL | bar().await;
47+
| ^^^^^^^^^^^
48+
49+
error[E0698]: type inside `async fn` body must be known in this context
50+
--> $DIR/unresolved_type_param.rs:9:5
51+
|
52+
LL | bar().await;
53+
| ^^^ cannot infer type for type parameter `T` declared on the function `bar`
54+
|
55+
note: the type is part of the `async fn` body because of this `await`
56+
--> $DIR/unresolved_type_param.rs:9:5
57+
|
58+
LL | bar().await;
59+
| ^^^^^^^^^^^
60+
61+
error: aborting due to 5 previous errors
3862

3963
For more information about this error, try `rustc --explain E0698`.

0 commit comments

Comments
 (0)