Skip to content

Commit

Permalink
Unify lints handling in rustdoc
Browse files Browse the repository at this point in the history
  • Loading branch information
GuillaumeGomez committed Apr 27, 2020
1 parent 019ab73 commit 9ae85e1
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 69 deletions.
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

0 comments on commit 9ae85e1

Please sign in to comment.