rustdoc: improve refdef handling in the unresolved link lint

This commit takes advantage of a feature in pulldown-cmark that
makes the list of link definitions available to the consuming
application. It produces unresolved link warnings for refdefs
that aren't used, and can now produce exact spans for the dest
even when it has escapes.
This commit is contained in:
Michael Howell 2025-01-31 11:55:53 -07:00
parent 608e228ca9
commit 61a97448e5
4 changed files with 170 additions and 43 deletions

View file

@ -7,7 +7,7 @@ use pulldown_cmark::{
use rustc_ast as ast;
use rustc_ast::attr::AttributeExt;
use rustc_ast::util::comments::beautify_doc_string;
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
use rustc_middle::ty::TyCtxt;
use rustc_span::def_id::DefId;
use rustc_span::{DUMMY_SP, InnerSpan, Span, Symbol, kw, sym};
@ -422,9 +422,11 @@ fn parse_links<'md>(doc: &'md str) -> Vec<Box<str>> {
);
let mut links = Vec::new();
let mut refids = FxHashSet::default();
while let Some(event) = event_iter.next() {
match event {
Event::Start(Tag::Link { link_type, dest_url, title: _, id: _ })
Event::Start(Tag::Link { link_type, dest_url, title: _, id })
if may_be_doc_link(link_type) =>
{
if matches!(
@ -439,6 +441,12 @@ fn parse_links<'md>(doc: &'md str) -> Vec<Box<str>> {
links.push(display_text);
}
}
if matches!(
link_type,
LinkType::Reference | LinkType::Shortcut | LinkType::Collapsed
) {
refids.insert(id);
}
links.push(preprocess_link(&dest_url));
}
@ -446,6 +454,12 @@ fn parse_links<'md>(doc: &'md str) -> Vec<Box<str>> {
}
}
for (label, refdef) in event_iter.reference_definitions().iter() {
if !refids.contains(label) {
links.push(preprocess_link(&refdef.dest));
}
}
links
}