Skip to content

Commit

Permalink
fix(cargo-lints): Respect Forbid lint level
Browse files Browse the repository at this point in the history
  • Loading branch information
Muscraft committed Apr 21, 2024
1 parent 2d40a47 commit 11d6013
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 8 deletions.
2 changes: 1 addition & 1 deletion crates/cargo-util-schemas/src/manifest/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1506,7 +1506,7 @@ pub struct TomlLintConfig {
pub priority: i8,
}

#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
#[derive(Serialize, Deserialize, Debug, Copy, Clone, Eq, PartialEq)]
#[serde(rename_all = "kebab-case")]
pub enum TomlLintLevel {
Forbid,
Expand Down
35 changes: 28 additions & 7 deletions src/cargo/util/lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,13 @@ pub struct LintGroup {
pub edition_lint_opts: Option<(Edition, LintLevel)>,
}

const TEST_DUMMY_UNSTABLE: LintGroup = LintGroup {
name: "test_dummy_unstable",
desc: "test_dummy_unstable is meant to only be used in tests",
default_level: LintLevel::Allow,
edition_lint_opts: None,
};

#[derive(Copy, Clone, Debug)]
pub struct Lint {
pub name: &'static str,
Expand All @@ -79,23 +86,37 @@ pub struct Lint {

impl Lint {
pub fn level(&self, lints: &TomlToolLints, edition: Edition) -> LintLevel {
let edition_level = self
.edition_lint_opts
.filter(|(e, _)| edition >= *e)
.map(|(_, l)| l);

if self.default_level == LintLevel::Forbid || edition_level == Some(LintLevel::Forbid) {
return LintLevel::Forbid;
}

let level = self
.groups
.iter()
.map(|g| g.name)
.chain(std::iter::once(self.name))
.filter_map(|n| lints.get(n).map(|l| (n, l)))
.max_by_key(|(n, l)| (l.priority(), std::cmp::Reverse(*n)));
.max_by_key(|(n, l)| {
(
l.level() == TomlLintLevel::Forbid,
l.priority(),
std::cmp::Reverse(*n),
)
});

match level {
Some((_, toml_lint)) => toml_lint.level().into(),
None => {
if let Some((lint_edition, lint_level)) = self.edition_lint_opts {
if edition >= lint_edition {
return lint_level;
}
if let Some(level) = edition_level {
level
} else {
self.default_level
}
self.default_level
}
}
}
Expand Down Expand Up @@ -145,7 +166,7 @@ impl From<TomlLintLevel> for LintLevel {
const IM_A_TEAPOT: Lint = Lint {
name: "im_a_teapot",
desc: "`im_a_teapot` is specified",
groups: &[],
groups: &[TEST_DUMMY_UNSTABLE],
default_level: LintLevel::Allow,
edition_lint_opts: None,
};
Expand Down
40 changes: 40 additions & 0 deletions tests/testsuite/lints_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -899,3 +899,43 @@ warning: `im_a_teapot` is specified
)
.run();
}

#[cargo_test]
fn forbid_not_overridden() {
let p = project()
.file(
"Cargo.toml",
r#"
cargo-features = ["test-dummy-unstable"]
[package]
name = "foo"
version = "0.0.1"
edition = "2015"
authors = []
im-a-teapot = true
[lints.cargo]
im-a-teapot = { level = "warn", priority = 10 }
test-dummy-unstable = { level = "forbid", priority = -1 }
"#,
)
.file("src/lib.rs", "")
.build();

p.cargo("check -Zcargo-lints")
.masquerade_as_nightly_cargo(&["cargo-lints", "test-dummy-unstable"])
.with_status(101)
.with_stderr(
"\
error: `im_a_teapot` is specified
--> Cargo.toml:9:1
|
9 | im-a-teapot = true
| ^^^^^^^^^^^^^^^^^^
|
= note: `cargo::im_a_teapot` is set to `forbid`
",
)
.run();
}

0 comments on commit 11d6013

Please sign in to comment.