@@ -12,17 +12,17 @@ use rustc_span::symbol::sym;
1212use rustc_span:: { Span , Symbol } ;
1313
1414use crate :: errors:: {
15- AttrOnlyInFunctions , AttrOnlyOnMain , AttrOnlyOnRootMain , ExternMain , MultipleRustcMain ,
16- MultipleStartFunctions , NoMainErr , UnixSigpipeValues ,
15+ AttrOnlyInFunctions , AttrOnlyOnMain , ExternMain , MultipleRustcMain , MultipleStartFunctions ,
16+ NoMainErr , UnixSigpipeValues ,
1717} ;
1818
1919struct EntryContext < ' tcx > {
2020 tcx : TyCtxt < ' tcx > ,
2121
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 ) > ,
2424
25- /// The function that has the attribute ' start' on it.
25+ /// The function that has the attribute `#[ start]` on it.
2626 start_fn : Option < ( LocalDefId , Span ) > ,
2727
2828 /// 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)> {
4343 }
4444
4545 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 ( ) } ;
4747
4848 for id in tcx. hir ( ) . items ( ) {
49- find_item ( id, & mut ctxt) ;
49+ check_and_search_item ( id, & mut ctxt) ;
5050 }
5151
5252 configure_main ( tcx, & ctxt)
@@ -57,7 +57,16 @@ fn attr_span_by_symbol(ctxt: &EntryContext<'_>, id: ItemId, sym: Symbol) -> Opti
5757 attr:: find_by_name ( attrs, sym) . map ( |attr| attr. span )
5858}
5959
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+
6170 let at_root = ctxt. tcx . opt_local_parent ( id. owner_id . def_id ) == Some ( CRATE_DEF_ID ) ;
6271
6372 let attrs = ctxt. tcx . hir ( ) . attrs ( id. hir_id ( ) ) ;
@@ -66,41 +75,32 @@ fn find_item(id: ItemId, ctxt: &mut EntryContext<'_>) {
6675 at_root,
6776 ctxt. tcx . opt_item_name ( id. owner_id . to_def_id ( ) ) ,
6877 ) ;
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+
6986 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 => { }
8389 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- }
8790 ctxt. non_main_fns . push ( ctxt. tcx . def_span ( id. owner_id ) ) ;
8891 }
8992 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 ) ) ) ;
9295 } else {
9396 ctxt. tcx . dcx ( ) . emit_err ( MultipleRustcMain {
9497 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 ,
9699 additional : ctxt. tcx . def_span ( id. owner_id . to_def_id ( ) ) ,
97100 } ) ;
98101 }
99102 }
100103 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- }
104104 if ctxt. start_fn . is_none ( ) {
105105 ctxt. start_fn = Some ( ( id. owner_id . def_id , ctxt. tcx . def_span ( id. owner_id ) ) ) ;
106106 } else {
@@ -118,10 +118,11 @@ fn find_item(id: ItemId, ctxt: &mut EntryContext<'_>) {
118118fn configure_main ( tcx : TyCtxt < ' _ > , visitor : & EntryContext < ' _ > ) -> Option < ( DefId , EntryFnType ) > {
119119 if let Some ( ( def_id, _) ) = visitor. start_fn {
120120 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 {
122122 let def_id = local_def_id. to_def_id ( ) ;
123123 Some ( ( def_id, EntryFnType :: Main { sigpipe : sigpipe ( tcx, def_id) } ) )
124124 } else {
125+ // The actual resolution of main happens in the resolver, this here
125126 if let Some ( main_def) = tcx. resolutions ( ( ) ) . main_def
126127 && let Some ( def_id) = main_def. opt_fn_def_id ( )
127128 {
0 commit comments