mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 23:34:48 +00:00
Rollup merge of #71174 - Nokel81:fix-async-main-error, r=petrochenkov
Check that main/start is not async * Add new error code E0752 * Add span to hir::IsAsync::Yes * Emit an error if main or the start function is marked as async * Add two regression tests This PR fixes #68523.
This commit is contained in:
commit
e3a514c44a
@ -431,6 +431,7 @@ E0748: include_str!("./error_codes/E0748.md"),
|
||||
E0749: include_str!("./error_codes/E0749.md"),
|
||||
E0750: include_str!("./error_codes/E0750.md"),
|
||||
E0751: include_str!("./error_codes/E0751.md"),
|
||||
E0752: include_str!("./error_codes/E0752.md"),
|
||||
;
|
||||
// E0006, // merged with E0005
|
||||
// E0008, // cannot bind by-move into a pattern guard
|
||||
|
11
src/librustc_error_codes/error_codes/E0752.md
Normal file
11
src/librustc_error_codes/error_codes/E0752.md
Normal file
@ -0,0 +1,11 @@
|
||||
`fn main()` or the specified start function is not allowed to be
|
||||
async. You might be seeing this error because your async runtime
|
||||
library is not set up correctly.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0752
|
||||
async fn main() -> Result<i32, ()> {
|
||||
Ok(1)
|
||||
}
|
||||
```
|
@ -82,10 +82,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
match &node {
|
||||
hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, _, body_id), .. }) => {
|
||||
self.describe_generator(*body_id).or_else(|| {
|
||||
Some(if let hir::FnHeader { asyncness: hir::IsAsync::Async, .. } = sig.header {
|
||||
"an async function"
|
||||
} else {
|
||||
"a function"
|
||||
Some(match sig.header {
|
||||
hir::FnHeader { asyncness: hir::IsAsync::Async, .. } => "an async function",
|
||||
_ => "a function",
|
||||
})
|
||||
})
|
||||
}
|
||||
@ -97,10 +96,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
kind: hir::ImplItemKind::Fn(sig, body_id),
|
||||
..
|
||||
}) => self.describe_generator(*body_id).or_else(|| {
|
||||
Some(if let hir::FnHeader { asyncness: hir::IsAsync::Async, .. } = sig.header {
|
||||
"an async method"
|
||||
} else {
|
||||
"a method"
|
||||
Some(match sig.header {
|
||||
hir::FnHeader { asyncness: hir::IsAsync::Async, .. } => "an async method",
|
||||
_ => "a method",
|
||||
})
|
||||
}),
|
||||
hir::Node::Expr(hir::Expr {
|
||||
|
@ -1318,10 +1318,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
|
||||
let is_async = inner_generator_body
|
||||
.and_then(|body| body.generator_kind())
|
||||
.map(|generator_kind| match generator_kind {
|
||||
hir::GeneratorKind::Async(..) => true,
|
||||
_ => false,
|
||||
})
|
||||
.map(|generator_kind| matches!(generator_kind, hir::GeneratorKind::Async(..)))
|
||||
.unwrap_or(false);
|
||||
let (await_or_yield, an_await_or_yield) =
|
||||
if is_async { ("await", "an await") } else { ("yield", "a yield") };
|
||||
|
@ -159,7 +159,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
|
||||
match main_t.kind {
|
||||
ty::FnDef(..) => {
|
||||
if let Some(Node::Item(it)) = tcx.hir().find(main_id) {
|
||||
if let hir::ItemKind::Fn(.., ref generics, _) = it.kind {
|
||||
if let hir::ItemKind::Fn(ref sig, ref generics, _) = it.kind {
|
||||
let mut error = false;
|
||||
if !generics.params.is_empty() {
|
||||
let msg = "`main` function is not allowed to have generic \
|
||||
@ -182,6 +182,18 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
|
||||
.emit();
|
||||
error = true;
|
||||
}
|
||||
if let hir::IsAsync::Async = sig.header.asyncness {
|
||||
let span = tcx.sess.source_map().guess_head_span(it.span);
|
||||
struct_span_err!(
|
||||
tcx.sess,
|
||||
span,
|
||||
E0752,
|
||||
"`main` function is not allowed to be `async`"
|
||||
)
|
||||
.span_label(span, "`main` function is not allowed to be `async`")
|
||||
.emit();
|
||||
error = true;
|
||||
}
|
||||
if error {
|
||||
return;
|
||||
}
|
||||
@ -226,7 +238,7 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) {
|
||||
match start_t.kind {
|
||||
ty::FnDef(..) => {
|
||||
if let Some(Node::Item(it)) = tcx.hir().find(start_id) {
|
||||
if let hir::ItemKind::Fn(.., ref generics, _) = it.kind {
|
||||
if let hir::ItemKind::Fn(ref sig, ref generics, _) = it.kind {
|
||||
let mut error = false;
|
||||
if !generics.params.is_empty() {
|
||||
struct_span_err!(
|
||||
@ -250,6 +262,18 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) {
|
||||
.emit();
|
||||
error = true;
|
||||
}
|
||||
if let hir::IsAsync::Async = sig.header.asyncness {
|
||||
let span = tcx.sess.source_map().guess_head_span(it.span);
|
||||
struct_span_err!(
|
||||
tcx.sess,
|
||||
span,
|
||||
E0752,
|
||||
"start is not allowed to be `async`"
|
||||
)
|
||||
.span_label(span, "start is not allowed to be `async`")
|
||||
.emit();
|
||||
error = true;
|
||||
}
|
||||
if error {
|
||||
return;
|
||||
}
|
||||
|
9
src/test/ui/async-await/issue-68523-start.rs
Normal file
9
src/test/ui/async-await/issue-68523-start.rs
Normal file
@ -0,0 +1,9 @@
|
||||
// edition:2018
|
||||
|
||||
#![feature(start)]
|
||||
|
||||
#[start]
|
||||
pub async fn start(_: isize, _: *const *const u8) -> isize {
|
||||
//~^ ERROR start is not allowed to be `async`
|
||||
0
|
||||
}
|
9
src/test/ui/async-await/issue-68523-start.stderr
Normal file
9
src/test/ui/async-await/issue-68523-start.stderr
Normal file
@ -0,0 +1,9 @@
|
||||
error[E0752]: start is not allowed to be `async`
|
||||
--> $DIR/issue-68523-start.rs:6:1
|
||||
|
|
||||
LL | pub async fn start(_: isize, _: *const *const u8) -> isize {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ start is not allowed to be `async`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0752`.
|
7
src/test/ui/async-await/issue-68523.rs
Normal file
7
src/test/ui/async-await/issue-68523.rs
Normal file
@ -0,0 +1,7 @@
|
||||
// edition:2018
|
||||
|
||||
async fn main() -> Result<i32, ()> {
|
||||
//~^ ERROR `main` function is not allowed to be `async`
|
||||
//~^^ ERROR `main` has invalid return type `impl std::future::Future`
|
||||
Ok(1)
|
||||
}
|
18
src/test/ui/async-await/issue-68523.stderr
Normal file
18
src/test/ui/async-await/issue-68523.stderr
Normal file
@ -0,0 +1,18 @@
|
||||
error[E0277]: `main` has invalid return type `impl std::future::Future`
|
||||
--> $DIR/issue-68523.rs:3:20
|
||||
|
|
||||
LL | async fn main() -> Result<i32, ()> {
|
||||
| ^^^^^^^^^^^^^^^ `main` can only return types that implement `std::process::Termination`
|
||||
|
|
||||
= help: consider using `()`, or a `Result`
|
||||
|
||||
error[E0752]: `main` function is not allowed to be `async`
|
||||
--> $DIR/issue-68523.rs:3:1
|
||||
|
|
||||
LL | async fn main() -> Result<i32, ()> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `main` function is not allowed to be `async`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0277, E0752.
|
||||
For more information about an error, try `rustc --explain E0277`.
|
Loading…
Reference in New Issue
Block a user