rustc_ast/
entry.rs

1use rustc_span::{Symbol, sym};
2
3use crate::attr::{self, AttributeExt};
4
5#[derive(Debug)]
6pub enum EntryPointType {
7    /// This function is not an entrypoint.
8    None,
9    /// This is a function called `main` at the root level.
10    /// ```
11    /// fn main() {}
12    /// ```
13    MainNamed,
14    /// This is a function with the `#[rustc_main]` attribute.
15    /// Used by the testing harness to create the test entrypoint.
16    /// ```ignore (clashes with test entrypoint)
17    /// #[rustc_main]
18    /// fn main() {}
19    /// ```
20    RustcMainAttr,
21    /// This function is **not** an entrypoint but simply named `main` (not at the root).
22    /// This is only used for diagnostics.
23    /// ```
24    /// #[allow(dead_code)]
25    /// mod meow {
26    ///     fn main() {}
27    /// }
28    /// ```
29    OtherMain,
30}
31
32pub fn entry_point_type(
33    attrs: &[impl AttributeExt],
34    at_root: bool,
35    name: Option<Symbol>,
36) -> EntryPointType {
37    if attr::contains_name(attrs, sym::rustc_main) {
38        EntryPointType::RustcMainAttr
39    } else if let Some(name) = name
40        && name == sym::main
41    {
42        if at_root {
43            // This is a top-level function so it can be `main`.
44            EntryPointType::MainNamed
45        } else {
46            EntryPointType::OtherMain
47        }
48    } else {
49        EntryPointType::None
50    }
51}