@@ -14,6 +14,7 @@ use rustc_middle::ty;
1414use rustc_parse:: maybe_new_parser_from_source_str;
1515use rustc_session:: parse:: ParseSess ;
1616use rustc_session:: { declare_tool_lint, impl_lint_pass} ;
17+ use rustc_span:: edition:: Edition ;
1718use rustc_span:: source_map:: { BytePos , FilePathMapping , MultiSpan , SourceMap , Span } ;
1819use rustc_span:: { sym, FileName , Pos } ;
1920use std:: io;
@@ -377,7 +378,7 @@ fn check_attrs<'a>(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, attrs
377378 check_doc ( cx, valid_idents, events, & spans)
378379}
379380
380- const RUST_CODE : & [ & str ] = & [ "rust" , "no_run" , "should_panic" , "compile_fail" , "edition2018" ] ;
381+ const RUST_CODE : & [ & str ] = & [ "rust" , "no_run" , "should_panic" , "compile_fail" ] ;
381382
382383fn check_doc < ' a , Events : Iterator < Item = ( pulldown_cmark:: Event < ' a > , Range < usize > ) > > (
383384 cx : & LateContext < ' _ > ,
@@ -400,13 +401,21 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
400401 let mut in_link = None ;
401402 let mut in_heading = false ;
402403 let mut is_rust = false ;
404+ let mut edition = None ;
403405 for ( event, range) in events {
404406 match event {
405407 Start ( CodeBlock ( ref kind) ) => {
406408 in_code = true ;
407409 if let CodeBlockKind :: Fenced ( lang) = kind {
408- is_rust =
409- lang. is_empty ( ) || !lang. contains ( "ignore" ) && lang. split ( ',' ) . any ( |i| RUST_CODE . contains ( & i) ) ;
410+ let infos = lang. split ( ',' ) . collect :: < Vec < _ > > ( ) ;
411+ is_rust = !infos. iter ( ) . any ( |& i| i == "ignore" )
412+ && infos
413+ . iter ( )
414+ . any ( |i| i. is_empty ( ) || i. starts_with ( "edition" ) || RUST_CODE . contains ( & i) ) ;
415+ edition = infos
416+ . iter ( )
417+ . find_map ( |i| i. starts_with ( "edition" ) . then ( || i[ 7 ..] . parse :: < Edition > ( ) . ok ( ) ) )
418+ . flatten ( ) ;
410419 }
411420 } ,
412421 End ( CodeBlock ( _) ) => {
@@ -436,7 +445,8 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
436445 let ( begin, span) = spans[ index] ;
437446 if in_code {
438447 if is_rust {
439- check_code ( cx, & text, span) ;
448+ let edition = edition. unwrap_or_else ( || cx. tcx . sess . edition ( ) ) ;
449+ check_code ( cx, & text, edition, span) ;
440450 }
441451 } else {
442452 // Adjust for the beginning of the current `Event`
@@ -450,10 +460,10 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
450460 headers
451461}
452462
453- fn check_code ( cx : & LateContext < ' _ > , text : & str , span : Span ) {
454- fn has_needless_main ( cx : & LateContext < ' _ > , code : & str ) -> bool {
463+ fn check_code ( cx : & LateContext < ' _ > , text : & str , edition : Edition , span : Span ) {
464+ fn has_needless_main ( code : & str , edition : Edition ) -> bool {
455465 rustc_driver:: catch_fatal_errors ( || {
456- rustc_span:: with_session_globals ( cx . tcx . sess . edition ( ) , || {
466+ rustc_span:: with_session_globals ( edition, || {
457467 let filename = FileName :: anon_source_code ( code) ;
458468
459469 let sm = Lrc :: new ( SourceMap :: new ( FilePathMapping :: empty ( ) ) ) ;
@@ -516,7 +526,7 @@ fn check_code(cx: &LateContext<'_>, text: &str, span: Span) {
516526 . unwrap_or_default ( )
517527 }
518528
519- if has_needless_main ( cx , text ) {
529+ if has_needless_main ( text , edition ) {
520530 span_lint ( cx, NEEDLESS_DOCTEST_MAIN , span, "needless `fn main` in doctest" ) ;
521531 }
522532}
0 commit comments