Skip to content

Commit cd407df

Browse files
repnopQuietMisdreavus
authored andcommitted
Separates inner attributes from code during doctest parsing.
1 parent 43b65b5 commit cd407df

File tree

1 file changed

+37
-23
lines changed

1 file changed

+37
-23
lines changed

src/librustdoc/test.rs

+37-23
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ pub fn make_test(s: &str,
378378
dont_insert_main: bool,
379379
opts: &TestOptions)
380380
-> (String, usize) {
381-
let (crate_attrs, everything_else) = partition_source(s);
381+
let (crate_attrs, everything_else, crates) = partition_source(s);
382382
let everything_else = everything_else.trim();
383383
let mut line_offset = 0;
384384
let mut prog = String::new();
@@ -409,38 +409,47 @@ pub fn make_test(s: &str,
409409
use crate::syntax_pos::FileName;
410410

411411
let filename = FileName::Anon;
412-
let source = s.to_owned();
412+
let source = crates + &everything_else;
413413
let sess = ParseSess::new(FilePathMapping::empty());
414414

415415
let mut parser = parse::new_parser_from_source_str(&sess, filename, source);
416416

417417
let mut found_main = false;
418418
let mut found_extern_crate = cratename.is_none();
419419

420-
while let Ok(Some(item)) = parser.parse_item() {
421-
if !found_main {
422-
if let ast::ItemKind::Fn(..) = item.node {
423-
if item.ident.as_str() == "main" {
424-
found_main = true;
420+
loop {
421+
match parser.parse_item() {
422+
Ok(Some(item)) => {
423+
if !found_main {
424+
if let ast::ItemKind::Fn(..) = item.node {
425+
if item.ident.as_str() == "main" {
426+
found_main = true;
427+
}
428+
}
425429
}
426-
}
427-
}
428430

429-
if !found_extern_crate {
430-
if let ast::ItemKind::ExternCrate(original) = item.node {
431-
// This code will never be reached if `cratename` is none because
432-
// `found_extern_crate` is initialized to `true` if it is none.
433-
let cratename = cratename.unwrap();
431+
if !found_extern_crate {
432+
if let ast::ItemKind::ExternCrate(original) = item.node {
433+
// This code will never be reached if `cratename` is none because
434+
// `found_extern_crate` is initialized to `true` if it is none.
435+
let cratename = cratename.unwrap();
436+
437+
match original {
438+
Some(name) => found_extern_crate = name.as_str() == cratename,
439+
None => found_extern_crate = item.ident.as_str() == cratename,
440+
}
441+
}
442+
}
434443

435-
match original {
436-
Some(name) => found_extern_crate = name.as_str() == cratename,
437-
None => found_extern_crate = item.ident.as_str() == cratename,
444+
if found_main && found_extern_crate {
445+
break;
438446
}
439447
}
440-
}
441-
442-
if found_main && found_extern_crate {
443-
break;
448+
Ok(None) => break,
449+
Err(mut e) => {
450+
e.cancel();
451+
break;
452+
}
444453
}
445454
}
446455

@@ -474,9 +483,10 @@ pub fn make_test(s: &str,
474483
}
475484

476485
// FIXME(aburka): use a real parser to deal with multiline attributes
477-
fn partition_source(s: &str) -> (String, String) {
486+
fn partition_source(s: &str) -> (String, String, String) {
478487
let mut after_header = false;
479488
let mut before = String::new();
489+
let mut crates = String::new();
480490
let mut after = String::new();
481491

482492
for line in s.lines() {
@@ -490,12 +500,16 @@ fn partition_source(s: &str) -> (String, String) {
490500
after.push_str(line);
491501
after.push_str("\n");
492502
} else {
503+
if trimline.starts_with("#[macro_use] extern crate")
504+
|| trimline.starts_with("extern crate") {
505+
crates.push_str(line);
506+
}
493507
before.push_str(line);
494508
before.push_str("\n");
495509
}
496510
}
497511

498-
(before, after)
512+
(before, after, crates)
499513
}
500514

501515
pub trait Tester {

0 commit comments

Comments
 (0)