@@ -473,37 +473,64 @@ impl<'a> LintExtractor<'a> {
473
473
. filter ( |line| line. starts_with ( '{' ) )
474
474
. map ( serde_json:: from_str)
475
475
. collect :: < Result < Vec < serde_json:: Value > , _ > > ( ) ?;
476
+
476
477
// First try to find the messages with the `code` field set to our lint.
477
478
let matches: Vec < _ > = msgs
478
479
. iter ( )
479
480
. filter ( |msg| matches ! ( & msg[ "code" ] [ "code" ] , serde_json:: Value :: String ( s) if s==name) )
480
481
. map ( |msg| msg[ "rendered" ] . as_str ( ) . expect ( "rendered field should exist" ) . to_string ( ) )
481
482
. collect ( ) ;
482
- if matches. is_empty ( ) {
483
- // Some lints override their code to something else (E0566).
484
- // Try to find something that looks like it could be our lint.
485
- let matches: Vec < _ > = msgs. iter ( ) . filter ( |msg|
486
- matches ! ( & msg[ "rendered" ] , serde_json:: Value :: String ( s) if s. contains( name) ) )
487
- . map ( |msg| msg[ "rendered" ] . as_str ( ) . expect ( "rendered field should exist" ) . to_string ( ) )
488
- . collect ( ) ;
489
- if matches. is_empty ( ) {
490
- let rendered: Vec < & str > =
491
- msgs. iter ( ) . filter_map ( |msg| msg[ "rendered" ] . as_str ( ) ) . collect ( ) ;
492
- let non_json: Vec < & str > =
493
- stderr. lines ( ) . filter ( |line| !line. starts_with ( '{' ) ) . collect ( ) ;
494
- Err ( format ! (
495
- "did not find lint `{}` in output of example, got:\n {}\n {}" ,
496
- name,
497
- non_json. join( "\n " ) ,
498
- rendered. join( "\n " )
499
- )
500
- . into ( ) )
501
- } else {
502
- Ok ( matches. join ( "\n " ) )
503
- }
504
- } else {
505
- Ok ( matches. join ( "\n " ) )
483
+ if !matches. is_empty ( ) {
484
+ return Ok ( matches. join ( "\n " ) ) ;
485
+ }
486
+
487
+ // Try to detect if an unstable lint forgot to enable a `#![feature(..)]`.
488
+ // Specifically exclude `test_unstable_lint` which exercises this on purpose.
489
+ if name != "test_unstable_lint"
490
+ && msgs. iter ( ) . any ( |msg| {
491
+ matches ! ( & msg[ "code" ] [ "code" ] , serde_json:: Value :: String ( s) if s=="unknown_lints" )
492
+ && matches ! ( & msg[ "message" ] , serde_json:: Value :: String ( s) if s. contains( name) )
493
+ } )
494
+ {
495
+ let rendered: Vec < & str > =
496
+ msgs. iter ( ) . filter_map ( |msg| msg[ "rendered" ] . as_str ( ) ) . collect ( ) ;
497
+ let non_json: Vec < & str > =
498
+ stderr. lines ( ) . filter ( |line| !line. starts_with ( '{' ) ) . collect ( ) ;
499
+ return Err ( format ! (
500
+ "did not find lint `{}` in output of example (got unknown_lints)\n \
501
+ Is the lint possibly misspelled, or does it need a `#![feature(...)]`?\n \
502
+ Output was:\n \
503
+ {}\n {}",
504
+ name,
505
+ rendered. join( "\n " ) ,
506
+ non_json. join( "\n " ) ,
507
+ )
508
+ . into ( ) ) ;
506
509
}
510
+
511
+ // Some lints override their code to something else (E0566).
512
+ // Try to find something that looks like it could be our lint.
513
+ let matches: Vec < _ > = msgs
514
+ . iter ( )
515
+ . filter (
516
+ |msg| matches ! ( & msg[ "rendered" ] , serde_json:: Value :: String ( s) if s. contains( name) ) ,
517
+ )
518
+ . map ( |msg| msg[ "rendered" ] . as_str ( ) . expect ( "rendered field should exist" ) . to_string ( ) )
519
+ . collect ( ) ;
520
+ if !matches. is_empty ( ) {
521
+ return Ok ( matches. join ( "\n " ) ) ;
522
+ }
523
+
524
+ // Otherwise, give a descriptive error.
525
+ let rendered: Vec < & str > = msgs. iter ( ) . filter_map ( |msg| msg[ "rendered" ] . as_str ( ) ) . collect ( ) ;
526
+ let non_json: Vec < & str > = stderr. lines ( ) . filter ( |line| !line. starts_with ( '{' ) ) . collect ( ) ;
527
+ Err ( format ! (
528
+ "did not find lint `{}` in output of example, got:\n {}\n {}" ,
529
+ name,
530
+ non_json. join( "\n " ) ,
531
+ rendered. join( "\n " )
532
+ )
533
+ . into ( ) )
507
534
}
508
535
509
536
/// Saves the mdbook lint chapters at the given path.
0 commit comments