Skip to content

Commit 1240a7d

Browse files
Correctly handle fn main in macro
1 parent e164e33 commit 1240a7d

File tree

2 files changed

+35
-18
lines changed

2 files changed

+35
-18
lines changed

src/librustdoc/doctest/make.rs

+30-13
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,17 @@ use std::fmt::{self, Write as _};
55
use std::io;
66
use std::sync::Arc;
77

8-
use rustc_ast::{self as ast, HasAttrs};
8+
use rustc_ast::token::{Delimiter, TokenKind};
9+
use rustc_ast::tokenstream::TokenTree;
10+
use rustc_ast::{self as ast, HasAttrs, StmtKind};
911
use rustc_errors::ColorConfig;
1012
use rustc_errors::emitter::stderr_destination;
1113
use rustc_parse::new_parser_from_source_str;
1214
use rustc_session::parse::ParseSess;
13-
use rustc_span::FileName;
1415
use rustc_span::edition::Edition;
1516
use rustc_span::source_map::SourceMap;
1617
use rustc_span::symbol::sym;
18+
use rustc_span::{FileName, kw};
1719
use tracing::debug;
1820

1921
use super::GlobalTestOptions;
@@ -319,7 +321,7 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result<ParseSourceIn
319321
let extra_len = DOCTEST_CODE_WRAPPER.len();
320322
// We need to shift by 1 because we added `{` at the beginning of the source.we provided
321323
// to the parser.
322-
let lo = prev_span_hi.unwrap_or(span.lo().0 as usize - extra_len);
324+
let lo = prev_span_hi.unwrap_or(0);
323325
let mut hi = span.hi().0 as usize - extra_len;
324326
if hi > source.len() {
325327
hi = source.len();
@@ -351,11 +353,8 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result<ParseSourceIn
351353
}
352354
if let Some(ref body) = fn_item.body {
353355
for stmt in &body.stmts {
354-
match stmt.kind {
355-
ast::StmtKind::Item(ref item) => {
356-
check_item(item, info, crate_name, false)
357-
}
358-
_ => {}
356+
if let StmtKind::Item(ref item) = stmt.kind {
357+
check_item(item, info, crate_name, false)
359358
}
360359
}
361360
}
@@ -381,8 +380,6 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result<ParseSourceIn
381380
let not_crate_attrs = [sym::forbid, sym::allow, sym::warn, sym::deny];
382381
let parsed = parser.parse_item(rustc_parse::parser::ForceCollect::No);
383382

384-
debug!("+++++> {parsed:#?}");
385-
386383
let result = match parsed {
387384
Ok(Some(ref item))
388385
if let ast::ItemKind::Fn(ref fn_item) = item.kind
@@ -416,11 +413,31 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result<ParseSourceIn
416413
}
417414
for stmt in &body.stmts {
418415
match stmt.kind {
419-
ast::StmtKind::Item(ref item) => check_item(&item, &mut info, crate_name, true),
420-
ast::StmtKind::Expr(ref expr) if matches!(expr.kind, ast::ExprKind::Err(_)) => {
416+
StmtKind::Item(ref item) => check_item(&item, &mut info, crate_name, true),
417+
StmtKind::Expr(ref expr) if matches!(expr.kind, ast::ExprKind::Err(_)) => {
421418
cancel_error_count(&psess);
422419
return Err(());
423420
}
421+
StmtKind::MacCall(ref mac_call) if !info.has_main_fn => {
422+
let mut iter = mac_call.mac.args.tokens.iter();
423+
424+
while let Some(token) = iter.next() {
425+
if let TokenTree::Token(token, _) = token
426+
&& let TokenKind::Ident(name, _) = token.kind
427+
&& name == kw::Fn
428+
&& let Some(TokenTree::Token(fn_token, _)) = iter.peek()
429+
&& let TokenKind::Ident(fn_name, _) = fn_token.kind
430+
&& fn_name == sym::main
431+
&& let Some(TokenTree::Delimited(_, _, Delimiter::Parenthesis, _)) = {
432+
iter.next();
433+
iter.peek()
434+
}
435+
{
436+
info.has_main_fn = true;
437+
break;
438+
}
439+
}
440+
}
424441
_ => {}
425442
}
426443

@@ -433,7 +450,7 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result<ParseSourceIn
433450
if info.everything_else.is_empty()
434451
&& (!info.maybe_crate_attrs.is_empty() || !info.crate_attrs.is_empty())
435452
{
436-
// We add potential backlines into attributes if there are some.
453+
// We add potential backlines/comments into attributes if there are some.
437454
push_to_s(
438455
&mut info.maybe_crate_attrs,
439456
source,

src/librustdoc/doctest/tests.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,8 @@ fn make_test_manual_extern_crate() {
127127
use asdf::qwop;
128128
assert_eq!(2+2, 4);";
129129
let expected = "#![allow(unused)]
130-
extern crate asdf;
131130
fn main() {
131+
extern crate asdf;
132132
use asdf::qwop;
133133
assert_eq!(2+2, 4);
134134
}"
@@ -144,8 +144,8 @@ fn make_test_manual_extern_crate_with_macro_use() {
144144
use asdf::qwop;
145145
assert_eq!(2+2, 4);";
146146
let expected = "#![allow(unused)]
147-
#[macro_use] extern crate asdf;
148147
fn main() {
148+
#[macro_use] extern crate asdf;
149149
use asdf::qwop;
150150
assert_eq!(2+2, 4);
151151
}"
@@ -228,8 +228,8 @@ fn make_test_fake_main() {
228228
let input = "//Ceci n'est pas une `fn main`
229229
assert_eq!(2+2, 4);";
230230
let expected = "#![allow(unused)]
231-
//Ceci n'est pas une `fn main`
232231
fn main() {
232+
//Ceci n'est pas une `fn main`
233233
assert_eq!(2+2, 4);
234234
}"
235235
.to_string();
@@ -259,8 +259,8 @@ fn make_test_issues_21299() {
259259
assert_eq!(2+2, 4);";
260260

261261
let expected = "#![allow(unused)]
262-
// fn main
263262
fn main() {
263+
// fn main
264264
assert_eq!(2+2, 4);
265265
}"
266266
.to_string();
@@ -277,10 +277,10 @@ fn make_test_issues_33731() {
277277
assert_eq!(asdf::foo, 4);";
278278

279279
let expected = "#![allow(unused)]
280-
extern crate hella_qwop;
281280
#[allow(unused_extern_crates)]
282281
extern crate r#asdf;
283282
fn main() {
283+
extern crate hella_qwop;
284284
assert_eq!(asdf::foo, 4);
285285
}"
286286
.to_string();

0 commit comments

Comments
 (0)