Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #21265 from J3m3/lint-attr-order
fix: respect rustc's lint attribute application order
Chayim Refael Friedman 4 months ago
parent c410127 · parent 2619bd2 · commit 87cf663
-rw-r--r--crates/hir/src/semantics.rs2
-rw-r--r--crates/ide-diagnostics/src/handlers/incorrect_case.rs3
-rw-r--r--crates/ide-diagnostics/src/handlers/unused_variables.rs55
-rw-r--r--crates/ide-diagnostics/src/lib.rs10
4 files changed, 60 insertions, 10 deletions
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index ffb518b1e6..b15e642daa 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -267,7 +267,7 @@ impl<DB: HirDatabase + ?Sized> Semantics<'_, DB> {
&self,
krate: Crate,
item: ast::AnyHasAttrs,
- ) -> impl Iterator<Item = (LintAttr, SmolStr)> {
+ ) -> impl DoubleEndedIterator<Item = (LintAttr, SmolStr)> {
let mut cfg_options = None;
let cfg_options = || *cfg_options.get_or_insert_with(|| krate.id.cfg_options(self.db));
let mut result = Vec::new();
diff --git a/crates/ide-diagnostics/src/handlers/incorrect_case.rs b/crates/ide-diagnostics/src/handlers/incorrect_case.rs
index fdc426c32c..4a12c5a26d 100644
--- a/crates/ide-diagnostics/src/handlers/incorrect_case.rs
+++ b/crates/ide-diagnostics/src/handlers/incorrect_case.rs
@@ -1000,7 +1000,8 @@ mod OtherBadCase;
// ^^^^^^^^^^^^ 💡 error: Module `OtherBadCase` should have snake_case name, e.g. `other_bad_case`
//- /BAD_CASE/OtherBadCase.rs
-#![deny(non_snake_case)]
+#![allow(non_snake_case)]
+#![deny(non_snake_case)] // The lint level has been overridden.
fn FOO() {}
// ^^^ 💡 error: Function `FOO` should have snake_case name, e.g. `foo`
diff --git a/crates/ide-diagnostics/src/handlers/unused_variables.rs b/crates/ide-diagnostics/src/handlers/unused_variables.rs
index 84e63acbc0..b7ec8fa53f 100644
--- a/crates/ide-diagnostics/src/handlers/unused_variables.rs
+++ b/crates/ide-diagnostics/src/handlers/unused_variables.rs
@@ -183,6 +183,61 @@ fn main2() {
}
#[test]
+ fn apply_last_lint_attribute_when_multiple_are_present() {
+ check_diagnostics(
+ r#"
+#![allow(unused_variables)]
+#![warn(unused_variables)]
+#![deny(unused_variables)]
+
+fn main() {
+ let x = 2;
+ //^ 💡 error: unused variable
+
+ #[deny(unused_variables)]
+ #[warn(unused_variables)]
+ #[allow(unused_variables)]
+ let y = 0;
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn prefer_closest_ancestor_lint_attribute() {
+ check_diagnostics(
+ r#"
+#![allow(unused_variables)]
+
+fn main() {
+ #![warn(unused_variables)]
+
+ #[deny(unused_variables)]
+ let x = 2;
+ //^ 💡 error: unused variable
+}
+
+#[warn(unused_variables)]
+fn main2() {
+ #[deny(unused_variables)]
+ let x = 2;
+ //^ 💡 error: unused variable
+}
+
+#[warn(unused_variables)]
+fn main3() {
+ let x = 2;
+ //^ 💡 warn: unused variable
+}
+
+fn main4() {
+ let x = 2;
+}
+"#,
+ );
+ }
+
+ #[test]
fn fix_unused_variable() {
check_fix(
r#"
diff --git a/crates/ide-diagnostics/src/lib.rs b/crates/ide-diagnostics/src/lib.rs
index fe04bd175c..343c28e8f9 100644
--- a/crates/ide-diagnostics/src/lib.rs
+++ b/crates/ide-diagnostics/src/lib.rs
@@ -643,19 +643,13 @@ fn find_outline_mod_lint_severity(
let mod_def = sema.to_module_def(&mod_node)?;
let module_source_file = sema.module_definition_node(mod_def);
- let mut result = None;
let lint_groups = lint_groups(&diag.code, edition);
lint_attrs(
sema,
krate,
ast::AnyHasAttrs::cast(module_source_file.value).expect("SourceFile always has attrs"),
)
- .for_each(|(lint, severity)| {
- if lint_groups.contains(&lint) {
- result = Some(severity);
- }
- });
- result
+ .find_map(|(lint, severity)| lint_groups.contains(&lint).then_some(severity))
}
fn lint_severity_at(
@@ -682,7 +676,7 @@ fn lint_attrs(
krate: hir::Crate,
ancestor: ast::AnyHasAttrs,
) -> impl Iterator<Item = (SmolStr, Severity)> {
- sema.lint_attrs(krate, ancestor).map(|(lint_attr, lint)| {
+ sema.lint_attrs(krate, ancestor).rev().map(|(lint_attr, lint)| {
let severity = match lint_attr {
hir::LintAttr::Allow | hir::LintAttr::Expect => Severity::Allow,
hir::LintAttr::Warn => Severity::Warning,