@@ -655,205 +655,6 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
655
655
headers
656
656
}
657
657
658
- <<<<<<< HEAD : src/tools/clippy/clippy_lints/src/doc/mod . rs
659
- =======
660
- fn check_link_quotes ( cx : & LateContext < ' _ > , trimmed_text : & str , range : Range < usize > , fragments : Fragments < ' _ > ) {
661
- if trimmed_text. starts_with ( '\'' )
662
- && trimmed_text. ends_with( '\'' )
663
- && let Some ( span) = fragments. span( cx, range)
664
- {
665
- span_lint(
666
- cx,
667
- DOC_LINK_WITH_QUOTES ,
668
- span,
669
- "possible intra-doc link using quotes instead of backticks" ,
670
- ) ;
671
- }
672
- }
673
-
674
- fn check_code ( cx : & LateContext < ' _ > , text : & str , edition : Edition , range : Range < usize > , fragments : Fragments < ' _ > ) {
675
- fn has_needless_main ( code : String , edition : Edition ) -> bool {
676
- rustc_driver:: catch_fatal_errors ( || {
677
- rustc_span:: create_session_globals_then( edition, || {
678
- let filename = FileName :: anon_source_code( & code) ;
679
-
680
- let fallback_bundle =
681
- rustc_errors:: fallback_fluent_bundle( rustc_driver:: DEFAULT_LOCALE_RESOURCES . to_vec( ) , false ) ;
682
- let emitter = EmitterWriter :: new( Box :: new( io:: sink( ) ) , fallback_bundle) ;
683
- let handler = Handler :: with_emitter( Box :: new( emitter) ) . disable_warnings( ) ;
684
- #[ expect( clippy:: arc_with_non_send_sync) ] // `Lrc` is expected by with_span_handler
685
- let sm = Lrc :: new( SourceMap :: new( FilePathMapping :: empty( ) ) ) ;
686
- let sess = ParseSess :: with_span_handler( handler, sm) ;
687
-
688
- let mut parser = match maybe_new_parser_from_source_str( & sess, filename, code) {
689
- Ok ( p) => p,
690
- Err ( errs) => {
691
- drop( errs) ;
692
- return false ;
693
- } ,
694
- } ;
695
-
696
- let mut relevant_main_found = false ;
697
- loop {
698
- match parser. parse_item( ForceCollect :: No ) {
699
- Ok ( Some ( item) ) => match & item. kind {
700
- ItemKind : : Fn ( box Fn {
701
- sig, body : Some ( block) , ..
702
- } ) if item. ident. name == sym:: main => {
703
- let is_async = sig. header. coro_kind. map_or( false , |coro| coro. is_async( ) ) ;
704
- let returns_nothing = match & sig. decl. output {
705
- FnRetTy : : Default ( ..) => true ,
706
- FnRetTy : : Ty ( ty) if ty. kind. is_unit( ) => true ,
707
- FnRetTy : : Ty ( _) => false ,
708
- } ;
709
-
710
- if returns_nothing && !is_async && !block. stmts. is_empty( ) {
711
- // This main function should be linted, but only if there are no other functions
712
- relevant_main_found = true ;
713
- } else {
714
- // This main function should not be linted, we're done
715
- return false ;
716
- }
717
- } ,
718
- // Tests with one of these items are ignored
719
- ItemKind :: Static ( ..)
720
- | ItemKind :: Const ( ..)
721
- | ItemKind :: ExternCrate ( ..)
722
- | ItemKind :: ForeignMod ( ..)
723
- // Another function was found; this case is ignored
724
- | ItemKind :: Fn ( ..) => return false,
725
- _ => { } ,
726
- } ,
727
- Ok ( None ) => break ,
728
- Err ( e) => {
729
- e. cancel( ) ;
730
- return false ;
731
- } ,
732
- }
733
- }
734
-
735
- relevant_main_found
736
- } )
737
- } )
738
- . ok( )
739
- . unwrap_or_default( )
740
- }
741
-
742
- let trailing_whitespace = text. len( ) - text. trim_end( ) . len( ) ;
743
-
744
- // Because of the global session, we need to create a new session in a different thread with
745
- // the edition we need.
746
- let text = text. to_owned( ) ;
747
- if thread:: spawn( move || has_needless_main( text, edition) )
748
- . join( )
749
- . expect( "thread:: spawn failed")
750
- && let Some ( span) = fragments. span( cx, range. start..range. end - trailing_whitespace)
751
- {
752
- span_lint( cx, NEEDLESS_DOCTEST_MAIN , span, "needless `fn main` in doctest") ;
753
- }
754
- }
755
-
756
- fn check_text( cx: & LateContext < ' _ > , valid_idents : & FxHashSet < String > , text : & str , span : Span ) {
757
- for word in text. split( |c: char | c. is_whitespace( ) || c == '\'' ) {
758
- // Trim punctuation as in `some comment (see foo::bar).`
759
- // ^^
760
- // Or even as in `_foo bar_` which is emphasized. Also preserve `::` as a prefix/suffix.
761
- let mut word = word. trim_matches( |c: char | !c. is_alphanumeric( ) && c != ':' ) ;
762
-
763
- // Remove leading or trailing single `:` which may be part of a sentence.
764
- if word. starts_with( ':' ) && !word. starts_with( ":: ") {
765
- word = word. trim_start_matches( ':' ) ;
766
- }
767
- if word. ends_with( ':' ) && !word. ends_with( ":: ") {
768
- word = word. trim_end_matches( ':' ) ;
769
- }
770
-
771
- if valid_idents. contains( word) || word. chars( ) . all( |c| c == ':' ) {
772
- continue ;
773
- }
774
-
775
- // Adjust for the current word
776
- let offset = word. as_ptr( ) as usize - text. as_ptr ( ) as usize ;
777
- let span = Span :: new (
778
- span . lo( ) + BytePos :: from_usize ( offset ) ,
779
- span . lo( ) + BytePos :: from_usize ( offset + word . len( ) ) ,
780
- span. ctxt ( ) ,
781
- span. parent ( ) ,
782
- ) ;
783
-
784
- check_word ( cx , word , span ) ;
785
- }
786
- }
787
-
788
- fn check_word ( cx : & LateContext < ' _ > , word : & str , span : Span ) {
789
- /// Checks if a string is upper-camel-case, i.e., starts with an uppercase and
790
- /// contains at least two uppercase letters (`Clippy` is ok) and one lower-case
791
- /// letter (`NASA` is ok).
792
- /// Plurals are also excluded (`IDs` is ok).
793
- fn is_camel_case ( s : & str ) -> bool {
794
- if s. starts_with( |c: char | c. is_ascii_digit( ) | c. is_ascii_lowercase( ) ) {
795
- return false ;
796
- }
797
-
798
- let s = s. strip_suffix( 's' ) . unwrap_or( s) ;
799
-
800
- s. chars( ) . all ( char:: is_alphanumeric )
801
- && s. chars( ) . filter( |& c| c. is_uppercase( ) ) . take( 2 ) . count( ) > 1
802
- && s. chars( ) . filter( |& c| c. is_lowercase( ) ) . take( 1 ) . count( ) > 0
803
- }
804
-
805
- fn has_underscore ( s : & str ) -> bool {
806
- s != "_" && !s. contains( "\\ _" ) && s. contains( '_' )
807
- }
808
-
809
- fn has_hyphen ( s : & str ) -> bool {
810
- s != "-" && s. contains( '-' )
811
- }
812
-
813
- if let Ok ( url) = Url :: parse ( word ) {
814
- // try to get around the fact that `foo::bar` parses as a valid URL
815
- if !url. cannot_be_a_base( ) {
816
- span_lint(
817
- cx,
818
- DOC_MARKDOWN ,
819
- span,
820
- "you should put bare URLs between `<`/`>` or make a proper Markdown link" ,
821
- ) ;
822
-
823
- return ;
824
- }
825
- }
826
-
827
- // We assume that mixed-case words are not meant to be put inside backticks. (Issue #2343)
828
- if has_underscore( word) && has_hyphen( word) {
829
- return ;
830
- }
831
-
832
- if has_underscore( word) || word. contains( "::" ) || is_camel_case( word) {
833
- let mut applicability = Applicability :: MachineApplicable ;
834
-
835
- span_lint_and_then(
836
- cx,
837
- DOC_MARKDOWN ,
838
- span,
839
- "item in documentation is missing backticks" ,
840
- |diag| {
841
- let snippet = snippet_with_applicability( cx, span, ".." , & mut applicability) ;
842
- diag. span_suggestion_with_style(
843
- span,
844
- "try" ,
845
- format ! ( "`{snippet}`" ) ,
846
- applicability,
847
- // always show the suggestion in a separate line, since the
848
- // inline presentation adds another pair of backticks
849
- SuggestionStyle :: ShowAlways ,
850
- ) ;
851
- } ,
852
- ) ;
853
- }
854
- }
855
-
856
- >>>>>>> d116f1718f1 ( Merge Async and Gen into CoroutineKind ) : src/tools/clippy/clippy_lints/src/doc. rs
857
658
struct FindPanicUnwrap < ' a , ' tcx > {
858
659
cx : & ' a LateContext < ' tcx > ,
859
660
panic_span : Option < Span > ,
0 commit comments