Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unify lints handling in rustdoc #71581

Merged
merged 1 commit into from
May 8, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
96 changes: 60 additions & 36 deletions src/librustdoc/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,56 @@ pub fn new_handler(
)
}

/// This function is used to setup the lint initialization. By default, in rustdoc, everything
/// is "allowed". Depending if we run in test mode or not, we want some of them to be at their
/// default level. For example, the "INVALID_CODEBLOCK_ATTRIBUTE" lint is activated in both
/// modes.
///
/// A little detail easy to forget is that there is a way to set the lint level for all lints
/// through the "WARNINGS" lint. To prevent this to happen, we set it back to its "normal" level
/// inside this function.
///
/// It returns a tuple containing:
/// * Vector of tuples of lints' name and their associated "max" level
/// * HashMap of lint id with their associated "max" level
pub fn init_lints<F>(
mut whitelisted_lints: Vec<String>,
lint_opts: Vec<(String, lint::Level)>,
filter_call: F,
) -> (Vec<(String, lint::Level)>, FxHashMap<lint::LintId, lint::Level>)
where
F: Fn(&lint::Lint) -> Option<(String, lint::Level)>,
{
let warnings_lint_name = lint::builtin::WARNINGS.name;

whitelisted_lints.push(warnings_lint_name.to_owned());
whitelisted_lints.extend(lint_opts.iter().map(|(lint, _)| lint).cloned());

let lints = || {
lint::builtin::HardwiredLints::get_lints()
.into_iter()
.chain(rustc_lint::SoftLints::get_lints().into_iter())
};

let lint_opts = lints()
.filter_map(|lint| if lint.name == warnings_lint_name { None } else { filter_call(lint) })
.chain(lint_opts.into_iter())
.collect::<Vec<_>>();

let lint_caps = lints()
.filter_map(|lint| {
// We don't want to whitelist *all* lints so let's
// ignore those ones.
if whitelisted_lints.iter().any(|l| lint.name == l) {
None
} else {
Some((lint::LintId::of(lint), lint::Allow))
}
})
.collect();
(lint_opts, lint_caps)
}

pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOptions) {
// Parse, resolve, and typecheck the given crate.

Expand Down Expand Up @@ -248,7 +298,6 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
let input = Input::File(input);

let intra_link_resolution_failure_name = lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE.name;
let warnings_lint_name = lint::builtin::WARNINGS.name;
let missing_docs = rustc_lint::builtin::MISSING_DOCS.name;
let missing_doc_example = rustc_lint::builtin::MISSING_DOC_CODE_EXAMPLES.name;
let private_doc_tests = rustc_lint::builtin::PRIVATE_DOC_TESTS.name;
Expand All @@ -257,8 +306,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt

// In addition to those specific lints, we also need to whitelist those given through
// command line, otherwise they'll get ignored and we don't want that.
let mut whitelisted_lints = vec![
warnings_lint_name.to_owned(),
let whitelisted_lints = vec![
intra_link_resolution_failure_name.to_owned(),
missing_docs.to_owned(),
missing_doc_example.to_owned(),
Expand All @@ -267,39 +315,15 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
invalid_codeblock_attribute_name.to_owned(),
];

whitelisted_lints.extend(lint_opts.iter().map(|(lint, _)| lint).cloned());

let lints = || {
lint::builtin::HardwiredLints::get_lints()
.into_iter()
.chain(rustc_lint::SoftLints::get_lints().into_iter())
};

let lint_opts = lints()
.filter_map(|lint| {
if lint.name == warnings_lint_name
|| lint.name == intra_link_resolution_failure_name
|| lint.name == invalid_codeblock_attribute_name
{
None
} else {
Some((lint.name_lower(), lint::Allow))
}
})
.chain(lint_opts.into_iter())
.collect::<Vec<_>>();

let lint_caps = lints()
.filter_map(|lint| {
// We don't want to whitelist *all* lints so let's
// ignore those ones.
if whitelisted_lints.iter().any(|l| lint.name == l) {
None
} else {
Some((lint::LintId::of(lint), lint::Allow))
}
})
.collect();
let (lint_opts, lint_caps) = init_lints(whitelisted_lints, lint_opts, |lint| {
if lint.name == intra_link_resolution_failure_name
|| lint.name == invalid_codeblock_attribute_name
{
None
} else {
Some((lint.name_lower(), lint::Allow))
}
});

let crate_types = if proc_macro_crate {
vec![config::CrateType::ProcMacro]
Expand Down
42 changes: 9 additions & 33 deletions src/librustdoc/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use tempfile::Builder as TempFileBuilder;

use crate::clean::Attributes;
use crate::config::Options;
use crate::core::init_lints;
use crate::html::markdown::{self, ErrorCodes, Ignore, LangString};
use crate::passes::span_of_attrs;

Expand All @@ -43,44 +44,19 @@ pub struct TestOptions {
pub fn run(options: Options) -> i32 {
let input = config::Input::File(options.input.clone());

let warnings_lint_name = lint::builtin::WARNINGS.name;
let invalid_codeblock_attribute_name = rustc_lint::builtin::INVALID_CODEBLOCK_ATTRIBUTE.name;

// In addition to those specific lints, we also need to whitelist those given through
// command line, otherwise they'll get ignored and we don't want that.
let mut whitelisted_lints =
vec![warnings_lint_name.to_owned(), invalid_codeblock_attribute_name.to_owned()];
let whitelisted_lints = vec![invalid_codeblock_attribute_name.to_owned()];

whitelisted_lints.extend(options.lint_opts.iter().map(|(lint, _)| lint).cloned());

let lints = || {
lint::builtin::HardwiredLints::get_lints()
.into_iter()
.chain(rustc_lint::SoftLints::get_lints().into_iter())
};

let lint_opts = lints()
.filter_map(|lint| {
if lint.name == warnings_lint_name || lint.name == invalid_codeblock_attribute_name {
None
} else {
Some((lint.name_lower(), lint::Allow))
}
})
.chain(options.lint_opts.clone().into_iter())
.collect::<Vec<_>>();

let lint_caps = lints()
.filter_map(|lint| {
// We don't want to whitelist *all* lints so let's
// ignore those ones.
if whitelisted_lints.iter().any(|l| lint.name == l) {
None
} else {
Some((lint::LintId::of(lint), lint::Allow))
}
})
.collect();
let (lint_opts, lint_caps) = init_lints(whitelisted_lints, options.lint_opts.clone(), |lint| {
if lint.name == invalid_codeblock_attribute_name {
None
} else {
Some((lint.name_lower(), lint::Allow))
}
});

let crate_types = if options.proc_macro_crate {
vec![config::CrateType::ProcMacro]
Expand Down