mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Rollup merge of #77971 - jyn514:broken-intra-doc-links, r=mark-simulacrum
Deny broken intra-doc links in linkchecker Since rustdoc isn't warning about these links, check for them manually. This also fixes the broken links that popped up from the lint.
This commit is contained in:
@@ -1744,6 +1744,10 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "linkchecker"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linked-hash-map"
|
||||
|
||||
@@ -9,4 +9,4 @@ llvm_asm!("nop" "nop");
|
||||
Considering that this would be a long explanation, we instead recommend you
|
||||
take a look at the [`llvm_asm`] chapter of the Unstable book:
|
||||
|
||||
[llvm_asm]: https://doc.rust-lang.org/stable/unstable-book/library-features/llvm-asm.html
|
||||
[`llvm_asm`]: https://doc.rust-lang.org/stable/unstable-book/library-features/llvm-asm.html
|
||||
|
||||
@@ -10,4 +10,4 @@ llvm_asm!("nop" : "r"(a));
|
||||
Considering that this would be a long explanation, we instead recommend you
|
||||
take a look at the [`llvm_asm`] chapter of the Unstable book:
|
||||
|
||||
[llvm_asm]: https://doc.rust-lang.org/stable/unstable-book/library-features/llvm-asm.html
|
||||
[`llvm_asm`]: https://doc.rust-lang.org/stable/unstable-book/library-features/llvm-asm.html
|
||||
|
||||
@@ -13,4 +13,4 @@ llvm_asm!("xor %eax, %eax"
|
||||
Considering that this would be a long explanation, we instead recommend you
|
||||
take a look at the [`llvm_asm`] chapter of the Unstable book:
|
||||
|
||||
[llvm_asm]: https://doc.rust-lang.org/stable/unstable-book/library-features/llvm-asm.html
|
||||
[`llvm_asm`]: https://doc.rust-lang.org/stable/unstable-book/library-features/llvm-asm.html
|
||||
|
||||
@@ -13,4 +13,4 @@ llvm_asm!("xor %eax, %eax"
|
||||
Considering that this would be a long explanation, we instead recommend you
|
||||
take a look at the [`llvm_asm`] chapter of the Unstable book:
|
||||
|
||||
[llvm_asm]: https://doc.rust-lang.org/stable/unstable-book/library-features/llvm-asm.html
|
||||
[`llvm_asm`]: https://doc.rust-lang.org/stable/unstable-book/library-features/llvm-asm.html
|
||||
|
||||
@@ -13,4 +13,4 @@ llvm_asm!("mov $$0x200, %eax"
|
||||
Considering that this would be a long explanation, we instead recommend you
|
||||
take a look at the [`llvm_asm`] chapter of the Unstable book:
|
||||
|
||||
[llvm_asm]: https://doc.rust-lang.org/stable/unstable-book/library-features/llvm-asm.html
|
||||
[`llvm_asm`]: https://doc.rust-lang.org/stable/unstable-book/library-features/llvm-asm.html
|
||||
|
||||
@@ -89,13 +89,11 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
pub unsafe trait AllocRef {
|
||||
/// Attempts to allocate a block of memory.
|
||||
///
|
||||
/// On success, returns a [`NonNull<[u8]>`] meeting the size and alignment guarantees of `layout`.
|
||||
/// On success, returns a [`NonNull<[u8]>`][NonNull] meeting the size and alignment guarantees of `layout`.
|
||||
///
|
||||
/// The returned block may have a larger size than specified by `layout.size()`, and may or may
|
||||
/// not have its contents initialized.
|
||||
///
|
||||
/// [`NonNull<[u8]>`]: NonNull
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returning `Err` indicates that either memory is exhausted or `layout` does not meet
|
||||
@@ -146,7 +144,7 @@ fn alloc_zeroed(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
|
||||
|
||||
/// Attempts to extend the memory block.
|
||||
///
|
||||
/// Returns a new [`NonNull<[u8]>`] containing a pointer and the actual size of the allocated
|
||||
/// Returns a new [`NonNull<[u8]>`][NonNull] containing a pointer and the actual size of the allocated
|
||||
/// memory. The pointer is suitable for holding data described by `new_layout`. To accomplish
|
||||
/// this, the allocator may extend the allocation referenced by `ptr` to fit the new layout.
|
||||
///
|
||||
@@ -158,8 +156,6 @@ fn alloc_zeroed(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
|
||||
/// If this method returns `Err`, then ownership of the memory block has not been transferred to
|
||||
/// this allocator, and the contents of the memory block are unaltered.
|
||||
///
|
||||
/// [`NonNull<[u8]>`]: NonNull
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// * `ptr` must denote a block of memory [*currently allocated*] via this allocator.
|
||||
@@ -271,7 +267,7 @@ unsafe fn grow_zeroed(
|
||||
|
||||
/// Attempts to shrink the memory block.
|
||||
///
|
||||
/// Returns a new [`NonNull<[u8]>`] containing a pointer and the actual size of the allocated
|
||||
/// Returns a new [`NonNull<[u8]>`][NonNull] containing a pointer and the actual size of the allocated
|
||||
/// memory. The pointer is suitable for holding data described by `new_layout`. To accomplish
|
||||
/// this, the allocator may shrink the allocation referenced by `ptr` to fit the new layout.
|
||||
///
|
||||
@@ -283,8 +279,6 @@ unsafe fn grow_zeroed(
|
||||
/// If this method returns `Err`, then ownership of the memory block has not been transferred to
|
||||
/// this allocator, and the contents of the memory block are unaltered.
|
||||
///
|
||||
/// [`NonNull<[u8]>`]: NonNull
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// * `ptr` must denote a block of memory [*currently allocated*] via this allocator.
|
||||
|
||||
@@ -134,6 +134,7 @@ pub const fn identity<T>(x: T) -> T {
|
||||
/// want to accept all references that can be converted to [`&str`] as an argument.
|
||||
/// Since both [`String`] and [`&str`] implement `AsRef<str>` we can accept both as input argument.
|
||||
///
|
||||
/// [`&str`]: primitive@str
|
||||
/// [`Option<T>`]: Option
|
||||
/// [`Result<T, E>`]: Result
|
||||
/// [`Borrow`]: crate::borrow::Borrow
|
||||
|
||||
@@ -122,6 +122,9 @@ pub trait DoubleEndedIterator: Iterator {
|
||||
/// assert_eq!(iter.advance_back_by(0), Ok(()));
|
||||
/// assert_eq!(iter.advance_back_by(100), Err(1)); // only `&3` was skipped
|
||||
/// ```
|
||||
///
|
||||
/// [`Ok(())`]: Ok
|
||||
/// [`Err(k)`]: Err
|
||||
#[inline]
|
||||
#[unstable(feature = "iter_advance_by", reason = "recently added", issue = "77404")]
|
||||
fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
|
||||
|
||||
@@ -289,12 +289,12 @@ fn some<T>(_: Option<T>, x: T) -> Option<T> {
|
||||
/// This method will eagerly skip `n` elements by calling [`next`] up to `n`
|
||||
/// times until [`None`] is encountered.
|
||||
///
|
||||
/// `advance_by(n)` will return [`Ok(())`] if the iterator successfully advances by
|
||||
/// `n` elements, or [`Err(k)`] if [`None`] is encountered, where `k` is the number
|
||||
/// `advance_by(n)` will return [`Ok(())`][Ok] if the iterator successfully advances by
|
||||
/// `n` elements, or [`Err(k)`][Err] if [`None`] is encountered, where `k` is the number
|
||||
/// of elements the iterator is advanced by before running out of elements (i.e. the
|
||||
/// length of the iterator). Note that `k` is always less than `n`.
|
||||
///
|
||||
/// Calling `advance_by(0)` does not consume any elements and always returns [`Ok(())`].
|
||||
/// Calling `advance_by(0)` does not consume any elements and always returns [`Ok(())`][Ok].
|
||||
///
|
||||
/// [`next`]: Iterator::next
|
||||
///
|
||||
|
||||
@@ -687,6 +687,7 @@ pub fn and_then<U, F: FnOnce(T) -> Option<U>>(self, f: F) -> Option<U> {
|
||||
/// assert_eq!(Some(4).filter(is_even), Some(4));
|
||||
/// ```
|
||||
///
|
||||
/// [`Some(t)`]: Some
|
||||
#[inline]
|
||||
#[stable(feature = "option_filter", since = "1.27.0")]
|
||||
pub fn filter<P: FnOnce(&T) -> bool>(self, predicate: P) -> Self {
|
||||
|
||||
@@ -1383,7 +1383,8 @@ pub fn to_str(&self) -> Result<&str, str::Utf8Error> {
|
||||
/// [`U+FFFD REPLACEMENT CHARACTER`][U+FFFD] and return a
|
||||
/// [`Cow`]`::`[`Owned`]`(`[`String`]`)` with the result.
|
||||
///
|
||||
/// [`str`]: prim@str
|
||||
/// [`str`]: primitive@str
|
||||
/// [`&str`]: primitive@str
|
||||
/// [`Borrowed`]: Cow::Borrowed
|
||||
/// [`Owned`]: Cow::Owned
|
||||
/// [U+FFFD]: crate::char::REPLACEMENT_CHARACTER
|
||||
|
||||
+1
-1
Submodule src/doc/embedded-book updated: 79ab777692...ca8169e69b
@@ -10,6 +10,8 @@ Adds a free `default()` function to the `std::default` module. This function
|
||||
just forwards to [`Default::default()`], but may remove repetition of the word
|
||||
"default" from the call site.
|
||||
|
||||
[`Default::default()`]: https://doc.rust-lang.org/nightly/std/default/trait.Default.html#tymethod.default
|
||||
|
||||
Here is an example:
|
||||
|
||||
```rust
|
||||
|
||||
+1
-1
Submodule src/tools/cargo updated: 12db56cded...79b397d72c
@@ -7,3 +7,7 @@ edition = "2018"
|
||||
[[bin]]
|
||||
name = "linkchecker"
|
||||
path = "main.rs"
|
||||
|
||||
[dependencies]
|
||||
regex = "1"
|
||||
once_cell = "1"
|
||||
|
||||
@@ -21,6 +21,9 @@
|
||||
use std::path::{Component, Path, PathBuf};
|
||||
use std::rc::Rc;
|
||||
|
||||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
|
||||
use crate::Redirect::*;
|
||||
|
||||
// Add linkcheck exceptions here
|
||||
@@ -50,6 +53,44 @@
|
||||
("alloc/collections/btree_set/struct.BTreeSet.html", &["#insert-and-complex-keys"]),
|
||||
];
|
||||
|
||||
#[rustfmt::skip]
|
||||
const INTRA_DOC_LINK_EXCEPTIONS: &[(&str, &[&str])] = &[
|
||||
// This will never have links that are not in other pages.
|
||||
// To avoid repeating the exceptions twice, an empty list means all broken links are allowed.
|
||||
("reference/print.html", &[]),
|
||||
// All the reference 'links' are actually ENBF highlighted as code
|
||||
("reference/comments.html", &[
|
||||
"/</code> <code>!",
|
||||
"*</code> <code>!",
|
||||
]),
|
||||
("reference/identifiers.html", &[
|
||||
"a</code>-<code>z</code> <code>A</code>-<code>Z",
|
||||
"a</code>-<code>z</code> <code>A</code>-<code>Z</code> <code>0</code>-<code>9</code> <code>_",
|
||||
"a</code>-<code>z</code> <code>A</code>-<code>Z</code>] [<code>a</code>-<code>z</code> <code>A</code>-<code>Z</code> <code>0</code>-<code>9</code> <code>_",
|
||||
]),
|
||||
("reference/tokens.html", &[
|
||||
"0</code>-<code>1",
|
||||
"0</code>-<code>7",
|
||||
"0</code>-<code>9",
|
||||
"0</code>-<code>9",
|
||||
"0</code>-<code>9</code> <code>a</code>-<code>f</code> <code>A</code>-<code>F",
|
||||
]),
|
||||
("reference/notation.html", &[
|
||||
"b</code> <code>B",
|
||||
"a</code>-<code>z",
|
||||
]),
|
||||
// This is being used in the sense of 'inclusive range', not a markdown link
|
||||
("core/ops/struct.RangeInclusive.html", &["begin</code>, <code>end"]),
|
||||
("std/ops/struct.RangeInclusive.html", &["begin</code>, <code>end"]),
|
||||
("core/slice/trait.SliceIndex.html", &["begin</code>, <code>end"]),
|
||||
("alloc/slice/trait.SliceIndex.html", &["begin</code>, <code>end"]),
|
||||
("std/slice/trait.SliceIndex.html", &["begin</code>, <code>end"]),
|
||||
|
||||
];
|
||||
|
||||
static BROKEN_INTRA_DOC_LINK: Lazy<Regex> =
|
||||
Lazy::new(|| Regex::new(r#"\[<code>(.*)</code>\]"#).unwrap());
|
||||
|
||||
macro_rules! t {
|
||||
($e:expr) => {
|
||||
match $e {
|
||||
@@ -138,6 +179,14 @@ fn walk(cache: &mut Cache, root: &Path, dir: &Path, errors: &mut bool) {
|
||||
}
|
||||
}
|
||||
|
||||
fn is_intra_doc_exception(file: &Path, link: &str) -> bool {
|
||||
if let Some(entry) = INTRA_DOC_LINK_EXCEPTIONS.iter().find(|&(f, _)| file.ends_with(f)) {
|
||||
entry.1.is_empty() || entry.1.contains(&link)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn is_exception(file: &Path, link: &str) -> bool {
|
||||
if let Some(entry) = LINKCHECK_EXCEPTIONS.iter().find(|&(f, _)| file.ends_with(f)) {
|
||||
entry.1.contains(&link)
|
||||
@@ -292,6 +341,19 @@ fn check(cache: &mut Cache, root: &Path, file: &Path, errors: &mut bool) -> Opti
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Search for intra-doc links that rustdoc didn't warn about
|
||||
// FIXME(#77199, 77200) Rustdoc should just warn about these directly.
|
||||
// NOTE: only looks at one line at a time; in practice this should find most links
|
||||
for (i, line) in contents.lines().enumerate() {
|
||||
for broken_link in BROKEN_INTRA_DOC_LINK.captures_iter(line) {
|
||||
if !is_intra_doc_exception(file, &broken_link[1]) {
|
||||
*errors = true;
|
||||
print!("{}:{}: broken intra-doc link - ", pretty_file.display(), i + 1);
|
||||
println!("{}", &broken_link[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(pretty_file)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user