@@ -12,17 +12,17 @@ use rustc_span::symbol::sym;
12
12
use rustc_span:: { Span , Symbol } ;
13
13
14
14
use crate :: errors:: {
15
- AttrOnlyInFunctions , AttrOnlyOnMain , AttrOnlyOnRootMain , ExternMain , MultipleRustcMain ,
16
- MultipleStartFunctions , NoMainErr , UnixSigpipeValues ,
15
+ AttrOnlyInFunctions , AttrOnlyOnMain , ExternMain , MultipleRustcMain , MultipleStartFunctions ,
16
+ NoMainErr , UnixSigpipeValues ,
17
17
} ;
18
18
19
19
struct EntryContext < ' tcx > {
20
20
tcx : TyCtxt < ' tcx > ,
21
21
22
- /// The function that has attribute named `main` .
23
- attr_main_fn : Option < ( LocalDefId , Span ) > ,
22
+ /// The function has the `#[rustc_main]` attribute .
23
+ rustc_main_fn : Option < ( LocalDefId , Span ) > ,
24
24
25
- /// The function that has the attribute ' start' on it.
25
+ /// The function that has the attribute `#[ start]` on it.
26
26
start_fn : Option < ( LocalDefId , Span ) > ,
27
27
28
28
/// The functions that one might think are `main` but aren't, e.g.
@@ -43,10 +43,10 @@ fn entry_fn(tcx: TyCtxt<'_>, (): ()) -> Option<(DefId, EntryFnType)> {
43
43
}
44
44
45
45
let mut ctxt =
46
- EntryContext { tcx, attr_main_fn : None , start_fn : None , non_main_fns : Vec :: new ( ) } ;
46
+ EntryContext { tcx, rustc_main_fn : None , start_fn : None , non_main_fns : Vec :: new ( ) } ;
47
47
48
48
for id in tcx. hir ( ) . items ( ) {
49
- find_item ( id, & mut ctxt) ;
49
+ check_and_search_item ( id, & mut ctxt) ;
50
50
}
51
51
52
52
configure_main ( tcx, & ctxt)
@@ -57,7 +57,16 @@ fn attr_span_by_symbol(ctxt: &EntryContext<'_>, id: ItemId, sym: Symbol) -> Opti
57
57
attr:: find_by_name ( attrs, sym) . map ( |attr| attr. span )
58
58
}
59
59
60
- fn find_item ( id : ItemId , ctxt : & mut EntryContext < ' _ > ) {
60
+ fn check_and_search_item ( id : ItemId , ctxt : & mut EntryContext < ' _ > ) {
61
+ if !matches ! ( ctxt. tcx. def_kind( id. owner_id) , DefKind :: Fn ) {
62
+ for attr in [ sym:: start, sym:: rustc_main] {
63
+ if let Some ( span) = attr_span_by_symbol ( ctxt, id, attr) {
64
+ ctxt. tcx . dcx ( ) . emit_err ( AttrOnlyInFunctions { span, attr } ) ;
65
+ }
66
+ }
67
+ return ;
68
+ }
69
+
61
70
let at_root = ctxt. tcx . opt_local_parent ( id. owner_id . def_id ) == Some ( CRATE_DEF_ID ) ;
62
71
63
72
let attrs = ctxt. tcx . hir ( ) . attrs ( id. hir_id ( ) ) ;
@@ -66,41 +75,32 @@ fn find_item(id: ItemId, ctxt: &mut EntryContext<'_>) {
66
75
at_root,
67
76
ctxt. tcx . opt_item_name ( id. owner_id . to_def_id ( ) ) ,
68
77
) ;
78
+
79
+ if let EntryPointType :: None | EntryPointType :: OtherMain | EntryPointType :: Start =
80
+ entry_point_type
81
+ && let Some ( span) = attr_span_by_symbol ( ctxt, id, sym:: unix_sigpipe)
82
+ {
83
+ ctxt. tcx . dcx ( ) . emit_err ( AttrOnlyOnMain { span, attr : sym:: unix_sigpipe } ) ;
84
+ }
85
+
69
86
match entry_point_type {
70
- EntryPointType :: None => {
71
- if let Some ( span) = attr_span_by_symbol ( ctxt, id, sym:: unix_sigpipe) {
72
- ctxt. tcx . dcx ( ) . emit_err ( AttrOnlyOnMain { span, attr : sym:: unix_sigpipe } ) ;
73
- }
74
- }
75
- _ if !matches ! ( ctxt. tcx. def_kind( id. owner_id) , DefKind :: Fn ) => {
76
- for attr in [ sym:: start, sym:: rustc_main] {
77
- if let Some ( span) = attr_span_by_symbol ( ctxt, id, attr) {
78
- ctxt. tcx . dcx ( ) . emit_err ( AttrOnlyInFunctions { span, attr } ) ;
79
- }
80
- }
81
- }
82
- EntryPointType :: MainNamed => ( ) ,
87
+ EntryPointType :: None => { }
88
+ EntryPointType :: MainNamed => { }
83
89
EntryPointType :: OtherMain => {
84
- if let Some ( span) = attr_span_by_symbol ( ctxt, id, sym:: unix_sigpipe) {
85
- ctxt. tcx . dcx ( ) . emit_err ( AttrOnlyOnRootMain { span, attr : sym:: unix_sigpipe } ) ;
86
- }
87
90
ctxt. non_main_fns . push ( ctxt. tcx . def_span ( id. owner_id ) ) ;
88
91
}
89
92
EntryPointType :: RustcMainAttr => {
90
- if ctxt. attr_main_fn . is_none ( ) {
91
- ctxt. attr_main_fn = Some ( ( id. owner_id . def_id , ctxt. tcx . def_span ( id. owner_id ) ) ) ;
93
+ if ctxt. rustc_main_fn . is_none ( ) {
94
+ ctxt. rustc_main_fn = Some ( ( id. owner_id . def_id , ctxt. tcx . def_span ( id. owner_id ) ) ) ;
92
95
} else {
93
96
ctxt. tcx . dcx ( ) . emit_err ( MultipleRustcMain {
94
97
span : ctxt. tcx . def_span ( id. owner_id . to_def_id ( ) ) ,
95
- first : ctxt. attr_main_fn . unwrap ( ) . 1 ,
98
+ first : ctxt. rustc_main_fn . unwrap ( ) . 1 ,
96
99
additional : ctxt. tcx . def_span ( id. owner_id . to_def_id ( ) ) ,
97
100
} ) ;
98
101
}
99
102
}
100
103
EntryPointType :: Start => {
101
- if let Some ( span) = attr_span_by_symbol ( ctxt, id, sym:: unix_sigpipe) {
102
- ctxt. tcx . dcx ( ) . emit_err ( AttrOnlyOnMain { span, attr : sym:: unix_sigpipe } ) ;
103
- }
104
104
if ctxt. start_fn . is_none ( ) {
105
105
ctxt. start_fn = Some ( ( id. owner_id . def_id , ctxt. tcx . def_span ( id. owner_id ) ) ) ;
106
106
} else {
@@ -118,10 +118,11 @@ fn find_item(id: ItemId, ctxt: &mut EntryContext<'_>) {
118
118
fn configure_main ( tcx : TyCtxt < ' _ > , visitor : & EntryContext < ' _ > ) -> Option < ( DefId , EntryFnType ) > {
119
119
if let Some ( ( def_id, _) ) = visitor. start_fn {
120
120
Some ( ( def_id. to_def_id ( ) , EntryFnType :: Start ) )
121
- } else if let Some ( ( local_def_id, _) ) = visitor. attr_main_fn {
121
+ } else if let Some ( ( local_def_id, _) ) = visitor. rustc_main_fn {
122
122
let def_id = local_def_id. to_def_id ( ) ;
123
123
Some ( ( def_id, EntryFnType :: Main { sigpipe : sigpipe ( tcx, def_id) } ) )
124
124
} else {
125
+ // The actual resolution of main happens in the resolver, this here
125
126
if let Some ( main_def) = tcx. resolutions ( ( ) ) . main_def
126
127
&& let Some ( def_id) = main_def. opt_fn_def_id ( )
127
128
{
0 commit comments