@@ -78,29 +78,38 @@ fn entry_fn(tcx: TyCtxt<'_>, cnum: CrateNum) -> Option<(LocalDefId, EntryFnType)
78
78
// Beware, this is duplicated in `librustc_builtin_macros/test_harness.rs`
79
79
// (with `ast::Item`), so make sure to keep them in sync.
80
80
fn entry_point_type ( sess : & Session , item : & Item < ' _ > , at_root : bool ) -> EntryPointType {
81
- match item. kind {
82
- ItemKind :: Fn ( ..) => {
83
- if sess. contains_name ( & item. attrs , sym:: start) {
84
- EntryPointType :: Start
85
- } else if sess. contains_name ( & item. attrs , sym:: main) {
86
- EntryPointType :: MainAttr
87
- } else if item. ident . name == sym:: main {
88
- if at_root {
89
- // This is a top-level function so can be `main`.
90
- EntryPointType :: MainNamed
91
- } else {
92
- EntryPointType :: OtherMain
93
- }
94
- } else {
95
- EntryPointType :: None
96
- }
81
+ if sess. contains_name ( & item. attrs , sym:: start) {
82
+ EntryPointType :: Start
83
+ } else if sess. contains_name ( & item. attrs , sym:: main) {
84
+ EntryPointType :: MainAttr
85
+ } else if item. ident . name == sym:: main {
86
+ if at_root {
87
+ // This is a top-level function so can be `main`.
88
+ EntryPointType :: MainNamed
89
+ } else {
90
+ EntryPointType :: OtherMain
97
91
}
98
- _ => EntryPointType :: None ,
92
+ } else {
93
+ EntryPointType :: None
99
94
}
100
95
}
101
96
97
+ fn throw_attr_err ( sess : & Session , span : Span , attr : & str ) {
98
+ sess. struct_span_err ( span, & format ! ( "`{}` attribute can only be used on functions" , attr) )
99
+ . emit ( ) ;
100
+ }
101
+
102
102
fn find_item ( item : & Item < ' _ > , ctxt : & mut EntryContext < ' _ , ' _ > , at_root : bool ) {
103
103
match entry_point_type ( & ctxt. session , item, at_root) {
104
+ EntryPointType :: None => ( ) ,
105
+ _ if !matches ! ( item. kind, ItemKind :: Fn ( ..) ) => {
106
+ if let Some ( attr) = ctxt. session . find_by_name ( item. attrs , sym:: start) {
107
+ throw_attr_err ( & ctxt. session , attr. span , "start" ) ;
108
+ }
109
+ if let Some ( attr) = ctxt. session . find_by_name ( item. attrs , sym:: main) {
110
+ throw_attr_err ( & ctxt. session , attr. span , "main" ) ;
111
+ }
112
+ }
104
113
EntryPointType :: MainNamed => {
105
114
if ctxt. main_fn . is_none ( ) {
106
115
ctxt. main_fn = Some ( ( item. hir_id , item. span ) ) ;
@@ -137,7 +146,6 @@ fn find_item(item: &Item<'_>, ctxt: &mut EntryContext<'_, '_>, at_root: bool) {
137
146
. emit ( ) ;
138
147
}
139
148
}
140
- EntryPointType :: None => ( ) ,
141
149
}
142
150
}
143
151
0 commit comments