@@ -18,10 +18,10 @@ use crate::errors::{
18
18
struct EntryContext < ' tcx > {
19
19
tcx : TyCtxt < ' tcx > ,
20
20
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 ) > ,
23
23
24
- /// The function that has the attribute ' start' on it.
24
+ /// The function that has the attribute `#[ start]` on it.
25
25
start_fn : Option < ( LocalDefId , Span ) > ,
26
26
27
27
/// 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)> {
42
42
}
43
43
44
44
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 ( ) } ;
46
46
47
47
for id in tcx. hir ( ) . items ( ) {
48
- find_item ( id, & mut ctxt) ;
48
+ check_and_search_item ( id, & mut ctxt) ;
49
49
}
50
50
51
51
configure_main ( tcx, & ctxt)
@@ -56,7 +56,16 @@ fn attr_span_by_symbol(ctxt: &EntryContext<'_>, id: ItemId, sym: Symbol) -> Opti
56
56
attr:: find_by_name ( attrs, sym) . map ( |attr| attr. span )
57
57
}
58
58
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
+
60
69
let at_root = ctxt. tcx . opt_local_parent ( id. owner_id . def_id ) == Some ( CRATE_DEF_ID ) ;
61
70
62
71
let attrs = ctxt. tcx . hir ( ) . attrs ( id. hir_id ( ) ) ;
@@ -65,26 +74,20 @@ fn find_item(id: ItemId, ctxt: &mut EntryContext<'_>) {
65
74
at_root,
66
75
ctxt. tcx . opt_item_name ( id. owner_id . to_def_id ( ) ) ,
67
76
) ;
77
+
68
78
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 => { }
78
81
EntryPointType :: OtherMain => {
79
82
ctxt. non_main_fns . push ( ctxt. tcx . def_span ( id. owner_id ) ) ;
80
83
}
81
84
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 ) ) ) ;
84
87
} else {
85
88
ctxt. tcx . dcx ( ) . emit_err ( MultipleRustcMain {
86
89
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 ,
88
91
additional : ctxt. tcx . def_span ( id. owner_id . to_def_id ( ) ) ,
89
92
} ) ;
90
93
}
@@ -107,10 +110,11 @@ fn find_item(id: ItemId, ctxt: &mut EntryContext<'_>) {
107
110
fn configure_main ( tcx : TyCtxt < ' _ > , visitor : & EntryContext < ' _ > ) -> Option < ( DefId , EntryFnType ) > {
108
111
if let Some ( ( def_id, _) ) = visitor. start_fn {
109
112
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 {
111
114
let def_id = local_def_id. to_def_id ( ) ;
112
115
Some ( ( def_id, EntryFnType :: Main { sigpipe : sigpipe ( tcx) } ) )
113
116
} else {
117
+ // The actual resolution of main happens in the resolver, this here
114
118
if let Some ( main_def) = tcx. resolutions ( ( ) ) . main_def
115
119
&& let Some ( def_id) = main_def. opt_fn_def_id ( )
116
120
{
0 commit comments