Skip to content

Commit 9af1e8c

Browse files
authored
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.
2 parents 00bc2a4 + 1572c0d commit 9af1e8c

File tree

5 files changed

+49
-43
lines changed

5 files changed

+49
-43
lines changed

Diff for: compiler/rustc_ast/src/entry.rs

+25-1
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,35 @@ use rustc_span::Symbol;
44

55
#[derive(Debug)]
66
pub enum EntryPointType {
7+
/// This function is not an entrypoint.
78
None,
9+
/// This is a function called `main` at the root level.
10+
/// ```
11+
/// fn main() {}
12+
/// ```
813
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+
/// ```
920
RustcMainAttr,
21+
/// This is a function with the `#[start]` attribute.
22+
/// ```ignore (clashes with test entrypoint)
23+
/// #[start]
24+
/// fn main() {}
25+
/// ```
1026
Start,
11-
OtherMain, // Not an entry point, but some other function named main
27+
/// This function is **not** an entrypoint but simply named `main` (not at the root).
28+
/// This is only used for diagnostics.
29+
/// ```
30+
/// #[allow(dead_code)]
31+
/// mod meow {
32+
/// fn main() {}
33+
/// }
34+
/// ```
35+
OtherMain,
1236
}
1337

1438
pub fn entry_point_type(

Diff for: compiler/rustc_builtin_macros/src/test_harness.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ fn generate_test_harness(
266266
///
267267
/// By default this expands to
268268
///
269-
/// ```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?)
269+
/// ```ignore (messes with test internals)
270270
/// #[rustc_main]
271271
/// pub fn main() {
272272
/// extern crate test;

Diff for: compiler/rustc_passes/messages.ftl

-6
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,6 @@ passes_attr_crate_level =
4949
passes_attr_only_in_functions =
5050
`{$attr}` attribute can only be used on functions
5151
52-
passes_attr_only_on_main =
53-
`{$attr}` attribute can only be used on `fn main()`
54-
55-
passes_attr_only_on_root_main =
56-
`{$attr}` attribute can only be used on root `fn main()`
57-
5852
passes_both_ffi_const_and_pure =
5953
`#[ffi_const]` function cannot be `#[ffi_pure]`
6054

Diff for: compiler/rustc_passes/src/entry.rs

+23-19
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ use crate::errors::{
1818
struct EntryContext<'tcx> {
1919
tcx: TyCtxt<'tcx>,
2020

21-
/// The function that has attribute named `main`.
22-
attr_main_fn: Option<(LocalDefId, Span)>,
21+
/// The function has the `#[rustc_main]` attribute.
22+
rustc_main_fn: Option<(LocalDefId, Span)>,
2323

24-
/// The function that has the attribute 'start' on it.
24+
/// The function that has the attribute `#[start]` on it.
2525
start_fn: Option<(LocalDefId, Span)>,
2626

2727
/// 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)> {
4242
}
4343

4444
let mut ctxt =
45-
EntryContext { tcx, attr_main_fn: None, start_fn: None, non_main_fns: Vec::new() };
45+
EntryContext { tcx, rustc_main_fn: None, start_fn: None, non_main_fns: Vec::new() };
4646

4747
for id in tcx.hir().items() {
48-
find_item(id, &mut ctxt);
48+
check_and_search_item(id, &mut ctxt);
4949
}
5050

5151
configure_main(tcx, &ctxt)
@@ -56,7 +56,16 @@ fn attr_span_by_symbol(ctxt: &EntryContext<'_>, id: ItemId, sym: Symbol) -> Opti
5656
attr::find_by_name(attrs, sym).map(|attr| attr.span)
5757
}
5858

59-
fn find_item(id: ItemId, ctxt: &mut EntryContext<'_>) {
59+
fn check_and_search_item(id: ItemId, ctxt: &mut EntryContext<'_>) {
60+
if !matches!(ctxt.tcx.def_kind(id.owner_id), DefKind::Fn) {
61+
for attr in [sym::start, sym::rustc_main] {
62+
if let Some(span) = attr_span_by_symbol(ctxt, id, attr) {
63+
ctxt.tcx.dcx().emit_err(AttrOnlyInFunctions { span, attr });
64+
}
65+
}
66+
return;
67+
}
68+
6069
let at_root = ctxt.tcx.opt_local_parent(id.owner_id.def_id) == Some(CRATE_DEF_ID);
6170

6271
let attrs = ctxt.tcx.hir().attrs(id.hir_id());
@@ -65,26 +74,20 @@ fn find_item(id: ItemId, ctxt: &mut EntryContext<'_>) {
6574
at_root,
6675
ctxt.tcx.opt_item_name(id.owner_id.to_def_id()),
6776
);
77+
6878
match entry_point_type {
69-
EntryPointType::None => (),
70-
_ if !matches!(ctxt.tcx.def_kind(id.owner_id), DefKind::Fn) => {
71-
for attr in [sym::start, sym::rustc_main] {
72-
if let Some(span) = attr_span_by_symbol(ctxt, id, attr) {
73-
ctxt.tcx.dcx().emit_err(AttrOnlyInFunctions { span, attr });
74-
}
75-
}
76-
}
77-
EntryPointType::MainNamed => (),
79+
EntryPointType::None => {}
80+
EntryPointType::MainNamed => {}
7881
EntryPointType::OtherMain => {
7982
ctxt.non_main_fns.push(ctxt.tcx.def_span(id.owner_id));
8083
}
8184
EntryPointType::RustcMainAttr => {
82-
if ctxt.attr_main_fn.is_none() {
83-
ctxt.attr_main_fn = Some((id.owner_id.def_id, ctxt.tcx.def_span(id.owner_id)));
85+
if ctxt.rustc_main_fn.is_none() {
86+
ctxt.rustc_main_fn = Some((id.owner_id.def_id, ctxt.tcx.def_span(id.owner_id)));
8487
} else {
8588
ctxt.tcx.dcx().emit_err(MultipleRustcMain {
8689
span: ctxt.tcx.def_span(id.owner_id.to_def_id()),
87-
first: ctxt.attr_main_fn.unwrap().1,
90+
first: ctxt.rustc_main_fn.unwrap().1,
8891
additional: ctxt.tcx.def_span(id.owner_id.to_def_id()),
8992
});
9093
}
@@ -107,10 +110,11 @@ fn find_item(id: ItemId, ctxt: &mut EntryContext<'_>) {
107110
fn configure_main(tcx: TyCtxt<'_>, visitor: &EntryContext<'_>) -> Option<(DefId, EntryFnType)> {
108111
if let Some((def_id, _)) = visitor.start_fn {
109112
Some((def_id.to_def_id(), EntryFnType::Start))
110-
} else if let Some((local_def_id, _)) = visitor.attr_main_fn {
113+
} else if let Some((local_def_id, _)) = visitor.rustc_main_fn {
111114
let def_id = local_def_id.to_def_id();
112115
Some((def_id, EntryFnType::Main { sigpipe: sigpipe(tcx) }))
113116
} else {
117+
// The actual resolution of main happens in the resolver, this here
114118
if let Some(main_def) = tcx.resolutions(()).main_def
115119
&& let Some(def_id) = main_def.opt_fn_def_id()
116120
{

Diff for: compiler/rustc_passes/src/errors.rs

-16
Original file line numberDiff line numberDiff line change
@@ -1206,22 +1206,6 @@ pub struct NakedFunctionsMustUseNoreturn {
12061206
pub last_span: Span,
12071207
}
12081208

1209-
#[derive(Diagnostic)]
1210-
#[diag(passes_attr_only_on_main)]
1211-
pub struct AttrOnlyOnMain {
1212-
#[primary_span]
1213-
pub span: Span,
1214-
pub attr: Symbol,
1215-
}
1216-
1217-
#[derive(Diagnostic)]
1218-
#[diag(passes_attr_only_on_root_main)]
1219-
pub struct AttrOnlyOnRootMain {
1220-
#[primary_span]
1221-
pub span: Span,
1222-
pub attr: Symbol,
1223-
}
1224-
12251209
#[derive(Diagnostic)]
12261210
#[diag(passes_attr_only_in_functions)]
12271211
pub struct AttrOnlyInFunctions {

0 commit comments

Comments
 (0)