Skip to content

Commit 426d526

Browse files
committed
refactor(lints): Keep workspace and package lints separate
1 parent 3c9df90 commit 426d526

File tree

3 files changed

+79
-36
lines changed

3 files changed

+79
-36
lines changed

src/cargo/core/workspace.rs

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1180,6 +1180,21 @@ impl<'gctx> Workspace<'gctx> {
11801180
}
11811181

11821182
pub fn emit_lints(&self, pkg: &Package, path: &Path) -> CargoResult<()> {
1183+
let ws_lints = self
1184+
.root_maybe()
1185+
.workspace_config()
1186+
.inheritable()
1187+
.and_then(|i| i.lints().ok())
1188+
.unwrap_or_default();
1189+
1190+
let ws_cargo_lints = ws_lints
1191+
.get("cargo")
1192+
.cloned()
1193+
.unwrap_or_default()
1194+
.into_iter()
1195+
.map(|(k, v)| (k.replace('-', "_"), v))
1196+
.collect();
1197+
11831198
let mut error_count = 0;
11841199
let toml_lints = pkg
11851200
.manifest()
@@ -1197,9 +1212,30 @@ impl<'gctx> Workspace<'gctx> {
11971212
.map(|(name, lint)| (name.replace('-', "_"), lint))
11981213
.collect();
11991214

1200-
check_im_a_teapot(pkg, &path, &normalized_lints, &mut error_count, self.gctx)?;
1201-
check_implicit_features(pkg, &path, &normalized_lints, &mut error_count, self.gctx)?;
1202-
unused_dependencies(pkg, &path, &normalized_lints, &mut error_count, self.gctx)?;
1215+
check_im_a_teapot(
1216+
pkg,
1217+
&path,
1218+
&normalized_lints,
1219+
&ws_cargo_lints,
1220+
&mut error_count,
1221+
self.gctx,
1222+
)?;
1223+
check_implicit_features(
1224+
pkg,
1225+
&path,
1226+
&normalized_lints,
1227+
&ws_cargo_lints,
1228+
&mut error_count,
1229+
self.gctx,
1230+
)?;
1231+
unused_dependencies(
1232+
pkg,
1233+
&path,
1234+
&normalized_lints,
1235+
&ws_cargo_lints,
1236+
&mut error_count,
1237+
self.gctx,
1238+
)?;
12031239
if error_count > 0 {
12041240
Err(crate::util::errors::AlreadyPrintedError::new(anyhow!(
12051241
"encountered {error_count} errors(s) while running lints"

src/cargo/util/lints.rs

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,12 @@ pub trait LevelTrait {
6464
fn default_level(&self) -> LintLevel;
6565
fn edition_lint_opts(&self) -> Option<(Edition, LintLevel)>;
6666
fn name(&self) -> &str;
67-
fn level_priority(&self, lints: &TomlToolLints, edition: Edition) -> (LintLevel, i8) {
67+
fn level_priority(
68+
&self,
69+
pkg_lints: &TomlToolLints,
70+
ws_lints: &TomlToolLints,
71+
edition: Edition,
72+
) -> (LintLevel, i8) {
6873
let unspecified_level = if let Some(level) = self
6974
.edition_lint_opts()
7075
.filter(|(e, _)| edition >= *e)
@@ -80,7 +85,9 @@ pub trait LevelTrait {
8085
return (unspecified_level, 0);
8186
}
8287

83-
if let Some(defined_level) = lints.get(self.name()) {
88+
if let Some(defined_level) = pkg_lints.get(self.name()) {
89+
(defined_level.level().into(), defined_level.priority())
90+
} else if let Some(defined_level) = ws_lints.get(self.name()) {
8491
(defined_level.level().into(), defined_level.priority())
8592
} else {
8693
(unspecified_level, 0)
@@ -141,13 +148,18 @@ impl LevelTrait for Lint {
141148
}
142149

143150
impl Lint {
144-
pub fn level(&self, lints: &TomlToolLints, edition: Edition) -> LintLevel {
151+
pub fn level(
152+
&self,
153+
lints: &TomlToolLints,
154+
ws_lints: &TomlToolLints,
155+
edition: Edition,
156+
) -> LintLevel {
145157
self.groups
146158
.iter()
147-
.map(|g| (g.name, g.level_priority(lints, edition)))
159+
.map(|g| (g.name, g.level_priority(lints, ws_lints, edition)))
148160
.chain(std::iter::once((
149161
self.name,
150-
self.level_priority(lints, edition),
162+
self.level_priority(lints, ws_lints, edition),
151163
)))
152164
.max_by_key(|(n, (l, p))| (l == &LintLevel::Forbid, *p, std::cmp::Reverse(*n)))
153165
.map(|(_, (l, _))| l)
@@ -207,12 +219,13 @@ const IM_A_TEAPOT: Lint = Lint {
207219
pub fn check_im_a_teapot(
208220
pkg: &Package,
209221
path: &Path,
210-
lints: &TomlToolLints,
222+
pkg_lints: &TomlToolLints,
223+
ws_lints: &TomlToolLints,
211224
error_count: &mut usize,
212225
gctx: &GlobalContext,
213226
) -> CargoResult<()> {
214227
let manifest = pkg.manifest();
215-
let lint_level = IM_A_TEAPOT.level(lints, manifest.edition());
228+
let lint_level = IM_A_TEAPOT.level(pkg_lints, ws_lints, manifest.edition());
216229
if lint_level == LintLevel::Allow {
217230
return Ok(());
218231
}
@@ -275,7 +288,8 @@ const IMPLICIT_FEATURES: Lint = Lint {
275288
pub fn check_implicit_features(
276289
pkg: &Package,
277290
path: &Path,
278-
lints: &TomlToolLints,
291+
pkg_lints: &TomlToolLints,
292+
ws_lints: &TomlToolLints,
279293
error_count: &mut usize,
280294
gctx: &GlobalContext,
281295
) -> CargoResult<()> {
@@ -286,7 +300,7 @@ pub fn check_implicit_features(
286300
return Ok(());
287301
}
288302

289-
let lint_level = IMPLICIT_FEATURES.level(lints, edition);
303+
let lint_level = IMPLICIT_FEATURES.level(pkg_lints, ws_lints, edition);
290304
if lint_level == LintLevel::Allow {
291305
return Ok(());
292306
}
@@ -358,7 +372,8 @@ const UNUSED_OPTIONAL_DEPENDENCY: Lint = Lint {
358372
pub fn unused_dependencies(
359373
pkg: &Package,
360374
path: &Path,
361-
lints: &TomlToolLints,
375+
pkg_lints: &TomlToolLints,
376+
ws_lints: &TomlToolLints,
362377
error_count: &mut usize,
363378
gctx: &GlobalContext,
364379
) -> CargoResult<()> {
@@ -368,7 +383,7 @@ pub fn unused_dependencies(
368383
return Ok(());
369384
}
370385

371-
let lint_level = UNUSED_OPTIONAL_DEPENDENCY.level(lints, edition);
386+
let lint_level = UNUSED_OPTIONAL_DEPENDENCY.level(pkg_lints, ws_lints, edition);
372387
if lint_level == LintLevel::Allow {
373388
return Ok(());
374389
}

src/cargo/util/toml/mod.rs

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -411,15 +411,7 @@ fn resolve_toml(
411411
}
412412
resolved_toml.target = (!resolved_target.is_empty()).then_some(resolved_target);
413413

414-
let resolved_lints = original_toml
415-
.lints
416-
.clone()
417-
.map(|value| lints_inherit_with(value, || inherit()?.lints()))
418-
.transpose()?;
419-
resolved_toml.lints = resolved_lints.map(|lints| manifest::InheritableLints {
420-
workspace: false,
421-
lints,
422-
});
414+
resolved_toml.lints = original_toml.lints.clone();
423415

424416
let resolved_badges = original_toml
425417
.badges
@@ -803,7 +795,7 @@ impl InheritableFields {
803795
}
804796

805797
/// Gets the field `workspace.lint`.
806-
fn lints(&self) -> CargoResult<manifest::TomlLints> {
798+
pub fn lints(&self) -> CargoResult<manifest::TomlLints> {
807799
let Some(val) = &self.lints else {
808800
bail!("`workspace.lints` was not defined");
809801
};
@@ -1284,18 +1276,18 @@ fn to_real_manifest(
12841276
}
12851277
}
12861278

1287-
verify_lints(
1288-
resolved_toml.resolved_lints().expect("previously resolved"),
1289-
gctx,
1290-
warnings,
1291-
)?;
1292-
let default = manifest::TomlLints::default();
1293-
let rustflags = lints_to_rustflags(
1294-
resolved_toml
1295-
.resolved_lints()
1296-
.expect("previously resolved")
1297-
.unwrap_or(&default),
1298-
);
1279+
let resolved_lints = original_toml
1280+
.lints
1281+
.clone()
1282+
.map(|value| {
1283+
lints_inherit_with(value, || {
1284+
load_inheritable_fields(gctx, manifest_file, &workspace_config)?.lints()
1285+
})
1286+
})
1287+
.transpose()?;
1288+
1289+
verify_lints(resolved_lints.as_ref(), gctx, warnings)?;
1290+
let rustflags = lints_to_rustflags(&resolved_lints.unwrap_or_default());
12991291

13001292
let metadata = ManifestMetadata {
13011293
description: resolved_package

0 commit comments

Comments
 (0)