s
}
-crate fn markdown_links(md: &str) -> Vec<(String, Option<Range<usize>>)> {
+crate fn markdown_links(md: &str) -> Vec<(String, Range<usize>)> {
if md.is_empty() {
return vec![];
}
let mut links = vec![];
let mut shortcut_links = vec![];
- let locate = |s: &str| unsafe {
+ let locate = |s: &str, fallback: Range<usize>| unsafe {
let s_start = s.as_ptr();
let s_end = s_start.add(s.len());
let md_start = md.as_ptr();
if md_start <= s_start && s_end <= md_end {
let start = s_start.offset_from(md_start) as usize;
let end = s_end.offset_from(md_start) as usize;
- Some(start..end)
+ start..end
} else {
- None
+ fallback
}
};
let mut push = |link: BrokenLink<'_>| {
// FIXME: use `link.span` instead of `locate`
// (doing it now includes the `[]` as well as the text)
- shortcut_links.push((link.reference.to_owned(), locate(link.reference)));
+ shortcut_links.push((link.reference.to_owned(), locate(link.reference, link.span)));
None
};
let p = Parser::new_with_broken_link_callback(md, opts(), Some(&mut push)).into_offset_iter();
if let Event::Start(Tag::Link(_, dest, _)) = ev.0 {
debug!("found link: {}", dest);
links.push(match dest {
- CowStr::Borrowed(s) => (s.to_owned(), locate(s)),
- s @ (CowStr::Boxed(..) | CowStr::Inlined(..)) => (s.into_string(), None),
+ CowStr::Borrowed(s) => (s.to_owned(), locate(s, ev.1)),
+ s @ (CowStr::Boxed(..) | CowStr::Inlined(..)) => (s.into_string(), ev.1),
});
}
}
item: &'a Item,
dox: &'a str,
ori_link: &'a str,
- link_range: Option<Range<usize>>,
+ link_range: Range<usize>,
}
#[derive(Clone, Debug, Hash)]
parent_node: Option<DefId>,
krate: CrateNum,
ori_link: String,
- link_range: Option<Range<usize>>,
+ link_range: Range<usize>,
) -> Option<ItemLink> {
trace!("considering link '{}'", ori_link);
msg: &str,
item: &Item,
dox: &str,
- link_range: &Option<Range<usize>>,
+ link_range: &Range<usize>,
decorate: impl FnOnce(&mut DiagnosticBuilder<'_>, Option<rustc_span::Span>),
) {
let hir_id = match cx.as_local_hir_id(item.def_id) {
cx.tcx.struct_span_lint_hir(lint, hir_id, sp, |lint| {
let mut diag = lint.build(msg);
- let span = link_range
- .as_ref()
- .and_then(|range| super::source_span_for_markdown_range(cx, dox, range, attrs));
+ let span = super::source_span_for_markdown_range(cx, dox, link_range, attrs);
- if let Some(link_range) = link_range {
- if let Some(sp) = span {
- diag.set_span(sp);
- } else {
- // blah blah blah\nblah\nblah [blah] blah blah\nblah blah
- // ^ ~~~~
- // | link_range
- // last_new_line_offset
- let last_new_line_offset = dox[..link_range.start].rfind('\n').map_or(0, |n| n + 1);
- let line = dox[last_new_line_offset..].lines().next().unwrap_or("");
-
- // Print the line containing the `link_range` and manually mark it with '^'s.
- diag.note(&format!(
- "the link appears in this line:\n\n{line}\n\
+ if let Some(sp) = span {
+ diag.set_span(sp);
+ } else {
+ // blah blah blah\nblah\nblah [blah] blah blah\nblah blah
+ // ^ ~~~~
+ // | link_range
+ // last_new_line_offset
+ let last_new_line_offset = dox[..link_range.start].rfind('\n').map_or(0, |n| n + 1);
+ let line = dox[last_new_line_offset..].lines().next().unwrap_or("");
+
+ // Print the line containing the `link_range` and manually mark it with '^'s.
+ diag.note(&format!(
+ "the link appears in this line:\n\n{line}\n\
{indicator: <before$}{indicator:^<found$}",
- line = line,
- indicator = "",
- before = link_range.start - last_new_line_offset,
- found = link_range.len(),
- ));
- }
+ line = line,
+ indicator = "",
+ before = link_range.start - last_new_line_offset,
+ found = link_range.len(),
+ ));
}
decorate(&mut diag, span);
path_str: &str,
disambiguator: Option<Disambiguator>,
dox: &str,
- link_range: Option<Range<usize>>,
+ link_range: Range<usize>,
kinds: SmallVec<[ResolutionFailure<'_>; 3]>,
) {
let tcx = collector.cx.tcx;
item: &Item,
path_str: &str,
dox: &str,
- link_range: Option<Range<usize>>,
+ link_range: Range<usize>,
failure: AnchorFailure,
) {
let msg = match failure {
item: &Item,
path_str: &str,
dox: &str,
- link_range: Option<Range<usize>>,
+ link_range: Range<usize>,
candidates: Vec<Res>,
) {
let mut msg = format!("`{}` is ", path_str);
path_str: &str,
dox: &str,
sp: Option<rustc_span::Span>,
- link_range: &Option<Range<usize>>,
+ link_range: &Range<usize>,
) {
let suggestion = disambiguator.suggestion();
let help = format!("to link to the {}, {}", disambiguator.descr(), suggestion.descr());
if let Some(sp) = sp {
- let link_range = link_range.as_ref().expect("must have a link range if we have a span");
let msg = if dox.bytes().nth(link_range.start) == Some(b'`') {
format!("`{}`", suggestion.as_help(path_str))
} else {
item: &Item,
path_str: &str,
dox: &str,
- link_range: Option<Range<usize>>,
+ link_range: Range<usize>,
) {
let sym;
let item_name = match item.name {