about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-05-04 18:36:37 +0200
committerGitHub <noreply@github.com>2024-05-04 18:36:37 +0200
commit9af1e8ce42e6a058bd4f36be587d2d9966adb452 (patch)
tree7778a22c9127eaf4dea6e157841c31566ecc5b7f
parent00bc2a425c98fe7067a862e3c822d4ca6c6be2ff (diff)
parent1572c0dcd7b5d9e4fcd400d3b34f1d675201f150 (diff)
downloadrust-9af1e8ce42e6a058bd4f36be587d2d9966adb452.tar.gz
rust-9af1e8ce42e6a058bd4f36be587d2d9966adb452.zip
Rollup merge of #124584 - Nilstrieb:entrypointy, r=fee1-dead
Various improvements to entrypoint code

This moves some code around and adds some documentation comments to make it easier to understand what's going on with the entrypoint logic, which is a bit complicated.

The only change in behavior is consolidating the error messages for unix_sigpipe to make the code slightly simpler.
-rw-r--r--compiler/rustc_ast/src/entry.rs26
-rw-r--r--compiler/rustc_builtin_macros/src/test_harness.rs2
-rw-r--r--compiler/rustc_passes/messages.ftl6
-rw-r--r--compiler/rustc_passes/src/entry.rs42
-rw-r--r--compiler/rustc_passes/src/errors.rs16
5 files changed, 49 insertions, 43 deletions
diff --git a/compiler/rustc_ast/src/entry.rs b/compiler/rustc_ast/src/entry.rs
index cd8a5a66920..dd231e286d5 100644
--- a/compiler/rustc_ast/src/entry.rs
+++ b/compiler/rustc_ast/src/entry.rs
@@ -4,11 +4,35 @@ use rustc_span::Symbol;
 
 #[derive(Debug)]
 pub enum EntryPointType {
+    /// This function is not an entrypoint.
     None,
+    /// This is a function called `main` at the root level.
+    /// ```
+    /// fn main() {}
+    /// ```
     MainNamed,
+    /// This is a function with the `#[rustc_main]` attribute.
+    /// Used by the testing harness to create the test entrypoint.
+    /// ```ignore (clashes with test entrypoint)
+    /// #[rustc_main]
+    /// fn main() {}
+    /// ```
     RustcMainAttr,
+    /// This is a function with the `#[start]` attribute.
+    /// ```ignore (clashes with test entrypoint)
+    /// #[start]
+    /// fn main() {}
+    /// ```
     Start,
-    OtherMain, // Not an entry point, but some other function named main
+    /// This function is **not** an entrypoint but simply named `main` (not at the root).
+    /// This is only used for diagnostics.
+    /// ```
+    /// #[allow(dead_code)]
+    /// mod meow {
+    ///     fn main() {}
+    /// }
+    /// ```
+    OtherMain,
 }
 
 pub fn entry_point_type(
diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs
index a2015445b42..8cf431482ff 100644
--- a/compiler/rustc_builtin_macros/src/test_harness.rs
+++ b/compiler/rustc_builtin_macros/src/test_harness.rs
@@ -266,7 +266,7 @@ fn generate_test_harness(
 ///
 /// By default this expands to
 ///
-/// ```ignore UNSOLVED (I think I still need guidance for this one. Is it correct? Do we try to make it run? How do we nicely fill it out?)
+/// ```ignore (messes with test internals)
 /// #[rustc_main]
 /// pub fn main() {
 ///     extern crate test;
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index 8878310d6e9..9d58d301e2b 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -49,12 +49,6 @@ passes_attr_crate_level =
 passes_attr_only_in_functions =
     `{$attr}` attribute can only be used on functions
 
-passes_attr_only_on_main =
-    `{$attr}` attribute can only be used on `fn main()`
-
-passes_attr_only_on_root_main =
-    `{$attr}` attribute can only be used on root `fn main()`
-
 passes_both_ffi_const_and_pure =
     `#[ffi_const]` function cannot be `#[ffi_pure]`
 
diff --git a/compiler/rustc_passes/src/entry.rs b/compiler/rustc_passes/src/entry.rs
index d52092f2aa9..b43c8282db1 100644
--- a/compiler/rustc_passes/src/entry.rs
+++ b/compiler/rustc_passes/src/entry.rs
@@ -18,10 +18,10 @@ use crate::errors::{
 struct EntryContext<'tcx> {
     tcx: TyCtxt<'tcx>,
 
-    /// The function that has attribute named `main`.
-    attr_main_fn: Option<(LocalDefId, Span)>,
+    /// The function has the `#[rustc_main]` attribute.
+    rustc_main_fn: Option<(LocalDefId, Span)>,
 
-    /// The function that has the attribute 'start' on it.
+    /// The function that has the attribute `#[start]` on it.
     start_fn: Option<(LocalDefId, Span)>,
 
     /// The functions that one might think are `main` but aren't, e.g.
@@ -42,10 +42,10 @@ fn entry_fn(tcx: TyCtxt<'_>, (): ()) -> Option<(DefId, EntryFnType)> {
     }
 
     let mut ctxt =
-        EntryContext { tcx, attr_main_fn: None, start_fn: None, non_main_fns: Vec::new() };
+        EntryContext { tcx, rustc_main_fn: None, start_fn: None, non_main_fns: Vec::new() };
 
     for id in tcx.hir().items() {
-        find_item(id, &mut ctxt);
+        check_and_search_item(id, &mut ctxt);
     }
 
     configure_main(tcx, &ctxt)
@@ -56,7 +56,16 @@ fn attr_span_by_symbol(ctxt: &EntryContext<'_>, id: ItemId, sym: Symbol) -> Opti
     attr::find_by_name(attrs, sym).map(|attr| attr.span)
 }
 
-fn find_item(id: ItemId, ctxt: &mut EntryContext<'_>) {
+fn check_and_search_item(id: ItemId, ctxt: &mut EntryContext<'_>) {
+    if !matches!(ctxt.tcx.def_kind(id.owner_id), DefKind::Fn) {
+        for attr in [sym::start, sym::rustc_main] {
+            if let Some(span) = attr_span_by_symbol(ctxt, id, attr) {
+                ctxt.tcx.dcx().emit_err(AttrOnlyInFunctions { span, attr });
+            }
+        }
+        return;
+    }
+
     let at_root = ctxt.tcx.opt_local_parent(id.owner_id.def_id) == Some(CRATE_DEF_ID);
 
     let attrs = ctxt.tcx.hir().attrs(id.hir_id());
@@ -65,26 +74,20 @@ fn find_item(id: ItemId, ctxt: &mut EntryContext<'_>) {
         at_root,
         ctxt.tcx.opt_item_name(id.owner_id.to_def_id()),
     );
+
     match entry_point_type {
-        EntryPointType::None => (),
-        _ if !matches!(ctxt.tcx.def_kind(id.owner_id), DefKind::Fn) => {
-            for attr in [sym::start, sym::rustc_main] {
-                if let Some(span) = attr_span_by_symbol(ctxt, id, attr) {
-                    ctxt.tcx.dcx().emit_err(AttrOnlyInFunctions { span, attr });
-                }
-            }
-        }
-        EntryPointType::MainNamed => (),
+        EntryPointType::None => {}
+        EntryPointType::MainNamed => {}
         EntryPointType::OtherMain => {
             ctxt.non_main_fns.push(ctxt.tcx.def_span(id.owner_id));
         }
         EntryPointType::RustcMainAttr => {
-            if ctxt.attr_main_fn.is_none() {
-                ctxt.attr_main_fn = Some((id.owner_id.def_id, ctxt.tcx.def_span(id.owner_id)));
+            if ctxt.rustc_main_fn.is_none() {
+                ctxt.rustc_main_fn = Some((id.owner_id.def_id, ctxt.tcx.def_span(id.owner_id)));
             } else {
                 ctxt.tcx.dcx().emit_err(MultipleRustcMain {
                     span: ctxt.tcx.def_span(id.owner_id.to_def_id()),
-                    first: ctxt.attr_main_fn.unwrap().1,
+                    first: ctxt.rustc_main_fn.unwrap().1,
                     additional: ctxt.tcx.def_span(id.owner_id.to_def_id()),
                 });
             }
@@ -107,10 +110,11 @@ fn find_item(id: ItemId, ctxt: &mut EntryContext<'_>) {
 fn configure_main(tcx: TyCtxt<'_>, visitor: &EntryContext<'_>) -> Option<(DefId, EntryFnType)> {
     if let Some((def_id, _)) = visitor.start_fn {
         Some((def_id.to_def_id(), EntryFnType::Start))
-    } else if let Some((local_def_id, _)) = visitor.attr_main_fn {
+    } else if let Some((local_def_id, _)) = visitor.rustc_main_fn {
         let def_id = local_def_id.to_def_id();
         Some((def_id, EntryFnType::Main { sigpipe: sigpipe(tcx) }))
     } else {
+        // The actual resolution of main happens in the resolver, this here
         if let Some(main_def) = tcx.resolutions(()).main_def
             && let Some(def_id) = main_def.opt_fn_def_id()
         {
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 743faf54560..65cad82cc8c 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -1207,22 +1207,6 @@ pub struct NakedFunctionsMustUseNoreturn {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_attr_only_on_main)]
-pub struct AttrOnlyOnMain {
-    #[primary_span]
-    pub span: Span,
-    pub attr: Symbol,
-}
-
-#[derive(Diagnostic)]
-#[diag(passes_attr_only_on_root_main)]
-pub struct AttrOnlyOnRootMain {
-    #[primary_span]
-    pub span: Span,
-    pub attr: Symbol,
-}
-
-#[derive(Diagnostic)]
 #[diag(passes_attr_only_in_functions)]
 pub struct AttrOnlyInFunctions {
     #[primary_span]