Skip to content

Commit dac6eec

Browse files
semi-revert libsyntax doctest parsing if a macro is wrapping main
1 parent 21ac19d commit dac6eec

File tree

1 file changed

+48
-3
lines changed

1 file changed

+48
-3
lines changed

src/librustdoc/test.rs

+48-3
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ pub fn make_test(s: &str,
394394

395395
// Uses libsyntax to parse the doctest and find if there's a main fn and the extern
396396
// crate already is included.
397-
let (already_has_main, already_has_extern_crate) = crate::syntax::with_globals(|| {
397+
let (already_has_main, already_has_extern_crate, found_macro) = crate::syntax::with_globals(|| {
398398
use crate::syntax::{ast, parse::{self, ParseSess}, source_map::FilePathMapping};
399399
use crate::syntax_pos::FileName;
400400
use errors::emitter::EmitterWriter;
@@ -412,6 +412,7 @@ pub fn make_test(s: &str,
412412

413413
let mut found_main = false;
414414
let mut found_extern_crate = cratename.is_none();
415+
let mut found_macro = false;
415416

416417
let mut parser = match parse::maybe_new_parser_from_source_str(&sess, filename, source) {
417418
Ok(p) => p,
@@ -420,7 +421,7 @@ pub fn make_test(s: &str,
420421
err.cancel();
421422
}
422423

423-
return (found_main, found_extern_crate);
424+
return (found_main, found_extern_crate, found_macro);
424425
}
425426
};
426427

@@ -448,6 +449,12 @@ pub fn make_test(s: &str,
448449
}
449450
}
450451

452+
if !found_macro {
453+
if let ast::ItemKind::Mac(..) = item.node {
454+
found_macro = true;
455+
}
456+
}
457+
451458
if found_main && found_extern_crate {
452459
break;
453460
}
@@ -460,9 +467,28 @@ pub fn make_test(s: &str,
460467
}
461468
}
462469

463-
(found_main, found_extern_crate)
470+
(found_main, found_extern_crate, found_macro)
464471
});
465472

473+
// If a doctest's `fn main` is being masked by a wrapper macro, the parsing loop above won't
474+
// see it. In that case, run the old text-based scan to see if they at least have a main
475+
// function written inside a macro invocation. See
476+
// https://github.com/rust-lang/rust/issues/56898
477+
let already_has_main = if found_macro && !already_has_main {
478+
s.lines()
479+
.map(|line| {
480+
let comment = line.find("//");
481+
if let Some(comment_begins) = comment {
482+
&line[0..comment_begins]
483+
} else {
484+
line
485+
}
486+
})
487+
.any(|code| code.contains("fn main"))
488+
} else {
489+
already_has_main
490+
};
491+
466492
// Don't inject `extern crate std` because it's already injected by the
467493
// compiler.
468494
if !already_has_extern_crate && !opts.no_crate_inject && cratename != Some("std") {
@@ -1143,4 +1169,23 @@ assert_eq!(asdf::foo, 4);
11431169
let output = make_test(input, Some("asdf"), false, &opts);
11441170
assert_eq!(output, (expected, 3));
11451171
}
1172+
1173+
#[test]
1174+
fn make_test_main_in_macro() {
1175+
let opts = TestOptions::default();
1176+
let input =
1177+
"#[macro_use] extern crate my_crate;
1178+
test_wrapper! {
1179+
fn main() {}
1180+
}";
1181+
let expected =
1182+
"#![allow(unused)]
1183+
#[macro_use] extern crate my_crate;
1184+
test_wrapper! {
1185+
fn main() {}
1186+
}".to_string();
1187+
1188+
let output = make_test(input, Some("my_crate"), false, &opts);
1189+
assert_eq!(output, (expected, 1));
1190+
}
11461191
}

0 commit comments

Comments
 (0)