From 0e0a84ae4e656fda2becd9ba33428fff613b44cb Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 24 Oct 2024 15:02:58 +0200 Subject: [PATCH] Do not consider nested functions as `main` function even if named `main` in doctests --- src/librustdoc/doctest/make.rs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/doctest/make.rs b/src/librustdoc/doctest/make.rs index efbb332d12d84..3ae60938749ec 100644 --- a/src/librustdoc/doctest/make.rs +++ b/src/librustdoc/doctest/make.rs @@ -289,7 +289,12 @@ fn parse_source( // Recurse through functions body. It is necessary because the doctest source code is // wrapped in a function to limit the number of AST errors. If we don't recurse into // functions, we would thing all top-level items (so basically nothing). - fn check_item(item: &ast::Item, info: &mut ParseSourceInfo, crate_name: &Option<&str>) { + fn check_item( + item: &ast::Item, + info: &mut ParseSourceInfo, + crate_name: &Option<&str>, + is_top_level: bool, + ) { if !info.has_global_allocator && item.attrs.iter().any(|attr| attr.name_or_empty() == sym::global_allocator) { @@ -297,13 +302,15 @@ fn parse_source( } match item.kind { ast::ItemKind::Fn(ref fn_item) if !info.has_main_fn => { - if item.ident.name == sym::main { + if item.ident.name == sym::main && is_top_level { info.has_main_fn = true; } if let Some(ref body) = fn_item.body { for stmt in &body.stmts { match stmt.kind { - ast::StmtKind::Item(ref item) => check_item(item, info, crate_name), + ast::StmtKind::Item(ref item) => { + check_item(item, info, crate_name, false) + } ast::StmtKind::MacCall(..) => info.found_macro = true, _ => {} } @@ -329,7 +336,7 @@ fn parse_source( loop { match parser.parse_item(ForceCollect::No) { Ok(Some(item)) => { - check_item(&item, info, crate_name); + check_item(&item, info, crate_name, true); if info.has_main_fn && info.found_extern_crate { break;