Skip to content

Commit 017ae1b

Browse files
committed
Auto merge of #132105 - GuillaumeGomez:doctest-nested-main, r=notriddle
[rustdoc] Do not consider nested functions as main function even if named `main` in doctests Fixes #131893. If a nested function is called `main`, it is not considered as the entry point of the program. Therefore, doctests should not consider such functions as such either. r? `@notriddle`
2 parents 788202a + aab2b67 commit 017ae1b

File tree

3 files changed

+42
-4
lines changed

3 files changed

+42
-4
lines changed

Diff for: src/librustdoc/doctest/make.rs

+11-4
Original file line numberDiff line numberDiff line change
@@ -289,21 +289,28 @@ fn parse_source(
289289
// Recurse through functions body. It is necessary because the doctest source code is
290290
// wrapped in a function to limit the number of AST errors. If we don't recurse into
291291
// functions, we would thing all top-level items (so basically nothing).
292-
fn check_item(item: &ast::Item, info: &mut ParseSourceInfo, crate_name: &Option<&str>) {
292+
fn check_item(
293+
item: &ast::Item,
294+
info: &mut ParseSourceInfo,
295+
crate_name: &Option<&str>,
296+
is_top_level: bool,
297+
) {
293298
if !info.has_global_allocator
294299
&& item.attrs.iter().any(|attr| attr.name_or_empty() == sym::global_allocator)
295300
{
296301
info.has_global_allocator = true;
297302
}
298303
match item.kind {
299304
ast::ItemKind::Fn(ref fn_item) if !info.has_main_fn => {
300-
if item.ident.name == sym::main {
305+
if item.ident.name == sym::main && is_top_level {
301306
info.has_main_fn = true;
302307
}
303308
if let Some(ref body) = fn_item.body {
304309
for stmt in &body.stmts {
305310
match stmt.kind {
306-
ast::StmtKind::Item(ref item) => check_item(item, info, crate_name),
311+
ast::StmtKind::Item(ref item) => {
312+
check_item(item, info, crate_name, false)
313+
}
307314
ast::StmtKind::MacCall(..) => info.found_macro = true,
308315
_ => {}
309316
}
@@ -329,7 +336,7 @@ fn parse_source(
329336
loop {
330337
match parser.parse_item(ForceCollect::No) {
331338
Ok(Some(item)) => {
332-
check_item(&item, info, crate_name);
339+
check_item(&item, info, crate_name, true);
333340

334341
if info.has_main_fn && info.found_extern_crate {
335342
break;

Diff for: tests/rustdoc-ui/doctest/nested-main.rs

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//@ check-pass
2+
//@ compile-flags:--test --test-args=--test-threads=1
3+
//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR"
4+
//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME"
5+
6+
// Regression test for <https://github.com/rust-lang/rust/issues/131893>.
7+
// It ensures that if a function called `main` is nested, it will not consider
8+
// it as the `main` function.
9+
10+
/// ```
11+
/// fn dox() {
12+
/// fn main() {}
13+
/// }
14+
/// ```
15+
pub fn foo() {}
16+
17+
// This one ensures that having a nested `main` doesn't prevent the
18+
// actual `main` function to be detected.
19+
/// ```
20+
/// fn main() {
21+
/// fn main() {}
22+
/// }
23+
/// ```
24+
pub fn foo2() {}

Diff for: tests/rustdoc-ui/doctest/nested-main.stdout

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
running 2 tests
3+
test $DIR/nested-main.rs - foo (line 10) ... ok
4+
test $DIR/nested-main.rs - foo2 (line 19) ... ok
5+
6+
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
7+

0 commit comments

Comments
 (0)