33
44use crate :: clean:: * ;
55use crate :: core:: DocContext ;
6+ use crate :: errors:: BareUrlNotHyperlink ;
67use crate :: html:: markdown:: main_body_opts;
78use crate :: passes:: source_span_for_markdown_range;
89use core:: ops:: Range ;
910use pulldown_cmark:: { Event , Parser , Tag } ;
1011use regex:: Regex ;
11- use rustc_errors:: Applicability ;
1212use std:: mem;
1313use std:: sync:: LazyLock ;
1414
@@ -20,25 +20,31 @@ pub(super) fn visit_item(cx: &DocContext<'_>, item: &Item) {
2020 } ;
2121 let dox = item. attrs . collapsed_doc_value ( ) . unwrap_or_default ( ) ;
2222 if !dox. is_empty ( ) {
23- let report_diag = |cx : & DocContext < ' _ > , msg : & str , url : & str , range : Range < usize > | {
24- let sp = source_span_for_markdown_range ( cx. tcx , & dox, & range, & item. attrs )
25- . unwrap_or_else ( || item. attr_span ( cx. tcx ) ) ;
26- cx. tcx . struct_span_lint_hir ( crate :: lint:: BARE_URLS , hir_id, sp, msg, |lint| {
27- lint. note ( "bare URLs are not automatically turned into clickable links" )
28- . span_suggestion (
29- sp,
30- "use an automatic link instead" ,
31- format ! ( "<{}>" , url) ,
32- Applicability :: MachineApplicable ,
33- )
34- } ) ;
35- } ;
36-
3723 let mut p = Parser :: new_ext ( & dox, main_body_opts ( ) ) . into_offset_iter ( ) ;
3824
3925 while let Some ( ( event, range) ) = p. next ( ) {
4026 match event {
41- Event :: Text ( s) => find_raw_urls ( cx, & s, range, & report_diag) ,
27+ Event :: Text ( text) => {
28+ trace ! ( "looking for raw urls in {}" , text) ;
29+ // For now, we only check "full" URLs (meaning, starting with "http://" or "https://").
30+ for match_ in URL_REGEX . find_iter ( & text) {
31+ let url = match_. as_str ( ) ;
32+ let url_range = match_. range ( ) ;
33+ let range = Range {
34+ start : range. start + url_range. start ,
35+ end : range. start + url_range. end ,
36+ } ;
37+ let span =
38+ source_span_for_markdown_range ( cx. tcx , & dox, & range, & item. attrs )
39+ . unwrap_or_else ( || item. attr_span ( cx. tcx ) ) ;
40+ cx. tcx . emit_spanned_lint (
41+ crate :: lint:: BARE_URLS ,
42+ hir_id,
43+ span,
44+ BareUrlNotHyperlink { span, url } ,
45+ ) ;
46+ }
47+ }
4248 // We don't want to check the text inside code blocks or links.
4349 Event :: Start ( tag @ ( Tag :: CodeBlock ( _) | Tag :: Link ( ..) ) ) => {
4450 while let Some ( ( event, _) ) = p. next ( ) {
@@ -67,23 +73,3 @@ static URL_REGEX: LazyLock<Regex> = LazyLock::new(|| {
6773 ) )
6874 . expect ( "failed to build regex" )
6975} ) ;
70-
71- fn find_raw_urls (
72- cx : & DocContext < ' _ > ,
73- text : & str ,
74- range : Range < usize > ,
75- f : & impl Fn ( & DocContext < ' _ > , & str , & str , Range < usize > ) ,
76- ) {
77- trace ! ( "looking for raw urls in {}" , text) ;
78- // For now, we only check "full" URLs (meaning, starting with "http://" or "https://").
79- for match_ in URL_REGEX . find_iter ( text) {
80- let url = match_. as_str ( ) ;
81- let url_range = match_. range ( ) ;
82- f (
83- cx,
84- "this URL is not a hyperlink" ,
85- url,
86- Range { start : range. start + url_range. start , end : range. start + url_range. end } ,
87- ) ;
88- }
89- }
0 commit comments