use std::path::Path;
+/// Error code markdown is restricted to 80 columns because they can be
+/// displayed on the console with --example.
const ERROR_CODE_COLS: usize = 80;
const COLS: usize = 100;
/// Lines of this form are allowed to be overlength, because Markdown
/// offers no way to split a line in the middle of a URL, and the lengths
/// of URLs to external references are beyond our control.
-fn line_is_url(columns: usize, line: &str) -> bool {
- // more basic check for error_codes.rs, to avoid complexity in implementing two state machines
- if columns == ERROR_CODE_COLS {
+fn line_is_url(is_error_code: bool, columns: usize, line: &str) -> bool {
+ // more basic check for markdown, to avoid complexity in implementing two state machines
+ if is_error_code {
return line.starts_with('[') && line.contains("]:") && line.contains("http");
}
/// Returns `true` if `line` is allowed to be longer than the normal limit.
/// Currently there is only one exception, for long URLs, but more
/// may be added in the future.
-fn long_line_is_ok(max_columns: usize, line: &str) -> bool {
- if line_is_url(max_columns, line) {
+fn long_line_is_ok(extension: &str, is_error_code: bool, max_columns: usize, line: &str) -> bool {
+ if extension != "md" || is_error_code {
+ if line_is_url(is_error_code, max_columns, line) {
+ return true;
+ }
+ } else if extension == "md" {
+ // non-error code markdown is allowed to be any length
return true;
}
}
}
+fn skip_markdown_path(path: &Path) -> bool {
+ // These aren't ready for tidy.
+ const SKIP_MD: &[&str] = &[
+ "src/doc/edition-guide",
+ "src/doc/embedded-book",
+ "src/doc/nomicon",
+ "src/doc/reference",
+ "src/doc/rust-by-example",
+ "src/doc/rustc-dev-guide",
+ ];
+ SKIP_MD.iter().any(|p| path.ends_with(p))
+}
+
+fn is_unexplained_ignore(extension: &str, line: &str) -> bool {
+ if !line.ends_with("```ignore") && !line.ends_with("```rust,ignore") {
+ return false;
+ }
+ if extension == "md" && line.trim().starts_with("//") {
+ // Markdown examples may include doc comments with ignore inside a
+ // code block.
+ return false;
+ }
+ true
+}
+
pub fn check(path: &Path, bad: &mut bool) {
- super::walk(path, &mut super::filter_dirs, &mut |entry, contents| {
+ fn skip(path: &Path) -> bool {
+ super::filter_dirs(path) || skip_markdown_path(path)
+ }
+ super::walk(path, &mut skip, &mut |entry, contents| {
let file = entry.path();
let filename = file.file_name().unwrap().to_string_lossy();
let extensions = [".rs", ".py", ".js", ".sh", ".c", ".cpp", ".h", ".md", ".css"];
a.ends_with("src/doc/book")
});
- if filename.ends_with(".md")
- && file.parent().unwrap().file_name().unwrap().to_string_lossy() != "error_codes"
- {
- // We don't want to check all ".md" files (almost of of them aren't compliant
- // currently), just the long error code explanation ones.
- return;
- }
if is_style_file && !is_in(file, "src", "librustdoc") {
// We only check CSS files in rustdoc.
return;
tidy_error!(bad, "{}: empty file", file.display());
}
- let max_columns = if filename == "error_codes.rs" || filename.ends_with(".md") {
- ERROR_CODE_COLS
- } else {
- COLS
- };
+ let extension = file.extension().unwrap().to_string_lossy();
+ let is_error_code = extension == "md" && is_in(file, "src", "error_codes");
+
+ let max_columns = if is_error_code { ERROR_CODE_COLS } else { COLS };
let can_contain = contents.contains("// ignore-tidy-")
|| contents.contains("# ignore-tidy-")
};
if !under_rustfmt
&& line.chars().count() > max_columns
- && !long_line_is_ok(max_columns, line)
+ && !long_line_is_ok(&extension, is_error_code, max_columns, line)
{
suppressible_tidy_err!(
err,
suppressible_tidy_err!(err, skip_undocumented_unsafe, "undocumented unsafe");
}
}
- if line.contains("// SAFETY:") || line.contains("// Safety:") {
+ if line.contains("// SAFETY:") {
last_safety_comment = true;
} else if line.trim().starts_with("//") || line.trim().is_empty() {
// keep previous value
"copyright notices attributed to the Rust Project Developers are deprecated"
);
}
- if line.ends_with("```ignore") || line.ends_with("```rust,ignore") {
+ if is_unexplained_ignore(&extension, line) {
err(UNEXPLAINED_IGNORE_DOCTEST_INFO);
}
if filename.ends_with(".cpp") && line.contains("llvm_unreachable") {