@@ -655,205 +655,6 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
655655 headers
656656}
657657
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
857658struct FindPanicUnwrap < ' a , ' tcx > {
858659 cx : & ' a LateContext < ' tcx > ,
859660 panic_span : Option < Span > ,
0 commit comments