Skip to content

Check that main/start is not async #71174

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/librustc_error_codes/error_codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
11 changes: 11 additions & 0 deletions src/librustc_error_codes/error_codes/E0752.md
Original file line number Diff line number Diff line change
@@ -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)
}
```
Original file line number Diff line number Diff line change
Expand Up @@ -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",
})
})
}
Expand All @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1313,10 +1313,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") };
Expand Down
28 changes: 26 additions & 2 deletions src/librustc_typeck/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand All @@ -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;
}
Expand Down Expand Up @@ -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!(
Expand All @@ -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;
}
Expand Down
9 changes: 9 additions & 0 deletions src/test/ui/async-await/issue-68523-start.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 9 additions & 0 deletions src/test/ui/async-await/issue-68523-start.stderr
Original file line number Diff line number Diff line change
@@ -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 changes: 7 additions & 0 deletions src/test/ui/async-await/issue-68523.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 18 additions & 0 deletions src/test/ui/async-await/issue-68523.stderr
Original file line number Diff line number Diff line change
@@ -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`.