@@ -14,6 +14,7 @@ use rustc_middle::ty;
14
14
use rustc_parse:: maybe_new_parser_from_source_str;
15
15
use rustc_session:: parse:: ParseSess ;
16
16
use rustc_session:: { declare_tool_lint, impl_lint_pass} ;
17
+ use rustc_span:: edition:: Edition ;
17
18
use rustc_span:: source_map:: { BytePos , FilePathMapping , MultiSpan , SourceMap , Span } ;
18
19
use rustc_span:: { sym, FileName , Pos } ;
19
20
use std:: io;
@@ -377,7 +378,7 @@ fn check_attrs<'a>(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, attrs
377
378
check_doc ( cx, valid_idents, events, & spans)
378
379
}
379
380
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" ] ;
381
382
382
383
fn check_doc < ' a , Events : Iterator < Item = ( pulldown_cmark:: Event < ' a > , Range < usize > ) > > (
383
384
cx : & LateContext < ' _ > ,
@@ -400,13 +401,21 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
400
401
let mut in_link = None ;
401
402
let mut in_heading = false ;
402
403
let mut is_rust = false ;
404
+ let mut edition = None ;
403
405
for ( event, range) in events {
404
406
match event {
405
407
Start ( CodeBlock ( ref kind) ) => {
406
408
in_code = true ;
407
409
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 ( ) ;
410
419
}
411
420
} ,
412
421
End ( CodeBlock ( _) ) => {
@@ -436,7 +445,8 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
436
445
let ( begin, span) = spans[ index] ;
437
446
if in_code {
438
447
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) ;
440
450
}
441
451
} else {
442
452
// 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
450
460
headers
451
461
}
452
462
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 {
455
465
rustc_driver:: catch_fatal_errors ( || {
456
- rustc_span:: with_session_globals ( cx . tcx . sess . edition ( ) , || {
466
+ rustc_span:: with_session_globals ( edition, || {
457
467
let filename = FileName :: anon_source_code ( code) ;
458
468
459
469
let sm = Lrc :: new ( SourceMap :: new ( FilePathMapping :: empty ( ) ) ) ;
@@ -516,7 +526,7 @@ fn check_code(cx: &LateContext<'_>, text: &str, span: Span) {
516
526
. unwrap_or_default ( )
517
527
}
518
528
519
- if has_needless_main ( cx , text ) {
529
+ if has_needless_main ( text , edition ) {
520
530
span_lint ( cx, NEEDLESS_DOCTEST_MAIN , span, "needless `fn main` in doctest" ) ;
521
531
}
522
532
}
0 commit comments