@@ -13,14 +13,14 @@ use rustc_session::parse::ParseSess;
13
13
use rustc_span::edition::Edition;
14
14
use rustc_span::source_map::SourceMap;
15
15
use rustc_span::symbol::sym;
16
- use rustc_span::{ FileName, Span, DUMMY_SP} ;
16
+ use rustc_span::FileName;
17
17
18
18
use super::GlobalTestOptions;
19
19
20
20
pub(crate) struct DocTest {
21
21
pub(crate) supports_color: bool,
22
22
pub(crate) already_has_extern_crate: bool,
23
- pub(crate) main_fn_span: Option<Span> ,
23
+ pub(crate) has_main_fn: bool ,
24
24
pub(crate) crate_attrs: String,
25
25
pub(crate) crates: String,
26
26
pub(crate) everything_else: String,
@@ -43,7 +43,7 @@ impl DocTest {
43
43
44
44
// Uses librustc_ast to parse the doctest and find if there's a main fn and the extern
45
45
// crate already is included.
46
- let Ok((main_fn_span , already_has_extern_crate, failed_ast)) =
46
+ let Ok((has_main_fn , already_has_extern_crate, failed_ast)) =
47
47
check_for_main_and_extern_crate(
48
48
crate_name,
49
49
source,
@@ -58,7 +58,7 @@ impl DocTest {
58
58
// The error will be reported during compilation.
59
59
return DocTest {
60
60
supports_color: false,
61
- main_fn_span: None ,
61
+ has_main_fn: false ,
62
62
crate_attrs,
63
63
crates,
64
64
everything_else,
@@ -70,7 +70,7 @@ impl DocTest {
70
70
};
71
71
Self {
72
72
supports_color,
73
- main_fn_span ,
73
+ has_main_fn ,
74
74
crate_attrs,
75
75
crates,
76
76
everything_else,
@@ -141,7 +141,7 @@ impl DocTest {
141
141
}
142
142
143
143
// FIXME: This code cannot yet handle no_std test cases yet
144
- if dont_insert_main || self.main_fn_span.is_some() || prog.contains("![no_std]") {
144
+ if dont_insert_main || self.has_main_fn || prog.contains("![no_std]") {
145
145
prog.push_str(everything_else);
146
146
} else {
147
147
let returns_result = everything_else.ends_with("(())");
@@ -218,7 +218,7 @@ fn cancel_error_count(psess: &ParseSess) {
218
218
219
219
fn parse_source(
220
220
source: String,
221
- found_main_span : &mut Option<Span> ,
221
+ has_main_fn : &mut bool ,
222
222
found_extern_crate: &mut bool,
223
223
found_macro: &mut bool,
224
224
crate_name: &Option<&str>,
@@ -263,22 +263,22 @@ fn parse_source(
263
263
// functions, we would thing all top-level items (so basically nothing).
264
264
fn check_item(
265
265
item: &ast::Item,
266
- found_main_span : &mut Option<Span> ,
266
+ has_main_fn : &mut bool ,
267
267
found_extern_crate: &mut bool,
268
268
found_macro: &mut bool,
269
269
crate_name: &Option<&str>,
270
270
) {
271
271
match item.kind {
272
- ast::ItemKind::Fn(ref fn_item) if found_main_span.is_none() => {
272
+ ast::ItemKind::Fn(ref fn_item) if !*has_main_fn => {
273
273
if item.ident.name == sym::main {
274
- *found_main_span = Some(item.span) ;
274
+ *has_main_fn = true ;
275
275
}
276
276
if let Some(ref body) = fn_item.body {
277
277
for stmt in &body.stmts {
278
278
match stmt.kind {
279
279
ast::StmtKind::Item(ref item) => check_item(
280
280
item,
281
- found_main_span ,
281
+ has_main_fn ,
282
282
found_extern_crate,
283
283
found_macro,
284
284
crate_name,
@@ -305,9 +305,9 @@ fn parse_source(
305
305
loop {
306
306
match parser.parse_item(ForceCollect::No) {
307
307
Ok(Some(item)) => {
308
- check_item(&item, found_main_span , found_extern_crate, found_macro, crate_name);
308
+ check_item(&item, has_main_fn , found_extern_crate, found_macro, crate_name);
309
309
310
- if found_main_span.is_some() && *found_extern_crate {
310
+ if *has_main_fn && *found_extern_crate {
311
311
break;
312
312
}
313
313
}
@@ -319,7 +319,7 @@ fn parse_source(
319
319
}
320
320
}
321
321
322
- // The supplied slice is only used for diagnostics,
322
+ // The supplied item is only used for diagnostics,
323
323
// which are swallowed here anyway.
324
324
parser.maybe_consume_incorrect_semicolon(None);
325
325
}
@@ -328,6 +328,7 @@ fn parse_source(
328
328
parsing_result
329
329
}
330
330
331
+ /// Returns `(has_main_fn, already_has_extern_crate, failed_ast)`.
331
332
fn check_for_main_and_extern_crate(
332
333
crate_name: Option<&str>,
333
334
original_source_code: &str,
@@ -336,16 +337,16 @@ fn check_for_main_and_extern_crate(
336
337
edition: Edition,
337
338
supports_color: &mut bool,
338
339
can_merge_doctests: bool,
339
- ) -> Result<(Option<Span> , bool, bool), FatalError> {
340
+ ) -> Result<(bool , bool, bool), FatalError> {
340
341
let result = rustc_driver::catch_fatal_errors(|| {
341
342
rustc_span::create_session_if_not_set_then(edition, |_| {
342
- let mut found_main_span = None ;
343
+ let mut has_main_fn = false ;
343
344
let mut found_extern_crate = crate_name.is_none();
344
345
let mut found_macro = false;
345
346
346
347
let mut parsing_result = parse_source(
347
348
format!("{crates}{everything_else}"),
348
- &mut found_main_span ,
349
+ &mut has_main_fn ,
349
350
&mut found_extern_crate,
350
351
&mut found_macro,
351
352
&crate_name,
@@ -366,21 +367,21 @@ fn check_for_main_and_extern_crate(
366
367
// faster doctests run time.
367
368
parsing_result = parse_source(
368
369
format!("{crates}\nfn __doctest_wrap(){{{everything_else}\n}}"),
369
- &mut found_main_span ,
370
+ &mut has_main_fn ,
370
371
&mut found_extern_crate,
371
372
&mut found_macro,
372
373
&crate_name,
373
374
supports_color,
374
375
);
375
376
}
376
377
377
- (found_main_span , found_extern_crate, found_macro, parsing_result)
378
+ (has_main_fn , found_extern_crate, found_macro, parsing_result)
378
379
})
379
380
});
380
- let (mut main_fn_span , already_has_extern_crate, found_macro, parsing_result) = match result {
381
+ let (mut has_main_fn , already_has_extern_crate, found_macro, parsing_result) = match result {
381
382
Err(..) | Ok((_, _, _, ParsingResult::Failed)) => return Err(FatalError),
382
- Ok((main_fn_span , already_has_extern_crate, found_macro, parsing_result)) => {
383
- (main_fn_span , already_has_extern_crate, found_macro, parsing_result)
383
+ Ok((has_main_fn , already_has_extern_crate, found_macro, parsing_result)) => {
384
+ (has_main_fn , already_has_extern_crate, found_macro, parsing_result)
384
385
}
385
386
};
386
387
@@ -389,7 +390,7 @@ fn check_for_main_and_extern_crate(
389
390
// function written inside a macro invocation. See
390
391
// https://github.com/rust-lang/rust/issues/56898
391
392
if found_macro
392
- && main_fn_span.is_none()
393
+ && !has_main_fn
393
394
&& original_source_code
394
395
.lines()
395
396
.map(|line| {
@@ -398,10 +399,10 @@ fn check_for_main_and_extern_crate(
398
399
})
399
400
.any(|code| code.contains("fn main"))
400
401
{
401
- main_fn_span = Some(DUMMY_SP) ;
402
+ has_main_fn = true ;
402
403
}
403
404
404
- Ok((main_fn_span , already_has_extern_crate, parsing_result != ParsingResult::Ok))
405
+ Ok((has_main_fn , already_has_extern_crate, parsing_result != ParsingResult::Ok))
405
406
}
406
407
407
408
fn check_if_attr_is_complete(source: &str, edition: Edition) -> bool {
@@ -448,6 +449,7 @@ fn check_if_attr_is_complete(source: &str, edition: Edition) -> bool {
448
449
.unwrap_or(false)
449
450
}
450
451
452
+ /// Returns `(crate_attrs, content, crates)`.
451
453
fn partition_source(s: &str, edition: Edition) -> (String, String, String) {
452
454
#[derive(Copy, Clone, PartialEq)]
453
455
enum PartitionState {
@@ -456,7 +458,7 @@ fn partition_source(s: &str, edition: Edition) -> (String, String, String) {
456
458
Other,
457
459
}
458
460
let mut state = PartitionState::Attrs;
459
- let mut before = String::new();
461
+ let mut crate_attrs = String::new();
460
462
let mut crates = String::new();
461
463
let mut after = String::new();
462
464
@@ -520,8 +522,8 @@ fn partition_source(s: &str, edition: Edition) -> (String, String, String) {
520
522
521
523
match state {
522
524
PartitionState::Attrs => {
523
- before .push_str(line);
524
- before .push('\n');
525
+ crate_attrs .push_str(line);
526
+ crate_attrs .push('\n');
525
527
}
526
528
PartitionState::Crates => {
527
529
crates.push_str(line);
0 commit comments