@@ -1135,6 +1135,7 @@ crate fn markdown_links(md: &str) -> Vec<(String, Range<usize>)> {
11351135
11361136 let links = RefCell :: new ( vec ! [ ] ) ;
11371137
1138+ // FIXME: remove this function once pulldown_cmark can provide spans for link definitions.
11381139 let locate = |s : & str , fallback : Range < usize > | unsafe {
11391140 let s_start = s. as_ptr ( ) ;
11401141 let s_end = s_start. add ( s. len ( ) ) ;
@@ -1149,10 +1150,25 @@ crate fn markdown_links(md: &str) -> Vec<(String, Range<usize>)> {
11491150 }
11501151 } ;
11511152
1153+ let span_for_link = |link : & CowStr < ' _ > , span : Range < usize > | {
1154+ // For diagnostics, we want to underline the link's definition but `span` will point at
1155+ // where the link is used. This is a problem for reference-style links, where the definition
1156+ // is separate from the usage.
1157+ match link {
1158+ // `Borrowed` variant means the string (the link's destination) may come directly from
1159+ // the markdown text and we can locate the original link destination.
1160+ // NOTE: LinkReplacer also provides `Borrowed` but possibly from other sources,
1161+ // so `locate()` can fall back to use `span`.
1162+ CowStr :: Borrowed ( s) => locate ( s, span) ,
1163+
1164+ // For anything else, we can only use the provided range.
1165+ CowStr :: Boxed ( _) | CowStr :: Inlined ( _) => span,
1166+ }
1167+ } ;
1168+
11521169 let mut push = |link : BrokenLink < ' _ > | {
1153- // FIXME: use `link.span` instead of `locate`
1154- // (doing it now includes the `[]` as well as the text)
1155- links. borrow_mut ( ) . push ( ( link. reference . to_owned ( ) , locate ( link. reference , link. span ) ) ) ;
1170+ let span = span_for_link ( & CowStr :: Borrowed ( link. reference ) , link. span ) ;
1171+ links. borrow_mut ( ) . push ( ( link. reference . to_owned ( ) , span) ) ;
11561172 None
11571173 } ;
11581174 let p = Parser :: new_with_broken_link_callback ( md, opts ( ) , Some ( & mut push) ) . into_offset_iter ( ) ;
@@ -1165,10 +1181,8 @@ crate fn markdown_links(md: &str) -> Vec<(String, Range<usize>)> {
11651181 for ev in iter {
11661182 if let Event :: Start ( Tag :: Link ( _, dest, _) ) = ev. 0 {
11671183 debug ! ( "found link: {}" , dest) ;
1168- links. borrow_mut ( ) . push ( match dest {
1169- CowStr :: Borrowed ( s) => ( s. to_owned ( ) , locate ( s, ev. 1 ) ) ,
1170- s @ ( CowStr :: Boxed ( ..) | CowStr :: Inlined ( ..) ) => ( s. into_string ( ) , ev. 1 ) ,
1171- } ) ;
1184+ let span = span_for_link ( & dest, ev. 1 ) ;
1185+ links. borrow_mut ( ) . push ( ( dest. into_string ( ) , span) ) ;
11721186 }
11731187 }
11741188
0 commit comments