Auto merge of #104833 - Swatinem:async-identity-future, r=compiler-errors

Remove `identity_future` indirection

This was previously needed because the indirection used to hide some unexplained lifetime errors, which it turned out were related to the `min_choice` algorithm.

Removing the indirection also solves a couple of cycle errors, large moves and makes async blocks support the `#[track_caller]`annotation.

Fixes https://github.com/rust-lang/rust/issues/104826.
This commit is contained in:
bors 2023-03-14 10:12:58 +00:00
commit 669e751639
32 changed files with 149 additions and 361 deletions

View File

@ -32,7 +32,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> {
ensure_sufficient_stack(|| {
match &e.kind {
// Paranthesis expression does not have a HirId and is handled specially.
// Parenthesis expression does not have a HirId and is handled specially.
ExprKind::Paren(ex) => {
let mut ex = self.lower_expr_mut(ex);
// Include parens in span, but only if it is a super-span.
@ -63,6 +63,20 @@ impl<'hir> LoweringContext<'_, 'hir> {
ExprKind::ForLoop(pat, head, body, opt_label) => {
return self.lower_expr_for(e, pat, head, body, *opt_label);
}
// Similarly, async blocks do not use `e.id` but rather `closure_node_id`.
ExprKind::Async(capture_clause, closure_node_id, block) => {
let hir_id = self.lower_node_id(*closure_node_id);
self.lower_attrs(hir_id, &e.attrs);
return self.make_async_expr(
*capture_clause,
hir_id,
*closure_node_id,
None,
e.span,
hir::AsyncGeneratorKind::Block,
|this| this.with_new_scopes(|this| this.lower_block_expr(block)),
);
}
_ => (),
}
@ -173,15 +187,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.arena.alloc_from_iter(arms.iter().map(|x| self.lower_arm(x))),
hir::MatchSource::Normal,
),
ExprKind::Async(capture_clause, closure_node_id, block) => self.make_async_expr(
*capture_clause,
hir_id,
*closure_node_id,
None,
e.span,
hir::AsyncGeneratorKind::Block,
|this| this.with_new_scopes(|this| this.lower_block_expr(block)),
),
ExprKind::Await(expr) => {
let dot_await_span = if expr.span.hi() < e.span.hi() {
let span_with_whitespace = self
@ -315,7 +320,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
),
ExprKind::Try(sub_expr) => self.lower_expr_try(e.span, sub_expr),
ExprKind::Paren(_) | ExprKind::ForLoop(..) => unreachable!("already handled"),
ExprKind::Paren(_) | ExprKind::ForLoop(..) | ExprKind::Async(..) => {
unreachable!("already handled")
}
ExprKind::MacCall(_) => panic!("{:?} shouldn't exist here", e.span),
};
@ -577,9 +584,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
/// This results in:
///
/// ```text
/// std::future::identity_future(static move? |_task_context| -> <ret_ty> {
/// static move? |_task_context| -> <ret_ty> {
/// <body>
/// })
/// }
/// ```
pub(super) fn make_async_expr(
&mut self,
@ -590,7 +597,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
span: Span,
async_gen_kind: hir::AsyncGeneratorKind,
body: impl FnOnce(&mut Self) -> hir::Expr<'hir>,
) -> hir::ExprKind<'hir> {
) -> hir::Expr<'hir> {
let output = ret_ty.unwrap_or_else(|| hir::FnRetTy::DefaultReturn(self.lower_span(span)));
// Resume argument type: `ResumeTy`
@ -655,13 +662,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
};
let hir_id = self.lower_node_id(closure_node_id);
let unstable_span =
self.mark_span_with_reason(DesugaringKind::Async, span, self.allow_gen_future.clone());
if self.tcx.features().closure_track_caller
&& let Some(attrs) = self.attrs.get(&outer_hir_id.local_id)
&& attrs.into_iter().any(|attr| attr.has_name(sym::track_caller))
{
let unstable_span =
self.mark_span_with_reason(DesugaringKind::Async, span, self.allow_gen_future.clone());
self.lower_attrs(
hir_id,
&[Attribute {
@ -680,22 +686,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
);
}
let generator = hir::Expr { hir_id, kind: generator_kind, span: self.lower_span(span) };
// FIXME(swatinem):
// For some reason, the async block needs to flow through *any*
// call (like the identity function), as otherwise type and lifetime
// inference have a hard time figuring things out.
// Without this, we would get:
// E0720 in tests/ui/impl-trait/in-trait/default-body-with-rpit.rs
// E0700 in tests/ui/self/self_lifetime-async.rs
// `future::identity_future`:
let identity_future =
self.expr_lang_item_path(unstable_span, hir::LangItem::IdentityFuture, None);
// `future::identity_future(generator)`:
hir::ExprKind::Call(self.arena.alloc(identity_future), arena_vec![self; generator])
hir::Expr { hir_id, kind: generator_kind, span: self.lower_span(span) }
}
/// Desugar `<expr>.await` into:
@ -1001,7 +992,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
// Transform `async |x: u8| -> X { ... }` into
// `|x: u8| identity_future(|| -> X { ... })`.
// `|x: u8| || -> X { ... }`.
let body_id = this.lower_fn_body(&outer_decl, |this| {
let async_ret_ty = if let FnRetTy::Ty(ty) = &decl.output {
let itctx = ImplTraitContext::Disallowed(ImplTraitPosition::AsyncBlock);
@ -1010,7 +1001,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
None
};
let async_body = this.make_async_expr(
this.make_async_expr(
capture_clause,
closure_hir_id,
inner_closure_id,
@ -1018,8 +1009,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
body.span,
hir::AsyncGeneratorKind::Closure,
|this| this.with_new_scopes(|this| this.lower_expr_mut(body)),
);
this.expr(fn_decl_span, async_body)
)
});
body_id
});

View File

@ -1180,7 +1180,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
},
);
(this.arena.alloc_from_iter(parameters), this.expr(body.span, async_expr))
(this.arena.alloc_from_iter(parameters), async_expr)
})
}

View File

@ -296,7 +296,6 @@ language_item_table! {
// FIXME(swatinem): the following lang items are used for async lowering and
// should become obsolete eventually.
ResumeTy, sym::ResumeTy, resume_ty, Target::Struct, GenericRequirement::None;
IdentityFuture, sym::identity_future, identity_future_fn, Target::Fn, GenericRequirement::None;
GetContext, sym::get_context, get_context_fn, Target::Fn, GenericRequirement::None;
Context, sym::Context, context, Target::Struct, GenericRequirement::None;

View File

@ -311,9 +311,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let fn_decl_span = if hir.body(body).generator_kind
== Some(hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Closure))
{
// Actually need to unwrap a few more layers of HIR to get to
// Actually need to unwrap one more layer of HIR to get to
// the _real_ closure...
let async_closure = hir.parent_id(hir.parent_id(parent_hir_id));
let async_closure = hir.parent_id(parent_hir_id);
if let hir::Node::Expr(hir::Expr {
kind: hir::ExprKind::Closure(&hir::Closure { fn_decl_span, .. }),
..

View File

@ -924,12 +924,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
hir_id,
kind: hir::ExprKind::Closure(..),
..
}) if let Some(Node::Expr(&hir::Expr {
hir_id,
kind: hir::ExprKind::Call(..),
..
})) = self.tcx.hir().find_parent(hir_id) &&
let Some(Node::Item(&hir::Item {
}) if let Some(Node::Item(&hir::Item {
ident,
kind: hir::ItemKind::Fn(ref sig, ..),
..

View File

@ -792,7 +792,6 @@ symbols! {
i64,
i8,
ident,
identity_future,
if_let,
if_let_guard,
if_while_or_patterns,

View File

@ -3033,8 +3033,6 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
}
};
let identity_future = tcx.require_lang_item(LangItem::IdentityFuture, None);
// Don't print the tuple of capture types
'print: {
if !is_upvar_tys_infer_tuple {
@ -3047,12 +3045,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
None => err.note(&msg),
},
ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) => {
// Avoid printing the future from `core::future::identity_future`, it's not helpful
if tcx.parent(*def_id) == identity_future {
break 'print;
}
// If the previous type is `identity_future`, this is the future generated by the body of an async function.
// If the previous type is async fn, this is the future generated by the body of an async function.
// Avoid printing it twice (it was already printed in the `ty::Generator` arm below).
let is_future = tcx.ty_is_opaque_future(ty);
debug!(

View File

@ -67,14 +67,10 @@ pub unsafe fn get_context<'a, 'b>(cx: ResumeTy) -> &'a mut Context<'b> {
unsafe { &mut *cx.0.as_ptr().cast() }
}
// FIXME(swatinem): This fn is currently needed to work around shortcomings
// in type and lifetime inference.
// See the comment at the bottom of `LoweringContext::make_async_expr` and
// <https://github.com/rust-lang/rust/issues/104826>.
#[doc(hidden)]
#[unstable(feature = "gen_future", issue = "50547")]
#[inline]
#[lang = "identity_future"]
#[cfg_attr(bootstrap, lang = "identity_future")]
pub const fn identity_future<O, Fut: Future<Output = O>>(f: Fut) -> Fut {
f
}

View File

@ -1,5 +1,4 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::match_function_call_with_def_id;
use clippy_utils::source::{position_before_rarrow, snippet_block, snippet_opt};
use if_chain::if_chain;
use rustc_errors::Applicability;
@ -175,16 +174,10 @@ fn captures_all_lifetimes(inputs: &[Ty<'_>], output_lifetimes: &[LifetimeName])
fn desugared_async_block<'tcx>(cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) -> Option<&'tcx Body<'tcx>> {
if_chain! {
if let Some(block_expr) = block.expr;
if let Some(args) = cx
.tcx
.lang_items()
.identity_future_fn()
.and_then(|def_id| match_function_call_with_def_id(cx, block_expr, def_id));
if args.len() == 1;
if let Expr {
kind: ExprKind::Closure(&Closure { body, .. }),
..
} = args[0];
} = block_expr;
let closure_body = cx.tcx.hir().body(body);
if closure_body.generator_kind == Some(GeneratorKind::Async(AsyncGeneratorKind::Block));
then {

View File

@ -1904,16 +1904,7 @@ pub fn is_async_fn(kind: FnKind<'_>) -> bool {
/// Peels away all the compiler generated code surrounding the body of an async function,
pub fn get_async_fn_body<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'_>) -> Option<&'tcx Expr<'tcx>> {
if let ExprKind::Call(
_,
&[
Expr {
kind: ExprKind::Closure(&Closure { body, .. }),
..
},
],
) = body.value.kind
{
if let ExprKind::Closure(&Closure { body, .. }) = body.value.kind {
if let ExprKind::Block(
Block {
stmts: [],

View File

@ -43,11 +43,7 @@ if let ExprKind::Block(block, None) = expr.kind
if let ExprKind::Closure(CaptureBy::Value, fn_decl, body_id, _, None) = expr.kind
&& let FnRetTy::DefaultReturn(_) = fn_decl.output
&& expr1 = &cx.tcx.hir().body(body_id).value
&& let ExprKind::Call(func, args) = expr1.kind
&& let ExprKind::Path(ref qpath) = func.kind
&& matches!(qpath, QPath::LangItem(LangItem::IdentityFuture, _))
&& args.len() == 1
&& let ExprKind::Closure(CaptureBy::Value, fn_decl1, body_id1, _, Some(Movability::Static)) = args[0].kind
&& let ExprKind::Closure(CaptureBy::Value, fn_decl1, body_id1, _, Some(Movability::Static)) = expr1.kind
&& let FnRetTy::DefaultReturn(_) = fn_decl1.output
&& expr2 = &cx.tcx.hir().body(body_id1).value
&& let ExprKind::Block(block, None) = expr2.kind

View File

@ -4,7 +4,7 @@
_0: GeneratorSavedTy {
ty: impl std::future::Future<Output = ()>,
source_info: SourceInfo {
span: $DIR/async_await.rs:15:8: 15:14 (#9),
span: $DIR/async_await.rs:15:8: 15:14 (#8),
scope: scope[0],
},
ignore_for_traits: false,
@ -12,7 +12,7 @@
_1: GeneratorSavedTy {
ty: impl std::future::Future<Output = ()>,
source_info: SourceInfo {
span: $DIR/async_await.rs:16:8: 16:14 (#12),
span: $DIR/async_await.rs:16:8: 16:14 (#11),
scope: scope[0],
},
ignore_for_traits: false,

View File

@ -2,16 +2,18 @@ error[E0308]: mismatched types
--> $DIR/generator-desc.rs:10:19
|
LL | fun(async {}, async {});
| -------- ^^^^^^^^
| | |
| | expected `async` block, found a different `async` block
| | arguments to this function are incorrect
| the expected `async` block
| --- -------- ^^^^^^^^ expected `async` block, found a different `async` block
| | |
| | the expected `async` block
| arguments to this function are incorrect
|
= note: expected `async` block `[async block@$DIR/generator-desc.rs:10:9: 10:17]`
found `async` block `[async block@$DIR/generator-desc.rs:10:19: 10:27]`
note: function defined here
--> $SRC_DIR/core/src/future/mod.rs:LL:COL
--> $DIR/generator-desc.rs:8:4
|
LL | fn fun<F: Future<Output = ()>>(f1: F, f2: F) {}
| ^^^ -----
error[E0308]: mismatched types
--> $DIR/generator-desc.rs:12:16

View File

@ -1,22 +1,3 @@
error: moving 10024 bytes
--> $DIR/large_moves.rs:13:13
|
LL | let x = async {
| _____________^
LL | | let y = [0; 9999];
LL | | dbg!(y);
LL | | thing(&y).await;
LL | | dbg!(y);
LL | | };
| |_____^ value moved from here
|
= note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]`
note: the lint level is defined here
--> $DIR/large_moves.rs:1:9
|
LL | #![deny(large_assignments)]
| ^^^^^^^^^^^^^^^^^
error: moving 10024 bytes
--> $DIR/large_moves.rs:19:14
|
@ -24,6 +5,11 @@ LL | let z = (x, 42);
| ^ value moved from here
|
= note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]`
note: the lint level is defined here
--> $DIR/large_moves.rs:1:9
|
LL | #![deny(large_assignments)]
| ^^^^^^^^^^^^^^^^^
error: moving 10024 bytes
--> $DIR/large_moves.rs:19:13
@ -41,5 +27,5 @@ LL | let a = z.0;
|
= note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]`
error: aborting due to 4 previous errors
error: aborting due to 3 previous errors

View File

@ -1,22 +1,3 @@
error: moving 10024 bytes
--> $DIR/large_moves.rs:13:13
|
LL | let x = async {
| _____________^
LL | | let y = [0; 9999];
LL | | dbg!(y);
LL | | thing(&y).await;
LL | | dbg!(y);
LL | | };
| |_____^ value moved from here
|
= note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]`
note: the lint level is defined here
--> $DIR/large_moves.rs:1:9
|
LL | #![deny(large_assignments)]
| ^^^^^^^^^^^^^^^^^
error: moving 10024 bytes
--> $DIR/large_moves.rs:19:14
|
@ -24,6 +5,11 @@ LL | let z = (x, 42);
| ^ value moved from here
|
= note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]`
note: the lint level is defined here
--> $DIR/large_moves.rs:1:9
|
LL | #![deny(large_assignments)]
| ^^^^^^^^^^^^^^^^^
error: moving 10024 bytes
--> $DIR/large_moves.rs:19:13
@ -41,5 +27,5 @@ LL | let a = z.0;
|
= note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]`
error: aborting due to 4 previous errors
error: aborting due to 3 previous errors

View File

@ -10,7 +10,7 @@
// compile-flags: -Zmir-opt-level=0
fn main() {
let x = async { //~ ERROR large_assignments
let x = async {
let y = [0; 9999];
dbg!(y);
thing(&y).await;

View File

@ -3,4 +3,3 @@
pub const async fn x() {}
//~^ ERROR functions cannot be both `const` and `async`
//~| ERROR cycle detected

View File

@ -7,36 +7,5 @@ LL | pub const async fn x() {}
| | `async` because of this
| `const` because of this
error[E0391]: cycle detected when computing type of `x::{opaque#0}`
--> $DIR/no-const-async.rs:4:24
|
LL | pub const async fn x() {}
| ^
|
note: ...which requires borrow-checking `x`...
--> $DIR/no-const-async.rs:4:1
|
LL | pub const async fn x() {}
| ^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires processing MIR for `x`...
--> $DIR/no-const-async.rs:4:1
|
LL | pub const async fn x() {}
| ^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires const checking `x`...
--> $DIR/no-const-async.rs:4:1
|
LL | pub const async fn x() {}
| ^^^^^^^^^^^^^^^^^^^^^^
= note: ...which requires computing whether `x::{opaque#0}` is freeze...
= note: ...which requires evaluating trait selection obligation `x::{opaque#0}: core::marker::Freeze`...
= note: ...which again requires computing type of `x::{opaque#0}`, completing the cycle
note: cycle used when checking item types in top-level module
--> $DIR/no-const-async.rs:4:1
|
LL | pub const async fn x() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0391`.

View File

@ -1,9 +1,9 @@
// edition:2021
#![feature(closure_track_caller, stmt_expr_attributes)]
#![feature(stmt_expr_attributes)]
fn main() {
let _ = #[track_caller] async {
//~^ ERROR attribute should be applied to a function definition [E0739]
//~^ ERROR `#[track_caller]` on closures is currently unstable [E0658]
};
}

View File

@ -1,12 +1,12 @@
error[E0739]: attribute should be applied to a function definition
error[E0658]: `#[track_caller]` on closures is currently unstable
--> $DIR/async-block.rs:6:13
|
LL | let _ = #[track_caller] async {
| _____________^^^^^^^^^^^^^^^_-
LL | |
LL | | };
| |_____- not a function definition
LL | let _ = #[track_caller] async {
| ^^^^^^^^^^^^^^^
|
= note: see issue #87417 <https://github.com/rust-lang/rust/issues/87417> for more information
= help: add `#![feature(closure_track_caller)]` to the crate attributes to enable
error: aborting due to previous error
For more information about this error, try `rustc --explain E0739`.
For more information about this error, try `rustc --explain E0658`.

View File

@ -79,6 +79,16 @@ async fn foo_closure() {
c().await
}
// Since compilation is expected to fail for this fn when using
// `nofeat`, we test that separately in `async-block.rs`
#[cfg(feat)]
async fn foo_block() {
let a = #[track_caller] async {
panic!();
};
a.await
}
fn panicked_at(f: impl FnOnce() + panic::UnwindSafe) -> u32 {
let loc = Arc::new(Mutex::new(None));
@ -110,4 +120,7 @@ fn main() {
#[cfg(feat)]
assert_eq!(panicked_at(|| block_on(foo_closure())), 79);
#[cfg(feat)]
assert_eq!(panicked_at(|| block_on(foo_block())), 89);
}

View File

@ -4,7 +4,7 @@
// compile-flags:-Z trait-solver=chalk
// error-pattern:internal compiler error
// failure-status:101
// normalize-stderr-test "DefId([^)]*)" -> "..."
// normalize-stderr-test "DefId\([^)]*\)" -> "..."
// normalize-stderr-test "\nerror: internal compiler error.*\n\n" -> ""
// normalize-stderr-test "note:.*unexpectedly panicked.*\n\n" -> ""
// normalize-stderr-test "note: we would appreciate a bug report.*\n\n" -> ""

View File

@ -1,33 +1,3 @@
error[E0277]: `[async fn body@$DIR/async.rs:23:29: 25:2]` is not a future
--> $DIR/async.rs:23:29
|
LL | async fn foo(x: u32) -> u32 {
| _____________________________-
LL | | x
LL | | }
| | ^
| | |
| |_`[async fn body@$DIR/async.rs:23:29: 25:2]` is not a future
| required by a bound introduced by this call
|
= help: the trait `Future` is not implemented for `[async fn body@$DIR/async.rs:23:29: 25:2]`
= note: [async fn body@$DIR/async.rs:23:29: 25:2] must be a future or must implement `IntoFuture` to be awaited
note: required by a bound in `identity_future`
--> $SRC_DIR/core/src/future/mod.rs:LL:COL
error[E0277]: the size for values of type `<[async fn body@$DIR/async.rs:23:29: 25:2] as Future>::Output` cannot be known at compilation time
--> $DIR/async.rs:23:29
|
LL | async fn foo(x: u32) -> u32 {
| _____________________________^
LL | | x
LL | | }
| |_^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `<[async fn body@$DIR/async.rs:23:29: 25:2] as Future>::Output`
note: required by a bound in `identity_future`
--> $SRC_DIR/core/src/future/mod.rs:LL:COL
error[E0277]: `[async fn body@$DIR/async.rs:23:29: 25:2]` is not a future
--> $DIR/async.rs:23:25
|
@ -37,7 +7,7 @@ LL | async fn foo(x: u32) -> u32 {
= help: the trait `Future` is not implemented for `[async fn body@$DIR/async.rs:23:29: 25:2]`
= note: [async fn body@$DIR/async.rs:23:29: 25:2] must be a future or must implement `IntoFuture` to be awaited
error: internal compiler error: projection clauses should be implied from elsewhere. obligation: `Obligation(predicate=Binder(ProjectionPredicate(AliasTy { substs: [[async fn body@$DIR/async.rs:23:29: 25:2]], def_id: ...) }, Term::Ty(u32)), []), depth=0)`
error: internal compiler error: projection clauses should be implied from elsewhere. obligation: `Obligation(predicate=Binder(ProjectionPredicate(AliasTy { substs: [[async fn body@$DIR/async.rs:23:29: 25:2]], def_id: ... }, Term::Ty(u32)), []), depth=0)`
--> $DIR/async.rs:23:25
|
LL | async fn foo(x: u32) -> u32 {
@ -53,6 +23,6 @@ LL | async fn foo(x: u32) -> u32 {
#8 [check_mod_item_types] checking item types in top-level module
#9 [analysis] running analysis passes on this crate
end of query stack
error: aborting due to 4 previous errors
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0277`.

View File

@ -1,7 +1,9 @@
// edition:2021
#![feature(stmt_expr_attributes)]
#![feature(generators)]
fn main() {
let _closure = #[track_caller] || {}; //~ `#[track_caller]` on closures
let _generator = #[track_caller] || { yield; }; //~ `#[track_caller]` on closures
let _future = #[track_caller] async {}; //~ `#[track_caller]` on closures
}

View File

@ -1,5 +1,5 @@
error[E0658]: `#[track_caller]` on closures is currently unstable
--> $DIR/feature-gate-closure_track_caller.rs:5:20
--> $DIR/feature-gate-closure_track_caller.rs:6:20
|
LL | let _closure = #[track_caller] || {};
| ^^^^^^^^^^^^^^^
@ -8,7 +8,7 @@ LL | let _closure = #[track_caller] || {};
= help: add `#![feature(closure_track_caller)]` to the crate attributes to enable
error[E0658]: `#[track_caller]` on closures is currently unstable
--> $DIR/feature-gate-closure_track_caller.rs:6:22
--> $DIR/feature-gate-closure_track_caller.rs:7:22
|
LL | let _generator = #[track_caller] || { yield; };
| ^^^^^^^^^^^^^^^
@ -16,6 +16,15 @@ LL | let _generator = #[track_caller] || { yield; };
= note: see issue #87417 <https://github.com/rust-lang/rust/issues/87417> for more information
= help: add `#![feature(closure_track_caller)]` to the crate attributes to enable
error: aborting due to 2 previous errors
error[E0658]: `#[track_caller]` on closures is currently unstable
--> $DIR/feature-gate-closure_track_caller.rs:8:19
|
LL | let _future = #[track_caller] async {};
| ^^^^^^^^^^^^^^^
|
= note: see issue #87417 <https://github.com/rust-lang/rust/issues/87417> for more information
= help: add `#![feature(closure_track_caller)]` to the crate attributes to enable
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0658`.

View File

@ -1,5 +1,5 @@
// check-pass
// edition:2021
// known-bug: #108304
#![feature(async_fn_in_trait, return_position_impl_trait_in_trait)]
#![allow(incomplete_features)]

View File

@ -0,0 +1,24 @@
error: concrete type differs from previous defining opaque type use
--> $DIR/default-body-with-rpit.rs:11:9
|
LL | ""
| ^^ expected `impl Debug`, got `&'static str`
|
note: previous use here
--> $DIR/default-body-with-rpit.rs:10:39
|
LL | async fn baz(&self) -> impl Debug {
| _______________________________________^
LL | | ""
LL | | }
| |_____^
error[E0720]: cannot resolve opaque type
--> $DIR/default-body-with-rpit.rs:10:28
|
LL | async fn baz(&self) -> impl Debug {
| ^^^^^^^^^^ cannot resolve opaque type
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0720`.

View File

@ -12,7 +12,6 @@ struct Bug {
}
let f: F = async { 1 };
//~^ ERROR `async` blocks are not allowed in constants
//~| ERROR destructor of
1
}],
}

View File

@ -7,22 +7,13 @@ LL | let f: F = async { 1 };
= note: see issue #85368 <https://github.com/rust-lang/rust/issues/85368> for more information
= help: add `#![feature(const_async_blocks)]` to the crate attributes to enable
error[E0493]: destructor of `F` cannot be evaluated at compile-time
--> $DIR/issue-78722.rs:13:13
|
LL | let f: F = async { 1 };
| ^ the destructor for this type cannot be evaluated in constants
...
LL | }],
| - value is dropped here
error[E0271]: expected `[async block@$DIR/issue-78722.rs:11:13: 11:21]` to be a future that resolves to `u8`, but it resolves to `()`
--> $DIR/issue-78722.rs:9:30
|
LL | fn concrete_use() -> F {
| ^ expected `()`, found `u8`
error: aborting due to 3 previous errors
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0271, E0493, E0658.
Some errors have detailed explanations: E0271, E0658.
For more information about an error, try `rustc --explain E0271`.

View File

@ -11,7 +11,6 @@ fn main() {
extern "C" fn ff4() {} // OK.
const async unsafe extern "C" fn ff5() {}
//~^ ERROR functions cannot be both `const` and `async`
//~| ERROR cycle detected
trait X {
async fn ft1(); //~ ERROR functions in traits cannot be declared `async`
@ -34,7 +33,6 @@ fn main() {
//~^ ERROR functions in traits cannot be declared `async`
//~| ERROR functions in traits cannot be declared const
//~| ERROR functions cannot be both `const` and `async`
//~| ERROR cycle detected
}
impl Y {
@ -44,7 +42,6 @@ fn main() {
extern "C" fn fi4() {} // OK.
const async unsafe extern "C" fn fi5() {}
//~^ ERROR functions cannot be both `const` and `async`
//~| ERROR cycle detected
}
extern "C" {

View File

@ -8,19 +8,19 @@ LL | const async unsafe extern "C" fn ff5() {}
| `const` because of this
error[E0379]: functions in traits cannot be declared const
--> $DIR/fn-header-semantic-fail.rs:19:9
--> $DIR/fn-header-semantic-fail.rs:18:9
|
LL | const fn ft3();
| ^^^^^ functions in traits cannot be const
error[E0379]: functions in traits cannot be declared const
--> $DIR/fn-header-semantic-fail.rs:21:9
--> $DIR/fn-header-semantic-fail.rs:20:9
|
LL | const async unsafe extern "C" fn ft5();
| ^^^^^ functions in traits cannot be const
error: functions cannot be both `const` and `async`
--> $DIR/fn-header-semantic-fail.rs:21:9
--> $DIR/fn-header-semantic-fail.rs:20:9
|
LL | const async unsafe extern "C" fn ft5();
| ^^^^^-^^^^^----------------------------
@ -29,19 +29,19 @@ LL | const async unsafe extern "C" fn ft5();
| `const` because of this
error[E0379]: functions in traits cannot be declared const
--> $DIR/fn-header-semantic-fail.rs:31:9
--> $DIR/fn-header-semantic-fail.rs:30:9
|
LL | const fn ft3() {}
| ^^^^^ functions in traits cannot be const
error[E0379]: functions in traits cannot be declared const
--> $DIR/fn-header-semantic-fail.rs:33:9
--> $DIR/fn-header-semantic-fail.rs:32:9
|
LL | const async unsafe extern "C" fn ft5() {}
| ^^^^^ functions in traits cannot be const
error: functions cannot be both `const` and `async`
--> $DIR/fn-header-semantic-fail.rs:33:9
--> $DIR/fn-header-semantic-fail.rs:32:9
|
LL | const async unsafe extern "C" fn ft5() {}
| ^^^^^-^^^^^------------------------------
@ -50,7 +50,7 @@ LL | const async unsafe extern "C" fn ft5() {}
| `const` because of this
error: functions cannot be both `const` and `async`
--> $DIR/fn-header-semantic-fail.rs:45:9
--> $DIR/fn-header-semantic-fail.rs:43:9
|
LL | const async unsafe extern "C" fn fi5() {}
| ^^^^^-^^^^^------------------------------
@ -59,7 +59,7 @@ LL | const async unsafe extern "C" fn fi5() {}
| `const` because of this
error: functions in `extern` blocks cannot have qualifiers
--> $DIR/fn-header-semantic-fail.rs:51:18
--> $DIR/fn-header-semantic-fail.rs:48:18
|
LL | extern "C" {
| ---------- in this `extern` block
@ -72,7 +72,7 @@ LL | fn fe1();
| ~~
error: functions in `extern` blocks cannot have qualifiers
--> $DIR/fn-header-semantic-fail.rs:52:19
--> $DIR/fn-header-semantic-fail.rs:49:19
|
LL | extern "C" {
| ---------- in this `extern` block
@ -86,7 +86,7 @@ LL | fn fe2();
| ~~
error: functions in `extern` blocks cannot have qualifiers
--> $DIR/fn-header-semantic-fail.rs:53:18
--> $DIR/fn-header-semantic-fail.rs:50:18
|
LL | extern "C" {
| ---------- in this `extern` block
@ -100,7 +100,7 @@ LL | fn fe3();
| ~~
error: functions in `extern` blocks cannot have qualifiers
--> $DIR/fn-header-semantic-fail.rs:54:23
--> $DIR/fn-header-semantic-fail.rs:51:23
|
LL | extern "C" {
| ---------- in this `extern` block
@ -114,7 +114,7 @@ LL | fn fe4();
| ~~
error: functions in `extern` blocks cannot have qualifiers
--> $DIR/fn-header-semantic-fail.rs:55:42
--> $DIR/fn-header-semantic-fail.rs:52:42
|
LL | extern "C" {
| ---------- in this `extern` block
@ -128,7 +128,7 @@ LL | fn fe5();
| ~~
error: functions cannot be both `const` and `async`
--> $DIR/fn-header-semantic-fail.rs:55:9
--> $DIR/fn-header-semantic-fail.rs:52:9
|
LL | const async unsafe extern "C" fn fe5();
| ^^^^^-^^^^^----------------------------
@ -137,7 +137,7 @@ LL | const async unsafe extern "C" fn fe5();
| `const` because of this
error[E0706]: functions in traits cannot be declared `async`
--> $DIR/fn-header-semantic-fail.rs:17:9
--> $DIR/fn-header-semantic-fail.rs:16:9
|
LL | async fn ft1();
| -----^^^^^^^^^^
@ -150,7 +150,7 @@ LL | async fn ft1();
= help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
error[E0706]: functions in traits cannot be declared `async`
--> $DIR/fn-header-semantic-fail.rs:21:9
--> $DIR/fn-header-semantic-fail.rs:20:9
|
LL | const async unsafe extern "C" fn ft5();
| ^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -163,7 +163,7 @@ LL | const async unsafe extern "C" fn ft5();
= help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
error[E0706]: functions in traits cannot be declared `async`
--> $DIR/fn-header-semantic-fail.rs:29:9
--> $DIR/fn-header-semantic-fail.rs:28:9
|
LL | async fn ft1() {}
| -----^^^^^^^^^
@ -176,7 +176,7 @@ LL | async fn ft1() {}
= help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
error[E0706]: functions in traits cannot be declared `async`
--> $DIR/fn-header-semantic-fail.rs:33:9
--> $DIR/fn-header-semantic-fail.rs:32:9
|
LL | const async unsafe extern "C" fn ft5() {}
| ^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -188,115 +188,7 @@ LL | const async unsafe extern "C" fn ft5() {}
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
= help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
error[E0391]: cycle detected when computing type of `main::ff5::{opaque#0}`
--> $DIR/fn-header-semantic-fail.rs:12:44
|
LL | const async unsafe extern "C" fn ff5() {}
| ^
|
note: ...which requires borrow-checking `main::ff5`...
--> $DIR/fn-header-semantic-fail.rs:12:5
|
LL | const async unsafe extern "C" fn ff5() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires processing MIR for `main::ff5`...
--> $DIR/fn-header-semantic-fail.rs:12:5
|
LL | const async unsafe extern "C" fn ff5() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires const checking `main::ff5`...
--> $DIR/fn-header-semantic-fail.rs:12:5
|
LL | const async unsafe extern "C" fn ff5() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...which requires computing whether `main::ff5::{opaque#0}` is freeze...
= note: ...which requires evaluating trait selection obligation `main::ff5::{opaque#0}: core::marker::Freeze`...
= note: ...which again requires computing type of `main::ff5::{opaque#0}`, completing the cycle
note: cycle used when checking item types in top-level module
--> $DIR/fn-header-semantic-fail.rs:5:1
|
LL | / #![feature(const_extern_fn)]
LL | |
LL | | fn main() {
LL | | async fn ff1() {} // OK.
... |
LL | | }
LL | | }
| |_^
error: aborting due to 18 previous errors
error[E0391]: cycle detected when computing type of `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 28:17>::ft5::{opaque#0}`
--> $DIR/fn-header-semantic-fail.rs:33:48
|
LL | const async unsafe extern "C" fn ft5() {}
| ^
|
note: ...which requires borrow-checking `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 28:17>::ft5`...
--> $DIR/fn-header-semantic-fail.rs:33:9
|
LL | const async unsafe extern "C" fn ft5() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires processing MIR for `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 28:17>::ft5`...
--> $DIR/fn-header-semantic-fail.rs:33:9
|
LL | const async unsafe extern "C" fn ft5() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires const checking `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 28:17>::ft5`...
--> $DIR/fn-header-semantic-fail.rs:33:9
|
LL | const async unsafe extern "C" fn ft5() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...which requires computing whether `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 28:17>::ft5::{opaque#0}` is freeze...
= note: ...which requires evaluating trait selection obligation `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 28:17>::ft5::{opaque#0}: core::marker::Freeze`...
= note: ...which again requires computing type of `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 28:17>::ft5::{opaque#0}`, completing the cycle
note: cycle used when checking item types in top-level module
--> $DIR/fn-header-semantic-fail.rs:5:1
|
LL | / #![feature(const_extern_fn)]
LL | |
LL | | fn main() {
LL | | async fn ff1() {} // OK.
... |
LL | | }
LL | | }
| |_^
error[E0391]: cycle detected when computing type of `main::<impl at $DIR/fn-header-semantic-fail.rs:40:5: 40:11>::fi5::{opaque#0}`
--> $DIR/fn-header-semantic-fail.rs:45:48
|
LL | const async unsafe extern "C" fn fi5() {}
| ^
|
note: ...which requires borrow-checking `main::<impl at $DIR/fn-header-semantic-fail.rs:40:5: 40:11>::fi5`...
--> $DIR/fn-header-semantic-fail.rs:45:9
|
LL | const async unsafe extern "C" fn fi5() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires processing MIR for `main::<impl at $DIR/fn-header-semantic-fail.rs:40:5: 40:11>::fi5`...
--> $DIR/fn-header-semantic-fail.rs:45:9
|
LL | const async unsafe extern "C" fn fi5() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires const checking `main::<impl at $DIR/fn-header-semantic-fail.rs:40:5: 40:11>::fi5`...
--> $DIR/fn-header-semantic-fail.rs:45:9
|
LL | const async unsafe extern "C" fn fi5() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...which requires computing whether `main::<impl at $DIR/fn-header-semantic-fail.rs:40:5: 40:11>::fi5::{opaque#0}` is freeze...
= note: ...which requires evaluating trait selection obligation `main::<impl at $DIR/fn-header-semantic-fail.rs:40:5: 40:11>::fi5::{opaque#0}: core::marker::Freeze`...
= note: ...which again requires computing type of `main::<impl at $DIR/fn-header-semantic-fail.rs:40:5: 40:11>::fi5::{opaque#0}`, completing the cycle
note: cycle used when checking item types in top-level module
--> $DIR/fn-header-semantic-fail.rs:5:1
|
LL | / #![feature(const_extern_fn)]
LL | |
LL | | fn main() {
LL | | async fn ff1() {} // OK.
... |
LL | | }
LL | | }
| |_^
error: aborting due to 21 previous errors
Some errors have detailed explanations: E0379, E0391, E0706.
Some errors have detailed explanations: E0379, E0706.
For more information about an error, try `rustc --explain E0379`.

View File

@ -69,18 +69,15 @@ note: required by a bound in `Pin::<P>::new`
error[E0308]: mismatched types
--> $DIR/expected-boxed-future-isnt-pinned.rs:28:5
|
LL | fn zap() -> BoxFuture<'static, i32> {
| ----------------------- expected `Pin<Box<(dyn Future<Output = i32> + Send + 'static)>>` because of return type
LL | / async {
LL | | 42
LL | | }
| | ^
| | |
| |_____expected `Pin<Box<...>>`, found `async` block
| arguments to this function are incorrect
| |_____^ expected `Pin<Box<...>>`, found `async` block
|
= note: expected struct `Pin<Box<dyn Future<Output = i32> + Send>>`
= note: expected struct `Pin<Box<(dyn Future<Output = i32> + Send + 'static)>>`
found `async` block `[async block@$DIR/expected-boxed-future-isnt-pinned.rs:28:5: 30:6]`
note: function defined here
--> $SRC_DIR/core/src/future/mod.rs:LL:COL
help: you need to pin and box this expression
|
LL ~ Box::pin(async {