@@ -5,15 +5,17 @@ use std::fmt::{self, Write as _};
55use std:: io;
66use 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 } ;
911use rustc_errors:: ColorConfig ;
1012use rustc_errors:: emitter:: stderr_destination;
1113use rustc_parse:: new_parser_from_source_str;
1214use rustc_session:: parse:: ParseSess ;
13- use rustc_span:: FileName ;
1415use rustc_span:: edition:: Edition ;
1516use rustc_span:: source_map:: SourceMap ;
1617use rustc_span:: symbol:: sym;
18+ use rustc_span:: { FileName , kw} ;
1719use tracing:: debug;
1820
1921use 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,
0 commit comments