about summary refs log tree commit diff
diff options
context:
space:
mode:
authorasquared31415 <34665709+asquared31415@users.noreply.github.com>2021-06-09 23:11:35 -0400
committerasquared31415 <34665709+asquared31415@users.noreply.github.com>2021-06-09 23:14:02 -0400
commit9b2ba6d1a19fb75b66db64ce6ebedc595e894107 (patch)
treef46e5486e322895685056c499d8b54567fd81b56
parent1639a16ebfaad2aa74fd535c778fd1614475b53d (diff)
downloadrust-9b2ba6d1a19fb75b66db64ce6ebedc595e894107.tar.gz
rust-9b2ba6d1a19fb75b66db64ce6ebedc595e894107.zip
Fix ICE when `main` is declared in an `extern` block
-rw-r--r--compiler/rustc_ast/src/entry.rs1
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs2
-rw-r--r--compiler/rustc_passes/src/entry.rs16
-rw-r--r--src/test/ui/extern/extern-main-issue-86110.rs7
-rw-r--r--src/test/ui/extern/extern-main-issue-86110.stderr8
5 files changed, 32 insertions, 2 deletions
diff --git a/compiler/rustc_ast/src/entry.rs b/compiler/rustc_ast/src/entry.rs
index 290f6006de0..c0a837985fd 100644
--- a/compiler/rustc_ast/src/entry.rs
+++ b/compiler/rustc_ast/src/entry.rs
@@ -1,3 +1,4 @@
+#[derive(Debug)]
 pub enum EntryPointType {
     None,
     MainNamed,
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 227aa8dc284..c8811771283 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -126,7 +126,7 @@ pub struct ResolverOutputs {
     pub main_def: Option<MainDefinition>,
 }
 
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
 pub struct MainDefinition {
     pub res: Res<ast::NodeId>,
     pub is_import: bool,
diff --git a/compiler/rustc_passes/src/entry.rs b/compiler/rustc_passes/src/entry.rs
index ca6a7561f3e..34ea5e9abd4 100644
--- a/compiler/rustc_passes/src/entry.rs
+++ b/compiler/rustc_passes/src/entry.rs
@@ -2,7 +2,7 @@ use rustc_ast::entry::EntryPointType;
 use rustc_errors::struct_span_err;
 use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
 use rustc_hir::itemlikevisit::ItemLikeVisitor;
-use rustc_hir::{ForeignItem, HirId, ImplItem, Item, ItemKind, TraitItem, CRATE_HIR_ID};
+use rustc_hir::{ForeignItem, HirId, ImplItem, Item, ItemKind, Node, TraitItem, CRATE_HIR_ID};
 use rustc_middle::hir::map::Map;
 use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::TyCtxt;
@@ -148,6 +148,20 @@ fn configure_main(tcx: TyCtxt<'_>, visitor: &EntryContext<'_, '_>) -> Option<(De
     } else if let Some((hir_id, _)) = visitor.attr_main_fn {
         Some((tcx.hir().local_def_id(hir_id).to_def_id(), EntryFnType::Main))
     } else if let Some(def_id) = tcx.main_def.and_then(|main_def| main_def.opt_fn_def_id()) {
+        // non-local main imports are handled below
+        if def_id.is_local() {
+            let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
+            if matches!(tcx.hir().find(hir_id), Some(Node::ForeignItem(_))) {
+                tcx.sess
+                    .struct_span_err(
+                        tcx.hir().span(hir_id),
+                        "the `main` function cannot be declared in an `extern` block",
+                    )
+                    .emit();
+                return None;
+            }
+        }
+
         if tcx.main_def.unwrap().is_import && !tcx.features().imported_main {
             let span = tcx.main_def.unwrap().span;
             feature_err(
diff --git a/src/test/ui/extern/extern-main-issue-86110.rs b/src/test/ui/extern/extern-main-issue-86110.rs
new file mode 100644
index 00000000000..83af7a14ccc
--- /dev/null
+++ b/src/test/ui/extern/extern-main-issue-86110.rs
@@ -0,0 +1,7 @@
+// missing and missing2 exist to make sure that the error only happens on a `main` declaration
+extern "C" {
+    fn missing();
+    fn main();
+    //~^ the `main` function cannot be declared in an `extern` block
+    fn missing2();
+}
diff --git a/src/test/ui/extern/extern-main-issue-86110.stderr b/src/test/ui/extern/extern-main-issue-86110.stderr
new file mode 100644
index 00000000000..cd3de227dcf
--- /dev/null
+++ b/src/test/ui/extern/extern-main-issue-86110.stderr
@@ -0,0 +1,8 @@
+error: the `main` function cannot be declared in an `extern` block
+  --> $DIR/extern-main-issue-86110.rs:4:5
+   |
+LL |     fn main();
+   |     ^^^^^^^^^^
+
+error: aborting due to previous error
+