Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
18ad5a5
Add a regression test for issue-72793
JohnTitor Aug 19, 2020
aa40c02
Unstable Book: add links to tracking issues for FFI features
ArekPiekarz Aug 26, 2020
f03d0b3
`impl Rc::new_cyclic`
mental32 Aug 27, 2020
42fb270
typo
mental32 Aug 29, 2020
bb5e79c
Link vec doc to & reference
pickfire Aug 29, 2020
1b19354
[WIP] Fix intra-doc links on pub re-exports
jyn514 Aug 29, 2020
20a6866
Try removing [prim@reference]
pickfire Aug 30, 2020
e885f00
Comment out test for generated docs until rustdoc changes its behavio…
jyn514 Aug 30, 2020
d715015
Improve tests
jyn514 Aug 30, 2020
0f301e8
Removed [inline] and copied over comments from Arc::new_cyclic
mental32 Sep 1, 2020
af19262
Fold length constant in Rvalue::Repeat
tmiasko Sep 2, 2020
2276991
Avoid spurious print outs during dryrun
Mark-Simulacrum Sep 2, 2020
850c321
Move jointness censoring to proc_macro
matklad Sep 3, 2020
89ae59a
Remove needless .to_owned() for link
jyn514 Jul 6, 2020
d5495e2
Refactor `ItemLink` into its own struct
jyn514 Jul 6, 2020
31a7b6e
Refactor RenderedLink into its own type
jyn514 Jul 6, 2020
9815010
Remove disambiguators from link text
jyn514 Jul 6, 2020
9d7e797
display_for -> suggestion_for
jyn514 Aug 29, 2020
4df6490
Link & primitive using relative link
pickfire Sep 3, 2020
af13338
Check test/example/benchmark on x.py check
Mark-Simulacrum Sep 2, 2020
09d3db2
Optimize Cursor::look_ahead
matklad Sep 3, 2020
85146b9
Add slice primitive link to vec
pickfire Sep 4, 2020
18c14fd
Misc cleanup
jyn514 Aug 29, 2020
cbc396f
inliner: Check for target features compatibility
tmiasko Sep 3, 2020
326b772
inliner: Check for no_sanitize attribute compatibility
tmiasko Sep 3, 2020
c23151b
inliner: Add mir-opt tests for codegen attributes compatibility
tmiasko Sep 4, 2020
b97d413
Refactor byteorder to std in rustc_middle
workingjubilee Aug 20, 2020
74b4eea
Remove reference to byteorder limits
workingjubilee Aug 20, 2020
fe2a867
Be explicit that we're handling bytes
workingjubilee Aug 20, 2020
dc00eff
Explain contract of {read, write}_target_uint
workingjubilee Aug 21, 2020
2df552b
Fix big endian read/write
workingjubilee Aug 22, 2020
cb33a15
Rollup merge of #75695 - JohnTitor:regression-test, r=Dylan-DPC
Dylan-DPC Sep 5, 2020
e160d2b
Rollup merge of #75741 - workingjubilee:refactor-byteorder, r=matthew…
Dylan-DPC Sep 5, 2020
c3a09fb
Rollup merge of #75954 - ArekPiekarz:unstable_book_ffi_tracking_issue…
Dylan-DPC Sep 5, 2020
4bd3f26
Rollup merge of #75994 - mental32:impl-rc-new-cyclic, r=KodrAus
Dylan-DPC Sep 5, 2020
86cf797
Rollup merge of #76060 - pickfire:patch-12, r=jyn514
Dylan-DPC Sep 5, 2020
ed39e6d
Rollup merge of #76078 - jyn514:no-disambiguator, r=manishearth
Dylan-DPC Sep 5, 2020
f1eb5f8
Rollup merge of #76082 - jyn514:top-level-links, r=ollie27,GuillaumeG…
Dylan-DPC Sep 5, 2020
79b8f59
Rollup merge of #76254 - tmiasko:fold-len, r=wesleywiser
Dylan-DPC Sep 5, 2020
45bdee8
Rollup merge of #76258 - Mark-Simulacrum:check-tests, r=ehuss
Dylan-DPC Sep 5, 2020
b4d3873
Rollup merge of #76263 - tmiasko:inline-codegen-fn-attrs, r=ecstatic-…
Dylan-DPC Sep 5, 2020
85cee57
Rollup merge of #76285 - matklad:censor-spacing, r=petrochenkov
Dylan-DPC Sep 5, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Misc cleanup
- Preserve suffixes when displaying
- Rename test file to match `intra-link*`
- Remove unnecessary .clone()s
- Improve comments and naming
- Fix more bugs and add tests
- Escape intra-doc link example in public documentation
  • Loading branch information
jyn514 committed Sep 4, 2020
commit 18c14fde0d293a18fbd3c14487b52e1ce7daa205
6 changes: 4 additions & 2 deletions src/librustdoc/clean/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -439,15 +439,17 @@ pub struct ItemLink {
/// The link text displayed in the HTML.
///
/// This may not be the same as `link` if there was a disambiguator
/// in an intra-doc link (e.g. [`fn@f`])
/// in an intra-doc link (e.g. \[`fn@f`\])
pub(crate) link_text: String,
pub(crate) did: Option<DefId>,
/// The url fragment to append to the link
pub(crate) fragment: Option<String>,
}

pub struct RenderedLink {
/// The text the link was original written as
/// The text the link was original written as.
///
/// This could potentially include disambiguators and backticks.
pub(crate) original_text: String,
/// The text to display in the HTML
pub(crate) new_text: String,
Expand Down
65 changes: 42 additions & 23 deletions src/librustdoc/html/markdown.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,83 +338,102 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
}

/// Make headings links with anchor IDs and build up TOC.
struct LinkReplacer<'a, 'b, I: Iterator<Item = Event<'a>>> {
struct LinkReplacer<'a, I: Iterator<Item = Event<'a>>> {
inner: I,
links: &'a [RenderedLink],
shortcut_link: Option<&'b RenderedLink>,
shortcut_link: Option<&'a RenderedLink>,
}

impl<'a, I: Iterator<Item = Event<'a>>> LinkReplacer<'a, '_, I> {
impl<'a, I: Iterator<Item = Event<'a>>> LinkReplacer<'a, I> {
fn new(iter: I, links: &'a [RenderedLink]) -> Self {
LinkReplacer { inner: iter, links, shortcut_link: None }
}
}

impl<'a: 'b, 'b, I: Iterator<Item = Event<'a>>> Iterator for LinkReplacer<'a, 'b, I> {
impl<'a, I: Iterator<Item = Event<'a>>> Iterator for LinkReplacer<'a, I> {
type Item = Event<'a>;

fn next(&mut self) -> Option<Self::Item> {
use pulldown_cmark::LinkType;

let mut event = self.inner.next();

// Remove disambiguators from shortcut links (`[fn@f]`)
// Replace intra-doc links and remove disambiguators from shortcut links (`[fn@f]`).
match &mut event {
// This is a shortcut link that was resolved by the broken_link_callback: `[fn@f]`
// Remove any disambiguator.
Some(Event::Start(Tag::Link(
pulldown_cmark::LinkType::ShortcutUnknown,
// [fn@f] or [fn@f][]
LinkType::ShortcutUnknown | LinkType::CollapsedUnknown,
dest,
title,
))) => {
debug!("saw start of shortcut link to {} with title {}", dest, title);
let link = if let Some(link) =
self.links.iter().find(|&link| *link.original_text == **dest)
{
// Not sure why this is necessary - maybe the broken_link_callback doesn't always work?
*dest = CowStr::Borrowed(link.href.as_ref());
Some(link)
} else {
self.links.iter().find(|&link| *link.href == **dest)
};
// If this is a shortcut link, it was resolved by the broken_link_callback.
// So the URL will already be updated properly.
let link = self.links.iter().find(|&link| *link.href == **dest);
// Since this is an external iterator, we can't replace the inner text just yet.
// Store that we saw a link so we know to replace it later.
if let Some(link) = link {
trace!("it matched");
assert!(self.shortcut_link.is_none(), "shortcut links cannot be nested");
self.shortcut_link = Some(link);
}
}
Some(Event::End(Tag::Link(pulldown_cmark::LinkType::ShortcutUnknown, dest, _))) => {
// Now that we're done with the shortcut link, don't replace any more text.
Some(Event::End(Tag::Link(
LinkType::ShortcutUnknown | LinkType::CollapsedUnknown,
dest,
_,
))) => {
debug!("saw end of shortcut link to {}", dest);
if let Some(_link) = self.links.iter().find(|&link| *link.href == **dest) {
if self.links.iter().find(|&link| *link.href == **dest).is_some() {
assert!(self.shortcut_link.is_some(), "saw closing link without opening tag");
self.shortcut_link = None;
}
}
// Handle backticks in inline code blocks
// Handle backticks in inline code blocks, but only if we're in the middle of a shortcut link.
// [`fn@f`]
Some(Event::Code(text)) => {
trace!("saw code {}", text);
if let Some(link) = self.shortcut_link {
trace!("original text was {}", link.original_text);
// NOTE: this only replaces if the code block is the *entire* text.
// If only part of the link has code highlighting, the disambiguator will not be removed.
// e.g. [fn@`f`]
// This is a limitation from `collect_intra_doc_links`: it passes a full link,
// and does not distinguish at all between code blocks.
// So we could never be sure we weren't replacing too much:
// [fn@my_`f`unc] is treated the same as [my_func()] in that pass.
//
// NOTE: &[1..len() - 1] is to strip the backticks
if **text == link.original_text[1..link.original_text.len() - 1] {
debug!("replacing {} with {}", text, link.new_text);
*text = link.new_text.clone().into();
*text = CowStr::Borrowed(&link.new_text);
}
}
}
// Replace plain text in links
// Replace plain text in links, but only in the middle of a shortcut link.
// [fn@f]
Some(Event::Text(text)) => {
trace!("saw text {}", text);
if let Some(link) = self.shortcut_link {
trace!("original text was {}", link.original_text);
// NOTE: same limitations as `Event::Code`
if **text == *link.original_text {
debug!("replacing {} with {}", text, link.new_text);
*text = link.new_text.clone().into();
*text = CowStr::Borrowed(&link.new_text);
}
}
}
// If this is a link, but not a shortcut link,
// replace the URL, since the broken_link_callback was not called.
Some(Event::Start(Tag::Link(_, dest, _))) => {
if let Some(link) = self.links.iter().find(|&link| *link.original_text == **dest) {
// Not sure why this is necessary - maybe the broken_link_callback doesn't always work?
*dest = CowStr::Borrowed(link.href.as_ref());
}
}
// Anything else couldn't have been a valid Rust path
// Anything else couldn't have been a valid Rust path, so no need to replace the text.
_ => {}
}

Expand Down
22 changes: 17 additions & 5 deletions src/librustdoc/passes/collect_intra_doc_links.rs
Original file line number Diff line number Diff line change
Expand Up @@ -717,11 +717,11 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
continue;
}

// We stripped ` characters for `path_str`.
// The original link might have had multiple pairs of backticks,
// but we don't handle this case.
//link_text = if had_backticks { format!("`{}`", path_str) } else { path_str.to_owned() };
link_text = path_str.to_owned();
// We stripped `()` and `!` when parsing the disambiguator.
// Add them back to be displayed, but not prefix disambiguators.
link_text = disambiguator
.map(|d| d.display_for(path_str))
.unwrap_or_else(|| path_str.to_owned());

// In order to correctly resolve intra-doc-links we need to
// pick a base AST node to work from. If the documentation for
Expand Down Expand Up @@ -1000,6 +1000,18 @@ enum Disambiguator {
}

impl Disambiguator {
/// The text that should be displayed when the path is rendered as HTML.
///
/// NOTE: `path` is not the original link given by the user, but a name suitable for passing to `resolve`.
fn display_for(&self, path: &str) -> String {
match self {
// FIXME: this will have different output if the user had `m!()` originally.
Self::Kind(DefKind::Macro(MacroKind::Bang)) => format!("{}!", path),
Self::Kind(DefKind::Fn) => format!("{}()", path),
_ => path.to_owned(),
}
}

/// (disambiguator, path_str)
fn from_str(link: &str) -> Result<(Self, &str), ()> {
use Disambiguator::{Kind, Namespace as NS, Primitive};
Expand Down
33 changes: 0 additions & 33 deletions src/test/rustdoc/disambiguator_removed.rs

This file was deleted.

51 changes: 51 additions & 0 deletions src/test/rustdoc/intra-link-disambiguators-removed.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// ignore-tidy-linelength
#![deny(intra_doc_link_resolution_failure)]
// first try backticks
/// Trait: [`trait@Name`], fn: [`fn@Name`], [`Name`][`macro@Name`]
// @has intra_link_disambiguators_removed/struct.AtDisambiguator.html
// @has - '//a[@href="../intra_link_disambiguators_removed/trait.Name.html"][code]' "Name"
// @has - '//a[@href="../intra_link_disambiguators_removed/fn.Name.html"][code]' "Name"
// @has - '//a[@href="../intra_link_disambiguators_removed/macro.Name.html"][code]' "Name"
pub struct AtDisambiguator;

/// fn: [`Name()`], macro: [`Name!`]
// @has intra_link_disambiguators_removed/struct.SymbolDisambiguator.html
// @has - '//a[@href="../intra_link_disambiguators_removed/fn.Name.html"][code]' "Name()"
// @has - '//a[@href="../intra_link_disambiguators_removed/macro.Name.html"][code]' "Name!"
pub struct SymbolDisambiguator;

// Now make sure that backticks aren't added if they weren't already there
/// [fn@Name]
// @has intra_link_disambiguators_removed/trait.Name.html
// @has - '//a[@href="../intra_link_disambiguators_removed/fn.Name.html"]' "Name"
// @!has - '//a[@href="../intra_link_disambiguators_removed/fn.Name.html"][code]' "Name"

// FIXME: this will turn !() into ! alone
/// [Name!()]
// @has - '//a[@href="../intra_link_disambiguators_removed/macro.Name.html"]' "Name!"
pub trait Name {}

#[allow(non_snake_case)]

// Try collapsed reference links
/// [macro@Name][]
// @has intra_link_disambiguators_removed/fn.Name.html
// @has - '//a[@href="../intra_link_disambiguators_removed/macro.Name.html"]' "Name"

// Try links that have the same text as a generated URL
/// Weird URL aligned [../intra_link_disambiguators_removed/macro.Name.html][trait@Name]
// @has - '//a[@href="../intra_link_disambiguators_removed/trait.Name.html"]' "../intra_link_disambiguators_removed/macro.Name.html"
pub fn Name() {}

#[macro_export]
// Rustdoc doesn't currently handle links that have weird interspersing of inline code blocks.
/// [fn@Na`m`e]
// @has intra_link_disambiguators_removed/macro.Name.html
// @has - '//a[@href="../intra_link_disambiguators_removed/fn.Name.html"]' "fn@Name"

// It also doesn't handle any case where the code block isn't the whole link text:
/// [trait@`Name`]
// @has - '//a[@href="../intra_link_disambiguators_removed/trait.Name.html"]' "trait@Name"
macro_rules! Name {
() => ()
}