Reintroduce into_future
in .await
desugaring
This is a reintroduction of the remaining parts from https://github.com/rust-lang/rust/pull/65244 that have not been relanded yet. Issues GH-67644, GH-67982
This commit is contained in:
parent
936f2600b6
commit
dfa0db5961
9 changed files with 91 additions and 9 deletions
|
@ -593,7 +593,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
|
|
||||||
/// Desugar `<expr>.await` into:
|
/// Desugar `<expr>.await` into:
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// match <expr> {
|
/// match ::std::future::IntoFuture::into_future(<expr>) {
|
||||||
/// mut pinned => loop {
|
/// mut pinned => loop {
|
||||||
/// match unsafe { ::std::future::Future::poll(
|
/// match unsafe { ::std::future::Future::poll(
|
||||||
/// <::std::pin::Pin>::new_unchecked(&mut pinned),
|
/// <::std::pin::Pin>::new_unchecked(&mut pinned),
|
||||||
|
@ -629,7 +629,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
await_span,
|
await_span,
|
||||||
self.allow_gen_future.clone(),
|
self.allow_gen_future.clone(),
|
||||||
);
|
);
|
||||||
let expr = self.lower_expr(expr);
|
let expr = self.lower_expr_mut(expr);
|
||||||
|
|
||||||
let pinned_ident = Ident::with_dummy_span(sym::pinned);
|
let pinned_ident = Ident::with_dummy_span(sym::pinned);
|
||||||
let (pinned_pat, pinned_pat_hid) =
|
let (pinned_pat, pinned_pat_hid) =
|
||||||
|
@ -746,10 +746,26 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
// mut pinned => loop { ... }
|
// mut pinned => loop { ... }
|
||||||
let pinned_arm = self.arm(pinned_pat, loop_expr);
|
let pinned_arm = self.arm(pinned_pat, loop_expr);
|
||||||
|
|
||||||
// match <expr> {
|
// `match ::std::future::IntoFuture::into_future(<expr>) { ... }`
|
||||||
// mut pinned => loop { .. }
|
let into_future_span = self.mark_span_with_reason(
|
||||||
|
DesugaringKind::Await,
|
||||||
|
await_span,
|
||||||
|
self.allow_into_future.clone(),
|
||||||
|
);
|
||||||
|
//let expr = self.lower_expr_mut(expr);
|
||||||
|
let into_future_expr = self.expr_call_lang_item_fn(
|
||||||
|
into_future_span,
|
||||||
|
hir::LangItem::IntoFutureIntoFuture,
|
||||||
|
arena_vec![self; expr],
|
||||||
|
);
|
||||||
|
|
||||||
|
// match <into_future_expr> { // mut pinned => loop { .. }
|
||||||
// }
|
// }
|
||||||
hir::ExprKind::Match(expr, arena_vec![self; pinned_arm], hir::MatchSource::AwaitDesugar)
|
hir::ExprKind::Match(
|
||||||
|
into_future_expr,
|
||||||
|
arena_vec![self; pinned_arm],
|
||||||
|
hir::MatchSource::AwaitDesugar,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_expr_closure(
|
fn lower_expr_closure(
|
||||||
|
|
|
@ -162,6 +162,7 @@ struct LoweringContext<'a, 'hir: 'a> {
|
||||||
|
|
||||||
allow_try_trait: Option<Lrc<[Symbol]>>,
|
allow_try_trait: Option<Lrc<[Symbol]>>,
|
||||||
allow_gen_future: Option<Lrc<[Symbol]>>,
|
allow_gen_future: Option<Lrc<[Symbol]>>,
|
||||||
|
allow_into_future: Option<Lrc<[Symbol]>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ResolverAstLowering {
|
pub trait ResolverAstLowering {
|
||||||
|
@ -320,6 +321,7 @@ pub fn lower_crate<'a, 'hir>(
|
||||||
in_scope_lifetimes: Vec::new(),
|
in_scope_lifetimes: Vec::new(),
|
||||||
allow_try_trait: Some([sym::try_trait_v2][..].into()),
|
allow_try_trait: Some([sym::try_trait_v2][..].into()),
|
||||||
allow_gen_future: Some([sym::gen_future][..].into()),
|
allow_gen_future: Some([sym::gen_future][..].into()),
|
||||||
|
allow_into_future: Some([sym::into_future][..].into()),
|
||||||
}
|
}
|
||||||
.lower_crate(krate)
|
.lower_crate(krate)
|
||||||
}
|
}
|
||||||
|
|
|
@ -347,6 +347,7 @@ language_item_table! {
|
||||||
ControlFlowContinue, sym::Continue, cf_continue_variant, Target::Variant, GenericRequirement::None;
|
ControlFlowContinue, sym::Continue, cf_continue_variant, Target::Variant, GenericRequirement::None;
|
||||||
ControlFlowBreak, sym::Break, cf_break_variant, Target::Variant, GenericRequirement::None;
|
ControlFlowBreak, sym::Break, cf_break_variant, Target::Variant, GenericRequirement::None;
|
||||||
|
|
||||||
|
IntoFutureIntoFuture, sym::into_future, into_future_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None;
|
||||||
IntoIterIntoIter, sym::into_iter, into_iter_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None;
|
IntoIterIntoIter, sym::into_iter, into_iter_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None;
|
||||||
IteratorNext, sym::next, next_fn, Target::Method(MethodKind::Trait { body: false}), GenericRequirement::None;
|
IteratorNext, sym::next, next_fn, Target::Method(MethodKind::Trait { body: false}), GenericRequirement::None;
|
||||||
|
|
||||||
|
|
|
@ -196,6 +196,7 @@ symbols! {
|
||||||
Implied,
|
Implied,
|
||||||
Input,
|
Input,
|
||||||
Into,
|
Into,
|
||||||
|
IntoFuture,
|
||||||
IntoIterator,
|
IntoIterator,
|
||||||
IoRead,
|
IoRead,
|
||||||
IoWrite,
|
IoWrite,
|
||||||
|
@ -734,6 +735,7 @@ symbols! {
|
||||||
inout,
|
inout,
|
||||||
instruction_set,
|
instruction_set,
|
||||||
intel,
|
intel,
|
||||||
|
into_future,
|
||||||
into_iter,
|
into_iter,
|
||||||
intra_doc_pointers,
|
intra_doc_pointers,
|
||||||
intrinsics,
|
intrinsics,
|
||||||
|
|
|
@ -13,6 +13,7 @@ pub trait IntoFuture {
|
||||||
|
|
||||||
/// Creates a future from a value.
|
/// Creates a future from a value.
|
||||||
#[unstable(feature = "into_future", issue = "67644")]
|
#[unstable(feature = "into_future", issue = "67644")]
|
||||||
|
#[cfg_attr(not(bootstrap), lang = "into_future")]
|
||||||
fn into_future(self) -> Self::Future;
|
fn into_future(self) -> Self::Future;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -112,7 +112,7 @@ async fn mixed_sizes() {
|
||||||
fn main() {
|
fn main() {
|
||||||
assert_eq!(1025, std::mem::size_of_val(&single()));
|
assert_eq!(1025, std::mem::size_of_val(&single()));
|
||||||
assert_eq!(1026, std::mem::size_of_val(&single_with_noop()));
|
assert_eq!(1026, std::mem::size_of_val(&single_with_noop()));
|
||||||
assert_eq!(3078, std::mem::size_of_val(&joined()));
|
assert_eq!(3076, std::mem::size_of_val(&joined()));
|
||||||
assert_eq!(3079, std::mem::size_of_val(&joined_with_noop()));
|
assert_eq!(3076, std::mem::size_of_val(&joined_with_noop()));
|
||||||
assert_eq!(7181, std::mem::size_of_val(&mixed_sizes()));
|
assert_eq!(6157, std::mem::size_of_val(&mixed_sizes()));
|
||||||
}
|
}
|
||||||
|
|
28
src/test/ui/async-await/await-into-future.rs
Normal file
28
src/test/ui/async-await/await-into-future.rs
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
// edition:2021
|
||||||
|
|
||||||
|
#![feature(into_future)]
|
||||||
|
|
||||||
|
use std::{future::{Future, IntoFuture}, pin::Pin};
|
||||||
|
|
||||||
|
struct AwaitMe;
|
||||||
|
|
||||||
|
impl IntoFuture for AwaitMe {
|
||||||
|
type Output = i32;
|
||||||
|
type Future = Pin<Box<dyn Future<Output = i32>>>;
|
||||||
|
|
||||||
|
fn into_future(self) -> Self::Future {
|
||||||
|
Box::pin(me())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn me() -> i32 {
|
||||||
|
41
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn run() {
|
||||||
|
assert_eq!(AwaitMe.await, 41);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -10,12 +10,20 @@ async fn foo() {
|
||||||
//~^ ERROR type inside `async fn` body must be known in this context
|
//~^ ERROR type inside `async fn` body must be known in this context
|
||||||
//~| ERROR type inside `async fn` body must be known in this context
|
//~| ERROR type inside `async fn` body must be known in this context
|
||||||
//~| ERROR type inside `async fn` body must be known in this context
|
//~| ERROR type inside `async fn` body must be known in this context
|
||||||
|
//~| ERROR type inside `async fn` body must be known in this context
|
||||||
|
//~| ERROR type inside `async fn` body must be known in this context
|
||||||
|
//~| NOTE cannot infer type for type parameter `T`
|
||||||
|
//~| NOTE cannot infer type for type parameter `T`
|
||||||
//~| NOTE cannot infer type for type parameter `T`
|
//~| NOTE cannot infer type for type parameter `T`
|
||||||
//~| NOTE cannot infer type for type parameter `T`
|
//~| NOTE cannot infer type for type parameter `T`
|
||||||
//~| NOTE cannot infer type for type parameter `T`
|
//~| NOTE cannot infer type for type parameter `T`
|
||||||
//~| NOTE the type is part of the `async fn` body because of this `await`
|
//~| NOTE the type is part of the `async fn` body because of this `await`
|
||||||
//~| NOTE the type is part of the `async fn` body because of this `await`
|
//~| NOTE the type is part of the `async fn` body because of this `await`
|
||||||
//~| NOTE the type is part of the `async fn` body because of this `await`
|
//~| NOTE the type is part of the `async fn` body because of this `await`
|
||||||
|
//~| NOTE the type is part of the `async fn` body because of this `await`
|
||||||
|
//~| NOTE the type is part of the `async fn` body because of this `await`
|
||||||
|
//~| NOTE in this expansion of desugaring of `await`
|
||||||
|
//~| NOTE in this expansion of desugaring of `await`
|
||||||
//~| NOTE in this expansion of desugaring of `await`
|
//~| NOTE in this expansion of desugaring of `await`
|
||||||
//~| NOTE in this expansion of desugaring of `await`
|
//~| NOTE in this expansion of desugaring of `await`
|
||||||
//~| NOTE in this expansion of desugaring of `await`
|
//~| NOTE in this expansion of desugaring of `await`
|
||||||
|
|
|
@ -34,6 +34,30 @@ note: the type is part of the `async fn` body because of this `await`
|
||||||
LL | bar().await;
|
LL | bar().await;
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error[E0698]: type inside `async fn` body must be known in this context
|
||||||
|
--> $DIR/unresolved_type_param.rs:9:5
|
||||||
|
|
|
||||||
|
LL | bar().await;
|
||||||
|
| ^^^ cannot infer type for type parameter `T` declared on the function `bar`
|
||||||
|
|
|
||||||
|
note: the type is part of the `async fn` body because of this `await`
|
||||||
|
--> $DIR/unresolved_type_param.rs:9:5
|
||||||
|
|
|
||||||
|
LL | bar().await;
|
||||||
|
| ^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0698]: type inside `async fn` body must be known in this context
|
||||||
|
--> $DIR/unresolved_type_param.rs:9:5
|
||||||
|
|
|
||||||
|
LL | bar().await;
|
||||||
|
| ^^^ cannot infer type for type parameter `T` declared on the function `bar`
|
||||||
|
|
|
||||||
|
note: the type is part of the `async fn` body because of this `await`
|
||||||
|
--> $DIR/unresolved_type_param.rs:9:5
|
||||||
|
|
|
||||||
|
LL | bar().await;
|
||||||
|
| ^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0698`.
|
For more information about this error, try `rustc --explain E0698`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue