Revert "Cleanup markdown span handling"
This caused a diagnostic regression, originally it was: ``` warning: unresolved link to `std::process::Comman` --> link.rs:3:10 | 3 | //! [a]: std::process::Comman | ^^^^^^^^^^^^^^^^^^^^ no item named `Comman` in module `process` | = note: `#[warn(broken_intra_doc_links)]` on by default ``` but after that PR rustdoc now displays ``` warning: unresolved link to `std::process::Comman` --> link.rs:1:14 | 1 | //! Links to [a] [link][a] | ^^^ no item named `Comman` in module `process` | = note: `#[warn(broken_intra_doc_links)]` on by default ``` which IMO is much less clear.
This commit is contained in:
parent
1f5beec3b1
commit
0f2571235b
4 changed files with 123 additions and 86 deletions
|
@ -418,7 +418,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for LinkReplacer<'a, I> {
|
||||||
struct HeadingLinks<'a, 'b, 'ids, I> {
|
struct HeadingLinks<'a, 'b, 'ids, I> {
|
||||||
inner: I,
|
inner: I,
|
||||||
toc: Option<&'b mut TocBuilder>,
|
toc: Option<&'b mut TocBuilder>,
|
||||||
buf: VecDeque<(Event<'a>, Range<usize>)>,
|
buf: VecDeque<Event<'a>>,
|
||||||
id_map: &'ids mut IdMap,
|
id_map: &'ids mut IdMap,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -428,10 +428,8 @@ impl<'a, 'b, 'ids, I> HeadingLinks<'a, 'b, 'ids, I> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b, 'ids, I: Iterator<Item = (Event<'a>, Range<usize>)>> Iterator
|
impl<'a, 'b, 'ids, I: Iterator<Item = Event<'a>>> Iterator for HeadingLinks<'a, 'b, 'ids, I> {
|
||||||
for HeadingLinks<'a, 'b, 'ids, I>
|
type Item = Event<'a>;
|
||||||
{
|
|
||||||
type Item = (Event<'a>, Range<usize>);
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
if let Some(e) = self.buf.pop_front() {
|
if let Some(e) = self.buf.pop_front() {
|
||||||
|
@ -439,29 +437,31 @@ impl<'a, 'b, 'ids, I: Iterator<Item = (Event<'a>, Range<usize>)>> Iterator
|
||||||
}
|
}
|
||||||
|
|
||||||
let event = self.inner.next();
|
let event = self.inner.next();
|
||||||
if let Some((Event::Start(Tag::Heading(level)), _)) = event {
|
if let Some(Event::Start(Tag::Heading(level))) = event {
|
||||||
let mut id = String::new();
|
let mut id = String::new();
|
||||||
for event in &mut self.inner {
|
for event in &mut self.inner {
|
||||||
match &event.0 {
|
match &event {
|
||||||
Event::End(Tag::Heading(..)) => break,
|
Event::End(Tag::Heading(..)) => break,
|
||||||
Event::Start(Tag::Link(_, _, _)) | Event::End(Tag::Link(..)) => {}
|
|
||||||
Event::Text(text) | Event::Code(text) => {
|
Event::Text(text) | Event::Code(text) => {
|
||||||
id.extend(text.chars().filter_map(slugify));
|
id.extend(text.chars().filter_map(slugify));
|
||||||
self.buf.push_back(event);
|
|
||||||
}
|
}
|
||||||
_ => self.buf.push_back(event),
|
_ => {}
|
||||||
|
}
|
||||||
|
match event {
|
||||||
|
Event::Start(Tag::Link(_, _, _)) | Event::End(Tag::Link(..)) => {}
|
||||||
|
event => self.buf.push_back(event),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let id = self.id_map.derive(id);
|
let id = self.id_map.derive(id);
|
||||||
|
|
||||||
if let Some(ref mut builder) = self.toc {
|
if let Some(ref mut builder) = self.toc {
|
||||||
let mut html_header = String::new();
|
let mut html_header = String::new();
|
||||||
html::push_html(&mut html_header, self.buf.iter().map(|(ev, _)| ev.clone()));
|
html::push_html(&mut html_header, self.buf.iter().cloned());
|
||||||
let sec = builder.push(level as u32, html_header, id.clone());
|
let sec = builder.push(level as u32, html_header, id.clone());
|
||||||
self.buf.push_front((Event::Html(format!("{} ", sec).into()), 0..0));
|
self.buf.push_front(Event::Html(format!("{} ", sec).into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
self.buf.push_back((Event::Html(format!("</a></h{}>", level).into()), 0..0));
|
self.buf.push_back(Event::Html(format!("</a></h{}>", level).into()));
|
||||||
|
|
||||||
let start_tags = format!(
|
let start_tags = format!(
|
||||||
"<h{level} id=\"{id}\" class=\"section-header\">\
|
"<h{level} id=\"{id}\" class=\"section-header\">\
|
||||||
|
@ -469,7 +469,7 @@ impl<'a, 'b, 'ids, I: Iterator<Item = (Event<'a>, Range<usize>)>> Iterator
|
||||||
id = id,
|
id = id,
|
||||||
level = level
|
level = level
|
||||||
);
|
);
|
||||||
return Some((Event::Html(start_tags.into()), 0..0));
|
return Some(Event::Html(start_tags.into()));
|
||||||
}
|
}
|
||||||
event
|
event
|
||||||
}
|
}
|
||||||
|
@ -560,23 +560,23 @@ impl<'a, I> Footnotes<'a, I> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, I: Iterator<Item = (Event<'a>, Range<usize>)>> Iterator for Footnotes<'a, I> {
|
impl<'a, I: Iterator<Item = Event<'a>>> Iterator for Footnotes<'a, I> {
|
||||||
type Item = (Event<'a>, Range<usize>);
|
type Item = Event<'a>;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
loop {
|
loop {
|
||||||
match self.inner.next() {
|
match self.inner.next() {
|
||||||
Some((Event::FootnoteReference(ref reference), range)) => {
|
Some(Event::FootnoteReference(ref reference)) => {
|
||||||
let entry = self.get_entry(&reference);
|
let entry = self.get_entry(&reference);
|
||||||
let reference = format!(
|
let reference = format!(
|
||||||
"<sup id=\"fnref{0}\"><a href=\"#fn{0}\">{0}</a></sup>",
|
"<sup id=\"fnref{0}\"><a href=\"#fn{0}\">{0}</a></sup>",
|
||||||
(*entry).1
|
(*entry).1
|
||||||
);
|
);
|
||||||
return Some((Event::Html(reference.into()), range));
|
return Some(Event::Html(reference.into()));
|
||||||
}
|
}
|
||||||
Some((Event::Start(Tag::FootnoteDefinition(def)), _)) => {
|
Some(Event::Start(Tag::FootnoteDefinition(def))) => {
|
||||||
let mut content = Vec::new();
|
let mut content = Vec::new();
|
||||||
for (event, _) in &mut self.inner {
|
for event in &mut self.inner {
|
||||||
if let Event::End(Tag::FootnoteDefinition(..)) = event {
|
if let Event::End(Tag::FootnoteDefinition(..)) = event {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -607,7 +607,7 @@ impl<'a, I: Iterator<Item = (Event<'a>, Range<usize>)>> Iterator for Footnotes<'
|
||||||
ret.push_str("</li>");
|
ret.push_str("</li>");
|
||||||
}
|
}
|
||||||
ret.push_str("</ol></div>");
|
ret.push_str("</ol></div>");
|
||||||
return Some((Event::Html(ret.into()), 0..0));
|
return Some(Event::Html(ret.into()));
|
||||||
} else {
|
} else {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -917,14 +917,13 @@ impl Markdown<'_> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let p = Parser::new_with_broken_link_callback(md, opts(), Some(&mut replacer));
|
let p = Parser::new_with_broken_link_callback(md, opts(), Some(&mut replacer));
|
||||||
let p = p.into_offset_iter();
|
|
||||||
|
|
||||||
let mut s = String::with_capacity(md.len() * 3 / 2);
|
let mut s = String::with_capacity(md.len() * 3 / 2);
|
||||||
|
|
||||||
let p = HeadingLinks::new(p, None, &mut ids);
|
let p = HeadingLinks::new(p, None, &mut ids);
|
||||||
let p = Footnotes::new(p);
|
let p = LinkReplacer::new(p, links);
|
||||||
let p = LinkReplacer::new(p.map(|(ev, _)| ev), links);
|
|
||||||
let p = CodeBlocks::new(p, codes, edition, playground);
|
let p = CodeBlocks::new(p, codes, edition, playground);
|
||||||
|
let p = Footnotes::new(p);
|
||||||
html::push_html(&mut s, p);
|
html::push_html(&mut s, p);
|
||||||
|
|
||||||
s
|
s
|
||||||
|
@ -935,7 +934,7 @@ impl MarkdownWithToc<'_> {
|
||||||
crate fn into_string(self) -> String {
|
crate fn into_string(self) -> String {
|
||||||
let MarkdownWithToc(md, mut ids, codes, edition, playground) = self;
|
let MarkdownWithToc(md, mut ids, codes, edition, playground) = self;
|
||||||
|
|
||||||
let p = Parser::new_ext(md, opts()).into_offset_iter();
|
let p = Parser::new_ext(md, opts());
|
||||||
|
|
||||||
let mut s = String::with_capacity(md.len() * 3 / 2);
|
let mut s = String::with_capacity(md.len() * 3 / 2);
|
||||||
|
|
||||||
|
@ -943,8 +942,8 @@ impl MarkdownWithToc<'_> {
|
||||||
|
|
||||||
{
|
{
|
||||||
let p = HeadingLinks::new(p, Some(&mut toc), &mut ids);
|
let p = HeadingLinks::new(p, Some(&mut toc), &mut ids);
|
||||||
|
let p = CodeBlocks::new(p, codes, edition, playground);
|
||||||
let p = Footnotes::new(p);
|
let p = Footnotes::new(p);
|
||||||
let p = CodeBlocks::new(p.map(|(ev, _)| ev), codes, edition, playground);
|
|
||||||
html::push_html(&mut s, p);
|
html::push_html(&mut s, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -960,19 +959,19 @@ impl MarkdownHtml<'_> {
|
||||||
if md.is_empty() {
|
if md.is_empty() {
|
||||||
return String::new();
|
return String::new();
|
||||||
}
|
}
|
||||||
let p = Parser::new_ext(md, opts()).into_offset_iter();
|
let p = Parser::new_ext(md, opts());
|
||||||
|
|
||||||
// Treat inline HTML as plain text.
|
// Treat inline HTML as plain text.
|
||||||
let p = p.map(|event| match event.0 {
|
let p = p.map(|event| match event {
|
||||||
Event::Html(text) => (Event::Text(text), event.1),
|
Event::Html(text) => Event::Text(text),
|
||||||
_ => event,
|
_ => event,
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut s = String::with_capacity(md.len() * 3 / 2);
|
let mut s = String::with_capacity(md.len() * 3 / 2);
|
||||||
|
|
||||||
let p = HeadingLinks::new(p, None, &mut ids);
|
let p = HeadingLinks::new(p, None, &mut ids);
|
||||||
|
let p = CodeBlocks::new(p, codes, edition, playground);
|
||||||
let p = Footnotes::new(p);
|
let p = Footnotes::new(p);
|
||||||
let p = CodeBlocks::new(p.map(|(ev, _)| ev), codes, edition, playground);
|
|
||||||
html::push_html(&mut s, p);
|
html::push_html(&mut s, p);
|
||||||
|
|
||||||
s
|
s
|
||||||
|
@ -1125,45 +1124,50 @@ crate fn plain_text_summary(md: &str) -> String {
|
||||||
s
|
s
|
||||||
}
|
}
|
||||||
|
|
||||||
crate fn markdown_links(md: &str) -> Vec<(String, Range<usize>)> {
|
crate fn markdown_links(md: &str) -> Vec<(String, Option<Range<usize>>)> {
|
||||||
if md.is_empty() {
|
if md.is_empty() {
|
||||||
return vec![];
|
return vec![];
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut links = vec![];
|
let mut links = vec![];
|
||||||
// Used to avoid mutable borrow issues in the `push` closure
|
|
||||||
// Probably it would be more efficient to use a `RefCell` but it doesn't seem worth the churn.
|
|
||||||
let mut shortcut_links = vec![];
|
let mut shortcut_links = vec![];
|
||||||
|
|
||||||
let span_for_link = |link: &str, span: Range<usize>| {
|
{
|
||||||
// Pulldown includes the `[]` as well as the URL. Only highlight the relevant span.
|
let locate = |s: &str| unsafe {
|
||||||
// NOTE: uses `rfind` in case the title and url are the same: `[Ok][Ok]`
|
let s_start = s.as_ptr();
|
||||||
match md[span.clone()].rfind(link) {
|
let s_end = s_start.add(s.len());
|
||||||
Some(start) => {
|
let md_start = md.as_ptr();
|
||||||
let start = span.start + start;
|
let md_end = md_start.add(md.len());
|
||||||
start..start + link.len()
|
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)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
}
|
}
|
||||||
// This can happen for things other than intra-doc links, like `#1` expanded to `https://github.com/rust-lang/rust/issues/1`.
|
};
|
||||||
None => span,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let mut push = |link: BrokenLink<'_>| {
|
|
||||||
let span = span_for_link(link.reference, link.span);
|
|
||||||
shortcut_links.push((link.reference.to_owned(), span));
|
|
||||||
None
|
|
||||||
};
|
|
||||||
let p = Parser::new_with_broken_link_callback(md, opts(), Some(&mut push));
|
|
||||||
|
|
||||||
// There's no need to thread an IdMap through to here because
|
let mut push = |link: BrokenLink<'_>| {
|
||||||
// the IDs generated aren't going to be emitted anywhere.
|
// FIXME: use `link.span` instead of `locate`
|
||||||
let mut ids = IdMap::new();
|
// (doing it now includes the `[]` as well as the text)
|
||||||
let iter = Footnotes::new(HeadingLinks::new(p.into_offset_iter(), None, &mut ids));
|
shortcut_links.push((link.reference.to_owned(), locate(link.reference)));
|
||||||
|
None
|
||||||
|
};
|
||||||
|
let p = Parser::new_with_broken_link_callback(md, opts(), Some(&mut push));
|
||||||
|
|
||||||
for ev in iter {
|
// There's no need to thread an IdMap through to here because
|
||||||
if let Event::Start(Tag::Link(_, dest, _)) = ev.0 {
|
// the IDs generated aren't going to be emitted anywhere.
|
||||||
debug!("found link: {}", dest);
|
let mut ids = IdMap::new();
|
||||||
let span = span_for_link(&dest, ev.1);
|
let iter = Footnotes::new(HeadingLinks::new(p, None, &mut ids));
|
||||||
links.push((dest.into_string(), span));
|
|
||||||
|
for ev in iter {
|
||||||
|
if let Event::Start(Tag::Link(_, dest, _)) = ev {
|
||||||
|
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),
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -180,7 +180,7 @@ struct DiagnosticInfo<'a> {
|
||||||
item: &'a Item,
|
item: &'a Item,
|
||||||
dox: &'a str,
|
dox: &'a str,
|
||||||
ori_link: &'a str,
|
ori_link: &'a str,
|
||||||
link_range: Range<usize>,
|
link_range: Option<Range<usize>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Hash)]
|
#[derive(Clone, Debug, Hash)]
|
||||||
|
@ -920,7 +920,7 @@ impl LinkCollector<'_, '_> {
|
||||||
parent_node: Option<DefId>,
|
parent_node: Option<DefId>,
|
||||||
krate: CrateNum,
|
krate: CrateNum,
|
||||||
ori_link: String,
|
ori_link: String,
|
||||||
link_range: Range<usize>,
|
link_range: Option<Range<usize>>,
|
||||||
) -> Option<ItemLink> {
|
) -> Option<ItemLink> {
|
||||||
trace!("considering link '{}'", ori_link);
|
trace!("considering link '{}'", ori_link);
|
||||||
|
|
||||||
|
@ -1566,7 +1566,7 @@ fn report_diagnostic(
|
||||||
msg: &str,
|
msg: &str,
|
||||||
item: &Item,
|
item: &Item,
|
||||||
dox: &str,
|
dox: &str,
|
||||||
link_range: &Range<usize>,
|
link_range: &Option<Range<usize>>,
|
||||||
decorate: impl FnOnce(&mut DiagnosticBuilder<'_>, Option<rustc_span::Span>),
|
decorate: impl FnOnce(&mut DiagnosticBuilder<'_>, Option<rustc_span::Span>),
|
||||||
) {
|
) {
|
||||||
let hir_id = match cx.as_local_hir_id(item.def_id) {
|
let hir_id = match cx.as_local_hir_id(item.def_id) {
|
||||||
|
@ -1584,26 +1584,31 @@ fn report_diagnostic(
|
||||||
cx.tcx.struct_span_lint_hir(lint, hir_id, sp, |lint| {
|
cx.tcx.struct_span_lint_hir(lint, hir_id, sp, |lint| {
|
||||||
let mut diag = lint.build(msg);
|
let mut diag = lint.build(msg);
|
||||||
|
|
||||||
let span = super::source_span_for_markdown_range(cx, dox, link_range, attrs);
|
let span = link_range
|
||||||
if let Some(sp) = span {
|
.as_ref()
|
||||||
diag.set_span(sp);
|
.and_then(|range| super::source_span_for_markdown_range(cx, dox, range, attrs));
|
||||||
} 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.
|
if let Some(link_range) = link_range {
|
||||||
diag.note(&format!(
|
if let Some(sp) = span {
|
||||||
"the link appears in this line:\n\n{line}\n\
|
diag.set_span(sp);
|
||||||
{indicator: <before$}{indicator:^<found$}",
|
} else {
|
||||||
line = line,
|
// blah blah blah\nblah\nblah [blah] blah blah\nblah blah
|
||||||
indicator = "",
|
// ^ ~~~~
|
||||||
before = link_range.start - last_new_line_offset,
|
// | link_range
|
||||||
found = link_range.len(),
|
// 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(),
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
decorate(&mut diag, span);
|
decorate(&mut diag, span);
|
||||||
|
@ -1623,7 +1628,7 @@ fn resolution_failure(
|
||||||
path_str: &str,
|
path_str: &str,
|
||||||
disambiguator: Option<Disambiguator>,
|
disambiguator: Option<Disambiguator>,
|
||||||
dox: &str,
|
dox: &str,
|
||||||
link_range: Range<usize>,
|
link_range: Option<Range<usize>>,
|
||||||
kinds: SmallVec<[ResolutionFailure<'_>; 3]>,
|
kinds: SmallVec<[ResolutionFailure<'_>; 3]>,
|
||||||
) {
|
) {
|
||||||
report_diagnostic(
|
report_diagnostic(
|
||||||
|
@ -1857,7 +1862,7 @@ fn anchor_failure(
|
||||||
item: &Item,
|
item: &Item,
|
||||||
path_str: &str,
|
path_str: &str,
|
||||||
dox: &str,
|
dox: &str,
|
||||||
link_range: Range<usize>,
|
link_range: Option<Range<usize>>,
|
||||||
failure: AnchorFailure,
|
failure: AnchorFailure,
|
||||||
) {
|
) {
|
||||||
let msg = match failure {
|
let msg = match failure {
|
||||||
|
@ -1882,7 +1887,7 @@ fn ambiguity_error(
|
||||||
item: &Item,
|
item: &Item,
|
||||||
path_str: &str,
|
path_str: &str,
|
||||||
dox: &str,
|
dox: &str,
|
||||||
link_range: Range<usize>,
|
link_range: Option<Range<usize>>,
|
||||||
candidates: Vec<Res>,
|
candidates: Vec<Res>,
|
||||||
) {
|
) {
|
||||||
let mut msg = format!("`{}` is ", path_str);
|
let mut msg = format!("`{}` is ", path_str);
|
||||||
|
@ -1931,12 +1936,13 @@ fn suggest_disambiguator(
|
||||||
path_str: &str,
|
path_str: &str,
|
||||||
dox: &str,
|
dox: &str,
|
||||||
sp: Option<rustc_span::Span>,
|
sp: Option<rustc_span::Span>,
|
||||||
link_range: &Range<usize>,
|
link_range: &Option<Range<usize>>,
|
||||||
) {
|
) {
|
||||||
let suggestion = disambiguator.suggestion();
|
let suggestion = disambiguator.suggestion();
|
||||||
let help = format!("to link to the {}, {}", disambiguator.descr(), suggestion.descr());
|
let help = format!("to link to the {}, {}", disambiguator.descr(), suggestion.descr());
|
||||||
|
|
||||||
if let Some(sp) = sp {
|
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'`') {
|
let msg = if dox.bytes().nth(link_range.start) == Some(b'`') {
|
||||||
format!("`{}`", suggestion.as_help(path_str))
|
format!("`{}`", suggestion.as_help(path_str))
|
||||||
} else {
|
} else {
|
||||||
|
@ -1955,7 +1961,7 @@ fn privacy_error(
|
||||||
item: &Item,
|
item: &Item,
|
||||||
path_str: &str,
|
path_str: &str,
|
||||||
dox: &str,
|
dox: &str,
|
||||||
link_range: Range<usize>,
|
link_range: Option<Range<usize>>,
|
||||||
) {
|
) {
|
||||||
let sym;
|
let sym;
|
||||||
let item_name = match item.name {
|
let item_name = match item.name {
|
||||||
|
|
7
src/test/rustdoc-ui/reference-links.rs
Normal file
7
src/test/rustdoc-ui/reference-links.rs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
// Test that errors point to the reference, not to the title text.
|
||||||
|
#![deny(broken_intra_doc_links)]
|
||||||
|
//! Links to [a] [link][a]
|
||||||
|
//!
|
||||||
|
//! [a]: std::process::Comman
|
||||||
|
//~^ ERROR unresolved
|
||||||
|
//~| ERROR unresolved
|
20
src/test/rustdoc-ui/reference-links.stderr
Normal file
20
src/test/rustdoc-ui/reference-links.stderr
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
error: unresolved link to `std::process::Comman`
|
||||||
|
--> $DIR/reference-links.rs:5:10
|
||||||
|
|
|
||||||
|
LL | //! [a]: std::process::Comman
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^ no item named `Comman` in module `process`
|
||||||
|
|
|
||||||
|
note: the lint level is defined here
|
||||||
|
--> $DIR/reference-links.rs:2:9
|
||||||
|
|
|
||||||
|
LL | #![deny(broken_intra_doc_links)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: unresolved link to `std::process::Comman`
|
||||||
|
--> $DIR/reference-links.rs:5:10
|
||||||
|
|
|
||||||
|
LL | //! [a]: std::process::Comman
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^ no item named `Comman` in module `process`
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue