about summary refs log tree commit diff
path: root/compiler/rustc_resolve/src/rustdoc.rs
diff options
context:
space:
mode:
authorKyle Lin <minecraft.kyle.train@gmail.com>2023-06-30 02:01:21 +0800
committerKyle Lin <minecraft.kyle.train@gmail.com>2023-08-18 15:19:10 +0800
commit65e24a57bbd510e79d667d5c6e18507895e36447 (patch)
tree0f5a0142d934a2c0b7d3ed8a5a43c9ce832db73b /compiler/rustc_resolve/src/rustdoc.rs
parentda582a71d2c19a2ded0c45f464cb64c9544c26eb (diff)
downloadrust-65e24a57bbd510e79d667d5c6e18507895e36447.tar.gz
rust-65e24a57bbd510e79d667d5c6e18507895e36447.zip
Fix resolution caching
Diffstat (limited to 'compiler/rustc_resolve/src/rustdoc.rs')
-rw-r--r--compiler/rustc_resolve/src/rustdoc.rs57
1 files changed, 49 insertions, 8 deletions
diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs
index d433391f272..083d16d3b04 100644
--- a/compiler/rustc_resolve/src/rustdoc.rs
+++ b/compiler/rustc_resolve/src/rustdoc.rs
@@ -392,16 +392,57 @@ pub(crate) fn attrs_to_preprocessed_links(attrs: &[ast::Attribute]) -> Vec<Box<s
     let (doc_fragments, _) = attrs_to_doc_fragments(attrs.iter().map(|attr| (attr, None)), true);
     let doc = prepare_to_doc_link_resolution(&doc_fragments).into_values().next().unwrap();
 
-    Parser::new_with_broken_link_callback(
+    parse_links(&doc)
+}
+
+/// Similiar version of `markdown_links` from rustdoc.
+/// This will collect destination links and display text if exists.
+fn parse_links<'md>(doc: &'md str) -> Vec<Box<str>> {
+    let mut broken_link_callback = |link: BrokenLink<'md>| Some((link.reference, "".into()));
+    let mut event_iter = Parser::new_with_broken_link_callback(
         &doc,
         main_body_opts(),
-        Some(&mut |link: BrokenLink<'_>| Some((link.reference, "".into()))),
+        Some(&mut broken_link_callback),
     )
-    .filter_map(|event| match event {
-        Event::Start(Tag::Link(link_type, dest, _)) if may_be_doc_link(link_type) => {
-            Some(preprocess_link(&dest))
+    .into_iter();
+    let mut links = Vec::new();
+
+    while let Some(event) = event_iter.next() {
+        match event {
+            Event::Start(Tag::Link(link_type, dest, _)) if may_be_doc_link(link_type) => {
+                if let Some(display_text) = collect_link_data(&mut event_iter) {
+                    links.push(display_text);
+                }
+
+                links.push(preprocess_link(&dest));
+            }
+            _ => {}
+        }
+    }
+
+    links
+}
+
+/// Collects additional data of link.
+fn collect_link_data<'input, 'callback>(
+    event_iter: &mut Parser<'input, 'callback>,
+) -> Option<Box<str>> {
+    let mut display_text = None;
+
+    while let Some(event) = event_iter.next() {
+        match event {
+            Event::Text(code) => {
+                display_text = Some(code.to_string().into_boxed_str());
+            }
+            Event::Code(code) => {
+                display_text = Some(code.to_string().into_boxed_str());
+            }
+            Event::End(_) => {
+                break;
+            }
+            _ => {}
         }
-        _ => None,
-    })
-    .collect()
+    }
+
+    display_text
 }