Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #21374 from Jefffrey/excuse-non-camel-case-repr-c
fix: don't fire `non_camel_case_types` lint for structs/enums marked with `repr(C)`
| -rw-r--r-- | crates/hir-def/src/signatures.rs | 11 | ||||
| -rw-r--r-- | crates/hir-ty/src/diagnostics/decl_check.rs | 37 | ||||
| -rw-r--r-- | crates/ide-diagnostics/src/handlers/incorrect_case.rs | 15 | ||||
| -rw-r--r-- | crates/ide-diagnostics/src/lib.rs | 1 |
4 files changed, 50 insertions, 14 deletions
diff --git a/crates/hir-def/src/signatures.rs b/crates/hir-def/src/signatures.rs index a13ef484ba..0dd88edbfb 100644 --- a/crates/hir-def/src/signatures.rs +++ b/crates/hir-def/src/signatures.rs @@ -185,6 +185,9 @@ impl UnionSignature { bitflags! { #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub struct EnumFlags: u8 { + /// Indicates whether this enum has `#[repr]`. + const HAS_REPR = 1 << 0; + /// Indicates whether the enum has a `#[rustc_has_incoherent_inherent_impls]` attribute. const RUSTC_HAS_INCOHERENT_INHERENT_IMPLS = 1 << 1; } } @@ -205,6 +208,9 @@ impl EnumSignature { if attrs.contains(AttrFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS) { flags |= EnumFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS; } + if attrs.contains(AttrFlags::HAS_REPR) { + flags |= EnumFlags::HAS_REPR; + } let InFile { file_id, value: source } = loc.source(db); let (store, generic_params, source_map) = lower_generic_params( @@ -233,6 +239,11 @@ impl EnumSignature { _ => IntegerType::Pointer(true), } } + + #[inline] + pub fn repr(&self, db: &dyn DefDatabase, id: EnumId) -> Option<ReprOptions> { + if self.flags.contains(EnumFlags::HAS_REPR) { AttrFlags::repr(db, id.into()) } else { None } + } } bitflags::bitflags! { #[derive(Debug, Clone, Copy, Eq, PartialEq, Default)] diff --git a/crates/hir-ty/src/diagnostics/decl_check.rs b/crates/hir-ty/src/diagnostics/decl_check.rs index a6852b87f6..29da1b0c51 100644 --- a/crates/hir-ty/src/diagnostics/decl_check.rs +++ b/crates/hir-ty/src/diagnostics/decl_check.rs @@ -293,12 +293,18 @@ impl<'a> DeclValidator<'a> { fn validate_struct(&mut self, struct_id: StructId) { // Check the structure name. let data = self.db.struct_signature(struct_id); - self.create_incorrect_case_diagnostic_for_item_name( - struct_id, - &data.name, - CaseType::UpperCamelCase, - IdentType::Structure, - ); + + // rustc implementation excuses repr(C) since C structs predominantly don't + // use camel case. + let has_repr_c = data.repr(self.db, struct_id).is_some_and(|repr| repr.c()); + if !has_repr_c { + self.create_incorrect_case_diagnostic_for_item_name( + struct_id, + &data.name, + CaseType::UpperCamelCase, + IdentType::Structure, + ); + } // Check the field names. self.validate_struct_fields(struct_id); @@ -378,15 +384,20 @@ impl<'a> DeclValidator<'a> { } fn validate_enum(&mut self, enum_id: EnumId) { + // Check the enum name. let data = self.db.enum_signature(enum_id); - // Check the enum name. - self.create_incorrect_case_diagnostic_for_item_name( - enum_id, - &data.name, - CaseType::UpperCamelCase, - IdentType::Enum, - ); + // rustc implementation excuses repr(C) since C structs predominantly don't + // use camel case. + let has_repr_c = data.repr(self.db, enum_id).is_some_and(|repr| repr.c()); + if !has_repr_c { + self.create_incorrect_case_diagnostic_for_item_name( + enum_id, + &data.name, + CaseType::UpperCamelCase, + IdentType::Enum, + ); + } // Check the variant names. self.validate_enum_variants(enum_id) diff --git a/crates/ide-diagnostics/src/handlers/incorrect_case.rs b/crates/ide-diagnostics/src/handlers/incorrect_case.rs index 8f68312b40..c47449f259 100644 --- a/crates/ide-diagnostics/src/handlers/incorrect_case.rs +++ b/crates/ide-diagnostics/src/handlers/incorrect_case.rs @@ -1059,4 +1059,19 @@ fn foo(_HelloWorld: ()) {} "#, ); } + + #[test] + fn allow_with_repr_c() { + check_diagnostics( + r#" +#[repr(C)] +struct FFI_Struct; + +#[repr(C)] +enum FFI_Enum { + Field, +} + "#, + ); + } } diff --git a/crates/ide-diagnostics/src/lib.rs b/crates/ide-diagnostics/src/lib.rs index 360ded1c0b..0c6953419f 100644 --- a/crates/ide-diagnostics/src/lib.rs +++ b/crates/ide-diagnostics/src/lib.rs @@ -108,7 +108,6 @@ use syntax::{ ast::{self, AstNode}, }; -// FIXME: Make this an enum #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] pub enum DiagnosticCode { RustcHardError(&'static str), |