about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSebastian Malton <smalton@mirantis.com>2020-04-08 15:39:02 -0400
committerSebastian Malton <smalton@mirantis.com>2020-04-20 09:37:11 -0400
commit6120acec8799616dbd7e646c1d7957eab894202b (patch)
treebb5e2fe36276198b77d71ad68c0127080fd84181
parent8d67f576b56e8fc98a31123e5963f8d00e40611c (diff)
downloadrust-6120acec8799616dbd7e646c1d7957eab894202b.tar.gz
rust-6120acec8799616dbd7e646c1d7957eab894202b.zip
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

Fix formatting errors and bless test outputs
* move tests to ui/async-await

fix test error text

remove span from IsAsync
-rw-r--r--src/librustc_error_codes/error_codes.rs1
-rw-r--r--src/librustc_error_codes/error_codes/E0752.md11
-rw-r--r--src/librustc_trait_selection/traits/error_reporting/on_unimplemented.rs14
-rw-r--r--src/librustc_trait_selection/traits/error_reporting/suggestions.rs5
-rw-r--r--src/librustc_typeck/lib.rs28
-rw-r--r--src/test/ui/async-await/issue-68523-start.rs9
-rw-r--r--src/test/ui/async-await/issue-68523-start.stderr9
-rw-r--r--src/test/ui/async-await/issue-68523.rs7
-rw-r--r--src/test/ui/async-await/issue-68523.stderr18
9 files changed, 88 insertions, 14 deletions
diff --git a/src/librustc_error_codes/error_codes.rs b/src/librustc_error_codes/error_codes.rs
index 225ede851b4..bc04809eaa1 100644
--- a/src/librustc_error_codes/error_codes.rs
+++ b/src/librustc_error_codes/error_codes.rs
@@ -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
diff --git a/src/librustc_error_codes/error_codes/E0752.md b/src/librustc_error_codes/error_codes/E0752.md
new file mode 100644
index 00000000000..86945f83b55
--- /dev/null
+++ b/src/librustc_error_codes/error_codes/E0752.md
@@ -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)
+}
+```
diff --git a/src/librustc_trait_selection/traits/error_reporting/on_unimplemented.rs b/src/librustc_trait_selection/traits/error_reporting/on_unimplemented.rs
index 1ecc7fdafc4..3b6c741b890 100644
--- a/src/librustc_trait_selection/traits/error_reporting/on_unimplemented.rs
+++ b/src/librustc_trait_selection/traits/error_reporting/on_unimplemented.rs
@@ -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 {
diff --git a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs
index 254db6cb869..982ceec7dca 100644
--- a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs
+++ b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs
@@ -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") };
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index df8290fd018..cd76184c9bf 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -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;
                     }
diff --git a/src/test/ui/async-await/issue-68523-start.rs b/src/test/ui/async-await/issue-68523-start.rs
new file mode 100644
index 00000000000..5988dffd68f
--- /dev/null
+++ b/src/test/ui/async-await/issue-68523-start.rs
@@ -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
+}
diff --git a/src/test/ui/async-await/issue-68523-start.stderr b/src/test/ui/async-await/issue-68523-start.stderr
new file mode 100644
index 00000000000..e471945900e
--- /dev/null
+++ b/src/test/ui/async-await/issue-68523-start.stderr
@@ -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`.
diff --git a/src/test/ui/async-await/issue-68523.rs b/src/test/ui/async-await/issue-68523.rs
new file mode 100644
index 00000000000..e6250c40c71
--- /dev/null
+++ b/src/test/ui/async-await/issue-68523.rs
@@ -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)
+}
diff --git a/src/test/ui/async-await/issue-68523.stderr b/src/test/ui/async-await/issue-68523.stderr
new file mode 100644
index 00000000000..62e37cf2629
--- /dev/null
+++ b/src/test/ui/async-await/issue-68523.stderr
@@ -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`.