@@ -71,12 +71,6 @@ struct CargoToml {
71
71
workspace: Workspace,
72
72
}
73
73
74
- #[derive(Default, Debug)]
75
- struct LintsAndGroups {
76
- lints: Vec<Spanned<String>>,
77
- groups: Vec<(Spanned<String>, Spanned<LintConfig>)>,
78
- }
79
-
80
74
fn toml_span(range: Range<usize>, file: &SourceFile) -> Span {
81
75
Span::new(
82
76
file.start_pos + BytePos::from_usize(range.start),
@@ -86,27 +80,28 @@ fn toml_span(range: Range<usize>, file: &SourceFile) -> Span {
86
80
)
87
81
}
88
82
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();
91
86
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));
95
93
} else {
96
- lints_and_groups. lints.push(name);
94
+ lints.push(( name, config.into_inner()) );
97
95
}
98
96
}
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);
103
97
104
- for (priority, LintsAndGroups { lints, groups }) in by_priority {
105
- let Some(last_lint_alphabetically) = lints.last() else {
106
- continue;
107
- };
108
-
109
- for (group, config) in groups {
98
+ for (group, group_config) in groups {
99
+ let priority = group_config.get_ref().priority();
100
+ let level = group_config.get_ref().level();
101
+ if let Some((conflict, _)) = lints
102
+ .iter()
103
+ .rfind(|(_, lint_config)| lint_config.priority() == priority && lint_config.level() != level)
104
+ {
110
105
span_lint_and_then(
111
106
cx,
112
107
LINT_GROUPS_PRIORITY,
@@ -116,22 +111,23 @@ fn check_table(cx: &LateContext<'_>, table: LintTable, groups: &FxHashSet<&str>,
116
111
group.as_ref()
117
112
),
118
113
|diag| {
119
- let config_span = toml_span(config.span(), file);
120
- if config.as_ref().is_implicit() {
114
+ let config_span = toml_span(group_config.span(), file);
115
+
116
+ if group_config.as_ref().is_implicit() {
121
117
diag.span_label(config_span, "has an implicit priority of 0");
122
118
}
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");
119
+ diag.span_label(toml_span(conflict.span(), file), "has the same priority as this lint");
130
120
diag.note("the order of the lints in the table is ignored by Cargo");
121
+
131
122
let mut suggestion = String::new();
123
+ let low_priority = lints
124
+ .iter()
125
+ .map(|(_, config)| config.priority().saturating_sub(1))
126
+ .min()
127
+ .unwrap_or(-1);
132
128
Serialize::serialize(
133
129
&LintConfigTable {
134
- level: config.as_ref(). level() .into(),
130
+ level: level.into(),
135
131
priority: Some(low_priority),
136
132
},
137
133
toml::ser::ValueSerializer::new(&mut suggestion),
0 commit comments