Skip to content

Commit 34ef4f4

Browse files
committed
lint_groups_priority: ignore lints & groups at the same level
1 parent 0b1bf37 commit 34ef4f4

File tree

4 files changed

+83
-77
lines changed

4 files changed

+83
-77
lines changed

clippy_lints/src/cargo/lint_groups_priority.rs

Lines changed: 64 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,6 @@ struct CargoToml {
7171
workspace: Workspace,
7272
}
7373

74-
#[derive(Default, Debug)]
75-
struct LintsAndGroups {
76-
lints: Vec<Spanned<String>>,
77-
groups: Vec<(Spanned<String>, Spanned<LintConfig>)>,
78-
}
79-
8074
fn toml_span(range: Range<usize>, file: &SourceFile) -> Span {
8175
Span::new(
8276
file.start_pos + BytePos::from_usize(range.start),
@@ -86,69 +80,78 @@ fn toml_span(range: Range<usize>, file: &SourceFile) -> Span {
8680
)
8781
}
8882

89-
fn check_table(cx: &LateContext<'_>, table: LintTable, groups: &FxHashSet<&str>, file: &SourceFile) {
90-
let mut by_priority = BTreeMap::<_, LintsAndGroups>::new();
83+
fn check_table(cx: &LateContext<'_>, table: LintTable, known_groups: &FxHashSet<&str>, file: &SourceFile) {
84+
let mut lints = Vec::new();
85+
let mut groups = Vec::new();
9186
for (name, config) in table {
92-
let lints_and_groups = by_priority.entry(config.as_ref().priority()).or_default();
93-
if groups.contains(name.get_ref().as_str()) {
94-
lints_and_groups.groups.push((name, config));
87+
if name.get_ref() == "warnings" {
88+
continue;
89+
}
90+
91+
if known_groups.contains(name.get_ref().as_str()) {
92+
groups.push((name, config));
9593
} else {
96-
lints_and_groups.lints.push(name);
94+
lints.push((name, config.into_inner()));
9795
}
9896
}
99-
let low_priority = by_priority
100-
.iter()
101-
.find(|(_, lints_and_groups)| !lints_and_groups.lints.is_empty())
102-
.map_or(-1, |(&lowest_lint_priority, _)| lowest_lint_priority - 1);
10397

104-
for (priority, LintsAndGroups { lints, groups }) in by_priority {
105-
let Some(last_lint_alphabetically) = lints.last() else {
98+
for (group, group_config) in groups {
99+
let priority = group_config.get_ref().priority();
100+
let level = group_config.get_ref().level();
101+
let mut conflicts = lints
102+
.iter()
103+
.filter(|(_, lint_config)| lint_config.priority() == priority && lint_config.level() != level);
104+
105+
let Some(last_conflict) = conflicts.next_back() else {
106106
continue;
107107
};
108108

109-
for (group, config) in groups {
110-
span_lint_and_then(
111-
cx,
112-
LINT_GROUPS_PRIORITY,
113-
toml_span(group.span(), file),
114-
format!(
115-
"lint group `{}` has the same priority ({priority}) as a lint",
116-
group.as_ref()
117-
),
118-
|diag| {
119-
let config_span = toml_span(config.span(), file);
120-
if config.as_ref().is_implicit() {
121-
diag.span_label(config_span, "has an implicit priority of 0");
122-
}
123-
// add the label to next lint after this group that has the same priority
124-
let lint = lints
125-
.iter()
126-
.filter(|lint| lint.span().start > group.span().start)
127-
.min_by_key(|lint| lint.span().start)
128-
.unwrap_or(last_lint_alphabetically);
129-
diag.span_label(toml_span(lint.span(), file), "has the same priority as this lint");
130-
diag.note("the order of the lints in the table is ignored by Cargo");
131-
let mut suggestion = String::new();
132-
Serialize::serialize(
133-
&LintConfigTable {
134-
level: config.as_ref().level().into(),
135-
priority: Some(low_priority),
136-
},
137-
toml::ser::ValueSerializer::new(&mut suggestion),
138-
)
139-
.unwrap();
140-
diag.span_suggestion_verbose(
141-
config_span,
142-
format!(
143-
"to have lints override the group set `{}` to a lower priority",
144-
group.as_ref()
145-
),
146-
suggestion,
147-
Applicability::MaybeIncorrect,
148-
);
149-
},
150-
);
151-
}
109+
span_lint_and_then(
110+
cx,
111+
LINT_GROUPS_PRIORITY,
112+
toml_span(group.span(), file),
113+
format!(
114+
"lint group `{}` has the same priority ({priority}) as a lint",
115+
group.as_ref()
116+
),
117+
|diag| {
118+
let config_span = toml_span(group_config.span(), file);
119+
120+
if group_config.as_ref().is_implicit() {
121+
diag.span_label(config_span, "has an implicit priority of 0");
122+
}
123+
// add the label to next lint after this group that has the same priority
124+
let (lint, _) = conflicts
125+
.find(|(lint, _)| lint.span().start > group.span().start)
126+
.unwrap_or(last_conflict);
127+
diag.span_label(toml_span(lint.span(), file), "has the same priority as this lint");
128+
diag.note("the order of the lints in the table is ignored by Cargo");
129+
130+
let mut suggestion = String::new();
131+
let low_priority = lints
132+
.iter()
133+
.map(|(_, config)| config.priority().saturating_sub(1))
134+
.min()
135+
.unwrap_or(-1);
136+
Serialize::serialize(
137+
&LintConfigTable {
138+
level: level.into(),
139+
priority: Some(low_priority),
140+
},
141+
toml::ser::ValueSerializer::new(&mut suggestion),
142+
)
143+
.unwrap();
144+
diag.span_suggestion_verbose(
145+
config_span,
146+
format!(
147+
"to have lints override the group set `{}` to a lower priority",
148+
group.as_ref()
149+
),
150+
suggestion,
151+
Applicability::MaybeIncorrect,
152+
);
153+
},
154+
);
152155
}
153156
}
154157

tests/ui-cargo/lint_groups_priority/fail/Cargo.stderr

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,45 +29,45 @@ help: to have lints override the group set `unused` to a lower priority
2929
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3030

3131
error: lint group `pedantic` has the same priority (-1) as a lint
32-
--> Cargo.toml:19:1
32+
--> Cargo.toml:15:1
3333
|
34-
19 | pedantic = { level = "warn", priority = -1 }
34+
15 | pedantic = { level = "warn", priority = -1 }
3535
| ^^^^^^^^
36-
20 | similar_names = { level = "allow", priority = -1 }
36+
16 | similar_names = { level = "allow", priority = -1 }
3737
| ------------- has the same priority as this lint
3838
|
3939
= note: the order of the lints in the table is ignored by Cargo
4040
help: to have lints override the group set `pedantic` to a lower priority
4141
|
42-
19 | pedantic = { level = "warn", priority = -2 }
42+
15 | pedantic = { level = "warn", priority = -2 }
4343
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4444

4545
error: lint group `rust_2018_idioms` has the same priority (0) as a lint
46-
--> Cargo.toml:23:1
46+
--> Cargo.toml:19:1
4747
|
48-
23 | rust_2018_idioms = "warn"
48+
19 | rust_2018_idioms = "warn"
4949
| ^^^^^^^^^^^^^^^^ ------ has an implicit priority of 0
50-
24 | bare_trait_objects = "allow"
50+
20 | bare_trait_objects = "allow"
5151
| ------------------ has the same priority as this lint
5252
|
5353
= note: the order of the lints in the table is ignored by Cargo
5454
help: to have lints override the group set `rust_2018_idioms` to a lower priority
5555
|
56-
23 | rust_2018_idioms = { level = "warn", priority = -1 }
56+
19 | rust_2018_idioms = { level = "warn", priority = -1 }
5757
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5858

5959
error: lint group `pedantic` has the same priority (0) as a lint
60-
--> Cargo.toml:27:1
60+
--> Cargo.toml:23:1
6161
|
62-
27 | pedantic = "warn"
62+
23 | pedantic = "warn"
6363
| ^^^^^^^^ ------ has an implicit priority of 0
64-
28 | similar_names = "allow"
64+
24 | similar_names = "allow"
6565
| ------------- has the same priority as this lint
6666
|
6767
= note: the order of the lints in the table is ignored by Cargo
6868
help: to have lints override the group set `pedantic` to a lower priority
6969
|
70-
27 | pedantic = { level = "warn", priority = -1 }
70+
23 | pedantic = { level = "warn", priority = -1 }
7171
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7272

7373
error: could not compile `fail` (lib) due to 5 previous errors

tests/ui-cargo/lint_groups_priority/fail/Cargo.toml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,6 @@ unused = { level = "deny" }
1111
unused_braces = { level = "allow", priority = 1 }
1212
unused_attributes = { level = "allow" }
1313

14-
# `warnings` is not a group so the order it is passed does not matter
15-
warnings = "deny"
16-
deprecated = "allow"
17-
1814
[lints.clippy]
1915
pedantic = { level = "warn", priority = -1 }
2016
similar_names = { level = "allow", priority = -1 }

tests/ui-cargo/lint_groups_priority/pass/Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@ name = "pass"
33
version = "0.1.0"
44
publish = false
55

6+
[lints.rust]
7+
# Warnings does not conflict with any group or lint
8+
warnings = "deny"
9+
# Groups & lints at the same level do not conflict
10+
rust_2018_idioms = "warn"
11+
unsafe_code = "warn"
12+
613
[lints.clippy]
714
pedantic = { level = "warn", priority = -1 }
815
style = { level = "warn", priority = 1 }

0 commit comments

Comments
 (0)