Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/hir-ty/src/diagnostics/decl_check.rs21
-rw-r--r--crates/ide-diagnostics/src/handlers/incorrect_case.rs58
2 files changed, 73 insertions, 6 deletions
diff --git a/crates/hir-ty/src/diagnostics/decl_check.rs b/crates/hir-ty/src/diagnostics/decl_check.rs
index 0249f3ba25..82517e6991 100644
--- a/crates/hir-ty/src/diagnostics/decl_check.rs
+++ b/crates/hir-ty/src/diagnostics/decl_check.rs
@@ -24,6 +24,7 @@ use hir_expand::{
name::{AsName, Name},
HirFileId, HirFileIdExt,
};
+use intern::sym;
use stdx::{always, never};
use syntax::{
ast::{self, HasName},
@@ -197,12 +198,20 @@ impl<'a> DeclValidator<'a> {
// Skipped if function is an associated item of a trait implementation.
if !self.is_trait_impl_container(container) {
let data = self.db.function_data(func);
- self.create_incorrect_case_diagnostic_for_item_name(
- func,
- &data.name,
- CaseType::LowerSnakeCase,
- IdentType::Function,
- );
+
+ // Don't run the lint on extern "[not Rust]" fn items with the
+ // #[no_mangle] attribute.
+ let no_mangle = data.attrs.by_key(&sym::no_mangle).exists();
+ if no_mangle && data.abi.as_ref().is_some_and(|abi| *abi != sym::Rust) {
+ cov_mark::hit!(extern_func_no_mangle_ignored);
+ } else {
+ self.create_incorrect_case_diagnostic_for_item_name(
+ func,
+ &data.name,
+ CaseType::LowerSnakeCase,
+ IdentType::Function,
+ );
+ }
} else {
cov_mark::hit!(trait_impl_assoc_func_name_incorrect_case_ignored);
}
diff --git a/crates/ide-diagnostics/src/handlers/incorrect_case.rs b/crates/ide-diagnostics/src/handlers/incorrect_case.rs
index ddc19a0121..ec25c3d52b 100644
--- a/crates/ide-diagnostics/src/handlers/incorrect_case.rs
+++ b/crates/ide-diagnostics/src/handlers/incorrect_case.rs
@@ -419,6 +419,64 @@ fn f((_O): u8) {}
}
#[test]
+ fn ignores_no_mangle_items() {
+ cov_mark::check!(extern_func_no_mangle_ignored);
+ check_diagnostics(
+ r#"
+#[no_mangle]
+extern "C" fn NonSnakeCaseName(some_var: u8) -> u8;
+ "#,
+ );
+ }
+
+ #[test]
+ fn ignores_no_mangle_items_with_no_abi() {
+ cov_mark::check!(extern_func_no_mangle_ignored);
+ check_diagnostics(
+ r#"
+#[no_mangle]
+extern fn NonSnakeCaseName(some_var: u8) -> u8;
+ "#,
+ );
+ }
+
+ #[test]
+ fn no_mangle_items_with_rust_abi() {
+ check_diagnostics(
+ r#"
+#[no_mangle]
+extern "Rust" fn NonSnakeCaseName(some_var: u8) -> u8;
+ // ^^^^^^^^^^^^^^^^ 💡 warn: Function `NonSnakeCaseName` should have snake_case name, e.g. `non_snake_case_name`
+ "#,
+ );
+ }
+
+ #[test]
+ fn no_mangle_items_non_extern() {
+ check_diagnostics(
+ r#"
+#[no_mangle]
+fn NonSnakeCaseName(some_var: u8) -> u8;
+// ^^^^^^^^^^^^^^^^ 💡 warn: Function `NonSnakeCaseName` should have snake_case name, e.g. `non_snake_case_name`
+ "#,
+ );
+ }
+
+ #[test]
+ fn extern_fn_name() {
+ check_diagnostics(
+ r#"
+extern "C" fn NonSnakeCaseName(some_var: u8) -> u8;
+ // ^^^^^^^^^^^^^^^^ 💡 warn: Function `NonSnakeCaseName` should have snake_case name, e.g. `non_snake_case_name`
+extern "Rust" fn NonSnakeCaseName(some_var: u8) -> u8;
+ // ^^^^^^^^^^^^^^^^ 💡 warn: Function `NonSnakeCaseName` should have snake_case name, e.g. `non_snake_case_name`
+extern fn NonSnakeCaseName(some_var: u8) -> u8;
+ // ^^^^^^^^^^^^^^^^ 💡 warn: Function `NonSnakeCaseName` should have snake_case name, e.g. `non_snake_case_name`
+ "#,
+ );
+ }
+
+ #[test]
fn ignores_extern_items() {
cov_mark::check!(extern_func_incorrect_case_ignored);
cov_mark::check!(extern_static_incorrect_case_ignored);