@@ -17,17 +17,17 @@ struct EntryContext<'a, 'tcx> {
17
17
map : Map < ' tcx > ,
18
18
19
19
/// The top-level function called `main`.
20
- main_fn : Option < ( HirId , Span ) > ,
20
+ main_fn : Option < HirId > ,
21
21
22
22
/// The function that has attribute named `main`.
23
- attr_main_fn : Option < ( HirId , Span ) > ,
23
+ attr_main_fn : Option < HirId > ,
24
24
25
25
/// The function that has the attribute 'start' on it.
26
- start_fn : Option < ( HirId , Span ) > ,
26
+ start_fn : Option < HirId > ,
27
27
28
28
/// The functions that one might think are `main` but aren't, e.g.
29
29
/// main functions not defined at the top level. For diagnostics.
30
- non_main_fns : Vec < ( HirId , Span ) > ,
30
+ non_main_fns : Vec < HirId > ,
31
31
}
32
32
33
33
impl < ' a , ' tcx > ItemLikeVisitor < ' tcx > for EntryContext < ' a , ' tcx > {
@@ -117,37 +117,42 @@ fn find_item(item: &Item<'_>, ctxt: &mut EntryContext<'_, '_>, at_root: bool) {
117
117
}
118
118
EntryPointType :: MainNamed => {
119
119
if ctxt. main_fn . is_none ( ) {
120
- ctxt. main_fn = Some ( ( item. hir_id ( ) , item . span ) ) ;
120
+ ctxt. main_fn = Some ( item. hir_id ( ) ) ;
121
121
} else {
122
- struct_span_err ! ( ctxt. session, item. span, E0136 , "multiple `main` functions" )
122
+ let item_span = ctxt. map . span_with_body ( item. hir_id ( ) ) ;
123
+ struct_span_err ! ( ctxt. session, item_span, E0136 , "multiple `main` functions" )
123
124
. emit ( ) ;
124
125
}
125
126
}
126
127
EntryPointType :: OtherMain => {
127
- ctxt. non_main_fns . push ( ( item. hir_id ( ) , item . span ) ) ;
128
+ ctxt. non_main_fns . push ( item. hir_id ( ) ) ;
128
129
}
129
130
EntryPointType :: MainAttr => {
130
131
if ctxt. attr_main_fn . is_none ( ) {
131
- ctxt. attr_main_fn = Some ( ( item. hir_id ( ) , item . span ) ) ;
132
+ ctxt. attr_main_fn = Some ( item. hir_id ( ) ) ;
132
133
} else {
134
+ let item_span = ctxt. map . span_with_body ( item. hir_id ( ) ) ;
135
+ let old_span = ctxt. map . span_with_body ( ctxt. attr_main_fn . unwrap ( ) ) ;
133
136
struct_span_err ! (
134
137
ctxt. session,
135
- item . span ,
138
+ item_span ,
136
139
E0137 ,
137
140
"multiple functions with a `#[main]` attribute"
138
141
)
139
- . span_label ( item . span , "additional `#[main]` function" )
140
- . span_label ( ctxt . attr_main_fn . unwrap ( ) . 1 , "first `#[main]` function" )
142
+ . span_label ( item_span , "additional `#[main]` function" )
143
+ . span_label ( old_span , "first `#[main]` function" )
141
144
. emit ( ) ;
142
145
}
143
146
}
144
147
EntryPointType :: Start => {
145
148
if ctxt. start_fn . is_none ( ) {
146
- ctxt. start_fn = Some ( ( item. hir_id ( ) , item . span ) ) ;
149
+ ctxt. start_fn = Some ( item. hir_id ( ) ) ;
147
150
} else {
148
- struct_span_err ! ( ctxt. session, item. span, E0138 , "multiple `start` functions" )
149
- . span_label ( ctxt. start_fn . unwrap ( ) . 1 , "previous `#[start]` function here" )
150
- . span_label ( item. span , "multiple `start` functions" )
151
+ let item_span = ctxt. map . span_with_body ( item. hir_id ( ) ) ;
152
+ let old_span = ctxt. map . span_with_body ( ctxt. start_fn . unwrap ( ) ) ;
153
+ struct_span_err ! ( ctxt. session, item_span, E0138 , "multiple `start` functions" )
154
+ . span_label ( old_span, "previous `#[start]` function here" )
155
+ . span_label ( item_span, "multiple `start` functions" )
151
156
. emit ( ) ;
152
157
}
153
158
}
@@ -158,11 +163,11 @@ fn configure_main(
158
163
tcx : TyCtxt < ' _ > ,
159
164
visitor : & EntryContext < ' _ , ' _ > ,
160
165
) -> Option < ( LocalDefId , EntryFnType ) > {
161
- if let Some ( ( hir_id, _ ) ) = visitor. start_fn {
166
+ if let Some ( hir_id) = visitor. start_fn {
162
167
Some ( ( tcx. hir ( ) . local_def_id ( hir_id) , EntryFnType :: Start ) )
163
- } else if let Some ( ( hir_id, _ ) ) = visitor. attr_main_fn {
168
+ } else if let Some ( hir_id) = visitor. attr_main_fn {
164
169
Some ( ( tcx. hir ( ) . local_def_id ( hir_id) , EntryFnType :: Main ) )
165
- } else if let Some ( ( hir_id, _ ) ) = visitor. main_fn {
170
+ } else if let Some ( hir_id) = visitor. main_fn {
166
171
Some ( ( tcx. hir ( ) . local_def_id ( hir_id) , EntryFnType :: Main ) )
167
172
} else {
168
173
no_main_err ( tcx, visitor) ;
@@ -171,7 +176,7 @@ fn configure_main(
171
176
}
172
177
173
178
fn no_main_err ( tcx : TyCtxt < ' _ > , visitor : & EntryContext < ' _ , ' _ > ) {
174
- let sp = tcx. hir ( ) . span ( CRATE_HIR_ID ) ;
179
+ let sp = tcx. hir ( ) . span_with_body ( CRATE_HIR_ID ) ;
175
180
if * tcx. sess . parse_sess . reached_eof . borrow ( ) {
176
181
// There's an unclosed brace that made the parser reach `Eof`, we shouldn't complain about
177
182
// the missing `fn main()` then as it might have been hidden inside an unclosed block.
@@ -189,7 +194,8 @@ fn no_main_err(tcx: TyCtxt<'_>, visitor: &EntryContext<'_, '_>) {
189
194
) ;
190
195
let filename = & tcx. sess . local_crate_source_file ;
191
196
let note = if !visitor. non_main_fns . is_empty ( ) {
192
- for & ( _, span) in & visitor. non_main_fns {
197
+ for & hir_id in & visitor. non_main_fns {
198
+ let span = tcx. hir ( ) . span_with_body ( hir_id) ;
193
199
err. span_note ( span, "here is a function named `main`" ) ;
194
200
}
195
201
err. note ( "you have one or more functions named `main` not defined at the crate level" ) ;
0 commit comments