Rollup merge of #123986 - ehuss:lint-renamed, r=Mark-Simulacrum

lint-docs: Add redirects for renamed lints.

This updates the lint docs to include a redirect for renamed lints to the new name. This helps ensure that links to the old name will still be valid.

Note that this currently uses a hard-coded list. As mentioned in the comment, a future enhancement may gather this information in a better way.

Unblocks #123680
This commit is contained in:
许杰友 Jieyou Xu (Joe) 2024-04-20 21:45:35 +01:00 committed by GitHub
commit 871c3e3075
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -7,6 +7,43 @@
mod groups;
/// List of lints which have been renamed.
///
/// These will get redirects in the output to the new name. The
/// format is `(level, [(old_name, new_name), ...])`.
///
/// Note: This hard-coded list is a temporary hack. The intent is in the
/// future to have `rustc` expose this information in some way (like a `-Z`
/// flag spitting out JSON). Also, this does not yet support changing the
/// level of the lint, which will be more difficult to support, since rustc
/// currently does not track that historical information.
static RENAMES: &[(Level, &[(&str, &str)])] = &[
(
Level::Allow,
&[
("single-use-lifetime", "single-use-lifetimes"),
("elided-lifetime-in-path", "elided-lifetimes-in-paths"),
("async-idents", "keyword-idents"),
("disjoint-capture-migration", "rust-2021-incompatible-closure-captures"),
("or-patterns-back-compat", "rust-2021-incompatible-or-patterns"),
],
),
(
Level::Warn,
&[
("bare-trait-object", "bare-trait-objects"),
("unstable-name-collision", "unstable-name-collisions"),
("unused-doc-comment", "unused-doc-comments"),
("redundant-semicolon", "redundant-semicolons"),
("overlapping-patterns", "overlapping-range-endpoints"),
("non-fmt-panic", "non-fmt-panics"),
("unused-tuple-struct-fields", "dead-code"),
("static-mut-ref", "static-mut-refs"),
],
),
(Level::Deny, &[("exceeding-bitshifts", "arithmetic-overflow")]),
];
pub struct LintExtractor<'a> {
/// Path to the `src` directory, where it will scan for `.rs` files to
/// find lint declarations.
@ -126,6 +163,7 @@ pub fn extract_lint_docs(&self) -> Result<(), Box<dyn Error>> {
)
})?;
}
add_renamed_lints(&mut lints);
self.save_lints_markdown(&lints)?;
self.generate_group_docs(&lints)?;
Ok(())
@ -482,6 +520,7 @@ fn save_level(&self, lints: &[Lint], level: Level, header: &str) -> Result<(), B
}
result.push('\n');
}
add_rename_redirect(level, &mut result);
let out_path = self.out_path.join("listing").join(level.doc_filename());
// Delete the output because rustbuild uses hard links in its copies.
let _ = fs::remove_file(&out_path);
@ -491,6 +530,56 @@ fn save_level(&self, lints: &[Lint], level: Level, header: &str) -> Result<(), B
}
}
/// Adds `Lint`s that have been renamed.
fn add_renamed_lints(lints: &mut Vec<Lint>) {
for (level, names) in RENAMES {
for (from, to) in *names {
lints.push(Lint {
name: from.to_string(),
doc: vec![format!("The lint `{from}` has been renamed to [`{to}`](#{to}).")],
level: *level,
path: PathBuf::new(),
lineno: 0,
});
}
}
}
// This uses DOMContentLoaded instead of running immediately because for some
// reason on Firefox (124 of this writing) doesn't update the `target` CSS
// selector if only the hash changes.
static RENAME_START: &str = "
<script>
document.addEventListener(\"DOMContentLoaded\", (event) => {
var fragments = {
";
static RENAME_END: &str = "\
};
var target = fragments[window.location.hash];
if (target) {
var url = window.location.toString();
var base = url.substring(0, url.lastIndexOf('/'));
window.location.replace(base + \"/\" + target);
}
});
</script>
";
/// Adds the javascript redirection code to the given markdown output.
fn add_rename_redirect(level: Level, output: &mut String) {
for (rename_level, names) in RENAMES {
if *rename_level == level {
let filename = level.doc_filename().replace(".md", ".html");
output.push_str(RENAME_START);
for (from, to) in *names {
write!(output, " \"#{from}\": \"{filename}#{to}\",\n").unwrap();
}
output.push_str(RENAME_END);
}
}
}
/// Extracts the lint name (removing the visibility modifier, and checking validity).
fn lint_name(line: &str) -> Result<String, &'static str> {
// Skip over any potential `pub` visibility.