@@ -451,66 +451,72 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
451
451
}
452
452
453
453
fn check_code ( cx : & LateContext < ' _ > , text : & str , span : Span ) {
454
- fn has_needless_main ( code : & str ) -> bool {
455
- let filename = FileName :: anon_source_code ( code) ;
456
-
457
- let sm = Lrc :: new ( SourceMap :: new ( FilePathMapping :: empty ( ) ) ) ;
458
- let emitter = EmitterWriter :: new ( box io:: sink ( ) , None , false , false , false , None , false ) ;
459
- let handler = Handler :: with_emitter ( false , None , box emitter) ;
460
- let sess = ParseSess :: with_span_handler ( handler, sm) ;
461
-
462
- let mut parser = match maybe_new_parser_from_source_str ( & sess, filename, code. into ( ) ) {
463
- Ok ( p) => p,
464
- Err ( errs) => {
465
- for mut err in errs {
466
- err. cancel ( ) ;
467
- }
468
- return false ;
469
- } ,
470
- } ;
471
-
472
- let mut relevant_main_found = false ;
473
- loop {
474
- match parser. parse_item ( ) {
475
- Ok ( Some ( item) ) => match & item. kind {
476
- // Tests with one of these items are ignored
477
- ItemKind :: Static ( ..)
478
- | ItemKind :: Const ( ..)
479
- | ItemKind :: ExternCrate ( ..)
480
- | ItemKind :: ForeignMod ( ..) => return false ,
481
- // We found a main function ...
482
- ItemKind :: Fn ( _, sig, _, Some ( block) ) if item. ident . name == sym:: main => {
483
- let is_async = matches ! ( sig. header. asyncness, Async :: Yes { .. } ) ;
484
- let returns_nothing = match & sig. decl . output {
485
- FnRetTy :: Default ( ..) => true ,
486
- FnRetTy :: Ty ( ty) if ty. kind . is_unit ( ) => true ,
487
- _ => false ,
488
- } ;
489
-
490
- if returns_nothing && !is_async && !block. stmts . is_empty ( ) {
491
- // This main function should be linted, but only if there are no other functions
492
- relevant_main_found = true ;
493
- } else {
494
- // This main function should not be linted, we're done
495
- return false ;
454
+ fn has_needless_main ( cx : & LateContext < ' _ > , code : & str ) -> bool {
455
+ rustc_driver:: catch_fatal_errors ( || {
456
+ rustc_span:: with_session_globals ( cx. tcx . sess . edition ( ) , || {
457
+ let filename = FileName :: anon_source_code ( code) ;
458
+
459
+ let sm = Lrc :: new ( SourceMap :: new ( FilePathMapping :: empty ( ) ) ) ;
460
+ let emitter = EmitterWriter :: new ( box io:: sink ( ) , None , false , false , false , None , false ) ;
461
+ let handler = Handler :: with_emitter ( false , None , box emitter) ;
462
+ let sess = ParseSess :: with_span_handler ( handler, sm) ;
463
+
464
+ let mut parser = match maybe_new_parser_from_source_str ( & sess, filename, code. into ( ) ) {
465
+ Ok ( p) => p,
466
+ Err ( errs) => {
467
+ for mut err in errs {
468
+ err. cancel ( ) ;
496
469
}
470
+ return false ;
497
471
} ,
498
- // Another function was found; this case is ignored too
499
- ItemKind :: Fn ( ..) => return false ,
500
- _ => { } ,
501
- } ,
502
- Ok ( None ) => break ,
503
- Err ( mut e) => {
504
- e. cancel ( ) ;
505
- return false ;
506
- } ,
507
- }
508
- }
472
+ } ;
473
+
474
+ let mut relevant_main_found = false ;
475
+ loop {
476
+ match parser. parse_item ( ) {
477
+ Ok ( Some ( item) ) => match & item. kind {
478
+ // Tests with one of these items are ignored
479
+ ItemKind :: Static ( ..)
480
+ | ItemKind :: Const ( ..)
481
+ | ItemKind :: ExternCrate ( ..)
482
+ | ItemKind :: ForeignMod ( ..) => return false ,
483
+ // We found a main function ...
484
+ ItemKind :: Fn ( _, sig, _, Some ( block) ) if item. ident . name == sym:: main => {
485
+ let is_async = matches ! ( sig. header. asyncness, Async :: Yes { .. } ) ;
486
+ let returns_nothing = match & sig. decl . output {
487
+ FnRetTy :: Default ( ..) => true ,
488
+ FnRetTy :: Ty ( ty) if ty. kind . is_unit ( ) => true ,
489
+ _ => false ,
490
+ } ;
491
+
492
+ if returns_nothing && !is_async && !block. stmts . is_empty ( ) {
493
+ // This main function should be linted, but only if there are no other functions
494
+ relevant_main_found = true ;
495
+ } else {
496
+ // This main function should not be linted, we're done
497
+ return false ;
498
+ }
499
+ } ,
500
+ // Another function was found; this case is ignored too
501
+ ItemKind :: Fn ( ..) => return false ,
502
+ _ => { } ,
503
+ } ,
504
+ Ok ( None ) => break ,
505
+ Err ( mut e) => {
506
+ e. cancel ( ) ;
507
+ return false ;
508
+ } ,
509
+ }
510
+ }
509
511
510
- relevant_main_found
512
+ relevant_main_found
513
+ } )
514
+ } )
515
+ . ok ( )
516
+ . unwrap_or_default ( )
511
517
}
512
518
513
- if has_needless_main ( text) {
519
+ if has_needless_main ( cx , text) {
514
520
span_lint ( cx, NEEDLESS_DOCTEST_MAIN , span, "needless `fn main` in doctest" ) ;
515
521
}
516
522
}
0 commit comments